OSDN Git Service

3299c6d2cd90f1b2ecfd47bd8978cc9f78b0b6ce
[opentween/open-tween.git] / OpenTween / Connection / HttpTwitter.cs
1 // OpenTween - Client of Twitter
2 // Copyright (c) 2007-2011 kiri_feather (@kiri_feather) <kiri.feather@gmail.com>
3 //           (c) 2008-2011 Moz (@syo68k)
4 //           (c) 2008-2011 takeshik (@takeshik) <http://www.takeshik.org/>
5 //           (c) 2010-2011 anis774 (@anis774) <http://d.hatena.ne.jp/anis774/>
6 //           (c) 2010-2011 fantasticswallow (@f_swallow) <http://twitter.com/f_swallow>
7 //           (c) 2011      kim_upsilon (@kim_upsilon) <https://upsilo.net/~upsilon/>
8 // All rights reserved.
9 // 
10 // This file is part of OpenTween.
11 // 
12 // This program is free software; you can redistribute it and/or modify it
13 // under the terms of the GNU General public License as published by the Free
14 // Software Foundation; either version 3 of the License, or (at your option)
15 // any later version.
16 // 
17 // This program is distributed in the hope that it will be useful, but
18 // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General public License
20 // for more details. 
21 // 
22 // You should have received a copy of the GNU General public License along
23 // with this program. If not, see <http://www.gnu.org/licenses/>, or write to
24 // the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
25 // Boston, MA 02110-1301, USA.
26
27 using System;
28 using System.Collections.Generic;
29 using System.Linq;
30 using System.Text;
31 using System.Net;
32 using System.IO;
33
34 namespace OpenTween
35 {
36     public class HttpTwitter : ICloneable
37     {
38         //OAuth関連
39         ///<summary>
40         ///OAuthのアクセストークン取得先URI
41         ///</summary>
42         private const string AccessTokenUrlXAuth = "https://api.twitter.com/oauth/access_token";
43         private const string RequestTokenUrl = "https://api.twitter.com/oauth/request_token";
44         private const string AuthorizeUrl = "https://api.twitter.com/oauth/authorize";
45         private const string AccessTokenUrl = "https://api.twitter.com/oauth/access_token";
46
47         private const string PostMethod = "POST";
48         private const string GetMethod = "GET";
49
50         private IHttpConnection httpCon; //HttpConnectionApi or HttpConnectionOAuth
51         private HttpVarious httpConVar = new HttpVarious();
52
53         private enum AuthMethod
54         {
55             OAuth,
56             Basic,
57         }
58         private AuthMethod connectionType = AuthMethod.Basic;
59
60         private string requestToken;
61
62         private static string tk = "";
63         private static string tks = "";
64         private static string un = "";
65
66         public void Initialize(string accessToken,
67                                         string accessTokenSecret,
68                                         string username,
69                                         long userId)
70         {
71             //for OAuth
72             HttpOAuthApiProxy con = new HttpOAuthApiProxy();
73             if (tk != accessToken || tks != accessTokenSecret ||
74                     un != username || connectionType != AuthMethod.OAuth)
75             {
76                 // 以前の認証状態よりひとつでも変化があったらhttpヘッダより読み取ったカウントは初期化
77                 tk = accessToken;
78                 tks = accessTokenSecret;
79                 un = username;
80             }
81             con.Initialize(ApplicationSettings.TwitterConsumerKey, ApplicationSettings.TwitterConsumerSecret, accessToken, accessTokenSecret, username, userId, "screen_name", "user_id");
82             httpCon = con;
83             connectionType = AuthMethod.OAuth;
84             requestToken = "";
85         }
86
87         public string AccessToken
88         {
89             get
90             {
91                 if (httpCon != null)
92                     return ((HttpConnectionOAuth)httpCon).AccessToken;
93                 else
94                     return "";
95             }
96         }
97
98         public string AccessTokenSecret
99         {
100             get
101             {
102                 if (httpCon != null)
103                     return ((HttpConnectionOAuth)httpCon).AccessTokenSecret;
104                 else
105                     return "";
106             }
107         }
108
109         public string AuthenticatedUsername
110         {
111             get
112             {
113                 if (httpCon != null)
114                     return httpCon.AuthUsername;
115                 else
116                     return "";
117             }
118         }
119
120         public long AuthenticatedUserId
121         {
122             get
123             {
124                 if (httpCon != null)
125                     return httpCon.AuthUserId;
126                 else
127                     return 0;
128             }
129             set
130             {
131                 if (httpCon != null)
132                     httpCon.AuthUserId = value;
133             }
134         }
135
136         public string Password
137         {
138             get
139             {
140                 return "";
141             }
142         }
143
144         public bool AuthGetRequestToken(ref string content)
145         {
146             Uri authUri = null;
147             bool result = ((HttpOAuthApiProxy)httpCon).AuthenticatePinFlowRequest(RequestTokenUrl, AuthorizeUrl, ref requestToken, ref authUri);
148             content = authUri.ToString();
149             return result;
150         }
151
152         public HttpStatusCode AuthGetAccessToken(string pin)
153         {
154             return ((HttpOAuthApiProxy)httpCon).AuthenticatePinFlow(AccessTokenUrl, requestToken, pin);
155         }
156
157         public HttpStatusCode AuthUserAndPass(string username, string password, ref string content)
158         {
159             return httpCon.Authenticate(new Uri(AccessTokenUrlXAuth), username, password, ref content);
160         }
161
162         public void ClearAuthInfo()
163         {
164             this.Initialize("", "", "", 0);
165         }
166
167         public HttpStatusCode UpdateStatus(string status, long? replyToId, ref string content)
168         {
169             Dictionary<string, string> param = new Dictionary<string, string>();
170             param.Add("status", status);
171             if (replyToId != null) param.Add("in_reply_to_status_id", replyToId.ToString());
172             param.Add("include_entities", "true");
173             //if (AppendSettingDialog.Instance.ShortenTco && AppendSettingDialog.Instance.UrlConvertAuto) param.Add("wrap_links", "true")
174
175             return httpCon.GetContent(PostMethod,
176                 this.CreateTwitterUri("/1.1/statuses/update.json"),
177                 param,
178                 ref content,
179                 null,
180                 null);
181         }
182
183         public HttpStatusCode UpdateStatusWithMedia(string status, long? replyToId, FileInfo mediaFile, ref string content)
184         {
185             //画像投稿用エンドポイント
186             Dictionary<string, string> param = new Dictionary<string, string>();
187             param.Add("status", status);
188             if (replyToId != null) param.Add("in_reply_to_status_id", replyToId.ToString());
189             param.Add("include_entities", "true");
190             //if (AppendSettingDialog.Instance.ShortenTco && AppendSettingDialog.Instance.UrlConvertAuto) param.Add("wrap_links", "true")
191
192             List<KeyValuePair<string, FileInfo>> binary = new List<KeyValuePair<string, FileInfo>>();
193             binary.Add(new KeyValuePair<string, FileInfo>("media[]", mediaFile));
194
195             return httpCon.GetContent(PostMethod,
196                 this.CreateTwitterUri("/1.1/statuses/update_with_media.json"),
197                 param,
198                 binary,
199                 ref content,
200                 this.CreateRatelimitHeadersDict(),
201                 this.CreateApiCalllback("/statuses/update_with_media"));
202         }
203
204         public HttpStatusCode DestroyStatus(long id)
205         {
206             string content = null;
207
208             return httpCon.GetContent(PostMethod,
209                 this.CreateTwitterUri("/1.1/statuses/destroy/" + id + ".json"),
210                 null,
211                 ref content,
212                 null,
213                 null);
214         }
215
216         public HttpStatusCode SendDirectMessage(string status, string sendto, ref string content)
217         {
218             Dictionary<string, string> param = new Dictionary<string, string>();
219             param.Add("text", status);
220             param.Add("screen_name", sendto);
221             //if (AppendSettingDialog.Instance.ShortenTco && AppendSettingDialog.Instance.UrlConvertAuto) param.Add("wrap_links", "true")
222
223             return httpCon.GetContent(PostMethod,
224                 this.CreateTwitterUri("/1.1/direct_messages/new.json"),
225                 param,
226                 ref content,
227                 null,
228                 null);
229         }
230
231         public HttpStatusCode DestroyDirectMessage(long id)
232         {
233             string content = null;
234
235             var param = new Dictionary<string, string>();
236             param.Add("id", id.ToString());
237
238             return httpCon.GetContent(PostMethod,
239                 this.CreateTwitterUri("/1.1/direct_messages/destroy.json"),
240                 param,
241                 ref content,
242                 null,
243                 null);
244         }
245
246         public HttpStatusCode RetweetStatus(long id, ref string content)
247         {
248             Dictionary<string, string> param = new Dictionary<string, string>();
249             param.Add("include_entities", "true");
250
251             return httpCon.GetContent(PostMethod,
252                 this.CreateTwitterUri("/1.1/statuses/retweet/" + id + ".json"),
253                 param,
254                 ref content,
255                 null,
256                 null);
257         }
258
259         public HttpStatusCode ShowUserInfo(string screenName, ref string content)
260         {
261             Dictionary<string, string> param = new Dictionary<string, string>();
262             param.Add("screen_name", screenName);
263             param.Add("include_entities", "true");
264             return httpCon.GetContent(GetMethod,
265                 this.CreateTwitterUri("/1.1/users/show.json"),
266                 param,
267                 ref content,
268                 this.CreateRatelimitHeadersDict(),
269                 this.CreateApiCalllback("/users/show/:id"));
270         }
271
272         public HttpStatusCode CreateFriendships(string screenName, ref string content)
273         {
274             Dictionary<string, string> param = new Dictionary<string, string>();
275             param.Add("screen_name", screenName);
276
277             return httpCon.GetContent(PostMethod,
278                 this.CreateTwitterUri("/1.1/friendships/create.json"),
279                 param,
280                 ref content,
281                 null,
282                 null);
283         }
284
285         public HttpStatusCode DestroyFriendships(string screenName, ref string content)
286         {
287             Dictionary<string, string> param = new Dictionary<string, string>();
288             param.Add("screen_name", screenName);
289
290             return httpCon.GetContent(PostMethod,
291                 this.CreateTwitterUri("/1.1/friendships/destroy.json"),
292                 param,
293                 ref content,
294                 null,
295                 null);
296         }
297
298         public HttpStatusCode CreateBlock(string screenName, ref string content)
299         {
300             Dictionary<string, string> param = new Dictionary<string, string>();
301             param.Add("screen_name", screenName);
302
303             return httpCon.GetContent(PostMethod,
304                 this.CreateTwitterUri("/1.1/blocks/create.json"),
305                 param,
306                 ref content,
307                 null,
308                 null);
309         }
310
311         public HttpStatusCode DestroyBlock(string screenName, ref string content)
312         {
313             Dictionary<string, string> param = new Dictionary<string, string>();
314             param.Add("screen_name", screenName);
315
316             return httpCon.GetContent(PostMethod,
317                 this.CreateTwitterUri("/1.1/blocks/destroy.json"),
318                 param,
319                 ref content,
320                 null,
321                 null);
322         }
323
324         public HttpStatusCode ReportSpam(string screenName, ref string content)
325         {
326             Dictionary<string, string> param = new Dictionary<string, string>();
327             param.Add("screen_name", screenName);
328
329             return httpCon.GetContent(PostMethod,
330                 this.CreateTwitterUri("/1.1/users/report_spam.json"),
331                 param,
332                 ref content,
333                 null,
334                 null);
335         }
336
337         public HttpStatusCode ShowFriendships(string souceScreenName, string targetScreenName, ref string content)
338         {
339             Dictionary<string, string> param = new Dictionary<string, string>();
340             param.Add("source_screen_name", souceScreenName);
341             param.Add("target_screen_name", targetScreenName);
342
343             return httpCon.GetContent(GetMethod,
344                 this.CreateTwitterUri("/1.1/friendships/show.json"),
345                 param,
346                 ref content,
347                 this.CreateRatelimitHeadersDict(),
348                 this.CreateApiCalllback("/friendships/show"));
349         }
350
351         public HttpStatusCode ShowStatuses(long id, ref string content)
352         {
353             Dictionary<string, string> param = new Dictionary<string, string>();
354             param.Add("include_entities", "true");
355             return httpCon.GetContent(GetMethod,
356                 this.CreateTwitterUri("/1.1/statuses/show/" + id + ".json"),
357                 param,
358                 ref content,
359                 this.CreateRatelimitHeadersDict(),
360                 this.CreateApiCalllback("/statuses/show/:id"));
361         }
362
363         public HttpStatusCode CreateFavorites(long id, ref string content)
364         {
365             var param = new Dictionary<string, string>();
366             param.Add("id", id.ToString());
367
368             return httpCon.GetContent(PostMethod,
369                 this.CreateTwitterUri("/1.1/favorites/create.json"),
370                 param,
371                 ref content,
372                 null,
373                 null);
374         }
375
376         public HttpStatusCode DestroyFavorites(long id, ref string content)
377         {
378             var param = new Dictionary<string, string>();
379             param.Add("id", id.ToString());
380
381             return httpCon.GetContent(PostMethod,
382                 this.CreateTwitterUri("/1.1/favorites/destroy.json"),
383                 param,
384                 ref content,
385                 null,
386                 null);
387         }
388
389         public HttpStatusCode HomeTimeline(int? count, long? max_id, long? since_id, ref string content)
390         {
391             Dictionary<string, string> param = new Dictionary<string, string>();
392             if (count != null)
393                 param.Add("count", count.ToString());
394             if (max_id != null)
395                 param.Add("max_id", max_id.ToString());
396             if (since_id != null)
397                 param.Add("since_id", since_id.ToString());
398
399             param.Add("include_entities", "true");
400
401             return httpCon.GetContent(GetMethod,
402                 this.CreateTwitterUri("/1.1/statuses/home_timeline.json"),
403                 param,
404                 ref content,
405                 this.CreateRatelimitHeadersDict(),
406                 this.CreateApiCalllback("/statuses/home_timeline"));
407         }
408
409         public HttpStatusCode UserTimeline(long? user_id, string screen_name, int? count, long? max_id, long? since_id, ref string content)
410         {
411             Dictionary<string, string> param = new Dictionary<string, string>();
412
413             if ((user_id == null && string.IsNullOrEmpty(screen_name)) ||
414                 (user_id != null && !string.IsNullOrEmpty(screen_name))) return HttpStatusCode.BadRequest;
415
416             if (user_id != null)
417                 param.Add("user_id", user_id.ToString());
418             if (!string.IsNullOrEmpty(screen_name))
419                 param.Add("screen_name", screen_name);
420             if (count != null)
421                 param.Add("count", count.ToString());
422             if (max_id != null)
423                 param.Add("max_id", max_id.ToString());
424             if (since_id != null)
425                 param.Add("since_id", since_id.ToString());
426
427             param.Add("include_rts", "true");
428             param.Add("include_entities", "true");
429
430             return httpCon.GetContent(GetMethod,
431                 this.CreateTwitterUri("/1.1/statuses/user_timeline.json"),
432                 param,
433                 ref content,
434                 this.CreateRatelimitHeadersDict(),
435                 this.CreateApiCalllback("/statuses/user_timeline"));
436         }
437
438         public HttpStatusCode Mentions(int? count, long? max_id, long? since_id, ref string content)
439         {
440             Dictionary<string, string> param = new Dictionary<string, string>();
441             if (count != null)
442                 param.Add("count", count.ToString());
443             if (max_id != null)
444                 param.Add("max_id", max_id.ToString());
445             if (since_id != null)
446                 param.Add("since_id", since_id.ToString());
447
448             param.Add("include_entities", "true");
449
450             return httpCon.GetContent(GetMethod,
451                 this.CreateTwitterUri("/1.1/statuses/mentions_timeline.json"),
452                 param,
453                 ref content,
454                 this.CreateRatelimitHeadersDict(),
455                 this.CreateApiCalllback("/statuses/mentions_timeline"));
456         }
457
458         public HttpStatusCode DirectMessages(int? count, long? max_id, long? since_id, ref string content)
459         {
460             Dictionary<string, string> param = new Dictionary<string, string>();
461             if (count != null)
462                 param.Add("count", count.ToString());
463             if (max_id != null)
464                 param.Add("max_id", max_id.ToString());
465             if (since_id != null)
466                 param.Add("since_id", since_id.ToString());
467             param.Add("include_entities", "true");
468
469             return httpCon.GetContent(GetMethod,
470                 this.CreateTwitterUri("/1.1/direct_messages.json"),
471                 param,
472                 ref content,
473                 this.CreateRatelimitHeadersDict(),
474                 this.CreateApiCalllback("/direct_messages"));
475         }
476
477         public HttpStatusCode DirectMessagesSent(int? count, long? max_id, long? since_id, ref string content)
478         {
479             Dictionary<string, string> param = new Dictionary<string, string>();
480             if (count != null)
481                 param.Add("count", count.ToString());
482             if (max_id != null)
483                 param.Add("max_id", max_id.ToString());
484             if (since_id != null)
485                 param.Add("since_id", since_id.ToString());
486             param.Add("include_entities", "true");
487
488             return httpCon.GetContent(GetMethod,
489                 this.CreateTwitterUri("/1.1/direct_messages/sent.json"),
490                 param,
491                 ref content,
492                 this.CreateRatelimitHeadersDict(),
493                 this.CreateApiCalllback("/direct_messages/sent"));
494         }
495
496         public HttpStatusCode Favorites(int? count, int? page, ref string content)
497         {
498             Dictionary<string, string> param = new Dictionary<string, string>();
499             if (count != null) param.Add("count", count.ToString());
500
501             if (page != null)
502             {
503                 param.Add("page", page.ToString());
504             }
505
506             param.Add("include_entities", "true");
507
508             return httpCon.GetContent(GetMethod,
509                 this.CreateTwitterUri("/1.1/favorites/list.json"),
510                 param,
511                 ref content,
512                 this.CreateRatelimitHeadersDict(),
513                 this.CreateApiCalllback("/favorites/list"));
514         }
515
516         public HttpStatusCode Search(string words, string lang, int? count, long? maxId, long? sinceId, ref string content)
517         {
518             Dictionary<string, string> param = new Dictionary<string, string>();
519             if (!string.IsNullOrEmpty(words)) param.Add("q", words);
520             if (!string.IsNullOrEmpty(lang)) param.Add("lang", lang);
521             if (count != null) param.Add("count", count.ToString());
522             if (maxId != null) param.Add("max_id", maxId.ToString());
523             if (sinceId != null) param.Add("since_id", sinceId.ToString());
524
525             if (param.Count == 0) return HttpStatusCode.BadRequest;
526
527             param.Add("result_type", "recent");
528             param.Add("include_entities", "true");
529             return httpCon.GetContent(GetMethod,
530                 this.CreateTwitterUri("/1.1/search/tweets.json"),
531                 param,
532                 ref content,
533                 this.CreateRatelimitHeadersDict(),
534                 this.CreateApiCalllback("/search/tweets"));
535         }
536
537         public HttpStatusCode SavedSearches(ref string content)
538         {
539             return httpCon.GetContent(GetMethod,
540                 this.CreateTwitterUri("/1.1/saved_searches/list.json"),
541                 null,
542                 ref content,
543                 this.CreateRatelimitHeadersDict(),
544                 this.CreateApiCalllback("/saved_searches/list"));
545         }
546
547         public HttpStatusCode FollowerIds(long cursor, ref string content)
548         {
549             Dictionary<string, string> param = new Dictionary<string, string>();
550             param.Add("cursor", cursor.ToString());
551
552             return httpCon.GetContent(GetMethod,
553                 this.CreateTwitterUri("/1.1/followers/ids.json"),
554                 param,
555                 ref content,
556                 this.CreateRatelimitHeadersDict(),
557                 this.CreateApiCalllback("/followers/ids"));
558         }
559
560         public HttpStatusCode NoRetweetIds(ref string content)
561         {
562             return httpCon.GetContent(GetMethod,
563                 this.CreateTwitterUri("/1.1/friendships/no_retweets/ids.json"),
564                 null,
565                 ref content,
566                 this.CreateRatelimitHeadersDict(),
567                 this.CreateApiCalllback("/friendships/no_retweets/ids"));
568         }
569
570         public HttpStatusCode RateLimitStatus(ref string content)
571         {
572             return httpCon.GetContent(GetMethod,
573                 this.CreateTwitterUri("/1.1/application/rate_limit_status.json"),
574                 null,
575                 ref content,
576                 this.CreateRatelimitHeadersDict(),
577                 this.CreateApiCalllback("/application/rate_limit_status"));
578         }
579
580         #region Lists
581         public HttpStatusCode GetLists(string user, ref string content)
582         {
583             Dictionary<string, string> param = new Dictionary<string, string>();
584             param.Add("screen_name", user);
585
586             return httpCon.GetContent(GetMethod,
587                 this.CreateTwitterUri("/1.1/lists/list.json"),
588                 param,
589                 ref content,
590                 this.CreateRatelimitHeadersDict(),
591                 this.CreateApiCalllback("/lists/list"));
592         }
593
594         public HttpStatusCode UpdateListID(string user, string list_id, string name, Boolean isPrivate, string description, ref string content)
595         {
596             string mode = "public";
597             if (isPrivate)
598                 mode = "private";
599
600             Dictionary<string, string> param = new Dictionary<string, string>();
601             param.Add("screen_name", user);
602             param.Add("list_id", list_id);
603             if (name != null) param.Add("name", name);
604             if (mode != null) param.Add("mode", mode);
605             if (description != null) param.Add("description", description);
606
607             return httpCon.GetContent(PostMethod,
608                 this.CreateTwitterUri("/1.1/lists/update.json"),
609                 param,
610                 ref content,
611                 null,
612                 null);
613         }
614
615         public HttpStatusCode DeleteListID(string user, string list_id, ref string content)
616         {
617             Dictionary<string, string> param = new Dictionary<string, string>();
618             param.Add("screen_name", user);
619             param.Add("list_id", list_id);
620
621             return httpCon.GetContent(PostMethod,
622                 this.CreateTwitterUri("/1.1/lists/destroy.json"),
623                 param,
624                 ref content,
625                 null,
626                 null);
627         }
628
629         public HttpStatusCode GetListsSubscriptions(string user, ref string content)
630         {
631             Dictionary<string, string> param = new Dictionary<string, string>();
632             param.Add("screen_name", user);
633
634             return httpCon.GetContent(GetMethod,
635                 this.CreateTwitterUri("/1.1/lists/subscriptions.json"),
636                 param,
637                 ref content,
638                 this.CreateRatelimitHeadersDict(),
639                 this.CreateApiCalllback("/lists/subscriptions"));
640         }
641
642         public HttpStatusCode GetListsStatuses(long userId, long list_id, int? per_page, long? max_id, long? since_id, Boolean isRTinclude, ref string content)
643         {
644             //認証なくても取得できるが、protectedユーザー分が抜ける
645             Dictionary<string, string> param = new Dictionary<string, string>();
646             param.Add("user_id", userId.ToString());
647             param.Add("list_id", list_id.ToString());
648             param.Add("include_rts", isRTinclude ? "true" : "false");
649             if (per_page != null)
650                 param.Add("count", per_page.ToString());
651             if (max_id != null)
652                 param.Add("max_id", max_id.ToString());
653             if (since_id != null)
654                 param.Add("since_id", since_id.ToString());
655             param.Add("include_entities", "true");
656
657             return httpCon.GetContent(GetMethod,
658                 this.CreateTwitterUri("/1.1/lists/statuses.json"),
659                 param,
660                 ref content,
661                 this.CreateRatelimitHeadersDict(),
662                 this.CreateApiCalllback("/lists/statuses"));
663         }
664
665         public HttpStatusCode CreateLists(string listname, Boolean isPrivate, string description, ref string content)
666         {
667             string mode = "public";
668             if (isPrivate)
669                 mode = "private";
670
671             Dictionary<string, string> param = new Dictionary<string, string>();
672             param.Add("name", listname);
673             param.Add("mode", mode);
674             if (!string.IsNullOrEmpty(description))
675                 param.Add("description", description);
676
677             return httpCon.GetContent(PostMethod,
678                 this.CreateTwitterUri("/1.1/lists/create.json"),
679                 param,
680                 ref content,
681                 null,
682                 null);
683         }
684
685         public HttpStatusCode GetListMembers(string user, string list_id, long cursor, ref string content)
686         {
687             Dictionary<string, string> param = new Dictionary<string, string>();
688             param.Add("screen_name", user);
689             param.Add("list_id", list_id);
690             param.Add("cursor", cursor.ToString());
691             return httpCon.GetContent(GetMethod,
692                 this.CreateTwitterUri("/1.1/lists/members.json"),
693                 param,
694                 ref content,
695                 this.CreateRatelimitHeadersDict(),
696                 this.CreateApiCalllback("/lists/members"));
697         }
698
699         public HttpStatusCode CreateListMembers(string list_id, string memberName, ref string content)
700         {
701             Dictionary<string, string> param = new Dictionary<string, string>();
702             param.Add("list_id", list_id);
703             param.Add("screen_name", memberName);
704             return httpCon.GetContent(PostMethod,
705                 this.CreateTwitterUri("/1.1/lists/members/create.json"),
706                 param,
707                 ref content,
708                 null,
709                 null);
710         }
711
712         public HttpStatusCode DeleteListMembers(string list_id, string memberName, ref string content)
713         {
714             Dictionary<string, string> param = new Dictionary<string, string>();
715             param.Add("screen_name", memberName);
716             param.Add("list_id", list_id);
717             return httpCon.GetContent(PostMethod,
718                 this.CreateTwitterUri("/1.1/lists/members/destroy.json"),
719                 param,
720                 ref content,
721                 null,
722                 null);
723         }
724
725         public HttpStatusCode ShowListMember(string list_id, string memberName, ref string content)
726         {
727             Dictionary<string, string> param = new Dictionary<string, string>();
728             param.Add("screen_name", memberName);
729             param.Add("list_id", list_id);
730             return httpCon.GetContent(GetMethod,
731                 this.CreateTwitterUri("/1.1/lists/members/show.json"),
732                 param,
733                 ref content,
734                 this.CreateRatelimitHeadersDict(),
735                 this.CreateApiCalllback("/lists/members/show"));
736         }
737         #endregion
738
739         public HttpStatusCode Statusid_retweeted_by_ids(long statusid, int? count, int? page, ref string content)
740         {
741             Dictionary<string, string> param = new Dictionary<string, string>();
742             if (count != null)
743                 param.Add("count", count.ToString());
744             if (page != null)
745                 param.Add("page", page.ToString());
746
747             param.Add("id", statusid.ToString());
748
749             return httpCon.GetContent(GetMethod,
750                 this.CreateTwitterUri("/1.1/statuses/retweeters/ids.json"),
751                 param,
752                 ref content,
753                 this.CreateRatelimitHeadersDict(),
754                 this.CreateApiCalllback("/statuses/retweeters/ids"));
755         }
756
757         public HttpStatusCode UpdateProfile(string name, string url, string location, string description, ref string content)
758         {
759             Dictionary<string, string> param = new Dictionary<string, string>();
760
761             param.Add("name", WebUtility.HtmlEncode(name));
762             param.Add("url", url);
763             param.Add("location", WebUtility.HtmlEncode(location));
764             param.Add("description", WebUtility.HtmlEncode(description));
765             param.Add("include_entities", "true");
766
767             return httpCon.GetContent(PostMethod,
768                 this.CreateTwitterUri("/1.1/account/update_profile.json"),
769                 param,
770                 ref content,
771                 null,
772                 null);
773         }
774
775         public HttpStatusCode UpdateProfileImage(FileInfo imageFile, ref string content)
776         {
777             List<KeyValuePair<string, FileInfo>> binary = new List<KeyValuePair<string, FileInfo>>();
778             binary.Add(new KeyValuePair<string, FileInfo>("image", imageFile));
779
780             return httpCon.GetContent(PostMethod,
781                 this.CreateTwitterUri("/1.1/account/update_profile_image.json"),
782                 null,
783                 binary,
784                 ref content,
785                 null,
786                 null);
787         }
788
789         public HttpStatusCode GetBlockUserIds(ref string content, long? cursor)
790         {
791             var param = new Dictionary<string, string>();
792
793             if (cursor != null)
794                 param.Add("cursor", cursor.ToString());
795
796             return httpCon.GetContent(GetMethod,
797                 this.CreateTwitterUri("/1.1/blocks/ids.json"),
798                 param,
799                 ref content,
800                 this.CreateRatelimitHeadersDict(),
801                 this.CreateApiCalllback("/blocks/ids"));
802         }
803
804         public HttpStatusCode GetMuteUserIds(ref string content, long? cursor)
805         {
806             var param = new Dictionary<string, string>();
807
808             if (cursor != null)
809                 param.Add("cursor", cursor.ToString());
810
811             return httpCon.GetContent(GetMethod,
812                 this.CreateTwitterUri("/1.1/mutes/users/ids.json"),
813                 param,
814                 ref content,
815                 this.CreateRatelimitHeadersDict(),
816                 this.CreateApiCalllback("/1.1/mutes/users/ids"));
817         }
818
819         public HttpStatusCode GetConfiguration(ref string content)
820         {
821             return httpCon.GetContent(GetMethod,
822                 this.CreateTwitterUri("/1.1/help/configuration.json"),
823                 null,
824                 ref content,
825                 this.CreateRatelimitHeadersDict(),
826                 this.CreateApiCalllback("/help/configuration"));
827         }
828
829         public HttpStatusCode VerifyCredentials(ref string content)
830         {
831             return httpCon.GetContent(GetMethod,
832                 this.CreateTwitterUri("/1.1/account/verify_credentials.json"),
833                 null,
834                 ref content,
835                 this.CreateRatelimitHeadersDict(),
836                 this.CreateApiCalllback("/account/verify_credentials"));
837         }
838
839         #region Proxy API
840         private static string _twitterUrl = "api.twitter.com";
841         private static string _twitterUserStreamUrl = "userstream.twitter.com";
842         private static string _twitterStreamUrl = "stream.twitter.com";
843
844         private Uri CreateTwitterUri(string path)
845         {
846             return new Uri(string.Format("{0}{1}{2}", "https://", _twitterUrl, path));
847         }
848
849         private Uri CreateTwitterUserStreamUri(string path)
850         {
851             return new Uri(string.Format("{0}{1}{2}", "https://", _twitterUserStreamUrl, path));
852         }
853
854         private Uri CreateTwitterStreamUri(string path)
855         {
856             return new Uri(string.Format("{0}{1}{2}", "http://", _twitterStreamUrl, path));
857         }
858
859         public static string TwitterUrl
860         {
861             set
862             {
863                 _twitterUrl = value;
864                 HttpOAuthApiProxy.ProxyHost = value;
865             }
866         }
867         #endregion
868
869         private Dictionary<string, string> CreateRatelimitHeadersDict()
870         {
871             return new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
872             {
873                 {"X-Access-Level", ""},
874                 {"X-RateLimit-Limit", ""},
875                 {"X-RateLimit-Remaining", ""},
876                 {"X-RateLimit-Reset", ""},
877                 {"X-Rate-Limit-Limit", ""},
878                 {"X-Rate-Limit-Remaining", ""},
879                 {"X-Rate-Limit-Reset", ""},
880                 {"X-MediaRateLimit-Limit", ""},
881                 {"X-MediaRateLimit-Remaining", ""},
882                 {"X-MediaRateLimit-Reset", ""},
883             };
884         }
885
886         private CallbackDelegate CreateApiCalllback(string endpointName)
887         {
888             return (sender, code, headerInfo, content) =>
889             {
890                 if (code < HttpStatusCode.InternalServerError)
891                     MyCommon.TwitterApiInfo.UpdateFromHeader(headerInfo, endpointName);
892             };
893         }
894
895         public HttpStatusCode UserStream(ref Stream content,
896                                          bool allAtReplies,
897                                          string trackwords,
898                                          string userAgent)
899         {
900             Dictionary<string, string> param = new Dictionary<string, string>();
901
902             if (allAtReplies)
903                 param.Add("replies", "all");
904
905             if (!string.IsNullOrEmpty(trackwords))
906                 param.Add("track", trackwords);
907
908             return httpCon.GetContent(GetMethod,
909                 this.CreateTwitterUserStreamUri("/1.1/user.json"),
910                 param,
911                 ref content,
912                 userAgent);
913         }
914
915         public HttpStatusCode FilterStream(ref Stream content,
916                                            string trackwords,
917                                            string userAgent)
918         {
919             //文中の日本語キーワードに反応せず、使えない(スペースで分かち書きしてないと反応しない)
920             Dictionary<string, string> param = new Dictionary<string, string>();
921
922             if (!string.IsNullOrEmpty(trackwords))
923                 param.Add("track", string.Join(",", trackwords.Split(" ".ToCharArray())));
924
925             return httpCon.GetContent(PostMethod,
926                 this.CreateTwitterStreamUri("/1.1/statuses/filter.json"),
927                 param,
928                 ref content,
929                 userAgent);
930         }
931
932         public void RequestAbort()
933         {
934             httpCon.RequestAbort();
935         }
936
937         public object Clone()
938         {
939             HttpTwitter myCopy = new HttpTwitter();
940             myCopy.Initialize(this.AccessToken, this.AccessTokenSecret, this.AuthenticatedUsername, this.AuthenticatedUserId);
941             return myCopy;
942         }
943     }
944 }