private void UpdateList() { if (!AccountStorage.Contains(_selectedScreenName)) { return; } var acc = AccountStorage.Get(_selectedScreenName); IsListLoading = true; Task.Factory.StartNew(() => { try { var lists = acc.GetFollowingListsAll(_selectedScreenName); if (lists != null) { lists.ForEach(l => acc.RegisterFollowingList(l)); } RaisePropertyChanged(() => ListItems); } catch { this.Messenger.Raise(new InformationMessage("リスト情報を取得できません。", "リストロードエラー", System.Windows.MessageBoxImage.Error, "WarningMessage")); } finally { IsListLoading = false; } }); }
private static IEnumerable <AccountInfo> GetAccountInfos(string argument) { if (argument == null) { return(new AccountInfo[0]); } return(argument.Split(',').Select(s => AccountStorage.Get(s.Trim())) .Where(i => i != null) .Distinct()); }
private AccountInfo FallbackAccount(AccountInfo original, AccountInfo current) { if (!PostOffice.IsAccountUnderControlled(current)) { return(current); } var fallback = AccountStorage.Get(current.AccountProperty.FallbackAccount); if (fallback == null || fallback == original) { return(current); } else { return(FallbackAccount(original, fallback)); } }
private static AccountInfo CheckFallback(AccountInfo d) { if (d == null) { throw new ArgumentNullException("d"); } AccountInfo origin = d; while ( Setting.Instance.InputExperienceProperty.OfficialRetweetFallback && IsAccountUnderControlled(d) && !String.IsNullOrEmpty(d.AccountProperty.FallbackAccount)) { var fallback = AccountStorage.Get(d.AccountProperty.FallbackAccount); if (fallback == null || fallback == origin) { break; } d = fallback; } return(d); }
static void Main(string[] args) { var transactionsParser = new TransactionsParser(); var res = transactionsParser.ParseTransactions(new string[] { }); var accountStorage = new AccountStorage(); var transactionsImporter = new TransactionsImporter(accountStorage, transactionsParser); var accountGuid = Guid.Parse("a7fce19b-ab94-4e4f-891c-6003dce94aa0"); var account = new Account(accountGuid); accountStorage.Save(account); while (Console.ReadLine() != "exit") { Console.WriteLine("Importing transactions..."); transactionsImporter.ImportTransactions("transactions.txt", account.Id); var updatedAccount = accountStorage.Get(accountGuid); Console.WriteLine($"Account contains {updatedAccount.Transactions.Count} transactions"); } }
public static void RegisterReceive(string listUser, string listName) { System.Diagnostics.Debug.WriteLine("** LIST LISTEN START:@" + listUser + "/" + listName); listName = NormalizeListName(listName); var fullname = BuildListName(listUser, listName); lock (rcLocker) { if (referenceCount.ContainsKey(fullname)) { referenceCount[fullname]++; } else { var target = AccountStorage.Get(listUser); if (target == null) { target = AccountStorage.GetRandom(ai => ai.IsFollowingList(listUser, listName), true); } var tscheduler = target != null?AutoCruiseSchedulerManager.GetScheduler(target) : null; if (tscheduler == null) { // スケジューラがまだない // スケジューラが更新されるまで待つ waitings.Add(new Tuple <string, string>(listUser, listName)); return; } var task = new ListReceiveTask(target, listUser, listName); receivers.Add(fullname, task); tscheduler.AddSchedule(task); Task.Factory.StartNew(() => ListStorage.Get(listUser, listName)); referenceCount.Add(fullname, 1); } } }
public void SetInReplyTo(TweetViewModel tweet) { if (tweet == null) { // clear in reply to this.CurrentInputDescription.InReplyToId = 0; } else { // スクリーン名の取得 var screen = tweet.Status.User.ScreenName; var sid = tweet.Status.Id; var ts = tweet.Status as TwitterStatus; if (!Setting.Instance.InputExperienceProperty.OfficialRetweetInReplyToRetweeter && ts != null && ts.RetweetedOriginal != null) { screen = ts.RetweetedOriginal.User.ScreenName; sid = ts.RetweetedOriginal.Id; } if (this.CurrentInputDescription.InputText.StartsWith(".@")) { // multi replication mode string remain; var screens = SplitTweet(this.CurrentInputDescription.InputText, out remain); if (screens.FirstOrDefault(s => s.Equals(screen, StringComparison.CurrentCultureIgnoreCase)) != null) { // 選択ユーザーのスクリーン名だけ抜く this.CurrentInputDescription.InputText = "." + screens.Where(s => !s.Equals(screen, StringComparison.CurrentCultureIgnoreCase)) .Select(s => "@" + s) .JoinString(" ") + " " + remain; } else { this.CurrentInputDescription.InputText = "." + screens.Select(s => "@" + s).JoinString(" ") + " " + "@" + screen + " " + remain; this.SetInputCaretIndex(this.CurrentInputDescription.InputText.Length); } this.CurrentInputDescription.InReplyToId = 0; } else if (this.CurrentInputDescription.InReplyToId != 0 && this.CurrentInputDescription.InputText.StartsWith("@")) { // single reply mode -> muliti reply mode string remain; var screens = SplitTweet(this.CurrentInputDescription.InputText, out remain); this.CurrentInputDescription.InputText = "." + screens.Select(s => "@" + s).Concat(new[] { "@" + screen }).Distinct().JoinString(" ") + " " + remain; this.CurrentInputDescription.InReplyToId = 0; this.SetInputCaretIndex(this.CurrentInputDescription.InputText.Length); this.overrideTargets = null; } else { // single reply mode this.CurrentInputDescription.InReplyToId = sid; if (tweet.Status is TwitterDirectMessage) { this.OverrideTarget(new[] { AccountStorage.Get(((TwitterDirectMessage)tweet.Status).Recipient.ScreenName) }); this.CurrentInputDescription.InputText = "d @" + screen + " "; this.SetInputCaretIndex(this.CurrentInputDescription.InputText.Length); } else { var mentions = RegularExpressions.AtRegex.Matches(tweet.TweetText); var sns = new[] { "@" + screen }.Concat(mentions.Cast <Match>().Select(m => m.Value)) .Distinct().Where(s => !AccountStorage.Contains(s)).ToArray(); /* * if (tweet.Status is TwitterStatus && AccountStorage.Contains(((TwitterStatus)tweet.Status).InReplyToUserScreenName)) * sns = sns.Except(new[] { "@" + ((TwitterStatus)tweet.Status).InReplyToUserScreenName }).ToArray(); */ if (sns.Length > 1) { this.CurrentInputDescription.InputText = sns.JoinString(" ") + " "; this.SetInputCaretIndex(sns[0].Length + 1, sns.JoinString(" ").Length - sns[0].Length); } else { this.CurrentInputDescription.InputText = "@" + screen + " "; this.SetInputCaretIndex(this.CurrentInputDescription.InputText.Length); } if (tweet.Status is TwitterStatus && AccountStorage.Contains(((TwitterStatus)tweet.Status).InReplyToUserScreenName)) { var ainfo = AccountStorage.Get(((TwitterStatus)tweet.Status).InReplyToUserScreenName); if (ainfo != null && Setting.Instance.InputExperienceProperty.FallbackBackTracking) { ainfo = FallbackBackTracking(ainfo); } this.OverrideTarget(new[] { ainfo }); } } } } }
private bool WorkCore() { try { try { // build text // attach image if (!String.IsNullOrEmpty(this.attachImagePath) && !isImageAttached) { if (File.Exists(this.attachImagePath)) { try { var upl = UploaderManager.GetSuggestedUploader(); if (upl == null) { throw new InvalidOperationException("画像のアップローダ―が指定されていません。"); } var delgupl = upl as IPostDelegatingUploader; if (delgupl != null) { // delegating upload delgupl.PostAndUpload(this.accountInfo, this.attachImagePath, this.body, this.inReplyToId); this.WorkingState = InputBlock.WorkingState.Updated; return(true); } body += " " + upl.UploadImage(this.accountInfo, this.attachImagePath, this.body); isImageAttached = true; } catch (Exception e) { throw new WebException("画像のアップロードに失敗しました。", e); } } else { throw new FileNotFoundException("添付ファイルが見つかりません。"); } } // trimming space and line feeding body = body.TrimStart(TwitterDefine.TrimmingChars).TrimEnd(TwitterDefine.TrimmingChars); if (TweetTextCounter.Count(body) > TwitterDefine.TweetMaxLength) { if (Setting.Instance.InputExperienceProperty.TrimExceedChars) { while (TweetTextCounter.Count(body) > TwitterDefine.TweetMaxLength) { body = body.Substring(0, body.Length - 1); } } else { throw new Exception("ツイートが140文字を超えました。"); } } if (!isBodyStandby) { // is Unoffocial RT bool isQuoting = false; string quoteBody = String.Empty; // split "unofficial RT" var quoteindex = -1; var rtidx = body.IndexOf("RT @"); if (rtidx >= 0) { quoteindex = rtidx; } var qtidx = body.IndexOf("QT @"); if (qtidx >= 0 && (quoteindex == -1 || qtidx < quoteindex)) { quoteindex = qtidx; } if (quoteindex >= 0) { isQuoting = true; quoteBody = " " + body.Substring(quoteindex).Trim(); body = body.Substring(0, quoteindex); } body = body.TrimEnd(' ', '\t'); // add footer (when is in not "unofficial RT") if (!isQuoting && !String.IsNullOrEmpty(accountInfo.AccountProperty.FooterString) && TweetTextCounter.Count(body) + TweetTextCounter.Count(accountInfo.AccountProperty.FooterString) + 1 <= TwitterDefine.TweetMaxLength) { body += " " + accountInfo.AccountProperty.FooterString; } // bind tag if (tags != null && this.tags.Any()) { foreach (var tag in tags.Select(t => t.StartsWith("#") ? t : "#" + t)) { if (TweetTextCounter.Count(body) + TweetTextCounter.Count(quoteBody) + tag.Length + 1 <= TwitterDefine.TweetMaxLength) { body += " " + tag; } } } // join quote body += quoteBody; isBodyStandby = true; } // uniquify body if (Setting.Instance.InputExperienceProperty.AutoUniquify) { body = Uniquify(body); } this.TweetSummary = "@" + this.accountInfo.ScreenName + ": " + body; // ready if (this.inReplyToId != 0) { this.RecentPostCount = PostOffice.UpdateTweet(this.accountInfo, body, this.inReplyToId); } else { this.RecentPostCount = PostOffice.UpdateTweet(this.accountInfo, body); } this.WorkingState = InputBlock.WorkingState.Updated; return(true); } catch (TweetFailedException tfex) { var acc = AccountStorage.Get(this.accountInfo.AccountProperty.FallbackAccount); if (tfex.ErrorKind != TweetFailedException.TweetErrorKind.Controlled || acc == null) { throw; } else { // fallbacking // 画像のattachやタグのbindはもう必要ない FallbackRequired(new TweetWorker(this.parent, acc, body, this.inReplyToId, null, null)); throw new TweetAnnotationException(TweetAnnotationException.AnnotationKind.Fallbacked); } } } catch (Exception ex) { this.WorkingState = ex is TweetAnnotationException ? InputBlock.WorkingState.Annotated : InputBlock.WorkingState.Failed; this.ExceptionString = ex.ToString(); ParseFailException(ex); this.RecentPostCount = -1; return(this.WorkingState == InputBlock.WorkingState.Annotated); } }
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); } }
/// <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; } }