New localization module (l10n)

Resolves #691
This commit is contained in:
bmng-dev 2014-08-06 02:01:01 +00:00
parent d2f988e7ac
commit 269506ff8f
5 changed files with 86 additions and 98 deletions

View File

@ -25,6 +25,7 @@ import shared
import ConfigParser
from addresses import *
from pyelliptic.openssl import OpenSSL
import l10n
quit = False
menutab = 1
@ -210,7 +211,7 @@ def drawtab(stdscr):
stdscr.addstr(8+i, 18, str(item).ljust(2))
# Uptime and processing data
stdscr.addstr(6, 35, "Since startup on "+unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'), localtime(int(startuptime)))))
stdscr.addstr(6, 35, "Since startup on "+l10n.formatTimestamp(startuptime, False))
stdscr.addstr(7, 40, "Processed "+str(shared.numberOfMessagesProcessed).ljust(4)+" person-to-person messages.")
stdscr.addstr(8, 40, "Processed "+str(shared.numberOfBroadcastsProcessed).ljust(4)+" broadcast messages.")
stdscr.addstr(9, 40, "Processed "+str(shared.numberOfPubkeysProcessed).ljust(4)+" public keys.")
@ -851,8 +852,7 @@ def loadInbox():
# Load into array
inbox.append([msgid, tolabel, toaddr, fromlabel, fromaddr, subject,
strftime(shared.config.get('bitmessagesettings', 'timeformat'), localtime(int(received))),
read])
l10n.formatTimestamp(received, False), read])
inbox.reverse()
def loadSent():
sys.stdout = sys.__stdout__
@ -902,20 +902,20 @@ def loadSent():
elif status == "msgqueued":
statstr = "Message queued"
elif status == "msgsent":
t = strftime(shared.config.get('bitmessagesettings', 'timeformat'), localtime(int(lastactiontime)))
t = l10n.formatTimestamp(lastactiontime, False)
statstr = "Message sent at "+t+".Waiting for acknowledgement."
elif status == "msgsentnoackexpected":
t = strftime(shared.config.get('bitmessagesettings', 'timeformat'), localtime(int(lastactiontime)))
t = l10n.formatTimestamp(lastactiontime, False)
statstr = "Message sent at "+t+"."
elif status == "doingmsgpow":
statstr = "The proof of work required to send the message has been queued."
elif status == "askreceived":
t = strftime(shared.config.get('bitmessagesettings', 'timeformat'), localtime(int(lastactiontime)))
t = l10n.formatTimestamp(lastactiontime, False)
statstr = "Acknowledgment of the message received at "+t+"."
elif status == "broadcastqueued":
statstr = "Broadcast queued."
elif status == "broadcastsent":
t = strftime(shared.config.get('bitmessagesettings', 'timeformat'), localtime(int(lastactiontime)))
t = l10n.formatTimestamp(lastactiontime, False)
statstr = "Broadcast sent at "+t+"."
elif status == "forcepow":
statstr = "Forced difficulty override. Message will start sending soon."
@ -924,12 +924,12 @@ def loadSent():
elif status == "toodifficult":
statstr = "Error: The work demanded by the recipient is more difficult than you are willing to do."
else:
t = strftime(shared.config.get('bitmessagesettings', 'timeformat'), localtime(int(lastactiontime)))
t = l10n.formatTimestamp(lastactiontime, False)
statstr = "Unknown status "+status+" at "+t+"."
# Load into array
sentbox.append([tolabel, toaddr, fromlabel, fromaddr, subject, statstr, ackdata,
strftime(shared.config.get('bitmessagesettings', 'timeformat'), localtime(int(lastactiontime)))])
l10n.formatTimestamp(lastactiontime, False)])
sentbox.reverse()
def loadAddrBook():
sys.stdout = sys.__stdout__

View File

