Represents twitter status.
 public void NotifyRetweeted(TwitterUser source, TwitterStatus status)
 {
     if (_proxy.NotifyRetweeted(source, status) && this.Next != null)
     {
         this.Next.NotifyRetweeted(source, status);
     }
 }
예제 #2
0
 public void NotifyNewArrival(TwitterStatus status, NotificationType type, string explicitSoundSource)
 {
     if (!_proxy.NotifyNewArrival(status, type, explicitSoundSource))
     {
         Next?.NotifyNewArrival(status, type, explicitSoundSource);
     }
 }
예제 #3
0
 public void NotifyFavorited(TwitterUser source, TwitterStatus status)
 {
     if (!_proxy.NotifyFavorited(source, status))
     {
         Next?.NotifyFavorited(source, status);
     }
 }
예제 #4
0
 internal static void EndAcceptNewArrival(TwitterStatus status)
 {
     List<TabModel> removal;
     lock (_acceptingArrivals)
     {
         if (!_acceptingArrivals.TryGetValue(status.Id, out removal) || removal.Count == 0) return;
     }
     var soundSource = removal
         .Select(t => t.NotifySoundSource)
         .Where(s => !String.IsNullOrEmpty(s))
         .Where(File.Exists)
         .FirstOrDefault();
     if (status.StatusType == StatusType.DirectMessage)
     {
         Task.Run(() => NotifyNewArrival(status, NotificationType.DirectMessage, soundSource));
     }
     else if (FilterSystemUtil.InReplyToUsers(status).Intersect(Setting.Accounts.Ids).Any())
     {
         Task.Run(() => NotifyNewArrival(status, NotificationType.Mention, soundSource));
     }
     else
     {
         Task.Run(() => NotifyNewArrival(status, NotificationType.Normal, soundSource));
     }
 }
예제 #5
0
 internal static void StartAcceptNewArrival(TwitterStatus status)
 {
     lock (_acceptingArrivals)
     {
         _acceptingArrivals[status.Id] = new List<TabModel>();
     }
 }
예제 #6
0
 public void NotifyReceived(TwitterStatus status)
 {
     if (!_proxy.NotifyReceived(status))
     {
         Next?.NotifyReceived(status);
     }
 }
 public void NotifyUnfavorited(TwitterUser source, TwitterStatus status)
 {
     if (!_proxy.NotifyUnfavorited(source, status) && this.Next != null)
     {
         this.Next.NotifyUnfavorited(source, status);
     }
 }
예제 #8
0
 public TwitterStatus(dynamic json)
 {
     this.GenerateFromJson = true;
     this.Id = ((string)json.id_str).ParseLong();
     this.CreatedAt = ((string)json.created_at).ParseDateTime(ParsingExtension.TwitterDateTimeFormat);
     this.Text = ParsingExtension.ResolveEntity(json.text);
     if (json.extended_entities())
     {
         this.Entities = Enumerable.ToArray(Enumerable.Concat(
             TwitterEntity.GetEntities(json.entities),
             TwitterEntity.GetEntities(json.extended_entities)));
     }
     else if (json.entities())
     {
         this.Entities = Enumerable.ToArray(TwitterEntity.GetEntities(json.entities));
     }
     else
     {
         this.Entities = new TwitterEntity[0];
     }
     if (json.recipient())
     {
         // THIS IS DIRECT MESSAGE!
         this.StatusType = StatusType.DirectMessage;
         this.User = new TwitterUser(json.sender);
         this.Recipient = new TwitterUser(json.recipient);
     }
     else
     {
         this.StatusType = StatusType.Tweet;
         this.User = new TwitterUser(json.user);
         this.Source = json.source;
         if (json.in_reply_to_status_id_str())
         {
             this.InReplyToStatusId = ((string)json.in_reply_to_status_id_str).ParseNullableId();
         }
         if (json.in_reply_to_user_id_str())
         {
             this.InReplyToUserId = ((string)json.in_reply_to_user_id_str).ParseNullableId();
         }
         if (json.in_reply_to_screen_name())
         {
             this.InReplyToScreenName = json.in_reply_to_screen_name;
         }
         if (json.retweeted_status())
         {
             var original = new TwitterStatus(json.retweeted_status);
             this.RetweetedOriginal = original;
             this.RetweetedOriginalId = original.Id;
             // merge text and entities
             this.Text = original.Text;
             this.Entities = original.Entities.Guard().ToArray();
         }
         if (json.coordinates() && json.coordinates != null)
         {
             this.Longitude = (double)json.coordinates.coordinates[0];
             this.Latitude = (double)json.coordinates.coordinates[1];
         }
     }
 }
 public void NotifyReceived(TwitterStatus status)
 {
     if (!_proxy.NotifyReceived(status) && this.Next != null)
     {
         this.Next.NotifyReceived(status);
     }
 }
 public void NotifyNewArrival(TwitterStatus status, NotificationType type, string explicitSoundSource)
 {
     if (!_proxy.NotifyNewArrival(status, type, explicitSoundSource) && this.Next != null)
     {
         this.Next.NotifyNewArrival(status, type, explicitSoundSource);
     }
 }
