Skip to content

Commit 49f9620

Browse files
committed
Add sqlite functions while versioning
1 parent f5fba7d commit 49f9620

19 files changed

+638
-405
lines changed

src/addresses.py

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
Operations with addresses
33
"""
44
# pylint: disable=redefined-outer-name,inconsistent-return-statements
5+
import sys
56
import hashlib
67
import logging
78
from binascii import hexlify, unhexlify
@@ -149,18 +150,31 @@ def encodeAddress(version, stream, ripe):
149150
'Programming error in encodeAddress: The length of'
150151
' a given ripe hash was not 20.'
151152
)
152-
if ripe[:2] == b'\x00\x00':
153-
ripe = ripe[2:]
154-
elif ripe[:1] == b'\x00':
155-
ripe = ripe[1:]
153+
154+
if isinstance(ripe, str):
155+
if ripe[:2] == '\x00\x00':
156+
ripe = ripe[2:]
157+
elif ripe[:1] == '\x00':
158+
ripe = ripe[1:]
159+
else:
160+
if ripe[:2] == b'\x00\x00':
161+
ripe = ripe[2:]
162+
elif ripe[:1] == b'\x00':
163+
ripe = ripe[1:]
156164
elif version == 4:
157165
if len(ripe) != 20:
158166
raise Exception(
159167
'Programming error in encodeAddress: The length of'
160168
' a given ripe hash was not 20.')
161-
ripe = ripe.lstrip(b'\x00')
169+
ripe = ripe.lstrip('\x00')
162170

163-
storedBinaryData = encodeVarint(version) + encodeVarint(stream) + ripe
171+
if sys.version_info[0] == 3:
172+
if isinstance(ripe, str):
173+
storedBinaryData = encodeVarint(version) + encodeVarint(stream) + ripe.encode('utf-8')
174+
else:
175+
storedBinaryData = encodeVarint(version) + encodeVarint(stream) + ripe
176+
else:
177+
storedBinaryData = encodeVarint(version) + encodeVarint(stream) + ripe
164178

165179
# Generate the checksum
166180
sha = hashlib.new('sha512')

src/bitmessagecli.py

Lines changed: 309 additions & 307 deletions
Large diffs are not rendered by default.

src/bmconfigparser.py

Lines changed: 85 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -53,18 +53,16 @@
5353

5454
@Singleton
5555
class BMConfigParser(SafeConfigParser):
56-
5756
"""
58-
Singleton class inherited from :class:`ConfigParser.SafeConfigParser`
59-
with additional methods specific to bitmessage config.
57+
Singleton class inherited from :class:`ConfigParser.SafeConfigParser`
58+
with additional methods specific to bitmessage config.
6059
"""
6160
# pylint: disable=too-many-ancestors
62-
6361
_temp = {}
6462

6563
def set(self, section, option, value=None):
6664
if self._optcre is self.OPTCRE or value:
67-
if not isinstance(value, basestring):
65+
if not isinstance(value, str):
6866
raise TypeError("option values must be strings")
6967
if not self.validate(section, option, value):
7068
raise ValueError("Invalid value %s" % value)
@@ -73,20 +71,20 @@ def set(self, section, option, value=None):
7371
def get(self, section, option, raw=False, vars=None):
7472
if sys.version_info[0] == 3:
7573
# pylint: disable=arguments-differ
76-
try:
74+
try:
7775
if section == "bitmessagesettings" and option == "timeformat":
7876
return ConfigParser.ConfigParser.get(
79-
self, section, option)
77+
self, section, option, raw=True, vars=vars)
8078
try:
8179
return self._temp[section][option]
8280
except KeyError:
8381
pass
8482
return ConfigParser.ConfigParser.get(
85-
self, section, option)
86-
except ConfigParser.InterpolationError:
83+
self, section, option, raw=True, vars=vars)
84+
except ConfigParser.InterpolationError:
8785
return ConfigParser.ConfigParser.get(
88-
self, section, option)
89-
except (ConfigParser.NoSectionError, ConfigParser.NoOptionError) as e:
86+
self, section, option, raw=True, vars=vars)
87+
except (ConfigParser.NoSectionError, ConfigParser.NoOptionError) as e:
9088
try:
9189
return BMConfigDefaults[section][option]
9290
except (KeyError, ValueError, AttributeError):
@@ -122,6 +120,10 @@ def setTemp(self, section, option, value=None):
122120
def safeGetBoolean(self, section, field):
123121
"""Return value as boolean, False on exceptions"""
124122
try:
123+
# Used in the python2.7
124+
# return self.getboolean(section, field)
125+
# Used in the python3.5.2
126+
# print(config, section, field)
125127
return self.getboolean(section, field)
126128
except (ConfigParser.NoSectionError, ConfigParser.NoOptionError,
127129
ValueError, AttributeError):
@@ -131,7 +133,10 @@ def safeGetInt(self, section, field, default=0):
131133
"""Return value as integer, default on exceptions,
132134
0 if default missing"""
133135
try:
134-
return self.getint(section, field)
136+
# Used in the python2.7
137+
# return self.getint(section, field)
138+
# Used in the python3.7.0
139+
return int(self.get(section, field))
135140
except (ConfigParser.NoSectionError, ConfigParser.NoOptionError,
136141
ValueError, AttributeError):
137142
return default
@@ -145,43 +150,71 @@ def safeGet(self, section, option, default=None):
145150
return default
146151

147152
def items(self, section, raw=False, variables=None):
153+
# pylint: disable=signature-differs
148154
"""Return section variables as parent,
149155
but override the "raw" argument to always True"""
150-
# pylint: disable=arguments-differ
151156
return ConfigParser.ConfigParser.items(self, section, True, variables)
152157

153-
@staticmethod
154-
def addresses():
155-
"""Return a list of local bitmessage addresses (from section labels)"""
156-
return [
157-
x for x in BMConfigParser().sections() if x.startswith('BM-')]
158-
159-
def _reset(self):
160-
"""Reset current config. There doesn't appear to be a built in
161-
method for this"""
162-
sections = self.sections()
163-
for x in sections:
164-
self.remove_section(x)
165-
166-
def read(self, filenames):
167-
"""Read config and populate defaults"""
168-
self._reset()
169-
ConfigParser.ConfigParser.read(self, filenames)
170-
for section in self.sections():
171-
for option in self.options(section):
172-
try:
173-
if not self.validate(
174-
section, option,
175-
ConfigParser.ConfigParser.get(self, section, option)
176-
):
177-
try:
178-
newVal = BMConfigDefaults[section][option]
179-
except KeyError:
180-
continue
181-
ConfigParser.ConfigParser.set(
182-
self, section, option, newVal)
183-
except ConfigParser.InterpolationError:
184-
continue
158+
if sys.version_info[0] == 3:
159+
@staticmethod
160+
def addresses(hidden=False):
161+
"""Return a list of local bitmessage addresses (from section labels)"""
162+
return [x for x in BMConfigParser().sections() if x.startswith('BM-') and (
163+
hidden or not BMConfigParser().safeGetBoolean(x, 'hidden'))]
164+
165+
def read(self, filenames):
166+
ConfigParser.ConfigParser.read(self, filenames)
167+
for section in self.sections():
168+
for option in self.options(section):
169+
try:
170+
if not self.validate(
171+
section, option,
172+
self[section][option]
173+
):
174+
try:
175+
newVal = BMConfigDefaults[section][option]
176+
except ConfigParser.NoSectionError:
177+
continue
178+
except KeyError:
179+
continue
180+
ConfigParser.ConfigParser.set(
181+
self, section, option, newVal)
182+
except ConfigParser.InterpolationError:
183+
continue
184+
185+
else:
186+
@staticmethod
187+
def addresses():
188+
"""Return a list of local bitmessage addresses (from section labels)"""
189+
return [
190+
x for x in BMConfigParser().sections() if x.startswith('BM-')]
191+
192+
def _reset(self):
193+
"""Reset current config. There doesn't appear to be a built in
194+
method for this"""
195+
sections = self.sections()
196+
for x in sections:
197+
self.remove_section(x)
198+
199+
def read(self, filenames):
200+
"""Read config and populate defaults"""
201+
self._reset()
202+
ConfigParser.ConfigParser.read(self, filenames)
203+
for section in self.sections():
204+
for option in self.options(section):
205+
try:
206+
if not self.validate(
207+
section, option,
208+
ConfigParser.ConfigParser.get(self, section, option)
209+
):
210+
try:
211+
newVal = BMConfigDefaults[section][option]
212+
except KeyError:
213+
continue
214+
ConfigParser.ConfigParser.set(
215+
self, section, option, newVal)
216+
except ConfigParser.InterpolationError:
217+
continue
185218

186219
def save(self):
187220
"""Save the runtime config onto the filesystem"""
@@ -198,8 +231,8 @@ def save(self):
198231
# The backup failed. This can happen if the file
199232
# didn't exist before.
200233
fileNameExisted = False
201-
# write the file
202-
with open(fileName, 'wb') as configfile:
234+
235+
with open(fileName, 'w') as configfile:
203236
self.write(configfile)
204237
# delete the backup
205238
if fileNameExisted:
@@ -208,7 +241,11 @@ def save(self):
208241
def validate(self, section, option, value):
209242
"""Input validator interface (using factory pattern)"""
210243
try:
211-
return getattr(self, 'validate_%s_%s' % (section, option))(value)
244+
if sys.version_info[0] == 3:
245+
return getattr(self, 'validate_{}_{}'.format(
246+
section, option))(value)
247+
else:
248+
return getattr(self, 'validate_%s_%s' % (section, option))(value)
212249
except AttributeError:
213250
return True
214251

@@ -222,4 +259,3 @@ def validate_bitmessagesettings_maxoutboundconnections(value):
222259
if value < 0 or value > 8:
223260
return False
224261
return True
225-

src/class_sqlThread.py

Lines changed: 40 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,28 @@
99
import threading
1010
import time
1111

12-
import helper_sql
13-
import helper_startup
14-
import paths
15-
import queues
16-
import state
17-
import tr
18-
from bmconfigparser import BMConfigParser
19-
from debug import logger
20-
# pylint: disable=attribute-defined-outside-init,protected-access
12+
if sys.version_info[0] == 3:
13+
from . import helper_sql
14+
from . import helper_startup
15+
from . import paths
16+
from . import queues
17+
from . import state
18+
from . import tr
19+
from .bmconfigparser import BMConfigParser
20+
from .debug import logger
21+
# pylint: disable=attribute-defined-outside-init,protected-access
22+
from .addresses import encodeAddress
23+
else:
24+
import helper_sql
25+
import helper_startup
26+
import paths
27+
import queues
28+
import state
29+
import tr
30+
from bmconfigparser import BMConfigParser
31+
from debug import logger
32+
# pylint: disable=attribute-defined-outside-init,protected-access
33+
from addresses import encodeAddress
2134

2235

2336
class sqlThread(threading.Thread):
@@ -35,6 +48,9 @@ def run(self): # pylint: disable=too-many-locals, too-many-branches, too-many-s
3548

3649
self.cur.execute('PRAGMA secure_delete = true')
3750

51+
# call create_function for encode address
52+
self.create_function()
53+
3854
try:
3955
self.cur.execute(
4056
'''CREATE TABLE inbox (msgid blob, toaddress text, fromaddress text, subject text,'''
@@ -325,6 +341,7 @@ def run(self): # pylint: disable=too-many-locals, too-many-branches, too-many-s
325341

326342
# We'll also need a `sleeptill` field and a `ttl` field. Also we
327343
# can combine the pubkeyretrynumber and msgretrynumber into one.
344+
328345
item = '''SELECT value FROM settings WHERE key='version';'''
329346
parameters = ''
330347
self.cur.execute(item, parameters)
@@ -358,16 +375,11 @@ def run(self): # pylint: disable=too-many-locals, too-many-branches, too-many-s
358375
logger.debug('In messages.dat database, adding address field to the pubkeys table.')
359376
# We're going to have to calculate the address for each row in the pubkeys
360377
# table. Then we can take out the hash field.
361-
self.cur.execute('''ALTER TABLE pubkeys ADD address text DEFAULT '' ''')
362-
self.cur.execute('''SELECT hash, addressversion FROM pubkeys''')
363-
queryResult = self.cur.fetchall()
364-
from addresses import encodeAddress
365-
for row in queryResult:
366-
addressHash, addressVersion = row
367-
address = encodeAddress(addressVersion, 1, hash)
368-
item = '''UPDATE pubkeys SET address=? WHERE hash=?;'''
369-
parameters = (address, addressHash)
370-
self.cur.execute(item, parameters)
378+
self.cur.execute('''ALTER TABLE pubkeys ADD address text DEFAULT '' ;''')
379+
380+
# replica for loop to update hashed address
381+
self.cur.execute('''UPDATE pubkeys SET address=(enaddr(pubkeys.addressversion, 1, hash)); ''')
382+
371383
# Now we can remove the hash field from the pubkeys table.
372384
self.cur.execute(
373385
'''CREATE TEMPORARY TABLE pubkeys_backup'''
@@ -622,3 +634,12 @@ def run(self): # pylint: disable=too-many-locals, too-many-branches, too-many-s
622634

623635
helper_sql.sqlReturnQueue.put((self.cur.fetchall(), rowcount))
624636
# helper_sql.sqlSubmitQueue.task_done()
637+
638+
def create_function(self):
639+
# create_function
640+
try:
641+
self.conn.create_function("enaddr", 3, func=encodeAddress, deterministic=True)
642+
except (TypeError, sqlite3.NotSupportedError) as err:
643+
logger.debug(
644+
"Got error while pass deterministic in sqlite create function {}, Passing 3 params".format(err))
645+
self.conn.create_function("enaddr", 3, encodeAddress)

src/debug.py

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,26 @@
3535
just import and log.
3636
"""
3737

38-
import ConfigParser
38+
# import ConfigParser
39+
import sys
40+
if sys.version_info[0] == 3:
41+
# python 3
42+
import configparser as ConfigParser
43+
else:
44+
# python 2
45+
import ConfigParser
46+
3947
import logging
4048
import logging.config
4149
import os
4250
import sys
4351

44-
import helper_startup
45-
import state
52+
if sys.version_info[0] == 3:
53+
from . import helper_startup
54+
from . import state
55+
else:
56+
import helper_startup
57+
import state
4658

4759
helper_startup.loadConfig()
4860

@@ -74,7 +86,7 @@ def configureLogging():
7486
False,
7587
'Loaded logger configuration from %s' % logging_config
7688
)
77-
except (OSError, ConfigParser.NoSectionError):
89+
except (OSError, ConfigParser.NoSectionError, KeyError):
7890
if os.path.isfile(logging_config):
7991
fail_msg = \
8092
'Failed to load logger configuration from %s, using default' \
@@ -149,6 +161,7 @@ def resetLogging():
149161

150162

151163
# !
164+
152165
preconfigured, msg = configureLogging()
153166
logger = logging.getLogger('default')
154167
if msg:

0 commit comments

Comments
 (0)