예제 #1
0
        public void EmptyRuleTest()
        {
            var filter = new PostFilterRule { };
            var post = new PostClass { ScreenName = "hogehoge" };

            Assert.Equal(MyCommon.HITRESULT.None, filter.ExecFilter(post));
        }
예제 #2
0
        public void CloneTest()
        {
            var post = new PostClass();
            var clonePost = post.Clone();

            TestUtils.CheckDeepCloning(post, clonePost);
        }
예제 #3
0
        public void NameTest()
        {
            var filter = new FiltersClass();
            PostClass post;

            filter.NameFilter = "hoge";
            post = new PostClass { ScreenName = "hoge", Text = "test" };
            Assert.That(filter.IsHit(post), Is.EqualTo(MyCommon.HITRESULT.CopyAndMark));

            filter.NameFilter = "hoge";
            post = new PostClass { ScreenName = "foo", Text = "test" };
            Assert.That(filter.IsHit(post), Is.EqualTo(MyCommon.HITRESULT.None));

            // NameFilter は RetweetedBy にもマッチする
            filter.NameFilter = "hoge";
            post = new PostClass { ScreenName = "foo", Text = "test", RetweetedBy = "hoge" };
            Assert.That(filter.IsHit(post), Is.EqualTo(MyCommon.HITRESULT.CopyAndMark));

            filter.NameFilter = "hoge";
            post = new PostClass { ScreenName = "foo", Text = "test", RetweetedBy = "bar" };
            Assert.That(filter.IsHit(post), Is.EqualTo(MyCommon.HITRESULT.None));

            // NameFilter は部分一致ではない
            filter.NameFilter = "hoge";
            post = new PostClass { ScreenName = "hogehoge", Text = "test" };
            Assert.That(filter.IsHit(post), Is.EqualTo(MyCommon.HITRESULT.None));

            // 大小文字を区別しないオプション
            filter.NameFilter = "hoge";
            filter.CaseSensitive = false;
            post = new PostClass { ScreenName = "Hoge", Text = "test" };
            Assert.That(filter.IsHit(post), Is.EqualTo(MyCommon.HITRESULT.CopyAndMark));
        }
예제 #4
0
        public void ExcludeOnlyTest()
        {
            var filter = new PostFilterRule { ExFilterName = "hogehoge" };
            var post = new PostClass { ScreenName = "hogehoge" };

            Assert.Equal(MyCommon.HITRESULT.Exclude, filter.ExecFilter(post));
        }
예제 #5
0
        public void MatchOnlyTest()
        {
            var filter = new PostFilterRule { FilterName = "hogehoge" };
            var post = new PostClass { ScreenName = "hogehoge" };

            Assert.Equal(MyCommon.HITRESULT.CopyAndMark, filter.ExecFilter(post));
        }
예제 #6
0
        public async Task ShowThumbnailAsync(PostClass post, CancellationToken cancelToken)
        {
            var loadTasks = new List<Task>();

            this.scrollBar.Enabled = false;

            if (post.Media.Count == 0 && post.PostGeo.Lat == 0 && post.PostGeo.Lng == 0)
            {
                this.SetThumbnailCount(0);

                if (this.ThumbnailNotFound != null)
                    this.ThumbnailNotFound(this, EventArgs.Empty);
                return;
            }

            var thumbnails = (await this.GetThumbailInfoAsync(post, cancelToken))
                .ToArray();

            cancelToken.ThrowIfCancellationRequested();

            this.SetThumbnailCount(thumbnails.Length);
            if (thumbnails.Length == 0)
            {
                if (this.ThumbnailNotFound != null)
                    this.ThumbnailNotFound(this, EventArgs.Empty);
                return;
            }

            for (int i = 0; i < thumbnails.Length; i++)
            {
                var thumb = thumbnails[i];
                var picbox = this.pictureBox[i];

                picbox.Tag = thumb;

                var loadTask = this.SetThumbnailImageAsync(picbox, thumb, cancelToken);
                loadTasks.Add(loadTask);

                var tooltipText = thumb.TooltipText;
                if (!string.IsNullOrEmpty(tooltipText))
                {
                    this.toolTip.SetToolTip(picbox, tooltipText);
                }

                cancelToken.ThrowIfCancellationRequested();
            }

            if (thumbnails.Length > 1)
                this.scrollBar.Enabled = true;

            if (this.ThumbnailLoading != null)
                this.ThumbnailLoading(this, EventArgs.Empty);

            await Task.WhenAll(loadTasks).ConfigureAwait(false);
        }
예제 #7
0
        public async Task ShowThumbnailAsync(PostClass post, CancellationToken cancelToken)
        {
            var loadTasks = new List<Task>();

            this.scrollBar.Enabled = false;
            this.scrollBar.Visible = false;

            if (post.ExpandedUrls.Length == 0 && post.Media.Count == 0 && post.PostGeo == null)
            {
                this.SetThumbnailCount(0);
                return;
            }

            var thumbnails = (await this.GetThumbailInfoAsync(post, cancelToken))
                .ToArray();

            cancelToken.ThrowIfCancellationRequested();

            this.SetThumbnailCount(thumbnails.Length);
            if (thumbnails.Length == 0)
                return;

            for (int i = 0; i < thumbnails.Length; i++)
            {
                var thumb = thumbnails[i];
                var picbox = this.pictureBox[i];

                picbox.Tag = thumb;
                picbox.ContextMenuStrip = this.contextMenuStrip;

                var loadTask = picbox.SetImageFromTask(() => thumb.LoadThumbnailImageAsync(cancelToken));
                loadTasks.Add(loadTask);

                var tooltipText = thumb.TooltipText;
                if (!string.IsNullOrEmpty(tooltipText))
                {
                    this.toolTip.SetToolTip(picbox, tooltipText);
                    picbox.AccessibleDescription = tooltipText;
                }

                cancelToken.ThrowIfCancellationRequested();
            }

            if (thumbnails.Length > 1)
            {
                this.scrollBar.Enabled = true;
                this.scrollBar.Visible = true;
            }

            this.ThumbnailLoading?.Invoke(this, EventArgs.Empty);

            await Task.WhenAll(loadTasks).ConfigureAwait(false);
        }
        public void CancelAsyncTest()
        {
            using (var thumbbox = new TweetThumbnail())
            {
                var post = new PostClass();

                SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
                var task = thumbbox.ShowThumbnailAsync(post);

                thumbbox.CancelAsync();

                Assert.That(task.IsCanceled, Is.True);
            }
        }
예제 #9
0
        public void CancelAsyncTest()
        {
            using (var thumbbox = new TweetThumbnail())
            {
                var post = new PostClass();

                SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
                var task = thumbbox.ShowThumbnailAsync(post);

                thumbbox.CancelAsync();

                Assert.Throws<AggregateException>(() => task.Wait());
                Assert.True(task.IsCanceled);
            }
        }
예제 #10
0
        public void NullTest()
        {
            var filter = new PostFilterRule
            {
                FilterName = null,
                FilterSource = null,
                ExFilterName = null,
                ExFilterSource = null,
            };
            var post = new PostClass { ScreenName = "hogehoge" };

            Assert.Equal(MyCommon.HITRESULT.None, filter.ExecFilter(post));

            Assert.Throws<ArgumentNullException>(() => filter.FilterBody = null);
            Assert.Throws<ArgumentNullException>(() => filter.ExFilterBody = null);
        }
