private void ReceiveTimeline() { if (User == null || User.TwitterUser == null) { return; } IsStandby = false; Task.Factory.StartNew(() => { try { var acc = AccountStorage.GetRandom(a => a.Followings.Contains(this.User.TwitterUser.NumericId), true); var tweets = InjectionPoint.UnfoldTimeline(i => acc.GetUserTimeline(userId: this.User.TwitterUser.NumericId, count: 100, includeRts: true, page: i), 100, 5); if (tweets != null) { tweets.ForEach(t => TweetStorage.Register(t)); } } catch (Exception e) { ExceptionStorage.Register(e, ExceptionCategory.TwitterError, "ユーザータイムラインを受信できませんでした: @" + this.User.TwitterUser.ScreenName, ReceiveTimeline); } finally { IsStandby = true; } }); }
private static void AddUnderControlled(AccountInfo info) { if (underControls.ContainsKey(info)) { NotifyStorage.Notify("[規制管理: @" + info.ScreenName + " は規制されています。解除予想時刻: " + underControls[info].ToString("HH:mm:ss")); return; } var timestamp = DateTime.Now.Subtract(TwitterDefine.UnderControlTimespan); // APIを利用してツイートを遡り受信 var notify = NotifyStorage.NotifyManually("[規制管理: @" + info.ScreenName + " の直近のツイートを受信しています...]"); try { ApiHelper.ExecApi(() => info.GetUserTimeline(count: 150, includeRts: true)) .Guard() .ForEach(i => TweetStorage.Register(i)); notify.Message = "[規制管理:規制開始時刻を割り出しています...]"; // 127tweet/3hours var originate = TweetStorage.GetAll( t => t.Status.User.ScreenName == info.ScreenName && DateTime.Now.Subtract(t.CreatedAt) < TwitterDefine.UnderControlTimespan) .OrderByDescending((t) => t.Status.CreatedAt) .Skip(TwitterDefine.UnderControlCount - 1) .FirstOrDefault(); if (originate == null) { originate = TweetStorage.GetAll( t => t.Status.User.ScreenName == info.ScreenName && DateTime.Now.Subtract(t.CreatedAt) < TwitterDefine.UnderControlTimespan) .OrderByDescending((t) => t.Status.CreatedAt) .LastOrDefault(); } if (originate == null) { NotifyStorage.Notify("[規制管理: @" + info.ScreenName + " はPOST規制されていますが、解除時刻を予想できません。しばらく置いて試してみてください。]"); } else { var release = (originate.Status.CreatedAt + TwitterDefine.UnderControlTimespan); NotifyStorage.Notify("[規制管理: @" + info.ScreenName + " はPOST規制されています。解除予想時刻は " + release.ToString("HH:mm:ss") + " です。]"); underControls.AddOrUpdate(info, release); OnOnUnderControlChanged(new UnderControlEventArgs(info, true)); } } finally { notify.Dispose(); } }
private static void UpdateDirectMessageSink(AccountInfo info, string target, string body) { var status = info.SendDirectMessage(target, body); if (status == null || status.Id == 0) { throw new WebException("Timeout or failure sending tweet.", WebExceptionStatus.Timeout); } TweetStorage.Register(status); NotifyStorage.Notify("DMを送信しました: @" + info.ScreenName + " -> @" + target + ": " + body); }
private static void UpdateTweetSink(AccountInfo info, string text, long?inReplyToId = null) { var status = info.UpdateStatus(text, inReplyToId); if (status == null || status.Id == 0) { throw new WebException("Timeout or failure sending tweet.", WebExceptionStatus.Timeout); } TweetStorage.Register(status); NotifyStorage.Notify("ツイートしました:@" + info.ScreenName + ": " + text); }
void f_RequirePartialReaccept(TwitterStatusBase tsb) { var tvm = TweetStorage.Register(tsb); if (tvm == null || !TweetStorage.ValidateTweet(tvm)) { return; } if (CheckFilters(tvm)) { AddTweet(tvm); } else { RemoveTweet(tvm); } }
public sealed override void DoWork() { try { var received = (GetTweets() ?? new TwitterStatusBase[0]).ToArray(); previousReceived = DateTime.Now; // var newbiesCount = received.Count(s => TweetStorage.Contains(s.Id) == TweetExistState.Unreceived); received.ForEach(s => TweetStorage.Register(s)); var pivotarray = received.Take(TwitterDefine.IntervalLookPrevious).ToArray(); var pivot = pivotarray.LastOrDefault(); var newest = received.FirstOrDefault(); if (pivot != null && newest != null) { // newbiesRate = (double)newbiesCount / received.Length; if (newbiesRate < TwitterDefine.MinNewbiesRate) { newbiesRate = TwitterDefine.MinNewbiesRate; } timesPerTweet = (double)(newest.CreatedAt.Subtract(pivot.CreatedAt)).TotalMilliseconds / pivotarray.Length; if (timesPerTweet > TwitterDefine.TimesPerTweetMaximumValue) { timesPerTweet = TwitterDefine.TimesPerTweetMaximumValue; } } else { // 受信すべきタイムラインが無い // 受信レートを最小にして様子を見る newbiesRate = TwitterDefine.MinNewbiesRate; timesPerTweet = TwitterDefine.TimesPerTweetMaximumValue; } } catch (WebException ex) { ExceptionStorage.Register(ex, ExceptionCategory.TwitterError, "Twitterとの通信に失敗しました。"); } catch (IOException ioex) { ExceptionStorage.Register(ioex, ExceptionCategory.TwitterError, "ネットワークでエラーが発生しました。"); } catch (Exception ex) { ExceptionStorage.Register(ex, ExceptionCategory.InternalError, "ステータス受信時に内部エラーが発生しました。"); } }
public void Loaded() { KernelService.AddMenu("Import JSON", () => { var dialog = new OpenFileDialog(); dialog.Filter = "JSON Format|*.json|すべてのファイル|*.*"; dialog.Multiselect = true; var result = dialog.ShowDialog(); if (result.HasValue && result.Value) { Task.Factory.StartNew(() => { dialog.FileNames.AsParallel().ForAll(file => { var fileName = Path.GetFileName(file); using (var notify = NotifyStorage.NotifyManually(fileName + " を読み込んでいます")) { try { using (var reader = JsonReaderWriterFactory.CreateJsonReader(new FileStream(file, FileMode.Open, FileAccess.Read), XmlDictionaryReaderQuotas.Max)) { XElement.Load(reader).Elements() .Select(TwitterStatus.FromNode) .ForEach(s => TweetStorage.Register(s)); } } catch (Exception ex) { ExceptionStorage.Register(ex, ExceptionCategory.UserError, fileName + " を読み込めませんでした"); } } }); }); } }); }
public FilterStatusId(long pivot, bool getStatus) { this.Range = LongRange.FromPivotValue(pivot); if (getStatus) { if (TweetStorage.Contains(pivot) != TweetExistState.Exists) { Task.Factory.StartNew(() => { try { var status = ApiHelper.ExecApi(() => AccountStorage.GetRandom().GetStatus(pivot)); if (status != null) { TweetStorage.Register(status); RaisePartialRequireReaccept(status); } } catch { } }); } } }
/// <summary> /// ストリームエレメントを処理します。 /// </summary> /// <param name="info">ストリームエレメントを受信したアカウント</param> /// <param name="elem">ストリームエレメント</param> private static void RegisterStreamElement(AccountInfo info, StreamingEvent elem) { switch (elem.Kind) { case ElementKind.Status: case ElementKind.DirectMessage: // 通常ステータスを受信した TweetStorage.Register(elem.Status); break; case ElementKind.Favorite: var avm = TweetStorage.Register(elem.Status); if (avm == null) { return; } var uavm = UserStorage.Get(elem.SourceUser); if (avm.RegisterFavored(uavm)) { EventStorage.OnFavored(avm, uavm); } break; case ElementKind.Unfavorite: var rvm = TweetStorage.Register(elem.Status); if (rvm == null) { return; } var urvm = UserStorage.Get(elem.SourceUser); if (rvm.RemoveFavored(urvm)) { EventStorage.OnUnfavored(rvm, urvm); } break; case ElementKind.Delete: TweetStorage.Remove(elem.DeletedStatusId); break; /* * TODO:Implements later? * case ElementKind.ListUpdated: * break; * case ElementKind.ListMemberAdded: * if (ListStorage.IsListMemberCached(elem.TargetList.User.ScreenName, elem.TargetList.Name)) * { * var members = ListStorage.GetListMembers(elem.TargetList.User.ScreenName, elem.TargetList.Name); * } * break; * * case ElementKind.ListMemberRemoved: * case ElementKind.ListSubscribed: * case ElementKind.ListUnsubscribed: * // TODO: do something * * break; */ case ElementKind.Follow: case ElementKind.Unfollow: var affect = AccountStorage.Get(elem.SourceUser.ScreenName); var effect = AccountStorage.Get(elem.TargetUser.ScreenName); if (affect != null) { // Add/Remove followings if (elem.Kind == ElementKind.Follow) { affect.RegisterFollowing(elem.TargetUser.NumericId); } else { affect.RemoveFollowing(elem.TargetUser.NumericId); } } if (effect != null) { // Add/Remove followers if (elem.Kind == ElementKind.Follow) { effect.RegisterFollower(elem.SourceUser.NumericId); } else { effect.RemoveFollower(elem.SourceUser.NumericId); } } if (elem.Kind == ElementKind.Follow) { EventStorage.OnFollowed(UserStorage.Get(elem.SourceUser), UserStorage.Get(elem.TargetUser)); } else { EventStorage.OnRemoved(UserStorage.Get(elem.SourceUser), UserStorage.Get(elem.TargetUser)); } break; case ElementKind.Blocked: if (info == null) { break; } info.RemoveFollowing(elem.TargetUser.NumericId); info.RemoveFollower(elem.TargetUser.NumericId); info.RegisterBlocking(elem.TargetUser.NumericId); // TODO: notify events break; case ElementKind.Unblocked: if (info == null) { break; } info.RemoveBlocking(elem.TargetUser.NumericId); // TODO: Notify events break; default: System.Diagnostics.Debug.WriteLine("unknown:" + elem.ToString()); break; } }
private void RecursiveCheckId(long id) { if (id == 0) { RaiseRequireReaccept(); return; } var cont = TweetStorage.Contains(id); if (cont == TweetExistState.Exists) { // データをチェックして、先があれば再帰 var tweet = TweetStorage.Get(id); if (tweet == null) { RaiseRequireReaccept(); return; } var ts = tweet.Status as TwitterStatus; if (ts != null && ts.InReplyToStatusId != 0) { this.tracePoint = ts.InReplyToStatusId; RaisePartialRequireReaccept(ts); RecursiveCheckId(ts.InReplyToStatusId); tweet.RefreshInReplyToInfo(); // 返信情報の更新を通知 } else { RaiseRequireReaccept(); } } else if (cont == TweetExistState.ServerDeleted) { // 消されてるからダメ RaiseRequireReaccept(); return; } else { // tweetを受信しようか Action receive = null; receive = () => { try { var status = ApiHelper.ExecApi(() => AccountStorage.GetRandom().GetStatus(id)); if (status != null) { var vm = TweetStorage.Register(status); this.tracePoint = status.Id; // temporarily id Task.Factory.StartNew(() => RecursiveCheckId(status.Id)); Task.Factory.StartNew(() => TweetStorage.GetAll(tvm => (tvm.Status is TwitterStatus) && ((TwitterStatus)tvm.Status).InReplyToStatusId == id) .ForEach(tvm => tvm.RefreshInReplyToInfo())); } else { RaiseRequireReaccept(); } } catch (Exception e) { ExceptionStorage.Register(e, ExceptionCategory.TwitterError, "ツイート " + id + " の受信に失敗しました。", receive); RaiseRequireReaccept(); } }; Task.Factory.StartNew(() => receive()); } }