Exemple #1
0
        public void OldestUnreadId_Test()
        {
            var tab = new TabClass { TabType = MyCommon.TabUsageType.UserTimeline };

            tab.UnreadManage = true;

            // 未読なし
            Assert.Equal(-1L, tab.OldestUnreadId);

            tab.AddPostToInnerStorage(new PostClass
            {
                StatusId = 100L,
                IsRead = false, // 未読
            });
            tab.AddSubmit();

            Assert.Equal(100L, tab.OldestUnreadId);

            tab.AddPostToInnerStorage(new PostClass
            {
                StatusId = 50L,
                IsRead = true, // 既読
            });
            tab.AddSubmit();

            Assert.Equal(100L, tab.OldestUnreadId);
        }
Exemple #2
0
        public void NextUnreadId_DisabledTest()
        {
            var tab = new TabClass { TabType = MyCommon.TabUsageType.UserTimeline };

            // 未読表示無効
            tab.UnreadManage = false;

            tab.AddPostToInnerStorage(new PostClass
            {
                StatusId = 100L,
                IsRead = false, // 未読
            });
            tab.AddSubmit();

            Assert.Equal(-1L, tab.NextUnreadId);
        }
Exemple #3
0
        public void SetReadState_MarkAsUnreadTest()
        {
            var tab = new TabClass { TabType = MyCommon.TabUsageType.UserTimeline };

            tab.UnreadManage = true;

            tab.AddPostToInnerStorage(new PostClass
            {
                StatusId = 100L,
                IsRead = true, // 既読
            });
            tab.AddSubmit();

            Assert.Equal(0, tab.UnreadCount);

            tab.SetReadState(100L, false); // 未読にする

            Assert.Equal(1, tab.UnreadCount);
        }
Exemple #4
0
        public void OldestUnreadIndex_DisabledTest()
        {
            var tab = new TabClass { TabType = MyCommon.TabUsageType.UserTimeline };

            // 未読表示無効
            tab.UnreadManage = false;

            tab.AddPostToInnerStorage(new PostClass
            {
                StatusId = 100L,
                IsRead = false, // 未読
            });
            tab.AddSubmit();

            tab.SortMode = ComparerMode.Id;
            tab.SortOrder = SortOrder.Ascending;
            tab.Sort();

            Assert.Equal(-1, tab.OldestUnreadIndex);
        }
Exemple #5
0
        public void GetRelatedResult(bool read, TabClass tab)
        {
            var relPosts = new Dictionary<Int64, PostClass>();
            if (tab.RelationTargetPost.TextFromApi.Contains("@") && tab.RelationTargetPost.InReplyToStatusId == null)
            {
                //検索結果対応
                var p = TabInformations.GetInstance()[tab.RelationTargetPost.StatusId];
                if (p != null && p.InReplyToStatusId != null)
                {
                    tab.RelationTargetPost = p;
                }
                else
                {
                    p = this.GetStatusApi(read, tab.RelationTargetPost.StatusId);
                    tab.RelationTargetPost = p;
                }
            }
            relPosts.Add(tab.RelationTargetPost.StatusId, tab.RelationTargetPost);

            Exception lastException = null;

            // in_reply_to_status_id を使用してリプライチェインを辿る
            var nextPost = FindTopOfReplyChain(relPosts, tab.RelationTargetPost.StatusId);
            var loopCount = 1;
            while (nextPost.InReplyToStatusId != null && loopCount++ <= 20)
            {
                var inReplyToId = nextPost.InReplyToStatusId.Value;

                var inReplyToPost = TabInformations.GetInstance()[inReplyToId];
                if (inReplyToPost == null)
                {
                    try
                    {
                        inReplyToPost = this.GetStatusApi(read, inReplyToId);
                    }
                    catch (WebApiException ex)
                    {
                        lastException = ex;
                        break;
                    }
                }

                relPosts.Add(inReplyToPost.StatusId, inReplyToPost);

                nextPost = FindTopOfReplyChain(relPosts, nextPost.StatusId);
            }

            //MRTとかに対応のためツイート内にあるツイートを指すURLを取り込む
            var text = tab.RelationTargetPost.Text;
            var ma = Twitter.StatusUrlRegex.Matches(text).Cast<Match>()
                .Concat(Twitter.ThirdPartyStatusUrlRegex.Matches(text).Cast<Match>());
            foreach (var _match in ma)
            {
                Int64 _statusId;
                if (Int64.TryParse(_match.Groups["StatusId"].Value, out _statusId))
                {
                    if (relPosts.ContainsKey(_statusId))
                        continue;

                    var p = TabInformations.GetInstance()[_statusId];
                    if (p == null)
                    {
                        try
                        {
                            p = this.GetStatusApi(read, _statusId);
                        }
                        catch (WebApiException ex)
                        {
                            lastException = ex;
                            break;
                        }
                    }

                    if (p != null)
                        relPosts.Add(p.StatusId, p);
                }
            }

            relPosts.Values.ToList().ForEach(p =>
            {
                if (p.IsMe && !read && this._readOwnPost)
                    p.IsRead = true;
                else
                    p.IsRead = read;

                tab.AddPostToInnerStorage(p);
            });

            if (lastException != null)
                throw new WebApiException(lastException.Message, lastException);
        }
