예제 #1
0
        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;
                }
            });
        }
예제 #2
0
 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());
 }
예제 #3
0
        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));
            }
        }
예제 #4
0
        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);
        }
예제 #5
0
        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");
            }
        }
예제 #6
0
        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);
                }
            }
        }
예제 #7
0
        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 });
                        }
                    }
                }
            }
        }
예제 #8
0
        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);
            }
        }
예제 #9
0
        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);
            }
        }
예제 #10
0
        /// <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;
            }
        }