From 25222d31f5c5f4095798147c2818d0512a845fc6 Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Sat, 26 Oct 2013 18:44:41 +0400 Subject: [PATCH 01/83] move some global members of tc_client to BuddyList TOR_CONFIG tor_pid tor_proc tor_timer startPortableTor() stopPortableTor() startPortableTorTimer() onPortableTorTimer() --- torchat/src/dlg_settings.py | 3 +- torchat/src/tc_client.py | 230 ++++++++++++++++++------------------ torchat/src/torchat.py | 3 +- 3 files changed, 117 insertions(+), 119 deletions(-) diff --git a/torchat/src/dlg_settings.py b/torchat/src/dlg_settings.py index 422f7a6b..65d08824 100644 --- a/torchat/src/dlg_settings.py +++ b/torchat/src/dlg_settings.py @@ -17,7 +17,6 @@ import wx import dlg import config -import tc_client import translations lang = translations.lang_en @@ -71,7 +70,7 @@ def __init__(self, main_window): dlg.Text(self.p1, lang.DSET_NET_LISTEN_PORT, ("client", "listen_port")) self.p1.fit() - portable = (tc_client.TOR_CONFIG == "tor_portable") + portable = (self.mw.buddy_list.tor_config == "tor_portable") if portable: self.s_tor.setEnabled(False) else: diff --git a/torchat/src/tc_client.py b/torchat/src/tc_client.py index bbcf63ea..8d6c834f 100644 --- a/torchat/src/tc_client.py +++ b/torchat/src/tc_client.py @@ -30,9 +30,10 @@ import hashlib import config import version +from functools import partial TORCHAT_PORT = 11009 #do NOT change this. -TOR_CONFIG = "tor" #the name of the active section in the .ini file + STATUS_OFFLINE = 0 STATUS_HANDSHAKE = 1 STATUS_ONLINE = 2 @@ -50,9 +51,6 @@ tb = config.tb # the traceback function has moved to config tb1 = config.tb1 -tor_pid = None -tor_proc = None -tor_timer = None def splitLine(text): @@ -541,8 +539,12 @@ class BuddyList(object): def __init__(self, callback, socket=None): print "(1) initializing buddy list" self.gui = callback + self.tor_pid = None + self.tor_proc = None + self.tor_timer = None + self.tor_config = 'tor' - startPortableTor() + self.startPortableTor() self.file_sender = {} self.file_receiver = {} @@ -739,11 +741,115 @@ def onConnected(self, connection): connection.buddy.onOutConnectionSuccess() def stopClient(self): - stopPortableTor() + self.stopPortableTor() for buddy in self.list + self.incoming_buddies: buddy.disconnect() self.listener.close() #FIXME: does this really work? + def startPortableTor(self): + print "(1) entering function startPortableTor()" + old_dir = os.getcwd() + print "(1) current working directory is %s" % os.getcwd() + try: + print "(1) changing working directory" + os.chdir(config.getDataDir()) + os.chdir("Tor") + print "(1) current working directory is %s" % os.getcwd() + # completely remove all cache files from the previous run + #for root, dirs, files in os.walk("tor_data", topdown=False): + # for name in files: + # os.remove(os.path.join(root, name)) + # for name in dirs: + # os.rmdir(os.path.join(root, name)) + + # now start tor with the supplied config file + print "(1) trying to start Tor" + + if config.isWindows(): + if os.path.exists("tor.exe"): + #start the process without opening a console window + startupinfo = subprocess.STARTUPINFO() + startupinfo.dwFlags |= 1 #STARTF_USESHOWWINDOW + self.tor_proc = subprocess.Popen("tor.exe -f torrc.txt".split(), startupinfo=startupinfo) + self.tor_pid = self.tor_proc.pid + else: + print "(1) there is no portable tor.exe" + self.tor_pid = False + else: + if os.path.exists("tor.sh"): + #let our shell script start a tor instance + os.system("chmod 0700 tor.sh") + self.tor_proc = subprocess.Popen("./tor.sh".split()) + self.tor_pid = self.tor_proc.pid + print "(1) tor pid is %i" % self.tor_pid + else: + print "(1) there is no Tor starter script (tor.sh)" + self.tor_pid = False + + if self.tor_pid: + #tor = subprocess.Popen("tor.exe -f torrc.txt".split(), creationflags=0x08000000) + print "(1) successfully started Tor (pid=%i)" % self.tor_pid + + # we now assume the existence of our hostname file + # it WILL be created after the first start + # if not, something must be totally wrong. + cnt = 0 + found = False + while cnt <= 20: + try: + print "(1) trying to read hostname file (try %i of 20)" % (cnt + 1) + f = open(os.path.join("hidden_service", "hostname"), "r") + hostname = f.read().rstrip()[:-6] + print "(1) found hostname: %s" % hostname + print "(1) writing own_hostname to torchat.ini" + config.set("client", "own_hostname", hostname) + found = True + f.close() + break + except: + # we wait 20 seconds for the file to appear + time.sleep(1) + cnt += 1 + + if not found: + print "(0) very strange: portable tor started but hostname could not be read" + print "(0) will use section [tor] and not [tor_portable]" + else: + #in portable mode we run Tor on some non-standard ports: + #so we switch to the other set of config-options + print "(1) switching active config section from [tor] to [tor_portable]" + self.tor_config = "tor_portable" + #start the timer that will periodically check that tor is still running + self.startPortableTorTimer() + else: + print "(1) no own Tor instance. Settings in [tor] will be used" + + except: + print "(1) an error occured while starting tor, see traceback:" + tb(1) + + print "(1) changing working directory back to %s" % old_dir + os.chdir(old_dir) + print "(1) current working directory is %s" % os.getcwd() + + def stopPortableTor(self): + if not self.tor_pid: + return + else: + print "(1) tor has pid %i, terminating." % self.tor_pid + config.killProcess(self.tor_pid) + + def startPortableTorTimer(self): + self.tor_timer = threading.Timer(10, + partial(BuddyList.onPortableTorTimer, self)) + self.tor_timer.start() + + def onPortableTorTimer(self): + if self.tor_proc.poll() != None: + print "(1) Tor stopped running. Will restart it now" + self.startPortableTor() + else: + self.startPortableTorTimer() class FileSender(threading.Thread): def __init__(self, buddy, file_name, callback): @@ -1897,8 +2003,8 @@ def run(self): try: self.socket = socks.socksocket() self.socket.setproxy(socks.PROXY_TYPE_SOCKS4, - config.get(TOR_CONFIG, "tor_server"), - config.getint(TOR_CONFIG, "tor_server_socks_port")) + config.get(self.bl.tor_config, "tor_server"), + config.getint(self.bl.tor_config, "tor_server_socks_port")) print "(2) trying to connect '%s'" % self.address self.socket.connect((str(self.address), TORCHAT_PORT)) print "(2) connected to %s" % self.address @@ -2019,111 +2125,3 @@ def tryBindPort(interface, port): tb() return False -def startPortableTor(): - print "(1) entering function startPortableTor()" - global tor_in, tor_out - global TOR_CONFIG - global tor_pid - global tor_proc - old_dir = os.getcwd() - print "(1) current working directory is %s" % os.getcwd() - try: - print "(1) changing working directory" - os.chdir(config.getDataDir()) - os.chdir("Tor") - print "(1) current working directory is %s" % os.getcwd() - # completely remove all cache files from the previous run - #for root, dirs, files in os.walk("tor_data", topdown=False): - # for name in files: - # os.remove(os.path.join(root, name)) - # for name in dirs: - # os.rmdir(os.path.join(root, name)) - - # now start tor with the supplied config file - print "(1) trying to start Tor" - - if config.isWindows(): - if os.path.exists("tor.exe"): - #start the process without opening a console window - startupinfo = subprocess.STARTUPINFO() - startupinfo.dwFlags |= 1 #STARTF_USESHOWWINDOW - tor_proc = subprocess.Popen("tor.exe -f torrc.txt".split(), startupinfo=startupinfo) - tor_pid = tor_proc.pid - else: - print "(1) there is no portable tor.exe" - tor_pid = False - else: - if os.path.exists("tor.sh"): - #let our shell script start a tor instance - os.system("chmod 0700 tor.sh") - tor_proc = subprocess.Popen("./tor.sh".split()) - tor_pid = tor_proc.pid - print "(1) tor pid is %i" % tor_pid - else: - print "(1) there is no Tor starter script (tor.sh)" - tor_pid = False - - if tor_pid: - #tor = subprocess.Popen("tor.exe -f torrc.txt".split(), creationflags=0x08000000) - print "(1) successfully started Tor (pid=%i)" % tor_pid - - # we now assume the existence of our hostname file - # it WILL be created after the first start - # if not, something must be totally wrong. - cnt = 0 - found = False - while cnt <= 20: - try: - print "(1) trying to read hostname file (try %i of 20)" % (cnt + 1) - f = open(os.path.join("hidden_service", "hostname"), "r") - hostname = f.read().rstrip()[:-6] - print "(1) found hostname: %s" % hostname - print "(1) writing own_hostname to torchat.ini" - config.set("client", "own_hostname", hostname) - found = True - f.close() - break - except: - # we wait 20 seconds for the file to appear - time.sleep(1) - cnt += 1 - - if not found: - print "(0) very strange: portable tor started but hostname could not be read" - print "(0) will use section [tor] and not [tor_portable]" - else: - #in portable mode we run Tor on some non-standard ports: - #so we switch to the other set of config-options - print "(1) switching active config section from [tor] to [tor_portable]" - TOR_CONFIG = "tor_portable" - #start the timer that will periodically check that tor is still running - startPortableTorTimer() - else: - print "(1) no own Tor instance. Settings in [tor] will be used" - - except: - print "(1) an error occured while starting tor, see traceback:" - tb(1) - - print "(1) changing working directory back to %s" % old_dir - os.chdir(old_dir) - print "(1) current working directory is %s" % os.getcwd() - -def stopPortableTor(): - if not tor_pid: - return - else: - print "(1) tor has pid %i, terminating." % tor_pid - config.killProcess(tor_pid) - -def startPortableTorTimer(): - global tor_timer - tor_timer = threading.Timer(10, onPortableTorTimer) - tor_timer.start() - -def onPortableTorTimer(): - if tor_proc.poll() != None: - print "(1) Tor stopped running. Will restart it now" - startPortableTor() - else: - startPortableTorTimer() diff --git a/torchat/src/torchat.py b/torchat/src/torchat.py index d25e984b..bd85b0f1 100755 --- a/torchat/src/torchat.py +++ b/torchat/src/torchat.py @@ -44,6 +44,7 @@ import tc_gui def main(): + global app print "(2) wxPython version %s" % wx.version() #create the mandatory wx application object if config.isMac(): @@ -77,4 +78,4 @@ def main(): try: main() except KeyboardInterrupt: - tc_client.stopPortableTor() + app.mw.buddy_list.stopPortableTor() From b4117bf01199d6fd4320e056a9d85fc74fec3036 Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Fri, 1 Nov 2013 02:29:57 +0400 Subject: [PATCH 02/83] listen on random free port if port=0 * tor_portable.socks_port * client.port --- torchat/src/Tor/tor.sh | 2 +- torchat/src/config.py | 4 ++-- torchat/src/tc_client.py | 51 +++++++++++++++++++++++++++++++--------- 3 files changed, 43 insertions(+), 14 deletions(-) diff --git a/torchat/src/Tor/tor.sh b/torchat/src/Tor/tor.sh index 5ea33413..5b8dba01 100755 --- a/torchat/src/Tor/tor.sh +++ b/torchat/src/Tor/tor.sh @@ -3,5 +3,5 @@ trap 'kill -15 `cat tor.pid`' 15 export PATH=$PATH:/usr/sbin -tor -f torrc.txt --PidFile tor.pid & +tor -f torrc.temp.txt --PidFile tor.pid & wait diff --git a/torchat/src/config.py b/torchat/src/config.py index be158105..f39456df 100644 --- a/torchat/src/config.py +++ b/torchat/src/config.py @@ -33,11 +33,11 @@ def isWindows(): ("tor", "tor_server_socks_port") : 9050, ("tor", "tor_server_control_port") : 9051, ("tor_portable", "tor_server") : "127.0.0.1", - ("tor_portable", "tor_server_socks_port") : 11109, + ("tor_portable", "tor_server_socks_port") : 0, ("tor_portable", "tor_server_control_port") : 11119, ("client", "own_hostname") : "0000000000000000", ("client", "listen_interface") : "127.0.0.1", - ("client", "listen_port") : 11009, + ("client", "listen_port") : 0, ("logging", "log_file") : "", ("logging", "log_level") : 0, ("files", "temp_files_in_data_dir") : 1, diff --git a/torchat/src/tc_client.py b/torchat/src/tc_client.py index 8d6c834f..e8ca2bf7 100644 --- a/torchat/src/tc_client.py +++ b/torchat/src/tc_client.py @@ -30,6 +30,7 @@ import hashlib import config import version +import re from functools import partial TORCHAT_PORT = 11009 #do NOT change this. @@ -542,9 +543,11 @@ def __init__(self, callback, socket=None): self.tor_pid = None self.tor_proc = None self.tor_timer = None - self.tor_config = 'tor' - - self.startPortableTor() + self.tor_config = 'tor_portable' + self.tor_server_socks_port = config.getint(self.tor_config, "tor_server_socks_port") + if self.tor_server_socks_port == 0: + interface = config.get("client", "listen_interface") + self.tor_server_socks_port = getFreePort(interface) self.file_sender = {} self.file_receiver = {} @@ -557,6 +560,8 @@ def __init__(self, callback, socket=None): self.listener = Listener(self, socket) self.own_status = STATUS_ONLINE + self.startPortableTor() + filename = os.path.join(config.getDataDir(), "buddy-list.txt") #create empty buddy list file if it does not already exist @@ -755,6 +760,16 @@ def startPortableTor(self): os.chdir(config.getDataDir()) os.chdir("Tor") print "(1) current working directory is %s" % os.getcwd() + torrc = open('torrc.txt').read() + torrc = re.sub(r'SocksPort \d+', 'SocksPort %i' % + self.tor_server_socks_port, torrc) + print("(0) " +torrc) + torrc = re.sub(r'HiddenServicePort %i 127.0.0.1:\d+' % TORCHAT_PORT, + 'HiddenServicePort %i 127.0.0.1:%i' % + (TORCHAT_PORT, self.listener.port), torrc) + temp_torrc = open('torrc.temp.txt', 'w') + temp_torrc.write(torrc) + temp_torrc.close() # completely remove all cache files from the previous run #for root, dirs, files in os.walk("tor_data", topdown=False): # for name in files: @@ -770,7 +785,7 @@ def startPortableTor(self): #start the process without opening a console window startupinfo = subprocess.STARTUPINFO() startupinfo.dwFlags |= 1 #STARTF_USESHOWWINDOW - self.tor_proc = subprocess.Popen("tor.exe -f torrc.txt".split(), startupinfo=startupinfo) + self.tor_proc = subprocess.Popen("tor.exe -f torrc.temp.txt".split(), startupinfo=startupinfo) self.tor_pid = self.tor_proc.pid else: print "(1) there is no portable tor.exe" @@ -2004,7 +2019,7 @@ def run(self): self.socket = socks.socksocket() self.socket.setproxy(socks.PROXY_TYPE_SOCKS4, config.get(self.bl.tor_config, "tor_server"), - config.getint(self.bl.tor_config, "tor_server_socks_port")) + self.bl.tor_server_socks_port) print "(2) trying to connect '%s'" % self.address self.socket.connect((str(self.address), TORCHAT_PORT)) print "(2) connected to %s" % self.address @@ -2061,16 +2076,17 @@ def __init__(self, buddy_list, socket=None): self.buddy_list = buddy_list self.conns = [] self.socket = socket + self.port = config.getint("client", "listen_port") + if not self.socket: + interface = config.get("client", "listen_interface") + self.socket = tryBindPort(interface, self.port) + self.port = self.socket.getsockname()[1] + self.socket.listen(5) self.start() self.startTimer() def run(self): self.running = True - if not self.socket: - interface = config.get("client", "listen_interface") - port = config.getint("client", "listen_port") - self.socket = tryBindPort(interface, port) - self.socket.listen(5) while self.running: try: conn, address = self.socket.accept() @@ -2088,7 +2104,7 @@ def close(self): try: print "(2) closing listening socket %s:%s" \ % (config.get("client", "listen_interface"), - config.get("client", "listen_port")) + self.port) self.socket.close() print "(2) success" except: @@ -2125,3 +2141,16 @@ def tryBindPort(interface, port): tb() return False +def getFreePort(interface): + try: + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + s.bind((interface, 0)) + s.listen(5) + port = s.getsockname()[1] + s.close() + return port + except: + tb() + return False + From 916e7f9d0fc210052bf04e9012db6999bbf1ee08 Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Fri, 1 Nov 2013 03:47:00 +0400 Subject: [PATCH 03/83] check existance of wx_ctrl in Control.setEnabled fix attribute error in subclass Check --- torchat/src/dlg.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/torchat/src/dlg.py b/torchat/src/dlg.py index 1abfb92e..37dda055 100644 --- a/torchat/src/dlg.py +++ b/torchat/src/dlg.py @@ -92,7 +92,8 @@ def getDefault(self, default): return default def setEnabled(self, enabled): - self.wx_label.Enable(enabled) + if hasattr(self, 'wx_label'): + self.wx_label.Enable(enabled) if self.wx_ctrl: self.wx_ctrl.Enable(enabled) From 18db80ad99adbe897f7c51b61e843d924810832c Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Fri, 1 Nov 2013 03:48:35 +0400 Subject: [PATCH 04/83] add config item turning account into chat room additional config item is to prefer nicks over torchat ids --- torchat/src/config.py | 2 ++ torchat/src/dlg_settings.py | 7 +++++++ torchat/src/tc_client.py | 9 +++++++++ torchat/src/translations/lang_en.py | 2 ++ 4 files changed, 20 insertions(+) diff --git a/torchat/src/config.py b/torchat/src/config.py index f39456df..dda7fd97 100644 --- a/torchat/src/config.py +++ b/torchat/src/config.py @@ -66,6 +66,8 @@ def isWindows(): ("branding", "support_name") : "Bernd, author of TorChat", ("profile", "name") : "", ("profile", "text") : "", + ("conference", "enabled") : 0, + ("conference", "prefer_nicks") : 1, } LOCALE_ENC = locale.getpreferredencoding() diff --git a/torchat/src/dlg_settings.py b/torchat/src/dlg_settings.py index 65d08824..5a43787f 100644 --- a/torchat/src/dlg_settings.py +++ b/torchat/src/dlg_settings.py @@ -95,12 +95,19 @@ def __init__(self, main_window): self.dir_tmp = dlg.Dir(self.p3, lang.DSET_MISC_TEMP_CUSTOM_DIR, ("files", "temp_files_custom_dir")) self.dir_tmp.setEnabled(not self.chk_tmp.getValue()) self.chk_tmp.wx_ctrl.Bind(wx.EVT_CHECKBOX, self.onChkTmp) + self.conference_enabled = dlg.Check(self.p3, lang.DSET_MISC_CONFERENCE_ENABLED, ("conference", "enabled")) + self.conference_prefer_nicks = dlg.Check(self.p3, lang.DSET_MISC_CONFERENCE_PREFER_NICKS, ("conference", "prefer_nicks")) + self.onConferenceEnabled(None) + self.conference_enabled.wx_ctrl.Bind(wx.EVT_CHECKBOX, self.onConferenceEnabled) #4 fit the sizers outer_sizer.Fit(self) def onChkTmp(self, evt): self.dir_tmp.setEnabled(not self.chk_tmp.getValue()) + + def onConferenceEnabled(self, evt): + self.conference_prefer_nicks.setEnabled(self.conference_enabled.getValue()) def onCancel(self, evt): evt.Skip() #let the frame now process the Cancel event diff --git a/torchat/src/tc_client.py b/torchat/src/tc_client.py index e8ca2bf7..aa0ba249 100644 --- a/torchat/src/tc_client.py +++ b/torchat/src/tc_client.py @@ -1711,6 +1711,15 @@ def execute(self): if self.buddy: if self.buddy in self.bl.list: self.buddy.onChatMessage(self.text) + if config.get("conference", "enabled"): + nick = self.buddy.address + if int(config.get("conference", "prefer_nicks")) == 1 \ + and self.buddy.profile_name: + nick = self.buddy.profile_name + resent_message = '%s: %s' % (nick, self.text) + for buddy in self.bl.list: + if buddy != self.buddy and buddy != self.bl.own_buddy: + buddy.sendChatMessage(resent_message) else: print "(1) ***** protocol violation reply to %s" % self.buddy.address msg = "This is an automatic reply." diff --git a/torchat/src/translations/lang_en.py b/torchat/src/translations/lang_en.py index fec2dfe5..a4f807c2 100644 --- a/torchat/src/translations/lang_en.py +++ b/torchat/src/translations/lang_en.py @@ -137,6 +137,8 @@ DSET_MISC_TITLE = u"Misc" DSET_MISC_TEMP_IN_DATA = u"Store temporary files inside data directory" DSET_MISC_TEMP_CUSTOM_DIR = u"Temporary directory (leave empty for OS-default)" +DSET_MISC_CONFERENCE_ENABLED = u"Turn this account into a conference" +DSET_MISC_CONFERENCE_PREFER_NICKS = u"Show torchat nick if available instead of id to conference members" #notices in the chat window (those in square brackets) NOTICE_DELAYED_MSG_WAITING = u"delayed messages waiting to be sent" From 26d3c7feb5bb7dd18656ee0ed058d21799dfba8c Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Fri, 1 Nov 2013 03:50:07 +0400 Subject: [PATCH 05/83] remove debugging print --- torchat/src/tc_client.py | 1 - 1 file changed, 1 deletion(-) diff --git a/torchat/src/tc_client.py b/torchat/src/tc_client.py index aa0ba249..e5b5df5b 100644 --- a/torchat/src/tc_client.py +++ b/torchat/src/tc_client.py @@ -763,7 +763,6 @@ def startPortableTor(self): torrc = open('torrc.txt').read() torrc = re.sub(r'SocksPort \d+', 'SocksPort %i' % self.tor_server_socks_port, torrc) - print("(0) " +torrc) torrc = re.sub(r'HiddenServicePort %i 127.0.0.1:\d+' % TORCHAT_PORT, 'HiddenServicePort %i 127.0.0.1:%i' % (TORCHAT_PORT, self.listener.port), torrc) From 082426d648b12653eb8b17ef1474b21018b47efd Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Fri, 1 Nov 2013 03:52:05 +0400 Subject: [PATCH 06/83] do not allow nicks looking like addresses in chats move isValidAddress to global tc_client's namespace --- torchat/src/tc_client.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/torchat/src/tc_client.py b/torchat/src/tc_client.py index e5b5df5b..44351a1c 100644 --- a/torchat/src/tc_client.py +++ b/torchat/src/tc_client.py @@ -1361,6 +1361,13 @@ def execute(self): if self.buddy: print "(2) %s says it can't handle '%s'" % (self.buddy.address, self.offending_command) +def isValidAddress(address): + if len(address) <> 16: + return False + for c in address: + if not c in "234567abcdefghijklmnopqrstuvwxyz": # base32 + return False + return True class ProtocolMsg_ping(ProtocolMsg): """a ping message consists of sender address and a random string (cookie). @@ -1370,12 +1377,7 @@ def parse(self): self.address, self.answer = splitLine(self.blob) def isValidAddress(self): - if len(self.address) <> 16: - return False - for c in self.address: - if not c in "234567abcdefghijklmnopqrstuvwxyz": # base32 - return False - return True + return isValidAddress(self.address) def execute(self): print "(2) <<< PING %s" % self.address @@ -1713,7 +1715,8 @@ def execute(self): if config.get("conference", "enabled"): nick = self.buddy.address if int(config.get("conference", "prefer_nicks")) == 1 \ - and self.buddy.profile_name: + and self.buddy.profile_name \ + and not isValidAddress(self.buddy.profile_name): nick = self.buddy.profile_name resent_message = '%s: %s' % (nick, self.text) for buddy in self.bl.list: From 2cf5320c1cd67298c00cda26099e6bb61b761183 Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Fri, 1 Nov 2013 04:15:08 +0400 Subject: [PATCH 07/83] reported user agent can be changed in preferences allow UTF-8 in user agent --- torchat/src/config.py | 3 +++ torchat/src/dlg_settings.py | 10 ++++++++++ torchat/src/tc_client.py | 10 ++++++---- torchat/src/translations/lang_en.py | 2 ++ 4 files changed, 21 insertions(+), 4 deletions(-) diff --git a/torchat/src/config.py b/torchat/src/config.py index dda7fd97..55f32f6d 100644 --- a/torchat/src/config.py +++ b/torchat/src/config.py @@ -21,6 +21,7 @@ import inspect import translations import shutil +import version def isWindows(): return sys.platform.startswith("win") @@ -38,6 +39,8 @@ def isWindows(): ("client", "own_hostname") : "0000000000000000", ("client", "listen_interface") : "127.0.0.1", ("client", "listen_port") : 0, + ("client", "reported_client") : version.NAME, + ("client", "reported_version") : version.VERSION, ("logging", "log_file") : "", ("logging", "log_level") : 0, ("files", "temp_files_in_data_dir") : 1, diff --git a/torchat/src/dlg_settings.py b/torchat/src/dlg_settings.py index 5a43787f..bebf033c 100644 --- a/torchat/src/dlg_settings.py +++ b/torchat/src/dlg_settings.py @@ -99,6 +99,8 @@ def __init__(self, main_window): self.conference_prefer_nicks = dlg.Check(self.p3, lang.DSET_MISC_CONFERENCE_PREFER_NICKS, ("conference", "prefer_nicks")) self.onConferenceEnabled(None) self.conference_enabled.wx_ctrl.Bind(wx.EVT_CHECKBOX, self.onConferenceEnabled) + self.client = dlg.Text(self.p3, lang.DSET_MISC_REPORT_CLIENT, ("client", "reported_client")) + self.version = dlg.Text(self.p3, lang.DSET_MISC_REPORT_VERSION, ("client", "reported_version")) #4 fit the sizers outer_sizer.Fit(self) @@ -113,10 +115,18 @@ def onCancel(self, evt): evt.Skip() #let the frame now process the Cancel event def onOk(self, evt): + need_send_ua = False + if self.client.getValue() != config.get("client", "reported_client"): + need_send_ua = True + if self.version.getValue() != config.get("client", "reported_version"): + need_send_ua = True self.p1.saveAllData() self.p2.saveAllData() self.p3.saveAllData() if self.lang.getValue() != self.lang_old: config.importLanguage() evt.Skip() #let the frame now process the Ok event + if need_send_ua: + for buddy in self.mw.buddy_list.list: + buddy.sendVersion() diff --git a/torchat/src/tc_client.py b/torchat/src/tc_client.py index 44351a1c..76eaecf5 100644 --- a/torchat/src/tc_client.py +++ b/torchat/src/tc_client.py @@ -510,9 +510,11 @@ def sendRemoveMe(self): def sendVersion(self): if self.isAlreadyPonged(): - msg = ProtocolMsg_client(self, version.NAME) + client = config.get("client", "reported_client").encode('UTF-8') + msg = ProtocolMsg_client(self, client) msg.send() - msg = ProtocolMsg_version(self, version.VERSION) + version = config.get("client", "reported_version").encode('UTF-8') + msg = ProtocolMsg_version(self, version) msg.send() else: print "(2) not connected, not sending version to %s" % self.address @@ -1548,7 +1550,7 @@ def execute(self): class ProtocolMsg_client(ProtocolMsg): """transmits the name of the client software. Usually sent after the pong""" def parse(self): - self.client = self.blob + self.client = self.blob.decode('UTF-8') def execute(self): if self.buddy: @@ -1559,7 +1561,7 @@ def execute(self): class ProtocolMsg_version(ProtocolMsg): """transmits the version number of the client software. Usually sent after the 'client' message""" def parse(self): - self.version = self.blob + self.version = self.blob.decode('UTF-8') def execute(self): if self.buddy: diff --git a/torchat/src/translations/lang_en.py b/torchat/src/translations/lang_en.py index a4f807c2..684ba987 100644 --- a/torchat/src/translations/lang_en.py +++ b/torchat/src/translations/lang_en.py @@ -139,6 +139,8 @@ DSET_MISC_TEMP_CUSTOM_DIR = u"Temporary directory (leave empty for OS-default)" DSET_MISC_CONFERENCE_ENABLED = u"Turn this account into a conference" DSET_MISC_CONFERENCE_PREFER_NICKS = u"Show torchat nick if available instead of id to conference members" +DSET_MISC_REPORT_CLIENT = u"Client reported" +DSET_MISC_REPORT_VERSION = u"Version reported" #notices in the chat window (those in square brackets) NOTICE_DELAYED_MSG_WAITING = u"delayed messages waiting to be sent" From 3909f2e284e130f970a050a4c73ea7676bd7f84f Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Sat, 2 Nov 2013 03:31:28 +0400 Subject: [PATCH 08/83] plugin loading --- torchat/src/config.py | 1 + torchat/src/torchat.py | 47 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/torchat/src/config.py b/torchat/src/config.py index 55f32f6d..dcb256de 100644 --- a/torchat/src/config.py +++ b/torchat/src/config.py @@ -71,6 +71,7 @@ def isWindows(): ("profile", "text") : "", ("conference", "enabled") : 0, ("conference", "prefer_nicks") : 1, + ("plugin", "enabled_plugins") : '', } LOCALE_ENC = locale.getpreferredencoding() diff --git a/torchat/src/torchat.py b/torchat/src/torchat.py index bd85b0f1..e1989758 100755 --- a/torchat/src/torchat.py +++ b/torchat/src/torchat.py @@ -40,9 +40,54 @@ import wx import os +import sys +import imp + import tc_client import tc_gui - +import dlg +import dlg_settings + +CORE_MODULES = ('config', 'dlg', 'dlg_settings', 'tc_client', 'tc_gui') +# translations are not restored, plugins should not change old members +ORIG_MEMBERS = {} +for module in CORE_MODULES: + ORIG_MEMBERS[module] = dict(vars(__import__(module))) + +def restore_orig_members(): + for module in CORE_MODULES: + vars(__import__(module)).update(ORIG_MEMBERS[module]) + +plugins = {} # shortname to python modules +# plugin module must have NAME member (string, long name) +# plugin module must have load(torchat) member, torchat is this module +# plugin module should have NAME_ with translation of name +# plugins are searched in app's plugins/ dir and in getDataDir()/plugins +# plugins with same name in getDataDir()/plugins win over app's plugins/ dir +plugins_parent_dirs = [] +try: + plugins_parent_dirs.append(os.path.dirname(__file__)) +except: + pass +plugins_parent_dirs.append(config.getDataDir()) +for plugins_parent_dir in plugins_parent_dirs: + plugins_dir = os.path.join(plugins_parent_dir, 'plugins') + if os.path.exists(plugins_dir): + for plugin_file in os.listdir(plugins_dir): + if plugin_file.endswith('.py'): + plugin_name = plugin_file[:-3] + plugin_path = os.path.join(plugins_dir, plugin_file) + plugins[plugin_name] = imp.load_source(plugin_name, plugin_path) + +def reload_plugins(): + restore_orig_members() + enabled_plugins = config.get('plugin', 'enabled_plugins').split(',') + for plugin_name in enabled_plugins: + if plugin_name in plugins: + plugins[plugin_name].load(sys.modules[__name__]) + +reload_plugins() + def main(): global app print "(2) wxPython version %s" % wx.version() From dd692f675f2b0e3a012646b77851d15ff2d2d265 Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Sat, 2 Nov 2013 03:32:23 +0400 Subject: [PATCH 09/83] test plugin sendin 'test' instead of any message --- torchat/src/plugins/test_plugin.py | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 torchat/src/plugins/test_plugin.py diff --git a/torchat/src/plugins/test_plugin.py b/torchat/src/plugins/test_plugin.py new file mode 100644 index 00000000..b2ae94c9 --- /dev/null +++ b/torchat/src/plugins/test_plugin.py @@ -0,0 +1,9 @@ +NAME = u'Test plugin, replaces all sent messages with "test"' +def load(torchat): + sendChatMessage = torchat.tc_client.Buddy.sendChatMessage + class Buddy(torchat.tc_client.Buddy): + def sendChatMessage(self, text): + text = u'test' + sendChatMessage(self, text) + torchat.tc_client.Buddy = Buddy + From 29fea2c01773e59aadef2a6129c42964af0d9aa4 Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Sat, 2 Nov 2013 04:38:17 +0400 Subject: [PATCH 10/83] change translation rules for plugins --- torchat/src/plugins/test_plugin.py | 5 ++++- torchat/src/torchat.py | 34 ++++++++++++++++++++---------- 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/torchat/src/plugins/test_plugin.py b/torchat/src/plugins/test_plugin.py index b2ae94c9..6a7f706f 100644 --- a/torchat/src/plugins/test_plugin.py +++ b/torchat/src/plugins/test_plugin.py @@ -1,4 +1,7 @@ -NAME = u'Test plugin, replaces all sent messages with "test"' +# -*- coding: UTF-8 -*- + +NAME_en = u'Test plugin, replaces all sent messages with "test"' +NAME_ru = u'Проверочный плагин, заменяет все отправляемые сообщения на "test"' def load(torchat): sendChatMessage = torchat.tc_client.Buddy.sendChatMessage class Buddy(torchat.tc_client.Buddy): diff --git a/torchat/src/torchat.py b/torchat/src/torchat.py index e1989758..83b4ff67 100755 --- a/torchat/src/torchat.py +++ b/torchat/src/torchat.py @@ -39,6 +39,7 @@ print "(2) wxversion screwed up, this is harmless, ignoring it." import wx +import re import os import sys import imp @@ -47,6 +48,7 @@ import tc_gui import dlg import dlg_settings +import translations CORE_MODULES = ('config', 'dlg', 'dlg_settings', 'tc_client', 'tc_gui') # translations are not restored, plugins should not change old members @@ -58,18 +60,23 @@ def restore_orig_members(): for module in CORE_MODULES: vars(__import__(module)).update(ORIG_MEMBERS[module]) -plugins = {} # shortname to python modules -# plugin module must have NAME member (string, long name) +# xx to module +TRANSLATIONS = {} +translations_dir = os.path.join(os.path.dirname(__file__), 'translations') +for translation_file in os.listdir(translations_dir): + if re.match(r'^lang_..\.py$', translation_file): + translation_name = translation_file[:-3] + xx = translation_name[-2:] + translation_path = os.path.join(translations_dir, translation_file) + TRANSLATIONS[xx] = getattr(translations, translation_name) + +PLUGINS = {} # shortname to python modules +# plugin module must have NAME_en member (string, long name) # plugin module must have load(torchat) member, torchat is this module # plugin module should have NAME_ with translation of name # plugins are searched in app's plugins/ dir and in getDataDir()/plugins # plugins with same name in getDataDir()/plugins win over app's plugins/ dir -plugins_parent_dirs = [] -try: - plugins_parent_dirs.append(os.path.dirname(__file__)) -except: - pass -plugins_parent_dirs.append(config.getDataDir()) +plugins_parent_dirs = [os.path.dirname(__file__), config.getDataDir()] for plugins_parent_dir in plugins_parent_dirs: plugins_dir = os.path.join(plugins_parent_dir, 'plugins') if os.path.exists(plugins_dir): @@ -77,14 +84,19 @@ def restore_orig_members(): if plugin_file.endswith('.py'): plugin_name = plugin_file[:-3] plugin_path = os.path.join(plugins_dir, plugin_file) - plugins[plugin_name] = imp.load_source(plugin_name, plugin_path) + PLUGINS[plugin_name] = imp.load_source(plugin_name, plugin_path) + for xx in TRANSLATIONS: + if hasattr(PLUGINS[plugin_name], 'NAME_' + xx): + dscr = getattr(PLUGINS[plugin_name], 'NAME_' + xx) + var_name = 'DSET_PLUGIN_' + plugin_name.upper() + setattr(TRANSLATIONS[xx], var_name, dscr) def reload_plugins(): restore_orig_members() enabled_plugins = config.get('plugin', 'enabled_plugins').split(',') for plugin_name in enabled_plugins: - if plugin_name in plugins: - plugins[plugin_name].load(sys.modules[__name__]) + if plugin_name in PLUGINS: + PLUGINS[plugin_name].load(sys.modules[__name__]) reload_plugins() From e49f2b3f46a1452a464a3029a17e7131cd6fc8f3 Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Sat, 2 Nov 2013 04:39:02 +0400 Subject: [PATCH 11/83] add Plugins tab to Preferences, a plugin is Check --- torchat/src/dlg_settings.py | 20 +++++++++++++++++++- torchat/src/translations/lang_en.py | 1 + 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/torchat/src/dlg_settings.py b/torchat/src/dlg_settings.py index bebf033c..d9127deb 100644 --- a/torchat/src/dlg_settings.py +++ b/torchat/src/dlg_settings.py @@ -101,7 +101,18 @@ def __init__(self, main_window): self.conference_enabled.wx_ctrl.Bind(wx.EVT_CHECKBOX, self.onConferenceEnabled) self.client = dlg.Text(self.p3, lang.DSET_MISC_REPORT_CLIENT, ("client", "reported_client")) self.version = dlg.Text(self.p3, lang.DSET_MISC_REPORT_VERSION, ("client", "reported_version")) - + + #3.4 plugins + self.p4 = dlg.Panel(self.notebook) + self.notebook.AddPage(self.p4, lang.DSET_PLUGINS_TITLE) + self.plugins = {} + enabled_plugins = set(config.get('plugin', 'enabled_plugins').split(',')) + import torchat + for plugin_name in torchat.PLUGINS: + plugin_dscr = getattr(lang, 'DSET_PLUGIN_' + plugin_name.upper()) + enabled = int(bool(plugin_name in enabled_plugins)) + self.plugins[plugin_name] = dlg.Check(self.p4, plugin_dscr, enabled) + #4 fit the sizers outer_sizer.Fit(self) @@ -123,6 +134,13 @@ def onOk(self, evt): self.p1.saveAllData() self.p2.saveAllData() self.p3.saveAllData() + #enabled_plugins = set(config.get('plugin', 'enabled_plugins').split(',')) + import torchat + enabled_plugins = [] + for plugin_name in torchat.PLUGINS: + if self.plugins[plugin_name].getValue(): + enabled_plugins.append(plugin_name) + config.set('plugin', 'enabled_plugins', ','.join(enabled_plugins)) if self.lang.getValue() != self.lang_old: config.importLanguage() evt.Skip() #let the frame now process the Ok event diff --git a/torchat/src/translations/lang_en.py b/torchat/src/translations/lang_en.py index 684ba987..b7707c5c 100644 --- a/torchat/src/translations/lang_en.py +++ b/torchat/src/translations/lang_en.py @@ -141,6 +141,7 @@ DSET_MISC_CONFERENCE_PREFER_NICKS = u"Show torchat nick if available instead of id to conference members" DSET_MISC_REPORT_CLIENT = u"Client reported" DSET_MISC_REPORT_VERSION = u"Version reported" +DSET_PLUGINS_TITLE = u"Plugins" #notices in the chat window (those in square brackets) NOTICE_DELAYED_MSG_WAITING = u"delayed messages waiting to be sent" From b2f549a53b7523b3c05e74172011ba819186cc12 Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Sat, 2 Nov 2013 04:48:33 +0400 Subject: [PATCH 12/83] plugins replace methods not classes --- torchat/src/plugins/test_plugin.py | 11 +++++------ torchat/src/torchat.py | 22 ++++------------------ 2 files changed, 9 insertions(+), 24 deletions(-) diff --git a/torchat/src/plugins/test_plugin.py b/torchat/src/plugins/test_plugin.py index 6a7f706f..6d32e2d8 100644 --- a/torchat/src/plugins/test_plugin.py +++ b/torchat/src/plugins/test_plugin.py @@ -3,10 +3,9 @@ NAME_en = u'Test plugin, replaces all sent messages with "test"' NAME_ru = u'Проверочный плагин, заменяет все отправляемые сообщения на "test"' def load(torchat): - sendChatMessage = torchat.tc_client.Buddy.sendChatMessage - class Buddy(torchat.tc_client.Buddy): - def sendChatMessage(self, text): - text = u'test' - sendChatMessage(self, text) - torchat.tc_client.Buddy = Buddy + _sendChatMessage = torchat.tc_client.Buddy.sendChatMessage + def sendChatMessage(self, text): + text = u'test' + _sendChatMessage(self, text) + torchat.tc_client.Buddy.sendChatMessage = sendChatMessage diff --git a/torchat/src/torchat.py b/torchat/src/torchat.py index 83b4ff67..e470c7c8 100755 --- a/torchat/src/torchat.py +++ b/torchat/src/torchat.py @@ -50,16 +50,6 @@ import dlg_settings import translations -CORE_MODULES = ('config', 'dlg', 'dlg_settings', 'tc_client', 'tc_gui') -# translations are not restored, plugins should not change old members -ORIG_MEMBERS = {} -for module in CORE_MODULES: - ORIG_MEMBERS[module] = dict(vars(__import__(module))) - -def restore_orig_members(): - for module in CORE_MODULES: - vars(__import__(module)).update(ORIG_MEMBERS[module]) - # xx to module TRANSLATIONS = {} translations_dir = os.path.join(os.path.dirname(__file__), 'translations') @@ -91,14 +81,10 @@ def restore_orig_members(): var_name = 'DSET_PLUGIN_' + plugin_name.upper() setattr(TRANSLATIONS[xx], var_name, dscr) -def reload_plugins(): - restore_orig_members() - enabled_plugins = config.get('plugin', 'enabled_plugins').split(',') - for plugin_name in enabled_plugins: - if plugin_name in PLUGINS: - PLUGINS[plugin_name].load(sys.modules[__name__]) - -reload_plugins() +enabled_plugins = config.get('plugin', 'enabled_plugins').split(',') +for plugin_name in enabled_plugins: + if plugin_name in PLUGINS: + PLUGINS[plugin_name].load(sys.modules[__name__]) def main(): global app From 78528dbaf4b7f1a821c3620bfd3000768f1529af Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Sat, 2 Nov 2013 18:22:15 +0400 Subject: [PATCH 13/83] load plugins from torchat.main plugins must not be loaded each time torchat module is imported --- torchat/src/torchat.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/torchat/src/torchat.py b/torchat/src/torchat.py index e470c7c8..600fd3ad 100755 --- a/torchat/src/torchat.py +++ b/torchat/src/torchat.py @@ -81,12 +81,14 @@ var_name = 'DSET_PLUGIN_' + plugin_name.upper() setattr(TRANSLATIONS[xx], var_name, dscr) -enabled_plugins = config.get('plugin', 'enabled_plugins').split(',') -for plugin_name in enabled_plugins: - if plugin_name in PLUGINS: - PLUGINS[plugin_name].load(sys.modules[__name__]) +def load_plugins(): + enabled_plugins = config.get('plugin', 'enabled_plugins').split(',') + for plugin_name in enabled_plugins: + if plugin_name in PLUGINS: + PLUGINS[plugin_name].load(sys.modules[__name__]) def main(): + load_plugins() global app print "(2) wxPython version %s" % wx.version() #create the mandatory wx application object From 52f26159db7866f5b604a4052bd6f4dc788c2a88 Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Sat, 2 Nov 2013 18:23:44 +0400 Subject: [PATCH 14/83] import plugins without imp module imp reinitializes module even if it is already loaded --- torchat/src/torchat.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/torchat/src/torchat.py b/torchat/src/torchat.py index 600fd3ad..fc76806e 100755 --- a/torchat/src/torchat.py +++ b/torchat/src/torchat.py @@ -42,7 +42,6 @@ import re import os import sys -import imp import tc_client import tc_gui @@ -66,15 +65,15 @@ # plugin module should have NAME_ with translation of name # plugins are searched in app's plugins/ dir and in getDataDir()/plugins # plugins with same name in getDataDir()/plugins win over app's plugins/ dir -plugins_parent_dirs = [os.path.dirname(__file__), config.getDataDir()] +plugins_parent_dirs = [config.getDataDir(), os.path.dirname(__file__)] for plugins_parent_dir in plugins_parent_dirs: plugins_dir = os.path.join(plugins_parent_dir, 'plugins') if os.path.exists(plugins_dir): + sys.path.append(plugins_dir) for plugin_file in os.listdir(plugins_dir): if plugin_file.endswith('.py'): plugin_name = plugin_file[:-3] - plugin_path = os.path.join(plugins_dir, plugin_file) - PLUGINS[plugin_name] = imp.load_source(plugin_name, plugin_path) + PLUGINS[plugin_name] = __import__(plugin_name) for xx in TRANSLATIONS: if hasattr(PLUGINS[plugin_name], 'NAME_' + xx): dscr = getattr(PLUGINS[plugin_name], 'NAME_' + xx) From 76e780756a23b5ff56a90794723591607c4225f8 Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Sat, 2 Nov 2013 18:30:46 +0400 Subject: [PATCH 15/83] feature test_plugin *settings item for replacement text *translations --- torchat/src/plugins/test_plugin.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/torchat/src/plugins/test_plugin.py b/torchat/src/plugins/test_plugin.py index 6d32e2d8..611024b7 100644 --- a/torchat/src/plugins/test_plugin.py +++ b/torchat/src/plugins/test_plugin.py @@ -2,10 +2,24 @@ NAME_en = u'Test plugin, replaces all sent messages with "test"' NAME_ru = u'Проверочный плагин, заменяет все отправляемые сообщения на "test"' + def load(torchat): _sendChatMessage = torchat.tc_client.Buddy.sendChatMessage def sendChatMessage(self, text): - text = u'test' + text = torchat.config.get("test_plugin", "text") _sendChatMessage(self, text) torchat.tc_client.Buddy.sendChatMessage = sendChatMessage + torchat.config.config_defaults['test_plugin', 'text'] = 'test' + + torchat.TRANSLATIONS['en'].DSET_TEST_PLUGIN_TEXT = u'Replace any message with text' + torchat.TRANSLATIONS['ru'].DSET_TEST_PLUGIN_TEXT = u'Заменять сообщения текстом' + torchat.config.importLanguage() + + _constructor = torchat.dlg_settings.Dialog.__init__ + def constructor(self, main_window): + _constructor(self, main_window) + torchat.dlg.Text(self.p3, torchat.dlg_settings.lang.DSET_TEST_PLUGIN_TEXT, + ("test_plugin", "text")) + torchat.dlg_settings.Dialog.__init__ = constructor + From 5d885accd96dfce92e08cf806d464b4c96ae0bb4 Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Sat, 2 Nov 2013 19:05:55 +0400 Subject: [PATCH 16/83] show plugin name if no description available --- torchat/src/dlg_settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/torchat/src/dlg_settings.py b/torchat/src/dlg_settings.py index d9127deb..06b0ec17 100644 --- a/torchat/src/dlg_settings.py +++ b/torchat/src/dlg_settings.py @@ -109,7 +109,7 @@ def __init__(self, main_window): enabled_plugins = set(config.get('plugin', 'enabled_plugins').split(',')) import torchat for plugin_name in torchat.PLUGINS: - plugin_dscr = getattr(lang, 'DSET_PLUGIN_' + plugin_name.upper()) + plugin_dscr = getattr(lang, 'DSET_PLUGIN_' + plugin_name.upper(), plugin_name) enabled = int(bool(plugin_name in enabled_plugins)) self.plugins[plugin_name] = dlg.Check(self.p4, plugin_dscr, enabled) From 964e4549e94a151bdf23ca7f67905e4bae8404a2 Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Sat, 2 Nov 2013 19:07:06 +0400 Subject: [PATCH 17/83] conference features as a plugin --- torchat/src/config.py | 2 -- torchat/src/dlg_settings.py | 7 ------ torchat/src/plugins/conference.py | 36 +++++++++++++++++++++++++++++ torchat/src/tc_client.py | 10 -------- torchat/src/translations/lang_en.py | 2 -- 5 files changed, 36 insertions(+), 21 deletions(-) create mode 100644 torchat/src/plugins/conference.py diff --git a/torchat/src/config.py b/torchat/src/config.py index dcb256de..696e86ec 100644 --- a/torchat/src/config.py +++ b/torchat/src/config.py @@ -69,8 +69,6 @@ def isWindows(): ("branding", "support_name") : "Bernd, author of TorChat", ("profile", "name") : "", ("profile", "text") : "", - ("conference", "enabled") : 0, - ("conference", "prefer_nicks") : 1, ("plugin", "enabled_plugins") : '', } diff --git a/torchat/src/dlg_settings.py b/torchat/src/dlg_settings.py index 06b0ec17..cc18d38a 100644 --- a/torchat/src/dlg_settings.py +++ b/torchat/src/dlg_settings.py @@ -95,10 +95,6 @@ def __init__(self, main_window): self.dir_tmp = dlg.Dir(self.p3, lang.DSET_MISC_TEMP_CUSTOM_DIR, ("files", "temp_files_custom_dir")) self.dir_tmp.setEnabled(not self.chk_tmp.getValue()) self.chk_tmp.wx_ctrl.Bind(wx.EVT_CHECKBOX, self.onChkTmp) - self.conference_enabled = dlg.Check(self.p3, lang.DSET_MISC_CONFERENCE_ENABLED, ("conference", "enabled")) - self.conference_prefer_nicks = dlg.Check(self.p3, lang.DSET_MISC_CONFERENCE_PREFER_NICKS, ("conference", "prefer_nicks")) - self.onConferenceEnabled(None) - self.conference_enabled.wx_ctrl.Bind(wx.EVT_CHECKBOX, self.onConferenceEnabled) self.client = dlg.Text(self.p3, lang.DSET_MISC_REPORT_CLIENT, ("client", "reported_client")) self.version = dlg.Text(self.p3, lang.DSET_MISC_REPORT_VERSION, ("client", "reported_version")) @@ -119,9 +115,6 @@ def __init__(self, main_window): def onChkTmp(self, evt): self.dir_tmp.setEnabled(not self.chk_tmp.getValue()) - def onConferenceEnabled(self, evt): - self.conference_prefer_nicks.setEnabled(self.conference_enabled.getValue()) - def onCancel(self, evt): evt.Skip() #let the frame now process the Cancel event diff --git a/torchat/src/plugins/conference.py b/torchat/src/plugins/conference.py new file mode 100644 index 00000000..a58cebab --- /dev/null +++ b/torchat/src/plugins/conference.py @@ -0,0 +1,36 @@ +# -*- coding: UTF-8 -*- + +NAME_en = u'Turn this account into a conference' +NAME_ru = u'Превращает аккаунт в конференцию' + +def load(torchat): + _execute = torchat.tc_client.ProtocolMsg_message.execute + def execute(self): + _execute(self) + if self.buddy and self.buddy in self.bl.list: + nick = self.buddy.address + if int(torchat.config.get("conference", "prefer_nicks")) == 1 \ + and self.buddy.profile_name \ + and not torchat.tc_client.isValidAddress(self.buddy.profile_name): + nick = self.buddy.profile_name + resent_message = '%s: %s' % (nick, self.text) + for buddy in self.bl.list: + if buddy != self.buddy and buddy != self.bl.own_buddy: + buddy.sendChatMessage(resent_message) + torchat.tc_client.ProtocolMsg_message.execute = execute + + torchat.config.config_defaults['conference', 'prefer_nicks'] = 1 + + torchat.TRANSLATIONS['en'].DSET_MISC_CONFERENCE_PREFER_NICKS = \ + u'Show torchat nick if available instead of id to conference members' + torchat.TRANSLATIONS['ru'].DSET_MISC_CONFERENCE_PREFER_NICKS = \ + u'Показывать ник отправителя вместо id, если ник выставлен' + torchat.config.importLanguage() + + _constructor = torchat.dlg_settings.Dialog.__init__ + def constructor(self, main_window): + _constructor(self, main_window) + torchat.dlg.Check(self.p3, torchat.dlg_settings.lang.DSET_MISC_CONFERENCE_PREFER_NICKS, + ("conference", "prefer_nicks")) + torchat.dlg_settings.Dialog.__init__ = constructor + diff --git a/torchat/src/tc_client.py b/torchat/src/tc_client.py index 76eaecf5..f87f1b8c 100644 --- a/torchat/src/tc_client.py +++ b/torchat/src/tc_client.py @@ -1714,16 +1714,6 @@ def execute(self): if self.buddy: if self.buddy in self.bl.list: self.buddy.onChatMessage(self.text) - if config.get("conference", "enabled"): - nick = self.buddy.address - if int(config.get("conference", "prefer_nicks")) == 1 \ - and self.buddy.profile_name \ - and not isValidAddress(self.buddy.profile_name): - nick = self.buddy.profile_name - resent_message = '%s: %s' % (nick, self.text) - for buddy in self.bl.list: - if buddy != self.buddy and buddy != self.bl.own_buddy: - buddy.sendChatMessage(resent_message) else: print "(1) ***** protocol violation reply to %s" % self.buddy.address msg = "This is an automatic reply." diff --git a/torchat/src/translations/lang_en.py b/torchat/src/translations/lang_en.py index b7707c5c..02521f94 100644 --- a/torchat/src/translations/lang_en.py +++ b/torchat/src/translations/lang_en.py @@ -137,8 +137,6 @@ DSET_MISC_TITLE = u"Misc" DSET_MISC_TEMP_IN_DATA = u"Store temporary files inside data directory" DSET_MISC_TEMP_CUSTOM_DIR = u"Temporary directory (leave empty for OS-default)" -DSET_MISC_CONFERENCE_ENABLED = u"Turn this account into a conference" -DSET_MISC_CONFERENCE_PREFER_NICKS = u"Show torchat nick if available instead of id to conference members" DSET_MISC_REPORT_CLIENT = u"Client reported" DSET_MISC_REPORT_VERSION = u"Version reported" DSET_PLUGINS_TITLE = u"Plugins" From e3e3265f50b27ad20a5b781176a4cb3a29b5c376 Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Sat, 2 Nov 2013 19:11:49 +0400 Subject: [PATCH 18/83] import tranlation after plugin import plugin description are not translated if translation is not imported --- torchat/src/torchat.py | 1 + 1 file changed, 1 insertion(+) diff --git a/torchat/src/torchat.py b/torchat/src/torchat.py index fc76806e..9f07cfe8 100755 --- a/torchat/src/torchat.py +++ b/torchat/src/torchat.py @@ -79,6 +79,7 @@ dscr = getattr(PLUGINS[plugin_name], 'NAME_' + xx) var_name = 'DSET_PLUGIN_' + plugin_name.upper() setattr(TRANSLATIONS[xx], var_name, dscr) + config.importLanguage() def load_plugins(): enabled_plugins = config.get('plugin', 'enabled_plugins').split(',') From bd36d9991be0f68431d99f5949067026b4020205 Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Sat, 2 Nov 2013 19:13:18 +0400 Subject: [PATCH 19/83] russian translate tab title Plugins --- torchat/src/translations/lang_ru.py | 1 + 1 file changed, 1 insertion(+) diff --git a/torchat/src/translations/lang_ru.py b/torchat/src/translations/lang_ru.py index 8952b462..c9e01b5a 100644 --- a/torchat/src/translations/lang_ru.py +++ b/torchat/src/translations/lang_ru.py @@ -136,6 +136,7 @@ DSET_MISC_TITLE = u"Разное" DSET_MISC_TEMP_IN_DATA = u"Хранить временные файлы внутри папки с программой" DSET_MISC_TEMP_CUSTOM_DIR = u"Папка для временных файлов (оставьте пустой для папки по-умолчанию)" +DSET_PLUGINS_TITLE = u"Плагины" #notices in the chat window (those in square brackets) NOTICE_DELAYED_MSG_WAITING = u"отложенные сообщения ждут отправки" From 024df101e263b296f245f2a7cb590aa43ad5906e Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Sat, 2 Nov 2013 21:06:45 +0400 Subject: [PATCH 20/83] Check conference.no_gui --- torchat/src/plugins/conference.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/torchat/src/plugins/conference.py b/torchat/src/plugins/conference.py index a58cebab..2b1052d5 100644 --- a/torchat/src/plugins/conference.py +++ b/torchat/src/plugins/conference.py @@ -6,8 +6,10 @@ def load(torchat): _execute = torchat.tc_client.ProtocolMsg_message.execute def execute(self): - _execute(self) - if self.buddy and self.buddy in self.bl.list: + goood_message = self.buddy and self.buddy in self.bl.list + if int(torchat.config.get("conference", "no_gui")) == 0 or not goood_message: + _execute(self) + if goood_message: nick = self.buddy.address if int(torchat.config.get("conference", "prefer_nicks")) == 1 \ and self.buddy.profile_name \ @@ -20,11 +22,16 @@ def execute(self): torchat.tc_client.ProtocolMsg_message.execute = execute torchat.config.config_defaults['conference', 'prefer_nicks'] = 1 + torchat.config.config_defaults['conference', 'no_gui'] = 0 torchat.TRANSLATIONS['en'].DSET_MISC_CONFERENCE_PREFER_NICKS = \ u'Show torchat nick if available instead of id to conference members' torchat.TRANSLATIONS['ru'].DSET_MISC_CONFERENCE_PREFER_NICKS = \ u'Показывать ник отправителя вместо id, если ник выставлен' + torchat.TRANSLATIONS['en'].DSET_MISC_CONFERENCE_NO_GUI = \ + u'Do not reflect new messages in GUI' + torchat.TRANSLATIONS['ru'].DSET_MISC_CONFERENCE_NO_GUI = \ + u'Не отображать новые сообщения в графическом интерфейсе' torchat.config.importLanguage() _constructor = torchat.dlg_settings.Dialog.__init__ @@ -32,5 +39,7 @@ def constructor(self, main_window): _constructor(self, main_window) torchat.dlg.Check(self.p3, torchat.dlg_settings.lang.DSET_MISC_CONFERENCE_PREFER_NICKS, ("conference", "prefer_nicks")) + torchat.dlg.Check(self.p3, torchat.dlg_settings.lang.DSET_MISC_CONFERENCE_NO_GUI, + ("conference", "no_gui")) torchat.dlg_settings.Dialog.__init__ = constructor From 520b2a7a6223a22623878e1da28321883826c6db Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Sat, 2 Nov 2013 21:34:19 +0400 Subject: [PATCH 21/83] conference !list command --- torchat/src/plugins/conference.py | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/torchat/src/plugins/conference.py b/torchat/src/plugins/conference.py index 2b1052d5..bb0a65de 100644 --- a/torchat/src/plugins/conference.py +++ b/torchat/src/plugins/conference.py @@ -5,20 +5,31 @@ def load(torchat): _execute = torchat.tc_client.ProtocolMsg_message.execute + def nick_repr(buddy, nick_viewer): + nick = buddy.address + if int(torchat.config.get("conference", "prefer_nicks")) == 1 \ + and buddy.profile_name \ + and not torchat.tc_client.isValidAddress(buddy.profile_name): + nick = buddy.profile_name + return nick def execute(self): goood_message = self.buddy and self.buddy in self.bl.list if int(torchat.config.get("conference", "no_gui")) == 0 or not goood_message: _execute(self) if goood_message: - nick = self.buddy.address - if int(torchat.config.get("conference", "prefer_nicks")) == 1 \ - and self.buddy.profile_name \ - and not torchat.tc_client.isValidAddress(self.buddy.profile_name): - nick = self.buddy.profile_name - resent_message = '%s: %s' % (nick, self.text) - for buddy in self.bl.list: - if buddy != self.buddy and buddy != self.bl.own_buddy: - buddy.sendChatMessage(resent_message) + if self.text.startswith('!'): + # command + if self.text == '!list': + nicks = [] + for buddy in self.bl.list: + nicks.append(nick_repr(buddy, self.buddy)) + self.buddy.sendChatMessage(' '.join(nicks)) + else: + # resend message + for buddy in self.bl.list: + resent_message = '%s: %s' % (nick_repr(self.buddy, buddy), self.text) + if buddy != self.buddy and buddy != self.bl.own_buddy: + buddy.sendChatMessage(resent_message) torchat.tc_client.ProtocolMsg_message.execute = execute torchat.config.config_defaults['conference', 'prefer_nicks'] = 1 From 99d64426451dd4e99ef228656f781f94c9a87266 Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Sun, 3 Nov 2013 02:31:37 +0400 Subject: [PATCH 22/83] fix update of other buddy's avatar to no avatar If somebody removed his avatar, this was reflected in GUI only after GUI restart --- torchat/src/tc_gui.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/torchat/src/tc_gui.py b/torchat/src/tc_gui.py index e79433ed..6b887635 100644 --- a/torchat/src/tc_gui.py +++ b/torchat/src/tc_gui.py @@ -913,12 +913,16 @@ def onBuddyProfileChanged(self, buddy): def onBuddyAvatarChanged(self, buddy): print "(2) converting %s avatar data into wx.Bitmap" % buddy.address try: - image = wx.ImageFromData(64, 64, buddy.profile_avatar_data) - if buddy.profile_avatar_data_alpha: - print "(2) %s avatar has alpha channel" % buddy.address - image.SetAlphaData(buddy.profile_avatar_data_alpha) - buddy.profile_avatar_object = wx.BitmapFromImage(image) - + if buddy.profile_avatar_data: + image = wx.ImageFromData(64, 64, buddy.profile_avatar_data) + if buddy.profile_avatar_data_alpha: + print "(2) %s avatar has alpha channel" % buddy.address + image.SetAlphaData(buddy.profile_avatar_data_alpha) + buddy.profile_avatar_object = wx.BitmapFromImage(image) + else: + torchat_png = os.path.join(config.ICON_DIR, "torchat.png") + bitmap = wx.Bitmap(torchat_png, wx.BITMAP_TYPE_PNG) + buddy.profile_avatar_object = bitmap except: print "(2) could not convert %s avatar data to wx.Bitmap" % buddy.address tb() From cf1ef60386107f6acd8f9acd1e560aad7e10c943 Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Sun, 3 Nov 2013 02:38:08 +0400 Subject: [PATCH 23/83] many commands in conference plugin * roles * mute/kick/etc * topic, description, avatar --- torchat/src/plugins/conference.py | 369 ++++++++++++++++++++++++++++-- 1 file changed, 356 insertions(+), 13 deletions(-) diff --git a/torchat/src/plugins/conference.py b/torchat/src/plugins/conference.py index bb0a65de..8a562c82 100644 --- a/torchat/src/plugins/conference.py +++ b/torchat/src/plugins/conference.py @@ -1,40 +1,350 @@ # -*- coding: UTF-8 -*- +import os +import wx +import json + NAME_en = u'Turn this account into a conference' NAME_ru = u'Превращает аккаунт в конференцию' +NOBODY = set(['help']) +GUEST = NOBODY | set(['read_actions', 'read', 'list', 'ignore', 'unignore']) +USER = GUEST | set(['write', 'pm']) +MODER = USER | set(['mute', 'unmute', 'kick', 'invite', 'ban', 'unban', + 'topic', 'description', 'set_avatar', 'list_for_moder']) +ADMIN = MODER | set(['role', 'prefer_nicks', + 'allow_list', 'allow_pm', 'list_status', 'list_role', 'default_role', + 'show_admin_actions', 'show_enter_leave', 'welcome_help']) +OWNER = ADMIN | set(['add_admin', 'remove_admin']) + +ROLES = {'nobody': NOBODY, 'guest': GUEST, 'user': USER, + 'moder': MODER, 'admin': ADMIN, 'owner': OWNER} + +HELP = {} +HELP['nobody'] = ''' +!help get help +''' +HELP['guest'] = HELP['nobody'] + ''' +!list get list of room members +!ignore nick ignore messages from nick +!unignore nick undo ignore +''' +HELP['user'] = HELP['guest'] + ''' +!pm nick message private message to nick +''' +HELP['moder'] = HELP['user'] + ''' +!mute nick mute nick (role: user->guest) +!unmute nick undo mute (role: guest,nobody->user) +!kick nick kick nick from room +!invite nick invite nick to room +!ban nick ban nick (needs Ban plugin) +!unban nick undo ban +!topic text change topic of room +!description text change description of room +!set_avatar nick set avatar of nick as room's avatar +''' +HELP['admin'] = HELP['moder'] + ''' +!role [nobody|guest|user|moder] nick get or set role of nick +!prefer_nicks [yes|no] get or set prefer_nicks +!allow_list [yes|no] get or set allow_list +!allow_pm [yes|no] get or set allow_pm +!list_status [yes|no] get or set list_status +!list_role [yes|no] get or set list_role +!default_role [nobody|guest|user] get or set default_role +!show_admin_actions [yes|no] get or set show_admin_actions +!show_enter_leave [yes|no] get or set show_enter_leave +!welcome_help [yes|no] get or set welcome_help +''' +HELP['owner'] = HELP['admin'] + ''' +!add_admin nick set nick's role to admin +!remove_admin nick set nick's role to user +''' + def load(torchat): + torchat.config.config_defaults['conference', 'prefer_nicks'] = 1 + torchat.config.config_defaults['conference', 'no_gui'] = 0 + torchat.config.config_defaults['conference', 'roles'] = '{}' + torchat.config.config_defaults['conference', 'default_role'] = 'user' + torchat.config.config_defaults['conference', 'allow_list'] = 1 + torchat.config.config_defaults['conference', 'allow_pm'] = 1 + torchat.config.config_defaults['conference', 'list_status'] = 1 + torchat.config.config_defaults['conference', 'list_role'] = 1 + torchat.config.config_defaults['conference', 'show_admin_actions'] = 1 + torchat.config.config_defaults['conference', 'show_enter_leave'] = 1 + torchat.config.config_defaults['conference', 'welcome_help'] = 1 + torchat.config.config_defaults['conference', 'ignored'] = '{"who-bywho":1}' + _execute = torchat.tc_client.ProtocolMsg_message.execute - def nick_repr(buddy, nick_viewer): + + def sstatus(status): + if status == torchat.tc_client.STATUS_OFFLINE: + return 'offline' + if status == torchat.tc_client.STATUS_HANDSHAKE: + return 'handshake' + if status == torchat.tc_client.STATUS_ONLINE: + return 'online' + if status == torchat.tc_client.STATUS_AWAY: + return 'away' + if status == torchat.tc_client.STATUS_XA: + return 'busy' + def buddy_list(): + return torchat.app.mw.buddy_list + def get(option): + return torchat.config.get("conference", option) + def set_option(option, value): + torchat.config.set("conference", option, value) + roles = json.loads(get("roles")) + def role_of(torchat_id): + if torchat_id == buddy_list().own_buddy.address: + return 'owner' + default_role = get("default_role") + return roles.get(torchat_id, default_role) + def set_role(torchat_id, role): + roles[torchat_id] = role + set_option("roles", json.dumps(roles)) + ignored = json.loads(get("ignored")) + def is_ignored(who, bywho): + return ('%s-%s' % (who, bywho)) in ignored + def ignore(who, bywho): + ignored[('%s-%s' % (who, bywho))] = 1 + set_option("ignored", json.dumps(ignored)) + def unignore(who, bywho): + ignored.pop(('%s-%s' % (who, bywho)), None) + set_option("ignored", json.dumps(ignored)) + def role_can(role, action): + return role in ROLES and action in ROLES[role] + def is_moder(torchat_id): + return role_of(torchat_id) in ('moder', 'admin', 'owner') + def can(torchat_id, action): + return role_can(role_of(torchat_id), action) + def buddy_from_nick(nick, me): + if nick == 'me': + return me + for buddy in buddy_list().list: + if buddy.address == nick or buddy.profile_name == nick: + return buddy + def nick_repr(buddy, moder=False): nick = buddy.address - if int(torchat.config.get("conference", "prefer_nicks")) == 1 \ + if int(get("prefer_nicks")) == 1 \ and buddy.profile_name \ and not torchat.tc_client.isValidAddress(buddy.profile_name): nick = buddy.profile_name + if moder: + nick += ' (%s)' % buddy.address + if moder or get('list_role'): + buddy_role = role_of(buddy.address) + if buddy_role in ('admin', 'owner'): + nick = '@' + nick + if buddy_role == 'moder': + nick = '%' + nick + if get('list_status') and buddy.status != torchat.tc_client.STATUS_ONLINE: + nick += ' [%s]' % sstatus(buddy.status) return nick + def send_help(buddy, buddy_role): + buddy.sendChatMessage(HELP[buddy_role]) + def announce(text, moder): + text = '[room] %s' % text + for buddy in buddy_list().list: + if not can(buddy.address, 'read'): + continue + if moder and not is_moder(buddy.address) \ + and int(get("show_admin_actions")) != 1: + continue + if not moder and not is_moder(buddy.address) \ + and int(get("show_enter_leave")) != 1: + continue + buddy.sendChatMessage(text) + def splitLine(line): + return torchat.tc_client.splitLine(line) + def execute(self): goood_message = self.buddy and self.buddy in self.bl.list - if int(torchat.config.get("conference", "no_gui")) == 0 or not goood_message: + if int(get("no_gui")) == 0 or not goood_message: _execute(self) if goood_message: + me = self.buddy + my_address = me.address + my_role = role_of(my_address) if self.text.startswith('!'): - # command - if self.text == '!list': + command, argument = splitLine(self.text) + command = command[1:] # pop "!" + if not role_can(my_role, command): + me.sendChatMessage('[room] Action not allowed') + return + if command == 'help': + send_help(me, my_role) + if command == 'list': + list_for_moder = role_can(my_role, 'list_for_moder') + if int(get('allow_list')) != 1 and not list_for_moder: + me.sendChatMessage('[room] Action not allowed') + return nicks = [] for buddy in self.bl.list: - nicks.append(nick_repr(buddy, self.buddy)) - self.buddy.sendChatMessage(' '.join(nicks)) + nicks.append(nick_repr(buddy, list_for_moder)) + self.buddy.sendChatMessage('[room]\n' + '\n'.join(nicks)) + if command == 'ignore': + buddy = buddy_from_nick(argument, me) + if buddy: + ignore(buddy, me) + else: + me.sendChatMessage('[room] Unknown nick') + if command == 'unignore': + buddy = buddy_from_nick(argument, me) + if buddy: + unignore(buddy, me) + else: + me.sendChatMessage('[room] Unknown nick') + if command == 'pm': + if int(get('allow_pm')) != 1: + me.sendChatMessage('[room] Private messages disabled') + return + dest, message = splitLine(argument) + dest = buddy_from_nick(dest, me) + if not dest: + me.sendChatMessage('[room] Unknown nick') + return + if is_ignored(me, dest): + me.sendChatMessage('[room] Buddy ignores you') + return + my_nick = nick_repr(me, is_moder(dest.address)) + dest.sendChatMessage('[private] %s: %s' % (my_nick, message)) + if command == 'mute': + buddy = buddy_from_nick(argument, me) + if not buddy: + me.sendChatMessage('[room] Unknown nick') + return + if role_of(argument) != 'user': + me.sendChatMessage('[room] You can mute only users') + return + set_role(argument, 'guest') + announce('%s muted %s' % (nick_repr(me), nick_repr(buddy)), True) + if command == 'unmute': + buddy = buddy_from_nick(argument, me) + if not buddy: + me.sendChatMessage('[room] Unknown nick') + return + if role_of(argument) not in ('nobody', 'guest'): + me.sendChatMessage('[room] You can unmute nobody,guest') + return + announce('%s unmuted %s' % (nick_repr(me), nick_repr(buddy)), True) + set_role(argument, 'user') + if command == 'kick': + buddy = buddy_from_nick(argument, me) + if not buddy: + me.sendChatMessage('[room] Unknown nick') + return + if role_of(argument) not in ('nobody', 'guest', 'user'): + me.sendChatMessage('[room] You can kick nobody,guest,user') + return + buddy_list().removeBuddy(buddy, disconnect=False) + announce('%s kicked %s' % (nick_repr(me), nick_repr(buddy)), True) + if command == 'invite': + if not torchat.tc_client.isValidAddress(argument): + me.sendChatMessage('[room] Bad address') + return + buddy = buddy_from_nick(argument, me) + if buddy: + me.sendChatMessage('[room] Already in room') + return + buddy = torchat.tc_client.Buddy(argument, buddy_list(), '') + self.bl.addBuddy(buddy) + announce('%s invited %s' % (nick_repr(me), argument), True) + if command == 'ban': + buddy = buddy_from_nick(argument, me) + if not buddy: + me.sendChatMessage('[room] Unknown nick') + return + if role_of(argument) not in ('nobody', 'guest', 'user'): + me.sendChatMessage('[room] You can ban nobody,guest,user') + return + ban_list = json.loads(torchat.config.get("ban", 'list')) + ban_list[buddy.address] = 1 + torchat.config.set("ban", 'list', json.dumps(ban_list)) + buddy_list().removeBuddy(buddy, disconnect=False) + announce('%s banned %s' % (nick_repr(me), nick_repr(buddy)), True) + if command == 'unban': + announce('%s unbanned %s' % (nick_repr(me), argument), True) + ban_list = json.loads(torchat.config.get("ban", 'list')) + ban_list.pop(argument, None) + torchat.config.set("ban", 'list', json.dumps(ban_list)) + if command == 'topic': + torchat.config.set("profile", "name", argument) + for buddy in buddy_list().list: + buddy.sendProfile() + announce('%s changed the topic to %s' % (nick_repr(me), argument), True) + if command == 'description': + torchat.config.set("profile", "text", argument) + for buddy in buddy_list().list: + buddy.sendProfile() + announce('%s changed the description to %s' % (nick_repr(me), argument), True) + if command == 'set_avatar': + buddy = buddy_from_nick(argument, me) + if not buddy: + me.sendChatMessage('[room] Unknown nick') + return + alpha = buddy.profile_avatar_data_alpha + avatar = buddy.profile_avatar_data + buddy_list().own_avatar_data_alpha = alpha + buddy_list().own_avatar_data = avatar + file_name = os.path.join(torchat.config.getDataDir(), "avatar.png") + if not avatar: + torchat.tc_client.wipeFile(file_name) + else: + image = wx.ImageFromData(64, 64, avatar) + if alpha: + image.SetAlphaData(alpha) + image.SaveFile(file_name, wx.BITMAP_TYPE_PNG) + for buddy in buddy_list().list: + buddy.sendAvatar(send_empty=True) + announce('%s changed image of the room' % nick_repr(me), True) + if command == 'role': + arg1, arg2 = splitLine(argument) + if arg2: + # set + new_role, nick = arg1, arg2 + buddy = buddy_from_nick(nick, me) + if not buddy: + me.sendChatMessage('[room] Unknown nick') + return + if role_of(buddy.address) in ('admin', 'owner'): + me.sendChatMessage('[room] Can not change role of admin,owner') + return + if new_role not in ('nobody', 'guest', 'user', 'moder'): + me.sendChatMessage('[room] Can change role to nobody,guest,user,moder') + return + set_role(buddy.address, new_role) + announce('%s set role of %s to %s' % + (nick_repr(me), nick_repr(buddy), new_role), True) + else : + # get + nick = arg1 + buddy = buddy_from_nick(nick, me) + if not buddy: + me.sendChatMessage('[room] Unknown nick') + return + me.sendChatMessage('[room] role(%s)=%s' % + (nick, role_of(buddy.address))) + # TODO admin settings else: + if not role_can(my_role, 'write'): + self.buddy.sendChatMessage('[room] You can not send messages') + return # resend message for buddy in self.bl.list: - resent_message = '%s: %s' % (nick_repr(self.buddy, buddy), self.text) - if buddy != self.buddy and buddy != self.bl.own_buddy: - buddy.sendChatMessage(resent_message) + if not can(buddy.address, 'read'): + continue + if buddy == self.buddy: + continue + if buddy == self.bl.own_buddy: + continue + if self.buddy == self.bl.own_buddy \ + and self.text.startswith('[room]'): + continue + sender_nick = nick_repr(self.buddy, is_moder(buddy.address)) + resent_message = '%s: %s' % (sender_nick, self.text) + buddy.sendChatMessage(resent_message) torchat.tc_client.ProtocolMsg_message.execute = execute - torchat.config.config_defaults['conference', 'prefer_nicks'] = 1 - torchat.config.config_defaults['conference', 'no_gui'] = 0 - torchat.TRANSLATIONS['en'].DSET_MISC_CONFERENCE_PREFER_NICKS = \ u'Show torchat nick if available instead of id to conference members' torchat.TRANSLATIONS['ru'].DSET_MISC_CONFERENCE_PREFER_NICKS = \ @@ -43,6 +353,38 @@ def execute(self): u'Do not reflect new messages in GUI' torchat.TRANSLATIONS['ru'].DSET_MISC_CONFERENCE_NO_GUI = \ u'Не отображать новые сообщения в графическом интерфейсе' + torchat.TRANSLATIONS['en'].DSET_MISC_CONFERENCE_DEFAULT_ROLE = \ + u'Default role for new members (nobody|guest|user)' + torchat.TRANSLATIONS['ru'].DSET_MISC_CONFERENCE_DEFAULT_ROLE = \ + u'Роль по умолчанию для новых членов (nobody|guest|user)' + torchat.TRANSLATIONS['en'].DSET_MISC_CONFERENCE_ALLOW_LIST = \ + u'Regular users can get list of users' + torchat.TRANSLATIONS['ru'].DSET_MISC_CONFERENCE_ALLOW_LIST = \ + u'Обычные пользователи могут смотреть список пользователей' + torchat.TRANSLATIONS['en'].DSET_MISC_CONFERENCE_ALLOW_PM = \ + u'Allow private messages' + torchat.TRANSLATIONS['ru'].DSET_MISC_CONFERENCE_ALLOW_PM = \ + u'Разрешить личные сообщения' + torchat.TRANSLATIONS['en'].DSET_MISC_CONFERENCE_LIST_STATUS = \ + u'Regular users view status of users' + torchat.TRANSLATIONS['ru'].DSET_MISC_CONFERENCE_LIST_STATUS = \ + u'Обычные пользователи видят статус пользователей' + torchat.TRANSLATIONS['en'].DSET_MISC_CONFERENCE_LIST_ROLE = \ + u'Regular users view role of users' + torchat.TRANSLATIONS['ru'].DSET_MISC_CONFERENCE_LIST_ROLE = \ + u'Обычные пользователи видят роль пользователей' + torchat.TRANSLATIONS['en'].DSET_MISC_CONFERENCE_SHOW_ADMIN_ACTIONS = \ + u"Regular users view administrators' actions" + torchat.TRANSLATIONS['ru'].DSET_MISC_CONFERENCE_SHOW_ADMIN_ACTIONS = \ + u'Обычные пользователи видят действия администраторов' + torchat.TRANSLATIONS['en'].DSET_MISC_CONFERENCE_SHOW_ENTER_LEAVE = \ + u"Regular users view somebody enter or leave room" + torchat.TRANSLATIONS['ru'].DSET_MISC_CONFERENCE_SHOW_ADMIN_ACTIONS = \ + u'Обычные пользователи видят, когда кто-то входит или выходит' + torchat.TRANSLATIONS['en'].DSET_MISC_CONFERENCE_WELCOME_HELP = \ + u"Welcome new users with help message" + torchat.TRANSLATIONS['ru'].DSET_MISC_CONFERENCE_WELCOME_HELP = \ + u'Приветствовать новых пользователей справкой' torchat.config.importLanguage() _constructor = torchat.dlg_settings.Dialog.__init__ @@ -52,5 +394,6 @@ def constructor(self, main_window): ("conference", "prefer_nicks")) torchat.dlg.Check(self.p3, torchat.dlg_settings.lang.DSET_MISC_CONFERENCE_NO_GUI, ("conference", "no_gui")) + # TODO torchat.dlg_settings.Dialog.__init__ = constructor From 4b0e9347bc7c3cd1fffb807c4f66925137f7d605 Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Sun, 3 Nov 2013 03:31:34 +0400 Subject: [PATCH 24/83] each conference command lives in own function --- torchat/src/plugins/conference.py | 363 +++++++++++++++--------------- 1 file changed, 185 insertions(+), 178 deletions(-) diff --git a/torchat/src/plugins/conference.py b/torchat/src/plugins/conference.py index 8a562c82..dfec4899 100644 --- a/torchat/src/plugins/conference.py +++ b/torchat/src/plugins/conference.py @@ -111,12 +111,11 @@ def ignore(who, bywho): def unignore(who, bywho): ignored.pop(('%s-%s' % (who, bywho)), None) set_option("ignored", json.dumps(ignored)) - def role_can(role, action): - return role in ROLES and action in ROLES[role] def is_moder(torchat_id): return role_of(torchat_id) in ('moder', 'admin', 'owner') def can(torchat_id, action): - return role_can(role_of(torchat_id), action) + role = role_of(torchat_id) + return role in ROLES and action in ROLES[role] def buddy_from_nick(nick, me): if nick == 'me': return me @@ -140,8 +139,6 @@ def nick_repr(buddy, moder=False): if get('list_status') and buddy.status != torchat.tc_client.STATUS_ONLINE: nick += ' [%s]' % sstatus(buddy.status) return nick - def send_help(buddy, buddy_role): - buddy.sendChatMessage(HELP[buddy_role]) def announce(text, moder): text = '[room] %s' % text for buddy in buddy_list().list: @@ -157,192 +154,202 @@ def announce(text, moder): def splitLine(line): return torchat.tc_client.splitLine(line) + def do_help(me, _): + me.sendChatMessage(HELP[role_of(me.address)]) + def do_list(me, _): + list_for_moder = can(me.address, 'list_for_moder') + if int(get('allow_list')) != 1 and not list_for_moder: + me.sendChatMessage('[room] Action not allowed') + return + nicks = [] + for buddy in buddy_list().list: + nicks.append(nick_repr(buddy, list_for_moder)) + me.sendChatMessage('[room]\n' + '\n'.join(nicks)) + def do_ignore(me, nick): + buddy = buddy_from_nick(nick, me) + if buddy: + ignore(buddy, me) + else: + me.sendChatMessage('[room] Unknown nick') + def do_unignore(me, nick): + buddy = buddy_from_nick(nick, me) + if buddy: + unignore(buddy, me) + else: + me.sendChatMessage('[room] Unknown nick') + def do_pm(me, argument): + if int(get('allow_pm')) != 1: + me.sendChatMessage('[room] Private messages disabled') + return + dest, message = splitLine(argument) + dest = buddy_from_nick(dest, me) + if not dest: + me.sendChatMessage('[room] Unknown nick') + return + if is_ignored(me, dest): + me.sendChatMessage('[room] Buddy ignores you') + return + my_nick = nick_repr(me, is_moder(dest.address)) + dest.sendChatMessage('[private] %s: %s' % (my_nick, message)) + def do_mute(me, nick): + buddy = buddy_from_nick(nick, me) + if not buddy: + me.sendChatMessage('[room] Unknown nick') + return + if role_of(buddy.address) != 'user': + me.sendChatMessage('[room] You can mute only users') + return + set_role(buddy.address, 'guest') + announce('%s muted %s' % (nick_repr(me), nick_repr(buddy)), True) + def do_unmute(me, nick): + buddy = buddy_from_nick(nick, me) + if not buddy: + me.sendChatMessage('[room] Unknown nick') + return + if role_of(buddy.address) not in ('nobody', 'guest'): + me.sendChatMessage('[room] You can unmute nobody,guest') + return + announce('%s unmuted %s' % (nick_repr(me), nick_repr(buddy)), True) + set_role(buddy.address, 'user') + def do_kick(me, nick): + buddy = buddy_from_nick(nick, me) + if not buddy: + me.sendChatMessage('[room] Unknown nick') + return + if role_of(buddy.address) not in ('nobody', 'guest', 'user'): + me.sendChatMessage('[room] You can kick nobody,guest,user') + return + buddy_list().removeBuddy(buddy, disconnect=False) + announce('%s kicked %s' % (nick_repr(me), nick_repr(buddy)), True) + def do_invite(me, address): + if not torchat.tc_client.isValidAddress(address): + me.sendChatMessage('[room] Bad address') + return + buddy = buddy_from_nick(address, me) + if buddy: + me.sendChatMessage('[room] Already in room') + return + buddy = torchat.tc_client.Buddy(address, buddy_list(), '') + buddy_list().addBuddy(buddy) + announce('%s invited %s' % (nick_repr(me), address), True) + def do_ban(me, nick): + buddy = buddy_from_nick(nick, me) + if not buddy: + me.sendChatMessage('[room] Unknown nick') + return + if role_of(buddy.address) not in ('nobody', 'guest', 'user'): + me.sendChatMessage('[room] You can ban nobody,guest,user') + return + ban_list = json.loads(torchat.config.get("ban", 'list')) + ban_list[buddy.address] = 1 + torchat.config.set("ban", 'list', json.dumps(ban_list)) + buddy_list().removeBuddy(buddy, disconnect=False) + announce('%s banned %s' % (nick_repr(me), nick_repr(buddy)), True) + def do_unban(me, address): + announce('%s unbanned %s' % (nick_repr(me), address), True) + ban_list = json.loads(torchat.config.get("ban", 'list')) + ban_list.pop(address, None) + torchat.config.set("ban", 'list', json.dumps(ban_list)) + def do_topic(me, topic): + torchat.config.set("profile", "name", topic) + for buddy in buddy_list().list: + buddy.sendProfile() + announce('%s changed the topic to %s' % (nick_repr(me), topic), True) + def do_description(me, topic): + torchat.config.set("profile", "text", topic) + for buddy in buddy_list().list: + buddy.sendProfile() + announce('%s changed the description to %s' % (nick_repr(me), topic), True) + def do_set_avatar(me, nick): + buddy = buddy_from_nick(nick, me) + if not buddy: + me.sendChatMessage('[room] Unknown nick') + return + alpha = buddy.profile_avatar_data_alpha + avatar = buddy.profile_avatar_data + buddy_list().own_avatar_data_alpha = alpha + buddy_list().own_avatar_data = avatar + file_name = os.path.join(torchat.config.getDataDir(), "avatar.png") + if not avatar: + torchat.tc_client.wipeFile(file_name) + else: + image = wx.ImageFromData(64, 64, avatar) + if alpha: + image.SetAlphaData(alpha) + image.SaveFile(file_name, wx.BITMAP_TYPE_PNG) + for buddy in buddy_list().list: + buddy.sendAvatar(send_empty=True) + announce('%s changed image of the room' % nick_repr(me), True) + def do_role(me, argument): + arg1, arg2 = splitLine(argument) + if arg2: + # set + new_role, nick = arg1, arg2 + buddy = buddy_from_nick(nick, me) + if not buddy: + me.sendChatMessage('[room] Unknown nick') + return + if role_of(buddy.address) in ('admin', 'owner'): + me.sendChatMessage('[room] Can not change role of admin,owner') + return + if new_role not in ('nobody', 'guest', 'user', 'moder'): + me.sendChatMessage('[room] Can change role to nobody,guest,user,moder') + return + set_role(buddy.address, new_role) + announce('%s set role of %s to %s' % + (nick_repr(me), nick_repr(buddy), new_role), True) + else : + # get + nick = arg1 + buddy = buddy_from_nick(nick, me) + if not buddy: + me.sendChatMessage('[room] Unknown nick') + return + me.sendChatMessage('[room] role(%s)=%s' % + (nick, role_of(buddy.address))) + # TODO admin settings + def resend(me, text): + if not can(me.address, 'write'): + me.sendChatMessage('[room] You can not send messages') + return + for buddy in buddy_list().list: + if not can(buddy.address, 'read'): + continue + if buddy == me: + continue + if buddy == buddy_list().own_buddy: + continue + if me == buddy_list().own_buddy \ + and text.startswith('[room]'): + continue + sender_nick = nick_repr(me, is_moder(buddy.address)) + resent_message = '%s: %s' % (sender_nick, text) + buddy.sendChatMessage(resent_message) + + load_vars = vars() + def execute(self): goood_message = self.buddy and self.buddy in self.bl.list if int(get("no_gui")) == 0 or not goood_message: _execute(self) if goood_message: me = self.buddy - my_address = me.address - my_role = role_of(my_address) if self.text.startswith('!'): command, argument = splitLine(self.text) command = command[1:] # pop "!" - if not role_can(my_role, command): + if not can(me.address, command): me.sendChatMessage('[room] Action not allowed') return - if command == 'help': - send_help(me, my_role) - if command == 'list': - list_for_moder = role_can(my_role, 'list_for_moder') - if int(get('allow_list')) != 1 and not list_for_moder: - me.sendChatMessage('[room] Action not allowed') - return - nicks = [] - for buddy in self.bl.list: - nicks.append(nick_repr(buddy, list_for_moder)) - self.buddy.sendChatMessage('[room]\n' + '\n'.join(nicks)) - if command == 'ignore': - buddy = buddy_from_nick(argument, me) - if buddy: - ignore(buddy, me) - else: - me.sendChatMessage('[room] Unknown nick') - if command == 'unignore': - buddy = buddy_from_nick(argument, me) - if buddy: - unignore(buddy, me) - else: - me.sendChatMessage('[room] Unknown nick') - if command == 'pm': - if int(get('allow_pm')) != 1: - me.sendChatMessage('[room] Private messages disabled') - return - dest, message = splitLine(argument) - dest = buddy_from_nick(dest, me) - if not dest: - me.sendChatMessage('[room] Unknown nick') - return - if is_ignored(me, dest): - me.sendChatMessage('[room] Buddy ignores you') - return - my_nick = nick_repr(me, is_moder(dest.address)) - dest.sendChatMessage('[private] %s: %s' % (my_nick, message)) - if command == 'mute': - buddy = buddy_from_nick(argument, me) - if not buddy: - me.sendChatMessage('[room] Unknown nick') - return - if role_of(argument) != 'user': - me.sendChatMessage('[room] You can mute only users') - return - set_role(argument, 'guest') - announce('%s muted %s' % (nick_repr(me), nick_repr(buddy)), True) - if command == 'unmute': - buddy = buddy_from_nick(argument, me) - if not buddy: - me.sendChatMessage('[room] Unknown nick') - return - if role_of(argument) not in ('nobody', 'guest'): - me.sendChatMessage('[room] You can unmute nobody,guest') - return - announce('%s unmuted %s' % (nick_repr(me), nick_repr(buddy)), True) - set_role(argument, 'user') - if command == 'kick': - buddy = buddy_from_nick(argument, me) - if not buddy: - me.sendChatMessage('[room] Unknown nick') - return - if role_of(argument) not in ('nobody', 'guest', 'user'): - me.sendChatMessage('[room] You can kick nobody,guest,user') - return - buddy_list().removeBuddy(buddy, disconnect=False) - announce('%s kicked %s' % (nick_repr(me), nick_repr(buddy)), True) - if command == 'invite': - if not torchat.tc_client.isValidAddress(argument): - me.sendChatMessage('[room] Bad address') - return - buddy = buddy_from_nick(argument, me) - if buddy: - me.sendChatMessage('[room] Already in room') - return - buddy = torchat.tc_client.Buddy(argument, buddy_list(), '') - self.bl.addBuddy(buddy) - announce('%s invited %s' % (nick_repr(me), argument), True) - if command == 'ban': - buddy = buddy_from_nick(argument, me) - if not buddy: - me.sendChatMessage('[room] Unknown nick') - return - if role_of(argument) not in ('nobody', 'guest', 'user'): - me.sendChatMessage('[room] You can ban nobody,guest,user') - return - ban_list = json.loads(torchat.config.get("ban", 'list')) - ban_list[buddy.address] = 1 - torchat.config.set("ban", 'list', json.dumps(ban_list)) - buddy_list().removeBuddy(buddy, disconnect=False) - announce('%s banned %s' % (nick_repr(me), nick_repr(buddy)), True) - if command == 'unban': - announce('%s unbanned %s' % (nick_repr(me), argument), True) - ban_list = json.loads(torchat.config.get("ban", 'list')) - ban_list.pop(argument, None) - torchat.config.set("ban", 'list', json.dumps(ban_list)) - if command == 'topic': - torchat.config.set("profile", "name", argument) - for buddy in buddy_list().list: - buddy.sendProfile() - announce('%s changed the topic to %s' % (nick_repr(me), argument), True) - if command == 'description': - torchat.config.set("profile", "text", argument) - for buddy in buddy_list().list: - buddy.sendProfile() - announce('%s changed the description to %s' % (nick_repr(me), argument), True) - if command == 'set_avatar': - buddy = buddy_from_nick(argument, me) - if not buddy: - me.sendChatMessage('[room] Unknown nick') - return - alpha = buddy.profile_avatar_data_alpha - avatar = buddy.profile_avatar_data - buddy_list().own_avatar_data_alpha = alpha - buddy_list().own_avatar_data = avatar - file_name = os.path.join(torchat.config.getDataDir(), "avatar.png") - if not avatar: - torchat.tc_client.wipeFile(file_name) - else: - image = wx.ImageFromData(64, 64, avatar) - if alpha: - image.SetAlphaData(alpha) - image.SaveFile(file_name, wx.BITMAP_TYPE_PNG) - for buddy in buddy_list().list: - buddy.sendAvatar(send_empty=True) - announce('%s changed image of the room' % nick_repr(me), True) - if command == 'role': - arg1, arg2 = splitLine(argument) - if arg2: - # set - new_role, nick = arg1, arg2 - buddy = buddy_from_nick(nick, me) - if not buddy: - me.sendChatMessage('[room] Unknown nick') - return - if role_of(buddy.address) in ('admin', 'owner'): - me.sendChatMessage('[room] Can not change role of admin,owner') - return - if new_role not in ('nobody', 'guest', 'user', 'moder'): - me.sendChatMessage('[room] Can change role to nobody,guest,user,moder') - return - set_role(buddy.address, new_role) - announce('%s set role of %s to %s' % - (nick_repr(me), nick_repr(buddy), new_role), True) - else : - # get - nick = arg1 - buddy = buddy_from_nick(nick, me) - if not buddy: - me.sendChatMessage('[room] Unknown nick') - return - me.sendChatMessage('[room] role(%s)=%s' % - (nick, role_of(buddy.address))) - # TODO admin settings - else: - if not role_can(my_role, 'write'): - self.buddy.sendChatMessage('[room] You can not send messages') + func_name = "do_%s" % command + if func_name in load_vars: + func = load_vars[func_name] + func(me, argument) + else: + me.sendChatMessage('[room] Not implemented') return + else: # resend message - for buddy in self.bl.list: - if not can(buddy.address, 'read'): - continue - if buddy == self.buddy: - continue - if buddy == self.bl.own_buddy: - continue - if self.buddy == self.bl.own_buddy \ - and self.text.startswith('[room]'): - continue - sender_nick = nick_repr(self.buddy, is_moder(buddy.address)) - resent_message = '%s: %s' % (sender_nick, self.text) - buddy.sendChatMessage(resent_message) + resend(me, self.text) torchat.tc_client.ProtocolMsg_message.execute = execute torchat.TRANSLATIONS['en'].DSET_MISC_CONFERENCE_PREFER_NICKS = \ From e6deb933a63207931b003b609611ae3bc02f1779 Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Sun, 3 Nov 2013 03:37:12 +0400 Subject: [PATCH 25/83] fix conference.ignore, address in place of buddy --- torchat/src/plugins/conference.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/torchat/src/plugins/conference.py b/torchat/src/plugins/conference.py index dfec4899..a5a1389a 100644 --- a/torchat/src/plugins/conference.py +++ b/torchat/src/plugins/conference.py @@ -168,13 +168,13 @@ def do_list(me, _): def do_ignore(me, nick): buddy = buddy_from_nick(nick, me) if buddy: - ignore(buddy, me) + ignore(buddy.address, me.address) else: me.sendChatMessage('[room] Unknown nick') def do_unignore(me, nick): buddy = buddy_from_nick(nick, me) if buddy: - unignore(buddy, me) + unignore(buddy.address, me.address) else: me.sendChatMessage('[room] Unknown nick') def do_pm(me, argument): @@ -186,7 +186,7 @@ def do_pm(me, argument): if not dest: me.sendChatMessage('[room] Unknown nick') return - if is_ignored(me, dest): + if is_ignored(me.address, dest.address): me.sendChatMessage('[room] Buddy ignores you') return my_nick = nick_repr(me, is_moder(dest.address)) @@ -322,6 +322,8 @@ def resend(me, text): if me == buddy_list().own_buddy \ and text.startswith('[room]'): continue + if is_ignored(me.address, buddy.address): + continue sender_nick = nick_repr(me, is_moder(buddy.address)) resent_message = '%s: %s' % (sender_nick, text) buddy.sendChatMessage(resent_message) From f8ceeb3d63eafa0cc09955fca4b7673f2eb6e577 Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Sun, 3 Nov 2013 03:43:31 +0400 Subject: [PATCH 26/83] conference members can not ignore moderators --- torchat/src/plugins/conference.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/torchat/src/plugins/conference.py b/torchat/src/plugins/conference.py index a5a1389a..48d8663f 100644 --- a/torchat/src/plugins/conference.py +++ b/torchat/src/plugins/conference.py @@ -168,7 +168,10 @@ def do_list(me, _): def do_ignore(me, nick): buddy = buddy_from_nick(nick, me) if buddy: - ignore(buddy.address, me.address) + if is_moder(buddy.address): + me.sendChatMessage('[room] Can not ignore moderator') + else: + ignore(buddy.address, me.address) else: me.sendChatMessage('[room] Unknown nick') def do_unignore(me, nick): From 6afbc982e239793ea77885635ef0c9cf71b24dfb Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Sun, 3 Nov 2013 03:44:38 +0400 Subject: [PATCH 27/83] conference doesn't resend messages starting with [ --- torchat/src/plugins/conference.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/torchat/src/plugins/conference.py b/torchat/src/plugins/conference.py index 48d8663f..d0729792 100644 --- a/torchat/src/plugins/conference.py +++ b/torchat/src/plugins/conference.py @@ -323,7 +323,7 @@ def resend(me, text): if buddy == buddy_list().own_buddy: continue if me == buddy_list().own_buddy \ - and text.startswith('[room]'): + and text.startswith('['): # [room] [delayed] [private] etc continue if is_ignored(me.address, buddy.address): continue From 6a0601298684a849617cc6589557669fdba38955 Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Sun, 3 Nov 2013 04:01:58 +0400 Subject: [PATCH 28/83] conference recognizes nicks with @/% or by part --- torchat/src/plugins/conference.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/torchat/src/plugins/conference.py b/torchat/src/plugins/conference.py index d0729792..c8d248d4 100644 --- a/torchat/src/plugins/conference.py +++ b/torchat/src/plugins/conference.py @@ -122,6 +122,15 @@ def buddy_from_nick(nick, me): for buddy in buddy_list().list: if buddy.address == nick or buddy.profile_name == nick: return buddy + if nick.startswith('@') or nick.startswith('%'): + nick = nick[1:] + for buddy in buddy_list().list: + if buddy.address == nick or buddy.profile_name == nick: + return buddy + i_am_moder = is_moder(me.address) + for buddy in buddy_list().list: + if nick in nick_repr(buddy, i_am_moder): + return buddy def nick_repr(buddy, moder=False): nick = buddy.address if int(get("prefer_nicks")) == 1 \ From 7fb4c95c49a88f78ca14d9207d252e693d3322d1 Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Sun, 3 Nov 2013 04:13:51 +0400 Subject: [PATCH 29/83] notes in conference help --- torchat/src/plugins/conference.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/torchat/src/plugins/conference.py b/torchat/src/plugins/conference.py index c8d248d4..f55d84b9 100644 --- a/torchat/src/plugins/conference.py +++ b/torchat/src/plugins/conference.py @@ -25,11 +25,17 @@ !help get help ''' HELP['guest'] = HELP['nobody'] + ''' +You can refer nick or torchat id, with or without % and @. +You can refer part of nick. + !list get list of room members !ignore nick ignore messages from nick !unignore nick undo ignore ''' HELP['user'] = HELP['guest'] + ''' +You can send messages to chat. Just send regular messages! +To prevent !smth from interpreting as a command, prepend it with "_ ". + !pm nick message private message to nick ''' HELP['moder'] = HELP['user'] + ''' From c1317b6441e6e2edfec809aa1648c90115172f02 Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Sun, 3 Nov 2013 04:44:05 +0400 Subject: [PATCH 30/83] implement conference admin commands --- torchat/src/plugins/conference.py | 60 ++++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/torchat/src/plugins/conference.py b/torchat/src/plugins/conference.py index f55d84b9..74caba0a 100644 --- a/torchat/src/plugins/conference.py +++ b/torchat/src/plugins/conference.py @@ -325,7 +325,65 @@ def do_role(me, argument): return me.sendChatMessage('[room] role(%s)=%s' % (nick, role_of(buddy.address))) - # TODO admin settings + def yes_no_command(me, option, yes_no): + if yes_no in ('yes', 'no'): + # set + set_option(option, int(yes_no == 'yes')) + announce('%s set %s to %s' % + (nick_repr(me), option, yes_no), True) + elif not yes_no: + # get + value = 'yes' if int(get(option)) == 1 else 'no' + me.sendChatMessage('[room] %s=%s' % (option, value)) + else: + me.sendChatMessage('[room] Bad argument') + def do_prefer_nicks(me, yes_no): + yes_no_command(me, 'prefer_nicks', yes_no) + def do_allow_list(me, yes_no): + yes_no_command(me, 'allow_list', yes_no) + def do_allow_pm(me, yes_no): + yes_no_command(me, 'allow_pm', yes_no) + def do_list_status(me, yes_no): + yes_no_command(me, 'list_status', yes_no) + def do_list_role(me, yes_no): + yes_no_command(me, 'list_role', yes_no) + def do_show_admin_actions(me, yes_no): + yes_no_command(me, 'show_admin_actions', yes_no) + def do_show_enter_leave(me, yes_no): + yes_no_command(me, 'show_enter_leave', yes_no) + def do_welcome_help(me, yes_no): + yes_no_command(me, 'welcome_help', yes_no) + def do_default_role(me, role): + if role in ('nobody', 'guest', 'user'): + # set + set_option('default_role', role) + announce('%s set default role to %s' % + (nick_repr(me), role), True) + elif not role: + # get + me.sendChatMessage('[room] default_role=%s' % get('default_role')) + def do_add_admin(me, nick): + buddy = buddy_from_nick(nick, me) + if not buddy: + me.sendChatMessage('[room] Unknown nick') + return + if role_of(buddy.address) in ('admin', 'owner'): + me.sendChatMessage('[room] This user is already admin or owner') + return + set_role(buddy.address, 'admin') + announce("%s set %s's role to admin" % + (nick_repr(me), nick_repr(buddy)), True) + def do_remove_admin(me, nick): + buddy = buddy_from_nick(nick, me) + if not buddy: + me.sendChatMessage('[room] Unknown nick') + return + if role_of(buddy.address) != 'admin': + me.sendChatMessage('[room] This user is not admin') + return + set_role(buddy.address, 'user') + announce("%s set %s's role to user" % + (nick_repr(me), nick_repr(buddy)), True) def resend(me, text): if not can(me.address, 'write'): me.sendChatMessage('[room] You can not send messages') From 26d20ca34186f853edf2b46814ffaa3ab63b1fab Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Sun, 3 Nov 2013 04:45:33 +0400 Subject: [PATCH 31/83] start conference help message with [help] to prevent resending --- torchat/src/plugins/conference.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/torchat/src/plugins/conference.py b/torchat/src/plugins/conference.py index 74caba0a..0b77cf9f 100644 --- a/torchat/src/plugins/conference.py +++ b/torchat/src/plugins/conference.py @@ -21,7 +21,7 @@ 'moder': MODER, 'admin': ADMIN, 'owner': OWNER} HELP = {} -HELP['nobody'] = ''' +HELP['nobody'] = '''[help] !help get help ''' HELP['guest'] = HELP['nobody'] + ''' From 08c5fa861ad8b823f0ffc4fa6476ba2e251ccb96 Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Sun, 3 Nov 2013 04:49:39 +0400 Subject: [PATCH 32/83] conference responds with Unknown command instead of "Action not allowed" to unknown commands --- torchat/src/plugins/conference.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/torchat/src/plugins/conference.py b/torchat/src/plugins/conference.py index 0b77cf9f..9db6cda6 100644 --- a/torchat/src/plugins/conference.py +++ b/torchat/src/plugins/conference.py @@ -415,6 +415,9 @@ def execute(self): if self.text.startswith('!'): command, argument = splitLine(self.text) command = command[1:] # pop "!" + if command not in OWNER: + me.sendChatMessage('[room] Unknown command') + return if not can(me.address, command): me.sendChatMessage('[room] Action not allowed') return From 3214ffa5812c7f56fb5d610e706cd7140e1bd70b Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Sun, 3 Nov 2013 04:59:33 +0400 Subject: [PATCH 33/83] conference welcome to new users implemented --- torchat/src/plugins/conference.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/torchat/src/plugins/conference.py b/torchat/src/plugins/conference.py index 9db6cda6..43331658 100644 --- a/torchat/src/plugins/conference.py +++ b/torchat/src/plugins/conference.py @@ -80,8 +80,6 @@ def load(torchat): torchat.config.config_defaults['conference', 'welcome_help'] = 1 torchat.config.config_defaults['conference', 'ignored'] = '{"who-bywho":1}' - _execute = torchat.tc_client.ProtocolMsg_message.execute - def sstatus(status): if status == torchat.tc_client.STATUS_OFFLINE: return 'offline' @@ -406,10 +404,11 @@ def resend(me, text): load_vars = vars() - def execute(self): + _message_execute = torchat.tc_client.ProtocolMsg_message.execute + def message_execute(self): goood_message = self.buddy and self.buddy in self.bl.list if int(get("no_gui")) == 0 or not goood_message: - _execute(self) + _message_execute(self) if goood_message: me = self.buddy if self.text.startswith('!'): @@ -431,7 +430,14 @@ def execute(self): else: # resend message resend(me, self.text) - torchat.tc_client.ProtocolMsg_message.execute = execute + torchat.tc_client.ProtocolMsg_message.execute = message_execute + + _add_me_execute = torchat.tc_client.ProtocolMsg_add_me.execute + def add_me_execute(self): + _add_me_execute(self) + if int(get('welcome_help')) == 1: + do_help(self.buddy, None) + torchat.tc_client.ProtocolMsg_add_me.execute = add_me_execute torchat.TRANSLATIONS['en'].DSET_MISC_CONFERENCE_PREFER_NICKS = \ u'Show torchat nick if available instead of id to conference members' From 0ae66ba51d9b498f31fbbe6b1b8a5fdc0cf18bc5 Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Sun, 3 Nov 2013 05:05:23 +0400 Subject: [PATCH 34/83] conference says welcome to user one time --- torchat/src/plugins/conference.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/torchat/src/plugins/conference.py b/torchat/src/plugins/conference.py index 43331658..fbe35687 100644 --- a/torchat/src/plugins/conference.py +++ b/torchat/src/plugins/conference.py @@ -434,8 +434,9 @@ def message_execute(self): _add_me_execute = torchat.tc_client.ProtocolMsg_add_me.execute def add_me_execute(self): + welcome = self.buddy not in buddy_list().list _add_me_execute(self) - if int(get('welcome_help')) == 1: + if int(get('welcome_help')) == 1 and welcome: do_help(self.buddy, None) torchat.tc_client.ProtocolMsg_add_me.execute = add_me_execute From e2e2eb2f8a2a4519391b04bf9a71320c96cb2229 Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Sun, 3 Nov 2013 05:10:18 +0400 Subject: [PATCH 35/83] show topic and description in conference help --- torchat/src/plugins/conference.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/torchat/src/plugins/conference.py b/torchat/src/plugins/conference.py index fbe35687..d5943042 100644 --- a/torchat/src/plugins/conference.py +++ b/torchat/src/plugins/conference.py @@ -65,6 +65,10 @@ !add_admin nick set nick's role to admin !remove_admin nick set nick's role to user ''' +WELCOME = '''%s +Topic: %s + +Description: %s''' def load(torchat): torchat.config.config_defaults['conference', 'prefer_nicks'] = 1 @@ -168,7 +172,10 @@ def splitLine(line): return torchat.tc_client.splitLine(line) def do_help(me, _): - me.sendChatMessage(HELP[role_of(me.address)]) + topic = buddy_list().own_buddy.profile_name + description = buddy_list().own_buddy.profile_text + text = WELCOME % (HELP[role_of(me.address)], topic, description) + me.sendChatMessage(text) def do_list(me, _): list_for_moder = can(me.address, 'list_for_moder') if int(get('allow_list')) != 1 and not list_for_moder: From fa22551a479f2781b92d74747188d1fc52fdcc5e Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Sun, 3 Nov 2013 05:37:05 +0400 Subject: [PATCH 36/83] conference ban is just another role --- torchat/src/plugins/conference.py | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/torchat/src/plugins/conference.py b/torchat/src/plugins/conference.py index d5943042..c776c729 100644 --- a/torchat/src/plugins/conference.py +++ b/torchat/src/plugins/conference.py @@ -17,10 +17,11 @@ 'show_admin_actions', 'show_enter_leave', 'welcome_help']) OWNER = ADMIN | set(['add_admin', 'remove_admin']) -ROLES = {'nobody': NOBODY, 'guest': GUEST, 'user': USER, +ROLES = {'banned': set(), 'nobody': NOBODY, 'guest': GUEST, 'user': USER, 'moder': MODER, 'admin': ADMIN, 'owner': OWNER} HELP = {} +HELP['banned'] = 'You are banned' HELP['nobody'] = '''[help] !help get help ''' @@ -43,7 +44,7 @@ !unmute nick undo mute (role: guest,nobody->user) !kick nick kick nick from room !invite nick invite nick to room -!ban nick ban nick (needs Ban plugin) +!ban nick ban nick !unban nick undo ban !topic text change topic of room !description text change description of room @@ -263,16 +264,15 @@ def do_ban(me, nick): if role_of(buddy.address) not in ('nobody', 'guest', 'user'): me.sendChatMessage('[room] You can ban nobody,guest,user') return - ban_list = json.loads(torchat.config.get("ban", 'list')) - ban_list[buddy.address] = 1 - torchat.config.set("ban", 'list', json.dumps(ban_list)) + set_role(buddy.address, 'banned') buddy_list().removeBuddy(buddy, disconnect=False) announce('%s banned %s' % (nick_repr(me), nick_repr(buddy)), True) def do_unban(me, address): + if role_of(address) != 'banned': + me.sendChatMessage('[room] The address is not banned') + return + set_role(address, 'user') announce('%s unbanned %s' % (nick_repr(me), address), True) - ban_list = json.loads(torchat.config.get("ban", 'list')) - ban_list.pop(address, None) - torchat.config.set("ban", 'list', json.dumps(ban_list)) def do_topic(me, topic): torchat.config.set("profile", "name", topic) for buddy in buddy_list().list: @@ -442,9 +442,12 @@ def message_execute(self): _add_me_execute = torchat.tc_client.ProtocolMsg_add_me.execute def add_me_execute(self): welcome = self.buddy not in buddy_list().list - _add_me_execute(self) - if int(get('welcome_help')) == 1 and welcome: - do_help(self.buddy, None) + if role_of(self.buddy.address) != 'banned': + _add_me_execute(self) + if int(get('welcome_help')) == 1 and welcome: + do_help(self.buddy, None) + else: + self.buddy.sendChatMessage('[room] You are banned') torchat.tc_client.ProtocolMsg_add_me.execute = add_me_execute torchat.TRANSLATIONS['en'].DSET_MISC_CONFERENCE_PREFER_NICKS = \ From fcb5440911bfc73eca1cf062212bf026277a576b Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Sun, 3 Nov 2013 05:45:53 +0400 Subject: [PATCH 37/83] conference default_mode can be banned --- torchat/src/plugins/conference.py | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/torchat/src/plugins/conference.py b/torchat/src/plugins/conference.py index c776c729..ccf50c61 100644 --- a/torchat/src/plugins/conference.py +++ b/torchat/src/plugins/conference.py @@ -51,16 +51,19 @@ !set_avatar nick set avatar of nick as room's avatar ''' HELP['admin'] = HELP['moder'] + ''' -!role [nobody|guest|user|moder] nick get or set role of nick -!prefer_nicks [yes|no] get or set prefer_nicks -!allow_list [yes|no] get or set allow_list -!allow_pm [yes|no] get or set allow_pm -!list_status [yes|no] get or set list_status -!list_role [yes|no] get or set list_role -!default_role [nobody|guest|user] get or set default_role -!show_admin_actions [yes|no] get or set show_admin_actions -!show_enter_leave [yes|no] get or set show_enter_leave -!welcome_help [yes|no] get or set welcome_help +!role [nobody|guest|user|moder] nick get or set role of nick +!prefer_nicks [yes|no] get or set prefer_nicks +!allow_list [yes|no] get or set allow_list +!allow_pm [yes|no] get or set allow_pm +!list_status [yes|no] get or set list_status +!list_role [yes|no] get or set list_role +!default_role [banned|nobody|guest|user] get or set default_role +!show_admin_actions [yes|no] get or set show_admin_actions +!show_enter_leave [yes|no] get or set show_enter_leave +!welcome_help [yes|no] get or set welcome_help + +To make closed conference, set role of each user to 'user' explicitly +and then set default_role=banned. ''' HELP['owner'] = HELP['admin'] + ''' !add_admin nick set nick's role to admin @@ -359,7 +362,7 @@ def do_show_enter_leave(me, yes_no): def do_welcome_help(me, yes_no): yes_no_command(me, 'welcome_help', yes_no) def do_default_role(me, role): - if role in ('nobody', 'guest', 'user'): + if role in ('banned', 'nobody', 'guest', 'user'): # set set_option('default_role', role) announce('%s set default role to %s' % From 68b8b031d268dd7c8876cbd80ee2a60cb9d93630 Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Sun, 3 Nov 2013 06:03:11 +0400 Subject: [PATCH 38/83] conference password --- torchat/src/plugins/conference.py | 32 +++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/torchat/src/plugins/conference.py b/torchat/src/plugins/conference.py index ccf50c61..602fb586 100644 --- a/torchat/src/plugins/conference.py +++ b/torchat/src/plugins/conference.py @@ -14,7 +14,7 @@ 'topic', 'description', 'set_avatar', 'list_for_moder']) ADMIN = MODER | set(['role', 'prefer_nicks', 'allow_list', 'allow_pm', 'list_status', 'list_role', 'default_role', - 'show_admin_actions', 'show_enter_leave', 'welcome_help']) + 'show_admin_actions', 'show_enter_leave', 'welcome_help', 'password']) OWNER = ADMIN | set(['add_admin', 'remove_admin']) ROLES = {'banned': set(), 'nobody': NOBODY, 'guest': GUEST, 'user': USER, @@ -61,6 +61,7 @@ !show_admin_actions [yes|no] get or set show_admin_actions !show_enter_leave [yes|no] get or set show_enter_leave !welcome_help [yes|no] get or set welcome_help +!password [password] get or set room password To make closed conference, set role of each user to 'user' explicitly and then set default_role=banned. @@ -86,6 +87,7 @@ def load(torchat): torchat.config.config_defaults['conference', 'show_admin_actions'] = 1 torchat.config.config_defaults['conference', 'show_enter_leave'] = 1 torchat.config.config_defaults['conference', 'welcome_help'] = 1 + torchat.config.config_defaults['conference', 'password'] = '' torchat.config.config_defaults['conference', 'ignored'] = '{"who-bywho":1}' def sstatus(status): @@ -370,6 +372,14 @@ def do_default_role(me, role): elif not role: # get me.sendChatMessage('[room] default_role=%s' % get('default_role')) + def do_password(me, password): + if password: + # set + set_option('password', password) + announce('%s set password to %s' % (nick_repr(me), password), True) + else: + # get + me.sendChatMessage('[room] password=%s' % get('password')) def do_add_admin(me, nick): buddy = buddy_from_nick(nick, me) if not buddy: @@ -421,6 +431,13 @@ def message_execute(self): _message_execute(self) if goood_message: me = self.buddy + if get('password') and role_of(me.address) == 'nobody': + if self.text == get('password'): + set_role(me.address, get('default_role')) + announce('%s entered password' % nick_repr(me), False) + else: + me.sendChatMessage('[room] Wrong password') + return if self.text.startswith('!'): command, argument = splitLine(self.text) command = command[1:] # pop "!" @@ -445,12 +462,15 @@ def message_execute(self): _add_me_execute = torchat.tc_client.ProtocolMsg_add_me.execute def add_me_execute(self): welcome = self.buddy not in buddy_list().list - if role_of(self.buddy.address) != 'banned': - _add_me_execute(self) - if int(get('welcome_help')) == 1 and welcome: - do_help(self.buddy, None) - else: + if role_of(self.buddy.address) == 'banned': self.buddy.sendChatMessage('[room] You are banned') + return + _add_me_execute(self) + if int(get('welcome_help')) == 1 and welcome: + do_help(self.buddy, None) + if get('password') and welcome: + set_role(self.buddy.address, 'nobody') + self.buddy.sendChatMessage('[room] Enter password, please') torchat.tc_client.ProtocolMsg_add_me.execute = add_me_execute torchat.TRANSLATIONS['en'].DSET_MISC_CONFERENCE_PREFER_NICKS = \ From 4aa1dc5390368b91ab70834f04a0875616bd620a Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Sun, 3 Nov 2013 06:05:43 +0400 Subject: [PATCH 39/83] conference announce with [admin] and [user] --- torchat/src/plugins/conference.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/torchat/src/plugins/conference.py b/torchat/src/plugins/conference.py index 602fb586..d71edd0e 100644 --- a/torchat/src/plugins/conference.py +++ b/torchat/src/plugins/conference.py @@ -163,7 +163,8 @@ def nick_repr(buddy, moder=False): nick += ' [%s]' % sstatus(buddy.status) return nick def announce(text, moder): - text = '[room] %s' % text + prefix = '[admin]' if moder else '[user]' + text = '%s %s' % (prefix, text) for buddy in buddy_list().list: if not can(buddy.address, 'read'): continue From e565c4e7264e8917a6ed480e88150bcfba998156 Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Sun, 3 Nov 2013 06:14:39 +0400 Subject: [PATCH 40/83] conference error with list_role fixed --- torchat/src/plugins/conference.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/torchat/src/plugins/conference.py b/torchat/src/plugins/conference.py index d71edd0e..f0d93811 100644 --- a/torchat/src/plugins/conference.py +++ b/torchat/src/plugins/conference.py @@ -153,13 +153,14 @@ def nick_repr(buddy, moder=False): nick = buddy.profile_name if moder: nick += ' (%s)' % buddy.address - if moder or get('list_role'): + if moder or int(get('list_role')) == 1: buddy_role = role_of(buddy.address) if buddy_role in ('admin', 'owner'): nick = '@' + nick if buddy_role == 'moder': nick = '%' + nick - if get('list_status') and buddy.status != torchat.tc_client.STATUS_ONLINE: + if int(get('list_status')) == 1 and \ + buddy.status != torchat.tc_client.STATUS_ONLINE: nick += ' [%s]' % sstatus(buddy.status) return nick def announce(text, moder): From df76cf17f399e1d9a3e42ab76b95dd359d111130 Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Sun, 3 Nov 2013 06:15:08 +0400 Subject: [PATCH 41/83] conference shows user's role in !list --- torchat/src/plugins/conference.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/torchat/src/plugins/conference.py b/torchat/src/plugins/conference.py index f0d93811..47d9079e 100644 --- a/torchat/src/plugins/conference.py +++ b/torchat/src/plugins/conference.py @@ -185,13 +185,15 @@ def do_help(me, _): text = WELCOME % (HELP[role_of(me.address)], topic, description) me.sendChatMessage(text) def do_list(me, _): - list_for_moder = can(me.address, 'list_for_moder') - if int(get('allow_list')) != 1 and not list_for_moder: + if int(get('allow_list')) != 1 and not is_moder(me.address): me.sendChatMessage('[room] Action not allowed') return nicks = [] for buddy in buddy_list().list: - nicks.append(nick_repr(buddy, list_for_moder)) + nick = nick_repr(buddy, is_moder(me.address)) + if int(get('list_role')) == 1 or is_moder(me.address): + nick += ' /%s/' % role_of(buddy.address) + nicks.append(nick) me.sendChatMessage('[room]\n' + '\n'.join(nicks)) def do_ignore(me, nick): buddy = buddy_from_nick(nick, me) From d131625e55e8e705094f80b962b962656ce28dac Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Sun, 3 Nov 2013 14:38:09 +0400 Subject: [PATCH 42/83] remove conference role list_for_moder, not used --- torchat/src/plugins/conference.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/torchat/src/plugins/conference.py b/torchat/src/plugins/conference.py index 47d9079e..d3b01bd9 100644 --- a/torchat/src/plugins/conference.py +++ b/torchat/src/plugins/conference.py @@ -11,7 +11,7 @@ GUEST = NOBODY | set(['read_actions', 'read', 'list', 'ignore', 'unignore']) USER = GUEST | set(['write', 'pm']) MODER = USER | set(['mute', 'unmute', 'kick', 'invite', 'ban', 'unban', - 'topic', 'description', 'set_avatar', 'list_for_moder']) + 'topic', 'description', 'set_avatar']) ADMIN = MODER | set(['role', 'prefer_nicks', 'allow_list', 'allow_pm', 'list_status', 'list_role', 'default_role', 'show_admin_actions', 'show_enter_leave', 'welcome_help', 'password']) From 0d358c8153dbdd3a6f2ef0e1f2f356ecbfd08d01 Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Sun, 3 Nov 2013 14:50:21 +0400 Subject: [PATCH 43/83] conference announce when user left room --- torchat/src/plugins/conference.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/torchat/src/plugins/conference.py b/torchat/src/plugins/conference.py index d3b01bd9..c544f551 100644 --- a/torchat/src/plugins/conference.py +++ b/torchat/src/plugins/conference.py @@ -477,6 +477,14 @@ def add_me_execute(self): self.buddy.sendChatMessage('[room] Enter password, please') torchat.tc_client.ProtocolMsg_add_me.execute = add_me_execute + _remove_me_execute = torchat.tc_client.ProtocolMsg_remove_me.execute + def remove_me_execute(self): + user_left = self.buddy and self.buddy in buddy_list().list + nick = nick_repr(self.buddy) + _remove_me_execute(self) + announce('%s left room' % nick, False) + torchat.tc_client.ProtocolMsg_remove_me.execute = remove_me_execute + torchat.TRANSLATIONS['en'].DSET_MISC_CONFERENCE_PREFER_NICKS = \ u'Show torchat nick if available instead of id to conference members' torchat.TRANSLATIONS['ru'].DSET_MISC_CONFERENCE_PREFER_NICKS = \ From 5432ec548ae610782c18deccfd3bdccc5c218831 Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Sun, 3 Nov 2013 14:56:50 +0400 Subject: [PATCH 44/83] add plugins to make_*.py --- torchat/src/make_debian_package.py | 2 ++ torchat/src/make_release_zip.py | 3 +++ 2 files changed, 5 insertions(+) diff --git a/torchat/src/make_debian_package.py b/torchat/src/make_debian_package.py index 94e5e78c..96ca2ae5 100755 --- a/torchat/src/make_debian_package.py +++ b/torchat/src/make_debian_package.py @@ -86,11 +86,13 @@ "usr/lib/torchat", "usr/lib/torchat/SocksiPy", "usr/lib/torchat/translations", + "usr/lib/torchat/plugins", "usr/lib/torchat/Tor", ] files = [("translations/*.py", "usr/lib/torchat/translations"), ("translations/*.txt", "usr/lib/torchat/translations"), + ("plugins/*", "usr/lib/torchat/plugins"), ("icons/*", "usr/share/pixmaps/torchat"), ("SocksiPy/__init__.py", "usr/lib/torchat/SocksiPy"), ("SocksiPy/socks.py", "usr/lib/torchat/SocksiPy"), diff --git a/torchat/src/make_release_zip.py b/torchat/src/make_release_zip.py index 5a1acdb7..8831ff7c 100644 --- a/torchat/src/make_release_zip.py +++ b/torchat/src/make_release_zip.py @@ -95,6 +95,8 @@ def zipSrc(zipfile_name): "src\\translations\\insert_missing.py", "src\\translations\\__init__.py", + "src\\plugins\\*", + "src\\SocksiPy\\*.py", "src\\SocksiPy\\BUGS", "src\\SocksiPy\\LICENSE", @@ -130,6 +132,7 @@ def clean(folder): def cleanSrc(): clean(".") clean("translations") + clean("plugins") clean("SocksiPy") # ------------------ From 4d17607418d5144728cdd554dc100ac526e5e3fd Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Sun, 3 Nov 2013 15:18:57 +0400 Subject: [PATCH 45/83] conference gui preferences --- torchat/src/plugins/conference.py | 88 +++++++++++++++---------------- 1 file changed, 43 insertions(+), 45 deletions(-) diff --git a/torchat/src/plugins/conference.py b/torchat/src/plugins/conference.py index c544f551..a5796687 100644 --- a/torchat/src/plugins/conference.py +++ b/torchat/src/plugins/conference.py @@ -485,55 +485,53 @@ def remove_me_execute(self): announce('%s left room' % nick, False) torchat.tc_client.ProtocolMsg_remove_me.execute = remove_me_execute - torchat.TRANSLATIONS['en'].DSET_MISC_CONFERENCE_PREFER_NICKS = \ - u'Show torchat nick if available instead of id to conference members' - torchat.TRANSLATIONS['ru'].DSET_MISC_CONFERENCE_PREFER_NICKS = \ - u'Показывать ник отправителя вместо id, если ник выставлен' - torchat.TRANSLATIONS['en'].DSET_MISC_CONFERENCE_NO_GUI = \ - u'Do not reflect new messages in GUI' - torchat.TRANSLATIONS['ru'].DSET_MISC_CONFERENCE_NO_GUI = \ - u'Не отображать новые сообщения в графическом интерфейсе' - torchat.TRANSLATIONS['en'].DSET_MISC_CONFERENCE_DEFAULT_ROLE = \ - u'Default role for new members (nobody|guest|user)' - torchat.TRANSLATIONS['ru'].DSET_MISC_CONFERENCE_DEFAULT_ROLE = \ - u'Роль по умолчанию для новых членов (nobody|guest|user)' - torchat.TRANSLATIONS['en'].DSET_MISC_CONFERENCE_ALLOW_LIST = \ - u'Regular users can get list of users' - torchat.TRANSLATIONS['ru'].DSET_MISC_CONFERENCE_ALLOW_LIST = \ - u'Обычные пользователи могут смотреть список пользователей' - torchat.TRANSLATIONS['en'].DSET_MISC_CONFERENCE_ALLOW_PM = \ - u'Allow private messages' - torchat.TRANSLATIONS['ru'].DSET_MISC_CONFERENCE_ALLOW_PM = \ - u'Разрешить личные сообщения' - torchat.TRANSLATIONS['en'].DSET_MISC_CONFERENCE_LIST_STATUS = \ - u'Regular users view status of users' - torchat.TRANSLATIONS['ru'].DSET_MISC_CONFERENCE_LIST_STATUS = \ - u'Обычные пользователи видят статус пользователей' - torchat.TRANSLATIONS['en'].DSET_MISC_CONFERENCE_LIST_ROLE = \ - u'Regular users view role of users' - torchat.TRANSLATIONS['ru'].DSET_MISC_CONFERENCE_LIST_ROLE = \ - u'Обычные пользователи видят роль пользователей' - torchat.TRANSLATIONS['en'].DSET_MISC_CONFERENCE_SHOW_ADMIN_ACTIONS = \ - u"Regular users view administrators' actions" - torchat.TRANSLATIONS['ru'].DSET_MISC_CONFERENCE_SHOW_ADMIN_ACTIONS = \ - u'Обычные пользователи видят действия администраторов' - torchat.TRANSLATIONS['en'].DSET_MISC_CONFERENCE_SHOW_ENTER_LEAVE = \ - u"Regular users view somebody enter or leave room" - torchat.TRANSLATIONS['ru'].DSET_MISC_CONFERENCE_SHOW_ADMIN_ACTIONS = \ - u'Обычные пользователи видят, когда кто-то входит или выходит' - torchat.TRANSLATIONS['en'].DSET_MISC_CONFERENCE_WELCOME_HELP = \ - u"Welcome new users with help message" - torchat.TRANSLATIONS['ru'].DSET_MISC_CONFERENCE_WELCOME_HELP = \ - u'Приветствовать новых пользователей справкой' + def set_tr(lang, option, translation): + setattr(torchat.TRANSLATIONS[lang], + 'DSET_CONFERENCE_' + option.upper(), translation) + set_tr('en', 'no_gui', u'Do not reflect new messages in GUI') + set_tr('ru', 'no_gui', u'Не отображать новые сообщения в графическом интерфейсе') + set_tr('en', 'prefer_nicks', u'Show torchat nick if available instead of id to conference members') + set_tr('ru', 'prefer_nicks', u'Показывать ник отправителя вместо id, если ник выставлен') + set_tr('en', 'default_role', u'Default role for new members (banned|nobody|guest|user)') + set_tr('ru', 'default_role', u'Роль по умолчанию для новых членов (banned|nobody|guest|user)') + set_tr('en', 'allow_list', u'Regular users can get list of users') + set_tr('ru', 'allow_list', u'Обычные пользователи могут смотреть список пользователей') + set_tr('en', 'allow_pm', u'Allow private messages') + set_tr('ru', 'allow_pm', u'Разрешить личные сообщения') + set_tr('en', 'list_status', u'Regular users view status of users') + set_tr('ru', 'list_status', u'Обычные пользователи видят статус пользователей') + set_tr('en', 'list_role', u'Regular users view role of users') + set_tr('ru', 'list_role', u'Обычные пользователи видят роль пользователей') + set_tr('en', 'show_admin_actions', u"Regular users view administrators' actions") + set_tr('ru', 'show_admin_actions', u'Обычные пользователи видят действия администраторов') + set_tr('en', 'show_enter_leave', u'Regular users view somebody enter or leave room') + set_tr('ru', 'show_enter_leave', u'Обычные пользователи видят, когда кто-то входит или выходит') + set_tr('en', 'welcome_help', u'Welcome new users with help message') + set_tr('ru', 'welcome_help', u'Приветствовать новых пользователей справкой') torchat.config.importLanguage() _constructor = torchat.dlg_settings.Dialog.__init__ def constructor(self, main_window): _constructor(self, main_window) - torchat.dlg.Check(self.p3, torchat.dlg_settings.lang.DSET_MISC_CONFERENCE_PREFER_NICKS, - ("conference", "prefer_nicks")) - torchat.dlg.Check(self.p3, torchat.dlg_settings.lang.DSET_MISC_CONFERENCE_NO_GUI, - ("conference", "no_gui")) - # TODO + def tr(option): + attr_name = 'DSET_CONFERENCE_' + option.upper() + if hasattr(torchat.dlg_settings.lang, attr_name): + return getattr(torchat.dlg_settings.lang, attr_name) + else: + return option + def check(self, option): + torchat.dlg.Check(self.p3, tr(option), ("conference", option)) + def text(self, option): + torchat.dlg.Text(self.p3, tr(option), ("conference", option)) + check(self, 'no_gui') + check(self, 'prefer_nicks') + check(self, 'allow_list') + check(self, 'allow_pm') + check(self, 'list_status') + check(self, 'list_role') + check(self, 'show_admin_actions') + check(self, 'show_enter_leave') + check(self, 'welcome_help') + text(self, 'default_role') torchat.dlg_settings.Dialog.__init__ = constructor From 60ca212124a67bb8b8ab24843107a01f31f1c794 Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Sun, 3 Nov 2013 15:54:24 +0400 Subject: [PATCH 46/83] save outer_sizer in self object (dlg_settings) and fit tabs 1-4 --- torchat/src/dlg_settings.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/torchat/src/dlg_settings.py b/torchat/src/dlg_settings.py index cc18d38a..999f67e6 100644 --- a/torchat/src/dlg_settings.py +++ b/torchat/src/dlg_settings.py @@ -28,16 +28,16 @@ def __init__(self, main_window): #1 outer panel and vertical sizer self.outer_panel = wx.Panel(self) - outer_sizer = wx.BoxSizer(wx.VERTICAL) - self.outer_panel.SetSizer(outer_sizer) + self.outer_sizer = wx.BoxSizer(wx.VERTICAL) + self.outer_panel.SetSizer(self.outer_sizer) #1.1 the notebook on the top self.notebook = wx.Notebook(self.outer_panel) - outer_sizer.Add(self.notebook, 1, wx.EXPAND|wx.LEFT|wx.TOP|wx.RIGHT, border=5) + self.outer_sizer.Add(self.notebook, 1, wx.EXPAND|wx.LEFT|wx.TOP|wx.RIGHT, border=5) #1.2 the button_sizer at the bottom button_sizer = wx.BoxSizer(wx.HORIZONTAL) - outer_sizer.Add(button_sizer, 0, wx.ALIGN_RIGHT | wx.ALL, border=5) + self.outer_sizer.Add(button_sizer, 0, wx.ALIGN_RIGHT | wx.ALL, border=5) #1.2.1 cancel button btn_cancel = wx.Button(self.outer_panel, wx.ID_CANCEL, lang.BTN_CANCEL) @@ -87,6 +87,7 @@ def __init__(self, main_window): dlg.Check(self.p2, lang.DSET_GUI_NOTIFICATION_POPUP, ("gui", "notification_popup")) dlg.Text(self.p2, lang.DSET_GUI_NOTIFICATION_METHOD, ("gui", "notification_method")) dlg.Check(self.p2, lang.DSET_GUI_FLASH_WINDOW, ("gui", "notification_flash_window")) + self.p2.fit() #3.3 misc options self.p3 = dlg.Panel(self.notebook) @@ -97,6 +98,7 @@ def __init__(self, main_window): self.chk_tmp.wx_ctrl.Bind(wx.EVT_CHECKBOX, self.onChkTmp) self.client = dlg.Text(self.p3, lang.DSET_MISC_REPORT_CLIENT, ("client", "reported_client")) self.version = dlg.Text(self.p3, lang.DSET_MISC_REPORT_VERSION, ("client", "reported_version")) + self.p3.fit() #3.4 plugins self.p4 = dlg.Panel(self.notebook) @@ -108,9 +110,10 @@ def __init__(self, main_window): plugin_dscr = getattr(lang, 'DSET_PLUGIN_' + plugin_name.upper(), plugin_name) enabled = int(bool(plugin_name in enabled_plugins)) self.plugins[plugin_name] = dlg.Check(self.p4, plugin_dscr, enabled) + self.p4.fit() #4 fit the sizers - outer_sizer.Fit(self) + self.outer_sizer.Fit(self) def onChkTmp(self, evt): self.dir_tmp.setEnabled(not self.chk_tmp.getValue()) From 0b0e20f5614ffca555e28355a29a73e76a32a472 Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Sun, 3 Nov 2013 15:55:39 +0400 Subject: [PATCH 47/83] conference preferences fit tab p3 --- torchat/src/plugins/conference.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/torchat/src/plugins/conference.py b/torchat/src/plugins/conference.py index a5796687..2c6adbeb 100644 --- a/torchat/src/plugins/conference.py +++ b/torchat/src/plugins/conference.py @@ -533,5 +533,7 @@ def text(self, option): check(self, 'show_enter_leave') check(self, 'welcome_help') text(self, 'default_role') + self.p3.fit() + self.outer_sizer.Fit(self) torchat.dlg_settings.Dialog.__init__ = constructor From 6db1578bdd658587b3e880c026968e6d2b3bdb8a Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Sun, 3 Nov 2013 16:05:17 +0400 Subject: [PATCH 48/83] conference preferences in Conference tab --- torchat/src/plugins/conference.py | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/torchat/src/plugins/conference.py b/torchat/src/plugins/conference.py index 2c6adbeb..4c569ef9 100644 --- a/torchat/src/plugins/conference.py +++ b/torchat/src/plugins/conference.py @@ -488,6 +488,8 @@ def remove_me_execute(self): def set_tr(lang, option, translation): setattr(torchat.TRANSLATIONS[lang], 'DSET_CONFERENCE_' + option.upper(), translation) + set_tr('en', 'title', u'Conference') + set_tr('ru', 'title', u'Конференция') set_tr('en', 'no_gui', u'Do not reflect new messages in GUI') set_tr('ru', 'no_gui', u'Не отображать новые сообщения в графическом интерфейсе') set_tr('en', 'prefer_nicks', u'Show torchat nick if available instead of id to conference members') @@ -510,9 +512,12 @@ def set_tr(lang, option, translation): set_tr('ru', 'welcome_help', u'Приветствовать новых пользователей справкой') torchat.config.importLanguage() - _constructor = torchat.dlg_settings.Dialog.__init__ - def constructor(self, main_window): - _constructor(self, main_window) + _dlg_settings_constructor = torchat.dlg_settings.Dialog.__init__ + def dlg_settings_constructor(self, main_window): + _dlg_settings_constructor(self, main_window) + self.p_conference = torchat.dlg.Panel(self.notebook) + self.notebook.AddPage(self.p_conference, + torchat.dlg_settings.lang.DSET_CONFERENCE_TITLE) def tr(option): attr_name = 'DSET_CONFERENCE_' + option.upper() if hasattr(torchat.dlg_settings.lang, attr_name): @@ -520,9 +525,9 @@ def tr(option): else: return option def check(self, option): - torchat.dlg.Check(self.p3, tr(option), ("conference", option)) + torchat.dlg.Check(self.p_conference, tr(option), ("conference", option)) def text(self, option): - torchat.dlg.Text(self.p3, tr(option), ("conference", option)) + torchat.dlg.Text(self.p_conference, tr(option), ("conference", option)) check(self, 'no_gui') check(self, 'prefer_nicks') check(self, 'allow_list') @@ -533,7 +538,12 @@ def text(self, option): check(self, 'show_enter_leave') check(self, 'welcome_help') text(self, 'default_role') - self.p3.fit() + self.p_conference.fit() self.outer_sizer.Fit(self) - torchat.dlg_settings.Dialog.__init__ = constructor + torchat.dlg_settings.Dialog.__init__ = dlg_settings_constructor + _dlg_settings_onOk = torchat.dlg_settings.Dialog.onOk + def dlg_settings_onOk(self, evt): + _dlg_settings_onOk(self, evt) + self.p_conference.saveAllData() + torchat.dlg_settings.Dialog.onOk = dlg_settings_onOk From 32293ae0acc652dffceaa81dba57d759886f43de Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Sun, 3 Nov 2013 16:21:40 +0400 Subject: [PATCH 49/83] conference option receiver_status --- torchat/src/plugins/conference.py | 37 +++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/torchat/src/plugins/conference.py b/torchat/src/plugins/conference.py index 4c569ef9..0880705c 100644 --- a/torchat/src/plugins/conference.py +++ b/torchat/src/plugins/conference.py @@ -12,7 +12,7 @@ USER = GUEST | set(['write', 'pm']) MODER = USER | set(['mute', 'unmute', 'kick', 'invite', 'ban', 'unban', 'topic', 'description', 'set_avatar']) -ADMIN = MODER | set(['role', 'prefer_nicks', +ADMIN = MODER | set(['role', 'prefer_nicks', 'receiver_status', 'allow_list', 'allow_pm', 'list_status', 'list_role', 'default_role', 'show_admin_actions', 'show_enter_leave', 'welcome_help', 'password']) OWNER = ADMIN | set(['add_admin', 'remove_admin']) @@ -53,6 +53,8 @@ HELP['admin'] = HELP['moder'] + ''' !role [nobody|guest|user|moder] nick get or set role of nick !prefer_nicks [yes|no] get or set prefer_nicks +!receiver_status [offline,][handshake,][online,][away,][busy] + get or set list of allowed receiver statuses !allow_list [yes|no] get or set allow_list !allow_pm [yes|no] get or set allow_pm !list_status [yes|no] get or set list_status @@ -77,6 +79,7 @@ def load(torchat): torchat.config.config_defaults['conference', 'prefer_nicks'] = 1 + torchat.config.config_defaults['conference', 'receiver_status'] = 'online,away' torchat.config.config_defaults['conference', 'no_gui'] = 0 torchat.config.config_defaults['conference', 'roles'] = '{}' torchat.config.config_defaults['conference', 'default_role'] = 'user' @@ -101,6 +104,7 @@ def sstatus(status): return 'away' if status == torchat.tc_client.STATUS_XA: return 'busy' + STATUSES = set(['offline', 'handshake', 'online', 'away', 'busy']) def buddy_list(): return torchat.app.mw.buddy_list def get(option): @@ -169,12 +173,13 @@ def announce(text, moder): for buddy in buddy_list().list: if not can(buddy.address, 'read'): continue - if moder and not is_moder(buddy.address) \ - and int(get("show_admin_actions")) != 1: - continue - if not moder and not is_moder(buddy.address) \ - and int(get("show_enter_leave")) != 1: - continue + if not is_moder(buddy.address): + if moder and int(get("show_admin_actions")) != 1: + continue + if not moder and int(get("show_enter_leave")) != 1: + continue + if sstatus(buddy.status) not in get('receiver_status'): + continue buddy.sendChatMessage(text) def splitLine(line): return torchat.tc_client.splitLine(line) @@ -376,6 +381,19 @@ def do_default_role(me, role): elif not role: # get me.sendChatMessage('[room] default_role=%s' % get('default_role')) + def do_receiver_status(me, statuses): + if statuses: + # set + statuses = set(statuses.split(',')) + if not all(status in STATUSES for status in statuses): + me.sendChatMessage('[room] Bad status') + return + set_option('receiver_status', ','.join(statuses)) + announce('%s set receiver statuses to %s' % + (nick_repr(me), ','.join(statuses)), True) + else: + # get + me.sendChatMessage('[room] receiver_status=%s' % get('receiver_status')) def do_password(me, password): if password: # set @@ -422,6 +440,8 @@ def resend(me, text): continue if is_ignored(me.address, buddy.address): continue + if sstatus(buddy.status) not in get('receiver_status'): + continue sender_nick = nick_repr(me, is_moder(buddy.address)) resent_message = '%s: %s' % (sender_nick, text) buddy.sendChatMessage(resent_message) @@ -510,6 +530,8 @@ def set_tr(lang, option, translation): set_tr('ru', 'show_enter_leave', u'Обычные пользователи видят, когда кто-то входит или выходит') set_tr('en', 'welcome_help', u'Welcome new users with help message') set_tr('ru', 'welcome_help', u'Приветствовать новых пользователей справкой') + set_tr('en', 'receiver_status', u'Statuses of receivers [offline,][handshake,][online,][away,][busy]') + set_tr('ru', 'receiver_status', u'Статусы получателей [offline,][handshake,][online,][away,][busy]') torchat.config.importLanguage() _dlg_settings_constructor = torchat.dlg_settings.Dialog.__init__ @@ -538,6 +560,7 @@ def text(self, option): check(self, 'show_enter_leave') check(self, 'welcome_help') text(self, 'default_role') + text(self, 'receiver_status') self.p_conference.fit() self.outer_sizer.Fit(self) torchat.dlg_settings.Dialog.__init__ = dlg_settings_constructor From 2eb6af4a5f79067ae9f1bcd2b383d3cad1b18666 Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Sun, 3 Nov 2013 16:26:15 +0400 Subject: [PATCH 50/83] conference GUI option password --- torchat/src/plugins/conference.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/torchat/src/plugins/conference.py b/torchat/src/plugins/conference.py index 0880705c..6bfd548f 100644 --- a/torchat/src/plugins/conference.py +++ b/torchat/src/plugins/conference.py @@ -532,6 +532,8 @@ def set_tr(lang, option, translation): set_tr('ru', 'welcome_help', u'Приветствовать новых пользователей справкой') set_tr('en', 'receiver_status', u'Statuses of receivers [offline,][handshake,][online,][away,][busy]') set_tr('ru', 'receiver_status', u'Статусы получателей [offline,][handshake,][online,][away,][busy]') + set_tr('en', 'password', u'Room enter password') + set_tr('ru', 'password', u'Пароль для входа в комнату') torchat.config.importLanguage() _dlg_settings_constructor = torchat.dlg_settings.Dialog.__init__ @@ -561,6 +563,7 @@ def text(self, option): check(self, 'welcome_help') text(self, 'default_role') text(self, 'receiver_status') + text(self, 'password') self.p_conference.fit() self.outer_sizer.Fit(self) torchat.dlg_settings.Dialog.__init__ = dlg_settings_constructor From e7bc968ba220ae835fa893ff48c523576ba2123c Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Sun, 3 Nov 2013 16:30:12 +0400 Subject: [PATCH 51/83] conference expand text preferences --- torchat/src/plugins/conference.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/torchat/src/plugins/conference.py b/torchat/src/plugins/conference.py index 6bfd548f..c52071d9 100644 --- a/torchat/src/plugins/conference.py +++ b/torchat/src/plugins/conference.py @@ -549,9 +549,11 @@ def tr(option): else: return option def check(self, option): - torchat.dlg.Check(self.p_conference, tr(option), ("conference", option)) + torchat.dlg.Check(self.p_conference, tr(option), + ("conference", option)) def text(self, option): - torchat.dlg.Text(self.p_conference, tr(option), ("conference", option)) + torchat.dlg.Text(self.p_conference, tr(option), + ("conference", option), expand=True) check(self, 'no_gui') check(self, 'prefer_nicks') check(self, 'allow_list') From 37e073c4e658896470f0c404e8fd6ff5aeecae05 Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Sun, 3 Nov 2013 16:59:40 +0400 Subject: [PATCH 52/83] conference set role of invited user to user --- torchat/src/plugins/conference.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/torchat/src/plugins/conference.py b/torchat/src/plugins/conference.py index c52071d9..658357e7 100644 --- a/torchat/src/plugins/conference.py +++ b/torchat/src/plugins/conference.py @@ -269,6 +269,8 @@ def do_invite(me, address): return buddy = torchat.tc_client.Buddy(address, buddy_list(), '') buddy_list().addBuddy(buddy) + if role_of(address) in ('banned', 'nobody', 'guest'): + set_role(address, 'user') announce('%s invited %s' % (nick_repr(me), address), True) def do_ban(me, nick): buddy = buddy_from_nick(nick, me) From 71835bf7829b624d72acc2072704743959ed9748 Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Sun, 3 Nov 2013 17:49:02 +0400 Subject: [PATCH 53/83] move password feature from to add_password plugin conference still can set password[_tip], but all work is performed by add_password --- torchat/src/plugins/add_password.py | 62 +++++++++++++++++++++++++++++ torchat/src/plugins/conference.py | 35 ++++++++-------- 2 files changed, 80 insertions(+), 17 deletions(-) create mode 100644 torchat/src/plugins/add_password.py diff --git a/torchat/src/plugins/add_password.py b/torchat/src/plugins/add_password.py new file mode 100644 index 00000000..8403fde9 --- /dev/null +++ b/torchat/src/plugins/add_password.py @@ -0,0 +1,62 @@ +# -*- coding: UTF-8 -*- + +NAME_en = u'Password protection against new contacts' +NAME_ru = u'Защита паролем от новых контактов' + +def load(torchat): + def get(option): + return torchat.config.get("password", option) + + torchat.config.config_defaults['password', 'password'] = '' + torchat.config.config_defaults['password', 'password_tip'] = '' + + _message_execute = torchat.tc_client.ProtocolMsg_message.execute + def message_execute(self): + if self.buddy and self.buddy not in self.bl.list and get('password'): + if get('password') in self.text: + self.buddy.sendChatMessage('Good password') + self.__class__ = torchat.tc_client.ProtocolMsg_add_me + _add_me_execute(self) + else: + self.buddy.sendChatMessage('Bad password') + return # to suppress warning sent by torchat and password passing + _message_execute(self) + torchat.tc_client.ProtocolMsg_message.execute = message_execute + + _add_me_execute = torchat.tc_client.ProtocolMsg_add_me.execute + def add_me_execute(self): + if self.buddy and self.buddy not in self.bl.list and get('password'): + message = u'Enter password' + if get('password_tip'): + message += u'. Password tip: %s' % get('password_tip') + self.buddy.sendChatMessage(message) + else: + _add_me_execute(self) + torchat.tc_client.ProtocolMsg_add_me.execute = add_me_execute + + def set_tr(lang, option, translation): + setattr(torchat.TRANSLATIONS[lang], + 'DSET_PASSWORD_' + option.upper(), translation) + set_tr('en', 'password', u'Password for new contacts') + set_tr('ru', 'password', u'Пароль для новых контактов') + set_tr('en', 'password_tip', u'Password tip') + set_tr('ru', 'password_tip', u'Подсказка о пароле') + torchat.config.importLanguage() + + _dlg_settings_constructor = torchat.dlg_settings.Dialog.__init__ + def dlg_settings_constructor(self, main_window): + _dlg_settings_constructor(self, main_window) + def tr(option): + attr_name = 'DSET_PASSWORD_' + option.upper() + if hasattr(torchat.dlg_settings.lang, attr_name): + return getattr(torchat.dlg_settings.lang, attr_name) + else: + return option + def text(self, option): + torchat.dlg.Text(self.p3, tr(option), + ("password", option), expand=True) + text(self, 'password') + text(self, 'password_tip') + self.p3.fit() + self.outer_sizer.Fit(self) + torchat.dlg_settings.Dialog.__init__ = dlg_settings_constructor diff --git a/torchat/src/plugins/conference.py b/torchat/src/plugins/conference.py index 658357e7..a62ed5b1 100644 --- a/torchat/src/plugins/conference.py +++ b/torchat/src/plugins/conference.py @@ -14,7 +14,8 @@ 'topic', 'description', 'set_avatar']) ADMIN = MODER | set(['role', 'prefer_nicks', 'receiver_status', 'allow_list', 'allow_pm', 'list_status', 'list_role', 'default_role', - 'show_admin_actions', 'show_enter_leave', 'welcome_help', 'password']) + 'show_admin_actions', 'show_enter_leave', 'welcome_help', + 'password', 'password_tip']) OWNER = ADMIN | set(['add_admin', 'remove_admin']) ROLES = {'banned': set(), 'nobody': NOBODY, 'guest': GUEST, 'user': USER, @@ -64,6 +65,9 @@ !show_enter_leave [yes|no] get or set show_enter_leave !welcome_help [yes|no] get or set welcome_help !password [password] get or set room password + (needs add_password plugin) +!password_tip [password tip] get or set room password tip + (needs add_password plugin) To make closed conference, set role of each user to 'user' explicitly and then set default_role=banned. @@ -90,7 +94,6 @@ def load(torchat): torchat.config.config_defaults['conference', 'show_admin_actions'] = 1 torchat.config.config_defaults['conference', 'show_enter_leave'] = 1 torchat.config.config_defaults['conference', 'welcome_help'] = 1 - torchat.config.config_defaults['conference', 'password'] = '' torchat.config.config_defaults['conference', 'ignored'] = '{"who-bywho":1}' def sstatus(status): @@ -399,11 +402,22 @@ def do_receiver_status(me, statuses): def do_password(me, password): if password: # set - set_option('password', password) + torchat.config.set('password', 'password', password) announce('%s set password to %s' % (nick_repr(me), password), True) else: # get - me.sendChatMessage('[room] password=%s' % get('password')) + password = torchat.config.get('password', 'password') + me.sendChatMessage('[room] password=%s' % password) + def do_password_tip(me, password_tip): + if password_tip: + # set + torchat.config.set('password', 'password_tip', password_tip) + announce('%s set password tip to %s' % + (nick_repr(me), password_tip), True) + else: + # get + password_tip = torchat.config.get('password', 'password_tip') + me.sendChatMessage('[room] password_tip=%s' % password_tip) def do_add_admin(me, nick): buddy = buddy_from_nick(nick, me) if not buddy: @@ -457,13 +471,6 @@ def message_execute(self): _message_execute(self) if goood_message: me = self.buddy - if get('password') and role_of(me.address) == 'nobody': - if self.text == get('password'): - set_role(me.address, get('default_role')) - announce('%s entered password' % nick_repr(me), False) - else: - me.sendChatMessage('[room] Wrong password') - return if self.text.startswith('!'): command, argument = splitLine(self.text) command = command[1:] # pop "!" @@ -494,9 +501,6 @@ def add_me_execute(self): _add_me_execute(self) if int(get('welcome_help')) == 1 and welcome: do_help(self.buddy, None) - if get('password') and welcome: - set_role(self.buddy.address, 'nobody') - self.buddy.sendChatMessage('[room] Enter password, please') torchat.tc_client.ProtocolMsg_add_me.execute = add_me_execute _remove_me_execute = torchat.tc_client.ProtocolMsg_remove_me.execute @@ -534,8 +538,6 @@ def set_tr(lang, option, translation): set_tr('ru', 'welcome_help', u'Приветствовать новых пользователей справкой') set_tr('en', 'receiver_status', u'Statuses of receivers [offline,][handshake,][online,][away,][busy]') set_tr('ru', 'receiver_status', u'Статусы получателей [offline,][handshake,][online,][away,][busy]') - set_tr('en', 'password', u'Room enter password') - set_tr('ru', 'password', u'Пароль для входа в комнату') torchat.config.importLanguage() _dlg_settings_constructor = torchat.dlg_settings.Dialog.__init__ @@ -567,7 +569,6 @@ def text(self, option): check(self, 'welcome_help') text(self, 'default_role') text(self, 'receiver_status') - text(self, 'password') self.p_conference.fit() self.outer_sizer.Fit(self) torchat.dlg_settings.Dialog.__init__ = dlg_settings_constructor From ce8a7f59baa1c0e736561e2f810a3459a5953078 Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Sun, 3 Nov 2013 17:54:39 +0400 Subject: [PATCH 54/83] import version in torchat.py --- torchat/src/torchat.py | 1 + 1 file changed, 1 insertion(+) diff --git a/torchat/src/torchat.py b/torchat/src/torchat.py index 9f07cfe8..c1947fa2 100755 --- a/torchat/src/torchat.py +++ b/torchat/src/torchat.py @@ -48,6 +48,7 @@ import dlg import dlg_settings import translations +import version # xx to module TRANSLATIONS = {} From 665021ef8483e0c16ee8e6fdaf4c02073bf83756 Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Sun, 3 Nov 2013 18:12:33 +0400 Subject: [PATCH 55/83] fake_user_agent plugin --- torchat/src/config.py | 3 -- torchat/src/dlg_settings.py | 10 ----- torchat/src/plugins/fake_user_agent.py | 61 ++++++++++++++++++++++++++ torchat/src/tc_client.py | 6 +-- torchat/src/translations/lang_en.py | 2 - 5 files changed, 63 insertions(+), 19 deletions(-) create mode 100644 torchat/src/plugins/fake_user_agent.py diff --git a/torchat/src/config.py b/torchat/src/config.py index 696e86ec..881a276b 100644 --- a/torchat/src/config.py +++ b/torchat/src/config.py @@ -21,7 +21,6 @@ import inspect import translations import shutil -import version def isWindows(): return sys.platform.startswith("win") @@ -39,8 +38,6 @@ def isWindows(): ("client", "own_hostname") : "0000000000000000", ("client", "listen_interface") : "127.0.0.1", ("client", "listen_port") : 0, - ("client", "reported_client") : version.NAME, - ("client", "reported_version") : version.VERSION, ("logging", "log_file") : "", ("logging", "log_level") : 0, ("files", "temp_files_in_data_dir") : 1, diff --git a/torchat/src/dlg_settings.py b/torchat/src/dlg_settings.py index 999f67e6..398a561d 100644 --- a/torchat/src/dlg_settings.py +++ b/torchat/src/dlg_settings.py @@ -96,8 +96,6 @@ def __init__(self, main_window): self.dir_tmp = dlg.Dir(self.p3, lang.DSET_MISC_TEMP_CUSTOM_DIR, ("files", "temp_files_custom_dir")) self.dir_tmp.setEnabled(not self.chk_tmp.getValue()) self.chk_tmp.wx_ctrl.Bind(wx.EVT_CHECKBOX, self.onChkTmp) - self.client = dlg.Text(self.p3, lang.DSET_MISC_REPORT_CLIENT, ("client", "reported_client")) - self.version = dlg.Text(self.p3, lang.DSET_MISC_REPORT_VERSION, ("client", "reported_version")) self.p3.fit() #3.4 plugins @@ -122,11 +120,6 @@ def onCancel(self, evt): evt.Skip() #let the frame now process the Cancel event def onOk(self, evt): - need_send_ua = False - if self.client.getValue() != config.get("client", "reported_client"): - need_send_ua = True - if self.version.getValue() != config.get("client", "reported_version"): - need_send_ua = True self.p1.saveAllData() self.p2.saveAllData() self.p3.saveAllData() @@ -140,7 +133,4 @@ def onOk(self, evt): if self.lang.getValue() != self.lang_old: config.importLanguage() evt.Skip() #let the frame now process the Ok event - if need_send_ua: - for buddy in self.mw.buddy_list.list: - buddy.sendVersion() diff --git a/torchat/src/plugins/fake_user_agent.py b/torchat/src/plugins/fake_user_agent.py new file mode 100644 index 00000000..c05ac9e5 --- /dev/null +++ b/torchat/src/plugins/fake_user_agent.py @@ -0,0 +1,61 @@ +# -*- coding: UTF-8 -*- + +NAME_en = u'Fake client and version' +NAME_ru = u'Подделывает отсылаемый клиент и версию' + +def load(torchat): + def get(option): + return torchat.config.get("fake_user_agent", option) + + torchat.config.config_defaults['fake_user_agent', 'client'] = \ + torchat.version.NAME + torchat.config.config_defaults['fake_user_agent', 'version'] = \ + torchat.version.VERSION + + _sendVersion = torchat.tc_client.Buddy.sendVersion + def sendVersion(self): + if self.isAlreadyPonged(): + msg = torchat.tc_client.ProtocolMsg_client(self, get('client')) + msg.send() + msg = torchat.tc_client.ProtocolMsg_version(self, get('version')) + msg.send() + else: + _sendVersion(self) + torchat.tc_client.Buddy.sendVersion = sendVersion + + def set_tr(lang, option, translation): + setattr(torchat.TRANSLATIONS[lang], + 'DSET_FAKEUA_' + option.upper(), translation) + set_tr('en', 'client', u'Client reported') + set_tr('ru', 'client', u'Отсылаемое название клиента') + set_tr('en', 'version', u'Version reported') + set_tr('ru', 'version', u'Отсылаемая версия клиента') + torchat.config.importLanguage() + + _dlg_settings_constructor = torchat.dlg_settings.Dialog.__init__ + def dlg_settings_constructor(self, main_window): + _dlg_settings_constructor(self, main_window) + def tr(option): + attr_name = 'DSET_FAKEUA_' + option.upper() + if hasattr(torchat.dlg_settings.lang, attr_name): + return getattr(torchat.dlg_settings.lang, attr_name) + else: + return option + def text(self, option): + torchat.dlg.Text(self.p3, tr(option), + ("fake_user_agent", option), expand=True) + text(self, 'client') + text(self, 'version') + self.p3.fit() + self.outer_sizer.Fit(self) + torchat.dlg_settings.Dialog.__init__ = dlg_settings_constructor + + _dlg_settings_onOk = torchat.dlg_settings.Dialog.onOk + def dlg_settings_onOk(self, evt): + old_client = get("client") + old_version = get("version") + _dlg_settings_onOk(self, evt) + if get("client") != old_client or get("version") != old_version: + for buddy in self.mw.buddy_list.list: + buddy.sendVersion() + torchat.dlg_settings.Dialog.onOk = dlg_settings_onOk diff --git a/torchat/src/tc_client.py b/torchat/src/tc_client.py index f87f1b8c..cd2b5f99 100644 --- a/torchat/src/tc_client.py +++ b/torchat/src/tc_client.py @@ -510,11 +510,9 @@ def sendRemoveMe(self): def sendVersion(self): if self.isAlreadyPonged(): - client = config.get("client", "reported_client").encode('UTF-8') - msg = ProtocolMsg_client(self, client) + msg = ProtocolMsg_client(self, version.NAME) msg.send() - version = config.get("client", "reported_version").encode('UTF-8') - msg = ProtocolMsg_version(self, version) + msg = ProtocolMsg_version(self, version.VERSION) msg.send() else: print "(2) not connected, not sending version to %s" % self.address diff --git a/torchat/src/translations/lang_en.py b/torchat/src/translations/lang_en.py index 02521f94..1fd6a539 100644 --- a/torchat/src/translations/lang_en.py +++ b/torchat/src/translations/lang_en.py @@ -137,8 +137,6 @@ DSET_MISC_TITLE = u"Misc" DSET_MISC_TEMP_IN_DATA = u"Store temporary files inside data directory" DSET_MISC_TEMP_CUSTOM_DIR = u"Temporary directory (leave empty for OS-default)" -DSET_MISC_REPORT_CLIENT = u"Client reported" -DSET_MISC_REPORT_VERSION = u"Version reported" DSET_PLUGINS_TITLE = u"Plugins" #notices in the chat window (those in square brackets) From 49a9eb6063d9b7c91882b28676c59ba19632965d Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Sun, 3 Nov 2013 18:58:41 +0400 Subject: [PATCH 56/83] disable_echo plugin --- torchat/src/plugins/disable_echo.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 torchat/src/plugins/disable_echo.py diff --git a/torchat/src/plugins/disable_echo.py b/torchat/src/plugins/disable_echo.py new file mode 100644 index 00000000..2ab889ad --- /dev/null +++ b/torchat/src/plugins/disable_echo.py @@ -0,0 +1,23 @@ +# -*- coding: UTF-8 -*- + +import os + +NAME_en = u'Do not show self-echo messages' +NAME_ru = u'Не отображать эхо-ответы от самого себя' + +def load(torchat): + _onSend = torchat.tc_gui.ChatWindow.onSend + text_last = None + def onSend(self, evt): + global text_last + text_last = self.txt_out.GetValue().rstrip().lstrip().replace("\x0b", os.linesep) + _onSend(self, evt) + torchat.tc_gui.ChatWindow.onSend = onSend + + _onChatMessage = torchat.tc_client.Buddy.onChatMessage + def onChatMessage(self, text): + global text_last + if self == self.bl.own_buddy and text == text_last: + return + _onChatMessage(self, text) + torchat.tc_client.Buddy.onChatMessage = onChatMessage From b712876517a033e26ada3c030ffa973d15974bfd Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Sun, 3 Nov 2013 19:08:14 +0400 Subject: [PATCH 57/83] conference shows status and role only in !list --- torchat/src/plugins/conference.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/torchat/src/plugins/conference.py b/torchat/src/plugins/conference.py index a62ed5b1..fbdb0427 100644 --- a/torchat/src/plugins/conference.py +++ b/torchat/src/plugins/conference.py @@ -158,17 +158,12 @@ def nick_repr(buddy, moder=False): and buddy.profile_name \ and not torchat.tc_client.isValidAddress(buddy.profile_name): nick = buddy.profile_name - if moder: - nick += ' (%s)' % buddy.address if moder or int(get('list_role')) == 1: buddy_role = role_of(buddy.address) if buddy_role in ('admin', 'owner'): nick = '@' + nick if buddy_role == 'moder': nick = '%' + nick - if int(get('list_status')) == 1 and \ - buddy.status != torchat.tc_client.STATUS_ONLINE: - nick += ' [%s]' % sstatus(buddy.status) return nick def announce(text, moder): prefix = '[admin]' if moder else '[user]' @@ -199,6 +194,11 @@ def do_list(me, _): nicks = [] for buddy in buddy_list().list: nick = nick_repr(buddy, is_moder(me.address)) + if buddy.address not in nick and is_moder(me.address): + nick += ' (%s)' % buddy.address + if buddy.status != torchat.tc_client.STATUS_ONLINE: + if int(get('list_status')) == 1 or is_moder(me.address): + nick += ' [%s]' % sstatus(buddy.status) if int(get('list_role')) == 1 or is_moder(me.address): nick += ' /%s/' % role_of(buddy.address) nicks.append(nick) From 475e49d9576c5825a998479b790f553803a28fff Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Sun, 3 Nov 2013 23:20:53 +0400 Subject: [PATCH 58/83] allow multiple ping/pong on one connection --- torchat/src/tc_client.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/torchat/src/tc_client.py b/torchat/src/tc_client.py index cd2b5f99..48d8aaf7 100644 --- a/torchat/src/tc_client.py +++ b/torchat/src/tc_client.py @@ -1479,16 +1479,15 @@ def execute(self): self.buddy.count_unanswered_pings = 0 self.buddy.sendPing() + #now we can finally put our answer into the send queue + print "(2) PONG >>> %s" % self.address + answer = ProtocolMsg_pong(self.buddy, self.answer) + answer.send() if self.buddy.isAlreadyPonged(): #but we don't need to send more than one pong on the same conn_out #only if this is also a new conn_out because the last one failed print "(2) not sending another pong over same connection" return - - #now we can finally put our answer into the send queue - print "(2) PONG >>> %s" % self.address - answer = ProtocolMsg_pong(self.buddy, self.answer) - answer.send() self.buddy.conn_out.pong_sent = True self.buddy.sendVersion() From 431bf6fa301e8bf9997eff479c04aa3c1fa010a9 Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Sun, 3 Nov 2013 23:21:35 +0400 Subject: [PATCH 59/83] ping plugin --- torchat/src/plugins/ping.py | 43 +++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 torchat/src/plugins/ping.py diff --git a/torchat/src/plugins/ping.py b/torchat/src/plugins/ping.py new file mode 100644 index 00000000..cd7f3f6d --- /dev/null +++ b/torchat/src/plugins/ping.py @@ -0,0 +1,43 @@ +# -*- coding: UTF-8 -*- + +from functools import partial +from datetime import datetime + +import wx + +NAME_en = u'Add "Ping" button' +NAME_ru = u'Добавляет кнопку "Ping"' + +def load(torchat): + def set_tr(lang, option, translation): + setattr(torchat.TRANSLATIONS[lang], + 'PING_' + option.upper(), translation) + set_tr('en', 'ping', u'Ping') + torchat.config.importLanguage() + + def onPing(chat_window, evt): + chat_window.last_ping = datetime.now() + chat_window.buddy.sendPing() + + _ChatWindow_PopupMenu = torchat.tc_gui.ChatWindow.PopupMenu + def ChatWindow_PopupMenu(self, menu): + # add Ping item + id = wx.NewId() + item = wx.MenuItem(menu, id, torchat.dlg_settings.lang.PING_PING) + self.Bind(wx.EVT_MENU, partial(onPing, self), id=id) + menu.AppendItem(item) + # show + _ChatWindow_PopupMenu(self, menu) + torchat.tc_gui.ChatWindow.PopupMenu = ChatWindow_PopupMenu + + _Buddy_onInConnectionFound = torchat.tc_client.Buddy.onInConnectionFound + def Buddy_onInConnectionFound(self, conn): + _Buddy_onInConnectionFound(self, conn) + for window in torchat.app.mw.chat_windows: + if window.buddy == self and hasattr(window, 'last_ping'): + delay = datetime.now() - window.last_ping + del window.last_ping + ms = delay.seconds * 1000 + delay.microseconds // 1000 + window.writeHintLine('time=%i ms' % ms) + torchat.tc_client.Buddy.onInConnectionFound = Buddy_onInConnectionFound + From 49f651c4d6d6a24f6c8de0100b37b860ca3d7f83 Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Mon, 4 Nov 2013 02:10:43 +0400 Subject: [PATCH 60/83] global variable in disable_echo moved to global ns --- torchat/src/plugins/disable_echo.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/torchat/src/plugins/disable_echo.py b/torchat/src/plugins/disable_echo.py index 2ab889ad..db50b743 100644 --- a/torchat/src/plugins/disable_echo.py +++ b/torchat/src/plugins/disable_echo.py @@ -5,9 +5,10 @@ NAME_en = u'Do not show self-echo messages' NAME_ru = u'Не отображать эхо-ответы от самого себя' +text_last = None + def load(torchat): _onSend = torchat.tc_gui.ChatWindow.onSend - text_last = None def onSend(self, evt): global text_last text_last = self.txt_out.GetValue().rstrip().lstrip().replace("\x0b", os.linesep) From bec68dcd4c3a17fd52329739ec4772f566854d3f Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Mon, 4 Nov 2013 04:51:34 +0400 Subject: [PATCH 61/83] ping plugin calls GUI via CallAfter calling GUI directly from network thread is dangerous --- torchat/src/plugins/ping.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/torchat/src/plugins/ping.py b/torchat/src/plugins/ping.py index cd7f3f6d..e68e9bd0 100644 --- a/torchat/src/plugins/ping.py +++ b/torchat/src/plugins/ping.py @@ -38,6 +38,7 @@ def Buddy_onInConnectionFound(self, conn): delay = datetime.now() - window.last_ping del window.last_ping ms = delay.seconds * 1000 + delay.microseconds // 1000 - window.writeHintLine('time=%i ms' % ms) + wx.CallAfter(torchat.tc_gui.ChatWindow.writeHintLine, + window, 'time=%i ms' % ms) torchat.tc_client.Buddy.onInConnectionFound = Buddy_onInConnectionFound From 4faa97649fedd43b7bd39352565581a5fa84cdc9 Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Mon, 4 Nov 2013 05:48:08 +0400 Subject: [PATCH 62/83] plugin rock-paper-scissors --- torchat/src/plugins/rps.py | 172 +++++++++++++++++++++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100644 torchat/src/plugins/rps.py diff --git a/torchat/src/plugins/rps.py b/torchat/src/plugins/rps.py new file mode 100644 index 00000000..22c06e94 --- /dev/null +++ b/torchat/src/plugins/rps.py @@ -0,0 +1,172 @@ +# -*- coding: UTF-8 -*- + +import os +import re +import random +from hashlib import sha1 +from functools import partial + +import wx + +NAME_en = u'Rock-paper-scissors' +NAME_ru = u'Камень-ножницы-бумага' + +FULL = { + 'r': 'rock', + 'p': 'paper', + 's': 'scissors', +} + +HASH_RE = r'\b[0-9a-f]{40}$' +CLEARTEXT_RE = r'\b\S{10,}-[rps]$' + +def winner_of(a, b): + if a == b: + return 'draw' + if a == 'rock' and b == 'scissors': + return a + if a == 'scissors' and b == 'paper': + return a + if a == 'paper' and b == 'rock': + return a + return b + +def load(torchat): + def get_lang(): + return torchat.dlg_settings.lang + def set_tr(lang, option, translation): + setattr(torchat.TRANSLATIONS[lang], + 'RPS_' + option.upper(), translation) + def tr(option): + return getattr(get_lang(), 'RPS_' + option.upper(), option) + set_tr('en', 'rock', u'Rock') + set_tr('ru', 'rock', u'Камень') + set_tr('en', 'paper', u'Paper') + set_tr('ru', 'paper', u'Бумага') + set_tr('en', 'scissors', u'Scissors') + set_tr('ru', 'scissors', u'Ножницы') + set_tr('en', 'random', u'Random') + set_tr('ru', 'random', u'Наугад') + set_tr('en', 'reset', u'Reset') + set_tr('ru', 'reset', u'Сброс') + set_tr('en', 'draw', u'Draw') + set_tr('ru', 'draw', u'Ничья') + set_tr('en', 'hash_sent', u'Hash sent') + set_tr('ru', 'hash_sent', u'Хеш отправлен') + set_tr('en', 'cleartext_sent', u'Cleartext sent') + set_tr('ru', 'cleartext_sent', u'Открытый текст отправлен') + set_tr('en', 'you_won', u'You won') + set_tr('ru', 'you_won', u'Вы победили') + set_tr('en', 'opponent_won', u'Opponent won') + set_tr('ru', 'opponent_won', u'Соперник победил') + set_tr('en', 'cheat', u'Hash mismatch. Cheat!') + set_tr('ru', 'cheat', u'Хеш не совпадает. Жулик!') + set_tr('en', 'unknown_choice', u'Unknown choice') + set_tr('ru', 'unknown_choice', u'Неизвестный выбор') + torchat.config.importLanguage() + + def make_cleartext(salt, choice): + return '%s-%s' % (salt, choice[0]) + + def write_hint(window, hint): + wx.CallAfter(torchat.tc_gui.ChatWindow.writeHintLine, window, hint) + + def send_hash(window): + if hasattr(window, 'rps_hash_sent') and window.rps_hash_sent: + return + window.rps_hash_sent = True + cleartext = make_cleartext(window.rps_salt, window.rps_choice) + hash = sha1(cleartext).hexdigest() + window.buddy.sendChatMessage(hash) + write_hint(window, tr('hash_sent')) + + def send_cleartext(window): + if hasattr(window, 'rps_cleartext_sent') and window.rps_cleartext_sent: + return + window.rps_cleartext_sent = True + cleartext = make_cleartext(window.rps_salt, window.rps_choice) + window.buddy.sendChatMessage(cleartext) + write_hint(window, tr('cleartext_sent')) + + def reset(window): + window.rps_choice = '' + window.rps_salt = '' + window.rps_cleartext_sent = '' + window.rps_hash_sent = '' + + def onRps(window, what, evt): + reset(window) + if what == 'reset': + return + if what == 'random': + what = random.choice(['rock', 'paper', 'scissors']) + window.rps_salt = sha1(str(random.getrandbits(256))).hexdigest() + window.rps_choice = what + write_hint(window, tr(window.rps_choice)) + cleartext = make_cleartext(window.rps_salt, window.rps_choice) + write_hint(window, cleartext) + send_hash(window) + + _ChatWindow_PopupMenu = torchat.tc_gui.ChatWindow.PopupMenu + def ChatWindow_PopupMenu(self, menu): + # rps submenu + self.rps_submenu = wx.Menu() + menu.AppendMenu(-1, get_lang().DSET_PLUGIN_RPS, self.rps_submenu) + def add_item(what): + id = wx.NewId() + item = wx.MenuItem(self.rps_submenu, id, tr(what)) + self.Bind(wx.EVT_MENU, partial(onRps, self, what), id=id) + self.rps_submenu.AppendItem(item) + add_item('rock') + add_item('paper') + add_item('scissors') + add_item('random') + add_item('reset') + # show + _ChatWindow_PopupMenu(self, menu) + torchat.tc_gui.ChatWindow.PopupMenu = ChatWindow_PopupMenu + + _message_execute = torchat.tc_client.ProtocolMsg_message.execute + def message_execute(self): + _message_execute(self) + goood_message = self.buddy and self.buddy in self.bl.list + if goood_message: + hash_match = re.search(HASH_RE, self.text) + if hash_match: + hash = hash_match.group() + for window in torchat.app.mw.chat_windows: + if window.buddy == self.buddy: + window.rps_opponent_hash = hash + if hasattr(window, 'rps_choice') and window.rps_choice: + send_cleartext(window) + cleartext_match = re.search(CLEARTEXT_RE, self.text) + if cleartext_match: + cleartext = cleartext_match.group() + for window in torchat.app.mw.chat_windows: + if window.buddy == self.buddy: + send_cleartext(window) + hash = window.rps_opponent_hash + if sha1(cleartext).hexdigest() != hash: + self.buddy.sendChatMessage('Hash mismatch. Cheat!') + write_hint(window, tr('cheat')) + return + choice = cleartext.split('-')[-1] + if choice not in 'rps': + self.buddy.sendChatMessage('Unknown choice') + write_hint(window, tr('cheat')) + return + choice_full = FULL[choice] + winner = winner_of(choice_full, window.rps_choice) + tr_my = tr(window.rps_choice).lower() + tr_his = tr(choice_full).lower() + if winner == 'draw': + write_hint(window, tr('draw')) + elif winner == choice_full: + write_hint(window, tr('opponent_won') + + ': %s > %s' % (tr_his, tr_my)) + elif winner == window.rps_choice: + write_hint(window, tr('you_won') + + ': %s > %s' % (tr_my, tr_his)) + reset(window) + torchat.tc_client.ProtocolMsg_message.execute = message_execute + From 719b46c1fee56ca9fd34655c2311a64089987f99 Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Mon, 4 Nov 2013 05:53:42 +0400 Subject: [PATCH 63/83] update ping plugin name from button to popup menu --- torchat/src/plugins/ping.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/torchat/src/plugins/ping.py b/torchat/src/plugins/ping.py index e68e9bd0..3bffcf8c 100644 --- a/torchat/src/plugins/ping.py +++ b/torchat/src/plugins/ping.py @@ -5,8 +5,8 @@ import wx -NAME_en = u'Add "Ping" button' -NAME_ru = u'Добавляет кнопку "Ping"' +NAME_en = u'Add "Ping" item to popup menu' +NAME_ru = u'Добавляет пункт "Ping" в контекстное меню' def load(torchat): def set_tr(lang, option, translation): From 6d584d65650f0561334d6363e9f93e12509affb9 Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Mon, 4 Nov 2013 05:55:59 +0400 Subject: [PATCH 64/83] sort list of plugins in preferences --- torchat/src/dlg_settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/torchat/src/dlg_settings.py b/torchat/src/dlg_settings.py index 398a561d..f5773f9d 100644 --- a/torchat/src/dlg_settings.py +++ b/torchat/src/dlg_settings.py @@ -104,7 +104,7 @@ def __init__(self, main_window): self.plugins = {} enabled_plugins = set(config.get('plugin', 'enabled_plugins').split(',')) import torchat - for plugin_name in torchat.PLUGINS: + for plugin_name in sorted(torchat.PLUGINS.keys()): plugin_dscr = getattr(lang, 'DSET_PLUGIN_' + plugin_name.upper(), plugin_name) enabled = int(bool(plugin_name in enabled_plugins)) self.plugins[plugin_name] = dlg.Check(self.p4, plugin_dscr, enabled) From 07407dca092adefaf2d2757338ee751a1de0d0b4 Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Mon, 4 Nov 2013 05:58:28 +0400 Subject: [PATCH 65/83] see popup menu in name of rps plugin --- torchat/src/plugins/rps.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/torchat/src/plugins/rps.py b/torchat/src/plugins/rps.py index 22c06e94..1aec06a2 100644 --- a/torchat/src/plugins/rps.py +++ b/torchat/src/plugins/rps.py @@ -8,8 +8,8 @@ import wx -NAME_en = u'Rock-paper-scissors' -NAME_ru = u'Камень-ножницы-бумага' +NAME_en = u'Rock-paper-scissors (see popup menu)' +NAME_ru = u'Камень-ножницы-бумага (см. контекстное меню)' FULL = { 'r': 'rock', From b69465fb816d32c7d9c78edb4540210c248a4dfd Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Mon, 4 Nov 2013 18:10:41 +0400 Subject: [PATCH 66/83] tc_client uses socks5 instead of socks4 --- torchat/src/tc_client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/torchat/src/tc_client.py b/torchat/src/tc_client.py index 48d8aaf7..1e412d73 100644 --- a/torchat/src/tc_client.py +++ b/torchat/src/tc_client.py @@ -2017,7 +2017,7 @@ def run(self): self.running = True try: self.socket = socks.socksocket() - self.socket.setproxy(socks.PROXY_TYPE_SOCKS4, + self.socket.setproxy(socks.PROXY_TYPE_SOCKS5, config.get(self.bl.tor_config, "tor_server"), self.bl.tor_server_socks_port) print "(2) trying to connect '%s'" % self.address From 34ea697e950bc3c25130d3fc8911ae86098686d0 Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Tue, 5 Nov 2013 04:54:59 +0400 Subject: [PATCH 67/83] plugins add preferences through addPluginSettings addPluginSettings is defined by plugin This was changed to avoid double calls to .fit() which is buggy on win32 --- torchat/src/dlg_settings.py | 16 +++++++++++----- torchat/src/plugins/add_password.py | 10 ++++------ torchat/src/plugins/conference.py | 9 ++++----- torchat/src/plugins/fake_user_agent.py | 10 ++++------ torchat/src/plugins/test_plugin.py | 8 ++++---- 5 files changed, 27 insertions(+), 26 deletions(-) diff --git a/torchat/src/dlg_settings.py b/torchat/src/dlg_settings.py index f5773f9d..a556794c 100644 --- a/torchat/src/dlg_settings.py +++ b/torchat/src/dlg_settings.py @@ -68,7 +68,6 @@ def __init__(self, main_window): dlg.Separator(self.p1, "Client") dlg.Text(self.p1, lang.DSET_NET_LISTEN_INTERFACE, ("client", "listen_interface"), True) dlg.Text(self.p1, lang.DSET_NET_LISTEN_PORT, ("client", "listen_port")) - self.p1.fit() portable = (self.mw.buddy_list.tor_config == "tor_portable") if portable: @@ -87,7 +86,6 @@ def __init__(self, main_window): dlg.Check(self.p2, lang.DSET_GUI_NOTIFICATION_POPUP, ("gui", "notification_popup")) dlg.Text(self.p2, lang.DSET_GUI_NOTIFICATION_METHOD, ("gui", "notification_method")) dlg.Check(self.p2, lang.DSET_GUI_FLASH_WINDOW, ("gui", "notification_flash_window")) - self.p2.fit() #3.3 misc options self.p3 = dlg.Panel(self.notebook) @@ -96,7 +94,6 @@ def __init__(self, main_window): self.dir_tmp = dlg.Dir(self.p3, lang.DSET_MISC_TEMP_CUSTOM_DIR, ("files", "temp_files_custom_dir")) self.dir_tmp.setEnabled(not self.chk_tmp.getValue()) self.chk_tmp.wx_ctrl.Bind(wx.EVT_CHECKBOX, self.onChkTmp) - self.p3.fit() #3.4 plugins self.p4 = dlg.Panel(self.notebook) @@ -108,11 +105,20 @@ def __init__(self, main_window): plugin_dscr = getattr(lang, 'DSET_PLUGIN_' + plugin_name.upper(), plugin_name) enabled = int(bool(plugin_name in enabled_plugins)) self.plugins[plugin_name] = dlg.Check(self.p4, plugin_dscr, enabled) - self.p4.fit() + + # add plugins' settings + self.addPluginSettings(main_window) #4 fit the sizers + self.p1.fit() + self.p2.fit() + self.p3.fit() + self.p4.fit() self.outer_sizer.Fit(self) - + + def addPluginSettings(self, main_window): + pass + def onChkTmp(self, evt): self.dir_tmp.setEnabled(not self.chk_tmp.getValue()) diff --git a/torchat/src/plugins/add_password.py b/torchat/src/plugins/add_password.py index 8403fde9..22c97730 100644 --- a/torchat/src/plugins/add_password.py +++ b/torchat/src/plugins/add_password.py @@ -43,9 +43,9 @@ def set_tr(lang, option, translation): set_tr('ru', 'password_tip', u'Подсказка о пароле') torchat.config.importLanguage() - _dlg_settings_constructor = torchat.dlg_settings.Dialog.__init__ - def dlg_settings_constructor(self, main_window): - _dlg_settings_constructor(self, main_window) + _addPluginSettings = torchat.dlg_settings.Dialog.addPluginSettings + def addPluginSettings(self, main_window): + _addPluginSettings(self, main_window) def tr(option): attr_name = 'DSET_PASSWORD_' + option.upper() if hasattr(torchat.dlg_settings.lang, attr_name): @@ -57,6 +57,4 @@ def text(self, option): ("password", option), expand=True) text(self, 'password') text(self, 'password_tip') - self.p3.fit() - self.outer_sizer.Fit(self) - torchat.dlg_settings.Dialog.__init__ = dlg_settings_constructor + torchat.dlg_settings.Dialog.addPluginSettings = addPluginSettings diff --git a/torchat/src/plugins/conference.py b/torchat/src/plugins/conference.py index fbdb0427..34fdead0 100644 --- a/torchat/src/plugins/conference.py +++ b/torchat/src/plugins/conference.py @@ -540,9 +540,9 @@ def set_tr(lang, option, translation): set_tr('ru', 'receiver_status', u'Статусы получателей [offline,][handshake,][online,][away,][busy]') torchat.config.importLanguage() - _dlg_settings_constructor = torchat.dlg_settings.Dialog.__init__ - def dlg_settings_constructor(self, main_window): - _dlg_settings_constructor(self, main_window) + _addPluginSettings = torchat.dlg_settings.Dialog.addPluginSettings + def addPluginSettings(self, main_window): + _addPluginSettings(self, main_window) self.p_conference = torchat.dlg.Panel(self.notebook) self.notebook.AddPage(self.p_conference, torchat.dlg_settings.lang.DSET_CONFERENCE_TITLE) @@ -570,8 +570,7 @@ def text(self, option): text(self, 'default_role') text(self, 'receiver_status') self.p_conference.fit() - self.outer_sizer.Fit(self) - torchat.dlg_settings.Dialog.__init__ = dlg_settings_constructor + torchat.dlg_settings.Dialog.addPluginSettings = addPluginSettings _dlg_settings_onOk = torchat.dlg_settings.Dialog.onOk def dlg_settings_onOk(self, evt): diff --git a/torchat/src/plugins/fake_user_agent.py b/torchat/src/plugins/fake_user_agent.py index c05ac9e5..76e58c57 100644 --- a/torchat/src/plugins/fake_user_agent.py +++ b/torchat/src/plugins/fake_user_agent.py @@ -32,9 +32,9 @@ def set_tr(lang, option, translation): set_tr('ru', 'version', u'Отсылаемая версия клиента') torchat.config.importLanguage() - _dlg_settings_constructor = torchat.dlg_settings.Dialog.__init__ - def dlg_settings_constructor(self, main_window): - _dlg_settings_constructor(self, main_window) + _addPluginSettings = torchat.dlg_settings.Dialog.addPluginSettings + def addPluginSettings(self, main_window): + _addPluginSettings(self, main_window) def tr(option): attr_name = 'DSET_FAKEUA_' + option.upper() if hasattr(torchat.dlg_settings.lang, attr_name): @@ -46,9 +46,7 @@ def text(self, option): ("fake_user_agent", option), expand=True) text(self, 'client') text(self, 'version') - self.p3.fit() - self.outer_sizer.Fit(self) - torchat.dlg_settings.Dialog.__init__ = dlg_settings_constructor + torchat.dlg_settings.Dialog.addPluginSettings = addPluginSettings _dlg_settings_onOk = torchat.dlg_settings.Dialog.onOk def dlg_settings_onOk(self, evt): diff --git a/torchat/src/plugins/test_plugin.py b/torchat/src/plugins/test_plugin.py index 611024b7..baa46b6c 100644 --- a/torchat/src/plugins/test_plugin.py +++ b/torchat/src/plugins/test_plugin.py @@ -16,10 +16,10 @@ def sendChatMessage(self, text): torchat.TRANSLATIONS['ru'].DSET_TEST_PLUGIN_TEXT = u'Заменять сообщения текстом' torchat.config.importLanguage() - _constructor = torchat.dlg_settings.Dialog.__init__ - def constructor(self, main_window): - _constructor(self, main_window) + _addPluginSettings = torchat.dlg_settings.Dialog.addPluginSettings + def addPluginSettings(self, main_window): + _addPluginSettings(self, main_window) torchat.dlg.Text(self.p3, torchat.dlg_settings.lang.DSET_TEST_PLUGIN_TEXT, ("test_plugin", "text")) - torchat.dlg_settings.Dialog.__init__ = constructor + torchat.dlg_settings.Dialog.addPluginSettings = addPluginSettings From 98c28781f163aa75dd01e4bd0aae0db22d3535ff Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Tue, 5 Nov 2013 05:11:33 +0400 Subject: [PATCH 68/83] rps fix attribute error --- torchat/src/plugins/rps.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/torchat/src/plugins/rps.py b/torchat/src/plugins/rps.py index 1aec06a2..d271fa83 100644 --- a/torchat/src/plugins/rps.py +++ b/torchat/src/plugins/rps.py @@ -143,7 +143,8 @@ def message_execute(self): if cleartext_match: cleartext = cleartext_match.group() for window in torchat.app.mw.chat_windows: - if window.buddy == self.buddy: + if window.buddy == self.buddy \ + and hasattr(window, 'rps_opponent_hash'): send_cleartext(window) hash = window.rps_opponent_hash if sha1(cleartext).hexdigest() != hash: From 1bd0d2446d21fc7b2f76c8ef3afc74cc181082dd Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Tue, 5 Nov 2013 05:17:17 +0400 Subject: [PATCH 69/83] rps remove "see popup menu" from popup menu --- torchat/src/plugins/rps.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/torchat/src/plugins/rps.py b/torchat/src/plugins/rps.py index d271fa83..2b5b5edd 100644 --- a/torchat/src/plugins/rps.py +++ b/torchat/src/plugins/rps.py @@ -39,6 +39,8 @@ def set_tr(lang, option, translation): 'RPS_' + option.upper(), translation) def tr(option): return getattr(get_lang(), 'RPS_' + option.upper(), option) + set_tr('en', 'rps', u'Rock-paper-scissors') + set_tr('ru', 'rps', u'Камень-ножницы-бумага') set_tr('en', 'rock', u'Rock') set_tr('ru', 'rock', u'Камень') set_tr('en', 'paper', u'Paper') @@ -111,7 +113,7 @@ def onRps(window, what, evt): def ChatWindow_PopupMenu(self, menu): # rps submenu self.rps_submenu = wx.Menu() - menu.AppendMenu(-1, get_lang().DSET_PLUGIN_RPS, self.rps_submenu) + menu.AppendMenu(-1, tr('rps'), self.rps_submenu) def add_item(what): id = wx.NewId() item = wx.MenuItem(self.rps_submenu, id, tr(what)) From 66c50e67f9a01cafedc792598f5e47408c8f97ba Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Tue, 5 Nov 2013 05:28:25 +0400 Subject: [PATCH 70/83] conference announce buddy entered room --- torchat/src/plugins/conference.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/torchat/src/plugins/conference.py b/torchat/src/plugins/conference.py index 34fdead0..c05504b1 100644 --- a/torchat/src/plugins/conference.py +++ b/torchat/src/plugins/conference.py @@ -501,6 +501,8 @@ def add_me_execute(self): _add_me_execute(self) if int(get('welcome_help')) == 1 and welcome: do_help(self.buddy, None) + nick = nick_repr(self.buddy) + announce('%s entered room' % nick, False) torchat.tc_client.ProtocolMsg_add_me.execute = add_me_execute _remove_me_execute = torchat.tc_client.ProtocolMsg_remove_me.execute From 221149c94f004afed9e1887b69e6803dd473cfb3 Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Tue, 5 Nov 2013 05:40:36 +0400 Subject: [PATCH 71/83] conference list members not currently in room for example, banned members --- torchat/src/plugins/conference.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/torchat/src/plugins/conference.py b/torchat/src/plugins/conference.py index c05504b1..cfeb8602 100644 --- a/torchat/src/plugins/conference.py +++ b/torchat/src/plugins/conference.py @@ -192,7 +192,9 @@ def do_list(me, _): me.sendChatMessage('[room] Action not allowed') return nicks = [] + shown = set() for buddy in buddy_list().list: + shown.add(buddy.address) nick = nick_repr(buddy, is_moder(me.address)) if buddy.address not in nick and is_moder(me.address): nick += ' (%s)' % buddy.address @@ -202,7 +204,15 @@ def do_list(me, _): if int(get('list_role')) == 1 or is_moder(me.address): nick += ' /%s/' % role_of(buddy.address) nicks.append(nick) - me.sendChatMessage('[room]\n' + '\n'.join(nicks)) + text = '[room]\n' + '\n'.join(nicks) + if is_moder(me.address): + not_in_room = [] + for address, role in roles.items(): + if address not in shown: + not_in_room.append('%s /%s/' % (address, role)) + if not_in_room: + text += '\n\nNot in room:\n' + '\n'.join(not_in_room) + me.sendChatMessage(text) def do_ignore(me, nick): buddy = buddy_from_nick(nick, me) if buddy: From d38d51b5f2135f0b0234ef0bd1d58c29c0dc69b5 Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Fri, 8 Nov 2013 00:05:15 +0400 Subject: [PATCH 72/83] update user name If user chanhes his profile_name, this event is sent to other users. Previous behaviour was to do nothing, if this user had name already set (local alias OR remote profile_name). Current variant will not update user name if name change happened while user was offline. --- torchat/src/tc_client.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/torchat/src/tc_client.py b/torchat/src/tc_client.py index 1e412d73..de50a8a3 100644 --- a/torchat/src/tc_client.py +++ b/torchat/src/tc_client.py @@ -280,10 +280,10 @@ def onStatus(self, status): def onProfileName(self, name): print "(2) %s.onProfile" % self.address - self.profile_name = name - if self.name == "" and name <> "": + if name and (not self.name or self.name == self.profile_name): self.name = name self.bl.save() + self.profile_name = name self.bl.gui(CB_TYPE_PROFILE, self) def onProfileText(self, text): From fe43c02725d52c0ce8e26d7da76559347416078c Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Fri, 8 Nov 2013 00:16:40 +0400 Subject: [PATCH 73/83] add () after method call --- torchat/src/tc_client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/torchat/src/tc_client.py b/torchat/src/tc_client.py index de50a8a3..652f9e6a 100644 --- a/torchat/src/tc_client.py +++ b/torchat/src/tc_client.py @@ -570,7 +570,7 @@ def __init__(self, callback, socket=None): f = open(filename, "r") l = f.read().replace("\r", "\n").replace("\n\n", "\n").split("\n") - f.close + f.close() self.list = [] for line in l: line = line.rstrip().decode("UTF-8") From 9d9558462715cfbd4f56ccc7a3b9730bcfa4888c Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Fri, 8 Nov 2013 00:37:46 +0400 Subject: [PATCH 74/83] move buddy-list from buddy-list.txt to torchat.ini and change format from simple text to JSON. * new lines in profile_name could break simple text format * store both name (set by local user) and profile_name (set by remote user) --- torchat/src/config.py | 24 ++++++++++++++++++++++++ torchat/src/tc_client.py | 34 +++++++++++----------------------- 2 files changed, 35 insertions(+), 23 deletions(-) diff --git a/torchat/src/config.py b/torchat/src/config.py index 881a276b..f35a8fde 100644 --- a/torchat/src/config.py +++ b/torchat/src/config.py @@ -21,6 +21,7 @@ import inspect import translations import shutil +import json def isWindows(): return sys.platform.startswith("win") @@ -38,6 +39,7 @@ def isWindows(): ("client", "own_hostname") : "0000000000000000", ("client", "listen_interface") : "127.0.0.1", ("client", "listen_port") : 0, + ("client", "buddy-list") : '[]', ("logging", "log_file") : "", ("logging", "log_level") : 0, ("files", "temp_files_in_data_dir") : 1, @@ -494,4 +496,26 @@ def main(): #now switch to the configured translation importLanguage() + if not json.loads(get('client', 'buddy-list')): + # backward compatibility with buddy-list.txt + filename = os.path.join(getDataDir(), "buddy-list.txt") + + if os.path.exists(filename): + f = open(filename) + buddy_list = [] + for line in f: + line = line.rstrip().decode("UTF-8") + if len(line) > 15: + address = line[0:16] + if len(line) > 17: + name = line[17:] + else: + name = u"" + buddy = {'address': address, + 'name': name.encode("UTF-8"), + 'profile_name': ''} + buddy_list.append(buddy) + f.close() + set('client', 'buddy-list', json.dumps(buddy_list)) + main() diff --git a/torchat/src/tc_client.py b/torchat/src/tc_client.py index 652f9e6a..d5f4336e 100644 --- a/torchat/src/tc_client.py +++ b/torchat/src/tc_client.py @@ -31,6 +31,7 @@ import config import version import re +import json from functools import partial TORCHAT_PORT = 11009 #do NOT change this. @@ -562,26 +563,12 @@ def __init__(self, callback, socket=None): self.startPortableTor() - filename = os.path.join(config.getDataDir(), "buddy-list.txt") - - #create empty buddy list file if it does not already exist - f = open(filename, "a") - f.close() - - f = open(filename, "r") - l = f.read().replace("\r", "\n").replace("\n\n", "\n").split("\n") - f.close() self.list = [] - for line in l: - line = line.rstrip().decode("UTF-8") - if len(line) > 15: - address = line[0:16] - if len(line) > 17: - name = line[17:] - else: - name = u"" - buddy = Buddy(address, self, name) - self.list.append(buddy) + + for buddy_dict in json.loads(config.get('client', 'buddy-list')): + buddy = Buddy(buddy_dict['address'], self, buddy_dict['name']) + buddy.profile_name = buddy_dict['profile_name'] + self.list.append(buddy) found = False for buddy in self.list: @@ -610,11 +597,12 @@ def __init__(self, callback, socket=None): print "(1) BuddList initialized" def save(self): - f = open(os.path.join(config.getDataDir(), "buddy-list.txt"), "w") + buddy_list = [] for buddy in self.list: - line = ("%s %s\r\n" % (buddy.address, buddy.name.rstrip())).encode("UTF-8") - f.write(line) - f.close() + buddy_list.append({'address': buddy.address, + 'name': buddy.name.encode("UTF-8"), + 'profile_name': buddy.profile_name.encode("UTF-8")}) + config.set('client', 'buddy-list', json.dumps(buddy_list)) print "(2) buddy list saved" # this is the optimal spot to notify the GUI to redraw the list From 4f1406b810d2323e8d7e7173abe09313944158a4 Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Fri, 8 Nov 2013 01:15:53 +0400 Subject: [PATCH 75/83] show local name or remote profile_name or address Do this in method buddy.getShortDisplayName Method buddy.getDisplayName shown address and (buddy.getShortDisplayName) if differs. --- torchat/src/tc_client.py | 34 +++++++++++++--------------------- torchat/src/tc_gui.py | 29 ++++++++++------------------- 2 files changed, 23 insertions(+), 40 deletions(-) diff --git a/torchat/src/tc_client.py b/torchat/src/tc_client.py index d5f4336e..f283549d 100644 --- a/torchat/src/tc_client.py +++ b/torchat/src/tc_client.py @@ -281,10 +281,8 @@ def onStatus(self, status): def onProfileName(self, name): print "(2) %s.onProfile" % self.address - if name and (not self.name or self.name == self.profile_name): - self.name = name - self.bl.save() self.profile_name = name + self.bl.save() self.bl.gui(CB_TYPE_PROFILE, self) def onProfileText(self, text): @@ -353,18 +351,6 @@ def sendOfflineMessages(self): print "(2) could not send offline messages, not fully connected." pass - def getDisplayNameOrAddress(self): - if self.name == "": - return self.address - else: - return self.name - - def getAddressAndDisplayName(self): - if self.name == "": - return self.address - else: - return self.address + " (" + self.name + ")" - def sendFile(self, filename, gui_callback): sender = FileSender(self, filename, gui_callback) return sender @@ -518,13 +504,20 @@ def sendVersion(self): else: print "(2) not connected, not sending version to %s" % self.address - def getDisplayName(self): - if self.name != "": - line = "%s (%s)" % (self.address, self.name) + def getShortDisplayName(self): + if self.name: + return self.name + elif self.profile_name: + return self.profile_name else: - line = self.address - return line + return self.address + def getDisplayName(self): + short_name = self.getShortDisplayName() + if short_name != self.address: + return "%s (%s)" % (self.address, short_name) + else: + return self.address class BuddyList(object): """the BuddyList object is the central API of the client. @@ -1663,7 +1656,6 @@ def execute(self): print "(2) add me from %s" % self.buddy.address if not self.buddy in self.bl.list: print "(2) received add_me from new buddy %s" % self.buddy.address - self.buddy.name = self.buddy.profile_name self.bl.addBuddy(self.buddy) msg = "<- has added you" self.buddy.onChatMessage(msg) diff --git a/torchat/src/tc_gui.py b/torchat/src/tc_gui.py index 6b887635..4ceaeabc 100644 --- a/torchat/src/tc_gui.py +++ b/torchat/src/tc_gui.py @@ -308,7 +308,7 @@ def __init__(self, main_window, type): self.Bind(wx.EVT_MENU, self.onQuit, item) def onSendFile(self, evt): - title = lang.DFT_FILE_OPEN_TITLE % self.buddy.getAddressAndDisplayName() + title = lang.DFT_FILE_OPEN_TITLE % self.buddy.getDisplayName() dialog = wx.FileDialog(self.mw, title, style=wx.OPEN) dialog.SetDirectory(config.getHomeDir()) if dialog.ShowModal() == wx.ID_OK: @@ -320,7 +320,8 @@ def onEdit(self, evt): dialog.ShowModal() def onDelete(self, evt): - answer = wx.MessageBox(lang.D_CONFIRM_DELETE_MESSAGE % (self.buddy.address, self.buddy.name), + answer = wx.MessageBox(lang.D_CONFIRM_DELETE_MESSAGE % + (self.buddy.getDisplayName(), ''), lang.D_CONFIRM_DELETE_TITLE, wx.YES_NO|wx.NO_DEFAULT) if answer == wx.YES: @@ -1009,11 +1010,8 @@ def __init__(self, list, index): self.avatar = wx.StaticBitmap(self.panel, -1, bitmap) sizer.Add(self.avatar, 0, wx.ALL, 5) - name = self.buddy.name - if self.buddy.profile_name <> u"": - name = self.buddy.profile_name - - text = "%s\n%s" % (self.buddy.address, name) + text = "%s\n%s\n%s" % (self.buddy.address, + self.buddy.profile_name, self.buddy.name) if self.buddy.profile_text <> u"": text = "%s\n\n%s" % (text, textwrap.fill(self.buddy.profile_text, 30)) @@ -1261,9 +1259,7 @@ def updateTitle(self): else: title = "" - title += self.buddy.address - if self.buddy.name != "": - title += " (%s)" % self.buddy.name + title += self.buddy.getDisplayName() self.SetTitle(title + " %s" % config.getProfileLongName()) @@ -1329,10 +1325,7 @@ def notifyOfflineSent(self): def process(self, message): #message must be unicode - if self.buddy.name != "": - name = self.buddy.name - else: - name = self.buddy.address + name = self.buddy.getShortDisplayName() self.writeColored(config.get("gui", "color_nick_buddy"), name, message) self.notify(name, message) @@ -1457,7 +1450,7 @@ def onCopy(self, evt): wx.TheClipboard.Close() def onSendFile(self, evt): - title = lang.DFT_FILE_OPEN_TITLE % self.buddy.getAddressAndDisplayName() + title = lang.DFT_FILE_OPEN_TITLE % self.buddy.getDisplayName() dialog = wx.FileDialog(self, title, style=wx.OPEN) dialog.SetDirectory(config.getHomeDir()) if dialog.ShowModal() == wx.ID_OK: @@ -1681,9 +1674,7 @@ def updateOutput(self): self.bytes_complete = 0 percent = 100.0 * self.bytes_complete / self.bytes_total - peer_name = self.buddy.address - if self.buddy.name != "": - peer_name += " (%s)" % self.buddy.name + peer_name = self.buddy.getDisplayName() title = "%04.1f%% - %s" % (percent, os.path.basename(self.file_name)) self.SetTitle(title) self.progress_bar.SetValue(percent) @@ -1758,7 +1749,7 @@ def onCancel(self, evt): self.Close() def onSave(self, evt): - title = lang.DFT_FILE_SAVE_TITLE % self.buddy.getAddressAndDisplayName() + title = lang.DFT_FILE_SAVE_TITLE % self.buddy.getDisplayName() dialog = wx.FileDialog(self, title, defaultFile=self.file_name, style=wx.SAVE) if config.isPortable(): dialog.SetDirectory(config.getDataDir()) From 3f3406884892725d564626d8056f96875068ea9a Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Fri, 8 Nov 2013 01:27:28 +0400 Subject: [PATCH 76/83] sanitize profile_name prior to using it in GUI * too long words in profile_name could cause crases in tooltip * new lines in profile_name could confuse user --- torchat/src/tc_client.py | 7 +++++-- torchat/src/tc_gui.py | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/torchat/src/tc_client.py b/torchat/src/tc_client.py index f283549d..06a5b776 100644 --- a/torchat/src/tc_client.py +++ b/torchat/src/tc_client.py @@ -504,11 +504,14 @@ def sendVersion(self): else: print "(2) not connected, not sending version to %s" % self.address + def getSaneProfileName(self): + return self.profile_name.replace('\n', ' ').replace('\r', ' ')[:100] + def getShortDisplayName(self): if self.name: return self.name - elif self.profile_name: - return self.profile_name + elif self.getSaneProfileName(): + return self.getSaneProfileName() else: return self.address diff --git a/torchat/src/tc_gui.py b/torchat/src/tc_gui.py index 4ceaeabc..c339c6d3 100644 --- a/torchat/src/tc_gui.py +++ b/torchat/src/tc_gui.py @@ -1011,7 +1011,7 @@ def __init__(self, list, index): sizer.Add(self.avatar, 0, wx.ALL, 5) text = "%s\n%s\n%s" % (self.buddy.address, - self.buddy.profile_name, self.buddy.name) + self.buddy.getSaneProfileName(), self.buddy.name) if self.buddy.profile_text <> u"": text = "%s\n\n%s" % (text, textwrap.fill(self.buddy.profile_text, 30)) From f8b2478b43e1c35728ef196894c10e33bdac361f Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Fri, 8 Nov 2013 01:42:02 +0400 Subject: [PATCH 77/83] no add \n for empty name or profile_name in tip --- torchat/src/tc_gui.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/torchat/src/tc_gui.py b/torchat/src/tc_gui.py index c339c6d3..21c39fa8 100644 --- a/torchat/src/tc_gui.py +++ b/torchat/src/tc_gui.py @@ -1010,8 +1010,11 @@ def __init__(self, list, index): self.avatar = wx.StaticBitmap(self.panel, -1, bitmap) sizer.Add(self.avatar, 0, wx.ALL, 5) - text = "%s\n%s\n%s" % (self.buddy.address, - self.buddy.getSaneProfileName(), self.buddy.name) + text = self.buddy.address + if self.buddy.getSaneProfileName(): + text += "\n" + self.buddy.getSaneProfileName() + if self.buddy.name: + text += "\n" + self.buddy.name if self.buddy.profile_text <> u"": text = "%s\n\n%s" % (text, textwrap.fill(self.buddy.profile_text, 30)) From 31cff97af9d58141f95e2e2c0117cdbd0db3161f Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Fri, 8 Nov 2013 01:44:45 +0400 Subject: [PATCH 78/83] conference sends sane profile_name of other users --- torchat/src/plugins/conference.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/torchat/src/plugins/conference.py b/torchat/src/plugins/conference.py index cfeb8602..d0e03c10 100644 --- a/torchat/src/plugins/conference.py +++ b/torchat/src/plugins/conference.py @@ -157,7 +157,7 @@ def nick_repr(buddy, moder=False): if int(get("prefer_nicks")) == 1 \ and buddy.profile_name \ and not torchat.tc_client.isValidAddress(buddy.profile_name): - nick = buddy.profile_name + nick = buddy.getSaneProfileName() if moder or int(get('list_role')) == 1: buddy_role = role_of(buddy.address) if buddy_role in ('admin', 'owner'): From 1161138af1b45b820800faeb4bfc253b6ac5bc64 Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Fri, 8 Nov 2013 02:42:46 +0400 Subject: [PATCH 79/83] bind any port is specified port is in use --- torchat/src/tc_client.py | 20 +++++++++++++++++--- torchat/src/torchat.py | 3 +++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/torchat/src/tc_client.py b/torchat/src/tc_client.py index 06a5b776..6db6d267 100644 --- a/torchat/src/tc_client.py +++ b/torchat/src/tc_client.py @@ -542,9 +542,10 @@ def __init__(self, callback, socket=None): self.tor_timer = None self.tor_config = 'tor_portable' self.tor_server_socks_port = config.getint(self.tor_config, "tor_server_socks_port") - if self.tor_server_socks_port == 0: - interface = config.get("client", "listen_interface") - self.tor_server_socks_port = getFreePort(interface) + tor_interface = config.get("client", "listen_interface") + if self.tor_server_socks_port == 0 or \ + not isPortFree(tor_interface, self.tor_server_socks_port): + self.tor_server_socks_port = getFreePort(tor_interface) self.file_sender = {} self.file_receiver = {} @@ -2063,6 +2064,8 @@ def __init__(self, buddy_list, socket=None): if not self.socket: interface = config.get("client", "listen_interface") self.socket = tryBindPort(interface, self.port) + if not self.socket: + self.socket = tryBindPort(interface, 0) self.port = self.socket.getsockname()[1] self.socket.listen(5) self.start() @@ -2124,6 +2127,17 @@ def tryBindPort(interface, port): tb() return False +def isPortFree(interface, port): + try: + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + s.bind((interface, port)) + s.listen(5) + s.close() + return True + except: + return False + def getFreePort(interface): try: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) diff --git a/torchat/src/torchat.py b/torchat/src/torchat.py index c1947fa2..41c99022 100755 --- a/torchat/src/torchat.py +++ b/torchat/src/torchat.py @@ -104,6 +104,9 @@ def main(): port = config.getint("client", "listen_port") print "(1) opening TorChat listener on %s:%s" % (interface, port) listen_socket = tc_client.tryBindPort(interface, port) + if not listen_socket: + print "(1) opening TorChat listener on %s, any port" % interface + listen_socket = tc_client.tryBindPort(interface, 0) if not listen_socket: print "(1) %s:%s is already in use" % (interface, port) wx.MessageBox(tc_gui.lang.D_WARN_USED_PORT_MESSAGE % (interface, port), From 0d8c275b313075e65270f05f5c4514a0b000d9a7 Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Fri, 8 Nov 2013 02:46:48 +0400 Subject: [PATCH 80/83] update howto_second_instance --- torchat/doc/howto_second_instance.html | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/torchat/doc/howto_second_instance.html b/torchat/doc/howto_second_instance.html index c26ad633..1601fd4e 100644 --- a/torchat/doc/howto_second_instance.html +++ b/torchat/doc/howto_second_instance.html @@ -11,6 +11,16 @@

