public static TwitterUser GetSuggestedUser(TweetViewModel status) { if (IsPublishedByRetweet(status)) return ((TwitterStatus)status.Status).RetweetedOriginal.User; else return status.Status.User; }
public TabDependentTweetViewModel(TweetViewModel tvm, TabViewModel parent) { if (tvm == null) throw new ArgumentNullException("tvm"); if (parent == null) throw new ArgumentNullException("parent"); this.Parent = parent; this.Tweet = tvm; switch (Setting.Instance.TimelineExperienceProperty.TimelineItemInitStrategy) { case ItemInitStrategy.None: break; case ItemInitStrategy.DefaultColors: _lightningColorCache = Setting.Instance.ColoringProperty.BaseHighlightColor.GetColor(); _foreColorCache = Setting.Instance.ColoringProperty.BaseColor.GetDarkColor(); _backColorCache = Setting.Instance.ColoringProperty.BaseColor.GetLightColor(); _foreBrushCache = new SolidColorBrush(_foreColorCache).CloneFreeze(); _backBrushCache = new SolidColorBrush(_backColorCache).CloneFreeze(); break; case ItemInitStrategy.Full: CommitColorChanged(true); break; } }
public EventDescription(EventKind kind, UserViewModel source, UserViewModel target, TweetViewModel tweet = null) { this.CreatedAt = DateTime.Now; this.Kind = kind; this.SourceUser = source; this.TargetUser = target; this.TargetTweet = tweet; }
public static void QueueNotify(TweetViewModel tweet, string soundSource = null) { if (soundSource == null) soundSource = String.Empty; lock (waitingsLocker) { if (waitings.ContainsKey(tweet)) waitings[tweet] = soundSource; } }
public static void RegisterNotify(TweetViewModel tweet) { if (!Setting.Instance.NotificationProperty.NotifyReceives || tweet.CreatedAt < DateTime.Now.Subtract(TimeSpan.FromMinutes(10)) || !CheckIsAllowed(tweet)) return; lock (waitingsLocker) { if (!waitings.ContainsKey(tweet)) waitings.Add(tweet, null); } }
public static void DispatchNotify(TweetViewModel tweet) { lock (waitingsLocker) { if (waitings.ContainsKey(tweet)) { var notify = waitings[tweet]; waitings.Remove(tweet); if (notify != null) IssueNotification(UserStorage.Get(tweet.Status.User), null, tweet.Status.Text, EventKind.Undefined, notify); } } }
public static void DispatchNotify(TweetViewModel tweet) { lock (waitingsLocker) { if (waitings.ContainsKey(tweet)) { var notify = waitings[tweet]; waitings.Remove(tweet); if (notify != null) { UserViewModel source = UserStorage.Get(tweet.Status.User); RaiseNotificationEvent(null, new EventDescriptionEventArgs(new EventDescription(EventKind.Undefined, source, null, tweet))); IssueNotification(source, null, tweet.Status.Text, EventKind.Undefined, notify); } } } }
public static void Unretweet(IEnumerable<AccountInfo> infos, TweetViewModel status) { operationDispatcher.Enqueue(() => UnretweetSink(infos, status)); }
public static void OnRetweeted(TweetViewModel tweet, UserViewModel retweeter) { if (AccountStorage.Contains(retweeter.TwitterUser.ScreenName) || tweet.CreatedAt < wakeupTime) return; Register(new EventDescription(EventKind.Retweet, retweeter, UserStorage.Get(tweet.Status.User), tweet)); }
private void RemoveTweet(TweetViewModel tvm) { this._tweetsSource.Remove(new TabDependentTweetViewModel(tvm, this.Parent)); }
public bool CheckFilters(TweetViewModel viewModel) { try { if (!viewModel.IsStatusInfoContains || FilterHelper.IsMuted(viewModel.Status)) return false; return (this.sources ?? this.Parent.TabProperty.TweetSources ?? new IFilter[0]) .Any(f => f.Filter(viewModel.Status)); } catch (Exception ex) { ExceptionStorage.Register(ex, ExceptionCategory.InternalError, "フィルタ処理中に内部エラーが発生しました。"); return false; } }
private static void UnfavTweetSink(IEnumerable<AccountInfo> infos, TweetViewModel status) { var ts = status.Status as TwitterStatus; if (ts == null) { NotifyStorage.Notify("DirectMessageはFavできません。"); return; } if (ts.RetweetedOriginal != null) status = TweetStorage.Get(ts.RetweetedOriginal.Id, true); if (status == null) { NotifyStorage.Notify("Unfav 対象ステータスが見つかりません。"); return; } bool success = true; Parallel.ForEach(infos, (d) => { var ud = d.UserViewModel; // ふぁぼり状態更新 if (ud != null) status.RemoveFavored(ud); try { unfavoriteInjection.Execute(new Tuple<AccountInfo, TweetViewModel>(d, status)); } catch (Exception ex) { success = false; if (ud != null) status.RegisterFavored(ud); NotifyStorage.Notify("Unfavに失敗しました: @" + d.ScreenName); if (!(ex is ApplicationException)) { ExceptionStorage.Register(ex, ExceptionCategory.TwitterError, "Unfav操作時にエラーが発生しました"); } } }); if (success) NotifyStorage.Notify("Unfavしました: @" + status.Status.User.ScreenName + ": " + status.Status.Text); }
private static void RetweetCore(AccountInfo d, TweetViewModel status) { if (ApiHelper.ExecApi(() => d.Retweet(status.Status.Id)) == null) throw new ApplicationException(); }
private static void FavTweetCore(AccountInfo d, TweetViewModel status) { /* if (ApiHelper.ExecApi(() => d.CreateFavorites(status.Status.Id)) == null) throw new ApplicationException(); */ for (int i = 0; i < 3; i++) { try { if (d.CreateFavorites(status.Status.Id) != null) break; } catch (WebException wex) { var hwr = wex.Response as HttpWebResponse; if (wex.Status == WebExceptionStatus.ProtocolError && hwr != null && hwr.StatusCode == HttpStatusCode.Forbidden) { // あとIt's great that ... ならふぁぼ規制 using (var read = new StreamReader( hwr.GetResponseStream())) { var desc = read.ReadToEnd(); if (desc.Contains("It's great that you like so many updates, but we only allow so many updates to be marked as a favorite per day.")) { throw new FavoriteSuspendedException(); } } } else if (wex.Status == WebExceptionStatus.Timeout) { continue; } else { break; } } } }
public static bool IsPublishedByRetweet(TweetViewModel status) { if (status == null || !status.IsStatusInfoContains) return false; return IsPublishedByRetweet(status.Status); }
public static bool IsMyTweet(TweetViewModel status) { if (status == null || !status.IsStatusInfoContains) return false; return AccountStorage.Accounts .Any(d => status.Status.User.ScreenName == d.ScreenName); }
public static bool IsMyCurrentTweet(TweetViewModel status, TabProperty property) { if (status == null || !status.IsStatusInfoContains || property == null) return false; return property.LinkAccountScreenNames.Any(a => a == status.Status.User.ScreenName); }
private static void RemoveRetweetCore(AccountInfo d, TweetViewModel status) { // リツイートステータスの特定 var rts = TweetStorage.GetAll(vm => vm.Status.User.ScreenName == d.ScreenName && vm.Status is TwitterStatus && ((TwitterStatus)vm.Status).RetweetedOriginal != null && ((TwitterStatus)vm.Status).RetweetedOriginal.Id == status.Status.Id).FirstOrDefault(); if (rts == null || ApiHelper.ExecApi(() => d.DestroyStatus(rts.Status.Id) == null)) throw new ApplicationException(); }
public static bool IsFavoredThis(TweetViewModel status) { if (status == null || !status.IsStatusInfoContains) return false; var fvd = status.FavoredUsers.Select(d => d.TwitterUser.ScreenName).ToArray(); return AccountStorage.Accounts.Any(d => fvd.Contains(d.ScreenName)); }
private static void UnfavTweetCore(AccountInfo d, TweetViewModel status) { if (ApiHelper.ExecApi(() => d.DestroyFavorites(status.Status.Id)) == null) throw new ApplicationException(); }
public static bool IsFavoredThisWithCurrent(TweetViewModel status, TabProperty property) { if (status == null || !status.IsStatusInfoContains || property == null) return false; var fvd = status.FavoredUsers.Select(d => d.TwitterUser.ScreenName).ToArray(); return property.LinkAccountScreenNames.Any(a => fvd.Contains(a)); }
private static void UnretweetSink(IEnumerable<AccountInfo> infos, TweetViewModel status) { var ts = status.Status as TwitterStatus; if (ts == null) { NotifyStorage.Notify("DirectMessageはUnretweetできません。"); return; } if (ts.RetweetedOriginal != null) status = TweetStorage.Get(ts.RetweetedOriginal.Id, true); if (status == null) { NotifyStorage.Notify("Retweet オリジナルデータが見つかりません。"); return; } bool success = true; Parallel.ForEach(infos, d => { // リツイート状態更新 var ud = d.UserViewModel; if (ud != null) status.RegisterRetweeted(ud); try { unretweetInjection.Execute(new Tuple<AccountInfo, TweetViewModel>(d, status)); } catch (Exception ex) { if (ud != null) status.RemoveRetweeted(ud); success = false; NotifyStorage.Notify("Retweetキャンセルに失敗しました: @" + d.ScreenName); if (!(ex is ApplicationException)) { ExceptionStorage.Register(ex, ExceptionCategory.TwitterError, "Retweetキャンセル操作時にエラーが発生しました"); } } }); if (success) NotifyStorage.Notify("Retweetをキャンセルしました: @" + status.Status.User.ScreenName + ": " + status.Status.Text); }
public static bool IsInReplyToMe(TweetViewModel status) { if (status == null || !status.IsStatusInfoContains) return false; return AccountStorage.Accounts.Any(d => Regex.IsMatch(status.Status.Text, "@" + d.ScreenName + "(?![a-zA-Z0-9_])", RegexOptions.Singleline | RegexOptions.IgnoreCase)); }
private void AddTweet(TweetViewModel tvm) { var atdtvm = new TabDependentTweetViewModel(tvm, this.Parent); if (this._tweetsSource.Contains(atdtvm)) return; if (Setting.Instance.TimelineExperienceProperty.UseIntelligentOrdering && DateTime.Now.Subtract(tvm.CreatedAt).TotalSeconds < Setting.Instance.TimelineExperienceProperty.IntelligentOrderingThresholdSec) { if (Setting.Instance.TimelineExperienceProperty.OrderByAscending) this._tweetsSource.AddLastSingle(atdtvm); else this._tweetsSource.AddTopSingle(atdtvm); } else { this._tweetsSource.AddOrderedSingle( atdtvm, Setting.Instance.TimelineExperienceProperty.OrderByAscending, t => t.Tweet.CreatedAt); } OnNewTweetReceived(); }
public static bool IsInReplyToMeCurrent(TweetViewModel status, TabProperty property) { if (status == null || !status.IsStatusInfoContains || property == null) return false; return property.LinkAccountScreenNames.Any(a => Regex.IsMatch(status.Status.Text, "@" + a + "(?![a-zA-Z0-9_])", RegexOptions.Singleline | RegexOptions.IgnoreCase)); }
public static void OnMention(TweetViewModel tweet) { if (AccountStorage.Contains(tweet.Status.User.ScreenName) || tweet.CreatedAt < wakeupTime) return; Register(new EventDescription(EventKind.Mention, UserStorage.Get(tweet.Status.User), null, tweet)); }
public static bool IsInReplyToMeCurrentStrict(TweetViewModel status, TabProperty property) { if (status == null || !status.IsStatusInfoContains || property == null) return false; var s = status.Status as TwitterStatus; if (s != null) { return property.LinkAccountScreenNames.Any(a => a == s.InReplyToUserScreenName); } else { var dm = status.Status as TwitterDirectMessage; if (dm != null) { return property.LinkAccountScreenNames.Any(a => a == dm.Recipient.ScreenName); } else { return false; } } }
public static void OnUnfavored(TweetViewModel tweet, UserViewModel favorer) { if (AccountStorage.Contains(favorer.TwitterUser.ScreenName) || !Setting.Instance.NotificationProperty.IsNotifyOthersFavoriteEnabled && !AccountStorage.Contains(tweet.Status.User.ScreenName)) return; Register(new EventDescription(EventKind.Unfavorite, favorer, UserStorage.Get(tweet.Status.User), tweet)); }
public static void OnUnfavored(TweetViewModel tweet, UserViewModel favorer) { if (AccountStorage.Contains(favorer.TwitterUser.ScreenName)) return; Register(new EventDescription(EventKind.Unfavorite, favorer, UserStorage.Get(tweet.Status.User), tweet)); }
public static void FavTweetSink(IEnumerable<AccountInfo> infos, TweetViewModel status) { var ts = status.Status as TwitterStatus; if (ts == null) { NotifyStorage.Notify("DirectMessageはFavできません。"); return; } if (ts.RetweetedOriginal != null) status = TweetStorage.Get(ts.RetweetedOriginal.Id, true); if (status == null) { NotifyStorage.Notify("Fav 対象ステータスが見つかりません。"); return; } bool success = true; Parallel.ForEach(infos, (d) => { var ud = d.UserViewModel; // ふぁぼり状態更新 if (ud != null) status.RegisterFavored(ud); try { favoriteInjection.Execute(new Tuple<AccountInfo, TweetViewModel>(d, status)); } catch (Exception ex) { success = false; if (ud != null) status.RemoveFavored(ud); if (ex is FavoriteSuspendedException && Setting.Instance.InputExperienceProperty.EnableFavoriteFallback) { // ふぁぼ規制 -> フォールバック AccountInfo fallback = null; if(!String.IsNullOrEmpty( d.AccountProperty.FallbackAccount) && (fallback = AccountStorage.Get(d.AccountProperty.FallbackAccount)) != null && !status.FavoredUsers.Contains(fallback.UserViewModel)) { NotifyStorage.Notify("Fav fallbackします: @" + d.ScreenName + " >> @"); FavTweetSink(new[] { fallback }, status); } } else { NotifyStorage.Notify("Favに失敗しました: @" + d.ScreenName); if (!(ex is ApplicationException)) { ExceptionStorage.Register(ex, ExceptionCategory.TwitterError, "Fav操作時にエラーが発生しました"); } } } }); if (success) NotifyStorage.Notify("Favしました: @" + status.Status.User.ScreenName + ": " + status.Status.Text); }
internal void NotifyNewTweetReceived(TimelineListCoreViewModel timelineListCoreViewModel, TimelineChild.TweetViewModel tweetViewModel) { if (AccountStorage.Contains(tweetViewModel.Status.User.ScreenName) || !this.IsAlive) { return; } // 正直謎設定だし、スタックトップTLの新着を伝えるってあんまり直感的じゃないから // 設定じゃなくて固定にしてよかったかもしれない if (Setting.Instance.NotificationProperty.NotifyStackTopTimeline ? this.CurrentForegroundTimeline.CoreViewModel == timelineListCoreViewModel : this.BaseTimeline.CoreViewModel == timelineListCoreViewModel) { // NewTweetsCountはプロパティが良きに計らってくれるので // _人人人人人人人人人人人人人人人_ // > インクリしていってね!!!< //  ̄YYYYYYYYYYYYYYY ̄ this.NewTweetsCount++; if (this.TabProperty.IsNotifyEnabled) { if (String.IsNullOrEmpty(this.TabProperty.NotifySoundPath)) { NotificationCore.QueueNotify(tweetViewModel); } else { NotificationCore.QueueNotify(tweetViewModel, this.TabProperty.NotifySoundPath); } } } }