Merge pull request #43 from NicolasConstant/topic_add-api-statistics

Topic add api statistics
This commit is contained in:
Nicolas Constant 2021-01-13 05:58:26 +01:00 committed by GitHub
commit a37ebff6a2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 122 additions and 8 deletions

View File

@ -0,0 +1,12 @@
namespace BirdsiteLive.Twitter.Models
{
public class ApiStatistics
{
public int UserCallsCount { get; set; }
public int UserCallsMax { get; set; }
public int TweetCallsCount { get; set; }
public int TweetCallsMax { get; set; }
public int TimelineCallsCount { get; set; }
public int TimelineCallsMax { get; set; }
}
}

View File

@ -0,0 +1,80 @@
using System.Threading;
using System.Timers;
using BirdsiteLive.Twitter.Models;
namespace BirdsiteLive.Statistics.Domain
{
public interface ITwitterStatisticsHandler
{
void CalledUserApi();
void CalledTweetApi();
void CalledTimelineApi();
ApiStatistics GetStatistics();
}
//Rate limits: https://developer.twitter.com/en/docs/twitter-api/v1/rate-limits
public class TwitterStatisticsHandler : ITwitterStatisticsHandler
{
private static int _previousUserCalls;
private static int _previousTweetCalls;
private static int _previousTimelineCalls;
private static int _userCalls;
private static int _tweetCalls;
private static int _timelineCalls;
private static System.Timers.Timer _resetTimer;
#region Ctor
public TwitterStatisticsHandler()
{
if (_resetTimer == null)
{
_resetTimer = new System.Timers.Timer();
_resetTimer.Elapsed += OnTimeResetEvent;
_resetTimer.Interval = 15 * 60 * 1000; // 15"
_resetTimer.Enabled = true;
}
}
#endregion
private void OnTimeResetEvent(object sender, ElapsedEventArgs e)
{
_previousUserCalls = _userCalls;
_previousTweetCalls = _tweetCalls;
_previousTimelineCalls = _timelineCalls;
Interlocked.Exchange(ref _userCalls, 0);
Interlocked.Exchange(ref _tweetCalls, 0);
Interlocked.Exchange(ref _timelineCalls, 0);
}
public void CalledUserApi() //GET users/show - 900/15mins
{
Interlocked.Increment(ref _userCalls);
}
public void CalledTweetApi() //GET statuses/lookup - 300/15mins
{
Interlocked.Increment(ref _tweetCalls);
}
public void CalledTimelineApi() // GET statuses/user_timeline - 1500/15 mins
{
Interlocked.Increment(ref _timelineCalls);
}
public ApiStatistics GetStatistics()
{
return new ApiStatistics
{
UserCallsCount = _previousUserCalls,
UserCallsMax = 900,
TweetCallsCount = _previousTweetCalls,
TweetCallsMax = 300,
TimelineCallsCount = _previousTimelineCalls,
TimelineCallsMax = 1500
};
}
}
}

View File

@ -4,6 +4,7 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using BirdsiteLive.Common.Settings; using BirdsiteLive.Common.Settings;
using BirdsiteLive.Statistics.Domain;
using BirdsiteLive.Twitter.Extractors; using BirdsiteLive.Twitter.Extractors;
using BirdsiteLive.Twitter.Models; using BirdsiteLive.Twitter.Models;
using Tweetinvi; using Tweetinvi;
@ -24,12 +25,14 @@ namespace BirdsiteLive.Twitter
{ {
private readonly TwitterSettings _settings; private readonly TwitterSettings _settings;
private readonly ITweetExtractor _tweetExtractor; private readonly ITweetExtractor _tweetExtractor;
private readonly ITwitterStatisticsHandler _statisticsHandler;
#region Ctor #region Ctor
public TwitterService(TwitterSettings settings, ITweetExtractor tweetExtractor) public TwitterService(TwitterSettings settings, ITweetExtractor tweetExtractor, ITwitterStatisticsHandler statisticsHandler)
{ {
_settings = settings; _settings = settings;
_tweetExtractor = tweetExtractor; _tweetExtractor = tweetExtractor;
_statisticsHandler = statisticsHandler;
Auth.SetApplicationOnlyCredentials(_settings.ConsumerKey, _settings.ConsumerSecret, true); Auth.SetApplicationOnlyCredentials(_settings.ConsumerKey, _settings.ConsumerSecret, true);
} }
#endregion #endregion
@ -37,6 +40,7 @@ namespace BirdsiteLive.Twitter
public TwitterUser GetUser(string username) public TwitterUser GetUser(string username)
{ {
var user = User.GetUserFromScreenName(username); var user = User.GetUserFromScreenName(username);
_statisticsHandler.CalledUserApi();
if (user == null) return null; if (user == null) return null;
return new TwitterUser return new TwitterUser
@ -55,6 +59,8 @@ namespace BirdsiteLive.Twitter
{ {
TweetinviConfig.CurrentThreadSettings.TweetMode = TweetMode.Extended; TweetinviConfig.CurrentThreadSettings.TweetMode = TweetMode.Extended;
var tweet = Tweet.GetTweet(statusId); var tweet = Tweet.GetTweet(statusId);
_statisticsHandler.CalledTweetApi();
if (tweet == null) return null; //TODO: test this
return _tweetExtractor.Extract(tweet); return _tweetExtractor.Extract(tweet);
} }
@ -63,10 +69,12 @@ namespace BirdsiteLive.Twitter
TweetinviConfig.CurrentThreadSettings.TweetMode = TweetMode.Extended; TweetinviConfig.CurrentThreadSettings.TweetMode = TweetMode.Extended;
var user = User.GetUserFromScreenName(username); var user = User.GetUserFromScreenName(username);
_statisticsHandler.CalledUserApi();
var tweets = new List<ITweet>(); var tweets = new List<ITweet>();
if (fromTweetId == -1) if (fromTweetId == -1)
{ {
var timeline = Timeline.GetUserTimeline(user.Id, nberTweets); var timeline = Timeline.GetUserTimeline(user.Id, nberTweets);
_statisticsHandler.CalledTimelineApi();
if (timeline != null) tweets.AddRange(timeline); if (timeline != null) tweets.AddRange(timeline);
} }
else else
@ -77,11 +85,11 @@ namespace BirdsiteLive.Twitter
MaximumNumberOfTweetsToRetrieve = nberTweets MaximumNumberOfTweetsToRetrieve = nberTweets
}; };
var timeline = Timeline.GetUserTimeline(user.Id, timelineRequestParameters); var timeline = Timeline.GetUserTimeline(user.Id, timelineRequestParameters);
_statisticsHandler.CalledTimelineApi();
if (timeline != null) tweets.AddRange(timeline); if (timeline != null) tweets.AddRange(timeline);
} }
return tweets.Select(_tweetExtractor.Extract).ToArray(); return tweets.Select(_tweetExtractor.Extract).ToArray();
//return tweets.Where(x => returnReplies || string.IsNullOrWhiteSpace(x.InReplyToScreenName)).ToArray();
} }
} }
} }

