separate core and gui in different modules

This commit is contained in:
thomasv 2013-03-02 12:26:21 +01:00
parent f9f59d8dff
commit a563091f30
17 changed files with 53 additions and 1072 deletions

View File

@ -38,6 +38,8 @@ if os.path.exists("lib"):
import imp import imp
fp, pathname, description = imp.find_module('lib') fp, pathname, description = imp.find_module('lib')
imp.load_module('electrum', fp, pathname, description) imp.load_module('electrum', fp, pathname, description)
fp, pathname, description = imp.find_module('gui')
imp.load_module('electrumGUI', fp, pathname, description)
from electrum import * from electrum import *
@ -115,17 +117,16 @@ if __name__ == '__main__':
#right GUI toolkit based the GUI command line option given #right GUI toolkit based the GUI command line option given
if cmd == 'gui': if cmd == 'gui':
pref_gui = config.get('gui','classic') pref_gui = config.get('gui','classic')
if pref_gui == 'gtk': if pref_gui == 'gtk':
import electrum.gui as gui import electrumGUI.gui as gui
elif pref_gui in ['classic', 'qt']: elif pref_gui in ['classic', 'qt']:
import electrum.gui_qt as gui import electrumGUI.gui_qt as gui
elif pref_gui == 'lite': elif pref_gui == 'lite':
import electrum.gui_lite as gui import electrumGUI.gui_lite as gui
elif pref_gui == 'text': elif pref_gui == 'text':
import electrum.gui_text as gui import electrumGUI.gui_text as gui
elif pref_gui == 'android': elif pref_gui == 'android':
import electrum.gui_android as gui import electrumGUI.gui_android as gui
else: else:
sys.exit("Error: Unknown GUI: " + pref_gui ) sys.exit("Error: Unknown GUI: " + pref_gui )
@ -136,7 +137,6 @@ if __name__ == '__main__':
if interface.is_connected: if interface.is_connected:
interface.send([('server.peers.subscribe',[])]) interface.send([('server.peers.subscribe',[])])
set_language(config.get('language'))
gui = gui.ElectrumGui(wallet, config) gui = gui.ElectrumGui(wallet, config)
found = config.wallet_file_exists found = config.wallet_file_exists

1
gui/__init__.py Normal file
View File

@ -0,0 +1 @@
# do not remove this file

View File

@ -23,18 +23,18 @@ import pygtk
pygtk.require('2.0') pygtk.require('2.0')
import gtk, gobject import gtk, gobject
from decimal import Decimal from decimal import Decimal
from util import print_error from electrum.util import print_error
from bitcoin import is_valid from electrum import is_valid
from electrum import mnemonic
import pyqrnative, mnemonic import pyqrnative
gtk.gdk.threads_init() gtk.gdk.threads_init()
APP_NAME = "Electrum" APP_NAME = "Electrum"
import platform import platform
MONOSPACE_FONT = 'Lucida Console' if platform.system() == 'Windows' else 'monospace' MONOSPACE_FONT = 'Lucida Console' if platform.system() == 'Windows' else 'monospace'
from wallet import format_satoshis from electrum.util import format_satoshis
from interface import DEFAULT_SERVERS from electrum.interface import DEFAULT_SERVERS
def numbify(entry, is_int = False): def numbify(entry, is_int = False):
text = entry.get_text().strip() text = entry.get_text().strip()

View File

@ -21,10 +21,9 @@
import android import android
from electrum import SimpleConfig, Interface, WalletSynchronizer, Wallet, format_satoshis, mnemonic_encode, mnemonic_decode from electrum import SimpleConfig, Interface, WalletSynchronizer, Wallet, format_satoshis, mnemonic_encode, mnemonic_decode, is_valid
from decimal import Decimal from decimal import Decimal
import datetime, re import datetime, re
from bitcoin import is_valid

View File

@ -12,8 +12,8 @@ except ImportError:
sys.exit(0) sys.exit(0)
from decimal import Decimal as D from decimal import Decimal as D
from util import get_resource_path as rsrc from electrum.util import get_resource_path as rsrc
from bitcoin import is_valid from electrum.bitcoin import is_valid
from i18n import _ from i18n import _
import decimal import decimal
import exchange_rate import exchange_rate
@ -21,16 +21,16 @@ import os.path
import random import random
import re import re
import time import time
import wallet from electrum import wallet
import webbrowser import webbrowser
import history_widget import history_widget
import receiving_widget import receiving_widget
import util from electrum import util
import csv import csv
import datetime import datetime
from version import ELECTRUM_VERSION as electrum_version from electrum.version import ELECTRUM_VERSION as electrum_version
from wallet import format_satoshis from electrum.util import format_satoshis, age
import gui_qt import gui_qt
import shutil import shutil
@ -581,7 +581,6 @@ class MiniWindow(QDialog):
def update_history(self, tx_history): def update_history(self, tx_history):
from util import format_satoshis, age
self.history_list.empty() self.history_list.empty()

View File

