using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Threading.Tasks; using BirdsiteLive.Common.Settings; using BirdsiteLive.DAL.Contracts; using BirdsiteLive.DAL.Models; using BirdsiteLive.Domain; using BirdsiteLive.Twitter.Models; using Microsoft.Extensions.Logging; namespace BirdsiteLive.Pipeline.Processors.SubTasks { public interface ISendTweetsToInboxTask { Task ExecuteAsync(IEnumerable tweets, Follower follower, SyncTwitterUser user); } public class SendTweetsToInboxTask : ISendTweetsToInboxTask { private readonly IActivityPubService _activityPubService; private readonly IStatusService _statusService; private readonly IFollowersDal _followersDal; private readonly InstanceSettings _settings; private readonly ILogger _logger; #region Ctor public SendTweetsToInboxTask(IActivityPubService activityPubService, IStatusService statusService, IFollowersDal followersDal, InstanceSettings settings, ILogger logger) { _activityPubService = activityPubService; _statusService = statusService; _followersDal = followersDal; _settings = settings; _logger = logger; } #endregion public async Task ExecuteAsync(IEnumerable tweets, Follower follower, SyncTwitterUser user) { var userId = user.Id; var fromStatusId = follower.FollowingsSyncStatus[userId]; var tweetsToSend = tweets .Where(x => x.Id > fromStatusId) .OrderBy(x => x.Id) .ToList(); var inbox = follower.InboxRoute; var syncStatus = fromStatusId; try { foreach (var tweet in tweetsToSend) { try { if (!tweet.IsReply || tweet.IsReply && tweet.IsThread || _settings.PublishReplies) { var note = _statusService.GetStatus(user.Acct, tweet); await _activityPubService.PostNewNoteActivity(note, user.Acct, tweet.Id.ToString(), follower.Host, inbox); } } catch (ArgumentException e) { if (e.Message.Contains("Invalid pattern") && e.Message.Contains("at offset")) //Regex exception { _logger.LogError(e, "Can't parse {MessageContent} from Tweet {Id}", tweet.MessageContent, tweet.Id); } else { throw; } } syncStatus = tweet.Id; } } finally { if (syncStatus != fromStatusId) { follower.FollowingsSyncStatus[userId] = syncStatus; await _followersDal.UpdateFollowerAsync(follower); } } } } }