예제 #11
0
            public override Task<ThumbnailInfo> GetThumbnailInfoAsync(string url, PostClass post, CancellationToken token)
            {
                return Task.Run<ThumbnailInfo>(() =>
                {
                    var match = this.regex.Match(url);

                    if (!match.Success) return null;

                    return new MockThumbnailInfo
                    {
                        ImageUrl = url,
                        ThumbnailUrl = match.Result(this.replaceUrl),
                        TooltipText = this.replaceTooltip != null ? match.Result(this.replaceTooltip) : null,
                    };
                });
            }
예제 #12
0
        public void FormatQuoteTweetHtml_PostClassTest()
        {
            var post = new PostClass
            {
                StatusId = 12345L,
                Nickname = "upsilon",
                ScreenName = "kim_upsilon",
                Text = "<a href=\"https://twitter.com/twitterapi\">@twitterapi</a> hogehoge",
                CreatedAt = new DateTime(2015, 3, 30, 3, 30, 0),
            };

            // PostClass.Text はリンクを除去するのみでエスケープは行わない
            // (TweetFormatter によって既にエスケープされた文字列が格納されているため)

            var expected = "<a class=\"quote-tweet-link\" href=\"//opentween/status/12345\">" +
                "<blockquote class=\"quote-tweet\">" +
                "<p>@twitterapi hogehoge</p> &mdash; upsilon (@kim_upsilon) " + DateTime.Parse("2015/03/30 3:30:00") +
                "</blockquote></a>";
            Assert.Equal(expected, TweetDetailsView.FormatQuoteTweetHtml(post, isReply: false));
        }
예제 #13
0
        public void FieldNullAwareTest()
        {
            var nullPost = new PostClass { Source = null };

            // Source が null であっても ArgumentNullException 等を投げない
            var filter1 = new PostFilterRule
            {
                FilterSource = "(hoge){2}",
                UseRegex = true,
            };
            Assert.Equal(MyCommon.HITRESULT.None, filter1.ExecFilter(nullPost));

            // null は空文字列と同じ扱いにする
            var filter2 = new PostFilterRule
            {
                FilterSource = "^$",
                UseRegex = true,
            };
            Assert.Equal(MyCommon.HITRESULT.CopyAndMark, filter2.ExecFilter(nullPost));
        }
예제 #14
0
        public string GetStatusApi(bool read,
                                   Int64 id,
                                   ref PostClass post)
        {
            if (Twitter.AccountState != MyCommon.ACCOUNT_STATE.Valid) return string.Empty;

            if (MyCommon._endingFlag) return string.Empty;

            HttpStatusCode res = HttpStatusCode.BadRequest;
            var content = string.Empty;

            try
            {
                res = twCon.ShowStatuses(id, ref content);
            }
            catch(Exception ex)
            {
                return "Err:" + ex.Message;
            }
            switch (res)
            {
                case HttpStatusCode.OK:
                    Twitter.AccountState = MyCommon.ACCOUNT_STATE.Valid;
                    break;
                case HttpStatusCode.Unauthorized:
                    Twitter.AccountState = MyCommon.ACCOUNT_STATE.Invalid;
                    return Properties.Resources.Unauthorized;
                case HttpStatusCode.BadRequest:
                    return "Err:API Limits?";
                case HttpStatusCode.Forbidden:
                    return "Err:protected user's tweet";
                default:
                    return "Err:" + res.ToString() + "(" + MethodBase.GetCurrentMethod().Name + ")";
            }

            TwitterDataModel.Status status;
            try
            {
                status = MyCommon.CreateDataFromJson<TwitterDataModel.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!";
            }

            var item = CreatePostsFromStatusData(status);
            if (item == null) return "Err:Can't create post";
            item.IsRead = read;
            if (item.IsMe && !read && _readOwnPost) item.IsRead = true;

            post = item;
            return string.Empty;
        }
예제 #15
0
        public string RemoveDirectMessage(long id, PostClass post)
        {
            if (MyCommon._endingFlag) return string.Empty;

            if (Twitter.AccountState != MyCommon.ACCOUNT_STATE.Valid) return string.Empty;
            if (MyCommon.TwitterApiInfo.AccessLevel != ApiAccessLevel.None)
            {
                if (!MyCommon.TwitterApiInfo.IsDirectMessagePermission) return "Auth Err:try to re-authorization.";
            }

            HttpStatusCode res = HttpStatusCode.BadRequest;

            //if (post.IsMe)
            //    _deletemessages.Add(post)
            //}
            try
            {
                res = twCon.DestroyDirectMessage(id);
            }
            catch(Exception ex)
            {
                return "Err:" + ex.Message;
            }

            switch (res)
            {
            case HttpStatusCode.OK:
                Twitter.AccountState = MyCommon.ACCOUNT_STATE.Valid;
                return string.Empty;
            case HttpStatusCode.Unauthorized:
                Twitter.AccountState = MyCommon.ACCOUNT_STATE.Invalid;
                return Properties.Resources.Unauthorized;
            case HttpStatusCode.NotFound:
                return string.Empty;
            default:
                return "Err:" + res.ToString() + "(" + MethodBase.GetCurrentMethod().Name + ")";
            }
        }