@ -17,9 +17,9 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import sys, time, datetime, re import sys, time, datetime, re
from i18n import _ from i18n import _, set_language
from util import print_error from electrum.util import print_error
import os.path, json, util, ast import os.path, json, ast
try: try:
import PyQt4 import PyQt4
@ -30,16 +30,18 @@ from PyQt4.QtGui import *
from PyQt4.QtCore import * from PyQt4.QtCore import *
import PyQt4.QtCore as QtCore import PyQt4.QtCore as QtCore
import PyQt4.QtGui as QtGui import PyQt4.QtGui as QtGui
from interface import DEFAULT_SERVERS from electrum.interface import DEFAULT_SERVERS
try: try:
import icons_rc import icons_rc
except: except:
sys.exit("Error: Could not import icons_rc.py, please generate it with: 'pyrcc4 icons.qrc -o lib/icons_rc.py'") sys.exit("Error: Could not import icons_rc.py, please generate it with: 'pyrcc4 icons.qrc -o lib/icons_rc.py'")
from wallet import format_satoshis from electrum.wallet import format_satoshis
from bitcoin import Transaction, is_valid from electrum.bitcoin import Transaction, is_valid
import bmp, mnemonic, pyqrnative, qrscanner from electrum import mnemonic
import bmp, pyqrnative, qrscanner
import exchange_rate import exchange_rate
from decimal import Decimal from decimal import Decimal
@ -59,7 +61,7 @@ else:
ALIAS_REGEXP = '^(|([\w\-\.]+)@)((\w[\w\-]+\.)+[\w\-]+)$' ALIAS_REGEXP = '^(|([\w\-\.]+)@)((\w[\w\-]+\.)+[\w\-]+)$'
from version import ELECTRUM_VERSION from electrum import ELECTRUM_VERSION
import re import re
class UpdateLabel(QtGui.QLabel): class UpdateLabel(QtGui.QLabel):
@ -404,6 +406,8 @@ class ElectrumWindow(QMainWindow):
self.receive_tab_mode = config.get('qt_receive_tab_mode', 0) self.receive_tab_mode = config.get('qt_receive_tab_mode', 0)
self.merchant_name = config.get('merchant_name', 'Invoice') self.merchant_name = config.get('merchant_name', 'Invoice')
set_language(config.get('language'))
self.qr_window = None self.qr_window = None
self.funds_error = False self.funds_error = False
self.completions = QStringListModel() self.completions = QStringListModel()
@ -1316,7 +1320,7 @@ class ElectrumWindow(QMainWindow):
def create_console_tab(self): def create_console_tab(self):
from qt_console import Console from qt_console import Console
import util, bitcoin, commands from electrum import util, bitcoin, commands
self.console = console = Console() self.console = console = Console()
console.updateNamespace({'wallet' : self.wallet, 'interface' : self.wallet.interface, 'gui':self}) console.updateNamespace({'wallet' : self.wallet, 'interface' : self.wallet.interface, 'gui':self})
console.updateNamespace({'util' : util, 'bitcoin':bitcoin}) console.updateNamespace({'util' : util, 'bitcoin':bitcoin})

View File

@ -2,8 +2,8 @@ import curses, datetime
from decimal import Decimal from decimal import Decimal
_ = lambda x:x _ = lambda x:x
#from i18n import _ #from i18n import _
from util import format_satoshis, set_verbosity from electrum.util import format_satoshis, set_verbosity
from bitcoin import is_valid from electrum.bitcoin import is_valid
import tty, sys import tty, sys

View File

@ -1,4 +1,4 @@
from util import print_error from electrum.util import print_error
try: try:
import zbar import zbar

View File

@ -4,7 +4,7 @@ import sys, os, re
import traceback import traceback
from PyQt4 import QtCore from PyQt4 import QtCore
from PyQt4 import QtGui from PyQt4 import QtGui
import util from electrum import util

View File

@ -1,13 +1,12 @@
from version import ELECTRUM_VERSION from version import ELECTRUM_VERSION
from util import format_satoshis, print_msg, print_json, print_error, set_verbosity from util import format_satoshis, print_msg, print_json, print_error, set_verbosity
from i18n import set_language
from wallet import WalletSynchronizer from wallet import WalletSynchronizer
from wallet_factory import WalletFactory as Wallet from wallet_factory import WalletFactory as Wallet
from verifier import WalletVerifier from verifier import WalletVerifier
from interface import Interface, pick_random_server, DEFAULT_SERVERS from interface import Interface, pick_random_server, DEFAULT_SERVERS
from simple_config import SimpleConfig from simple_config import SimpleConfig
import bitcoin import bitcoin
from bitcoin import Transaction, EC_KEY from bitcoin import Transaction, EC_KEY, is_valid
from mnemonic import mn_encode as mnemonic_encode from mnemonic import mn_encode as mnemonic_encode
from mnemonic import mn_decode as mnemonic_decode from mnemonic import mn_decode as mnemonic_decode
from commands import protected_commands, known_commands, offline_commands, Commands from commands import protected_commands, known_commands, offline_commands, Commands

View File

