• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

LINQ To TwitterのUserStreamをもっと使いやすくしようとか妄想してるプロジェクト


Commit MetaInfo

Revisionbc06fdee5e87659f55fd398144ba11b1b73afeea (tree)
Zeit2011-02-09 18:33:23
Autorazyobuzin <azyobuzin@user...>
Commiterazyobuzin

Log Message

・Stopメソッドで停止したときにStoppedEventArgs.ReasonがErrorになる不具合を修正
・メソッドチェーンでつなげるようにした
・コード整理

Ändern Zusammenfassung

Diff

--- /dev/null
+++ b/UserStreamEx/EventArgs.cs
@@ -0,0 +1,179 @@
1+using System;
2+using System.Globalization;
3+using System.Xml.Linq;
4+using Codeplex.Data;
5+using LinqToTwitter;
6+
7+namespace Azyobuzi.UserStreamEx
8+{
9+ public class StoppedEventArgs : EventArgs
10+ {
11+ public StoppedEventArgs(StopReason reason, Exception ex)
12+ {
13+ this.Reason = reason;
14+ this.Exception = ex;
15+ }
16+
17+ public StopReason Reason { private set; get; }
18+ public Exception Exception { private set; get; }
19+ }
20+
21+ public enum StopReason
22+ {
23+ /// <summary>
24+ /// Twitterが切断
25+ /// </summary>
26+ CloseResponse,
27+ /// <summary>
28+ /// Stopメソッドが呼ばれた
29+ /// </summary>
30+ UserStop,
31+ /// <summary>
32+ /// その他の例外
33+ /// </summary>
34+ Error
35+ }
36+
37+ public class ReceiveJsonEventArgs : EventArgs
38+ {
39+ public ReceiveJsonEventArgs(string line)
40+ {
41+ this.Line = line;
42+ }
43+
44+ public string Line { private set; get; }
45+ }
46+
47+ public class ReceiveFriendsEventArgs : ReceiveJsonEventArgs
48+ {
49+ public ReceiveFriendsEventArgs(string line)
50+ : base(line)
51+ {
52+ FriendIds = (string[])DynamicJson.Parse(line).friends;
53+ }
54+
55+ public string[] FriendIds { private set; get; }
56+ }
57+
58+ public class NewTweetEventArgs : ReceiveJsonEventArgs
59+ {
60+ public NewTweetEventArgs(string line)
61+ : base(line)
62+ {
63+ Status = Status.CreateStatus(line.JsonToXml());
64+ }
65+
66+ public Status Status { private set; get; }
67+ }
68+
69+ public class NewDirectMessageEventArgs : ReceiveJsonEventArgs
70+ {
71+ public NewDirectMessageEventArgs(string line)
72+ : base(line)
73+ {
74+ var json = DynamicJson.Parse(line).direct_message;
75+ DirectMessage = new DirectMessage()
76+ {
77+ ID = (ulong)json.id,
78+ SenderID = (ulong)json.sender_id,
79+ Text = json.text,
80+ RecipientID = (ulong)json.recipient_id,
81+ CreatedAt = DateTime.ParseExact(json.created_at, "ddd MMM dd HH:mm:ss %zzzz yyyy", CultureInfo.InvariantCulture),
82+ SenderScreenName = json.sender_screen_name,
83+ RecipientScreenName = json.recipient_screen_name,
84+ Sender = User.CreateUser(((string)json.sender.ToString()).JsonToXml()),
85+ Recipient = User.CreateUser(((string)json.recipient.ToString()).JsonToXml())
86+ };
87+ }
88+
89+ public DirectMessage DirectMessage { private set; get; }
90+ }
91+
92+ public class DeleteStatusEventArgs : ReceiveJsonEventArgs
93+ {
94+ public DeleteStatusEventArgs(string line)
95+ : base(line)
96+ {
97+ var json = DynamicJson.Parse(line).delete;
98+ if (!json.direct_message())
99+ {
100+ //ツイート
101+ StatusId = json.status.id_str;
102+ UserId = json.status.user_id_str;
103+ IsDirectMessage = false;
104+ }
105+ else
106+ {
107+ //DM
108+ StatusId = json.direct_message.id.ToString();
109+ UserId = json.direct_message.user_id.ToString();
110+ IsDirectMessage = true;
111+ }
112+ }
113+
114+ public string StatusId { private set; get; }
115+ public string UserId { private set; get; }
116+ public bool IsDirectMessage { private set; get; }
117+ }
118+
119+ public class ReceiveEventEventArgs : ReceiveJsonEventArgs
120+ {
121+ public ReceiveEventEventArgs(string line)
122+ : base(line)
123+ {
124+ var json = DynamicJson.Parse(line);
125+ EventTypes eventType = EventTypes.Unknown;
126+ Enum.TryParse(((string)json.@event).Replace("_", ""), true, out eventType);
127+ EventType = eventType;
128+ CreatedAt = DateTime.ParseExact(json.created_at, "ddd MMM dd HH:mm:ss %zzzz yyyy", CultureInfo.InvariantCulture).ToLocalTime();
129+ Source = User.CreateUser(((string)json.source.ToString()).JsonToXml());
130+ Target = User.CreateUser(((string)json.target.ToString()).JsonToXml());
131+ if (json.target_object())
132+ {
133+ if (json.target_object.mode())
134+ {
135+ //リスト
136+ TargetList = List.CreateList(((string)json.target_object.ToString()).JsonToXml(), new XElement("lists_list"));
137+ }
138+ else
139+ {
140+ //ツイート
141+ TargetStatus = Status.CreateStatus(((string)json.target_object.ToString()).JsonToXml());
142+ }
143+ }
144+ }
145+
146+ public EventTypes EventType { private set; get; }
147+ public DateTime CreatedAt { private set; get; }
148+ public User Source { private set; get; }
149+ public User Target { private set; get; }
150+ public Status TargetStatus { private set; get; }
151+ public List TargetList { private set; get; }
152+ }
153+
154+ public enum EventTypes
155+ {
156+ Unknown,
157+ Favorite,
158+ Unfavorite,
159+ Follow,
160+ ListMemberAdded,
161+ ListMemberRemoved,
162+ Block,
163+ Unblock,
164+ UserUpdate,
165+ ListCreated,
166+ ListDestroyed
167+ }
168+
169+ public class TrackLimitEventArgs : ReceiveJsonEventArgs
170+ {
171+ public TrackLimitEventArgs(string line)
172+ : base(line)
173+ {
174+ Track = (ulong)DynamicJson.Parse(line).limit.track;
175+ }
176+
177+ public ulong Track { private set; get; }
178+ }
179+}
--- a/UserStreamEx/Extensions.cs
+++ b/UserStreamEx/Extensions.cs
@@ -8,7 +8,7 @@ namespace Azyobuzi.UserStreamEx
88 {
99 public static class AddToLinqToTwitter
1010 {
11- public static UserStream UserStreamEx(this TwitterContext twCtx)
11+ public static INotStartedUserStream UserStreamEx(this TwitterContext twCtx)
1212 {
1313 return new UserStream(twCtx.AuthorizedClient);
1414 }
--- /dev/null
+++ b/UserStreamEx/Interfaces.cs
@@ -0,0 +1,39 @@
1+using System;
2+
3+namespace Azyobuzi.UserStreamEx
4+{
5+ public interface INotStartedUserStream
6+ {
7+ IStartedUserStream Start(string track, bool allReplies);
8+
9+ #region Events
10+ event EventHandler Started;
11+ event EventHandler<StoppedEventArgs> Stopped;
12+ event EventHandler<ReceiveFriendsEventArgs> ReceiveFriends;
13+ event EventHandler<NewTweetEventArgs> NewTweet;
14+ event EventHandler<NewDirectMessageEventArgs> NewDirectMessage;
15+ event EventHandler<DeleteStatusEventArgs> DeleteStatus;
16+ event EventHandler<ReceiveEventEventArgs> ReceiveEvent;
17+ event EventHandler<TrackLimitEventArgs> TrackLimit;
18+ event EventHandler<ReceiveJsonEventArgs> ReceiveUnsupportedData;
19+ #endregion
20+
21+ #region AddHandlerMethod
22+ INotStartedUserStream SetStartedEvent(EventHandler handler);
23+ INotStartedUserStream SetStoppedEvent(EventHandler<StoppedEventArgs> handler);
24+ INotStartedUserStream SetReceiveFriendsEvent(EventHandler<ReceiveFriendsEventArgs> handler);
25+ INotStartedUserStream SetNewTweetEvent(EventHandler<NewTweetEventArgs> handler);
26+ INotStartedUserStream SetNewDirectMessageEvent(EventHandler<NewDirectMessageEventArgs> handler);
27+ INotStartedUserStream SetDeleteStatusEvent(EventHandler<DeleteStatusEventArgs> handler);
28+ INotStartedUserStream SetReceiveEventEvent(EventHandler<ReceiveEventEventArgs> handler);
29+ INotStartedUserStream SetTrackLimitEvent(EventHandler<TrackLimitEventArgs> handler);
30+ INotStartedUserStream SetReceiveUnsupportedDataEvent(EventHandler<ReceiveJsonEventArgs> handler);
31+ #endregion
32+ }
33+
34+ public interface IStartedUserStream
35+ {
36+ INotStartedUserStream Stop();
37+ IStartedUserStream SetTimeout(int waitTime);
38+ }
39+}
--- a/UserStreamEx/Properties/AssemblyInfo.cs
+++ b/UserStreamEx/Properties/AssemblyInfo.cs
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
3232 // すべての値を指定するか、下のように '*' を使ってビルドおよびリビジョン番号を
3333 // 既定値にすることができます:
3434 // [assembly: AssemblyVersion("1.0.*")]
35-[assembly: AssemblyVersion("1.0.1.0")]
36-[assembly: AssemblyFileVersion("1.0.1.0")]
35+[assembly: AssemblyVersion("1.1.0.0")]
36+[assembly: AssemblyFileVersion("1.1.0.0")]
--- a/UserStreamEx/Readme.txt
+++ b/UserStreamEx/Readme.txt
@@ -16,6 +16,11 @@ LINQ to Twitter用UserStream補助ライブラリ
1616 何かあったら@azyobuzinまで
1717
1818 更新履歴
19+ 1.1 (2011/2/9)
20+ ・list_destroyedイベントに対応
21+ ・Stopメソッドで停止したときにStoppedEventArgs.ReasonがErrorになる不具合を修正
22+ ・list_createdイベント発生時に例外を吐くのを修正
23+ ・メソッドチェーンでつなげるように改良
1924 1.0.1 (2011/2/7)
2025 ・DirectMessageを受信したときに例外を吐くのを修正
2126 ・limitに対応
--- a/UserStreamEx/UserStreamEx.cs
+++ b/UserStreamEx/UserStreamEx.cs
@@ -1,17 +1,16 @@
11 using System;
22 using System.Collections.Generic;
3-using System.Globalization;
43 using System.IO;
54 using System.Linq;
65 using System.Net;
76 using System.Threading;
8-using System.Xml.Linq;
97 using Codeplex.Data;
108 using LinqToTwitter;
119
1210 namespace Azyobuzi.UserStreamEx
1311 {
1412 public class UserStream
13+ : INotStartedUserStream, IStartedUserStream
1514 {
1615 public UserStream(ITwitterAuthorizer auth)
1716 {
@@ -21,8 +20,10 @@ namespace Azyobuzi.UserStreamEx
2120 private ITwitterAuthorizer auth;
2221 private HttpWebRequest req;
2322
24- public void Start(string track, bool allReplies)
23+ public IStartedUserStream Start(string track, bool allReplies)
2524 {
25+ if (req != null) req.Abort();
26+
2627 var reqUri = new UriBuilder("https://userstream.twitter.com/2/user.json");
2728 var param = new Dictionary<string, string>();
2829 if (!string.IsNullOrEmpty(track)) param.Add("track", track);
@@ -54,46 +55,25 @@ namespace Azyobuzi.UserStreamEx
5455
5556 if (string.IsNullOrWhiteSpace(line)) continue;
5657
57- var t = new Thread(_ =>
58- {
59- var _line = (string)_;
60- var json = DynamicJson.Parse(_line);
61- if (json.friends())
62- {
63- if (ReceiveFriends != null) ReceiveFriends(this, new ReceiveFriendsEventArgs(_line));
64- }
65- else if (json.delete())
66- {
67- if (DeleteStatus != null) DeleteStatus(this, new DeleteStatusEventArgs(_line));
68- }
69- else if (json.direct_message())
70- {
71- if (NewDirectMessage != null) NewDirectMessage(this, new NewDirectMessageEventArgs(_line));
72- }
73- else if (json.@event())
74- {
75- if (ReceiveEvent != null) ReceiveEvent(this, new ReceiveEventEventArgs(_line));
76- }
77- else if (json.limit())
78- {
79- if (TrackLimit != null) TrackLimit(this, new TrackLimitEventArgs(_line));
80- }
81- else if (json.text())
82- {
83- if (NewTweet != null) NewTweet(this, new NewTweetEventArgs(_line));
84- }
85- else
86- {
87- if (ReceiveUnsupportedData != null) ReceiveUnsupportedData(this, new ReceiveJsonEventArgs(_line));
88- }
89- });
58+ var t = new Thread(RaiseEvent);
9059 t.Start(line);
9160 }
9261 }
9362
9463 if (Stopped != null)
95- Stopped(this, new StoppedEventArgs(userStop ? StopReason.UserStop : StopReason.CloseResponse, null));
96- userStop = false;
64+ Stopped(this, new StoppedEventArgs(StopReason.CloseResponse, null));
65+ }
66+ catch (WebException ex)
67+ {
68+ if (ex.Status == WebExceptionStatus.RequestCanceled)
69+ {
70+ if (Stopped != null)
71+ Stopped(this, new StoppedEventArgs(StopReason.UserStop, ex));
72+ }
73+ else
74+ {
75+ throw;
76+ }
9777 }
9878 catch (Exception ex)
9979 {
@@ -102,19 +82,73 @@ namespace Azyobuzi.UserStreamEx
10282 }
10383 req = null;
10484 }, null);
85+
86+ return this;
10587 }
10688
107- private bool userStop;
89+ private void RaiseEvent(object args)
90+ {
91+ var line = (string)args;
92+ var json = DynamicJson.Parse(line);
93+ if (json.friends())
94+ {
95+ if (ReceiveFriends != null) ReceiveFriends(this, new ReceiveFriendsEventArgs(line));
96+ }
97+ else if (json.delete())
98+ {
99+ if (DeleteStatus != null) DeleteStatus(this, new DeleteStatusEventArgs(line));
100+ }
101+ else if (json.direct_message())
102+ {
103+ if (NewDirectMessage != null) NewDirectMessage(this, new NewDirectMessageEventArgs(line));
104+ }
105+ else if (json.@event())
106+ {
107+ if (ReceiveEvent != null) ReceiveEvent(this, new ReceiveEventEventArgs(line));
108+ }
109+ else if (json.limit())
110+ {
111+ if (TrackLimit != null) TrackLimit(this, new TrackLimitEventArgs(line));
112+ }
113+ else if (json.text())
114+ {
115+ if (NewTweet != null) NewTweet(this, new NewTweetEventArgs(line));
116+ }
117+ else
118+ {
119+ if (ReceiveUnsupportedData != null) ReceiveUnsupportedData(this, new ReceiveJsonEventArgs(line));
120+ }
121+ }
108122
109- public void Stop()
123+ public INotStartedUserStream Stop()
110124 {
111- userStop = true;
112125 if (req != null) req.Abort();
113126 req = null;
127+ return this;
128+ }
129+
130+ public IStartedUserStream SetTimeout(int waitTime)
131+ {
132+ if (waitTime < 1)
133+ {
134+ Stop();
135+ }
136+ else
137+ {
138+ var t = new Thread(_ =>
139+ {
140+ Thread.Sleep((int)_);
141+ Stop();
142+ });
143+ t.IsBackground = true;
144+ t.Start(waitTime);
145+ }
146+ return this;
114147 }
115148
116149 public TextWriter StreamingWriter { set; get; }
117150
151+ #region Events
118152 public event EventHandler Started;
119153 public event EventHandler<StoppedEventArgs> Stopped;
120154 public event EventHandler<ReceiveFriendsEventArgs> ReceiveFriends;
@@ -124,176 +158,62 @@ namespace Azyobuzi.UserStreamEx
124158 public event EventHandler<ReceiveEventEventArgs> ReceiveEvent;
125159 public event EventHandler<TrackLimitEventArgs> TrackLimit;
126160 public event EventHandler<ReceiveJsonEventArgs> ReceiveUnsupportedData;
127- }
161+ #endregion
128162
129- public class StoppedEventArgs : EventArgs
130- {
131- public StoppedEventArgs(StopReason reason, Exception ex)
163+ #region AddHandlerMethod
164+ public INotStartedUserStream SetStartedEvent(EventHandler handler)
132165 {
133- this.Reason = reason;
134- this.Exception = ex;
166+ Started += handler;
167+ return this;
135168 }
136169
137- public StopReason Reason { private set; get; }
138- public Exception Exception { private set; get; }
139- }
140-
141- public enum StopReason
142- {
143- /// <summary>
144- /// Twitterが切断
145- /// </summary>
146- CloseResponse,
147- /// <summary>
148- /// Stopメソッドが呼ばれた
149- /// </summary>
150- UserStop,
151- /// <summary>
152- /// その他の例外
153- /// </summary>
154- Error
155- }
156-
157- public class ReceiveJsonEventArgs : EventArgs
158- {
159- public ReceiveJsonEventArgs(string line)
170+ public INotStartedUserStream SetStoppedEvent(EventHandler<StoppedEventArgs> handler)
160171 {
161- this.Line = line;
172+ Stopped += handler;
173+ return this;
162174 }
163175
164- public string Line { private set; get; }
165- }
166-
167- public class ReceiveFriendsEventArgs : ReceiveJsonEventArgs
168- {
169- public ReceiveFriendsEventArgs(string line)
170- : base(line)
176+ public INotStartedUserStream SetReceiveFriendsEvent(EventHandler<ReceiveFriendsEventArgs> handler)
171177 {
172- FriendIds = (string[])DynamicJson.Parse(line).friends;
178+ ReceiveFriends += handler;
179+ return this;
173180 }
174181
175- public string[] FriendIds { private set; get; }
176- }
177-
178- public class NewTweetEventArgs : ReceiveJsonEventArgs
179- {
180- public NewTweetEventArgs(string line)
181- : base(line)
182+ public INotStartedUserStream SetNewTweetEvent(EventHandler<NewTweetEventArgs> handler)
182183 {
183- Status = Status.CreateStatus(line.JsonToXml());
184+ NewTweet += handler;
185+ return this;
184186 }
185187
186- public Status Status { private set; get; }
187- }
188-
189- public class NewDirectMessageEventArgs : ReceiveJsonEventArgs
190- {
191- public NewDirectMessageEventArgs(string line)
192- : base(line)
188+ public INotStartedUserStream SetNewDirectMessageEvent(EventHandler<NewDirectMessageEventArgs> handler)
193189 {
194- var json = DynamicJson.Parse(line).direct_message;
195- DirectMessage = new DirectMessage()
196- {
197- ID = (ulong)json.id,
198- SenderID = (ulong)json.sender_id,
199- Text = json.text,
200- RecipientID = (ulong)json.recipient_id,
201- CreatedAt = DateTime.ParseExact(json.created_at, "ddd MMM dd HH:mm:ss %zzzz yyyy", CultureInfo.InvariantCulture),
202- SenderScreenName = json.sender_screen_name,
203- RecipientScreenName = json.recipient_screen_name,
204- Sender = User.CreateUser(((string)json.sender.ToString()).JsonToXml()),
205- Recipient = User.CreateUser(((string)json.recipient.ToString()).JsonToXml())
206- };
190+ NewDirectMessage += handler;
191+ return this;
207192 }
208193
209- public DirectMessage DirectMessage { private set; get; }
210- }
211-
212- public class DeleteStatusEventArgs : ReceiveJsonEventArgs
213- {
214- public DeleteStatusEventArgs(string line)
215- : base(line)
194+ public INotStartedUserStream SetDeleteStatusEvent(EventHandler<DeleteStatusEventArgs> handler)
216195 {
217- var json = DynamicJson.Parse(line).delete;
218- if (!json.direct_message())
219- {
220- //ツイート
221- StatusId = json.status.id_str;
222- UserId = json.status.user_id_str;
223- IsDirectMessage = false;
224- }
225- else
226- {
227- //DM
228- StatusId = json.direct_message.id.ToString();
229- UserId = json.direct_message.user_id.ToString();
230- IsDirectMessage = true;
231- }
196+ DeleteStatus += handler;
197+ return this;
232198 }
233199
234- public string StatusId { private set; get; }
235- public string UserId { private set; get; }
236- public bool IsDirectMessage { private set; get; }
237- }
238-
239- public class ReceiveEventEventArgs : ReceiveJsonEventArgs
240- {
241- public ReceiveEventEventArgs(string line)
242- : base(line)
200+ public INotStartedUserStream SetReceiveEventEvent(EventHandler<ReceiveEventEventArgs> handler)
243201 {
244- var json = DynamicJson.Parse(line);
245- EventTypes eventType = EventTypes.Unknown;
246- Enum.TryParse(((string)json.@event).Replace("_", ""), true, out eventType);
247- EventType = eventType;
248- CreatedAt = DateTime.ParseExact(json.created_at, "ddd MMM dd HH:mm:ss %zzzz yyyy", CultureInfo.InvariantCulture).ToLocalTime();
249- Source = User.CreateUser(((string)json.source.ToString()).JsonToXml());
250- Target = User.CreateUser(((string)json.target.ToString()).JsonToXml());
251- if (json.target_object())
252- {
253- if (json.target_object.mode())
254- {
255- //リスト
256- TargetList = List.CreateList(((string)json.target_object.ToString()).JsonToXml(), new XElement("lists_list"));
257- }
258- else
259- {
260- //ツイート
261- TargetStatus = Status.CreateStatus(((string)json.target_object.ToString()).JsonToXml());
262- }
263- }
202+ ReceiveEvent += handler;
203+ return this;
264204 }
265205
266- public EventTypes EventType { private set; get; }
267- public DateTime CreatedAt { private set; get; }
268- public User Source { private set; get; }
269- public User Target { private set; get; }
270- public Status TargetStatus { private set; get; }
271- public List TargetList { private set; get; }
272- }
273-
274- public enum EventTypes
275- {
276- Unknown,
277- Favorite,
278- Unfavorite,
279- Follow,
280- ListMemberAdded,
281- ListMemberRemoved,
282- Block,
283- Unblock,
284- UserUpdate,
285- ListCreated,
286- ListDestroyed
287- }
288-
289- public class TrackLimitEventArgs : ReceiveJsonEventArgs
290- {
291- public TrackLimitEventArgs(string line)
292- : base(line)
206+ public INotStartedUserStream SetTrackLimitEvent(EventHandler<TrackLimitEventArgs> handler)
293207 {
294- Track = (ulong)DynamicJson.Parse(line).limit.track;
208+ TrackLimit += handler;
209+ return this;
295210 }
296211
297- public ulong Track { private set; get; }
212+ public INotStartedUserStream SetReceiveUnsupportedDataEvent(EventHandler<ReceiveJsonEventArgs> handler)
213+ {
214+ ReceiveUnsupportedData += handler;
215+ return this;
216+ }
217+ #endregion
298218 }
299219 }
--- a/UserStreamEx/UserStreamEx.csproj
+++ b/UserStreamEx/UserStreamEx.csproj
@@ -47,7 +47,9 @@
4747 <Reference Include="System.Xml" />
4848 </ItemGroup>
4949 <ItemGroup>
50+ <Compile Include="EventArgs.cs" />
5051 <Compile Include="Extensions.cs" />
52+ <Compile Include="Interfaces.cs" />
5153 <Compile Include="UserStreamEx.cs" />
5254 <Compile Include="Properties\AssemblyInfo.cs" />
5355 </ItemGroup>