@ -1,8 +1,3 @@
try:
import locale
except:
pass
withMessagingMenu = False
try:
from gi.repository import MessagingMenu
@ -40,6 +35,7 @@ from debug import logger
import subprocess
import datetime
from helper_sql import *
import l10n
try:
from PyQt4 import QtCore, QtGui
@ -578,7 +574,7 @@ class MyForm(QtGui.QMainWindow):
self.statusbar = self.statusBar()
self.statusbar.insertPermanentWidget(0, self.ui.pushButtonStatusIcon)
self.ui.labelStartupTime.setText(_translate("MainWindow", "Since startup on %1").arg(
unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'), localtime(int(time.time()))),'utf-8')))
l10n.formatTimestamp()))
self.numberOfMessagesProcessed = 0
self.numberOfBroadcastsProcessed = 0
self.numberOfPubkeysProcessed = 0
@ -837,34 +833,34 @@ class MyForm(QtGui.QMainWindow):
"MainWindow", "Queued.")
elif status == 'msgsent':
statusText = _translate("MainWindow", "Message sent. Waiting for acknowledgement. Sent at %1").arg(
unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'), localtime(lastactiontime)),'utf-8'))
l10n.formatTimestamp(lastactiontime))
elif status == 'msgsentnoackexpected':
statusText = _translate("MainWindow", "Message sent. Sent at %1").arg(
unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'), localtime(lastactiontime)),'utf-8'))
l10n.formatTimestamp(lastactiontime))
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'))
l10n.formatTimestamp(lastactiontime))
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'))
statusText = _translate("MainWindow", "Broadcast on %1").arg(
l10n.formatTimestamp(lastactiontime))
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'))
l10n.formatTimestamp(lastactiontime))
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'))
l10n.formatTimestamp(lastactiontime))
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'))
statusText = _translate("MainWindow", "Unknown status: %1 %2").arg(status).arg(
l10n.formatTimestamp(lastactiontime))
newItem = myTableWidgetItem(statusText)
newItem.setToolTip(statusText)
newItem.setData(Qt.UserRole, QByteArray(ackdata))
@ -971,10 +967,8 @@ class MyForm(QtGui.QMainWindow):
subject_item.setFont(font)
self.ui.tableWidgetInbox.setItem(0, 2, subject_item)
# time received
time_item = myTableWidgetItem(unicode(strftime(shared.config.get(
'bitmessagesettings', 'timeformat'), localtime(int(received))), 'utf-8'))
time_item.setToolTip(unicode(strftime(shared.config.get(
'bitmessagesettings', 'timeformat'), localtime(int(received))), 'utf-8'))
time_item = myTableWidgetItem(l10n.formatTimestamp(received))
time_item.setToolTip(l10n.formatTimestamp(received))
time_item.setData(Qt.UserRole, QByteArray(msgid))
time_item.setData(33, int(received))
time_item.setFlags(
@ -2062,12 +2056,9 @@ class MyForm(QtGui.QMainWindow):
self.ui.tableWidgetSent.setItem(0, 2, newItem)
# newItem = QtGui.QTableWidgetItem('Doing work necessary to send
# broadcast...'+
# unicode(strftime(shared.config.get('bitmessagesettings',
# 'timeformat'),localtime(int(time.time()))),'utf-8'))
newItem = myTableWidgetItem(_translate("MainWindow", "Work is queued. %1").arg(unicode(strftime(shared.config.get(
'bitmessagesettings', 'timeformat'), localtime(int(time.time()))), 'utf-8')))
newItem.setToolTip(_translate("MainWindow", "Work is queued. %1").arg(unicode(strftime(shared.config.get(
'bitmessagesettings', 'timeformat'), localtime(int(time.time()))), 'utf-8')))
# l10n.formatTimestamp())
newItem = myTableWidgetItem(_translate("MainWindow", "Work is queued. %1").arg(l10n.formatTimestamp()))
newItem.setToolTip(_translate("MainWindow", "Work is queued. %1").arg(l10n.formatTimestamp()))
newItem.setData(Qt.UserRole, QByteArray(ackdata))
newItem.setData(33, int(time.time()))
self.ui.tableWidgetSent.setItem(0, 3, newItem)
@ -2134,10 +2125,8 @@ class MyForm(QtGui.QMainWindow):
#newItem.setData(Qt.UserRole, unicode(message, 'utf-8)')) # No longer hold the message in the table; we'll use a SQL query to display it as needed.
newItem.setFont(font)
self.ui.tableWidgetInbox.setItem(0, 2, newItem)
newItem = myTableWidgetItem(unicode(strftime(shared.config.get(
'bitmessagesettings', 'timeformat'), localtime(int(time.time()))), 'utf-8'))
newItem.setToolTip(unicode(strftime(shared.config.get(
'bitmessagesettings', 'timeformat'), localtime(int(time.time()))), 'utf-8'))
newItem = myTableWidgetItem(l10n.formatTimestamp())
newItem.setToolTip(l10n.formatTimestamp())
newItem.setData(Qt.UserRole, QByteArray(inventoryHash))
newItem.setData(33, int(time.time()))
newItem.setFont(font)
@ -3811,52 +3800,12 @@ def run():
app = QtGui.QApplication(sys.argv)
translator = QtCore.QTranslator()
try:
locale_countrycode = str(locale.getdefaultlocale()[0])
except:
# The above is not compatible with all versions of OSX.
locale_countrycode = "en_US" # Default to english.
locale_lang = locale_countrycode[0:2]
user_countrycode = str(shared.config.get('bitmessagesettings', 'userlocale'))
user_lang = user_countrycode[0:2]
try:
translation_path = os.path.join(sys._MEIPASS, "translations/bitmessage_")
except Exception, e:
translation_path = "translations/bitmessage_"
if shared.config.get('bitmessagesettings', 'userlocale') == 'system':
# try to detect the users locale otherwise fallback to English
try:
# try the users full locale, e.g. 'en_US':
# since we usually only provide languages, not localozations
# this will usually fail
translator.load(translation_path + locale_countrycode)
except:
try:
# try the users locale language, e.g. 'en':
# since we usually only provide languages, not localozations
# this will usually succeed
translator.load(translation_path + locale_lang)
except:
# as English is already the default language, we don't
# need to do anything. No need to translate.
pass
else:
try:
# check if the user input is a valid translation file:
# since user_countrycode will be usually set by the combobox
# it will usually just be a language code
translator.load(translation_path + user_countrycode)
except:
try:
# check if the user lang is a valid translation file:
# this is only needed if the user manually set his 'userlocale'
# in the keys.dat to a countrycode (e.g. 'de_CH')
translator.load(translation_path + user_lang)
except:
# as English is already the default language, we don't
# need to do anything. No need to translate.
pass
translationpath = os.path.join(
getattr(sys, '_MEIPASS', ''),
'translations',
'bitmessage_' + l10n.getTranslationLanguage()
)
translator.load(translationpath)
QtGui.QApplication.installTranslator(translator)
app.setStyleSheet("QStatusBar::item { border: 0px solid black }")

View File

@ -19,6 +19,7 @@ import helper_sent
from helper_sql import *
import tr
from debug import logger
import l10n
class objectProcessor(threading.Thread):
@ -421,8 +422,7 @@ class objectProcessor(threading.Thread):
del shared.ackdataForWhichImWatching[data[readPosition:]]
sqlExecute('UPDATE sent SET status=? WHERE ackdata=?',
'ackreceived', data[readPosition:])
shared.UISignalQueue.put(('updateSentItemStatusByAckdata', (data[readPosition:], tr.translateText("MainWindow",'Acknowledgement of the message received. %1').arg(unicode(
time.strftime(shared.config.get('bitmessagesettings', 'timeformat'), time.localtime(int(time.time()))), 'utf-8')))))
shared.UISignalQueue.put(('updateSentItemStatusByAckdata', (data[readPosition:], tr.translateText("MainWindow",'Acknowledgement of the message received. %1').arg(l10n.formatTimestamp()))))
return
else:
logger.info('This was NOT an acknowledgement bound for me.')

View File

@ -13,6 +13,7 @@ from debug import logger
from helper_sql import *
import helper_inbox
from helper_generic import addDataPadding
import l10n
# This thread, of which there is only one, does the heavy lifting:
# calculating POWs.
@ -440,8 +441,7 @@ class singleWorker(threading.Thread):
shared.broadcastToSendDataQueues((
streamNumber, 'advertiseobject', inventoryHash))
shared.UISignalQueue.put(('updateSentItemStatusByAckdata', (ackdata, tr.translateText("MainWindow", "Broadcast sent on %1").arg(unicode(
strftime(shared.config.get('bitmessagesettings', 'timeformat'), localtime(int(time.time()))), 'utf-8')))))
shared.UISignalQueue.put(('updateSentItemStatusByAckdata', (ackdata, tr.translateText("MainWindow", "Broadcast sent on %1").arg(l10n.formatTimestamp()))))
# Update the status of the message in the 'sent' table to have
# a 'broadcastsent' status
@ -616,7 +616,7 @@ class singleWorker(threading.Thread):
if shared.isBitSetWithinBitfield(behaviorBitfield,30): # if receiver is a mobile device who expects that their address RIPE is included unencrypted on the front of the message..
if not shared.safeConfigGetBoolean('bitmessagesettings','willinglysendtomobile'): # if we are Not willing to include the receiver's RIPE hash on the message..
logger.info('The receiver is a mobile user but the sender (you) has not selected that you are willing to send to mobiles. Aborting send.')
shared.UISignalQueue.put(('updateSentItemStatusByAckdata',(ackdata,tr.translateText("MainWindow",'Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. %1').arg(unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'),localtime(int(time.time()))),'utf-8')))))
shared.UISignalQueue.put(('updateSentItemStatusByAckdata',(ackdata,tr.translateText("MainWindow",'Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. %1').arg(l10n.formatTimestamp()))))
# if the human changes their setting and then sends another message or restarts their client, this one will send at that time.
continue
readPosition += 4 # to bypass the bitfield of behaviors
@ -655,7 +655,7 @@ class singleWorker(threading.Thread):
'''UPDATE sent SET status='toodifficult' WHERE ackdata=? ''',
ackdata)
shared.UISignalQueue.put(('updateSentItemStatusByAckdata', (ackdata, tr.translateText("MainWindow", "Problem: The work demanded by the recipient (%1 and %2) is more difficult than you are willing to do.").arg(str(float(requiredAverageProofOfWorkNonceTrialsPerByte) / shared.networkDefaultProofOfWorkNonceTrialsPerByte)).arg(str(float(
requiredPayloadLengthExtraBytes) / shared.networkDefaultPayloadLengthExtraBytes)).arg(unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'), localtime(int(time.time()))), 'utf-8')))))
requiredPayloadLengthExtraBytes) / shared.networkDefaultPayloadLengthExtraBytes)).arg(l10n.formatTimestamp()))))
continue
else: # if we are sending a message to ourselves or a chan..
with shared.printLock:
@ -666,7 +666,7 @@ class singleWorker(threading.Thread):
privEncryptionKeyBase58 = shared.config.get(
toaddress, 'privencryptionkey')
except Exception as err:
shared.UISignalQueue.put(('updateSentItemStatusByAckdata',(ackdata,tr.translateText("MainWindow",'Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. %1').arg(unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'),localtime(int(time.time()))),'utf-8')))))
shared.UISignalQueue.put(('updateSentItemStatusByAckdata',(ackdata,tr.translateText("MainWindow",'Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. %1').arg(l10n.formatTimestamp()))))
with shared.printLock:
sys.stderr.write(
'Error within sendMsg. Could not read the keys from the keys.dat file for our own address. %s\n' % err)
@ -803,7 +803,7 @@ class singleWorker(threading.Thread):
encrypted = highlevelcrypto.encrypt(payload,"04"+pubEncryptionKeyBase256.encode('hex'))
except:
sqlExecute('''UPDATE sent SET status='badkey' WHERE ackdata=?''', ackdata)
shared.UISignalQueue.put(('updateSentItemStatusByAckdata',(ackdata,tr.translateText("MainWindow",'Problem: The recipient\'s encryption key is no good. Could not encrypt message. %1').arg(unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'),localtime(int(time.time()))),'utf-8')))))
shared.UISignalQueue.put(('updateSentItemStatusByAckdata',(ackdata,tr.translateText("MainWindow",'Problem: The recipient\'s encryption key is no good. Could not encrypt message. %1').arg(l10n.formatTimestamp()))))
continue
encryptedPayload = embeddedTime + encodeVarint(toStreamNumber) + encrypted
target = 2**64 / ((len(encryptedPayload)+requiredPayloadLengthExtraBytes+8) * requiredAverageProofOfWorkNonceTrialsPerByte)
@ -828,12 +828,10 @@ class singleWorker(threading.Thread):
objectType, toStreamNumber, encryptedPayload, int(time.time()),'')
shared.inventorySets[toStreamNumber].add(inventoryHash)
if shared.config.has_section(toaddress):
shared.UISignalQueue.put(('updateSentItemStatusByAckdata', (ackdata, tr.translateText("MainWindow", "Message sent. Sent on %1").arg(unicode(
strftime(shared.config.get('bitmessagesettings', 'timeformat'), localtime(int(time.time()))), 'utf-8')))))
shared.UISignalQueue.put(('updateSentItemStatusByAckdata', (ackdata, tr.translateText("MainWindow", "Message sent. Sent on %1").arg(l10n.formatTimestamp()))))
else:
# not sending to a chan or one of my addresses
shared.UISignalQueue.put(('updateSentItemStatusByAckdata', (ackdata, tr.translateText("MainWindow", "Message sent. Waiting for acknowledgement. Sent on %1").arg(unicode(
strftime(shared.config.get('bitmessagesettings', 'timeformat'), localtime(int(time.time()))), 'utf-8')))))
shared.UISignalQueue.put(('updateSentItemStatusByAckdata', (ackdata, tr.translateText("MainWindow", "Message sent. Waiting for acknowledgement. Sent on %1").arg(l10n.formatTimestamp()))))
print 'Broadcasting inv for my msg(within sendmsg function):', inventoryHash.encode('hex')
shared.broadcastToSendDataQueues((
toStreamNumber, 'advertiseobject', inventoryHash))
@ -926,8 +924,7 @@ class singleWorker(threading.Thread):
shared.UISignalQueue.put((
'updateStatusBar', tr.translateText("MainWindow",'Broacasting the public key request. This program will auto-retry if they are offline.')))
shared.UISignalQueue.put(('updateSentItemStatusByHash', (ripe, tr.translateText("MainWindow",'Sending public key request. Waiting for reply. Requested at %1').arg(unicode(
strftime(shared.config.get('bitmessagesettings', 'timeformat'), localtime(int(time.time()))), 'utf-8')))))
shared.UISignalQueue.put(('updateSentItemStatusByHash', (ripe, tr.translateText("MainWindow",'Sending public key request. Waiting for reply. Requested at %1').arg(l10n.formatTimestamp()))))
def generateFullAckMessage(self, ackdata, toStreamNumber):
embeddedTime = pack('>Q', (int(time.time()) + random.randrange(

42
src/l10n.py Normal file
View File

@ -0,0 +1,42 @@
import logging
import time
import shared
#logger = logging.getLogger(__name__)
logger = logging.getLogger('file_only')
try:
import locale
encoding = locale.getpreferredencoding(False)
language = locale.getlocale()[0] or locale.getdefaultlocale()[0]
except:
logger.exception('Could not determine language or encoding')
if not encoding:
encoding = 'ISO8859-1'
language = 'en_US'
time_format = shared.config.get('bitmessagesettings', 'timeformat')
def formatTimestamp(timestamp = None, as_unicode = True):
if timestamp and isinstance(timestamp, (float, int)):
timestring = time.strftime(time_format, time.localtime(timestamp))
else:
timestring = time.strftime(time_format)
if as_unicode:
return unicode(timestring, encoding)
return timestring
def getTranslationLanguage():
userlocale = None
if shared.config.has_option('bitmessagesettings', 'userlocale'):
userlocale = shared.config.get('bitmessagesettings', 'userlocale')
if userlocale in [None, '', 'system']:
return language
return userlocale