@ -1,59 +0,0 @@
from PyQt4.QtCore import SIGNAL
import decimal
import httplib
import json
import threading
class Exchanger(threading.Thread):
def __init__(self, parent):
threading.Thread.__init__(self)
self.daemon = True
self.parent = parent
self.quote_currencies = None
self.lock = threading.Lock()
# Do price discovery
self.start()
def exchange(self, btc_amount, quote_currency):
with self.lock:
if self.quote_currencies is None:
return None
quote_currencies = self.quote_currencies.copy()
if quote_currency not in quote_currencies:
return None
return btc_amount * quote_currencies[quote_currency]
def run(self):
self.discovery()
def discovery(self):
try:
connection = httplib.HTTPConnection('blockchain.info')
connection.request("GET", "/ticker")
except:
return
response = connection.getresponse()
if response.reason == httplib.responses[httplib.NOT_FOUND]:
return
response = json.loads(response.read())
quote_currencies = {}
try:
for r in response:
quote_currencies[r] = self._lookup_rate(response, r)
with self.lock:
self.quote_currencies = quote_currencies
self.parent.emit(SIGNAL("refresh_balance()"))
except KeyError:
pass
def get_currencies(self):
return [] if self.quote_currencies == None else sorted(self.quote_currencies.keys())
def _lookup_rate(self, response, quote_id):
return decimal.Decimal(str(response[str(quote_id)]["15m"]))
if __name__ == "__main__":
exch = Exchanger(("BRL", "CNY", "EUR", "GBP", "RUB", "USD"))
print exch.exchange(1, "EUR")

View File

