irc.py

changeset 146
c17b82b1f573
parent 143
d86a81540a71
child 152
1b734faab67a
equal deleted inserted replaced
145:588aff83bb87 146:c17b82b1f573
24 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 ''' 27 '''
28 28
29 from __future__ import print_function
29 import asyncore 30 import asyncore
30 import socket 31 import socket
31 import sys 32 import sys
32 import re 33 import re
33 import modulecore as ModuleCore 34 import modulecore as ModuleCore
58 59
59 # 60 #
60 # Prints a line to log channel(s) 61 # Prints a line to log channel(s)
61 # 62 #
62 def broadcast (line): 63 def broadcast (line):
63 print line 64 print (line)
65
64 for client in all_clients: 66 for client in all_clients:
65 if not client.flags & CLIF_CONNECTED: 67 if not client.flags & CLIF_CONNECTED:
66 continue 68 continue
67 69
68 for channel in client.channels: 70 for channel in client.channels:
102 self.verbose = Config.get_value ('verbose', default=False) 104 self.verbose = Config.get_value ('verbose', default=False)
103 self.commandprefix = Config.get_value ('commandprefix', default='.') 105 self.commandprefix = Config.get_value ('commandprefix', default='.')
104 all_clients.append (self) 106 all_clients.append (self)
105 asyncore.dispatcher.__init__ (self) 107 asyncore.dispatcher.__init__ (self)
106 self.create_socket (socket.AF_INET, socket.SOCK_STREAM) 108 self.create_socket (socket.AF_INET, socket.SOCK_STREAM)
107 print "[%s] Connecting to [%s] %s:%d..." % (get_timestamp(), self.name, self.host, self.port) 109 print ("[%s] Connecting to [%s] %s:%d..." % \
110 (get_timestamp(), self.name, self.host, self.port))
108 self.connect ((self.host, self.port)) 111 self.connect ((self.host, self.port))
109 ClientsByName[self.name] = self 112 ClientsByName[self.name] = self
110 113
111 def register_to_irc (self): 114 def register_to_irc (self):
112 ident = Config.get_value ('ident', default='cobalt') 115 ident = Config.get_value ('ident', default='cobalt')
114 self.write ("PASS %s" % self.password) 117 self.write ("PASS %s" % self.password)
115 self.write ("USER %s * * :%s" % (ident, gecos)) 118 self.write ("USER %s * * :%s" % (ident, gecos))
116 self.write ("NICK %s" % self.mynick) 119 self.write ("NICK %s" % self.mynick)
117 120
118 def handle_connect (self): 121 def handle_connect (self):
119 print "[%s] Connected to [%s] %s:%d" % (get_timestamp(), self.name, self.host, self.port) 122 print ("[%s] Connected to [%s] %s:%d" % (get_timestamp(), self.name, self.host, self.port))
120 self.register_to_irc() 123 self.register_to_irc()
121 124
122 def write (self, utfdata): 125 def write (self, utfdata):
123 try: 126 try:
124 self.send_buffer.append ("%s" % utfdata.decode("utf-8","ignore").encode("ascii","ignore")) 127 if sys.version_info < (3, 0):
128 self.send_buffer.append (utfdata.decode("utf-8","ignore").encode("ascii","ignore"))
129 else:
130 self.send_buffer.append (utfdata)
125 except UnicodeEncodeError: 131 except UnicodeEncodeError:
126 pass 132 pass
127 133
128 def handle_close (self): 134 def handle_close (self):
129 print "[%s] Connection to [%s] %s:%d terminated." % (get_timestamp(), self.name, self.host, self.port) 135 print ("[%s] Connection to [%s] %s:%d terminated." %
136 (get_timestamp(), self.name, self.host, self.port))
130 self.close() 137 self.close()
131 138
132 def handle_write (self): 139 def handle_write (self):
133 self.send_all_now() 140 self.send_all_now()
134 141
139 return len (self.send_buffer) > 0 146 return len (self.send_buffer) > 0
140 147
141 def send_all_now (self): 148 def send_all_now (self):
142 for line in self.send_buffer: 149 for line in self.send_buffer:
143 if self.verbose: 150 if self.verbose:
144 print "[%s] [%s] <- %s" % (get_timestamp(), self.name, line) 151 print ("[%s] [%s] <- %s" % (get_timestamp(), self.name, line))
145 self.send ("%s\n" % line) 152
153 if sys.version_info >= (3, 0):
154 self.send (bytes (line + '\n', 'UTF-8'))
155 else:
156 self.send (line + '\n')
146 time.sleep (0.25) 157 time.sleep (0.25)
147 self.send_buffer = [] 158 self.send_buffer = []
148 159
149 def handle_read (self): 160 def handle_read (self):
150 lines = self.recv (4096).splitlines() 161 lines = self.recv (4096).splitlines()
151 for utfline in lines: 162 for line in lines:
152 try: 163 try:
153 line = utfline.decode("utf-8","ignore").encode("ascii","ignore") 164 line = line.decode ('utf-8', 'ignore')
165
166 if sys.version_info < (3, 0):
167 line = line.encode ('ascii', 'ignore')
154 except UnicodeDecodeError: 168 except UnicodeDecodeError:
155 continue 169 continue
156 170
157 if self.verbose: 171 if self.verbose:
158 print "[%s] [%s] -> %s" % (get_timestamp(), self.name, line) 172 print ("[%s] [%s] -> %s" % (get_timestamp(), self.name, line))
159 173
160 if line.startswith ("PING :"): 174 if line[:len('PING :')] == ('PING :'):
161 self.write ("PONG :%s" % line[6:]) 175 self.write ("PONG :%s" % line[len('PING :'):])
162 self.send_all_now() # pings must be responded to immediately! 176 self.send_all_now() # pings must be responded to immediately!
163 else: 177 else:
164 words = line.split(" ") 178 words = line.split(" ")
165 if len(words) >= 2: 179 if len(words) >= 2:
166 if words[1] == "001": 180 if words[1] == "001":
170 184
171 if umode != '': 185 if umode != '':
172 self.write ('MODE %s %s' % (self.mynick, self.cfg.get_value ('umode', ''))) 186 self.write ('MODE %s %s' % (self.mynick, self.cfg.get_value ('umode', '')))
173 187
174 for channel in self.channels: 188 for channel in self.channels:
175 self.write ("JOIN %s %s" % (channel.get_value ('name'), channel.get_value ('password', default=''))) 189 self.write ("JOIN %s %s" %
190 (channel.get_value ('name'),
191 channel.get_value ('password', default='')))
176 elif words[1] == "PRIVMSG": 192 elif words[1] == "PRIVMSG":
177 self.handle_privmsg (line) 193 self.handle_privmsg (line)
178 elif words[1] == 'QUIT': 194 elif words[1] == 'QUIT':
179 rex = re.compile (r'^:([^!]+)!([^@]+)@([^ ]+) QUIT') 195 rex = re.compile (r'^:([^!]+)!([^@]+)@([^ ]+) QUIT')
180 match = rex.match (line) 196 match = rex.match (line)
269 for line in lines[1:]: 285 for line in lines[1:]:
270 self.privmsg (replyto, ' ' + line) 286 self.privmsg (replyto, ' ' + line)
271 return 287 return
272 288
273 def handle_error(self): 289 def handle_error(self):
274 raise RestartError (traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback)) 290 raise RestartError (traceback.format_exception (*sys.exc_info()))
275 291
276 def restart(self): 292 def restart(self):
277 raise RestartError('') 293 raise RestartError('')
278 294
279 def privmsg (self, channel, msg): 295 def privmsg (self, channel, msg):

mercurial