From 14bf35421bf75d26fe4799286c026a0cb7679615 Mon Sep 17 00:00:00 2001 From: Gregor Robinson Date: Wed, 26 Jun 2013 12:28:01 +0000 Subject: [PATCH 01/39] Fixing issue #258, bad keyfile permissions. This spits out a warning to the console, but ideally it would also issue a warning to the GUI for those who didn't start it from the console. N.B. the warning is a one shot thing, since it fixes the problem in a way essentially undetectable in the future, so it should be done right if it is to be done at all. Maybe we should even disable all keys automatically if the keyfile is found in an insecure state. --- src/shared.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/shared.py b/src/shared.py index 5dc6964b..09d0bae8 100644 --- a/src/shared.py +++ b/src/shared.py @@ -21,6 +21,7 @@ import socket import random import highlevelcrypto import shared +import stat config = ConfigParser.SafeConfigParser() myECCryptorObjects = {} @@ -196,8 +197,10 @@ def reloadMyAddressHashes(): myAddressesByHash.clear() #myPrivateKeys.clear() configSections = config.sections() + hasExistingKeys = False for addressInKeysFile in configSections: if addressInKeysFile <> 'bitmessagesettings': + hasExistingKeys = True isEnabled = config.getboolean(addressInKeysFile, 'enabled') if isEnabled: status,addressVersionNumber,streamNumber,hash = decodeAddress(addressInKeysFile) @@ -208,6 +211,7 @@ def reloadMyAddressHashes(): myAddressesByHash[hash] = addressInKeysFile else: sys.stderr.write('Error in reloadMyAddressHashes: Can\'t handle address versions other than 2 or 3.\n') + fixKeyfilePermissions(appdata + 'keys.dat', hasExistingKeys) def reloadBroadcastSendersForWhichImWatching(): printLock.acquire() @@ -298,3 +302,26 @@ def fixPotentiallyInvalidUTF8Data(text): except: output = 'Part of the message is corrupt. The message cannot be displayed the normal way.\n\n' + repr(text) return output + +# Fix keyfile permissions due to inappropriate umask during keys.dat creation. +def fixKeyfilePermissions(keyfile, hasExistingKeys): + present_keyfile_permissions = os.stat(keyfile)[0] + keyfile_disallowed_permissions = stat.S_IRWXG | stat.S_IRWXO + if (present_keyfile_permissions & keyfile_disallowed_permissions) != 0: + allowed_keyfile_permissions = ((1<<32)-1) ^ keyfile_disallowed_permissions + new_keyfile_permissions = ( + allowed_keyfile_permissions & present_keyfile_permissions) + os.chmod(keyfile, new_keyfile_permissions) + if hasExistingKeys: + print + print '******************************************************************' + print '** !! WARNING !! **' + print '******************************************************************' + print '** Possibly major security problem: **' + print '** Your keyfiles were vulnerable to being read by other users **' + print '** (including some untrusted daemons). You may wish to consider **' + print '** generating new keys and discontinuing use of your old ones. **' + print '** The problem has been automatically fixed. **' + print '******************************************************************' + print + From db3120f65530310f92a23f482be02853d1661089 Mon Sep 17 00:00:00 2001 From: Gregor Robinson Date: Thu, 27 Jun 2013 10:02:52 +0000 Subject: [PATCH 02/39] Fix #263 & #262: insecure keyfile permissions. * Added conditional to keyfile fix code that excludes windows. * Cleaned up old keyfile permissions fix. * Added umask (not conditional against Windows, because I don't think that is necessary). --- src/helper_startup.py | 2 + src/shared.py | 97 +++++++++++++++++++++++++++++++------------ 2 files changed, 72 insertions(+), 27 deletions(-) diff --git a/src/helper_startup.py b/src/helper_startup.py index df27fd6e..f9eefc01 100644 --- a/src/helper_startup.py +++ b/src/helper_startup.py @@ -74,6 +74,8 @@ def loadConfig(): print 'Creating new config files in', shared.appdata if not os.path.exists(shared.appdata): os.makedirs(shared.appdata) + if not sys.platform.startswith('win'): + os.umask(0o077) with open(shared.appdata + 'keys.dat', 'wb') as configfile: shared.config.write(configfile) diff --git a/src/shared.py b/src/shared.py index 09d0bae8..57067334 100644 --- a/src/shared.py +++ b/src/shared.py @@ -169,10 +169,10 @@ def isAddressInMyAddressBookSubscriptionsListOrWhitelist(address): return False def safeConfigGetBoolean(section,field): - try: - return config.getboolean(section,field) - except: - return False + try: + return config.getboolean(section,field) + except: + return False def decodeWalletImportFormat(WIFstring): fullString = arithmetic.changebase(WIFstring,58,256) @@ -196,22 +196,37 @@ def reloadMyAddressHashes(): myECCryptorObjects.clear() myAddressesByHash.clear() #myPrivateKeys.clear() + + keyfileSecure = checkSensitiveFilePermissions(appdata + 'keys.dat') configSections = config.sections() - hasExistingKeys = False + hasEnabledKeys = False for addressInKeysFile in configSections: if addressInKeysFile <> 'bitmessagesettings': - hasExistingKeys = True + hasEnabledKeys = True isEnabled = config.getboolean(addressInKeysFile, 'enabled') if isEnabled: - status,addressVersionNumber,streamNumber,hash = decodeAddress(addressInKeysFile) - if addressVersionNumber == 2 or addressVersionNumber == 3: - privEncryptionKey = decodeWalletImportFormat(config.get(addressInKeysFile, 'privencryptionkey')).encode('hex') #returns a simple 32 bytes of information encoded in 64 Hex characters, or null if there was an error - if len(privEncryptionKey) == 64:#It is 32 bytes encoded as 64 hex characters - myECCryptorObjects[hash] = highlevelcrypto.makeCryptor(privEncryptionKey) - myAddressesByHash[hash] = addressInKeysFile + if keyfileSecure: + status,addressVersionNumber,streamNumber,hash = decodeAddress(addressInKeysFile) + if addressVersionNumber == 2 or addressVersionNumber == 3: + # Returns a simple 32 bytes of information encoded in 64 Hex characters, or null if there was an error. + privEncryptionKey = decodeWalletImportFormat( + config.get(addressInKeysFile, 'privencryptionkey')).encode('hex') + + if len(privEncryptionKey) == 64:#It is 32 bytes encoded as 64 hex characters + myECCryptorObjects[hash] = highlevelcrypto.makeCryptor(privEncryptionKey) + myAddressesByHash[hash] = addressInKeysFile + else: + sys.stderr.write('Error in reloadMyAddressHashes: Can\'t handle address versions other than 2 or 3.\n') else: - sys.stderr.write('Error in reloadMyAddressHashes: Can\'t handle address versions other than 2 or 3.\n') - fixKeyfilePermissions(appdata + 'keys.dat', hasExistingKeys) + # Insecure keyfile permissions. Disable key. + config.set(addressInKeysFile, 'enabled', 'false') + try: + if not keyfileSecure: + with open(appdata + 'keys.dat', 'wb') as keyfile: + config.write(keyfile) + except: + print 'Failed to disable vulnerable keyfiles.' + raise def reloadBroadcastSendersForWhichImWatching(): printLock.acquire() @@ -303,16 +318,14 @@ def fixPotentiallyInvalidUTF8Data(text): output = 'Part of the message is corrupt. The message cannot be displayed the normal way.\n\n' + repr(text) return output -# Fix keyfile permissions due to inappropriate umask during keys.dat creation. -def fixKeyfilePermissions(keyfile, hasExistingKeys): - present_keyfile_permissions = os.stat(keyfile)[0] - keyfile_disallowed_permissions = stat.S_IRWXG | stat.S_IRWXO - if (present_keyfile_permissions & keyfile_disallowed_permissions) != 0: - allowed_keyfile_permissions = ((1<<32)-1) ^ keyfile_disallowed_permissions - new_keyfile_permissions = ( - allowed_keyfile_permissions & present_keyfile_permissions) - os.chmod(keyfile, new_keyfile_permissions) - if hasExistingKeys: +def checkSensitiveFilePermissions(filename): + if sys.platform == 'win32': + # TODO: This might deserve extra checks by someone familiar with + # Windows systems. + fileSecure = True + else: + fileSecure = secureFilePermissions(filename) + if not fileSecure: print print '******************************************************************' print '** !! WARNING !! **' @@ -321,7 +334,37 @@ def fixKeyfilePermissions(keyfile, hasExistingKeys): print '** Your keyfiles were vulnerable to being read by other users **' print '** (including some untrusted daemons). You may wish to consider **' print '** generating new keys and discontinuing use of your old ones. **' - print '** The problem has been automatically fixed. **' - print '******************************************************************' - print + print '** Your private keys have been disabled for your security, but **' + print '** you may re-enable them using the "Your Identities" tab in **' + print '** the default GUI or by modifying keys.dat such that your keys **' + print '** show "enabled = true". **' + try: + fixSensitiveFilePermissions(filename) + print '** The problem has been automatically fixed. **' + print '******************************************************************' + print + except Exception, e: + print '** Could NOT automatically fix permissions. **' + print '******************************************************************' + print + raise + return fileSecure + + +# Checks sensitive file permissions for inappropriate umask during keys.dat creation. +# (Or unwise subsequent chmod.) +# Returns true iff file appears to have appropriate permissions. +def secureFilePermissions(filename): + present_permissions = os.stat(filename)[0] + disallowed_permissions = stat.S_IRWXG | stat.S_IRWXO + return present_permissions & disallowed_permissions == 0 + +# Fixes permissions on a sensitive file. +def fixSensitiveFilePermissions(filename): + present_permissions = os.stat(filename)[0] + disallowed_permissions = stat.S_IRWXG | stat.S_IRWXO + allowed_permissions = ((1<<32)-1) ^ disallowed_permissions + new_permissions = ( + allowed_permissions & present_permissions) + os.chmod(filename, new_permissions) From 1ed34b00848c07e5266ac4575474dbf3c42bc168 Mon Sep 17 00:00:00 2001 From: Gregor Robinson Date: Thu, 27 Jun 2013 10:44:49 +0000 Subject: [PATCH 03/39] Make warning message more specific. --- src/shared.py | 136 +++++++++++++++++++++++++++----------------------- 1 file changed, 73 insertions(+), 63 deletions(-) diff --git a/src/shared.py b/src/shared.py index 57067334..ea1e3848 100644 --- a/src/shared.py +++ b/src/shared.py @@ -202,31 +202,36 @@ def reloadMyAddressHashes(): hasEnabledKeys = False for addressInKeysFile in configSections: if addressInKeysFile <> 'bitmessagesettings': - hasEnabledKeys = True isEnabled = config.getboolean(addressInKeysFile, 'enabled') if isEnabled: - if keyfileSecure: - status,addressVersionNumber,streamNumber,hash = decodeAddress(addressInKeysFile) - if addressVersionNumber == 2 or addressVersionNumber == 3: - # Returns a simple 32 bytes of information encoded in 64 Hex characters, or null if there was an error. - privEncryptionKey = decodeWalletImportFormat( - config.get(addressInKeysFile, 'privencryptionkey')).encode('hex') + hasEnabledKeys = True + status,addressVersionNumber,streamNumber,hash = decodeAddress(addressInKeysFile) + if addressVersionNumber == 2 or addressVersionNumber == 3: + # Returns a simple 32 bytes of information encoded in 64 Hex characters, + # or null if there was an error. + privEncryptionKey = decodeWalletImportFormat( + config.get(addressInKeysFile, 'privencryptionkey')).encode('hex') - if len(privEncryptionKey) == 64:#It is 32 bytes encoded as 64 hex characters - myECCryptorObjects[hash] = highlevelcrypto.makeCryptor(privEncryptionKey) - myAddressesByHash[hash] = addressInKeysFile - else: - sys.stderr.write('Error in reloadMyAddressHashes: Can\'t handle address versions other than 2 or 3.\n') + if len(privEncryptionKey) == 64:#It is 32 bytes encoded as 64 hex characters + myECCryptorObjects[hash] = highlevelcrypto.makeCryptor(privEncryptionKey) + myAddressesByHash[hash] = addressInKeysFile + + if not keyfileSecure: + # Insecure keyfile permissions. Disable key. + config.set(addressInKeysFile, 'enabled', 'false') else: - # Insecure keyfile permissions. Disable key. - config.set(addressInKeysFile, 'enabled', 'false') - try: - if not keyfileSecure: - with open(appdata + 'keys.dat', 'wb') as keyfile: - config.write(keyfile) - except: - print 'Failed to disable vulnerable keyfiles.' - raise + sys.stderr.write('Error in reloadMyAddressHashes: Can\'t handle address ' + 'versions other than 2 or 3.\n') + + if not keyfileSecure: + fixSensitiveFilePermissions(appdata + 'keys.dat', hasEnabledKeys) + if hasEnabledKeys: + try: + with open(appdata + 'keys.dat', 'wb') as keyfile: + config.write(keyfile) + except: + print 'Failed to disable vulnerable keys.' + raise def reloadBroadcastSendersForWhichImWatching(): printLock.acquire() @@ -318,53 +323,58 @@ def fixPotentiallyInvalidUTF8Data(text): output = 'Part of the message is corrupt. The message cannot be displayed the normal way.\n\n' + repr(text) return output +# Checks sensitive file permissions for inappropriate umask during keys.dat creation. +# (Or unwise subsequent chmod.) +# Returns true iff file appears to have appropriate permissions. def checkSensitiveFilePermissions(filename): if sys.platform == 'win32': # TODO: This might deserve extra checks by someone familiar with # Windows systems. - fileSecure = True + return True else: - fileSecure = secureFilePermissions(filename) - if not fileSecure: - print - print '******************************************************************' - print '** !! WARNING !! **' - print '******************************************************************' - print '** Possibly major security problem: **' - print '** Your keyfiles were vulnerable to being read by other users **' - print '** (including some untrusted daemons). You may wish to consider **' - print '** generating new keys and discontinuing use of your old ones. **' - print '** Your private keys have been disabled for your security, but **' - print '** you may re-enable them using the "Your Identities" tab in **' - print '** the default GUI or by modifying keys.dat such that your keys **' - print '** show "enabled = true". **' - try: - fixSensitiveFilePermissions(filename) - print '** The problem has been automatically fixed. **' - print '******************************************************************' - print - except Exception, e: - print '** Could NOT automatically fix permissions. **' - print '******************************************************************' - print - raise - return fileSecure - - -# Checks sensitive file permissions for inappropriate umask during keys.dat creation. -# (Or unwise subsequent chmod.) -# Returns true iff file appears to have appropriate permissions. -def secureFilePermissions(filename): - present_permissions = os.stat(filename)[0] - disallowed_permissions = stat.S_IRWXG | stat.S_IRWXO - return present_permissions & disallowed_permissions == 0 + present_permissions = os.stat(filename)[0] + disallowed_permissions = stat.S_IRWXG | stat.S_IRWXO + return present_permissions & disallowed_permissions == 0 # Fixes permissions on a sensitive file. -def fixSensitiveFilePermissions(filename): - present_permissions = os.stat(filename)[0] - disallowed_permissions = stat.S_IRWXG | stat.S_IRWXO - allowed_permissions = ((1<<32)-1) ^ disallowed_permissions - new_permissions = ( - allowed_permissions & present_permissions) - os.chmod(filename, new_permissions) +def fixSensitiveFilePermissions(filename, hasEnabledKeys): + if hasEnabledKeys: + print + print '******************************************************************' + print '** !! WARNING !! **' + print '******************************************************************' + print '** Possibly major security problem: **' + print '** Your keyfile was vulnerable to being read by other users **' + print '** (including some untrusted daemons). You may wish to consider **' + print '** generating new keys and discontinuing use of your old ones. **' + print '** Your private keys have been disabled for your security, but **' + print '** you may re-enable them using the "Your Identities" tab in **' + print '** the default GUI or by modifying keys.dat such that your keys **' + print '** show "enabled = true". **' + else: + print '******************************************************************' + print '** !! WARNING !! **' + print '******************************************************************' + print '** Possibly major security problem: **' + print '** Your keyfile was vulnerable to being read by other users. **' + print '** Fortunately, you don\'t have any enabled keys, but be aware **' + print '** that any disabled keys may have been compromised by malware **' + print '** running by other users and that you should reboot before **' + print '** generating any new keys. **' + try: + present_permissions = os.stat(filename)[0] + disallowed_permissions = stat.S_IRWXG | stat.S_IRWXO + allowed_permissions = ((1<<32)-1) ^ disallowed_permissions + new_permissions = ( + allowed_permissions & present_permissions) + os.chmod(filename, new_permissions) + + print '** The file permissions have been automatically fixed. **' + print '******************************************************************' + print + except Exception, e: + print '** Could NOT automatically fix permissions. **' + print '******************************************************************' + print + raise From ebaa1bf3468d617cc9ec5353f34e32facb992840 Mon Sep 17 00:00:00 2001 From: Gregor Robinson Date: Mon, 8 Jul 2013 23:21:29 +0300 Subject: [PATCH 04/39] No paranoid key disable for bad keyfile perms. --- src/shared.py | 81 ++++++++++++++++++--------------------------------- 1 file changed, 28 insertions(+), 53 deletions(-) diff --git a/src/shared.py b/src/shared.py index 9a1cd428..2930784e 100644 --- a/src/shared.py +++ b/src/shared.py @@ -8,20 +8,24 @@ maximumAgeOfNodesThatIAdvertiseToOthers = 10800 # Equals three hours useVeryEasyProofOfWorkForTesting = False # If you set this to True while on the normal network, you won't be able to send or sometimes receive messages. -import threading -import sys -from addresses import * -import highlevelcrypto -import Queue -import pickle -import os -import time +# Libraries. import ConfigParser -import socket +import os +import pickle +import Queue import random +import socket +import sys +import stat +import threading +import time + +# Project imports. +from addresses import * +from debug import logger import highlevelcrypto import shared -import stat + config = ConfigParser.SafeConfigParser() myECCryptorObjects = {} @@ -131,12 +135,14 @@ def lookupAppdataFolder(): except KeyError: dataFolder = path.join(environ["HOME"], ".config", APPNAME) # Migrate existing data to the proper location if this is an existing install - try: - print "Moving data folder to ~/.config/%s" % APPNAME - move(path.join(environ["HOME"], ".%s" % APPNAME), dataFolder) - dataFolder = dataFolder + '/' - except IOError: - dataFolder = dataFolder + '/' + if not os.path.exists(dataFolder): + try: + print "Moving data folder to ~/.config/%s" % APPNAME + move(path.join(environ["HOME"], ".%s" % APPNAME), dataFolder) + dataFolder = dataFolder + except IOError: + dataFolder = dataFolder + dataFolder = dataFolder + '/' return dataFolder def isAddressInMyAddressBook(address): @@ -227,22 +233,12 @@ def reloadMyAddressHashes(): myECCryptorObjects[hash] = highlevelcrypto.makeCryptor(privEncryptionKey) myAddressesByHash[hash] = addressInKeysFile - if not keyfileSecure: - # Insecure keyfile permissions. Disable key. - config.set(addressInKeysFile, 'enabled', 'false') else: sys.stderr.write('Error in reloadMyAddressHashes: Can\'t handle address ' 'versions other than 2 or 3.\n') if not keyfileSecure: fixSensitiveFilePermissions(appdata + 'keys.dat', hasEnabledKeys) - if hasEnabledKeys: - try: - with open(appdata + 'keys.dat', 'wb') as keyfile: - config.write(keyfile) - except: - print 'Failed to disable vulnerable keys.' - raise def reloadBroadcastSendersForWhichImWatching(): printLock.acquire() @@ -350,28 +346,10 @@ def checkSensitiveFilePermissions(filename): # Fixes permissions on a sensitive file. def fixSensitiveFilePermissions(filename, hasEnabledKeys): if hasEnabledKeys: - print - print '******************************************************************' - print '** !! WARNING !! **' - print '******************************************************************' - print '** Possibly major security problem: **' - print '** Your keyfile was vulnerable to being read by other users **' - print '** (including some untrusted daemons). You may wish to consider **' - print '** generating new keys and discontinuing use of your old ones. **' - print '** Your private keys have been disabled for your security, but **' - print '** you may re-enable them using the "Your Identities" tab in **' - print '** the default GUI or by modifying keys.dat such that your keys **' - print '** show "enabled = true". **' + logger.warning('Keyfile had insecure permissions, and there were enabled keys. ' + 'The truly paranoid should stop using them immediately.') else: - print '******************************************************************' - print '** !! WARNING !! **' - print '******************************************************************' - print '** Possibly major security problem: **' - print '** Your keyfile was vulnerable to being read by other users. **' - print '** Fortunately, you don\'t have any enabled keys, but be aware **' - print '** that any disabled keys may have been compromised by malware **' - print '** running by other users and that you should reboot before **' - print '** generating any new keys. **' + logger.warning('Keyfile had insecure permissions, but there were no enabled keys.') try: present_permissions = os.stat(filename)[0] disallowed_permissions = stat.S_IRWXG | stat.S_IRWXO @@ -380,12 +358,9 @@ def fixSensitiveFilePermissions(filename, hasEnabledKeys): allowed_permissions & present_permissions) os.chmod(filename, new_permissions) - print '** The file permissions have been automatically fixed. **' - print '******************************************************************' - print + logger.info('Keyfile permissions automatically fixed.') + except Exception, e: - print '** Could NOT automatically fix permissions. **' - print '******************************************************************' - print + logger.exception('Keyfile permissions could not be fixed.') raise From 1ff1c1b8a5b8d523971f69e3b646742362f35bce Mon Sep 17 00:00:00 2001 From: Gregor Robinson Date: Mon, 8 Jul 2013 23:33:15 +0300 Subject: [PATCH 05/39] Spelling. --- src/helper_bootstrap.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/helper_bootstrap.py b/src/helper_bootstrap.py index 296dda6b..c3d5c1fd 100644 --- a/src/helper_bootstrap.py +++ b/src/helper_bootstrap.py @@ -33,7 +33,7 @@ def dns(): print 'Adding', item[4][0], 'to knownNodes based on DNS boostrap method' shared.knownNodes[1][item[4][0]] = (8080, int(time.time())) except: - print 'bootstrap8080.bitmessage.org DNS bootstraping failed.' + print 'bootstrap8080.bitmessage.org DNS bootstrapping failed.' try: for item in socket.getaddrinfo('bootstrap8444.bitmessage.org', 80): print 'Adding', item[4][0], 'to knownNodes based on DNS boostrap method' From a579e8f1d324dac0c547c2d18cbce6e2f4bee7d9 Mon Sep 17 00:00:00 2001 From: Gregor Robinson Date: Wed, 10 Jul 2013 11:43:18 +0300 Subject: [PATCH 06/39] Logging fixes. --- src/debug.py | 3 +++ src/shared.py | 57 +++++++++++++++++++++++++-------------------------- 2 files changed, 31 insertions(+), 29 deletions(-) diff --git a/src/debug.py b/src/debug.py index d8033f2d..14214686 100644 --- a/src/debug.py +++ b/src/debug.py @@ -48,12 +48,15 @@ logging.config.dictConfig({ 'loggers': { 'console_only': { 'handlers': ['console'], + 'propagate' : 0 }, 'file_only': { 'handlers': ['file'], + 'propagate' : 0 }, 'both': { 'handlers': ['console', 'file'], + 'propagate' : 0 }, }, 'root': { diff --git a/src/shared.py b/src/shared.py index 2930784e..e7a412ac 100644 --- a/src/shared.py +++ b/src/shared.py @@ -123,7 +123,8 @@ def lookupAppdataFolder(): if "HOME" in environ: dataFolder = path.join(os.environ["HOME"], "Library/Application Support/", APPNAME) + '/' else: - print 'Could not find home folder, please report this message and your OS X version to the BitMessage Github.' + logger.critical('Could not find home folder, please report this message and your ' + 'OS X version to the BitMessage Github.') sys.exit() elif 'win32' in sys.platform or 'win64' in sys.platform: @@ -137,7 +138,7 @@ def lookupAppdataFolder(): # Migrate existing data to the proper location if this is an existing install if not os.path.exists(dataFolder): try: - print "Moving data folder to ~/.config/%s" % APPNAME + logger.info("Moving data folder to %s" % (dataFolder)) move(path.join(environ["HOME"], ".%s" % APPNAME), dataFolder) dataFolder = dataFolder except IOError: @@ -195,21 +196,22 @@ def decodeWalletImportFormat(WIFstring): fullString = arithmetic.changebase(WIFstring,58,256) privkey = fullString[:-4] if fullString[-4:] != hashlib.sha256(hashlib.sha256(privkey).digest()).digest()[:4]: - sys.stderr.write('Major problem! When trying to decode one of your private keys, the checksum failed. Here is the PRIVATE key: %s\n' % str(WIFstring)) + logger.error('Major problem! When trying to decode one of your private keys, the checksum ' + 'failed. Here is the PRIVATE key: %s\n' % str(WIFstring)) return "" else: #checksum passed if privkey[0] == '\x80': return privkey[1:] else: - sys.stderr.write('Major problem! When trying to decode one of your private keys, the checksum passed but the key doesn\'t begin with hex 80. Here is the PRIVATE key: %s\n' % str(WIFstring)) + logger.error('Major problem! When trying to decode one of your private keys, the ' + 'checksum passed but the key doesn\'t begin with hex 80. Here is the ' + 'PRIVATE key: %s\n' % str(WIFstring)) return "" def reloadMyAddressHashes(): - printLock.acquire() - print 'reloading keys from keys.dat file' - printLock.release() + logger.debug('reloading keys from keys.dat file') myECCryptorObjects.clear() myAddressesByHash.clear() #myPrivateKeys.clear() @@ -241,9 +243,7 @@ def reloadMyAddressHashes(): fixSensitiveFilePermissions(appdata + 'keys.dat', hasEnabledKeys) def reloadBroadcastSendersForWhichImWatching(): - printLock.acquire() - print 'reloading subscriptions...' - printLock.release() + logger.debug('reloading subscriptions...') broadcastSendersForWhichImWatching.clear() MyECSubscriptionCryptorObjects.clear() sqlLock.acquire() @@ -266,46 +266,44 @@ def doCleanShutdown(): knownNodesLock.acquire() UISignalQueue.put(('updateStatusBar','Saving the knownNodes list of peers to disk...')) output = open(appdata + 'knownnodes.dat', 'wb') - print 'finished opening knownnodes.dat. Now pickle.dump' + logger.info('finished opening knownnodes.dat. Now pickle.dump') pickle.dump(knownNodes, output) - print 'Completed pickle.dump. Closing output...' + logger.info('Completed pickle.dump. Closing output...') output.close() knownNodesLock.release() - printLock.acquire() - print 'Finished closing knownnodes.dat output file.' - printLock.release() + logger.info('Finished closing knownnodes.dat output file.') UISignalQueue.put(('updateStatusBar','Done saving the knownNodes list of peers to disk.')) broadcastToSendDataQueues((0, 'shutdown', 'all')) - printLock.acquire() - print 'Flushing inventory in memory out to disk...' - printLock.release() - UISignalQueue.put(('updateStatusBar','Flushing inventory in memory out to disk. This should normally only take a second...')) + logger.info('Flushing inventory in memory out to disk...') + UISignalQueue.put(('updateStatusBar','Flushing inventory in memory out to disk. ' + 'This should normally only take a second...')) flushInventory() - #This one last useless query will guarantee that the previous flush committed before we close the program. + # This one last useless query will guarantee that the previous flush committed before we close + # the program. sqlLock.acquire() sqlSubmitQueue.put('SELECT address FROM subscriptions') sqlSubmitQueue.put('') sqlReturnQueue.get() sqlSubmitQueue.put('exit') sqlLock.release() - printLock.acquire() - print 'Finished flushing inventory.' - printLock.release() + logger.info('Finished flushing inventory.') - time.sleep(.25) #Wait long enough to guarantee that any running proof of work worker threads will check the shutdown variable and exit. If the main thread closes before they do then they won't stop. + # Wait long enough to guarantee that any running proof of work worker threads will check the + # shutdown variable and exit. If the main thread closes before they do then they won't stop. + time.sleep(.25) if safeConfigGetBoolean('bitmessagesettings','daemon'): - printLock.acquire() - print 'Done.' - printLock.release() + logger.info('Clean shutdown complete.') os._exit(0) -#When you want to command a sendDataThread to do something, like shutdown or send some data, this function puts your data into the queues for each of the sendDataThreads. The sendDataThreads are responsible for putting their queue into (and out of) the sendDataQueues list. +# When you want to command a sendDataThread to do something, like shutdown or send some data, this +# function puts your data into the queues for each of the sendDataThreads. The sendDataThreads are +# responsible for putting their queue into (and out of) the sendDataQueues list. def broadcastToSendDataQueues(data): - #print 'running broadcastToSendDataQueues' + # logger.debug('running broadcastToSendDataQueues') for q in sendDataQueues: q.put((data)) @@ -332,6 +330,7 @@ def fixPotentiallyInvalidUTF8Data(text): # Checks sensitive file permissions for inappropriate umask during keys.dat creation. # (Or unwise subsequent chmod.) +# # Returns true iff file appears to have appropriate permissions. def checkSensitiveFilePermissions(filename): if sys.platform == 'win32': From 2e2db97250d38f190cdc7aeb600360ba9c4054a6 Mon Sep 17 00:00:00 2001 From: Gregor Robinson Date: Wed, 10 Jul 2013 19:50:18 +0100 Subject: [PATCH 07/39] Don't propagate loggers; add some logging. --- src/debug.py | 3 +++ src/shared.py | 61 +++++++++++++++++++++++---------------------------- 2 files changed, 31 insertions(+), 33 deletions(-) diff --git a/src/debug.py b/src/debug.py index d8033f2d..14214686 100644 --- a/src/debug.py +++ b/src/debug.py @@ -48,12 +48,15 @@ logging.config.dictConfig({ 'loggers': { 'console_only': { 'handlers': ['console'], + 'propagate' : 0 }, 'file_only': { 'handlers': ['file'], + 'propagate' : 0 }, 'both': { 'handlers': ['console', 'file'], + 'propagate' : 0 }, }, 'root': { diff --git a/src/shared.py b/src/shared.py index 4b3ef73b..313e2ac6 100644 --- a/src/shared.py +++ b/src/shared.py @@ -118,7 +118,8 @@ def lookupAppdataFolder(): if "HOME" in environ: dataFolder = path.join(os.environ["HOME"], "Library/Application Support/", APPNAME) + '/' else: - print 'Could not find home folder, please report this message and your OS X version to the BitMessage Github.' + logger.critical('Could not find home folder, please report this message and your ' + 'OS X version to the BitMessage Github.') sys.exit() elif 'win32' in sys.platform or 'win64' in sys.platform: @@ -129,13 +130,14 @@ def lookupAppdataFolder(): dataFolder = path.join(environ["XDG_CONFIG_HOME"], APPNAME) except KeyError: dataFolder = path.join(environ["HOME"], ".config", APPNAME) + # Migrate existing data to the proper location if this is an existing install - try: - print "Moving data folder to ~/.config/%s" % APPNAME - move(path.join(environ["HOME"], ".%s" % APPNAME), dataFolder) - dataFolder = dataFolder + '/' - except IOError: - dataFolder = dataFolder + '/' + if not os.path.exists(dataFolder): + try: + logger.info("Moving data folder to ~/.config/%s" % APPNAME) + move(path.join(environ["HOME"], ".%s" % APPNAME), dataFolder) + except IOError: + dataFolder = dataFolder + '/' return dataFolder def isAddressInMyAddressBook(address): @@ -200,9 +202,7 @@ def decodeWalletImportFormat(WIFstring): def reloadMyAddressHashes(): - printLock.acquire() - print 'reloading keys from keys.dat file' - printLock.release() + logger.debug('reloading keys from keys.dat file') myECCryptorObjects.clear() myAddressesByHash.clear() #myPrivateKeys.clear() @@ -221,9 +221,7 @@ def reloadMyAddressHashes(): sys.stderr.write('Error in reloadMyAddressHashes: Can\'t handle address versions other than 2 or 3.\n') def reloadBroadcastSendersForWhichImWatching(): - printLock.acquire() - print 'reloading subscriptions...' - printLock.release() + logger.debug('reloading subscriptions...') broadcastSendersForWhichImWatching.clear() MyECSubscriptionCryptorObjects.clear() sqlLock.acquire() @@ -246,46 +244,43 @@ def doCleanShutdown(): knownNodesLock.acquire() UISignalQueue.put(('updateStatusBar','Saving the knownNodes list of peers to disk...')) output = open(appdata + 'knownnodes.dat', 'wb') - print 'finished opening knownnodes.dat. Now pickle.dump' + logger.info('finished opening knownnodes.dat. Now pickle.dump') pickle.dump(knownNodes, output) - print 'Completed pickle.dump. Closing output...' + logger.info('Completed pickle.dump. Closing output...') output.close() knownNodesLock.release() - printLock.acquire() - print 'Finished closing knownnodes.dat output file.' - printLock.release() + logger.info('Finished closing knownnodes.dat output file.') UISignalQueue.put(('updateStatusBar','Done saving the knownNodes list of peers to disk.')) broadcastToSendDataQueues((0, 'shutdown', 'all')) - printLock.acquire() - print 'Flushing inventory in memory out to disk...' - printLock.release() - UISignalQueue.put(('updateStatusBar','Flushing inventory in memory out to disk. This should normally only take a second...')) + logger.info('Flushing inventory in memory out to disk...') + UISignalQueue.put(('updateStatusBar','Flushing inventory in memory out to disk. ' + 'This should normally only take a second...')) flushInventory() - #This one last useless query will guarantee that the previous flush committed before we close the program. + # This one last useless query will guarantee that the previous flush committed before we close + # the program. sqlLock.acquire() sqlSubmitQueue.put('SELECT address FROM subscriptions') sqlSubmitQueue.put('') sqlReturnQueue.get() sqlSubmitQueue.put('exit') sqlLock.release() - printLock.acquire() - print 'Finished flushing inventory.' - printLock.release() - - time.sleep(.25) #Wait long enough to guarantee that any running proof of work worker threads will check the shutdown variable and exit. If the main thread closes before they do then they won't stop. + logger.info('Finished flushing inventory.') + # Wait long enough to guarantee that any running proof of work worker threads will check the + # shutdown variable and exit. If the main thread closes before they do then they won't stop. + time.sleep(.25) if safeConfigGetBoolean('bitmessagesettings','daemon'): - printLock.acquire() - print 'Done.' - printLock.release() + logger.info('Clean shutdown complete.') os._exit(0) -#When you want to command a sendDataThread to do something, like shutdown or send some data, this function puts your data into the queues for each of the sendDataThreads. The sendDataThreads are responsible for putting their queue into (and out of) the sendDataQueues list. +# When you want to command a sendDataThread to do something, like shutdown or send some data, this +# function puts your data into the queues for each of the sendDataThreads. The sendDataThreads are +# responsible for putting their queue into (and out of) the sendDataQueues list. def broadcastToSendDataQueues(data): - #print 'running broadcastToSendDataQueues' + # logger.debug('running broadcastToSendDataQueues') for q in sendDataQueues: q.put((data)) From 3179ea30f01912a55d1ede14b1fc161d48b7969a Mon Sep 17 00:00:00 2001 From: Gregor Robinson Date: Wed, 10 Jul 2013 20:15:04 +0100 Subject: [PATCH 08/39] These changes slipped from last commit. Sorry. --- src/shared.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/shared.py b/src/shared.py index 313e2ac6..c706038a 100644 --- a/src/shared.py +++ b/src/shared.py @@ -21,6 +21,7 @@ import socket import random import highlevelcrypto import shared +from debug import logger config = ConfigParser.SafeConfigParser() myECCryptorObjects = {} @@ -132,11 +133,11 @@ def lookupAppdataFolder(): dataFolder = path.join(environ["HOME"], ".config", APPNAME) # Migrate existing data to the proper location if this is an existing install - if not os.path.exists(dataFolder): - try: - logger.info("Moving data folder to ~/.config/%s" % APPNAME) - move(path.join(environ["HOME"], ".%s" % APPNAME), dataFolder) - except IOError: + try: + logger.info("Moving data folder to %s" % (dataFolder)) + move(path.join(environ["HOME"], ".%s" % APPNAME), dataFolder) + except IOError: + pass dataFolder = dataFolder + '/' return dataFolder @@ -255,8 +256,9 @@ def doCleanShutdown(): broadcastToSendDataQueues((0, 'shutdown', 'all')) logger.info('Flushing inventory in memory out to disk...') - UISignalQueue.put(('updateStatusBar','Flushing inventory in memory out to disk. ' - 'This should normally only take a second...')) + UISignalQueue.put(( + 'updateStatusBar', + 'Flushing inventory in memory out to disk. This should normally only take a second...')) flushInventory() # This one last useless query will guarantee that the previous flush committed before we close From e8fa5aaefe32a0d77c9a0c634ee07623ae1bc1bd Mon Sep 17 00:00:00 2001 From: Gregor Robinson Date: Wed, 10 Jul 2013 20:29:07 +0100 Subject: [PATCH 09/39] Switch an stderr message to logger. --- src/shared.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/shared.py b/src/shared.py index 0dbeef5d..816cea2a 100644 --- a/src/shared.py +++ b/src/shared.py @@ -236,8 +236,8 @@ def reloadMyAddressHashes(): myAddressesByHash[hash] = addressInKeysFile else: - sys.stderr.write('Error in reloadMyAddressHashes: Can\'t handle address ' - 'versions other than 2 or 3.\n') + logger.error('Error in reloadMyAddressHashes: Can\'t handle address ' + 'versions other than 2 or 3.\n') if not keyfileSecure: fixSensitiveFilePermissions(appdata + 'keys.dat', hasEnabledKeys) From 14266de0c69725b62823845a275ab9ec9bc56574 Mon Sep 17 00:00:00 2001 From: Rainulf Pineda Date: Thu, 11 Jul 2013 03:23:39 -0400 Subject: [PATCH 10/39] Updated bitmessageui for search. --- src/bitmessageqt/bitmessageui.ui | 76 ++++++++++++++++++++++++++------ 1 file changed, 62 insertions(+), 14 deletions(-) diff --git a/src/bitmessageqt/bitmessageui.ui b/src/bitmessageqt/bitmessageui.ui index 48f5c224..8aef2309 100644 --- a/src/bitmessageqt/bitmessageui.ui +++ b/src/bitmessageqt/bitmessageui.ui @@ -14,7 +14,7 @@ Bitmessage - + :/newPrefix/images/can-icon-24px.png:/newPrefix/images/can-icon-24px.png @@ -22,7 +22,16 @@ - + + 0 + + + 0 + + + 0 + + 0 @@ -61,13 +70,52 @@ - + :/newPrefix/images/inbox.png:/newPrefix/images/inbox.png Inbox + + + + 0 + + + + + + + + + All + + + + + To + + + + + From + + + + + Subject + + + + + Received + + + + + + @@ -145,7 +193,7 @@ - + :/newPrefix/images/send.png:/newPrefix/images/send.png @@ -214,8 +262,8 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;"> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html> +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2';"><br /></p></body></html> @@ -303,7 +351,7 @@ p, li { white-space: pre-wrap; } - + :/newPrefix/images/sent.png:/newPrefix/images/sent.png @@ -380,7 +428,7 @@ p, li { white-space: pre-wrap; } - + :/newPrefix/images/identities.png:/newPrefix/images/identities.png @@ -480,7 +528,7 @@ p, li { white-space: pre-wrap; } - + :/newPrefix/images/subscriptions.png:/newPrefix/images/subscriptions.png @@ -565,7 +613,7 @@ p, li { white-space: pre-wrap; } - + :/newPrefix/images/addressbook.png:/newPrefix/images/addressbook.png @@ -647,7 +695,7 @@ p, li { white-space: pre-wrap; } - + :/newPrefix/images/blacklist.png:/newPrefix/images/blacklist.png @@ -739,7 +787,7 @@ p, li { white-space: pre-wrap; } - + :/newPrefix/images/networkstatus.png:/newPrefix/images/networkstatus.png @@ -758,7 +806,7 @@ p, li { white-space: pre-wrap; } - + :/newPrefix/images/redicon.png:/newPrefix/images/redicon.png @@ -925,7 +973,7 @@ p, li { white-space: pre-wrap; } 0 0 795 - 18 + 20 From fa53eb370ca7584bd0d88de2ad956d8894ab7a8e Mon Sep 17 00:00:00 2001 From: Gregor Robinson Date: Thu, 11 Jul 2013 23:58:10 +0100 Subject: [PATCH 11/39] Clarify IOError handling with comment. --- src/shared.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/shared.py b/src/shared.py index 816cea2a..85246906 100644 --- a/src/shared.py +++ b/src/shared.py @@ -142,6 +142,7 @@ def lookupAppdataFolder(): logger.info("Moving data folder to %s" % (dataFolder)) move(path.join(environ["HOME"], ".%s" % APPNAME), dataFolder) except IOError: + # Old directory may not exist. pass dataFolder = dataFolder + '/' return dataFolder From 855a9f963f02b79aaab1003ab63b18f480dc7527 Mon Sep 17 00:00:00 2001 From: Rainulf Pineda Date: Fri, 12 Jul 2013 02:01:33 -0400 Subject: [PATCH 12/39] Generated py for search. --- Makefile | 0 debian.sh | 0 debian/rules | 0 osx.sh | 0 src/bitmessageqt/bitmessageui.py | 30 +++++++++++++++++++++++++----- src/bitmessageqt/bitmessageui.ui | 20 ++++++++++---------- 6 files changed, 35 insertions(+), 15 deletions(-) mode change 100755 => 100644 Makefile mode change 100755 => 100644 debian.sh mode change 100755 => 100644 debian/rules mode change 100755 => 100644 osx.sh diff --git a/Makefile b/Makefile old mode 100755 new mode 100644 diff --git a/debian.sh b/debian.sh old mode 100755 new mode 100644 diff --git a/debian/rules b/debian/rules old mode 100755 new mode 100644 diff --git a/osx.sh b/osx.sh old mode 100755 new mode 100644 diff --git a/src/bitmessageqt/bitmessageui.py b/src/bitmessageqt/bitmessageui.py index 1186e814..dbb33fb0 100644 --- a/src/bitmessageqt/bitmessageui.py +++ b/src/bitmessageqt/bitmessageui.py @@ -2,8 +2,8 @@ # Form implementation generated from reading ui file 'bitmessageui.ui' # -# Created: Thu Jun 13 01:02:50 2013 -# by: PyQt4 UI code generator 4.10.1 +# Created: Fri Jul 12 01:59:15 2013 +# by: PyQt4 UI code generator 4.10 # # WARNING! All changes made in this file will be lost! @@ -54,6 +54,21 @@ class Ui_MainWindow(object): self.inbox.setObjectName(_fromUtf8("inbox")) self.verticalLayout_2 = QtGui.QVBoxLayout(self.inbox) self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2")) + self.horizontalLayoutSearch = QtGui.QHBoxLayout() + self.horizontalLayoutSearch.setContentsMargins(-1, 0, -1, -1) + self.horizontalLayoutSearch.setObjectName(_fromUtf8("horizontalLayoutSearch")) + self.searchLineEdit = QtGui.QLineEdit(self.inbox) + self.searchLineEdit.setObjectName(_fromUtf8("searchLineEdit")) + self.horizontalLayoutSearch.addWidget(self.searchLineEdit) + self.searchOptionCB = QtGui.QComboBox(self.inbox) + self.searchOptionCB.setObjectName(_fromUtf8("searchOptionCB")) + self.searchOptionCB.addItem(_fromUtf8("")) + self.searchOptionCB.addItem(_fromUtf8("")) + self.searchOptionCB.addItem(_fromUtf8("")) + self.searchOptionCB.addItem(_fromUtf8("")) + self.searchOptionCB.addItem(_fromUtf8("")) + self.horizontalLayoutSearch.addWidget(self.searchOptionCB) + self.verticalLayout_2.addLayout(self.horizontalLayoutSearch) self.tableWidgetInbox = QtGui.QTableWidget(self.inbox) self.tableWidgetInbox.setAlternatingRowColors(True) self.tableWidgetInbox.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection) @@ -392,7 +407,7 @@ class Ui_MainWindow(object): self.gridLayout.addWidget(self.tabWidget, 0, 0, 1, 1) MainWindow.setCentralWidget(self.centralwidget) self.menubar = QtGui.QMenuBar(MainWindow) - self.menubar.setGeometry(QtCore.QRect(0, 0, 795, 18)) + self.menubar.setGeometry(QtCore.QRect(0, 0, 795, 20)) self.menubar.setObjectName(_fromUtf8("menubar")) self.menuFile = QtGui.QMenu(self.menubar) self.menuFile.setObjectName(_fromUtf8("menuFile")) @@ -467,6 +482,11 @@ class Ui_MainWindow(object): def retranslateUi(self, MainWindow): MainWindow.setWindowTitle(_translate("MainWindow", "Bitmessage", None)) + self.searchOptionCB.setItemText(0, _translate("MainWindow", "All", None)) + self.searchOptionCB.setItemText(1, _translate("MainWindow", "To", None)) + self.searchOptionCB.setItemText(2, _translate("MainWindow", "From", None)) + self.searchOptionCB.setItemText(3, _translate("MainWindow", "Subject", None)) + self.searchOptionCB.setItemText(4, _translate("MainWindow", "Received", None)) self.tableWidgetInbox.setSortingEnabled(True) item = self.tableWidgetInbox.horizontalHeaderItem(0) item.setText(_translate("MainWindow", "To", None)) @@ -484,8 +504,8 @@ class Ui_MainWindow(object): self.textEditMessage.setHtml(_translate("MainWindow", "\n" "\n" -"


