2020-03-21 18:58:23 -04:00
|
|
|
|
using System;
|
2020-07-18 23:35:19 -04:00
|
|
|
|
using System.Collections.Generic;
|
2020-07-22 20:19:40 -04:00
|
|
|
|
using System.IO;
|
2020-07-18 23:35:19 -04:00
|
|
|
|
using System.Linq;
|
2020-03-22 01:29:51 -04:00
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using BirdsiteLive.Common.Settings;
|
|
|
|
|
using BirdsiteLive.Twitter.Models;
|
2020-03-21 23:55:49 -04:00
|
|
|
|
using Tweetinvi;
|
2020-07-01 22:45:43 -04:00
|
|
|
|
using Tweetinvi.Models;
|
2020-07-22 20:19:40 -04:00
|
|
|
|
using Tweetinvi.Models.Entities;
|
2020-07-18 23:35:19 -04:00
|
|
|
|
using Tweetinvi.Parameters;
|
2020-03-21 18:58:23 -04:00
|
|
|
|
|
|
|
|
|
namespace BirdsiteLive.Twitter
|
|
|
|
|
{
|
|
|
|
|
public interface ITwitterService
|
|
|
|
|
{
|
2020-03-22 01:29:51 -04:00
|
|
|
|
TwitterUser GetUser(string username);
|
2020-07-22 20:19:40 -04:00
|
|
|
|
ExtractedTweet GetTweet(long statusId);
|
|
|
|
|
ExtractedTweet[] GetTimeline(string username, int nberTweets, long fromTweetId = -1);
|
2020-03-21 18:58:23 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class TwitterService : ITwitterService
|
|
|
|
|
{
|
|
|
|
|
private readonly TwitterSettings _settings;
|
|
|
|
|
|
|
|
|
|
#region Ctor
|
|
|
|
|
public TwitterService(TwitterSettings settings)
|
|
|
|
|
{
|
|
|
|
|
_settings = settings;
|
2020-07-18 23:35:19 -04:00
|
|
|
|
Auth.SetApplicationOnlyCredentials(_settings.ConsumerKey, _settings.ConsumerSecret, true);
|
2020-03-21 18:58:23 -04:00
|
|
|
|
}
|
|
|
|
|
#endregion
|
2020-03-21 23:55:49 -04:00
|
|
|
|
|
2020-03-22 01:29:51 -04:00
|
|
|
|
public TwitterUser GetUser(string username)
|
2020-03-21 23:55:49 -04:00
|
|
|
|
{
|
|
|
|
|
var user = User.GetUserFromScreenName(username);
|
2020-03-22 16:38:15 -04:00
|
|
|
|
if (user == null) return null;
|
2020-03-22 01:29:51 -04:00
|
|
|
|
|
|
|
|
|
return new TwitterUser
|
|
|
|
|
{
|
2020-03-22 16:38:15 -04:00
|
|
|
|
Acct = username,
|
2020-03-22 01:29:51 -04:00
|
|
|
|
Name = user.Name,
|
|
|
|
|
Description = user.Description,
|
2020-03-22 16:45:26 -04:00
|
|
|
|
Url = $"https://twitter.com/{username}",
|
2020-03-22 16:38:15 -04:00
|
|
|
|
ProfileImageUrl = user.ProfileImageUrlFullSize,
|
|
|
|
|
ProfileBackgroundImageUrl = user.ProfileBackgroundImageUrlHttps,
|
|
|
|
|
ProfileBannerURL = user.ProfileBannerURL
|
2020-03-22 01:29:51 -04:00
|
|
|
|
};
|
2020-03-21 23:55:49 -04:00
|
|
|
|
}
|
2020-07-01 22:45:43 -04:00
|
|
|
|
|
2020-07-22 20:19:40 -04:00
|
|
|
|
public ExtractedTweet GetTweet(long statusId)
|
2020-07-01 22:45:43 -04:00
|
|
|
|
{
|
2020-07-22 20:19:40 -04:00
|
|
|
|
TweetinviConfig.CurrentThreadSettings.TweetMode = TweetMode.Extended;
|
2020-07-01 22:45:43 -04:00
|
|
|
|
var tweet = Tweet.GetTweet(statusId);
|
2020-07-22 20:19:40 -04:00
|
|
|
|
return Extract(tweet);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private ExtractedTweet Extract(ITweet tweet)
|
|
|
|
|
{
|
|
|
|
|
var extractedTweet = new ExtractedTweet
|
|
|
|
|
{
|
|
|
|
|
Id = tweet.Id,
|
|
|
|
|
InReplyToStatusId = tweet.InReplyToStatusId,
|
|
|
|
|
MessageContent = ExtractMessage(tweet),
|
|
|
|
|
Media = ExtractMedia(tweet.Media),
|
|
|
|
|
CreatedAt = tweet.CreatedAt
|
|
|
|
|
};
|
|
|
|
|
return extractedTweet;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private string ExtractMessage(ITweet tweet)
|
|
|
|
|
{
|
|
|
|
|
var tweetUrls = tweet.Media.Select(x => x.URL).Distinct();
|
|
|
|
|
var message = tweet.FullText;
|
|
|
|
|
foreach (var tweetUrl in tweetUrls)
|
|
|
|
|
message = message.Replace(tweetUrl, string.Empty).Trim();
|
|
|
|
|
|
|
|
|
|
if (tweet.QuotedTweet != null) message = $"[Quote RT] {message}";
|
|
|
|
|
if (tweet.IsRetweet)
|
|
|
|
|
{
|
|
|
|
|
if (tweet.RetweetedTweet != null)
|
|
|
|
|
message = $"[RT {tweet.RetweetedTweet.CreatedBy.ScreenName}] {tweet.RetweetedTweet.FullText}";
|
|
|
|
|
else
|
|
|
|
|
message = message.Replace("RT", "[RT]");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return message;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private ExtractedMedia[] ExtractMedia(List<IMediaEntity> media)
|
|
|
|
|
{
|
|
|
|
|
var result = new List<ExtractedMedia>();
|
|
|
|
|
|
|
|
|
|
foreach (var m in media)
|
|
|
|
|
{
|
|
|
|
|
var mediaUrl = GetMediaUrl(m);
|
|
|
|
|
var mediaType = GetMediaType(m.MediaType, mediaUrl);
|
|
|
|
|
if (mediaType == null) continue;
|
|
|
|
|
|
|
|
|
|
var att = new ExtractedMedia
|
|
|
|
|
{
|
|
|
|
|
MediaType = mediaType,
|
|
|
|
|
Url = mediaUrl
|
|
|
|
|
};
|
|
|
|
|
result.Add(att);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result.ToArray();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private string GetMediaUrl(IMediaEntity media)
|
|
|
|
|
{
|
|
|
|
|
switch (media.MediaType)
|
|
|
|
|
{
|
|
|
|
|
case "photo": return media.MediaURLHttps;
|
|
|
|
|
case "animated_gif": return media.VideoDetails.Variants[0].URL;
|
|
|
|
|
case "video": return media.VideoDetails.Variants.OrderByDescending(x => x.Bitrate).First().URL;
|
|
|
|
|
default: return null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private string GetMediaType(string mediaType, string mediaUrl)
|
|
|
|
|
{
|
|
|
|
|
switch (mediaType)
|
|
|
|
|
{
|
|
|
|
|
case "photo":
|
|
|
|
|
var ext = Path.GetExtension(mediaUrl);
|
|
|
|
|
switch (ext)
|
|
|
|
|
{
|
|
|
|
|
case ".jpg":
|
|
|
|
|
case ".jpeg":
|
|
|
|
|
return "image/jpeg";
|
|
|
|
|
case ".png":
|
|
|
|
|
return "image/png";
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
|
|
|
|
|
case "animated_gif":
|
|
|
|
|
return "image/gif";
|
|
|
|
|
|
|
|
|
|
case "video":
|
|
|
|
|
return "video/mp4";
|
|
|
|
|
}
|
|
|
|
|
return null;
|
2020-07-01 22:45:43 -04:00
|
|
|
|
}
|
2020-07-18 23:35:19 -04:00
|
|
|
|
|
2020-07-22 20:19:40 -04:00
|
|
|
|
public ExtractedTweet[] GetTimeline(string username, int nberTweets, long fromTweetId = -1)
|
2020-07-18 23:35:19 -04:00
|
|
|
|
{
|
|
|
|
|
TweetinviConfig.CurrentThreadSettings.TweetMode = TweetMode.Extended;
|
|
|
|
|
|
|
|
|
|
var user = User.GetUserFromScreenName(username);
|
|
|
|
|
var tweets = new List<ITweet>();
|
|
|
|
|
if (fromTweetId == -1)
|
|
|
|
|
{
|
|
|
|
|
var timeline = Timeline.GetUserTimeline(user.Id, nberTweets);
|
|
|
|
|
if (timeline != null) tweets.AddRange(timeline);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
var timelineRequestParameters = new UserTimelineParameters
|
|
|
|
|
{
|
|
|
|
|
SinceId = fromTweetId,
|
|
|
|
|
MaximumNumberOfTweetsToRetrieve = nberTweets
|
|
|
|
|
};
|
|
|
|
|
var timeline = Timeline.GetUserTimeline(user.Id, timelineRequestParameters);
|
|
|
|
|
if (timeline != null) tweets.AddRange(timeline);
|
|
|
|
|
}
|
|
|
|
|
|
2020-07-22 20:19:40 -04:00
|
|
|
|
return tweets.Select(Extract).ToArray();
|
2020-07-18 23:35:19 -04:00
|
|
|
|
//return tweets.Where(x => returnReplies || string.IsNullOrWhiteSpace(x.InReplyToScreenName)).ToArray();
|
|
|
|
|
}
|
2020-03-21 18:58:23 -04:00
|
|
|
|
}
|
|
|
|
|
}
|