示例#1
0
        private string GetRelatedResultsApi(bool read, PostClass post, TabClass tab, List<PostClass> relatedPosts)
        {
            if (AccountState != AccountState.Valid)
            {
                return string.Empty;
            }

            if (MyCommon.IsEnding)
            {
                return string.Empty;
            }

            HttpStatusCode res;
            string content = string.Empty;
            try
            {
                res = _twitterConnection.GetRelatedResults(post.OriginalStatusId, ref content);
            }
            catch (Exception ex)
            {
                return "Err:" + ex.Message;
            }

            switch (res)
            {
                case HttpStatusCode.OK:
                    AccountState = AccountState.Valid;
                    break;

                case HttpStatusCode.Unauthorized:
                    AccountState = AccountState.Invalid;
                    return R.Unauthorized;

                case HttpStatusCode.BadRequest:
                    return "Err:API Limits?";

                default:
                    return string.Format("Err:{0}({1})", res, MethodBase.GetCurrentMethod().Name);
            }

            List<RelatedResult> items;
            try
            {
                items = D.CreateDataFromJson<List<RelatedResult>>(content);
            }
            catch (SerializationException ex)
            {
                MyCommon.TraceOut(ex.Message + Environment.NewLine + content);
                return "Json Parse Error(DataContractJsonSerializer)";
            }
            catch (Exception ex)
            {
                MyCommon.TraceOut(ex, MethodBase.GetCurrentMethod().Name + " " + content);
                return "Invalid Json!";
            }

            PostClass targetItem = post;

            // if (targetItem == null){return string.Empty;}

            targetItem = targetItem.Copy();
            targetItem.RelTabName = tab.TabName;
            TabInformations.Instance.AddPost(targetItem);
            PostClass replyToItem = null;
            if (targetItem.InReplyToStatusId > 0 && TabInformations.Instance.Item(targetItem.InReplyToStatusId) != null)
            {
                replyToItem = TabInformations.Instance.Item(targetItem.InReplyToStatusId).Copy();
                replyToItem.IsRead = read || replyToItem.IsMe && ReadOwnPost;

                replyToItem.RelTabName = tab.TabName;
            }

            var replyAdded = false;
            foreach (var relatedData in items)
            {
                foreach (var result in relatedData.Results)
                {
                    var item = CreatePostsFromStatusData(result.Status);
                    if (item == null)
                    {
                        continue;
                    }

                    if (targetItem.InReplyToStatusId == item.StatusId)
                    {
                        replyToItem = null;
                        replyAdded = true;
                    }

                    item.IsRead = read || item.IsMe && ReadOwnPost;

                    // if (tab != null)
                    {
                        item.RelTabName = tab.TabName;
                    }

                    // 非同期アイコン取得&StatusDictionaryに追加
                    relatedPosts.Add(item);
                }
            }

            if (replyToItem != null)
            {
                relatedPosts.Add(replyToItem);
            }
            else if (targetItem.InReplyToStatusId > 0 && !replyAdded)
            {
                PostClass p = null;
                var rslt = GetStatusApi(read, targetItem.InReplyToStatusId, ref p);
                if (string.IsNullOrEmpty(rslt))
                {
                    p.IsRead = read;
                    p.RelTabName = tab.TabName;
                    relatedPosts.Add(p);
                }

                return rslt;
            }

            // MRTとかに対応のためツイート内にあるツイートを指すURLを取り込む
            var ma = Regex.Matches(tab.RelationTargetPost.Text, "title=\"https?://twitter.com/(#!/)?(?<ScreenName>[a-zA-Z0-9_]+)(/status(es)?/(?<StatusId>[0-9]+))\"");
            foreach (Match m in ma)
            {
                long statusId;
                if (!long.TryParse(m.Groups["StatusId"].Value, out statusId)) continue;

                PostClass p = null;
                var p2 = TabInformations.Instance.Item(statusId);
                if (p2 == null)
                {
                    GetStatusApi(read, statusId, ref p);
                }
                else
                {
                    p = p2.Copy();
                }

                if (p != null)
                {
                    p.IsRead = read;
                    p.RelTabName = tab.TabName;
                    relatedPosts.Add(p);
                }
            }

            return string.Empty;
        }