예제 #11
0
 public virtual void NotifyReceived(TwitterStatus status)
 {
     if (Next != null)
     {
         Next.NotifyReceived(status);
     }
 }
예제 #12
0
 public void NotifyDeleted(long statusId, TwitterStatus deleted)
 {
     if (Next != null)
     {
         Next.NotifyDeleted(statusId, deleted);
     }
 }
예제 #13
0
 public void NotifyRetweeted(TwitterUser source, TwitterStatus status)
 {
     if (Next != null)
     {
         Next.NotifyRetweeted(source, status);
     }
 }
예제 #14
0
 public static void RegisterStatus(TwitterStatus status)
 {
     status.Entities
         .Where(e => e.EntityType == EntityType.Hashtags)
         .Select(e => e.DisplayText)
         .ForEach(RegisterHashtag);
 }
 public void NotifyRetweeted(TwitterUser source, TwitterStatus original, TwitterStatus retweet)
 {
     if (!_proxy.NotifyRetweeted(source, original, retweet) && this.Next != null)
     {
         this.Next.NotifyRetweeted(source, original, retweet);
     }
 }
예제 #16
0
 public void MessageReceived(TwitterStatus status)
 {
     lock (_urgentPriorityQueue)
     {
         _urgentPriorityQueue.AddLast(new NotificationData(SlimNotificationKind.Message, status));
     }
     OnNewNotificationDataQueued.SafeInvoke();
 }
예제 #17
0
 public void NotifyRetweeted(TwitterUser source, TwitterStatus original, TwitterStatus retweet)
 {
     if (Setting.Accounts.Contains(source.Id) ||
         Setting.Accounts.Contains(original.User.Id))
     {
         BackstageModel.RegisterEvent(new RetweetedEvent(source, original));
     }
 }
예제 #18
0
 internal static void NotifyReceived(TwitterStatus status)
 {
     if (status.RetweetedOriginal != null)
     {
         NotifyRetweeted(status.User, status.RetweetedOriginal);
     }
     Head.NotifyReceived(status);
 }
예제 #19
0
 public void StatusReceived(TwitterStatus status)
 {
     lock (_lowPriorityQueue)
     {
         _lowPriorityQueue.AddLast(new NotificationData(SlimNotificationKind.New, status));
     }
     OnNewNotificationDataQueued.SafeInvoke();
 }
예제 #20
0
 private bool CheckVisibleTimeline(TwitterStatus status, IEnumerable<TwitterAccount> datas)
 {
     if (status.StatusType == StatusType.DirectMessage)
         return false;
     return datas.Any(account =>
                      status.User.Id == account.Id ||
                      account.RelationData.IsFollowing(status.User.Id) ||
                      FilterSystemUtil.InReplyToUsers(status).Contains(account.Id));
 }
