from PyQt5.QtCore import QUrl, QThread, pyqtSignal, QObject, pyqtSlot, Qt
from PyQt5.QtQuick import QQuickView, QQuickItem, QQuickWindow
import IrcConnection
import Channel
import User
class IrcHandler(QObject):
sig = pyqtSignal(str,str)
join_sig = pyqtSignal(str)
def __init__(self, window):
super(self.__class__, self).__init__()
self.channels = {}
self.nick = "wtest"
self.server = "irc.blatech.net"
self.irc = IrcConnection.ircConnectThread(self)
self.window = window
def get_channels():
return self.channels
def set_channels(channels):
self.channels = channels
def add_channel(self, channel):
self.channels[channel.get_name()] = channel
def remove_channel(self, channel_name):
del self.channels[channel_name]
def get_server():
return self.server
def set_server(server):
self.server = server
def get_nick(self):
return self.nick
def set_nick(self, nick):
self.nick = nick
def change_nick(self, new_nick):
self.irc.change_nick(new_nick)
@pyqtSlot(str)
def join_channel(self, channelStr):
res = self.irc.join_channel(channelStr)
if (res):
channel = Channel.Channel(channelStr)
self.add_channel(channel)
self.window.channel_tabs.add_channel(channelStr)
channel_view = self.window.view.findChild(QQuickItem, "channel-" + channelStr)
send_button = channel_view.findChild(QQuickItem, "send_button")
input_field = channel_view.findChild(QQuickItem, "input")
send_button.clicked.connect(self.handle_input)
input_field.send_to_irc.connect(self.handle_input)
channel.set_view(channel_view)
def part_channel(self, channelStr):
if (channelStr in self.channels):
res = self.irc.part_channel(channelStr)
if (res):
self.remove_channel(channelStr)
self.window.channel_tabs.remove_channel(channelStr)
def handle_input(self):
current_channel = self.window.channel_tabs.property('currentItem').property('text')
text = self.window.get_input(current_channel)
if (text.startswith("/")):
params = text.split(" ")
command = params[0][1:]
if (command == "join"):
channel = params[1]
self.join_channel(channel)
elif (command == "part"):
if (len(params) > 1 and params[1].strip() != ""):
channel = params[1]
else:
channel = current_channel
self.part_channel(channel)
elif (command == "nick"):
new_nick = params[1]
self.change_nick(new_nick)
else:
self.sig.emit(current_channel, text)
self.window.update_chat(current_channel, "<" + self.nick + "> " + text)
self.window.reset_input(current_channel)
@pyqtSlot(str, str, str)
def handle_msg(self, channelStr, nick, msg):
if channelStr in self.channels:
channel = self.channels[channelStr]
self.window.update_chat(channelStr, "<" + nick + "> " + msg)
@pyqtSlot(str)
def handle_status_msg(self, msg):
self.window.update_chat("status", msg)
@pyqtSlot(str, str)
def handle_nicks(self, channelStr, nicks):
nick_listStr = nicks.split(" ")[0:-1]
if (channelStr in self.channels):
channel = self.channels.get(channelStr)
user_list = channel.get_view().findChild(QQuickItem, "nick_list")
for nickStr in nick_listStr:
if (nickStr[0] in ["@", "+", "~", "%"]):
mode = nickStr[0]
nickStr = nickStr[1:]
else:
mode = ""
user = User.User(nickStr, mode)
channel.add_user(user)
user_list.add_nick(nickStr, mode)
def handle_join(self, channelStr, nickStr):
if (channelStr in self.channels):
channel = self.channels.get(channelStr)
user_list = channel.get_view().findChild(QQuickItem, "nick_list")
chat_area = channel.get_view().findChild(QQuickItem, "chat_area")
if (nickStr != self.get_nick()):
if (nickStr[0] in ["@", "+", "~", "%"]):
mode = nickStr[0]
nickStr = nickStr[1:]
else:
mode = ""
user = User.User(nickStr, mode)
channel.add_user(user)
user_list.add_nick(nickStr, mode)
chat_area.append(nickStr + " joined " + channelStr)
def handle_part(self, channelStr, user):
if (channelStr in self.channels):
channel = self.channels.get(channelStr)
user_list = channel.get_view().findChild(QQuickItem, "nick_list")
chat_area = channel.get_view().findChild(QQuickItem, "chat_area")
if (user != self.get_nick()):
user_list.remove_nick(user)
channel.remove_user(user)
chat_area.append(user + " left " + channelStr)
def handle_quit(self, nickStr, quit_msg):
for channel_name, channel in self.channels.items():
if (nickStr in channel.get_users()):
channel.remove_user(nickStr)
user_list = channel.get_view().findChild(QQuickItem, "nick_list")
chat_area = channel.get_view().findChild(QQuickItem, "chat_area")
user_list.remove_nick(nickStr)
chat_area.append(nickStr + " quit (" + quit_msg + ")")
def handle_kick(self, kicked_nick, channelStr, by_nick, reason):
if (channelStr in self.channels):
channel = self.channels.get(channelStr)
user_list = channel.get_view().findChild(QQuickItem, "nick_list")
chat_area = channel.get_view().findChild(QQuickItem, "chat_area")
if (kicked_nick != self.get_nick()):
user_list.remove_nick(kicked_nick)
channel.remove_user(kicked_nick)
chat_area.append(kicked_nick + " was kicked from " + channelStr + " by " + by_nick + " (" + reason +")")
def handle_topic(self, channelStr, topic):
if (channelStr in self.channels):
channel = self.channels.get(channelStr)
channel.set_topic(topic)
self.window.update_topic(channel, topic)
def handle_nick(self, previous_nick, new_nick):
for channel_name, channel in self.channels.items():
if (previous_nick in channel.get_users()):
channel = self.channels.get(channel_name)
user_list = channel.get_view().findChild(QQuickItem, "nick_list")
chat_area = channel.get_view().findChild(QQuickItem, "chat_area")
user_list.update_nick(previous_nick, new_nick)
new_user = User.User(new_nick, channel.get_users()[previous_nick].get_mode())
channel.remove_user(previous_nick)
channel.add_user(new_user)
chat_area.append(previous_nick + " is now known as " + new_nick)
def handle_user_mode(self, channelStr, target_user, mode, source_user):
if (channelStr in self.channels):
channel = self.channels.get(channelStr)
user_list = channel.get_view().findChild(QQuickItem, "nick_list")
chat_area = channel.get_view().findChild(QQuickItem, "chat_area")
if (mode == "+v"):
mode_char = "+"
mode_chat_str = " gave voice to "
elif (mode == "+h"):
mode_char = "%"
mode_chat_str = " gave half-ops to "
elif (mode == "+o"):
mode_char = "@"
mode_chat_str = " gave ops to "
elif (mode == "+a"):
mode_char = "&"
mode_chat_str = " gave owner status to "
elif (mode == "-v"):
mode_char = ""
mode_chat_str = " removed voice from "
elif (mode == "-h"):
mode_char = ""
mode_chat_str = " removed half-ops from "
elif (mode == "-o"):
mode_char = ""
mode_chat_str = " removed ops from "
elif (mode == "-a"):
mode_char = ""
mode_chat_str = " removed owner status from "
user_list.update_mode(target_user, mode_char)
channel.get_users()[target_user].set_mode(mode)
chat_area.append(source_user + mode_chat_str + target_user)
def handle_error(self, error_msg, target):
#Output the error in the relevant channel if one is provided
if(target != ""):
channel_view = self.channels.get(target).get_view();
#Otherwise use the currently selected channel
else:
current_channel = self.window.channel_tabs.property('currentItem').property('text')
channel = self.channels.get(current_channel)
#Default to the status channel if there's an issue (probably because status is the currently selected channel)
if (channel == None):
target = "status"
else:
target = current_channel
self.window.update_chat(target, error_msg)
def connect_to_irc(self, view):
self.irc.sig.connect(self.handle_msg)
self.irc.namreply_sig.connect(self.handle_nicks)
self.irc.join_sig.connect(self.handle_join)
self.irc.nick_sig.connect(self.handle_nick)
self.irc.part_sig.connect(self.handle_part)
self.irc.quit_sig.connect(self.handle_quit)
self.irc.kick_sig.connect(self.handle_kick)
self.irc.topic_sig.connect(self.handle_topic)
self.irc.user_mode_sig.connect(self.handle_user_mode)
self.irc.error_sig.connect(self.handle_error)
self.irc.status_sig.connect(self.handle_status_msg)
# self.irc.join_sig.connect(self.join_channel)
self.irc.start()
self.sig.connect(self.irc.send_msg)