示例#2
0
        public string GetUserTimelineApi(bool read, int count, string userName, TabClass tab, bool more)
        {
            if (AccountState != AccountState.Valid)
            {
                return string.Empty;
            }

            if (MyCommon.IsEnding)
            {
                return string.Empty;
            }

            HttpStatusCode res;
            string content = string.Empty;
            if (count == 0)
            {
                count = 20;
            }

            try
            {
                if (string.IsNullOrEmpty(userName))
                {
                    string target = tab.User;
                    if (string.IsNullOrEmpty(target))
                    {
                        return string.Empty;
                    }

                    userName = target;
                    res = _twitterConnection.UserTimeline(0, target, count, 0, 0, ref content);
                }
                else
                {
                    res = _twitterConnection.UserTimeline(0, userName, count, more ? tab.OldestId : 0, 0, ref content);
                }
            }
            catch (Exception ex)
            {
                return "Err:" + ex.Message;
            }

            switch (res)
            {
                case HttpStatusCode.OK:
                    AccountState = AccountState.Valid;
                    break;

                case HttpStatusCode.Unauthorized:
                    AccountState = AccountState.Valid;
                    return string.Format("Err:@{0}'s Tweets are protected.", userName);

                case HttpStatusCode.BadRequest:
                    return "Err:API Limits?";

                default:
                    return string.Format("Err:{0}({1})", res, MethodBase.GetCurrentMethod().Name);
            }

            List<Status> items;
            try
            {
                items = D.CreateDataFromJson<List<Status>>(content);
            }
            catch (SerializationException ex)
            {
                MyCommon.TraceOut(ex.Message + Environment.NewLine + content);
                return "Json Parse Error(DataContractJsonSerializer)";
            }
            catch (Exception ex)
            {
                MyCommon.TraceOut(ex, MethodBase.GetCurrentMethod().Name + " " + content);
                return "Invalid Json!";
            }

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

                if (item.StatusId < tab.OldestId)
                {
                    tab.OldestId = item.StatusId;
                }

                item.IsRead = read || (item.IsMe && ReadOwnPost);

                // if (tab != null)
                {
                    item.RelTabName = tab.TabName;
                }

                // 非同期アイコン取得&StatusDictionaryに追加
                TabInformations.Instance.AddPost(item);
            }

            return string.Empty;
        }
示例#3
0
        // TODO: clean arguments
        private string CreatePostsFromJson(string content, WorkerType workerType, TabClass tab, bool read, int count, ref long minimumId)
        {
            List<Status> items;
            try
            {
                items = D.CreateDataFromJson<List<Status>>(content);
            }
            catch (SerializationException ex)
            {
                MyCommon.TraceOut(ex.Message + Environment.NewLine + content);
                return "Json Parse Error(DataContractJsonSerializer)";
            }
            catch (Exception ex)
            {
                MyCommon.TraceOut(ex, MethodBase.GetCurrentMethod().Name + " " + content);
                return "Invalid Json!";
            }

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

                if (minimumId > post.StatusId)
                {
                    minimumId = post.StatusId;
                }

                // 二重取得回避
                lock (_lockObj)
                {
                    if (tab == null)
                    {
                        if (TabInformations.Instance.ContainsKey(post.StatusId))
                        {
                            continue;
                        }
                    }
                    else
                    {
                        if (TabInformations.Instance.ContainsKey(post.StatusId, tab.TabName))
                        {
                            continue;
                        }
                    }
                }

                // RT禁止ユーザーによるもの
                if (post.IsRetweeted && _noRetweetIds.Contains(post.RetweetedByUserId))
                {
                    continue;
                }

                post.IsRead = read || post.IsMe && ReadOwnPost;

                if (tab != null)
                {
                    post.RelTabName = tab.TabName;
                }

                // 非同期アイコン取得&StatusDictionaryに追加
                TabInformations.Instance.AddPost(post);
            }

            return string.Empty;
        }