Exemple #6
0
        private long? CreatePostsFromSearchJson(string content, TabClass tab, bool read, int count, bool more)
        {
            TwitterSearchResult items;
            try
            {
                items = TwitterSearchResult.ParseJson(content);
            }
            catch (SerializationException ex)
            {
                MyCommon.TraceOut(ex.Message + Environment.NewLine + content);
                throw new WebApiException("Json Parse Error(DataContractJsonSerializer)", content, ex);
            }
            catch (Exception ex)
            {
                MyCommon.TraceOut(ex, MethodBase.GetCurrentMethod().Name + " " + content);
                throw new WebApiException("Invalid Json!", content, ex);
            }

            long? minimumId = null;

            foreach (var result in items.Statuses)
            {
                PostClass post = null;
                post = CreatePostsFromStatusData(result);

                if (post == null)
                {
                    // Search API は相変わらずぶっ壊れたデータを返すことがあるため、必要なデータが欠如しているものは取得し直す
                    try
                    {
                        post = this.GetStatusApi(read, result.Id);
                    }
                    catch (WebApiException)
                    {
                        continue;
                    }
                }

                if (minimumId == null || minimumId.Value > post.StatusId)
                    minimumId = post.StatusId;

                if (!more && post.StatusId > tab.SinceId) tab.SinceId = post.StatusId;
                //二重取得回避
                lock (LockObj)
                {
                    if (tab == null)
                    {
                        if (TabInformations.GetInstance().ContainsKey(post.StatusId)) continue;
                    }
                    else
                    {
                        if (tab.Contains(post.StatusId)) continue;
                    }
                }

                post.IsRead = read;
                if ((post.IsMe && !read) && this._readOwnPost) post.IsRead = true;

                //非同期アイコン取得&StatusDictionaryに追加
                if (tab != null && tab.IsInnerStorageTabType)
                    tab.AddPostToInnerStorage(post);
                else
                    TabInformations.GetInstance().AddPost(post);
            }

            return minimumId;
        }
Exemple #7
0
        private long? CreatePostsFromJson(string content, MyCommon.WORKERTYPE gType, TabClass tab, bool read)
        {
            TwitterStatus[] items;
            try
            {
                items = TwitterStatus.ParseJsonArray(content);
            }
            catch(SerializationException ex)
            {
                MyCommon.TraceOut(ex.Message + Environment.NewLine + content);
                throw new WebApiException("Json Parse Error(DataContractJsonSerializer)", content, ex);
            }
            catch(Exception ex)
            {
                MyCommon.TraceOut(ex, MethodBase.GetCurrentMethod().Name + " " + content);
                throw new WebApiException("Invalid Json!", content, ex);
            }

            long? minimumId = null;

            foreach (var status in items)
            {
                PostClass post = null;
                post = CreatePostsFromStatusData(status);
                if (post == null) continue;

                if (minimumId == null || minimumId.Value > post.StatusId)
                    minimumId = post.StatusId;

                //二重取得回避
                lock (LockObj)
                {
                    if (tab == null)
                    {
                        if (TabInformations.GetInstance().ContainsKey(post.StatusId)) continue;
                    }
                    else
                    {
                        if (tab.Contains(post.StatusId)) continue;
                    }
                }

                //RT禁止ユーザーによるもの
                if (gType != MyCommon.WORKERTYPE.UserTimeline &&
                    post.RetweetedByUserId != null && this.noRTId.Contains(post.RetweetedByUserId.Value)) continue;

                post.IsRead = read;
                if (post.IsMe && !read && _readOwnPost) post.IsRead = true;

                //非同期アイコン取得&StatusDictionaryに追加
                if (tab != null && tab.IsInnerStorageTabType)
                    tab.AddPostToInnerStorage(post);
                else
                    TabInformations.GetInstance().AddPost(post);
            }

            return minimumId;
        }
