Changeset 391

Show
Ignore:
Timestamp:
05/18/08 11:24:50 (6 months ago)
Author:
tomoyo
Message:

Twitterのチェック周りを全部 Session.cs から TwitterService?.cs に移動した。

Location:
TwitterIrcGateway/branches/im-support
Files:
3 modified

Legend:

Unmodified
Added
Removed
  • TwitterIrcGateway/branches/im-support/TwitterIrcGatewayCLI/Program.cs

    r389 r391  
    1919            IPAddress bindAddress = IPAddress.Loopback; 
    2020            Encoding encoding = Encoding.GetEncoding("ISO-2022-JP"); 
    21             IWebProxy proxy = WebProxy.GetDefaultProxy(); 
     21            IWebProxy proxy = WebRequest.DefaultWebProxy; 
    2222 
    2323            CommandLineOptions options; 
  • TwitterIrcGateway/branches/im-support/TwitterIrcGatewayCore/Session.cs

    r389 r391  
    2929        private TwitterIMService _twitterIm; 
    3030        private LinkedList<Int32> _lastStatusIdsFromGateway; 
    31         private Timer _timer; 
    32         private Timer _timerDirectMessage; 
    33         private Timer _timerReplies; 
    3431        private Groups _groups; 
    3532        private Filters _filter; 
    3633        private Config _config; 
    3734 
    38         private DateTime _lastAccessTimeline = new DateTime(); 
    39         private DateTime _lastAccessReplies = new DateTime(); 
    4035        private List<String> _nickNames = new List<string>(); 
    4136        private Boolean _isFirstTime = true; 
    42         private Boolean _isFirstTimeReplies = true; 
    43         private DateTime _lastAccessDirectMessage = DateTime.Now; 
    44         private Int32 _bufferSize = 250; 
    45         private LinkedList<Status> _statusBuffer; 
    46         private LinkedList<Status> _repliesBuffer; 
     37 
    4738        private TraceListener _traceListeneer; 
    4839 
     
    8071            _server = server; 
    8172            _tcpClient = tcpClient; 
    82             _statusBuffer = new LinkedList<Status>(); 
    83             _repliesBuffer = new LinkedList<Status>(); 
    8473            _lastStatusIdsFromGateway = new LinkedList<int>(); 
    85             _timer = new Timer(new TimerCallback(OnTimerCallback), null, Timeout.Infinite, Timeout.Infinite); 
    86             _timerDirectMessage = new Timer(new TimerCallback(OnTimerCallbackDirectMessage), null, Timeout.Infinite, Timeout.Infinite); 
    87             _timerReplies = new Timer(new TimerCallback(OnTimerCallbackReplies), null, Timeout.Infinite, Timeout.Infinite); 
    8874        } 
    8975 
     
    121107            { 
    122108                return _clientHost; 
    123             } 
    124         } 
    125          
    126         /// <summary> 
    127         ///  
    128         /// </summary> 
    129         /// <param name="stateObject"></param> 
    130         private void OnTimerCallback(Object stateObject) 
    131         { 
    132             RunCallback(_timer, delegate 
    133             { 
    134                 SendPing(); 
    135  
    136                 // 初回だけは先にチェックしておかないとnamesが後から来てジャマ 
    137                 if (_isFirstTime) 
    138                 { 
    139                     CheckFriends(); 
    140                 } 
    141  
    142                 // Friendsをチェックするのは成功して、チェックが必要となったとき 
    143                 Boolean friendsCheckRequired = false; 
    144                 if (CheckNewTimeLine(out friendsCheckRequired) && friendsCheckRequired && !_server.DisableUserList) 
    145                 { 
    146                     CheckFriends(); 
    147                 } 
    148             }); 
    149         } 
    150  
    151         /// <summary> 
    152         ///  
    153         /// </summary> 
    154         /// <param name="stateObject"></param> 
    155         private void OnTimerCallbackDirectMessage(Object stateObject) 
    156         { 
    157             RunCallback(_timerDirectMessage, delegate 
    158             { 
    159                 CheckDirectMessage(); 
    160             }); 
    161         } 
    162          
    163         /// <summary> 
    164         ///  
    165         /// </summary> 
    166         /// <param name="stateObject"></param> 
    167         private void OnTimerCallbackReplies(Object stateObject) 
    168         { 
    169             RunCallback(_timerReplies, delegate 
    170             { 
    171                 CheckNewReplies(); 
    172             }); 
    173         } 
    174  
    175         /// <summary> 
    176         ///  
    177         /// </summary> 
    178         private delegate void CallbackProcedure(); 
    179  
    180         /// <summary> 
    181         /// タイマーコールバックの処理を実行します。 
    182         /// </summary> 
    183         /// <param name="timer"></param> 
    184         /// <param name="callbackProcedure"></param> 
    185         private void RunCallback(Timer timer, CallbackProcedure callbackProcedure) 
    186         { 
    187             // あまりに処理が遅れると二重になる可能性がある 
    188             if (Monitor.TryEnter(timer)) 
    189             { 
    190                 try 
    191                 { 
    192                     callbackProcedure(); 
    193                 } 
    194                 finally 
    195                 { 
    196                     Monitor.Exit(timer); 
    197                 } 
    198109            } 
    199110        } 
     
    613524            //_username = e.Message.CommandParams[0]; // usernameがtwitterのIDとなる 
    614525            _username = e.Message.CommandParams[3]; 
    615             _twitter = new TwitterService(_username, _password); 
    616             _twitter.CookieLoginMode = _server.CookieLoginMode; 
    617             if (_server.Proxy != null) 
    618                 _twitter.Proxy = _server.Proxy; 
    619526 
    620527            Type t = typeof(Server); 
     
    646553            Send(autoMsg); 
    647554 
     555            // 
     556            // Twitte Service Setup 
     557            // 
     558            _twitter = new TwitterService(_username, _password); 
     559            _twitter.CookieLoginMode = _server.CookieLoginMode; 
     560            _twitter.Interval = _server.Interval; 
     561            _twitter.IntervalDirectMessage = _server.IntervalDirectMessage; 
     562            _twitter.IntervalReplies = _server.IntervalReplies; 
     563            _twitter.EnableRepliesCheck = _server.EnableRepliesCheck; 
     564            _twitter.RepliesReceived += new EventHandler<StatusesUpdatedEventArgs>(twitter_RepliesReceived); 
     565            _twitter.TimelineStatusesReceived += new EventHandler<StatusesUpdatedEventArgs>(twitter_TimelineStatusesReceived); 
     566            _twitter.CheckError += new EventHandler<ErrorEventArgs>(twitter_CheckError); 
     567            _twitter.DirectMessageReceived += new EventHandler<DirectMessageEventArgs>(twitter_DirectMessageReceived); 
     568            if (_server.Proxy != null) 
     569                _twitter.Proxy = _server.Proxy; 
     570 
     571            _twitter.Start(); 
     572 
    648573            OnSessionStarted(_username); 
    649574            Trace.WriteLine(String.Format("SessionStarted: UserName={0}; Nickname={1}", _username, _nick)); 
    650  
    651             _timer.Change(0, _server.Interval * 1000); 
    652             _timerDirectMessage.Change(0, _server.IntervalDirectMessage * 1000); 
    653             if (_server.EnableRepliesCheck) 
    654             { 
    655                 _timerReplies.Change(0, _server.IntervalReplies * 1000); 
    656             } 
    657575        } 
    658576 
     
    995913        { 
    996914            _isFirstTime = false; // IMが先にきてしまったらあきらめる 
    997             if (ProcessDropProtection(_statusBuffer, e.Status)) 
     915            _twitter.ProcessStatus(e.Status, (s) => 
    998916            { 
    999917                Boolean friendsCheckRequired = false; 
    1000918                ProcessTimelineStatus(e.Status, ref friendsCheckRequired); 
     919            }); 
     920        } 
     921        #endregion 
     922 
     923        #region Twitter Service イベント 
     924        void twitter_CheckError(object sender, ErrorEventArgs e) 
     925        { 
     926            SendServerErrorMessage(e.Exception.Message); 
     927        } 
     928 
     929        void twitter_DirectMessageReceived(object sender, DirectMessageEventArgs e) 
     930        { 
     931            DirectMessage message = e.DirectMessage; 
     932            String text = (_server.ResolveTinyUrl) ? Utility.ResolveTinyUrlInMessage(message.Text) : message.Text; 
     933            String[] lines = text.Split(new Char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries); 
     934 
     935            foreach (String line in lines) 
     936            { 
     937                PrivMsgMessage privMsg = new PrivMsgMessage(); 
     938                privMsg.SenderNick = message.SenderScreenName; 
     939                privMsg.SenderHost = "twitter@" + Server.ServerName; 
     940                privMsg.Receiver = _nick; 
     941                //privMsg.Content = String.Format("{0}: {1}", screenName, text); 
     942                privMsg.Content = line; 
     943                Send(privMsg); 
     944            } 
     945        } 
     946 
     947        void twitter_TimelineStatusesReceived(object sender, StatusesUpdatedEventArgs e) 
     948        { 
     949            SendPing(); 
     950 
     951            if (_isFirstTime && e.IsFirstTime) 
     952                _isFirstTime = e.IsFirstTime; 
     953 
     954            // 初回だけは先にチェックしておかないとnamesが後から来てジャマ 
     955            if (_isFirstTime) 
     956            { 
     957                CheckFriends(); 
     958            } 
     959             
     960            Boolean friendsCheckRequired = e.FriendsCheckRequired; 
     961            foreach (Status status in e.Statuses.Status) 
     962            { 
     963                ProcessTimelineStatus(status, ref friendsCheckRequired); 
     964            } 
     965             
     966            // Friendsをチェックするのは成功して、チェックが必要となったとき 
     967            if (e.FriendsCheckRequired && !_server.DisableUserList) 
     968            { 
     969                CheckFriends(); 
     970            } 
     971        } 
     972 
     973        void twitter_RepliesReceived(object sender, StatusesUpdatedEventArgs e) 
     974        { 
     975            Boolean dummy = false; 
     976            foreach (Status status in e.Statuses.Status) 
     977            { 
     978                ProcessTimelineStatus(status, ref dummy); 
    1001979            } 
    1002980        } 
     
    11661144            }); 
    11671145        } 
    1168  
    1169         private Boolean CheckNewTimeLine(out Boolean friendsCheckRequired) 
    1170         { 
    1171             Boolean friendsCheckRequiredAnon = false; 
    1172             Boolean returnValue = RunCheck(delegate 
    1173             { 
    1174                 Statuses statuses = _twitter.GetTimeline(_lastAccessTimeline); 
    1175                 Array.Reverse(statuses.Status); 
    1176                 foreach (Status status in statuses.Status) 
    1177                 { 
    1178                     // 差分チェック 
    1179                     if (ProcessDropProtection(_statusBuffer, status)) 
    1180                     { 
    1181                         ProcessTimelineStatus(status, ref friendsCheckRequiredAnon); 
    1182                     } 
    1183                 } 
    1184  
    1185                 if (_isFirstTime && _server.EnableDropProtection) 
    1186                 { 
    1187                     _lastAccessTimeline = DateTime.Now; 
    1188                 } 
    1189                 _isFirstTime = false; 
    1190             }); 
    1191              
    1192             friendsCheckRequired = friendsCheckRequiredAnon; 
    1193             return returnValue; 
    1194         } 
    1195  
    1196         private Boolean CheckNewReplies() 
    1197         { 
    1198             Boolean friendsCheckRequired = false; 
    1199             return RunCheck(delegate 
    1200             { 
    1201                 Statuses statuses = _twitter.GetReplies(); 
    1202                 Array.Reverse(statuses.Status); 
    1203                 bool dummy = false; 
    1204                 foreach (Status status in statuses.Status) 
    1205                 { 
    1206                     if (status.CreatedAt < _lastAccessReplies) 
    1207                         continue; 
    1208                     // 差分チェック 
    1209                     if (ProcessDropProtection(_repliesBuffer, status) && ProcessDropProtection(_statusBuffer, status)) 
    1210                     { 
    1211                         // Here I pass dummy, because no matter how the replier flags 
    1212                         // friendsCheckRequired, we cannot receive his or her info 
    1213                         // through get_friends. 
    1214                         ProcessTimelineStatus(status, ref dummy); 
    1215                     } 
    1216                 } 
    1217  
    1218                 if (_isFirstTimeReplies && _server.EnableDropProtection) 
    1219                 { 
    1220                     _lastAccessReplies = DateTime.Now; 
    1221                 } 
    1222                 _isFirstTimeReplies = false; 
    1223             }); 
    1224         } 
    1225          
    1226         /// <summary> 
    1227         /// 既に受信したstatusかどうかをチェックします。既に送信済みの場合falseを返します。 
    1228         /// </summary> 
    1229         /// <param name="statusBuffer"></param> 
    1230         /// <param name="status"></param> 
    1231         /// <returns></returns> 
    1232         private Boolean ProcessDropProtection(LinkedList<Status> statusBuffer, Status status) 
    1233         { 
    1234             // 差分チェック 
    1235             if (_server.EnableDropProtection) 
    1236             { 
    1237                 if (statusBuffer.Contains(status)) 
    1238                     return false; 
    1239  
    1240                 statusBuffer.AddLast(status); 
    1241                 if (statusBuffer.Count > _bufferSize) 
    1242                 { 
    1243                     // 一番古いのを消す 
    1244                     //Status oldStatus = null; 
    1245                     //foreach (Status statTmp in _statusBuffer) 
    1246                     //{ 
    1247                     //    if (oldStatus == null || oldStatus.CreatedAt > statTmp.CreatedAt) 
    1248                     //    { 
    1249                     //        oldStatus = statTmp; 
    1250                     //    } 
    1251                     //} 
    1252                     //_statusBuffer.Remove(oldStatus); 
    1253                     statusBuffer.RemoveFirst(); 
    1254                 } 
    1255             } 
    1256              
    1257             return true; 
    1258         } 
    1259          
     1146       
    12601147        private void ProcessTimelineStatus (Status status, ref Boolean friendsCheckRequired) 
    12611148        { 
    1262  
    12631149            // チェック 
    12641150            if (status.User == null || String.IsNullOrEmpty(status.User.ScreenName)) 
     
    13301216                        } 
    13311217                    } 
    1332                 } 
    1333             } 
    1334  
    1335             // 最終更新時刻 
    1336             if (_server.EnableDropProtection) 
    1337             { 
    1338                 // 取りこぼし防止しているときは一番古い日付 
    1339                 if (status.CreatedAt < _lastAccessTimeline) 
    1340                 { 
    1341                     _lastAccessTimeline = status.CreatedAt; 
    1342                 } 
    1343             } 
    1344             else 
    1345             { 
    1346                 if (status.CreatedAt > _lastAccessTimeline) 
    1347                 { 
    1348                     _lastAccessTimeline = status.CreatedAt; 
    13491218                } 
    13501219            } 
     
    13751244        } 
    13761245 
    1377         /// <summary> 
    1378         ///  
    1379         /// </summary> 
    1380         private void CheckDirectMessage() 
    1381         { 
    1382             RunCheck(delegate 
    1383             { 
    1384                 DirectMessages directMessages = _twitter.GetDirectMessages(_lastAccessDirectMessage); 
    1385                 Array.Reverse(directMessages.DirectMessage); 
    1386                 foreach (DirectMessage message in directMessages.DirectMessage) 
    1387                 { 
    1388                     // チェック 
    1389                     if (message == null || String.IsNullOrEmpty(message.SenderScreenName)) 
    1390                     { 
    1391                         continue; 
    1392                     } 
    1393  
    1394                     String text = (_server.ResolveTinyUrl) ? Utility.ResolveTinyUrlInMessage(message.Text) : message.Text; 
    1395                     String[] lines = text.Split(new Char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries); 
    1396  
    1397                     foreach (String line in lines) 
    1398                     { 
    1399                         PrivMsgMessage privMsg = new PrivMsgMessage(); 
    1400                         privMsg.SenderNick = message.SenderScreenName; 
    1401                         privMsg.SenderHost = "twitter@" + Server.ServerName; 
    1402                         privMsg.Receiver = _nick; 
    1403                         //privMsg.Content = String.Format("{0}: {1}", screenName, text); 
    1404                         privMsg.Content = line; 
    1405                         Send(privMsg); 
    1406                     } 
    1407                     // 最終更新時刻 
    1408                     if (message.CreatedAt > _lastAccessDirectMessage) 
    1409                     { 
    1410                         _lastAccessDirectMessage = message.CreatedAt; 
    1411                     } 
    1412                 } 
    1413             }); 
    1414         } 
    1415  
    1416         private delegate void CheckProcedure(); 
     1246        private delegate void Procedure(); 
    14171247        /// <summary> 
    14181248        /// チェックを実行します。例外が発生した場合には自動的にメッセージを送信します。 
     
    14201250        /// <param name="proc">実行するチェック処理</param> 
    14211251        /// <returns></returns> 
    1422         private Boolean RunCheck(CheckProcedure proc) 
     1252        private Boolean RunCheck(Procedure proc) 
    14231253        { 
    14241254            try 
     
    14311261                { 
    14321262                    // not-modified 以外 
    1433                     SendServerErrorMessage(ex.Message); 
     1263                    twitter_CheckError(_twitter, new ErrorEventArgs(ex)); 
    14341264                    return false; 
    14351265                } 
     
    14371267            catch (TwitterServiceException ex2) 
    14381268            { 
    1439                 SendServerErrorMessage(ex2.Message); 
     1269                twitter_CheckError(_twitter, new ErrorEventArgs(ex2)); 
    14401270                return false; 
    14411271            } 
    1442  
    14431272            return true; 
    14441273        } 
    14451274         
    1446  
    14471275        /// <summary> 
    14481276        ///  
     
    14721300                { 
    14731301                    Trace.Listeners.Remove(_traceListeneer); 
    1474                 } 
    1475  
    1476                 if (_timer != null) 
    1477                 { 
    1478                     _timer.Dispose(); 
    1479                     _timer = null; 
    1480                 } 
    1481                 if (_timerDirectMessage != null) 
    1482                 { 
    1483                     _timerDirectMessage.Dispose(); 
    1484                     _timerDirectMessage = null; 
    1485                 } 
    1486                 if (_timerReplies != null) 
    1487                 { 
    1488                     _timerReplies.Dispose(); 
    1489                     _timerReplies = null; 
    14901302                } 
    14911303 
  • TwitterIrcGateway/branches/im-support/TwitterIrcGatewayCore/TwitterService.cs

    r390 r391  
    2222        private String _userName; 
    2323        private Boolean _cookieLoginMode = false; 
     24        private Boolean _enableDropProtection = true; 
     25 
     26        private Timer _timer; 
     27        private Timer _timerDirectMessage; 
     28        private Timer _timerReplies; 
     29         
     30        private DateTime _lastAccessTimeline = new DateTime(); 
     31        private DateTime _lastAccessReplies = new DateTime(); 
     32        private DateTime _lastAccessDirectMessage = DateTime.Now; 
     33        private Boolean _isFirstTime = true; 
     34        private Boolean _isFirstTimeReplies = true; 
     35 
     36        private Int32 _bufferSize = 250; 
     37        private LinkedList<Status> _statusBuffer; 
     38        private LinkedList<Status> _repliesBuffer; 
     39 
     40        public event EventHandler<ErrorEventArgs> CheckError; 
     41        public event EventHandler<StatusesUpdatedEventArgs> TimelineStatusesReceived; 
     42        public event EventHandler<StatusesUpdatedEventArgs> RepliesReceived; 
     43        public event EventHandler<DirectMessageEventArgs> DirectMessageReceived; 
    2444 
    2545        public static readonly String ServiceServerPrefix = "http://twitter.com"; 
     
    3656 
    3757            _userName = userName; 
     58             
     59            _timer = new Timer(new TimerCallback(OnTimerCallback), null, Timeout.Infinite, Timeout.Infinite); 
     60            _timerDirectMessage = new Timer(new TimerCallback(OnTimerCallbackDirectMessage), null, Timeout.Infinite, Timeout.Infinite); 
     61            _timerReplies = new Timer(new TimerCallback(OnTimerCallbackReplies), null, Timeout.Infinite, Timeout.Infinite); 
     62             
     63            _statusBuffer = new LinkedList<Status>(); 
     64            _repliesBuffer = new LinkedList<Status>(); 
    3865 
    3966            //_webClient = new PreAuthenticatedWebClient(); 
     
    6794            set { _cookieLoginMode = value; } 
    6895        } 
     96         
     97        /// <summary> 
     98        /// �����ڂ��h�~����邩�ǂ�����肵�܂��B 
     99        /// </summary> 
     100        public Boolean EnableDropProtection 
     101        { 
     102            get { return _enableDropProtection; } 
     103            set { _enableDropProtection = value; } 
     104        } 
     105 
     106        /// <summary> 
     107        /// �^�C�����C����F�b�N�����u��肵�܂��B 
     108        /// </summary> 
     109        public Int32 Interval 
     110        { 
     111            get; 
     112            set; 
     113        } 
     114 
     115        /// <summary> 
     116        /// �_�C���N�g���b�Z�[�W��F�b�N�����u��肵�܂��B 
     117        /// </summary> 
     118        public Int32 IntervalDirectMessage 
     119        { 
     120            get; 
     121            set; 
     122        } 
     123 
     124        /// <summary> 
     125        /// Replies��F�b�N�����u��肵�܂��B 
     126        /// </summary> 
     127        public Int32 IntervalReplies 
     128        { 
     129            get; 
     130            set; 
     131        } 
     132 
     133        /// <summary> 
     134        /// Replies�̃`�F�b�N��s���邩�ǂ�����肵�܂��B 
     135        /// </summary> 
     136        public Boolean EnableRepliesCheck 
     137        { 
     138            get; 
     139            set; 
     140        } 
    69141 
    70142        /// <summary> 
     
    75147        { 
    76148            String encodedMessage = TwitterService.EncodeMessage(message); 
    77             try 
     149            return ExecuteRequest<Status>(() => 
    78150            { 
    79151                String responseBody = POST(String.Format("/statuses/update.xml?status={0}&source={1}", encodedMessage, TwitterService.ClientName), Encoding.Default.GetBytes("1")); 
     
    87159                    return status; 
    88160                } 
    89             } 
    90             catch (WebException we) 
    91             { 
    92                 throw; 
    93             } 
    94             catch (InvalidOperationException ioe) 
    95             { 
    96                 // XmlSerializer 
    97                 throw new TwitterServiceException(ioe); 
    98             } 
    99             catch (XmlException xe) 
    100             { 
    101                 throw new TwitterServiceException(xe); 
    102             } 
    103             catch (IOException ie) 
    104             { 
    105                 throw new TwitterServiceException(ie); 
    106             } 
     161            }); 
    107162        } 
    108163 
     
    115170        { 
    116171            String encodedMessage = TwitterService.EncodeMessage(message); 
    117             try 
     172            ExecuteRequest(() => 
    118173            { 
    119174                String responseBody = POST(String.Format("/direct_messages/new.xml?user={0}&text={1}", targetId, encodedMessage), new Byte[0]); 
    120             } 
    121             catch (WebException we) 
    122             { 
    123                 throw; 
    124             } 
    125             catch (InvalidOperationException ioe) 
    126             { 
    127                 // XmlSerializer 
    128                 throw new TwitterServiceException(ioe); 
    129             } 
    130             catch (XmlException xe) 
    131             { 
    132                 throw new TwitterServiceException(xe); 
    133             } 
    134             catch (IOException ie) 
    135             { 
    136                 throw new TwitterServiceException(ie); 
    137             } 
     175            }); 
    138176        } 
    139177 
     
    147185            List<User> usersList = new List<User>(); 
    148186            Int32 page = 0; 
    149             try 
     187            return ExecuteRequest<User[]>(() => 
    150188            { 
    151189                while (page++ != 1 /*10*/) 
     
    171209                // ���܂������ꍇ�͂����܂ŁB 
    172210                return usersList.ToArray(); 
    173             } 
    174             catch (WebException we) 
    175     &nb