示例#4
0
        public string GetSearch(bool read, TabClass tab, bool more)
        {
            if (MyCommon.IsEnding)
            {
                return string.Empty;
            }

            var count = Configs.Instance.UseAdditionalCount && Configs.Instance.SearchCountApi != 0
                ? Configs.Instance.SearchCountApi
                : Configs.Instance.CountApi;

            HttpStatusCode res;
            var content = string.Empty;
            try
            {
                res = _twitterConnection.Search(tab.SearchWords, tab.SearchLang, count, tab.SinceId, ref content);
            }
            catch (Exception ex)
            {
                return "Err:" + ex.Message;
            }

            switch (res)
            {
                case HttpStatusCode.BadRequest:
                    return "Invalid query";

                case HttpStatusCode.NotFound:
                    return "Invalid query";

                case HttpStatusCode.PaymentRequired:

                    // API Documentには420と書いてあるが、該当コードがないので402にしてある
                    return "Search API Limit?";

                case HttpStatusCode.OK:
                    break;

                default:
                    return string.Format("Err:{0}({1})", res, MethodBase.GetCurrentMethod().Name);
            }

            if (!TabInformations.Instance.ContainsTab(tab))
            {
                return string.Empty;
            }

            SearchResult sres;
            try
            {
                sres = D.CreateDataFromJson<SearchResult>(content);
            }
            catch (Exception ex)
            {
                MyCommon.TraceOut(ex, MethodBase.GetCurrentMethod().Name + " " + content);
                return "Invalid JSON!";
            }

            foreach (var item in sres.Statuses.Select(CreatePostsFromStatusData).Where(item => item != null))
            {
                if (item.StatusId < tab.OldestId)
                {
                    tab.OldestId = item.StatusId;
                }

                item.IsRead = read || (item.IsMe && ReadOwnPost);

                // if (tab != null)
                {
                    item.RelTabName = tab.TabName;
                }

                // 非同期アイコン取得&StatusDictionaryに追加
                TabInformations.Instance.AddPost(item);
            }

            // TODO: use more sres.SearchMetadata
            tab.SinceId = sres.SearchMetadata.MaxId;

            return string.Empty;
        }
示例#5
0
        public string GetStatusApi(bool read, long id, TabClass tab)
        {
            PostClass post = null;
            string r = GetStatusApi(read, id, ref post);
            if (string.IsNullOrEmpty(r))
            {
                if (tab != null)
                {
                    post.RelTabName = tab.TabName;
                }

                // 非同期アイコン取得&StatusDictionaryに追加
                TabInformations.Instance.AddPost(post);
            }

            return r;
        }
示例#6
0
        public string GetRelatedResult(bool read, TabClass tab)
        {
            string rslt;
            var relPosts = new List<PostClass>();
            if (tab.RelationTargetPost.TextFromApi.Contains("@") && tab.RelationTargetPost.InReplyToStatusId == 0)
            {
                // 検索結果対応
                var p = TabInformations.Instance.Item(tab.RelationTargetPost.StatusId);
                if (p != null && p.InReplyToStatusId > 0)
                {
                    tab.RelationTargetPost = p;
                }
                else
                {
                    rslt = GetStatusApi(read, tab.RelationTargetPost.StatusId, ref p);
                    if (!string.IsNullOrEmpty(rslt))
                    {
                        return rslt;
                    }

                    tab.RelationTargetPost = p;
                }
            }

            relPosts.Add(tab.RelationTargetPost.Copy());
            var tmpPost = relPosts[0];
            do
            {
                rslt = GetRelatedResultsApi(read, tmpPost, tab, relPosts);
                if (!string.IsNullOrEmpty(rslt))
                {
                    break;
                }

                tmpPost = CheckReplyToPost(relPosts);
            }
            while (tmpPost != null);
            relPosts.ForEach(p => TabInformations.Instance.AddPost(p));
            return rslt;
        }
