class Client(object): """Main""" def __init__(self, channel, password, daemon_addr, conf): self.channel = channel self.password = password self.daemon_addr = daemon_addr self.conf = conf self.nick = None self.users = UserManager() self.terminal = None self.server = None def init(self): """Initialize""" self.start_interface() self.start_remote() def start_interface(self): """Start UI""" self.terminal = Terminal(self.users) self.terminal.set_channel(self.channel) def start_remote(self): """Connect to remote server""" sock = get_daemon_connection() self.server = Server(sock) if self.password: self.server.write("/pw " + self.password) time.sleep(1) if self.channel.startswith("#"): self.server.write("/join " + self.channel) else: # Private message (query). /private is not standard. self.server.write("/private " + self.channel) def run(self): """Main loop""" while 1: try: ready, _, _ = select.select( [sys.stdin, self.server.conn], [], []) except: # Window resize signal aborts select # Curses makes the resize event a fake keypress, so read it self.terminal.receive_one() continue if self.server.conn in ready: sock_data = self.server.receive_one() self.act_server(sock_data) if sys.stdin in ready: term_data = self.terminal.receive_one() self.act_user(term_data) def act_user(self, msg): """Act on user input""" if not msg: return # Local only commands if msg == u"/quit": raise StopException() elif msg == u"/url": url = self.terminal.get_url() if url: self.terminal.write(url) show_url(self.conf, url) else: self.terminal.write("No url found") return self.server.write(msg) if msg.startswith(u"/me "): me_msg = u"* " + msg.replace(u"/me ", self.nick + u" ") self.terminal.write(me_msg) elif not is_irc_command(msg): self.terminal.write_msg(self.nick, msg) def act_server(self, msg): """Act on server data""" display = translate_in(msg, self) if display: self.terminal.write(display) def stop(self): """Close remote connection, restore terminal to sanity""" if self.terminal: self.terminal.stop() if self.server: self.server.stop() # # hfilter callbacks # def on_nick(self, obj): """A nick change, possibly our own.""" old_nick = obj['user'] if old_nick and old_nick not in self.users: # User not in our channel return -1 new_nick = obj['content'] self.users.remove(old_nick) self.users.add(new_nick) if not old_nick or old_nick == self.nick: self.nick = new_nick self.terminal.set_nick(self.nick) return u"You are now known as %s" % self.nick def on_privmsg(self, obj): """A message. Format it nicely.""" username = obj['user'] self.terminal.write_msg(username, obj['content']) self.users.mark_active(username) self.terminal.set_active_users(self.users.active_count()) return -1 def on_join(self, obj): """User joined channel""" self.users.add(obj['user']) self.terminal.set_users(self.users.count()) self.terminal.set_active_users(self.users.active_count()) # Don't display joins in large channels if self.users.count() > SENSIBLE_AMOUNT: return -1 def on_part(self, obj): """User left channel""" who_left = obj['user'] if who_left not in self.users: # User was not in this channel return -1 self.users.remove(who_left) self.terminal.set_users(self.users.count()) self.terminal.set_active_users(self.users.active_count()) # Don't display parts in large channels if self.users.count() > SENSIBLE_AMOUNT: return -1 def on_quit(self, obj): """User quit IRC - treat it the same as leaving the channel""" return self.on_part(obj) def on_353(self, obj): """Reply to /names""" self.users.add_all(obj['content']) self.terminal.set_users(self.users.count()) self.terminal.set_active_users(self.users.active_count()) # Don't display list of users if there's too many if self.users.count() > SENSIBLE_AMOUNT: return -1 def on_002(self, obj): """Extract host name. The first PING will replace this""" host_msg = obj['content'].split(',')[0] host_msg = host_msg.replace("Your host is ", "").strip() self.terminal.set_host(host_msg) def on_328(self, obj): """Channel url""" url = obj['content'] msg = u"%s (%s)" % (self.channel, url) self.terminal.set_channel(msg) return -1 def on_mode(self, obj): """Block mode messages with an empty mode""" if not obj['content']: return -1 def on_ping(self, obj): """Tell the UI we got a server ping""" server_name = obj['content'] self.terminal.set_ping(server_name) self.terminal.set_active_users(self.users.active_count()) return -1
# -*- coding: utf-8 -*- """pelt main python file. Handles communication between Electron/Flask and the terminal code. """ from flask import Flask, render_template, request, send_from_directory from term import Terminal from theme import Theme import os # Global variables THEMES = list() TERMINAL = Terminal(name='main') # Load themes THEMES_DIR = os.getcwd() + '/themes/' for root in os.walk(THEMES_DIR): for folder in root[1]: THEMES.append(Theme(path=THEMES_DIR + folder)) # Initialize flask app if len(THEMES) > 0: APP = Flask(__name__, static_folder=THEMES_DIR + THEMES[0].name) else: APP = Flask(__name__) APP.debug = False @APP.route('/') def peyl_page(): """Provides the main.html template"""
def start_interface(self): """Start UI""" self.terminal = Terminal(self.users) self.terminal.set_channel(self.channel)