예제 #16
0
        public string GetFavoritesApi(bool read,
                            MyCommon.WORKERTYPE gType,
                            bool more)
        {
            if (Twitter.AccountState != MyCommon.ACCOUNT_STATE.Valid) return string.Empty;

            if (MyCommon._endingFlag) return string.Empty;

            HttpStatusCode res;
            var content = string.Empty;
            var count = AppendSettingDialog.Instance.CountApi;
            if (AppendSettingDialog.Instance.UseAdditionalCount &&
                AppendSettingDialog.Instance.FavoritesCountApi != 0)
            {
                count = AppendSettingDialog.Instance.FavoritesCountApi;
            }

            // 前ページ取得の場合はページカウンタをインクリメント、それ以外の場合はページカウンタリセット
            if (more)
            {
                page_++;
            }
            else
            {
                page_ = 1;
            }

            try
            {
                res = twCon.Favorites(count, page_, ref content);
            }
            catch(Exception ex)
            {
                return "Err:" + ex.Message + "(" + MethodBase.GetCurrentMethod().Name + ")";
            }

            switch (res)
            {
                case HttpStatusCode.OK:
                    Twitter.AccountState = MyCommon.ACCOUNT_STATE.Valid;
                    break;
                case HttpStatusCode.Unauthorized:
                    Twitter.AccountState = MyCommon.ACCOUNT_STATE.Invalid;
                    return Properties.Resources.Unauthorized;
                case HttpStatusCode.BadRequest:
                    return "Err:API Limits?";
                default:
                    return "Err:" + res.ToString() + "(" + MethodBase.GetCurrentMethod().Name + ")";
            }

            var serializer = new DataContractJsonSerializer(typeof(List<TwitterDataModel.Status>));
            List<TwitterDataModel.Status> item;

            try
            {
                item = MyCommon.CreateDataFromJson<List<TwitterDataModel.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 item)
            {
                var post = new PostClass();
                TwitterDataModel.Entities entities;

                try
                {
                    post.StatusId = status.Id;
                    //二重取得回避
                    lock (LockObj)
                    {
                        if (TabInformations.GetInstance().GetTabByType(MyCommon.TabUsageType.Favorites).Contains(post.StatusId)) continue;
                    }
                    //Retweet判定
                    if (status.RetweetedStatus != null)
                    {
                        var retweeted = status.RetweetedStatus;
                        post.CreatedAt = MyCommon.DateTimeParse(retweeted.CreatedAt);

                        //Id
                        post.RetweetedId = post.StatusId;
                        //本文
                        post.TextFromApi = retweeted.Text;
                        entities = retweeted.Entities;
                        //Source取得(htmlの場合は、中身を取り出し)
                        post.Source = retweeted.Source;
                        //Reply先
                        long inReplyToStatusId;
                        long.TryParse(retweeted.InReplyToStatusId, out inReplyToStatusId);
                        post.InReplyToStatusId = inReplyToStatusId;
                        post.InReplyToUser = retweeted.InReplyToScreenName;
                        long inReplyToUserId;
                        long.TryParse(retweeted.InReplyToUserId, out inReplyToUserId);
                        post.InReplyToUserId = inReplyToUserId;
                        post.IsFav = true;

                        //以下、ユーザー情報
                        var user = retweeted.User;
                        post.UserId = user.Id;
                        post.ScreenName = user.ScreenName;
                        post.Nickname = user.Name.Trim();
                        post.ImageUrl = user.ProfileImageUrl;
                        post.IsProtect = user.Protected;

                        //Retweetした人
                        post.RetweetedBy = status.User.ScreenName;
                        post.IsMe = post.RetweetedBy.ToLower().Equals(_uname);
                    }
                    else
                    {
                        post.CreatedAt = MyCommon.DateTimeParse(status.CreatedAt);

                        //本文
                        post.TextFromApi = status.Text;
                        entities = status.Entities;
                        //Source取得(htmlの場合は、中身を取り出し)
                        post.Source = status.Source;
                        long inReplyToStatusId;
                        long.TryParse(status.InReplyToStatusId, out inReplyToStatusId);
                        post.InReplyToStatusId = inReplyToStatusId;
                        post.InReplyToUser = status.InReplyToScreenName;
                        long inReplyToUserId;
                        long.TryParse(status.InReplyToUserId, out inReplyToUserId);
                        post.InReplyToUserId = inReplyToUserId;

                        post.IsFav = true;

                        //以下、ユーザー情報
                        var user = status.User;
                        post.UserId = user.Id;
                        post.ScreenName = user.ScreenName;
                        post.Nickname = user.Name.Trim();
                        post.ImageUrl = user.ProfileImageUrl;
                        post.IsProtect = user.Protected;
                        post.IsMe = post.ScreenName.ToLower().Equals(_uname);
                    }
                    //HTMLに整形
                    string textFromApi = post.TextFromApi;
                    post.Text = CreateHtmlAnchor(ref textFromApi, post.ReplyToList, entities, post.Media);
                    post.TextFromApi = textFromApi;
                    post.TextFromApi = this.ReplaceTextFromApi(post.TextFromApi, entities);
                    post.TextFromApi = HttpUtility.HtmlDecode(post.TextFromApi);
                    post.TextFromApi = post.TextFromApi.Replace("<3", "?");
                    //Source整形
                    CreateSource(ref post);

                    post.IsRead = read;
                    post.IsReply = post.ReplyToList.Contains(_uname);
                    post.IsExcludeReply = false;

                    if (post.IsMe)
                    {
                        post.IsOwl = false;
                    }
                    else
                    {
                        if (followerId.Count > 0) post.IsOwl = !followerId.Contains(post.UserId);
                    }

                    post.IsDm = false;
                }
                catch(Exception ex)
                {
                    MyCommon.TraceOut(ex, MethodBase.GetCurrentMethod().Name + " " + content);
                    continue;
                }

                TabInformations.GetInstance().AddPost(post);

            }

            return string.Empty;
        }