示例#7
0
        public string GetListStatus(bool read, TabClass tab, bool more, bool startup)
        {
            if (MyCommon.IsEnding)
            {
                return string.Empty;
            }

            HttpStatusCode res;
            string content = string.Empty;
            int count;
            if (Configs.Instance.UseAdditionalCount)
            {
                count = Configs.Instance.ListCountApi;
                if (count == 0)
                {
                    if (more && Configs.Instance.MoreCountApi != 0)
                    {
                        count = Configs.Instance.MoreCountApi;
                    }
                    else if (startup && Configs.Instance.FirstCountApi != 0)
                    {
                        count = Configs.Instance.FirstCountApi;
                    }
                    else
                    {
                        count = Configs.Instance.CountApi;
                    }
                }
            }
            else
            {
                count = Configs.Instance.CountApi;
            }

            try
            {
                long oldest = more ? tab.OldestId : 0L;
                res = _twitterConnection.GetListsStatuses(tab.ListInfo.UserId, tab.ListInfo.Id, count, oldest, 0, Configs.Instance.IsListStatusesIncludeRts, ref content);
            }
            catch (Exception ex)
            {
                return "Err:" + ex.Message;
            }

            switch (res)
            {
                case HttpStatusCode.OK:
                    AccountState = AccountState.Valid;
                    break;

                case HttpStatusCode.Unauthorized:
                    AccountState = AccountState.Invalid;
                    return R.Unauthorized;

                case HttpStatusCode.BadRequest:
                    return "Err:API Limits?";

                default:
                    return string.Format("Err:{0}({1})", res, MethodBase.GetCurrentMethod().Name);
            }

            var t = tab.OldestId;
            var ret = CreatePostsFromJson(content, WorkerType.List, tab, read, count, ref t);
            tab.OldestId = t;
            return ret;
        }
示例#8
0
 public bool ContainsTab(TabClass ts)
 {
     return Tabs.ContainsValue(ts);
 }
示例#9
0
 private void SetNextUnreadId(long currentId, TabClass tab)
 {
     // CurrentID:今既読にしたID(OldestIDの可能性あり)
     // 最古未読が設定されていて、既読の場合(1発言以上存在)
     try
     {
         // 次の未読探索
         var posts = tab.IsInnerStorageTabType ? tab.Posts : _statuses;
         if (tab.OldestUnreadId > -1 && posts.ContainsKey(tab.OldestUnreadId)
             && posts[tab.OldestUnreadId].IsRead && _sorter.Mode == IdComparerClass.ComparerMode.Id)
         {
             if (tab.UnreadCount == 0)
             {
                 // 未読数0→最古未読なし
                 tab.OldestUnreadId = -1;
             }
             else if (tab.OldestUnreadId == currentId && currentId > -1)
             {
                 // 最古IDを既読にしたタイミング→次のIDから続けて探索
                 int idx = tab.IndexOf(currentId);
                 if (idx > -1)
                 {
                     // 続きから探索
                     FindUnreadId(idx, tab);
                 }
                 else
                 {
                     // 頭から探索
                     FindUnreadId(-1, tab);
                 }
             }
             else
             {
                 // 頭から探索
                 FindUnreadId(-1, tab);
             }
         }
         else
         {
             // 頭から探索
             FindUnreadId(-1, tab);
         }
     }
     catch (KeyNotFoundException)
     {
         // 頭から探索
         FindUnreadId(-1, tab);
     }
 }
示例#10
0
        private void FindUnreadId(int startIdx, TabClass tab)
        {
            if (tab.AllCount == 0)
            {
                tab.OldestUnreadId = -1;
                tab.UnreadCount = 0;
                return;
            }

            int toIdx;
            int stp;
            tab.OldestUnreadId = -1;
            if (_sorter.Order == SortOrder.Ascending)
            {
                if (startIdx == -1)
                {
                    startIdx = 0;
                }
                else
                {
                    if (startIdx > tab.AllCount - 1)
                    {
                        startIdx = tab.AllCount - 1; // 念のため
                    }
                }

                toIdx = tab.AllCount - 1;
                if (toIdx < 0)
                {
                    toIdx = 0; // 念のため
                }

                stp = 1;
            }
            else
            {
                if (startIdx == -1)
                {
                    startIdx = tab.AllCount - 1;
                }

                if (startIdx < 0)
                {
                    startIdx = 0;
                }

                // 念のため
                toIdx = 0;
                stp = -1;
            }

            var posts = tab.IsInnerStorageTabType ? tab.Posts : _statuses;
            for (int i = startIdx; i <= toIdx; i += stp)
            {
                long id = tab.GetId(i);
                if (id > -1 && !posts[id].IsRead)
                {
                    tab.OldestUnreadId = id;
                    break;
                }
            }
        }