-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathirc.py
128 lines (112 loc) · 4.54 KB
/
irc.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# Copyright Beatrice Tohni 2021
""" This file is part of wiggleVerse.
wiggleVerse is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
wiggleVerse is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with wiggleVerse. If not, see <https://www.gnu.org/licenses/>."""
import socket
import ircsocket
import threading
import logging
from ircsocket import IrcSocket
from exceptions import *
class Irc:
"""A class to manage channels and users on one IRC network
This class is a wrapper for the IrcSocket class
"""
def get_messages(self, stop, buffer):
while 1:
if stop:
logging.info('[IRC] Receive thread sent stop signal')
break
try:
lines = self.socket.get_raw()
for line in lines:
# Handle ping and pong here
if line[0:4] == 'PING':
self.send_raw('PONG' + line[4:])
logging.debug('Sent pong successfully')
continue
buffer.put(line)
except OSError as err:
logging.error(err)
if self.connected:
self.buffer.put(f'>>Error receiving messages: {err}')
self.disconnect()
logging.info('[IRC] Socket error in receive thread, stopping...')
break
def __init__(self, host, port, nick, user, real, get_messages_callback, buffer, tag=False):
"""Create a new IRC instance
Each instance represents one connection to one server"""
self.host = host
self.port = port
self.nick = nick
self.user = user
self.real = real
self.channels = []
self.get_messages_callback = get_messages_callback
self.buffer = buffer
self.connected = False
# Assign server tag if none given
# This works well for host names, is not great for IPs but oh well
if not tag:
try:
self.tag = host.split('.')[:-2]
except IndexError:
self.tag = host
def connect(self):
# Try to connect
if self.connected:
buffer.put('>>We are already connected')
try:
self.socket = IrcSocket()
self.socket.connect(self.host, self.port)
self.socket.put_raw(f"USER {self.user} 0 * :{self.real}")
# TODO Support alternate nick
self.socket.put_raw(f"NICK {self.nick}")
self.stop_thread = False # used to stop the thread when connection dies
self.receive_thread = threading.Thread(target=self.get_messages, args=(self.stop_thread, self.buffer,), daemon=True)
self.receive_thread.start()
self.connected = True
except OSError as err:
logging.error(err)
self.buffer.put(f'>>Connection failed due to error: {err}')
self.disconnect()
def disconnect(self):
"""Shut down the socket and run clean up code"""
try:
logging.debug('[IRC] Disconnection process started')
self.connected = False
self.stop_thread = True # failsafe
self.socket.disconnect()
except OSError as err:
logging.warning('[IRC] IRC socket reported error closing.')
finally:
logging.info('[IRC] IRC connection closed')
logging.debug('[IRC] Disconnection process finished')
self.buffer.put('>>IRC connection lost')
self.buffer.put('[wiggleVerse] DROPCON')
def send_raw(self, message):
try:
self.socket.put_raw(message)
except OSError as err:
logging.error(f"[IRC] Error sending: {err}")
buffer.put(f'>>Error sending message: {err}')
buffer.put('Disconnecting...')
self.disconnect()
def is_connected(self):
return self.connected
def get_tag(self):
return self.tag
# def join(self, channel):
# pass
# def part(self, channel):
# pass
# def nick(self, new_nick):
# pass