View File

@ -4,7 +4,7 @@
<TargetFramework>netcoreapp3.1</TargetFramework> <TargetFramework>netcoreapp3.1</TargetFramework>
<UserSecretsId>d21486de-a812-47eb-a419-05682bb68856</UserSecretsId> <UserSecretsId>d21486de-a812-47eb-a419-05682bb68856</UserSecretsId>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS> <DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<Version>0.5.0</Version> <Version>0.6.0</Version>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View File

@ -3,7 +3,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using BirdsiteLive.DAL.Contracts; using BirdsiteLive.DAL.Contracts;
using BirdsiteLive.Models.StatisticsModels; using BirdsiteLive.Statistics.Domain;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
namespace BirdsiteLive.Controllers namespace BirdsiteLive.Controllers
@ -12,21 +12,24 @@ namespace BirdsiteLive.Controllers
{ {
private readonly ITwitterUserDal _twitterUserDal; private readonly ITwitterUserDal _twitterUserDal;
private readonly IFollowersDal _followersDal; private readonly IFollowersDal _followersDal;
private readonly ITwitterStatisticsHandler _twitterStatistics;
#region Ctor #region Ctor
public StatisticsController(ITwitterUserDal twitterUserDal, IFollowersDal followersDal) public StatisticsController(ITwitterUserDal twitterUserDal, IFollowersDal followersDal, ITwitterStatisticsHandler twitterStatistics)
{ {
_twitterUserDal = twitterUserDal; _twitterUserDal = twitterUserDal;
_followersDal = followersDal; _followersDal = followersDal;
_twitterStatistics = twitterStatistics;
} }
#endregion #endregion
public async Task<IActionResult> Index() public async Task<IActionResult> Index()
{ {
var stats = new Statistics var stats = new Models.StatisticsModels.Statistics
{ {
FollowersCount = await _followersDal.GetFollowersCountAsync(), FollowersCount = await _followersDal.GetFollowersCountAsync(),
TwitterUserCount = await _twitterUserDal.GetTwitterUsersCountAsync() TwitterUserCount = await _twitterUserDal.GetTwitterUsersCountAsync(),
TwitterStatistics = _twitterStatistics.GetStatistics()
}; };
return View(stats); return View(stats);
} }

View File

@ -1,8 +1,11 @@
namespace BirdsiteLive.Models.StatisticsModels using BirdsiteLive.Twitter.Models;
namespace BirdsiteLive.Models.StatisticsModels
{ {
public class Statistics public class Statistics
{ {
public int FollowersCount { get; set; } public int FollowersCount { get; set; }
public int TwitterUserCount { get; set; } public int TwitterUserCount { get; set; }
public ApiStatistics TwitterStatistics { get; set; }
} }
} }

View File

@ -6,7 +6,15 @@
<h2>Statistics</h2> <h2>Statistics</h2>
<h4>Instance</h4>
<ul> <ul>
<li>Twitter Users: @Model.TwitterUserCount</li> <li>Twitter Users: @Model.TwitterUserCount</li>
<li>Followers: @Model.FollowersCount</li> <li>Followers: @Model.FollowersCount</li>
</ul> </ul>
<h4>Twitter API</h4>
<ul>
<li>Users Calls: @Model.TwitterStatistics.UserCallsCount / @Model.TwitterStatistics.UserCallsMax</li>
<li>Tweets Calls: @Model.TwitterStatistics.TweetCallsCount / @Model.TwitterStatistics.TweetCallsMax</li>
<li>Timeline Calls: @Model.TwitterStatistics.TimelineCallsCount / @Model.TwitterStatistics.TimelineCallsMax</li>
</ul>