Moved most of frequently used SQL-queries to helper_db module.

This commit is contained in:
Dmitri Bogomolov 2018-03-12 12:55:42 +02:00
parent ef849d2dd3
commit cc2fa62b90
Signed by untrusted user: g1itch
GPG Key ID: 720A756F18DEED13
9 changed files with 353 additions and 422 deletions

View File

@ -35,9 +35,10 @@ from foldertree import (
MessageList_TimeWidget) MessageList_TimeWidget)
import settingsmixin import settingsmixin
import support import support
from helper_sql import sqlQuery, sqlExecute, sqlExecuteChunked, sqlStoredProcedure from helper_ackPayload import genAckPayload
import helper_addressbook from helper_sql import (
import helper_search sqlQuery, sqlExecute, sqlExecuteChunked, sqlStoredProcedure)
import helper_db
import l10n import l10n
from utils import str_broadcast_subscribers, avatarize from utils import str_broadcast_subscribers, avatarize
from account import ( from account import (
@ -54,7 +55,6 @@ from statusbar import BMStatusBar
import sound import sound
# This is needed for tray icon # This is needed for tray icon
import bitmessage_icons_rc # noqa:F401 pylint: disable=unused-import import bitmessage_icons_rc # noqa:F401 pylint: disable=unused-import
import helper_sent
try: try:
from plugins.plugin import get_plugin, get_plugins from plugins.plugin import get_plugin, get_plugins
@ -1214,7 +1214,7 @@ class MyForm(settingsmixin.SMainWindow):
tableWidget.setColumnHidden(1, bool(account)) tableWidget.setColumnHidden(1, bool(account))
xAddress = 'fromaddress' xAddress = 'fromaddress'
queryreturn = helper_search.search_sql( queryreturn = helper_db.search_sql(
xAddress, account, "sent", where, what, False) xAddress, account, "sent", where, what, False)
for row in queryreturn: for row in queryreturn:
@ -1254,7 +1254,7 @@ class MyForm(settingsmixin.SMainWindow):
tableWidget.setColumnHidden(0, False) tableWidget.setColumnHidden(0, False)
tableWidget.setColumnHidden(1, False) tableWidget.setColumnHidden(1, False)
queryreturn = helper_search.search_sql( queryreturn = helper_db.search_sql(
xAddress, account, folder, where, what, unreadOnly) xAddress, account, folder, where, what, unreadOnly)
for row in queryreturn: for row in queryreturn:
@ -1937,8 +1937,7 @@ class MyForm(settingsmixin.SMainWindow):
newRows = {} newRows = {}
# subscriptions # subscriptions
queryreturn = sqlQuery('SELECT label, address FROM subscriptions WHERE enabled = 1') for row in helper_db.get_subscriptions():
for row in queryreturn:
label, address = row label, address = row
newRows[address] = [label, AccountMixin.SUBSCRIPTION] newRows[address] = [label, AccountMixin.SUBSCRIPTION]
# chans # chans
@ -1948,8 +1947,7 @@ class MyForm(settingsmixin.SMainWindow):
if (account.type == AccountMixin.CHAN and BMConfigParser().safeGetBoolean(address, 'enabled')): if (account.type == AccountMixin.CHAN and BMConfigParser().safeGetBoolean(address, 'enabled')):
newRows[address] = [account.getLabel(), AccountMixin.CHAN] newRows[address] = [account.getLabel(), AccountMixin.CHAN]
# normal accounts # normal accounts
queryreturn = sqlQuery('SELECT * FROM addressbook') for row in helper_db.get_addressbook():
for row in queryreturn:
label, address = row label, address = row
newRows[address] = [label, AccountMixin.NORMAL] newRows[address] = [label, AccountMixin.NORMAL]
@ -2166,18 +2164,19 @@ class MyForm(settingsmixin.SMainWindow):
" send the message but it won\'t send until" " send the message but it won\'t send until"
" you connect.") " you connect.")
) )
ackdata = helper_sent.insert( stealthLevel = BMConfigParser().safeGetInt(
toAddress=toAddress, fromAddress=fromAddress, 'bitmessagesettings', 'ackstealthlevel')
subject=subject, message=message, encoding=encoding) ackdata = genAckPayload(streamNumber, stealthLevel)
toLabel = '' helper_db.put_sent(
queryreturn = sqlQuery('''select label from addressbook where address=?''', toAddress, fromAddress, subject, message, ackdata,
toAddress) 'msgqueued', encoding, ripe
if queryreturn != []: )
for row in queryreturn:
toLabel, = row toLabel = helper_db.get_label(toAddress) or ''
self.displayNewSentMessage( self.displayNewSentMessage(
toAddress, toLabel, fromAddress, subject, message, ackdata) toAddress, toLabel, fromAddress, subject,
message, ackdata)
queues.workerQueue.put(('sendmessage', toAddress)) queues.workerQueue.put(('sendmessage', toAddress))
self.click_pushButtonClear() self.click_pushButtonClear()
@ -2202,15 +2201,14 @@ class MyForm(settingsmixin.SMainWindow):
# We don't actually need the ackdata for acknowledgement since # We don't actually need the ackdata for acknowledgement since
# this is a broadcast message, but we can use it to update the # this is a broadcast message, but we can use it to update the
# user interface when the POW is done generating. # user interface when the POW is done generating.
toAddress = str_broadcast_subscribers streamNumber = decodeAddress(fromAddress)[2]
ackdata = genAckPayload(streamNumber, 0)
toAddress = toLabel = str_broadcast_subscribers
# msgid. We don't know what this will be until the POW is done. helper_db.put_sent(
ackdata = helper_sent.insert( toAddress, fromAddress, subject, message, ackdata,
fromAddress=fromAddress, 'broadcastqueued', encoding
subject=subject, message=message, )
status='broadcastqueued', encoding=encoding)
toLabel = str_broadcast_subscribers
self.displayNewSentMessage( self.displayNewSentMessage(
toAddress, toLabel, fromAddress, subject, message, ackdata) toAddress, toLabel, fromAddress, subject, message, ackdata)
@ -2338,7 +2336,7 @@ class MyForm(settingsmixin.SMainWindow):
self.ui.treeWidgetChans self.ui.treeWidgetChans
) and self.getCurrentAccount(treeWidget) != toAddress: ) and self.getCurrentAccount(treeWidget) != toAddress:
continue continue
elif not helper_search.check_match( elif not helper_db.check_match(
toAddress, fromAddress, subject, message, toAddress, fromAddress, subject, message,
self.getCurrentSearchOption(tab), self.getCurrentSearchOption(tab),
self.getCurrentSearchLine(tab) self.getCurrentSearchLine(tab)
@ -2368,7 +2366,7 @@ class MyForm(settingsmixin.SMainWindow):
tab += 1 tab += 1
if tab == 1: if tab == 1:
tab = 2 tab = 2
if not helper_search.check_match( if not helper_db.check_match(
toAddress, fromAddress, subject, message, toAddress, fromAddress, subject, message,
self.getCurrentSearchOption(tab), self.getCurrentSearchOption(tab),
self.getCurrentSearchLine(tab) self.getCurrentSearchLine(tab)
@ -2427,10 +2425,7 @@ class MyForm(settingsmixin.SMainWindow):
except AttributeError: except AttributeError:
return return
# First we must check to see if the address is already in the if not helper_db.put_addressbook(label, address):
# address book. The user cannot add it again or else it will
# cause problems when updating and deleting the entry.
if shared.isAddressInMyAddressBook(address):
self.updateStatusBar(_translate( self.updateStatusBar(_translate(
"MainWindow", "MainWindow",
"Error: You cannot add the same address to your" "Error: You cannot add the same address to your"
@ -2439,30 +2434,25 @@ class MyForm(settingsmixin.SMainWindow):
)) ))
return return
if helper_addressbook.insert(label=label, address=address): self.rerenderMessagelistFromLabels()
self.rerenderMessagelistFromLabels() self.rerenderMessagelistToLabels()
self.rerenderMessagelistToLabels() self.rerenderAddressBook()
self.rerenderAddressBook()
else:
self.updateStatusBar(_translate(
"MainWindow",
"Error: You cannot add your own address in the address book."
))
def addSubscription(self, address, label): def addSubscription(self, address, label):
# This should be handled outside of this function, for error displaying if not helper_db.put_subscriptions(label, address):
# and such, but it must also be checked here. self.updateStatusBar(_translate(
if shared.isAddressInMySubscriptionsList(address): "MainWindow",
"Error: You cannot add the same address to your"
" subscriptions twice. Perhaps rename the existing one"
" if you want."
))
return return
# Add to database (perhaps this should be separated from the MyForm class)
sqlExecute(
'''INSERT INTO subscriptions VALUES (?,?,?)''',
label, address, True
)
self.rerenderMessagelistFromLabels() self.rerenderMessagelistFromLabels()
shared.reloadBroadcastSendersForWhichImWatching() shared.reloadBroadcastSendersForWhichImWatching()
self.rerenderAddressBook() self.rerenderAddressBook()
self.rerenderTabTreeSubscriptions() self.rerenderTabTreeSubscriptions()
return True
def click_pushButtonAddSubscription(self): def click_pushButtonAddSubscription(self):
dialog = dialogs.NewSubscriptionDialog(self) dialog = dialogs.NewSubscriptionDialog(self)
@ -2472,19 +2462,9 @@ class MyForm(settingsmixin.SMainWindow):
except AttributeError: except AttributeError:
return return
# We must check to see if the address is already in the if not self.addSubscription(address, label):
# subscriptions list. The user cannot add it again or else it
# will cause problems when updating and deleting the entry.
if shared.isAddressInMySubscriptionsList(address):
self.updateStatusBar(_translate(
"MainWindow",
"Error: You cannot add the same address to your"
" subscriptions twice. Perhaps rename the existing one"
" if you want."
))
return return
self.addSubscription(address, label)
# Now, if the user wants to display old broadcasts, let's get # Now, if the user wants to display old broadcasts, let's get
# them out of the inventory and put them # them out of the inventory and put them
# to the objectProcessorQueue to be processed # to the objectProcessorQueue to be processed
@ -2815,11 +2795,7 @@ class MyForm(settingsmixin.SMainWindow):
textEdit = self.getCurrentMessageTextedit() textEdit = self.getCurrentMessageTextedit()
if not msgid: if not msgid:
return return
queryreturn = sqlQuery( messageText = helper_db.get_message(msgid)
'''select message from inbox where msgid=?''', msgid)
if queryreturn != []:
for row in queryreturn:
messageText, = row
lines = messageText.split('\n') lines = messageText.split('\n')
totalLines = len(lines) totalLines = len(lines)
@ -3052,24 +3028,20 @@ class MyForm(settingsmixin.SMainWindow):
currentInboxRow, 1).data(QtCore.Qt.UserRole) currentInboxRow, 1).data(QtCore.Qt.UserRole)
recipientAddress = tableWidget.item( recipientAddress = tableWidget.item(
currentInboxRow, 0).data(QtCore.Qt.UserRole) currentInboxRow, 0).data(QtCore.Qt.UserRole)
# Let's make sure that it isn't already in the address book label = "\"" + tableWidget.item(currentInboxRow, 2).subject + \
queryreturn = sqlQuery('''select * from blacklist where address=?''', "\" in " + BMConfigParser().get(recipientAddress, "label")
addressAtCurrentInboxRow) if not helper_db.put_blacklist(label, addressAtCurrentInboxRow):
if queryreturn == []:
label = "\"" + tableWidget.item(currentInboxRow, 2).subject + "\" in " + BMConfigParser().get(recipientAddress, "label")
sqlExecute('''INSERT INTO blacklist VALUES (?,?, ?)''',
label,
addressAtCurrentInboxRow, True)
self.ui.blackwhitelist.rerenderBlackWhiteList()
self.updateStatusBar(_translate(
"MainWindow",
"Entry added to the blacklist. Edit the label to your liking.")
)
else:
self.updateStatusBar(_translate( self.updateStatusBar(_translate(
"MainWindow", "MainWindow",
"Error: You cannot add the same address to your blacklist" "Error: You cannot add the same address to your blacklist"
" twice. Try renaming the existing one if you want.")) " twice. Try renaming the existing one if you want."))
return
self.ui.blackwhitelist.rerenderBlackWhiteList()
self.updateStatusBar(_translate(
"MainWindow",
"Entry added to the blacklist. Edit the label to your liking.")
)
def deleteRowFromMessagelist( def deleteRowFromMessagelist(
self, row=None, inventoryHash=None, ackData=None, messageLists=None self, row=None, inventoryHash=None, ackData=None, messageLists=None
@ -3168,11 +3140,7 @@ class MyForm(settingsmixin.SMainWindow):
# Retrieve the message data out of the SQL database # Retrieve the message data out of the SQL database
msgid = tableWidget.item(currentInboxRow, 3).data() msgid = tableWidget.item(currentInboxRow, 3).data()
queryreturn = sqlQuery( message = helper_db.get_message(msgid)
'''select message from inbox where msgid=?''', msgid)
if queryreturn != []:
for row in queryreturn:
message, = row
defaultFilename = "".join(x for x in subjectAtCurrentInboxRow if x.isalnum()) + '.txt' defaultFilename = "".join(x for x in subjectAtCurrentInboxRow if x.isalnum()) + '.txt'
filename = QtGui.QFileDialog.getSaveFileName(self, _translate("MainWindow","Save As..."), defaultFilename, "Text files (*.txt);;All files (*.*)") filename = QtGui.QFileDialog.getSaveFileName(self, _translate("MainWindow","Save As..."), defaultFilename, "Text files (*.txt);;All files (*.*)")
@ -3280,15 +3248,6 @@ class MyForm(settingsmixin.SMainWindow):
def on_action_AddressBookSubscribe(self): def on_action_AddressBookSubscribe(self):
for item in self.getAddressbookSelectedItems(): for item in self.getAddressbookSelectedItems():
# Then subscribe to it...
# provided it's not already in the address book
if shared.isAddressInMySubscriptionsList(item.address):
self.updateStatusBar(_translate(
"MainWindow",
"Error: You cannot add the same address to your"
" subscriptions twice. Perhaps rename the existing"
" one if you want."))
continue
self.addSubscription(item.address, item.label) self.addSubscription(item.address, item.label)
self.ui.tabWidget.setCurrentIndex( self.ui.tabWidget.setCurrentIndex(
self.ui.tabWidget.indexOf(self.ui.subscriptions) self.ui.tabWidget.indexOf(self.ui.subscriptions)

View File

@ -4,43 +4,30 @@ account.py
========== ==========
Account related functions. Account related functions.
""" """
from __future__ import absolute_import
import inspect import inspect
import re import re
import sys import sys
import time
from PyQt4 import QtGui
import helper_db
import queues import queues
from addresses import decodeAddress from addresses import decodeAddress
from bmconfigparser import BMConfigParser from bmconfigparser import BMConfigParser
from helper_ackPayload import genAckPayload from helper_ackPayload import genAckPayload
from helper_sql import sqlQuery, sqlExecute from helper_sql import sqlQuery
from .foldertree import AccountMixin from foldertree import AccountMixin
from .utils import str_broadcast_subscribers from utils import str_broadcast_subscribers
from tr import _translate
def getSortedAccounts(): def getSortedAccounts():
"""Get a sorted list of configSections""" """Get a sorted list of configSections"""
configSections = BMConfigParser().addresses() configSections = BMConfigParser().addresses()
configSections.sort( configSections.sort(
cmp=lambda x, y: cmp( cmp=lambda x, y: cmp(
unicode( unicode(BMConfigParser().get(x, 'label'), 'utf-8').lower(),
BMConfigParser().get( unicode(BMConfigParser().get(y, 'label'), 'utf-8').lower()))
x,
'label'),
'utf-8').lower(),
unicode(
BMConfigParser().get(
y,
'label'),
'utf-8').lower()))
return configSections return configSections
@ -107,29 +94,27 @@ def accountClass(address):
class AccountColor(AccountMixin): # pylint: disable=too-few-public-methods class AccountColor(AccountMixin): # pylint: disable=too-few-public-methods
"""Set the type of account""" """Set the type of account"""
def __init__(self, address, address_type=None): def __init__(self, address, address_type=None):
self.isEnabled = True self.isEnabled = True
self.address = address self.address = address
if address_type is None: if address_type:
if address is None:
self.type = AccountMixin.ALL
elif BMConfigParser().safeGetBoolean(self.address, 'mailinglist'):
self.type = AccountMixin.MAILINGLIST
elif BMConfigParser().safeGetBoolean(self.address, 'chan'):
self.type = AccountMixin.CHAN
elif sqlQuery(
'''select label from subscriptions where address=?''', self.address):
self.type = AccountMixin.SUBSCRIPTION
else:
self.type = AccountMixin.NORMAL
else:
self.type = address_type self.type = address_type
return
# AccountMixin.setType()
if self.address is None:
self.type = self.ALL
elif BMConfigParser().safeGetBoolean(self.address, 'chan'):
self.type = self.CHAN
elif BMConfigParser().safeGetBoolean(self.address, 'mailinglist'):
self.type = self.MAILINGLIST
elif helper_db.get_label(self.address, "subscriptions"):
self.type = AccountMixin.SUBSCRIPTION
else:
self.type = self.NORMAL
class BMAccount(object): class BMAccount(object):
"""Encapsulate a Bitmessage account""" """Encapsulate a Bitmessage account"""
def __init__(self, address=None): def __init__(self, address=None):
self.address = address self.address = address
self.type = AccountMixin.NORMAL self.type = AccountMixin.NORMAL
@ -140,29 +125,19 @@ class BMAccount(object):
self.type = AccountMixin.MAILINGLIST self.type = AccountMixin.MAILINGLIST
elif self.address == str_broadcast_subscribers: elif self.address == str_broadcast_subscribers:
self.type = AccountMixin.BROADCAST self.type = AccountMixin.BROADCAST
else: elif helper_db.get_label(self.address, "subscriptions"):
queryreturn = sqlQuery( self.type = AccountMixin.SUBSCRIPTION
'''select label from subscriptions where address=?''', self.address)
if queryreturn:
self.type = AccountMixin.SUBSCRIPTION
def getLabel(self, address=None): def getLabel(self, address=None):
"""Get a label for this bitmessage account""" """Get a label for this bitmessage account"""
if address is None: if address is None:
address = self.address address = self.address
label = BMConfigParser().safeGet(address, 'label', address) if BMConfigParser().has_section(address):
queryreturn = sqlQuery( return BMConfigParser().get(address, 'label')
'''select label from addressbook where address=?''', address) return (
if queryreturn != []: helper_db.get_label(address) or
for row in queryreturn: helper_db.get_label(address, "subscriptions") or address
label, = row )
else:
queryreturn = sqlQuery(
'''select label from subscriptions where address=?''', address)
if queryreturn != []:
for row in queryreturn:
label, = row
return label
def parseMessage(self, toAddress, fromAddress, subject, message): def parseMessage(self, toAddress, fromAddress, subject, message):
"""Set metadata and address labels on self""" """Set metadata and address labels on self"""
@ -186,9 +161,7 @@ class NoAccount(BMAccount):
self.type = AccountMixin.NORMAL self.type = AccountMixin.NORMAL
def getLabel(self, address=None): def getLabel(self, address=None):
if address is None: return address or self.address
address = self.address
return address
class SubscriptionAccount(BMAccount): class SubscriptionAccount(BMAccount):
@ -213,31 +186,17 @@ class GatewayAccount(BMAccount):
def send(self): def send(self):
"""Override the send method for gateway accounts""" """Override the send method for gateway accounts"""
streamNumber, ripe = decodeAddress(self.toAddress)[2:]
# pylint: disable=unused-variable stealthLevel = BMConfigParser().safeGetInt(
status, addressVersionNumber, streamNumber, ripe = decodeAddress(self.toAddress) 'bitmessagesettings', 'ackstealthlevel')
stealthLevel = BMConfigParser().safeGetInt('bitmessagesettings', 'ackstealthlevel')
ackdata = genAckPayload(streamNumber, stealthLevel) ackdata = genAckPayload(streamNumber, stealthLevel)
sqlExecute( helper_db.put_sent(
'''INSERT INTO sent VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)''', self.toAddress, self.fromAddress, self.subject, self.message,
'', ackdata, 'msgqueued', 2, ripe,
self.toAddress, min(
ripe, BMConfigParser().getint('bitmessagesettings', 'ttl'),
self.fromAddress, 86400 * 2) # not necessary to have a TTL higher than 2 days
self.subject,
self.message,
ackdata,
int(time.time()), # sentTime (this will never change)
int(time.time()), # lastActionTime
0, # sleepTill time. This will get set when the POW gets done.
'msgqueued',
0, # retryNumber
'sent', # folder
2, # encodingtype
# not necessary to have a TTL higher than 2 days
min(BMConfigParser().getint('bitmessagesettings', 'ttl'), 86400 * 2)
) )
queues.workerQueue.put(('sendmessage', self.toAddress)) queues.workerQueue.put(('sendmessage', self.toAddress))
@ -292,9 +251,7 @@ class MailchuckAccount(GatewayAccount):
self.toAddress = self.registrationAddress self.toAddress = self.registrationAddress
self.subject = "config" self.subject = "config"
self.message = QtGui.QApplication.translate( self.message = _translate("Mailchuck", """# You can use this to configure your email gateway account
"Mailchuck",
"""# You can use this to configure your email gateway account
# Uncomment the setting you want to use # Uncomment the setting you want to use
# Here are the options: # Here are the options:
# #

View File

@ -8,8 +8,8 @@ from cgi import escape
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
import helper_db
from bmconfigparser import BMConfigParser from bmconfigparser import BMConfigParser
from helper_sql import sqlExecute, sqlQuery
from settingsmixin import SettingsMixin from settingsmixin import SettingsMixin
from tr import _translate from tr import _translate
from utils import avatarize from utils import avatarize
@ -110,15 +110,13 @@ class AccountMixin(object):
self.type = self.CHAN self.type = self.CHAN
elif BMConfigParser().safeGetBoolean(self.address, 'mailinglist'): elif BMConfigParser().safeGetBoolean(self.address, 'mailinglist'):
self.type = self.MAILINGLIST self.type = self.MAILINGLIST
elif sqlQuery( elif helper_db.get_label(self.address, "subscriptions"):
'''select label from subscriptions where address=?''', self.address):
self.type = AccountMixin.SUBSCRIPTION self.type = AccountMixin.SUBSCRIPTION
else: else:
self.type = self.NORMAL self.type = self.NORMAL
def defaultLabel(self): def defaultLabel(self):
"""Default label (in case no label is set manually)""" """Default label (in case no label is set manually)"""
queryreturn = None
retval = None retval = None
if self.type in ( if self.type in (
AccountMixin.NORMAL, AccountMixin.NORMAL,
@ -127,16 +125,9 @@ class AccountMixin(object):
retval = unicode( retval = unicode(
BMConfigParser().get(self.address, 'label'), 'utf-8') BMConfigParser().get(self.address, 'label'), 'utf-8')
except Exception: except Exception:
queryreturn = sqlQuery( retval = helper_db.get_label(self.address)
'''select label from addressbook where address=?''', self.address)
elif self.type == AccountMixin.SUBSCRIPTION: elif self.type == AccountMixin.SUBSCRIPTION:
queryreturn = sqlQuery( retval = helper_db.get_label(self.address, "subscriptions")
'''select label from subscriptions where address=?''', self.address)
if queryreturn is not None:
if queryreturn != []:
for row in queryreturn:
retval, = row
retval = unicode(retval, 'utf-8')
elif self.address is None or self.type == AccountMixin.ALL: elif self.address is None or self.type == AccountMixin.ALL:
return unicode( return unicode(
str(_translate("MainWindow", "All accounts")), 'utf-8') str(_translate("MainWindow", "All accounts")), 'utf-8')
@ -306,13 +297,8 @@ class Ui_SubscriptionWidget(Ui_AddressWidget):
parent, pos, address, unreadCount, enabled) parent, pos, address, unreadCount, enabled)
def _getLabel(self): def _getLabel(self):
queryreturn = sqlQuery( return helper_db.get_label(self.address, "subscriptions") \
'''select label from subscriptions where address=?''', self.address) or self.address
if queryreturn != []:
for row in queryreturn:
retval, = row
return unicode(retval, 'utf-8', 'ignore')
return unicode(self.address, 'utf-8')
def setType(self): def setType(self):
"""Set account type""" """Set account type"""
@ -327,9 +313,7 @@ class Ui_SubscriptionWidget(Ui_AddressWidget):
value.toString().toUtf8()).decode('utf-8', 'ignore') value.toString().toUtf8()).decode('utf-8', 'ignore')
else: else:
label = unicode(value, 'utf-8', 'ignore') label = unicode(value, 'utf-8', 'ignore')
sqlExecute( helper_db.set_label(self.address, label, "subscriptions")
'''UPDATE subscriptions SET label=? WHERE address=?''',
label, self.address)
return super(Ui_SubscriptionWidget, self).setData(column, role, value) return super(Ui_SubscriptionWidget, self).setData(column, role, value)
@ -402,7 +386,6 @@ class MessageList_AddressWidget(BMAddressWidget):
if label is not None: if label is not None:
return return
newLabel = self.address newLabel = self.address
queryreturn = None
if self.type in ( if self.type in (
AccountMixin.NORMAL, AccountMixin.NORMAL,
AccountMixin.CHAN, AccountMixin.MAILINGLIST): AccountMixin.CHAN, AccountMixin.MAILINGLIST):
@ -411,14 +394,9 @@ class MessageList_AddressWidget(BMAddressWidget):
BMConfigParser().get(self.address, 'label'), BMConfigParser().get(self.address, 'label'),
'utf-8', 'ignore') 'utf-8', 'ignore')
except: except:
queryreturn = sqlQuery( newLabel = helper_db.get_label(self.address)
'''select label from addressbook where address=?''', self.address)
elif self.type == AccountMixin.SUBSCRIPTION: elif self.type == AccountMixin.SUBSCRIPTION:
queryreturn = sqlQuery( newLabel = helper_db.get_label(self.address, "subscriptions")
'''select label from subscriptions where address=?''', self.address)
if queryreturn:
for row in queryreturn:
newLabel = unicode(row[0], 'utf-8', 'ignore')
self.label = newLabel self.label = newLabel
@ -525,9 +503,9 @@ class Ui_AddressBookWidgetItem(BMAddressWidget):
BMConfigParser().set(self.address, 'label', self.label) BMConfigParser().set(self.address, 'label', self.label)
BMConfigParser().save() BMConfigParser().save()
except: except:
sqlExecute('''UPDATE addressbook set label=? WHERE address=?''', self.label, self.address) helper_db.set_label(self.address, self.label)
elif self.type == AccountMixin.SUBSCRIPTION: elif self.type == AccountMixin.SUBSCRIPTION:
sqlExecute('''UPDATE subscriptions set label=? WHERE address=?''', self.label, self.address) helper_db.set_label(self.address, self.label, "subscriptions")
else: else:
pass pass
return super(Ui_AddressBookWidgetItem, self).setData(role, value) return super(Ui_AddressBookWidgetItem, self).setData(role, value)

View File

@ -10,6 +10,7 @@ from PyQt4 import QtCore
import account import account
import defaults import defaults
import helper_db
import network.stats import network.stats
import paths import paths
import proofofwork import proofofwork
@ -17,7 +18,7 @@ import queues
import state import state
from bmconfigparser import BMConfigParser from bmconfigparser import BMConfigParser
from foldertree import AccountMixin from foldertree import AccountMixin
from helper_sql import sqlExecute, sqlQuery from helper_sql import sqlExecute
from l10n import getTranslationLanguage from l10n import getTranslationLanguage
from openclpow import openclEnabled from openclpow import openclEnabled
from pyelliptic.openssl import OpenSSL from pyelliptic.openssl import OpenSSL
@ -67,12 +68,8 @@ Connected hosts: {}
def checkAddressBook(myapp): def checkAddressBook(myapp):
sqlExecute('DELETE from addressbook WHERE address=?', OLD_SUPPORT_ADDRESS) sqlExecute('DELETE FROM addressbook WHERE address=?', OLD_SUPPORT_ADDRESS)
queryreturn = sqlQuery('SELECT * FROM addressbook WHERE address=?', SUPPORT_ADDRESS) if helper_db.put_addressbook(SUPPORT_LABEL.toUtf8(), SUPPORT_ADDRESS):
if queryreturn == []:
sqlExecute(
'INSERT INTO addressbook VALUES (?,?)',
SUPPORT_LABEL.toUtf8(), SUPPORT_ADDRESS)
myapp.rerenderAddressBook() myapp.rerenderAddressBook()

View File

@ -10,12 +10,10 @@ import random
import threading import threading
import time import time
from binascii import hexlify from binascii import hexlify
from subprocess import call # nosec
import helper_bitcoin import helper_bitcoin
import helper_inbox
import helper_msgcoding import helper_msgcoding
import helper_sent import helper_db
import highlevelcrypto import highlevelcrypto
import l10n import l10n
import protocol import protocol
@ -29,10 +27,10 @@ from addresses import (
) )
from bmconfigparser import BMConfigParser from bmconfigparser import BMConfigParser
from fallback import RIPEMD160Hash from fallback import RIPEMD160Hash
from helper_ackPayload import genAckPayload
from helper_sql import sql_ready, SqlBulkExecute, sqlExecute, sqlQuery from helper_sql import sql_ready, SqlBulkExecute, sqlExecute, sqlQuery
from network import bmproto, knownnodes from network import bmproto, knownnodes
from network.node import Peer from network.node import Peer
# pylint: disable=too-many-locals, too-many-return-statements, too-many-branches, too-many-statements
logger = logging.getLogger('default') logger = logging.getLogger('default')
@ -343,24 +341,7 @@ class objectProcessor(threading.Thread):
) )
address = encodeAddress(addressVersion, streamNumber, ripe) address = encodeAddress(addressVersion, streamNumber, ripe)
helper_db.put_pubkey(address, addressVersion, dataToStore)
queryreturn = sqlQuery(
"SELECT usedpersonally FROM pubkeys WHERE address=?"
" AND usedpersonally='yes'", address)
# if this pubkey is already in our database and if we have
# used it personally:
if queryreturn != []:
logger.info(
'We HAVE used this pubkey personally. Updating time.')
t = (address, addressVersion, dataToStore,
int(time.time()), 'yes')
else:
logger.info(
'We have NOT used this pubkey personally. Inserting'
' in database.')
t = (address, addressVersion, dataToStore,
int(time.time()), 'no')
sqlExecute('''INSERT INTO pubkeys VALUES (?,?,?,?,?)''', *t)
self.possibleNewPubkey(address) self.possibleNewPubkey(address)
if addressVersion == 3: if addressVersion == 3:
if len(data) < 170: # sanity check. if len(data) < 170: # sanity check.
@ -408,23 +389,7 @@ class objectProcessor(threading.Thread):
) )
address = encodeAddress(addressVersion, streamNumber, ripe) address = encodeAddress(addressVersion, streamNumber, ripe)
queryreturn = sqlQuery( helper_db.put_pubkey(address, addressVersion, dataToStore)
"SELECT usedpersonally FROM pubkeys WHERE address=?"
" AND usedpersonally='yes'", address)
# if this pubkey is already in our database and if we have
# used it personally:
if queryreturn != []:
logger.info(
'We HAVE used this pubkey personally. Updating time.')
t = (address, addressVersion, dataToStore,
int(time.time()), 'yes')
else:
logger.info(
'We have NOT used this pubkey personally. Inserting'
' in database.')
t = (address, addressVersion, dataToStore,
int(time.time()), 'no')
sqlExecute('''INSERT INTO pubkeys VALUES (?,?,?,?,?)''', *t)
self.possibleNewPubkey(address) self.possibleNewPubkey(address)
if addressVersion == 4: if addressVersion == 4:
@ -623,13 +588,10 @@ class objectProcessor(threading.Thread):
# Let's store the public key in case we want to reply to this # Let's store the public key in case we want to reply to this
# person. # person.
sqlExecute( helper_db.put_pubkey(
'''INSERT INTO pubkeys VALUES (?,?,?,?,?)''', fromAddress, sendersAddressVersionNumber,
fromAddress, decryptedData[:endOfThePublicKeyPosition], True
sendersAddressVersionNumber, )
decryptedData[:endOfThePublicKeyPosition],
int(time.time()),
'yes')
# Check to see whether we happen to be awaiting this # Check to see whether we happen to be awaiting this
# pubkey in order to send a message. If we are, it will do the POW # pubkey in order to send a message. If we are, it will do the POW
@ -693,78 +655,56 @@ class objectProcessor(threading.Thread):
subject = decodedMessage.subject subject = decodedMessage.subject
body = decodedMessage.body body = decodedMessage.body
# Let us make sure that we haven't already received this message if helper_db.put_inbox(
if helper_inbox.isMessageAlreadyInInbox(sigHash): toAddress, fromAddress, subject, body, inventoryHash, sigHash,
logger.info('This msg is already in our inbox. Ignoring it.') encoding=messageEncodingType
blockMessage = True ) is False:
if not blockMessage: # logger.info('This msg is already in our inbox. Ignoring it.')
if messageEncodingType != 0: return
t = (inventoryHash, toAddress, fromAddress, subject,
int(time.time()), body, 'inbox', messageEncodingType,
0, sigHash)
helper_inbox.insert(t)
queues.UISignalQueue.put(('displayNewInboxMessage', ( # Let us now check and see whether our receiving address is
inventoryHash, toAddress, fromAddress, subject, body))) # behaving as a mailing list
if BMConfigParser().safeGetBoolean(toAddress, 'mailinglist'):
mailingListName = BMConfigParser().safeGet(
toAddress, 'mailinglistname', '')
# If we are behaving as an API then we might need to run an # Let us send out this message as a broadcast
# outside command to let some program know that a new message subject = self.addMailingListNameToSubject(
# has arrived. subject, mailingListName)
if BMConfigParser().safeGetBoolean( # Let us now send this message out as a broadcast
'bitmessagesettings', 'apienabled'): message = time.strftime("%a, %Y-%m-%d %H:%M:%S UTC", time.gmtime(
try: )) + ' Message ostensibly from ' + fromAddress + ':\n\n' + body
apiNotifyPath = BMConfigParser().get( # The fromAddress for the broadcast that we are about to
'bitmessagesettings', 'apinotifypath') # send is the toAddress (my address) for the msg message
except: # we are currently processing.
apiNotifyPath = '' fromAddress = toAddress
if apiNotifyPath != '': # We don't actually need the ackdata for acknowledgement
call([apiNotifyPath, "newMessage"]) # since this is a broadcast message but we can use it to
# update the user interface when the POW is done generating.
streamNumber = decodeAddress(fromAddress)[2]
# Let us now check and see whether our receiving address is ackdata = genAckPayload(streamNumber, 0)
# behaving as a mailing list toAddress = toLabel = '[Broadcast subscribers]'
if BMConfigParser().safeGetBoolean(toAddress, 'mailinglist') \
and messageEncodingType != 0:
try:
mailingListName = BMConfigParser().get(
toAddress, 'mailinglistname')
except:
mailingListName = ''
# Let us send out this message as a broadcast
subject = self.addMailingListNameToSubject(
subject, mailingListName)
# Let us now send this message out as a broadcast
message = time.strftime(
"%a, %Y-%m-%d %H:%M:%S UTC", time.gmtime()
) + ' Message ostensibly from ' + fromAddress \
+ ':\n\n' + body
# The fromAddress for the broadcast that we are about to
# send is the toAddress (my address) for the msg message
# we are currently processing.
fromAddress = toAddress
# We don't actually need the ackdata for acknowledgement
# since this is a broadcast message but we can use it to
# update the user interface when the POW is done generating.
toAddress = '[Broadcast subscribers]'
ackdata = helper_sent.insert( # We really should have a discussion about how to
fromAddress=fromAddress, # set the TTL for mailing list broadcasts. This is obviously
status='broadcastqueued', # hard-coded.
subject=subject, TTL = 2 * 7 * 24 * 60 * 60 # 2 weeks
message=message, helper_db.put_sent(
encoding=messageEncodingType) toAddress, fromAddress, subject, message, ackdata,
'broadcastqueued', messageEncodingType, ttl=TTL
)
queues.UISignalQueue.put(( queues.UISignalQueue.put((
'displayNewSentMessage', ( 'displayNewSentMessage',
toAddress, '[Broadcast subscribers]', fromAddress, (toAddress, toLabel, fromAddress, subject, message, ackdata)
subject, message, ackdata) ))
)) queues.workerQueue.put(('sendbroadcast', ''))
queues.workerQueue.put(('sendbroadcast', ''))
# Don't send ACK if invalid, blacklisted senders, invisible # Don't send ACK if invalid, blacklisted senders, invisible
# messages, disabled or chan # messages, disabled or chan
if ( if (
self.ackDataHasAValidHeader(ackData) and not blockMessage and self.ackDataHasAValidHeader(ackData) and not blockMessage and
messageEncodingType != 0 and
not BMConfigParser().safeGetBoolean(toAddress, 'dontsendack') and not BMConfigParser().safeGetBoolean(toAddress, 'dontsendack') and
not BMConfigParser().safeGetBoolean(toAddress, 'chan') not BMConfigParser().safeGetBoolean(toAddress, 'chan')
): ):
@ -975,12 +915,11 @@ class objectProcessor(threading.Thread):
logger.info('fromAddress: %s', fromAddress) logger.info('fromAddress: %s', fromAddress)
# Let's store the public key in case we want to reply to this person. # Let's store the public key in case we want to reply to this person.
sqlExecute('''INSERT INTO pubkeys VALUES (?,?,?,?,?)''', helper_db.put_pubkey(
fromAddress, fromAddress, sendersAddressVersion,
sendersAddressVersion, decryptedData[:endOfPubkeyPosition],
decryptedData[:endOfPubkeyPosition], True
int(time.time()), )
'yes')
# Check to see whether we happen to be awaiting this # Check to see whether we happen to be awaiting this
# pubkey in order to send a message. If we are, it will do the POW # pubkey in order to send a message. If we are, it will do the POW
@ -1000,27 +939,12 @@ class objectProcessor(threading.Thread):
body = decodedMessage.body body = decodedMessage.body
toAddress = '[Broadcast subscribers]' toAddress = '[Broadcast subscribers]'
if helper_inbox.isMessageAlreadyInInbox(sigHash): if helper_db.put_inbox(
logger.info('This broadcast is already in our inbox. Ignoring it.') toAddress, fromAddress, subject, body, inventoryHash, sigHash,
encoding=messageEncodingType
) is False:
# logger.info('This broadcast is already in inbox. Ignoring it.')
return return
t = (inventoryHash, toAddress, fromAddress, subject, int(
time.time()), body, 'inbox', messageEncodingType, 0, sigHash)
helper_inbox.insert(t)
queues.UISignalQueue.put(('displayNewInboxMessage', (
inventoryHash, toAddress, fromAddress, subject, body)))
# If we are behaving as an API then we might need to run an
# outside command to let some program know that a new message
# has arrived.
if BMConfigParser().safeGetBoolean('bitmessagesettings', 'apienabled'):
try:
apiNotifyPath = BMConfigParser().get(
'bitmessagesettings', 'apinotifypath')
except:
apiNotifyPath = ''
if apiNotifyPath != '':
call([apiNotifyPath, "newBroadcast"])
# Display timing data # Display timing data
logger.info( logger.info(

View File

@ -10,10 +10,9 @@ import hashlib
import time import time
from binascii import hexlify, unhexlify from binascii import hexlify, unhexlify
from struct import pack from struct import pack
from subprocess import call # nosec
import defaults import defaults
import helper_inbox import helper_db
import helper_msgcoding import helper_msgcoding
import helper_random import helper_random
import helper_sql import helper_sql
@ -1312,25 +1311,11 @@ class singleWorker(StoppableThread):
# Used to detect and ignore duplicate messages in our inbox # Used to detect and ignore duplicate messages in our inbox
sigHash = hashlib.sha512(hashlib.sha512( sigHash = hashlib.sha512(hashlib.sha512(
signature).digest()).digest()[32:] signature).digest()).digest()[32:]
t = (inventoryHash, toaddress, fromaddress, subject, int(
time.time()), message, 'inbox', encoding, 0, sigHash)
helper_inbox.insert(t)
queues.UISignalQueue.put(('displayNewInboxMessage', ( helper_db.put_inbox(
inventoryHash, toaddress, fromaddress, subject, message))) toaddress, fromaddress, subject, message, inventoryHash, sigHash,
encoding=encoding
# If we are behaving as an API then we might need to run an )
# outside command to let some program know that a new message
# has arrived.
if BMConfigParser().safeGetBoolean(
'bitmessagesettings', 'apienabled'):
try:
apiNotifyPath = BMConfigParser().get(
'bitmessagesettings', 'apinotifypath')
except:
apiNotifyPath = ''
if apiNotifyPath != '':
call([apiNotifyPath, "newMessage"])
def requestPubKey(self, toAddress): def requestPubKey(self, toAddress):
"""Send a getpubkey object""" """Send a getpubkey object"""

180
src/helper_db.py Normal file
View File

@ -0,0 +1,180 @@
import subprocess # nosec
import time
import queues
from bmconfigparser import BMConfigParser
from helper_search import search_sql, check_match
from helper_sql import sqlExecute, sqlQuery
__all__ = ["search_sql", "check_match"]
# + genAckPayload
def put_sent(
to_address, from_address, subject, message, ackdata,
status, encoding,
ripe='', ttl=0, msgid='', sent_time=None, last_action_time=None,
sleep_till_time=0, retrynumber=0):
"""Put message into Sent table"""
# We don't know msgid until the POW is done.
# sleep_till_time will get set when the POW gets done
if not sent_time:
sent_time = time.time()
if not last_action_time:
last_action_time = sent_time
if not ttl:
ttl = BMConfigParser().getint('bitmessagesettings', 'ttl')
sqlExecute(
"INSERT INTO sent VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",
msgid, to_address, ripe, from_address, subject, message, ackdata,
int(sent_time), int(last_action_time), sleep_till_time, status, retrynumber,
'sent', encoding, ttl
)
def _in_inbox_already(sighash):
return sqlQuery(
"SELECT COUNT(*) FROM inbox WHERE sighash=?", sighash
)[0][0] != 0
def put_inbox(
to_address, from_address, subject, message, msgid, sighash,
encoding=0, received_time=None, broadcast=False):
"""Put message into Inbox table"""
if not received_time:
received_time = time.time()
if encoding == 0 or _in_inbox_already(sighash):
return False
sqlExecute(
"INSERT INTO inbox VALUES (?,?,?,?,?,?,?,?,?,?)",
msgid, to_address, from_address, subject, int(received_time), message,
'inbox', encoding, 0, sighash
)
queues.UISignalQueue.put((
'displayNewInboxMessage',
(msgid, to_address, from_address, subject, message)
))
# If we are behaving as an API then we might need to run an
# outside command to let some program know that a new message
# has arrived.
if BMConfigParser().safeGetBoolean('bitmessagesettings', 'apienabled'):
apinotify_path = BMConfigParser().safeGet(
'bitmessagesettings', 'apinotifypath')
if apinotify_path:
subprocess.call([
apinotify_path,
"newBroadcast" if broadcast else "newMessage"])
def put_pubkey(address, address_version, data, used_personally=None):
"""Put pubkey into Pubkeys table"""
if used_personally is None:
if sqlQuery(
"SELECT * FROM pubkeys WHERE address=? AND usedpersonally='yes'",
address
) == []:
used_personally = False
else:
sqlExecute(
"UPDATE pubkeys SET time=? WHERE address=?",
time.time(), address
)
return
sqlExecute(
"INSERT INTO pubkeys VALUES (?,?,?,?,?)",
address, address_version, data, time.time(),
'yes' if used_personally else 'no'
)
def _in_group_already(address, group="addressbook"):
return sqlQuery(
"SELECT enabled FROM %s WHERE address=?" % group, address)
def put_addresslist(label, address, group="blacklist", enabled=True):
"""Put address into address list (e.g. blacklist, subscriptions...)"""
# We must check to see if the address is already in the
# subscriptions list. The user cannot add it again or else it
# will cause problems when updating and deleting the entry.
# FIXME: address should be primary key in this case
if _in_group_already(address, group):
return False
sqlExecute(
"INSERT INTO %s VALUES (?,?,?)" % group, label, address, enabled)
return True
def put_blacklist(label, address):
"""Put address into blacklist"""
return put_addresslist(label, address, "blacklist")
def put_subscriptions(label, address, enabled=True):
"""Put address into subscriptions"""
return put_addresslist(label, address, "subscriptions", enabled)
def put_addressbook(label, address):
"""Put address into Addressbook"""
# First we must check to see if the address is already in the
# address book. The user cannot add it again or else it will
# cause problems when updating and deleting the entry.
if _in_group_already(address):
return False
sqlExecute("INSERT INTO addressbook VALUES (?,?)", label, address)
return True
def get_subscriptions():
"""Generator for Subscriptions"""
queryreturn = sqlQuery(
"SELECT label, address FROM subscriptions WHERE enabled=1")
for row in queryreturn:
yield row
def get_addressbook():
"""Generator for Addressbook"""
queryreturn = sqlQuery("SELECT * FROM addressbook")
for row in queryreturn:
yield row
def get_addresslist(group="blacklist"):
"""Generator for address list given by group arg"""
queryreturn = sqlQuery("SELECT * FROM %s" % group)
for row in queryreturn:
yield row
def get_label(address, group="addressbook"):
"""
Get address label from address list given by group arg
(default is addressbook)
"""
queryreturn = sqlQuery(
"SELECT label FROM %s WHERE address=?" % group, address)
try:
return unicode(queryreturn[-1][0], 'utf-8')
except IndexError:
pass
def set_label(address, label, group="addressbook"):
"""Set address label in the address list given by group arg"""
sqlExecute("UPDATE %s set label=? WHERE address=?" % group, label, address)
def get_message(msgid):
"""Get inbox message by msgid"""
queryreturn = sqlQuery("SELECT message FROM inbox WHERE msgid=?", msgid)
try:
return queryreturn[-1][0]
except IndexError:
return ''

View File

@ -1,48 +0,0 @@
"""
Insert values into sent table
"""
import time
import uuid
from addresses import decodeAddress
from bmconfigparser import BMConfigParser
from helper_ackPayload import genAckPayload
from helper_sql import sqlExecute
# pylint: disable=too-many-arguments
def insert(msgid=None, toAddress='[Broadcast subscribers]', fromAddress=None, subject=None,
message=None, status='msgqueued', ripe=None, ackdata=None, sentTime=None,
lastActionTime=None, sleeptill=0, retryNumber=0, encoding=2, ttl=None, folder='sent'):
"""Perform an insert into the `sent` table"""
# pylint: disable=unused-variable
# pylint: disable-msg=too-many-locals
valid_addr = True
if not ripe or not ackdata:
addr = fromAddress if toAddress == '[Broadcast subscribers]' else toAddress
new_status, addressVersionNumber, streamNumber, new_ripe = decodeAddress(addr)
valid_addr = True if new_status == 'success' else False
if not ripe:
ripe = new_ripe
if not ackdata:
stealthLevel = BMConfigParser().safeGetInt(
'bitmessagesettings', 'ackstealthlevel')
new_ackdata = genAckPayload(streamNumber, stealthLevel)
ackdata = new_ackdata
if valid_addr:
msgid = msgid if msgid else uuid.uuid4().bytes
sentTime = sentTime if sentTime else int(time.time()) # sentTime (this doesn't change)
lastActionTime = lastActionTime if lastActionTime else int(time.time())
ttl = ttl if ttl else BMConfigParser().getint('bitmessagesettings', 'ttl')
t = (msgid, toAddress, ripe, fromAddress, subject, message, ackdata,
sentTime, lastActionTime, sleeptill, status, retryNumber, folder,
encoding, ttl)
sqlExecute('''INSERT INTO sent VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)''', *t)
return ackdata
else:
return None

View File

@ -14,6 +14,7 @@ from binascii import hexlify
from struct import Struct, pack, unpack from struct import Struct, pack, unpack
import defaults import defaults
import helper_db
import highlevelcrypto import highlevelcrypto
import state import state
from addresses import ( from addresses import (
@ -21,7 +22,6 @@ from addresses import (
from bmconfigparser import BMConfigParser from bmconfigparser import BMConfigParser
from debug import logger from debug import logger
from fallback import RIPEMD160Hash from fallback import RIPEMD160Hash
from helper_sql import sqlExecute
from version import softwareVersion from version import softwareVersion
# Service flags # Service flags
@ -503,8 +503,7 @@ def decryptAndCheckPubkeyPayload(data, address):
hexlify(publicSigningKey), hexlify(publicEncryptionKey) hexlify(publicSigningKey), hexlify(publicEncryptionKey)
) )
t = (address, addressVersion, storedData, int(time.time()), 'yes') helper_db.put_pubkey(address, addressVersion, storedData, True)
sqlExecute('''INSERT INTO pubkeys VALUES (?,?,?,?,?)''', *t)
return 'successful' return 'successful'
except varintDecodeError: except varintDecodeError:
logger.info( logger.info(