Skip to content

Commit

Permalink
issue sim0629#16 해결. 이제 모든 채널은 퍼센트 인코딩 되어서 db에 들어감
Browse files Browse the repository at this point in the history
  • Loading branch information
Algy committed Sep 17, 2012
1 parent ad826f3 commit 5f44ef7
Show file tree
Hide file tree
Showing 2 changed files with 124 additions and 112 deletions.
221 changes: 113 additions & 108 deletions bot.py
Original file line number Diff line number Diff line change
@@ -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()

15 changes: 11 additions & 4 deletions wsgi.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import Cookie
import jinja2

import urllib2
import pymongo

PATH = os.path.dirname(os.path.realpath(__file__))
Expand Down Expand Up @@ -133,15 +134,18 @@ 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})
context['channel'] = channel
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)
Expand All @@ -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)
Expand All @@ -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({
Expand Down

0 comments on commit 5f44ef7

Please sign in to comment.