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 |
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): |