From 0b2658374b5da5243aac619ae2eca4f27a4a3f4f Mon Sep 17 00:00:00 2001 From: Kevin Froman Date: Sun, 16 Aug 2020 19:52:50 -0500 Subject: [PATCH] Added/corrected timeouts for sqlite3 database connections Bumped mail plugin patch version for sqlite3 timeout change Code formatting corrections --- src/communicatorutils/housekeeping.py | 4 +- src/coredb/blockmetadb/__init__.py | 38 +++++------ src/coredb/blockmetadb/expiredblocks.py | 25 +++---- src/coredb/keydb/transportinfo.py | 57 ++++++++-------- src/onionrblocks/onionrblacklist.py | 5 +- src/onionrstorage/__init__.py | 64 ++++++++++-------- src/onionrstorage/removeblock.py | 4 +- src/onionrstorage/setdata.py | 4 +- src/onionrusers/onionrusers.py | 71 +++++++++++++------- src/onionrutils/blockmetadata/hasblock.py | 3 +- static-data/default-plugins/pms/info.json | 2 +- static-data/default-plugins/pms/main.py | 2 +- static-data/default-plugins/pms/sentboxdb.py | 2 +- 13 files changed, 158 insertions(+), 123 deletions(-) diff --git a/src/communicatorutils/housekeeping.py b/src/communicatorutils/housekeeping.py index ee90440a..4d002b48 100755 --- a/src/communicatorutils/housekeeping.py +++ b/src/communicatorutils/housekeeping.py @@ -17,6 +17,7 @@ import onionrstorage from onionrstorage import removeblock from onionrblocks import onionrblacklist from onionrblocks.storagecounter import StorageCounter +from etc.onionrvalues import DATABASE_LOCK_TIMEOUT """ This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -71,7 +72,8 @@ def clean_old_blocks(comm_inst): def clean_keys(comm_inst): """Delete expired forward secrecy keys""" - conn = sqlite3.connect(dbfiles.user_id_info_db, timeout=10) + conn = sqlite3.connect(dbfiles.user_id_info_db, + timeout=DATABASE_LOCK_TIMEOUT) c = conn.cursor() time = epoch.get_epoch() deleteKeys = [] diff --git a/src/coredb/blockmetadb/__init__.py b/src/coredb/blockmetadb/__init__.py index 952f7a49..10e36f0a 100644 --- a/src/coredb/blockmetadb/__init__.py +++ b/src/coredb/blockmetadb/__init__.py @@ -1,7 +1,6 @@ -""" - Onionr - Private P2P Communication +"""Onionr - Private P2P Communication. - This module works with information relating to blocks stored on the node +Work with information relating to blocks stored on the node """ import sqlite3 @@ -27,18 +26,18 @@ update_block_info = updateblockinfo.update_block_info add_to_block_DB = add.add_to_block_DB -def get_block_list(dateRec = None, unsaved = False): - """ - Get list of our blocks - """ - if dateRec == None: - dateRec = 0 +def get_block_list(date_rec=None, unsaved=False): + """Get list of our blocks.""" + if date_rec is None: + date_rec = 0 - conn = sqlite3.connect(dbfiles.block_meta_db, timeout=onionrvalues.DATABASE_LOCK_TIMEOUT) + conn = sqlite3.connect( + dbfiles.block_meta_db, timeout=onionrvalues.DATABASE_LOCK_TIMEOUT) c = conn.cursor() - execute = 'SELECT hash FROM hashes WHERE dateReceived >= ? ORDER BY dateReceived ASC;' - args = (dateRec,) + execute = 'SELECT hash FROM hashes WHERE dateReceived' + \ + ' >= ? ORDER BY dateReceived ASC;' + args = (date_rec,) rows = list() for row in c.execute(execute, args): for i in row: @@ -48,11 +47,9 @@ def get_block_list(dateRec = None, unsaved = False): def get_block_date(blockHash): - """ - Returns the date a block was received - """ - - conn = sqlite3.connect(dbfiles.block_meta_db, timeout=onionrvalues.DATABASE_LOCK_TIMEOUT) + """Return the date a block was received.""" + conn = sqlite3.connect( + dbfiles.block_meta_db, timeout=onionrvalues.DATABASE_LOCK_TIMEOUT) c = conn.cursor() execute = 'SELECT dateReceived FROM hashes WHERE hash=?;' @@ -65,11 +62,10 @@ def get_block_date(blockHash): def get_blocks_by_type(blockType, orderDate=True): - """ - Returns a list of blocks by the type - """ + """Return a list of blocks by the type.""" - conn = sqlite3.connect(dbfiles.block_meta_db, timeout=onionrvalues.DATABASE_LOCK_TIMEOUT) + conn = sqlite3.connect( + dbfiles.block_meta_db, timeout=onionrvalues.DATABASE_LOCK_TIMEOUT) c = conn.cursor() if orderDate: diff --git a/src/coredb/blockmetadb/expiredblocks.py b/src/coredb/blockmetadb/expiredblocks.py index 120e7566..da4deaf6 100644 --- a/src/coredb/blockmetadb/expiredblocks.py +++ b/src/coredb/blockmetadb/expiredblocks.py @@ -1,9 +1,12 @@ -''' - Onionr - Private P2P Communication +"""Onionr - Private P2P Communication. - Get a list of expired blocks still stored -''' -''' +Get a list of expired blocks still stored +""" +import sqlite3 +from onionrutils import epoch +from .. import dbfiles +from etc import onionrvalues +""" This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or @@ -16,15 +19,13 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . -''' -import sqlite3 -from onionrutils import epoch -from .. import dbfiles -from etc import onionrvalues +""" + def get_expired_blocks(): - '''Returns a list of expired blocks''' - conn = sqlite3.connect(dbfiles.block_meta_db, timeout=onionrvalues.DATABASE_LOCK_TIMEOUT) + """Return a list of expired blocks""" + conn = sqlite3.connect( + dbfiles.block_meta_db, timeout=onionrvalues.DATABASE_LOCK_TIMEOUT) c = conn.cursor() date = int(epoch.get_epoch()) diff --git a/src/coredb/keydb/transportinfo.py b/src/coredb/keydb/transportinfo.py index d9efd365..e2b9dc01 100644 --- a/src/coredb/keydb/transportinfo.py +++ b/src/coredb/keydb/transportinfo.py @@ -1,9 +1,11 @@ -''' - Onionr - Private P2P Communication +"""Onionr - Private P2P Communication. - get or set transport address meta information -''' -''' +get or set transport address meta information +""" +import sqlite3 +from .. import dbfiles +from etc import onionrvalues +""" This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or @@ -16,28 +18,27 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . -''' -import sqlite3 -from .. import dbfiles -from etc import onionrvalues +""" + def get_address_info(address, info): - ''' - Get info about an address from its database entry + """ + Get info about an address from its database entry - address text, 0 - type int, 1 - knownPeer text, 2 - speed int, 3 - success int, 4 - powValue 5 - failure int 6 - lastConnect 7 - trust 8 - introduced 9 - ''' + address text, 0 + type int, 1 + knownPeer text, 2 + speed int, 3 + success int, 4 + powValue 5 + failure int 6 + lastConnect 7 + trust 8 + introduced 9 + """ - conn = sqlite3.connect(dbfiles.address_info_db, timeout=onionrvalues.DATABASE_LOCK_TIMEOUT) + conn = sqlite3.connect( + dbfiles.address_info_db, timeout=onionrvalues.DATABASE_LOCK_TIMEOUT) c = conn.cursor() command = (address,) @@ -57,12 +58,12 @@ def get_address_info(address, info): return retVal -def set_address_info(address, key, data): - ''' - Update an address for a key - ''' - conn = sqlite3.connect(dbfiles.address_info_db, timeout=onionrvalues.DATABASE_LOCK_TIMEOUT) +def set_address_info(address, key, data): + """Update an address for a key.""" + + conn = sqlite3.connect( + dbfiles.address_info_db, timeout=onionrvalues.DATABASE_LOCK_TIMEOUT) c = conn.cursor() command = (data, address) diff --git a/src/onionrblocks/onionrblacklist.py b/src/onionrblocks/onionrblacklist.py index a0824edf..f2775d49 100755 --- a/src/onionrblocks/onionrblacklist.py +++ b/src/onionrblocks/onionrblacklist.py @@ -9,6 +9,7 @@ from onionrplugins.onionrevents import event import onionrcrypto from onionrutils import epoch, bytesconverter from coredb import dbfiles +from etc.onionrvalues import DATABASE_LOCK_TIMEOUT """ This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -48,8 +49,8 @@ class OnionrBlackList: return retData - def _dbExecute(self, toExec, params = ()): - conn = sqlite3.connect(self.blacklistDB) + def _dbExecute(self, toExec, params=()): + conn = sqlite3.connect(self.blacklistDB, timeout=DATABASE_LOCK_TIMEOUT) c = conn.cursor() retData = c.execute(toExec, params) conn.commit() diff --git a/src/onionrstorage/__init__.py b/src/onionrstorage/__init__.py index 27ef8ccd..125d3c77 100755 --- a/src/onionrstorage/__init__.py +++ b/src/onionrstorage/__init__.py @@ -9,10 +9,11 @@ import os from onionrutils import bytesconverter from onionrutils import stringvalidators from coredb import dbfiles -import filepaths +from filepaths import block_data_location import onionrexceptions from onionrcrypto import hashers from . import setdata +from etc.onionrvalues import DATABASE_LOCK_TIMEOUT """ This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -34,73 +35,80 @@ DB_ENTRY_SIZE_LIMIT = 10000 # Will be a config option set_data = setdata.set_data -def _dbInsert(blockHash, data): - conn = sqlite3.connect(dbfiles.block_data_db, timeout=10) +def _dbInsert(block_hash, data): + conn = sqlite3.connect(dbfiles.block_data_db, + timeout=DATABASE_LOCK_TIMEOUT) c = conn.cursor() - data = (blockHash, data) + data = (block_hash, data) c.execute('INSERT INTO blockData (hash, data) VALUES(?, ?);', data) conn.commit() conn.close() -def _dbFetch(blockHash): - conn = sqlite3.connect(dbfiles.block_data_db, timeout=10) +def _dbFetch(block_hash): + conn = sqlite3.connect(dbfiles.block_data_db, + timeout=DATABASE_LOCK_TIMEOUT) c = conn.cursor() - for i in c.execute('SELECT data from blockData where hash = ?', (blockHash,)): + for i in c.execute( + 'SELECT data from blockData where hash = ?', (block_hash,)): return i[0] conn.commit() conn.close() return None -def deleteBlock(blockHash): - # You should call removeblock.remove_block if you automatically want to remove storage byte count - if os.path.exists('%s/%s.dat' % (filepaths.block_data_location, blockHash)): - os.remove('%s/%s.dat' % (filepaths.block_data_location, blockHash)) +def deleteBlock(block_hash): + # Call removeblock.remove_block to automatically want to remove storage byte count + if os.path.exists(f'{block_data_location}/{block_hash}.dat'): + os.remove(f'{block_data_location}/{block_hash}.dat') return True - conn = sqlite3.connect(dbfiles.block_data_db, timeout=10) + conn = sqlite3.connect(dbfiles.block_data_db, + timeout=DATABASE_LOCK_TIMEOUT) c = conn.cursor() - data = (blockHash,) + data = (block_hash,) c.execute('DELETE FROM blockData where hash = ?', data) conn.commit() conn.close() return True -def store(data, blockHash=''): - if not stringvalidators.validate_hash(blockHash): raise ValueError +def store(data, block_hash=''): + if not stringvalidators.validate_hash(block_hash): + raise ValueError ourHash = hashers.sha3_hash(data) - if blockHash != '': - if not ourHash == blockHash: + if block_hash != '': + if not ourHash == block_hash: raise ValueError('Hash specified does not meet internal hash check') else: - blockHash = ourHash + block_hash = ourHash if DB_ENTRY_SIZE_LIMIT >= sys.getsizeof(data): - _dbInsert(blockHash, data) + _dbInsert(block_hash, data) else: - with open('%s/%s.dat' % (filepaths.block_data_location, blockHash), 'wb') as blockFile: - blockFile.write(data) + with open( + f'{block_data_location}/{block_hash}.dat', 'wb') as blck_file: + blck_file.write(data) def getData(bHash): - if not stringvalidators.validate_hash(bHash): raise ValueError + if not stringvalidators.validate_hash(bHash): + raise ValueError bHash = bytesconverter.bytes_to_str(bHash) bHash = bHash.strip() # First check DB for data entry by hash # if no entry, check disk # If no entry in either, raise an exception - retData = None - fileLocation = '%s/%s.dat' % (filepaths.block_data_location, bHash) + ret_data = None + fileLocation = '%s/%s.dat' % (block_data_location, bHash) not_found_msg = "Block data not found for: " if os.path.exists(fileLocation): with open(fileLocation, 'rb') as block: - retData = block.read() + ret_data = block.read() else: - retData = _dbFetch(bHash) + ret_data = _dbFetch(bHash) - if retData is None: + if ret_data is None: raise onionrexceptions.NoDataAvailable(not_found_msg + str(bHash)) - return retData + return ret_data diff --git a/src/onionrstorage/removeblock.py b/src/onionrstorage/removeblock.py index 1589efa8..d6ab4272 100644 --- a/src/onionrstorage/removeblock.py +++ b/src/onionrstorage/removeblock.py @@ -10,6 +10,7 @@ import onionrstorage from onionrutils import stringvalidators from coredb import dbfiles from onionrblocks import storagecounter +from etc.onionrvalues import DATABASE_LOCK_TIMEOUT """ This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -33,7 +34,8 @@ def remove_block(block): **You may want blacklist.addToDB(blockHash) """ if stringvalidators.validate_hash(block): - conn = sqlite3.connect(dbfiles.block_meta_db, timeout=30) + conn = sqlite3.connect( + dbfiles.block_meta_db, timeout=DATABASE_LOCK_TIMEOUT) c = conn.cursor() t = (block,) c.execute('Delete from hashes where hash=?;', t) diff --git a/src/onionrstorage/setdata.py b/src/onionrstorage/setdata.py index e742ff7e..4a81a0c4 100644 --- a/src/onionrstorage/setdata.py +++ b/src/onionrstorage/setdata.py @@ -12,6 +12,7 @@ import filepaths from onionrblocks import storagecounter from coredb import dbfiles from onionrutils import blockmetadata, bytesconverter +from etc.onionrvalues import DATABASE_LOCK_TIMEOUT """ This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -50,7 +51,8 @@ def set_data(data) -> str: except onionrexceptions.NoDataAvailable: if storage_counter.add_bytes(dataSize) is not False: onionrstorage.store(data, blockHash=dataHash) - conn = sqlite3.connect(dbfiles.block_meta_db, timeout=30) + conn = sqlite3.connect( + dbfiles.block_meta_db, timeout=DATABASE_LOCK_TIMEOUT) c = conn.cursor() c.execute( "UPDATE hashes SET dataSaved=1 WHERE hash = ?;", diff --git a/src/onionrusers/onionrusers.py b/src/onionrusers/onionrusers.py index 388d8cac..21263772 100755 --- a/src/onionrusers/onionrusers.py +++ b/src/onionrusers/onionrusers.py @@ -14,6 +14,7 @@ import nacl.exceptions from coredb import keydb, dbfiles import onionrcrypto from onionrcrypto import getourkeypair +from etc.onionrvalues import DATABASE_LOCK_TIMEOUT """ This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -32,7 +33,8 @@ from onionrcrypto import getourkeypair def deleteExpiredKeys(): # Fetch the keys we generated for the peer, that are still around - conn = sqlite3.connect(dbfiles.forward_keys_db, timeout=10) + conn = sqlite3.connect( + dbfiles.forward_keys_db, timeout=DATABASE_LOCK_TIMEOUT) c = conn.cursor() curTime = epoch.get_epoch() @@ -44,7 +46,8 @@ def deleteExpiredKeys(): def deleteTheirExpiredKeys(pubkey): - conn = sqlite3.connect(dbfiles.user_id_info_db, timeout=10) + conn = sqlite3.connect( + dbfiles.user_id_info_db, timeout=DATABASE_LOCK_TIMEOUT) c = conn.cursor() # Prepare the insert @@ -63,12 +66,13 @@ class OnionrUser: def __init__(self, publicKey, saveUser=False): """ - OnionrUser is an abstraction for "users" of the network. + OnionrUser is an abstraction for "users" of the network. - Takes a base32 encoded ed25519 public key, and a bool saveUser - saveUser determines if we should add a user to our peer database or not. + Takes a base32 encoded ed25519 public key, and a bool saveUser + saveUser determines if we should add a user to our peer database or not. """ - publicKey = unpaddedbase32.repad(bytesconverter.str_to_bytes(publicKey)).decode() + publicKey = unpaddedbase32.repad( + bytesconverter.str_to_bytes(publicKey)).decode() self.trust = 0 self.publicKey = publicKey @@ -76,7 +80,7 @@ class OnionrUser: if saveUser and not publicKey == getourkeypair.get_keypair(): try: keydb.addkeys.add_peer(publicKey) - except (AssertionError, ValueError) as e: + except (AssertionError, ValueError) as _: pass self.trust = keydb.userinfo.get_user_info(self.publicKey, 'trust') @@ -102,11 +106,13 @@ class OnionrUser: return retData def encrypt(self, data): - encrypted = onionrcrypto.encryption.pub_key_encrypt(data, self.publicKey, encodedData=True) + encrypted = onionrcrypto.encryption.pub_key_encrypt( + data, self.publicKey, encodedData=True) return encrypted def decrypt(self, data): - decrypted = onionrcrypto.encryption.pub_key_decrypt(data, self.publicKey, encodedData=True) + decrypted = onionrcrypto.encryption.pub_key_decrypt( + data, self.publicKey, encodedData=True) return decrypted def forwardEncrypt(self, data): @@ -115,33 +121,39 @@ class OnionrUser: retData = '' forwardKey = self._getLatestForwardKey() if stringvalidators.validate_pub_key(forwardKey[0]): - retData = onionrcrypto.encryption.pub_key_encrypt(data, forwardKey[0], encodedData=True) + retData = onionrcrypto.encryption.pub_key_encrypt( + data, forwardKey[0], encodedData=True) else: - raise onionrexceptions.InvalidPubkey("No valid forward secrecy key available for this user") - #self.generateForwardKey() + raise onionrexceptions.InvalidPubkey( + "No valid forward secrecy key available for this user") return (retData, forwardKey[0], forwardKey[1]) def forwardDecrypt(self, encrypted): retData = "" for key in self.getGeneratedForwardKeys(False): try: - retData = onionrcrypto.encryption.pub_key_decrypt(encrypted, privkey=key[1], encodedData=True) + retData = onionrcrypto.encryption.pub_key_decrypt( + encrypted, privkey=key[1], encodedData=True) except nacl.exceptions.CryptoError: retData = False else: break else: - raise onionrexceptions.DecryptionError("Could not decrypt forward secrecy content") + raise onionrexceptions.DecryptionError( + "Could not decrypt forward secrecy content") return retData def _getLatestForwardKey(self): # Get the latest forward secrecy key for a peer key = "" - conn = sqlite3.connect(dbfiles.user_id_info_db, timeout=10) + conn = sqlite3.connect( + dbfiles.user_id_info_db, timeout=DATABASE_LOCK_TIMEOUT) c = conn.cursor() # TODO: account for keys created at the same time (same epoch) - for row in c.execute("SELECT forwardKey, max(EXPIRE) FROM forwardKeys WHERE peerKey = ? ORDER BY expire DESC", (self.publicKey,)): + for row in c.execute( + "SELECT forwardKey, max(EXPIRE) FROM forwardKeys WHERE peerKey = ? ORDER BY expire DESC", # noqa + (self.publicKey,)): key = (row[0], row[1]) break @@ -151,11 +163,14 @@ class OnionrUser: return key def _getForwardKeys(self): - conn = sqlite3.connect(dbfiles.user_id_info_db, timeout=10) + conn = sqlite3.connect( + dbfiles.user_id_info_db, timeout=DATABASE_LOCK_TIMEOUT) c = conn.cursor() keyList = [] - for row in c.execute("SELECT forwardKey, date FROM forwardKeys WHERE peerKey = ? ORDER BY expire DESC", (self.publicKey,)): + for row in c.execute( + "SELECT forwardKey, date FROM forwardKeys WHERE peerKey = ? ORDER BY expire DESC", # noqa + (self.publicKey,)): keyList.append((row[0], row[1])) conn.commit() @@ -166,7 +181,8 @@ class OnionrUser: def generateForwardKey(self, expire=DEFAULT_KEY_EXPIRE): # Generate a forward secrecy key for the peer - conn = sqlite3.connect(dbfiles.forward_keys_db, timeout=10) + conn = sqlite3.connect( + dbfiles.forward_keys_db, timeout=DATABASE_LOCK_TIMEOUT) c = conn.cursor() # Prepare the insert time = epoch.get_epoch() @@ -184,14 +200,16 @@ class OnionrUser: def getGeneratedForwardKeys(self, genNew=True): # Fetch the keys we generated for the peer, that are still around - conn = sqlite3.connect(dbfiles.forward_keys_db, timeout=10) + conn = sqlite3.connect( + dbfiles.forward_keys_db, timeout=DATABASE_LOCK_TIMEOUT) c = conn.cursor() pubkey = self.publicKey pubkey = bytesconverter.bytes_to_str(pubkey) command = (pubkey,) - keyList = [] # list of tuples containing pub, private for peer + keyList = [] # list of tuples containing pub, private for peer - for result in c.execute("SELECT * FROM myForwardKeys WHERE peer = ?", command): + for result in c.execute( + "SELECT * FROM myForwardKeys WHERE peer = ?", command): keyList.append((result[1], result[2])) if len(keyList) == 0: @@ -201,12 +219,14 @@ class OnionrUser: return list(keyList) def addForwardKey(self, newKey, expire=DEFAULT_KEY_EXPIRE): - newKey = bytesconverter.bytes_to_str(unpaddedbase32.repad(bytesconverter.str_to_bytes(newKey))) + newKey = bytesconverter.bytes_to_str( + unpaddedbase32.repad(bytesconverter.str_to_bytes(newKey))) if not stringvalidators.validate_pub_key(newKey): # Do not add if something went wrong with the key raise onionrexceptions.InvalidPubkey(newKey) - conn = sqlite3.connect(dbfiles.user_id_info_db, timeout=10) + conn = sqlite3.connect( + dbfiles.user_id_info_db, timeout=DATABASE_LOCK_TIMEOUT) c = conn.cursor() # Get the time we're inserting the key at @@ -218,7 +238,8 @@ class OnionrUser: return False if entry[1] == timeInsert: timeInsert += 1 - time.sleep(1) # Sleep if our time is the same in order to prevent duplicate time records + # Sleep if our time is the same to prevent dupe time records + time.sleep(1) # Add a forward secrecy key for the peer # Prepare the insert diff --git a/src/onionrutils/blockmetadata/hasblock.py b/src/onionrutils/blockmetadata/hasblock.py index 8f4bbb2a..9ee59134 100644 --- a/src/onionrutils/blockmetadata/hasblock.py +++ b/src/onionrutils/blockmetadata/hasblock.py @@ -27,7 +27,8 @@ def has_block(hash: str) -> bool: ''' Check for new block in the block meta db ''' - conn = sqlite3.connect(dbfiles.block_meta_db, timeout=onionrvalues.DATABASE_LOCK_TIMEOUT) + conn = sqlite3.connect(dbfiles.block_meta_db, + timeout=onionrvalues.DATABASE_LOCK_TIMEOUT) c = conn.cursor() if not stringvalidators.validate_hash(hash): raise onionrexceptions.InvalidHexHash("Invalid hash") diff --git a/static-data/default-plugins/pms/info.json b/static-data/default-plugins/pms/info.json index 55c20967..d654f11e 100755 --- a/static-data/default-plugins/pms/info.json +++ b/static-data/default-plugins/pms/info.json @@ -1,5 +1,5 @@ { "name" : "pms", - "version" : "0.1.0", + "version" : "0.1.1", "author" : "onionr" } diff --git a/static-data/default-plugins/pms/main.py b/static-data/default-plugins/pms/main.py index 0b0a1c5b..7ff46150 100755 --- a/static-data/default-plugins/pms/main.py +++ b/static-data/default-plugins/pms/main.py @@ -31,7 +31,7 @@ import notifier locale.setlocale(locale.LC_ALL, '') plugin_name = 'pms' -PLUGIN_VERSION = '0.1.0' +PLUGIN_VERSION = '0.1.1' sys.path.insert(0, os.path.dirname(os.path.realpath(__file__))) import sentboxdb, mailapi, loadinbox # import after path insert diff --git a/static-data/default-plugins/pms/sentboxdb.py b/static-data/default-plugins/pms/sentboxdb.py index b07445a8..b5d37330 100755 --- a/static-data/default-plugins/pms/sentboxdb.py +++ b/static-data/default-plugins/pms/sentboxdb.py @@ -31,7 +31,7 @@ class SentBox: return def connect(self): - self.conn = sqlite3.connect(self.dbLocation) + self.conn = sqlite3.connect(self.dbLocation, timeout=30) self.cursor = self.conn.cursor() def close(self):