added first iteration of API statistics

This commit is contained in:
Nicolas Constant 2021-01-12 23:53:23 -05:00
parent cb64e9747a
commit 39a56244e5
No known key found for this signature in database
GPG key ID: 1E9F677FB01A5688
6 changed files with 121 additions and 7 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.Threading.Tasks;
using BirdsiteLive.Common.Settings;
using BirdsiteLive.Statistics.Domain;
using BirdsiteLive.Twitter.Extractors;
using BirdsiteLive.Twitter.Models;
using Tweetinvi;
@ -24,12 +25,14 @@ namespace BirdsiteLive.Twitter
{
private readonly TwitterSettings _settings;
private readonly ITweetExtractor _tweetExtractor;
private readonly ITwitterStatisticsHandler _statisticsHandler;
#region Ctor
public TwitterService(TwitterSettings settings, ITweetExtractor tweetExtractor)
public TwitterService(TwitterSettings settings, ITweetExtractor tweetExtractor, ITwitterStatisticsHandler statisticsHandler)
{
_settings = settings;
_tweetExtractor = tweetExtractor;
_statisticsHandler = statisticsHandler;
Auth.SetApplicationOnlyCredentials(_settings.ConsumerKey, _settings.ConsumerSecret, true);
}
#endregion
@ -37,6 +40,7 @@ namespace BirdsiteLive.Twitter
public TwitterUser GetUser(string username)
{
var user = User.GetUserFromScreenName(username);
_statisticsHandler.CalledUserApi();
if (user == null) return null;
return new TwitterUser
@ -55,6 +59,8 @@ namespace BirdsiteLive.Twitter
{
TweetinviConfig.CurrentThreadSettings.TweetMode = TweetMode.Extended;
var tweet = Tweet.GetTweet(statusId);
_statisticsHandler.CalledTweetApi();
if (tweet == null) return null; //TODO: test this
return _tweetExtractor.Extract(tweet);
}
@ -63,10 +69,12 @@ namespace BirdsiteLive.Twitter
TweetinviConfig.CurrentThreadSettings.TweetMode = TweetMode.Extended;
var user = User.GetUserFromScreenName(username);
_statisticsHandler.CalledUserApi();
var tweets = new List<ITweet>();
if (fromTweetId == -1)
{
var timeline = Timeline.GetUserTimeline(user.Id, nberTweets);
_statisticsHandler.CalledTimelineApi();
if (timeline != null) tweets.AddRange(timeline);
}
else
@ -77,11 +85,11 @@ namespace BirdsiteLive.Twitter
MaximumNumberOfTweetsToRetrieve = nberTweets
};
var timeline = Timeline.GetUserTimeline(user.Id, timelineRequestParameters);
_statisticsHandler.CalledTimelineApi();
if (timeline != null) tweets.AddRange(timeline);
}
return tweets.Select(_tweetExtractor.Extract).ToArray();
//return tweets.Where(x => returnReplies || string.IsNullOrWhiteSpace(x.InReplyToScreenName)).ToArray();
}
}
}

View file

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

View file

@ -6,7 +6,15 @@
<h2>Statistics</h2>
<h4>Instance</h4>
<ul>
<li>Twitter Users: @Model.TwitterUserCount</li>
<li>Followers: @Model.FollowersCount</li>
</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>