• R/O
  • HTTP
  • SSH
  • HTTPS

open-tween: Commit

開発に使用するリポジトリ


Commit MetaInfo

Revision2e071159cebdcf934eafa43ba76731e929014cac (tree)
Time2012-02-18 23:11:09
Authorkiri_feather <kiri_feather@user...>
CommiterKimura Youichi

Log Message

0881開発版。OAuth(xAuth)対応。URL検出正規表現修正。

git-svn-id: http://svn.sourceforge.jp/svnroot/tween/trunk@116 e39ad16e-3079-482e-bb30-4b4d378143b6

Change Summary

Incremental Difference

--- a/Tween/Connection/HttpConnection.vb
+++ b/Tween/Connection/HttpConnection.vb
@@ -56,7 +56,7 @@ Public Class HttpConnection
5656 '''<returns>引数で指定された内容を反映したHttpWebRequestオブジェクト</returns>
5757 Protected Function CreateRequest(ByVal method As RequestMethod, _
5858 ByVal requestUri As Uri, _
59- ByVal param As SortedList(Of String, String), _
59+ ByVal param As Dictionary(Of String, String), _
6060 ByVal withCookie As Boolean _
6161 ) As HttpWebRequest
6262 If Not isInitialize Then Throw New Exception("Sequence error.(not initialized)")
@@ -166,7 +166,7 @@ Public Class HttpConnection
166166 End Function
167167
168168 Protected Function GetResponse(ByVal webRequest As HttpWebRequest, _
169- ByVal contentBitmap As Bitmap, _
169+ ByRef contentBitmap As Bitmap, _
170170 ByVal headerInfo As Dictionary(Of String, String), _
171171 ByVal withCookie As Boolean _
172172 ) As HttpStatusCode
@@ -251,7 +251,7 @@ Public Class HttpConnection
251251 '''クエリコレクションをkey=value形式の文字列に構成して戻す
252252 '''</summary>
253253 '''<param name="param">クエリ、またはポストデータとなるkey-valueコレクション</param>
254- Protected Function CreateQueryString(ByVal param As SortedList(Of String, String)) As String
254+ Protected Function CreateQueryString(ByVal param As IDictionary(Of String, String)) As String
255255 If param Is Nothing OrElse param.Count = 0 Then Return String.Empty
256256
257257 Dim query As New StringBuilder
--- a/Tween/Connection/HttpConnectionApi.vb
+++ b/Tween/Connection/HttpConnectionApi.vb
@@ -10,7 +10,7 @@ Public Class HttpConnectionApi
1010
1111 Protected Function GetContent(ByVal method As RequestMethod, _
1212 ByVal requestUri As Uri, _
13- ByVal param As SortedList(Of String, String), _
13+ ByVal param As Dictionary(Of String, String), _
1414 ByRef content As String, _
1515 ByVal headerInfo As Dictionary(Of String, String), _
1616 ByVal authRequired As Boolean) As HttpStatusCode
--- a/Tween/Connection/HttpConnectionOAuth.vb
+++ b/Tween/Connection/HttpConnectionOAuth.vb
@@ -21,24 +21,24 @@ Public Class HttpConnectionOAuth
2121 '''<summary>
2222 '''OAuthのアクセストークン。永続化可能(ユーザー取り消しの可能性はある)。
2323 '''</summary>
24- Private Shared token As String = ""
24+ Private token As String = ""
2525
2626 '''<summary>
2727 '''OAuthの署名作成用秘密アクセストークン。永続化可能(ユーザー取り消しの可能性はある)。
2828 '''</summary>
29- Private Shared tokenSecret As String = ""
29+ Private tokenSecret As String = ""
3030
3131 '''<summary>
3232 '''OAuthのコンシューマー鍵
3333 '''</summary>
34- Private Shared consumerKey As String
34+ Private consumerKey As String
3535
3636 '''<summary>
3737 '''OAuthの署名作成用秘密コンシューマーデータ
3838 '''</summary>
39- Private Shared consumerSecret As String
39+ Private consumerSecret As String
4040
41- Private Shared authorizedUsername As String
41+ Private authorizedUsername As String
4242 '''<summary>
4343 '''HTTP通信してコンテンツを取得する(文字列コンテンツ)
4444 '''</summary>
@@ -55,7 +55,7 @@ Public Class HttpConnectionOAuth
5555 '''<returns>通信結果のHttpStatusCode</returns>
5656 Protected Function GetContent(ByVal method As RequestMethod, _
5757 ByVal requestUri As Uri, _
58- ByVal param As SortedList(Of String, String), _
58+ ByVal param As Dictionary(Of String, String), _
5959 ByRef content As String, _
6060 ByVal headerInfo As Dictionary(Of String, String)) As HttpStatusCode
6161 '認証済かチェック
@@ -76,22 +76,21 @@ Public Class HttpConnectionOAuth
7676 End Function
7777
7878 #Region "認証処理"
79- Protected Function AuthorizePinFlow(ByVal requestTokenUrl As String, _
80- ByVal accessTokenUrl As String, _
81- ByVal authorizeUrl As String) As Boolean
79+ Protected Function AuthorizePinFlowRequest(ByVal requestTokenUrl As String, _
80+ ByVal authorizeUrl As String, _
81+ ByRef requestToken As String, _
82+ ByRef authUri As Uri) As Boolean
8283 'PIN-based flow
83- Dim requestToken As String = ""
84- Dim authUri As Uri = GetAuthorizePageUri(requestTokenUrl, authorizeUrl, requestToken)
84+ authUri = GetAuthorizePageUri(requestTokenUrl, authorizeUrl, requestToken)
8585 If authUri Is Nothing Then Return False
86- System.Diagnostics.Process.Start(authUri.PathAndQuery) 'ブラウザで表示
87- Dim inputForm As New InputTabName
88- inputForm.FormTitle = "Input PIN code"
89- inputForm.FormDescription = "Input the PIN code shown in the browser after you accept OAuth request."
90- If inputForm.ShowDialog() = DialogResult.OK AndAlso Not String.IsNullOrEmpty(inputForm.TabName) Then
91- Return GetAccessToken(accessTokenUrl, inputForm.TabName, requestToken)
92- Else
93- Return False
94- End If
86+ Return True
87+ End Function
88+
89+ Protected Function AuthorizePinFlow(ByVal accessTokenUrl As String, _
90+ ByVal requestToken As String, _
91+ ByVal pinCode As String) As Boolean
92+ 'PIN-based flow
93+ Return GetAccessToken(accessTokenUrl, pinCode, requestToken)
9594 End Function
9695
9796 Protected Function AuthorizeXAuth(ByVal url As String, ByVal username As String, ByVal password As String) As Boolean
@@ -99,40 +98,29 @@ Public Class HttpConnectionOAuth
9998 If String.IsNullOrEmpty(username) OrElse String.IsNullOrEmpty(password) Then
10099 Throw New Exception("Sequence error.(username or password is blank)")
101100 End If
102- Dim reqUri As New Uri(url)
103- Dim parameter As New SortedList(Of String, String)
101+ Dim parameter As New Dictionary(Of String, String)
104102 parameter.Add("x_auth_mode", "client_auth")
105103 parameter.Add("x_auth_username", username)
106104 parameter.Add("x_auth_password", password)
107105
108- webReq = CreateRequest(RequestMethod.ReqPost, reqUri, parameter, False)
106+ Dim accessTokenData As NameValueCollection = GetOAuthToken(New Uri(url), "", "", parameter)
109107
110- AppendOAuthInfo(webReq, parameter, "", "")
111-
112- Try
113- Dim status As HttpStatusCode
114- Dim contentText As String = ""
115- status = GetResponse(webReq, contentText, Nothing, False)
116- If status = HttpStatusCode.OK Then
117- Dim tokenData As NameValueCollection = ParseQueryString(contentText)
118- token = tokenData.Item("oauth_token")
119- tokenSecret = tokenData.Item("oauth_token_secret")
120- ''' TODO:その他情報も格納するか検討(user_idなど)
121- If token = "" Then Return False
122- Return True
123- Else
124- Return False
125- End If
126- Catch ex As Exception
108+ If accessTokenData IsNot Nothing Then
109+ token = accessTokenData.Item("oauth_token")
110+ tokenSecret = accessTokenData.Item("oauth_token_secret")
111+ authorizedUsername = accessTokenData.Item("screen_name")
112+ If token = "" Then Return False
113+ Return True
114+ Else
127115 Return False
128- End Try
116+ End If
129117 End Function
130118
131119 Private Function GetAuthorizePageUri(ByVal requestTokenUrl As String, _
132120 ByVal authorizeUrl As String, _
133121 ByRef requestToken As String) As Uri
134122 Const tokenKey As String = "oauth_token"
135- Dim reqTokenData As NameValueCollection = GetOAuthToken(New Uri(requestTokenUrl), "", "")
123+ Dim reqTokenData As NameValueCollection = GetOAuthToken(New Uri(requestTokenUrl), "", "", Nothing)
136124 If reqTokenData IsNot Nothing Then
137125 requestToken = reqTokenData.Item(tokenKey)
138126 Dim ub As New UriBuilder(authorizeUrl)
@@ -146,7 +134,7 @@ Public Class HttpConnectionOAuth
146134 Private Function GetAccessToken(ByVal accessTokenUrl As String, ByVal pinCode As String, ByVal requestToken As String) As Boolean
147135 If String.IsNullOrEmpty(requestToken) Then Throw New Exception("Sequence error.(requestToken is blank)")
148136
149- Dim accessTokenData As NameValueCollection = GetOAuthToken(New Uri(accessTokenUrl), pinCode, requestToken)
137+ Dim accessTokenData As NameValueCollection = GetOAuthToken(New Uri(accessTokenUrl), pinCode, requestToken, Nothing)
150138
151139 If accessTokenData IsNot Nothing Then
152140 token = accessTokenData.Item("oauth_token")
@@ -158,14 +146,19 @@ Public Class HttpConnectionOAuth
158146 End If
159147 End Function
160148
161- Private Function GetOAuthToken(ByVal requestUri As Uri, ByVal pinCode As String, ByVal requestToken As String) As NameValueCollection
149+ Private Function GetOAuthToken(ByVal requestUri As Uri, ByVal pinCode As String, ByVal requestToken As String, ByVal parameter As Dictionary(Of String, String)) As NameValueCollection
162150 Dim webReq As HttpWebRequest = Nothing
163- If String.IsNullOrEmpty(pinCode) Then
151+ If String.IsNullOrEmpty(pinCode) AndAlso parameter Is Nothing Then
164152 webReq = CreateRequest(RequestMethod.ReqGet, requestUri, Nothing, False)
165153 Else
166- webReq = CreateRequest(RequestMethod.ReqPost, requestUri, Nothing, False)
154+ webReq = CreateRequest(RequestMethod.ReqPost, requestUri, parameter, False)
155+ End If
156+ Dim query As New Dictionary(Of String, String)
157+ If parameter IsNot Nothing Then
158+ For Each kvp As KeyValuePair(Of String, String) In parameter
159+ query.Add(kvp.Key, kvp.Value)
160+ Next
167161 End If
168- Dim query As New SortedList(Of String, String)
169162 If Not String.IsNullOrEmpty(pinCode) Then query.Add("oauth_verifier", pinCode)
170163 AppendOAuthInfo(webReq, query, requestToken, "")
171164 Try
@@ -185,10 +178,10 @@ Public Class HttpConnectionOAuth
185178
186179 #Region "OAuth認証用ヘッダ作成・付加処理"
187180 Private Sub AppendOAuthInfo(ByVal webRequest As HttpWebRequest, _
188- ByVal query As SortedList(Of String, String), _
181+ ByVal query As Dictionary(Of String, String), _
189182 ByVal token As String, _
190183 ByVal tokenSecret As String)
191- Dim parameter As SortedList(Of String, String) = GetOAuthParameter(token)
184+ Dim parameter As Dictionary(Of String, String) = GetOAuthParameter(token)
192185 If query IsNot Nothing Then
193186 For Each item As KeyValuePair(Of String, String) In query
194187 parameter.Add(item.Key, item.Value)
@@ -204,8 +197,8 @@ Public Class HttpConnectionOAuth
204197 webRequest.Headers.Add(HttpRequestHeader.Authorization, sb.ToString)
205198 End Sub
206199
207- Private Function GetOAuthParameter(ByVal token As String) As SortedList(Of String, String)
208- Dim parameter As New SortedList(Of String, String)
200+ Private Function GetOAuthParameter(ByVal token As String) As Dictionary(Of String, String)
201+ Dim parameter As New Dictionary(Of String, String)
209202 parameter.Add("oauth_consumer_key", consumerKey)
210203 parameter.Add("oauth_signature_method", "HMAC-SHA1")
211204 parameter.Add("oauth_timestamp", GetTimestamp())
@@ -218,9 +211,10 @@ Public Class HttpConnectionOAuth
218211 Private Function CreateSignature(ByVal tokenSecret As String, _
219212 ByVal method As String, _
220213 ByVal uri As Uri, _
221- ByVal parameter As SortedList(Of String, String) _
214+ ByVal parameter As Dictionary(Of String, String) _
222215 ) As String
223- Dim paramString As String = CreateQueryString(parameter)
216+ Dim sorted As New SortedDictionary(Of String, String)(parameter)
217+ Dim paramString As String = CreateQueryString(sorted)
224218 Dim url As String = String.Format("{0}://{1}{2}", uri.Scheme, uri.Host, uri.AbsolutePath)
225219 Dim signatureBase As String = String.Format("{0}&{1}&{2}", method, UrlEncode(url), UrlEncode(paramString))
226220 Dim key As String = UrlEncode(consumerSecret) + "&"
@@ -239,17 +233,17 @@ Public Class HttpConnectionOAuth
239233 End Function
240234 #End Region
241235
242- Protected Shared Sub Initialize(ByVal consumerKeyStr As String, _
236+ Protected Sub Initialize(ByVal consumerKeyStr As String, _
243237 ByVal consumerSecretStr As String, _
244238 ByVal accessToken As String, _
245239 ByVal accessTokenSecret As String)
246- consumerKey = consumerKeyStr
247- consumerSecret = consumerSecretStr
248- HttpConnectionOAuth.token = accessToken
249- HttpConnectionOAuth.tokenSecret = accessTokenSecret
240+ Me.consumerKey = consumerKeyStr
241+ Me.consumerSecret = consumerSecretStr
242+ Me.token = accessToken
243+ Me.tokenSecret = accessTokenSecret
250244 End Sub
251245
252- Protected Shared Sub Initialize(ByVal consumerKeyStr As String, _
246+ Protected Sub Initialize(ByVal consumerKeyStr As String, _
253247 ByVal consumerSecretStr As String, _
254248 ByVal accessToken As String, _
255249 ByVal accessTokenSecret As String, _
@@ -258,21 +252,21 @@ Public Class HttpConnectionOAuth
258252 authorizedUsername = username
259253 End Sub
260254
261- Protected Shared ReadOnly Property AccessToken() As String
255+ Protected ReadOnly Property AccessToken() As String
262256 Get
263- Return HttpConnectionOAuth.token
257+ Return token
264258 End Get
265259 End Property
266260
267- Protected Shared ReadOnly Property AccessTokenSecret() As String
261+ Protected ReadOnly Property AccessTokenSecret() As String
268262 Get
269- Return HttpConnectionOAuth.tokenSecret
263+ Return tokenSecret
270264 End Get
271265 End Property
272266
273- Protected Shared ReadOnly Property AuthUsername() As String
267+ Protected ReadOnly Property AuthUsername() As String
274268 Get
275- Return HttpConnectionOAuth.authorizedUsername
269+ Return authorizedUsername
276270 End Get
277271 End Property
278272 End Class
--- a/Tween/Connection/HttpTwitter.vb
+++ b/Tween/Connection/HttpTwitter.vb
@@ -7,12 +7,12 @@ Public Class HttpTwitter
77 '''<summary>
88 '''OAuthのコンシューマー鍵
99 '''</summary>
10- Private Const ConsumerKey As String = "EANjQEa5LokuVld682tTDA"
10+ Private Const ConsumerKey As String = "iOQHfiCUsyOyamW8JJ8jg"
1111
1212 '''<summary>
1313 '''OAuthの署名作成用秘密コンシューマーデータ
1414 '''</summary>
15- Private Const ConsumerSecret As String = "zXfwkzmuO6FcHtoikleV3EVgdh5vVAs6ft6ZxtYTYM"
15+ Private Const ConsumerSecret As String = "5PS2oa5f2VaKMPrlZa7DTbz0aFULKd3Ojxqgsm142Dw"
1616
1717 '''<summary>
1818 '''OAuthのアクセストークン取得先URI
@@ -29,24 +29,24 @@ Public Class HttpTwitter
2929 Public Overloads Sub Initialize(ByVal accessToken As String, _
3030 ByVal accessTokenSecret As String, _
3131 ByVal username As String)
32- HttpConnectionOAuth.Initialize(ConsumerKey, ConsumerSecret, accessToken, accessTokenSecret, username)
32+ Initialize(ConsumerKey, ConsumerSecret, accessToken, accessTokenSecret, username)
3333 End Sub
3434
3535 Public Overloads ReadOnly Property AccessToken() As String
3636 Get
37- Return HttpConnectionOAuth.AccessToken
37+ Return MyBase.AccessToken
3838 End Get
3939 End Property
4040
4141 Public Overloads ReadOnly Property AccessTokenSecret() As String
4242 Get
43- Return HttpConnectionOAuth.AccessTokenSecret
43+ Return MyBase.AccessTokenSecret
4444 End Get
4545 End Property
4646
4747 Public Overloads ReadOnly Property AuthUsername() As String
4848 Get
49- Return HttpConnectionOAuth.AuthUsername
49+ Return MyBase.AuthUsername
5050 End Get
5151 End Property
5252
@@ -55,7 +55,7 @@ Public Class HttpTwitter
5555 End Function
5656
5757 Public Sub ClearAuthInfo()
58- HttpConnectionOAuth.Initialize(ConsumerKey, ConsumerSecret, "", "", "")
58+ MyBase.Initialize(ConsumerKey, ConsumerSecret, "", "", "")
5959 End Sub
6060
6161 Public Shared WriteOnly Property UseSsl() As Boolean
@@ -75,10 +75,10 @@ Public Class HttpTwitter
7575 End Property
7676
7777 Public Function UpdateStatus(ByVal status As String, ByVal replyToId As Long, ByRef content As String) As HttpStatusCode
78- If HttpConnectionOAuth.AuthUsername = "" Then
78+ If Me.AuthUsername = "" Then
7979 Return HttpStatusCode.Unauthorized
8080 End If
81- Dim param As New SortedList(Of String, String)
81+ Dim param As New Dictionary(Of String, String)
8282 param.Add("status", status)
8383 If replyToId > 0 Then param.Add("in_reply_to_status_id", replyToId.ToString)
8484 Try
@@ -97,7 +97,7 @@ Public Class HttpTwitter
9797 End Function
9898
9999 Public Function DestroyStatus(ByVal id As Long) As HttpStatusCode
100- If HttpConnectionOAuth.AuthUsername = "" Then
100+ If Me.AuthUsername = "" Then
101101 Return HttpStatusCode.Unauthorized
102102 End If
103103 Try
@@ -116,7 +116,7 @@ Public Class HttpTwitter
116116 End Function
117117
118118 Public Function DestroyDirectMessage(ByVal id As Long) As HttpStatusCode
119- If HttpConnectionOAuth.AuthUsername = "" Then
119+ If Me.AuthUsername = "" Then
120120 Return HttpStatusCode.Unauthorized
121121 End If
122122 Try
@@ -135,7 +135,7 @@ Public Class HttpTwitter
135135 End Function
136136
137137 Public Function RetweetStatus(ByVal id As Long, ByRef content As String) As HttpStatusCode
138- If HttpConnectionOAuth.AuthUsername = "" Then
138+ If Me.AuthUsername = "" Then
139139 Return HttpStatusCode.Unauthorized
140140 End If
141141 Try
@@ -154,10 +154,10 @@ Public Class HttpTwitter
154154 End Function
155155
156156 Public Function CreateFriendships(ByVal screenName As String) As HttpStatusCode
157- If HttpConnectionOAuth.AuthUsername = "" Then
157+ If Me.AuthUsername = "" Then
158158 Return HttpStatusCode.Unauthorized
159159 End If
160- Dim param As New SortedList(Of String, String)
160+ Dim param As New Dictionary(Of String, String)
161161 param.Add("screen_name", screenName)
162162 Try
163163 Return GetContent(RequestMethod.ReqPost, _
@@ -175,10 +175,10 @@ Public Class HttpTwitter
175175 End Function
176176
177177 Public Function DestroyFriendships(ByVal screenName As String) As HttpStatusCode
178- If HttpConnectionOAuth.AuthUsername = "" Then
178+ If Me.AuthUsername = "" Then
179179 Return HttpStatusCode.Unauthorized
180180 End If
181- Dim param As New SortedList(Of String, String)
181+ Dim param As New Dictionary(Of String, String)
182182 param.Add("screen_name", screenName)
183183 Try
184184 Return GetContent(RequestMethod.ReqPost, _
@@ -196,10 +196,10 @@ Public Class HttpTwitter
196196 End Function
197197
198198 Public Function ShowFriendships(ByVal souceScreenName As String, ByVal targetScreenName As String, ByRef content As String) As HttpStatusCode
199- If HttpConnectionOAuth.AuthUsername = "" Then
199+ If Me.AuthUsername = "" Then
200200 Return HttpStatusCode.Unauthorized
201201 End If
202- Dim param As New SortedList(Of String, String)
202+ Dim param As New Dictionary(Of String, String)
203203 param.Add("source_screen_name", souceScreenName)
204204 param.Add("target_screen_name", targetScreenName)
205205 Try
@@ -218,7 +218,7 @@ Public Class HttpTwitter
218218 End Function
219219
220220 Public Function ShowStatuses(ByVal id As Long, ByRef content As String) As HttpStatusCode
221- If HttpConnectionOAuth.AuthUsername = "" Then
221+ If Me.AuthUsername = "" Then
222222 Return HttpStatusCode.Unauthorized
223223 End If
224224 Try
@@ -237,7 +237,7 @@ Public Class HttpTwitter
237237 End Function
238238
239239 Public Function CreateFavorites(ByVal id As Long) As HttpStatusCode
240- If HttpConnectionOAuth.AuthUsername = "" Then
240+ If Me.AuthUsername = "" Then
241241 Return HttpStatusCode.Unauthorized
242242 End If
243243 Try
@@ -256,7 +256,7 @@ Public Class HttpTwitter
256256 End Function
257257
258258 Public Function DestroyFavorites(ByVal id As Long) As HttpStatusCode
259- If HttpConnectionOAuth.AuthUsername = "" Then
259+ If Me.AuthUsername = "" Then
260260 Return HttpStatusCode.Unauthorized
261261 End If
262262 Try
@@ -275,10 +275,10 @@ Public Class HttpTwitter
275275 End Function
276276
277277 Public Function HomeTimeline(ByVal count As Integer, ByRef content As String) As HttpStatusCode
278- If HttpConnectionOAuth.AuthUsername = "" Then
278+ If Me.AuthUsername = "" Then
279279 Return HttpStatusCode.Unauthorized
280280 End If
281- Dim param As New SortedList(Of String, String)
281+ Dim param As New Dictionary(Of String, String)
282282 If count > 0 Then
283283 param.Add("count", count.ToString())
284284 End If
@@ -298,10 +298,10 @@ Public Class HttpTwitter
298298 End Function
299299
300300 Public Function Mentions(ByVal count As Integer, ByRef content As String) As HttpStatusCode
301- If HttpConnectionOAuth.AuthUsername = "" Then
301+ If Me.AuthUsername = "" Then
302302 Return HttpStatusCode.Unauthorized
303303 End If
304- Dim param As New SortedList(Of String, String)
304+ Dim param As New Dictionary(Of String, String)
305305 If count > 0 Then
306306 param.Add("count", count.ToString())
307307 End If
@@ -321,7 +321,7 @@ Public Class HttpTwitter
321321 End Function
322322
323323 Public Function DirectMessages(ByRef content As String) As HttpStatusCode
324- If HttpConnectionOAuth.AuthUsername = "" Then
324+ If Me.AuthUsername = "" Then
325325 Return HttpStatusCode.Unauthorized
326326 End If
327327 Try
@@ -340,7 +340,7 @@ Public Class HttpTwitter
340340 End Function
341341
342342 Public Function DirectMessagesSent(ByRef content As String) As HttpStatusCode
343- If HttpConnectionOAuth.AuthUsername = "" Then
343+ If Me.AuthUsername = "" Then
344344 Return HttpStatusCode.Unauthorized
345345 End If
346346 Try
@@ -359,10 +359,10 @@ Public Class HttpTwitter
359359 End Function
360360
361361 Public Function Favorites(ByVal count As Integer, ByRef content As String) As HttpStatusCode
362- If HttpConnectionOAuth.AuthUsername = "" Then
362+ If Me.AuthUsername = "" Then
363363 Return HttpStatusCode.Unauthorized
364364 End If
365- Dim param As New SortedList(Of String, String)
365+ Dim param As New Dictionary(Of String, String)
366366 If count <> 20 Then param.Add("count", count.ToString())
367367 Try
368368 Return GetContent(RequestMethod.ReqGet, _
@@ -380,7 +380,7 @@ Public Class HttpTwitter
380380 End Function
381381
382382 Public Function Search(ByVal words As String, ByVal lang As String, ByVal rpp As Integer, ByVal page As Integer, ByRef content As String) As HttpStatusCode
383- Dim param As New SortedList(Of String, String)
383+ Dim param As New Dictionary(Of String, String)
384384 If Not String.IsNullOrEmpty(words) Then param.Add("q", words)
385385 If Not String.IsNullOrEmpty(lang) Then param.Add("lang", lang)
386386 If rpp > 0 Then param.Add("rpp", rpp.ToString())
@@ -405,10 +405,10 @@ Public Class HttpTwitter
405405 End Function
406406
407407 Public Function FollowerIds(ByVal cursor As Long, ByRef content As String) As HttpStatusCode
408- If HttpConnectionOAuth.AuthUsername = "" Then
408+ If Me.AuthUsername = "" Then
409409 Return HttpStatusCode.Unauthorized
410410 End If
411- Dim param As New SortedList(Of String, String)
411+ Dim param As New Dictionary(Of String, String)
412412 param.Add("cursor", cursor.ToString())
413413 Try
414414 Return GetContent(RequestMethod.ReqGet, _
@@ -426,7 +426,7 @@ Public Class HttpTwitter
426426 End Function
427427
428428 Public Function RateLimitStatus(ByRef content As String) As HttpStatusCode
429- If HttpConnectionOAuth.AuthUsername = "" Then
429+ If Me.AuthUsername = "" Then
430430 Return HttpStatusCode.Unauthorized
431431 End If
432432 Try
--- a/Tween/Connection/HttpVarious.vb
+++ b/Tween/Connection/HttpVarious.vb
@@ -34,7 +34,7 @@ Public Class HttpVarious
3434 End Try
3535 End Function
3636
37- Public Function PostData(ByVal Url As String, ByVal param As SortedList(Of String, String)) As Boolean
37+ Public Function PostData(ByVal Url As String, ByVal param As Dictionary(Of String, String)) As Boolean
3838 Dim req As HttpWebRequest = CreateRequest(RequestMethod.ReqPost, New Uri(Url), param, False)
3939 Try
4040 Dim res As HttpStatusCode = Me.GetResponse(req, Nothing, False)
@@ -45,7 +45,7 @@ Public Class HttpVarious
4545 End Try
4646 End Function
4747
48- Public Function PostData(ByVal Url As String, ByVal param As SortedList(Of String, String), ByRef content As String) As Boolean
48+ Public Function PostData(ByVal Url As String, ByVal param As Dictionary(Of String, String), ByRef content As String) As Boolean
4949 Dim req As HttpWebRequest = CreateRequest(RequestMethod.ReqPost, New Uri(Url), param, False)
5050 Try
5151 Dim res As HttpStatusCode = Me.GetResponse(req, content, Nothing, False)
@@ -56,7 +56,7 @@ Public Class HttpVarious
5656 End Try
5757 End Function
5858
59- Public Function GetData(ByVal Url As String, ByVal param As SortedList(Of String, String), ByRef content As String) As Boolean
59+ Public Function GetData(ByVal Url As String, ByVal param As Dictionary(Of String, String), ByRef content As String) As Boolean
6060 Dim req As HttpWebRequest = CreateRequest(RequestMethod.ReqGet, New Uri(Url), param, False)
6161 Try
6262 Dim res As HttpStatusCode = Me.GetResponse(req, content, Nothing, False)
--- a/Tween/My Project/AssemblyInfo.vb
+++ b/Tween/My Project/AssemblyInfo.vb
@@ -55,5 +55,5 @@ Imports System.Runtime.InteropServices
5555 ' <Assembly: AssemblyVersion("1.0.*")>
5656
5757 <Assembly: AssemblyVersion("0.1.0.0")>
58-<Assembly: AssemblyFileVersion("0.8.8.0")>
58+<Assembly: AssemblyFileVersion("0.8.8.1")>
5959
--- a/Tween/My Project/Resources.Designer.vb
+++ b/Tween/My Project/Resources.Designer.vb
@@ -1,7 +1,7 @@
11 '------------------------------------------------------------------------------
22 ' <auto-generated>
33 ' このコードはツールによって生成されました。
4-' ランタイム バージョン:2.0.50727.4927
4+' ランタイム バージョン:2.0.50727.3603
55 '
66 ' このファイルへの変更は、以下の状況下で不正な動作の原因になったり、
77 ' コードが再生成されるときに損失したりします。
@@ -1646,6 +1646,15 @@ Namespace My.Resources
16461646 End Property
16471647
16481648 '''<summary>
1649+ ''' アカウントが認証されていません。閉じてもよろしいですか? に類似しているローカライズされた文字列を検索します。
1650+ '''</summary>
1651+ Friend ReadOnly Property Setting_FormClosing1() As String
1652+ Get
1653+ Return ResourceManager.GetString("Setting_FormClosing1", resourceCulture)
1654+ End Get
1655+ End Property
1656+
1657+ '''<summary>
16491658 ''' まだあなたのプロフィール情報を取得していません。投稿後に再度お試しください。 に類似しているローカライズされた文字列を検索します。
16501659 '''</summary>
16511660 Friend ReadOnly Property ShowYourProfileText1() As String
--- a/Tween/My Project/Resources.en.resx
+++ b/Tween/My Project/Resources.en.resx
@@ -756,4 +756,7 @@
756756 <data name="AuthorizeButton_Click4" xml:space="preserve">
757757 <value>Not authenticated</value>
758758 </data>
759+ <data name="Setting_FormClosing1" xml:space="preserve">
760+ <value>Account is not Validated. Will you close setting dialog?</value>
761+ </data>
759762 </root>
\ No newline at end of file
--- a/Tween/My Project/Resources.resx
+++ b/Tween/My Project/Resources.resx
@@ -808,4 +808,7 @@
808808 <data name="AuthorizeButton_Click4" xml:space="preserve">
809809 <value>未認証</value>
810810 </data>
811+ <data name="Setting_FormClosing1" xml:space="preserve">
812+ <value>アカウントが認証されていません。閉じてもよろしいですか?</value>
813+ </data>
811814 </root>
\ No newline at end of file
--- a/Tween/Outputz.vb
+++ b/Tween/Outputz.vb
@@ -75,7 +75,7 @@ Public Module Outputz
7575
7676 Dim content As String = ""
7777 Dim output As String = "http://outputz.com/api/post"
78- Dim param As New SortedList(Of String, String)
78+ Dim param As New Dictionary(Of String, String)
7979 param.Add("key", myApikeyEncoded)
8080 param.Add("uri", myOuturlEncoded)
8181 param.Add("size", length.ToString)
--- a/Tween/Resources/ChangeLog.txt
+++ b/Tween/Resources/ChangeLog.txt
@@ -1,5 +1,11 @@
11 更新履歴
22
3+==== Ver 0.8.8.1(2010/03/3)
4+ * Webモード廃止
5+ * OAuth(xAuth)対応(API上限が350へ)
6+ * URL等のリンク検出ロジックの調整
7+ * フォロー・アンフォロー等のID指定画面でIDを変更しても、結果画面のIDが変わらないバグ修正
8+ * 時速表示バグの修正
39 ==== Ver 0.8.8.0(2010/02/23)
410 * ふぁぼったーのURLを変更(favotter.matope.com→favotter.netに変更)
511 ==== Ver 0.8.7.0(2010/02/23)
--- a/Tween/Setting.Designer.vb
+++ b/Tween/Setting.Designer.vb
@@ -127,6 +127,7 @@ Partial Class Setting
127127 Me.Label47 = New System.Windows.Forms.Label
128128 Me.TabControl1 = New System.Windows.Forms.TabControl
129129 Me.TabPage1 = New System.Windows.Forms.TabPage
130+ Me.AuthClearButton = New System.Windows.Forms.Button
130131 Me.AuthUserLabel = New System.Windows.Forms.Label
131132 Me.AuthStateLabel = New System.Windows.Forms.Label
132133 Me.Label4 = New System.Windows.Forms.Label
@@ -217,7 +218,6 @@ Partial Class Setting
217218 Me.Label59 = New System.Windows.Forms.Label
218219 Me.TextBoxOutputzKey = New System.Windows.Forms.TextBox
219220 Me.CheckOutputz = New System.Windows.Forms.CheckBox
220- Me.AuthClearButton = New System.Windows.Forms.Button
221221 Me.GroupBox1.SuspendLayout()
222222 Me.TabControl1.SuspendLayout()
223223 Me.TabPage1.SuspendLayout()
@@ -889,6 +889,12 @@ Partial Class Setting
889889 Me.TabPage1.Name = "TabPage1"
890890 Me.TabPage1.UseVisualStyleBackColor = True
891891 '
892+ 'AuthClearButton
893+ '
894+ resources.ApplyResources(Me.AuthClearButton, "AuthClearButton")
895+ Me.AuthClearButton.Name = "AuthClearButton"
896+ Me.AuthClearButton.UseVisualStyleBackColor = True
897+ '
892898 'AuthUserLabel
893899 '
894900 Me.AuthUserLabel.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D
@@ -1502,12 +1508,6 @@ Partial Class Setting
15021508 Me.CheckOutputz.Name = "CheckOutputz"
15031509 Me.CheckOutputz.UseVisualStyleBackColor = True
15041510 '
1505- 'AuthClearButton
1506- '
1507- resources.ApplyResources(Me.AuthClearButton, "AuthClearButton")
1508- Me.AuthClearButton.Name = "AuthClearButton"
1509- Me.AuthClearButton.UseVisualStyleBackColor = True
1510- '
15111511 'Setting
15121512 '
15131513 Me.AcceptButton = Me.Save
--- a/Tween/Setting.en.resx
+++ b/Tween/Setting.en.resx
@@ -139,30 +139,12 @@
139139 <data name="Label3.Text" xml:space="preserve">
140140 <value>Timeline Fetching Interval (sec.)</value>
141141 </data>
142- <data name="Label4.Size" type="System.Drawing.Size, System.Drawing">
143- <value>153, 12</value>
144- </data>
145- <data name="Label4.Text" xml:space="preserve">
146- <value>Threshold of Fetching (1-20)</value>
147- </data>
148142 <data name="Label5.Size" type="System.Drawing.Size, System.Drawing">
149143 <value>144, 12</value>
150144 </data>
151145 <data name="Label5.Text" xml:space="preserve">
152146 <value>DM Fetching Interval (sec.)</value>
153147 </data>
154- <data name="Label6.Size" type="System.Drawing.Size, System.Drawing">
155- <value>205, 12</value>
156- </data>
157- <data name="Label6.Text" xml:space="preserve">
158- <value>Fetching Pages at Once over threshold</value>
159- </data>
160- <data name="Label8.Size" type="System.Drawing.Size, System.Drawing">
161- <value>142, 12</value>
162- </data>
163- <data name="Label8.Text" xml:space="preserve">
164- <value>First-time Fetching Pages:</value>
165- </data>
166148 <data name="Label9.Size" type="System.Drawing.Size, System.Drawing">
167149 <value>135, 12</value>
168150 </data>
@@ -478,12 +460,6 @@
478460 <data name="Label44.Text" xml:space="preserve">
479461 <value>Path to Browser</value>
480462 </data>
481- <data name="CheckboxReply.Size" type="System.Drawing.Size, System.Drawing">
482- <value>95, 16</value>
483- </data>
484- <data name="CheckboxReply.Text" xml:space="preserve">
485- <value>Fetch Replies</value>
486- </data>
487463 <data name="CheckDispUsername.Size" type="System.Drawing.Size, System.Drawing">
488464 <value>58, 16</value>
489465 </data>
@@ -529,23 +505,23 @@
529505 <data name="Label47.Text" xml:space="preserve">
530506 <value>Apply after restarting</value>
531507 </data>
532- <data name="Label7.Size" type="System.Drawing.Size, System.Drawing">
533- <value>149, 12</value>
508+ <data name="AuthClearButton.Text" xml:space="preserve">
509+ <value>Clear</value>
534510 </data>
535- <data name="Label7.Text" xml:space="preserve">
536- <value>Public Search Interval (sec.)</value>
511+ <data name="Label4.Size" type="System.Drawing.Size, System.Drawing">
512+ <value>65, 12</value>
537513 </data>
538- <data name="Label70.Size" type="System.Drawing.Size, System.Drawing">
539- <value>176, 12</value>
514+ <data name="Label4.Text" xml:space="preserve">
515+ <value>Auth status</value>
540516 </data>
541- <data name="Label70.Text" xml:space="preserve">
542- <value>Show warning if API isn't enabled</value>
517+ <data name="AuthorizeButton.Text" xml:space="preserve">
518+ <value>Auth</value>
543519 </data>
544- <data name="CheckStartupAPImodeNoWarning.Size" type="System.Drawing.Size, System.Drawing">
545- <value>80, 16</value>
520+ <data name="Label7.Size" type="System.Drawing.Size, System.Drawing">
521+ <value>149, 12</value>
546522 </data>
547- <data name="CheckStartupAPImodeNoWarning.Text" xml:space="preserve">
548- <value>Don't show</value>
523+ <data name="Label7.Text" xml:space="preserve">
524+ <value>Public Search Interval (sec.)</value>
549525 </data>
550526 <data name="Label69.Size" type="System.Drawing.Size, System.Drawing">
551527 <value>156, 12</value>
@@ -565,30 +541,6 @@
565541 <data name="Label67.Text" xml:space="preserve">
566542 <value>Getting number of tweets/mentions in API </value>
567543 </data>
568- <data name="Label66.Size" type="System.Drawing.Size, System.Drawing">
569- <value>75, 12</value>
570- </data>
571- <data name="Label66.Text" xml:space="preserve">
572- <value>POST method</value>
573- </data>
574- <data name="CheckPostMethod.Size" type="System.Drawing.Size, System.Drawing">
575- <value>58, 16</value>
576- </data>
577- <data name="CheckPostMethod.Text" xml:space="preserve">
578- <value>Enable</value>
579- </data>
580- <data name="Label43.Size" type="System.Drawing.Size, System.Drawing">
581- <value>59, 12</value>
582- </data>
583- <data name="Label43.Text" xml:space="preserve">
584- <value>TwitterAPI</value>
585- </data>
586- <data name="CheckUseApi.Size" type="System.Drawing.Size, System.Drawing">
587- <value>58, 16</value>
588- </data>
589- <data name="CheckUseApi.Text" xml:space="preserve">
590- <value>Enable</value>
591- </data>
592544 <data name="Label54.Size" type="System.Drawing.Size, System.Drawing">
593545 <value>131, 12</value>
594546 </data>
@@ -601,18 +553,6 @@
601553 <data name="CheckStartupFollowers.Text" xml:space="preserve">
602554 <value>Enable</value>
603555 </data>
604- <data name="Label53.Size" type="System.Drawing.Size, System.Drawing">
605- <value>169, 12</value>
606- </data>
607- <data name="Label53.Text" xml:space="preserve">
608- <value>Update Parsing Keys in Starting</value>
609- </data>
610- <data name="CheckStartupKey.Size" type="System.Drawing.Size, System.Drawing">
611- <value>58, 16</value>
612- </data>
613- <data name="CheckStartupKey.Text" xml:space="preserve">
614- <value>Enable</value>
615- </data>
616556 <data name="Label51.Size" type="System.Drawing.Size, System.Drawing">
617557 <value>158, 12</value>
618558 </data>
--- a/Tween/Setting.resx
+++ b/Tween/Setting.resx
@@ -273,7 +273,7 @@
273273 <value>130, 12</value>
274274 </data>
275275 <data name="Label3.TabIndex" type="System.Int32, mscorlib">
276- <value>4</value>
276+ <value>5</value>
277277 </data>
278278 <data name="Label3.Text" xml:space="preserve">
279279 <value>タイムライン更新間隔(秒)</value>
@@ -297,7 +297,7 @@
297297 <value>65, 19</value>
298298 </data>
299299 <data name="TimelinePeriod.TabIndex" type="System.Int32, mscorlib">
300- <value>5</value>
300+ <value>6</value>
301301 </data>
302302 <data name="&gt;&gt;TimelinePeriod.Name" xml:space="preserve">
303303 <value>TimelinePeriod</value>
@@ -2989,7 +2989,7 @@
29892989 <value>75, 23</value>
29902990 </data>
29912991 <data name="AuthorizeButton.TabIndex" type="System.Int32, mscorlib">
2992- <value>43</value>
2992+ <value>4</value>
29932993 </data>
29942994 <data name="AuthorizeButton.Text" xml:space="preserve">
29952995 <value>認証する</value>
@@ -3142,7 +3142,7 @@
31423142 <value>84, 16</value>
31433143 </data>
31443144 <data name="CheckPostAndGet.TabIndex" type="System.Int32, mscorlib">
3145- <value>6</value>
3145+ <value>7</value>
31463146 </data>
31473147 <data name="CheckPostAndGet.Text" xml:space="preserve">
31483148 <value>投稿時取得</value>
--- a/Tween/Setting.vb
+++ b/Tween/Setting.vb
@@ -286,6 +286,14 @@ Public Class Setting
286286 End Try
287287 End Sub
288288
289+ Private Sub Setting_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
290+ If Twitter.Username = "" Then
291+ If MessageBox.Show(My.Resources.Setting_FormClosing1, "Confirm", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) = Windows.Forms.DialogResult.Cancel Then
292+ e.Cancel = True
293+ End If
294+ End If
295+ End Sub
296+
289297 Private Sub Setting_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
290298 'Username.Text = _MyuserID
291299 'Password.Text = _Mypassword
@@ -1829,27 +1837,27 @@ Public Class Setting
18291837 End Set
18301838 End Property
18311839
1832- Private Sub Username_Validating(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles Username.Validating
1833- If Username.Text.Trim = "" Then
1834- MessageBox.Show(My.Resources.Save_ClickText1)
1835- e.Cancel = True
1836- Exit Sub
1837- End If
1838- If Username.Text.Contains("@") Then
1839- MessageBox.Show(My.Resources.Save_ClickText2)
1840- e.Cancel = True
1841- Exit Sub
1842- End If
1840+ 'Private Sub Username_Validating(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles Username.Validating
1841+ ' If Username.Text.Trim = "" Then
1842+ ' MessageBox.Show(My.Resources.Save_ClickText1)
1843+ ' e.Cancel = True
1844+ ' Exit Sub
1845+ ' End If
1846+ ' If Username.Text.Contains("@") Then
1847+ ' MessageBox.Show(My.Resources.Save_ClickText2)
1848+ ' e.Cancel = True
1849+ ' Exit Sub
1850+ ' End If
18431851
1844- End Sub
1852+ 'End Sub
18451853
1846- Private Sub Password_Validating(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles Password.Validating
1847- If Password.Text.Trim = "" Then
1848- MessageBox.Show(My.Resources.Save_ClickText1)
1849- e.Cancel = True
1850- Exit Sub
1851- End If
1852- End Sub
1854+ 'Private Sub Password_Validating(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles Password.Validating
1855+ ' If Password.Text.Trim = "" Then
1856+ ' MessageBox.Show(My.Resources.Save_ClickText1)
1857+ ' e.Cancel = True
1858+ ' Exit Sub
1859+ ' End If
1860+ 'End Sub
18531861
18541862 Private Sub ComboBoxAutoShortUrlFirst_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBoxAutoShortUrlFirst.SelectedIndexChanged
18551863 If ComboBoxAutoShortUrlFirst.SelectedIndex = UrlConverter.Bitly OrElse _
@@ -1940,5 +1948,6 @@ Public Class Setting
19401948 Me.AuthStateLabel.Text = My.Resources.AuthorizeButton_Click4
19411949 Me.AuthUserLabel.Text = ""
19421950 End Sub
1951+
19431952 End Class
19441953
--- a/Tween/Tween.vb
+++ b/Tween/Tween.vb
@@ -1813,6 +1813,21 @@ Public Class TweenMain
18131813 Me.Activate()
18141814 End Sub
18151815
1816+ Private Shared Function CheckAccountValid() As Boolean
1817+ Static errorCount As Integer = 0
1818+ If Twitter.AccountState <> ACCOUNT_STATE.Valid Then
1819+ errorCount += 1
1820+ If errorCount > 5 Then
1821+ errorCount = 0
1822+ Twitter.AccountState = ACCOUNT_STATE.Valid
1823+ Return True
1824+ End If
1825+ Return False
1826+ End If
1827+ errorCount = 0
1828+ Return True
1829+ End Function
1830+
18161831 Private Sub GetTimelineWorker_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs)
18171832 Dim bw As BackgroundWorker = DirectCast(sender, BackgroundWorker)
18181833 If bw.CancellationPending OrElse _endingFlag Then
@@ -1832,6 +1847,12 @@ Public Class TweenMain
18321847
18331848 Dim args As GetWorkerArg = DirectCast(e.Argument, GetWorkerArg)
18341849
1850+ If Not CheckAccountValid() Then
1851+ rslt.retMsg = "Auth error. Check your account"
1852+ rslt.type = args.type
1853+ rslt.tName = args.tName
1854+ e.Result = rslt
1855+ End If
18351856
18361857 If args.type <> WORKERTYPE.OpenUri Then bw.ReportProgress(0, "") 'Notifyアイコンアニメーション開始
18371858 Select Case args.type
@@ -4873,121 +4894,104 @@ RETRY:
48734894 Private Sub SaveConfigsCommon()
48744895 If _ignoreConfigSave Then Exit Sub
48754896
4876- If Twitter.Username <> "" Then
4877- modifySettingCommon = False
4878- SyncLock _syncObject
4879- _cfgCommon.UserName = Twitter.Username
4880- '_cfgCommon.Password = SettingDialog.PasswordStr
4881- _cfgCommon.Token = Twitter.AccessToken
4882- _cfgCommon.TokenSecret = Twitter.AccessTokenSecret
4883- '_cfgCommon.NextPageThreshold = SettingDialog.NextPageThreshold
4884- '_cfgCommon.NextPages = SettingDialog.NextPagesInt
4885- _cfgCommon.TimelinePeriod = SettingDialog.TimelinePeriodInt
4886- _cfgCommon.ReplyPeriod = SettingDialog.ReplyPeriodInt
4887- _cfgCommon.DMPeriod = SettingDialog.DMPeriodInt
4888- _cfgCommon.PubSearchPeriod = SettingDialog.PubSearchPeriodInt
4889- _cfgCommon.MaxPostNum = SettingDialog.MaxPostNum
4890- '_cfgCommon.ReadPages = SettingDialog.ReadPages
4891- '_cfgCommon.ReadPagesReply = SettingDialog.ReadPagesReply
4892- '_cfgCommon.ReadPagesDM = SettingDialog.ReadPagesDM
4893- _cfgCommon.Read = SettingDialog.Readed
4894- _cfgCommon.IconSize = SettingDialog.IconSz
4895- _cfgCommon.UnreadManage = SettingDialog.UnreadManage
4896- _cfgCommon.PlaySound = SettingDialog.PlaySound
4897- _cfgCommon.OneWayLove = SettingDialog.OneWayLove
4898-
4899- _cfgCommon.NameBalloon = SettingDialog.NameBalloon
4900- _cfgCommon.PostCtrlEnter = SettingDialog.PostCtrlEnter
4901- '_cfgCommon.UseApi = SettingDialog.UseAPI
4902- _cfgCommon.CountApi = SettingDialog.CountApi
4903- _cfgCommon.CountApiReply = SettingDialog.CountApiReply
4904- '_cfgCommon.UsePostMethod = False
4905- _cfgCommon.HubServer = SettingDialog.HubServer
4906- '_cfgCommon.CheckReply = SettingDialog.CheckReply
4907- _cfgCommon.PostAndGet = SettingDialog.PostAndGet
4908- _cfgCommon.DispUsername = SettingDialog.DispUsername
4909- _cfgCommon.MinimizeToTray = SettingDialog.MinimizeToTray
4910- _cfgCommon.CloseToExit = SettingDialog.CloseToExit
4911- _cfgCommon.DispLatestPost = SettingDialog.DispLatestPost
4912- _cfgCommon.SortOrderLock = SettingDialog.SortOrderLock
4913- _cfgCommon.TinyUrlResolve = SettingDialog.TinyUrlResolve
4914- _cfgCommon.PeriodAdjust = SettingDialog.PeriodAdjust
4915- _cfgCommon.StartupVersion = SettingDialog.StartupVersion
4916- '_cfgCommon.StartupKey = SettingDialog.StartupKey
4917- _cfgCommon.StartupFollowers = SettingDialog.StartupFollowers
4918- '_cfgCommon.StartupApiModeNoWarning = SettingDialog.StartupAPImodeNoWarning
4919- _cfgCommon.RestrictFavCheck = SettingDialog.RestrictFavCheck
4920- _cfgCommon.AlwaysTop = SettingDialog.AlwaysTop
4921- _cfgCommon.UrlConvertAuto = SettingDialog.UrlConvertAuto
4922- _cfgCommon.Outputz = SettingDialog.OutputzEnabled
4923- _cfgCommon.OutputzKey = SettingDialog.OutputzKey
4924- _cfgCommon.OutputzUrlMode = SettingDialog.OutputzUrlmode
4925- _cfgCommon.UseUnreadStyle = SettingDialog.UseUnreadStyle
4926- _cfgCommon.DateTimeFormat = SettingDialog.DateTimeFormat
4927- _cfgCommon.DefaultTimeOut = SettingDialog.DefaultTimeOut
4928- _cfgCommon.ProtectNotInclude = SettingDialog.ProtectNotInclude
4929- _cfgCommon.LimitBalloon = SettingDialog.LimitBalloon
4930- _cfgCommon.AutoShortUrlFirst = SettingDialog.AutoShortUrlFirst
4931- _cfgCommon.TabIconDisp = SettingDialog.TabIconDisp
4932- _cfgCommon.ReplyIconState = SettingDialog.ReplyIconState
4933- _cfgCommon.ReadOwnPost = SettingDialog.ReadOwnPost
4934- _cfgCommon.GetFav = SettingDialog.GetFav
4935- _cfgCommon.IsMonospace = SettingDialog.IsMonospace
4936- If IdeographicSpaceToSpaceToolStripMenuItem IsNot Nothing AndAlso _
4937- IdeographicSpaceToSpaceToolStripMenuItem.IsDisposed = False Then
4938- _cfgCommon.WideSpaceConvert = Me.IdeographicSpaceToSpaceToolStripMenuItem.Checked
4939- End If
4940- _cfgCommon.ReadOldPosts = SettingDialog.ReadOldPosts
4941- _cfgCommon.UseSsl = SettingDialog.UseSsl
4942- _cfgCommon.BilyUser = SettingDialog.BitlyUser
4943- _cfgCommon.BitlyPwd = SettingDialog.BitlyPwd
4944- _cfgCommon.ShowGrid = SettingDialog.ShowGrid
4945- _cfgCommon.UseAtIdSupplement = SettingDialog.UseAtIdSupplement
4946- _cfgCommon.UseHashSupplement = SettingDialog.UseHashSupplement
4947- _cfgCommon.Language = SettingDialog.Language
4948-
4949- _cfgCommon.SortOrder = _statuses.SortOrder
4950- Select Case _statuses.SortMode
4951- Case IdComparerClass.ComparerMode.Nickname 'ニックネーム
4952- _cfgCommon.SortColumn = 1
4953- Case IdComparerClass.ComparerMode.Data '本文
4954- _cfgCommon.SortColumn = 2
4955- Case IdComparerClass.ComparerMode.Id '時刻=発言Id
4956- _cfgCommon.SortColumn = 3
4957- Case IdComparerClass.ComparerMode.Name '名前
4958- _cfgCommon.SortColumn = 4
4959- Case IdComparerClass.ComparerMode.Source 'Source
4960- _cfgCommon.SortColumn = 7
4961- End Select
4897+ modifySettingCommon = False
4898+ SyncLock _syncObject
4899+ _cfgCommon.UserName = Twitter.Username
4900+ '_cfgCommon.Password = SettingDialog.PasswordStr
4901+ _cfgCommon.Token = Twitter.AccessToken
4902+ _cfgCommon.TokenSecret = Twitter.AccessTokenSecret
4903+ '_cfgCommon.NextPageThreshold = SettingDialog.NextPageThreshold
4904+ '_cfgCommon.NextPages = SettingDialog.NextPagesInt
4905+ _cfgCommon.TimelinePeriod = SettingDialog.TimelinePeriodInt
4906+ _cfgCommon.ReplyPeriod = SettingDialog.ReplyPeriodInt
4907+ _cfgCommon.DMPeriod = SettingDialog.DMPeriodInt
4908+ _cfgCommon.PubSearchPeriod = SettingDialog.PubSearchPeriodInt
4909+ _cfgCommon.MaxPostNum = SettingDialog.MaxPostNum
4910+ '_cfgCommon.ReadPages = SettingDialog.ReadPages
4911+ '_cfgCommon.ReadPagesReply = SettingDialog.ReadPagesReply
4912+ '_cfgCommon.ReadPagesDM = SettingDialog.ReadPagesDM
4913+ _cfgCommon.Read = SettingDialog.Readed
4914+ _cfgCommon.IconSize = SettingDialog.IconSz
4915+ _cfgCommon.UnreadManage = SettingDialog.UnreadManage
4916+ _cfgCommon.PlaySound = SettingDialog.PlaySound
4917+ _cfgCommon.OneWayLove = SettingDialog.OneWayLove
4918+
4919+ _cfgCommon.NameBalloon = SettingDialog.NameBalloon
4920+ _cfgCommon.PostCtrlEnter = SettingDialog.PostCtrlEnter
4921+ '_cfgCommon.UseApi = SettingDialog.UseAPI
4922+ _cfgCommon.CountApi = SettingDialog.CountApi
4923+ _cfgCommon.CountApiReply = SettingDialog.CountApiReply
4924+ '_cfgCommon.UsePostMethod = False
4925+ _cfgCommon.HubServer = SettingDialog.HubServer
4926+ '_cfgCommon.CheckReply = SettingDialog.CheckReply
4927+ _cfgCommon.PostAndGet = SettingDialog.PostAndGet
4928+ _cfgCommon.DispUsername = SettingDialog.DispUsername
4929+ _cfgCommon.MinimizeToTray = SettingDialog.MinimizeToTray
4930+ _cfgCommon.CloseToExit = SettingDialog.CloseToExit
4931+ _cfgCommon.DispLatestPost = SettingDialog.DispLatestPost
4932+ _cfgCommon.SortOrderLock = SettingDialog.SortOrderLock
4933+ _cfgCommon.TinyUrlResolve = SettingDialog.TinyUrlResolve
4934+ _cfgCommon.PeriodAdjust = SettingDialog.PeriodAdjust
4935+ _cfgCommon.StartupVersion = SettingDialog.StartupVersion
4936+ '_cfgCommon.StartupKey = SettingDialog.StartupKey
4937+ _cfgCommon.StartupFollowers = SettingDialog.StartupFollowers
4938+ '_cfgCommon.StartupApiModeNoWarning = SettingDialog.StartupAPImodeNoWarning
4939+ _cfgCommon.RestrictFavCheck = SettingDialog.RestrictFavCheck
4940+ _cfgCommon.AlwaysTop = SettingDialog.AlwaysTop
4941+ _cfgCommon.UrlConvertAuto = SettingDialog.UrlConvertAuto
4942+ _cfgCommon.Outputz = SettingDialog.OutputzEnabled
4943+ _cfgCommon.OutputzKey = SettingDialog.OutputzKey
4944+ _cfgCommon.OutputzUrlMode = SettingDialog.OutputzUrlmode
4945+ _cfgCommon.UseUnreadStyle = SettingDialog.UseUnreadStyle
4946+ _cfgCommon.DateTimeFormat = SettingDialog.DateTimeFormat
4947+ _cfgCommon.DefaultTimeOut = SettingDialog.DefaultTimeOut
4948+ _cfgCommon.ProtectNotInclude = SettingDialog.ProtectNotInclude
4949+ _cfgCommon.LimitBalloon = SettingDialog.LimitBalloon
4950+ _cfgCommon.AutoShortUrlFirst = SettingDialog.AutoShortUrlFirst
4951+ _cfgCommon.TabIconDisp = SettingDialog.TabIconDisp
4952+ _cfgCommon.ReplyIconState = SettingDialog.ReplyIconState
4953+ _cfgCommon.ReadOwnPost = SettingDialog.ReadOwnPost
4954+ _cfgCommon.GetFav = SettingDialog.GetFav
4955+ _cfgCommon.IsMonospace = SettingDialog.IsMonospace
4956+ If IdeographicSpaceToSpaceToolStripMenuItem IsNot Nothing AndAlso _
4957+ IdeographicSpaceToSpaceToolStripMenuItem.IsDisposed = False Then
4958+ _cfgCommon.WideSpaceConvert = Me.IdeographicSpaceToSpaceToolStripMenuItem.Checked
4959+ End If
4960+ _cfgCommon.ReadOldPosts = SettingDialog.ReadOldPosts
4961+ _cfgCommon.UseSsl = SettingDialog.UseSsl
4962+ _cfgCommon.BilyUser = SettingDialog.BitlyUser
4963+ _cfgCommon.BitlyPwd = SettingDialog.BitlyPwd
4964+ _cfgCommon.ShowGrid = SettingDialog.ShowGrid
4965+ _cfgCommon.UseAtIdSupplement = SettingDialog.UseAtIdSupplement
4966+ _cfgCommon.UseHashSupplement = SettingDialog.UseHashSupplement
4967+ _cfgCommon.Language = SettingDialog.Language
4968+
4969+ _cfgCommon.SortOrder = _statuses.SortOrder
4970+ Select Case _statuses.SortMode
4971+ Case IdComparerClass.ComparerMode.Nickname 'ニックネーム
4972+ _cfgCommon.SortColumn = 1
4973+ Case IdComparerClass.ComparerMode.Data '本文
4974+ _cfgCommon.SortColumn = 2
4975+ Case IdComparerClass.ComparerMode.Id '時刻=発言Id
4976+ _cfgCommon.SortColumn = 3
4977+ Case IdComparerClass.ComparerMode.Name '名前
4978+ _cfgCommon.SortColumn = 4
4979+ Case IdComparerClass.ComparerMode.Source 'Source
4980+ _cfgCommon.SortColumn = 7
4981+ End Select
49624982
4963- _cfgCommon.Nicoms = SettingDialog.Nicoms
4964- _cfgCommon.HashTags = HashMgr.HashHistories
4965- If HashMgr.IsPermanent Then
4966- _cfgCommon.HashSelected = HashMgr.UseHash
4967- Else
4968- _cfgCommon.HashSelected = ""
4969- End If
4970- _cfgCommon.HashIsHead = HashMgr.IsHead
4971- _cfgCommon.HashIsPermanent = HashMgr.IsPermanent
4972- '_cfgCommon.HashSelected = Me.HashSelectComboBox.Text
4973-
4974- ' _cfgCommon.TabList.Clear()
4975- ' For i As Integer = 0 To ListTab.TabPages.Count - 1
4976- ' Dim tnList As String = ListTab.TabPages(i).Text
4977- ' Dim seq As Integer = 1
4978- 'RETRY:
4979- ' seq += 1
4980- ' For Each tn As String In _cfgCommon.TabList
4981- ' If tn.ToLower() = tnList.ToLower() Then
4982- ' tnList += "_" + seq.ToString()
4983- ' End If
4984- ' Next
4985- ' _cfgCommon.TabList.Add(ListTab.TabPages(i).Text)
4986- ' Next
4987-
4988- _cfgCommon.Save()
4989- End SyncLock
4990- End If
4983+ _cfgCommon.Nicoms = SettingDialog.Nicoms
4984+ _cfgCommon.HashTags = HashMgr.HashHistories
4985+ If HashMgr.IsPermanent Then
4986+ _cfgCommon.HashSelected = HashMgr.UseHash
4987+ Else
4988+ _cfgCommon.HashSelected = ""
4989+ End If
4990+ _cfgCommon.HashIsHead = HashMgr.IsHead
4991+ _cfgCommon.HashIsPermanent = HashMgr.IsPermanent
4992+
4993+ _cfgCommon.Save()
4994+ End SyncLock
49914995 End Sub
49924996
49934997 Private Sub SaveConfigsLocal()
@@ -6385,15 +6389,20 @@ RETRY:
63856389 Private Function UrlConvert(ByVal Converter_Type As UrlConverter) As Boolean
63866390 'Converter_Type=Nicomsの場合は、nicovideoのみ短縮する
63876391 Dim result As String = ""
6388- Dim url As Regex = New Regex("(?<![0-9A-Za-z])(?:https?|shttp)://(?:(?:[-_.!~*'()a-zA-Z0-9;:&=+$,]|%[0-9A-Fa-f" + _
6389- "][0-9A-Fa-f])*@)?(?:(?:[a-zA-Z0-9](?:[-a-zA-Z0-9]*[a-zA-Z0-9])?\.)" + _
6390- "*[a-zA-Z](?:[-a-zA-Z0-9]*[a-zA-Z0-9])?\.?|[0-9]+\.[0-9]+\.[0-9]+\." + _
6391- "[0-9]+)(?::[0-9]*)?(?:/(?:[-_.!~*'()a-zA-Z0-9:@&=+$,]|%[0-9A-Fa-f]" + _
6392- "[0-9A-Fa-f])*(?:;(?:[-_.!~*'()a-zA-Z0-9:@&=+$,]|%[0-9A-Fa-f][0-9A-" + _
6393- "Fa-f])*)*(?:/(?:[-_.!~*'()a-zA-Z0-9:@&=+$,]|%[0-9A-Fa-f][0-9A-Fa-f" + _
6394- "])*(?:;(?:[-_.!~*'()a-zA-Z0-9:@&=+$,]|%[0-9A-Fa-f][0-9A-Fa-f])*)*)" + _
6395- "*)?(?:\?(?:[-_.!~*'()a-zA-Z0-9;/?:@&=+$,]|%[0-9A-Fa-f][0-9A-Fa-f])" + _
6396- "*)?(?:#(?:[-_.!~*'()a-zA-Z0-9;/?:@&=+$,]|%[0-9A-Fa-f][0-9A-Fa-f])*)?")
6392+ Dim url As Regex = New Regex("(?<before>(?:[^\/""':!=]|^|\:))" + _
6393+ "(?<url>(?<protocol>https?://|www\.)" + _
6394+ "(?<domain>(?:[\.-]|[^\p{P}])+\.[a-z]{2,}(?::[0-9]+)?)" + _
6395+ "(?<path>/[a-z0-9!*'();:&=+$/%#\[\]\-_.,~]*[a-z0-9)=#/]?)?" + _
6396+ "(?<query>\?[a-z0-9!*'();:&=+$/%#\[\]\-_.,~]*[a-z0-9_&=#])?)", RegexOptions.IgnoreCase Or RegexOptions.Compiled)
6397+ 'Dim url As Regex = New Regex("(?<![0-9A-Za-z])(?:https?|shttp)://(?:(?:[-_.!~*'()a-zA-Z0-9;:&=+$,]|%[0-9A-Fa-f" + _
6398+ ' "][0-9A-Fa-f])*@)?(?:(?:[a-zA-Z0-9](?:[-a-zA-Z0-9]*[a-zA-Z0-9])?\.)" + _
6399+ ' "*[a-zA-Z](?:[-a-zA-Z0-9]*[a-zA-Z0-9])?\.?|[0-9]+\.[0-9]+\.[0-9]+\." + _
6400+ ' "[0-9]+)(?::[0-9]*)?(?:/(?:[-_.!~*'()a-zA-Z0-9:@&=+$,]|%[0-9A-Fa-f]" + _
6401+ ' "[0-9A-Fa-f])*(?:;(?:[-_.!~*'()a-zA-Z0-9:@&=+$,]|%[0-9A-Fa-f][0-9A-" + _
6402+ ' "Fa-f])*)*(?:/(?:[-_.!~*'()a-zA-Z0-9:@&=+$,]|%[0-9A-Fa-f][0-9A-Fa-f" + _
6403+ ' "])*(?:;(?:[-_.!~*'()a-zA-Z0-9:@&=+$,]|%[0-9A-Fa-f][0-9A-Fa-f])*)*)" + _
6404+ ' "*)?(?:\?(?:[-_.!~*'()a-zA-Z0-9;/?:@&=+$,]|%[0-9A-Fa-f][0-9A-Fa-f])" + _
6405+ ' "*)?(?:#(?:[-_.!~*'()a-zA-Z0-9;/?:@&=+$,]|%[0-9A-Fa-f][0-9A-Fa-f])*)?")
63976406 Dim nico As Regex = New Regex("^https?://[a-z]+\.(nicovideo|niconicommons)\.jp/[a-z]+/[a-z0-9]+$")
63986407
63996408 If StatusText.SelectionLength > 0 Then
@@ -6439,16 +6448,14 @@ RETRY:
64396448 End If
64406449 End If
64416450 Else
6442- Dim urls As RegularExpressions.MatchCollection = Nothing
6443- urls = url.Matches(StatusText.Text)
6444-
64456451 ' 正規表現にマッチしたURL文字列をtinyurl化
6446- For Each tmp2 As Match In urls
6447- Dim tmp As String = tmp2.ToString
6452+ For Each mt As Match In url.Matches(StatusText.Text)
6453+ Dim tmp As String = mt.Result("${url}")
6454+ If tmp.StartsWith("w", StringComparison.OrdinalIgnoreCase) Then tmp = "http://" + tmp
64486455 Dim undotmp As New urlUndo
64496456
64506457 '選んだURLを選択(?)
6451- StatusText.Select(StatusText.Text.IndexOf(tmp, StringComparison.Ordinal), tmp.Length)
6458+ StatusText.Select(StatusText.Text.IndexOf(mt.Result("${url}"), StringComparison.Ordinal), mt.Result("${url}").Length)
64526459
64536460 'nico.ms使用、nicovideoにマッチしたら変換
64546461 If SettingDialog.Nicoms AndAlso nico.IsMatch(tmp) Then
@@ -6469,10 +6476,10 @@ RETRY:
64696476 End If
64706477
64716478 If Not result = "" Then
6472- StatusText.Select(StatusText.Text.IndexOf(tmp, StringComparison.Ordinal), tmp.Length)
6479+ StatusText.Select(StatusText.Text.IndexOf(mt.Result("${url}"), StringComparison.Ordinal), mt.Result("${url}").Length)
64736480 StatusText.SelectedText = result
64746481 'undoバッファにセット
6475- undotmp.Before = tmp
6482+ undotmp.Before = mt.Result("${url}")
64766483 undotmp.After = result
64776484
64786485 If urlUndoBuffer Is Nothing Then
--- a/Tween/Twitter.vb
+++ b/Tween/Twitter.vb
@@ -2974,7 +2974,7 @@ Public Module Twitter
29742974
29752975 Public Function MakeShortUrl(ByVal ConverterType As UrlConverter, ByVal SrcUrl As String) As String
29762976 Dim src As String = urlEncodeMultibyteChar(SrcUrl)
2977- Dim param As New SortedList(Of String, String)
2977+ Dim param As New Dictionary(Of String, String)
29782978 Dim content As String = ""
29792979
29802980 For Each svc As String In _ShortUrlService
@@ -3236,6 +3236,11 @@ Public Module Twitter
32363236 Public WriteOnly Property UseSsl() As Boolean
32373237 Set(ByVal value As Boolean)
32383238 HttpTwitter.UseSsl = value
3239+ If value Then
3240+ _protocol = "https://"
3241+ Else
3242+ _protocol = "http://"
3243+ End If
32393244 End Set
32403245 End Property
32413246
@@ -3856,40 +3861,32 @@ Public Module Twitter
38563861 'Dim retStr As String = HttpUtility.HtmlDecode(Text)
38573862 Dim retStr As String = ""
38583863 'uriの正規表現
3859- Dim rgUrl As Regex = New Regex("(?<![0-9A-Za-z=])(?:https?|shttp|ftps?)://(?:(?:[-_.!~*'()a-zA-Z0-9;:&=+$,]|%[0-9A-Fa-f" + _
3860- "][0-9A-Fa-f])*@)?(?:(?:[a-zA-Z0-9](?:[-a-zA-Z0-9]*[a-zA-Z0-9])?\.)" + _
3861- "*[a-zA-Z](?:[-a-zA-Z0-9]*[a-zA-Z0-9])?\.?|[0-9]+\.[0-9]+\.[0-9]+\." + _
3862- "[0-9]+)(?::[0-9]*)?(?:/(?:[-_.!~*'()a-zA-Z0-9:@&=+$,]|%[0-9A-Fa-f]" + _
3863- "[0-9A-Fa-f])*(?:;(?:[-_.!~*'()a-zA-Z0-9:@&=+$,]|%[0-9A-Fa-f][0-9A-" + _
3864- "Fa-f])*)*(?:/(?:[-_.!~*'()a-zA-Z0-9:@&=+$,]|%[0-9A-Fa-f][0-9A-Fa-f" + _
3865- "])*(?:;(?:[-_.!~*'()a-zA-Z0-9:@&=+$,]|%[0-9A-Fa-f][0-9A-Fa-f])*)*)" + _
3866- "*)?(?:\?(?:[-_.!~*'()a-zA-Z0-9;/?:@&=+$,]|%[0-9A-Fa-f][0-9A-Fa-f])" + _
3867- "*)?(?:#(?:[-_.!~*'()a-zA-Z0-9;/?:@&=+$,]|%[0-9A-Fa-f][0-9A-Fa-f])*)?")
3868- Dim rgUrl2 As Regex = New Regex("(?<![^\/""':!=]|^|\:)" + _
3869- "(?:https?://|www\.)" + _
3870- "((?:[\.-]|[^\p{IsGeneralPunctuation}])+\.[a-z]{2,}(?::[0-9]+)?)" + _
3871- "(/[a-z0-9!*'();:&=+$/%#\[\]\-_.,~]*[a-z0-9)=#/]?)?" + _
3872- "(\?[a-z0-9!*'();:&=+$/%#\[\]\-_.,~]*[a-z0-9_&=#])?)")
3864+ 'Dim rgUrl As Regex = New Regex("(?<![0-9A-Za-z=])(?:https?|shttp|ftps?)://(?:(?:[-_.!~*'()a-zA-Z0-9;:&=+$,]|%[0-9A-Fa-f" + _
3865+ ' "][0-9A-Fa-f])*@)?(?:(?:[a-zA-Z0-9](?:[-a-zA-Z0-9]*[a-zA-Z0-9])?\.)" + _
3866+ ' "*[a-zA-Z](?:[-a-zA-Z0-9]*[a-zA-Z0-9])?\.?|[0-9]+\.[0-9]+\.[0-9]+\." + _
3867+ ' "[0-9]+)(?::[0-9]*)?(?:/(?:[-_.!~*'()a-zA-Z0-9:@&=+$,]|%[0-9A-Fa-f]" + _
3868+ ' "[0-9A-Fa-f])*(?:;(?:[-_.!~*'()a-zA-Z0-9:@&=+$,]|%[0-9A-Fa-f][0-9A-" + _
3869+ ' "Fa-f])*)*(?:/(?:[-_.!~*'()a-zA-Z0-9:@&=+$,]|%[0-9A-Fa-f][0-9A-Fa-f" + _
3870+ ' "])*(?:;(?:[-_.!~*'()a-zA-Z0-9:@&=+$,]|%[0-9A-Fa-f][0-9A-Fa-f])*)*)" + _
3871+ ' "*)?(?:\?(?:[-_.!~*'()a-zA-Z0-9;/?:@&=+$,]|%[0-9A-Fa-f][0-9A-Fa-f])" + _
3872+ ' "*)?(?:#(?:[-_.!~*'()a-zA-Z0-9;/?:@&=+$,]|%[0-9A-Fa-f][0-9A-Fa-f])*)?")
3873+ Dim rgUrl As Regex = New Regex("(?<before>(?:[^\/""':!=]|^|\:))" + _
3874+ "(?<url>(?<protocol>https?://|www\.)" + _
3875+ "(?<domain>(?:[\.-]|[^\p{P}])+\.[a-z]{2,}(?::[0-9]+)?)" + _
3876+ "(?<path>/[a-z0-9!*'();:&=+$/%#\[\]\-_.,~]*[a-z0-9)=#/]?)?" + _
3877+ "(?<query>\?[a-z0-9!*'();:&=+$/%#\[\]\-_.,~]*[a-z0-9_&=#])?)", RegexOptions.IgnoreCase Or RegexOptions.Compiled)
38733878 '絶対パス表現のUriをリンクに置換
3874- retStr = rgUrl.Replace(Text, "<a href=""$&"">$&</a>")
3875- 'Dim mts As MatchCollection = rgUrl.Matches(retStr)
3876- '''半角スペースを置換(Thanks @anis774)
3877- ''Text = Text.Replace(" ", "&nbsp;") 'HttpUtility.HtmlEncode()ではスペースが処理されない為
3878-
3879- 'For Each mt As Match In mts
3880- ' Text = Text.Replace(mt.Result("$&"), "<a href=""" + mt.Result("$&") + """>" + mt.Result("$&") + "</a>")
3881- 'Next
3882- 'retStr = Text
3879+ retStr = rgUrl.Replace(Text, New MatchEvaluator(AddressOf AutoLinkUrl))
38833880
38843881 '@返信を抽出し、@先リスト作成
38853882 'Dim rg As New Regex("(^|[ -/:-@[-^`{-~])@([a-zA-Z0-9_]{1,20}/[a-zA-Z0-9_\-]{1,24}[a-zA-Z0-9_])")
3886- Dim rg As New Regex("(^|[^a-zA-Z0-9_])[@@]([a-zA-Z0-9_]{1,20}/[a-zA-Z0-9_\-]{1,80}[a-zA-Z0-9_])")
3883+ Dim rg As New Regex("(^|[^a-zA-Z0-9_])[@@]([a-zA-Z0-9_]{1,20}/[a-zA-Z0-9_\-]{1,79}[a-zA-Z0-9_])", RegexOptions.Compiled)
38873884 Dim m As Match = rg.Match(retStr)
38883885 '@先をリンクに置換
38893886 retStr = rg.Replace(retStr, "$1@<a href=""/$2"">$2</a>")
38903887
38913888 'rg = New Regex("(^|[ -/:-@[-^`{-~])@([a-zA-Z0-9_]{1,20})")
3892- rg = New Regex("(^|[^a-zA-Z0-9_])[@@]([a-zA-Z0-9_]{1,20})")
3889+ rg = New Regex("(^|[^a-zA-Z0-9_])[@@]([a-zA-Z0-9_]{1,20})", RegexOptions.Compiled)
38933890 m = rg.Match(retStr)
38943891 While m.Success
38953892 AtList.Add(m.Result("$2").ToLower)
@@ -3900,7 +3897,7 @@ Public Module Twitter
39003897
39013898 'ハッシュタグを抽出し、リンクに置換
39023899 'Dim rgh As New Regex("(^|[ .!,\-:;<>?])#([^] !""#$%&'()*+,.:;<=>?@\-[\^`{|}~\r\n]+)")
3903- Dim rgh As New Regex("(^|[^a-zA-Z0-9_/&])[##]([a-zA-Z0-9_]+)")
3900+ Dim rgh As New Regex("(^|[^a-zA-Z0-9_/&])[##]([a-zA-Z0-9_]+)", RegexOptions.Compiled)
39043901 Dim mhs As MatchCollection = rgh.Matches(retStr)
39053902 For Each mt As Match In mhs
39063903 If Not IsNumeric(mt.Result("$2")) Then
@@ -3910,24 +3907,27 @@ Public Module Twitter
39103907 End SyncLock
39113908 End If
39123909 Next
3913- retStr = rgh.Replace(retStr, "$1<a href=""" + _protocol + "twitter.com/search?q=%23$2"">#$2</a>")
3914- '数字のみハッシュタグを戻す
3915- Dim rgnh As New Regex("<a href=""" + _protocol + "twitter.com/search\?q=%23[0-9]+"">(#[0-9]+)</a>")
3916- retStr = rgnh.Replace(retStr, "$1")
3917- 'If mh.Success Then
3918- ' retStr = rgh.Replace(retStr, "$1<a href=""" + _protocol + "twitter.com/search?q=%23$2"">#$2</a>")
3919- 'End If
3920- 'While mh.Success
3921- ' SyncLock LockObj
3922- ' _hashList.Add("#" + mh.Result("$2"))
3923- ' End SyncLock
3924- ' mh = mh.NextMatch
3925- 'End While
3910+ retStr = rgh.Replace(retStr, New MatchEvaluator(AddressOf AutoLinkHashtag))
39263911
39273912 retStr = AdjustHtml(ShortUrlResolve(PreProcessUrl(retStr))) 'IDN置換、短縮Uri解決、@リンクを相対→絶対にしてtarget属性付与
39283913 Return retStr
39293914 End Function
39303915
3916+ Private Function AutoLinkUrl(ByVal m As Match) As String
3917+ Dim sb As New StringBuilder(m.Result("${before}<a href="""))
3918+ If m.Result("${protocol}").StartsWith("w", StringComparison.OrdinalIgnoreCase) Then
3919+ sb.Append("http://")
3920+ End If
3921+ sb.Append(m.Result("${url}"">")).Append(m.Result("${url}")).Append("</a>")
3922+ Return sb.ToString
3923+ End Function
3924+
3925+ Private Function AutoLinkHashtag(ByVal m As Match) As String
3926+ If IsNumeric(m.Result("$2")) Then Return m.Result("$1#$2")
3927+ Dim sb As New StringBuilder(m.Result("$1<a href="""))
3928+ Return sb.Append(_protocol).Append("twitter.com/search?q=%23").Append(m.Result("$2"">#$2</a>")).ToString
3929+ End Function
3930+
39313931 Public ReadOnly Property RemainCountApi() As Integer
39323932 Get
39333933 Return twCon.RemainCountApi
@@ -4044,4 +4044,5 @@ Public Module Twitter
40444044 Return twCon.AccessTokenSecret
40454045 End Get
40464046 End Property
4047+
40474048 End Module
Show on old repository browser