", None)) +"\n" +"


", None)) self.label.setText(_translate("MainWindow", "To:", None)) self.label_2.setText(_translate("MainWindow", "From:", None)) self.radioButtonBroadcast.setText(_translate("MainWindow", "Broadcast to everyone who is subscribed to your address", None)) diff --git a/src/bitmessageqt/bitmessageui.ui b/src/bitmessageqt/bitmessageui.ui index 8aef2309..65ad632d 100644 --- a/src/bitmessageqt/bitmessageui.ui +++ b/src/bitmessageqt/bitmessageui.ui @@ -14,7 +14,7 @@ Bitmessage - + :/newPrefix/images/can-icon-24px.png:/newPrefix/images/can-icon-24px.png @@ -70,7 +70,7 @@ - + :/newPrefix/images/inbox.png:/newPrefix/images/inbox.png @@ -193,7 +193,7 @@ - + :/newPrefix/images/send.png:/newPrefix/images/send.png @@ -351,7 +351,7 @@ p, li { white-space: pre-wrap; } - + :/newPrefix/images/sent.png:/newPrefix/images/sent.png @@ -428,7 +428,7 @@ p, li { white-space: pre-wrap; } - + :/newPrefix/images/identities.png:/newPrefix/images/identities.png @@ -528,7 +528,7 @@ p, li { white-space: pre-wrap; } - + :/newPrefix/images/subscriptions.png:/newPrefix/images/subscriptions.png @@ -613,7 +613,7 @@ p, li { white-space: pre-wrap; } - + :/newPrefix/images/addressbook.png:/newPrefix/images/addressbook.png @@ -695,7 +695,7 @@ p, li { white-space: pre-wrap; } - + :/newPrefix/images/blacklist.png:/newPrefix/images/blacklist.png @@ -787,7 +787,7 @@ p, li { white-space: pre-wrap; } - + :/newPrefix/images/networkstatus.png:/newPrefix/images/networkstatus.png @@ -806,7 +806,7 @@ p, li { white-space: pre-wrap; } - + :/newPrefix/images/redicon.png:/newPrefix/images/redicon.png From c1496551e66440d252a622d1a6f3ef72b2e658fe Mon Sep 17 00:00:00 2001 From: akh81 Date: Fri, 12 Jul 2013 03:12:57 -0500 Subject: [PATCH 13/39] added translations --- src/translations/bitmessage_ru_RU.pro | 30 + src/translations/bitmessage_ru_RU.qm | Bin 0 -> 18186 bytes src/translations/bitmessage_ru_RU.ts | 1248 +++++++++++++++++++++++++ 3 files changed, 1278 insertions(+) create mode 100644 src/translations/bitmessage_ru_RU.pro create mode 100644 src/translations/bitmessage_ru_RU.qm create mode 100644 src/translations/bitmessage_ru_RU.ts diff --git a/src/translations/bitmessage_ru_RU.pro b/src/translations/bitmessage_ru_RU.pro new file mode 100644 index 00000000..71cac3ae --- /dev/null +++ b/src/translations/bitmessage_ru_RU.pro @@ -0,0 +1,30 @@ +SOURCES += ../addresses.py +SOURCES += ../bitmessagemain.py +SOURCES += ../class_addressGenerator.py +SOURCES += ../class_outgoingSynSender.py +SOURCES += ../class_receiveDataThread.py +SOURCES += ../class_sendDataThread.py +SOURCES += ../class_singleCleaner.py +SOURCES += ../class_singleListener.py +SOURCES += ../class_singleWorker.py +SOURCES += ../class_sqlThread.py +SOURCES += ../helper_bitcoin.py +SOURCES += ../helper_bootstrap.py +SOURCES += ../helper_generic.py +SOURCES += ../helper_inbox.py +SOURCES += ../helper_sent.py +SOURCES += ../helper_startup.py +SOURCES += ../shared.py +SOURCES += ../bitmessageqt/__init__.py +SOURCES += ../bitmessageqt/about.py +SOURCES += ../bitmessageqt/bitmessageui.py +SOURCES += ../bitmessageqt/help.py +SOURCES += ../bitmessageqt/iconglossary.py +SOURCES += ../bitmessageqt/newaddressdialog.py +SOURCES += ../bitmessageqt/newchandialog.py +SOURCES += ../bitmessageqt/newsubscriptiondialog.py +SOURCES += ../bitmessageqt/regenerateaddresses.py +SOURCES += ../bitmessageqt/settings.py +SOURCES += ../bitmessageqt/specialaddressbehavior.py + +TRANSLATIONS = bitmessage_ru_RU.ts diff --git a/src/translations/bitmessage_ru_RU.qm b/src/translations/bitmessage_ru_RU.qm new file mode 100644 index 0000000000000000000000000000000000000000..e878db88e37272e43abffc0181d99c25b5c2b4d1 GIT binary patch literal 18186 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 B#{K{R literal 0 HcmV?d00001 diff --git a/src/translations/bitmessage_ru_RU.ts b/src/translations/bitmessage_ru_RU.ts new file mode 100644 index 00000000..23061133 --- /dev/null +++ b/src/translations/bitmessage_ru_RU.ts @@ -0,0 +1,1248 @@ + + + + + MainWindow + + + One of your addresses, %1, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? + + + + + Reply + Ответить + + + + Add sender to your Address Book + Добавить отправителя в адресную книгу + + + + Move to Trash + Поместить в корзину + + + + View HTML code as formatted text + + + + + Save message as... + Сохранить сообщение как ... + + + + New + Новый адрес + + + + Enable + + + + + Disable + + + + + Copy address to clipboard + Скопировать адрес в буфер обмена + + + + Special address behavior... + + + + + Send message to this address + + + + + Subscribe to this address + + + + + Add New Address + Добавить новый адрес + + + + Delete + + + + + Copy destination address to clipboard + Скопировать адрес отправки в буфер обмена + + + + Force send + + + + + Add new entry + Добавить новую запись + + + + Waiting on their encryption key. Will request it again soon. + + + + + Encryption key request queued. + + + + + Queued. + + + + + Message sent. Waiting on acknowledgement. Sent at %1 + Сообщение отправлено. Ожидаем подтверждения. Отправлено в %1 + + + + Need to do work to send message. Work is queued. + + + + + Acknowledgement of the message received %1 + Сообщение получено %1 + + + + Broadcast queued. + + + + + Broadcast on %1 + + + + + Problem: The work demanded by the recipient is more difficult than you are willing to do. %1 + + + + + Problem: The recipient's encryption key is no good. Could not encrypt message. %1 + + + + + Forced difficulty override. Send should start soon. + + + + + Unknown status: %1 %2 + Неизвестный статус: %1 %2 + + + + Since startup on %1 + + + + + Not Connected + Не соединено + + + + Show Bitmessage + + + + + Send + Отправка + + + + Subscribe + Подписки + + + + Address Book + Адресная книга + + + + Quit + Выйти + + + + You may manage your keys by editing the keys.dat file stored in the same directory as this program. It is important that you back up this file. + + + + + You may manage your keys by editing the keys.dat file stored in + %1 +It is important that you back up this file. + + + + + Open keys.dat? + + + + + You may manage your keys by editing the keys.dat file stored in the same directory as this program. It is important that you back up this file. Would you like to open the file now? (Be sure to close Bitmessage before making any changes.) + + + + + You may manage your keys by editing the keys.dat file stored in + %1 +It is important that you back up this file. Would you like to open the file now? (Be sure to close Bitmessage before making any changes.) + + + + + Delete trash? + + + + + Are you sure you want to delete all trashed messages? + + + + + bad passphrase + Неподходящая секретная фраза + + + + You must type your passphrase. If you don't have one then this is not the form for you. + Вы должны ввести секретную фразу. Если Вы не хотите это делать, то Вы выбрали неправильную опцию. + + + + Processed %1 person-to-person messages. + + + + + Processed %1 broadcast messages. + + + + + Processed %1 public keys. + + + + + Total Connections: %1 + Всего соединений: %1 + + + + Connection lost + Соединение потеряно + + + + Connected + Соединено + + + + Message trashed + + + + + Error: Bitmessage addresses start with BM- Please check %1 + + + + + Error: The address %1 is not typed or copied correctly. Please check it. + + + + + Error: The address %1 contains invalid characters. Please check it. + + + + + Error: The address version in %1 is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. + + + + + Error: Some data encoded in the address %1 is too short. There might be something wrong with the software of your acquaintance. + + + + + Error: Some data encoded in the address %1 is too long. There might be something wrong with the software of your acquaintance. + + + + + Error: Something is wrong with the address %1. + + + + + Error: You must specify a From address. If you don't have one, go to the 'Your Identities' tab. + + + + + Sending to your address + + + + + Error: One of the addresses to which you are sending a message, %1, is yours. Unfortunately the Bitmessage client cannot process its own messages. Please try running a second client on a different computer or within a VM. + + + + + Address version number + + + + + Concerning the address %1, Bitmessage cannot understand address version numbers of %2. Perhaps upgrade Bitmessage to the latest version. + + + + + Stream number + Номер потока + + + + Concerning the address %1, Bitmessage cannot handle stream numbers of %2. Perhaps upgrade Bitmessage to the latest version. + + + + + Warning: You are currently not connected. Bitmessage will do the work necessary to send the message but it won't send until you connect. + + + + + Your 'To' field is empty. + + + + + Work is queued. + + + + + Right click one or more entries in your address book and select 'Send message to this address'. + + + + + Work is queued. %1 + + + + + New Message + + + + + From + От + + + + Address is valid. + + + + + Error: You cannot add the same address to your address book twice. Try renaming the existing one if you want. + + + + + The address you entered was invalid. Ignoring it. + + + + + Error: You cannot add the same address to your subsciptions twice. Perhaps rename the existing one if you want. + + + + + Restart + + + + + You must restart Bitmessage for the port number change to take effect. + + + + + Bitmessage will use your proxy from now on but you may want to manually restart Bitmessage now to close existing connections. + + + + + Error: You cannot add the same address to your list twice. Perhaps rename the existing one if you want. + + + + + Passphrase mismatch + + + + + The passphrase you entered twice doesn't match. Try again. + + + + + Choose a passphrase + Придумайте секретную фразу + + + + You really do need a passphrase. + Вы действительно должны ввести секретную фразу. + + + + All done. Closing user interface... + + + + + Address is gone + + + + + Bitmessage cannot find your address %1. Perhaps you removed it? + + + + + Address disabled + + + + + Error: The address from which you are trying to send is disabled. You'll have to enable it on the 'Your Identities' tab before using it. + + + + + Entry added to the Address Book. Edit the label to your liking. + + + + + Moved items to trash. There is no user interface to view your trash, but it is still on disk if you are desperate to get it back. + Удалено в корзину. Чтобы попасть в корзину, Вам нужно будет найти файл корзины на диске. + + + + Save As... + + + + + Write error. + + + + + No addresses selected. + + + + + Options have been disabled because they either aren't applicable or because they haven't yet been implemented for your operating system. + + + + + The address should start with ''BM-'' + + + + + The address is not typed or copied correctly (the checksum failed). + + + + + The version number of this address is higher than this software can support. Please upgrade Bitmessage. + + + + + The address contains invalid characters. + + + + + Some data encoded in the address is too short. + + + + + Some data encoded in the address is too long. + + + + + You are using TCP port %1. (This can be changed in the settings). + Вы используете TCP порт %1 (Его можно поменять в настройках). + + + + Bitmessage + Bitmessage + + + + To + Кому + + + + From + От кого + + + + Subject + Тема + + + + Received + Получено + + + + Inbox + Входящие + + + + Load from Address book + Взять из адресной книги + + + + Message: + Сообщение: + + + + Subject: + Тема: + + + + Send to one or more specific people + Отправить одному или нескольким указанным получателям + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html> + + + + + To: + Кому: + + + + From: + От: + + + + Broadcast to everyone who is subscribed to your address + Рассылка всем, кто подписался на Ваш адрес + + + + Be aware that broadcasts are only encrypted with your address. Anyone who knows your address can read them. + Пожалуйста, учитывайте, что рассылки шифруются лишь Вашим адресом. Любой человек, который знает Ваш адрес, сможет прочитать Вашу рассылку. + + + + Status + Статус + + + + Sent + Отправленные + + + + Label (not shown to anyone) + Название (не показывается никому) + + + + Address + Адрес + + + + Stream + Поток + + + + Your Identities + Ваши Адреса + + + + Here you can subscribe to 'broadcast messages' that are sent by other users. Messages will appear in your Inbox. Addresses here override those on the Blacklist tab. + Здесь Вы можете подписаться на рассылки от других пользователей. Все рассылки будут появлять у Вас во Входящих. Вы будете следить за всеми адресами, указанными здесь, даже если они в черном списке. + + + + Add new Subscription + Добавить новую подписку + + + + Label + Название + + + + Subscriptions + Подписки + + + + The Address book is useful for adding names or labels to other people's Bitmessage addresses so that you can recognize them more easily in your inbox. You can add entries here using the 'Add' button, or from your inbox by right-clicking on a message. + + + + + Name or Label + Название + + + + Use a Blacklist (Allow all incoming messages except those on the Blacklist) + Использовать черный список (Разрешить все входящие сообщения, кроме указанных в черном списке) + + + + Use a Whitelist (Block all incoming messages except those on the Whitelist) + Использовать белый список (блокировать все входящие сообщения, кроме указанных в белом списке) + + + + Blacklist + Черный список + + + + Stream # + № потока + + + + Connections + Соединений + + + + Total connections: 0 + Всего соединений: 0 + + + + Since startup at asdf: + + + + + Processed 0 person-to-person message. + + + + + Processed 0 public key. + + + + + Processed 0 broadcast. + + + + + Network Status + Статус сети + + + + File + Файл + + + + Settings + Настройки + + + + Help + Помощь + + + + Import keys + + + + + Manage keys + Управлять ключами + + + + About + О программе + + + + Regenerate deterministic addresses + Сгенерировать заново все адреса + + + + Delete all trashed messages + Стереть все сообщения из корзины + + + + NewAddressDialog + + + Create new Address + + + + + Here you may generate as many addresses as you like. Indeed, creating and abandoning addresses is encouraged. You may generate addresses by using either random numbers or by using a passphrase. If you use a passphrase, the address is called a "deterministic" address. +The 'Random Number' option is selected by default but deterministic addresses have several pros and cons: + + + + + <html><head/><body><p><span style=" font-weight:600;">Pros:<br/></span>You can recreate your addresses on any computer from memory. <br/>You need-not worry about backing up your keys.dat file as long as you can remember your passphrase. <br/><span style=" font-weight:600;">Cons:<br/></span>You must remember (or write down) your passphrase if you expect to be able to recreate your keys if they are lost. <br/>You must remember the address version number and the stream number along with your passphrase. <br/>If you choose a weak passphrase and someone on the Internet can brute-force it, they can read your messages and send messages as you.</p></body></html> + + + + + Use a random number generator to make an address + Использовать генератор случайных чисел для создания адреса + + + + Use a passphrase to make addresses + Использовать секретную фразу для создания адресов + + + + Spend several minutes of extra computing time to make the address(es) 1 or 2 characters shorter + Потратить несколько лишних минут, чтобы сделать адрес(а) короче на 1 или 2 символа + + + + Make deterministic addresses + + + + + Address version number: 3 + Версия адреса: 3 + + + + In addition to your passphrase, you must remember these numbers: + В дополнение к секретной фразе, Вам необходимо запомнить эти числа: + + + + Passphrase + Секретная фраза + + + + Number of addresses to make based on your passphrase: + Кол-во адресов, которые Вы хотите получить из секретной фразы: + + + + Stream number: 1 + Номер потока: 1 + + + + Retype passphrase + Повторите секретную фразу + + + + Randomly generate address + Сгенерировать случайный адрес + + + + Label (not shown to anyone except you) + Название (не показывается никому кроме Вас) + + + + Use the most available stream + Использовать наиболее доступный поток + + + + (best if this is the first of many addresses you will create) + + + + + Use the same stream as an existing address + + + + + (saves you some bandwidth and processing power) + + + + + NewChanDialog + + + Dialog + + + + + Create a new chan + + + + + Join a chan + + + + + <html><head/><body><p>A chan is a set of encryption keys that is shared by a group of people. The keys and bitmessage address used by a chan is generated from a human-friendly word or phrase (the chan name).</p><p>Chans are experimental and are unmoderatable.</p></body></html> + + + + + Chan name: + + + + + Chan bitmessage address: + + + + + Create a chan + + + + + Enter a name for your chan. If you choose a sufficiently complex chan name (like a strong and unique passphrase) and none of your friends share it publicly then the chan will be secure and private. + + + + + NewSubscriptionDialog + + + Add new entry + Добавить новую запись + + + + Label + Название + + + + Address + Адрес + + + + SpecialAddressBehaviorDialog + + + Special Address Behavior + + + + + Behave as a normal address + + + + + Behave as a pseudo-mailing-list address + + + + + Mail received to a pseudo-mailing-list address will be automatically broadcast to subscribers (and thus will be public). + + + + + Name of the pseudo-mailing-list: + + + + + aboutDialog + + + About + О программе + + + + PyBitmessage + PyBitmessage + + + + version ? + версия ? + + + + Copyright © 2013 Jonathan Warren + Копирайт © 2013 Джонатан Уоррен + + + + <html><head/><body><p>Distributed under the MIT/X11 software license; see <a href="http://www.opensource.org/licenses/mit-license.php"><span style=" text-decoration: underline; color:#0000ff;">http://www.opensource.org/licenses/mit-license.php</span></a></p></body></html> + <html><head/><body><p>Программа распространяется в соответствии с лицензией MIT/X11; см. <a href="http://www.opensource.org/licenses/mit-license.php"><span style=" text-decoration: underline; color:#0000ff;">http://www.opensource.org/licenses/mit-license.php</span></a></p></body></html> + + + + This is Beta software. + Это бета версия программы. + + + + helpDialog + + + Help + Помощь + + + + <a href="http://Bitmessage.org/wiki/PyBitmessage_Help">http://Bitmessage.org/wiki/PyBitmessage_Help</a> + <a href="http://Bitmessage.org/wiki/PyBitmessage_Help">http://Bitmessage.org/wiki/PyBitmessage_Help</a> + + + + As Bitmessage is a collaborative project, help can be found online in the Bitmessage Wiki: + Битмесседж - это общественный проект. Вы можете найти подсказки и советы на Wiki-страничке Битмесседж: + + + + iconGlossaryDialog + + + Icon Glossary + Описание значков + + + + You have no connections with other peers. + Нет соединения с другими участниками сети. + + + + You have made at least one connection to a peer using an outgoing connection but you have not yet received any incoming connections. Your firewall or home router probably isn't configured to forward incoming TCP connections to your computer. Bitmessage will work just fine but it would help the Bitmessage network if you allowed for incoming connections and will help you be a better-connected node. + На текущий момент Вы установили по-крайней мере одно исходящее соединение, но пока ни одного входящего. Ваш файрвол или маршрутизатор скорее всего не настроен на переброс входящих TCP соединений к Вашему компьютеру. Битмесседж будет прекрасно работать и без этого, но Вы могли бы помочь сети если бы разрешили и входящие соединения тоже. Это помогло бы Вам стать более важным узлом сети. + + + + You are using TCP port ?. (This can be changed in the settings). + Вы используете TCP порт ?. (Его можно поменять в настройках). + + + + You do have connections with other peers and your firewall is correctly configured. + Вы установили соединение с другими участниками сети и ваш файрвол настроен правильно. + + + + regenerateAddressesDialog + + + Regenerate Existing Addresses + Сгенерировать заново существующие адреса + + + + Regenerate existing addresses + Сгенерировать заново существующие адреса + + + + Passphrase + Секретная фраза + + + + Number of addresses to make based on your passphrase: + + + + + Address version Number: + Версия адреса: + + + + 3 + 3 + + + + Stream number: + Номер потока: + + + + 1 + 1 + + + + Spend several minutes of extra computing time to make the address(es) 1 or 2 characters shorter + Потратить несколько лишних минут, чтобы сделать адрес(а) короче на 1 или 2 символа + + + + You must check (or not check) this box just like you did (or didn't) when you made your addresses the first time. + Вы должны кликнуть эту галочку (или не кликать) точно также как Вы сделали в самый первый раз, когда создавали Ваши адреса. + + + + If you have previously made deterministic addresses but lost them due to an accident (like hard drive failure), you can regenerate them here. If you used the random number generator to make your addresses then this form will be of no use to you. + + + + + settingsDialog + + + Settings + Настройки + + + + Start Bitmessage on user login + Запускать Битмесседж при входе в систему + + + + Start Bitmessage in the tray (don't show main window) + Запускать Битмесседж в свернутом виде (не показывать главное окно) + + + + Minimize to tray + Сворачивать в трей + + + + Show notification when message received + Показывать уведомления при получении новых сообщений + + + + Run in Portable Mode + Запустить в переносном режиме + + + + In Portable Mode, messages and config files are stored in the same directory as the program rather than the normal application-data folder. This makes it convenient to run Bitmessage from a USB thumb drive. + + + + + User Interface + Пользовательские + + + + Listening port + Порт прослушивания + + + + Listen for connections on port: + Прослушивать соединения на порту: + + + + Proxy server / Tor + Прокси сервер / Тор + + + + Type: + Тип: + + + + none + отсутствует + + + + SOCKS4a + SOCKS4a + + + + SOCKS5 + SOCKS5 + + + + Server hostname: + Адрес сервера: + + + + Port: + Порт: + + + + Authentication + Авторизация + + + + Username: + Имя пользователя: + + + + Pass: + Прль: + + + + Network Settings + Сетевые настройки + + + + When someone sends you a message, their computer must first complete some work. The difficulty of this work, by default, is 1. You may raise this default for new addresses you create by changing the values here. Any new addresses you create will require senders to meet the higher difficulty. There is one exception: if you add a friend or acquaintance to your address book, Bitmessage will automatically notify them when you next send a message that they need only complete the minimum amount of work: difficulty 1. + + + + + Total difficulty: + Общая сложность: + + + + Small message difficulty: + Сложность для маленьких сообщений: + + + + The 'Small message difficulty' mostly only affects the difficulty of sending small messages. Doubling this value makes it almost twice as difficult to send a small message but doesn't really affect large messages. + + + + + The 'Total difficulty' affects the absolute amount of work the sender must complete. Doubling this value doubles the amount of work. + + + + + Demanded difficulty + Требуемая сложность + + + + Here you may set the maximum amount of work you are willing to do to send a message to another person. Setting these values to 0 means that any value is acceptable. + + + + + Maximum acceptable total difficulty: + Макс допустимая общая сложность: + + + + Maximum acceptable small message difficulty: + Макс допустимая сложность для маленький сообщений: + + + + Max acceptable difficulty + Макс допустимая сложность + + + From 45cfead4d0cd06d69327c827b6196cf977f531cc Mon Sep 17 00:00:00 2001 From: Rainulf Pineda Date: Fri, 12 Jul 2013 04:24:24 -0400 Subject: [PATCH 14/39] Inbox search. --- src/bitmessageqt/__init__.py | 435 +++++++++++++++++-------------- src/bitmessageqt/bitmessageui.py | 34 +-- src/bitmessageqt/bitmessageui.ui | 6 +- 3 files changed, 258 insertions(+), 217 deletions(-) diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py index ae5ab8a7..8f3042a0 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -308,205 +308,10 @@ class MyForm(QtGui.QMainWindow): addressInKeysFile) # Load inbox from messages database file - font = QFont() - font.setBold(True) - shared.sqlLock.acquire() - shared.sqlSubmitQueue.put( - '''SELECT msgid, toaddress, fromaddress, subject, received, message, read FROM inbox where folder='inbox' ORDER BY received''') - shared.sqlSubmitQueue.put('') - queryreturn = shared.sqlReturnQueue.get() - shared.sqlLock.release() - for row in queryreturn: - msgid, toAddress, fromAddress, subject, received, message, read = row - subject = shared.fixPotentiallyInvalidUTF8Data(subject) - message = shared.fixPotentiallyInvalidUTF8Data(message) - try: - if toAddress == self.str_broadcast_subscribers: - toLabel = self.str_broadcast_subscribers - else: - toLabel = shared.config.get(toAddress, 'label') - except: - toLabel = '' - if toLabel == '': - toLabel = toAddress - - fromLabel = '' - t = (fromAddress,) - shared.sqlLock.acquire() - shared.sqlSubmitQueue.put( - '''select label from addressbook where address=?''') - shared.sqlSubmitQueue.put(t) - queryreturn = shared.sqlReturnQueue.get() - shared.sqlLock.release() - - if queryreturn != []: - for row in queryreturn: - fromLabel, = row - - if fromLabel == '': # If this address wasn't in our address book... - t = (fromAddress,) - shared.sqlLock.acquire() - shared.sqlSubmitQueue.put( - '''select label from subscriptions where address=?''') - shared.sqlSubmitQueue.put(t) - queryreturn = shared.sqlReturnQueue.get() - shared.sqlLock.release() - - if queryreturn != []: - for row in queryreturn: - fromLabel, = row - - self.ui.tableWidgetInbox.insertRow(0) - newItem = QtGui.QTableWidgetItem(unicode(toLabel, 'utf-8')) - newItem.setToolTip(unicode(toLabel, 'utf-8')) - newItem.setFlags( - QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) - if not read: - newItem.setFont(font) - newItem.setData(Qt.UserRole, str(toAddress)) - if shared.safeConfigGetBoolean(toAddress, 'mailinglist'): - newItem.setTextColor(QtGui.QColor(137, 04, 177)) - self.ui.tableWidgetInbox.setItem(0, 0, newItem) - if fromLabel == '': - newItem = QtGui.QTableWidgetItem( - unicode(fromAddress, 'utf-8')) - newItem.setToolTip(unicode(fromAddress, 'utf-8')) - else: - newItem = QtGui.QTableWidgetItem(unicode(fromLabel, 'utf-8')) - newItem.setToolTip(unicode(fromLabel, 'utf-8')) - newItem.setFlags( - QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) - if not read: - newItem.setFont(font) - newItem.setData(Qt.UserRole, str(fromAddress)) - - self.ui.tableWidgetInbox.setItem(0, 1, newItem) - newItem = QtGui.QTableWidgetItem(unicode(subject, 'utf-8')) - newItem.setToolTip(unicode(subject, 'utf-8')) - newItem.setData(Qt.UserRole, unicode(message, 'utf-8)')) - newItem.setFlags( - QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) - if not read: - newItem.setFont(font) - self.ui.tableWidgetInbox.setItem(0, 2, newItem) - newItem = myTableWidgetItem(unicode(strftime(shared.config.get( - 'bitmessagesettings', 'timeformat'), localtime(int(received))), 'utf-8')) - newItem.setToolTip(unicode(strftime(shared.config.get( - 'bitmessagesettings', 'timeformat'), localtime(int(received))), 'utf-8')) - newItem.setData(Qt.UserRole, QByteArray(msgid)) - newItem.setData(33, int(received)) - newItem.setFlags( - QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) - if not read: - newItem.setFont(font) - self.ui.tableWidgetInbox.setItem(0, 3, newItem) - self.ui.tableWidgetInbox.sortItems(3, Qt.DescendingOrder) - self.ui.tableWidgetInbox.keyPressEvent = self.tableWidgetInboxKeyPressEvent + self.loadInbox() # Load Sent items from database - shared.sqlLock.acquire() - shared.sqlSubmitQueue.put( - '''SELECT toaddress, fromaddress, subject, message, status, ackdata, lastactiontime FROM sent where folder = 'sent' ORDER BY lastactiontime''') - shared.sqlSubmitQueue.put('') - queryreturn = shared.sqlReturnQueue.get() - shared.sqlLock.release() - for row in queryreturn: - toAddress, fromAddress, subject, message, status, ackdata, lastactiontime = row - subject = shared.fixPotentiallyInvalidUTF8Data(subject) - message = shared.fixPotentiallyInvalidUTF8Data(message) - try: - fromLabel = shared.config.get(fromAddress, 'label') - except: - fromLabel = '' - if fromLabel == '': - fromLabel = fromAddress - - toLabel = '' - t = (toAddress,) - shared.sqlLock.acquire() - shared.sqlSubmitQueue.put( - '''select label from addressbook where address=?''') - shared.sqlSubmitQueue.put(t) - queryreturn = shared.sqlReturnQueue.get() - shared.sqlLock.release() - - if queryreturn != []: - for row in queryreturn: - toLabel, = row - - self.ui.tableWidgetSent.insertRow(0) - if toLabel == '': - newItem = QtGui.QTableWidgetItem(unicode(toAddress, 'utf-8')) - newItem.setToolTip(unicode(toAddress, 'utf-8')) - else: - newItem = QtGui.QTableWidgetItem(unicode(toLabel, 'utf-8')) - newItem.setToolTip(unicode(toLabel, 'utf-8')) - newItem.setData(Qt.UserRole, str(toAddress)) - newItem.setFlags( - QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) - self.ui.tableWidgetSent.setItem(0, 0, newItem) - if fromLabel == '': - newItem = QtGui.QTableWidgetItem( - unicode(fromAddress, 'utf-8')) - newItem.setToolTip(unicode(fromAddress, 'utf-8')) - else: - newItem = QtGui.QTableWidgetItem(unicode(fromLabel, 'utf-8')) - newItem.setToolTip(unicode(fromLabel, 'utf-8')) - newItem.setData(Qt.UserRole, str(fromAddress)) - newItem.setFlags( - QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) - self.ui.tableWidgetSent.setItem(0, 1, newItem) - newItem = QtGui.QTableWidgetItem(unicode(subject, 'utf-8')) - newItem.setToolTip(unicode(subject, 'utf-8')) - newItem.setData(Qt.UserRole, unicode(message, 'utf-8)')) - newItem.setFlags( - QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) - self.ui.tableWidgetSent.setItem(0, 2, newItem) - if status == 'awaitingpubkey': - statusText = _translate( - "MainWindow", "Waiting on their encryption key. Will request it again soon.") - elif status == 'doingpowforpubkey': - statusText = _translate( - "MainWindow", "Encryption key request queued.") - elif status == 'msgqueued': - statusText = _translate( - "MainWindow", "Queued.") - elif status == 'msgsent': - statusText = _translate("MainWindow", "Message sent. Waiting on acknowledgement. Sent at %1").arg( - unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'), localtime(lastactiontime)),'utf-8')) - elif status == 'doingmsgpow': - statusText = _translate( - "MainWindow", "Need to do work to send message. Work is queued.") - elif status == 'ackreceived': - statusText = _translate("MainWindow", "Acknowledgement of the message received %1").arg( - unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'), localtime(lastactiontime)),'utf-8')) - elif status == 'broadcastqueued': - statusText = _translate( - "MainWindow", "Broadcast queued.") - elif status == 'broadcastsent': - statusText = _translate("MainWindow", "Broadcast on %1").arg(unicode(strftime( - shared.config.get('bitmessagesettings', 'timeformat'), localtime(lastactiontime)),'utf-8')) - elif status == 'toodifficult': - statusText = _translate("MainWindow", "Problem: The work demanded by the recipient is more difficult than you are willing to do. %1").arg( - unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'), localtime(lastactiontime)),'utf-8')) - elif status == 'badkey': - statusText = _translate("MainWindow", "Problem: The recipient\'s encryption key is no good. Could not encrypt message. %1").arg( - unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'), localtime(lastactiontime)),'utf-8')) - elif status == 'forcepow': - statusText = _translate( - "MainWindow", "Forced difficulty override. Send should start soon.") - else: - statusText = _translate("MainWindow", "Unknown status: %1 %2").arg(status).arg(unicode( - strftime(shared.config.get('bitmessagesettings', 'timeformat'), localtime(lastactiontime)),'utf-8')) - newItem = myTableWidgetItem(statusText) - newItem.setToolTip(statusText) - newItem.setData(Qt.UserRole, QByteArray(ackdata)) - newItem.setData(33, int(lastactiontime)) - newItem.setFlags( - QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) - self.ui.tableWidgetSent.setItem(0, 3, newItem) - self.ui.tableWidgetSent.sortItems(3, Qt.DescendingOrder) - self.ui.tableWidgetSent.keyPressEvent = self.tableWidgetSentKeyPressEvent + self.loadSent() # Initialize the address book shared.sqlLock.acquire() @@ -527,6 +332,10 @@ class MyForm(QtGui.QMainWindow): # Initialize the Subscriptions self.rerenderSubscriptions() + # Initialize the inbox search + QtCore.QObject.connect(self.ui.inboxSearchLineEdit, QtCore.SIGNAL( + "returnPressed()"), self.inboxSearchLineEditPressed) + # Initialize the Blacklist or Whitelist if shared.config.get('bitmessagesettings', 'blackwhitelist') == 'black': self.loadBlackWhiteList() @@ -686,6 +495,231 @@ class MyForm(QtGui.QMainWindow): self.appIndicatorShow() self.ui.tabWidget.setCurrentIndex(5) + # Load Sent items from database + def loadSent(self, where="", what=""): + shared.sqlLock.acquire() + shared.sqlSubmitQueue.put( + '''SELECT toaddress, fromaddress, subject, message, status, ackdata, lastactiontime FROM sent where folder = 'sent' ORDER BY lastactiontime''') + shared.sqlSubmitQueue.put('') + queryreturn = shared.sqlReturnQueue.get() + shared.sqlLock.release() + for row in queryreturn: + toAddress, fromAddress, subject, message, status, ackdata, lastactiontime = row + subject = shared.fixPotentiallyInvalidUTF8Data(subject) + message = shared.fixPotentiallyInvalidUTF8Data(message) + try: + fromLabel = shared.config.get(fromAddress, 'label') + except: + fromLabel = '' + if fromLabel == '': + fromLabel = fromAddress + + toLabel = '' + t = (toAddress,) + shared.sqlLock.acquire() + shared.sqlSubmitQueue.put( + '''select label from addressbook where address=?''') + shared.sqlSubmitQueue.put(t) + queryreturn = shared.sqlReturnQueue.get() + shared.sqlLock.release() + + if queryreturn != []: + for row in queryreturn: + toLabel, = row + + self.ui.tableWidgetSent.insertRow(0) + if toLabel == '': + newItem = QtGui.QTableWidgetItem(unicode(toAddress, 'utf-8')) + newItem.setToolTip(unicode(toAddress, 'utf-8')) + else: + newItem = QtGui.QTableWidgetItem(unicode(toLabel, 'utf-8')) + newItem.setToolTip(unicode(toLabel, 'utf-8')) + newItem.setData(Qt.UserRole, str(toAddress)) + newItem.setFlags( + QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) + self.ui.tableWidgetSent.setItem(0, 0, newItem) + if fromLabel == '': + newItem = QtGui.QTableWidgetItem( + unicode(fromAddress, 'utf-8')) + newItem.setToolTip(unicode(fromAddress, 'utf-8')) + else: + newItem = QtGui.QTableWidgetItem(unicode(fromLabel, 'utf-8')) + newItem.setToolTip(unicode(fromLabel, 'utf-8')) + newItem.setData(Qt.UserRole, str(fromAddress)) + newItem.setFlags( + QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) + self.ui.tableWidgetSent.setItem(0, 1, newItem) + newItem = QtGui.QTableWidgetItem(unicode(subject, 'utf-8')) + newItem.setToolTip(unicode(subject, 'utf-8')) + newItem.setData(Qt.UserRole, unicode(message, 'utf-8)')) + newItem.setFlags( + QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) + self.ui.tableWidgetSent.setItem(0, 2, newItem) + if status == 'awaitingpubkey': + statusText = _translate( + "MainWindow", "Waiting on their encryption key. Will request it again soon.") + elif status == 'doingpowforpubkey': + statusText = _translate( + "MainWindow", "Encryption key request queued.") + elif status == 'msgqueued': + statusText = _translate( + "MainWindow", "Queued.") + elif status == 'msgsent': + statusText = _translate("MainWindow", "Message sent. Waiting on acknowledgement. Sent at %1").arg( + unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'), localtime(lastactiontime)),'utf-8')) + elif status == 'doingmsgpow': + statusText = _translate( + "MainWindow", "Need to do work to send message. Work is queued.") + elif status == 'ackreceived': + statusText = _translate("MainWindow", "Acknowledgement of the message received %1").arg( + unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'), localtime(lastactiontime)),'utf-8')) + elif status == 'broadcastqueued': + statusText = _translate( + "MainWindow", "Broadcast queued.") + elif status == 'broadcastsent': + statusText = _translate("MainWindow", "Broadcast on %1").arg(unicode(strftime( + shared.config.get('bitmessagesettings', 'timeformat'), localtime(lastactiontime)),'utf-8')) + elif status == 'toodifficult': + statusText = _translate("MainWindow", "Problem: The work demanded by the recipient is more difficult than you are willing to do. %1").arg( + unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'), localtime(lastactiontime)),'utf-8')) + elif status == 'badkey': + statusText = _translate("MainWindow", "Problem: The recipient\'s encryption key is no good. Could not encrypt message. %1").arg( + unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'), localtime(lastactiontime)),'utf-8')) + elif status == 'forcepow': + statusText = _translate( + "MainWindow", "Forced difficulty override. Send should start soon.") + else: + statusText = _translate("MainWindow", "Unknown status: %1 %2").arg(status).arg(unicode( + strftime(shared.config.get('bitmessagesettings', 'timeformat'), localtime(lastactiontime)),'utf-8')) + newItem = myTableWidgetItem(statusText) + newItem.setToolTip(statusText) + newItem.setData(Qt.UserRole, QByteArray(ackdata)) + newItem.setData(33, int(lastactiontime)) + newItem.setFlags( + QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) + self.ui.tableWidgetSent.setItem(0, 3, newItem) + self.ui.tableWidgetSent.sortItems(3, Qt.DescendingOrder) + self.ui.tableWidgetSent.keyPressEvent = self.tableWidgetSentKeyPressEvent + + # Load inbox from messages database file + def loadInbox(self, where="", what=""): + what = "%" + what + "%" + if where == "To": + where = "toaddress" + elif where == "From": + where = "fromaddress" + elif where == "Subject": + where = "subject" + elif where == "Received": + where = "received" + elif where == "Message": + where = "message" + else: + where = "toaddress || fromaddress || subject || received || message" + + sqlQuery = ''' + SELECT msgid, toaddress, fromaddress, subject, received, message, read + FROM inbox WHERE folder="inbox" AND %s LIKE "%s" + ORDER BY received + ''' % (where, what) + + while self.ui.tableWidgetInbox.rowCount() > 0: + self.ui.tableWidgetInbox.removeRow(0) + + font = QFont() + font.setBold(True) + shared.sqlLock.acquire() + shared.sqlSubmitQueue.put(sqlQuery) + shared.sqlSubmitQueue.put('') + queryreturn = shared.sqlReturnQueue.get() + shared.sqlLock.release() + for row in queryreturn: + msgid, toAddress, fromAddress, subject, received, message, read = row + subject = shared.fixPotentiallyInvalidUTF8Data(subject) + message = shared.fixPotentiallyInvalidUTF8Data(message) + try: + if toAddress == self.str_broadcast_subscribers: + toLabel = self.str_broadcast_subscribers + else: + toLabel = shared.config.get(toAddress, 'label') + except: + toLabel = '' + if toLabel == '': + toLabel = toAddress + + fromLabel = '' + t = (fromAddress,) + shared.sqlLock.acquire() + shared.sqlSubmitQueue.put( + '''select label from addressbook where address=?''') + shared.sqlSubmitQueue.put(t) + queryreturn = shared.sqlReturnQueue.get() + shared.sqlLock.release() + + if queryreturn != []: + for row in queryreturn: + fromLabel, = row + + if fromLabel == '': # If this address wasn't in our address book... + t = (fromAddress,) + shared.sqlLock.acquire() + shared.sqlSubmitQueue.put( + '''select label from subscriptions where address=?''') + shared.sqlSubmitQueue.put(t) + queryreturn = shared.sqlReturnQueue.get() + shared.sqlLock.release() + + if queryreturn != []: + for row in queryreturn: + fromLabel, = row + + self.ui.tableWidgetInbox.insertRow(0) + newItem = QtGui.QTableWidgetItem(unicode(toLabel, 'utf-8')) + newItem.setToolTip(unicode(toLabel, 'utf-8')) + newItem.setFlags( + QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) + if not read: + newItem.setFont(font) + newItem.setData(Qt.UserRole, str(toAddress)) + if shared.safeConfigGetBoolean(toAddress, 'mailinglist'): + newItem.setTextColor(QtGui.QColor(137, 04, 177)) + self.ui.tableWidgetInbox.setItem(0, 0, newItem) + if fromLabel == '': + newItem = QtGui.QTableWidgetItem( + unicode(fromAddress, 'utf-8')) + newItem.setToolTip(unicode(fromAddress, 'utf-8')) + else: + newItem = QtGui.QTableWidgetItem(unicode(fromLabel, 'utf-8')) + newItem.setToolTip(unicode(fromLabel, 'utf-8')) + newItem.setFlags( + QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) + if not read: + newItem.setFont(font) + newItem.setData(Qt.UserRole, str(fromAddress)) + + self.ui.tableWidgetInbox.setItem(0, 1, newItem) + newItem = QtGui.QTableWidgetItem(unicode(subject, 'utf-8')) + newItem.setToolTip(unicode(subject, 'utf-8')) + newItem.setData(Qt.UserRole, unicode(message, 'utf-8)')) + newItem.setFlags( + QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) + if not read: + newItem.setFont(font) + self.ui.tableWidgetInbox.setItem(0, 2, newItem) + newItem = myTableWidgetItem(unicode(strftime(shared.config.get( + 'bitmessagesettings', 'timeformat'), localtime(int(received))), 'utf-8')) + newItem.setToolTip(unicode(strftime(shared.config.get( + 'bitmessagesettings', 'timeformat'), localtime(int(received))), 'utf-8')) + newItem.setData(Qt.UserRole, QByteArray(msgid)) + newItem.setData(33, int(received)) + newItem.setFlags( + QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) + if not read: + newItem.setFont(font) + self.ui.tableWidgetInbox.setItem(0, 3, newItem) + self.ui.tableWidgetInbox.sortItems(3, Qt.DescendingOrder) + self.ui.tableWidgetInbox.keyPressEvent = self.tableWidgetInboxKeyPressEvent + # create application indicator def appIndicatorInit(self, app): self.tray = QSystemTrayIcon(QtGui.QIcon( @@ -2507,6 +2541,13 @@ class MyForm(QtGui.QMainWindow): self.popMenuSent.addAction(self.actionForceSend) self.popMenuSent.exec_(self.ui.tableWidgetSent.mapToGlobal(point)) + def inboxSearchLineEditPressed(self): + searchKeyword = self.ui.inboxSearchLineEdit.text().toUtf8().data() + searchOption = self.ui.inboxSearchOptionCB.currentText().toUtf8().data() + self.ui.inboxSearchLineEdit.setText(QString("")) + self.ui.textEditInboxMessage.setPlainText(QString("")) + self.loadInbox(searchOption, searchKeyword) + def tableWidgetInboxItemClicked(self): currentRow = self.ui.tableWidgetInbox.currentRow() if currentRow >= 0: diff --git a/src/bitmessageqt/bitmessageui.py b/src/bitmessageqt/bitmessageui.py index dbb33fb0..ff23fa82 100644 --- a/src/bitmessageqt/bitmessageui.py +++ b/src/bitmessageqt/bitmessageui.py @@ -2,7 +2,7 @@ # Form implementation generated from reading ui file 'bitmessageui.ui' # -# Created: Fri Jul 12 01:59:15 2013 +# Created: Fri Jul 12 04:16:52 2013 # by: PyQt4 UI code generator 4.10 # # WARNING! All changes made in this file will be lost! @@ -57,17 +57,17 @@ class Ui_MainWindow(object): self.horizontalLayoutSearch = QtGui.QHBoxLayout() self.horizontalLayoutSearch.setContentsMargins(-1, 0, -1, -1) self.horizontalLayoutSearch.setObjectName(_fromUtf8("horizontalLayoutSearch")) - self.searchLineEdit = QtGui.QLineEdit(self.inbox) - self.searchLineEdit.setObjectName(_fromUtf8("searchLineEdit")) - self.horizontalLayoutSearch.addWidget(self.searchLineEdit) - self.searchOptionCB = QtGui.QComboBox(self.inbox) - self.searchOptionCB.setObjectName(_fromUtf8("searchOptionCB")) - self.searchOptionCB.addItem(_fromUtf8("")) - self.searchOptionCB.addItem(_fromUtf8("")) - self.searchOptionCB.addItem(_fromUtf8("")) - self.searchOptionCB.addItem(_fromUtf8("")) - self.searchOptionCB.addItem(_fromUtf8("")) - self.horizontalLayoutSearch.addWidget(self.searchOptionCB) + self.inboxSearchLineEdit = QtGui.QLineEdit(self.inbox) + self.inboxSearchLineEdit.setObjectName(_fromUtf8("inboxSearchLineEdit")) + self.horizontalLayoutSearch.addWidget(self.inboxSearchLineEdit) + self.inboxSearchOptionCB = QtGui.QComboBox(self.inbox) + self.inboxSearchOptionCB.setObjectName(_fromUtf8("inboxSearchOptionCB")) + self.inboxSearchOptionCB.addItem(_fromUtf8("")) + self.inboxSearchOptionCB.addItem(_fromUtf8("")) + self.inboxSearchOptionCB.addItem(_fromUtf8("")) + self.inboxSearchOptionCB.addItem(_fromUtf8("")) + self.inboxSearchOptionCB.addItem(_fromUtf8("")) + self.horizontalLayoutSearch.addWidget(self.inboxSearchOptionCB) self.verticalLayout_2.addLayout(self.horizontalLayoutSearch) self.tableWidgetInbox = QtGui.QTableWidget(self.inbox) self.tableWidgetInbox.setAlternatingRowColors(True) @@ -482,11 +482,11 @@ class Ui_MainWindow(object): def retranslateUi(self, MainWindow): MainWindow.setWindowTitle(_translate("MainWindow", "Bitmessage", None)) - self.searchOptionCB.setItemText(0, _translate("MainWindow", "All", None)) - self.searchOptionCB.setItemText(1, _translate("MainWindow", "To", None)) - self.searchOptionCB.setItemText(2, _translate("MainWindow", "From", None)) - self.searchOptionCB.setItemText(3, _translate("MainWindow", "Subject", None)) - self.searchOptionCB.setItemText(4, _translate("MainWindow", "Received", None)) + self.inboxSearchOptionCB.setItemText(0, _translate("MainWindow", "All", None)) + self.inboxSearchOptionCB.setItemText(1, _translate("MainWindow", "To", None)) + self.inboxSearchOptionCB.setItemText(2, _translate("MainWindow", "From", None)) + self.inboxSearchOptionCB.setItemText(3, _translate("MainWindow", "Subject", None)) + self.inboxSearchOptionCB.setItemText(4, _translate("MainWindow", "Message", None)) self.tableWidgetInbox.setSortingEnabled(True) item = self.tableWidgetInbox.horizontalHeaderItem(0) item.setText(_translate("MainWindow", "To", None)) diff --git a/src/bitmessageqt/bitmessageui.ui b/src/bitmessageqt/bitmessageui.ui index 65ad632d..2be3385d 100644 --- a/src/bitmessageqt/bitmessageui.ui +++ b/src/bitmessageqt/bitmessageui.ui @@ -83,10 +83,10 @@ 0 - + - + All @@ -109,7 +109,7 @@ - Received + Message From 997a8ff13ac5a311cece8f609de00b7c86447270 Mon Sep 17 00:00:00 2001 From: Rainulf Pineda Date: Fri, 12 Jul 2013 04:42:52 -0400 Subject: [PATCH 15/39] Sent search. --- src/bitmessageqt/__init__.py | 39 +++++++++++++++++--- src/bitmessageqt/bitmessageui.py | 26 +++++++++++-- src/bitmessageqt/bitmessageui.ui | 63 ++++++++++++++++++++++++++------ 3 files changed, 108 insertions(+), 20 deletions(-) diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py index 8f3042a0..92209bbe 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -336,6 +336,10 @@ class MyForm(QtGui.QMainWindow): QtCore.QObject.connect(self.ui.inboxSearchLineEdit, QtCore.SIGNAL( "returnPressed()"), self.inboxSearchLineEditPressed) + # Initialize the sent search + QtCore.QObject.connect(self.ui.sentSearchLineEdit, QtCore.SIGNAL( + "returnPressed()"), self.sentSearchLineEditPressed) + # Initialize the Blacklist or Whitelist if shared.config.get('bitmessagesettings', 'blackwhitelist') == 'black': self.loadBlackWhiteList() @@ -497,9 +501,29 @@ class MyForm(QtGui.QMainWindow): # Load Sent items from database def loadSent(self, where="", what=""): + what = "%" + what + "%" + if where == "To": + where = "toaddress" + elif where == "From": + where = "fromaddress" + elif where == "Subject": + where = "subject" + elif where == "Message": + where = "message" + else: + where = "toaddress || fromaddress || subject || message" + + sqlQuery = ''' + SELECT toaddress, fromaddress, subject, message, status, ackdata, lastactiontime + FROM sent WHERE folder="sent" AND %s LIKE "%s" + ORDER BY lastactiontime + ''' % (where, what) + + while self.ui.tableWidgetSent.rowCount() > 0: + self.ui.tableWidgetSent.removeRow(0) + shared.sqlLock.acquire() - shared.sqlSubmitQueue.put( - '''SELECT toaddress, fromaddress, subject, message, status, ackdata, lastactiontime FROM sent where folder = 'sent' ORDER BY lastactiontime''') + shared.sqlSubmitQueue.put(sqlQuery) shared.sqlSubmitQueue.put('') queryreturn = shared.sqlReturnQueue.get() shared.sqlLock.release() @@ -610,12 +634,10 @@ class MyForm(QtGui.QMainWindow): where = "fromaddress" elif where == "Subject": where = "subject" - elif where == "Received": - where = "received" elif where == "Message": where = "message" else: - where = "toaddress || fromaddress || subject || received || message" + where = "toaddress || fromaddress || subject || message" sqlQuery = ''' SELECT msgid, toaddress, fromaddress, subject, received, message, read @@ -2548,6 +2570,13 @@ class MyForm(QtGui.QMainWindow): self.ui.textEditInboxMessage.setPlainText(QString("")) self.loadInbox(searchOption, searchKeyword) + def sentSearchLineEditPressed(self): + searchKeyword = self.ui.sentSearchLineEdit.text().toUtf8().data() + searchOption = self.ui.sentSearchOptionCB.currentText().toUtf8().data() + self.ui.sentSearchLineEdit.setText(QString("")) + self.ui.textEditInboxMessage.setPlainText(QString("")) + self.loadSent(searchOption, searchKeyword) + def tableWidgetInboxItemClicked(self): currentRow = self.ui.tableWidgetInbox.currentRow() if currentRow >= 0: diff --git a/src/bitmessageqt/bitmessageui.py b/src/bitmessageqt/bitmessageui.py index ff23fa82..62466503 100644 --- a/src/bitmessageqt/bitmessageui.py +++ b/src/bitmessageqt/bitmessageui.py @@ -2,7 +2,7 @@ # Form implementation generated from reading ui file 'bitmessageui.ui' # -# Created: Fri Jul 12 04:16:52 2013 +# Created: Fri Jul 12 04:40:47 2013 # by: PyQt4 UI code generator 4.10 # # WARNING! All changes made in this file will be lost! @@ -172,6 +172,21 @@ class Ui_MainWindow(object): self.sent.setObjectName(_fromUtf8("sent")) self.verticalLayout = QtGui.QVBoxLayout(self.sent) self.verticalLayout.setObjectName(_fromUtf8("verticalLayout")) + self.horizontalLayout = QtGui.QHBoxLayout() + self.horizontalLayout.setContentsMargins(-1, 0, -1, -1) + self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout")) + self.sentSearchLineEdit = QtGui.QLineEdit(self.sent) + self.sentSearchLineEdit.setObjectName(_fromUtf8("sentSearchLineEdit")) + self.horizontalLayout.addWidget(self.sentSearchLineEdit) + self.sentSearchOptionCB = QtGui.QComboBox(self.sent) + self.sentSearchOptionCB.setObjectName(_fromUtf8("sentSearchOptionCB")) + self.sentSearchOptionCB.addItem(_fromUtf8("")) + self.sentSearchOptionCB.addItem(_fromUtf8("")) + self.sentSearchOptionCB.addItem(_fromUtf8("")) + self.sentSearchOptionCB.addItem(_fromUtf8("")) + self.sentSearchOptionCB.addItem(_fromUtf8("")) + self.horizontalLayout.addWidget(self.sentSearchOptionCB) + self.verticalLayout.addLayout(self.horizontalLayout) self.tableWidgetSent = QtGui.QTableWidget(self.sent) self.tableWidgetSent.setDragDropMode(QtGui.QAbstractItemView.DragDrop) self.tableWidgetSent.setAlternatingRowColors(True) @@ -407,7 +422,7 @@ class Ui_MainWindow(object): self.gridLayout.addWidget(self.tabWidget, 0, 0, 1, 1) MainWindow.setCentralWidget(self.centralwidget) self.menubar = QtGui.QMenuBar(MainWindow) - self.menubar.setGeometry(QtCore.QRect(0, 0, 795, 20)) + self.menubar.setGeometry(QtCore.QRect(0, 0, 795, 25)) self.menubar.setObjectName(_fromUtf8("menubar")) self.menuFile = QtGui.QMenu(self.menubar) self.menuFile.setObjectName(_fromUtf8("menuFile")) @@ -504,7 +519,7 @@ class Ui_MainWindow(object): self.textEditMessage.setHtml(_translate("MainWindow", "\n" "\n" +"\n" "


