1 ' Tween - Client of Twitter
2 ' Copyright (c) 2007-2010 kiri_feather (@kiri_feather) <kiri_feather@gmail.com>
3 ' (c) 2008-2010 Moz (@syo68k) <http://iddy.jp/profile/moz/>
4 ' (c) 2008-2010 takeshik (@takeshik) <http://www.takeshik.org/>
7 ' This file is part of Tween.
9 ' This program is free software; you can redistribute it and/or modify it
10 ' under the terms of the GNU General Public License as published by the Free
11 ' Software Foundation; either version 3 of the License, or (at your option)
14 ' This program is distributed in the hope that it will be useful, but
15 ' WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 ' or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 ' You should have received a copy of the GNU General Public License along
20 ' with this program. If not, see <http://www.gnu.org/licenses/>, or write to
21 ' the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
22 ' Boston, MA 02110-1301, USA.
27 Imports System.Threading
29 Imports System.Text.RegularExpressions
30 Imports System.Globalization
31 Imports System.Diagnostics
33 Imports System.Reflection
34 Imports System.Reflection.MethodBase
38 Delegate Sub GetIconImageDelegate(ByVal post As PostClass)
39 Private ReadOnly LockObj As New Object
40 Private followerId As New List(Of Long)
41 Private _GetFollowerResult As Boolean = False
43 Private _followersCount As Integer = 0
44 Private _friendsCount As Integer = 0
45 Private _statusesCount As Integer = 0
46 Private _location As String = ""
47 Private _bio As String = ""
48 Private _userinfoxml As String = ""
49 Private _protocol As String = "https://"
52 Private _uid As String
53 Private _iconSz As Integer
54 Private _getIcon As Boolean
55 Private _dIcon As IDictionary(Of String, Image)
57 Private _tinyUrlResolve As Boolean
58 Private _restrictFavCheck As Boolean
60 Private _hubServer As String
61 'Private _countApi As Integer
62 'Private _countApiReply As Integer
63 Private _readOwnPost As Boolean
64 Private _hashList As New List(Of String)
67 Private _remainCountApi As Integer = -1
69 Private op As New Outputz
70 'max_idで古い発言を取得するために保持(lists分は個別タブで管理)
71 Private minHomeTimeline As Long = Long.MaxValue
72 Private minMentions As Long = Long.MaxValue
73 Private minDirectmessage As Long = Long.MaxValue
74 Private minDirectmessageSent As Long = Long.MaxValue
76 Private twCon As New HttpTwitter
78 Public Function Authenticate(ByVal username As String, ByVal password As String) As String
80 Dim res As HttpStatusCode
81 Dim content As String = ""
83 TwitterApiInfo.Initialize()
85 res = twCon.AuthUserAndPass(username, password)
87 Return "Err:" + ex.Message
91 Case HttpStatusCode.OK
92 Twitter.AccountState = ACCOUNT_STATE.Valid
93 _uid = username.ToLower
95 Case HttpStatusCode.Unauthorized
96 Twitter.AccountState = ACCOUNT_STATE.Invalid
97 Return "Check your Username/Password."
98 Case HttpStatusCode.Forbidden
99 Dim xd As XmlDocument = New XmlDocument
102 Dim xNode As XmlNode = Nothing
103 xNode = xd.SelectSingleNode("/hash/error")
104 Return "Err:" + xNode.InnerText
105 Catch ex As Exception
106 Return "Err:Forbidden"
109 Return "Err:" + res.ToString + "(" + GetCurrentMethod.Name + ")"
114 Public Sub ClearAuthInfo()
115 Twitter.AccountState = ACCOUNT_STATE.Invalid
116 twCon.ClearAuthInfo()
120 Public Sub Initialize(ByVal token As String, ByVal tokenSecret As String, ByVal username As String)
122 If String.IsNullOrEmpty(token) OrElse String.IsNullOrEmpty(tokenSecret) OrElse String.IsNullOrEmpty(username) Then
123 Twitter.AccountState = ACCOUNT_STATE.Invalid
125 TwitterApiInfo.Initialize()
126 twCon.Initialize(token, tokenSecret, username)
127 _uid = username.ToLower
131 Public Sub Initialize(ByVal username As String, ByVal password As String)
133 If String.IsNullOrEmpty(username) OrElse String.IsNullOrEmpty(password) Then
134 Twitter.AccountState = ACCOUNT_STATE.Invalid
136 TwitterApiInfo.Initialize()
137 twCon.Initialize(username, password)
138 _uid = username.ToLower
142 Public Function PreProcessUrl(ByVal orgData As String) As String
144 Dim posl2 As Integer = 0
145 'Dim IDNConveter As IdnMapping = New IdnMapping()
146 Dim href As String = "<a href="""
149 If orgData.IndexOf(href, posl2, StringComparison.Ordinal) > -1 Then
150 Dim urlStr As String = ""
152 posl1 = orgData.IndexOf(href, posl2, StringComparison.Ordinal)
154 posl2 = orgData.IndexOf("""", posl1, StringComparison.Ordinal)
155 urlStr = orgData.Substring(posl1, posl2 - posl1)
157 If Not urlStr.StartsWith("http://") AndAlso Not urlStr.StartsWith("https://") AndAlso Not urlStr.StartsWith("ftp://") Then
161 Dim replacedUrl As String = IDNDecode(urlStr)
162 If replacedUrl Is Nothing Then Continue Do
163 If replacedUrl = urlStr Then Continue Do
165 orgData = orgData.Replace("<a href=""" + urlStr, "<a href=""" + replacedUrl)
174 Private Function GetPlainText(ByVal orgData As String) As String
175 Return HttpUtility.HtmlDecode(Regex.Replace(orgData, "(?<tagStart><a [^>]+>)(?<text>[^<]+)(?<tagEnd></a>)", "${text}"))
178 ' htmlの簡易サニタイズ(詳細表示に不要なタグの除去)
180 Private Function SanitizeHtml(ByVal orgdata As String) As String
181 Dim retdata As String = orgdata
183 retdata = Regex.Replace(retdata, "<(script|object|applet|image|frameset|fieldset|legend|style).*" & _
184 "</(script|object|applet|image|frameset|fieldset|legend|style)>", "", RegexOptions.IgnoreCase)
186 retdata = Regex.Replace(retdata, "<(frame|link|iframe|img)>", "", RegexOptions.IgnoreCase)
191 Private Function AdjustHtml(ByVal orgData As String) As String
192 Dim retStr As String = orgData
193 Dim m As Match = Regex.Match(retStr, "<a [^>]+>[#|#](?<1>[a-zA-Z0-9_]+)</a>")
196 _hashList.Add("#" + m.Groups(1).Value)
200 retStr = Regex.Replace(retStr, "<a [^>]*href=""/", "<a href=""" + _protocol + "twitter.com/")
201 retStr = retStr.Replace("<a href=", "<a target=""_self"" href=")
202 retStr = retStr.Replace(vbLf, "<br>")
204 '半角スペースを置換(Thanks @anis774)
205 Dim ret As Boolean = False
207 ret = EscapeSpace(retStr)
210 Return SanitizeHtml(retStr)
213 Private Function EscapeSpace(ByRef html As String) As Boolean
214 '半角スペースを置換(Thanks @anis774)
215 Dim isTag As Boolean = False
216 For i As Integer = 0 To html.Length - 1
217 If html(i) = "<"c Then
220 If html(i) = ">"c Then
224 If (Not isTag) AndAlso (html(i) = " "c) Then
225 html = html.Remove(i, 1)
226 html = html.Insert(i, " ")
233 Private Sub GetIconImage(ByVal post As PostClass)
238 post.ImageUrl = Nothing
239 TabInformations.GetInstance.AddPost(post)
243 If _dIcon.ContainsKey(post.ImageUrl) Then
244 TabInformations.GetInstance.AddPost(post)
248 Dim httpVar As New HttpVarious
249 img = httpVar.GetIconImage(post.ImageUrl, 10000)
250 If img Is Nothing Then
251 TabInformations.GetInstance.AddPost(post)
255 If _endingFlag Then Exit Sub
258 If Not _dIcon.ContainsKey(post.ImageUrl) Then
260 _dIcon.Add(post.ImageUrl, img)
261 Catch ex As InvalidOperationException
262 'タイミングにより追加できない場合がある?(キー重複ではない)
263 Catch ex As System.OverflowException
264 '不正なアイコン?DrawImageに失敗する場合あり
265 Catch ex As OutOfMemoryException
270 TabInformations.GetInstance.AddPost(post)
271 Catch ex As ArgumentException
279 Private Structure PostInfo
280 Public CreatedAt As String
282 Public Text As String
283 Public UserId As String
284 Public Sub New(ByVal Created As String, ByVal IdStr As String, ByVal txt As String, ByVal uid As String)
290 Public Shadows Function Equals(ByVal dst As PostInfo) As Boolean
291 If Me.CreatedAt = dst.CreatedAt AndAlso Me.Id = dst.Id AndAlso Me.Text = dst.Text AndAlso Me.UserId = dst.UserId Then
299 Private Function IsPostRestricted(ByRef resMsg As String) As Boolean
300 Static _prev As New PostInfo("", "", "", "")
301 Dim _current As New PostInfo("", "", "", "")
304 Dim xd As XmlDocument = New XmlDocument()
307 _current.CreatedAt = xd.SelectSingleNode("/status/created_at/text()").Value
308 _current.Id = xd.SelectSingleNode("/status/id/text()").Value
309 If xd.SelectSingleNode("/status/text/text()") Is Nothing Then
310 '制御文字のみ投稿した場合はNothing
313 _current.Text = xd.SelectSingleNode("/status/text/text()").Value
315 _current.UserId = xd.SelectSingleNode("/status/user/id/text()").Value
317 If _current.Equals(_prev) Then
320 _prev.CreatedAt = _current.CreatedAt
321 _prev.Id = _current.Id
322 _prev.Text = _current.Text
323 _prev.UserId = _current.UserId
324 Catch ex As XmlException
331 Public Function PostStatus(ByVal postStr As String, ByVal reply_to As Long) As String
333 If _endingFlag Then Return ""
335 If Twitter.AccountState <> ACCOUNT_STATE.Valid Then Return ""
337 postStr = postStr.Trim()
339 If Regex.Match(postStr, "^DM? +(?<id>[a-zA-Z0-9_]+) +(?<body>.+)", RegexOptions.IgnoreCase Or RegexOptions.Singleline).Success Then
340 Return SendDirectMessage(postStr)
343 Dim res As HttpStatusCode
344 Dim content As String = ""
346 res = twCon.UpdateStatus(postStr, reply_to, content)
347 Catch ex As Exception
348 Return "Err:" + ex.Message
352 Case HttpStatusCode.OK
353 Twitter.AccountState = ACCOUNT_STATE.Valid
354 Dim xd As XmlDocument = New XmlDocument()
357 Dim xNode As XmlNode = Nothing
358 xNode = xd.SelectSingleNode("/status/user/followers_count/text()")
359 If xNode IsNot Nothing Then _followersCount = Integer.Parse(xNode.Value)
360 xNode = xd.SelectSingleNode("/status/user/friends_count/text()")
361 If xNode IsNot Nothing Then _friendsCount = Integer.Parse(xNode.Value)
362 xNode = xd.SelectSingleNode("/status/user/statuses_count/text()")
363 If xNode IsNot Nothing Then _statusesCount = Integer.Parse(xNode.Value)
364 xNode = xd.SelectSingleNode("/status/user/location/text()")
365 If xNode IsNot Nothing Then _location = xNode.Value
366 xNode = xd.SelectSingleNode("/status/user/description/text()")
367 If xNode IsNot Nothing Then _bio = xNode.Value
368 xNode = xd.SelectSingleNode("/status/user/id/text()")
369 If xNode IsNot Nothing Then _UserIdNo = xNode.Value
371 _userinfoxml = String.Copy(content)
372 Catch ex As Exception
377 If Not postStr.StartsWith("D ", StringComparison.OrdinalIgnoreCase) AndAlso _
378 Not postStr.StartsWith("DM ", StringComparison.OrdinalIgnoreCase) AndAlso _
379 IsPostRestricted(content) Then
380 Return "OK:Delaying?"
382 If op.Post(postStr.Length) Then
385 Return "Outputz:Failed"
387 Case HttpStatusCode.Forbidden, HttpStatusCode.BadRequest
388 Dim xd As XmlDocument = New XmlDocument
391 Dim xNode As XmlNode = Nothing
392 xNode = xd.SelectSingleNode("/hash/error")
393 Return "Warn:" + xNode.InnerText
394 Catch ex As Exception
396 Return "Warn:" + res.ToString
397 Case HttpStatusCode.Conflict, _
398 HttpStatusCode.ExpectationFailed, _
399 HttpStatusCode.Gone, _
400 HttpStatusCode.LengthRequired, _
401 HttpStatusCode.MethodNotAllowed, _
402 HttpStatusCode.NotAcceptable, _
403 HttpStatusCode.NotFound, _
404 HttpStatusCode.PaymentRequired, _
405 HttpStatusCode.PreconditionFailed, _
406 HttpStatusCode.RequestedRangeNotSatisfiable, _
407 HttpStatusCode.RequestEntityTooLarge, _
408 HttpStatusCode.RequestTimeout, _
409 HttpStatusCode.RequestUriTooLong
410 '仕様書にない400系エラー。サーバまでは到達しているのでリトライしない
411 Return "Warn:" + res.ToString + "(" + GetCurrentMethod.Name + ")"
412 Case HttpStatusCode.Unauthorized
413 Twitter.AccountState = ACCOUNT_STATE.Invalid
414 Return "Check your Username/Password."
416 Return "Err:" + res.ToString + "(" + GetCurrentMethod.Name + ")"
420 Public Function SendDirectMessage(ByVal postStr As String) As String
422 If _endingFlag Then Return ""
424 If Twitter.AccountState <> ACCOUNT_STATE.Valid Then Return ""
426 postStr = postStr.Trim()
428 Dim res As HttpStatusCode
429 Dim content As String = ""
431 Dim mc As Match = Regex.Match(postStr, "^DM? +(?<id>[a-zA-Z0-9_]+) +(?<body>.+)", RegexOptions.IgnoreCase Or RegexOptions.Singleline)
434 res = twCon.SendDirectMessage(mc.Groups("body").Value, mc.Groups("id").Value, content)
435 Catch ex As Exception
436 Return "Err:" + ex.Message
440 Case HttpStatusCode.OK
441 Twitter.AccountState = ACCOUNT_STATE.Valid
442 Dim xd As XmlDocument = New XmlDocument()
445 Dim xNode As XmlNode = Nothing
446 xNode = xd.SelectSingleNode("/status/user/followers_count/text()")
447 If xNode IsNot Nothing Then _followersCount = Integer.Parse(xNode.Value)
448 xNode = xd.SelectSingleNode("/status/user/friends_count/text()")
449 If xNode IsNot Nothing Then _friendsCount = Integer.Parse(xNode.Value)
450 xNode = xd.SelectSingleNode("/status/user/statuses_count/text()")
451 If xNode IsNot Nothing Then _statusesCount = Integer.Parse(xNode.Value)
452 xNode = xd.SelectSingleNode("/status/user/location/text()")
453 If xNode IsNot Nothing Then _location = xNode.Value
454 xNode = xd.SelectSingleNode("/status/user/description/text()")
455 If xNode IsNot Nothing Then _bio = xNode.Value
456 xNode = xd.SelectSingleNode("/status/user/id/text()")
457 If xNode IsNot Nothing Then _userIdNo = xNode.Value
458 Catch ex As Exception
462 If op.Post(postStr.Length) Then
465 Return "Outputz:Failed"
467 Case HttpStatusCode.Forbidden, HttpStatusCode.BadRequest
468 Dim xd As XmlDocument = New XmlDocument
471 Dim xNode As XmlNode = Nothing
472 xNode = xd.SelectSingleNode("/hash/error")
473 Return "Warn:" + xNode.InnerText
474 Catch ex As Exception
476 Return "Warn:" + res.ToString
477 Case HttpStatusCode.Conflict, _
478 HttpStatusCode.ExpectationFailed, _
479 HttpStatusCode.Gone, _
480 HttpStatusCode.LengthRequired, _
481 HttpStatusCode.MethodNotAllowed, _
482 HttpStatusCode.NotAcceptable, _
483 HttpStatusCode.NotFound, _
484 HttpStatusCode.PaymentRequired, _
485 HttpStatusCode.PreconditionFailed, _
486 HttpStatusCode.RequestedRangeNotSatisfiable, _
487 HttpStatusCode.RequestEntityTooLarge, _
488 HttpStatusCode.RequestTimeout, _
489 HttpStatusCode.RequestUriTooLong
490 '仕様書にない400系エラー。サーバまでは到達しているのでリトライしない
491 Return "Warn:" + res.ToString
492 Case HttpStatusCode.Unauthorized
493 Twitter.AccountState = ACCOUNT_STATE.Invalid
494 Return "Check your Username/Password."
496 Return "Err:" + res.ToString + "(" + GetCurrentMethod.Name + ")"
500 Public Function RemoveStatus(ByVal id As Long) As String
501 If _endingFlag Then Return ""
503 If Twitter.AccountState <> ACCOUNT_STATE.Valid Then Return ""
505 Dim res As HttpStatusCode
508 res = twCon.DestroyStatus(id)
509 Catch ex As Exception
510 Return "Err:" + ex.Message
514 Case HttpStatusCode.OK
515 Twitter.AccountState = ACCOUNT_STATE.Valid
517 Case HttpStatusCode.Unauthorized
518 Twitter.AccountState = ACCOUNT_STATE.Invalid
519 Return "Check your Username/Password."
520 Case HttpStatusCode.NotFound
523 Return "Err:" + res.ToString + "(" + GetCurrentMethod.Name + ")"
528 Public Function PostRetweet(ByVal id As Long, ByVal read As Boolean) As String
529 If _endingFlag Then Return ""
530 If Twitter.AccountState <> ACCOUNT_STATE.Valid Then Return ""
533 Dim target As Long = id
534 If TabInformations.GetInstance.Item(id).RetweetedId > 0 Then
535 target = TabInformations.GetInstance.Item(id).RetweetedId '再RTの場合は元発言をRT
538 Dim res As HttpStatusCode
539 Dim content As String = ""
541 res = twCon.RetweetStatus(target, content)
542 Catch ex As Exception
543 Return "Err:" + ex.Message
547 Case HttpStatusCode.Unauthorized
548 Twitter.AccountState = ACCOUNT_STATE.Invalid
549 Return "Check your Username/Password."
550 Case Is <> HttpStatusCode.OK
551 Return "Err:" + res.ToString() + "(" + GetCurrentMethod.Name + ")"
554 Twitter.AccountState = ACCOUNT_STATE.Valid
556 Dim dlgt As GetIconImageDelegate 'countQueryに合わせる
557 Dim ar As IAsyncResult 'countQueryに合わせる
558 Dim xdoc As New XmlDocument
560 xdoc.LoadXml(content)
561 Catch ex As Exception
563 'MessageBox.Show("不正なXMLです。(TL-LoadXml)")
564 Return "Invalid XML!"
568 Dim xentryNode As XmlNode = xdoc.DocumentElement.SelectSingleNode("/status")
569 If xentryNode Is Nothing Then Return "Invalid XML!"
570 Dim xentry As XmlElement = CType(xentryNode, XmlElement)
571 Dim post As New PostClass
573 post.Id = Long.Parse(xentry.Item("id").InnerText)
576 If TabInformations.GetInstance.ContainsKey(post.Id) Then Return ""
579 Dim xRnode As XmlNode = xentry.SelectSingleNode("./retweeted_status")
580 If xRnode Is Nothing Then Return "Invalid XML!"
582 Dim xRentry As XmlElement = CType(xRnode, XmlElement)
583 post.PDate = DateTime.ParseExact(xRentry.Item("created_at").InnerText, "ddd MMM dd HH:mm:ss zzzz yyyy", System.Globalization.DateTimeFormatInfo.InvariantInfo, System.Globalization.DateTimeStyles.None)
585 post.RetweetedId = Long.Parse(xRentry.Item("id").InnerText)
587 post.Data = xRentry.Item("text").InnerText
588 'Source取得(htmlの場合は、中身を取り出し)
589 post.Source = xRentry.Item("source").InnerText
591 Long.TryParse(xRentry.Item("in_reply_to_status_id").InnerText, post.InReplyToId)
592 post.InReplyToUser = xRentry.Item("in_reply_to_screen_name").InnerText
593 post.IsFav = TabInformations.GetInstance.GetTabByType(TabUsageType.Favorites).Contains(post.RetweetedId)
596 Dim xRUentry As XmlElement = CType(xRentry.SelectSingleNode("./user"), XmlElement)
597 post.Uid = Long.Parse(xRUentry.Item("id").InnerText)
598 post.Name = xRUentry.Item("screen_name").InnerText
599 post.Nickname = xRUentry.Item("name").InnerText
600 post.ImageUrl = xRUentry.Item("profile_image_url").InnerText
601 post.IsProtect = Boolean.Parse(xRUentry.Item("protected").InnerText)
605 Dim xUentry As XmlElement = CType(xentry.SelectSingleNode("./user"), XmlElement)
606 post.RetweetedBy = xUentry.Item("screen_name").InnerText
609 post.OriginalData = CreateHtmlAnchor(post.Data, post.ReplyToList)
610 post.Data = HttpUtility.HtmlDecode(post.Data)
611 post.Data = post.Data.Replace("<3", "♡")
616 post.IsReply = post.ReplyToList.Contains(_uid)
617 post.IsExcludeReply = False
622 If followerId.Count > 0 Then post.IsOwl = Not followerId.Contains(post.Uid)
624 If post.IsMe AndAlso _readOwnPost Then post.IsRead = True
627 Catch ex As Exception
629 'MessageBox.Show("不正なXMLです。(TL-Parse)")
630 Return "Invalid XML!"
633 '非同期アイコン取得&StatusDictionaryに追加
634 dlgt = New GetIconImageDelegate(AddressOf GetIconImage)
635 ar = dlgt.BeginInvoke(post, Nothing, Nothing)
640 Catch ex As Exception
641 '最後までendinvoke回す(ゾンビ化回避)
642 ex.Data("IsTerminatePermission") = False
649 Public Function RemoveDirectMessage(ByVal id As Long) As String
650 If _endingFlag Then Return ""
652 If Twitter.AccountState <> ACCOUNT_STATE.Valid Then Return ""
654 Dim res As HttpStatusCode
657 res = twCon.DestroyDirectMessage(id)
658 Catch ex As Exception
659 Return "Err:" + ex.Message
663 Case HttpStatusCode.OK
664 Twitter.AccountState = ACCOUNT_STATE.Valid
666 Case HttpStatusCode.Unauthorized
667 Twitter.AccountState = ACCOUNT_STATE.Invalid
668 Return "Check your Username/Password."
669 Case HttpStatusCode.NotFound
672 Return "Err:" + res.ToString + "(" + GetCurrentMethod.Name + ")"
676 Public Function PostFollowCommand(ByVal screenName As String) As String
678 If _endingFlag Then Return ""
680 If Twitter.AccountState <> ACCOUNT_STATE.Valid Then Return ""
682 Dim res As HttpStatusCode
683 Dim content As String = ""
686 res = twCon.CreateFriendships(screenName, content)
687 Catch ex As Exception
688 Return "Err:" + ex.Message
692 Case HttpStatusCode.OK
693 Twitter.AccountState = ACCOUNT_STATE.Valid
695 Case HttpStatusCode.Unauthorized
696 Twitter.AccountState = ACCOUNT_STATE.Invalid
697 Return "Check your Username/Password."
698 Case HttpStatusCode.Forbidden
699 Dim xd As XmlDocument = New XmlDocument
702 Dim xNode As XmlNode = Nothing
703 xNode = xd.SelectSingleNode("/hash/error")
704 Return "Err:" + xNode.InnerText + "(" + GetCurrentMethod.Name + ")"
705 Catch ex As Exception
706 Return "Err:Forbidden" + "(" + GetCurrentMethod.Name + ")"
709 Return "Err:" + res.ToString + "(" + GetCurrentMethod.Name + ")"
713 Public Function PostRemoveCommand(ByVal screenName As String) As String
715 If _endingFlag Then Return ""
717 If Twitter.AccountState <> ACCOUNT_STATE.Valid Then Return ""
719 Dim res As HttpStatusCode
720 Dim content As String = ""
723 res = twCon.DestroyFriendships(screenName, content)
724 Catch ex As Exception
725 Return "Err:" + ex.Message + "(" + GetCurrentMethod.Name + ")"
729 Case HttpStatusCode.OK
730 Twitter.AccountState = ACCOUNT_STATE.Valid
732 Case HttpStatusCode.Unauthorized
733 Twitter.AccountState = ACCOUNT_STATE.Invalid
734 Return "Check your Username/Password."
735 Case HttpStatusCode.Forbidden
736 Dim xd As XmlDocument = New XmlDocument
739 Dim xNode As XmlNode = Nothing
740 xNode = xd.SelectSingleNode("/hash/error")
741 Return "Err:" + xNode.InnerText + "(" + GetCurrentMethod.Name + ")"
742 Catch ex As Exception
743 Return "Err:Forbidden" + "(" + GetCurrentMethod.Name + ")"
746 Return "Err:" + res.ToString + "(" + GetCurrentMethod.Name + ")"
750 Public Function PostCreateBlock(ByVal screenName As String) As String
752 If _endingFlag Then Return ""
754 If Twitter.AccountState <> ACCOUNT_STATE.Valid Then Return ""
756 Dim res As HttpStatusCode
757 Dim content As String = ""
760 res = twCon.CreateBlock(screenName, content)
761 Catch ex As Exception
762 Return "Err:" + ex.Message + "(" + GetCurrentMethod.Name + ")"
766 Case HttpStatusCode.OK
767 Twitter.AccountState = ACCOUNT_STATE.Valid
769 Case HttpStatusCode.Unauthorized
770 Twitter.AccountState = ACCOUNT_STATE.Invalid
771 Return "Check your Username/Password."
772 Case HttpStatusCode.Forbidden
773 Dim xd As XmlDocument = New XmlDocument
776 Dim xNode As XmlNode = Nothing
777 xNode = xd.SelectSingleNode("/hash/error")
778 Return "Err:" + xNode.InnerText + "(" + GetCurrentMethod.Name + ")"
779 Catch ex As Exception
780 Return "Err:Forbidden" + "(" + GetCurrentMethod.Name + ")"
783 Return "Err:" + res.ToString + "(" + GetCurrentMethod.Name + ")"
787 Public Function PostDestroyBlock(ByVal screenName As String) As String
789 If _endingFlag Then Return ""
791 If Twitter.AccountState <> ACCOUNT_STATE.Valid Then Return ""
793 Dim res As HttpStatusCode
794 Dim content As String = ""
797 res = twCon.DestroyBlock(screenName, content)
798 Catch ex As Exception
799 Return "Err:" + ex.Message + "(" + GetCurrentMethod.Name + ")"
803 Case HttpStatusCode.OK
804 Twitter.AccountState = ACCOUNT_STATE.Valid
806 Case HttpStatusCode.Unauthorized
807 Twitter.AccountState = ACCOUNT_STATE.Invalid
808 Return "Check your Username/Password."
809 Case HttpStatusCode.Forbidden
810 Dim xd As XmlDocument = New XmlDocument
813 Dim xNode As XmlNode = Nothing
814 xNode = xd.SelectSingleNode("/hash/error")
815 Return "Err:" + xNode.InnerText + "(" + GetCurrentMethod.Name + ")"
816 Catch ex As Exception
817 Return "Err:Forbidden" + "(" + GetCurrentMethod.Name + ")"
820 Return "Err:" + res.ToString + "(" + GetCurrentMethod.Name + ")"
824 Public Function PostReportSpam(ByVal screenName As String) As String
826 If _endingFlag Then Return ""
828 If Twitter.AccountState <> ACCOUNT_STATE.Valid Then Return ""
830 Dim res As HttpStatusCode
831 Dim content As String = ""
834 res = twCon.ReportSpam(screenName, content)
835 Catch ex As Exception
836 Return "Err:" + ex.Message + "(" + GetCurrentMethod.Name + ")"
840 Case HttpStatusCode.OK
841 Twitter.AccountState = ACCOUNT_STATE.Valid
843 Case HttpStatusCode.Unauthorized
844 Twitter.AccountState = ACCOUNT_STATE.Invalid
845 Return "Check your Username/Password."
846 Case HttpStatusCode.Forbidden
847 Dim xd As XmlDocument = New XmlDocument
850 Dim xNode As XmlNode = Nothing
851 xNode = xd.SelectSingleNode("/hash/error")
852 Return "Err:" + xNode.InnerText + "(" + GetCurrentMethod.Name + ")"
853 Catch ex As Exception
854 Return "Err:Forbidden" + "(" + GetCurrentMethod.Name + ")"
857 Return "Err:" + res.ToString + "(" + GetCurrentMethod.Name + ")"
861 Public Function GetFriendshipInfo(ByVal screenName As String, ByRef isFollowing As Boolean, ByRef isFollowed As Boolean) As String
863 If _endingFlag Then Return ""
865 If Twitter.AccountState <> ACCOUNT_STATE.Valid Then Return ""
867 Dim res As HttpStatusCode
868 Dim content As String = ""
870 res = twCon.ShowFriendships(_uid, screenName, content)
871 Catch ex As Exception
872 Return "Err:" + ex.Message + "(" + GetCurrentMethod.Name + ")"
876 Case HttpStatusCode.OK
877 Dim xdoc As New XmlDocument
878 Dim result As String = ""
879 Twitter.AccountState = ACCOUNT_STATE.Valid
881 xdoc.LoadXml(content)
882 isFollowing = Boolean.Parse(xdoc.SelectSingleNode("/relationship/source/following").InnerText)
883 isFollowed = Boolean.Parse(xdoc.SelectSingleNode("/relationship/source/followed_by").InnerText)
884 Catch ex As Exception
885 result = "Err:Invalid XML."
888 Case HttpStatusCode.BadRequest
889 Return "Err:API Limits?"
890 Case HttpStatusCode.Unauthorized
891 Twitter.AccountState = ACCOUNT_STATE.Invalid
892 Return "Check your Username/Password."
894 Return "Err:" + res.ToString + "(" + GetCurrentMethod.Name + ")"
898 Public Function GetUserInfo(ByVal screenName As String, ByRef xmlBuf As String) As String
900 If _endingFlag Then Return ""
902 If Twitter.AccountState <> ACCOUNT_STATE.Valid Then Return ""
904 Dim res As HttpStatusCode
905 Dim content As String = ""
908 res = twCon.ShowUserInfo(screenName, content)
909 Catch ex As Exception
910 Return "Err:" + ex.Message + "(" + GetCurrentMethod.Name + ")"
914 Case HttpStatusCode.OK
915 Dim xdoc As New XmlDocument
916 Dim result As String = ""
917 Twitter.AccountState = ACCOUNT_STATE.Valid
919 xdoc.LoadXml(content)
921 Catch ex As Exception
922 result = "Err:Invalid XML."
926 Case HttpStatusCode.BadRequest
927 Return "Err:API Limits?"
928 Case HttpStatusCode.Unauthorized
929 Twitter.AccountState = ACCOUNT_STATE.Invalid
930 Return "Check your Username/Password."
932 Return "Err:" + res.ToString + "(" + GetCurrentMethod.Name + ")"
936 Public Function GetStatus_Retweeted_Count(ByVal StatusId As Long, ByRef retweeted_count As Integer) As String
938 If _endingFlag Then Return ""
940 If Twitter.AccountState <> ACCOUNT_STATE.Valid Then Return ""
942 Dim res As HttpStatusCode
943 Dim content As String = ""
944 Dim xmlBuf As String = ""
948 ' 注:dev.twitter.comに記述されているcountパラメータは間違い。100が正しい
949 For i As Integer = 1 To 100
952 res = twCon.Statusid_retweeted_by_ids(StatusId, 100, i, content)
953 Catch ex As Exception
954 Return "Err:" + ex.Message
958 Case HttpStatusCode.OK
959 Dim xdoc As New XmlDocument
960 Dim xnode As XmlNodeList
961 Dim result As String = ""
962 Twitter.AccountState = ACCOUNT_STATE.Valid
964 xdoc.LoadXml(content)
965 xnode = xdoc.GetElementsByTagName("ids")
966 retweeted_count += xnode.ItemOf(0).ChildNodes.Count
967 If xnode.ItemOf(0).ChildNodes.Count < 100 Then Exit For
968 Catch ex As Exception
970 result = "Err:Invalid XML."
973 Case HttpStatusCode.BadRequest
975 Return "Err:API Limits?"
976 Case HttpStatusCode.Unauthorized
978 Twitter.AccountState = ACCOUNT_STATE.Invalid
979 Return "Check your Username/Password."
982 Return "Err:" + res.ToString + "(" + GetCurrentMethod.Name + ")"
988 Public Function PostFavAdd(ByVal id As Long) As String
989 If _endingFlag Then Return ""
991 If Twitter.AccountState <> ACCOUNT_STATE.Valid Then Return ""
993 Dim res As HttpStatusCode
994 Dim content As String = ""
996 res = twCon.CreateFavorites(id, content)
997 Catch ex As Exception
998 Return "Err:" + ex.Message + "(" + GetCurrentMethod.Name + ")"
1002 Case HttpStatusCode.OK
1003 Twitter.AccountState = ACCOUNT_STATE.Valid
1004 If Not _restrictFavCheck Then Return ""
1005 Case HttpStatusCode.Unauthorized
1006 Twitter.AccountState = ACCOUNT_STATE.Invalid
1007 Return "Check your Username/Password."
1008 Case HttpStatusCode.Forbidden
1009 Dim xd As XmlDocument = New XmlDocument
1012 Dim xNode As XmlNode = Nothing
1013 xNode = xd.SelectSingleNode("/hash/error")
1014 Return "Err:" + xNode.InnerText + "(" + GetCurrentMethod.Name + ")"
1015 Catch ex As Exception
1016 Return "Err:Forbidden" + "(" + GetCurrentMethod.Name + ")"
1019 Return "Err:" + res.ToString + "(" + GetCurrentMethod.Name + ")"
1022 'http://twitter.com/statuses/show/id.xml APIを発行して本文を取得
1024 'Dim content As String = ""
1027 res = twCon.ShowStatuses(id, content)
1028 Catch ex As Exception
1029 Return "Err:" + ex.Message
1033 Case HttpStatusCode.OK
1034 Twitter.AccountState = ACCOUNT_STATE.Valid
1036 Using rd As Xml.XmlTextReader = New Xml.XmlTextReader(New System.IO.StringReader(content))
1038 While rd.EOF = False
1039 If rd.IsStartElement("favorited") Then
1040 If rd.ReadElementContentAsBoolean() = True Then
1041 Return "" '正常にふぁぼれている
1043 Return "NG(Restricted?)" '正常応答なのにふぁぼれてないので制限っぽい
1050 Return "Err:Invalid XML!"
1052 Catch ex As XmlException
1055 Case HttpStatusCode.Unauthorized
1056 Twitter.AccountState = ACCOUNT_STATE.Invalid
1057 Return "Check your Username/Password."
1058 Case HttpStatusCode.BadRequest
1059 Return "Err:API Limits?"
1061 Return "Err:" + res.ToString + "(" + GetCurrentMethod.Name + ")"
1066 Public Function PostFavRemove(ByVal id As Long) As String
1067 If _endingFlag Then Return ""
1069 If Twitter.AccountState <> ACCOUNT_STATE.Valid Then Return ""
1071 Dim res As HttpStatusCode
1072 Dim content As String = ""
1074 res = twCon.DestroyFavorites(id, content)
1075 Catch ex As Exception
1076 Return "Err:" + ex.Message
1080 Case HttpStatusCode.OK
1081 Twitter.AccountState = ACCOUNT_STATE.Valid
1083 Case HttpStatusCode.Unauthorized
1084 Twitter.AccountState = ACCOUNT_STATE.Invalid
1085 Return "Check your Username/Password."
1086 Case HttpStatusCode.Forbidden
1087 Dim xd As XmlDocument = New XmlDocument
1090 Dim xNode As XmlNode = Nothing
1091 xNode = xd.SelectSingleNode("/hash/error")
1092 Return "Err:" + xNode.InnerText
1093 Catch ex As Exception
1094 Return "Err:Forbidden"
1097 Return "Err:" + res.ToString + "(" + GetCurrentMethod.Name + ")"
1101 Public Function PostUpdateProfile(ByVal name As String, ByVal url As String, ByVal location As String, ByVal description As String) As String
1102 If _endingFlag Then Return ""
1104 If Twitter.AccountState <> ACCOUNT_STATE.Valid Then Return ""
1106 Dim res As HttpStatusCode
1107 Dim content As String = ""
1109 res = twCon.UpdateProfile(name, url, location, description, content)
1110 Catch ex As Exception
1111 Return "Err:" + ex.Message
1115 Case HttpStatusCode.OK
1116 Twitter.AccountState = ACCOUNT_STATE.Valid
1118 Case HttpStatusCode.Unauthorized
1119 Twitter.AccountState = ACCOUNT_STATE.Invalid
1120 Return "Check your Username/Password."
1121 Case HttpStatusCode.Forbidden
1122 Dim xd As XmlDocument = New XmlDocument
1125 Dim xNode As XmlNode = Nothing
1126 xNode = xd.SelectSingleNode("/hash/error")
1127 Return "Err:" + xNode.InnerText + "(" + GetCurrentMethod.Name + ")"
1128 Catch ex As Exception
1129 Return "Err:Forbidden" + "(" + GetCurrentMethod.Name + ")"
1132 Return "Err:" + res.ToString + "(" + GetCurrentMethod.Name + ")"
1136 Public Function PostUpdateProfileImage(ByVal filename As String) As String
1137 If _endingFlag Then Return ""
1139 If Twitter.AccountState <> ACCOUNT_STATE.Valid Then Return ""
1141 Dim res As HttpStatusCode
1142 Dim content As String = ""
1144 res = twCon.UpdateProfileImage(New FileInfo(filename), content)
1145 Catch ex As Exception
1146 Return "Err:" + ex.Message + "(" + GetCurrentMethod.Name + ")"
1150 Case HttpStatusCode.OK
1151 Twitter.AccountState = ACCOUNT_STATE.Valid
1153 Case HttpStatusCode.Unauthorized
1154 Twitter.AccountState = ACCOUNT_STATE.Invalid
1155 Return "Check your Username/Password."
1156 Case HttpStatusCode.Forbidden
1157 Dim xd As XmlDocument = New XmlDocument
1160 Dim xNode As XmlNode = Nothing
1161 xNode = xd.SelectSingleNode("/hash/error")
1162 Return "Err:" + xNode.InnerText + "(" + GetCurrentMethod.Name + ")"
1163 Catch ex As Exception
1164 Return "Err:Forbidden" + "(" + GetCurrentMethod.Name + ")"
1167 Return "Err:" + res.ToString + "(" + GetCurrentMethod.Name + ")"
1171 Public ReadOnly Property Username() As String
1173 Return twCon.AuthenticatedUsername
1177 Public ReadOnly Property Password() As String
1179 Return twCon.Password
1183 Private Shared _accountState As ACCOUNT_STATE = ACCOUNT_STATE.Valid
1184 Public Shared Property AccountState() As ACCOUNT_STATE
1186 Return _accountState
1188 Set(ByVal value As ACCOUNT_STATE)
1189 _accountState = value
1193 Public WriteOnly Property GetIcon() As Boolean
1194 Set(ByVal value As Boolean)
1199 Public WriteOnly Property TinyUrlResolve() As Boolean
1200 Set(ByVal value As Boolean)
1201 _tinyUrlResolve = value
1205 Public WriteOnly Property RestrictFavCheck() As Boolean
1206 Set(ByVal value As Boolean)
1207 _restrictFavCheck = value
1211 Public WriteOnly Property IconSize() As Integer
1212 Set(ByVal value As Integer)
1218 Public Function GetVersionInfo() As String
1219 Dim content As String = ""
1220 If Not (New HttpVarious).GetData("http://tween.sourceforge.jp/version2.txt?" + Now.ToString("yyMMddHHmmss") + Environment.TickCount.ToString(), Nothing, content) Then
1221 Throw New Exception("GetVersionInfo Failed")
1226 Public Function GetTweenBinary(ByVal strVer As String) As String
1228 If Not (New HttpVarious).GetDataToFile("http://tween.sourceforge.jp/Tween" + strVer + ".gz?" + Now.ToString("yyMMddHHmmss") + Environment.TickCount.ToString(), _
1229 Path.Combine(Application.StartupPath(), "TweenNew.exe")) Then
1230 Return "Err:Download failed"
1232 If Directory.Exists(Path.Combine(Application.StartupPath(), "en")) = False Then
1233 Directory.CreateDirectory(Path.Combine(Application.StartupPath(), "en"))
1235 If Not (New HttpVarious).GetDataToFile("http://tween.sourceforge.jp/TweenRes" + strVer + ".gz?" + Now.ToString("yyMMddHHmmss") + Environment.TickCount.ToString(), _
1236 Path.Combine(Application.StartupPath(), "en\Tween.resourcesNew.dll")) Then
1237 Return "Err:Download failed"
1239 If Not (New HttpVarious).GetDataToFile("http://tween.sourceforge.jp/TweenUp.gz?" + Now.ToString("yyMMddHHmmss") + Environment.TickCount.ToString(), _
1240 Path.Combine(Application.StartupPath(), "TweenUp.exe")) Then
1241 Return "Err:Download failed"
1243 If Not (New HttpVarious).GetDataToFile("http://tween.sourceforge.jp/TweenDll" + strVer + ".gz?" + Now.ToString("yyMMddHHmmss") + Environment.TickCount.ToString(), _
1244 Path.Combine(Application.StartupPath(), "TweenNew.XmlSerializers.dll")) Then
1245 Return "Err:Download failed"
1248 Catch ex As Exception
1249 Return "Err:Download failed"
1254 Public Property DetailIcon() As IDictionary(Of String, Image)
1258 Set(ByVal value As IDictionary(Of String, Image))
1263 'Public WriteOnly Property CountApi() As Integer
1265 ' Set(ByVal value As Integer)
1270 'Public WriteOnly Property CountApiReply() As Integer
1271 ' 'API時のMentions取得件数
1272 ' Set(ByVal value As Integer)
1273 ' _countApiReply = value
1277 Public Property ReadOwnPost() As Boolean
1281 Set(ByVal value As Boolean)
1282 _readOwnPost = value
1286 Public ReadOnly Property FollowersCount() As Integer
1288 Return _followersCount
1292 Public ReadOnly Property FriendsCount() As Integer
1294 Return _friendsCount
1298 Public ReadOnly Property StatusesCount() As Integer
1300 Return _statusesCount
1304 Public ReadOnly Property Location() As String
1310 Public ReadOnly Property Bio() As String
1316 Public ReadOnly Property UserInfoXml As String
1322 Public WriteOnly Property UseSsl() As Boolean
1323 Set(ByVal value As Boolean)
1324 HttpTwitter.UseSsl = value
1326 _protocol = "https://"
1328 _protocol = "http://"
1333 'Public Overloads Function GetTimelineApi(ByVal read As Boolean, _
1334 ' ByVal gType As WORKERTYPE, _
1335 ' ByVal more As Boolean) As String
1337 ' Return GetTimelineApi(read, gType, more, -1)
1341 Public Overloads Function GetTimelineApi(ByVal read As Boolean, _
1342 ByVal gType As WORKERTYPE, _
1343 ByVal more As Boolean, _
1344 ByVal startup As Boolean) As String
1346 If Twitter.AccountState <> ACCOUNT_STATE.Valid Then Return ""
1348 If _endingFlag Then Return ""
1350 Dim res As HttpStatusCode
1351 Dim content As String = ""
1352 Dim count As Integer = Setting.Instance.CountApi
1353 If gType = WORKERTYPE.Reply Then count = Setting.Instance.CountApiReply
1354 If Setting.Instance.UseAdditionalCount Then
1355 If more AndAlso Setting.Instance.MoreCountApi <> 0 Then
1356 count = Setting.Instance.MoreCountApi
1357 ElseIf startup AndAlso Setting.Instance.FirstCountApi <> 0 AndAlso gType = WORKERTYPE.Timeline Then
1358 count = Setting.Instance.FirstCountApi
1362 If gType = WORKERTYPE.Timeline Then
1364 res = twCon.HomeTimeline(count, Me.minHomeTimeline, 0, content)
1366 res = twCon.HomeTimeline(count, 0, 0, content)
1370 res = twCon.Mentions(count, Me.minMentions, 0, content)
1372 res = twCon.Mentions(count, 0, 0, content)
1375 Catch ex As Exception
1376 Return "Err:" + ex.Message
1379 Case HttpStatusCode.OK
1380 Twitter.AccountState = ACCOUNT_STATE.Valid
1381 Case HttpStatusCode.Unauthorized
1382 Twitter.AccountState = ACCOUNT_STATE.Invalid
1383 Return "Check your Username/Password."
1384 Case HttpStatusCode.BadRequest
1385 Return "Err:API Limits?"
1387 Return "Err:" + res.ToString() + "(" + GetCurrentMethod.Name + ")"
1390 If gType = WORKERTYPE.Timeline Then
1391 Return CreatePostsFromXml(content, gType, Nothing, read, count, Me.minHomeTimeline)
1393 Return CreatePostsFromXml(content, gType, Nothing, read, count, Me.minMentions)
1397 'Public Overloads Function GetListStatus(ByVal read As Boolean, _
1398 ' ByVal tab As TabClass, _
1399 ' ByVal more As Boolean) As String
1401 ' Return GetListStatus(read, tab, more, -1)
1404 Public Overloads Function GetListStatus(ByVal read As Boolean, _
1405 ByVal tab As TabClass, _
1406 ByVal more As Boolean, _
1407 ByVal startup As Boolean) As String
1409 If _endingFlag Then Return ""
1411 Dim res As HttpStatusCode
1412 Dim content As String = ""
1413 Dim page As Integer = 0
1414 Dim count As Integer = Setting.Instance.CountApi
1415 If Setting.Instance.UseAdditionalCount Then
1416 If more AndAlso Setting.Instance.MoreCountApi <> 0 Then
1417 count = Setting.Instance.MoreCountApi
1418 ElseIf startup AndAlso Setting.Instance.FirstCountApi <> 0 Then
1419 count = Setting.Instance.FirstCountApi
1424 res = twCon.GetListsStatuses(tab.ListInfo.UserId.ToString, tab.ListInfo.Id.ToString, count, tab.OldestId, 0, content)
1426 res = twCon.GetListsStatuses(tab.ListInfo.UserId.ToString, tab.ListInfo.Id.ToString, count, 0, 0, content)
1428 Catch ex As Exception
1429 Return "Err:" + ex.Message
1432 Case HttpStatusCode.OK
1433 Twitter.AccountState = ACCOUNT_STATE.Valid
1434 Case HttpStatusCode.Unauthorized
1435 Twitter.AccountState = ACCOUNT_STATE.Invalid
1436 Return "Check your Username/Password."
1437 Case HttpStatusCode.BadRequest
1438 Return "Err:API Limits?"
1440 Return "Err:" + res.ToString() + "(" + GetCurrentMethod.Name + ")"
1443 Return CreatePostsFromXml(content, WORKERTYPE.List, tab, read, count, tab.OldestId)
1446 Private Function CreatePostsFromXml(ByVal content As String, ByVal gType As WORKERTYPE, ByVal tab As TabClass, ByVal read As Boolean, ByVal count As Integer, ByRef minimumId As Long) As String
1447 Dim arIdx As Integer = -1
1448 Dim dlgt(300) As GetIconImageDelegate 'countQueryに合わせる
1449 Dim ar(300) As IAsyncResult 'countQueryに合わせる
1450 Dim xdoc As New XmlDocument
1452 xdoc.LoadXml(content)
1453 Catch ex As Exception
1455 'MessageBox.Show("不正なXMLです。(TL-LoadXml)")
1456 Return "Invalid XML!"
1459 For Each xentryNode As XmlNode In xdoc.DocumentElement.SelectNodes("./status")
1460 Dim xentry As XmlElement = CType(xentryNode, XmlElement)
1461 Dim post As New PostClass
1463 post.Id = Long.Parse(xentry.Item("id").InnerText)
1464 If minimumId > post.Id Then minimumId = post.Id
1467 If tab Is Nothing Then
1468 If TabInformations.GetInstance.ContainsKey(post.Id) Then Continue For
1470 If TabInformations.GetInstance.ContainsKey(post.Id, tab.TabName) Then Continue For
1474 Dim xRnode As XmlNode = xentry.SelectSingleNode("./retweeted_status")
1475 If xRnode IsNot Nothing Then
1476 Dim xRentry As XmlElement = CType(xRnode, XmlElement)
1477 post.PDate = DateTime.ParseExact(xRentry.Item("created_at").InnerText, "ddd MMM dd HH:mm:ss zzzz yyyy", System.Globalization.DateTimeFormatInfo.InvariantInfo, System.Globalization.DateTimeStyles.None)
1479 post.RetweetedId = Long.Parse(xRentry.Item("id").InnerText)
1481 post.Data = xRentry.Item("text").InnerText
1482 'Source取得(htmlの場合は、中身を取り出し)
1483 post.Source = xRentry.Item("source").InnerText
1485 Long.TryParse(xRentry.Item("in_reply_to_status_id").InnerText, post.InReplyToId)
1486 post.InReplyToUser = xRentry.Item("in_reply_to_screen_name").InnerText
1487 post.IsFav = TabInformations.GetInstance.GetTabByType(TabUsageType.Favorites).Contains(post.RetweetedId)
1488 'post.IsFav = Boolean.Parse(xentry.Item("favorited").InnerText)
1491 Dim xRUentry As XmlElement = CType(xRentry.SelectSingleNode("./user"), XmlElement)
1492 post.Uid = Long.Parse(xRUentry.Item("id").InnerText)
1493 post.Name = xRUentry.Item("screen_name").InnerText
1494 post.Nickname = xRUentry.Item("name").InnerText
1495 post.ImageUrl = xRUentry.Item("profile_image_url").InnerText
1496 post.IsProtect = Boolean.Parse(xRUentry.Item("protected").InnerText)
1497 post.IsMe = post.Name.ToLower.Equals(_uid)
1498 If post.IsMe Then _UserIdNo = post.Uid.ToString()
1501 Dim xUentry As XmlElement = CType(xentry.SelectSingleNode("./user"), XmlElement)
1502 post.RetweetedBy = xUentry.Item("screen_name").InnerText
1504 post.PDate = DateTime.ParseExact(xentry.Item("created_at").InnerText, "ddd MMM dd HH:mm:ss zzzz yyyy", System.Globalization.DateTimeFormatInfo.InvariantInfo, System.Globalization.DateTimeStyles.None)
1506 post.Data = xentry.Item("text").InnerText
1507 'Source取得(htmlの場合は、中身を取り出し)
1508 post.Source = xentry.Item("source").InnerText
1509 Long.TryParse(xentry.Item("in_reply_to_status_id").InnerText, post.InReplyToId)
1510 post.InReplyToUser = xentry.Item("in_reply_to_screen_name").InnerText
1511 'in_reply_to_user_idを使うか?
1512 post.IsFav = Boolean.Parse(xentry.Item("favorited").InnerText)
1515 Dim xUentry As XmlElement = CType(xentry.SelectSingleNode("./user"), XmlElement)
1516 post.Uid = Long.Parse(xUentry.Item("id").InnerText)
1517 post.Name = xUentry.Item("screen_name").InnerText
1518 post.Nickname = xUentry.Item("name").InnerText
1519 post.ImageUrl = xUentry.Item("profile_image_url").InnerText
1520 post.IsProtect = Boolean.Parse(xUentry.Item("protected").InnerText)
1521 post.IsMe = post.Name.ToLower.Equals(_uid)
1522 If post.IsMe Then _UserIdNo = post.Uid.ToString()
1525 post.OriginalData = CreateHtmlAnchor(post.Data, post.ReplyToList)
1526 post.Data = HttpUtility.HtmlDecode(post.Data)
1527 post.Data = post.Data.Replace("<3", "♡")
1532 If gType = WORKERTYPE.Timeline OrElse tab IsNot Nothing Then
1533 post.IsReply = post.ReplyToList.Contains(_uid)
1537 post.IsExcludeReply = False
1542 If followerId.Count > 0 Then post.IsOwl = Not followerId.Contains(post.Uid)
1544 If post.IsMe AndAlso Not read AndAlso _readOwnPost Then post.IsRead = True
1547 If tab IsNot Nothing Then post.RelTabName = tab.TabName
1548 Catch ex As Exception
1550 'MessageBox.Show("不正なXMLです。(TL-Parse)")
1554 '非同期アイコン取得&StatusDictionaryに追加
1556 If arIdx > dlgt.Length - 1 Then
1560 dlgt(arIdx) = New GetIconImageDelegate(AddressOf GetIconImage)
1561 ar(arIdx) = dlgt(arIdx).BeginInvoke(post, Nothing, Nothing)
1565 For i As Integer = 0 To arIdx
1567 dlgt(i).EndInvoke(ar(i))
1568 Catch ex As IndexOutOfRangeException
1569 Throw New IndexOutOfRangeException(String.Format("i={0},dlgt.Length={1},ar.Length={2},arIdx={3}", i, dlgt.Length, ar.Length, arIdx))
1570 Catch ex As Exception
1571 '最後までendinvoke回す(ゾンビ化回避)
1572 ex.Data("IsTerminatePermission") = False
1580 Public Function GetSearch(ByVal read As Boolean, _
1581 ByVal tab As TabClass, _
1582 ByVal more As Boolean) As String
1584 If _endingFlag Then Return ""
1586 Dim res As HttpStatusCode
1587 Dim content As String = ""
1588 Dim page As Integer = 0
1589 Dim sinceId As Long = 0
1590 Dim count As Integer = 100
1591 If Setting.Instance.UseAdditionalCount AndAlso
1592 Setting.Instance.SearchCountApi <> 0 Then
1593 count = Setting.Instance.SearchCountApi
1596 page = tab.GetSearchPage(count)
1598 sinceId = tab.SinceId
1602 ' TODO:一時的に40>100件に 件数変更UI作成の必要あり
1603 res = twCon.Search(tab.SearchWords, tab.SearchLang, count, page, sinceId, content)
1604 Catch ex As Exception
1605 Return "Err:" + ex.Message
1608 Case HttpStatusCode.BadRequest
1609 Return "Invalid query"
1610 Case HttpStatusCode.NotFound
1611 Return "Invalid query"
1612 Case HttpStatusCode.PaymentRequired 'API Documentには420と書いてあるが、該当コードがないので402にしてある
1613 Return "Search API Limit?"
1614 Case HttpStatusCode.OK
1616 Return "Err:" + res.ToString + "(" + GetCurrentMethod.Name + ")"
1619 If Not TabInformations.GetInstance.ContainsTab(tab) Then Return ""
1621 Dim arIdx As Integer = -1
1622 Dim dlgt(300) As GetIconImageDelegate 'countQueryに合わせる
1623 Dim ar(300) As IAsyncResult 'countQueryに合わせる
1624 Dim xdoc As New XmlDocument
1626 xdoc.LoadXml(content)
1627 Catch ex As Exception
1629 Return "Invalid ATOM!"
1631 Dim nsmgr As New XmlNamespaceManager(xdoc.NameTable)
1632 nsmgr.AddNamespace("search", "http://www.w3.org/2005/Atom")
1633 nsmgr.AddNamespace("twitter", "http://api.twitter.com/")
1634 For Each xentryNode As XmlNode In xdoc.DocumentElement.SelectNodes("/search:feed/search:entry", nsmgr)
1635 Dim xentry As XmlElement = CType(xentryNode, XmlElement)
1636 Dim post As New PostClass
1638 post.Id = Long.Parse(xentry.Item("id").InnerText.Split(":"c)(2))
1639 If TabInformations.GetInstance.ContainsKey(post.Id, tab.TabName) Then Continue For
1640 post.PDate = DateTime.Parse(xentry.Item("published").InnerText)
1642 post.Data = xentry.Item("title").InnerText
1643 'Source取得(htmlの場合は、中身を取り出し)
1644 post.Source = xentry.Item("twitter:source").InnerText
1645 post.InReplyToId = 0
1646 post.InReplyToUser = ""
1650 Dim xUentry As XmlElement = CType(xentry.SelectSingleNode("./search:author", nsmgr), XmlElement)
1652 post.Name = xUentry.Item("name").InnerText.Split(" "c)(0).Trim
1653 post.Nickname = xUentry.Item("name").InnerText.Substring(post.Name.Length).Trim
1654 If post.Nickname.Length > 2 Then
1655 post.Nickname = post.Nickname.Substring(1, post.Nickname.Length - 2)
1657 post.Nickname = post.Name
1659 post.ImageUrl = CType(xentry.SelectSingleNode("./search:link[@type='image/png']", nsmgr), XmlElement).GetAttribute("href")
1660 post.IsProtect = False
1661 post.IsMe = post.Name.ToLower.Equals(_uid)
1664 post.OriginalData = CreateHtmlAnchor(HttpUtility.HtmlEncode(post.Data), post.ReplyToList)
1665 post.Data = HttpUtility.HtmlDecode(post.Data)
1670 post.IsReply = post.ReplyToList.Contains(_uid)
1671 post.IsExcludeReply = False
1674 If post.IsMe AndAlso Not read AndAlso _readOwnPost Then post.IsRead = True
1676 post.RelTabName = tab.TabName
1677 If Not more AndAlso post.Id > tab.SinceId Then tab.SinceId = post.Id
1678 Catch ex As Exception
1683 '非同期アイコン取得&StatusDictionaryに追加
1685 dlgt(arIdx) = New GetIconImageDelegate(AddressOf GetIconImage)
1686 ar(arIdx) = dlgt(arIdx).BeginInvoke(post, Nothing, Nothing)
1690 '' 遡るための情報max_idやnext_pageの情報を保持する
1693 For i As Integer = 0 To arIdx
1695 dlgt(i).EndInvoke(ar(i))
1696 Catch ex As Exception
1697 '最後までendinvoke回す(ゾンビ化回避)
1698 ex.Data("IsTerminatePermission") = False
1704 Dim xNode As XmlNode = xdoc.DocumentElement.SelectSingleNode("/search:feed/twitter:warning", nsmgr)
1706 If xNode IsNot Nothing Then
1707 Return "Warn:" + xNode.InnerText + "(" + GetCurrentMethod.Name + ")"
1714 Public Function GetDirectMessageApi(ByVal read As Boolean, _
1715 ByVal gType As WORKERTYPE, _
1716 ByVal more As Boolean) As String
1717 If _endingFlag Then Return ""
1719 If Twitter.AccountState <> ACCOUNT_STATE.Valid Then Return ""
1721 Dim res As HttpStatusCode
1722 Dim content As String = ""
1725 If gType = WORKERTYPE.DirectMessegeRcv Then
1727 res = twCon.DirectMessages(20, minDirectmessage, 0, content)
1729 res = twCon.DirectMessages(20, 0, 0, content)
1733 res = twCon.DirectMessagesSent(20, minDirectmessageSent, 0, content)
1735 res = twCon.DirectMessagesSent(20, 0, 0, content)
1738 Catch ex As Exception
1739 Return "Err:" + ex.Message
1743 Case HttpStatusCode.OK
1744 Twitter.AccountState = ACCOUNT_STATE.Valid
1745 Case HttpStatusCode.Unauthorized
1746 Twitter.AccountState = ACCOUNT_STATE.Invalid
1747 Return "Check your Username/Password."
1748 Case HttpStatusCode.BadRequest
1749 Return "Err:API Limits?"
1751 Return "Err:" + res.ToString() + "(" + GetCurrentMethod.Name + ")"
1754 Dim arIdx As Integer = -1
1755 Dim dlgt(300) As GetIconImageDelegate 'countQueryに合わせる
1756 Dim ar(300) As IAsyncResult 'countQueryに合わせる
1757 Dim xdoc As New XmlDocument
1759 xdoc.LoadXml(content)
1760 Catch ex As Exception
1762 'MessageBox.Show("不正なXMLです。(DM-LoadXml)")
1763 Return "Invalid XML!"
1766 For Each xentryNode As XmlNode In xdoc.DocumentElement.SelectNodes("./direct_message")
1767 Dim xentry As XmlElement = CType(xentryNode, XmlElement)
1768 Dim post As New PostClass
1770 post.Id = Long.Parse(xentry.Item("id").InnerText)
1771 If gType = WORKERTYPE.DirectMessegeRcv Then
1772 If minDirectmessage > post.Id Then minDirectmessage = post.Id
1774 If minDirectmessageSent > post.Id Then minDirectmessageSent = post.Id
1778 If TabInformations.GetInstance.GetTabByType(TabUsageType.DirectMessage).Contains(post.Id) Then Continue For
1782 post.PDate = DateTime.ParseExact(xentry.Item("created_at").InnerText, "ddd MMM dd HH:mm:ss zzzz yyyy", System.Globalization.DateTimeFormatInfo.InvariantInfo, System.Globalization.DateTimeStyles.None)
1784 post.Data = xentry.Item("text").InnerText
1786 post.OriginalData = CreateHtmlAnchor(post.Data, post.ReplyToList)
1787 post.Data = HttpUtility.HtmlDecode(post.Data)
1788 post.Data = post.Data.Replace("<3", "♡")
1791 If gType = WORKERTYPE.DirectMessegeRcv Then
1798 Dim xUentry As XmlElement
1799 If gType = WORKERTYPE.DirectMessegeRcv Then
1800 xUentry = CType(xentry.SelectSingleNode("./sender"), XmlElement)
1803 xUentry = CType(xentry.SelectSingleNode("./recipient"), XmlElement)
1806 post.Uid = Long.Parse(xUentry.Item("id").InnerText)
1807 post.Name = xUentry.Item("screen_name").InnerText
1808 post.Nickname = xUentry.Item("name").InnerText
1809 post.ImageUrl = xUentry.Item("profile_image_url").InnerText
1810 post.IsProtect = Boolean.Parse(xUentry.Item("protected").InnerText)
1811 Catch ex As Exception
1813 'MessageBox.Show("不正なXMLです。(DM-Parse)")
1818 If gType = WORKERTYPE.DirectMessegeSnt AndAlso Not read AndAlso _readOwnPost Then post.IsRead = True
1819 post.IsReply = False
1820 post.IsExcludeReply = False
1823 '非同期アイコン取得&StatusDictionaryに追加
1825 dlgt(arIdx) = New GetIconImageDelegate(AddressOf GetIconImage)
1826 ar(arIdx) = dlgt(arIdx).BeginInvoke(post, Nothing, Nothing)
1830 For i As Integer = 0 To arIdx
1832 dlgt(i).EndInvoke(ar(i))
1833 Catch ex As Exception
1834 '最後までendinvoke回す(ゾンビ化回避)
1835 ex.Data("IsTerminatePermission") = False
1843 Public Function GetFavoritesApi(ByVal read As Boolean, _
1844 ByVal gType As WORKERTYPE) As String
1846 If Twitter.AccountState <> ACCOUNT_STATE.Valid Then Return ""
1848 If _endingFlag Then Return ""
1850 Dim res As HttpStatusCode
1851 Dim content As String = ""
1852 Dim count As Integer = Setting.Instance.CountApi
1853 If Setting.Instance.UseAdditionalCount AndAlso
1854 Setting.Instance.FavoritesCountApi <> 0 Then
1855 count = Setting.Instance.FavoritesCountApi
1858 res = twCon.Favorites(count, content)
1859 Catch ex As Exception
1860 Return "Err:" + ex.Message + "(" + GetCurrentMethod.Name + ")"
1864 Case HttpStatusCode.OK
1865 Twitter.AccountState = ACCOUNT_STATE.Valid
1866 Case HttpStatusCode.Unauthorized
1867 Twitter.AccountState = ACCOUNT_STATE.Invalid
1868 Return "Check your Username/Password."
1869 Case HttpStatusCode.BadRequest
1870 Return "Err:API Limits?"
1872 Return "Err:" + res.ToString() + "(" + GetCurrentMethod.Name + ")"
1875 Dim arIdx As Integer = -1
1876 Dim dlgt(300) As GetIconImageDelegate 'countQueryに合わせる
1877 Dim ar(300) As IAsyncResult 'countQueryに合わせる
1878 Dim xdoc As New XmlDocument
1880 xdoc.LoadXml(content)
1881 Catch ex As Exception
1883 'MessageBox.Show("不正なXMLです。(TL-LoadXml)")
1884 Return "Invalid XML!"
1887 For Each xentryNode As XmlNode In xdoc.DocumentElement.SelectNodes("./status")
1888 Dim xentry As XmlElement = CType(xentryNode, XmlElement)
1889 Dim post As New PostClass
1891 post.Id = Long.Parse(xentry.Item("id").InnerText)
1894 'If TabInformations.GetInstance.ContainsKey(post.Id) Then Continue For
1895 If TabInformations.GetInstance.GetTabByType(TabUsageType.Favorites).Contains(post.Id) Then Continue For
1898 Dim xRnode As XmlNode = xentry.SelectSingleNode("./retweeted_status")
1899 If xRnode IsNot Nothing Then
1900 Dim xRentry As XmlElement = CType(xRnode, XmlElement)
1901 post.PDate = DateTime.ParseExact(xRentry.Item("created_at").InnerText, "ddd MMM dd HH:mm:ss zzzz yyyy", System.Globalization.DateTimeFormatInfo.InvariantInfo, System.Globalization.DateTimeStyles.None)
1903 post.RetweetedId = Long.Parse(xRentry.Item("id").InnerText)
1905 post.Data = xRentry.Item("text").InnerText
1906 'Source取得(htmlの場合は、中身を取り出し)
1907 post.Source = xRentry.Item("source").InnerText
1909 Long.TryParse(xRentry.Item("in_reply_to_status_id").InnerText, post.InReplyToId)
1910 post.InReplyToUser = xRentry.Item("in_reply_to_screen_name").InnerText
1911 'in_reply_to_user_idを使うか?
1912 post.IsFav = Boolean.Parse(xRentry.Item("favorited").InnerText)
1915 Dim xRUentry As XmlElement = CType(xRentry.SelectSingleNode("./user"), XmlElement)
1916 post.Uid = Long.Parse(xRUentry.Item("id").InnerText)
1917 post.Name = xRUentry.Item("screen_name").InnerText
1918 post.Nickname = xRUentry.Item("name").InnerText
1919 post.ImageUrl = xRUentry.Item("profile_image_url").InnerText
1920 post.IsProtect = Boolean.Parse(xRUentry.Item("protected").InnerText)
1921 post.IsMe = post.Name.ToLower.Equals(_uid)
1922 If post.IsMe Then _UserIdNo = post.Uid.ToString()
1925 Dim xUentry As XmlElement = CType(xentry.SelectSingleNode("./user"), XmlElement)
1926 post.RetweetedBy = xUentry.Item("screen_name").InnerText
1928 post.PDate = DateTime.ParseExact(xentry.Item("created_at").InnerText, "ddd MMM dd HH:mm:ss zzzz yyyy", System.Globalization.DateTimeFormatInfo.InvariantInfo, System.Globalization.DateTimeStyles.None)
1930 post.Data = xentry.Item("text").InnerText
1931 'Source取得(htmlの場合は、中身を取り出し)
1932 post.Source = xentry.Item("source").InnerText
1933 Long.TryParse(xentry.Item("in_reply_to_status_id").InnerText, post.InReplyToId)
1934 post.InReplyToUser = xentry.Item("in_reply_to_screen_name").InnerText
1935 'in_reply_to_user_idを使うか?
1936 post.IsFav = Boolean.Parse(xentry.Item("favorited").InnerText)
1939 Dim xUentry As XmlElement = CType(xentry.SelectSingleNode("./user"), XmlElement)
1940 post.Uid = Long.Parse(xUentry.Item("id").InnerText)
1941 post.Name = xUentry.Item("screen_name").InnerText
1942 post.Nickname = xUentry.Item("name").InnerText
1943 post.ImageUrl = xUentry.Item("profile_image_url").InnerText
1944 post.IsProtect = Boolean.Parse(xUentry.Item("protected").InnerText)
1945 post.IsMe = post.Name.ToLower.Equals(_uid)
1946 If post.IsMe Then _UserIdNo = post.Uid.ToString()
1949 post.OriginalData = CreateHtmlAnchor(post.Data, post.ReplyToList)
1950 post.Data = HttpUtility.HtmlDecode(post.Data)
1951 post.Data = post.Data.Replace("<3", "♡")
1956 post.IsReply = post.ReplyToList.Contains(_uid)
1957 post.IsExcludeReply = False
1962 If followerId.Count > 0 Then post.IsOwl = Not followerId.Contains(post.Uid)
1966 Catch ex As Exception
1968 'MessageBox.Show("不正なXMLです。(TL-Parse)")
1972 '非同期アイコン取得&StatusDictionaryに追加
1974 dlgt(arIdx) = New GetIconImageDelegate(AddressOf GetIconImage)
1975 ar(arIdx) = dlgt(arIdx).BeginInvoke(post, Nothing, Nothing)
1979 For i As Integer = 0 To arIdx
1981 dlgt(i).EndInvoke(ar(i))
1982 Catch ex As Exception
1983 '最後までendinvoke回す(ゾンビ化回避)
1984 ex.Data("IsTerminatePermission") = False
1992 Public Function GetFollowersApi() As String
1993 If _endingFlag Then Return ""
1994 Dim cursor As Long = -1
1995 Dim tmpFollower As New List(Of Long)(followerId)
1999 Dim ret As String = FollowerApi(cursor)
2000 If Not String.IsNullOrEmpty(ret) Then
2002 followerId.AddRange(tmpFollower)
2003 _GetFollowerResult = False
2006 Loop While cursor > 0
2008 TabInformations.GetInstance.RefreshOwl(followerId)
2010 _GetFollowerResult = True
2014 Public ReadOnly Property GetFollowersSuccess() As Boolean
2016 Return _GetFollowerResult
2020 Private Function FollowerApi(ByRef cursor As Long) As String
2021 If Twitter.AccountState <> ACCOUNT_STATE.Valid Then Return ""
2023 Dim res As HttpStatusCode
2024 Dim content As String = ""
2026 res = twCon.FollowerIds(cursor, content)
2027 Catch ex As Exception
2028 Return "Err:" + ex.Message + "(" + GetCurrentMethod.Name + ")"
2032 Case HttpStatusCode.OK
2033 Twitter.AccountState = ACCOUNT_STATE.Valid
2034 Case HttpStatusCode.Unauthorized
2035 Twitter.AccountState = ACCOUNT_STATE.Invalid
2036 Return "Check your Username/Password."
2037 Case HttpStatusCode.BadRequest
2038 Return "Err:API Limits?"
2040 Return "Err:" + res.ToString() + "(" + GetCurrentMethod.Name + ")"
2043 Dim xdoc As New XmlDocument
2045 xdoc.LoadXml(content)
2046 Catch ex As Exception
2048 Return "Invalid XML!"
2052 For Each xentryNode As XmlNode In xdoc.DocumentElement.SelectNodes("/id_list/ids/id")
2053 followerId.Add(Long.Parse(xentryNode.InnerText))
2055 cursor = Long.Parse(xdoc.DocumentElement.SelectSingleNode("/id_list/next_cursor").InnerText)
2056 Catch ex As Exception
2058 Return "Invalid XML!"
2065 Public Function GetListsApi() As String
2066 If Twitter.AccountState <> ACCOUNT_STATE.Valid Then Return ""
2068 Dim res As HttpStatusCode
2069 Dim content As String = ""
2070 Dim cursor As Long = -1
2072 Dim lists As New List(Of ListElement)
2075 res = twCon.GetLists(Me.Username, cursor, content)
2076 Catch ex As Exception
2077 Return "Err:" + ex.Message + "(" + GetCurrentMethod.Name + ")"
2081 Case HttpStatusCode.OK
2082 Twitter.AccountState = ACCOUNT_STATE.Valid
2083 Case HttpStatusCode.Unauthorized
2084 Twitter.AccountState = ACCOUNT_STATE.Invalid
2085 Return "Check your Username/Password."
2086 Case HttpStatusCode.BadRequest
2087 Return "Err:API Limits?"
2089 Return "Err:" + res.ToString() + "(" + GetCurrentMethod.Name + ")"
2092 Dim xdoc As New XmlDocument
2094 xdoc.LoadXml(content)
2095 Catch ex As Exception
2097 Return "Invalid XML!"
2101 For Each xentryNode As XmlNode In xdoc.DocumentElement.SelectNodes("/lists_list/lists/list")
2102 lists.Add(New ListElement(xentryNode, Me))
2104 cursor = Long.Parse(xdoc.DocumentElement.SelectSingleNode("/lists_list/next_cursor").InnerText)
2105 Catch ex As Exception
2107 Return "Invalid XML!"
2109 Loop While cursor <> 0
2115 res = twCon.GetListsSubscriptions(Me.Username, cursor, content)
2116 Catch ex As Exception
2117 Return "Err:" + ex.Message + "(" + GetCurrentMethod.Name + ")"
2121 Case HttpStatusCode.OK
2122 Twitter.AccountState = ACCOUNT_STATE.Valid
2123 Case HttpStatusCode.Unauthorized
2124 Twitter.AccountState = ACCOUNT_STATE.Invalid
2125 Return "Check your Username/Password."
2126 Case HttpStatusCode.BadRequest
2127 Return "Err:API Limits?"
2129 Return "Err:" + res.ToString() + "(" + GetCurrentMethod.Name + ")"
2132 Dim xdoc As New XmlDocument
2134 xdoc.LoadXml(content)
2135 Catch ex As Exception
2137 Return "Invalid XML!"
2141 For Each xentryNode As XmlNode In xdoc.DocumentElement.SelectNodes("/lists_list/lists/list")
2142 lists.Add(New ListElement(xentryNode, Me))
2144 cursor = Long.Parse(xdoc.DocumentElement.SelectSingleNode("/lists_list/next_cursor").InnerText)
2145 Catch ex As Exception
2147 Return "Invalid XML!"
2149 Loop While cursor <> 0
2151 TabInformations.GetInstance.SubscribableLists = lists
2155 Public Function DeleteList(ByVal list_id As String) As String
2156 Dim res As HttpStatusCode
2157 Dim content As String = ""
2160 res = twCon.DeleteListID(Me.Username, list_id, content)
2161 Catch ex As Exception
2162 Return "Err:" + ex.Message + "(" + GetCurrentMethod.Name + ")"
2166 Case HttpStatusCode.OK
2167 Twitter.AccountState = ACCOUNT_STATE.Valid
2168 Case HttpStatusCode.Unauthorized
2169 Twitter.AccountState = ACCOUNT_STATE.Invalid
2170 Return "Check your Username/Password."
2171 Case HttpStatusCode.BadRequest
2172 Return "Err:API Limits?"
2174 Return "Err:" + res.ToString() + "(" + GetCurrentMethod.Name + ")"
2180 Public Function EditList(ByVal list_id As String, ByVal new_name As String, ByVal isPrivate As Boolean, ByVal description As String, ByRef list As ListElement) As String
2181 Dim res As HttpStatusCode
2182 Dim content As String = ""
2183 Dim modeString As String = "public"
2185 modeString = "private"
2189 res = twCon.PostListID(Me.Username, list_id, new_name, modeString, description, content)
2190 Catch ex As Exception
2191 Return "Err:" + ex.Message + "(" + GetCurrentMethod.Name + ")"
2195 Case HttpStatusCode.OK
2196 Twitter.AccountState = ACCOUNT_STATE.Valid
2197 Case HttpStatusCode.Unauthorized
2198 Twitter.AccountState = ACCOUNT_STATE.Invalid
2199 Return "Check your Username/Password."
2200 Case HttpStatusCode.BadRequest
2201 Return "Err:API Limits?"
2203 Return "Err:" + res.ToString() + "(" + GetCurrentMethod.Name + ")"
2206 Dim xdoc As New XmlDocument
2208 xdoc.LoadXml(content)
2209 Dim newList As New ListElement(xdoc.DocumentElement, Me)
2210 list.Description = newList.Description
2211 list.Id = newList.Id
2212 list.IsPublic = newList.IsPublic
2213 list.MemberCount = newList.MemberCount
2214 list.Name = newList.Name
2215 list.SubscriberCount = newList.SubscriberCount
2216 list.Slug = newList.Slug
2217 list.Nickname = newList.Nickname
2218 list.Username = newList.Username
2219 list.UserId = newList.UserId
2220 Catch ex As Exception
2222 Return "Invalid XML!"
2228 Public Function GetListMembers(ByVal list_id As String, ByVal lists As List(Of UserInfo), ByRef cursor As Long) As String
2229 If Twitter.AccountState <> ACCOUNT_STATE.Valid Then Return ""
2231 Dim res As HttpStatusCode
2232 Dim content As String = ""
2233 'Dim cursor As Long = -1
2237 res = twCon.GetListMembers(Me.Username, list_id, cursor, content)
2238 Catch ex As Exception
2239 Return "Err:" + ex.Message
2243 Case HttpStatusCode.OK
2244 Twitter.AccountState = ACCOUNT_STATE.Valid
2245 Case HttpStatusCode.Unauthorized
2246 Twitter.AccountState = ACCOUNT_STATE.Invalid
2247 Return "Check your Username/Password."
2248 Case HttpStatusCode.BadRequest
2249 Return "Err:API Limits?"
2251 Return "Err:" + res.ToString() + "(" + GetCurrentMethod.Name + ")"
2254 Dim xdoc As New XmlDocument
2256 xdoc.LoadXml(content)
2257 Catch ex As Exception
2259 Return "Invalid XML!"
2263 For Each xentryNode As XmlNode In xdoc.DocumentElement.SelectNodes("/users_list/users/user")
2264 lists.Add(New UserInfo(xentryNode))
2266 cursor = Long.Parse(xdoc.DocumentElement.SelectSingleNode("/users_list/next_cursor").InnerText)
2267 Catch ex As Exception
2269 Return "Invalid XML!"
2271 'Loop While cursor <> 0
2276 Public Function CreateListApi(ByVal listName As String, ByVal isPrivate As Boolean, ByVal description As String) As String
2277 If Twitter.AccountState <> ACCOUNT_STATE.Valid Then Return ""
2279 Dim res As HttpStatusCode
2280 Dim content As String = ""
2283 res = twCon.PostLists(Me.Username, listName, isPrivate, description, content)
2284 Catch ex As Exception
2285 Return "Err:" + ex.Message + "(" + GetCurrentMethod.Name + ")"
2289 Case HttpStatusCode.OK
2290 Twitter.AccountState = ACCOUNT_STATE.Valid
2291 Case HttpStatusCode.Unauthorized
2292 Twitter.AccountState = ACCOUNT_STATE.Invalid
2293 Return "Check your Username/Password."
2294 Case HttpStatusCode.BadRequest
2295 Return "Err:API Limits?"
2297 Return "Err:" + res.ToString() + "(" + GetCurrentMethod.Name + ")"
2300 Dim xdoc As New XmlDocument
2302 xdoc.LoadXml(content)
2304 TabInformations.GetInstance().SubscribableLists.Add(New ListElement(xdoc.DocumentElement, Me))
2305 Catch ex As Exception
2307 Return "Invalid XML!"
2313 Public Function ContainsUserAtList(ByVal list_name As String, ByVal user As String, ByRef value As Boolean) As String
2316 If Twitter.AccountState <> ACCOUNT_STATE.Valid Then Return ""
2318 Dim res As HttpStatusCode
2319 Dim content As String = ""
2322 res = Me.twCon.GetListMembersID(Me.Username, list_name, user, content)
2323 Catch ex As Exception
2324 Return "Err:" + ex.Message + "(" + GetCurrentMethod.Name + ")"
2328 Case HttpStatusCode.OK
2329 Twitter.AccountState = ACCOUNT_STATE.Valid
2330 Case HttpStatusCode.Unauthorized
2331 Twitter.AccountState = ACCOUNT_STATE.Invalid
2332 Return "Check your Username/Password."
2333 Case HttpStatusCode.BadRequest
2334 Return "Err:API Limits?"
2335 Case HttpStatusCode.NotFound
2339 Return "Err:" + res.ToString() + "(" + GetCurrentMethod.Name + ")"
2342 Dim xdoc As New XmlDocument
2344 xdoc.LoadXml(content)
2345 value = xdoc.DocumentElement.Name = "user"
2346 Catch ex As Exception
2348 Return "Invalid XML!"
2354 Public Function AddUserToList(ByVal list_name As String, ByVal user As String) As String
2355 Dim content As String = ""
2356 Dim res As HttpStatusCode
2359 res = twCon.PostListMembers(Me.Username, list_name, user, content)
2360 Catch ex As Exception
2361 Return "Err:" + ex.Message + "(" + GetCurrentMethod.Name + ")"
2367 Public Function RemoveUserToList(ByVal list_name As String, ByVal user As String) As String
2368 Dim content As String = ""
2369 Dim res As HttpStatusCode
2372 res = twCon.DeleteListMembers(Me.Username, list_name, user, content)
2373 Catch ex As Exception
2374 Return "Err:" + ex.Message + "(" + GetCurrentMethod.Name + ")"
2381 Public Property fromIndex As Integer
2382 Public Property toIndex As Integer
2383 Public Sub New(ByVal fromIndex As Integer, ByVal toIndex As Integer)
2384 Me.fromIndex = fromIndex
2385 Me.toIndex = toIndex
2388 Public Function CreateHtmlAnchor(ByVal Text As String, ByVal AtList As List(Of String)) As String
2389 Dim retStr As String = Text.Replace(">", "<<<<<tweenだいなり>>>>>").Replace("<", "<<<<<tweenしょうなり>>>>>")
2391 'Const rgUrl As String = "(?<before>(?:[^\""':!=]|^|\:))" + _
2392 ' "(?<url>(?<protocol>https?://|www\.)" + _
2393 ' "(?<domain>(?:[\.-]|[^\p{P}\s])+\.[a-z]{2,}(?::[0-9]+)?)" + _
2394 ' "(?<path>/[a-z0-9!*'();:&=+$/%#\[\]\-_.,~@^]*[a-z0-9)=#/]?)?" + _
2395 ' "(?<query>\?[a-z0-9!*'();:&=+$/%#\[\]\-_.,~]*[a-z0-9_&=#])?)"
2396 Const url_valid_general_path_chars As String = "[a-z0-9!*';:=+$/%#\[\]\-_,~]"
2397 Const url_valid_url_path_ending_chars As String = "[a-z0-9=#/]"
2398 Const pth As String = "(?<path>/(?:(?:\(" + url_valid_general_path_chars + "+\))" +
2399 "|@" + url_valid_general_path_chars + "+/" +
2400 "|[.,]?" + url_valid_general_path_chars +
2402 url_valid_url_path_ending_chars + "?)?"
2403 Const qry As String = "(?<query>\?[a-z0-9!*'();:&=+$/%#\[\]\-_.,~]*[a-z0-9_&=#])?"
2404 Const rgUrl As String = "(?<before>(?:[^\""':!=]|^|\:))" +
2405 "(?<url>(?<protocol>https?://|www\.)" +
2406 "(?<domain>(?:[\.-]|[^\p{P}\s])+\.[a-z]{2,}(?::[0-9]+)?)" +
2411 retStr = Regex.Replace(retStr,
2413 New MatchEvaluator(Function(mu As Match)
2414 Dim sb As New StringBuilder(mu.Result("${before}<a href="""))
2415 If mu.Result("${protocol}").StartsWith("w", StringComparison.OrdinalIgnoreCase) Then
2416 sb.Append("http://")
2418 sb.Append(mu.Result("${url}"">")).Append(mu.Result("${url}")).Append("</a>")
2421 RegexOptions.IgnoreCase)
2424 retStr = Regex.Replace(retStr,
2425 "(^|[^a-zA-Z0-9_/])([@@]+)([a-zA-Z0-9_]{1,20}/[a-zA-Z][a-zA-Z0-9\p{IsLatin-1Supplement}\-]{0,79})",
2426 "$1$2<a href=""/$3"">$3</a>")
2428 Dim m As Match = Regex.Match(retStr, "(^|[^a-zA-Z0-9_])[@@]([a-zA-Z0-9_]{1,20})")
2430 If Not AtList.Contains(m.Result("$2").ToLower) Then AtList.Add(m.Result("$2").ToLower)
2434 retStr = Regex.Replace(retStr,
2435 "(^|[^a-zA-Z0-9_/])([@@])([a-zA-Z0-9_]{1,20})",
2436 "$1$2<a href=""/$3"">$3</a>")
2439 Dim anchorRange As New List(Of range)
2440 For i As Integer = 0 To retStr.Length - 1
2441 Dim index As Integer = retStr.IndexOf("<a ", i)
2442 If index > -1 AndAlso index < retStr.Length Then
2444 Dim toIndex As Integer = retStr.IndexOf("</a>", index)
2445 If toIndex > -1 Then
2446 anchorRange.Add(New range(index, toIndex + 3))
2451 retStr = Regex.Replace(retStr,
2452 "(^|[^a-zA-Z0-9/&])([##])([0-9a-zA-Z_]*[a-zA-Z_]+[a-zA-Z0-9_\xc0-\xd6\xd8-\xf6\xf8-\xff]*)",
2453 New MatchEvaluator(Function(mh As Match)
2454 For Each rng As range In anchorRange
2455 If mh.Index >= rng.fromIndex AndAlso
2456 mh.Index <= rng.toIndex Then Return mh.Result("$0")
2458 If IsNumeric(mh.Result("$3")) Then Return mh.Result("$0")
2460 _hashList.Add("#" + mh.Result("$3"))
2462 Return mh.Result("$1") + "<a href=""" & _protocol & "twitter.com/search?q=%23" + mh.Result("$3") + """>" + mh.Result("$2$3") + "</a>"
2464 RegexOptions.IgnoreCase)
2466 'Dim mhs As MatchCollection = Regex.Matches(retStr, "(^|[^a-zA-Z0-9/&])[##]([0-9a-zA-Z_]*[a-zA-Z_]+[a-zA-Z_\xc0-\xd6\xd8-\xf6\xf8-\xff]*)")
2467 'For Each mt As Match In mhs
2468 ' If Not IsNumeric(mt.Result("$2")) Then
2469 ' 'retStr = retStr.Replace(mt.Result("$1") + mt.Result("$2"), "<a href=""" + _protocol + "twitter.com/search?q=%23" + mt.Result("$2") + """>#" + mt.Result("$2") + "</a>")
2471 ' _hashList.Add("#" + mt.Result("$2"))
2475 'retStr = Regex.Replace(retStr, "(^|[^a-zA-Z0-9/&])([##])([0-9a-zA-Z_]*[a-zA-Z_]+[a-zA-Z0-9_\xc0-\xd6\xd8-\xf6\xf8-\xff]*)", "$1<a href=""" & _protocol & "twitter.com/search?q=%23$3"">$2$3</a>")
2477 retStr = Regex.Replace(retStr, "(^|[^a-zA-Z0-9_/&##@@>=.])(sm|nm)([0-9]{1,10})", "$1<a href=""http://www.nicovideo.jp/watch/$2$3"">$2$3</a>")
2479 retStr = retStr.Replace("<<<<<tweenだいなり>>>>>", ">").Replace("<<<<<tweenしょうなり>>>>>", "<")
2481 retStr = AdjustHtml(ShortUrl.Resolve(PreProcessUrl(retStr))) 'IDN置換、短縮Uri解決、@リンクを相対→絶対にしてtarget属性付与
2486 Private Sub CreateSource(ByRef post As PostClass)
2487 If post.Source.StartsWith("<") Then
2488 If Not post.Source.Contains("</a>") Then
2489 post.Source += "</a>"
2491 post.SourceHtml = String.Copy(ShortUrl.Resolve(PreProcessUrl(post.Source)))
2492 Dim mS As Match = Regex.Match(post.Source, ">(?<source>.+)<")
2494 post.Source = HttpUtility.HtmlDecode(mS.Result("${source}"))
2497 If post.Source = "web" Then
2498 post.SourceHtml = My.Resources.WebSourceString
2499 ElseIf post.Source = "Keitai Mail" Then
2500 post.SourceHtml = My.Resources.KeitaiMailSourceString
2502 post.SourceHtml = String.Copy(post.Source)
2507 Public Function GetInfoApi(ByVal info As ApiInfo) As Boolean
2508 If Twitter.AccountState <> ACCOUNT_STATE.Valid Then Return True
2510 If _endingFlag Then Return True
2512 Dim res As HttpStatusCode
2513 Dim content As String = ""
2515 res = twCon.RateLimitStatus(content)
2516 Catch ex As Exception
2517 TwitterApiInfo.Initialize()
2521 If res <> HttpStatusCode.OK Then Return False
2523 Dim xdoc As New XmlDocument
2525 xdoc.LoadXml(content)
2526 Dim arg As New ApiInformationChangedEventArgs
2528 arg.ApiInfo.MaxCount = Integer.Parse(xdoc.SelectSingleNode("/hash/hourly-limit").InnerText)
2529 arg.ApiInfo.RemainCount = Integer.Parse(xdoc.SelectSingleNode("/hash/remaining-hits").InnerText)
2530 arg.ApiInfo.ResetTime = DateTime.Parse(xdoc.SelectSingleNode("/hash/reset-time").InnerText)
2531 arg.ApiInfo.ResetTimeInSeconds = Integer.Parse(xdoc.SelectSingleNode("/hash/reset-time-in-seconds").InnerText)
2532 If info IsNot Nothing Then
2533 arg.ApiInfo.UsingCount = info.UsingCount
2535 info.MaxCount = arg.ApiInfo.MaxCount
2536 info.RemainCount = arg.ApiInfo.RemainCount
2537 info.ResetTime = arg.ApiInfo.ResetTime
2538 info.ResetTimeInSeconds = arg.ApiInfo.ResetTimeInSeconds
2541 RaiseEvent ApiInformationChanged(Me, arg)
2542 TwitterApiInfo.WriteBackEventArgs(arg)
2544 Catch ex As Exception
2545 TwitterApiInfo.Initialize()
2550 Public Function GetHashList() As String()
2551 Dim hashArray As String()
2553 hashArray = _hashList.ToArray
2559 Public ReadOnly Property AccessToken() As String
2561 Return twCon.AccessToken
2565 Public ReadOnly Property AccessTokenSecret() As String
2567 Return twCon.AccessTokenSecret
2571 Public Property UserIdNo As String
2573 Public Event ApiInformationChanged(ByVal sender As Object, ByVal e As ApiInformationChangedEventArgs)
2575 Private Sub Twitter_ApiInformationChanged(ByVal sender As Object, ByVal e As ApiInformationChangedEventArgs) Handles Me.ApiInformationChanged