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)