Changeset 347

Show
Ignore:
Timestamp:
10/30/07 10:29:55 (13 months ago)
Author:
tomoyo
Message:

* Redirect フィルタを追加
* Replies の扱いをいろいろ修正
* その他こまごまとした修正

Location:
TwitterIrcGateway/TwitterIrcGatewayCore
Files:
3 modified

Legend:

Unmodified
Added
Removed
  • TwitterIrcGateway/TwitterIrcGatewayCore/Filter.cs

    r343 r347  
    1010{ 
    1111    [XmlInclude(typeof(Drop))] 
    12     [XmlInclude(typeof(Reroute))] 
     12    [XmlInclude(typeof(Redirect))] 
    1313    [XmlInclude(typeof(RewriteContent))] 
    1414    public class Filters 
     
    204204    } 
    205205     
    206     public class Reroute : FilterItem 
     206    public class Redirect : FilterItem 
    207207    { 
    208208        private String _matchPattern = ""; 
     
    236236        public override void Execute(FilterArgs args) 
    237237        { 
     238            if (String.IsNullOrEmpty(_channelName)) 
     239                return; 
     240 
    238241            if (!String.IsNullOrEmpty(_matchPattern)) 
    239242            { 
     
    266269        public override string ToString() 
    267270        { 
    268             return "Reroute:" 
     271            return "Redirect:" 
    269272                + ((Enabled) ? "" : "[DISABLED]") 
    270273                + ((String.IsNullOrEmpty(_userMatchPattern)) ? "" : String.Format(" UserMatchPattern={0}", _userMatchPattern)) 
    271274                + ((String.IsNullOrEmpty(_matchPattern)) ? "" : String.Format(" MatchPattern={0}", _matchPattern)) 
     275                + ((String.IsNullOrEmpty(_channelName)) ? "" : String.Format(" ChannelName={0}", _channelName)) 
    272276                + ((_duplicate) ? " Duplicate" : "") 
    273277            ; 
  • TwitterIrcGateway/TwitterIrcGatewayCore/Server.cs

    r319 r347  
    2323        /// </summary> 
    2424        public Int32 IntervalDirectMessage = 60 * 5; 
     25 
     26        /// <summary> 
     27        /// Replies��F�b�N���邩�ǂ��� 
     28        /// </summary> 
     29        public Boolean EnableRepliesCheck = false; 
     30         
     31        /// <summary> 
     32        /// Replies�`�F�b�N�����u 
     33        /// </summary> 
     34        public Int32 IntervalReplies = 60 * 5; 
    2535 
    2636        /// <summary> 
  • TwitterIrcGateway/TwitterIrcGatewayCore/Session.cs

    r341 r347  
    11using System; 
    22using System.Collections.Generic; 
    3 using System.Text; 
     3using System.Diagnostics; 
     4using System.Globalization; 
     5using System.IO; 
    46using System.Net.Sockets; 
    57using System.Net; 
    6 using System.IO; 
     8using System.Reflection; 
     9using System.Text; 
     10using System.Text.RegularExpressions; 
     11using System.Threading; 
    712using System.Web; 
    8 using System.Threading; 
     13using System.Xml; 
     14 
    915using Misuzilla.Net.Irc; 
    10 using System.Xml; 
    11 using System.Diagnostics; 
    12 using System.Globalization; 
    13 using System.Text.RegularExpressions; 
    1416using Misuzilla.Applications.TwitterIrcGateway.Filter; 
    15 using System.Reflection; 
    1617 
    1718namespace Misuzilla.Applications.TwitterIrcGateway 
     
    2930        private Timer _timer; 
    3031        private Timer _timerDirectMessage; 
     32        private Timer _timerReplies; 
    3133        private Groups _groups; 
    3234        private Filters _filter; 
     
    3739        private DateTime _lastAccessDirectMessage = DateTime.Now; 
    3840        private LinkedList<Status> _statusBuffer; 
    39         private Boolean _isCallbackRunning = false; 
    40         private Boolean _isCallbackDirectMessageRunning = false; 
     41        private LinkedList<Status> _repliesBuffer; 
    4142        private TraceListener _traceListeneer; 
    4243 
     
    6970            _tcpClient = tcpClient; 
    7071            _statusBuffer = new LinkedList<Status>(); 
     72            _repliesBuffer = new LinkedList<Status>(); 
    7173            _lastStatusIdsFromGateway = new LinkedList<int>(); 
    7274            _timer = new Timer(new TimerCallback(OnTimerCallback), null, Timeout.Infinite, Timeout.Infinite); 
    7375            _timerDirectMessage = new Timer(new TimerCallback(OnTimerCallbackDirectMessage), null, Timeout.Infinite, Timeout.Infinite); 
     76            _timerReplies = new Timer(new TimerCallback(OnTimerCallbackReplies), null, Timeout.Infinite, Timeout.Infinite); 
    7477        } 
    7578 
     
    109112            } 
    110113        } 
    111  
     114         
    112115        /// <summary> 
    113116        ///  
     
    116119        private void OnTimerCallback(Object stateObject) 
    117120        { 
    118             // あまりに処理が遅れると二重になる可能性がある 
    119             lock (_timer) 
    120             { 
    121                 if (_isCallbackRunning) 
    122                     return; 
    123                 _isCallbackRunning = true; 
    124             } 
    125  
    126             try 
     121            RunCallback(_timer, delegate 
    127122            { 
    128123                SendPing(); 
     
    140135                    CheckFriends(); 
    141136                } 
    142             } 
    143             finally 
    144             { 
    145                 _isCallbackRunning = false; 
    146             } 
     137            }); 
    147138        } 
    148139 
     
    153144        private void OnTimerCallbackDirectMessage(Object stateObject) 
    154145        { 
     146            RunCallback(_timerDirectMessage, delegate 
     147            { 
     148                CheckDirectMessage(); 
     149            }); 
     150        } 
     151         
     152        /// <summary> 
     153        ///  
     154        /// </summary> 
     155        /// <param name="stateObject"></param> 
     156        private void OnTimerCallbackReplies(Object stateObject) 
     157        { 
     158            RunCallback(_timerReplies, delegate 
     159            { 
     160                CheckDirectMessage(); 
     161            }); 
     162        } 
     163 
     164        /// <summary> 
     165        ///  
     166        /// </summary> 
     167        private delegate void CallbackProcedure(); 
     168 
     169        /// <summary> 
     170        /// タイマーコールバックの処理を実行します。 
     171        /// </summary> 
     172        /// <param name="timer"></param> 
     173        /// <param name="callbackProcedure"></param> 
     174        private void RunCallback(Timer timer, CallbackProcedure callbackProcedure) 
     175        { 
    155176            // あまりに処理が遅れると二重になる可能性がある 
    156             lock (_timer) 
    157             { 
    158                 if (_isCallbackDirectMessageRunning) 
    159                     return; 
    160                 _isCallbackDirectMessageRunning = true; 
    161             } 
    162  
    163             try 
    164             { 
    165                 CheckDirectMessage(); 
    166             } 
    167             finally 
    168             { 
    169                 _isCallbackDirectMessageRunning = false; 
     177            if (Monitor.TryEnter(timer)) 
     178            { 
     179                try 
     180                { 
     181                    callbackProcedure(); 
     182                } 
     183                finally 
     184                { 
     185                    Monitor.Exit(timer); 
     186                } 
    170187            } 
    171188        } 
     
    190207                        try 
    191208                        { 
    192                             //Console.WriteLine(line); 
    193                             line = line.Replace('〜', '~'); // FIXME:  
    194209                            IRCMessage msg = IRCMessage.CreateMessage(line); 
    195210                            OnMessageRecieved(msg); 
    196211                        } 
    197212                        catch (IRCException) 
    198                         { 
    199                         } 
     213                        {} 
    200214                    } 
    201215                } 
    202216            } 
    203217            catch (IOException ie) 
    204             { 
    205             } 
     218            {} 
    206219            catch (NullReferenceException ne) 
    207             { 
    208             } 
     220            {} 
    209221            finally 
    210222            { 
     
    611623            _timer.Change(0, _server.Interval * 1000); 
    612624            _timerDirectMessage.Change(0, _server.IntervalDirectMessage * 1000); 
     625            _timerReplies.Change(0, _server.IntervalReplies * 1000); 
    613626        } 
    614627 
     
    870883        void GetFriendNames() 
    871884        { 
    872             try 
     885            RunCheck(delegate 
    873886            { 
    874887                User[] friends = _twitter.GetFriends(); 
    875                 _nickNames = new List<string>(Array.ConvertAll<User, String>(friends, delegate(User u) { 
     888                _nickNames = new List<string>(Array.ConvertAll<User, String>(friends, delegate(User u) 
     889                { 
    876890                    return u.ScreenName; 
    877891                })); 
     
    879893                SendNumericReply(NumericReply.RPL_NAMREPLY, "=", _server.ChannelName, String.Join(" ", _nickNames.ToArray())); 
    880894                SendNumericReply(NumericReply.RPL_ENDOFNAMES, _server.ChannelName, "End of NAMES list"); 
    881             } 
    882             catch (WebException ex) 
    883             { 
    884                 if (ex.Response == null || (ex.Response is HttpWebResponse) && ((HttpWebResponse)(ex.Response)).StatusCode != HttpStatusCode.NotModified) 
    885                 { 
    886                     // not-modified 以外 
    887                     SendTwitterGatewayServerMessage(ex.Message); 
    888                 } 
    889             } 
    890             catch (TwitterServiceException ex2) 
    891             { 
    892                 SendTwitterGatewayServerMessage(ex2.Message); 
    893             } 
     895            }); 
    894896        } 
    895897 
     
    913915            } 
    914916 
    915             try 
     917            RunCheck(delegate 
    916918            { 
    917919                User[] friends = _twitter.GetFriends(); 
     
    947949                _nickNames = screenNames; 
    948950 
    949             } 
    950             catch (WebException ex) 
    951             { 
    952                 if (ex.Response == null || !(ex.Response is HttpWebResponse) || ((HttpWebResponse)(ex.Response)).StatusCode != HttpStatusCode.NotModified) 
    953                 { 
    954                     // not-modified 以外 
    955                     SendServerErrorMessage(ex.Message); 
    956                 } 
    957             } 
    958             catch (TwitterServiceException ex2) 
    959             { 
    960                 SendServerErrorMessage(ex2.Message); 
    961             } 
     951            }); 
    962952        } 
    963953 
    964954        private Boolean CheckNewTimeLine(out Boolean friendsCheckRequired) 
    965955        { 
    966             friendsCheckRequired = false; 
    967  
    968             try 
     956            Boolean friendsCheckRequiredAnon = false; 
     957            Boolean returnValue = RunCheck(delegate 
    969958            { 
    970959                Statuses statuses = _twitter.GetTimeline(_lastAccessTimeline); 
     
    972961                foreach (Status status in statuses.Status) 
    973962                { 
    974                     ProcessTimelineStatus (status, ref friendsCheckRequired); 
    975                 } 
    976                 statuses = _twitter.GetReplies(); 
     963                    // 差分チェック 
     964                    if (ProcessDropProtection(_statusBuffer, status)) 
     965                    { 
     966                        ProcessTimelineStatus(status, ref friendsCheckRequiredAnon); 
     967                    } 
     968                } 
     969 
     970                if (_isFirstTime && _server.EnableDropProtection) 
     971                { 
     972                    _lastAccessTimeline = DateTime.Now; 
     973                } 
     974                _isFirstTime = false; 
     975            }); 
     976             
     977            friendsCheckRequired = friendsCheckRequiredAnon; 
     978            return returnValue; 
     979        } 
     980 
     981        private Boolean CheckNewReplies(out Boolean friendsCheckRequired) 
     982        { 
     983            friendsCheckRequired = false; 
     984            return RunCheck(delegate 
     985            { 
     986                Statuses statuses = _twitter.GetReplies(); 
    977987                Array.Reverse(statuses.Status); 
    978988                bool dummy = false; 
     
    981991                    if (status.CreatedAt < _lastAccessTimeline) 
    982992                        continue; 
    983                     // Here I pass dummy, because no matter how the replier flags 
    984                     // friendsCheckRequired, we cannot receive his or her info 
    985                     // through get_friends. 
    986                     ProcessTimelineStatus (status, ref dummy); 
     993                    // 差分チェック 
     994                    if (ProcessDropProtection(_statusBuffer, status) && ProcessDropProtection(_repliesBuffer, status)) 
     995                    { 
     996                        // Here I pass dummy, because no matter how the replier flags 
     997                        // friendsCheckRequired, we cannot receive his or her info 
     998                        // through get_friends. 
     999                        ProcessTimelineStatus(status, ref dummy); 
     1000                    } 
    9871001                } 
    9881002 
     
    9921006                } 
    9931007                _isFirstTime = false; 
    994             } 
    995             catch (WebException ex) 
    996             { 
    997                 if (ex.Response == null || !(ex.Response is HttpWebResponse) || ((HttpWebResponse)(ex.Response)).StatusCode != HttpStatusCode.NotModified) 
    998                 { 
    999                     // not-modified 以外 
    1000                     SendServerErrorMessage(ex.Message); 
    1001                 } 
    1002                 return false; 
    1003             } 
    1004             catch (TwitterServiceException ex2) 
    1005             { 
    1006                 SendServerErrorMessage(ex2.Message); 
    1007                 return false; 
    1008             } 
    1009  
    1010             return true; 
    1011         } 
    1012  
    1013         private void ProcessTimelineStatus (Status status, ref Boolean friendsCheckRequired) 
     1008            }); 
     1009        } 
     1010         
     1011        /// <summary> 
     1012        /// 既に受信したstatusかどうかをチェックします。既に送信済みの場合falseを返します。 
     1013        /// </summary> 
     1014        /// <param name="statusBuffer"></param> 
     1015        /// <param name="status"></param> 
     1016        /// <returns></returns> 
     1017        private Boolean ProcessDropProtection(LinkedList<Status> statusBuffer, Status status) 
    10141018        { 
    10151019            // 差分チェック 
    10161020            if (_server.EnableDropProtection) 
    10171021            { 
    1018                 if (_statusBuffer.Contains(status)) 
    1019                     return; 
    1020  
    1021                 _statusBuffer.AddLast(status); 
    1022                 if (_statusBuffer.Count > 100) 
     1022                if (statusBuffer.Contains(status)) 
     1023                    return false; 
     1024 
     1025                statusBuffer.AddLast(status); 
     1026                if (statusBuffer.Count > 100) 
    10231027                { 
    10241028                    // 一番古いのを消す 
     
    10321036                    //} 
    10331037                    //_statusBuffer.Remove(oldStatus); 
    1034                     _statusBuffer.RemoveFirst(); 
    1035                 } 
    1036             } 
     1038                    statusBuffer.RemoveFirst(); 
     1039                } 
     1040            } 
     1041             
     1042            return true; 
     1043        } 
     1044         
     1045        private void ProcessTimelineStatus (Status status, ref Boolean friendsCheckRequired) 
     1046        { 
    10371047 
    10381048            // チェック 
     
    11401150        private void CheckDirectMessage() 
    11411151        { 
    1142             try 
     1152            RunCheck(delegate 
    11431153            { 
    11441154                DirectMessages directMessages = _twitter.GetDirectMessages(_lastAccessDirectMessage); 
     
    11521162                    } 
    11531163 
    1154                     String text = (_server.ResolveTinyUrl) ? Utility.ResolveTinyUrlInMessage(message.Text) : message.Text;  
     1164                    String text = (_server.ResolveTinyUrl) ? Utility.ResolveTinyUrlInMessage(message.Text) : message.Text; 
    11551165                    String[] lines = text.Split(new Char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries); 
    11561166 
     
    11711181                    } 
    11721182                } 
     1183            }); 
     1184        } 
     1185 
     1186        private delegate void CheckProcedure(); 
     1187        /// <summary> 
     1188        /// チェックを実行します。例外が発生した場合には自動的にメッセージを送信します。 
     1189        /// </summary> 
     1190        /// <param name="proc">実行するチェック処理</param> 
     1191        /// <returns></returns> 
     1192        private Boolean RunCheck(CheckProcedure proc) 
     1193        { 
     1194            try 
     1195            { 
     1196                proc(); 
    11731197            } 
    11741198            catch (WebException ex) 
     
    11781202                    // not-modified 以外 
    11791203                    SendServerErrorMessage(ex.Message); 
     1204                    return false; 
    11801205                } 
    11811206            } 
     
    11831208            { 
    11841209                SendServerErrorMessage(ex2.Message); 
    1185             } 
    1186         } 
     1210                return false; 
     1211            } 
     1212 
     1213            return true; 
     1214        } 
     1215         
    11871216 
    11881217        /// <summary> 
     
    12251254                    _timerDirectMessage = null; 
    12261255                } 
    1227  
    1228                 // 一応待つ 
    1229                 while (_isCallbackRunning || _isCallbackDirectMessageRunning) 
    1230                     Thread.Sleep(100); 
     1256                if (_timerReplies != null) 
     1257                { 
     1258                    _timerReplies.Dispose(); 
     1259                    _timerReplies = null; 
     1260                } 
    12311261 
    12321262                if (_twitter != null)