@ -1,962 +0,0 @@
import math
#from PIL import Image, ImageDraw
#QRCode for Python
#
#Ported from the Javascript library by Sam Curren
#
#QRCode for Javascript
#http://d-project.googlecode.com/svn/trunk/misc/qrcode/js/qrcode.js
#
#Copyright (c) 2009 Kazuhiko Arase
#
#URL: http://www.d-project.com/
#
#Licensed under the MIT license:
# http://www.opensource.org/licenses/mit-license.php
#
# The word "QR Code" is registered trademark of
# DENSO WAVE INCORPORATED
# http://www.denso-wave.com/qrcode/faqpatent-e.html
class QR8bitByte:
def __init__(self, data):
self.mode = QRMode.MODE_8BIT_BYTE
self.data = data
def getLength(self):
return len(self.data)
def write(self, buffer):
for i in range(len(self.data)):
#// not JIS ...
buffer.put(ord(self.data[i]), 8)
def __repr__(self):
return self.data
class QRCode:
def __init__(self, typeNumber, errorCorrectLevel):
self.typeNumber = typeNumber
self.errorCorrectLevel = errorCorrectLevel
self.modules = None
self.moduleCount = 0
self.dataCache = None
self.dataList = []
def addData(self, data):
newData = QR8bitByte(data)
self.dataList.append(newData)
self.dataCache = None
def isDark(self, row, col):
if (row < 0 or self.moduleCount <= row or col < 0 or self.moduleCount <= col):
raise Exception("%s,%s - %s" % (row, col, self.moduleCount))
return self.modules[row][col]
def getModuleCount(self):
return self.moduleCount
def make(self):
self.makeImpl(False, self.getBestMaskPattern() )
def makeImpl(self, test, maskPattern):
self.moduleCount = self.typeNumber * 4 + 17
self.modules = [None for x in range(self.moduleCount)]
for row in range(self.moduleCount):
self.modules[row] = [None for x in range(self.moduleCount)]
for col in range(self.moduleCount):
self.modules[row][col] = None #//(col + row) % 3;
self.setupPositionProbePattern(0, 0)
self.setupPositionProbePattern(self.moduleCount - 7, 0)
self.setupPositionProbePattern(0, self.moduleCount - 7)
self.setupPositionAdjustPattern()
self.setupTimingPattern()
self.setupTypeInfo(test, maskPattern)
if (self.typeNumber >= 7):
self.setupTypeNumber(test)
if (self.dataCache == None):
self.dataCache = QRCode.createData(self.typeNumber, self.errorCorrectLevel, self.dataList)
self.mapData(self.dataCache, maskPattern)
def setupPositionProbePattern(self, row, col):
for r in range(-1, 8):
if (row + r <= -1 or self.moduleCount <= row + r): continue
for c in range(-1, 8):
if (col + c <= -1 or self.moduleCount <= col + c): continue
if ( (0 <= r and r <= 6 and (c == 0 or c == 6) )
or (0 <= c and c <= 6 and (r == 0 or r == 6) )
or (2 <= r and r <= 4 and 2 <= c and c <= 4) ):
self.modules[row + r][col + c] = True;
else:
self.modules[row + r][col + c] = False;
def getBestMaskPattern(self):
minLostPoint = 0
pattern = 0
for i in range(8):
self.makeImpl(True, i);
lostPoint = QRUtil.getLostPoint(self);
if (i == 0 or minLostPoint > lostPoint):
minLostPoint = lostPoint
pattern = i
return pattern
def setupTimingPattern(self):
for r in range(8, self.moduleCount - 8):
if (self.modules[r][6] != None):
continue
self.modules[r][6] = (r % 2 == 0)
for c in range(8, self.moduleCount - 8):
if (self.modules[6][c] != None):
continue
self.modules[6][c] = (c % 2 == 0)
def setupPositionAdjustPattern(self):
pos = QRUtil.getPatternPosition(self.typeNumber)
for i in range(len(pos)):
for j in range(len(pos)):
row = pos[i]
col = pos[j]
if (self.modules[row][col] != None):
continue
for r in range(-2, 3):
for c in range(-2, 3):
if (r == -2 or r == 2 or c == -2 or c == 2 or (r == 0 and c == 0) ):
self.modules[row + r][col + c] = True
else:
self.modules[row + r][col + c] = False
def setupTypeNumber(self, test):
bits = QRUtil.getBCHTypeNumber(self.typeNumber)
for i in range(18):
mod = (not test and ( (bits >> i) & 1) == 1)
self.modules[i // 3][i % 3 + self.moduleCount - 8 - 3] = mod;
for i in range(18):
mod = (not test and ( (bits >> i) & 1) == 1)
self.modules[i % 3 + self.moduleCount - 8 - 3][i // 3] = mod;
def setupTypeInfo(self, test, maskPattern):
data = (self.errorCorrectLevel << 3) | maskPattern
bits = QRUtil.getBCHTypeInfo(data)
#// vertical
for i in range(15):
mod = (not test and ( (bits >> i) & 1) == 1)
if (i < 6):
self.modules[i][8] = mod
elif (i < 8):
self.modules[i + 1][8] = mod
else:
self.modules[self.moduleCount - 15 + i][8] = mod
#// horizontal
for i in range(15):
mod = (not test and ( (bits >> i) & 1) == 1);
if (i < 8):
self.modules[8][self.moduleCount - i - 1] = mod
elif (i < 9):
self.modules[8][15 - i - 1 + 1] = mod
else:
self.modules[8][15 - i - 1] = mod
#// fixed module
self.modules[self.moduleCount - 8][8] = (not test)
def mapData(self, data, maskPattern):
inc = -1
row = self.moduleCount - 1
bitIndex = 7
byteIndex = 0
for col in range(self.moduleCount - 1, 0, -2):
if (col == 6): col-=1
while (True):
for c in range(2):
if (self.modules[row][col - c] == None):
dark = False
if (byteIndex < len(data)):
dark = ( ( (data[byteIndex] >> bitIndex) & 1) == 1)
mask = QRUtil.getMask(maskPattern, row, col - c)
if (mask):
dark = not dark
self.modules[row][col - c] = dark
bitIndex-=1
if (bitIndex == -1):
byteIndex+=1
bitIndex = 7
row += inc
if (row < 0 or self.moduleCount <= row):
row -= inc
inc = -inc
break
PAD0 = 0xEC
PAD1 = 0x11
@staticmethod
def createData(typeNumber, errorCorrectLevel, dataList):
rsBlocks = QRRSBlock.getRSBlocks(typeNumber, errorCorrectLevel)
buffer = QRBitBuffer();
for i in range(len(dataList)):
data = dataList[i]
buffer.put(data.mode, 4)
buffer.put(data.getLength(), QRUtil.getLengthInBits(data.mode, typeNumber) )
data.write(buffer)
#// calc num max data.
totalDataCount = 0;
for i in range(len(rsBlocks)):
totalDataCount += rsBlocks[i].dataCount
if (buffer.getLengthInBits() > totalDataCount * 8):
raise Exception("code length overflow. ("
+ buffer.getLengthInBits()
+ ">"
+ totalDataCount * 8
+ ")")
#// end code
if (buffer.getLengthInBits() + 4 <= totalDataCount * 8):
buffer.put(0, 4)
#// padding
while (buffer.getLengthInBits() % 8 != 0):
buffer.putBit(False)
#// padding
while (True):
if (buffer.getLengthInBits() >= totalDataCount * 8):
break
buffer.put(QRCode.PAD0, 8)
if (buffer.getLengthInBits() >= totalDataCount * 8):
break
buffer.put(QRCode.PAD1, 8)
return QRCode.createBytes(buffer, rsBlocks)
@staticmethod
def createBytes(buffer, rsBlocks):
offset = 0
maxDcCount = 0
maxEcCount = 0
dcdata = [0 for x in range(len(rsBlocks))]
ecdata = [0 for x in range(len(rsBlocks))]
for r in range(len(rsBlocks)):
dcCount = rsBlocks[r].dataCount
ecCount = rsBlocks[r].totalCount - dcCount
maxDcCount = max(maxDcCount, dcCount)
maxEcCount = max(maxEcCount, ecCount)
dcdata[r] = [0 for x in range(dcCount)]
for i in range(len(dcdata[r])):
dcdata[r][i] = 0xff & buffer.buffer[i + offset]
offset += dcCount
rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount)
rawPoly = QRPolynomial(dcdata[r], rsPoly.getLength() - 1)
modPoly = rawPoly.mod(rsPoly)
ecdata[r] = [0 for x in range(rsPoly.getLength()-1)]
for i in range(len(ecdata[r])):
modIndex = i + modPoly.getLength() - len(ecdata[r])
if (modIndex >= 0):
ecdata[r][i] = modPoly.get(modIndex)
else:
ecdata[r][i] = 0
totalCodeCount = 0
for i in range(len(rsBlocks)):
totalCodeCount += rsBlocks[i].totalCount
data = [None for x in range(totalCodeCount)]
index = 0
for i in range(maxDcCount):
for r in range(len(rsBlocks)):
if (i < len(dcdata[r])):
data[index] = dcdata[r][i]
index+=1
for i in range(maxEcCount):
for r in range(len(rsBlocks)):
if (i < len(ecdata[r])):
data[index] = ecdata[r][i]
index+=1
return data
class QRMode:
MODE_NUMBER = 1 << 0
MODE_ALPHA_NUM = 1 << 1
MODE_8BIT_BYTE = 1 << 2
MODE_KANJI = 1 << 3
class QRErrorCorrectLevel:
L = 1
M = 0
Q = 3
H = 2
class QRMaskPattern:
PATTERN000 = 0
PATTERN001 = 1
PATTERN010 = 2
PATTERN011 = 3
PATTERN100 = 4
PATTERN101 = 5
PATTERN110 = 6
PATTERN111 = 7
class QRUtil(object):
PATTERN_POSITION_TABLE = [
[],
[6, 18],
[6, 22],
[6, 26],
[6, 30],
[6, 34],
[6, 22, 38],
[6, 24, 42],
[6, 26, 46],
[6, 28, 50],
[6, 30, 54],
[6, 32, 58],
[6, 34, 62],
[6, 26, 46, 66],
[6, 26, 48, 70],
[6, 26, 50, 74],
[6, 30, 54, 78],
[6, 30, 56, 82],
[6, 30, 58, 86],
[6, 34, 62, 90],
[6, 28, 50, 72, 94],
[6, 26, 50, 74, 98],
[6, 30, 54, 78, 102],
[6, 28, 54, 80, 106],
[6, 32, 58, 84, 110],
[6, 30, 58, 86, 114],
[6, 34, 62, 90, 118],
[6, 26, 50, 74, 98, 122],
[6, 30, 54, 78, 102, 126],
[6, 26, 52, 78, 104, 130],
[6, 30, 56, 82, 108, 134],
[6, 34, 60, 86, 112, 138],
[6, 30, 58, 86, 114, 142],
[6, 34, 62, 90, 118, 146],
[6, 30, 54, 78, 102, 126, 150],
[6, 24, 50, 76, 102, 128, 154],
[6, 28, 54, 80, 106, 132, 158],
[6, 32, 58, 84, 110, 136, 162],
[6, 26, 54, 82, 110, 138, 166],
[6, 30, 58, 86, 114, 142, 170]
]
G15 = (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0)
G18 = (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0)
G15_MASK = (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1)
@staticmethod
def getBCHTypeInfo(data):
d = data << 10;
while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) >= 0):
d ^= (QRUtil.G15 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) ) )
return ( (data << 10) | d) ^ QRUtil.G15_MASK
@staticmethod
def getBCHTypeNumber(data):
d = data << 12;
while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) >= 0):
d ^= (QRUtil.G18 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) ) )
return (data << 12) | d
@staticmethod
def getBCHDigit(data):
digit = 0;
while (data != 0):
digit += 1
data >>= 1
return digit
@staticmethod
def getPatternPosition(typeNumber):
return QRUtil.PATTERN_POSITION_TABLE[typeNumber - 1]
@staticmethod
def getMask(maskPattern, i, j):
if maskPattern == QRMaskPattern.PATTERN000 : return (i + j) % 2 == 0
if maskPattern == QRMaskPattern.PATTERN001 : return i % 2 == 0
if maskPattern == QRMaskPattern.PATTERN010 : return j % 3 == 0
if maskPattern == QRMaskPattern.PATTERN011 : return (i + j) % 3 == 0
if maskPattern == QRMaskPattern.PATTERN100 : return (math.floor(i / 2) + math.floor(j / 3) ) % 2 == 0
if maskPattern == QRMaskPattern.PATTERN101 : return (i * j) % 2 + (i * j) % 3 == 0
if maskPattern == QRMaskPattern.PATTERN110 : return ( (i * j) % 2 + (i * j) % 3) % 2 == 0
if maskPattern == QRMaskPattern.PATTERN111 : return ( (i * j) % 3 + (i + j) % 2) % 2 == 0
raise Exception("bad maskPattern:" + maskPattern);
@staticmethod
def getErrorCorrectPolynomial(errorCorrectLength):
a = QRPolynomial([1], 0);
for i in range(errorCorrectLength):
a = a.multiply(QRPolynomial([1, QRMath.gexp(i)], 0) )
return a
@staticmethod
def getLengthInBits(mode, type):
if 1 <= type and type < 10:
#// 1 - 9
if mode == QRMode.MODE_NUMBER : return 10
if mode == QRMode.MODE_ALPHA_NUM : return 9
if mode == QRMode.MODE_8BIT_BYTE : return 8
if mode == QRMode.MODE_KANJI : return 8
raise Exception("mode:" + mode)
elif (type < 27):
#// 10 - 26
if mode == QRMode.MODE_NUMBER : return 12
if mode == QRMode.MODE_ALPHA_NUM : return 11
if mode == QRMode.MODE_8BIT_BYTE : return 16
if mode == QRMode.MODE_KANJI : return 10
raise Exception("mode:" + mode)
elif (type < 41):
#// 27 - 40
if mode == QRMode.MODE_NUMBER : return 14
if mode == QRMode.MODE_ALPHA_NUM : return 13
if mode == QRMode.MODE_8BIT_BYTE : return 16
if mode == QRMode.MODE_KANJI : return 12
raise Exception("mode:" + mode)
else:
raise Exception("type:" + type)
@staticmethod
def getLostPoint(qrCode):
moduleCount = qrCode.getModuleCount();
lostPoint = 0;
#// LEVEL1
for row in range(moduleCount):
for col in range(moduleCount):
sameCount = 0;
dark = qrCode.isDark(row, col);
for r in range(-1, 2):
if (row + r < 0 or moduleCount <= row + r):
continue
for c in range(-1, 2):
if (col + c < 0 or moduleCount <= col + c):
continue
if (r == 0 and c == 0):
continue
if (dark == qrCode.isDark(row + r, col + c) ):
sameCount+=1
if (sameCount > 5):
lostPoint += (3 + sameCount - 5)
#// LEVEL2
for row in range(moduleCount - 1):
for col in range(moduleCount - 1):
count = 0;
if (qrCode.isDark(row, col ) ): count+=1
if (qrCode.isDark(row + 1, col ) ): count+=1
if (qrCode.isDark(row, col + 1) ): count+=1
if (qrCode.isDark(row + 1, col + 1) ): count+=1
if (count == 0 or count == 4):
lostPoint += 3
#// LEVEL3
for row in range(moduleCount):
for col in range(moduleCount - 6):
if (qrCode.isDark(row, col)
and not qrCode.isDark(row, col + 1)
and qrCode.isDark(row, col + 2)
and qrCode.isDark(row, col + 3)
and qrCode.isDark(row, col + 4)
and not qrCode.isDark(row, col + 5)
and qrCode.isDark(row, col + 6) ):
lostPoint += 40
for col in range(moduleCount):
for row in range(moduleCount - 6):
if (qrCode.isDark(row, col)
and not qrCode.isDark(row + 1, col)
and qrCode.isDark(row + 2, col)
and qrCode.isDark(row + 3, col)
and qrCode.isDark(row + 4, col)
and not qrCode.isDark(row + 5, col)
and qrCode.isDark(row + 6, col) ):
lostPoint += 40
#// LEVEL4
darkCount = 0;
for col in range(moduleCount):
for row in range(moduleCount):
if (qrCode.isDark(row, col) ):
darkCount+=1
ratio = abs(100 * darkCount / moduleCount / moduleCount - 50) / 5
lostPoint += ratio * 10
return lostPoint
class QRMath:
@staticmethod
def glog(n):
if (n < 1):
raise Exception("glog(" + n + ")")
return LOG_TABLE[n];
@staticmethod
def gexp(n):
while n < 0:
n += 255
while n >= 256:
n -= 255
return EXP_TABLE[n];
EXP_TABLE = [x for x in range(256)]
LOG_TABLE = [x for x in range(256)]
for i in range(8):
EXP_TABLE[i] = 1 << i;
for i in range(8, 256):
EXP_TABLE[i] = EXP_TABLE[i - 4] ^ EXP_TABLE[i - 5] ^ EXP_TABLE[i - 6] ^ EXP_TABLE[i - 8]
for i in range(255):
LOG_TABLE[EXP_TABLE[i] ] = i
class QRPolynomial:
def __init__(self, num, shift):
if (len(num) == 0):
raise Exception(num.length + "/" + shift)
offset = 0
while offset < len(num) and num[offset] == 0:
offset += 1
self.num = [0 for x in range(len(num)-offset+shift)]
for i in range(len(num) - offset):
self.num[i] = num[i + offset]
def get(self, index):
return self.num[index]
def getLength(self):
return len(self.num)
def multiply(self, e):
num = [0 for x in range(self.getLength() + e.getLength() - 1)];
for i in range(self.getLength()):
for j in range(e.getLength()):
num[i + j] ^= QRMath.gexp(QRMath.glog(self.get(i) ) + QRMath.glog(e.get(j) ) )
return QRPolynomial(num, 0);
def mod(self, e):
if (self.getLength() - e.getLength() < 0):
return self;
ratio = QRMath.glog(self.get(0) ) - QRMath.glog(e.get(0) )
num = [0 for x in range(self.getLength())]
for i in range(self.getLength()):
num[i] = self.get(i);
for i in range(e.getLength()):
num[i] ^= QRMath.gexp(QRMath.glog(e.get(i) ) + ratio)
# recursive call
return QRPolynomial(num, 0).mod(e);
class QRRSBlock:
RS_BLOCK_TABLE = [
#// L
#// M
#// Q
#// H
#// 1
[1, 26, 19],
[1, 26, 16],
[1, 26, 13],
[1, 26, 9],
#// 2
[1, 44, 34],
[1, 44, 28],
[1, 44, 22],
[1, 44, 16],
#// 3
[1, 70, 55],
[1, 70, 44],
[2, 35, 17],
[2, 35, 13],
#// 4
[1, 100, 80],
[2, 50, 32],
[2, 50, 24],
[4, 25, 9],
#// 5
[1, 134, 108],
[2, 67, 43],
[2, 33, 15, 2, 34, 16],
[2, 33, 11, 2, 34, 12],
#// 6
[2, 86, 68],
[4, 43, 27],
[4, 43, 19],
[4, 43, 15],
#// 7
[2, 98, 78],
[4, 49, 31],
[2, 32, 14, 4, 33, 15],
[4, 39, 13, 1, 40, 14],
#// 8
[2, 121, 97],
[2, 60, 38, 2, 61, 39],
[4, 40, 18, 2, 41, 19],
[4, 40, 14, 2, 41, 15],
#// 9
[2, 146, 116],
[3, 58, 36, 2, 59, 37],
[4, 36, 16, 4, 37, 17],
[4, 36, 12, 4, 37, 13],
#// 10
[2, 86, 68, 2, 87, 69],
[4, 69, 43, 1, 70, 44],
[6, 43, 19, 2, 44, 20],
[6, 43, 15, 2, 44, 16],
# 11
[4, 101, 81],
[1, 80, 50, 4, 81, 51],
[4, 50, 22, 4, 51, 23],
[3, 36, 12, 8, 37, 13],
# 12
[2, 116, 92, 2, 117, 93],
[6, 58, 36, 2, 59, 37],
[4, 46, 20, 6, 47, 21],
[7, 42, 14, 4, 43, 15],
# 13
[4, 133, 107],
[8, 59, 37, 1, 60, 38],
[8, 44, 20, 4, 45, 21],
[12, 33, 11, 4, 34, 12],
# 14
[3, 145, 115, 1, 146, 116],
[4, 64, 40, 5, 65, 41],
[11, 36, 16, 5, 37, 17],
[11, 36, 12, 5, 37, 13],
# 15
[5, 109, 87, 1, 110, 88],
[5, 65, 41, 5, 66, 42],
[5, 54, 24, 7, 55, 25],
[11, 36, 12],
# 16
[5, 122, 98, 1, 123, 99],
[7, 73, 45, 3, 74, 46],
[15, 43, 19, 2, 44, 20],
[3, 45, 15, 13, 46, 16],
# 17
[1, 135, 107, 5, 136, 108],
[10, 74, 46, 1, 75, 47],
[1, 50, 22, 15, 51, 23],
[2, 42, 14, 17, 43, 15],
# 18
[5, 150, 120, 1, 151, 121],
[9, 69, 43, 4, 70, 44],
[17, 50, 22, 1, 51, 23],
[2, 42, 14, 19, 43, 15],
# 19
[3, 141, 113, 4, 142, 114],
[3, 70, 44, 11, 71, 45],
[17, 47, 21, 4, 48, 22],
[9, 39, 13, 16, 40, 14],
# 20
[3, 135, 107, 5, 136, 108],
[3, 67, 41, 13, 68, 42],
[15, 54, 24, 5, 55, 25],
[15, 43, 15, 10, 44, 16],
# 21
[4, 144, 116, 4, 145, 117],
[17, 68, 42],
[17, 50, 22, 6, 51, 23],
[19, 46, 16, 6, 47, 17],
# 22
[2, 139, 111, 7, 140, 112],
[17, 74, 46],
[7, 54, 24, 16, 55, 25],
[34, 37, 13],
# 23
[4, 151, 121, 5, 152, 122],
[4, 75, 47, 14, 76, 48],
[11, 54, 24, 14, 55, 25],
[16, 45, 15, 14, 46, 16],
# 24
[6, 147, 117, 4, 148, 118],
[6, 73, 45, 14, 74, 46],
[11, 54, 24, 16, 55, 25],
[30, 46, 16, 2, 47, 17],
# 25
[8, 132, 106, 4, 133, 107],
[8, 75, 47, 13, 76, 48],
[7, 54, 24, 22, 55, 25],
[22, 45, 15, 13, 46, 16],
# 26
[10, 142, 114, 2, 143, 115],
[19, 74, 46, 4, 75, 47],
[28, 50, 22, 6, 51, 23],
[33, 46, 16, 4, 47, 17],
# 27
[8, 152, 122, 4, 153, 123],
[22, 73, 45, 3, 74, 46],
[8, 53, 23, 26, 54, 24],
[12, 45, 15, 28, 46, 16],
# 28
[3, 147, 117, 10, 148, 118],
[3, 73, 45, 23, 74, 46],
[4, 54, 24, 31, 55, 25],
[11, 45, 15, 31, 46, 16],
# 29
[7, 146, 116, 7, 147, 117],
[21, 73, 45, 7, 74, 46],
[1, 53, 23, 37, 54, 24],
[19, 45, 15, 26, 46, 16],
# 30
[5, 145, 115, 10, 146, 116],
[19, 75, 47, 10, 76, 48],
[15, 54, 24, 25, 55, 25],
[23, 45, 15, 25, 46, 16],
# 31
[13, 145, 115, 3, 146, 116],
[2, 74, 46, 29, 75, 47],
[42, 54, 24, 1, 55, 25],
[23, 45, 15, 28, 46, 16],
# 32
[17, 145, 115],
[10, 74, 46, 23, 75, 47],
[10, 54, 24, 35, 55, 25],
[19, 45, 15, 35, 46, 16],
# 33
[17, 145, 115, 1, 146, 116],
[14, 74, 46, 21, 75, 47],
[29, 54, 24, 19, 55, 25],
[11, 45, 15, 46, 46, 16],
# 34
[13, 145, 115, 6, 146, 116],
[14, 74, 46, 23, 75, 47],
[44, 54, 24, 7, 55, 25],
[59, 46, 16, 1, 47, 17],
# 35
[12, 151, 121, 7, 152, 122],
[12, 75, 47, 26, 76, 48],
[39, 54, 24, 14, 55, 25],
[22, 45, 15, 41, 46, 16],
# 36
[6, 151, 121, 14, 152, 122],
[6, 75, 47, 34, 76, 48],
[46, 54, 24, 10, 55, 25],
[2, 45, 15, 64, 46, 16],
# 37
[17, 152, 122, 4, 153, 123],
[29, 74, 46, 14, 75, 47],
[49, 54, 24, 10, 55, 25],
[24, 45, 15, 46, 46, 16],
# 38
[4, 152, 122, 18, 153, 123],
[13, 74, 46, 32, 75, 47],
[48, 54, 24, 14, 55, 25],
[42, 45, 15, 32, 46, 16],
# 39
[20, 147, 117, 4, 148, 118],
[40, 75, 47, 7, 76, 48],
[43, 54, 24, 22, 55, 25],
[10, 45, 15, 67, 46, 16],
# 40
[19, 148, 118, 6, 149, 119],
[18, 75, 47, 31, 76, 48],
[34, 54, 24, 34, 55, 25],
[20, 45, 15, 61, 46, 16]
]
def __init__(self, totalCount, dataCount):
self.totalCount = totalCount
self.dataCount = dataCount
@staticmethod
def getRSBlocks(typeNumber, errorCorrectLevel):
rsBlock = QRRSBlock.getRsBlockTable(typeNumber, errorCorrectLevel);
if rsBlock == None:
raise Exception("bad rs block @ typeNumber:" + typeNumber + "/errorCorrectLevel:" + errorCorrectLevel)
length = len(rsBlock) / 3
list = []
for i in range(length):
count = rsBlock[i * 3 + 0]
totalCount = rsBlock[i * 3 + 1]
dataCount = rsBlock[i * 3 + 2]
for j in range(count):
list.append(QRRSBlock(totalCount, dataCount))
return list;
@staticmethod
def getRsBlockTable(typeNumber, errorCorrectLevel):
if errorCorrectLevel == QRErrorCorrectLevel.L:
return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 0];
elif errorCorrectLevel == QRErrorCorrectLevel.M:
return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 1];
elif errorCorrectLevel == QRErrorCorrectLevel.Q:
return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 2];
elif errorCorrectLevel == QRErrorCorrectLevel.H:
return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 3];
else:
return None;
class QRBitBuffer:
def __init__(self):
self.buffer = []
self.length = 0
def __repr__(self):
return ".".join([str(n) for n in self.buffer])
def get(self, index):
bufIndex = math.floor(index / 8)
val = ( (self.buffer[bufIndex] >> (7 - index % 8) ) & 1) == 1
print "get ", val
return ( (self.buffer[bufIndex] >> (7 - index % 8) ) & 1) == 1
def put(self, num, length):
for i in range(length):
self.putBit( ( (num >> (length - i - 1) ) & 1) == 1)
def getLengthInBits(self):
return self.length
def putBit(self, bit):
bufIndex = self.length // 8
if len(self.buffer) <= bufIndex:
self.buffer.append(0)
if bit:
self.buffer[bufIndex] |= (0x80 >> (self.length % 8) )
self.length+=1

