From 639ad3ae142028ad721799aec8acb1a4c5e5e831 Mon Sep 17 00:00:00 2001 From: Nicolas Constant Date: Mon, 18 Jan 2021 02:07:09 -0500 Subject: [PATCH 1/2] user twitter service to retrieve timelines --- .../Processors/RetrieveTweetsProcessor.cs | 10 ++-- .../CachedTwitterService.cs | 16 +----- .../Models/TwitterUser.cs | 1 + ...tterService.cs => TwitterTweetsService.cs} | 46 ++++------------ .../TwitterUserService.cs | 55 +++++++++++++++++++ .../Controllers/UsersController.cs | 12 ++-- .../Controllers/WellKnownController.cs | 8 +-- src/BirdsiteLive/Startup.cs | 4 +- .../RetrieveTweetsProcessorTests.cs | 6 +- 9 files changed, 90 insertions(+), 68 deletions(-) rename src/BirdsiteLive.Twitter/{TwitterService.cs => TwitterTweetsService.cs} (61%) create mode 100644 src/BirdsiteLive.Twitter/TwitterUserService.cs diff --git a/src/BirdsiteLive.Pipeline/Processors/RetrieveTweetsProcessor.cs b/src/BirdsiteLive.Pipeline/Processors/RetrieveTweetsProcessor.cs index 68ca0b0..ef20cad 100644 --- a/src/BirdsiteLive.Pipeline/Processors/RetrieveTweetsProcessor.cs +++ b/src/BirdsiteLive.Pipeline/Processors/RetrieveTweetsProcessor.cs @@ -14,13 +14,13 @@ namespace BirdsiteLive.Pipeline.Processors { public class RetrieveTweetsProcessor : IRetrieveTweetsProcessor { - private readonly ITwitterService _twitterService; + private readonly ITwitterTweetsService _twitterTweetsService; private readonly ITwitterUserDal _twitterUserDal; #region Ctor - public RetrieveTweetsProcessor(ITwitterService twitterService, ITwitterUserDal twitterUserDal) + public RetrieveTweetsProcessor(ITwitterTweetsService twitterTweetsService, ITwitterUserDal twitterUserDal) { - _twitterService = twitterService; + _twitterTweetsService = twitterTweetsService; _twitterUserDal = twitterUserDal; } #endregion @@ -56,9 +56,9 @@ namespace BirdsiteLive.Pipeline.Processors { ExtractedTweet[] tweets; if (user.LastTweetPostedId == -1) - tweets = _twitterService.GetTimeline(user.Acct, 1); + tweets = _twitterTweetsService.GetTimeline(user.Acct, 1); else - tweets = _twitterService.GetTimeline(user.Acct, 200, user.LastTweetSynchronizedForAllFollowersId); + tweets = _twitterTweetsService.GetTimeline(user.Acct, 200, user.LastTweetSynchronizedForAllFollowersId); return tweets; } diff --git a/src/BirdsiteLive.Twitter/CachedTwitterService.cs b/src/BirdsiteLive.Twitter/CachedTwitterService.cs index a77fb12..3b2de8d 100644 --- a/src/BirdsiteLive.Twitter/CachedTwitterService.cs +++ b/src/BirdsiteLive.Twitter/CachedTwitterService.cs @@ -4,9 +4,9 @@ using Microsoft.Extensions.Caching.Memory; namespace BirdsiteLive.Twitter { - public class CachedTwitterService : ITwitterService + public class CachedTwitterUserService : ITwitterUserService { - private readonly ITwitterService _twitterService; + private readonly ITwitterUserService _twitterService; private MemoryCache _userCache = new MemoryCache(new MemoryCacheOptions() { @@ -22,7 +22,7 @@ namespace BirdsiteLive.Twitter .SetAbsoluteExpiration(TimeSpan.FromDays(30)); #region Ctor - public CachedTwitterService(ITwitterService twitterService) + public CachedTwitterUserService(ITwitterUserService twitterService) { _twitterService = twitterService; } @@ -38,15 +38,5 @@ namespace BirdsiteLive.Twitter return user; } - - public ExtractedTweet GetTweet(long statusId) - { - return _twitterService.GetTweet(statusId); - } - - public ExtractedTweet[] GetTimeline(string username, int nberTweets, long fromTweetId = -1) - { - return _twitterService.GetTimeline(username, nberTweets, fromTweetId); - } } } \ No newline at end of file diff --git a/src/BirdsiteLive.Twitter/Models/TwitterUser.cs b/src/BirdsiteLive.Twitter/Models/TwitterUser.cs index 1050486..1db3350 100644 --- a/src/BirdsiteLive.Twitter/Models/TwitterUser.cs +++ b/src/BirdsiteLive.Twitter/Models/TwitterUser.cs @@ -2,6 +2,7 @@ { public class TwitterUser { + public long Id { get; set; } public string Name { get; set; } public string Description { get; set; } public string Url { get; set; } diff --git a/src/BirdsiteLive.Twitter/TwitterService.cs b/src/BirdsiteLive.Twitter/TwitterTweetsService.cs similarity index 61% rename from src/BirdsiteLive.Twitter/TwitterService.cs rename to src/BirdsiteLive.Twitter/TwitterTweetsService.cs index b4fdd92..ee104ae 100644 --- a/src/BirdsiteLive.Twitter/TwitterService.cs +++ b/src/BirdsiteLive.Twitter/TwitterTweetsService.cs @@ -1,65 +1,39 @@ -using System; -using System.Collections.Generic; -using System.IO; +using System.Collections.Generic; using System.Linq; -using System.Threading.Tasks; using BirdsiteLive.Common.Settings; using BirdsiteLive.Statistics.Domain; using BirdsiteLive.Twitter.Extractors; using BirdsiteLive.Twitter.Models; using Tweetinvi; using Tweetinvi.Models; -using Tweetinvi.Models.Entities; using Tweetinvi.Parameters; namespace BirdsiteLive.Twitter { - public interface ITwitterService + public interface ITwitterTweetsService { - TwitterUser GetUser(string username); ExtractedTweet GetTweet(long statusId); ExtractedTweet[] GetTimeline(string username, int nberTweets, long fromTweetId = -1); } - public class TwitterService : ITwitterService + public class TwitterTweetsService : ITwitterTweetsService { private readonly TwitterSettings _settings; private readonly ITweetExtractor _tweetExtractor; private readonly ITwitterStatisticsHandler _statisticsHandler; + private readonly ITwitterUserService _twitterUserService; #region Ctor - public TwitterService(TwitterSettings settings, ITweetExtractor tweetExtractor, ITwitterStatisticsHandler statisticsHandler) + public TwitterTweetsService(TwitterSettings settings, ITweetExtractor tweetExtractor, ITwitterStatisticsHandler statisticsHandler, ITwitterUserService twitterUserService) { _settings = settings; _tweetExtractor = tweetExtractor; _statisticsHandler = statisticsHandler; + _twitterUserService = twitterUserService; Auth.SetApplicationOnlyCredentials(_settings.ConsumerKey, _settings.ConsumerSecret, true); } #endregion - - public TwitterUser GetUser(string username) - { - var user = User.GetUserFromScreenName(username); - _statisticsHandler.CalledUserApi(); - if (user == null) return null; - - // Expand URLs - var description = user.Description; - foreach (var descriptionUrl in user.Entities?.Description?.Urls?.OrderByDescending(x => x.URL.Length)) - description = description.Replace(descriptionUrl.URL, descriptionUrl.ExpandedURL); - - return new TwitterUser - { - Acct = username, - Name = user.Name, - Description = description, - Url = $"https://twitter.com/{username}", - ProfileImageUrl = user.ProfileImageUrlFullSize, - ProfileBackgroundImageUrl = user.ProfileBackgroundImageUrlHttps, - ProfileBannerURL = user.ProfileBannerURL - }; - } - + public ExtractedTweet GetTweet(long statusId) { TweetinviConfig.CurrentThreadSettings.TweetMode = TweetMode.Extended; @@ -72,9 +46,9 @@ namespace BirdsiteLive.Twitter public ExtractedTweet[] GetTimeline(string username, int nberTweets, long fromTweetId = -1) { TweetinviConfig.CurrentThreadSettings.TweetMode = TweetMode.Extended; + + var user = _twitterUserService.GetUser(username); - var user = User.GetUserFromScreenName(username); - _statisticsHandler.CalledUserApi(); var tweets = new List(); if (fromTweetId == -1) { @@ -97,4 +71,4 @@ namespace BirdsiteLive.Twitter return tweets.Select(_tweetExtractor.Extract).ToArray(); } } -} +} \ No newline at end of file diff --git a/src/BirdsiteLive.Twitter/TwitterUserService.cs b/src/BirdsiteLive.Twitter/TwitterUserService.cs new file mode 100644 index 0000000..01a70bb --- /dev/null +++ b/src/BirdsiteLive.Twitter/TwitterUserService.cs @@ -0,0 +1,55 @@ +using System.Linq; +using BirdsiteLive.Common.Settings; +using BirdsiteLive.Statistics.Domain; +using BirdsiteLive.Twitter.Extractors; +using BirdsiteLive.Twitter.Models; +using Tweetinvi; + +namespace BirdsiteLive.Twitter +{ + public interface ITwitterUserService + { + TwitterUser GetUser(string username); + } + + public class TwitterUserService : ITwitterUserService + { + private readonly TwitterSettings _settings; + private readonly ITweetExtractor _tweetExtractor; + private readonly ITwitterStatisticsHandler _statisticsHandler; + + #region Ctor + public TwitterUserService(TwitterSettings settings, ITweetExtractor tweetExtractor, ITwitterStatisticsHandler statisticsHandler) + { + _settings = settings; + _tweetExtractor = tweetExtractor; + _statisticsHandler = statisticsHandler; + Auth.SetApplicationOnlyCredentials(_settings.ConsumerKey, _settings.ConsumerSecret, true); + } + #endregion + + public TwitterUser GetUser(string username) + { + var user = User.GetUserFromScreenName(username); + _statisticsHandler.CalledUserApi(); + if (user == null) return null; + + // Expand URLs + var description = user.Description; + foreach (var descriptionUrl in user.Entities?.Description?.Urls?.OrderByDescending(x => x.URL.Length)) + description = description.Replace(descriptionUrl.URL, descriptionUrl.ExpandedURL); + + return new TwitterUser + { + Id = user.Id, + Acct = username, + Name = user.Name, + Description = description, + Url = $"https://twitter.com/{username}", + ProfileImageUrl = user.ProfileImageUrlFullSize, + ProfileBackgroundImageUrl = user.ProfileBackgroundImageUrlHttps, + ProfileBannerURL = user.ProfileBannerURL + }; + } + } +} \ No newline at end of file diff --git a/src/BirdsiteLive/Controllers/UsersController.cs b/src/BirdsiteLive/Controllers/UsersController.cs index d1d22c8..f91b3cf 100644 --- a/src/BirdsiteLive/Controllers/UsersController.cs +++ b/src/BirdsiteLive/Controllers/UsersController.cs @@ -21,18 +21,20 @@ namespace BirdsiteLive.Controllers { public class UsersController : Controller { - private readonly ITwitterService _twitterService; + private readonly ITwitterUserService _twitterUserService; + private readonly ITwitterTweetsService _twitterTweetService; private readonly IUserService _userService; private readonly IStatusService _statusService; private readonly InstanceSettings _instanceSettings; #region Ctor - public UsersController(ITwitterService twitterService, IUserService userService, IStatusService statusService, InstanceSettings instanceSettings) + public UsersController(ITwitterUserService twitterUserService, IUserService userService, IStatusService statusService, InstanceSettings instanceSettings, ITwitterTweetsService twitterTweetService) { - _twitterService = twitterService; + _twitterUserService = twitterUserService; _userService = userService; _statusService = statusService; _instanceSettings = instanceSettings; + _twitterTweetService = twitterTweetService; } #endregion @@ -53,7 +55,7 @@ namespace BirdsiteLive.Controllers public IActionResult Index(string id) { id = id.Trim(new[] { ' ', '@' }).ToLowerInvariant(); - var user = _twitterService.GetUser(id); + var user = _twitterUserService.GetUser(id); var acceptHeaders = Request.Headers["Accept"]; if (acceptHeaders.Any()) @@ -96,7 +98,7 @@ namespace BirdsiteLive.Controllers if (!long.TryParse(statusId, out var parsedStatusId)) return NotFound(); - var tweet = _twitterService.GetTweet(parsedStatusId); + var tweet = _twitterTweetService.GetTweet(parsedStatusId); if (tweet == null) return NotFound(); diff --git a/src/BirdsiteLive/Controllers/WellKnownController.cs b/src/BirdsiteLive/Controllers/WellKnownController.cs index 255981d..553d8e7 100644 --- a/src/BirdsiteLive/Controllers/WellKnownController.cs +++ b/src/BirdsiteLive/Controllers/WellKnownController.cs @@ -16,14 +16,14 @@ namespace BirdsiteLive.Controllers [ApiController] public class WellKnownController : ControllerBase { - private readonly ITwitterService _twitterService; + private readonly ITwitterUserService _twitterUserService; private readonly ITwitterUserDal _twitterUserDal; private readonly InstanceSettings _settings; #region Ctor - public WellKnownController(InstanceSettings settings, ITwitterService twitterService, ITwitterUserDal twitterUserDal) + public WellKnownController(InstanceSettings settings, ITwitterUserService twitterUserService, ITwitterUserDal twitterUserDal) { - _twitterService = twitterService; + _twitterUserService = twitterUserService; _twitterUserDal = twitterUserDal; _settings = settings; } @@ -163,7 +163,7 @@ namespace BirdsiteLive.Controllers if (!string.IsNullOrWhiteSpace(domain) && domain != _settings.Domain) return NotFound(); - var user = _twitterService.GetUser(name); + var user = _twitterUserService.GetUser(name); if (user == null) return NotFound(); diff --git a/src/BirdsiteLive/Startup.cs b/src/BirdsiteLive/Startup.cs index 9c37a54..371e969 100644 --- a/src/BirdsiteLive/Startup.cs +++ b/src/BirdsiteLive/Startup.cs @@ -84,8 +84,8 @@ namespace BirdsiteLive throw new NotImplementedException($"{dbSettings.Type} is not supported"); } - services.For().DecorateAllWith(); - services.For().Use().Singleton(); + services.For().DecorateAllWith(); + services.For().Use().Singleton(); services.Scan(_ => { diff --git a/src/Tests/BirdsiteLive.Pipeline.Tests/Processors/RetrieveTweetsProcessorTests.cs b/src/Tests/BirdsiteLive.Pipeline.Tests/Processors/RetrieveTweetsProcessorTests.cs index 8873bf7..2bf5d74 100644 --- a/src/Tests/BirdsiteLive.Pipeline.Tests/Processors/RetrieveTweetsProcessorTests.cs +++ b/src/Tests/BirdsiteLive.Pipeline.Tests/Processors/RetrieveTweetsProcessorTests.cs @@ -40,7 +40,7 @@ namespace BirdsiteLive.Pipeline.Tests.Processors #endregion #region Mocks - var twitterServiceMock = new Mock(MockBehavior.Strict); + var twitterServiceMock = new Mock(MockBehavior.Strict); twitterServiceMock .Setup(x => x.GetTimeline( It.Is(y => y == user1.Acct), @@ -105,7 +105,7 @@ namespace BirdsiteLive.Pipeline.Tests.Processors #endregion #region Mocks - var twitterServiceMock = new Mock(MockBehavior.Strict); + var twitterServiceMock = new Mock(MockBehavior.Strict); twitterServiceMock .Setup(x => x.GetTimeline( It.Is(y => y == user1.Acct), @@ -165,7 +165,7 @@ namespace BirdsiteLive.Pipeline.Tests.Processors #endregion #region Mocks - var twitterServiceMock = new Mock(MockBehavior.Strict); + var twitterServiceMock = new Mock(MockBehavior.Strict); twitterServiceMock .Setup(x => x.GetTimeline( It.Is(y => y == user1.Acct), From 6ae5f06280fffad1e8cff51da39da35adfbf2c21 Mon Sep 17 00:00:00 2001 From: Nicolas Constant Date: Mon, 18 Jan 2021 02:08:50 -0500 Subject: [PATCH 2/2] road to 0.9.1 --- src/BirdsiteLive/BirdsiteLive.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/BirdsiteLive/BirdsiteLive.csproj b/src/BirdsiteLive/BirdsiteLive.csproj index 9cfe9db..34a2392 100644 --- a/src/BirdsiteLive/BirdsiteLive.csproj +++ b/src/BirdsiteLive/BirdsiteLive.csproj @@ -4,7 +4,7 @@ netcoreapp3.1 d21486de-a812-47eb-a419-05682bb68856 Linux - 0.9.0 + 0.9.1