예제 #17
0
        public string GetSearch(bool read,
                            TabClass tab,
                            bool more)
        {
            if (MyCommon._endingFlag) return string.Empty;

            HttpStatusCode res;
            var content = string.Empty;
            var page = 0;
            var sinceId = 0;
            var count = 100;
            if (AppendSettingDialog.Instance.UseAdditionalCount &&
                AppendSettingDialog.Instance.SearchCountApi != 0)
            {
                count = AppendSettingDialog.Instance.SearchCountApi;
            }
            else
            {
                count = AppendSettingDialog.Instance.CountApi;
            }
            if (more)
            {
                page = tab.GetSearchPage(count);
            }
            else
            {
                sinceId = (int)tab.SinceId;
            }

            try
            {
                // TODO:一時的に40>100件に 件数変更UI作成の必要あり
                res = twCon.Search(tab.SearchWords, tab.SearchLang, count, page, 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 "Err:" + res.ToString() + "(" + MethodBase.GetCurrentMethod().Name + ")";
            }

            if (!TabInformations.GetInstance().ContainsTab(tab)) return string.Empty;
            content = Regex.Replace(content, @"[\x00-\x1f-[\x0a\x0d]]+", " ");
            var xdoc = new XmlDocument();
            try
            {
                xdoc.LoadXml(content);
            }
            catch(Exception ex)
            {
                MyCommon.TraceOut(ex, MethodBase.GetCurrentMethod().Name + " " + content);
                return "Invalid ATOM!";
            }
            var nsmgr = new XmlNamespaceManager(xdoc.NameTable);
            nsmgr.AddNamespace("search", "http://www.w3.org/2005/Atom");
            nsmgr.AddNamespace("twitter", "http://api.twitter.com/");
            nsmgr.AddNamespace("georss", "http://www.georss.org/georss");
            foreach (var xentryNode in xdoc.DocumentElement.SelectNodes("/search:feed/search:entry", nsmgr))
            {
                var xentry = (XmlElement)xentryNode;
                var post = new PostClass();
                try
                {
                    post.StatusId = long.Parse(xentry["id"].InnerText.Split(':')[2]);
                    if (TabInformations.GetInstance().ContainsKey(post.StatusId, tab.TabName)) continue;
                    post.CreatedAt = DateTime.Parse(xentry["published"].InnerText);
                    //本文
                    post.TextFromApi = xentry["title"].InnerText;
                    //Source取得(htmlの場合は、中身を取り出し)
                    post.Source = xentry["twitter:source"].InnerText;
                    post.InReplyToStatusId = 0;
                    post.InReplyToUser = string.Empty;
                    post.InReplyToUserId = 0;
                    post.IsFav = false;

                    // Geoが勝手に付加されるバグがいっこうに修正されないので暫定的にGeo情報を無視する
                    if (xentry["twitter:geo"].HasChildNodes)
                    {
                        var pnt = ((XmlElement)xentry.SelectSingleNode("twitter:geo/georss:point", nsmgr)).InnerText.Split(' ');
                        post.PostGeo = new PostClass.StatusGeo {Lat = Double.Parse(pnt[0]), Lng = Double.Parse(pnt[1])};
                    }

                    //以下、ユーザー情報
                    var xUentry = (XmlElement)xentry.SelectSingleNode("./search:author", nsmgr);
                    post.UserId = 0;
                    post.ScreenName = xUentry["name"].InnerText.Split(' ')[0].Trim();
                    post.Nickname = xUentry["name"].InnerText.Substring(post.ScreenName.Length).Trim();
                    if (post.Nickname.Length > 2)
                    {
                        post.Nickname = post.Nickname.Substring(1, post.Nickname.Length - 2);
                    }
                    else
                    {
                        post.Nickname = post.ScreenName;
                    }
                    post.ImageUrl = ((XmlElement)xentry.SelectSingleNode("./search:link[@type='image/png']", nsmgr)).GetAttribute("href");
                    post.IsProtect = false;
                    post.IsMe = post.ScreenName.ToLower().Equals(_uname);

                    //HTMLに整形
                    post.Text = CreateHtmlAnchor(HttpUtility.HtmlEncode(post.TextFromApi), post.ReplyToList, post.Media);
                    post.TextFromApi = HttpUtility.HtmlDecode(post.TextFromApi);
                    //Source整形
                    CreateSource(ref post);

                    post.IsRead = read;
                    post.IsReply = post.ReplyToList.Contains(_uname);
                    post.IsExcludeReply = false;

                    post.IsOwl = false;
                    if (post.IsMe && !read && _readOwnPost) post.IsRead = true;
                    post.IsDm = false;
                    post.RelTabName = tab.TabName;
                    if (!more && post.StatusId > tab.SinceId) tab.SinceId = post.StatusId;
                }
                catch(Exception ex)
                {
                    MyCommon.TraceOut(ex, MethodBase.GetCurrentMethod().Name + " " + content);
                    continue;
                }

                //this._dIcon.Add(post.ImageUrl, null);
                TabInformations.GetInstance().AddPost(post);

            }

            // TODO
            // 遡るための情報max_idやnext_pageの情報を保持する

            #if UNDEFINED__
            var xNode = xdoc.DocumentElement.SelectSingleNode("/search:feed/twitter:warning", nsmgr);

            if (xNode != null)
            {
                return "Warn:" + xNode.InnerText + "(" + MethodBase.GetCurrentMethod().Name + ")";
            }
            #endif

            return string.Empty;
        }
예제 #18
0
        private void NotifyNewPosts(PostClass[] notifyPosts, string soundFile, int addCount, bool newMentions)
        {
            if (notifyPosts != null &&
                notifyPosts.Length > 0 &&
                this.SettingDialog.ReadOwnPost &&
                notifyPosts.All((post) => { return post.UserId == tw.UserId || post.ScreenName == tw.Username; }))
            {
                return;
            }

            //新着通知
            if (BalloonRequired())
            {
                if (notifyPosts != null && notifyPosts.Length > 0)
                {
                    //Growlは一個ずつばらして通知。ただし、3ポスト以上あるときはまとめる
                    if (SettingDialog.IsNotifyUseGrowl)
                    {
                        StringBuilder sb = new StringBuilder();
                        bool reply = false;
                        bool dm = false;

                        foreach (PostClass post in notifyPosts)
                        {
                            if (!(notifyPosts.Length > 3))
                            {
                                sb.Clear();
                                reply = false;
                                dm = false;
                            }
                            if (post.IsReply && !post.IsExcludeReply) reply = true;
                            if (post.IsDm) dm = true;
                            if (sb.Length > 0) sb.Append(System.Environment.NewLine);
                            switch (SettingDialog.NameBalloon)
                            {
                                case MyCommon.NameBalloonEnum.UserID:
                                    sb.Append(post.ScreenName).Append(" : ");
                                    break;
                                case MyCommon.NameBalloonEnum.NickName:
                                    sb.Append(post.Nickname).Append(" : ");
                                    break;
                            }
                            sb.Append(post.TextFromApi);
                            if (notifyPosts.Length > 3)
                            {
                                if (notifyPosts.Last() != post) continue;
                            }

                            StringBuilder title = new StringBuilder();
                            GrowlHelper.NotifyType nt;
                            if (SettingDialog.DispUsername)
                            {
                                title.Append(tw.Username);
                                title.Append(" - ");
                            }
                            else
                            {
                                //title.Clear();
                            }
                            if (dm)
                            {
                                //NotifyIcon1.BalloonTipIcon = ToolTipIcon.Warning;
                                //NotifyIcon1.BalloonTipTitle += Application.ProductName + " [DM] " + Properties.Resources.RefreshDirectMessageText1 + " " + addCount.ToString() + Properties.Resources.RefreshDirectMessageText2;
                                title.Append(Application.ProductName);
                                title.Append(" [DM] ");
                                title.Append(Properties.Resources.RefreshDirectMessageText1);
                                title.Append(" ");
                                title.Append(addCount);
                                title.Append(Properties.Resources.RefreshDirectMessageText2);
                                nt = GrowlHelper.NotifyType.DirectMessage;
                            }
                            else if (reply)
                            {
                                //NotifyIcon1.BalloonTipIcon = ToolTipIcon.Warning;
                                //NotifyIcon1.BalloonTipTitle += Application.ProductName + " [Reply!] " + Properties.Resources.RefreshTimelineText1 + " " + addCount.ToString() + Properties.Resources.RefreshTimelineText2;
                                title.Append(Application.ProductName);
                                title.Append(" [Reply!] ");
                                title.Append(Properties.Resources.RefreshTimelineText1);
                                title.Append(" ");
                                title.Append(addCount);
                                title.Append(Properties.Resources.RefreshTimelineText2);
                                nt = GrowlHelper.NotifyType.Reply;
                            }
                            else
                            {
                                //NotifyIcon1.BalloonTipIcon = ToolTipIcon.Info;
                                //NotifyIcon1.BalloonTipTitle += Application.ProductName + " " + Properties.Resources.RefreshTimelineText1 + " " + addCount.ToString() + Properties.Resources.RefreshTimelineText2;
                                title.Append(Application.ProductName);
                                title.Append(" ");
                                title.Append(Properties.Resources.RefreshTimelineText1);
                                title.Append(" ");
                                title.Append(addCount);
                                title.Append(Properties.Resources.RefreshTimelineText2);
                                nt = GrowlHelper.NotifyType.Notify;
                            }
                            string bText = sb.ToString();
                            if (string.IsNullOrEmpty(bText)) return;

                            gh.Notify(nt, post.StatusId.ToString(), title.ToString(), bText, this.TIconDic[post.ImageUrl], post.ImageUrl);
                        }
                    }
                    else
                    {
                        StringBuilder sb = new StringBuilder();
                        bool reply = false;
                        bool dm = false;
                        foreach (PostClass post in notifyPosts)
                        {
                            if (post.IsReply && !post.IsExcludeReply) reply = true;
                            if (post.IsDm) dm = true;
                            if (sb.Length > 0) sb.Append(System.Environment.NewLine);
                            switch (SettingDialog.NameBalloon)
                            {
                                case MyCommon.NameBalloonEnum.UserID:
                                    sb.Append(post.ScreenName).Append(" : ");
                                    break;
                                case MyCommon.NameBalloonEnum.NickName:
                                    sb.Append(post.Nickname).Append(" : ");
                                    break;
                            }
                            sb.Append(post.TextFromApi);

                        }
                        //if (SettingDialog.DispUsername) { NotifyIcon1.BalloonTipTitle = tw.Username + " - "; } else { NotifyIcon1.BalloonTipTitle = ""; }
                        StringBuilder title = new StringBuilder();
                        ToolTipIcon ntIcon;
                        if (SettingDialog.DispUsername)
                        {
                            title.Append(tw.Username);
                            title.Append(" - ");
                        }
                        else
                        {
                            //title.Clear();
                        }
                        if (dm)
                        {
                            //NotifyIcon1.BalloonTipIcon = ToolTipIcon.Warning;
                            //NotifyIcon1.BalloonTipTitle += Application.ProductName + " [DM] " + Properties.Resources.RefreshDirectMessageText1 + " " + addCount.ToString() + Properties.Resources.RefreshDirectMessageText2;
                            ntIcon = ToolTipIcon.Warning;
                            title.Append(Application.ProductName);
                            title.Append(" [DM] ");
                            title.Append(Properties.Resources.RefreshDirectMessageText1);
                            title.Append(" ");
                            title.Append(addCount);
                            title.Append(Properties.Resources.RefreshDirectMessageText2);
                        }
                        else if (reply)
                        {
                            //NotifyIcon1.BalloonTipIcon = ToolTipIcon.Warning;
                            //NotifyIcon1.BalloonTipTitle += Application.ProductName + " [Reply!] " + Properties.Resources.RefreshTimelineText1 + " " + addCount.ToString() + Properties.Resources.RefreshTimelineText2;
                            ntIcon = ToolTipIcon.Warning;
                            title.Append(Application.ProductName);
                            title.Append(" [Reply!] ");
                            title.Append(Properties.Resources.RefreshTimelineText1);
                            title.Append(" ");
                            title.Append(addCount);
                            title.Append(Properties.Resources.RefreshTimelineText2);
                        }
                        else
                        {
                            //NotifyIcon1.BalloonTipIcon = ToolTipIcon.Info;
                            //NotifyIcon1.BalloonTipTitle += Application.ProductName + " " + Properties.Resources.RefreshTimelineText1 + " " + addCount.ToString() + Properties.Resources.RefreshTimelineText2;
                            ntIcon = ToolTipIcon.Info;
                            title.Append(Application.ProductName);
                            title.Append(" ");
                            title.Append(Properties.Resources.RefreshTimelineText1);
                            title.Append(" ");
                            title.Append(addCount);
                            title.Append(Properties.Resources.RefreshTimelineText2);
                        }
                        string bText = sb.ToString();
                        if (string.IsNullOrEmpty(bText)) return;
                        //NotifyIcon1.BalloonTipText = sb.ToString();
                        //NotifyIcon1.ShowBalloonTip(500);
                        NotifyIcon1.BalloonTipTitle = title.ToString();
                        NotifyIcon1.BalloonTipText = bText;
                        NotifyIcon1.BalloonTipIcon = ntIcon;
                        NotifyIcon1.ShowBalloonTip(500);
                    }
                }
            }

            //サウンド再生
            if (!_initial && SettingDialog.PlaySound && !string.IsNullOrEmpty(soundFile))
            {
                try
                {
                    string dir = Application.StartupPath;
                    if (Directory.Exists(Path.Combine(dir, "Sounds")))
                    {
                        dir = Path.Combine(dir, "Sounds");
                    }
                    using (SoundPlayer player = new SoundPlayer(Path.Combine(dir, soundFile)))
                    {
                        player.Play();
                    }
                }
                catch (Exception)
                {
                }
            }

            //mentions新着時に画面ブリンク
            if (!_initial && SettingDialog.BlinkNewMentions && newMentions && Form.ActiveForm == null)
            {
                Win32Api.FlashMyWindow(this.Handle, Win32Api.FlashSpecification.FlashTray, 3);
            }
        }
예제 #19
0
        private void RemovePostFromFavTab(Int64[] ids)
        {
            string favTabName = _statuses.GetTabByType(MyCommon.TabUsageType.Favorites).TabName;
            int fidx = 0;
            if (_curTab.Text.Equals(favTabName))
            {
                if (_curList.FocusedItem != null)
                    fidx = _curList.FocusedItem.Index;
                else if (_curList.TopItem != null)
                    fidx = _curList.TopItem.Index;
                else
                    fidx = 0;
            }

            foreach (long i in ids)
            {
                try
                {
                    _statuses.RemoveFavPost(i);
                }
                catch (Exception)
                {
                    continue;
                }
            }
            if (_curTab != null && _curTab.Text.Equals(favTabName))
            {
                _itemCache = null;    //キャッシュ破棄
                _postCache = null;
                _curPost = null;
                //_curItemIndex = -1;
            }
            foreach (TabPage tp in ListTab.TabPages)
            {
                if (tp.Text == favTabName)
                {
                    ((DetailsListView)tp.Tag).VirtualListSize = _statuses.Tabs[favTabName].AllCount;
                    break;
                }
            }
            if (_curTab.Text.Equals(favTabName))
            {
                do
                {
                    _curList.SelectedIndices.Clear();
                }
                while (_curList.SelectedIndices.Count > 0);

                if (_statuses.Tabs[favTabName].AllCount > 0)
                {
                    if (_statuses.Tabs[favTabName].AllCount - 1 > fidx && fidx > -1)
                    {
                        _curList.SelectedIndices.Add(fidx);
                    }
                    else
                    {
                        _curList.SelectedIndices.Add(_statuses.Tabs[favTabName].AllCount - 1);
                    }
                    if (_curList.SelectedIndices.Count > 0)
                    {
                        _curList.EnsureVisible(_curList.SelectedIndices[0]);
                        _curList.FocusedItem = _curList.Items[_curList.SelectedIndices[0]];
                    }
                }
            }
        }
예제 #20
0
        private void MyList_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (_curList == null || _curList.SelectedIndices.Count != 1) return;

            _curItemIndex = _curList.SelectedIndices[0];
            if (_curItemIndex > _curList.VirtualListSize - 1) return;

            try
            {
                _curPost = GetCurTabPost(_curItemIndex);
            }
            catch (ArgumentException)
            {
                return;
            }

            this.PushSelectPostChain();

            if (SettingDialog.UnreadManage) _statuses.SetReadAllTab(true, _curTab.Text, _curItemIndex);
            //キャッシュの書き換え
            ChangeCacheStyleRead(true, _curItemIndex, _curTab);   //既読へ(フォント、文字色)

            ColorizeList();
            _colorize = true;
        }