How to run more than on instance of TorChat

+

+ + For torchat_py versions above 0.9.9.553 + this works out of box. + To start second account, add account's name to command line. + If you run portable torchat (Windows case), copy distribution + to another dir. Make sure not to copy Tor/hidden_service/ directory. + +

+

This howto will not work with versions below 0.9.9.260

From 8fe79adcfd757bf69d1e96178aada516ccb902c4 Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Sun, 13 Apr 2014 14:05:09 +0400 Subject: [PATCH 81/83] log socks proxy address and port --- torchat/src/tc_client.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/torchat/src/tc_client.py b/torchat/src/tc_client.py index 6db6d267..4d65d1b0 100644 --- a/torchat/src/tc_client.py +++ b/torchat/src/tc_client.py @@ -2001,9 +2001,10 @@ def run(self): self.running = True try: self.socket = socks.socksocket() - self.socket.setproxy(socks.PROXY_TYPE_SOCKS5, - config.get(self.bl.tor_config, "tor_server"), - self.bl.tor_server_socks_port) + socks_ip = config.get(self.bl.tor_config, "tor_server") + socks_port = self.bl.tor_server_socks_port + print "(2) using socks5 proxy '%s:%i'" % (socks_ip, socks_port) + self.socket.setproxy(socks.PROXY_TYPE_SOCKS5, socks_ip, socks_port) print "(2) trying to connect '%s'" % self.address self.socket.connect((str(self.address), TORCHAT_PORT)) print "(2) connected to %s" % self.address From b237a2c1ddb9c37759fccfb0acb243182281ab85 Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Sun, 13 Apr 2014 14:15:10 +0400 Subject: [PATCH 82/83] config item client.tor_config -> tor_portable/tor Client will use tor_portable and tor (eg, system-wide), depends on value of client.tor_config. --- torchat/src/config.py | 1 + torchat/src/tc_client.py | 9 ++++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/torchat/src/config.py b/torchat/src/config.py index f35a8fde..5d143e77 100644 --- a/torchat/src/config.py +++ b/torchat/src/config.py @@ -30,6 +30,7 @@ def isWindows(): import ctypes config_defaults = { + ("client", "tor_config") : "tor_portable", ("tor", "tor_server") : "127.0.0.1", ("tor", "tor_server_socks_port") : 9050, ("tor", "tor_server_control_port") : 9051, diff --git a/torchat/src/tc_client.py b/torchat/src/tc_client.py index 4d65d1b0..e05f1637 100644 --- a/torchat/src/tc_client.py +++ b/torchat/src/tc_client.py @@ -540,10 +540,12 @@ def __init__(self, callback, socket=None): self.tor_pid = None self.tor_proc = None self.tor_timer = None - self.tor_config = 'tor_portable' + self.tor_config = config.get('client', 'tor_config') self.tor_server_socks_port = config.getint(self.tor_config, "tor_server_socks_port") tor_interface = config.get("client", "listen_interface") - if self.tor_server_socks_port == 0 or \ + if self.tor_server_socks_port == 0: + self.tor_server_socks_port = getFreePort(tor_interface) + if self.tor_config == 'tor_portable' and \ not isPortFree(tor_interface, self.tor_server_socks_port): self.tor_server_socks_port = getFreePort(tor_interface) @@ -558,7 +560,8 @@ def __init__(self, callback, socket=None): self.listener = Listener(self, socket) self.own_status = STATUS_ONLINE - self.startPortableTor() + if self.tor_config == 'tor_portable': + self.startPortableTor() self.list = [] From 02ba5a432faf215f339427672641deb9b9d5a320 Mon Sep 17 00:00:00 2001 From: Bitcoin Fan Date: Sun, 13 Apr 2014 14:17:38 +0400 Subject: [PATCH 83/83] dlg_settings checkbox for client.tor_config --- torchat/src/dlg_settings.py | 8 +++++++- torchat/src/translations/lang_en.py | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/torchat/src/dlg_settings.py b/torchat/src/dlg_settings.py index a556794c..bc05aa44 100644 --- a/torchat/src/dlg_settings.py +++ b/torchat/src/dlg_settings.py @@ -56,6 +56,9 @@ def __init__(self, main_window): self.p1 = dlg.Panel(self.notebook) self.notebook.AddPage(self.p1, lang.DSET_NET_TITLE) + portable = (self.mw.buddy_list.tor_config == "tor_portable") + self.tor_portable = dlg.Check(self.p1, lang.DSET_GUI_TOR_PORTABLE, int(portable)) + self.s_tor_portable = dlg.Separator(self.p1, "Tor portable") dlg.Text(self.p1, lang.DSET_NET_TOR_ADDRESS, ("tor_portable", "tor_server"), True) dlg.Text(self.p1, lang.DSET_NET_TOR_SOCKS, ("tor_portable", "tor_server_socks_port")) @@ -69,7 +72,6 @@ def __init__(self, main_window): dlg.Text(self.p1, lang.DSET_NET_LISTEN_INTERFACE, ("client", "listen_interface"), True) dlg.Text(self.p1, lang.DSET_NET_LISTEN_PORT, ("client", "listen_port")) - portable = (self.mw.buddy_list.tor_config == "tor_portable") if portable: self.s_tor.setEnabled(False) else: @@ -131,6 +133,10 @@ def onOk(self, evt): self.p3.saveAllData() #enabled_plugins = set(config.get('plugin', 'enabled_plugins').split(',')) import torchat + if self.tor_portable.getValue() == 1: + config.set('client', 'tor_config', 'tor_portable') + else: + config.set('client', 'tor_config', 'tor') enabled_plugins = [] for plugin_name in torchat.PLUGINS: if self.plugins[plugin_name].getValue(): diff --git a/torchat/src/translations/lang_en.py b/torchat/src/translations/lang_en.py index 1fd6a539..9c2403b3 100644 --- a/torchat/src/translations/lang_en.py +++ b/torchat/src/translations/lang_en.py @@ -134,6 +134,7 @@ DSET_GUI_NOTIFICATION_POPUP = u"Notification pop-up" DSET_GUI_NOTIFICATION_METHOD = u"Notification method" DSET_GUI_FLASH_WINDOW = u"Flash window title on new message" +DSET_GUI_TOR_PORTABLE = u"use Tor portable (restart after change)" DSET_MISC_TITLE = u"Misc" DSET_MISC_TEMP_IN_DATA = u"Store temporary files inside data directory" DSET_MISC_TEMP_CUSTOM_DIR = u"Temporary directory (leave empty for OS-default)"