예제 #21
0
        public static async Task<StatusModel> Get(TwitterStatus status)
        {
            return GetIfCacheIsAlive(status.Id) ?? await _loader.StartNew(async () =>
            {
                if (status.GenerateFromJson)
                {
                    status = await StatusProxy.SyncStatusActivityAsync(status);
                }
                var rto = status.RetweetedOriginal == null
                              ? null
                              : await Get(status.RetweetedOriginal);
                var lockerobj = _generateLock.GetOrAdd(status.Id, new object());
                try
                {
                    lock (lockerobj)
                    {
                        StatusModel model;
                        WeakReference wr;
                        lock (_staticCacheLock)
                        {
                            _staticCache.TryGetValue(status.Id, out wr);
                        }
                        if (wr != null)
                        {
                            model = (StatusModel)wr.Target;
                            if (model != null)
                            {
                                return model;
                            }
                        }

                        // cache is dead/not cached yet
                        model = new StatusModel(status, rto);
                        wr = new WeakReference(model);
                        lock (_staticCacheLock)
                        {
                            _staticCache[status.Id] = wr;
                        }
                        return model;
                    }
                }
                finally
                {
                    _generateLock.TryRemove(status.Id, out lockerobj);
                    // ReSharper disable InvertIf
#pragma warning disable 4014
                    if (Interlocked.Increment(ref _cleanupCount) == CleanupInterval)
                    {
                        Interlocked.Exchange(ref _cleanupCount, 0);
                        Task.Run((Action)CollectGarbages);
                    }
#pragma warning restore 4014
                    // ReSharper restore InvertIf
                }
            }).Unwrap();
        }
예제 #22
0
        internal static void StartAcceptNewArrival(TwitterStatus status)
        {
            // check muted or blocked
            if (MuteBlockManager.IsUnwanted(status)) return;

            lock (_acceptingArrivals)
            {
                _acceptingArrivals[status.Id] = new List<TabModel>();
            }
        }
예제 #23
0
 internal static void NotifyNewArrival(TwitterStatus status, TabModel model)
 {
     lock (_acceptingArrivals)
     {
         List<TabModel> list;
         if (_acceptingArrivals.TryGetValue(status.Id, out list))
         {
             list.Add(model);
         }
     }
 }
        private static void PostDetected(TwitterStatus status)
        {
            // check timestamp
            if (status.CreatedAt < DateTime.Now - TimeSpan.FromSeconds(Setting.PostWindowTimeSec.Value))
            {
                return;
            }

            // lookup chunk
            LinkedList<TwitterStatus> statuses;
            lock (_dictLock)
            {
                if (!_dictionary.TryGetValue(status.User.Id, out statuses))
                {
                    return;
                }
            }

            lock (statuses)
            {
                // find insert position
                var afterThis =
                    statuses.First == null
                        ? null
                        : EnumerableEx.Generate(statuses.First, n => n.Next != null, n => n.Next, n => n)
                                      .TakeWhile(n => n.Value.Id >= status.Id)
                                      .LastOrDefault();
                if (afterThis == null)
                {
                    statuses.AddFirst(status);
                }
                else if (afterThis.Value.Id == status.Id)
                {
                    return;
                }
                else
                {
                    statuses.AddAfter(afterThis, status);
                }
                LinkedListNode<TwitterStatus> last;
                var stamp = DateTime.Now - TimeSpan.FromSeconds(Setting.PostWindowTimeSec.Value);
                while ((last = statuses.Last) != null)
                {
                    if (last.Value.CreatedAt >= stamp)
                    {
                        break;
                    }
                    // timeout
                    statuses.RemoveLast();
                }
            }
        }
예제 #25
0
 private static TwitterAccount GetSuitableReplyAccount(TwitterStatus status)
 {
     if (status.StatusType == StatusType.DirectMessage)
     {
         return Setting.Accounts.Get(status.Recipient.Id);
     }
     var replyTargets = status.Entities
                              .Where(e => e.EntityType == EntityType.UserMentions && e.UserId != null)
                              .Select(e => e.UserId.GetValueOrDefault())
                              .ToArray();
     var account = Setting.Accounts.Collection
                          .FirstOrDefault(a => replyTargets.Contains(a.Id));
     return account != null ? BacktrackFallback(account) : null;
 }
예제 #26
0
 public static IEnumerable<long> InReplyToUsers(TwitterStatus status)
 {
     if (status.StatusType == StatusType.DirectMessage)
     {
         return new[] { status.Recipient.Id };
     }
     if (status.Entities == null)
     {
         return Enumerable.Empty<long>();
     }
     return status.Entities
                  .Where(e => e.EntityType == EntityType.UserMentions)
                  .Select(e => e.UserId ?? 0)
                  .Where(id => id != 0);
 }