예제 #21
0
        public bool RemoveSpecifiedTab(string TabName, bool confirm)
        {
            int idx = 0;
            for (idx = 0; idx < ListTab.TabPages.Count; idx++)
            {
                if (ListTab.TabPages[idx].Text == TabName) break;
            }

            if (_statuses.IsDefaultTab(TabName)) return false;

            if (confirm)
            {
                string tmp = string.Format(Properties.Resources.RemoveSpecifiedTabText1, Environment.NewLine);
                if (MessageBox.Show(tmp, TabName + " " + Properties.Resources.RemoveSpecifiedTabText2,
                                 MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.Cancel)
                {
                    return false;
                }
            }

            SetListProperty();   //他のタブに列幅等を反映

            MyCommon.TabUsageType tabType = _statuses.Tabs[TabName].TabType;

            //オブジェクトインスタンスの削除
            this.SplitContainer1.Panel1.SuspendLayout();
            this.SplitContainer1.Panel2.SuspendLayout();
            this.SplitContainer1.SuspendLayout();
            this.ListTab.SuspendLayout();
            this.SuspendLayout();

            TabPage _tabPage = ListTab.TabPages[idx];
            DetailsListView _listCustom = (DetailsListView)_tabPage.Tag;
            _tabPage.Tag = null;

            _tabPage.SuspendLayout();

            if (this.ListTab.SelectedTab == this.ListTab.TabPages[idx])
            {
                this.ListTab.SelectTab((this._beforeSelectedTab != null && this.ListTab.TabPages.Contains(this._beforeSelectedTab)) ? this._beforeSelectedTab : this.ListTab.TabPages[0]);
            }
            this.ListTab.Controls.Remove(_tabPage);

            Control pnl = null;
            if (tabType == MyCommon.TabUsageType.PublicSearch)
            {
                pnl = _tabPage.Controls["panelSearch"];
                foreach (Control ctrl in pnl.Controls)
                {
                    if (ctrl.Name == "buttonSearch")
                    {
                        ctrl.Click -= SearchButton_Click;
                    }
                    ctrl.Enter -= SearchControls_Enter;
                    ctrl.Leave -= SearchControls_Leave;
                    pnl.Controls.Remove(ctrl);
                    ctrl.Dispose();
                }
                _tabPage.Controls.Remove(pnl);
            }

            _tabPage.Controls.Remove(_listCustom);
            _listCustom.Columns.Clear();
            _listCustom.ContextMenuStrip = null;

            _listCustom.SelectedIndexChanged -= MyList_SelectedIndexChanged;
            _listCustom.MouseDoubleClick -= MyList_MouseDoubleClick;
            _listCustom.ColumnClick -= MyList_ColumnClick;
            _listCustom.DrawColumnHeader -= MyList_DrawColumnHeader;
            _listCustom.DragDrop -= TweenMain_DragDrop;
            _listCustom.DragOver -= TweenMain_DragOver;
            _listCustom.DrawItem -= MyList_DrawItem;
            _listCustom.MouseClick -= MyList_MouseClick;
            _listCustom.ColumnReordered -= MyList_ColumnReordered;
            _listCustom.ColumnWidthChanged -= MyList_ColumnWidthChanged;
            _listCustom.CacheVirtualItems -= MyList_CacheVirtualItems;
            _listCustom.RetrieveVirtualItem -= MyList_RetrieveVirtualItem;
            _listCustom.DrawSubItem -= MyList_DrawSubItem;
            _listCustom.HScrolled -= MyList_HScrolled;

            TabDialog.RemoveTab(TabName);

            _listCustom.SmallImageList = null;
            _listCustom.ListViewItemSorter = null;

            //キャッシュのクリア
            if (_curTab.Equals(_tabPage))
            {
                _curTab = null;
                _curItemIndex = -1;
                _curList = null;
                _curPost = null;
            }
            _itemCache = null;
            _itemCacheIndex = -1;
            _postCache = null;

            _tabPage.ResumeLayout(false);

            this.SplitContainer1.Panel1.ResumeLayout(false);
            this.SplitContainer1.Panel2.ResumeLayout(false);
            this.SplitContainer1.ResumeLayout(false);
            this.ListTab.ResumeLayout(false);
            this.ResumeLayout(false);
            this.PerformLayout();

            _tabPage.Dispose();
            _listCustom.Dispose();
            _statuses.RemoveTab(TabName);

            foreach (TabPage tp in ListTab.TabPages)
            {
                DetailsListView lst = (DetailsListView)tp.Tag;
                if (lst.VirtualListSize != _statuses.Tabs[tp.Text].AllCount)
                {
                    lst.VirtualListSize = _statuses.Tabs[tp.Text].AllCount;
                }
            }

            return true;
        }
예제 #22
0
        private string CreateDirectMessagesFromJson(string content, MyCommon.WORKERTYPE gType, bool read)
        {
            List<TwitterDataModel.Directmessage> item;
            try
            {
                if (gType == MyCommon.WORKERTYPE.UserStream)
                {
                    var itm = MyCommon.CreateDataFromJson<List<TwitterDataModel.DirectmessageEvent>>(content);
                    item = new List<TwitterDataModel.Directmessage>();
                    foreach (var dat in itm)
                    {
                        item.Add(dat.Directmessage);
                    }
                }
                else
                {
                    item = MyCommon.CreateDataFromJson<List<TwitterDataModel.Directmessage>>(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 message in item)
            {
                var post = new PostClass();
                try
                {
                    post.StatusId = message.Id;
                    if (gType != MyCommon.WORKERTYPE.UserStream)
                    {
                        if (gType == MyCommon.WORKERTYPE.DirectMessegeRcv)
                        {
                            if (minDirectmessage > post.StatusId) minDirectmessage = post.StatusId;
                        }
                        else
                        {
                            if (minDirectmessageSent > post.StatusId) minDirectmessageSent = post.StatusId;
                        }
                    }

                    //二重取得回避
                    lock (LockObj)
                    {
                        if (TabInformations.GetInstance().GetTabByType(MyCommon.TabUsageType.DirectMessage).Contains(post.StatusId)) continue;
                    }
                    //sender_id
                    //recipient_id
                    post.CreatedAt = MyCommon.DateTimeParse(message.CreatedAt);
                    //本文
                    post.TextFromApi = message.Text;
                    //HTMLに整形
                    post.Text = CreateHtmlAnchor(post.TextFromApi, post.ReplyToList, post.Media);
                    post.TextFromApi = HttpUtility.HtmlDecode(post.TextFromApi);
                    post.TextFromApi = post.TextFromApi.Replace("<3", "?");
                    post.IsFav = false;

                    //以下、ユーザー情報
                    TwitterDataModel.User user;
                    if (gType == MyCommon.WORKERTYPE.UserStream)
                    {
                        if (twCon.AuthenticatedUsername.Equals(message.Recipient.ScreenName, StringComparison.CurrentCultureIgnoreCase))
                        {
                            user = message.Sender;
                            post.IsMe = false;
                            post.IsOwl = true;
                        }
                        else
                        {
                            user = message.Recipient;
                            post.IsMe = true;
                            post.IsOwl = false;
                        }
                    }
                    else
                    {
                        if (gType == MyCommon.WORKERTYPE.DirectMessegeRcv)
                        {
                            user = message.Sender;
                            post.IsMe = false;
                            post.IsOwl = true;
                        }
                        else
                        {
                            user = message.Recipient;
                            post.IsMe = true;
                            post.IsOwl = false;
                        }
                    }

                    post.UserId = user.Id;
                    post.ScreenName = user.ScreenName;
                    post.Nickname = user.Name.Trim();
                    post.ImageUrl = user.ProfileImageUrl;
                    post.IsProtect = user.Protected;
                }
                catch(Exception ex)
                {
                    MyCommon.TraceOut(ex, MethodBase.GetCurrentMethod().Name + " " + content);
                    MessageBox.Show("Parse Error(CreateDirectMessagesFromJson)");
                    continue;
                }

                post.IsRead = read;
                if (post.IsMe && !read && _readOwnPost) post.IsRead = true;
                post.IsReply = false;
                post.IsExcludeReply = false;
                post.IsDm = true;

                TabInformations.GetInstance().AddPost(post);
            }

            return string.Empty;
        }
예제 #23
0
 protected virtual Task<IEnumerable<ThumbnailInfo>> GetThumbailInfoAsync(PostClass post, CancellationToken token)
 {
     return ThumbnailGenerator.GetThumbnailsAsync(post, token);
 }
예제 #24
0
 //Source整形
 private void CreateSource(ref PostClass post)
 {
     if (post.Source.StartsWith("<"))
     {
         if (!post.Source.Contains("</a>"))
         {
             post.Source += "</a>";
         }
         var mS = Regex.Match(post.Source, ">(?<source>.+)<");
         if (mS.Success)
         {
             post.SourceHtml = string.Copy(ShortUrl.Resolve(PreProcessUrl(post.Source), false));
             post.Source = HttpUtility.HtmlDecode(mS.Result("${source}"));
         }
         else
         {
             post.Source = string.Empty;
             post.SourceHtml = string.Empty;
         }
     }
     else
     {
         if (post.Source == "web")
         {
             post.SourceHtml = Properties.Resources.WebSourceString;
         }
         else if (post.Source == "Keitai Mail")
         {
             post.SourceHtml = Properties.Resources.KeitaiMailSourceString;
         }
         else
         {
             post.SourceHtml = string.Copy(post.Source);
         }
     }
 }
예제 #25
0
        private PostClass CreatePostsFromStatusData(TwitterDataModel.Status status)
        {
            var post = new PostClass();
            TwitterDataModel.Entities entities;

            post.StatusId = status.Id;
            if (status.RetweetedStatus != null)
            {
                var retweeted = status.RetweetedStatus;

                post.CreatedAt = MyCommon.DateTimeParse(retweeted.CreatedAt);

                //Id
                post.RetweetedId = retweeted.Id;
                //本文
                post.TextFromApi = retweeted.Text;
                entities = retweeted.Entities;
                //Source取得(htmlの場合は、中身を取り出し)
                post.Source = retweeted.Source;
                //Reply先
                long inReplyToStatusId;
                long.TryParse(retweeted.InReplyToStatusId, out inReplyToStatusId);
                post.InReplyToStatusId = inReplyToStatusId;
                post.InReplyToUser = retweeted.InReplyToScreenName;
                long inReplyToUserId;
                long.TryParse(status.InReplyToUserId, out inReplyToUserId);
                post.InReplyToUserId = inReplyToUserId;

                //幻覚fav対策
                var tc = TabInformations.GetInstance().GetTabByType(MyCommon.TabUsageType.Favorites);
                post.IsFav = tc.Contains(post.RetweetedId);

                if (retweeted.Geo != null) post.PostGeo = new PostClass.StatusGeo {Lat = retweeted.Geo.Coordinates[0], Lng = retweeted.Geo.Coordinates[1]};

                //以下、ユーザー情報
                var user = retweeted.User;

                if (user.ScreenName == null || status.User.ScreenName == null) return null;

                post.UserId = user.Id;
                post.ScreenName = user.ScreenName;
                post.Nickname = user.Name.Trim();
                post.ImageUrl = user.ProfileImageUrl;
                post.IsProtect = user.Protected;

                //Retweetした人
                post.RetweetedBy = status.User.ScreenName;
                post.RetweetedByUserId = status.User.Id;
                post.IsMe = post.RetweetedBy.ToLower().Equals(_uname);
            }
            else
            {
                post.CreatedAt = MyCommon.DateTimeParse(status.CreatedAt);
                //本文
                post.TextFromApi = status.Text;
                entities = status.Entities;
                //Source取得(htmlの場合は、中身を取り出し)
                post.Source = status.Source;
                long inReplyToStatusId;
                long.TryParse(status.InReplyToStatusId, out inReplyToStatusId);
                post.InReplyToStatusId = inReplyToStatusId;
                post.InReplyToUser = status.InReplyToScreenName;
                long inReplyToUserId;
                long.TryParse(status.InReplyToUserId, out inReplyToUserId);
                post.InReplyToUserId = inReplyToUserId;

                if (status.Geo != null) post.PostGeo = new PostClass.StatusGeo {Lat = status.Geo.Coordinates[0], Lng = status.Geo.Coordinates[1]};

                //以下、ユーザー情報
                var user = status.User;

                if (user.ScreenName == null) return null;

                post.UserId = user.Id;
                post.ScreenName = user.ScreenName;
                post.Nickname = user.Name.Trim();
                post.ImageUrl = user.ProfileImageUrl;
                post.IsProtect = user.Protected;
                post.IsMe = post.ScreenName.ToLower().Equals(_uname);

                //幻覚fav対策
                var tc = TabInformations.GetInstance().GetTabByType(MyCommon.TabUsageType.Favorites);
                post.IsFav = tc.Contains(post.StatusId) && TabInformations.GetInstance()[post.StatusId].IsFav;
            }
            //HTMLに整形
            string textFromApi = post.TextFromApi;
            post.Text = CreateHtmlAnchor(ref textFromApi, post.ReplyToList, entities, post.Media);
            post.TextFromApi = textFromApi;
            post.TextFromApi = this.ReplaceTextFromApi(post.TextFromApi, entities);
            post.TextFromApi = HttpUtility.HtmlDecode(post.TextFromApi);
            post.TextFromApi = post.TextFromApi.Replace("<3", "?");

            //Source整形
            CreateSource(ref post);

            post.IsReply = post.ReplyToList.Contains(_uname);
            post.IsExcludeReply = false;

            if (post.IsMe)
            {
                post.IsOwl = false;
            }
            else
            {
                if (followerId.Count > 0) post.IsOwl = !followerId.Contains(post.UserId);
            }

            post.IsDm = false;
            return post;
        }
예제 #26
0
        private void IDRuleMenuItem_Click(object sender, EventArgs e)
        {
            string tabName = "";

            //未選択なら処理終了
            if (_curList.SelectedIndices.Count == 0) return;

            //タブ選択(or追加)
            if (!SelectTab(ref tabName)) return;

            bool mv = false;
            bool mk = false;
            MoveOrCopy(ref mv, ref mk);

            List<string> ids = new List<string>();
            foreach (int idx in _curList.SelectedIndices)
            {
                PostClass post = _statuses[_curTab.Text, idx];
                if (!ids.Contains(post.ScreenName))
                {
                    FiltersClass fc = new FiltersClass();
                    ids.Add(post.ScreenName);
                    if (post.RetweetedId == 0)
                    {
                        fc.NameFilter = post.ScreenName;
                    }
                    else
                    {
                        fc.NameFilter = post.RetweetedBy;
                    }
                    fc.SearchBoth = true;
                    fc.MoveFrom = mv;
                    fc.SetMark = mk;
                    fc.UseRegex = false;
                    fc.SearchUrl = false;
                    _statuses.Tabs[tabName].AddFilter(fc);
                }
            }
            if (ids.Count != 0)
            {
                List<string> atids = new List<string>();
                foreach (string id in ids)
                {
                    atids.Add("@" + id);
                }
                int cnt = AtIdSupl.ItemCount;
                AtIdSupl.AddRangeItem(atids.ToArray());
                if (AtIdSupl.ItemCount != cnt) _modifySettingAtId = true;
            }

            try
            {
                this.Cursor = Cursors.WaitCursor;
                _itemCache = null;
                _postCache = null;
                _curPost = null;
                _curItemIndex = -1;
                _statuses.FilterAll();
                foreach (TabPage tb in ListTab.TabPages)
                {
                    ((DetailsListView)tb.Tag).VirtualListSize = _statuses.Tabs[tb.Text].AllCount;
                    if (_statuses.ContainsTab(tb.Text))
                    {
                        if (_statuses.Tabs[tb.Text].UnreadCount > 0)
                        {
                            if (SettingDialog.TabIconDisp)
                                tb.ImageIndex = 0;
                        }
                        else
                        {
                            if (SettingDialog.TabIconDisp)
                                tb.ImageIndex = -1;
                        }
                    }
                }
                if (!SettingDialog.TabIconDisp) ListTab.Refresh();
            }
            finally
            {
                this.Cursor = Cursors.Default;
            }
            SaveConfigsTabs();
        }
예제 #27
0
        private string GetRelatedResultsApi(bool read,
                                             PostClass post,
                                             TabClass tab,
                                             List<PostClass> relatedPosts)
        {
            if (Twitter.AccountState != MyCommon.ACCOUNT_STATE.Valid) return string.Empty;

            if (MyCommon._endingFlag) return string.Empty;

            HttpStatusCode res = HttpStatusCode.BadRequest;
            var content = string.Empty;
            try
            {
                if (post.RetweetedId > 0)
                {
                    res = twCon.GetRelatedResults(post.RetweetedId, ref content);
                }
                else
                {
                    res = twCon.GetRelatedResults(post.StatusId, ref content);
                }
            }
            catch(Exception ex)
            {
                return "Err:" + ex.Message;
            }
            switch (res)
            {
                case HttpStatusCode.OK:
                    Twitter.AccountState = MyCommon.ACCOUNT_STATE.Valid;
                    break;
                case HttpStatusCode.Unauthorized:
                    Twitter.AccountState = MyCommon.ACCOUNT_STATE.Invalid;
                    return Properties.Resources.Unauthorized;
                case HttpStatusCode.BadRequest:
                    return "Err:API Limits?";
                default:
                    return "Err:" + res.ToString() + "(" + MethodBase.GetCurrentMethod().Name + ")";
            }

            List<TwitterDataModel.RelatedResult> items;
            try
            {
                items = MyCommon.CreateDataFromJson<List<TwitterDataModel.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!";
            }

            var targetItem = post;
            if (targetItem == null)
            {
                return string.Empty;
            }
            else
            {
                targetItem = targetItem.Copy();
            }
            targetItem.RelTabName = tab.TabName;
            TabInformations.GetInstance().AddPost(targetItem);

            PostClass replyToItem = null;
            var replyToUserName = targetItem.InReplyToUser;
            if (targetItem.InReplyToStatusId > 0 && TabInformations.GetInstance()[targetItem.InReplyToStatusId] != null)
            {
                replyToItem = TabInformations.GetInstance()[targetItem.InReplyToStatusId].Copy();
                replyToItem.IsRead = read;
                if (replyToItem.IsMe && !read && _readOwnPost) replyToItem.IsRead = true;
                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;
                    if (item.IsMe && !read && _readOwnPost) item.IsRead = true;
                    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 = string.Empty;
                rslt = GetStatusApi(read, targetItem.InReplyToStatusId, ref p);
                if (string.IsNullOrEmpty(rslt))
                {
                    p.IsRead = read;
                    p.RelTabName = tab.TabName;
                    relatedPosts.Add(p);
                }
                return rslt;
            }

            //発言者・返信先ユーザーの直近10発言取得
            //var rslt = this.GetUserTimelineApi(read, 10, string.Empty, tab);
            //if (!string.IsNullOrEmpty(rslt)) return rslt;
            //if (!string.IsNullOrEmpty(replyToUserName))
            //    rslt = this.GetUserTimelineApi(read, 10, replyToUserName, tab);
            //}
            //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 _match in ma)
            {
                Int64 _statusId;
                if (Int64.TryParse(_match.Groups["StatusId"].Value, out _statusId))
                {
                    PostClass p = null;
                    var _post = TabInformations.GetInstance()[_statusId];
                    if (_post == null)
                    {
                        var result = this.GetStatusApi(read, _statusId, ref p);
                    }
                    else
                    {
                        p = _post.Copy();
                    }
                    if (p != null)
                    {
                        p.IsRead = read;
                        p.RelTabName = tab.TabName;
                        relatedPosts.Add(p);
                    }
                }
            }
            return string.Empty;
        }
예제 #28
0
        private Color JudgeColor(PostClass BasePost, PostClass TargetPost)
        {
            Color cl;
            if (TargetPost.StatusId == BasePost.InReplyToStatusId)
                //@先
                cl = _clAtTo;
            else if (TargetPost.IsMe)
                //自分=発言者
                cl = _clSelf;
            else if (TargetPost.IsReply)
                //自分宛返信
                cl = _clAtSelf;
            else if (BasePost.ReplyToList.Contains(TargetPost.ScreenName.ToLower()))
                //返信先
                cl = _clAtFromTarget;
            else if (TargetPost.ReplyToList.Contains(BasePost.ScreenName.ToLower()))
                //その人への返信
                cl = _clAtTarget;
            else if (TargetPost.ScreenName.Equals(BasePost.ScreenName, StringComparison.OrdinalIgnoreCase))
                //発言者
                cl = _clTarget;
            else
                //その他
                cl = _clListBackcolor;

            return cl;
        }
예제 #29
0
 public Task ShowThumbnailAsync(PostClass post)
 {
     return this.ShowThumbnailAsync(post, CancellationToken.None);
 }
예제 #30
0
        private void ListTabSelect(TabPage _tab)
        {
            SetListProperty();

            _itemCache = null;
            _itemCacheIndex = -1;
            _postCache = null;

            _curTab = _tab;
            _curList = (DetailsListView)_tab.Tag;
            if (_curList.SelectedIndices.Count > 0)
            {
                _curItemIndex = _curList.SelectedIndices[0];
                _curPost = GetCurTabPost(_curItemIndex);
            }
            else
            {
                _curItemIndex = -1;
                _curPost = null;
            }

            _anchorPost = null;
            _anchorFlag = false;

            if (_iconCol)
            {
                ((DetailsListView)_tab.Tag).Columns[1].Text = ColumnText[2];
            }
            else
            {
                for (int i = 0; i < _curList.Columns.Count; i++)
                {
                    ((DetailsListView)_tab.Tag).Columns[i].Text = ColumnText[i];
                }
            }
        }