#! /usr/bin/env python # pymuseekd - Python tools for museekd # # Copyright (C) 2003-2004 Hyriand # # Contributions by daelstorm (C) 2005 # # This program 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. # # This program 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 this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA import curses, sys, time, pwd, os,commands import curses.wrapper import select, string, re, ConfigParser from time import sleep #from museek import messages, driver from UserDict import UserDict class SortedDict(UserDict): def keys(self): l = self.data.keys() l.sort() return l def items(self): l = self.data.items() l.sort() return l alpha_list = SortedDict() states = {} states[0] = "Finished" states[1] = "Transferring" states[2] = "Negotiating" states[3] = "Waiting" states[4] = "Establishing" states[5] = "Initiating" states[6] = "Connecting" states[7] = "Queued" states[8] = "Address" states[9] = "Status" states[10] = "Offline" states[11] = "ConnectionClosed" states[12] = "CannotConnect" states[13] = "Aborted" states[14] = "Error" config_dir = str(os.path.expanduser("~/.museekchat/")) config_file = config_dir+"config" parser = ConfigParser.ConfigParser() sections = {"connection":{"interface":'localhost:2240', "passw":None}, \ "museekchat":{}, "tickers":{'default_ticker': "http://thegraveyard.org/daelstorm/museekchat.html", \ 'tickers_enabled': 'yes', "rooms":{} }, "rooms": {"default_room":"museek"}} version = "0.3.1" def create_config(): #print "Creating Config" parser.read([config_file]) museekchat_config = file(config_file, 'w') for i in sections.keys(): if not parser.has_section(i): parser.add_section(i) for j in sections[i].keys(): if j not in ["sharedfiles","sharedfilesstreams","wordindex","fileindex","sharedmtimes"]: parser.set(i,j, sections[i][j]) else: parser.remove_option(i,j) parser.write(museekchat_config) museekchat_config.close() def read_config(): parser.read([config_file]) for i in parser.sections(): for j in parser.options(i): val = parser.get(i,j, raw = 1) if j in ['login','passw','interface', 'tickers_enabled', 'default_room'] : sections[i][j] = val #print j else: try: sections[i][j] = eval(val, {}) except: sections[i][j] = None #if i not in sections.keys(): # print "Bogus config section:",i #elif j not in sections[i].keys() and j != "filter": # print "Bogus config option",j,"section",i #for j, z in parser.items(i): # print i, j, z for j, z in sections.items(): print j, z#[0], z[1] #print "Config Loaded" def update_config(): museekchat_config = file(config_file, 'w') for i in sections.keys(): if not parser.has_section(i): parser.add_section(i) for j in sections[i].keys(): if j not in ["sharedfiles","sharedfilesstreams","wordindex","fileindex","sharedmtimes"]: parser.set(i,j, sections[i][j]) else: parser.remove_option(i,j) parser.write(museekchat_config) museekchat_config.close() def check_path(): if os.path.exists(config_dir): if os.path.exists(config_file) and os.stat(config_file)[6] > 0: #print "Config Exists" read_config() else: create_config() else: os.mkdir(config_dir, 0700) create_config() check_path() class editor: def __init__(self, win, escaped, textwin, chatlog, line = ""): self.win = win self.escaped = escaped self.h, self.w = win.getmaxyx() self.scroll = 0 self.textwin = textwin self.chatlog = chatlog self.line = line self.x = len(self.line) self.fixpos() self.escape = False self.y = None def process(self, c): pos = self.x + self.scroll #print '\n'+c if c == "KEY_LEFT" or c == chr(2): if self.escape: self.escaped(c, self.line) else: self.x -= 1 elif c == chr(93) or c == chr(91) or c == chr(34) or c == chr(35): if self.escape: self.escaped(c, self.line) else: self.line = self.line[:pos] + c + self.line[pos:] self.x += 1 elif c == "KEY_RIGHT" or c == chr(6): if self.escape: self.escaped(c, self.line) else: self.x += 1 elif c == "KEY_F(1)" or c == "KEY_F(2)" or c == "KEY_F(3)" or c == "KEY_F(4)" or c == "KEY_F(5)" or c == "KEY_F(6)" or c == "KEY_F(7)" or c == "KEY_F(8)" or c == "KEY_F(9)" or c == "KEY_F(10)" or c == "KEY_HOME": self.escaped(c, self.line) elif c == "KEY_UP": if not self.escape: self.escaped(c, self.line) elif c == "KEY_DOWN": if not self.escape: self.escaped(c, self.line) elif c == "KEY_IC": #if not self.escape: self.escaped(c, self.line) elif c == "KEY_DC" or c == chr(4): self.line = self.line[:pos] + self.line[pos+1:] elif c == chr(5): self.x = len(self.line) elif c == chr(1): self.x = self.scroll = 0 elif c == chr(10): self.escape = False return True elif c == chr(11): self.line = self.line[:pos] self.x = len(self.line) self.scroll = 0 elif c == chr(23): self.line = self.line[pos:] self.x = self.scroll = 0 elif c == chr(127) or c == "KEY_BACKSPACE" or c == chr(8): if pos > 0: self.line = self.line[:pos-1] + self.line[pos:] self.x -= 1 elif c == chr(27): self.escape = True return False elif len(c) == 1 and ord(c[0]) >= 32 and ord(c[0]) < 127: self.line = self.line[:pos] + c + self.line[pos:] self.x += 1 self.fixpos() self.escape = False return False def fixpos(self): self.x1 = self.x if self.x1 <= 0: self.x1 = 0 while self.scroll + self.x > len(self.line): self.x -= 1 while self.x >= self.w: self.scroll += 1 self.x -= 1 if self.x < 0: self.scroll += self.x self.x = 0 if self.scroll < 0: self.scroll = 0 self.win.erase() self.win.addstr(self.line[self.scroll:self.x1]) self.win.addstr(self.line[self.x1:self.x1+1], curses.A_STANDOUT) self.win.addstr(self.line[self.x1+1:]) self.win.refresh() def reset(self): self.x = self.scroll = 0 self.line = "" self.win.erase() self.win.refresh() class museekdchat(driver.Driver): def __init__(self): driver.Driver.__init__(self) self.rooms = {} self.joined = [] self.current = None # Non-Chat edit title self.username = None # Your username self.manualuser = None # Manual Download Username self.pm_user = None # Last Private Messaged user self.current_room = None # Current Chatroom # Temporary Logs self.log = ["\n"] * 1000 self.onlinestatuslog = ["\n"] * 5 self.usernamelog = ["\n"] * 5 self.uploadlog = ["\n"] * 5 self.downloadlog = ["\n"] * 5 self.searchwinlog = ["\n"] * 5 self.alertwinlog = ["\n"] * 5 self.chatlog = ["N\n"] * 2000 self.privatelog = ["\n"] * 2000 self.privatelog.append("\n/pm \n/msg ") self.privatelog = self.privatelog[-2000:] self.searchlog = ["\n"] * 5000 self.searchlog.append("\n/searchfor \n/download ") self.searchlog = self.searchlog[-5000:] self.browselog = ["\n"] * 5000 self.browselog.append("\n/buser \n/bdown \n/bsearch ") self.browselog = self.browselog[-5000:] self.infolog = ["\n"] * 5000 self.infolog.append("\n/userinfo \n/stat \n/ip ") self.infolog = self.infolog[-5000:] self.buddylog = ["\n"] * 1000 self.banlog = ["\n"] * 1000 self.ignorelog = ["\n"] * 1000 self.uptransferlog = ["\n"] * 1000 self.downtransferlog = ["\n"] * 1000 self.display_which_text = "chat" # default mode self.requested = None self.status_old = None self.startup = 1 self.size = None self.master_roomlist = {} self.pressed = 0 self.scrollup = 0 self.chatmode = "combined" # searches self.search_visible = 1 self.s_results = {} self.s_tickets = [] self.s_query = {} self.search_results = {} self.search_number = 0 # transfers self.browse_results = {} self.browse_number = 0 self.auto_buddy = 0 self.uploads_per_user = {} self.transfer_list = [] self.uploading = [] self.downloading = [] self.upload_number = 0 self.upload_results = {} self.download_number = 0 self.download_results = {} # config self.config = {} self.invalidpass = 0 # tickers self.ticker_room = None self.master_ticklist = {} # Help lists self.help_chat = "\n----[Chat Commands]---- \ \n/join \t/part \ \n/talk \ \n/chatmode (Experimental)\ \n/list (lists of users)\ \n/autojoin \t /noauto \ \n/roomlist (list of rooms)\ \n/pm (private message)\ \n/msg \t(send message to last user)\ \n/np\t(XMMS/BMP Now playing script)" self.help_ticker = "\n----[Ticker Commands]---- \ \n/tick \t(Choose room to set ticker)\ \n/settick \t(set ticker for last room)\ \n/lstick \t(Lists tickers in room)\ \n/ticker (Toggle tickers)" self.help_user = "\n----[User Commands]---- \ \n/buddy\t\t/unbuddy\ \n/autobuddy (buddy users you download from)\ \n/ban\t\t/unban \ \n/ignore\t\t/unignore\ \n/userinfo\t\t/ip \ \n/stat\t\ \n/away (Toggle your Online/Away Status)" self.help_mode = "\n----[Mode Commands]---- \ \n/chat\t\t[Chat Mode]\ \n/transfer\t[Transfer Mode]\ \n/info\t\t[Info Mode]\ \n/browse\t\t[Browse Mode]\ \n/private\t[Private Message Mode]\ \n/search\t\t[Search Mode]\ \n/buddylist\t\t[Buddy Mode]\ \n/banlist\t\t[Ban Mode]\ \n/ignorelist\t\t[Ignore Mode]\ " self.help_help = "\n----[Help Commands]---- \ \n/help\t\t(This Message)\ \n/help mode\t(Mode Commands)\ \n/help chat\t(Chatroom Commands)\ \n/help ticker\t(Ticker Commands)\ \n/help user\t(User Commands)\ \n/help search\t(Search Commands)\ \n/help download\t(Download Commands)\ \n/help keys\t(Special Keys)\ \n/quit" self.help_search = "\n----[Search/Browse Commands]----\ \n/search\t[Switch to Search Mode]\ \n/searchfor \ \n/download \ \n/browse\t[Switch to Browse Mode]\ \n/browseuser /buser \ \n/browsedown /bdown \ \n/browsesearch /bsearch " self.help_download = "\n----[Download Commands]----\ \n/user (sets download user)\ \n/downpath (download file from user)\ " self.help_keys ="\n------[Keys]------ \ \n(ESC|Alt) + Left or Right (Change Room)\ \n(ESC|Alt) + [ or ] (Change Room)\ \nUp\t(Scroll Up)\ \nDown\t(Clear/Scroll Down)\ \nF1->Chat\ \nF2->Private Messages\ \nF3->Transfers\ \nF4->Search\ \nF5->Info\ \nF6->Browse\ \nF7->Buddy List\ \nF8->Ban List\ \nF9->Ignore List" def build(self, stdscr, line = ""): self.stdscr = stdscr self.stdscr.clear() self.stdscr.refresh() self.h, self.w = self.stdscr.getmaxyx() if self.h >=15 and self.w >=45: self.inputwin = curses.newwin(3,self.w,self.h-3,0) self.inputwin.border() self.inputwin.refresh() self.editwin = curses.newwin(1, self.w-2, self.h-2, 1) if self.display_which_text == "chat": self.set_room(self.current_room) self.chat_mode() elif self.display_which_text == "private": self.private_mode() elif self.display_which_text == "browse": self.browse_mode() elif self.display_which_text == "transfer": self.transfer_mode() elif self.display_which_text == "info": self.info_mode() elif self.display_which_text == "buddy": self.buddy_mode() elif self.display_which_text == "ban": self.ban_mode() elif self.display_which_text == "ignore": self.ignore_mode() self.onlinestatus = curses.newwin(1, 8, 0, 0) self.onlinestatus.scrollok(1) self.onlinestatus.idlok(1) for i in range(1): self.onlinestatus.addstr(self.onlinestatuslog[-(1)]) self.onlinestatus.refresh() self.uploadwin = curses.newwin(1, 10, 0, 25) self.uploadwin.scrollok(1) self.uploadwin.idlok(1) for i in range(1): self.uploadwin.addstr(self.uploadlog[-(1)], curses.A_UNDERLINE) self.uploadwin.refresh() self.downloadwin = curses.newwin(1, 10, 0, 35) self.downloadwin.scrollok(1) self.downloadwin.idlok(1) for i in range(1): self.downloadwin.addstr(self.downloadlog[-(1)], curses.A_UNDERLINE) self.downloadwin.refresh() self.searchwin = curses.newwin(1, 15, 0, self.w-30) self.searchwin.scrollok(1) self.searchwin.idlok(1) for i in range(1): self.searchwin.addstr(self.searchwinlog[-(1)], curses.A_UNDERLINE) self.searchwin.refresh() self.alertwin = curses.newwin(1, 15, 0, self.w-15) self.alertwin.scrollok(1) self.alertwin.idlok(1) for i in range(1): self.alertwin.addstr(self.alertwinlog[-(1)], curses.color_pair(1) | curses.A_UNDERLINE) self.alertwin.refresh() self.usernamewin = curses.newwin(1, 16, 0, 9) self.usernamewin.scrollok(1) self.usernamewin.idlok(1) for i in range(1): self.usernamewin.addstr(self.usernamelog[-(1)]) self.usernamewin.refresh() self.edit = editor(self.editwin, self.escaped, self.textwin, self.chatlog, line) self.stdscr.nodelay(1) else: sys.exit("\nMuseek chat requires at least 45 columns and 15 rows") def connect(self):#, stdscr, line =""):#, host, password): keys = [] while 1: self.host = sections["connection"]["interface"] self.password = sections["connection"]["passw"] try: if self.invalidpass == 0: driver.Driver.connect(self, self.host, self.password, messages.EM_CHAT | messages.EM_USERINFO| messages.EM_PRIVATE| messages.EM_TRANSFERS | messages.EM_USERSHARES | messages.EM_CONFIG) #self.say(select.select([self.socket, sys.stdin], [], [self.socket], 1000)) break else: PASSWORD_INCORRECT() except Exception, e: self.say("Connection failed, try changing your interface or password") #self.say("WHY? "+str(e)) q = "42" while q == "42": sleep(0.1) try: c = self.stdscr.getkey(self.h-2, self.edit.x+1) keys.append(c) except: pass if not keys: d = 1000 else: d = 0 while keys: c, keys = keys[0], keys[1:] if self.edit.process(c): line = self.edit.line if line[:11] == "/interface " and line[11:] != "": self.info_mode() sections["connection"]["interface"] = line[11:] self.info_log("Museekd interface set to: " + line[11:]) elif line[:10] == "/password " and line[10:] != "": self.info_mode() sections["connection"]["passw"] = line[10:] self.info_log("New password set") elif line[:8] == "/connect": self.chat_mode() self.invalidpass = 0 q = "43" elif line[:8] == "/version": self.info_mode() self.info_log("\nMuseekchat version: %s" % version) elif line[:5] == "/help": self.info_mode() self.info_log("\nPre-Connection Configuration\ \n/connect\ \n/interface \ \n/password \ \n/save\ \n/help") elif line[:5] == "/save": update_config() self.info_mode() self.info_log("Config Saved") elif line[:5] == "/list": self.info_log(sections["connection"]["interface"]) self.info_log(sections["connection"]["passw"]) self.edit.reset() def process(self): # c = None keys = [] #self.say("Connected") while 1: try: c = self.stdscr.getkey(self.h-2, self.edit.x+1) keys.append(c) except: pass if not keys: d = 1000 else: d = 0 r, w, x = select.select([self.socket, sys.stdin], [], [self.socket], d) if self.socket in r: driver.Driver.process(self) if sys.stdin in r: try: c = self.stdscr.getkey(self.h-2, self.edit.x) keys.append(c) except Exception, e: pass while keys: c, keys = keys[0], keys[1:] if self.edit.process(c): line = self.edit.line if line[:1] == "/" and line[:4] != "/me ": if line == "/quit" or line == "/exit": return elif line[:5] == "/help": old = self.display_which_text self.display_which_text = "info" if line[5:] == " chat": self.info_log(self.help_chat) if line[5:] == " mode": self.info_log(self.help_mode) elif line[5:] == " user": self.info_log(self.help_user) elif line[5:] == " search": self.info_log(self.help_search) elif line[5:] == " ticker": self.info_log(self.help_search) elif line[5:] == " download": self.info_log(self.help_download) elif line[5:] == "": self.info_log(self.help_help) elif line[5:] == " keys": self.info_log(self.help_keys) self.display_which_text = old ''' Chatrooms ''' elif line[:6] == "/talk ": self.set_room(line[6:]) elif line[:6] == "/join ": self.send(messages.JoinRoom(line[6:])) elif line == "/part" and self.current_room: self.send(messages.LeaveRoom(self.current_room)) elif line[:6] == "/part ": self.send(messages.LeaveRoom(line[6:])) elif line[:10] == "/autojoin ": self.send(messages.ConfigSet("autojoin", line[10:], "")) self.say("Added %s to AutoJoin list" % line[5:]) elif line[:8] == "/noauto ": self.send(messages.ConfigRemove("autojoin", line[8:])) self.say("Removed %s from AutoJoin list" % line[7:]) elif line[:4] == "/pm ": if line[4:] != '': self.pm_user= line[4:] self.private_mode() self.set_edit_title("Send message to: " + self.pm_user) elif line[:5] == "/msg ": if self.pm_user != None: if line[5:] != '': message = line[5:] self.send(messages.PrivateMessage(self.pm_user, message)) self.private_log("PM to: [%s] %s" % (self.pm_user, message)) if self.alertwinlog[-(1)] == "\nNew PM": self.alert_status("\n ") else: self.private_log("Set a user to message with /pm!") elif line[:5] == "/away": if self.status_old == 0: self.send(messages.SetStatus(1)) elif self.status_old == 1: self.send(messages.SetStatus(0)) elif line[:3] == "/np": p = "/tmp/xmms-info" if os.path.exists(p): fsock = open(p) for i in range(3): s = fsock.readline()[8:-1] for i in range(10): m = fsock.readline()[7:-1] message ="Now %s: %s " % (s, m) fsock.close() self.send(messages.SayRoom(self.current_room, message)) else: self.say("WARNING: Your Media Player isn't running") ''' User Information ''' elif line[:10] == "/userinfo ": if line[10:] != '': self.send(messages.UserInfo(line[10:])) elif line[:4] == "/ip ": if line[4:] != '': self.requested = line[4:] self.send(messages.PeerAddress(line[4:])) elif line[:6] == "/stat ": if line[6:] != '': self.requested = line[6:] self.send(messages.PeerStats(line[6:])) ''' MODE SELECTIONS ''' elif line[:9] == "/chatmode": if self.chatmode == "combined": self.chatmode = "separate" self.info_log("Chatmode set to: Separate") elif self.chatmode == "separate": self.chatmode = "combined" self.info_log("Chatmode set to: Combined") elif line[:5] == "/chat": self.chat_mode() elif line[:8] == "/private" and line[8:] == '': self.private_mode() elif line[:7] == "/search" and line[7:] == '': self.browse_mode() elif line[:9] == "/transfer" and line[9:] == '': self.transfer_mode() elif line[:5] == "/info" and line[5:] == '': self.info_mode() elif line[:10] == "/buddylist" and line[10:] == '': self.buddy_mode() elif line[:8] == "/banlist" and line[8:] == '': self.ban_mode() elif line[:11] == "/ignorelist" and line[11:] == '': self.ignore_mode() ''' CONFIG ''' elif line[:5] == "/save": update_config() self.info_mode() self.info_log("Config Saved") if line[:11] == "/interface " and line[11:] != "": sections["connection"]["interface"] = line[11:] self.info_log("Museekd interface set to: " + line[11:]) elif line[:10] == "/password " and line[10:] != "": sections["connection"]["passw"] = line[10:] self.info_log("New password set") elif line[:8] == "/version": self.info_mode() self.info_log("\nMuseekchat version: %s" % version) elif line[:8] == "/connect": self.connect() # elif line[:10] == "/buddylist" and line[10:] == '': # self.buddylist() ''' Tickers ''' elif line[:6] == "/tick ": if line[6:] != '': #self.set_room("% Set ticker for: "+line[6:]+(" %")) self.ticker_room = line[6:] self.info_log("You picked room: " +self.ticker_room+" to set a ticker.") elif line[:7] == "/ticker": if sections["tickers"]["tickers_enabled"] == 'no': sections["tickers"]["tickers_enabled"] = 'yes' self.info_log("Tickers Enabled") elif sections["tickers"]["tickers_enabled"] == 'yes': sections["tickers"]["tickers_enabled"] = 'no' self.info_log("Tickers Disabled") elif line[:9] == "/tickroom": if line[9:] == '': self.ticker_room = self.current_room self.set_room("% Set ticker for: "+ self.current_room+(" %")) elif line[:9] == "/settick ": if self.ticker_room != None: message = line[9:] self.send(messages.RoomTickerSet(self.ticker_room, message)) sections["tickers"]["rooms"][self.ticker_room]=message self.info_log("You set your ticker in " +self.ticker_room+" to "+message) else: self.info_log("Choose a room with /tick, first.") ''' List tickers in current room or selected rooms ''' elif line[:9] == "/listtick": if line [9:] == '': woom = self.current_room else: woom = line[10:] alpha_list = SortedDict() for rooms in self.master_ticklist: alpha_list[rooms] = self.master_ticklist[rooms] for rooms, ticks in alpha_list.items(): if rooms == woom: if sections["tickers"]["tickers_enabled"] == 'yes': self.info_log("Tickers in room: "+str(rooms)) for names, ticker in ticks.items(): self.info_log("["+str(names)+'] '+str(ticker)) self.textwin.refresh() ''' User Management ''' elif line[:5] == "/ban ": self.send(messages.ConfigSet("banned", line[5:], "banned by museekchat")) self.info_log("Banned: %s" % line[5:]) elif line[:7] == "/unban ": if line[7:] != '': username = line[7:] if username in self.config["banned"].keys(): self.send(messages.ConfigRemove("banned", username)) #self.info_log("Unbanned: %s" % username) else: self.info_log("User not in ban list: %s" % username) elif line[:8] == "/ignore ": self.send(messages.ConfigSet("ignored", line[8:], "")) self.info_log("Ignored: %s" % line[8:]) elif line[:10] == "/unignore ": if line[10:] != '': username = line[10:] if username in self.config["ignored"].keys(): self.send(messages.ConfigRemove("ignored", username)) #self.info_log("Unignored: %s" % username) else: self.info_log("User not in ignore list: %s" % username) elif line[:7] == "/buddy ": self.send(messages.ConfigSet("buddies", line[7:], "buddied by museekchat")) #self.info_log("Buddied: %s" % line[7:]) elif line[:9] == "/unbuddy ": if line[9:] != '': username = line[9:] if username in self.config["buddies"].keys(): self.send(messages.ConfigRemove("buddies", username)) #self.info_log("UnBuddied: %s" % username) else: self.info_log("User not in buddy list: %s" % username) elif line[:11] == "/autobuddy": if self.auto_buddy == 1: self.auto_buddy = 0 self.info_log("\nAutoBuddy Disabled") if self.auto_buddy == 0: self.auto_buddy =1 self.info_log("\nAutoBuddy Enabled") ''' List Users in room ''' elif line[:5] == "/list": self.startup = 0 if line [5:6] == ' ': woom = line[6:] else: woom = self.current_room fiddlednames = [] for rooms, names in self.master_roomlist.items(): if rooms == woom: if len(names) == 1: for x in names: self.info_log("User in "+ woom +": "+ x) else: for x in names: fiddlednames.append(x +',') fiddlednames.sort() self.info_log("Users in "+ woom +": "+ (string.join(map(str, fiddlednames))[:-2])) self.textwin.refresh() ''' List Rooms whose number of users is greater than the number you input ''' elif line[:10] == "/roomlist ": if line[10:] != '': self.size = int(line[10:]) self.send(messages.RoomList()) ''' Manual Download ''' elif line[:6] == "/user ": if line[6:] != '': self.manualuser = line[6:] self.set_room("% % User: "+line[6:] + " (input download path) % %") elif line[:10] == "/downpath ": path = line[10:] if self.manualuser != None and self.manualuser != '' and path != '': user = self.user self.send(messages.DownloadFile(user, path)) self.info_log("Trying to Download: " + path+" from "+ user) ''' Search Globally for files & Download them ''' elif line[:11] == "/searchfor ": if line[11:] != '': query = line[11:] self.send(messages.Search(query)) self.search_log("Started search for: "+ query) elif line[:10] == "/download ": if line[10:] != '': try: searchnum = int(line[10:]) if self.search_results != {}: if self.search_results[searchnum] != None: user = self.search_results[searchnum][1] path = self.search_results[searchnum][5] self.send(messages.DownloadFile(user, path)) self.info_log("Try to Download: %s from %s" % (path, user)) if self.auto_buddy == 1: self.send(messages.ConfigSet("buddies", user, "buddied by museekchat")) self.info_log("Auto-Buddied: %s" % user) else: self.info_log("No such file") else: self.info_log("You need to search, first ;)") except: self.info_log("Enter an Integer") elif line[:10] == "/responses": if self.manualuser != None and self.manualuser != '': user = self.user self.info_log(str(self.s_results[self.user])) ''' Browse Shares & Download from them ''' elif line[:12] == "/browseuser " or line[:7] == "/buser ": l_input = None if line[:12] == "/browseuser " and line[12:] != '': l_input = line[12:] elif line[:7] == "/buser " and line[7:] != '': l_input = line[7:] if l_input != None: user = l_input self.send(messages.UserShares(user)) self.browse_log("\nStarted browsing: %s" % user) elif line[:14] == "/browsesearch " or line[:9] == "/bsearch ": l_input = None if line[:14] == "/browsesearch " and line[14:] != '': l_input = line[14:] elif line[:9] == "/bsearch " and line[9:] != '': l_input = line[9:] if l_input != None: search = re.compile('.*' +str(l_input) + '.*', re.DOTALL | re.I) self.browse_log("search compiled") for item, path in self.browse_results.items(): #self.browse_log(str(item) + path[0] + path[1]) if re.match( search, path[1]): self.browse_log("Found: [" + str(item) +'] ' +path[1]) #path = self.browse_results[browsenum][1] elif line[:12] == "/browsedown " or line[:7] == "/bdown ": l_input = None if line[:12] == "/browsedown " and line[12:] != '': l_input = line[12:] elif line[:7] == "/bdown " and line[7:] != '': l_input = line[7:] if l_input != None: try: browsenum = int(l_input) if self.browse_results != {}: if self.browse_results[browsenum] != None: user = self.browse_results[browsenum][0] path = self.browse_results[browsenum][1] self.send(messages.DownloadFile(user, path)) self.info_log("Try to Download: %s from %s" % (path, user)) if self.auto_buddy == 1: self.send(messages.ConfigSet("buddies", user, "buddied by museekchat")) self.info_log("Auto-Buddied: %s" % user) else: self.info_log("No such file") else: self.info_log("You need to browse, first ;)") except: self.info_log("Enter an Integer") elif line[:11] == "/hidesearch": self.search_visible = 0 self.info_log("Searches hidden") elif line[:11] == "/showsearch": self.search_visible = 1 self.info_log("Searches made visible") ''' Manage Transfers ''' elif line[:8] == "/abortd " or line[:11] == "/abortdown ": transfer = None if line[:8] == "/abortd " and line[8:] != '': transfer = int(line[8:]) elif line[:11] == "/abortdown " and line[11:] != '': transfer = int(line[11:]) if transfer != None: self.info_log("Pretending to abort download") #transfer #self.send(messages.TransferRemove(1, transfer, '')) elif line[:8] == "/abortu " or line[:9] == "/abortup ": transfer = None if line[:8] == "/abortu " and line[8:] != '': transfer = int(line[8:]) elif line[:9] == "/abortup " and line[9:] != '': transfer = int(line[9:]) if transfer != None: self.info_log("Pretending to abort upload") else: continue self.edit.reset() elif self.current and line: ''' Special Input Box for Downloading Manually ''' if self.current[:10] == '% % User: ': if self.manualuser != None and self.manualuser != '': user = self.user path = line self.send(messages.DownloadFile(user, path)) self.info_log("Trying to Download: " + path+" from "+ user) ''' Special Input Box for Private Messages ''' #elif self.current[:6] == '% PM: ': #self.send(messages.PrivateMessage(self.pm_user, line)) #self.private_log("PM to: [%s] %s" % (self.pm_user, line)) ''' Special Input Box for Setting Ticker ''' elif self.current[:12] == '% Set ticker': self.send(messages.RoomTickerSet(self.ticker_room, line)) ''' Normal Chat Message ''' else: if line != '': if self.display_which_text == "chat": if self.current_room: self.send(messages.SayRoom(self.current_room, line)) elif self.display_which_text == "private": if self.pm_user != None: self.send(messages.PrivateMessage(self.pm_user, line)) self.private_log("PM to: [%s] %s" % (self.pm_user, line)) else: self.pm_user = line self.set_edit_title("Send message to: " + self.pm_user) #self.private_log("Set a user to message with /pm!") elif self.display_which_text == "search": self.send(messages.Search(line)) elif self.display_which_text == "browse": self.send(messages.UserShares(line)) elif self.display_which_text == "info": self.info_log("Getting information about user: " +line) self.send(messages.UserInfo(line)) self.send(messages.PeerStats(line)) elif self.display_which_text == "buddy": self.send(messages.ConfigSet("buddies", line, "buddied by museekchat")) elif self.display_which_text == "ban": self.send(messages.ConfigSet("banned", line, "banned by museekchat")) elif self.display_which_text == "ignore": self.send(messages.ConfigSet("ignored", line, "ignored by museekchat")) self.edit.reset() # -- v Museek Messages v def cb_login_error(self, reason): if reason == "INVPASS": self.invalidpass = 1 self.say("couldn't log in: " + reason) self.connect() else: self.invalidpass = 0 self.say("couldn't log in: " + reason) def cb_login_ok(self): self.invalidpass = 0 self.say("Logging in...") def cb_server_state(self, state, username): self.username = username self.usernamelog.append("\n"+username[:15]) self.usernamelog = self.usernamelog[-5:] self.usernamewin.addstr(self.usernamelog[-1]) self.usernamewin.refresh() self.upload_status("0") self.download_status("0") self.search_status("\nResults: 0") if state: self.say("connected to soulseek, username: " + username) if sections["tickers"]["tickers_enabled"] == 'yes': self.say("Tickers enabled" + sections["tickers"]["tickers_enabled"]) else: self.say("Tickers disabled" + sections["tickers"]["tickers_enabled"]) else: self.say("not connected to soulseek") self.onlinestatuslog.append("\nOffline") self.onlinestatuslog = self.onlinestatuslog[-5:] self.onlinestatus.addstr(self.onlinestatuslog[-1]) self.onlinestatus.refresh() def cb_room_state(self, roomlist, joined, tickers): #default_ticker = "http://thegraveyard.org/daelstorm/" for room in joined: if len(joined[room]) > 1: u = "users" self.say("Joined room %s (%i %s)" % (room, len(joined[room]), u)) elif len(joined[room]) == 1: u = "user" self.say("Joined room %s (%i %s)" % (room, len(joined[room]), u)) elif len(joined[room]) == 0: self.say("Joined room %s (No users)" % room) self.rooms[room] = joined[room] self.roomlist = [] self.at_join = [] alpha_list = SortedDict() for users in joined[room]: self.at_join.append(users+',') self.roomlist.append(users) self.master_roomlist[room] = self.roomlist # tickers == (rooms, [(user1: message1), (user2: message2),] ) # a string and then a dictionary for rooms, ticks in tickers.items(): if rooms == room: self.master_ticklist[room] = ticks for rooms, ticks in alpha_list.items(): if rooms == room: self.master_ticklist[room] = alpha_list[room] # Send Default ticker to all rooms #self.send(messages.RoomTickerSet(room, default_ticker)) #SMALL ROOM USER PRINTOUT if len(joined[room]) <= 30: self.at_join.sort() x = string.join(map(str, self.at_join))[:-1] self.info_log("Users in "+ room +": "+ x) #TICKERS #for rooms, ticks in tickers.items(): #if 1 ==1: #self.say("Tickers enabled?: " + sections["tickers"]["tickers_enabled"] ) if sections["tickers"]["tickers_enabled"] == 'yes': for rooms, ticks in self.master_ticklist.items(): if rooms == room: self.info_log("Tickers in room: "+str(rooms)) for names, ticker in ticks.items(): self.info_log("["+str(names)+'] '+str(ticker)) self.textwin.refresh() self.joined = self.rooms.keys() if self.joined: if sections["rooms"]["default_room"] != None: if sections["rooms"]["default_room"] in self.joined: self.set_room(sections["rooms"]["default_room"]) else: self.set_room(self.joined[0]) self.say(":(") sleep(4) for rooms, tickers in sections["tickers"]["rooms"].items(): if rooms in self.joined: if self.username not in self.master_ticklist[rooms].keys(): self.send(messages.RoomTickerSet(rooms, tickers)) elif self.master_ticklist[rooms][self.username] != tickers: self.send(messages.RoomTickerSet(rooms, tickers)) #self.say(rooms +" "+ tickers ) def cb_room_list(self, roomlist): for name in roomlist: alpha_list[name] = roomlist[name] collapsed_roomlist = [] all_roomlist = [] if self.size == None: self.size = 50 for x, y in alpha_list.items(): if y >= self.size: collapsed_roomlist.append(x + ' ['+str(y)+'],') if y >= 1: all_roomlist.append(x) self.say("Rooms:" +(string.join(map(str, collapsed_roomlist))[:-1])) self.say("Rooms with more than %s users: %s" % (self.size, len(collapsed_roomlist))) self.say("Total Number of rooms: %s" % len(all_roomlist)) def cb_room_said(self, room, user, text): # chat text from combined rooms if self.chatmode == "combined": if text[:4] == "/me ": msg = "* %s %s" % (user, text[4:]) else: msg = "[%s] %s" % (user, text) if self.username in text: self.highlight_say("{%s} %s" % (room, msg)) if self.display_which_text != "chat": self.alert_status("Nick Mention") elif text[:4] == "/me ": self.me_say("{%s} %s" % (room, msg)) else: self.say("{%s} %s" % (room, msg)) if self.display_which_text != "chat": self.alert_status("New Chat") # chat text from current room elif self.chatmode == "separate": if text[:4] == "/me ": msg = "* %s %s" % (user, text[4:]) else: msg = "%s: %s" % (user, text) if room == self.current_room: self.say("[%s] %s" % (room, msg)) if self.display_which_text != "chat": self.alert_status("New Chat") else: s = "[%s] %s" % (room, msg) self.chatlog.append("M\n%s %s " % (time.strftime("%H:%M:%S"), s)) self.chatlog = self.chatlog[-2000:] if self.display_which_text != "chat": self.alert_status("New Chat") def cb_room_joined(self, room, users): if len(users) > 1: u = "users" self.say("Joined room %s (%i %s)" % (room, len(users), u)) elif len(users) == 1: u = "user" self.say("Joined room %s (%i %s)" % (room, len(users), u)) elif len(users) == 0: self.say("Joined room %s (No Users)" % (room)) self.rooms[room] = users; self.joined.append(room) if self.display_which_text == "chat": self.set_room(room) # Send Default ticker to all new rooms if sections["tickers"]["default_ticker"] != None: self.send(messages.RoomTickerSet(room, sections["tickers"]["default_ticker"])) def cb_room_left(self, room): self.say("Left room %s" % room) del self.rooms[room] if room == self.current_room: ix = self.joined.index(room) if ix > 0: ix -= 1 self.set_room(self.joined[ix]) self.joined.remove(room) if not self.joined: self.set_room(None) def cb_room_user_joined(self, room, user, data): if self.display_which_text == "chat": if self.chatmode == "combined": self.log_window("User %s joined room %s" % (user, room)) elif self.chatmode == "separate": if room == self.current_room: self.log_window("User %s joined room %s" % (user, room)) else: s ="User %s joined room %s" % (user, room) self.log.append("\n%s %s" % (time.strftime("%H:%M:%S"), s)) self.log = self.log[-1000:] else: s ="User %s joined room %s" % (user, room) self.log.append("\n%s %s" % (time.strftime("%H:%M:%S"), s)) self.log = self.log[-1000:] self.rooms[room][user] = data def cb_room_user_left(self, room, user): if self.display_which_text == "chat": if self.chatmode == "combined": self.log_window("User %s left room %s" % (user, room)) elif self.chatmode == "separate": if room == self.current_room: self.log_window("User %s left room %s" % (user, room)) else: s ="User %s left room %s" % (user, room) self.log.append("\n%s %s" % (time.strftime("%H:%M:%S"), s)) self.log = self.log[-1000:] else: s ="User %s left room %s" % (user, room) self.log.append("\n%s %s" % (time.strftime("%H:%M:%S"), s)) self.log = self.log[-1000:] del self.rooms[room][user] def cb_peer_status(self, user, status): if self.display_which_text == "chat": if status == 1: self.log_window("User %s went away" % user) elif status == 2: self.log_window("User %s came online" % user) elif status == 0: self.log_window("User %s is offline" % user) def cb_user_info(self, user, info, picture, uploads, queue, slotsfree): self.info_log( "\nGetting %s's userinfo ...\nUserinfo: %s \nQueue: %s \t\tUploads: %s \t\tFree Slots: %s\n" % (user, info, queue, uploads, slotsfree) ) if picture != '': r = file(str(user)+".image", 'w') print >> r, str(picture) r.close() self.info_log( "\nSaved UserImage as: "+ str(user)+".image") def cb_peer_address(self, user, ip, port): if self.requested == user: self.info_log("%s's IP: %s Port: %s" % (user, ip, str(port)) ) self.requested == None def cb_peer_stats(self, user, avgspeed, numdownloads, numfiles, numdirs): if user == self.requested: x = "Peer Stats for %s \nSpeed: %s \tDownloads: %s \nFiles: %s \tDirectories: %s" % (user, avgspeed, numdownloads, numfiles, numdirs) self.info_log(x) def cb_private_message(self, timestamp, user, message): self.private_log("PM from: [%s] %s" % ( user, message)) if self.display_which_text != "private": self.alert_status("New PM") def cb_server_status_set(self, status): if self.status_old != status: if status: stat = "Away" else: stat = "Online" self.onlinestatuslog.append("\n"+stat) self.onlinestatuslog = self.onlinestatuslog[-5:] self.onlinestatus.addstr(self.onlinestatuslog[-1]) self.onlinestatus.refresh() self.status_old = status def cb_room_ticker_set(self, room, user, message): for rooms, tickle in self.master_ticklist.items()[:]: if room == rooms: tickle[user] = message if self.display_which_text == "chat": if sections["tickers"]["tickers_enabled"] == 'yes': if message != '': self.log_window("%s set %s's ticker to %s" % (user, room, message)) def cb_search_ticket(self, query, ticket): #print query, ticket self.s_query[ticket] = query def cb_search_results(self, ticket, user, free, speed, queue, results): # search results if self.search_visible == 1: self.search_log("---------\nSearch: " +str(self.s_query[ticket]) + " Results from: User: "+ user ) for result in results: result_list = [] # Create Result List for future use # clear it next interation result_list = ticket, user, free, speed, queue, result[0], result[1], result[2], result[3] # Count Search Result self.search_number = self.search_number +1 # Send Num of Result to Search Window self.search_status(self.search_number) # Activate Number for Result self.search_results[self.search_number] = result_list # Display Search Result if self.search_visible == 1: path = result[0] size = str(result[1]/1024)+'KB' ftype = result[2] if ftype in ('mp3', 'ogg'): if result[3] != []: bitrate = result[3][0] length = result[3][1] minutes = int(length)/60 seconds = str(length - (60 * minutes)) if len(seconds) < 2: seconds = '0' + seconds else: bitrate = 'None' minutes = '00' seconds = '00' length = 0 else: bitrate = 'None' minutes = '00' seconds = '00' length = 0 self.search_log("Num: [" +str(self.search_number)+"] Path: "+ path+ "\nSize: "+str(size)+ " Type: "+ ftype + " Bitrate: "+ str(bitrate) + " Length: " + str(minutes)+":"+seconds) def cb_user_shares(self, user, shares): self.browse_log("Browsing: " + user) self.browse_results = {} self.browse_number = 0 for dirs, files in shares.items(): result_list = [] if files != {}: self.browse_log("------\nDIR: " + dirs) for file, stats in files.items(): self.browse_number = self.browse_number +1 size= str(stats[0]/1024)+"KB" ftype =stats[1] if ftype == '': ftype = "None" length = "00:00" bitrate = 'None' else: bitrate =str(stats[2][0]) if bitrate == '': bitrate = 'None' length =str(stats[2][1]) if length != '' and length != None: minutes = int(length)/60 seconds = str( int(length) - (60 * minutes)) if len(seconds) < 2: seconds = '0' + seconds length = str(minutes)+":"+str(seconds) else: length = "00:00" filename = dirs + "\\" + file result_list = user, filename # Activate Number for Result self.browse_results[self.browse_number] = result_list self.browse_log('['+str(self.browse_number)+'] ' + " Size: " + str(size) + " Type: " + ftype + " Length: " + length + " Bitrate: " + bitrate + "\nFile: " + file) self.browse_log("Finished browsing: " + user) def cb_transfer_state(self, downloads, uploads): #if downloads != '': # self.download_num = self.download_num + 1 if self.display_which_text == "transfer": self.textwin.clear() #self.uptransfer_log("UPLOADS:") for users in uploads: #current_transfer = (users[1], users[2], users[3]) user_path = (users[1], users[2]) status = users[3] #if status == 1: # self.transfer_log("UPLOADS:") # self.transfer_log("%s [%s] %s" % (states[status], users[1], users[2])) ''' username = current_transfer[0] path = current_transfer[1] status = current_transfer[2] path_exists = 0 user_exists = 0 if users[0] == 1: is_upload = 1 if username in self.uploads_per_user: user_exists = 1 if path in self.uploads_per_user: path_exists = 1 if status in (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14): if user_exists == 1: #print "adding transfer to current user" self.uploads_per_user[username] = self.uploads_per_user[username] + 1 self.transfer_list.append(current_transfer) elif user_exists == 0: #print "adding transfer to new user" self.uploads_per_user[username] = 1 self.transfer_list.append(current_transfer) ''' #if user_path not in self.upload_results.values(): for sa in self.upload_results.values(): if user_path not in sa[0]: self.upload_number = self.upload_number + 1 self.upload_results[self.upload_number] = [user_path, status] if status == 1: if user_path not in self.uploading: self.uploading.append(user_path) self.upload_status(str(len(self.uploading))) percent = str(100 * (int(users[5])) / int(users[6])) if len(percent) < 2: percent = '0' + percent self.uptransfer_log("(%s) [%s%%] [%s]\t%s" % (self.upload_number , percent, users[1], users[2])) #elif status != 1: # if user_path in self.uploading: # self.uploading.remove(user_path) # self.upload_status(str(len(self.uploading))) # delete self.upload_results[self.upload_number] = user_path #self.upload_status("5") for users in downloads: #current_transfer = (users[1], users[2], users[3]) user_path = (users[1], users[2]) status = users[3] for sa in self.download_results.values(): if user_path not in sa[0]:#self.download_results.values(): self.download_number = self.download_number + 1 self.download_results[self.download_number] = [user_path, status] if status == 1: #if status in (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14): if user_path not in self.downloading: self.downloading.append(user_path) self.download_status(str(len(self.downloading))) if int(users[6]) != 0: percent = str(100 * (int(users[5])) / int(users[6])) if len(percent) < 2: percent = '0' + percent else: percent = '00' self.downtransfer_log("(%s) [%s%%] [%s]\n%s" % (self.download_number, percent, users[1], users[2])) #elif status != 1: # if user_path in self.downloading: # self.downloading.remove(user_path) # self.download_status(str(len(self.downloading))) def cb_transfer_update(self, downloads, uploads): if self.display_which_text == "transfer": self.upwin.clear() self.downwin.clear() for users in uploads: #current_transfer = (users[1], users[2], users[3]) user_path = (users[1], users[2]) status = users[3] for sa in self.upload_results.values(): if user_path not in sa[0]: self.upload_number = self.upload_number + 1 self.upload_results[self.upload_number] = [user_path, status] #self.info_log('\n'+str(self.uploading)) if status ==1: #self.transfer_log(str(percent)+'%') #self.transfer_log(str(users[5]) + ' ' + str(users[6])) if user_path not in self.uploading: self.uploading.append(user_path) self.upload_status(str(len(self.uploading))) percent = str(100 * (int(users[5])) / int(users[6])) if len(percent) < 2: percent = '0' + percent self.uptransfer_log("[%s%%] [%s] %s" % (percent, users[1], users[2])) elif user_path in self.uploading: percent = str(100 * (int(users[5])) / int(users[6])) if len(percent) < 2: percent = '0' + percent self.uptransfer_log("[%s%%] [%s] %s" % (percent, users[1], users[2])) elif status != 1: #if user_path in self.uploading: # self.uploading.remove(user_path) # self.upload_status(str(len(self.uploading))) for n, u in self.upload_results.items(): if u in self.uploading: self.uploading.remove(u) self.upload_status(str(len(self.uploading))) self.info_log(str(len(self.uploading))) #delete self.upload_results[self.upload_number] = user_path for users in downloads: current_transfer = (users[1], users[2], users[3]) user_path = (users[1], users[2]) status = users[3] #if user_path not in self.download_results.values(): #self.download_number = self.download_number + 1 for sa in self.download_results.values(): if user_path not in sa[0]:#self.download_results.values(): self.download_number = self.download_number + 1 self.download_results[self.download_number] = [user_path, status] if status == 1: if user_path not in self.downloading: self.downloading.append(user_path) self.download_status(str(len(self.downloading))) percent = str(100 * (int(users[5])) / int(users[6])) if len(percent) < 2: percent = '0' + percent self.downtransfer_log("(%s) [%s%%] [%s]\n%s" % (self.download_number, percent, users[1], users[2])) elif user_path in self.downloading: percent = str(100 * (int(users[5])) / int(users[6])) if len(percent) < 2: percent = '0' + percent self.downtransfer_log("(%s) [%s%%] [%s]\n%s" % (self.download_number, percent, users[1], users[2])) elif status != 1: if user_path in self.downloading: self.downloading.remove(user_path) self.download_status(str(len(self.downloading))) #Add new keys to self.config def cb_config_set(self, domain, key, value): self.info_log("Added: "+key+" "+value + " to: " +domain) self.config[domain][key] = value #Delete keys from self.config def cb_config_remove(self, domain, key): self.info_log("Removed: "+key +" from: " +domain) del self.config[domain][key] #Copy config to self.config at connection def cb_config_state(self, config): self.config = config.copy() # -- ^ Museek Messages ^ # Change Room Title in edit window def set_room(self, r): self.current_room = r self.current = r if self.display_which_text == "chat": self.inputwin.border() if self.current_room: self.inputwin.addstr(0, 2, "[ "+self.current_room+" ]", curses.color_pair(5) | curses.A_BOLD) self.inputwin.refresh() self.editwin.refresh() def set_edit_title(self, r): self.current = r if self.display_which_text != "chat": self.inputwin.border() if self.current: self.inputwin.addstr(0, 2, "[ "+self.current+" ]", curses.color_pair(5) | curses.A_BOLD) self.inputwin.refresh() self.editwin.refresh() # Rebuild Buddylist from self.config def buddylist(self): self.buddylog = ["\n"] * 1000 for domain, key in self.config.items(): if domain == "buddies": for keyname, keyvalue in key.items(): banned = None ignored = None if len(keyname) <=5: tabs = "\t\t\t\t\t" elif len(keyname) >5 and len(keyname) <= 13: tabs = "\t\t\t\t" elif len(keyname) >13 and len(keyname) <= 21: tabs = "\t\t\t" elif len(keyname) >21 and len(keyname) <= 25: tabs = "\t\t" elif len(keyname) >25 : tabs = "\t\t" else: tabs = "\t\t" for bdomain, bkey in self.config.items()[:]: if bdomain == "banned": for bkeyname, bkeyvalue in bkey.items(): if keyname == bkeyname: banned = 1 elif bdomain == "ignored": for bkeyname, bkeyvalue in bkey.items(): if keyname == bkeyname: ignored = 1 if banned != None: self.buddy_log("B", "["+keyname[:30] +"]"+tabs+ keyvalue) elif ignored != None: self.buddy_log("I", "["+keyname[:30] +"]"+tabs+ keyvalue) else: self.buddy_log("N", "["+keyname[:30] +"]"+tabs+ keyvalue) self.buddy_log("N", str(len(key)) + " Buddies") # Rebuild Banlist from self.config def banlist(self): for domain, key in self.config.items(): if domain == "banned": for keyname, keyvalue in key.items(): if len(keyname) <=5: tabs = "\t\t\t\t\t" elif len(keyname) >5 and len(keyname) <= 13: tabs = "\t\t\t\t" elif len(keyname) >13 and len(keyname) <= 21: tabs = "\t\t\t" elif len(keyname) >21 and len(keyname) <= 25: tabs = "\t\t" elif len(keyname) >25 : tabs = "\t\t" else: tabs = "\t\t" self.ban_log("["+keyname[:30] +"]"+tabs+ keyvalue) self.ban_log(str(len(key)) + " Banned") # Rebuild Ignorelist from self.config def ignorelist(self): for domain, key in self.config.items(): if domain == "ignored": for keyname, keyvalue in key.items(): if len(keyname) <=5: tabs = "\t\t\t\t\t" elif len(keyname) >5 and len(keyname) <= 13: tabs = "\t\t\t\t" elif len(keyname) >13 and len(keyname) <= 21: tabs = "\t\t\t" elif len(keyname) >21 and len(keyname) <= 25: tabs = "\t\t" elif len(keyname) >25 : tabs = "\t\t" else: tabs = "\t\t" self.ignore_log("["+keyname[:30] +"]"+tabs+ keyvalue) self.ignore_log(str(len(key)) + " Ignored") # ---v KEYS v def escaped(self, key, line): if key == "KEY_UP": # SCROLLING UP # Redisplay chat log with one less line every time # the Up key is pressed self.scrollup = self.scrollup -1 self.pressed = self.pressed +1 self.textwin.clear() a_count = 0 color_added = None log_scroll = [] if self.display_which_text != "transfer": self.textwin.refresh() if self.display_which_text == "chat": self.window_height = -(self.h-12) else: self.window_height = -(self.h-6) if self.display_which_text == "chat": selected_log = self.chatlog elif self.display_which_text == "search": selected_log = self.searchlog elif self.display_which_text == "info": selected_log = self.infolog elif self.display_which_text == "transfer": selected_log = self.uptransferlog elif self.display_which_text == "private": selected_log = self.privatelog elif self.display_which_text == "browse": selected_log = self.browselog elif self.display_which_text == "buddy": selected_log = self.buddylog color_added = curses.color_pair(5) elif self.display_which_text == "ban": selected_log = self.banlog color_added = curses.color_pair(1) elif self.display_which_text == "ignore": selected_log = self.ignorelog color_added = curses.color_pair(2) for line in selected_log[self.window_height+self.scrollup:self.scrollup]: #a_count = a_count + 1 #if a_count <= self.scrollup: log_scroll.append(line) if self.display_which_text == "chat": for lines in log_scroll[self.window_height:]: if lines[0:1] == 'M': self.textwin.addstr(lines[1:], curses.color_pair(5)) elif lines[0:1] == 'R': self.textwin.addstr(lines[1:], curses.color_pair(1) | curses.A_BOLD) elif lines[0:1] == 'N': self.textwin.addstr(lines[1:]) else: self.textwin.addstr(lines[1:]) self.textwin.refresh() elif self.display_which_text == "transfer": for lines in log_scroll[self.h/2-11:]: self.upwin.addstr(lines) self.upwin.refresh() else: for lines in log_scroll[self.window_height:]: if color_added != None: if self.display_which_text == "buddy": if lines[0:1] == 'I': self.textwin.addstr(lines[1:], curses.color_pair(2) | curses.A_BOLD) elif lines[0:1] == 'B': self.textwin.addstr(lines[1:], curses.color_pair(1) | curses.A_BOLD) elif lines[0:1] == 'N': self.textwin.addstr(lines[1:]) else: self.textwin.addstr(lines) else: self.textwin.addstr(lines, color_added | curses.A_BOLD) else: self.textwin.addstr(lines) #self.textwin.addstr() self.textwin.refresh() elif key == "KEY_DOWN": #SCROLLING DOWN # Redisplay the entire log # go to the bottom self.pressed = 0 color_added = None if self.display_which_text == "chat": self.window_height = -(self.h-12) else: self.window_height = -(self.h-6) if self.display_which_text != "transfer": #self.textwin.refresh() self.textwin.clear() if self.display_which_text == "chat": self.scrollup = 2000 selected_log = self.chatlog elif self.display_which_text == "search": self.scrollup = 5000 selected_log = self.searchlog elif self.display_which_text == "info": self.scrollup = 5000 selected_log = self.infolog elif self.display_which_text == "transfer": self.scrollup = 1000 selected_log = self.uptransferlog elif self.display_which_text == "private": self.scrollup = 2000 selected_log = self.privatelog elif self.display_which_text == "browse": self.scrollup = 5000 selected_log = self.browselog elif self.display_which_text == "buddy": self.scrollup = 1000 selected_log = self.buddylog color_added = curses.color_pair(5) elif self.display_which_text == "ban": self.scrollup = 1000 selected_log = self.banlog color_added = curses.color_pair(1) elif self.display_which_text == "ignore": self.scrollup = 1000 selected_log = self.ignorelog color_added = curses.color_pair(2) if self.display_which_text == "chat": for lines in selected_log[self.window_height:]: if lines[0:1] == 'M': self.textwin.addstr(lines[1:], curses.color_pair(5)) elif lines[0:1] == 'R': self.textwin.addstr(lines[1:], curses.color_pair(1)) elif lines[0:1] == 'N': self.textwin.addstr(lines[1:]) else: self.textwin.addstr(lines[1:]) self.textwin.refresh() elif self.display_which_text == "transfer": for lines in selected_log:#[self.h/2-11:]: self.upwin.addstr(lines) self.upwin.refresh() else: for lines in selected_log[self.window_height:]: if color_added != None: if self.display_which_text == "buddy": if lines[0:1] == 'I': self.textwin.addstr(lines[1:], curses.color_pair(2) | curses.A_BOLD) elif lines[0:1] == 'B': self.textwin.addstr(lines[1:], curses.color_pair(1)| curses.A_BOLD) elif lines[0:1] == 'N': self.textwin.addstr(lines[1:]) else: self.textwin.addstr(lines) else: self.textwin.addstr(lines, color_added | curses.A_BOLD) else: self.textwin.addstr(lines) self.textwin.refresh() elif key == "KEY_F(1)" or c == chr(67): self.chat_mode() elif key == "KEY_F(2)" or c == chr(68): self.private_mode() elif key == "KEY_F(3)" or c == chr(69): self.transfer_mode() elif key == "KEY_F(4)": self.search_mode() elif key == "KEY_F(5)": self.info_mode() elif key == "KEY_F(6)": self.browse_mode() elif key == "KEY_F(7)": self.buddy_mode() elif key == "KEY_F(8)": self.ban_mode() elif key == "KEY_F(9)": self.ignore_mode() # AUTO-COMPLETION (NOT IMPLEMENTED) elif key == "KEY_IC": #for x in line: # self.info_log(' '+x) if len(line) >= 1: self.info_log(str(len(line))) if key == "KEY_LEFT" or key == chr(91) or key == chr(34) or key == "KEY_RIGHT" or key == chr(93) or key == chr(35): if not self.joined: return if self.display_which_text == "chat": if not self.current_room in self.joined: if key == "KEY_LEFT" or key == chr(91) or key == chr(34): ix = -1 elif key == "KEY_RIGHT" or key == chr(93) or key == chr(35): ix = 0 else: ix = self.joined.index(self.current_room) if key == "KEY_LEFT" or key == chr(91) or key == chr(34): ix -= 1 elif key == "KEY_RIGHT" or key == chr(93) or key == chr(35): ix += 1 if ix < 0: ix = -1 elif ix >= len(self.joined): ix = 0 if ix != None: self.set_room(self.joined[ix]) else: self.set_edit_title(self.current) # ---^ KEYS ^ # ---v MODES v def chat_mode(self): self.display_which_text = "chat" self.chatwin = curses.newwin(self.h - 10, self.w, 7, 0) self.chatwin.border() self.chatwin.addstr(0, 3, "[ Chat Rooms ]", curses.color_pair(5) | curses.A_BOLD) self.chatwin.refresh() self.textwin = self.chatwin.subwin(self.h-12,self.w-2,8,1) self.textwin.scrollok(1) self.textwin.idlok(1) self.scrollup = 2000 for lines in self.chatlog: if lines[0:1] == 'M': self.textwin.addstr(lines[1:], curses.color_pair(5)) elif lines[0:1] == 'R': self.textwin.addstr(lines[1:], curses.color_pair(1)) elif lines[0:1] == 'N': self.textwin.addstr(lines[1:]) else: self.textwin.addstr(lines[1:]) self.textwin.refresh() if self.alertwinlog[-(1)] in ( "\nNew Chat", "\nNick Mention"): self.alert_status("\n") self.borderlogwin = curses.newwin(6, self.w, 1, 0) self.borderlogwin.border() self.borderlogwin.addstr(0, 3, "[ Online Status Log ]", curses.color_pair(5) | curses.A_BOLD) self.borderlogwin.refresh() self.logwin = self.borderlogwin.subwin(4, self.w -2, 2, 1) self.logwin.scrollok(1) self.logwin.idlok(1) for i in range(4): self.logwin.addstr(self.log[-(4 - i)]) self.logwin.refresh() if self.current_room: self.set_room(self.current_room) # else: # self.set_room("Choose a user to Private Message") def private_mode(self): self.display_which_text = "private" self.chatwin = curses.newwin(self.h - 4, self.w, 1, 0) self.chatwin.border() self.chatwin.addstr(0, 3, "[ Private Chat ]", curses.color_pair(5) | curses.A_BOLD) self.chatwin.refresh() self.textwin = self.chatwin.subwin(self.h-6,self.w-2,2,1) self.textwin.scrollok(1) self.textwin.idlok(1) self.scrollup = 2000 for lines in self.privatelog: self.textwin.addstr(lines) self.textwin.refresh() if self.pm_user != None: self.set_edit_title("Send message to: " + self.pm_user) else: self.set_edit_title("Set a user to Private Message") if self.alertwinlog[-(1)] == "\nNew PM": self.alert_status(" ") def transfer_mode(self): self.display_which_text = "transfer" self.transwin = curses.newwin(self.h/2-2, self.w, 1, 0) self.transwin.border() self.transwin.addstr(0, 3, "[ Uploading Transfers ]", curses.color_pair(5) | curses.A_BOLD) self.transwin.refresh() self.upwin = self.transwin.subwin(self.h/2-4,self.w-2,2,1) self.upwin.scrollok(1) self.upwin.idlok(1) for lines in self.uptransferlog: self.upwin.addstr(lines) self.upwin.refresh() self.trans2win = curses.newwin(self.h/2-2, self.w, self.h/2 -1, 0) self.trans2win.border() self.trans2win.addstr(0, 3, "[ Downloading Transfers ]", curses.color_pair(5) | curses.A_BOLD) self.trans2win.refresh() self.downwin = self.trans2win.subwin(self.h/2-4,self.w-2,self.h/2,1) self.downwin.scrollok(1) self.downwin.idlok(1) self.scrollup = 1000 for lines in self.downtransferlog: self.downwin.addstr(lines) self.downwin.refresh() self.set_edit_title("Modify Transfers") def browse_mode(self): self.display_which_text = "browse" self.chatwin = curses.newwin(self.h - 4, self.w, 1, 0) self.chatwin.border() self.chatwin.addstr(0, 3, "[ Browse users ]", curses.color_pair(5) | curses.A_BOLD) self.chatwin.refresh() self.textwin = self.chatwin.subwin(self.h-6,self.w-2,2,1) self.textwin.scrollok(1) self.textwin.idlok(1) self.scrollup = 5000 for lines in self.browselog: self.textwin.addstr(lines) self.textwin.refresh() self.set_edit_title("Browse users' files") def search_mode(self): self.display_which_text = "search" self.chatwin = curses.newwin(self.h - 4, self.w, 1, 0) self.chatwin.border() self.chatwin.addstr(0, 3, "[ Search ]", curses.color_pair(5) | curses.A_BOLD) self.chatwin.refresh() self.textwin = self.chatwin.subwin(self.h-6,self.w-2,2,1) self.textwin.scrollok(1) self.textwin.idlok(1) self.scrollup = 5000 for lines in self.searchlog: self.textwin.addstr("\n"+lines) self.textwin.refresh() self.set_edit_title("Search for:") def info_mode(self): self.display_which_text = "info" self.chatwin = curses.newwin(self.h - 4, self.w, 1, 0) self.chatwin.border() self.chatwin.addstr(0, 3, "[ Info Mode ]", curses.color_pair(5) | curses.A_BOLD) self.chatwin.refresh() self.textwin = self.chatwin.subwin(self.h-6,self.w-2,2,1) self.textwin.scrollok(1) self.textwin.idlok(1) self.scrollup = 5000 for lines in self.infolog: self.textwin.addstr(lines) self.textwin.refresh() self.set_edit_title("Get info about user:") def buddy_mode(self): self.buddylist() self.display_which_text = "buddy" self.chatwin = curses.newwin(self.h - 4, self.w, 1, 0) self.chatwin.border() self.chatwin.addstr(0, 3, "[ Buddy Mode ]", curses.color_pair(5) | curses.A_BOLD) self.chatwin.refresh() self.textwin = self.chatwin.subwin(self.h-6,self.w-2,2,1) self.textwin.scrollok(1) self.textwin.idlok(1) self.scrollup = 1000 for lines in self.buddylog: if lines[0:1] == 'I': self.textwin.addstr(lines[1:], curses.color_pair(2) | curses.A_BOLD) elif lines[0:1] == 'B': self.textwin.addstr(lines[1:], curses.color_pair(1) | curses.A_BOLD) elif lines[0:1] == 'N': self.textwin.addstr(lines[1:]) else: self.textwin.addstr(lines[1:]) self.textwin.refresh() self.set_edit_title("Add Buddy") def ban_mode(self): self.banlist() self.display_which_text = "ban" self.chatwin = curses.newwin(self.h - 4, self.w, 1, 0) self.chatwin.border() self.chatwin.addstr(0, 3, "[ Ban Mode ]", curses.color_pair(5) | curses.A_BOLD) self.chatwin.refresh() self.textwin = self.chatwin.subwin(self.h-6,self.w-2,2,1) self.textwin.scrollok(1) self.textwin.idlok(1) self.scrollup = 1000 for lines in self.banlog: self.textwin.addstr(lines, curses.color_pair(1) | curses.A_BOLD ) self.textwin.refresh() self.set_edit_title("Add User to Ban List:") def ignore_mode(self): self.ignorelist() self.display_which_text = "ignore" self.chatwin = curses.newwin(self.h - 4, self.w, 1, 0) self.chatwin.border() self.chatwin.addstr(0, 3, "[ Ignore Mode ]", curses.color_pair(5) | curses.A_BOLD) self.chatwin.refresh() self.textwin = self.chatwin.subwin(self.h-6,self.w-2,2,1) self.textwin.scrollok(1) self.textwin.idlok(1) self.scrollup = 1000 for lines in self.ignorelog: self.textwin.addstr(lines, curses.color_pair(2) | curses.A_BOLD) self.textwin.refresh() self.set_edit_title("Add User to Ignore List") # ---^ MODES ^ # --- TEXT PLACEMENT v def say(self, s): self.chatlog.append("N\n%s %s " % (time.strftime("%H:%M:%S"), s)) self.chatlog = self.chatlog[-2000:] if self.display_which_text == "chat": self.textwin.addstr(self.chatlog[-1][1:]) self.textwin.refresh() def highlight_say(self, s): self.chatlog.append("R\n%s %s " % (time.strftime("%H:%M:%S"), s)) self.chatlog = self.chatlog[-2000:] if self.display_which_text == "chat": self.textwin.addstr(self.chatlog[-1][1:], curses.color_pair(1) | curses.A_BOLD) self.textwin.refresh() def me_say(self, s): self.chatlog.append("M\n%s %s " % (time.strftime("%H:%M:%S"), s)) self.chatlog = self.chatlog[-2000:] if self.display_which_text == "chat": self.textwin.addstr(self.chatlog[-1][1:], curses.color_pair(5) | curses.A_BOLD) self.textwin.refresh() def private_log(self, s): self.privatelog.append("\n%s %s " % (time.strftime("%H:%M:%S"), s)) self.privatelog = self.privatelog[-2000:] if self.display_which_text == "private": self.textwin.addstr(self.privatelog[-1]) self.textwin.refresh() def info_log(self, s): self.infolog.append("\n%s" % s) self.infolog = self.infolog[-5000:] if self.display_which_text == "info": self.textwin.addstr(self.infolog[-1], curses.A_BOLD) self.textwin.refresh() def buddy_log(self, S, s): self.buddylog.append("%s\n%s" % (S, s)) self.buddylog = self.buddylog[-1000:] if self.display_which_text == "buddy": self.textwin.addstr(self.buddylog[-1], curses.A_BOLD) self.textwin.refresh() def ban_log(self, s): self.banlog.append("\n%s" % s) self.banlog = self.banlog[-1000:] if self.display_which_text == "ban": self.textwin.addstr(self.banlog[-1], curses.A_BOLD) self.textwin.refresh() def ignore_log(self, s): self.ignorelog.append("\n%s" % s) self.ignorelog = self.ignorelog[-1000:] if self.display_which_text == "ignore": self.textwin.addstr(self.ignorelog[-1], curses.A_BOLD) self.textwin.refresh() def log_window(self, s): self.log.append("\n%s %s" % (time.strftime("%H:%M:%S"), s)) self.log = self.log[-1000:] self.logwin.addstr(self.log[-1]) self.logwin.refresh() def search_log(self, s): #self.searchlog.append("\n%s %s" % (time.strftime("%H:%M:%S"), s)) self.searchlog.append("\n%s" % s) self.searchlog = self.searchlog[-5000:] if self.display_which_text == "search": self.textwin.addstr("\n"+self.searchlog[-1]) self.textwin.refresh() def browse_log(self, s): self.browselog.append("\n%s" % s) self.browselog = self.browselog[-5000:] if self.display_which_text == "browse": self.textwin.addstr(self.browselog[-1]) self.textwin.refresh() def uptransfer_log(self, s): self.uptransferlog.append("\n%s" % s) self.uptransferlog = self.uptransferlog[-1000:] if self.display_which_text == "transfer": self.upwin.addstr(self.uptransferlog[-1]) self.upwin.refresh() def downtransfer_log(self, s): self.downtransferlog.append("\n%s" % s) self.downtransferlog = self.downtransferlog[-1000:] if self.display_which_text == "transfer": self.downwin.addstr(self.downtransferlog[-1]) self.downwin.refresh() def search_status(self, s): self.searchwinlog.append("\nResults: %s" % s) self.searchwinlog = self.searchwinlog[-1:] self.searchwin.addstr(self.searchwinlog[-1], curses.A_UNDERLINE) self.searchwin.refresh() def upload_status(self, s): self.uploadlog.append("\nUp: %s" % s) self.uploadlog = self.uploadlog[-5:] self.uploadwin.addstr(self.uploadlog[-1], curses.A_UNDERLINE) self.uploadwin.refresh() def download_status(self, s): self.downloadlog.append("\nDown: %s" % s) self.downloadlog = self.downloadlog[-5:] self.downloadwin.addstr(self.downloadlog[-1], curses.A_UNDERLINE) self.downloadwin.refresh() def alert_status(self, s): self.alertwinlog.append("\n%s" % s) self.alertwinlog = self.alertwinlog[-5:] self.alertwin.addstr(self.alertwinlog[-(1)], curses.color_pair(1) | curses.A_UNDERLINE) self.alertwin.refresh() # --- TEXT PLACEMENT ^ # if len(sys.argv) != 3: # print "Syntax: museekchat host:port password" # print "or: museekchat /path/to/socket password" # sys.exit(-1) print "Museekchat version: %s" % version c = museekdchat() line = "" try: while 1: stdscr = curses.initscr() curses.start_color() if curses.has_colors() == True: try: curses.use_default_colors() curses.can_change_color() curses.init_pair(1, curses.COLOR_RED, -1) curses.init_pair(2, curses.COLOR_YELLOW, -1) curses.init_pair(3, curses.COLOR_CYAN, -1) curses.init_pair(4, curses.COLOR_BLUE, -1) curses.init_pair(5, curses.COLOR_GREEN, -1) curses.init_pair(6, curses.COLOR_BLACK, curses.COLOR_WHITE) except AttributeError: curses.init_pair(1, curses.COLOR_RED, 0) curses.init_pair(2, curses.COLOR_YELLOW, 0) curses.init_pair(3, curses.COLOR_CYAN, 0) curses.init_pair(4, curses.COLOR_BLUE, 0) curses.init_pair(5, curses.COLOR_GREEN, 0) curses.init_pair(6, curses.COLOR_BLACK, curses.COLOR_WHITE) #curses.curs_set(0) curses.noecho() curses.cbreak() stdscr.keypad(1) c.build(stdscr, line) #sleep(5) if c.socket is None: c.connect()#host, passwordsys.argv[1], sys.argv[2]) #c.connect(sys.argv[1], sys.argv[2]) try: c.process() except select.error: line = c.edit.line curses.endwin() continue break except Exception, e: curses.nocbreak() stdscr.keypad(0) curses.echo() curses.endwin() print e sys.exit() curses.nocbreak() stdscr.keypad(0) curses.echo() curses.endwin()