View File

@ -45,7 +45,7 @@ data_files += [
setup(name = "Electrum", setup(name = "Electrum",
version = version.ELECTRUM_VERSION, version = version.ELECTRUM_VERSION,
install_requires = ['slowaes','ecdsa'], install_requires = ['slowaes','ecdsa'],
package_dir = {'electrum': 'lib'}, package_dir = {'electrum': 'lib', 'electrumGUI': 'gui'},
scripts= ['electrum'], scripts= ['electrum'],
data_files = data_files, data_files = data_files,
py_modules = ['electrum.version', py_modules = ['electrum.version',
@ -53,28 +53,28 @@ setup(name = "Electrum",
'electrum.wallet_bitkey', 'electrum.wallet_bitkey',
'electrum.wallet_factory', 'electrum.wallet_factory',
'electrum.interface', 'electrum.interface',
'electrum.gui',
'electrum.commands', 'electrum.commands',
'electrum.qt_console',
'electrum.gui_qt',
'electrum.gui_lite',
'electrum.gui_text',
'electrum.exchange_rate',
'electrum.icons_rc',
'electrum.mnemonic', 'electrum.mnemonic',
'electrum.pyqrnative',
'electrum.qrscanner',
'electrum.history_widget',
'electrum.receiving_widget',
'electrum.simple_config', 'electrum.simple_config',
'electrum.socks', 'electrum.socks',
'electrum.bmp',
'electrum.msqr', 'electrum.msqr',
'electrum.util', 'electrum.util',
'electrum.bitcoin', 'electrum.bitcoin',
'electrum.deserialize', 'electrum.deserialize',
'electrum.verifier', 'electrum.verifier',
'electrum.i18n'], 'electrumGUI.gui',
'electrumGUI.qt_console',
'electrumGUI.gui_qt',
'electrumGUI.gui_lite',
'electrumGUI.gui_text',
'electrumGUI.exchange_rate',
'electrumGUI.icons_rc',
'electrumGUI.pyqrnative',
'electrumGUI.qrscanner',
'electrumGUI.history_widget',
'electrumGUI.receiving_widget',
'electrumGUI.bmp',
'electrumGUI.i18n'],
description = "Lightweight Bitcoin Wallet", description = "Lightweight Bitcoin Wallet",
author = "thomasv", author = "thomasv",
author_email = "thomasv@gitorious", author_email = "thomasv@gitorious",