private static async void UpdateConfiguration() { var account = Setting.Accounts.GetRandomOne(); if (account == null) { // execute later Observable.Timer(TimeSpan.FromMinutes(1)) .ObserveOn(TaskPoolScheduler.Default) .Subscribe(_ => UpdateConfiguration()); return; } try { var config = await account.GetConfigurationAsync(); HttpUrlLength = config.ShortUrlLength; HttpsUrlLength = config.ShortUrlLengthHttps; MediaUrlLength = config.CharactersReservedPerMedia; } catch (Exception ex) { BackstageModel.RegisterEvent(new OperationFailedEvent(SubsystemResources.TwitterConfigurationReceiveError, ex)); // execute later Observable.Timer(TimeSpan.FromMinutes(5)) .ObserveOn(TaskPoolScheduler.Default) .Subscribe(_ => UpdateConfiguration()); } }
private async void OnTimer() { if (this._isDisposed) { return; } if (Interlocked.Decrement(ref this._remainCountDown) > 0) { return; } this._remainCountDown = this.IntervalSec; try { await Task.Run(async() => { using (MainWindowModel.SetState("受信中: " + ReceiverName)) { await this.DoReceive(); } }); } catch (Exception ex) { BackstageModel.RegisterEvent(new OperationFailedEvent("受信に失敗しました:" + ReceiverName, ex)); } }
public static void ApplyWebProxy() { switch (Setting.WebProxyType.Value) { case WebProxyConfiguration.Default: Anomaly.Core.UseSystemProxy = true; break; case WebProxyConfiguration.None: Anomaly.Core.UseSystemProxy = false; Anomaly.Core.ProxyProvider = null; break; case WebProxyConfiguration.Custom: Anomaly.Core.UseSystemProxy = false; try { Anomaly.Core.ProxyProvider = () => new WebProxy( new Uri("http://" + Setting.WebProxyHost.Value + ":" + Setting.WebProxyPort.Value.ToString(CultureInfo.InvariantCulture)), Setting.BypassWebProxyInLocal.Value, Setting.WebProxyBypassList.Value); } catch (Exception ex) { Anomaly.Core.ProxyProvider = null; BackstageModel.RegisterEvent(new OperationFailedEvent("プロキシ エラー", ex)); } break; default: throw new ArgumentOutOfRangeException(); } }
private async void OnTimer() { if (_isDisposed) { return; } if (Interlocked.Decrement(ref _remainCountDown) > 0) { return; } _remainCountDown = IntervalSec; try { await Task.Run(async() => { using (MainWindowModel.SetState(ReceivingResources.ReceivingFormat.SafeFormat(ReceiverName))) { await DoReceive().ConfigureAwait(false); } }).ConfigureAwait(false); } catch (Exception ex) { BackstageModel.RegisterEvent(new OperationFailedEvent( ReceivingResources.ReceiveFailedFormat.SafeFormat(ReceiverName), ex)); } }
public TabModel ToTabModel() { FilterQuery filter; try { filter = QueryCompiler.Compile(Query); } catch (FilterQueryException ex) { BackstageModel.RegisterEvent(new QueryCorruptionEvent(Name, ex)); filter = null; } var model = new TabModel { Name = Name, FilterQuery = filter, BindingHashtags = this.BindingHashtags, NotifyNewArrivals = this.NotifyNewArrivals, NotifySoundSource = this.NotifySoundSource, ShowUnreadCounts = this.ShowUnreadCounts }; this.BindingAccountIds.ForEach(model.BindingAccounts.Add); return(model); }
private void PostInitialize() { if (Setting.CheckDesktopHeap.Value) { try { var dh = SystemInformation.DesktopHeapSize; var rh = App.LeastDesktopHeapSize; if (dh < rh) { var msg = this.Messenger.GetResponse(new TaskDialogMessage(new TaskDialogOptions { Title = Resources.AppName, MainIcon = VistaTaskDialogIcon.Warning, MainInstruction = AppInitResources.MsgDesktopHeapInst, Content = AppInitResources.MsgDesktopHeapContent, ExpandedInfo = AppInitResources.MsgDesktopHeapInfoFormat.SafeFormat(dh, rh), CommandButtons = new[] { AppInitResources.MsgButtonBrowseMsKb, Resources.MsgButtonCancel }, VerificationText = Resources.MsgDoNotShowAgain, })); Setting.CheckDesktopHeap.Value = !msg.Response.VerificationChecked.GetValueOrDefault(); if (msg.Response.CommandButtonResult == 0) { BrowserHelper.Open("http://support.microsoft.com/kb/947246"); } } } catch (Exception ex) { BackstageModel.RegisterEvent(new OperationFailedEvent("sysinfo failed", ex)); } } }
private static async Task <bool> CheckUpdate(Version version) { if (IsUpdateBinaryExisted()) { return(true); } try { string verXml; using (var http = new HttpClient()) { verXml = await http.GetStringAsync(App.RemoteVersionXml); } var xdoc = XDocument.Load(new StringReader(verXml)); _patcherUri = xdoc.Root?.Attribute("patcher")?.Value ?? throw new Exception("could not read definition xml."); _patcherSignUri = xdoc.Root.Attribute("sign")?.Value; var releases = xdoc.Root.Descendants("release"); var latest = releases.Select(r => Version.Parse(r?.Attribute("version")?.Value ?? "0.0")) .Where(v => Setting.AcceptUnstableVersion.Value || v.Revision <= 0) .OrderByDescending(v => v) .FirstOrDefault(); if (version != null && latest > version) { return(true); } } catch (Exception ex) { BackstageModel.RegisterEvent(new OperationFailedEvent( SubsystemResources.FailedCheckingUpdate, ex)); } return(false); }
public void CopyTab() { try { var model = new TabModel { Name = Name, FilterQuery = Model.FilterQuery != null ? QueryCompiler.Compile(Model.FilterQuery.ToQuery()) : null, RawQueryString = Model.RawQueryString, BindingHashtags = Model.BindingHashtags.ToArray(), NotifyNewArrivals = Model.NotifyNewArrivals, ShowUnreadCounts = Model.ShowUnreadCounts, NotifySoundSource = Model.NotifySoundSource }; Model.BindingAccounts.ForEach(id => model.BindingAccounts.Add(id)); Parent.Model.CreateTab(model); } catch (FilterQueryException fqex) { BackstageModel.RegisterEvent( new OperationFailedEvent(QueryCompilerResources.QueryCompileFailed, fqex)); } }
public void NotifyRetweetRetweeted(TwitterUser source, TwitterUser target, TwitterStatus status) { if (Setting.Accounts.Contains(target.Id)) { BackstageModel.RegisterEvent(new RetweetedEvent(source, target, status)); } }
public void NotifyQuoted(TwitterUser source, TwitterStatus original, TwitterStatus quote) { if (quote.QuotedStatus != null && Setting.Accounts.Contains(original.User.Id)) { BackstageModel.RegisterEvent(new QuotedEvent(source, quote)); } }
public override async Task <TwitterStatus> Send(TwitterAccount account) { // ReSharper disable RedundantIfElseBlock if (_createRetweet) { Exception thrown; // make retweet var acc = account; do { try { var result = await acc.RetweetAsync(_id); BackstageModel.NotifyFallbackState(acc, false); return(result); } catch (TwitterApiException tae) { thrown = tae; if (tae.Message.Contains(LimitMessage)) { BackstageModel.NotifyFallbackState(acc, true); if (acc.FallbackAccountId != null) { // reached post limit, fallback var prev = acc; acc = Setting.Accounts.Get(acc.FallbackAccountId.Value); BackstageModel.RegisterEvent(new FallbackedEvent(prev, acc)); continue; } } } var id = await acc.GetMyRetweetIdOfStatusAsync(_id); if (id.HasValue) { // already retweeted. return(null); } throw thrown; } while (acc != null && acc.Id != account.Id); throw thrown; } else { // get retweet id var id = await account.GetMyRetweetIdOfStatusAsync(_id); if (!id.HasValue) { // retweet is not existed. return(null); } // destroy retweet return(await account.DestroyAsync(id.Value)); } // ReSharper restore RedundantIfElseBlock }
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)); } }
public void LoadMore() { if (!_isDeferLoadEnabled || this.IsLoading) { return; } this.IsLoading = true; Task.Run(async() => { var account = Setting.Accounts.GetRandomOne(); if (account == null) { _parent.Messenger.Raise(new TaskDialogMessage(new TaskDialogOptions { Title = "読み込みエラー", MainIcon = VistaTaskDialogIcon.Error, MainInstruction = "ユーザーの読み込みに失敗しました。", Content = "アカウントが登録されていません。", CommonButtons = TaskDialogCommonButtons.Close, })); BackstageModel.RegisterEvent(new OperationFailedEvent("アカウントが登録されていません。", null)); } var page = Interlocked.Increment(ref _currentPageCount); try { var result = await account.SearchUserAsync(this.Query, count: 100, page: page); var twitterUsers = result as TwitterUser[] ?? result.ToArray(); if (!twitterUsers.Any()) { _isDeferLoadEnabled = false; return; } await DispatcherHelper.UIDispatcher.InvokeAsync( () => twitterUsers.Where(u => Users.All(e => e.User.Id != u.Id)) // add distinct .ForEach(u => Users.Add(new UserResultItemViewModel(u)))); } catch (Exception ex) { _parent.Messenger.Raise(new TaskDialogMessage(new TaskDialogOptions { Title = "読み込みエラー", MainIcon = VistaTaskDialogIcon.Error, MainInstruction = "ユーザーの読み込みに失敗しました。", Content = ex.Message, CommonButtons = TaskDialogCommonButtons.Close, })); BackstageModel.RegisterEvent(new OperationFailedEvent("ユーザーの読み込みに失敗しました", ex)); } finally { IsLoading = false; } }); }
internal static async Task <bool> CheckPrepareUpdate(Version version) { if (!await CheckUpdate(version)) { return(false); } if (String.IsNullOrEmpty(_patcherUri) || String.IsNullOrEmpty(_patcherSignUri)) { return(false); } try { if (IsUpdateBinaryExisted() || Directory.Exists(App.LocalUpdateStorePath)) { // files are already downloaded. return(true); } try { Directory.CreateDirectory(App.LocalUpdateStorePath); using (var http = new HttpClient()) { var patcher = await http.GetByteArrayAsync(_patcherUri); var patcherSign = await http.GetByteArrayAsync(_patcherSignUri); var pubkey = File.ReadAllText(App.PublicKeyFile); if (!VerifySignature(patcher, patcherSign, pubkey)) { throw new Exception("Updater signature is invalid."); } File.WriteAllBytes(ExecutablePath, patcher); } UpdateStateChanged?.Invoke(); return(true); } catch { try { Directory.Delete(App.LocalUpdateStorePath, true); } catch { // ignored } throw; } } catch (Exception ex) { BackstageModel.RegisterEvent(new OperationFailedEvent( SubsystemResources.FailedPrepareUpdate, ex)); return(false); } }
public void NotifyFallbackState(bool isFallbacked) { if (!isFallbacked && !this.IsFallbacked) { return; } Task.Run(() => { this.IsFallbacked = isFallbacked; if (isFallbacked) { // calc prediction var threshold = DateTime.Now - TimeSpan.FromSeconds(Setting.PostWindowTimeSec.Value); var oldest = PostLimitPredictionService.GetStatuses(Account.Id) .Where(t => t.CreatedAt > threshold) .OrderByDescending(t => t.CreatedAt) .Take(Setting.PostLimitPerWindow.Value) // limit count .LastOrDefault(); if (oldest == null) { IsFallbacked = false; FallbackPredictedReleaseTime = DateTime.Now; } else { FallbackPredictedReleaseTime = oldest.CreatedAt + TimeSpan.FromSeconds(Setting.PostWindowTimeSec.Value); // create timer if (_prevScheduled != null) { _prevScheduled.Dispose(); } _prevScheduled = Observable.Timer(FallbackPredictedReleaseTime) .Subscribe(_ => { IsFallbacked = false; this.RaiseFallbackStateUpdated(); }); } } else { FallbackPredictedReleaseTime = DateTime.Now; if (_prevScheduled != null) { _prevScheduled.Dispose(); _prevScheduled = null; } } if (IsFallbacked) { BackstageModel.RegisterEvent(new PostLimitedEvent(Account, FallbackPredictedReleaseTime)); } this.RaiseFallbackStateUpdated(); }); }
public void OnExceptionThrownDuringParsing(Exception ex) { _parent.Log("user streams: unknown data received."); ex.ToString() .Split(new[] { "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries) .Select(s => "> " + s) .ForEach(_parent.Log); BackstageModel.RegisterEvent(new StreamDecodeFailedEvent( _parent.Account.UnreliableScreenName, ex)); }
public void NotifyLimitationInfoGot(IOAuthCredential account, int trackLimit) { var acc = account as TwitterAccount; if (acc == null) { return; } BackstageModel.RegisterEvent(new TrackLimitEvent(acc, trackLimit)); }
public async void Remove() { try { await this._account.DestroySavedSearchAsync(_id); } catch (Exception ex) { BackstageModel.RegisterEvent(new OperationFailedEvent("検索クエリの削除に失敗しました", ex)); } }
public async void Remove() { try { await this._account.DestroySavedSearchAsync(_id); } catch (Exception ex) { BackstageModel.RegisterEvent(new OperationFailedEvent(SearchFlipResources.InfoDeleteQueryFailed, ex)); } }
public void OpenEventTargetStatus() { var ev = TwitterEvent; if (ev?.TargetStatus == null) { return; } BackstageModel.RaiseCloseBackstage(); SearchFlipModel.RequestSearch("?from conv:\"" + ev.TargetStatus.Id + "\"", SearchMode.Local); }
public void OpenEventSourceUserProfile() { var ev = TwitterEvent; if (ev?.Source == null) { return; } BackstageModel.RaiseCloseBackstage(); SearchFlipModel.RequestSearch(ev.Source.ScreenName, SearchMode.UserScreenName); }
/// <summary> /// Receive older tweets. <para /> /// Tweets are registered to StatusStore automatically. /// </summary> /// <param name="maxId">receiving threshold id</param> public IObservable <TwitterStatus> Receive(long?maxId) { return(ReceiveSink(maxId) .Do(StatusInbox.Enqueue) .Catch((Exception ex) => { BackstageModel.RegisterEvent(new OperationFailedEvent( "フィルタソースからの受信に失敗しました: " + FilterKey + ": " + FilterValue, ex)); return Observable.Empty <TwitterStatus>(); })); }
/// <summary> /// Receive older tweets. <para /> /// Tweets are registered to StatusStore automatically. /// </summary> /// <param name="maxId">receiving threshold id</param> public IObservable <TwitterStatus> Receive(long?maxId) { return(ReceiveSink(maxId) .Do(StatusInbox.Enqueue) .Catch((Exception ex) => { BackstageModel.RegisterEvent(new OperationFailedEvent( FilterObjectResources.FilterSourceBaseReceiveFailed + " " + FilterKey + ": " + FilterValue, ex)); return Observable.Empty <TwitterStatus>(); })); }
private void SendCore(InputData data) { Task.Run(async() => { var r = await data.SendAsync().ConfigureAwait(false); if (r.Succeededs != null) { InputModel.InputCore.LastPostedData = r.Succeededs; BackstageModel.RegisterEvent(new PostSucceededEvent(r.Succeededs)); } if (r.Faileds != null) { var message = AnalyzeFailedReason(r.Exceptions) ?? InputAreaResources.MsgTweetFailedReasonUnknown; var ed = r.Exceptions .Guard() .SelectMany(ex => EnumerableEx.Generate( ex, e => e != null, e => e.InnerException, e => e)) .Where(e => e != null) .Select(e => e.ToString()) .JoinString(Environment.NewLine); if (Setting.ShowMessageOnTweetFailed.Value) { var resp = _parent.Messenger.GetResponseSafe(() => new TaskDialogMessage(new TaskDialogOptions { Title = InputAreaResources.MsgTweetFailedTitle, MainIcon = VistaTaskDialogIcon.Error, MainInstruction = InputAreaResources.MsgTweetFailedInst, Content = InputAreaResources.MsgTweetFailedContentFormat.SafeFormat(message), ExpandedInfo = ed, FooterText = InputAreaResources.MsgTweetFailedFooter, FooterIcon = VistaTaskDialogIcon.Information, VerificationText = Resources.MsgDoNotShowAgain, CommonButtons = TaskDialogCommonButtons.RetryCancel })); Setting.ShowMessageOnTweetFailed.Value = !resp.Response.VerificationChecked.GetValueOrDefault(); if (resp.Response.Result == TaskDialogSimpleResult.Retry) { SendCore(r.Faileds); return; } } else { BackstageModel.RegisterEvent(new PostFailedEvent(r.Faileds, message)); } // Send to draft InputModel.InputCore.Drafts.Add(r.Faileds); } }); }
private void SendCore(InputData data) { data.Send() .Subscribe(r => { if (r.Succeededs != null) { InputModel.InputCore.LastPostedData = r.Succeededs; BackstageModel.RegisterEvent(new PostSucceededEvent(r.Succeededs)); } if (r.Faileds != null) { var message = this.AnalyzeFailedReason(r.Exceptions) ?? "原因を特定できませんでした。"; var ed = r.Exceptions .Guard() .SelectMany(ex => EnumerableEx.Generate( ex, e => e != null, e => e.InnerException, e => e)) .Where(e => e != null) .Select(e => e.ToString()) .JoinString(Environment.NewLine); if (Setting.ShowMessageOnTweetFailed.Value) { var resp = _parent.Messenger.GetResponse(new TaskDialogMessage(new TaskDialogOptions { Title = "ツイートの失敗", MainIcon = VistaTaskDialogIcon.Error, MainInstruction = "ツイートに失敗しました。", Content = "エラー: " + message + Environment.NewLine + "もう一度投稿しますか?", ExpandedInfo = ed, FooterText = "再試行しない場合は、ツイートしようとした内容は下書きとして保存されます。", FooterIcon = VistaTaskDialogIcon.Information, VerificationText = "次回から表示しない", CommonButtons = TaskDialogCommonButtons.RetryCancel })); Setting.ShowMessageOnTweetFailed.Value = !resp.Response.VerificationChecked.GetValueOrDefault(); if (resp.Response.Result == TaskDialogSimpleResult.Retry) { this.SendCore(r.Faileds); return; } } else { BackstageModel.RegisterEvent(new PostFailedEvent(r.Faileds, message)); } // Send to draft InputModel.InputCore.Drafts.Add(r.Faileds); } }); }
public override async Task <TwitterStatus> Send(TwitterAccount account) { var latlong = _geoInfo == null ? null : Tuple.Create(_geoInfo.Latitude, _geoInfo.Longitude); Exception thrown; // make retweet var acc = account; do { try { TwitterStatus result; if (_attachedImageBin != null) { result = await acc.UpdateWithMediaAsync( this._status, new[] { this._attachedImageBin }, account.MarkMediaAsPossiblySensitive?true : (bool?)null, // Inherit property this._inReplyTo, latlong); } else { result = await acc.UpdateAsync( this._status, this._inReplyTo, latlong); } BackstageModel.NotifyFallbackState(acc, false); return(result); } catch (TwitterApiException tae) { thrown = tae; if (tae.Message.Contains(LimitMessage)) { BackstageModel.NotifyFallbackState(acc, true); if (acc.FallbackAccountId != null) { // reached post limit, fallback var prev = acc; acc = Setting.Accounts.Get(acc.FallbackAccountId.Value); BackstageModel.RegisterEvent(new FallbackedEvent(prev, acc)); continue; } } } throw thrown; } while (acc != null && acc.Id != account.Id); throw thrown; }
public void ReportAsSpam() { var msg = new TaskDialogMessage(new TaskDialogOptions { Title = "ユーザーをスパムとして報告", MainIcon = VistaTaskDialogIcon.Warning, MainInstruction = "ユーザー " + this.Status.User.ScreenName + " をスパム報告しますか?", Content = "全てのアカウントからブロックし、代表のアカウントからスパム報告します。", CustomButtons = new[] { "スパム報告", "キャンセル" }, AllowDialogCancellation = true, }); var response = this.Parent.Messenger.GetResponse(msg); if (response.Response.CustomButtonResult != 0) { return; } // report as a spam var accounts = Setting.Accounts.Collection.ToArray(); var reporter = accounts.FirstOrDefault(); if (reporter == null) { return; } var rreq = new UpdateRelationRequest(this.User.User, RelationKind.Block); accounts.ToObservable() .SelectMany(a => RequestQueue.Enqueue(a, rreq) .Do(r => BackstageModel.RegisterEvent( new BlockedEvent(a.GetPserudoUser(), this.User.User)))) .Merge( RequestQueue.Enqueue(reporter, new UpdateRelationRequest(this.User.User, RelationKind.ReportAsSpam)) .Do(r => BackstageModel.RegisterEvent( new BlockedEvent(reporter.GetPserudoUser(), this.User.User)))) .Subscribe( _ => { }, ex => BackstageModel.RegisterEvent(new InternalErrorEvent(ex.Message)), () => { var tid = this.Status.User.Id; var tidstr = tid.ToString(CultureInfo.InvariantCulture); StatusProxy.FetchStatuses( s => s.User.Id == tid || (s.RetweetedOriginal != null && s.RetweetedOriginal.User.Id == tid), "UserId = " + tidstr + " OR BaseUserId = " + tidstr) .Subscribe(s => StatusInbox.EnqueueRemoval(s.Id)); }); }
protected override async Task DoReceive() { var authInfo = this._auth ?? Setting.Accounts.GetRandomOne(); if (authInfo == null) { BackstageModel.RegisterEvent(new OperationFailedEvent( "アカウントが登録されていないため、リストタイムラインを受信できませんでした。", null)); return; } (await authInfo.GetListTimelineAsync(this._listInfo.Slug, this._listInfo.OwnerScreenName)) .ForEach(StatusInbox.Enqueue); }
protected override async Task DoReceive() { var authInfo = this._auth ?? Setting.Accounts.GetRandomOne(); if (authInfo == null) { BackstageModel.RegisterEvent(new OperationFailedEvent( ReceivingResources.AccountIsNotRegisteredForList, null)); return; } (await authInfo.GetListTimelineAsync(this._listInfo.Slug, this._listInfo.OwnerScreenName)) .ForEach(StatusInbox.Enqueue); }
public BackstageAccountModel(TwitterAccount account) { this._account = account; this.UpdateConnectionState(); StoreHelper.GetUser(this._account.Id) .Subscribe( u => { _user = u; this.RaiseTwitterUserChanged(); }, ex => BackstageModel.RegisterEvent( new OperationFailedEvent("アカウント情報を取得できません(@" + _account.UnreliableScreenName + ")", ex))); }