Compare commits

...

7 Commits

14 changed files with 459 additions and 512 deletions

View File

@ -73,8 +73,7 @@ from SimpleXMLRPCServer import SimpleXMLRPCRequestHandler, SimpleXMLRPCServer
from struct import pack from struct import pack
import defaults import defaults
import helper_inbox import helper_db
import helper_sent
import network.stats import network.stats
import proofofwork import proofofwork
import queues import queues
@ -587,14 +586,9 @@ class BMRPCDispatcher(object):
label = self._decode(label, "base64") label = self._decode(label, "base64")
address = addBMIfNotPresent(address) address = addBMIfNotPresent(address)
self._verifyAddress(address) self._verifyAddress(address)
# TODO: add unique together constraint in the table if not helper_db.put_addressbook(label, address):
queryreturn = sqlQuery(
"SELECT address FROM addressbook WHERE address=?", address)
if queryreturn != []:
raise APIError( raise APIError(
16, 'You already have this address in your address book.') 16, 'You already have this address in your address book.')
sqlExecute("INSERT INTO addressbook VALUES(?,?)", label, address)
queues.UISignalQueue.put(('rerenderMessagelistFromLabels', '')) queues.UISignalQueue.put(('rerenderMessagelistFromLabels', ''))
queues.UISignalQueue.put(('rerenderMessagelistToLabels', '')) queues.UISignalQueue.put(('rerenderMessagelistToLabels', ''))
queues.UISignalQueue.put(('rerenderAddressBook', '')) queues.UISignalQueue.put(('rerenderAddressBook', ''))
@ -1056,23 +1050,23 @@ class BMRPCDispatcher(object):
""" """
msgid = self._decode(msgid, "hex") msgid = self._decode(msgid, "hex")
# Trash if in inbox table # Trash if in inbox table
helper_inbox.trash(msgid) helper_db.put_trash(msgid)
# Trash if in sent table # Trash if in sent table
sqlExecute("UPDATE sent SET folder='trash' WHERE msgid=?", msgid) helper_db.put_trash(msgid, sent=True)
return 'Trashed message (assuming message existed).' return 'Trashed message (assuming message existed).'
@command('trashInboxMessage') @command('trashInboxMessage')
def HandleTrashInboxMessage(self, msgid): def HandleTrashInboxMessage(self, msgid):
"""Trash inbox message by msgid (encoded in hex).""" """Trash inbox message by msgid (encoded in hex)."""
msgid = self._decode(msgid, "hex") msgid = self._decode(msgid, "hex")
helper_inbox.trash(msgid) helper_db.put_trash(msgid)
return 'Trashed inbox message (assuming message existed).' return 'Trashed inbox message (assuming message existed).'
@command('trashSentMessage') @command('trashSentMessage')
def HandleTrashSentMessage(self, msgid): def HandleTrashSentMessage(self, msgid):
"""Trash sent message by msgid (encoded in hex).""" """Trash sent message by msgid (encoded in hex)."""
msgid = self._decode(msgid, "hex") msgid = self._decode(msgid, "hex")
sqlExecute('''UPDATE sent SET folder='trash' WHERE msgid=?''', msgid) helper_db.put_trash(msgid, sent=True)
return 'Trashed sent message (assuming message existed).' return 'Trashed sent message (assuming message existed).'
@command('sendMessage') @command('sendMessage')
@ -1110,18 +1104,15 @@ class BMRPCDispatcher(object):
if not fromAddressEnabled: if not fromAddressEnabled:
raise APIError(14, 'Your fromAddress is disabled. Cannot send.') raise APIError(14, 'Your fromAddress is disabled. Cannot send.')
ackdata = helper_sent.insert( stealthLevel = BMConfigParser().safeGetInt(
toAddress=toAddress, fromAddress=fromAddress, 'bitmessagesettings', 'ackstealthlevel')
subject=subject, message=message, encoding=encodingType, ttl=TTL) ackdata = genAckPayload(streamNumber, stealthLevel)
toLabel = '' helper_db.put_sent(
queryreturn = sqlQuery( toAddress, fromAddress, subject, message, ackdata,
"SELECT label FROM addressbook WHERE address=?", toAddress) 'msgqueued', encodingType, ttl=TTL)
try:
toLabel, = queryreturn[0][0]
except IndexError:
pass
toLabel = helper_db.get_label(toAddress) or ''
queues.UISignalQueue.put(('displayNewSentMessage', ( queues.UISignalQueue.put(('displayNewSentMessage', (
toAddress, toLabel, fromAddress, subject, message, ackdata))) toAddress, toLabel, fromAddress, subject, message, ackdata)))
queues.workerQueue.put(('sendmessage', toAddress)) queues.workerQueue.put(('sendmessage', toAddress))
@ -1151,15 +1142,15 @@ class BMRPCDispatcher(object):
self.config.getboolean(fromAddress, 'enabled') self.config.getboolean(fromAddress, 'enabled')
except BaseException: except BaseException:
raise APIError( raise APIError(
13, 'Could not find your fromAddress in the keys.dat file.') 13, 'could not find your fromAddress in the keys.dat file.')
toAddress = str_broadcast_subscribers streamNumber = decodeAddress(fromAddress)[2]
ackdata = genAckPayload(streamNumber, 0)
toAddress = toLabel = str_broadcast_subscribers
ackdata = helper_sent.insert( helper_db.put_sent(
fromAddress=fromAddress, subject=subject, toAddress, fromAddress, subject, message, ackdata,
message=message, status='broadcastqueued', 'broadcastqueued', encodingType, ttl=TTL)
encoding=encodingType)
toLabel = str_broadcast_subscribers
queues.UISignalQueue.put(('displayNewSentMessage', ( queues.UISignalQueue.put(('displayNewSentMessage', (
toAddress, toLabel, fromAddress, subject, message, ackdata))) toAddress, toLabel, fromAddress, subject, message, ackdata)))
queues.workerQueue.put(('sendbroadcast', '')) queues.workerQueue.put(('sendbroadcast', ''))
@ -1197,15 +1188,8 @@ class BMRPCDispatcher(object):
except UnicodeDecodeError: except UnicodeDecodeError:
raise APIError(17, 'Label is not valid UTF-8 data.') raise APIError(17, 'Label is not valid UTF-8 data.')
self._verifyAddress(address) self._verifyAddress(address)
address = addBMIfNotPresent(address) if not helper_db.put_subscriptions(label, address):
# First we must check to see if the address is already in the
# subscriptions list.
queryreturn = sqlQuery(
"SELECT * FROM subscriptions WHERE address=?", address)
if queryreturn:
raise APIError(16, 'You are already subscribed to that address.') raise APIError(16, 'You are already subscribed to that address.')
sqlExecute(
"INSERT INTO subscriptions VALUES (?,?,?)", label, address, True)
shared.reloadBroadcastSendersForWhichImWatching() shared.reloadBroadcastSendersForWhichImWatching()
queues.UISignalQueue.put(('rerenderMessagelistFromLabels', '')) queues.UISignalQueue.put(('rerenderMessagelistFromLabels', ''))
queues.UISignalQueue.put(('rerenderSubscriptions', '')) queues.UISignalQueue.put(('rerenderSubscriptions', ''))

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