Exemple #8
0
        public void GetStatusApi(bool read, long id, TabClass tab)
        {
            var post = this.GetStatusApi(read, id);

            //非同期アイコン取得&StatusDictionaryに追加
            if (tab != null && tab.IsInnerStorageTabType)
                tab.AddPostToInnerStorage(post);
            else
                TabInformations.GetInstance().AddPost(post);
        }
Exemple #9
0
        public void NextUnreadId_SortByIdAscTest()
        {
            var tab = new TabClass { TabType = MyCommon.TabUsageType.UserTimeline };

            tab.UnreadManage = true;

            // ID の昇順でソート
            tab.SetSortMode(ComparerMode.Id, SortOrder.Ascending);

            // 画面には上から 100 → 200 → 300 の順に並ぶ
            tab.AddPostToInnerStorage(new PostClass { StatusId = 100L, IsRead = false });
            tab.AddPostToInnerStorage(new PostClass { StatusId = 200L, IsRead = false });
            tab.AddPostToInnerStorage(new PostClass { StatusId = 300L, IsRead = false });
            tab.AddSubmit();

            // 昇順/降順に関わらず、ID の小さい順に未読の ID を返す
            Assert.Equal(100L, tab.NextUnreadId);
        }
Exemple #10
0
        public void GetUnreadIds_Test()
        {
            var tab = new TabClass { TabType = MyCommon.TabUsageType.UserTimeline };
            tab.UnreadManage = true;

            Assert.Empty(tab.GetUnreadIds());

            tab.AddPostToInnerStorage(new PostClass { StatusId = 100L, IsRead = false });
            tab.AddPostToInnerStorage(new PostClass { StatusId = 200L, IsRead = true });
            tab.AddSubmit();

            Assert.Equal(new[] { 100L }, tab.GetUnreadIds());

            tab.SetReadState(100L, true); // 既読にする

            Assert.Empty(tab.GetUnreadIds());
        }
Exemple #11
0
        public void NextUnreadIndex_Test()
        {
            var tab = new TabClass { TabType = MyCommon.TabUsageType.UserTimeline };
            tab.SetSortMode(ComparerMode.Id, SortOrder.Ascending);

            tab.UnreadManage = true;

            // 未読なし
            Assert.Equal(-1, tab.NextUnreadIndex);

            tab.AddPostToInnerStorage(new PostClass
            {
                StatusId = 50L,
                IsRead = true, // 既読
            });
            tab.AddPostToInnerStorage(new PostClass
            {
                StatusId = 100L,
                IsRead = false, // 未読
            });
            tab.AddPostToInnerStorage(new PostClass
            {
                StatusId = 150L,
                IsRead = false, // 未読
            });
            tab.AddSubmit();

            Assert.Equal(1, tab.NextUnreadIndex);
        }
Exemple #12
0
        public void NextUnreadId_SortByScreenNameDescTest()
        {
            var tab = new TabClass { TabType = MyCommon.TabUsageType.UserTimeline };

            tab.UnreadManage = true;

            // ScreenName の降順でソート
            tab.SetSortMode(ComparerMode.Name, SortOrder.Descending);

            // 画面には上から 300 → 100 → 200 の順に並ぶ
            tab.AddPostToInnerStorage(new PostClass { StatusId = 100L, ScreenName = "bbb", IsRead = false });
            tab.AddPostToInnerStorage(new PostClass { StatusId = 200L, ScreenName = "aaa", IsRead = false });
            tab.AddPostToInnerStorage(new PostClass { StatusId = 300L, ScreenName = "ccc", IsRead = false });
            tab.AddSubmit();

            // 昇順/降順に関わらず、ScreenName の辞書順で小さい順に未読の ID を返す
            Assert.Equal(200L, tab.NextUnreadId);
        }