From 0174a3260273d968b5c33c5a94e4f931546ffbcc Mon Sep 17 00:00:00 2001 From: Maksym Pavlenko Date: Thu, 5 Jan 2017 11:50:51 -0800 Subject: [PATCH 01/12] Implement Vimeo API client --- src/Podsync/Services/PodsyncConfiguration.cs | 2 + src/Podsync/Services/Videos/Vimeo/Group.cs | 19 +++ .../Services/Videos/Vimeo/IVimeoClient.cs | 20 +++ src/Podsync/Services/Videos/Vimeo/User.cs | 17 +++ src/Podsync/Services/Videos/Vimeo/Video.cs | 21 +++ .../Services/Videos/Vimeo/VimeoClient.cs | 140 ++++++++++++++++++ src/Podsync/Startup.cs | 2 + src/Podsync/appsettings.json | 1 + .../Services/Videos/Vimeo/VimeoClientTests.cs | 92 ++++++++++++ 9 files changed, 314 insertions(+) create mode 100644 src/Podsync/Services/Videos/Vimeo/Group.cs create mode 100644 src/Podsync/Services/Videos/Vimeo/IVimeoClient.cs create mode 100644 src/Podsync/Services/Videos/Vimeo/User.cs create mode 100644 src/Podsync/Services/Videos/Vimeo/Video.cs create mode 100644 src/Podsync/Services/Videos/Vimeo/VimeoClient.cs create mode 100644 test/Podsync.Tests/Services/Videos/Vimeo/VimeoClientTests.cs diff --git a/src/Podsync/Services/PodsyncConfiguration.cs b/src/Podsync/Services/PodsyncConfiguration.cs index 13e26c1..d31aae7 100644 --- a/src/Podsync/Services/PodsyncConfiguration.cs +++ b/src/Podsync/Services/PodsyncConfiguration.cs @@ -6,6 +6,8 @@ namespace Podsync.Services { public string YouTubeApiKey { get; set; } + public string VimeoApiKey { get; set; } + public string RedisConnectionString { get; set; } public string PatreonClientId { get; set; } diff --git a/src/Podsync/Services/Videos/Vimeo/Group.cs b/src/Podsync/Services/Videos/Vimeo/Group.cs new file mode 100644 index 0000000..08bbcda --- /dev/null +++ b/src/Podsync/Services/Videos/Vimeo/Group.cs @@ -0,0 +1,19 @@ +using System; + +namespace Podsync.Services.Videos.Vimeo +{ + public class Group + { + public string Name { get; set; } + + public string Description { get; set; } + + public Uri Link { get; set; } + + public DateTime CreatedAt { get; set; } + + public Uri Thumbnail { get; set; } + + public string Author { get; set; } + } +} \ No newline at end of file diff --git a/src/Podsync/Services/Videos/Vimeo/IVimeoClient.cs b/src/Podsync/Services/Videos/Vimeo/IVimeoClient.cs new file mode 100644 index 0000000..012ef61 --- /dev/null +++ b/src/Podsync/Services/Videos/Vimeo/IVimeoClient.cs @@ -0,0 +1,20 @@ +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Podsync.Services.Videos.Vimeo +{ + public interface IVimeoClient + { + Task Group(string id); + + Task Channel(string id); + + Task User(string id); + + Task> GroupVideos(string id, int count); + + Task> UserVideos(string id, int count); + + Task> ChannelVideos(string id, int count); + } +} \ No newline at end of file diff --git a/src/Podsync/Services/Videos/Vimeo/User.cs b/src/Podsync/Services/Videos/Vimeo/User.cs new file mode 100644 index 0000000..ed51c4f --- /dev/null +++ b/src/Podsync/Services/Videos/Vimeo/User.cs @@ -0,0 +1,17 @@ +using System; + +namespace Podsync.Services.Videos.Vimeo +{ + public class User + { + public string Name { get; set; } + + public string Bio { get; set; } + + public DateTime CreatedAt { get; set; } + + public Uri Link { get; set; } + + public Uri Thumbnail { get; set; } + } +} \ No newline at end of file diff --git a/src/Podsync/Services/Videos/Vimeo/Video.cs b/src/Podsync/Services/Videos/Vimeo/Video.cs new file mode 100644 index 0000000..e01ac47 --- /dev/null +++ b/src/Podsync/Services/Videos/Vimeo/Video.cs @@ -0,0 +1,21 @@ +using System; + +namespace Podsync.Services.Videos.Vimeo +{ + public class Video + { + public string Title { get; set; } + + public string Description { get; set; } + + public Uri Link { get; set; } + + public Uri Thumbnail { get; set; } + + public DateTime CreatedAt { get; set; } + + public long Size { get; set; } + + public TimeSpan Duration { get; set; } + } +} \ No newline at end of file diff --git a/src/Podsync/Services/Videos/Vimeo/VimeoClient.cs b/src/Podsync/Services/Videos/Vimeo/VimeoClient.cs new file mode 100644 index 0000000..6743422 --- /dev/null +++ b/src/Podsync/Services/Videos/Vimeo/VimeoClient.cs @@ -0,0 +1,140 @@ +using System; +using System.Collections.Generic; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Threading.Tasks; +using Microsoft.Extensions.Options; +using Newtonsoft.Json.Linq; + +namespace Podsync.Services.Videos.Vimeo +{ + // ReSharper disable once ClassNeverInstantiated.Global + public sealed class VimeoClient : IVimeoClient, IDisposable + { + private const int MaxPageSize = 100; + + private readonly HttpClient _client = new HttpClient(); + + public VimeoClient(IOptions configuration) + { + _client.BaseAddress = new Uri("https://api.vimeo.com/"); + _client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", configuration.Value.VimeoApiKey); + } + + public Task Group(string id) + { + return QueryGroup($"groups/{id}"); + } + + public Task Channel(string id) + { + return QueryGroup($"channels/{id}"); + } + + public async Task User(string id) + { + dynamic json = await QueryApi($"users/{id}"); + + return new User + { + Name = json.name, + Bio = json.bio, + Link = new Uri(json.link.ToString()), + Thumbnail = new Uri(json.pictures.sizes[0].link.ToString()), + CreatedAt = DateTime.Parse(json.created_time.ToString()), + }; + } + + public Task> GroupVideos(string id, int count) + { + return QueryVideos($"groups/{id}/videos", count); + } + + public Task> UserVideos(string id, int count) + { + return QueryVideos($"users/{id}/videos", count); + } + + public Task> ChannelVideos(string id, int count) + { + return QueryVideos($"channels/{id}/videos", count); + } + + public void Dispose() + { + _client.Dispose(); + } + + private async Task> QueryVideos(string path, int count) + { + if (count <= 0) + { + throw new ArgumentException("Invalid item count", nameof(count)); + } + + var collection = new List