@ -1,10 +1,11 @@
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
import helper_db
import widgets import widgets
from addresses import addBMIfNotPresent from addresses import addBMIfNotPresent
from bmconfigparser import BMConfigParser from bmconfigparser import BMConfigParser
from dialogs import AddAddressDialog from dialogs import AddAddressDialog
from helper_sql import sqlExecute, sqlQuery from helper_sql import sqlExecute
from queues import UISignalQueue from queues import UISignalQueue
from retranslateui import RetranslateMixin from retranslateui import RetranslateMixin
from tr import _translate from tr import _translate
@ -61,16 +62,14 @@ class Blacklist(QtGui.QWidget, RetranslateMixin):
_translate("MainWindow", "Address is valid."): _translate("MainWindow", "Address is valid."):
address = addBMIfNotPresent(str( address = addBMIfNotPresent(str(
self.NewBlacklistDialogInstance.lineEditAddress.text())) self.NewBlacklistDialogInstance.lineEditAddress.text()))
# First we must check to see if the address is already in the label = str(self.NewBlacklistDialogInstance.lineEditLabel.text().toUtf8())
# address book. The user cannot add it again or else it will if helper_db.put_addresslist(
# cause problems when updating and deleting the entry. label, address,
t = (address,) group='blacklist'
if BMConfigParser().get('bitmessagesettings', 'blackwhitelist') == 'black': if BMConfigParser().get(
sql = '''select * from blacklist where address=?''' 'bitmessagesettings', 'blackwhitelist') == 'black'
else: else 'whitelist'
sql = '''select * from whitelist where address=?''' ):
queryreturn = sqlQuery(sql,*t)
if queryreturn == []:
self.tableWidgetBlacklist.setSortingEnabled(False) self.tableWidgetBlacklist.setSortingEnabled(False)
self.tableWidgetBlacklist.insertRow(0) self.tableWidgetBlacklist.insertRow(0)
newItem = QtGui.QTableWidgetItem(unicode( newItem = QtGui.QTableWidgetItem(unicode(
@ -82,12 +81,6 @@ class Blacklist(QtGui.QWidget, RetranslateMixin):
QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
self.tableWidgetBlacklist.setItem(0, 1, newItem) self.tableWidgetBlacklist.setItem(0, 1, newItem)
self.tableWidgetBlacklist.setSortingEnabled(True) self.tableWidgetBlacklist.setSortingEnabled(True)
t = (str(self.NewBlacklistDialogInstance.lineEditLabel.text().toUtf8()), address, True)
if BMConfigParser().get('bitmessagesettings', 'blackwhitelist') == 'black':
sql = '''INSERT INTO blacklist VALUES (?,?,?)'''
else:
sql = '''INSERT INTO whitelist VALUES (?,?,?)'''
sqlExecute(sql, *t)
else: else:
UISignalQueue.put(( UISignalQueue.put((
'updateStatusBar', 'updateStatusBar',
@ -158,19 +151,18 @@ class Blacklist(QtGui.QWidget, RetranslateMixin):
def rerenderBlackWhiteList(self): def rerenderBlackWhiteList(self):
tabs = self.parent().parent() tabs = self.parent().parent()
if BMConfigParser().get('bitmessagesettings', 'blackwhitelist') == 'black': list_type = BMConfigParser().get(
tabs.setTabText(tabs.indexOf(self), _translate('blacklist', 'Blacklist')) 'bitmessagesettings', 'blackwhitelist')
else: tabs.setTabText(
tabs.setTabText(tabs.indexOf(self), _translate('blacklist', 'Whitelist')) tabs.indexOf(self),
_translate('blacklist', 'Blacklist') if list_type == 'black'
else _translate('blacklist', 'Whitelist'))
self.tableWidgetBlacklist.setRowCount(0) self.tableWidgetBlacklist.setRowCount(0)
listType = BMConfigParser().get('bitmessagesettings', 'blackwhitelist')
if listType == 'black':
queryreturn = sqlQuery('''SELECT label, address, enabled FROM blacklist''')
else:
queryreturn = sqlQuery('''SELECT label, address, enabled FROM whitelist''')
self.tableWidgetBlacklist.setSortingEnabled(False) self.tableWidgetBlacklist.setSortingEnabled(False)
for row in queryreturn: for label, address, enabled in helper_db.get_addresslist(
label, address, enabled = row group='blacklist' if list_type == 'black' else 'whiteslist'
):
self.tableWidgetBlacklist.insertRow(0) self.tableWidgetBlacklist.insertRow(0)
newItem = QtGui.QTableWidgetItem(unicode(label, 'utf-8')) newItem = QtGui.QTableWidgetItem(unicode(label, 'utf-8'))
if not enabled: if not enabled:

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"""

208
src/helper_db.py Normal file
View File

@ -0,0 +1,208 @@
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"]
_groups = ("blacklist", "whitelist", "subscriptions", "addressbook")
_groups_enable = ("blacklist", "whitelist", "subscriptions")
# + 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_trash(msgid, sent=False):
"""Put inbox message (or sent if sent=True) into trash by msgid"""
sqlExecute(
"UPDATE %s SET folder='trash' WHERE msgid=?" %
('sent' if sent else 'inbox'), msgid)
if not sent:
queues.UISignalQueue.put(('removeInboxRowByMsgid', msgid))
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"):
if group not in _groups:
return True
# elif group in _groups_enable:
# try:
# return sqlQuery(
# "SELECT enabled FROM %s WHERE address=?" % group, address
# )[-1][0]
# except IndexError:
# return
else:
return sqlQuery(
"SELECT * 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"""
if group not in _groups:
return
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)
"""
if group not in _groups:
return
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"""
if group not in _groups:
return
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,25 +0,0 @@
"""Helper Inbox performs inbox messages related operations"""
import queues
from helper_sql import sqlExecute, sqlQuery
def insert(t):
"""Perform an insert into the "inbox" table"""
sqlExecute('''INSERT INTO inbox VALUES (?,?,?,?,?,?,?,?,?,?)''', *t)
# shouldn't emit changedInboxUnread and displayNewInboxMessage
# at the same time
# queues.UISignalQueue.put(('changedInboxUnread', None))
def trash(msgid):
"""Mark a message in the `inbox` as `trash`"""
sqlExecute('''UPDATE inbox SET folder='trash' WHERE msgid=?''', msgid)
queues.UISignalQueue.put(('removeInboxRowByMsgid', msgid))
def isMessageAlreadyInInbox(sigHash):
"""Check for previous instances of this message"""
queryReturn = sqlQuery(
'''SELECT COUNT(*) FROM inbox WHERE sighash=?''', sigHash)
return queryReturn[0][0] != 0

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(

View File

@ -366,6 +366,10 @@ def run():
qt_tests = loader.loadTestsFromModule(bitmessageqt.tests) qt_tests = loader.loadTestsFromModule(bitmessageqt.tests)
suite.addTests(qt_tests) suite.addTests(qt_tests)
import sql
sql_tests = loader.loadTestsFromModule(sql)
suite.addTest(sql_tests)
def keep_exc(ex_cls, exc, tb): # pylint: disable=unused-argument def keep_exc(ex_cls, exc, tb): # pylint: disable=unused-argument
"""Own exception hook for test cases""" """Own exception hook for test cases"""
excQueue.put(('tests', exc)) excQueue.put(('tests', exc))

33
src/tests/sql.py Normal file
View File

@ -0,0 +1,33 @@
"""
SQL related core tests
"""
import unittest
import helper_db
class TestSQL(unittest.TestCase):
"""A test case for common SQL-related functions"""
test_address_1 = 'BM-2cVRo3WuKL5vDCKq2XJi1yR366nkHgHfcL'
test_address_2 = 'BM-2cVJn1BusL1j4UezuYkvpqNPCr7kCebeLw'
def test_subscriptions(self):
"""Put address into subscriptions and check that it was added"""
self.assertTrue(
helper_db.put_subscriptions('pass_1', self.test_address_1))
self.assertFalse(
helper_db.put_subscriptions('pass_2', self.test_address_1))
helper_db.put_subscriptions('pass_3', self.test_address_2, False)
for label, addr in helper_db.get_subscriptions():
if addr == self.test_address_1:
self.assertEqual(label, 'pass_1')
break
else:
self.fail('Could not find added address in subscriptions')
for label, addr in helper_db.get_subscriptions():
if addr == self.test_address_2:
self.fail('Got disabled subscription')