예제 #27
0
 private bool CheckConversation(TwitterStatus status)
 {
     lock (_statuses)
     {
         if (_statuses.Contains(status.Id))
         {
             return true;
         }
         if (status.InReplyToStatusId == null) return false;
         if (_statuses.Contains(status.InReplyToStatusId.Value))
         {
             _statuses.Add(status.Id);
             return true;
         }
     }
     return false;
 }
        internal static void StartAcceptNewArrival(TwitterStatus status)
        {
            // check muted or blocked
            if (MuteBlockManager.IsUnwanted(status)) return;

            if (!Setting.NotifyBackfilledTweets.Value &&
                status.CreatedAt < App.StartupDateTime)
            {
                // backfilled tweets
                return;
            }

            lock (_acceptingArrivals)
            {
                _acceptingArrivals[status.Id] = new List<TabModel>();
            }
        }
예제 #29
0
 public static IEnumerable<long> InReplyToUsers(TwitterStatus status)
 {
     if (status.StatusType == StatusType.DirectMessage)
     {
         if (status.Recipient == null)
         {
             throw new ArgumentException("Inconsistent status state: Recipient is not spcified in spite of status is direct message.");
         }
         return new[] { status.Recipient.Id };
     }
     if (status.Entities == null)
     {
         return Enumerable.Empty<long>();
     }
     return status.Entities
                  .Where(e => e.EntityType == EntityType.UserMentions)
                  .Select(e => e.UserId ?? 0)
                  .Where(id => id != 0);
 }
예제 #30
0
 public static async Task<TwitterStatus> SyncStatusActivityAsync(TwitterStatus status)
 {
     if (status.StatusType == StatusType.Tweet)
     {
         var favorers = await Database.FavoritesCrud.GetUsersAsync(status.Id);
         var retweeters = await Database.RetweetsCrud.GetUsersAsync(status.Id);
         status.FavoritedUsers = favorers.Guard().ToArray();
         status.RetweetedUsers = retweeters.Guard().ToArray();
     }
     return status;
 }
예제 #31
0
        public TwitterStatus(dynamic json)
        {
            this.GenerateFromJson = true;
            this.Id        = ((string)json.id_str).ParseLong();
            this.CreatedAt = ((string)json.created_at).ParseDateTime(ParsingExtension.TwitterDateTimeFormat);
            this.Text      = ParsingExtension.ResolveEntity(json.text);
            if (json.extended_entities())
            {
                // get correctly typed entities array
                var orgEntities = (TwitterEntity[])Enumerable.ToArray(TwitterEntity.GetEntities(json.entities));
                var extEntities = (TwitterEntity[])Enumerable.ToArray(TwitterEntity.GetEntities(json.extended_entities));

                // merge entities
                this.Entities = orgEntities.Where(e => e.EntityType != EntityType.Media)
                                .Concat(extEntities)            // extended entities contains media entities only.
                                .ToArray();
            }
            else if (json.entities())
            {
                this.Entities = Enumerable.ToArray(TwitterEntity.GetEntities(json.entities));
            }
            else
            {
                this.Entities = new TwitterEntity[0];
            }
            if (json.recipient())
            {
                // THIS IS DIRECT MESSAGE!
                this.StatusType = StatusType.DirectMessage;
                this.User       = new TwitterUser(json.sender);
                this.Recipient  = new TwitterUser(json.recipient);
            }
            else
            {
                this.StatusType = StatusType.Tweet;
                this.User       = new TwitterUser(json.user);
                this.Source     = json.source;
                if (json.in_reply_to_status_id_str())
                {
                    this.InReplyToStatusId = ((string)json.in_reply_to_status_id_str).ParseNullableId();
                }
                if (json.in_reply_to_user_id_str())
                {
                    this.InReplyToUserId = ((string)json.in_reply_to_user_id_str).ParseNullableId();
                }
                if (json.in_reply_to_screen_name())
                {
                    this.InReplyToScreenName = json.in_reply_to_screen_name;
                }
                if (json.retweeted_status())
                {
                    var original = new TwitterStatus(json.retweeted_status);
                    this.RetweetedOriginal   = original;
                    this.RetweetedOriginalId = original.Id;
                    // merge text and entities
                    this.Text     = original.Text;
                    this.Entities = original.Entities.Guard().ToArray();
                }
                if (json.coordinates() && json.coordinates != null)
                {
                    this.Longitude = (double)json.coordinates.coordinates[0];
                    this.Latitude  = (double)json.coordinates.coordinates[1];
                }
            }
        }