private void Loaded() { if (AccountStorage.Accounts.Count() == 0) { this.InputBlockViewModel.ShowConfig(); } var n = NotifyStorage.NotifyManually("タブとカラムを読み込んでいます。しばらくお待ちください..."); DispatcherHelper.BeginInvoke(() => { try { if (Setting.Instance.StateProperty.TabInformations != null) { Setting.Instance.StateProperty.TabInformations.ForEach(c => { var column = this.ColumnOwnerViewModel.CreateColumn(); c.ForEach(p => column.AddTab(p)); }); this.ColumnOwnerViewModel.GCColumn(); } } finally { n.Dispose(); Initializer.StandbyApp(); } }); }
public void RetweetThisTabAll() { Task.Factory.StartNew(() => { IEnumerable <TabDependentTweetViewModel> tweets; using (NotifyStorage.NotifyManually("タイムラインの内容を取得しています...")) { tweets = this.CurrentForegroundTimeline.CoreViewModel.TweetsSource.ToArrayVolatile(); } var msg = new ConfirmationMessage( "このタブに含まれるすべてのツイートをRetweetします。" + Environment.NewLine + "(対象ツイート: " + tweets.Count() + "件)" + Environment.NewLine + "よろしいですか?", "全てRetweet", System.Windows.MessageBoxImage.Warning, System.Windows.MessageBoxButton.OKCancel, "Confirm"); this.Parent.Messenger.Raise(msg); if (msg.Response.GetValueOrDefault()) { var lai = this.TabProperty.LinkAccountInfos.ToArray(); tweets.OrderBy(t => t.Tweet.CreatedAt) .ForEach(t => PostOffice.Retweet(lai, t.Tweet)); } }); }
private void RefreshIndividualInfo() { Task.Factory.StartNew(() => { using (var n = NotifyStorage.NotifyManually("アカウント情報を取得、更新しています...")) { AccountStorage.Accounts.ForEach(i => Communication.UserInformationManager.ReceiveInidividualInfo(i)); } }); }
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(); } }
/// <summary> /// タイムラインの再構築を行います。 /// </summary> public void InvalidateCache() { cacheInvalidator.Enqueue(() => { var stopwatch = new System.Diagnostics.Stopwatch(); stopwatch.Start(); using (var n = NotifyStorage.NotifyManually(this.TabProperty.Name + " - タイムラインを構築しています...")) { this.StackingTimelines.ToArray().ForEach(f => f.InvalidateCache()); } stopwatch.Stop(); NotifyStorage.Notify(this.TabProperty.Name + " - タイムライン構築完了(" + stopwatch.ElapsedMilliseconds + "msec)"); }); }
public void UnfavoriteThisTabAll() { Task.Factory.StartNew(() => { IEnumerable <TabDependentTweetViewModel> tweets; using (NotifyStorage.NotifyManually("タイムラインの内容を取得しています...")) { tweets = this.CurrentForegroundTimeline.CoreViewModel.TweetsSource.ToArrayVolatile(); } var msg = new ConfirmationMessage( "このタブに含まれるすべてのツイートをUnfavoriteします。" + Environment.NewLine + "(対象ツイート: " + tweets.Count() + "件)" + Environment.NewLine + "よろしいですか?", "全てUnfavorite", System.Windows.MessageBoxImage.Warning, System.Windows.MessageBoxButton.OKCancel, "Confirm"); this.Parent.Messenger.Raise(msg); if (msg.Response.GetValueOrDefault()) { tweets.ForEach(t => t.Unfavorite()); } }); }
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 + " を読み込めませんでした"); } } }); }); } }); }
/// <summary> /// ストリーミングAPIへ接続します。<para /> /// 接続に失敗した場合、規定アルゴリズムに沿って自動で再接続を試みます。<para /> /// それでも失敗する場合はfalseを返します。この場合、再接続を試みてはいけません。 /// </summary> /// <param name="track">トラック対象キーワード</param> private void ConnectCore(AccountInfo info, string track) { try { int failureWaitSec = 0; while (true) { // 接続 try { using (var n = NotifyStorage.NotifyManually("@" + info.ScreenName + ": インターネットへの接続を確認しています...")) { while (!NetworkInterface.GetIsNetworkAvailable()) { info.ConnectionState = ConnectionState.WaitNetwork; ConnectionManager.OnConnectionStateChanged(EventArgs.Empty); // ネットワークが利用可能になるまでポーリング Thread.Sleep(10000); } } using (var n = NotifyStorage.NotifyManually("@" + info.ScreenName + ": 接続しています...")) { info.ConnectionState = ConnectionState.TryConnection; ConnectionManager.OnConnectionStateChanged(EventArgs.Empty); System.Diagnostics.Debug.WriteLine(info.ScreenName + " - User Streams Connection with Track: " + track); connection = streamingCore.ConnectNew( info, StreamingDescription.ForUserStreams(TwitterDefine.UserStreamsTimeout, track: track, repliesAll: info.AccountProperty.UserStreamsRepliesAll)); } } catch (WebException we) { if ((int)we.Status == 420) { // 多重接続されている throw new WebException("@" + info.ScreenName + ": 多重接続されています。接続できません。"); } if (we.Status == WebExceptionStatus.Timeout) // タイムアウト例外なら再試行する { NotifyStorage.Notify("@" + info.ScreenName + ": User Streams接続がタイムアウトしました。再試行します..."); } else { string descText = we.Status.ToString(); if (we.Status == WebExceptionStatus.UnknownError) { descText = we.Message; } if (we.Status == WebExceptionStatus.ProtocolError) { var hwr = we.Response as HttpWebResponse; if (hwr != null) { descText += " - " + hwr.StatusCode + " : " + hwr.StatusDescription; } } throw new WebException("接続に失敗しました。(" + descText + ")"); } } catch { throw; } if (connection != null) { // Connection successful info.ConnectionState = ConnectionState.Connected; ConnectionManager.OnConnectionStateChanged(EventArgs.Empty); return; } if (failureWaitSec > 0) { if (failureWaitSec > Setting.Instance.ConnectionProperty.UserStreamsConnectionFailedMaxWaitSec) { throw new WebException("User Streamsへの接続に失敗しました。"); } else { NotifyStorage.Notify("@" + info.ScreenName + ": User Streamsへの接続に失敗。再試行まで" + failureWaitSec.ToString() + "秒待機...", failureWaitSec / 1000); // ウェイトカウント Thread.Sleep(failureWaitSec * 1000); NotifyStorage.Notify("@" + info.ScreenName + ": User Streamsへの接続を再試行します..."); } } else { NotifyStorage.Notify("@" + info.ScreenName + ": User Streamsへの接続に失敗しました。再試行します..."); } // 最初に失敗したらすぐに再接続 // 2回目以降はその倍に増やしていく // 300を超えたら接続失敗で戻る if (failureWaitSec == 0) { failureWaitSec = Setting.Instance.ConnectionProperty.UserStreamsConnectionFailedInitialWaitSec; } else { failureWaitSec *= 2; } } } catch (ThreadAbortException) { throw; } catch (Exception e) { this.AccountInfo.ConnectionState = ConnectionState.Disconnected; ConnectionManager.OnConnectionStateChanged(EventArgs.Empty); throw new WebException("User Streamsへの接続に失敗しました。", e); } }