", None)) self.label.setText(_translate("MainWindow", "To:", None)) self.label_2.setText(_translate("MainWindow", "From:", None)) @@ -512,6 +527,11 @@ class Ui_MainWindow(object): self.pushButtonSend.setText(_translate("MainWindow", "Send", None)) self.labelSendBroadcastWarning.setText(_translate("MainWindow", "Be aware that broadcasts are only encrypted with your address. Anyone who knows your address can read them.", None)) self.tabWidget.setTabText(self.tabWidget.indexOf(self.send), _translate("MainWindow", "Send", None)) + self.sentSearchOptionCB.setItemText(0, _translate("MainWindow", "All", None)) + self.sentSearchOptionCB.setItemText(1, _translate("MainWindow", "To", None)) + self.sentSearchOptionCB.setItemText(2, _translate("MainWindow", "From", None)) + self.sentSearchOptionCB.setItemText(3, _translate("MainWindow", "Subject", None)) + self.sentSearchOptionCB.setItemText(4, _translate("MainWindow", "Message", None)) self.tableWidgetSent.setSortingEnabled(True) item = self.tableWidgetSent.horizontalHeaderItem(0) item.setText(_translate("MainWindow", "To", None)) diff --git a/src/bitmessageqt/bitmessageui.ui b/src/bitmessageqt/bitmessageui.ui index 2be3385d..46ebd06a 100644 --- a/src/bitmessageqt/bitmessageui.ui +++ b/src/bitmessageqt/bitmessageui.ui @@ -14,7 +14,7 @@ Bitmessage - + :/newPrefix/images/can-icon-24px.png:/newPrefix/images/can-icon-24px.png @@ -70,7 +70,7 @@ - + :/newPrefix/images/inbox.png:/newPrefix/images/inbox.png @@ -193,7 +193,7 @@ - + :/newPrefix/images/send.png:/newPrefix/images/send.png @@ -262,7 +262,7 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'Sans'; font-size:9pt; font-weight:400; font-style:normal;"> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2';"><br /></p></body></html> @@ -351,13 +351,52 @@ p, li { white-space: pre-wrap; }
- + :/newPrefix/images/sent.png:/newPrefix/images/sent.png Sent + + + + 0 + + + + + + + + + All + + + + + To + + + + + From + + + + + Subject + + + + + Message + + + + + + @@ -428,7 +467,7 @@ p, li { white-space: pre-wrap; } - + :/newPrefix/images/identities.png:/newPrefix/images/identities.png @@ -528,7 +567,7 @@ p, li { white-space: pre-wrap; } - + :/newPrefix/images/subscriptions.png:/newPrefix/images/subscriptions.png @@ -613,7 +652,7 @@ p, li { white-space: pre-wrap; } - + :/newPrefix/images/addressbook.png:/newPrefix/images/addressbook.png @@ -695,7 +734,7 @@ p, li { white-space: pre-wrap; } - + :/newPrefix/images/blacklist.png:/newPrefix/images/blacklist.png @@ -787,7 +826,7 @@ p, li { white-space: pre-wrap; } - + :/newPrefix/images/networkstatus.png:/newPrefix/images/networkstatus.png @@ -806,7 +845,7 @@ p, li { white-space: pre-wrap; } - + :/newPrefix/images/redicon.png:/newPrefix/images/redicon.png @@ -973,7 +1012,7 @@ p, li { white-space: pre-wrap; } 0 0 795 - 20 + 25 From a3cdc28bbf156795f7ebbf04d2ee0e04a78440f7 Mon Sep 17 00:00:00 2001 From: Rainulf Pineda Date: Fri, 12 Jul 2013 05:02:21 -0400 Subject: [PATCH 16/39] Fixed crash on sql query. --- src/bitmessageqt/__init__.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py index 92209bbe..316f4205 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -515,16 +515,17 @@ class MyForm(QtGui.QMainWindow): sqlQuery = ''' SELECT toaddress, fromaddress, subject, message, status, ackdata, lastactiontime - FROM sent WHERE folder="sent" AND %s LIKE "%s" + FROM sent WHERE folder="sent" AND %s LIKE ? ORDER BY lastactiontime - ''' % (where, what) + ''' % (where,) while self.ui.tableWidgetSent.rowCount() > 0: self.ui.tableWidgetSent.removeRow(0) + t = (what,) shared.sqlLock.acquire() shared.sqlSubmitQueue.put(sqlQuery) - shared.sqlSubmitQueue.put('') + shared.sqlSubmitQueue.put(t) queryreturn = shared.sqlReturnQueue.get() shared.sqlLock.release() for row in queryreturn: @@ -641,18 +642,19 @@ class MyForm(QtGui.QMainWindow): sqlQuery = ''' SELECT msgid, toaddress, fromaddress, subject, received, message, read - FROM inbox WHERE folder="inbox" AND %s LIKE "%s" + FROM inbox WHERE folder="inbox" AND %s LIKE ? ORDER BY received - ''' % (where, what) + ''' % (where,) while self.ui.tableWidgetInbox.rowCount() > 0: self.ui.tableWidgetInbox.removeRow(0) font = QFont() font.setBold(True) + t = (what,) shared.sqlLock.acquire() shared.sqlSubmitQueue.put(sqlQuery) - shared.sqlSubmitQueue.put('') + shared.sqlSubmitQueue.put(t) queryreturn = shared.sqlReturnQueue.get() shared.sqlLock.release() for row in queryreturn: From 10b23d0946c0b3b3ee4f9cd8a9d0b4e27d3c1e06 Mon Sep 17 00:00:00 2001 From: fuzzgun Date: Fri, 12 Jul 2013 10:36:28 +0100 Subject: [PATCH 17/39] Packaging for multiple distros --- Makefile | 70 ++++---- arch.sh | 45 +++++ archpackage/PKGBUILD | 31 ++++ configure | 1 + debian.sh | 52 ++++-- debian/changelog | 4 +- debian/compat | 2 +- debian/control | 34 ++-- debian/copyright | 40 ++--- debian/manpages | 1 + debian/rules | 86 ++++----- desktop/icon14.xpm | 111 ++++++++++++ desktop/icon24.png | Bin 0 -> 1852 bytes desktop/pybitmessage.desktop | 27 +-- ebuild.sh | 33 ++++ ebuildpackage/pybitmessage-0.3.4-1.ebuild | 22 +++ generate.sh | 7 + man/pybitmessage.1.gz | Bin 0 -> 546 bytes puppy.sh | 66 +++++++ puppypackage/icon14.xpm | 111 ++++++++++++ puppypackage/pybitmessage-0.3.4.pet.specs | 1 + rpm.sh | 53 ++++++ rpmpackage/pybitmessage.spec | 207 ++++++++++++++++++++++ slack.sh | 48 +++++ slackpackage/doinst.sh | 4 + slackpackage/slack-desc | 19 ++ 26 files changed, 903 insertions(+), 172 deletions(-) mode change 100755 => 100644 Makefile create mode 100755 arch.sh create mode 100644 archpackage/PKGBUILD create mode 100755 configure create mode 100644 debian/manpages create mode 100644 desktop/icon14.xpm create mode 100644 desktop/icon24.png create mode 100755 ebuild.sh create mode 100755 ebuildpackage/pybitmessage-0.3.4-1.ebuild create mode 100755 generate.sh create mode 100644 man/pybitmessage.1.gz create mode 100755 puppy.sh create mode 100644 puppypackage/icon14.xpm create mode 100644 puppypackage/pybitmessage-0.3.4.pet.specs create mode 100755 rpm.sh create mode 100644 rpmpackage/pybitmessage.spec create mode 100755 slack.sh create mode 100755 slackpackage/doinst.sh create mode 100644 slackpackage/slack-desc diff --git a/Makefile b/Makefile old mode 100755 new mode 100644 index afb6744e..92b4e633 --- a/Makefile +++ b/Makefile @@ -1,43 +1,45 @@ APP=pybitmessage VERSION=0.3.4 -DEST_SHARE=${DESTDIR}/usr/share -DEST_APP=${DEST_SHARE}/${APP} +RELEASE=1 +ARCH_TYPE=`uname -m` all: - debug: - source: tar -cvzf ../${APP}_${VERSION}.orig.tar.gz ../${APP}-${VERSION} --exclude-vcs - install: - mkdir -m 755 -p ${DESTDIR}/usr/bin - mkdir -m 755 -p ${DEST_APP} - mkdir -m 755 -p ${DEST_SHARE}/applications - mkdir -m 755 -p ${DEST_APP}/images - mkdir -m 755 -p ${DEST_APP}/pyelliptic - mkdir -m 755 -p ${DEST_APP}/socks - mkdir -m 755 -p ${DEST_APP}/bitmessageqt - mkdir -m 755 -p ${DEST_APP}/translations - mkdir -m 755 -p ${DEST_SHARE}/pixmaps - mkdir -m 755 -p ${DEST_SHARE}/icons - mkdir -m 755 -p ${DEST_SHARE}/icons/hicolor - mkdir -m 755 -p ${DEST_SHARE}/icons/hicolor/scalable - mkdir -m 755 -p ${DEST_SHARE}/icons/hicolor/scalable/apps - mkdir -m 755 -p ${DEST_SHARE}/icons/hicolor/24x24 - mkdir -m 755 -p ${DEST_SHARE}/icons/hicolor/24x24/apps - - cp -r src/* ${DEST_APP} - install -m 755 debian/pybm ${DESTDIR}/usr/bin/${APP} - - install -m 644 desktop/${APP}.desktop ${DEST_SHARE}/applications/${APP}.desktop - install -m 644 src/images/can-icon-24px.png ${DEST_SHARE}/icons/hicolor/24x24/apps/${APP}.png - install -m 644 desktop/can-icon.svg ${DEST_SHARE}/icons/hicolor/scalable/apps/${APP}.svg - install -m 644 desktop/can-icon.svg ${DEST_SHARE}/pixmaps/${APP}.svg - + mkdir -p ${DESTDIR}/usr + mkdir -p ${DESTDIR}/usr/bin + mkdir -m 755 -p ${DESTDIR}/usr/share + mkdir -m 755 -p ${DESTDIR}/usr/share/man + mkdir -m 755 -p ${DESTDIR}/usr/share/man/man1 + install -m 644 man/${APP}.1.gz ${DESTDIR}/usr/share/man/man1 + mkdir -m 755 -p ${DESTDIR}/usr/share/${APP} + mkdir -m 755 -p ${DESTDIR}/usr/share/applications + mkdir -m 755 -p ${DESTDIR}/usr/share/pixmaps + mkdir -m 755 -p ${DESTDIR}/usr/share/icons + mkdir -m 755 -p ${DESTDIR}/usr/share/icons/hicolor + mkdir -m 755 -p ${DESTDIR}/usr/share/icons/hicolor/scalable + mkdir -m 755 -p ${DESTDIR}/usr/share/icons/hicolor/scalable/apps + mkdir -m 755 -p ${DESTDIR}/usr/share/icons/hicolor/24x24 + mkdir -m 755 -p ${DESTDIR}/usr/share/icons/hicolor/24x24/apps + install -m 644 desktop/${APP}.desktop ${DESTDIR}/usr/share/applications/${APP}.desktop + install -m 644 desktop/icon24.png ${DESTDIR}/usr/share/icons/hicolor/24x24/apps/${APP}.png + cp -rf src/* ${DESTDIR}/usr/share/${APP} + echo '#!/bin/sh' > ${DESTDIR}/usr/bin/${APP} + echo 'cd /usr/share/pybitmessage' >> ${DESTDIR}/usr/bin/${APP} + echo 'LD_LIBRARY_PATH="/opt/openssl-compat-bitcoin/lib/" exec python bitmessagemain.py' >> ${DESTDIR}/usr/bin/${APP} + chmod +x ${DESTDIR}/usr/bin/${APP} +uninstall: + rm -f /usr/share/man/man1/${APP}.1.gz + rm -rf /usr/share/${APP} + rm -f /usr/bin/${APP} + rm -f /usr/share/applications/${APP}.desktop + rm -f /usr/share/icons/hicolor/scalable/apps/${APP}.svg + /usr/share/pixmaps/${APP}.svg clean: - rm -rf debian/${APP} - rm -f ../${APP}_*.deb ../${APP}_*.asc ../${APP}_*.dsc ../${APP}*.changes - rm -f *.sh~ src/*.pyc src/socks/*.pyc src/pyelliptic/*.pyc - rm -f *.deb \#* \.#* debian/*.log debian/*.substvars - rm -f Makefile~ + rm -f ${APP} \#* \.#* gnuplot* *.png debian/*.substvars debian/*.log + rm -fr deb.* debian/${APP} rpmpackage/${ARCH_TYPE} + rm -f ../${APP}*.deb ../${APP}*.changes ../${APP}*.asc ../${APP}*.dsc + rm -f rpmpackage/*.src.rpm archpackage/*.gz + rm -f puppypackage/*.gz puppypackage/*.pet slackpackage/*.txz diff --git a/arch.sh b/arch.sh new file mode 100755 index 00000000..8917cef4 --- /dev/null +++ b/arch.sh @@ -0,0 +1,45 @@ +#!/bin/bash + +APP=pybitmessage +PREV_VERSION=0.3.4 +VERSION=0.3.4 +RELEASE=1 +ARCH_TYPE=`uname -m` +CURRDIR=`pwd` +SOURCE=archpackage/${APP}-${VERSION}.tar.gz + +# Update version numbers automatically - so you don't have to +sed -i 's/VERSION='${PREV_VERSION}'/VERSION='${VERSION}'/g' Makefile debian.sh rpm.sh puppy.sh ebuild.sh slack.sh +sed -i 's/Version: '${PREV_VERSION}'/Version: '${VERSION}'/g' rpmpackage/${APP}.spec +sed -i 's/Release: '${RELEASE}'/Release: '${RELEASE}'/g' rpmpackage/${APP}.spec +sed -i 's/pkgrel='${RELEASE}'/pkgrel='${RELEASE}'/g' archpackage/PKGBUILD +sed -i 's/pkgver='${PREV_VERSION}'/pkgver='${VERSION}'/g' archpackage/PKGBUILD +sed -i "s/-${PREV_VERSION}-/-${VERSION}-/g" puppypackage/*.specs +sed -i "s/|${PREV_VERSION}|/|${VERSION}|/g" puppypackage/*.specs +sed -i 's/VERSION='${PREV_VERSION}'/VERSION='${VERSION}'/g' puppypackage/pinstall.sh puppypackage/puninstall.sh +sed -i 's/-'${PREV_VERSION}'.so/-'${VERSION}'.so/g' debian/*.links + + +# Create the source code +make clean +rm -f archpackage/*.gz + +# having the root directory called name-version seems essential +mv ../${APP} ../${APP}-${VERSION} +tar -cvzf ${SOURCE} ../${APP}-${VERSION} --exclude-vcs + +# rename the root directory without the version number +mv ../${APP}-${VERSION} ../${APP} + +# calculate the MD5 checksum +CHECKSM=$(md5sum ${SOURCE}) +sed -i "s/md5sums[^)]*)/md5sums=(${CHECKSM%% *})/g" archpackage/PKGBUILD + +cd archpackage + +# Create the package +makepkg + +# Move back to the original directory +cd ${CURRDIR} + diff --git a/archpackage/PKGBUILD b/archpackage/PKGBUILD new file mode 100644 index 00000000..a75d262a --- /dev/null +++ b/archpackage/PKGBUILD @@ -0,0 +1,31 @@ +# Maintainer: Bob Mottram (4096 bits) +pkgname=pybitmessage +pkgver=0.3.4 +pkgrel=1 +pkgdesc="Bitmessage is a P2P communications protocol used to send encrypted messages to another person or to many subscribers. It is decentralized and trustless, meaning that you need-not inherently trust any entities like root certificate authorities. It uses strong authentication which means that the sender of a message cannot be spoofed, and it aims to hide "non-content" data, like the sender and receiver of messages, from passive eavesdroppers like those running warrantless wiretapping programs." +arch=('i686' 'x86_64') +url="https://github.com/Bitmessage/PyBitmessage" +license=('MIT') +groups=() +depends=() +makedepends=() +optdepends=() +provides=() +conflicts=() +replaces=() +backup=() +options=() +install= +changelog= +source=($pkgname-$pkgver.tar.gz) +noextract=() +md5sums=(56a8a225463e96b435b2a5b438006983) +build() { + cd "$srcdir/$pkgname-$pkgver" + ./configure --prefix=/usr + make +} +package() { + cd "$srcdir/$pkgname-$pkgver" + make DESTDIR="$pkgdir/" install +} diff --git a/configure b/configure new file mode 100755 index 00000000..0519ecba --- /dev/null +++ b/configure @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/debian.sh b/debian.sh index ac26380e..2d924251 100755 --- a/debian.sh +++ b/debian.sh @@ -1,32 +1,46 @@ -# To build a debian package first ensure that the code exists -# within a directory called pybitmessage-x.x.x (where the x's -# are the version number), make sure that the VERSION parameter -# within debian/rules and this script are correct, then run -# this script. - #!/bin/bash APP=pybitmessage -PREV_VERSION=0.3.3 +PREV_VERSION=0.3.4 VERSION=0.3.4 RELEASE=1 -ARCH_TYPE=all +ARCH_TYPE=`uname -m` +DIR=${APP}-${VERSION} -#update version numbers automatically - so you don't have to -sed -i 's/VERSION='${PREV_VERSION}'/VERSION='${VERSION}'/g' Makefile -sed -i 's/'''${PREV_VERSION}'''/'''${VERSION}'''/g' src/shared.py +if [ $ARCH_TYPE == "x86_64" ]; then + ARCH_TYPE="amd64" +fi +if [ $ARCH_TYPE == "i686" ]; then + ARCH_TYPE="i386" +fi + + +# Update version numbers automatically - so you don't have to +sed -i 's/VERSION='${PREV_VERSION}'/VERSION='${VERSION}'/g' Makefile rpm.sh arch.sh puppy.sh ebuild.sh slack.sh +sed -i 's/Version: '${PREV_VERSION}'/Version: '${VERSION}'/g' rpmpackage/${APP}.spec +sed -i 's/Release: '${RELEASE}'/Release: '${RELEASE}'/g' rpmpackage/${APP}.spec +sed -i 's/pkgrel='${RELEASE}'/pkgrel='${RELEASE}'/g' archpackage/PKGBUILD +sed -i 's/pkgver='${PREV_VERSION}'/pkgver='${VERSION}'/g' archpackage/PKGBUILD +sed -i "s/-${PREV_VERSION}-/-${VERSION}-/g" puppypackage/*.specs +sed -i "s/|${PREV_VERSION}|/|${VERSION}|/g" puppypackage/*.specs +sed -i 's/VERSION='${PREV_VERSION}'/VERSION='${VERSION}'/g' puppypackage/pinstall.sh puppypackage/puninstall.sh +sed -i 's/-'${PREV_VERSION}'.so/-'${VERSION}'.so/g' debian/*.links + +make clean +make + +# change the parent directory name to debian format +mv ../${APP} ../${DIR} # Create a source archive -make clean -# change the directory name to pybitmessage-version -mv ../PyBitmessage ../${APP}-${VERSION} make source # Build the package -dpkg-buildpackage -A +dpkg-buildpackage -F -# change the directory name back -mv ../${APP}-${VERSION} ../PyBitmessage - -gpg -ba ../${APP}_${VERSION}-${RELEASE}_${ARCH_TYPE}.deb +# sign files +gpg -ba ../${APP}_${VERSION}-1_${ARCH_TYPE}.deb gpg -ba ../${APP}_${VERSION}.orig.tar.gz + +# restore the parent directory name +mv ../${DIR} ../${APP} diff --git a/debian/changelog b/debian/changelog index 1d822cd1..b6e8adbf 100644 --- a/debian/changelog +++ b/debian/changelog @@ -18,7 +18,7 @@ pybitmessage (0.3.3-1) raring; urgency=low via Portage (Gentoo) * Fix message authentication bug - -- Bob Mottram (4096 bits) Sun, 30 June 2013 11:23:00 +0100 + -- Bob Mottram (4096 bits) Sat, 29 June 2013 11:23:00 +0100 pybitmessage (0.3.211-1) raring; urgency=low @@ -26,7 +26,7 @@ pybitmessage (0.3.211-1) raring; urgency=low as the multiprocessing module does not work well with pyinstaller's --onefile option. - -- Bob Mottram (4096 bits) Sun, 30 June 2013 11:23:00 +0100 + -- Bob Mottram (4096 bits) Fri, 28 June 2013 11:23:00 +0100 pybitmessage (0.3.2-1) raring; urgency=low diff --git a/debian/compat b/debian/compat index 45a4fb75..ec635144 100644 --- a/debian/compat +++ b/debian/compat @@ -1 +1 @@ -8 +9 diff --git a/debian/control b/debian/control index 2dd19194..de8f3a59 100644 --- a/debian/control +++ b/debian/control @@ -1,21 +1,21 @@ Source: pybitmessage -Section: contrib/comm Priority: extra -Maintainer: Jonathan Warren -Build-Depends: debhelper (>= 8.0.0), python (>= 2.7.0), openssl, python-qt4, libqt4-dev (>= 4.8.0), python-qt4-dev, sqlite3, libsqlite3-dev, libmessaging-menu-dev -Standards-Version: 3.9.2 -Homepage: https://bitmessage.org/ -Vcs-Browser: https://github.com/Bitmessage/PyBitmessage -Vcs-Git: https://github.com/Bitmessage/PyBitmessage.git +Maintainer: Bob Mottram (4096 bits) +Build-Depends: debhelper (>= 9.0.0) +Standards-Version: 3.9.4 +Homepage: https://github.com/Bitmessage/PyBitmessage +Vcs-Git: https://github.com/fuzzgun/autocv.git Package: pybitmessage -Architecture: all -Depends: ${misc:Depends}, python (>= 2.7.0), openssl, python-qt4, libqt4-dev (>= 4.8.0), python-qt4-dev, sqlite3, libsqlite3-dev, libmessaging-menu-dev -Description: Send encrypted messages to another person or to many subscribers - Bitmessage is a P2P communications protocol used to send encrypted messages - to another person or to many subscribers. It is decentralized and trustless, - meaning that you need-not inherently trust any entities like root certificate - authorities. It uses strong authentication which means that the sender of a - message cannot be spoofed, and it aims to hide "non-content" data, like the - sender and receiver of messages, from passive eavesdroppers like those - running warrantless wiretapping programs. +Section: mail +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends}, python (>= 2.7.0), openssl, python-qt4, libqt4-dev (>= 4.8.0), python-qt4-dev, sqlite3, libsqlite3-dev +Suggests: libmessaging-menu-dev +Description: Send encrypted messages + Bitmessage is a P2P communications protocol used to send encrypted + messages to another person or to many subscribers. It is decentralized and + trustless, meaning that you need-not inherently trust any entities like + root certificate authorities. It uses strong authentication which means + that the sender of a message cannot be spoofed, and it aims to hide + "non-content" data, like the sender and receiver of messages, from passive + eavesdroppers like those running warrantless wiretapping programs. diff --git a/debian/copyright b/debian/copyright index 4c5f69f3..32f13f19 100644 --- a/debian/copyright +++ b/debian/copyright @@ -1,30 +1,30 @@ -Format: http://dep.debian.net/deps/dep5 -Upstream-Name: PyBitmessage -Source: https://github.com/Bitmessage/PyBitmessage +Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: +Source: Files: * -Copyright: 2012 Jonathan Warren +Copyright: Copyright 2013 Bob Mottram (4096 bits) License: MIT Files: debian/* -Copyright: 2012 Jonathan Warren +Copyright: Copyright 2013 Bob Mottram (4096 bits) License: MIT License: MIT - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: . - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. . - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. \ No newline at end of file + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/debian/manpages b/debian/manpages new file mode 100644 index 00000000..54af5648 --- /dev/null +++ b/debian/manpages @@ -0,0 +1 @@ +man/pybitmessage.1.gz diff --git a/debian/rules b/debian/rules index 2a7767b6..233679ca 100755 --- a/debian/rules +++ b/debian/rules @@ -1,66 +1,42 @@ #!/usr/bin/make -f -APP=pybitmessage -DESTDIR=${CURDIR}/debian/${APP} -DEST_SHARE=${DESTDIR}/usr/share -DEST_APP=${DEST_SHARE}/${APP} -build: build-stamp +APP=pybitmessage +build: build-stamp make build-arch: build-stamp build-indep: build-stamp build-stamp: - dh_testdir - touch build-stamp + dh_testdir + touch build-stamp + clean: - dh_testdir - dh_testroot - rm -f build-stamp - dh_clean -install: - dh_testdir - dh_testroot - dh_prep - dh_clean -k - dh_installdirs - - mkdir -m 755 -p ${DESTDIR}/usr/bin - mkdir -m 755 -p ${DEST_APP} - mkdir -m 755 -p ${DEST_SHARE}/applications - mkdir -m 755 -p ${DEST_APP}/images - mkdir -m 755 -p ${DEST_APP}/pyelliptic - mkdir -m 755 -p ${DEST_APP}/socks - mkdir -m 755 -p ${DEST_APP}/bitmessageqt - mkdir -m 755 -p ${DEST_APP}/translations - mkdir -m 755 -p ${DEST_SHARE}/pixmaps - mkdir -m 755 -p ${DEST_SHARE}/icons - mkdir -m 755 -p ${DEST_SHARE}/icons/hicolor - mkdir -m 755 -p ${DEST_SHARE}/icons/hicolor/scalable - mkdir -m 755 -p ${DEST_SHARE}/icons/hicolor/scalable/apps - mkdir -m 755 -p ${DEST_SHARE}/icons/hicolor/24x24 - mkdir -m 755 -p ${DEST_SHARE}/icons/hicolor/24x24/apps - - cp -r src/* ${DEST_APP} - install -m 755 debian/pybm ${DESTDIR}/usr/bin/${APP} - - install -m 644 desktop/${APP}.desktop ${DEST_SHARE}/applications/${APP}.desktop - install -m 644 src/images/can-icon-24px.png ${DEST_SHARE}/icons/hicolor/24x24/apps/${APP}.png - install -m 644 desktop/can-icon.svg ${DEST_SHARE}/icons/hicolor/scalable/apps/${APP}.svg - install -m 644 desktop/can-icon.svg ${DEST_SHARE}/pixmaps/${APP}.svg + dh_testdir + dh_testroot + rm -f build-stamp + dh_clean +install: build clean + dh_testdir + dh_testroot + dh_prep + dh_installdirs + ${MAKE} install -B DESTDIR=${CURDIR}/debian/${APP} binary-indep: build install - dh_shlibdeps - dh_testdir - dh_testroot - dh_installchangelogs - dh_installdocs -# dh_installman - dh_link - dh_compress - dh_fixperms - dh_installdeb - dh_gencontrol - dh_md5sums - dh_builddeb + dh_testdir + dh_testroot + dh_installchangelogs + dh_installdocs + dh_installexamples + dh_installman + dh_link + dh_compress + dh_fixperms + dh_installdeb + dh_gencontrol + dh_md5sums + dh_builddeb + binary-arch: build install + binary: binary-indep binary-arch -.PHONY: build clean binary-indep binary install +.PHONY: build clean binary-indep binary-arch binary install diff --git a/desktop/icon14.xpm b/desktop/icon14.xpm new file mode 100644 index 00000000..6d50c8c7 --- /dev/null +++ b/desktop/icon14.xpm @@ -0,0 +1,111 @@ +/* XPM */ +static char * icon14_xpm[] = { +"14 14 94 2", +" c None", +". c #B9BABC", +"+ c #D2D3D4", +"@ c #BEBFC1", +"# c #CBCCCF", +"$ c #E0E3E1", +"% c #F6F8F8", +"& c #F3F3F3", +"* c #B9BABD", +"= c #C8C9CB", +"- c #DADCDB", +"; c #E6E8E7", +"> c #F7F7F7", +", c #FCFCFC", +"' c #F5F5F5", +") c #BCBDBF", +"! c #D3D5D5", +"~ c #E3E5E4", +"{ c #F1F2F2", +"] c #FDFDFD", +"^ c #F8F8F8", +"/ c #CBCCCC", +"( c #B2B3B6", +"_ c #B0B1B3", +": c #D3D4D6", +"< c #DFE0E0", +"[ c #EAEDEB", +"} c #FAF9F9", +"| c #DFE0DF", +"1 c #B9BBBD", +"2 c #C2C3C5", +"3 c #B7B8BC", +"4 c #CDCED0", +"5 c #DCDDDE", +"6 c #E7E9E7", +"7 c #F6F6F6", +"8 c #C0C1C2", +"9 c #DDDFDF", +"0 c #BCBCBF", +"a c #D7D9DA", +"b c #E2E4E3", +"c c #F0F2F1", +"d c #FAFAFA", +"e c #F9F9F9", +"f c #CCCDCD", +"g c #B6B7B9", +"h c #C7C8CA", +"i c #A6A7A9", +"j c #D3D4D5", +"k c #F2F5F3", +"l c #F1F2F1", +"m c #F6F8F7", +"n c #FCFBFC", +"o c #E8EAE9", +"p c #B6B7B8", +"q c #BFC0C2", +"r c #323138", +"s c #1D1D22", +"t c #111117", +"u c #4C4C51", +"v c #ECECED", +"w c #FFFFFF", +"x c #BBBDBD", +"y c #C9CACB", +"z c #333238", +"A c #313036", +"B c #27272C", +"C c #1E1F24", +"D c #16171D", +"E c #919193", +"F c #F2F3F3", +"G c #B4B5B7", +"H c #CDCFCF", +"I c #67666B", +"J c #37363C", +"K c #2C2B31", +"L c #2A292F", +"M c #16171C", +"N c #68696B", +"O c #C7C8C9", +"P c #CBCDCC", +"Q c #49474E", +"R c #39383E", +"S c #36353B", +"T c #333138", +"U c #28272D", +"V c #CED0D0", +"W c #67676C", +"X c #414046", +"Y c #424147", +"Z c #39383F", +"` c #8C8D8F", +" . c #6B6C70", +".. c #75757A", +" . + ", +" @ # $ % & ", +" * = - ; > , ' ", +" ) ! ~ { ] ^ / ( ", +" _ : < [ } , | 1 2 ", +" 3 4 5 6 7 , { 8 . 9 ", +" 2 0 a b c d e f g h ", +" i j k l m n o p q h ", +" r s t u v w ' x g y ", +" z A B C D E F G H ", +" I J A K L M N O P ", +" Q R R S T U V ", +" W X Y X Z ` ", +" ... "}; diff --git a/desktop/icon24.png b/desktop/icon24.png new file mode 100644 index 0000000000000000000000000000000000000000..30f7313eb378b69c4e2f6cb66264c2ae678059e1 GIT binary patch literal 1852 zcmV-C2gCS@P)M^!E?E!Z`=4*Xy`ht_>fhjLl+eV_hy>=-Ek(A(EP8wh@6>5>i{Jah=UrfpOJpyyEE@4x%__we9`O^8Gz zY+YB^0D>Su5CjlH;N;0u?*~Bu&N&bS0ppzGa8EB4rY4DVPDBKSF-HCU16P-HEJ7j{ zNB_V8#>OVLvurL0*LBHtT@Xo}Jb4<4WQ?)(U)V^qv$OC6A8)<&J1DB6+N!HAqgS40M1-^F1`!DUX8C&gnRGe@ zugOKk3q#X23}v$zA1@%4ZpGc13}Zxu2iAXy3X>BMLSomhm+{n7Pk?idful#^*Ezyr z?^5Ynsk5uAtC7-^+n#tfol2v%r3J6O`Z`vx?m{NB3ZCb|_3ZsV_dC<+bR%^l!h!ug z@VU>%#>bmZoH+5fD_6!g$w1(jJD&Yfx-GS5)rys1j5Ug#pWXb-IOmw2o?hS6(|2Sf zpMOr0oWEy8bh}FcG{zVdMbZCv^7OGpGT!ZY?yDjYR4SFe34j4u5I6t=RaNovCkHF@ zoiaipD2jq)GP(ESrQv7p6jU1RJ^w~D8qrNF1lzV@nHGW|z_EWH$MA4|HvlM%F)+q3 zSF1lXI(qr%k!S>tSt5A%%qNy7fY#@OJ=EhAw1( z_N}dtZ{57*k%%G? zyxTA|2q7B+k`g<9wZry251!{C8jT8 z-p;x=cW;j;6M^e_Sar{;s;=ulO|_=rc^-)9w)un*3;rOYd80A9^_8lsC>CeFcKY<0 z4{lZ}Ry-a%wttgbW>)Wx=%_7={5wQBW?I>Bfy4Z=_PG=NJe~Q9lP@w~J_0!8!Mi z9zFhP-S^kT<8fHF3CFQv7zRw!gk#&#H626*-}f;&HHG}>D5{mY;+HpXy5F+Q%Xe-M z0U*X0G)+UPbnTIkKRHlVHEm6MdpjbL2t3b)X_;^w2d-^HS2Yk3s?{on^CK7@$wLGZ zp64ZohO$2d01W`9rl;?qQ0VgL*oRY7S08R~Z--+$Fw77_rVcY?z%ng_LLsP%0zrgw zxr|)yA}WL9CMO3t=b?@zi(yy>Of!T~C+VOB*94LhM2&|}VG20s7@sU4HnuD?>4oOphsFb>PI zZUf%`%U?g-yLaC=7-Oi_YVf%apL0|y71Zl>Y~1)DcJ6!;YuDTZB0_HPA}(DTUI=X2 zCW^)4PlABI9SVie+1UxpvTpCezI`9Hzx&R+{}~^jXqkryAs~c+loA9&&G%88o5S~i zunk+bJl6RAN16Z-N~LQLgR%WmN-SO4fpAk3q?Bk*BpZN(hk5|U(0jP|^`65=ej%iQ zs;ZDuEGZ;^06r_>FlqtwW!jai!%a;Br5)J=X qQ5iHQ#>b literal 0 HcmV?d00001 diff --git a/desktop/pybitmessage.desktop b/desktop/pybitmessage.desktop index 2b1b6902..a97bd664 100644 --- a/desktop/pybitmessage.desktop +++ b/desktop/pybitmessage.desktop @@ -2,29 +2,8 @@ Type=Application Name=PyBitmessage GenericName=PyBitmessage -X-GNOME-FullName=PyBitmessage Secure Messaging -Comment=Send encrypted messages to another person or to many subscribers -Exec=pybitmessage %U +Comment=Send encrypted messages +Exec=pybitmessage %F Icon=pybitmessage Terminal=false -Categories=Network;Email;Application; -Keywords=Email;E-mail;Newsgroup;Messaging; -X-MessagingMenu-UsesChatSection=true -X-Ubuntu-Gettext-Domain=pybitmessage - -Actions=Send;Subscribe;AddressBook; - -[Desktop Action Send] -Name=Send -Exec=pybitmessage -s -OnlyShowIn=Unity; - -[Desktop Action Subscribe] -Name=Subscribe -Exec=pybitmessage -b -OnlyShowIn=Unity; - -[Desktop Action AddressBook] -Name=Address Book -Exec=pybitmessage -a -OnlyShowIn=Unity; +Categories=Office;Email; diff --git a/ebuild.sh b/ebuild.sh new file mode 100755 index 00000000..1a3d16e0 --- /dev/null +++ b/ebuild.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +APP=pybitmessage +PREV_VERSION=0.3.4 +VERSION=0.3.4 +RELEASE=1 +SOURCEDIR=. +ARCH_TYPE=`uname -m` +CURRDIR=`pwd` +SOURCE=~/ebuild/${APP}-${VERSION}.tar.gz + + +# Update version numbers automatically - so you don't have to +sed -i 's/VERSION='${PREV_VERSION}'/VERSION='${VERSION}'/g' Makefile debian.sh rpm.sh arch.sh puppy.sh slack.sh +sed -i 's/Version: '${PREV_VERSION}'/Version: '${VERSION}'/g' rpmpackage/${APP}.spec +sed -i 's/Release: '${RELEASE}'/Release: '${RELEASE}'/g' rpmpackage/${APP}.spec +sed -i 's/pkgrel='${RELEASE}'/pkgrel='${RELEASE}'/g' archpackage/PKGBUILD +sed -i 's/pkgver='${PREV_VERSION}'/pkgver='${VERSION}'/g' archpackage/PKGBUILD +sed -i "s/-${PREV_VERSION}-/-${VERSION}-/g" puppypackage/*.specs +sed -i "s/|${PREV_VERSION}|/|${VERSION}|/g" puppypackage/*.specs +sed -i 's/VERSION='${PREV_VERSION}'/VERSION='${VERSION}'/g' puppypackage/pinstall.sh puppypackage/puninstall.sh +sed -i 's/-'${PREV_VERSION}'.so/-'${VERSION}'.so/g' debian/*.links + +# create the source code in the SOURCES directory +make clean +mkdir -p ~/ebuild +rm -f ${SOURCE} +mv ../${APP} ../${APP}-${VERSION} +tar -cvzf ${SOURCE} ../${APP}-${VERSION} --exclude-vcs + +# rename the root directory without the version number +mv ../${APP}-${VERSION} ../${APP} + diff --git a/ebuildpackage/pybitmessage-0.3.4-1.ebuild b/ebuildpackage/pybitmessage-0.3.4-1.ebuild new file mode 100755 index 00000000..20f056e4 --- /dev/null +++ b/ebuildpackage/pybitmessage-0.3.4-1.ebuild @@ -0,0 +1,22 @@ +# $Header: $ + +EAPI=4 + +DESCRIPTION="Bitmessage is a P2P communications protocol used to send encrypted messages to another person or to many subscribers. It is decentralized and trustless, meaning that you need-not inherently trust any entities like root certificate authorities. It uses strong authentication which means that the sender of a message cannot be spoofed, and it aims to hide "non-content" data, like the sender and receiver of messages, from passive eavesdroppers like those running warrantless wiretapping programs." +HOMEPAGE="https://github.com/Bitmessage/PyBitmessage" +SRC_URI="${PN}/${P}.tar.gz" +LICENSE="MIT" +SLOT="0" +KEYWORDS="x86" +RDEPEND="dev-libs/popt" +DEPEND="${RDEPEND}" + +src_configure() { + econf --with-popt +} + +src_install() { + emake DESTDIR="${D}" install + # Install README and (Debian) changelog + dodoc README.md debian/changelog +} diff --git a/generate.sh b/generate.sh new file mode 100755 index 00000000..92bda853 --- /dev/null +++ b/generate.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +# Generates packaging + +rm -f Makefile rpmpackage/*.spec + +packagemonkey -n "PyBitmessage" --version "0.3.4" --dir "." -l "mit" -e "Bob Mottram (4096 bits) " --brief "Send encrypted messages" --desc "Bitmessage is a P2P communications protocol used to send encrypted messages to another person or to many subscribers. It is decentralized and trustless, meaning that you need-not inherently trust any entities like root certificate authorities. It uses strong authentication which means that the sender of a message cannot be spoofed, and it aims to hide \"non-content\" data, like the sender and receiver of messages, from passive eavesdroppers like those running warrantless wiretapping programs." --homepage "https://github.com/Bitmessage/PyBitmessage" --section "mail" --categories "Office/Email" --dependsdeb "python (>= 2.7.0), openssl, python-qt4, libqt4-dev (>= 4.8.0), python-qt4-dev, sqlite3, libsqlite3-dev" --dependsrpm "python, PyQt4, openssl-compat-bitcoin-libs" --mainscript "bitmessagemain.py" --librarypath "/opt/openssl-compat-bitcoin/lib/" --suggestsdeb "libmessaging-menu-dev" --dependspuppy "openssl, python-qt4, sqlite3, sqlite3-dev, python-openssl" diff --git a/man/pybitmessage.1.gz b/man/pybitmessage.1.gz new file mode 100644 index 0000000000000000000000000000000000000000..efa686a8c9831c74114a4f0a6e0f4d477bbbc078 GIT binary patch literal 546 zcmV+-0^R)|iwFq(6W>t)18{j_X>@I6b8}&5WiBxQrBY3g(?ATp=T}&{08*Q77lZ^t zh%QvLs9$Q@8<$BkZAP1nBipl8`1LqRt1f4xxy;yp&+pAk4hv}7%t>vT&Dp{f;^`EA zg$f=Yrtf2j^&HvK8-}&S_B<|G7uwa6eNPS1ou2L9S2$i9$b>o9xxRfq0dwL$owc1No zS$I;5Zhqy)ck5(YZ4ghk81)*QF68RojnWksVvl~DqZj3fp)g`b!;-IXyE#%f+{-|6 zvvdR}!WtUGtR=AK#d1N|boSmrkX3K+y;&DSWPI-+TpU?3P1C*W7oN$~oLnQY+@y!u zYBd`&5G_56sj5N0(+h=s`1`YpP_rRPZlmdZ4zpFd)v=lSPFBad5E$R|A-H!w9e<{A zw6_hCx)jbDFL_m-9S@7`UK5BJtWh)vHN5@s@aZFH>iHdf$uRpyn4$g*C*e5}{2C=0 kMadFMk%m7{CTAyQ$Px|g> ${APP}-${VERSION}-${RELEASE}.tar.gz +sync +mv -f ${APP}-${VERSION}-${RELEASE}.tar.gz ${APP}-${VERSION}-${RELEASE}.pet +sync +cd ${CURRDIR} + +# Remove the temporary build directory +rm -fr ${BUILDDIR} diff --git a/puppypackage/icon14.xpm b/puppypackage/icon14.xpm new file mode 100644 index 00000000..6d50c8c7 --- /dev/null +++ b/puppypackage/icon14.xpm @@ -0,0 +1,111 @@ +/* XPM */ +static char * icon14_xpm[] = { +"14 14 94 2", +" c None", +". c #B9BABC", +"+ c #D2D3D4", +"@ c #BEBFC1", +"# c #CBCCCF", +"$ c #E0E3E1", +"% c #F6F8F8", +"& c #F3F3F3", +"* c #B9BABD", +"= c #C8C9CB", +"- c #DADCDB", +"; c #E6E8E7", +"> c #F7F7F7", +", c #FCFCFC", +"' c #F5F5F5", +") c #BCBDBF", +"! c #D3D5D5", +"~ c #E3E5E4", +"{ c #F1F2F2", +"] c #FDFDFD", +"^ c #F8F8F8", +"/ c #CBCCCC", +"( c #B2B3B6", +"_ c #B0B1B3", +": c #D3D4D6", +"< c #DFE0E0", +"[ c #EAEDEB", +"} c #FAF9F9", +"| c #DFE0DF", +"1 c #B9BBBD", +"2 c #C2C3C5", +"3 c #B7B8BC", +"4 c #CDCED0", +"5 c #DCDDDE", +"6 c #E7E9E7", +"7 c #F6F6F6", +"8 c #C0C1C2", +"9 c #DDDFDF", +"0 c #BCBCBF", +"a c #D7D9DA", +"b c #E2E4E3", +"c c #F0F2F1", +"d c #FAFAFA", +"e c #F9F9F9", +"f c #CCCDCD", +"g c #B6B7B9", +"h c #C7C8CA", +"i c #A6A7A9", +"j c #D3D4D5", +"k c #F2F5F3", +"l c #F1F2F1", +"m c #F6F8F7", +"n c #FCFBFC", +"o c #E8EAE9", +"p c #B6B7B8", +"q c #BFC0C2", +"r c #323138", +"s c #1D1D22", +"t c #111117", +"u c #4C4C51", +"v c #ECECED", +"w c #FFFFFF", +"x c #BBBDBD", +"y c #C9CACB", +"z c #333238", +"A c #313036", +"B c #27272C", +"C c #1E1F24", +"D c #16171D", +"E c #919193", +"F c #F2F3F3", +"G c #B4B5B7", +"H c #CDCFCF", +"I c #67666B", +"J c #37363C", +"K c #2C2B31", +"L c #2A292F", +"M c #16171C", +"N c #68696B", +"O c #C7C8C9", +"P c #CBCDCC", +"Q c #49474E", +"R c #39383E", +"S c #36353B", +"T c #333138", +"U c #28272D", +"V c #CED0D0", +"W c #67676C", +"X c #414046", +"Y c #424147", +"Z c #39383F", +"` c #8C8D8F", +" . c #6B6C70", +".. c #75757A", +" . + ", +" @ # $ % & ", +" * = - ; > , ' ", +" ) ! ~ { ] ^ / ( ", +" _ : < [ } , | 1 2 ", +" 3 4 5 6 7 , { 8 . 9 ", +" 2 0 a b c d e f g h ", +" i j k l m n o p q h ", +" r s t u v w ' x g y ", +" z A B C D E F G H ", +" I J A K L M N O P ", +" Q R R S T U V ", +" W X Y X Z ` ", +" ... "}; diff --git a/puppypackage/pybitmessage-0.3.4.pet.specs b/puppypackage/pybitmessage-0.3.4.pet.specs new file mode 100644 index 00000000..81060a27 --- /dev/null +++ b/puppypackage/pybitmessage-0.3.4.pet.specs @@ -0,0 +1 @@ +pybitmessage-0.3.4-1|PyBitmessage|0.3.4|1|Internet;mailnews;|3.9M||pybitmessage-0.3.4-1.pet||Send encrypted messages|ubuntu|precise|5| diff --git a/rpm.sh b/rpm.sh new file mode 100755 index 00000000..8269ed9c --- /dev/null +++ b/rpm.sh @@ -0,0 +1,53 @@ +#!/bin/bash + +APP=pybitmessage +PREV_VERSION=0.3.4 +VERSION=0.3.4 +RELEASE=1 +SOURCEDIR=. +ARCH_TYPE=`uname -m` +CURRDIR=`pwd` +SOURCE=~/rpmbuild/SOURCES/${APP}_${VERSION}.orig.tar.gz + + +# Update version numbers automatically - so you don't have to +sed -i 's/VERSION='${PREV_VERSION}'/VERSION='${VERSION}'/g' Makefile debian.sh arch.sh puppy.sh ebuild.sh slack.sh +sed -i 's/Version: '${PREV_VERSION}'/Version: '${VERSION}'/g' rpmpackage/${APP}.spec +sed -i 's/Release: '${RELEASE}'/Release: '${RELEASE}'/g' rpmpackage/${APP}.spec +sed -i 's/pkgrel='${RELEASE}'/pkgrel='${RELEASE}'/g' archpackage/PKGBUILD +sed -i 's/pkgver='${PREV_VERSION}'/pkgver='${VERSION}'/g' archpackage/PKGBUILD +sed -i "s/-${PREV_VERSION}-/-${VERSION}-/g" puppypackage/*.specs +sed -i "s/|${PREV_VERSION}|/|${VERSION}|/g" puppypackage/*.specs +sed -i 's/VERSION='${PREV_VERSION}'/VERSION='${VERSION}'/g' puppypackage/pinstall.sh puppypackage/puninstall.sh +sed -i 's/-'${PREV_VERSION}'.so/-'${VERSION}'.so/g' debian/*.links + +sudo yum groupinstall "Development Tools" +sudo yum install rpmdevtools + +# setup the rpmbuild directory tree +rpmdev-setuptree + +# create the source code in the SOURCES directory +make clean +mkdir -p ~/rpmbuild/SOURCES +rm -f ${SOURCE} + +# having the root directory called name-version seems essential +mv ../${APP} ../${APP}-${VERSION} +tar -cvzf ${SOURCE} ../${APP}-${VERSION} --exclude-vcs + +# rename the root directory without the version number +mv ../${APP}-${VERSION} ../${APP} + +# copy the spec file into the SPECS directory +cp -f rpmpackage/${APP}.spec ~/rpmbuild/SPECS + +# build +cd ~/rpmbuild/SPECS +rpmbuild -ba ${APP}.spec +cd ${CURRDIR} + +# Copy the results into the rpmpackage directory +mkdir -p rpmpackage/${ARCH_TYPE} +cp -r ~/rpmbuild/RPMS/${ARCH_TYPE}/${APP}* rpmpackage/${ARCH_TYPE} +cp -r ~/rpmbuild/SRPMS/${APP}* rpmpackage diff --git a/rpmpackage/pybitmessage.spec b/rpmpackage/pybitmessage.spec new file mode 100644 index 00000000..27485d73 --- /dev/null +++ b/rpmpackage/pybitmessage.spec @@ -0,0 +1,207 @@ +Name: pybitmessage +Version: 0.3.4 +Release: 1%{?dist} +Summary: Send encrypted messages +License: MIT +URL: https://github.com/Bitmessage/PyBitmessage +Packager: Bob Mottram (4096 bits) +Source0: http://yourdomainname.com/src/%{name}_%{version}.orig.tar.gz +Group: Office/Email + +Requires: python, PyQt4, openssl-compat-bitcoin-libs + + +%description +Bitmessage is a P2P communications protocol used to send encrypted messages +to another person or to many subscribers. It is decentralized and +trustless, meaning that you need-not inherently trust any entities like +root certificate authorities. It uses strong authentication which means +that the sender of a message cannot be spoofed, and it aims to hide +"non-content" data, like the sender and receiver of messages, from passive +eavesdroppers like those running warrantless wiretapping programs. + +%prep +%setup -q + +%build +%configure +make %{?_smp_mflags} + +%install +rm -rf %{buildroot} +mkdir -p %{buildroot} +mkdir -p %{buildroot}/etc +mkdir -p %{buildroot}/etc/%{name} +mkdir -p %{buildroot}/usr +mkdir -p %{buildroot}/usr/bin +mkdir -p %{buildroot}/usr/share +mkdir -p %{buildroot}/usr/share/man +mkdir -p %{buildroot}/usr/share/man/man1 +mkdir -p %{buildroot}/usr/share/%{name} +mkdir -p %{buildroot}/usr/share/applications +mkdir -p %{buildroot}/usr/share/icons +mkdir -p %{buildroot}/usr/share/icons/hicolor +mkdir -p %{buildroot}/usr/share/icons/hicolor/24x24 +mkdir -p %{buildroot}/usr/share/icons/hicolor/24x24/apps + +mkdir -p %{buildroot}/usr/share/pixmaps +mkdir -p %{buildroot}/usr/share/icons/hicolor/scalable +mkdir -p %{buildroot}/usr/share/icons/hicolor/scalable/apps +# Make install but to the RPM BUILDROOT directory +make install -B DESTDIR=%{buildroot} + +%files +%doc README.md LICENSE +%defattr(-,root,root,-) +%dir /usr/share/%{name} +%dir /usr/share/applications +%dir /usr/share/icons/hicolor +%dir /usr/share/icons/hicolor/24x24 +%dir /usr/share/icons/hicolor/24x24/apps +%dir /usr/share/pixmaps +%dir /usr/share/icons/hicolor/scalable +%dir /usr/share/icons/hicolor/scalable/apps +/usr/share/%{name}/* +%{_bindir}/* +%{_mandir}/man1/* +%attr(644,root,root) /usr/share/applications/%{name}.desktop +%attr(644,root,root) /usr/share/icons/hicolor/24x24/apps/%{name}.png + +%changelog +* Sun Jun 30 2013 Bob Mottram (4096 bits) - 0.3.4-1 +- Switched addr, msg, broadcast, and getpubkey message types + to 8 byte time. Last remaining type is pubkey. +- Added tooltips to show the full subject of messages +- Added Maximum Acceptable Difficulty fields in the settings +- Send out pubkey immediately after generating deterministic + addresses rather than waiting for a request + +* Sat Jun 29 2013 Bob Mottram (4096 bits) - 0.3.3-1 +- Remove inbox item from GUI when using API command trashMessage +- Add missing trailing semicolons to pybitmessage.desktop +- Ensure $(DESTDIR)/usr/bin exists +- Update Makefile to correct sandbox violations when built + via Portage (Gentoo) +- Fix message authentication bug + +* Fri Jun 28 2013 Bob Mottram (4096 bits) - 0.3.211-1 +- Removed multi-core proof of work + as the multiprocessing module does not work well with + pyinstaller's --onefile option. + +* Mon Jun 03 2013 Bob Mottram (4096 bits) - 0.3.2-1 +- Bugfix: Remove remaining references to the old myapp.trayIcon +- Refactored message status-related code. API function getStatus + now returns one of these strings: notfound, msgqueued, + broadcastqueued, broadcastsent, doingpubkeypow, awaitingpubkey, + doingmsgpow, msgsent, or ackreceived +- Moved proof of work to low-priority multi-threaded child + processes +- Added menu option to delete all trashed messages +- Added inv flooding attack mitigation +- On Linux, when selecting Show Bitmessage, do not maximize + automatically +- Store tray icons in bitmessage_icons_rc.py + +* Sat May 25 2013 Jonathan Warren (4096 bits) - 0.3.1-1 +- Added new API commands: getDeterministicAddress, + addSubscription, deleteSubscription +- TCP Connection timeout for non-fully-established connections + now 20 seconds +- Don't update the time we last communicated with a node unless + the connection is fully established. This will allow us to + forget about active but non-Bitmessage nodes which have made + it into our knownNodes file. +- Prevent incoming connection flooding from crashing + singleListener thread. Client will now only accept one + connection per remote node IP +- Bugfix: Worker thread crashed when doing a POW to send out + a v2 pubkey (bug introduced in 0.3.0) +- Wrap all sock.shutdown functions in error handlers +- Put all 'commit' commands within SQLLocks +- Bugfix: If address book label is blank, Bitmessage wouldn't + show message (bug introduced in 0.3.0) +- Messaging menu item selects the oldest unread message +- Standardize on 'Quit' rather than 'Exit' +- [OSX] Try to seek homebrew installation of OpenSSL +- Prevent multiple instances of the application from running +- Show 'Connected' or 'Connection Lost' indicators +- Use only 9 half-open connections on Windows but 32 for + everyone else +- Added appIndicator (a more functional tray icon) and Ubuntu + Messaging Menu integration +- Changed Debian install directory and run script name based + on Github issue #135 + +* Tue May 6 2013 Bob Mottram (4096 bits) - 0.3.0-1 +- Added new API function: getStatus +- Added error-handling around all sock.sendall() functions + in the receiveData thread so that if there is a problem + sending data, the threads will close gracefully +- Abandoned and removed the connectionsCount data structure; + use the connectedHostsList instead because it has proved to be + more accurate than trying to maintain the connectionsCount +- Added daemon mode. All UI code moved into a module and many + shared objects moved into shared.py +- Truncate display of very long messages to avoid freezing the UI +- Added encrypted broadcasts for v3 addresses or v2 addresses + after 2013-05-28 10:00 UTC +- No longer self.sock.close() from within receiveDataThreads, + let the sendDataThreads do it +- Swapped out the v2 announcements subscription address for a v3 + announcements subscription address +- Vacuum the messages.dat file once a month: will greatly reduce the file size +- Added a settings table in message.dat +- Implemented v3 addresses: + pubkey messages must now include two var_ints: nonce_trials_per_byte + and extra_bytes, and also be signed. When sending a message to a v3 + address, the sender must use these values in calculating its POW or + else the message will not be accepted by the receiver. +- Display a privacy warning when selecting 'Send Broadcast from this address' +- Added gitignore file +- Added code in preparation for a switch from 32-bit time to 64-bit time. + Nodes will now advertise themselves as using protocol version 2. +- Don't necessarily delete entries from the inventory after 2.5 days; + leave pubkeys there for 28 days so that we don't process the same ones + many times throughout a month. This was causing the 'pubkeys processed' + indicator on the 'Network Status' tab to not accurately reflect the + number of truly new addresses on the network. +- Use 32 threads for outgoing connections in order to connect quickly +- Fix typo when calling os.environ in the sys.platform=='darwin' case +- Allow the cancelling of a message which is in the process of being + sent by trashing it then restarting Bitmessage +- Bug fix: can't delete address from address book + +* Tue Apr 9 2013 Bob Mottram (4096 bits) - 0.2.8-1 +- Fixed Ubuntu & OS X issue: + Bitmessage wouldn't receive any objects from peers after restart. +- Inventory flush to disk when exiting program now vastly faster. +- Fixed address generation bug (kept Bitmessage from restarting). +- Improve deserialization of messages + before processing (a 'best practice'). +- Change to help Macs find OpenSSL the way Unix systems find it. +- Do not share or accept IPs which are in the private IP ranges. +- Added time-fuzzing + to the embedded time in pubkey and getpubkey messages. +- Added a knownNodes lock + to prevent an exception from sometimes occurring when saving + the data-structure to disk. +- Show unread messages in bold + and do not display new messages automatically. +- Support selecting multiple items + in the inbox, sent box, and address book. +- Use delete key to trash Inbox or Sent messages. +- Display richtext(HTML) messages + from senders in address book or subscriptions (although not + pseudo-mailing-lists; use new right-click option). +- Trim spaces + from the beginning and end of addresses when adding to + address book, subscriptions, and blacklist. +- Improved the display of the time for foreign language users. + +* Tue Apr 1 2013 Bob Mottram (4096 bits) - 0.2.7-1 +- Added debian packaging +- Script to generate debian packages +- SVG icon for Gnome shell, etc +- Source moved int src directory for debian standards compatibility +- Trailing carriage return on COPYING LICENSE and README.md diff --git a/slack.sh b/slack.sh new file mode 100755 index 00000000..cc71e1f3 --- /dev/null +++ b/slack.sh @@ -0,0 +1,48 @@ +#!/bin/bash + +APP=pybitmessage +PREV_VERSION=0.3.4 +VERSION=0.3.4 +RELEASE=1 +ARCH_TYPE=`uname -m` +BUILDDIR=~/slackbuild +CURRDIR=`pwd` +PROJECTDIR=${BUILDDIR}/${APP}-${VERSION}-${RELEASE} + +# Update version numbers automatically - so you don't have to +sed -i 's/VERSION='${PREV_VERSION}'/VERSION='${VERSION}'/g' Makefile debian.sh rpm.sh arch.sh puppy.sh ebuild.sh +sed -i 's/Version: '${PREV_VERSION}'/Version: '${VERSION}'/g' rpmpackage/${APP}.spec +sed -i 's/Release: '${RELEASE}'/Release: '${RELEASE}'/g' rpmpackage/${APP}.spec +sed -i 's/pkgrel='${RELEASE}'/pkgrel='${RELEASE}'/g' archpackage/PKGBUILD +sed -i 's/pkgver='${PREV_VERSION}'/pkgver='${VERSION}'/g' archpackage/PKGBUILD +sed -i "s/-${PREV_VERSION}-/-${VERSION}-/g" puppypackage/*.specs +sed -i "s/|${PREV_VERSION}|/|${VERSION}|/g" puppypackage/*.specs +sed -i 's/VERSION='${PREV_VERSION}'/VERSION='${VERSION}'/g' puppypackage/pinstall.sh puppypackage/puninstall.sh +sed -i 's/-'${PREV_VERSION}'.so/-'${VERSION}'.so/g' debian/*.links + + +# Make directories within which the project will be built +mkdir -p ${BUILDDIR} +mkdir -p ${PROJECTDIR} + +# Build the project +make clean +make +make install -B DESTDIR=${PROJECTDIR} + +# Copy the slack-desc and doinst.sh files into the build install directory +mkdir ${PROJECTDIR}/install +cp ${CURRDIR}/slackpackage/slack-desc ${PROJECTDIR}/install +cp ${CURRDIR}/slackpackage/doinst.sh ${PROJECTDIR}/install + +# Compress the build directory +cd ${BUILDDIR} +tar -c -f ${APP}-${VERSION}-${RELEASE}.tar . +sync +xz ${APP}-${VERSION}-${RELEASE}.tar +sync +mv ${APP}-${VERSION}-${RELEASE}.tar.xz ${CURRDIR}/slackpackage/${APP}-${VERSION}-${ARCH_TYPE}-${RELEASE}.txz +cd ${CURRDIR} + +# Remove the temporary build directory +rm -fr ${BUILDDIR} diff --git a/slackpackage/doinst.sh b/slackpackage/doinst.sh new file mode 100755 index 00000000..2d703395 --- /dev/null +++ b/slackpackage/doinst.sh @@ -0,0 +1,4 @@ +#!/bin/sh -e + +# This script is run after installation. +# Any additional configuration goes here. diff --git a/slackpackage/slack-desc b/slackpackage/slack-desc new file mode 100644 index 00000000..8705a13b --- /dev/null +++ b/slackpackage/slack-desc @@ -0,0 +1,19 @@ +# HOW TO EDIT THIS FILE: +# The "handy ruler" below makes it easier to edit a package description. Line +# up the first '|' above the ':' following the base package name, and the '|' on +# the right side marks the last column you can put a character in. You must make +# exactly 11 lines for the formatting to be correct. It's also customary to +# leave one space after the ':'. + + |-----handy-ruler--------------------------------------------------| +pybitmessage: pybitmessage (Send encrypted messages) +pybitmessage: +pybitmessage: Bitmessage is a P2P communications protocol used to send +pybitmessage: encrypted messages to another person or to many subscribers. It +pybitmessage: is decentralized and trustless, meaning that you need-not +pybitmessage: inherently trust any entities like root certificate authorities. +pybitmessage: It uses strong authentication which means that the sender of a +pybitmessage: message cannot be spoofed, and it aims to hide "non-content" +pybitmessage: data, like the sender and receiver of messages, from passive +pybitmessage: eavesdroppers like those running warrantless wiretapping +pybitmessage: programs. From fc5da5d3ff5c26e6ab17d70e3a121db0ac85eb05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gerg=C3=B6=20Barany?= Date: Fri, 12 Jul 2013 12:16:34 +0200 Subject: [PATCH 18/39] Refactor type 2 message decoding, drop any extra lines from subject. This allows other clients to insert headers in extra lines of text between the Subject and Body fields of the message, as discussed on the 24x7 mailing list. The PyBitmessage client was never able to meaningfully display multi-line subjects, so this does not break anything. The extra lines are thrown away and never stored anywhere, so this also protects against watermarking attacks. --- src/class_receiveDataThread.py | 41 +++++++++++++++------------------- 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/src/class_receiveDataThread.py b/src/class_receiveDataThread.py index ad5e7b34..e73f3d2b 100644 --- a/src/class_receiveDataThread.py +++ b/src/class_receiveDataThread.py @@ -528,13 +528,7 @@ class receiveDataThread(threading.Thread): print 'fromAddress:', fromAddress if messageEncodingType == 2: - bodyPositionIndex = string.find(message, '\nBody:') - if bodyPositionIndex > 1: - subject = message[8:bodyPositionIndex] - body = message[bodyPositionIndex + 6:] - else: - subject = '' - body = message + subject, body = self.decodeType2Message(message) elif messageEncodingType == 1: body = message subject = '' @@ -684,13 +678,7 @@ class receiveDataThread(threading.Thread): print 'fromAddress:', fromAddress if messageEncodingType == 2: - bodyPositionIndex = string.find(message, '\nBody:') - if bodyPositionIndex > 1: - subject = message[8:bodyPositionIndex] - body = message[bodyPositionIndex + 6:] - else: - subject = '' - body = message + subject, body = self.decodeType2Message(message) elif messageEncodingType == 1: body = message subject = '' @@ -1005,15 +993,7 @@ class receiveDataThread(threading.Thread): toLabel = toAddress if messageEncodingType == 2: - bodyPositionIndex = string.find(message, '\nBody:') - if bodyPositionIndex > 1: - subject = message[8:bodyPositionIndex] - subject = subject[ - :500] # Only save and show the first 500 characters of the subject. Any more is probably an attak. - body = message[bodyPositionIndex + 6:] - else: - subject = '' - body = message + subject, body = self.decodeType2Message(message) elif messageEncodingType == 1: body = message subject = '' @@ -1086,6 +1066,21 @@ class receiveDataThread(threading.Thread): print 'Time to decrypt this message successfully:', timeRequiredToAttemptToDecryptMessage print 'Average time for all message decryption successes since startup:', sum / len(shared.successfullyDecryptMessageTimings) + def decodeType2Message(self, message): + bodyPositionIndex = string.find(message, '\nBody:') + if bodyPositionIndex > 1: + subject = message[8:bodyPositionIndex] + # Only save and show the first 500 characters of the subject. + # Any more is probably an attack. + subject = subject[:500] + body = message[bodyPositionIndex + 6:] + else: + subject = '' + body = message + # Throw away any extra lines (headers) after the subject. + if subject: + subject = subject.splitlines()[0] + return subject, body def isAckDataValid(self, ackData): if len(ackData) < 24: From 3364433765a9caea3001ba83cf554e5758ed7f73 Mon Sep 17 00:00:00 2001 From: fuzzgun Date: Fri, 12 Jul 2013 12:07:55 +0100 Subject: [PATCH 19/39] Fixing the puppy script --- archpackage/PKGBUILD | 2 +- generate.sh | 2 +- puppy.sh | 2 +- puppypackage/pybitmessage-0.3.4.pet.specs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/archpackage/PKGBUILD b/archpackage/PKGBUILD index a75d262a..97beecd2 100644 --- a/archpackage/PKGBUILD +++ b/archpackage/PKGBUILD @@ -19,7 +19,7 @@ install= changelog= source=($pkgname-$pkgver.tar.gz) noextract=() -md5sums=(56a8a225463e96b435b2a5b438006983) +md5sums=() build() { cd "$srcdir/$pkgname-$pkgver" ./configure --prefix=/usr diff --git a/generate.sh b/generate.sh index 92bda853..9d792e1d 100755 --- a/generate.sh +++ b/generate.sh @@ -4,4 +4,4 @@ rm -f Makefile rpmpackage/*.spec -packagemonkey -n "PyBitmessage" --version "0.3.4" --dir "." -l "mit" -e "Bob Mottram (4096 bits) " --brief "Send encrypted messages" --desc "Bitmessage is a P2P communications protocol used to send encrypted messages to another person or to many subscribers. It is decentralized and trustless, meaning that you need-not inherently trust any entities like root certificate authorities. It uses strong authentication which means that the sender of a message cannot be spoofed, and it aims to hide \"non-content\" data, like the sender and receiver of messages, from passive eavesdroppers like those running warrantless wiretapping programs." --homepage "https://github.com/Bitmessage/PyBitmessage" --section "mail" --categories "Office/Email" --dependsdeb "python (>= 2.7.0), openssl, python-qt4, libqt4-dev (>= 4.8.0), python-qt4-dev, sqlite3, libsqlite3-dev" --dependsrpm "python, PyQt4, openssl-compat-bitcoin-libs" --mainscript "bitmessagemain.py" --librarypath "/opt/openssl-compat-bitcoin/lib/" --suggestsdeb "libmessaging-menu-dev" --dependspuppy "openssl, python-qt4, sqlite3, sqlite3-dev, python-openssl" +packagemonkey -n "PyBitmessage" --version "0.3.4" --dir "." -l "mit" -e "Bob Mottram (4096 bits) " --brief "Send encrypted messages" --desc "Bitmessage is a P2P communications protocol used to send encrypted messages to another person or to many subscribers. It is decentralized and trustless, meaning that you need-not inherently trust any entities like root certificate authorities. It uses strong authentication which means that the sender of a message cannot be spoofed, and it aims to hide \"non-content\" data, like the sender and receiver of messages, from passive eavesdroppers like those running warrantless wiretapping programs." --homepage "https://github.com/Bitmessage/PyBitmessage" --section "mail" --categories "Office/Email" --dependsdeb "python (>= 2.7.0), openssl, python-qt4, libqt4-dev (>= 4.8.0), python-qt4-dev, sqlite3, libsqlite3-dev" --dependsrpm "python, PyQt4, openssl-compat-bitcoin-libs" --mainscript "bitmessagemain.py" --librarypath "/opt/openssl-compat-bitcoin/lib/" --suggestsdeb "libmessaging-menu-dev" --dependspuppy "openssl, python-qt4, sqlite3, sqlite3-dev, python-openssl, python-sip" diff --git a/puppy.sh b/puppy.sh index 3fc2db14..dd54ecc9 100755 --- a/puppy.sh +++ b/puppy.sh @@ -44,7 +44,7 @@ cp ${PROJECTDIR}/usr/bin/* ${PROJECTDIR}/usr/local/bin/ cp ${CURRDIR}/puppypackage/${APP}-${VERSION}.pet.specs ${PROJECTDIR} # Copy the XPM mini icon into the build directory -cp ${CURRDIR}//home/motters/develop/pybitmessage/desktop/icon14.xpm ${PROJECTDIR}/pybitmessage.xpm +cp ${CURRDIR}/desktop/icon14.xpm ${PROJECTDIR}/${APP}.xpm # Compress the build directory cd ${BUILDDIR} diff --git a/puppypackage/pybitmessage-0.3.4.pet.specs b/puppypackage/pybitmessage-0.3.4.pet.specs index 81060a27..5c9b2a41 100644 --- a/puppypackage/pybitmessage-0.3.4.pet.specs +++ b/puppypackage/pybitmessage-0.3.4.pet.specs @@ -1 +1 @@ -pybitmessage-0.3.4-1|PyBitmessage|0.3.4|1|Internet;mailnews;|3.9M||pybitmessage-0.3.4-1.pet||Send encrypted messages|ubuntu|precise|5| +pybitmessage-0.3.4-1|PyBitmessage|0.3.4|1|Internet;mailnews;|4.1M||pybitmessage-0.3.4-1.pet|+openssl,+python-qt4,+sqlite3,+sqlite3-dev,+python-openssl,+python-sip|Send encrypted messages|ubuntu|precise|5| From 28d1bfa645dd3d59eb660431aaa8f1f335e66134 Mon Sep 17 00:00:00 2001 From: fuzzgun Date: Fri, 12 Jul 2013 14:03:11 +0100 Subject: [PATCH 20/39] Some Arch dependencies --- Makefile | 2 +- arch.sh | 5 ++++- archpackage/PKGBUILD | 2 +- generate.sh | 2 +- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 92b4e633..e7577494 100644 --- a/Makefile +++ b/Makefile @@ -41,5 +41,5 @@ clean: rm -f ${APP} \#* \.#* gnuplot* *.png debian/*.substvars debian/*.log rm -fr deb.* debian/${APP} rpmpackage/${ARCH_TYPE} rm -f ../${APP}*.deb ../${APP}*.changes ../${APP}*.asc ../${APP}*.dsc - rm -f rpmpackage/*.src.rpm archpackage/*.gz + rm -f rpmpackage/*.src.rpm archpackage/*.gz archpackage/*.xz rm -f puppypackage/*.gz puppypackage/*.pet slackpackage/*.txz diff --git a/arch.sh b/arch.sh index 8917cef4..77332d09 100755 --- a/arch.sh +++ b/arch.sh @@ -38,7 +38,10 @@ sed -i "s/md5sums[^)]*)/md5sums=(${CHECKSM%% *})/g" archpackage/PKGBUILD cd archpackage # Create the package -makepkg +tar -c -f ${APP}-${VERSION}.pkg.tar . +sync +xz ${APP}-${VERSION}.pkg.tar +sync # Move back to the original directory cd ${CURRDIR} diff --git a/archpackage/PKGBUILD b/archpackage/PKGBUILD index 97beecd2..b7c9626f 100644 --- a/archpackage/PKGBUILD +++ b/archpackage/PKGBUILD @@ -7,7 +7,7 @@ arch=('i686' 'x86_64') url="https://github.com/Bitmessage/PyBitmessage" license=('MIT') groups=() -depends=() +depends=( 'python2' 'qt4' 'python2-pyqt4' 'python2-gevent' 'sqlite' 'openssl') makedepends=() optdepends=() provides=() diff --git a/generate.sh b/generate.sh index 9d792e1d..0b612765 100755 --- a/generate.sh +++ b/generate.sh @@ -4,4 +4,4 @@ rm -f Makefile rpmpackage/*.spec -packagemonkey -n "PyBitmessage" --version "0.3.4" --dir "." -l "mit" -e "Bob Mottram (4096 bits) " --brief "Send encrypted messages" --desc "Bitmessage is a P2P communications protocol used to send encrypted messages to another person or to many subscribers. It is decentralized and trustless, meaning that you need-not inherently trust any entities like root certificate authorities. It uses strong authentication which means that the sender of a message cannot be spoofed, and it aims to hide \"non-content\" data, like the sender and receiver of messages, from passive eavesdroppers like those running warrantless wiretapping programs." --homepage "https://github.com/Bitmessage/PyBitmessage" --section "mail" --categories "Office/Email" --dependsdeb "python (>= 2.7.0), openssl, python-qt4, libqt4-dev (>= 4.8.0), python-qt4-dev, sqlite3, libsqlite3-dev" --dependsrpm "python, PyQt4, openssl-compat-bitcoin-libs" --mainscript "bitmessagemain.py" --librarypath "/opt/openssl-compat-bitcoin/lib/" --suggestsdeb "libmessaging-menu-dev" --dependspuppy "openssl, python-qt4, sqlite3, sqlite3-dev, python-openssl, python-sip" +packagemonkey -n "PyBitmessage" --version "0.3.4" --dir "." -l "mit" -e "Bob Mottram (4096 bits) " --brief "Send encrypted messages" --desc "Bitmessage is a P2P communications protocol used to send encrypted messages to another person or to many subscribers. It is decentralized and trustless, meaning that you need-not inherently trust any entities like root certificate authorities. It uses strong authentication which means that the sender of a message cannot be spoofed, and it aims to hide \"non-content\" data, like the sender and receiver of messages, from passive eavesdroppers like those running warrantless wiretapping programs." --homepage "https://github.com/Bitmessage/PyBitmessage" --section "mail" --categories "Office/Email" --dependsdeb "python (>= 2.7.0), openssl, python-qt4, libqt4-dev (>= 4.8.0), python-qt4-dev, sqlite3, libsqlite3-dev" --dependsrpm "python, PyQt4, openssl-compat-bitcoin-libs" --mainscript "bitmessagemain.py" --librarypath "/opt/openssl-compat-bitcoin/lib/" --suggestsdeb "libmessaging-menu-dev" --dependspuppy "openssl, python-qt4, sqlite3, sqlite3-dev, python-openssl, python-sip" --dependsarch "python2, qt4, python2-pyqt4, python2-gevent, sqlite, openssl" From 33a41367b3cd401614798cb1a241e148c3ba862d Mon Sep 17 00:00:00 2001 From: fuzzgun Date: Fri, 12 Jul 2013 14:09:10 +0100 Subject: [PATCH 21/39] Duplocated command in Makefile --- puppypackage/pybitmessage-0.3.4.pet.specs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/puppypackage/pybitmessage-0.3.4.pet.specs b/puppypackage/pybitmessage-0.3.4.pet.specs index 5c9b2a41..d9649f3c 100644 --- a/puppypackage/pybitmessage-0.3.4.pet.specs +++ b/puppypackage/pybitmessage-0.3.4.pet.specs @@ -1 +1 @@ -pybitmessage-0.3.4-1|PyBitmessage|0.3.4|1|Internet;mailnews;|4.1M||pybitmessage-0.3.4-1.pet|+openssl,+python-qt4,+sqlite3,+sqlite3-dev,+python-openssl,+python-sip|Send encrypted messages|ubuntu|precise|5| +pybitmessage-0.3.4-1|PyBitmessage|0.3.4|1|Internet;mailnews;|4.2M||pybitmessage-0.3.4-1.pet|+openssl,+python-qt4,+sqlite3,+sqlite3-dev,+python-openssl,+python-sip|Send encrypted messages|ubuntu|precise|5| From d3b76eb610bb835b24a833bb968cac53057014a1 Mon Sep 17 00:00:00 2001 From: fuzzgun Date: Fri, 12 Jul 2013 18:09:59 +0100 Subject: [PATCH 22/39] python2-gevent is optional --- archpackage/PKGBUILD | 4 ++-- debian/control | 2 +- generate.sh | 2 +- puppypackage/pybitmessage-0.3.4.pet.specs | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/archpackage/PKGBUILD b/archpackage/PKGBUILD index b7c9626f..79ee8ded 100644 --- a/archpackage/PKGBUILD +++ b/archpackage/PKGBUILD @@ -7,9 +7,9 @@ arch=('i686' 'x86_64') url="https://github.com/Bitmessage/PyBitmessage" license=('MIT') groups=() -depends=( 'python2' 'qt4' 'python2-pyqt4' 'python2-gevent' 'sqlite' 'openssl') +depends=('python2' 'qt4' 'python2-pyqt4' 'sqlite' 'openssl') makedepends=() -optdepends=() +optdepends=('python2-gevent') provides=() conflicts=() replaces=() diff --git a/debian/control b/debian/control index de8f3a59..e2d860d0 100644 --- a/debian/control +++ b/debian/control @@ -4,7 +4,7 @@ Maintainer: Bob Mottram (4096 bits) Build-Depends: debhelper (>= 9.0.0) Standards-Version: 3.9.4 Homepage: https://github.com/Bitmessage/PyBitmessage -Vcs-Git: https://github.com/fuzzgun/autocv.git +Vcs-Git: https://github.com/fuzzgun/libgpr.git Package: pybitmessage Section: mail diff --git a/generate.sh b/generate.sh index 0b612765..44aca136 100755 --- a/generate.sh +++ b/generate.sh @@ -4,4 +4,4 @@ rm -f Makefile rpmpackage/*.spec -packagemonkey -n "PyBitmessage" --version "0.3.4" --dir "." -l "mit" -e "Bob Mottram (4096 bits) " --brief "Send encrypted messages" --desc "Bitmessage is a P2P communications protocol used to send encrypted messages to another person or to many subscribers. It is decentralized and trustless, meaning that you need-not inherently trust any entities like root certificate authorities. It uses strong authentication which means that the sender of a message cannot be spoofed, and it aims to hide \"non-content\" data, like the sender and receiver of messages, from passive eavesdroppers like those running warrantless wiretapping programs." --homepage "https://github.com/Bitmessage/PyBitmessage" --section "mail" --categories "Office/Email" --dependsdeb "python (>= 2.7.0), openssl, python-qt4, libqt4-dev (>= 4.8.0), python-qt4-dev, sqlite3, libsqlite3-dev" --dependsrpm "python, PyQt4, openssl-compat-bitcoin-libs" --mainscript "bitmessagemain.py" --librarypath "/opt/openssl-compat-bitcoin/lib/" --suggestsdeb "libmessaging-menu-dev" --dependspuppy "openssl, python-qt4, sqlite3, sqlite3-dev, python-openssl, python-sip" --dependsarch "python2, qt4, python2-pyqt4, python2-gevent, sqlite, openssl" +packagemonkey -n "PyBitmessage" --version "0.3.4" --dir "." -l "mit" -e "Bob Mottram (4096 bits) " --brief "Send encrypted messages" --desc "Bitmessage is a P2P communications protocol used to send encrypted messages to another person or to many subscribers. It is decentralized and trustless, meaning that you need-not inherently trust any entities like root certificate authorities. It uses strong authentication which means that the sender of a message cannot be spoofed, and it aims to hide \"non-content\" data, like the sender and receiver of messages, from passive eavesdroppers like those running warrantless wiretapping programs." --homepage "https://github.com/Bitmessage/PyBitmessage" --section "mail" --categories "Office/Email" --dependsdeb "python (>= 2.7.0), openssl, python-qt4, libqt4-dev (>= 4.8.0), python-qt4-dev, sqlite3, libsqlite3-dev" --dependsrpm "python, PyQt4, openssl-compat-bitcoin-libs" --mainscript "bitmessagemain.py" --librarypath "/opt/openssl-compat-bitcoin/lib/" --suggestsdeb "libmessaging-menu-dev" --dependspuppy "openssl, python-qt4, sqlite3, sqlite3-dev, python-openssl, python-sip" --dependsarch "python2, qt4, python2-pyqt4, sqlite, openssl" --suggestsarch "python2-gevent" diff --git a/puppypackage/pybitmessage-0.3.4.pet.specs b/puppypackage/pybitmessage-0.3.4.pet.specs index d9649f3c..2d576f60 100644 --- a/puppypackage/pybitmessage-0.3.4.pet.specs +++ b/puppypackage/pybitmessage-0.3.4.pet.specs @@ -1 +1 @@ -pybitmessage-0.3.4-1|PyBitmessage|0.3.4|1|Internet;mailnews;|4.2M||pybitmessage-0.3.4-1.pet|+openssl,+python-qt4,+sqlite3,+sqlite3-dev,+python-openssl,+python-sip|Send encrypted messages|ubuntu|precise|5| +pybitmessage-0.3.4-1|PyBitmessage|0.3.4|1|Internet;mailnews;|4.5M||pybitmessage-0.3.4-1.pet|+openssl,+python-qt4,+sqlite3,+sqlite3-dev,+python-openssl,+python-sip|Send encrypted messages|ubuntu|precise|5| From 97f0c56aa856fda505255e0ba7bcee89677f6ea5 Mon Sep 17 00:00:00 2001 From: David Nichols Date: Fri, 12 Jul 2013 13:03:09 -0500 Subject: [PATCH 23/39] Adding configuration option to listen for connections when operating with a SOCKS proxy. --- src/bitmessageqt/__init__.py | 7 +++ src/bitmessageqt/settings.py | 84 +++++++++++++++++++++--------------- src/bitmessageqt/settings.ui | 8 ++++ src/class_singleListener.py | 4 +- src/class_sqlThread.py | 1 + src/helper_startup.py | 2 + 6 files changed, 69 insertions(+), 37 deletions(-) diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py index ae5ab8a7..ffba42c3 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -1764,6 +1764,8 @@ class MyForm(QtGui.QMainWindow): self.settingsDialogInstance.ui.lineEditSocksUsername.text())) shared.config.set('bitmessagesettings', 'sockspassword', str( self.settingsDialogInstance.ui.lineEditSocksPassword.text())) + shared.config.set('bitmessagesettings', 'sockslisten', str( + self.settingsDialogInstance.ui.checkBoxSocksListen.isChecked())) if float(self.settingsDialogInstance.ui.lineEditTotalDifficulty.text()) >= 1: shared.config.set('bitmessagesettings', 'defaultnoncetrialsperbyte', str(int(float( self.settingsDialogInstance.ui.lineEditTotalDifficulty.text()) * shared.networkDefaultProofOfWorkNonceTrialsPerByte))) @@ -2691,6 +2693,8 @@ class settingsDialog(QtGui.QDialog): shared.config.get('bitmessagesettings', 'port'))) self.ui.checkBoxAuthentication.setChecked(shared.config.getboolean( 'bitmessagesettings', 'socksauthentication')) + self.ui.checkBoxSocksListen.setChecked(shared.config.getboolean( + 'bitmessagesettings', 'sockslisten')) if str(shared.config.get('bitmessagesettings', 'socksproxytype')) == 'none': self.ui.comboBoxProxyType.setCurrentIndex(0) self.ui.lineEditSocksHostname.setEnabled(False) @@ -2698,6 +2702,7 @@ class settingsDialog(QtGui.QDialog): self.ui.lineEditSocksUsername.setEnabled(False) self.ui.lineEditSocksPassword.setEnabled(False) self.ui.checkBoxAuthentication.setEnabled(False) + self.ui.checkBoxSocksListen.setEnabled(False) elif str(shared.config.get('bitmessagesettings', 'socksproxytype')) == 'SOCKS4a': self.ui.comboBoxProxyType.setCurrentIndex(1) self.ui.lineEditTCPPort.setEnabled(False) @@ -2754,11 +2759,13 @@ class settingsDialog(QtGui.QDialog): self.ui.lineEditSocksUsername.setEnabled(False) self.ui.lineEditSocksPassword.setEnabled(False) self.ui.checkBoxAuthentication.setEnabled(False) + self.ui.checkBoxSocksListen.setEnabled(False) self.ui.lineEditTCPPort.setEnabled(True) elif comboBoxIndex == 1 or comboBoxIndex == 2: self.ui.lineEditSocksHostname.setEnabled(True) self.ui.lineEditSocksPort.setEnabled(True) self.ui.checkBoxAuthentication.setEnabled(True) + self.ui.checkBoxSocksListen.setEnabled(True) if self.ui.checkBoxAuthentication.isChecked(): self.ui.lineEditSocksUsername.setEnabled(True) self.ui.lineEditSocksPassword.setEnabled(True) diff --git a/src/bitmessageqt/settings.py b/src/bitmessageqt/settings.py index 8c94333c..d7672e9d 100644 --- a/src/bitmessageqt/settings.py +++ b/src/bitmessageqt/settings.py @@ -2,8 +2,8 @@ # Form implementation generated from reading ui file 'settings.ui' # -# Created: Mon Jun 10 11:31:56 2013 -# by: PyQt4 UI code generator 4.9.4 +# Created: Fri Jul 12 12:37:53 2013 +# by: PyQt4 UI code generator 4.10.1 # # WARNING! All changes made in this file will be lost! @@ -12,7 +12,16 @@ from PyQt4 import QtCore, QtGui try: _fromUtf8 = QtCore.QString.fromUtf8 except AttributeError: - _fromUtf8 = lambda s: s + def _fromUtf8(s): + return s + +try: + _encoding = QtGui.QApplication.UnicodeUTF8 + def _translate(context, text, disambig): + return QtGui.QApplication.translate(context, text, disambig, _encoding) +except AttributeError: + def _translate(context, text, disambig): + return QtGui.QApplication.translate(context, text, disambig) class Ui_settingsDialog(object): def setupUi(self, settingsDialog): @@ -122,6 +131,9 @@ class Ui_settingsDialog(object): self.lineEditSocksPassword.setEchoMode(QtGui.QLineEdit.Password) self.lineEditSocksPassword.setObjectName(_fromUtf8("lineEditSocksPassword")) self.gridLayout_2.addWidget(self.lineEditSocksPassword, 2, 5, 1, 1) + self.checkBoxSocksListen = QtGui.QCheckBox(self.groupBox_2) + self.checkBoxSocksListen.setObjectName(_fromUtf8("checkBoxSocksListen")) + self.gridLayout_2.addWidget(self.checkBoxSocksListen, 3, 1, 1, 4) self.gridLayout_4.addWidget(self.groupBox_2, 1, 0, 1, 1) spacerItem2 = QtGui.QSpacerItem(20, 70, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) self.gridLayout_4.addItem(spacerItem2, 2, 0, 1, 1) @@ -235,38 +247,40 @@ class Ui_settingsDialog(object): settingsDialog.setTabOrder(self.lineEditSocksPort, self.checkBoxAuthentication) settingsDialog.setTabOrder(self.checkBoxAuthentication, self.lineEditSocksUsername) settingsDialog.setTabOrder(self.lineEditSocksUsername, self.lineEditSocksPassword) - settingsDialog.setTabOrder(self.lineEditSocksPassword, self.buttonBox) + settingsDialog.setTabOrder(self.lineEditSocksPassword, self.checkBoxSocksListen) + settingsDialog.setTabOrder(self.checkBoxSocksListen, self.buttonBox) def retranslateUi(self, settingsDialog): - settingsDialog.setWindowTitle(QtGui.QApplication.translate("settingsDialog", "Settings", None, QtGui.QApplication.UnicodeUTF8)) - self.checkBoxStartOnLogon.setText(QtGui.QApplication.translate("settingsDialog", "Start Bitmessage on user login", None, QtGui.QApplication.UnicodeUTF8)) - self.checkBoxStartInTray.setText(QtGui.QApplication.translate("settingsDialog", "Start Bitmessage in the tray (don\'t show main window)", None, QtGui.QApplication.UnicodeUTF8)) - self.checkBoxMinimizeToTray.setText(QtGui.QApplication.translate("settingsDialog", "Minimize to tray", None, QtGui.QApplication.UnicodeUTF8)) - self.checkBoxShowTrayNotifications.setText(QtGui.QApplication.translate("settingsDialog", "Show notification when message received", None, QtGui.QApplication.UnicodeUTF8)) - self.checkBoxPortableMode.setText(QtGui.QApplication.translate("settingsDialog", "Run in Portable Mode", None, QtGui.QApplication.UnicodeUTF8)) - self.label_7.setText(QtGui.QApplication.translate("settingsDialog", "In Portable Mode, messages and config files are stored in the same directory as the program rather than the normal application-data folder. This makes it convenient to run Bitmessage from a USB thumb drive.", None, QtGui.QApplication.UnicodeUTF8)) - self.tabWidgetSettings.setTabText(self.tabWidgetSettings.indexOf(self.tabUserInterface), QtGui.QApplication.translate("settingsDialog", "User Interface", None, QtGui.QApplication.UnicodeUTF8)) - self.groupBox.setTitle(QtGui.QApplication.translate("settingsDialog", "Listening port", None, QtGui.QApplication.UnicodeUTF8)) - self.label.setText(QtGui.QApplication.translate("settingsDialog", "Listen for connections on port:", None, QtGui.QApplication.UnicodeUTF8)) - self.groupBox_2.setTitle(QtGui.QApplication.translate("settingsDialog", "Proxy server / Tor", None, QtGui.QApplication.UnicodeUTF8)) - self.label_2.setText(QtGui.QApplication.translate("settingsDialog", "Type:", None, QtGui.QApplication.UnicodeUTF8)) - self.comboBoxProxyType.setItemText(0, QtGui.QApplication.translate("settingsDialog", "none", None, QtGui.QApplication.UnicodeUTF8)) - self.comboBoxProxyType.setItemText(1, QtGui.QApplication.translate("settingsDialog", "SOCKS4a", None, QtGui.QApplication.UnicodeUTF8)) - self.comboBoxProxyType.setItemText(2, QtGui.QApplication.translate("settingsDialog", "SOCKS5", None, QtGui.QApplication.UnicodeUTF8)) - self.label_3.setText(QtGui.QApplication.translate("settingsDialog", "Server hostname:", None, QtGui.QApplication.UnicodeUTF8)) - self.label_4.setText(QtGui.QApplication.translate("settingsDialog", "Port:", None, QtGui.QApplication.UnicodeUTF8)) - self.checkBoxAuthentication.setText(QtGui.QApplication.translate("settingsDialog", "Authentication", None, QtGui.QApplication.UnicodeUTF8)) - self.label_5.setText(QtGui.QApplication.translate("settingsDialog", "Username:", None, QtGui.QApplication.UnicodeUTF8)) - self.label_6.setText(QtGui.QApplication.translate("settingsDialog", "Pass:", None, QtGui.QApplication.UnicodeUTF8)) - self.tabWidgetSettings.setTabText(self.tabWidgetSettings.indexOf(self.tabNetworkSettings), QtGui.QApplication.translate("settingsDialog", "Network Settings", None, QtGui.QApplication.UnicodeUTF8)) - self.label_8.setText(QtGui.QApplication.translate("settingsDialog", "When someone sends you a message, their computer must first complete some work. The difficulty of this work, by default, is 1. You may raise this default for new addresses you create by changing the values here. Any new addresses you create will require senders to meet the higher difficulty. There is one exception: if you add a friend or acquaintance to your address book, Bitmessage will automatically notify them when you next send a message that they need only complete the minimum amount of work: difficulty 1. ", None, QtGui.QApplication.UnicodeUTF8)) - self.label_9.setText(QtGui.QApplication.translate("settingsDialog", "Total difficulty:", None, QtGui.QApplication.UnicodeUTF8)) - self.label_11.setText(QtGui.QApplication.translate("settingsDialog", "Small message difficulty:", None, QtGui.QApplication.UnicodeUTF8)) - self.label_12.setText(QtGui.QApplication.translate("settingsDialog", "The \'Small message difficulty\' mostly only affects the difficulty of sending small messages. Doubling this value makes it almost twice as difficult to send a small message but doesn\'t really affect large messages.", None, QtGui.QApplication.UnicodeUTF8)) - self.label_10.setText(QtGui.QApplication.translate("settingsDialog", "The \'Total difficulty\' affects the absolute amount of work the sender must complete. Doubling this value doubles the amount of work.", None, QtGui.QApplication.UnicodeUTF8)) - self.tabWidgetSettings.setTabText(self.tabWidgetSettings.indexOf(self.tab), QtGui.QApplication.translate("settingsDialog", "Demanded difficulty", None, QtGui.QApplication.UnicodeUTF8)) - self.label_15.setText(QtGui.QApplication.translate("settingsDialog", "Here you may set the maximum amount of work you are willing to do to send a message to another person. Setting these values to 0 means that any value is acceptable.", None, QtGui.QApplication.UnicodeUTF8)) - self.label_13.setText(QtGui.QApplication.translate("settingsDialog", "Maximum acceptable total difficulty:", None, QtGui.QApplication.UnicodeUTF8)) - self.label_14.setText(QtGui.QApplication.translate("settingsDialog", "Maximum acceptable small message difficulty:", None, QtGui.QApplication.UnicodeUTF8)) - self.tabWidgetSettings.setTabText(self.tabWidgetSettings.indexOf(self.tab_2), QtGui.QApplication.translate("settingsDialog", "Max acceptable difficulty", None, QtGui.QApplication.UnicodeUTF8)) + settingsDialog.setWindowTitle(_translate("settingsDialog", "Settings", None)) + self.checkBoxStartOnLogon.setText(_translate("settingsDialog", "Start Bitmessage on user login", None)) + self.checkBoxStartInTray.setText(_translate("settingsDialog", "Start Bitmessage in the tray (don\'t show main window)", None)) + self.checkBoxMinimizeToTray.setText(_translate("settingsDialog", "Minimize to tray", None)) + self.checkBoxShowTrayNotifications.setText(_translate("settingsDialog", "Show notification when message received", None)) + self.checkBoxPortableMode.setText(_translate("settingsDialog", "Run in Portable Mode", None)) + self.label_7.setText(_translate("settingsDialog", "In Portable Mode, messages and config files are stored in the same directory as the program rather than the normal application-data folder. This makes it convenient to run Bitmessage from a USB thumb drive.", None)) + self.tabWidgetSettings.setTabText(self.tabWidgetSettings.indexOf(self.tabUserInterface), _translate("settingsDialog", "User Interface", None)) + self.groupBox.setTitle(_translate("settingsDialog", "Listening port", None)) + self.label.setText(_translate("settingsDialog", "Listen for connections on port:", None)) + self.groupBox_2.setTitle(_translate("settingsDialog", "Proxy server / Tor", None)) + self.label_2.setText(_translate("settingsDialog", "Type:", None)) + self.comboBoxProxyType.setItemText(0, _translate("settingsDialog", "none", None)) + self.comboBoxProxyType.setItemText(1, _translate("settingsDialog", "SOCKS4a", None)) + self.comboBoxProxyType.setItemText(2, _translate("settingsDialog", "SOCKS5", None)) + self.label_3.setText(_translate("settingsDialog", "Server hostname:", None)) + self.label_4.setText(_translate("settingsDialog", "Port:", None)) + self.checkBoxAuthentication.setText(_translate("settingsDialog", "Authentication", None)) + self.label_5.setText(_translate("settingsDialog", "Username:", None)) + self.label_6.setText(_translate("settingsDialog", "Pass:", None)) + self.checkBoxSocksListen.setText(_translate("settingsDialog", "Listen for incoming connections when using proxy", None)) + self.tabWidgetSettings.setTabText(self.tabWidgetSettings.indexOf(self.tabNetworkSettings), _translate("settingsDialog", "Network Settings", None)) + self.label_8.setText(_translate("settingsDialog", "When someone sends you a message, their computer must first complete some work. The difficulty of this work, by default, is 1. You may raise this default for new addresses you create by changing the values here. Any new addresses you create will require senders to meet the higher difficulty. There is one exception: if you add a friend or acquaintance to your address book, Bitmessage will automatically notify them when you next send a message that they need only complete the minimum amount of work: difficulty 1. ", None)) + self.label_9.setText(_translate("settingsDialog", "Total difficulty:", None)) + self.label_11.setText(_translate("settingsDialog", "Small message difficulty:", None)) + self.label_12.setText(_translate("settingsDialog", "The \'Small message difficulty\' mostly only affects the difficulty of sending small messages. Doubling this value makes it almost twice as difficult to send a small message but doesn\'t really affect large messages.", None)) + self.label_10.setText(_translate("settingsDialog", "The \'Total difficulty\' affects the absolute amount of work the sender must complete. Doubling this value doubles the amount of work.", None)) + self.tabWidgetSettings.setTabText(self.tabWidgetSettings.indexOf(self.tab), _translate("settingsDialog", "Demanded difficulty", None)) + self.label_15.setText(_translate("settingsDialog", "Here you may set the maximum amount of work you are willing to do to send a message to another person. Setting these values to 0 means that any value is acceptable.", None)) + self.label_13.setText(_translate("settingsDialog", "Maximum acceptable total difficulty:", None)) + self.label_14.setText(_translate("settingsDialog", "Maximum acceptable small message difficulty:", None)) + self.tabWidgetSettings.setTabText(self.tabWidgetSettings.indexOf(self.tab_2), _translate("settingsDialog", "Max acceptable difficulty", None)) diff --git a/src/bitmessageqt/settings.ui b/src/bitmessageqt/settings.ui index a1bb7c88..9414e1a4 100644 --- a/src/bitmessageqt/settings.ui +++ b/src/bitmessageqt/settings.ui @@ -247,6 +247,13 @@ + + + + Listen for incoming connections when using proxy + + +
@@ -508,6 +515,7 @@ checkBoxAuthentication lineEditSocksUsername lineEditSocksPassword + checkBoxSocksListen buttonBox diff --git a/src/class_singleListener.py b/src/class_singleListener.py index 58bddf6f..ec6afc39 100644 --- a/src/class_singleListener.py +++ b/src/class_singleListener.py @@ -24,7 +24,7 @@ class singleListener(threading.Thread): # We don't want to accept incoming connections if the user is using a # SOCKS proxy. If they eventually select proxy 'none' then this will # start listening for connections. - while shared.config.get('bitmessagesettings', 'socksproxytype')[0:5] == 'SOCKS': + while shared.config.get('bitmessagesettings', 'socksproxytype')[0:5] == 'SOCKS' and not shared.config.getboolean('bitmessagesettings', 'sockslisten'): time.sleep(300) with shared.printLock: @@ -43,7 +43,7 @@ class singleListener(threading.Thread): # We don't want to accept incoming connections if the user is using # a SOCKS proxy. If the user eventually select proxy 'none' then # this will start listening for connections. - while shared.config.get('bitmessagesettings', 'socksproxytype')[0:5] == 'SOCKS': + while shared.config.get('bitmessagesettings', 'socksproxytype')[0:5] == 'SOCKS' and not shared.config.getboolean('bitmessagesettings', 'sockslisten'): time.sleep(10) while len(shared.connectedHostsList) > 220: with shared.printLock: diff --git a/src/class_sqlThread.py b/src/class_sqlThread.py index 84014a8c..da5ace77 100644 --- a/src/class_sqlThread.py +++ b/src/class_sqlThread.py @@ -80,6 +80,7 @@ class sqlThread(threading.Thread): shared.config.set('bitmessagesettings', 'socksauthentication', 'false') shared.config.set('bitmessagesettings', 'socksusername', '') shared.config.set('bitmessagesettings', 'sockspassword', '') + shared.config.set('bitmessagesettings', 'sockslisten', 'false') shared.config.set('bitmessagesettings', 'keysencrypted', 'false') shared.config.set('bitmessagesettings', 'messagesencrypted', 'false') with open(shared.appdata + 'keys.dat', 'wb') as configfile: diff --git a/src/helper_startup.py b/src/helper_startup.py index e6590b0e..3cde6805 100644 --- a/src/helper_startup.py +++ b/src/helper_startup.py @@ -50,6 +50,8 @@ def loadConfig(): shared.config.set('bitmessagesettings', 'socksport', '9050') shared.config.set( 'bitmessagesettings', 'socksauthentication', 'false') + shared.config.set( + 'bitmessagesettings', 'sockslisten', 'false') shared.config.set('bitmessagesettings', 'socksusername', '') shared.config.set('bitmessagesettings', 'sockspassword', '') shared.config.set('bitmessagesettings', 'keysencrypted', 'false') From 27c0ac436c2c03207b33b0f7ee89583735816979 Mon Sep 17 00:00:00 2001 From: David Nichols Date: Fri, 12 Jul 2013 13:40:06 -0500 Subject: [PATCH 24/39] Updating code comments to reflect changes in listening for connections when using SOCKS. --- src/class_singleListener.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/class_singleListener.py b/src/class_singleListener.py index ec6afc39..d6b46643 100644 --- a/src/class_singleListener.py +++ b/src/class_singleListener.py @@ -21,9 +21,10 @@ class singleListener(threading.Thread): self.selfInitiatedConnections = selfInitiatedConnections def run(self): - # We don't want to accept incoming connections if the user is using a - # SOCKS proxy. If they eventually select proxy 'none' then this will - # start listening for connections. + # We typically don't want to accept incoming connections if the user is using a + # SOCKS proxy, unless they have configured otherwise. If they eventually select + # proxy 'none' or configure SOCKS listening then this will start listening for + # connections. while shared.config.get('bitmessagesettings', 'socksproxytype')[0:5] == 'SOCKS' and not shared.config.getboolean('bitmessagesettings', 'sockslisten'): time.sleep(300) @@ -40,9 +41,10 @@ class singleListener(threading.Thread): sock.listen(2) while True: - # We don't want to accept incoming connections if the user is using - # a SOCKS proxy. If the user eventually select proxy 'none' then - # this will start listening for connections. + # We typically don't want to accept incoming connections if the user is using a + # SOCKS proxy, unless they have configured otherwise. If they eventually select + # proxy 'none' or configure SOCKS listening then this will start listening for + # connections. while shared.config.get('bitmessagesettings', 'socksproxytype')[0:5] == 'SOCKS' and not shared.config.getboolean('bitmessagesettings', 'sockslisten'): time.sleep(10) while len(shared.connectedHostsList) > 220: From 922cce65585fa57862c04b3f57dd2d827792eee0 Mon Sep 17 00:00:00 2001 From: David Nichols Date: Fri, 12 Jul 2013 13:42:11 -0500 Subject: [PATCH 25/39] Initializing sockslisten config value to account for upgrades. Otherwise, settings panel will not load. --- src/helper_startup.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/helper_startup.py b/src/helper_startup.py index 3cde6805..aaf71709 100644 --- a/src/helper_startup.py +++ b/src/helper_startup.py @@ -78,3 +78,9 @@ def loadConfig(): os.makedirs(shared.appdata) with open(shared.appdata + 'keys.dat', 'wb') as configfile: shared.config.write(configfile) + + # Initialize settings that may be missing due to upgrades and could + # cause errors if missing. + if not shared.config.has_option('bitmessagesettings', 'sockslisten'): + shared.config.set('bitmessagesettings', 'sockslisten', 'false') + From f240f65d537e05479b6a9d04f601109f4e64a795 Mon Sep 17 00:00:00 2001 From: akh81 Date: Sat, 13 Jul 2013 01:19:59 -0500 Subject: [PATCH 26/39] added translations --- src/translations/bitmessage_ru_RU.qm | Bin 18186 -> 30541 bytes src/translations/bitmessage_ru_RU.ts | 320 +++++++++++++-------------- 2 files changed, 160 insertions(+), 160 deletions(-) diff --git a/src/translations/bitmessage_ru_RU.qm b/src/translations/bitmessage_ru_RU.qm index e878db88e37272e43abffc0181d99c25b5c2b4d1..9e7b7cb8d73d21fdf4949b7816a6c018381e7706 100644 GIT binary patch literal 30541 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 LoSz(Af6M;`{oXH| delta 1167 zcmXAneNa?o6vm(H-n+Y(d+)9bD9bJa1|||g2rIFyF0L4au_ML6mY@tDGYKRFX<)(< znv;OW%mw6QW0q>hgo(17`H^BOGfo7I4F-b~#f%MF z_yeZ-1mm`yFENfj^mL4`4Y^X-e|gpcuv!4|Kq5m-AZ`S>uYpx&Am;|KG91_yP5)_N zZ>|HhRF&-E5&_bex&C)# zbv&X1oyh9+BMxKdt8W8B30|+gMC|f0G9J0jWx!?|^7bAi?t|+_GGK5cU)>BiTsX9^ z2e9hVRT~PtcnH7fTLFDPX3d#osF>lsPXJ9c6SuMOZyg@FhqqE#yLfu ztHYUN1+jqXFQ)e^5^}I|0TbkQt(dOA4%qIhHdQtN$rY*zO)2G;$LjZxyp3m954;Ji zZecf{Bi~k;-R3+Etf^(o1*#tP8{1@{c7-wa>irFLevh5cZ+iAf{Knzm05dnNcez0)VwA)#sLtM0Kfe4fs>8 zUQPD3-GDAzliNo1B6!Ww*Mi|j>PgLKbw|i?yJoQU4zR-EW5j~yu9G@df2)02{SOtc z&~De!)`%I}pWQSFMx|Y7dY6RKw2KMD^zH&5IR6F>W|lXfdP;)-@jbs%0)eM^PY4Nb zaPwZ<67d!Oi6sIsAN4Dnv$%oKhsz%{$q~N`0!=b7!|!?{B@+0DU=Iieg3bueOd3UK zu#mk((c9XD;t#gc%2o+22M<#+<3ih&+jRec&@;J>k~0Y&K9N@SCtni;( zO63a;K=2u9{{)c_lBSABX(f%*(x0Cckpos2>+Gc{t92O*45x9 z%I8=%ly!VwpwlX%(a6X}rXHov9L^~GnrcQ~3biSh!!D^5W28$Z7sc;ZEJ>}5>`0!H q^Ib_wskM@oKegXhQqpo(D!W`eIK^7@R3m3rek6xiWy&e<`~MGvgg4{> diff --git a/src/translations/bitmessage_ru_RU.ts b/src/translations/bitmessage_ru_RU.ts index 23061133..7bb06bc1 100644 --- a/src/translations/bitmessage_ru_RU.ts +++ b/src/translations/bitmessage_ru_RU.ts @@ -6,82 +6,82 @@ One of your addresses, %1, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? - + Один из Ваших адресов, %1, является устаревшим адресом версии 1. Адреса версии 1 больше не поддерживаются. Хотите ли Вы удалить его сейчас? Reply - Ответить + Ответить Add sender to your Address Book - Добавить отправителя в адресную книгу + Добавить отправителя в адресную книгу Move to Trash - Поместить в корзину + Поместить в корзину View HTML code as formatted text - + Просмотреть HTML код как отформатированный текст Save message as... - Сохранить сообщение как ... + Сохранить сообщение как ... New - Новый адрес + Новый адрес Enable - + Разрешить Disable - + Запретить Copy address to clipboard - Скопировать адрес в буфер обмена + Скопировать адрес в буфер обмена Special address behavior... - + Особое поведение адресов... Send message to this address - + Отправить сообщение на этот адрес Subscribe to this address - + Подписаться на рассылку с этого адреса Add New Address - Добавить новый адрес + Добавить новый адрес Delete - + Удалить Copy destination address to clipboard - Скопировать адрес отправки в буфер обмена + Скопировать адрес отправки в буфер обмена @@ -91,7 +91,7 @@ Add new entry - Добавить новую запись + Добавить новую запись @@ -111,7 +111,7 @@ Message sent. Waiting on acknowledgement. Sent at %1 - Сообщение отправлено. Ожидаем подтверждения. Отправлено в %1 + Сообщение отправлено. Ожидаем подтверждения. Отправлено в %1 @@ -121,7 +121,7 @@ Acknowledgement of the message received %1 - Сообщение получено %1 + Сообщение получено %1 @@ -151,7 +151,7 @@ Unknown status: %1 %2 - Неизвестный статус: %1 %2 + Неизвестный статус: %1 %2 @@ -161,7 +161,7 @@ Not Connected - Не соединено + Не соединено @@ -171,22 +171,22 @@ Send - Отправка + Отправка Subscribe - Подписки + Подписки Address Book - Адресная книга + Адресная книга Quit - Выйти + Выйти @@ -230,12 +230,12 @@ It is important that you back up this file. Would you like to open the file now? bad passphrase - Неподходящая секретная фраза + Неподходящая секретная фраза You must type your passphrase. If you don't have one then this is not the form for you. - Вы должны ввести секретную фразу. Если Вы не хотите это делать, то Вы выбрали неправильную опцию. + Вы должны ввести секретную фразу. Если Вы не хотите это делать, то Вы выбрали неправильную опцию. @@ -255,17 +255,17 @@ It is important that you back up this file. Would you like to open the file now? Total Connections: %1 - Всего соединений: %1 + Всего соединений: %1 Connection lost - Соединение потеряно + Соединение потеряно Connected - Соединено + Соединено @@ -335,7 +335,7 @@ It is important that you back up this file. Would you like to open the file now? Stream number - Номер потока + Номер потока @@ -360,7 +360,7 @@ It is important that you back up this file. Would you like to open the file now? Right click one or more entries in your address book and select 'Send message to this address'. - + Нажмите правую кнопку мышки на каком-либо адресе и выберите "Отправить сообщение на этот адрес". @@ -375,7 +375,7 @@ It is important that you back up this file. Would you like to open the file now? From - От + От @@ -430,12 +430,12 @@ It is important that you back up this file. Would you like to open the file now? Choose a passphrase - Придумайте секретную фразу + Придумайте секретную фразу You really do need a passphrase. - Вы действительно должны ввести секретную фразу. + Вы действительно должны ввести секретную фразу. @@ -470,7 +470,7 @@ It is important that you back up this file. Would you like to open the file now? Moved items to trash. There is no user interface to view your trash, but it is still on disk if you are desperate to get it back. - Удалено в корзину. Чтобы попасть в корзину, Вам нужно будет найти файл корзины на диске. + Удалено в корзину. Чтобы попасть в корзину, Вам нужно будет найти файл корзины на диске. @@ -495,7 +495,7 @@ It is important that you back up this file. Would you like to open the file now? The address should start with ''BM-'' - + Адрес должен начинаться с "BM-" @@ -525,57 +525,57 @@ It is important that you back up this file. Would you like to open the file now? You are using TCP port %1. (This can be changed in the settings). - Вы используете TCP порт %1 (Его можно поменять в настройках). + Вы используете TCP порт %1 (Его можно поменять в настройках). Bitmessage - Bitmessage + Bitmessage To - Кому + Кому From - От кого + От кого Subject - Тема + Тема Received - Получено + Получено Inbox - Входящие + Входящие Load from Address book - Взять из адресной книги + Взять из адресной книги Message: - Сообщение: + Сообщение: Subject: - Тема: + Тема: Send to one or more specific people - Отправить одному или нескольким указанным получателям + Отправить одному или нескольким указанным получателям @@ -589,72 +589,72 @@ p, li { white-space: pre-wrap; } To: - Кому: + Кому: From: - От: + От: Broadcast to everyone who is subscribed to your address - Рассылка всем, кто подписался на Ваш адрес + Рассылка всем, кто подписался на Ваш адрес Be aware that broadcasts are only encrypted with your address. Anyone who knows your address can read them. - Пожалуйста, учитывайте, что рассылки шифруются лишь Вашим адресом. Любой человек, который знает Ваш адрес, сможет прочитать Вашу рассылку. + Пожалуйста, учитывайте, что рассылки шифруются лишь Вашим адресом. Любой человек, который знает Ваш адрес, сможет прочитать Вашу рассылку. Status - Статус + Статус Sent - Отправленные + Отправленные Label (not shown to anyone) - Название (не показывается никому) + Название (не показывается никому) Address - Адрес + Адрес Stream - Поток + Поток Your Identities - Ваши Адреса + Ваши Адреса Here you can subscribe to 'broadcast messages' that are sent by other users. Messages will appear in your Inbox. Addresses here override those on the Blacklist tab. - Здесь Вы можете подписаться на рассылки от других пользователей. Все рассылки будут появлять у Вас во Входящих. Вы будете следить за всеми адресами, указанными здесь, даже если они в черном списке. + Здесь Вы можете подписаться на рассылки от других пользователей. Все рассылки будут появлять у Вас во Входящих. Вы будете следить за всеми адресами, указанными здесь, даже если они в черном списке. Add new Subscription - Добавить новую подписку + Добавить новую подписку Label - Название + Название Subscriptions - Подписки + Подписки @@ -664,37 +664,37 @@ p, li { white-space: pre-wrap; } Name or Label - Название + Название Use a Blacklist (Allow all incoming messages except those on the Blacklist) - Использовать черный список (Разрешить все входящие сообщения, кроме указанных в черном списке) + Использовать черный список (Разрешить все входящие сообщения, кроме указанных в черном списке) Use a Whitelist (Block all incoming messages except those on the Whitelist) - Использовать белый список (блокировать все входящие сообщения, кроме указанных в белом списке) + Использовать белый список (блокировать все входящие сообщения, кроме указанных в белом списке) Blacklist - Черный список + Черный список Stream # - № потока + № потока Connections - Соединений + Соединений Total connections: 0 - Всего соединений: 0 + Всего соединений: 0 @@ -719,22 +719,22 @@ p, li { white-space: pre-wrap; } Network Status - Статус сети + Статус сети File - Файл + Файл Settings - Настройки + Настройки Help - Помощь + Помощь @@ -744,22 +744,22 @@ p, li { white-space: pre-wrap; } Manage keys - Управлять ключами + Управлять ключами About - О программе + О программе Regenerate deterministic addresses - Сгенерировать заново все адреса + Сгенерировать заново все адреса Delete all trashed messages - Стереть все сообщения из корзины + Стереть все сообщения из корзины @@ -767,98 +767,98 @@ p, li { white-space: pre-wrap; } Create new Address - + Создать новый адрес Here you may generate as many addresses as you like. Indeed, creating and abandoning addresses is encouraged. You may generate addresses by using either random numbers or by using a passphrase. If you use a passphrase, the address is called a "deterministic" address. The 'Random Number' option is selected by default but deterministic addresses have several pros and cons: - + Здесь Вы сможете сгенерировать столько адресов сколько хотите. На самом деле, создание и выкидывание адресов даже поощряется. Вы можете сгенерировать адреса используя либо генератор случайных чисел либо придумав секретную фразу. Если Вы используете секретную фразу, то адреса будут называться "детерминистическими". Генератор случайных чисел выбран по умолчанию, однако детерминистические адреса имеют следующие плюсы и минусы по сравнению с ними: <html><head/><body><p><span style=" font-weight:600;">Pros:<br/></span>You can recreate your addresses on any computer from memory. <br/>You need-not worry about backing up your keys.dat file as long as you can remember your passphrase. <br/><span style=" font-weight:600;">Cons:<br/></span>You must remember (or write down) your passphrase if you expect to be able to recreate your keys if they are lost. <br/>You must remember the address version number and the stream number along with your passphrase. <br/>If you choose a weak passphrase and someone on the Internet can brute-force it, they can read your messages and send messages as you.</p></body></html> - + <html><head/><body><p><span style=" font-weight:600;">Плюсы:<br/></span>Вы сможете восстановить адрес по памяти на любом компьютере<br/>Вам не нужно беспокоиться о сохранении файла keys.dat, если Вы запомнили секретную фразу<br/><span style=" font-weight:600;">Минусы:<br/></span>Вы должны запомнить (или записать) секретную фразу, если Вы хотите когда-либо восстановить Ваш адрес на другом компьютере <br/>Вы должны также запомнить версию адреса и номер потока вместе с секретной фразой<br/>Если Вы выберите слишком короткую секретную фразу, кто-нибудь в интернете сможет подобрать ключ и, как следствие, читать и отправлять от Вашего имени сообщения.</p></body></html> Use a random number generator to make an address - Использовать генератор случайных чисел для создания адреса + Использовать генератор случайных чисел для создания адреса Use a passphrase to make addresses - Использовать секретную фразу для создания адресов + Использовать секретную фразу для создания адресов Spend several minutes of extra computing time to make the address(es) 1 or 2 characters shorter - Потратить несколько лишних минут, чтобы сделать адрес(а) короче на 1 или 2 символа + Потратить несколько лишних минут, чтобы сделать адрес(а) короче на 1 или 2 символа Make deterministic addresses - + Создать детерминистический адрес Address version number: 3 - Версия адреса: 3 + Версия адреса: 3 In addition to your passphrase, you must remember these numbers: - В дополнение к секретной фразе, Вам необходимо запомнить эти числа: + В дополнение к секретной фразе, Вам необходимо запомнить эти числа: Passphrase - Секретная фраза + Придумайте секретную фразу Number of addresses to make based on your passphrase: - Кол-во адресов, которые Вы хотите получить из секретной фразы: + Кол-во адресов, которые Вы хотите получить из секретной фразы: Stream number: 1 - Номер потока: 1 + Номер потока: 1 Retype passphrase - Повторите секретную фразу + Повторите секретную фразу Randomly generate address - Сгенерировать случайный адрес + Сгенерировать случайный адрес Label (not shown to anyone except you) - Название (не показывается никому кроме Вас) + Название (не показывается никому кроме Вас) Use the most available stream - Использовать наиболее доступный поток + Использовать наиболее доступный поток (best if this is the first of many addresses you will create) - + (выберите этот вариант, если это лишь первый из многих адресов, которые Вы планируете создать) Use the same stream as an existing address - + Использовать тот же поток, что и указанный существующий адрес (saves you some bandwidth and processing power) - + (немного сэкономит Вам пропускную способность сети и вычислительную мощь) @@ -909,17 +909,17 @@ The 'Random Number' option is selected by default but deterministic ad Add new entry - Добавить новую запись + Добавить новую запись Label - Название + Название Address - Адрес + Адрес @@ -927,27 +927,27 @@ The 'Random Number' option is selected by default but deterministic ad Special Address Behavior - + Особое поведение адреса Behave as a normal address - + Вести себя как обычный адрес Behave as a pseudo-mailing-list address - + Вести себя как адрес псевдо-рассылки Mail received to a pseudo-mailing-list address will be automatically broadcast to subscribers (and thus will be public). - + Почта, полученная на адрес псевдо-рассылки, будет автоматически разослана всем подписчикам (и поэтому будет доступна общей публике). Name of the pseudo-mailing-list: - + Имя псевдо-рассылки: @@ -955,32 +955,32 @@ The 'Random Number' option is selected by default but deterministic ad About - О программе + О программе PyBitmessage - PyBitmessage + PyBitmessage version ? - версия ? + версия ? Copyright © 2013 Jonathan Warren - Копирайт © 2013 Джонатан Уоррен + Копирайт © 2013 Джонатан Уоррен <html><head/><body><p>Distributed under the MIT/X11 software license; see <a href="http://www.opensource.org/licenses/mit-license.php"><span style=" text-decoration: underline; color:#0000ff;">http://www.opensource.org/licenses/mit-license.php</span></a></p></body></html> - <html><head/><body><p>Программа распространяется в соответствии с лицензией MIT/X11; см. <a href="http://www.opensource.org/licenses/mit-license.php"><span style=" text-decoration: underline; color:#0000ff;">http://www.opensource.org/licenses/mit-license.php</span></a></p></body></html> + <html><head/><body><p>Программа распространяется в соответствии с лицензией MIT/X11; см. <a href="http://www.opensource.org/licenses/mit-license.php"><span style=" text-decoration: underline; color:#0000ff;">http://www.opensource.org/licenses/mit-license.php</span></a></p></body></html> This is Beta software. - Это бета версия программы. + Это бета версия программы. @@ -988,17 +988,17 @@ The 'Random Number' option is selected by default but deterministic ad Help - Помощь + Помощь <a href="http://Bitmessage.org/wiki/PyBitmessage_Help">http://Bitmessage.org/wiki/PyBitmessage_Help</a> - <a href="http://Bitmessage.org/wiki/PyBitmessage_Help">http://Bitmessage.org/wiki/PyBitmessage_Help</a> + <a href="http://Bitmessage.org/wiki/PyBitmessage_Help">http://Bitmessage.org/wiki/PyBitmessage_Help</a> As Bitmessage is a collaborative project, help can be found online in the Bitmessage Wiki: - Битмесседж - это общественный проект. Вы можете найти подсказки и советы на Wiki-страничке Битмесседж: + Битмесседж - это общественный проект. Вы можете найти подсказки и советы на Wiki-страничке Битмесседж: @@ -1006,27 +1006,27 @@ The 'Random Number' option is selected by default but deterministic ad Icon Glossary - Описание значков + Описание значков You have no connections with other peers. - Нет соединения с другими участниками сети. + Нет соединения с другими участниками сети. You have made at least one connection to a peer using an outgoing connection but you have not yet received any incoming connections. Your firewall or home router probably isn't configured to forward incoming TCP connections to your computer. Bitmessage will work just fine but it would help the Bitmessage network if you allowed for incoming connections and will help you be a better-connected node. - На текущий момент Вы установили по-крайней мере одно исходящее соединение, но пока ни одного входящего. Ваш файрвол или маршрутизатор скорее всего не настроен на переброс входящих TCP соединений к Вашему компьютеру. Битмесседж будет прекрасно работать и без этого, но Вы могли бы помочь сети если бы разрешили и входящие соединения тоже. Это помогло бы Вам стать более важным узлом сети. + На текущий момент Вы установили по-крайней мере одно исходящее соединение, но пока ни одного входящего. Ваш файрвол или маршрутизатор скорее всего не настроен на переброс входящих TCP соединений к Вашему компьютеру. Битмесседж будет прекрасно работать и без этого, но Вы могли бы помочь сети если бы разрешили и входящие соединения тоже. Это помогло бы Вам стать более важным узлом сети. You are using TCP port ?. (This can be changed in the settings). - Вы используете TCP порт ?. (Его можно поменять в настройках). + Вы используете TCP порт ?. (Его можно поменять в настройках). You do have connections with other peers and your firewall is correctly configured. - Вы установили соединение с другими участниками сети и ваш файрвол настроен правильно. + Вы установили соединение с другими участниками сети и ваш файрвол настроен правильно. @@ -1034,57 +1034,57 @@ The 'Random Number' option is selected by default but deterministic ad Regenerate Existing Addresses - Сгенерировать заново существующие адреса + Сгенерировать заново существующие адреса Regenerate existing addresses - Сгенерировать заново существующие адреса + Сгенерировать заново существующие адреса Passphrase - Секретная фраза + Секретная фраза Number of addresses to make based on your passphrase: - + Кол-во адресов, которые Вы хотите получить из Вашей секретной фразы: Address version Number: - Версия адреса: + Версия адреса: 3 - 3 + 3 Stream number: - Номер потока: + Номер потока: 1 - 1 + 1 Spend several minutes of extra computing time to make the address(es) 1 or 2 characters shorter - Потратить несколько лишних минут, чтобы сделать адрес(а) короче на 1 или 2 символа + Потратить несколько лишних минут, чтобы сделать адрес(а) короче на 1 или 2 символа You must check (or not check) this box just like you did (or didn't) when you made your addresses the first time. - Вы должны кликнуть эту галочку (или не кликать) точно также как Вы сделали в самый первый раз, когда создавали Ваши адреса. + Вы должны кликнуть эту галочку (или не кликать) точно также как Вы сделали в самый первый раз, когда создавали Ваши адреса. If you have previously made deterministic addresses but lost them due to an accident (like hard drive failure), you can regenerate them here. If you used the random number generator to make your addresses then this form will be of no use to you. - + Если Вы ранее делали детерминистические адреса, но случайно потеряли их, Вы можете их восстановить здесь. Если же Вы использовали генератор случайных чисел, чтобы создать Ваши адреса, то Вы не сможете их здесь восстановить. @@ -1092,157 +1092,157 @@ The 'Random Number' option is selected by default but deterministic ad Settings - Настройки + Настройки Start Bitmessage on user login - Запускать Битмесседж при входе в систему + Запускать Битмесседж при входе в систему Start Bitmessage in the tray (don't show main window) - Запускать Битмесседж в свернутом виде (не показывать главное окно) + Запускать Битмесседж в свернутом виде (не показывать главное окно) Minimize to tray - Сворачивать в трей + Сворачивать в трей Show notification when message received - Показывать уведомления при получении новых сообщений + Показывать уведомления при получении новых сообщений Run in Portable Mode - Запустить в переносном режиме + Запустить в переносном режиме In Portable Mode, messages and config files are stored in the same directory as the program rather than the normal application-data folder. This makes it convenient to run Bitmessage from a USB thumb drive. - + В переносном режиме, все сообщения и конфигурационные файлы сохраняются в той же самой папке что и сама программа. Это делает более удобным использование БитМесседж с USB-флэшки. User Interface - Пользовательские + Пользовательские Listening port - Порт прослушивания + Порт прослушивания Listen for connections on port: - Прослушивать соединения на порту: + Прослушивать соединения на порту: Proxy server / Tor - Прокси сервер / Тор + Прокси сервер / Тор Type: - Тип: + Тип: none - отсутствует + отсутствует SOCKS4a - SOCKS4a + SOCKS4a SOCKS5 - SOCKS5 + SOCKS5 Server hostname: - Адрес сервера: + Адрес сервера: Port: - Порт: + Порт: Authentication - Авторизация + Авторизация Username: - Имя пользователя: + Имя пользователя: Pass: - Прль: + Прль: Network Settings - Сетевые настройки + Сетевые настройки When someone sends you a message, their computer must first complete some work. The difficulty of this work, by default, is 1. You may raise this default for new addresses you create by changing the values here. Any new addresses you create will require senders to meet the higher difficulty. There is one exception: if you add a friend or acquaintance to your address book, Bitmessage will automatically notify them when you next send a message that they need only complete the minimum amount of work: difficulty 1. - + Когда кто-либо отправляет Вам сообщение, его компьютер должен сперва решить определенную вычислительную задачу. Сложность этой задачи по умолчанию равна 1. Вы можете повысить эту сложность для новых адресов, которые Вы создадите, здесь. Таким образом, любые новые адреса, которые Вы создадите, могут требовать от отправителей сложность большую чем 1. Однако, есть одно исключение: если Вы специально добавите Вашего собеседника в адресную книгу, то БитМесседж автоматически уведомит его о том, что для него минимальная сложность будет составлять всегда всего лишь 1. Total difficulty: - Общая сложность: + Общая сложность: Small message difficulty: - Сложность для маленьких сообщений: + Сложность для маленьких сообщений: The 'Small message difficulty' mostly only affects the difficulty of sending small messages. Doubling this value makes it almost twice as difficult to send a small message but doesn't really affect large messages. - + "Сложность для маленьких сообщений" влияет исключительно на небольшие сообщения. Увеличив это число в два раза, вы сделаете отправку маленьких сообщений в два раза сложнее, в то время как сложность отправки больших сообщений не изменится. The 'Total difficulty' affects the absolute amount of work the sender must complete. Doubling this value doubles the amount of work. - + "Общая сложность" влияет на абсолютное количество вычислений, которые отправитель должен провести, чтобы отправить сообщение. Увеличив это число в два раза, вы увеличите в два раза объем требуемых вычислений. Demanded difficulty - Требуемая сложность + Требуемая сложность Here you may set the maximum amount of work you are willing to do to send a message to another person. Setting these values to 0 means that any value is acceptable. - + Здесь Вы можете установить максимальную вычислительную работу, которую Вы согласны проделать, чтобы отправить сообщение другому пользователю. Ноль означает, чтобы любое значение допустимо. Maximum acceptable total difficulty: - Макс допустимая общая сложность: + Макс допустимая общая сложность: Maximum acceptable small message difficulty: - Макс допустимая сложность для маленький сообщений: + Макс допустимая сложность для маленький сообщений: Max acceptable difficulty - Макс допустимая сложность + Макс допустимая сложность From d93d92336438bc165839c4089cfaa80c519db730 Mon Sep 17 00:00:00 2001 From: Jonathan Warren Date: Sat, 13 Jul 2013 20:35:06 -0400 Subject: [PATCH 27/39] Added some default text to the search textbox, also fixed bitmessage_icons.qrc after file move --- src/bitmessagemain.py | 2 +- src/bitmessageqt/bitmessage_icons.qrc | 32 +++++++++++++-------------- src/bitmessageqt/bitmessageui.py | 22 ++++++------------ src/bitmessageqt/bitmessageui.ui | 29 ++++++++++++------------ 4 files changed, 38 insertions(+), 47 deletions(-) diff --git a/src/bitmessagemain.py b/src/bitmessagemain.py index e93fbd46..4ffc9f5b 100644 --- a/src/bitmessagemain.py +++ b/src/bitmessagemain.py @@ -14,7 +14,7 @@ try: from gevent import monkey monkey.patch_all() except ImportError as ex: - print "cannot find gevent" + print "Not using the gevent module as it was not found. No need to worry." import signal # Used to capture a Ctrl-C keypress so that Bitmessage can shutdown gracefully. # The next 3 are used for the API diff --git a/src/bitmessageqt/bitmessage_icons.qrc b/src/bitmessageqt/bitmessage_icons.qrc index a186b01b..bdd3fd07 100644 --- a/src/bitmessageqt/bitmessage_icons.qrc +++ b/src/bitmessageqt/bitmessage_icons.qrc @@ -1,20 +1,20 @@ - images/can-icon-24px-yellow.png - images/can-icon-24px-red.png - images/can-icon-24px-green.png - images/can-icon-24px.png - images/can-icon-16px.png - images/greenicon.png - images/redicon.png - images/yellowicon.png - images/addressbook.png - images/blacklist.png - images/identities.png - images/networkstatus.png - images/sent.png - images/subscriptions.png - images/send.png - images/inbox.png + ../images/can-icon-24px-yellow.png + ../images/can-icon-24px-red.png + ../images/can-icon-24px-green.png + ../images/can-icon-24px.png + ../images/can-icon-16px.png + ../images/greenicon.png + ../images/redicon.png + ../images/yellowicon.png + ../images/addressbook.png + ../images/blacklist.png + ../images/identities.png + ../images/networkstatus.png + ../images/sent.png + ../images/subscriptions.png + ../images/send.png + ../images/inbox.png diff --git a/src/bitmessageqt/bitmessageui.py b/src/bitmessageqt/bitmessageui.py index 62466503..1d04e5f1 100644 --- a/src/bitmessageqt/bitmessageui.py +++ b/src/bitmessageqt/bitmessageui.py @@ -2,8 +2,8 @@ # Form implementation generated from reading ui file 'bitmessageui.ui' # -# Created: Fri Jul 12 04:40:47 2013 -# by: PyQt4 UI code generator 4.10 +# Created: Sat Jul 13 20:23:44 2013 +# by: PyQt4 UI code generator 4.10.2 # # WARNING! All changes made in this file will be lost! @@ -422,7 +422,7 @@ class Ui_MainWindow(object): self.gridLayout.addWidget(self.tabWidget, 0, 0, 1, 1) MainWindow.setCentralWidget(self.centralwidget) self.menubar = QtGui.QMenuBar(MainWindow) - self.menubar.setGeometry(QtCore.QRect(0, 0, 795, 25)) + self.menubar.setGeometry(QtCore.QRect(0, 0, 795, 18)) self.menubar.setObjectName(_fromUtf8("menubar")) self.menuFile = QtGui.QMenu(self.menubar) self.menuFile.setObjectName(_fromUtf8("menuFile")) @@ -497,6 +497,7 @@ class Ui_MainWindow(object): def retranslateUi(self, MainWindow): MainWindow.setWindowTitle(_translate("MainWindow", "Bitmessage", None)) + self.inboxSearchLineEdit.setPlaceholderText(_translate("MainWindow", "Search", None)) self.inboxSearchOptionCB.setItemText(0, _translate("MainWindow", "All", None)) self.inboxSearchOptionCB.setItemText(1, _translate("MainWindow", "To", None)) self.inboxSearchOptionCB.setItemText(2, _translate("MainWindow", "From", None)) @@ -519,14 +520,15 @@ class Ui_MainWindow(object): self.textEditMessage.setHtml(_translate("MainWindow", "\n" "\n" -"


", None)) +"\n" +"


", None)) self.label.setText(_translate("MainWindow", "To:", None)) self.label_2.setText(_translate("MainWindow", "From:", None)) self.radioButtonBroadcast.setText(_translate("MainWindow", "Broadcast to everyone who is subscribed to your address", None)) self.pushButtonSend.setText(_translate("MainWindow", "Send", None)) self.labelSendBroadcastWarning.setText(_translate("MainWindow", "Be aware that broadcasts are only encrypted with your address. Anyone who knows your address can read them.", None)) self.tabWidget.setTabText(self.tabWidget.indexOf(self.send), _translate("MainWindow", "Send", None)) + self.sentSearchLineEdit.setPlaceholderText(_translate("MainWindow", "Search", None)) self.sentSearchOptionCB.setItemText(0, _translate("MainWindow", "All", None)) self.sentSearchOptionCB.setItemText(1, _translate("MainWindow", "To", None)) self.sentSearchOptionCB.setItemText(2, _translate("MainWindow", "From", None)) @@ -599,13 +601,3 @@ class Ui_MainWindow(object): self.actionDeleteAllTrashedMessages.setText(_translate("MainWindow", "Delete all trashed messages", None)) import bitmessage_icons_rc - -if __name__ == "__main__": - import sys - app = QtGui.QApplication(sys.argv) - MainWindow = QtGui.QMainWindow() - ui = Ui_MainWindow() - ui.setupUi(MainWindow) - MainWindow.show() - sys.exit(app.exec_()) - diff --git a/src/bitmessageqt/bitmessageui.ui b/src/bitmessageqt/bitmessageui.ui index 46ebd06a..6c18cbe0 100644 --- a/src/bitmessageqt/bitmessageui.ui +++ b/src/bitmessageqt/bitmessageui.ui @@ -22,16 +22,7 @@ - - 0 - - - 0 - - - 0 - - + 0 @@ -83,7 +74,11 @@ 0 - + + + Search + + @@ -262,8 +257,8 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans'; font-size:9pt; font-weight:400; font-style:normal;"> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2';"><br /></p></body></html> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html>
@@ -364,7 +359,11 @@ p, li { white-space: pre-wrap; } 0 - + + + Search + + @@ -1012,7 +1011,7 @@ p, li { white-space: pre-wrap; } 0 0 795 - 25 + 18 From d04b8747c7ea3a9980a9c05ca0296d47a2d6059f Mon Sep 17 00:00:00 2001 From: fuzzgun Date: Sun, 14 Jul 2013 12:31:58 +0100 Subject: [PATCH 28/39] Use python2 within /usr/bin/pybitmessage #296 --- Makefile | 2 +- debian/control | 2 +- generate.sh | 2 +- puppypackage/pybitmessage-0.3.4.pet.specs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index e7577494..b9a85ff7 100644 --- a/Makefile +++ b/Makefile @@ -28,7 +28,7 @@ install: cp -rf src/* ${DESTDIR}/usr/share/${APP} echo '#!/bin/sh' > ${DESTDIR}/usr/bin/${APP} echo 'cd /usr/share/pybitmessage' >> ${DESTDIR}/usr/bin/${APP} - echo 'LD_LIBRARY_PATH="/opt/openssl-compat-bitcoin/lib/" exec python bitmessagemain.py' >> ${DESTDIR}/usr/bin/${APP} + echo 'LD_LIBRARY_PATH="/opt/openssl-compat-bitcoin/lib/" exec python2 bitmessagemain.py' >> ${DESTDIR}/usr/bin/${APP} chmod +x ${DESTDIR}/usr/bin/${APP} uninstall: rm -f /usr/share/man/man1/${APP}.1.gz diff --git a/debian/control b/debian/control index e2d860d0..01bd7d8c 100644 --- a/debian/control +++ b/debian/control @@ -4,7 +4,7 @@ Maintainer: Bob Mottram (4096 bits) Build-Depends: debhelper (>= 9.0.0) Standards-Version: 3.9.4 Homepage: https://github.com/Bitmessage/PyBitmessage -Vcs-Git: https://github.com/fuzzgun/libgpr.git +Vcs-Git: https://github.com/fuzzgun/fin.git Package: pybitmessage Section: mail diff --git a/generate.sh b/generate.sh index 44aca136..8909cf2f 100755 --- a/generate.sh +++ b/generate.sh @@ -4,4 +4,4 @@ rm -f Makefile rpmpackage/*.spec -packagemonkey -n "PyBitmessage" --version "0.3.4" --dir "." -l "mit" -e "Bob Mottram (4096 bits) " --brief "Send encrypted messages" --desc "Bitmessage is a P2P communications protocol used to send encrypted messages to another person or to many subscribers. It is decentralized and trustless, meaning that you need-not inherently trust any entities like root certificate authorities. It uses strong authentication which means that the sender of a message cannot be spoofed, and it aims to hide \"non-content\" data, like the sender and receiver of messages, from passive eavesdroppers like those running warrantless wiretapping programs." --homepage "https://github.com/Bitmessage/PyBitmessage" --section "mail" --categories "Office/Email" --dependsdeb "python (>= 2.7.0), openssl, python-qt4, libqt4-dev (>= 4.8.0), python-qt4-dev, sqlite3, libsqlite3-dev" --dependsrpm "python, PyQt4, openssl-compat-bitcoin-libs" --mainscript "bitmessagemain.py" --librarypath "/opt/openssl-compat-bitcoin/lib/" --suggestsdeb "libmessaging-menu-dev" --dependspuppy "openssl, python-qt4, sqlite3, sqlite3-dev, python-openssl, python-sip" --dependsarch "python2, qt4, python2-pyqt4, sqlite, openssl" --suggestsarch "python2-gevent" +packagemonkey -n "PyBitmessage" --version "0.3.4" --dir "." -l "mit" -e "Bob Mottram (4096 bits) " --brief "Send encrypted messages" --desc "Bitmessage is a P2P communications protocol used to send encrypted messages to another person or to many subscribers. It is decentralized and trustless, meaning that you need-not inherently trust any entities like root certificate authorities. It uses strong authentication which means that the sender of a message cannot be spoofed, and it aims to hide \"non-content\" data, like the sender and receiver of messages, from passive eavesdroppers like those running warrantless wiretapping programs." --homepage "https://github.com/Bitmessage/PyBitmessage" --section "mail" --categories "Office/Email" --dependsdeb "python (>= 2.7.0), openssl, python-qt4, libqt4-dev (>= 4.8.0), python-qt4-dev, sqlite3, libsqlite3-dev" --dependsrpm "python, PyQt4, openssl-compat-bitcoin-libs" --mainscript "bitmessagemain.py" --librarypath "/opt/openssl-compat-bitcoin/lib/" --suggestsdeb "libmessaging-menu-dev" --dependspuppy "openssl, python-qt4, sqlite3, sqlite3-dev, python-openssl, python-sip" --dependsarch "python2, qt4, python2-pyqt4, sqlite, openssl" --suggestsarch "python2-gevent" --pythonversion 2 diff --git a/puppypackage/pybitmessage-0.3.4.pet.specs b/puppypackage/pybitmessage-0.3.4.pet.specs index 2d576f60..e346d0c9 100644 --- a/puppypackage/pybitmessage-0.3.4.pet.specs +++ b/puppypackage/pybitmessage-0.3.4.pet.specs @@ -1 +1 @@ -pybitmessage-0.3.4-1|PyBitmessage|0.3.4|1|Internet;mailnews;|4.5M||pybitmessage-0.3.4-1.pet|+openssl,+python-qt4,+sqlite3,+sqlite3-dev,+python-openssl,+python-sip|Send encrypted messages|ubuntu|precise|5| +pybitmessage-0.3.4-1|PyBitmessage|0.3.4|1|Internet;mailnews;|5.1M||pybitmessage-0.3.4-1.pet|+openssl,+python-qt4,+sqlite3,+sqlite3-dev,+python-openssl,+python-sip|Send encrypted messages|ubuntu|precise|5| From 1bf39dbfd06102268f532ba54007251f7535b80a Mon Sep 17 00:00:00 2001 From: Jonathan Warren Date: Sun, 14 Jul 2013 16:12:59 -0400 Subject: [PATCH 29/39] moved debug.log file to the config directory --- src/bitmessagemain.py | 5 +---- src/debug.py | 10 ++++++---- src/shared.py | 8 +++++--- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/bitmessagemain.py b/src/bitmessagemain.py index 4ffc9f5b..cfbfdd6c 100644 --- a/src/bitmessagemain.py +++ b/src/bitmessagemain.py @@ -32,7 +32,6 @@ from class_singleListener import * from class_addressGenerator import * # Helper Functions -import helper_startup import helper_bootstrap import sys @@ -719,11 +718,9 @@ if __name__ == "__main__": signal.signal(signal.SIGINT, helper_generic.signal_handler) # signal.signal(signal.SIGINT, signal.SIG_DFL) - helper_startup.loadConfig() - helper_bootstrap.knownNodes() helper_bootstrap.dns() - + # Start the address generation thread addressGeneratorThread = addressGenerator() addressGeneratorThread.daemon = True # close the main program even if there are threads left diff --git a/src/debug.py b/src/debug.py index 14214686..034d3102 100644 --- a/src/debug.py +++ b/src/debug.py @@ -18,6 +18,7 @@ Use: `from debug import logger` to import this facility into whatever module you ''' import logging import logging.config +import shared # TODO(xj9): Get from a config file. log_level = 'DEBUG' @@ -40,9 +41,9 @@ logging.config.dictConfig({ 'class': 'logging.handlers.RotatingFileHandler', 'formatter': 'default', 'level': log_level, - 'filename': 'bm.log', - 'maxBytes': 1024, - 'backupCount': 0, + 'filename': shared.appdata + 'debug.log', + 'maxBytes': 2097152, # 2 MiB + 'backupCount': 1, } }, 'loggers': { @@ -65,4 +66,5 @@ logging.config.dictConfig({ }, }) # TODO (xj9): Get from a config file. -logger = logging.getLogger('console_only') +#logger = logging.getLogger('console_only') +logger = logging.getLogger('both') diff --git a/src/shared.py b/src/shared.py index c706038a..5abeeb96 100644 --- a/src/shared.py +++ b/src/shared.py @@ -21,7 +21,8 @@ import socket import random import highlevelcrypto import shared -from debug import logger +import helper_startup + config = ConfigParser.SafeConfigParser() myECCryptorObjects = {} @@ -63,8 +64,6 @@ ackdataForWhichImWatching = {} networkDefaultProofOfWorkNonceTrialsPerByte = 320 #The amount of work that should be performed (and demanded) per byte of the payload. Double this number to double the work. networkDefaultPayloadLengthExtraBytes = 14000 #To make sending short messages a little more difficult, this value is added to the payload length for use in calculating the proof of work target. - - def isInSqlInventory(hash): t = (hash,) shared.sqlLock.acquire() @@ -306,3 +305,6 @@ def fixPotentiallyInvalidUTF8Data(text): except: output = 'Part of the message is corrupt. The message cannot be displayed the normal way.\n\n' + repr(text) return output + +helper_startup.loadConfig() +from debug import logger \ No newline at end of file From 3a06edbbd829df465d86b061ffd728ef38d44800 Mon Sep 17 00:00:00 2001 From: Jonathan Warren Date: Sun, 14 Jul 2013 17:10:37 -0400 Subject: [PATCH 30/39] manual merge, fix minor import issue --- src/shared.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/shared.py b/src/shared.py index 897a1cf0..03ee1752 100644 --- a/src/shared.py +++ b/src/shared.py @@ -22,7 +22,6 @@ import time # Project imports. from addresses import * -from debug import logger import highlevelcrypto import shared import helper_startup From d900b9de7074d5d2298139406835d2ebf75028fa Mon Sep 17 00:00:00 2001 From: DivineOmega Date: Mon, 15 Jul 2013 10:49:01 +0100 Subject: [PATCH 31/39] Added check for logger global before attempting to log in places where logging may occur before the logger is ready --- src/shared.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/shared.py b/src/shared.py index 5abeeb96..ddedf3d0 100644 --- a/src/shared.py +++ b/src/shared.py @@ -118,8 +118,9 @@ def lookupAppdataFolder(): if "HOME" in environ: dataFolder = path.join(os.environ["HOME"], "Library/Application Support/", APPNAME) + '/' else: - logger.critical('Could not find home folder, please report this message and your ' - 'OS X version to the BitMessage Github.') + if 'logger' in globals(): + logger.critical('Could not find home folder, please report this message and your ' + 'OS X version to the BitMessage Github.') sys.exit() elif 'win32' in sys.platform or 'win64' in sys.platform: @@ -133,7 +134,8 @@ def lookupAppdataFolder(): # Migrate existing data to the proper location if this is an existing install try: - logger.info("Moving data folder to %s" % (dataFolder)) + if 'logger' in globals(): + logger.info("Moving data folder to %s" % (dataFolder)) move(path.join(environ["HOME"], ".%s" % APPNAME), dataFolder) except IOError: pass From 3107150ace725a4928e1d05e8e2b94af4ba20729 Mon Sep 17 00:00:00 2001 From: DivineOmega Date: Mon, 15 Jul 2013 10:56:13 +0100 Subject: [PATCH 32/39] Added fall back print statements in case logger is unavailable --- src/shared.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/shared.py b/src/shared.py index ddedf3d0..ff39ea2e 100644 --- a/src/shared.py +++ b/src/shared.py @@ -118,9 +118,11 @@ def lookupAppdataFolder(): if "HOME" in environ: dataFolder = path.join(os.environ["HOME"], "Library/Application Support/", APPNAME) + '/' else: + stringToLog = 'Could not find home folder, please report this message and your OS X version to the BitMessage Github.' if 'logger' in globals(): - logger.critical('Could not find home folder, please report this message and your ' - 'OS X version to the BitMessage Github.') + logger.critical(stringToLog) + else: + print stringToLog sys.exit() elif 'win32' in sys.platform or 'win64' in sys.platform: @@ -134,8 +136,11 @@ def lookupAppdataFolder(): # Migrate existing data to the proper location if this is an existing install try: + stringToLog = "Moving data folder to %s" % (dataFolder) if 'logger' in globals(): - logger.info("Moving data folder to %s" % (dataFolder)) + logger.info(stringToLog) + else: + print stringToLog move(path.join(environ["HOME"], ".%s" % APPNAME), dataFolder) except IOError: pass From 52caec5e2b4a04c893e953d3fc8019e3a9547365 Mon Sep 17 00:00:00 2001 From: Jonathan Warren Date: Mon, 15 Jul 2013 12:19:53 -0400 Subject: [PATCH 33/39] Move one line of code so that correct program activity is logged --- src/bitmessagemain.py | 1 - src/shared.py | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/bitmessagemain.py b/src/bitmessagemain.py index cfbfdd6c..15acf545 100644 --- a/src/bitmessagemain.py +++ b/src/bitmessagemain.py @@ -720,7 +720,6 @@ if __name__ == "__main__": helper_bootstrap.knownNodes() helper_bootstrap.dns() - # Start the address generation thread addressGeneratorThread = addressGenerator() addressGeneratorThread.daemon = True # close the main program even if there are threads left diff --git a/src/shared.py b/src/shared.py index ff39ea2e..72badbc7 100644 --- a/src/shared.py +++ b/src/shared.py @@ -136,12 +136,12 @@ def lookupAppdataFolder(): # Migrate existing data to the proper location if this is an existing install try: + move(path.join(environ["HOME"], ".%s" % APPNAME), dataFolder) stringToLog = "Moving data folder to %s" % (dataFolder) if 'logger' in globals(): logger.info(stringToLog) else: print stringToLog - move(path.join(environ["HOME"], ".%s" % APPNAME), dataFolder) except IOError: pass dataFolder = dataFolder + '/' From 08694ecc38b0d3a18a01fe2b50f0cfacc26c4a0e Mon Sep 17 00:00:00 2001 From: Jonathan Warren Date: Mon, 15 Jul 2013 15:45:03 -0400 Subject: [PATCH 34/39] Portable mode moves debug.log --- src/bitmessageqt/__init__.py | 15 +++++++ src/class_sqlThread.py | 1 + src/debug.py | 85 ++++++++++++++++++++---------------- 3 files changed, 64 insertions(+), 37 deletions(-) diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py index 316f4205..b4ce6725 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -29,6 +29,8 @@ import os from pyelliptic.openssl import OpenSSL import pickle import platform +import debug +from debug import logger try: from PyQt4 import QtCore, QtGui @@ -1874,7 +1876,14 @@ class MyForm(QtGui.QMainWindow): shared.knownNodesLock.release() os.remove(shared.appdata + 'keys.dat') os.remove(shared.appdata + 'knownnodes.dat') + previousAppdataLocation = shared.appdata shared.appdata = '' + debug.restartLoggingInUpdatedAppdataLocation() + try: + os.remove(previousAppdataLocation + 'debug.log') + os.remove(previousAppdataLocation + 'debug.log.1') + except: + pass if shared.appdata == '' and not self.settingsDialogInstance.ui.checkBoxPortableMode.isChecked(): # If we ARE using portable mode now but the user selected that we shouldn't... shared.appdata = shared.lookupAppdataFolder() @@ -1894,6 +1903,12 @@ class MyForm(QtGui.QMainWindow): shared.knownNodesLock.release() os.remove('keys.dat') os.remove('knownnodes.dat') + debug.restartLoggingInUpdatedAppdataLocation() + try: + os.remove('debug.log') + os.remove('debug.log.1') + except: + pass def click_radioButtonBlacklist(self): if shared.config.get('bitmessagesettings', 'blackwhitelist') == 'white': diff --git a/src/class_sqlThread.py b/src/class_sqlThread.py index 84014a8c..a9de7042 100644 --- a/src/class_sqlThread.py +++ b/src/class_sqlThread.py @@ -5,6 +5,7 @@ import time import shutil # used for moving the messages.dat file import sys import os +from debug import logger # This thread exists because SQLITE3 is so un-threadsafe that we must # submit queries to it and it puts results back in a different queue. They diff --git a/src/debug.py b/src/debug.py index 034d3102..fe7815e7 100644 --- a/src/debug.py +++ b/src/debug.py @@ -23,48 +23,59 @@ import shared # TODO(xj9): Get from a config file. log_level = 'DEBUG' -logging.config.dictConfig({ - 'version': 1, - 'formatters': { - 'default': { - 'format': '%(asctime)s - %(levelname)s - %(message)s', +def configureLogging(): + logging.config.dictConfig({ + 'version': 1, + 'formatters': { + 'default': { + 'format': '%(asctime)s - %(levelname)s - %(message)s', + }, }, - }, - 'handlers': { - 'console': { - 'class': 'logging.StreamHandler', - 'formatter': 'default', - 'level': log_level, - 'stream': 'ext://sys.stdout' + 'handlers': { + 'console': { + 'class': 'logging.StreamHandler', + 'formatter': 'default', + 'level': log_level, + 'stream': 'ext://sys.stdout' + }, + 'file': { + 'class': 'logging.handlers.RotatingFileHandler', + 'formatter': 'default', + 'level': log_level, + 'filename': shared.appdata + 'debug.log', + 'maxBytes': 2097152, # 2 MiB + 'backupCount': 1, + } }, - 'file': { - 'class': 'logging.handlers.RotatingFileHandler', - 'formatter': 'default', + 'loggers': { + 'console_only': { + 'handlers': ['console'], + 'propagate' : 0 + }, + 'file_only': { + 'handlers': ['file'], + 'propagate' : 0 + }, + 'both': { + 'handlers': ['console', 'file'], + 'propagate' : 0 + }, + }, + 'root': { 'level': log_level, - 'filename': shared.appdata + 'debug.log', - 'maxBytes': 2097152, # 2 MiB - 'backupCount': 1, - } - }, - 'loggers': { - 'console_only': { 'handlers': ['console'], - 'propagate' : 0 }, - 'file_only': { - 'handlers': ['file'], - 'propagate' : 0 - }, - 'both': { - 'handlers': ['console', 'file'], - 'propagate' : 0 - }, - }, - 'root': { - 'level': log_level, - 'handlers': ['console'], - }, -}) + }) # TODO (xj9): Get from a config file. #logger = logging.getLogger('console_only') +configureLogging() logger = logging.getLogger('both') + +def restartLoggingInUpdatedAppdataLocation(): + global logger + for i in list(logger.handlers): + logger.removeHandler(i) + i.flush() + i.close() + configureLogging() + logger = logging.getLogger('both') \ No newline at end of file From 3427bc5c26002dd49a545e519d1544a60ba2e53d Mon Sep 17 00:00:00 2001 From: Jonathan Warren Date: Mon, 15 Jul 2013 19:27:53 -0400 Subject: [PATCH 35/39] Store msgid in sent table --- src/class_singleWorker.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/class_singleWorker.py b/src/class_singleWorker.py index 1a0fe149..56b7be6e 100644 --- a/src/class_singleWorker.py +++ b/src/class_singleWorker.py @@ -414,10 +414,10 @@ class singleWorker(threading.Thread): # Update the status of the message in the 'sent' table to have # a 'broadcastsent' status shared.sqlLock.acquire() - t = ('broadcastsent', int( + t = (inventoryHash,'broadcastsent', int( time.time()), fromaddress, subject, body, 'broadcastqueued') shared.sqlSubmitQueue.put( - 'UPDATE sent SET status=?, lastactiontime=? WHERE fromaddress=? AND subject=? AND message=? AND status=?') + 'UPDATE sent SET msgid=?, status=?, lastactiontime=? WHERE fromaddress=? AND subject=? AND message=? AND status=?') shared.sqlSubmitQueue.put(t) queryreturn = shared.sqlReturnQueue.get() shared.sqlSubmitQueue.put('commit') @@ -774,8 +774,8 @@ class singleWorker(threading.Thread): # Update the status of the message in the 'sent' table to have a # 'msgsent' status shared.sqlLock.acquire() - t = (ackdata,) - shared.sqlSubmitQueue.put('''UPDATE sent SET status='msgsent' WHERE ackdata=?''') + t = (inventoryHash,ackdata,) + shared.sqlSubmitQueue.put('''UPDATE sent SET msgid=?, status='msgsent' WHERE ackdata=?''') shared.sqlSubmitQueue.put(t) queryreturn = shared.sqlReturnQueue.get() shared.sqlSubmitQueue.put('commit') From 151ca020dfc87437a1eb08a502d8cdb7bb5f82c5 Mon Sep 17 00:00:00 2001 From: Jonathan Warren Date: Mon, 15 Jul 2013 19:36:37 -0400 Subject: [PATCH 36/39] Correct indent on a single line --- src/bitmessageqt/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py index 459b360f..46bac1f3 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -2780,7 +2780,7 @@ class settingsDialog(QtGui.QDialog): shared.config.get('bitmessagesettings', 'port'))) self.ui.checkBoxAuthentication.setChecked(shared.config.getboolean( 'bitmessagesettings', 'socksauthentication')) - self.ui.checkBoxSocksListen.setChecked(shared.config.getboolean( + self.ui.checkBoxSocksListen.setChecked(shared.config.getboolean( 'bitmessagesettings', 'sockslisten')) if str(shared.config.get('bitmessagesettings', 'socksproxytype')) == 'none': self.ui.comboBoxProxyType.setCurrentIndex(0) From 5f8209698fe5458f2a969efa06d4b2ff76eb07ac Mon Sep 17 00:00:00 2001 From: akh81 Date: Mon, 15 Jul 2013 23:10:36 -0500 Subject: [PATCH 37/39] all translations complete --- src/translations/bitmessage_ru_RU.qm | Bin 30541 -> 51726 bytes src/translations/bitmessage_ru_RU.ts | 174 ++++++++++++++------------- 2 files changed, 93 insertions(+), 81 deletions(-) diff --git a/src/translations/bitmessage_ru_RU.qm b/src/translations/bitmessage_ru_RU.qm index 9e7b7cb8d73d21fdf4949b7816a6c018381e7706..560b57b741c60cd9664f2f90a5082fa3c027d5a4 100644 GIT binary patch literal 51726 zcmeHwdzhV7dGDHJPbQg55<&$Ay<+>z*=C>>^(D^%QVK?I8kSgjYTmP6H2>)lqXMXcCjZTomCr&g;E9_`_@J=S_GM=O;+eX5+_?|r}Z zee2t^_9PLd{-KfCw{NZWu6Mon_g!oCKb|?~i~sMDw}0uP^FMd=b9vdk zV)fI;9Jtf;{KlikTz`ex^tF49x#xOw)x&=V7@pGCw|v3ufBW|_&Lw95!;N@7U=Hn> zFs5s#Ieg-e@p?jEA3SQVd*Bvhe*a!`EO$FzKWVQ2i!H_sPMcRPdcc?`o-n`q!YJU` zXpTR7mocy0V2VFRfA>9MX5ZUkOzStz9q)UMF^y&O>ioNm`N(zV9VgZp^NvyT#n0Vn z%$h$mUtac*F}+_l-}wATjal+(^R4r)2EMK~Kl;LR#vJ_Tx+U*^-k7s~P

K;GyTS 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 W;{D|v=Vo# n(gMiwuM>i+;%A)e9z diff --git a/src/translations/bitmessage_ru_RU.ts b/src/translations/bitmessage_ru_RU.ts index 7bb06bc1..98981c04 100644 --- a/src/translations/bitmessage_ru_RU.ts +++ b/src/translations/bitmessage_ru_RU.ts @@ -86,7 +86,7 @@ Force send - + Форсировать отправку @@ -96,17 +96,17 @@ Waiting on their encryption key. Will request it again soon. - + Ожидаем ключ шифрования от Вашего собеседника. Запрос будет повторен через некоторое время. Encryption key request queued. - + Запрос ключа шифрования поставлен в очередь. Queued. - + В очереди. @@ -116,7 +116,7 @@ Need to do work to send message. Work is queued. - + Нужно провести требуемые вычисления, чтобы отправить сообщение. Вычисления ожидают очереди. @@ -126,27 +126,27 @@ Broadcast queued. - + Рассылка ожидает очереди. Broadcast on %1 - + Рассылка на %1 Problem: The work demanded by the recipient is more difficult than you are willing to do. %1 - + Проблема: Ваш получатель требует более сложных вычислений, чем максимум, указанный в Ваших настройках. %1 Problem: The recipient's encryption key is no good. Could not encrypt message. %1 - + Проблема: ключ получателя неправильный. Невозможно зашифровать сообщение. %1 Forced difficulty override. Send should start soon. - + Форсирована смена сложности. Отправляем через некоторое время. @@ -156,7 +156,7 @@ Since startup on %1 - + С начала работы %1 @@ -166,7 +166,7 @@ Show Bitmessage - + Показать Bitmessage @@ -191,41 +191,49 @@ You may manage your keys by editing the keys.dat file stored in the same directory as this program. It is important that you back up this file. - + Вы можете управлять Вашими ключами, отредактировав файл keys.dat, находящийся в той же папке, что и эта программа. +Создайте резервную копию этого файла перед тем как будете его редактировать. You may manage your keys by editing the keys.dat file stored in %1 It is important that you back up this file. - + Вы можете управлять Вашими ключами, отредактировав файл keys.dat, находящийся в + %1 +Создайте резервную копию этого файла перед тем как будете его редактировать. Open keys.dat? - + Открыть файл keys.dat? You may manage your keys by editing the keys.dat file stored in the same directory as this program. It is important that you back up this file. Would you like to open the file now? (Be sure to close Bitmessage before making any changes.) - + Вы можете управлять Вашими ключами, отредактировав файл keys.dat, находящийся в той же папке, что и эта программа. +Создайте резервную копию этого файла перед тем как будете его редактировать. Хотели бы Вы открыть этот файл сейчас? +(пожалуйста, закройте Bitmessage до того как Вы внесете в этот файл какие-либо изменения.) You may manage your keys by editing the keys.dat file stored in %1 It is important that you back up this file. Would you like to open the file now? (Be sure to close Bitmessage before making any changes.) - + Вы можете управлять Вашими ключами, отредактировав файл keys.dat, находящийся в + %1 +Создайте резервную копию этого файла перед тем как будете его редактировать. Хотели бы Вы открыть этот файл сейчас? +(пожалуйста, закройте Bitmessage до того как Вы внесете в этот файл какие-либо изменения.) Delete trash? - + Очистить корзину? Are you sure you want to delete all trashed messages? - + Вы уверены, что хотите очистить корзину? @@ -240,17 +248,17 @@ It is important that you back up this file. Would you like to open the file now? Processed %1 person-to-person messages. - + Обработано %1 сообщений. Processed %1 broadcast messages. - + Обработано %1 рассылок. Processed %1 public keys. - + Обработано %1 открытых ключей. @@ -270,67 +278,67 @@ It is important that you back up this file. Would you like to open the file now? Message trashed - + Сообщение удалено Error: Bitmessage addresses start with BM- Please check %1 - + Ошибка: Bitmessage адреса начинаются с BM- Пожалуйста, проверьте %1 Error: The address %1 is not typed or copied correctly. Please check it. - + Ошибка: адрес %1 внесен или скопирован неправильно. Пожалуйста, перепроверьте. Error: The address %1 contains invalid characters. Please check it. - + Ошибка: адрес %1 содержит запрещенные символы. Пожалуйста, перепроверьте. Error: The address version in %1 is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. - + Ошибка: версия адреса в %1 слишком новая. Либо Вам нужно обновить Bitmessage, либо Ваш собеседник дал неправильный адрес. Error: Some data encoded in the address %1 is too short. There might be something wrong with the software of your acquaintance. - + Ошибка: некоторые данные, закодированные в адресе %1, слишком короткие. Возможно, что-то не так с программой Вашего собеседника. Error: Some data encoded in the address %1 is too long. There might be something wrong with the software of your acquaintance. - + Ошибка: некоторые данные, закодированные в адресе %1, слишком длинные. Возможно, что-то не так с программой Вашего собеседника. Error: Something is wrong with the address %1. - + Ошибка: что-то не так с адресом %1. Error: You must specify a From address. If you don't have one, go to the 'Your Identities' tab. - + Вы должны указать адрес в поле "От кого". Вы можете найти Ваш адрес во вкладе "Ваши Адреса". Sending to your address - + Отправка на Ваш собственный адрес Error: One of the addresses to which you are sending a message, %1, is yours. Unfortunately the Bitmessage client cannot process its own messages. Please try running a second client on a different computer or within a VM. - + Ошибка: Один из адресов, на который Вы отправляете сообщение, %1, принадлежит Вам. К сожалению, Bitmessage не может отправлять сообщения самому себе. Попробуйте запустить второго клиента на другом компьютере или на виртуальной машине. Address version number - + Версия адреса Concerning the address %1, Bitmessage cannot understand address version numbers of %2. Perhaps upgrade Bitmessage to the latest version. - + По поводу адреса %1: Bitmessage не поддерживаем адреса версии %2. Возможно, Вам нужно обновить клиент Bitmessage. @@ -340,22 +348,22 @@ It is important that you back up this file. Would you like to open the file now? Concerning the address %1, Bitmessage cannot handle stream numbers of %2. Perhaps upgrade Bitmessage to the latest version. - + По поводу адреса %1: Bitmessage не поддерживаем стрим номер %2. Возможно, Вам нужно обновить клиент Bitmessage. Warning: You are currently not connected. Bitmessage will do the work necessary to send the message but it won't send until you connect. - + Внимание: Вы не подключены к сети. Bitmessage проделает необходимые вычисления, чтобы отправить сообщение, но не отправит его до тех пор, пока Вы не подсоединитесь к сети. Your 'To' field is empty. - + Вы не заполнили поле 'Кому'. Work is queued. - + Вычисления поставлены в очередь. @@ -365,12 +373,12 @@ It is important that you back up this file. Would you like to open the file now? Work is queued. %1 - + Вычисления поставлены в очередь. %1 New Message - + Новое сообщение @@ -380,52 +388,52 @@ It is important that you back up this file. Would you like to open the file now? Address is valid. - + Адрес введен правильно. Error: You cannot add the same address to your address book twice. Try renaming the existing one if you want. - + Ошибка: Вы не можете добавлять один и тот же адрес в Адресную Книгу несколько раз. Просто переименуйте существующий адрес. The address you entered was invalid. Ignoring it. - + Вы ввели неправильный адрес. Это адрес проигнорирован. Error: You cannot add the same address to your subsciptions twice. Perhaps rename the existing one if you want. - + Ошибка: Вы не можете добавлять один и тот же адрес в подписку несколько раз. Просто переименуйте существующую подписку. Restart - + Перезапустить You must restart Bitmessage for the port number change to take effect. - + Вы должны перезапустить Bitmessage, чтобы смена номера порта имела эффект. Bitmessage will use your proxy from now on but you may want to manually restart Bitmessage now to close existing connections. - + Bitmessage будет использовать Ваш прокси в дальнейшем, тем не менее, мы рекомендуем перезапустить Bitmessage в ручную, чтобы закрыть уже существующие соединения. Error: You cannot add the same address to your list twice. Perhaps rename the existing one if you want. - + Ошибка: Вы не можете добавлять один и тот же адрес в список несколько раз. Просто переименуйте существующий адрес. Passphrase mismatch - + Секретная фраза не подходит The passphrase you entered twice doesn't match. Try again. - + Вы ввели две разные секретные фразы. Пожалуйста, повторите заново. @@ -440,32 +448,32 @@ It is important that you back up this file. Would you like to open the file now? All done. Closing user interface... - + Программа завершена. Закрываем пользовательский интерфейс... Address is gone - + Адрес утерян Bitmessage cannot find your address %1. Perhaps you removed it? - + Bitmessage не может найти Ваш адрес %1. Возможно Вы удалили его? Address disabled - + Адрес выключен Error: The address from which you are trying to send is disabled. You'll have to enable it on the 'Your Identities' tab before using it. - + Ошибка: адрес, с которого Вы пытаетесь отправить, выключен. Вам нужно будет включить этот адрес во вкладке "Ваши адреса". Entry added to the Address Book. Edit the label to your liking. - + Запись добавлена в Адресную Книгу. Вы можете ее отредактировать. @@ -475,22 +483,22 @@ It is important that you back up this file. Would you like to open the file now? Save As... - + Сохранить как ... Write error. - + Ошибка записи. No addresses selected. - + Вы не выбрали адрес. Options have been disabled because they either aren't applicable or because they haven't yet been implemented for your operating system. - + Опции были отключены, потому что ли они либо не подходят, либо еще не выполнены под Вашу операционную систему. @@ -500,27 +508,27 @@ It is important that you back up this file. Would you like to open the file now? The address is not typed or copied correctly (the checksum failed). - + Адрес введен или скопирован неверно (контрольная сумма не сходится). The version number of this address is higher than this software can support. Please upgrade Bitmessage. - + Версия этого адреса более поздняя, чем Ваша программа. Пожалуйста, обновите программу Bitmessage. The address contains invalid characters. - + Адрес содержит запрещенные символы. Some data encoded in the address is too short. - + Данные, закодированные в адресе, слишком короткие. Some data encoded in the address is too long. - + Данные, закодированные в адресе, слишком длинные. @@ -584,7 +592,11 @@ It is important that you back up this file. Would you like to open the file now? p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;"> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html> - + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html> @@ -659,7 +671,7 @@ p, li { white-space: pre-wrap; } The Address book is useful for adding names or labels to other people's Bitmessage addresses so that you can recognize them more easily in your inbox. You can add entries here using the 'Add' button, or from your inbox by right-clicking on a message. - + Адресная книга удобна для присвоения осмысленных имен Bitmessage адресам Ваших друзей. Вы можете добавлять новые записи с помощью кнопки "Добавить новую запись", или же правым кликом мышки на сообщении. @@ -699,22 +711,22 @@ p, li { white-space: pre-wrap; } Since startup at asdf: - + С начала работы программы в asdf: Processed 0 person-to-person message. - + Обработано 0 сообщений. Processed 0 public key. - + Обработано 0 открытых ключей. Processed 0 broadcast. - + Обработано 0 рассылок. @@ -739,7 +751,7 @@ p, li { white-space: pre-wrap; } Import keys - + Импортировать ключи @@ -866,42 +878,42 @@ The 'Random Number' option is selected by default but deterministic ad Dialog - + Новый chan Create a new chan - + Создать новый chan Join a chan - + Присоединиться к chan <html><head/><body><p>A chan is a set of encryption keys that is shared by a group of people. The keys and bitmessage address used by a chan is generated from a human-friendly word or phrase (the chan name).</p><p>Chans are experimental and are unmoderatable.</p></body></html> - + <html><head/><body><p>Chan - это набор ключей шифрования, которые известны некоторой группе людей. Ключи и Bitmessage-адрес используемый chan-ом генерируется из слова или фразы (имя chan-а).</p><p>Chan-ы - это экспериментальная новинка.</p></body></html> Chan name: - + Имя chan: Chan bitmessage address: - + Bitmessage адрес chan: Create a chan - + Создать chan Enter a name for your chan. If you choose a sufficiently complex chan name (like a strong and unique passphrase) and none of your friends share it publicly then the chan will be secure and private. - + Введите имя Вашего chan-a. Если Вы выберете достаточно сложное имя для chan-а (например, сложную и необычную секретную фразу) и никто из Ваших друзей не опубликует эту фразу, то Вам chan будет надежно зашифрован. From 1b722dca5c7577532995851320157c7003536192 Mon Sep 17 00:00:00 2001 From: akh81 Date: Mon, 15 Jul 2013 23:12:07 -0500 Subject: [PATCH 38/39] all translations complete --- src/translations/bitmessage_ru_RU.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/translations/bitmessage_ru_RU.ts b/src/translations/bitmessage_ru_RU.ts index 98981c04..338a6505 100644 --- a/src/translations/bitmessage_ru_RU.ts +++ b/src/translations/bitmessage_ru_RU.ts @@ -1,6 +1,5 @@ - - + MainWindow @@ -979,7 +978,7 @@ The 'Random Number' option is selected by default but deterministic ad version ? версия ? - + Copyright © 2013 Jonathan Warren Копирайт © 2013 Джонатан Уоррен From d1ea944f0e251fb3939bd8b8fe52b85f03c55a10 Mon Sep 17 00:00:00 2001 From: akh81 Date: Mon, 15 Jul 2013 23:52:08 -0500 Subject: [PATCH 39/39] complete Russian translation --- src/translations/bitmessage_ru_RU.qm | Bin 51726 -> 51720 bytes src/translations/bitmessage_ru_RU.ts | 25 +++++++++++++------------ 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/translations/bitmessage_ru_RU.qm b/src/translations/bitmessage_ru_RU.qm index 560b57b741c60cd9664f2f90a5082fa3c027d5a4..e917c3b0cdf1101ffc3e50e2487d6a6313c165a1 100644 GIT binary patch delta 2031 zcmXw4eN+=y9=(&9NivzqL=a2`6*ozM2VmoCMdu8JPDN+|LUD&%aJ! z`G3F{bHM5{@YR7pz-__^AgBqd$RMCg54)fzKn?@9-j~4KUGQ+~28<>wdfy6|HY|lt zUjdLGjgayyM51c~|8@;wM;}q4*AP~&A$$YjYqkRmg7IcX2VvF(nj;Zelni{Fji{t7 z!X|9EwhZv!gBWEI(AI*@qX|UF2PuO&K(qlnU(k7l9muTlf(fq;U~jz%(4=EuY87xc z92FTefQrqy@p&vTqZvKAV!*o>1D6{C;XLj*hmvA}7`ZwOtow-(jz0w)A2Tjaq{O0n z#$9p)_JuHu;)Z~u9gKGloom~`EVrZm0q-*YF+Q{}i81zZRM_E1CT?R5P;!?!wAl+t zTEu*CmO5#RW7_LjAW&uobA187A!aC(teRBKj41*DWtzfsunzF?R=j;MmDZOlvL6y* z*L#Y?JBe7#3PpVy71aNt_*WdE|4)ir*_TNncg29b6$lf2nRCblo6=*MD{kQZ332Ce~ z_5fw)2-~gt3m~0ihoXpBNFY0$LBHSX&;HiB9$1mW>9&wHO`+TrQ^Q6I+)8fMXB3{Z zH@N`gM<74A6p0R{BE3eHyT07M?-F8w?Q zXq>}c$(%_Yw{d;;UBFv?JagL%usg%cvkj!AnfG~AL3v-uFS|k6vaaG)%eRxnp$9C} zS-r`P-xfuBtp1Hpv)ZUk8()x1eSC7CuUJOM?-2N^C-l88o^LRdkZUIMr_I@ffqdg3 zp2`ICZHZLw^;*8$oJ@3%@uPuu6zSjjm*edexbb5F!+`rUCHo|m?j4kI?^uCj`;>_< zNgq>Df^v5$Ip6H0to!auVA*VC{ig%u)E;GnYbW*Vue6m+26AJRpN$J_$y45JuqQ{q zSJ{_Rl6*2$Vg20{u{o;sU9r?>fhw|;2ns>$3> z#x|->7vH11pyvJQsrY(NH@|!9$yRTJLv$w z458{9ayB$fsGb%Jlx-J|uN)(sFI+q`ObX@-52uqNYlDQR1~($)Cybph0ajhqY~N-D z&IM_b2Wfw{mC!_k+FhFSBHiXS!PvyVwG2K01>z*Rtw%F*(LFMZW0hHiP!IvS7E=3w&XKwWS~-~JCf9JS^NxGKyAQRqD(T>bhqa!T272O>w5uP>WSd^QPAc8R|CYg0yYfW+t89r|tx`c3WbZkl_Z&}Ic3A+^1=eK)-5CEBX};Yd8G)*#~| z75eamtmYQdqh2d}89$&Lddshm6j6}tz2tC^tc8*C@l8wV$zkO$s_6we<}P>7Cwo-0 zCa|bY?le&0`E-3xheTP!eLuQObq0W|zqx312Yh%vh8k2`_NJY8c5HE?93uGPg# ze}`_mE=M8~ep2`RFx{l)da|sGiLlkE4(dgFZY{T*TfrH*5R1XZL!89f|9@_K+hx#^ zDX|z0tsLjit+OeYL?<#=EV~k?DBx+y`+K>?EzZ$4&)UqsD*R>ItOXC4gz&&Fe z%g4Z%a6rKO;HyG_;4Z>QAoL7`s8FDF3hY830@-7j-uW1qlLj~EcEFg81@Bn^(^_x% z+{p*>)?#`2H6qbEj_+Sb#0Nu^=p{syYY2^46}A=d48fX=i-Z~DSR9F{qGaIHd_*Vh zCOn6=U;6@q>DZtw0&F&H9E~SJ2Bh@l05J=(<2Q;|U_)lL2TXYJdt}v`08JY9Y_9~) zMBzxrRNzQF+AhZeQ$I(Ct_1MvK=;)KKz#xCCWVt?;TX9-2)z0;qdqzeOnAWPok@uW zHOwq&IgSRh1VdUE{$|30QalUns$6*Hy?29&7^_nsQSXMy6){o84Nu_C*V z2)q2GIIx3=ZSYmprcy%32Z~#9gn>UR?q**lg*+79+RebS0YxuoN&||`tW?5N!hTln zXrv00S>3yxK*>bbrHT@-e}VPv{0z_yu?q_+fpZw^otguj)U!*CE;Zj6mY`)6v`i&}058?9csHdLwT>aeRz{Gvr+5Bi=UpZ&3asZ+VxGMv* zfrfe9wMQjnB`eIzIakf5exE1yZ_m%}XoTp5D zO!}CLHY?Lhsq>94%9`*02Kc%vYtMI6r_z;mE-h5AztVc}c_24N`Nb1~%_imTI(zEq zeZjtzoaFPi5Yg367Mm%oZjGfn_X<&^L~!p-Axp0X46;!0iW6D!pF(9y12FS|P@VY> zHMT)GUGgK{1r_)E2a279Rs%6>(hK*Ex5?X?!l)||NV=t3q5b+p@c2yO95z&N&#odg(Z?sdG#5m=&0zzYOG$o!pPS}tE_q?4p!wx+4tc&+RA-X(j(MVn z?EseS6lV;#(4CRQS(jpg7YaoG=Skw%<3wXPd3?`T<5*oHt{x*r&fXQ{vjWMQda-zS zKIPddmR_b7hdYav9-YBN;FegW_9DqHi#KwUfLM)q<6qRPh#~QAg%PMN61y@7fzNH` zd%WImND7!sv~zYzVddM2?lH5hbTs`UmH9i<#e7*Rdm|j!eL*^vVWX#MSZaJC|LQ#H zyx}O3$dZ~;N!7iq)Xb2vL;J?DF;%+cK)DJYN#7|1bNfR z3Q}{6oDgw^*6+$GBRN3gBYB%+I~o1&a(X+B-A~B7gAb9~Uhle|J!)R|-(F=0eL)$)& z+9S*u$D$@}mobm@`(Yf9v)Z17SYV2i&TwNYaGKG*TH^<78Pmml+5%MU(={xo0uDv% zn)DX>J9O2xP9P$yj_dw+fNoM_J+-WriLq7-`yE9`&Xe=!0yqN~WH#vCWP8qqW_*61 zSz%4l_e@}l%&!=ltSaxA#A!D7+$$t!N?YFjYO72C@j|;FiH2tJ_y6aEr%_o{~JafUCe{r_v>B^r1 Oo3E7Vtv`G - + + MainWindow @@ -40,12 +41,12 @@ Enable - Разрешить + Включить Disable - Запретить + Выключить @@ -650,7 +651,7 @@ p, li { white-space: pre-wrap; } Here you can subscribe to 'broadcast messages' that are sent by other users. Messages will appear in your Inbox. Addresses here override those on the Blacklist tab. - Здесь Вы можете подписаться на рассылки от других пользователей. Все рассылки будут появлять у Вас во Входящих. Вы будете следить за всеми адресами, указанными здесь, даже если они в черном списке. + Здесь Вы можете подписаться на рассылки от других пользователей. Все рассылки будут появляться у Вас во Входящих. Вы будете следить за всеми адресами, указанными здесь, даже если они в черном списке. @@ -978,7 +979,7 @@ The 'Random Number' option is selected by default but deterministic ad version ? версия ? - + Copyright © 2013 Jonathan Warren Копирайт © 2013 Джонатан Уоррен @@ -1009,7 +1010,7 @@ The 'Random Number' option is selected by default but deterministic ad As Bitmessage is a collaborative project, help can be found online in the Bitmessage Wiki: - Битмесседж - это общественный проект. Вы можете найти подсказки и советы на Wiki-страничке Битмесседж: + Bitmessage - общественный проект. Вы можете найти подсказки и советы на Wiki-страничке Bitmessage: @@ -1027,7 +1028,7 @@ The 'Random Number' option is selected by default but deterministic ad You have made at least one connection to a peer using an outgoing connection but you have not yet received any incoming connections. Your firewall or home router probably isn't configured to forward incoming TCP connections to your computer. Bitmessage will work just fine but it would help the Bitmessage network if you allowed for incoming connections and will help you be a better-connected node. - На текущий момент Вы установили по-крайней мере одно исходящее соединение, но пока ни одного входящего. Ваш файрвол или маршрутизатор скорее всего не настроен на переброс входящих TCP соединений к Вашему компьютеру. Битмесседж будет прекрасно работать и без этого, но Вы могли бы помочь сети если бы разрешили и входящие соединения тоже. Это помогло бы Вам стать более важным узлом сети. + На текущий момент Вы установили по-крайней мере одно исходящее соединение, но пока ни одного входящего. Ваш файрвол или маршрутизатор скорее всего не настроен на переброс входящих TCP соединений к Вашему компьютеру. Bitmessage будет прекрасно работать и без этого, но Вы могли бы помочь сети если бы разрешили и входящие соединения тоже. Это помогло бы Вам стать более важным узлом сети. @@ -1108,12 +1109,12 @@ The 'Random Number' option is selected by default but deterministic ad Start Bitmessage on user login - Запускать Битмесседж при входе в систему + Запускать Bitmessage при входе в систему Start Bitmessage in the tray (don't show main window) - Запускать Битмесседж в свернутом виде (не показывать главное окно) + Запускать Bitmessage в свернутом виде (не показывать главное окно) @@ -1133,7 +1134,7 @@ The 'Random Number' option is selected by default but deterministic ad In Portable Mode, messages and config files are stored in the same directory as the program rather than the normal application-data folder. This makes it convenient to run Bitmessage from a USB thumb drive. - В переносном режиме, все сообщения и конфигурационные файлы сохраняются в той же самой папке что и сама программа. Это делает более удобным использование БитМесседж с USB-флэшки. + В переносном режиме, все сообщения и конфигурационные файлы сохраняются в той же самой папке что и сама программа. Это делает более удобным использование Bitmessage с USB-флэшки. @@ -1153,7 +1154,7 @@ The 'Random Number' option is selected by default but deterministic ad Proxy server / Tor - Прокси сервер / Тор + Прокси сервер / Tor @@ -1208,7 +1209,7 @@ The 'Random Number' option is selected by default but deterministic ad When someone sends you a message, their computer must first complete some work. The difficulty of this work, by default, is 1. You may raise this default for new addresses you create by changing the values here. Any new addresses you create will require senders to meet the higher difficulty. There is one exception: if you add a friend or acquaintance to your address book, Bitmessage will automatically notify them when you next send a message that they need only complete the minimum amount of work: difficulty 1. - Когда кто-либо отправляет Вам сообщение, его компьютер должен сперва решить определенную вычислительную задачу. Сложность этой задачи по умолчанию равна 1. Вы можете повысить эту сложность для новых адресов, которые Вы создадите, здесь. Таким образом, любые новые адреса, которые Вы создадите, могут требовать от отправителей сложность большую чем 1. Однако, есть одно исключение: если Вы специально добавите Вашего собеседника в адресную книгу, то БитМесседж автоматически уведомит его о том, что для него минимальная сложность будет составлять всегда всего лишь 1. + Когда кто-либо отправляет Вам сообщение, его компьютер должен сперва решить определенную вычислительную задачу. Сложность этой задачи по умолчанию равна 1. Вы можете повысить эту сложность для новых адресов, которые Вы создадите, здесь. Таким образом, любые новые адреса, которые Вы создадите, могут требовать от отправителей сложность большую чем 1. Однако, есть одно исключение: если Вы специально добавите Вашего собеседника в адресную книгу, то Bitmessage автоматически уведомит его о том, что для него минимальная сложность будет составлять всегда всего лишь 1.