// フィルタに合致したら追加 public HITRESULT AddFiltered(PostClass post) { if (IsInnerStorageTabType) { return(HITRESULT.None); } var rslt = HITRESULT.None; // 全フィルタ評価(優先順位あり) lock (_lockObj) { foreach (FiltersClass ft in _filters) { try { switch (ft.IsHit(post)) { // フィルタクラスでヒット判定 case HITRESULT.None: break; case HITRESULT.Copy: if (rslt != HITRESULT.CopyAndMark) { rslt = HITRESULT.Copy; } break; case HITRESULT.CopyAndMark: rslt = HITRESULT.CopyAndMark; break; case HITRESULT.Move: rslt = HITRESULT.Move; break; case HITRESULT.Exclude: rslt = HITRESULT.Exclude; break; } } catch (NullReferenceException) { // IsHitでNullRef出る場合あり。暫定対応 MyCommon.TraceOut("IsHitでNullRef: " + ft); rslt = HITRESULT.None; } } } if (rslt != HITRESULT.None && rslt != HITRESULT.Exclude) { _tmpIds.Add(new TemporaryId(post.StatusId, post.IsRead)); } // マーク付けは呼び出し元で行うこと return(rslt); }
// 検索結果の追加 public void AddPostToInnerStorage(PostClass post) { if (Posts.ContainsKey(post.StatusId)) { return; } Posts.Add(post.StatusId, post); _tmpIds.Add(new TemporaryId(post.StatusId, post.IsRead)); }
public bool ExecuteExLambdaExpression(string expr, PostClass post) { if (_exlambdaExp == null || _exlambdaExpDelegate == null) { _exlambdaExp = DynamicExpression.ParseLambda <PostClass, bool>(expr, post); _exlambdaExpDelegate = _exlambdaExp.Compile(); } return((bool)_exlambdaExpDelegate.DynamicInvoke(post)); }
public bool Equals(PostClass other) { if (other == null) { return(false); } return(Nickname == other.Nickname && TextFromApi == other.TextFromApi && ImageUrl == other.ImageUrl && ScreenName == other.ScreenName && CreatedAt == other.CreatedAt && StatusId == other.StatusId && IsFav == other.IsFav && Text == other.Text && IsRead == other.IsRead && IsReply == other.IsReply && IsExcludeReply == other.IsExcludeReply && IsProtect == other.IsProtect && IsOwl == other.IsOwl && IsMark == other.IsMark && InReplyToUser == other.InReplyToUser && InReplyToStatusId == other.InReplyToStatusId && Source == other.Source && SourceHtml == other.SourceHtml && ReplyToList.Equals(other.ReplyToList) && IsMe == other.IsMe && IsDm == other.IsDm && UserId == other.UserId && FilterHit == other.FilterHit && RetweetedBy == other.RetweetedBy && RetweetedId == other.RetweetedId && RelTabName == other.RelTabName && IsDeleted == other.IsDeleted && InReplyToUserId == other.InReplyToUserId); }
public bool Equals(PostClass other) { if (other == null) { return false; } return Nickname == other.Nickname && TextFromApi == other.TextFromApi && ImageUrl == other.ImageUrl && ScreenName == other.ScreenName && CreatedAt == other.CreatedAt && StatusId == other.StatusId && IsFav == other.IsFav && Text == other.Text && IsRead == other.IsRead && IsReply == other.IsReply && IsExcludeReply == other.IsExcludeReply && IsProtect == other.IsProtect && IsOwl == other.IsOwl && IsMark == other.IsMark && InReplyToUser == other.InReplyToUser && InReplyToStatusId == other.InReplyToStatusId && Source == other.Source && SourceHtml == other.SourceHtml && ReplyToList.Equals(other.ReplyToList) && IsMe == other.IsMe && IsDm == other.IsDm && UserId == other.UserId && FilterHit == other.FilterHit && RetweetedBy == other.RetweetedBy && RetweetedId == other.RetweetedId && RelTabName == other.RelTabName && IsDeleted == other.IsDeleted && InReplyToUserId == other.InReplyToUserId; }
/// <summary> /// Source整形 /// </summary> /// <param name="post"></param> private void CreateSource(ref PostClass post) { if (post.Source.StartsWith("<")) { if (!post.Source.Contains("</a>")) { post.Source += "</a>"; } Match 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 = R.WebSourceString; } else if (post.Source == "Keitai Mail") { post.SourceHtml = R.KeitaiMailSourceString; } else { post.SourceHtml = string.Copy(post.Source); } } }
private string CreateDirectMessagesFromJson(string content, WorkerType workerType, bool read) { List<Directmessage> item; try { item = workerType == WorkerType.UserStream ? D.CreateDataFromJson<List<DirectmessageEvent>>(content).Select(dat => dat.Directmessage).ToList() : D.CreateDataFromJson<List<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 (workerType != WorkerType.UserStream) { if (workerType == WorkerType.DirectMessegeRcv) { if (_minDirectmessage > post.StatusId) { _minDirectmessage = post.StatusId; } } else { if (_minDirectmessageSent > post.StatusId) { _minDirectmessageSent = post.StatusId; } } } // 二重取得回避 lock (_lockObj) { if (TabInformations.Instance.GetTabByType(TabUsageType.DirectMessage).Contains(post.StatusId)) { continue; } } 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; // 以下、ユーザー情報 User user; if (workerType == WorkerType.UserStream) { if (_twitterConnection.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 (workerType == 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 || post.IsMe && !read && ReadOwnPost; post.IsReply = false; post.IsExcludeReply = false; post.IsDm = true; TabInformations.Instance.AddPost(post); } return string.Empty; }
public string GetStatusApi(bool read, long id, ref PostClass post) { if (AccountState != AccountState.Valid) { return string.Empty; } if (MyCommon.IsEnding) { return string.Empty; } HttpStatusCode res; string content = string.Empty; try { res = _twitterConnection.ShowStatuses(id, 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?"; case HttpStatusCode.Forbidden: return "Err:Protected user's tweet"; default: return string.Format("Err:{0}({1})", res, MethodBase.GetCurrentMethod().Name); } Status status; try { status = D.CreateDataFromJson<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!"; } PostClass item = CreatePostsFromStatusData(status); if (item == null) { return "Err:Can't create post"; } item.IsRead = read || (item.IsMe && ReadOwnPost); post = item; return string.Empty; }
public bool RemoveSpecifiedTab(string tabName, bool confirm) { int idx; 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(R.RemoveSpecifiedTabText1, Environment.NewLine); var result = MessageBox.Show(tmp, string.Format("{0} {1}", tabName, R.RemoveSpecifiedTabText2), MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2); if (result == DialogResult.Cancel) { return(false); } } SetListProperty(); // 他のタブに列幅等を反映 TabUsageType tabType = _statuses.Tabs[tabName].TabType; // オブジェクトインスタンスの削除 SplitContainer1.Panel1.SuspendLayout(); SplitContainer1.Panel2.SuspendLayout(); SplitContainer1.SuspendLayout(); ListTab.SuspendLayout(); SuspendLayout(); TabPage tabPage = ListTab.TabPages[idx]; var listCustom = (DetailsListView)tabPage.Tag; tabPage.Tag = null; tabPage.SuspendLayout(); if (ReferenceEquals(ListTab.SelectedTab, ListTab.TabPages[idx])) { ListTab.SelectTab(_prevSelectedTab != null && ListTab.TabPages.Contains(_prevSelectedTab) ? _prevSelectedTab : ListTab.TabPages[0]); } ListTab.Controls.Remove(tabPage); if (tabType == TabUsageType.PublicSearch) { Control 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); SplitContainer1.Panel1.ResumeLayout(false); SplitContainer1.Panel2.ResumeLayout(false); SplitContainer1.ResumeLayout(false); ListTab.ResumeLayout(false); ResumeLayout(false); PerformLayout(); tabPage.Dispose(); listCustom.Dispose(); _statuses.RemoveTab(tabName); foreach (TabPage tp in ListTab.TabPages) { var lst = (DetailsListView)tp.Tag; lst.VirtualListSize = _statuses.Tabs[tp.Text].AllCount; } return(true); }
public bool RemoveSpecifiedTab(string tabName, bool confirm) { int idx; 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(R.RemoveSpecifiedTabText1, Environment.NewLine); var result = MessageBox.Show(tmp, string.Format("{0} {1}", tabName, R.RemoveSpecifiedTabText2), MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2); if (result == DialogResult.Cancel) { return false; } } SetListProperty(); // 他のタブに列幅等を反映 TabUsageType tabType = _statuses.Tabs[tabName].TabType; // オブジェクトインスタンスの削除 SplitContainer1.Panel1.SuspendLayout(); SplitContainer1.Panel2.SuspendLayout(); SplitContainer1.SuspendLayout(); ListTab.SuspendLayout(); SuspendLayout(); TabPage tabPage = ListTab.TabPages[idx]; var listCustom = (DetailsListView)tabPage.Tag; tabPage.Tag = null; tabPage.SuspendLayout(); if (ReferenceEquals(ListTab.SelectedTab, ListTab.TabPages[idx])) { ListTab.SelectTab(_prevSelectedTab != null && ListTab.TabPages.Contains(_prevSelectedTab) ? _prevSelectedTab : ListTab.TabPages[0]); } ListTab.Controls.Remove(tabPage); if (tabType == TabUsageType.PublicSearch) { Control 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); SplitContainer1.Panel1.ResumeLayout(false); SplitContainer1.Panel2.ResumeLayout(false); SplitContainer1.ResumeLayout(false); ListTab.ResumeLayout(false); ResumeLayout(false); PerformLayout(); tabPage.Dispose(); listCustom.Dispose(); _statuses.RemoveTab(tabName); foreach (TabPage tp in ListTab.TabPages) { var lst = (DetailsListView)tp.Tag; lst.VirtualListSize = _statuses.Tabs[tp.Text].AllCount; } return true; }
public PostClass[] Item(string tabName, int startIndex, int endIndex) { var length = endIndex - startIndex + 1; var posts = new PostClass[length]; var tab = Tabs[tabName]; var postss = tab.IsInnerStorageTabType ? tab.Posts : _statuses; for (var i = 0; i < length; ++i) { posts[i] = postss[tab.GetId(startIndex + i)]; } return posts; }
public void AddPost(PostClass item) { lock (_lockObj) { // 公式検索、リスト、関連発言の場合 if (!string.IsNullOrEmpty(item.RelTabName)) { if (!Tabs.ContainsKey(item.RelTabName)) { return; } TabClass tb = Tabs[item.RelTabName]; if (tb == null) { return; } if (tb.Contains(item.StatusId)) { return; } tb.AddPostToInnerStorage(item); return; } if (item.IsDm) { // DM TabClass tb = GetTabByType(TabUsageType.DirectMessage); if (tb.Contains(item.StatusId)) { return; } tb.AddPostToInnerStorage(item); return; } if (_statuses.ContainsKey(item.StatusId)) { if (item.IsFav) { if (item.IsRetweeted) { item.IsFav = false; } else { _statuses[item.StatusId].IsFav = true; } } else { return; // 追加済みなら何もしない } } else { if (item.IsFav && item.IsRetweeted) { item.IsFav = false; } // 既に持っている公式RTは捨てる if (Configs.Instance.HideDuplicatedRetweets && !item.IsMe && _retweets.ContainsKey(item.RetweetedId) && _retweets[item.RetweetedId].RetweetedCount > 0) { return; } if (BlockIds.Contains(item.UserId)) { return; } _statuses.Add(item.StatusId, item); } if (item.IsRetweeted) { AddRetweet(item); } if (item.IsFav && _retweets.ContainsKey(item.StatusId)) { // Fav済みのRetweet元発言は追加しない return; } if (_addedIds == null) { _addedIds = new List<long>(); } // タブ追加用IDコレクション準備 _addedIds.Add(item.StatusId); } }
private void AddRetweet(PostClass item) { // True:追加、False:保持済み long retweetedId = item.RetweetedId; if (_retweets.ContainsKey(retweetedId)) { _retweets[retweetedId].RetweetedCount += 1; if (_retweets[retweetedId].RetweetedCount > 10) { _retweets[retweetedId].RetweetedCount = 0; } return; } var retweetPost = new PostClass { Nickname = item.Nickname, TextFromApi = item.TextFromApi, Text = item.Text, ImageUrl = item.ImageUrl, ScreenName = item.ScreenName, CreatedAt = item.CreatedAt, StatusId = retweetedId, IsFav = item.IsFav, IsRead = item.IsRead, IsReply = item.IsReply, IsExcludeReply = item.IsExcludeReply, IsProtect = item.IsProtect, IsOwl = item.IsOwl, IsMark = item.IsMark, InReplyToUser = item.InReplyToUser, InReplyToStatusId = item.InReplyToStatusId, Source = item.Source, SourceHtml = item.SourceHtml, ReplyToList = item.ReplyToList, IsMe = item.IsMe, IsDm = item.IsDm, UserId = item.UserId, FilterHit = item.FilterHit, RetweetedBy = string.Empty, RetweetedId = 0, PostGeo = item.PostGeo }; _retweets.Add(retweetedId, retweetPost); _retweets[retweetedId].RetweetedCount += 1; }
public int SubmitUpdate(ref string soundFile, ref PostClass[] notifyPosts, ref bool isMentionIncluded, ref bool isDeletePost, bool isUserStream) { // 注:メインスレッドから呼ぶこと lock (_lockObj) { if (_notifyPosts == null) { soundFile = string.Empty; notifyPosts = null; return 0; } foreach (TabClass tb in Tabs.Values) { if (tb.IsInnerStorageTabType) { _addCount += tb.GetTemporaryCount(); } tb.AddSubmit(ref isMentionIncluded); // 振分確定(各タブに反映) } if (!isUserStream || SortMode != IdComparerClass.ComparerMode.Id) { SortPosts(); } if (isUserStream) { isDeletePost = _deletedIds.Count > 0; foreach (long id in _deletedIds) { RemovePost(id); } _deletedIds.Clear(); } soundFile = _soundFile; _soundFile = string.Empty; notifyPosts = _notifyPosts.ToArray(); _notifyPosts.Clear(); _notifyPosts = null; int retCnt = _addCount; _addCount = 0; return retCnt; // 件数(EndUpdateの戻り値と同じ) } }
// フィルタに合致したら追加 public HITRESULT AddFiltered(PostClass post) { if (IsInnerStorageTabType) { return HITRESULT.None; } var rslt = HITRESULT.None; // 全フィルタ評価(優先順位あり) lock (_lockObj) { foreach (FiltersClass ft in _filters) { try { switch (ft.IsHit(post)) { // フィルタクラスでヒット判定 case HITRESULT.None: break; case HITRESULT.Copy: if (rslt != HITRESULT.CopyAndMark) { rslt = HITRESULT.Copy; } break; case HITRESULT.CopyAndMark: rslt = HITRESULT.CopyAndMark; break; case HITRESULT.Move: rslt = HITRESULT.Move; break; case HITRESULT.Exclude: rslt = HITRESULT.Exclude; break; } } catch (NullReferenceException) { // IsHitでNullRef出る場合あり。暫定対応 MyCommon.TraceOut("IsHitでNullRef: " + ft); rslt = HITRESULT.None; } } } if (rslt != HITRESULT.None && rslt != HITRESULT.Exclude) { _tmpIds.Add(new TemporaryId(post.StatusId, post.IsRead)); } // マーク付けは呼び出し元で行うこと return rslt; }
public void GenThumbnail(long id, List<string> links, PostClass.StatusGeo geo, Dictionary<string, string> media) { if (!_tweenMain.IsPreviewEnable) { _tweenMain.SplitContainer3.Panel2Collapsed = true; return; } if (_tweenMain.PreviewPicture.Image != null) { _tweenMain.PreviewPicture.Image.Dispose(); _tweenMain.PreviewPicture.Image = null; _tweenMain.SplitContainer3.Panel2Collapsed = true; } if (links.Count == 0 && geo == null && (media == null || media.Count == 0)) { _tweenMain.PreviewScrollBar.Maximum = 0; _tweenMain.PreviewScrollBar.Enabled = false; _tweenMain.SplitContainer3.Panel2Collapsed = true; return; } if (media != null && media.Count > 0) { foreach (var link in links.ToArray()) { if (media.ContainsKey(link)) { links.Remove(link); } } } var imglist = new List<KeyValuePair<string, string>>(); var dlg = new List<KeyValuePair<string, ImageCreatorDelegate>>(); foreach (string url in links) { foreach (var svc in _thumbnailServices) { if (svc.UrlCreator(new GetUrlArgs { Url = url, ImgList = imglist })) { // URLに対応したサムネイル作成処理デリゲートをリストに登録 dlg.Add(new KeyValuePair<string, ImageCreatorDelegate>(url, svc.ImageCreator)); break; } } } if (media != null) { foreach (var m in media) { foreach (var svc in _thumbnailServices) { if (svc.UrlCreator(new GetUrlArgs { Url = m.Key, Extended = m.Value, ImgList = imglist })) { // URLに対応したサムネイル作成処理デリゲートをリストに登録 dlg.Add(new KeyValuePair<string, ImageCreatorDelegate>(m.Key, svc.ImageCreator)); break; } } } } if (geo != null) { var args = new GetUrlArgs { Url = string.Empty, ImgList = imglist, GeoInfo = new Google.GlobalLocation { Latitude = geo.Lat, Longitude = geo.Lng } }; if (TwitterGeo_GetUrl(args)) { // URLに対応したサムネイル作成処理デリゲートをリストに登録 dlg.Add(new KeyValuePair<string, ImageCreatorDelegate>(args.Url, TwitterGeo_CreateImage)); } } if (imglist.Count == 0) { _tweenMain.PreviewScrollBar.Maximum = 0; _tweenMain.PreviewScrollBar.Enabled = false; _tweenMain.SplitContainer3.Panel2Collapsed = true; return; } ThumbnailProgressChanged(0); var bgw = new BackgroundWorker(); bgw.DoWork += Bgw_DoWork; bgw.RunWorkerCompleted += Bgw_Completed; bgw.RunWorkerAsync(new PreviewData(id, imglist, dlg)); }
public string GetFavoritesApi(bool read, WorkerType workerType, bool more) { if (AccountState != AccountState.Valid) { return string.Empty; } if (MyCommon.IsEnding) { return string.Empty; } HttpStatusCode res; string content = string.Empty; int count = Configs.Instance.CountApi; if (Configs.Instance.UseAdditionalCount && Configs.Instance.FavoritesCountApi != 0) { count = Configs.Instance.FavoritesCountApi; } // 前ページ取得の場合はページカウンタをインクリメント、それ以外の場合はページカウンタリセット if (more) { _prevFavPage += 1; } else { _prevFavPage = 1; } try { res = _twitterConnection.Favorites(count, _prevFavPage, ref content); } catch (Exception ex) { return string.Format("Err:{0}({1})", ex.Message, MethodBase.GetCurrentMethod().Name); } 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<Status> item; try { item = 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 item) { var post = new PostClass(); try { post.StatusId = status.Id; // 二重取得回避 lock (_lockObj) { if (TabInformations.Instance.GetTabByType(TabUsageType.Favorites).Contains(post.StatusId)) { continue; } } // Retweet判定 Entities entities; 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 t; long.TryParse(retweeted.InReplyToStatusId, out t); post.InReplyToStatusId = t; } post.InReplyToUser = retweeted.InReplyToScreenName; { long t; long.TryParse(retweeted.InReplyToUserId, out t); post.InReplyToUserId = t; } 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 t; long.TryParse(status.InReplyToStatusId, out t); post.InReplyToStatusId = t; } post.InReplyToUser = status.InReplyToScreenName; { long t; long.TryParse(status.InReplyToUserId, out t); post.InReplyToUserId = t; } 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に整形 { var t = post.TextFromApi; post.Text = CreateHtmlAnchor(ref t, post.ReplyToList, entities, post.Media); post.TextFromApi = t; } post.TextFromApi = ReplaceTextFromApi(post.TextFromApi, entities); post.TextFromApi = HttpUtility.HtmlDecode(post.TextFromApi); post.TextFromApi = post.TextFromApi.Replace("<3", "♡"); CreateSource(ref post); // Source整形 post.IsRead = read; post.IsReply = post.ReplyToList.Contains(_uname); post.IsExcludeReply = false; if (post.IsMe) { post.IsOwl = false; } else { if (_followerIds.Count > 0) { post.IsOwl = !_followerIds.Contains(post.UserId); } } post.IsDm = false; } catch (Exception ex) { MyCommon.TraceOut(ex, MethodBase.GetCurrentMethod().Name + " " + content); continue; } TabInformations.Instance.AddPost(post); } return string.Empty; }
private ListViewItem CreateItem(TabPage tabPage, PostClass post, int index) { var mk = new StringBuilder(); if (post.FavoritedCount > 0) { mk.AppendFormat("+{0}", post.FavoritedCount); } string postedByDetail = post.ScreenName; if (post.IsRetweeted) { postedByDetail += string.Format("{0}(RT:{1})", Environment.NewLine, post.RetweetedBy); } bool read = post.IsRead || (!_statuses.Tabs[tabPage.Text].UnreadManage || !_configs.UnreadManage); var subitem = new[] { string.Empty, post.Nickname, (post.IsDeleted ? "(DELETED)" : string.Empty) + post.TextFromApi, post.CreatedAt.ToString(_configs.DateTimeFormat), postedByDetail, string.Empty, mk.ToString(), post.Source }; var itm = new ImageListViewItem(subitem, _iconDict, post.ImageUrl) { StateImageIndex = post.StateIndex }; ChangeItemStyleRead(read, itm, post, null); if (tabPage.Equals(_curTab)) { ColorizeList(itm, index); } return itm; }
public string RemoveDirectMessage(long id, PostClass post) { if (MyCommon.IsEnding) { return string.Empty; } if (AccountState != AccountState.Valid) { return string.Empty; } if (MyCommon.TwitterApiInfo.AccessLevel != ApiAccessLevel.None) { if (!MyCommon.TwitterApiInfo.IsDirectMessagePermission) { return "Auth Err:try to re-authorization."; } } HttpStatusCode res; try { res = _twitterConnection.DestroyDirectMessage(id); } catch (Exception ex) { return "Err:" + ex.Message; } switch (res) { case HttpStatusCode.OK: AccountState = AccountState.Valid; return string.Empty; case HttpStatusCode.Unauthorized: AccountState = AccountState.Invalid; return R.Unauthorized; case HttpStatusCode.NotFound: return string.Empty; default: return string.Format("Err:{0}({1})", res, MethodBase.GetCurrentMethod().Name); } }
private bool IsPostMine(PostClass p) { return p.IsMe || p.RetweetedBy.ToLower() == _tw.Username.ToLower(); }
private PostClass CreatePostsFromStatusData(Status status) { Entities entities; var post = new PostClass { 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 t; long.TryParse(retweeted.InReplyToStatusId, out t); post.InReplyToStatusId = t; } post.InReplyToUser = retweeted.InReplyToScreenName; { long t; long.TryParse(status.InReplyToUserId, out t); post.InReplyToUserId = t; } // 幻覚fav対策 var tc = TabInformations.Instance.GetTabByType(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 t; long.TryParse(status.InReplyToStatusId, out t); post.InReplyToStatusId = t; } post.InReplyToUser = status.InReplyToScreenName; { long t; long.TryParse(status.InReplyToUserId, out t); post.InReplyToUserId = t; } 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 == null || 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.Instance.GetTabByType(TabUsageType.Favorites); post.IsFav = tc.Contains(post.StatusId) && TabInformations.Instance.Item(post.StatusId).IsFav; } // HTMLに整形 { var t = post.TextFromApi; post.Text = CreateHtmlAnchor(ref t, post.ReplyToList, entities, post.Media); post.TextFromApi = t; } post.TextFromApi = ReplaceTextFromApi(post.TextFromApi, entities); post.TextFromApi = HttpUtility.HtmlDecode(post.TextFromApi); post.TextFromApi = post.TextFromApi.Replace("<3", "♡"); CreateSource(ref post); // Source整形 post.IsReply = post.ReplyToList.Contains(_uname); post.IsExcludeReply = false; if (post.IsMe) { post.IsOwl = false; } else { if (_followerIds.Count > 0) { post.IsOwl = !_followerIds.Contains(post.UserId); } } post.IsDm = false; return post; }
private Color JudgeColor(PostClass basePost, PostClass targetPost) { Color cl = _clrListBackcolor; // その他 if (targetPost.StatusId == basePost.InReplyToStatusId) { cl = _clrAtTo; // @先 } else if (targetPost.IsMe) { cl = _clrSelf; // 自分=発言者 } else if (targetPost.IsReply) { cl = _clrAtSelf; // 自分宛返信 } else if (basePost.ReplyToList.Contains(targetPost.ScreenName.ToLower())) { cl = _clrAtFromTarget; // 返信先 } else if (targetPost.ReplyToList.Contains(basePost.ScreenName.ToLower())) { cl = _clrAtTarget; // その人への返信 } else if (targetPost.ScreenName.Equals(basePost.ScreenName, StringComparison.OrdinalIgnoreCase)) { cl = _clrTarget; // 発言者 } return cl; }
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; }
private void ChangeItemStyleRead(bool read, ListViewItem item, PostClass post, DetailsListView listView) { bool useUnreadStyle = _configs.UseUnreadStyle; // フォント Font fnt = read ? _fntReaded : _fntUnread; // 文字色 Color cl = _clrUnread; if (post.IsFav) { cl = _clrFav; } else if (post.IsRetweeted) { cl = _clrRetweet; } else if (post.IsOwl && (post.IsDm || _configs.OneWayLove)) { cl = _clrOwl; } else if (read || !useUnreadStyle) { cl = _clrRead; } item.SubItems[5].Text = read ? string.Empty : "★"; if (listView == null || item.Index == -1) { item.ForeColor = cl; if (useUnreadStyle) { item.Font = fnt; } } else { listView.Update(); if (useUnreadStyle) { listView.ChangeItemFontAndColor(item.Index, cl, fnt); } else { listView.ChangeItemForeColor(item.Index, cl); } } }
public HITRESULT IsHit(PostClass post) { string bodyText; string sourceText; if (SearchUrl) { bodyText = post.Text; sourceText = post.SourceHtml; } else { bodyText = post.TextFromApi; sourceText = post.Source; } // 検索オプション StringComparison compOpt; RegexOptions regexOption; if (CaseSensitive) { compOpt = StringComparison.Ordinal; regexOption = RegexOptions.None; } else { compOpt = StringComparison.OrdinalIgnoreCase; regexOption = RegexOptions.IgnoreCase; } bool isHit = true; if (SearchBoth) { if (string.IsNullOrEmpty(NameFilter) || (!UseRegex && (post.ScreenName.Equals(NameFilter, compOpt) || post.RetweetedBy.Equals(NameFilter, compOpt))) || (UseRegex && (Regex.IsMatch(post.ScreenName, NameFilter, regexOption) || (!string.IsNullOrEmpty(post.RetweetedBy) && Regex.IsMatch(post.RetweetedBy, NameFilter, regexOption))))) { if (_useLambda) { if (!ExecuteLambdaExpression(_body[0], post)) { isHit = false; } } else { foreach (string fs in _body) { if (UseRegex) { if (!Regex.IsMatch(bodyText, fs, regexOption)) { isHit = false; } } else { if (CaseSensitive) { if (!bodyText.Contains(fs)) { isHit = false; } } else { if (!bodyText.ToLower().Contains(fs.ToLower())) { isHit = false; } } } if (!isHit) { break; } } } } else { isHit = false; } } else { if (_useLambda) { if (!ExecuteLambdaExpression(_body[0], post)) { isHit = false; } } else { foreach (string fs in _body) { if (UseRegex) { if (!(Regex.IsMatch(post.ScreenName, fs, regexOption) || (!string.IsNullOrEmpty(post.RetweetedBy) && Regex.IsMatch(post.RetweetedBy, fs, regexOption)) || Regex.IsMatch(bodyText, fs, regexOption))) { isHit = false; } } else { if (CaseSensitive) { if (!(post.ScreenName.Contains(fs) || post.RetweetedBy.Contains(fs) || bodyText.Contains(fs))) { isHit = false; } } else { if (!(post.ScreenName.ToLower().Contains(fs.ToLower()) || post.RetweetedBy.ToLower().Contains(fs.ToLower()) || bodyText.ToLower().Contains(fs.ToLower()))) { isHit = false; } } } if (!isHit) { break; } } } } if (IsRt) { if (!post.IsRetweeted) { isHit = false; } } if (!string.IsNullOrEmpty(Source)) { if (UseRegex) { if (!Regex.IsMatch(sourceText, Source, regexOption)) { isHit = false; } } else { if (!sourceText.Equals(Source, compOpt)) { isHit = false; } } } if (!isHit) { return(HITRESULT.None); } // 除外判定 if (ExSearchUrl) { bodyText = post.Text; sourceText = post.SourceHtml; } else { bodyText = post.TextFromApi; sourceText = post.Source; } bool isExclude = false; if (!string.IsNullOrEmpty(ExNameFilter) || _exbody.Count > 0) { if (ExCaseSensitive) { compOpt = StringComparison.Ordinal; regexOption = RegexOptions.None; } else { compOpt = StringComparison.OrdinalIgnoreCase; regexOption = RegexOptions.IgnoreCase; } if (ExSearchBoth) { if (string.IsNullOrEmpty(ExNameFilter) || (!ExUseRegex && (post.ScreenName.Equals(ExNameFilter, compOpt) || post.RetweetedBy.Equals(ExNameFilter, compOpt))) || (ExUseRegex && (Regex.IsMatch(post.ScreenName, ExNameFilter, regexOption) || (!string.IsNullOrEmpty(post.RetweetedBy) && Regex.IsMatch(post.RetweetedBy, ExNameFilter, regexOption))))) { if (_exbody.Count > 0) { if (_exuseLambda) { if (ExecuteExLambdaExpression(_exbody[0], post)) { isExclude = true; } } else { foreach (string fs in _exbody) { if (ExUseRegex) { if (Regex.IsMatch(bodyText, fs, regexOption)) { isExclude = true; } } else { if (ExCaseSensitive) { if (bodyText.Contains(fs)) { isExclude = true; } } else { if (bodyText.ToLower().Contains(fs.ToLower())) { isExclude = true; } } } if (isExclude) { break; } } } } else { isExclude = true; } } } else { if (_exuseLambda) { if (ExecuteExLambdaExpression(_exbody[0], post)) { isExclude = true; } } else { foreach (string fs in _exbody) { if (ExUseRegex) { if (Regex.IsMatch(post.ScreenName, fs, regexOption) || (!string.IsNullOrEmpty(post.RetweetedBy) && Regex.IsMatch(post.RetweetedBy, fs, regexOption)) || Regex.IsMatch(bodyText, fs, regexOption)) { isExclude = true; } } else { if (ExCaseSensitive) { if (post.ScreenName.Contains(fs) || post.RetweetedBy.Contains(fs) || bodyText.Contains(fs)) { isExclude = true; } } else { if (post.ScreenName.ToLower().Contains(fs.ToLower()) || post.RetweetedBy.ToLower().Contains(fs.ToLower()) || bodyText.ToLower().Contains(fs.ToLower())) { isExclude = true; } } } if (isExclude) { break; } } } } } if (IsExRt) { if (post.IsRetweeted) { isExclude = true; } } if (!string.IsNullOrEmpty(ExSource)) { if (ExUseRegex) { if (Regex.IsMatch(sourceText, ExSource, regexOption)) { isExclude = true; } } else { if (sourceText.Equals(ExSource, compOpt)) { isExclude = true; } } } if (string.IsNullOrEmpty(NameFilter) && _body.Count == 0 && !IsRt && string.IsNullOrEmpty(Source)) { isHit = false; } if (isHit) { if (isExclude) { return(HITRESULT.Exclude); } if (MoveFrom) { return(HITRESULT.Move); } return(SetMark ? HITRESULT.CopyAndMark : HITRESULT.Copy); } return(isExclude ? HITRESULT.Exclude : HITRESULT.None); }
private void NotifyNewPosts(PostClass[] notifyPosts, string soundFile, int addCount, bool newMentions) { if (notifyPosts != null && notifyPosts.Any() && _configs.ReadOwnPost && notifyPosts.All(post => post.UserId == _tw.UserId || post.ScreenName == _tw.Username)) { return; } // 新着通知 if (IsBalloonRequired() && notifyPosts != null && notifyPosts.Length > 0) { // Growlは一個ずつばらして通知。ただし、3ポスト以上あるときはまとめる if (_configs.IsNotifyUseGrowl) { var sb = new StringBuilder(); bool reply = false; bool dm = false; foreach (var post in notifyPosts) { if (!(notifyPosts.Count() > 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(Environment.NewLine); } switch (_configs.NameBalloon) { case NameBalloonEnum.UserID: sb.Append(post.ScreenName).Append(" : "); break; case NameBalloonEnum.NickName: sb.Append(post.Nickname).Append(" : "); break; } sb.Append(post.TextFromApi); if (notifyPosts.Count() > 3) { if (!ReferenceEquals(notifyPosts.Last(), post)) { continue; } } string notifyText = sb.ToString(); if (string.IsNullOrEmpty(notifyText)) { return; } var titleStr = GetNotifyTitlteText(addCount, reply, dm); var nt = dm ? GrowlHelper.NotifyType.DirectMessage : reply ? GrowlHelper.NotifyType.Reply : GrowlHelper.NotifyType.Notify; _growlHelper.Notify(nt, post.StatusId.ToString(), titleStr, notifyText, _iconDict[post.ImageUrl], post.ImageUrl); } } else { var sb = new StringBuilder(); bool reply = false; bool dm = false; foreach (var post in notifyPosts) { if (post.IsReply && !post.IsExcludeReply) { reply = true; } if (post.IsDm) { dm = true; } if (sb.Length > 0) { sb.Append(Environment.NewLine); } switch (_configs.NameBalloon) { case NameBalloonEnum.UserID: sb.Append(post.ScreenName).Append(" : "); break; case NameBalloonEnum.NickName: sb.Append(post.Nickname).Append(" : "); break; } sb.Append(post.TextFromApi); } string notifyText = sb.ToString(); if (string.IsNullOrEmpty(notifyText)) { return; } var titleStr = GetNotifyTitlteText(addCount, reply, dm); var notifyIcon = dm ? ToolTipIcon.Warning : reply ? ToolTipIcon.Warning : ToolTipIcon.Info; NotifyIcon1.BalloonTipTitle = titleStr; NotifyIcon1.BalloonTipText = notifyText; NotifyIcon1.BalloonTipIcon = notifyIcon; NotifyIcon1.ShowBalloonTip(500); } } // サウンド再生 if (!_isInitializing && _configs.PlaySound) { MyCommon.PlaySound(soundFile); } // mentions新着時に画面ブリンク if (!_isInitializing && _configs.BlinkNewMentions && newMentions && ActiveForm == null) { Win32Api.FlashMyWindow(Handle, Win32Api.FlashSpecification.FlashTray, 3); } }