From 5f44ef78bbacc3091a00c6c8bfff33665766b92b Mon Sep 17 00:00:00 2001 From: Alchan Kim Date: Mon, 17 Sep 2012 16:30:51 +0900 Subject: [PATCH] =?UTF-8?q?issue=20#16=20=ED=95=B4=EA=B2=B0.=20=EC=9D=B4?= =?UTF-8?q?=EC=A0=9C=20=EB=AA=A8=EB=93=A0=20=EC=B1=84=EB=84=90=EC=9D=80=20?= =?UTF-8?q?=ED=8D=BC=EC=84=BC=ED=8A=B8=20=EC=9D=B8=EC=BD=94=EB=94=A9=20?= =?UTF-8?q?=EB=90=98=EC=96=B4=EC=84=9C=20db=EC=97=90=20=EB=93=A4=EC=96=B4?= =?UTF-8?q?=EA=B0=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bot.py | 221 +++++++++++++++++++++++++++++--------------------------- wsgi.py | 15 +++- 2 files changed, 124 insertions(+), 112 deletions(-) diff --git a/bot.py b/bot.py index 2d42854..7d04e97 100644 --- a/bot.py +++ b/bot.py @@ -1,108 +1,113 @@ -# coding: utf-8 - -import ircbot -import irclib - -import pymongo - -import datetime - -import config - -class SBot(ircbot.SingleServerIRCBot): - def __init__(self): - ircbot.SingleServerIRCBot.__init__(self, - [(config.SERVER, config.PORT), ], - config.BOT_NAME, - 'm', - ) - self.connected = False - - connection = pymongo.Connection() - self.db = connection[config.SIRC_DB] - self.db.send.remove() - self._fetch() - - def on_welcome(self, c, e): - self.connected = True - for target in self.db.collection_names(): - if target.startswith('#'): # TODO: is_channel? - c.join(target) - - def on_mode(self, c, e): - nick = irclib.nm_to_n(e.source()) - target = e.target() - if irclib.is_channel(target): - self._log(target, config.NOTIFY_NAME, '[%s] by <%s>.' % (' '.join(e.arguments()), nick)) - else: - pass - - def on_nick(self, c, e): - before = irclib.nm_to_n(e.source()) - after = e.target() - for target, ch in self.channels.items(): - if ch.has_user(before): - self._log(target, config.NOTIFY_NAME, '<%s> is now known as <%s>.' % (before, after)) - - def on_join(self, c, e): - nick = irclib.nm_to_n(e.source()) - self._log(e.target(), config.NOTIFY_NAME, '<%s> has joined.' % nick) - - def on_part(self, c, e): - nick = irclib.nm_to_n(e.source()) - self._log(e.target(), config.NOTIFY_NAME, '<%s> has left.' % nick) - - def on_quit(self, c, e): - nick = irclib.nm_to_n(e.source()) - for target, ch in self.channels.items(): - if ch.has_user(nick): - self._log(target, config.NOTIFY_NAME, '<%s> has quit.' % nick) - - def on_kick(self, c, e): - nick_s = irclib.nm_to_n(e.source()) - nick_m = e.arguments()[0] - because_of = e.arguments()[1] - self._log(e.target(), config.NOTIFY_NAME, '<%s> was kicked by <%s> because of "%s".' % (nick_m, nick_s, because_of)) - - def on_pubmsg(self, c, e): - nick = irclib.nm_to_n(e.source()) - target = e.target() - message = e.arguments()[0] - self._log(target, nick, message) - if self.channels[target].is_oper(c.get_nickname()) and \ - nick == config.OPERATOR_NAME and \ - message.startswith(config.OPERATOR_COMMAND): - self.connection.mode(target, '+o %s' % nick) - - def _log(self, target, source, message): - data = { - 'datetime': datetime.datetime.now(), - 'source': source, - 'message': message, - } - try: - self.db[target.lower()].insert(data) - except: - pass - - def _fetch(self): - if self.connected: - try: - for data in self.db.send.find(): - channel = data['channel'].encode('utf-8').lower() - if channel not in self.channels: - self.connection.join(channel) - account = data['account'].encode('utf-8') - message = ('<%s> %s' % (account, data['message'])).encode('utf-8') - self.connection.privmsg(channel, message) - self._log(channel, self._nickname, message) - self.db.send.remove(data) - except irclib.ServerNotConnectedError: - self.connected = False - self._connect() - self.ircobj.execute_delayed(1, self._fetch) - -if __name__ == '__main__': - bot = SBot() - bot.start() - +# coding: utf-8 + +import ircbot +import irclib + +import pymongo +import datetime + +import config + +import urllib2 # only for quote + +class SBot(ircbot.SingleServerIRCBot): + def __init__(self): + ircbot.SingleServerIRCBot.__init__(self, + [(config.SERVER, config.PORT), ], + config.BOT_NAME, + 'm', + ) + self.connected = False + + connection = pymongo.Connection() + self.db = connection[config.SIRC_DB] + self.db.send.remove() + self._fetch() + + def on_welcome(self,c, e): + self.connected = True + for target in self.db.collection_names(): #extract last channels the user used + target = urllib2.unquote(target.encode("utf-8")) + if target.startswith('#'): # TODO: is_channel? + c.join(target) #==self.connect.join(target) + + def on_mode(self, c, e): + nick = irclib.nm_to_n(e.source()) + target = e.target() + if irclib.is_channel(target): + self._log(target, config.NOTIFY_NAME, '[%s] by <%s>.' % (' '.join(e.arguments()), nick)) + else: + pass + + def on_nick(self, c, e): + before = irclib.nm_to_n(e.source()) + after = e.target() + for target, ch in self.channels.items(): + if ch.has_user(before): + self._log(target, config.NOTIFY_NAME, '<%s> is now known as <%s>.' % (before, after)) + + def on_join(self, c, e): + nick = irclib.nm_to_n(e.source()) + self._log(e.target(), config.NOTIFY_NAME, '<%s> has joined.' % nick) + + def on_part(self, c, e): + nick = irclib.nm_to_n(e.source()) + self._log(e.target(), config.NOTIFY_NAME, '<%s> has left.' % nick) + + def on_quit(self, c, e): + nick = irclib.nm_to_n(e.source()) + for target, ch in self.channels.items(): + if ch.has_user(nick): + self._log(target, config.NOTIFY_NAME, '<%s> has quit.' % nick) + + def on_kick(self, c, e): + nick_s = irclib.nm_to_n(e.source()) + nick_m = e.arguments()[0] + because_of = e.arguments()[1] + self._log(e.target(), config.NOTIFY_NAME, '<%s> was kicked by <%s> because of "%s".' % (nick_m, nick_s, because_of)) + # ޽ + def on_pubmsg(self, c, e): #c ĿƮ , 㳪 ̹ connection̶ Ƿ ׷ ʿ䰡 ?=> + nick = irclib.nm_to_n(e.source())# e: Eventü(source target ) + target = e.target() + message = e.arguments()[0] + self._log(target, nick, message) + if self.channels[target].is_oper(c.get_nickname()) and \ + nick == config.OPERATOR_NAME and \ + message.startswith(config.OPERATOR_COMMAND): + self.connection.mode(target, '+o %s' % nick) + def _log(self, target, source, message): + data = { + 'datetime': datetime.datetime.now(), + 'source': source, + 'message': message, + } + try: + channel = target.lower() + channel = urllib2.quote(channel) # percent encoding to deal with hangul channel + self.db[channel].insert(data) + except: + pass + #send ִ =>irc + #ڵ Ҹ + def _fetch(self): + if self.connected: + try: + for data in self.db.send.find(): + channel = data['channel'].lower().encode('utf-8').lower() + + if channel not in self.channels: + self.connection.join(channel) + account = data['account'].encode('utf-8') + message = ('<%s> %s' % (account, data['message'])).encode('utf-8') + self.connection.privmsg(channel, message) #߿: ޽ + self._log(channel, self._nickname, message) + self.db.send.remove(data) + except irclib.ServerNotConnectedError: + self.connected = False + self._connect() + self.ircobj.execute_delayed(1, self._fetch) # 1ʸ fetchϴ Լ + +if __name__ == '__main__': + bot = SBot() + bot.start() + diff --git a/wsgi.py b/wsgi.py index 4cf3368..8d20037 100644 --- a/wsgi.py +++ b/wsgi.py @@ -11,6 +11,7 @@ import Cookie import jinja2 +import urllib2 import pymongo PATH = os.path.dirname(os.path.realpath(__file__)) @@ -133,7 +134,10 @@ def update(environ, start_response, session, parameters): last_update = parse_datetime(parameters['last_update'][0].decode('utf-8')) if 'transition_id' not in parameters: return error(start_response, message = 'no transition_id') - channel = parameters['channel'][0].decode('utf-8').lower() + channel = parameters['channel'][0].lower()#.decode('utf-8').lower() + #channel is percent-encoded now + channel_encoded = urllib2.quote(channel) + transition_id = parameters['transition_id'][0].decode('utf-8') if db[session['account']].find({'channel': channel}).count() == 0: db[session['account']].insert({'channel': channel}) @@ -141,7 +145,7 @@ def update(environ, start_response, session, parameters): context['transition_id'] = transition_id logs = [] for i in xrange(30): - logs = list(db[channel].find({ + logs = list(db[channel_encoded].find({ 'datetime': {"$gt": last_update}, }, sort = [ ('datetime', pymongo.ASCENDING) @@ -166,11 +170,13 @@ def downdate(environ, start_response, session, parameters): last_downdate = parse_datetime(parameters['last_downdate'][0].decode('utf-8')) if 'transition_id' not in parameters: return error(start_response, message = 'no transition_id') - channel = parameters['channel'][0].decode('utf-8').lower() + channel = parameters['channel'][0].lower()#.decode('utf-8').lower() + channel_encoded = urllib2.quote(channel) #channel name is percent-encoded + transition_id = parameters['transition_id'][0].decode('utf-8') context['channel'] = channel context['transition_id'] = transition_id - logs = db[channel].find({ + logs = db[channel_encoded].find({ 'datetime': {"$lt": last_downdate}, }, limit = config.N_LINES, sort = [ ('datetime', pymongo.DESCENDING) @@ -189,6 +195,7 @@ def send(environ, start_response, session, parameters): return error(start_response, message = 'no channel') if 'message' not in parameters: return error(start_response, message = 'no message') + #send db에 넣을 때는 percent-encode할 필요가 없다 channel = parameters['channel'][0].decode('utf-8').lower() message = parameters['message'][0].decode('utf-8') db.send.insert({