OS X Build script and 'add subscription from address book' option #225

Merged
Atheros1 merged 14 commits from master into master 2013-06-19 19:16:58 +02:00
7 changed files with 190 additions and 59 deletions

3
.gitignore vendored
View File

@ -1,2 +1,5 @@
**pyc **pyc
**dat **dat
**.DS_Store
src/build
src/dist

24
osx.sh Executable file
View File

@ -0,0 +1,24 @@
#!/bin/bash
# OS X Build script wrapper around the py2app script.
# These build can only be generated on OS X.
# Requires all build dependencies for Bitmessage
# Especially important is openssl installed through brew
export ARCHFLAGS="-arch i386 -arch x86_64"
if [[ -z "$1" ]]; then
echo "Please supply a version number for this release as the first argument."
exit
fi
echo "Creating OS X packages for Bitmessage. This script will ask for sudo to create the dmg volume"
cd src && python build_osx.py py2app
if [[ $? = "0" ]]; then
sudo hdiutil create -fs HFS+ -volname "Bitmessage" -srcfolder dist/Bitmessage.app dist/bitmessage-v$1.dmg
else
echo "Problem creating Bitmessage.app, stopping."
exit
fi

View File

@ -188,6 +188,8 @@ class MyForm(QtGui.QMainWindow):
"MainWindow", "Send message to this address"), self.on_action_AddressBookSend) "MainWindow", "Send message to this address"), self.on_action_AddressBookSend)
self.actionAddressBookClipboard = self.ui.addressBookContextMenuToolbar.addAction(_translate( self.actionAddressBookClipboard = self.ui.addressBookContextMenuToolbar.addAction(_translate(
"MainWindow", "Copy address to clipboard"), self.on_action_AddressBookClipboard) "MainWindow", "Copy address to clipboard"), self.on_action_AddressBookClipboard)
self.actionAddressBookSubscribe = self.ui.addressBookContextMenuToolbar.addAction(_translate(
"MainWindow", "Subscribe to this address"), self.on_action_AddressBookSubscribe)
self.actionAddressBookNew = self.ui.addressBookContextMenuToolbar.addAction(_translate( self.actionAddressBookNew = self.ui.addressBookContextMenuToolbar.addAction(_translate(
"MainWindow", "Add New Address"), self.on_action_AddressBookNew) "MainWindow", "Add New Address"), self.on_action_AddressBookNew)
self.actionAddressBookDelete = self.ui.addressBookContextMenuToolbar.addAction(_translate( self.actionAddressBookDelete = self.ui.addressBookContextMenuToolbar.addAction(_translate(
@ -199,6 +201,7 @@ class MyForm(QtGui.QMainWindow):
self.popMenuAddressBook = QtGui.QMenu(self) self.popMenuAddressBook = QtGui.QMenu(self)
self.popMenuAddressBook.addAction(self.actionAddressBookSend) self.popMenuAddressBook.addAction(self.actionAddressBookSend)
self.popMenuAddressBook.addAction(self.actionAddressBookClipboard) self.popMenuAddressBook.addAction(self.actionAddressBookClipboard)
self.popMenuAddressBook.addAction( self.actionAddressBookSubscribe )
self.popMenuAddressBook.addSeparator() self.popMenuAddressBook.addSeparator()
self.popMenuAddressBook.addAction(self.actionAddressBookNew) self.popMenuAddressBook.addAction(self.actionAddressBookNew)
self.popMenuAddressBook.addAction(self.actionAddressBookDelete) self.popMenuAddressBook.addAction(self.actionAddressBookDelete)
@ -1646,51 +1649,44 @@ class MyForm(QtGui.QMainWindow):
self.statusBar().showMessage(_translate( self.statusBar().showMessage(_translate(
"MainWindow", "The address you entered was invalid. Ignoring it.")) "MainWindow", "The address you entered was invalid. Ignoring it."))
def click_pushButtonAddSubscription(self): def addSubscription(self, label, address):
self.NewSubscriptionDialogInstance = NewSubscriptionDialog(self) address = addBMIfNotPresent(address)
#This should be handled outside of this function, for error displaying and such, but it must also be checked here.
if self.NewSubscriptionDialogInstance.exec_(): if shared.isAddressInMySubscriptionsList(address):
if self.NewSubscriptionDialogInstance.ui.labelSubscriptionAddressCheck.text() == _translate("MainWindow", "Address is valid."): return
# First we must check to see if the address is already in the #Add to UI list
# subscriptions list. The user cannot add it again or else it
# will cause problems when updating and deleting the entry.
shared.sqlLock.acquire()
t = (addBMIfNotPresent(str(
self.NewSubscriptionDialogInstance.ui.lineEditSubscriptionAddress.text())),)
shared.sqlSubmitQueue.put(
'''select * from subscriptions where address=?''')
shared.sqlSubmitQueue.put(t)
queryreturn = shared.sqlReturnQueue.get()
shared.sqlLock.release()
if queryreturn == []:
self.ui.tableWidgetSubscriptions.setSortingEnabled(False) self.ui.tableWidgetSubscriptions.setSortingEnabled(False)
self.ui.tableWidgetSubscriptions.insertRow(0) self.ui.tableWidgetSubscriptions.insertRow(0)
newItem = QtGui.QTableWidgetItem(unicode( newItem = QtGui.QTableWidgetItem(unicode(label, 'utf-8'))
self.NewSubscriptionDialogInstance.ui.newsubscriptionlabel.text().toUtf8(), 'utf-8')) self.ui.tableWidgetSubscriptions.setItem(0,0,newItem)
self.ui.tableWidgetSubscriptions.setItem(0, 0, newItem) newItem = QtGui.QTableWidgetItem(address)
newItem = QtGui.QTableWidgetItem(addBMIfNotPresent( newItem.setFlags( QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled )
self.NewSubscriptionDialogInstance.ui.lineEditSubscriptionAddress.text())) self.ui.tableWidgetSubscriptions.setItem(0,1,newItem)
newItem.setFlags(
QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
self.ui.tableWidgetSubscriptions.setItem(0, 1, newItem)
self.ui.tableWidgetSubscriptions.setSortingEnabled(True) self.ui.tableWidgetSubscriptions.setSortingEnabled(True)
t = (str(self.NewSubscriptionDialogInstance.ui.newsubscriptionlabel.text().toUtf8()), addBMIfNotPresent( #Add to database (perhaps this should be separated from the MyForm class)
str(self.NewSubscriptionDialogInstance.ui.lineEditSubscriptionAddress.text())), True) t = (str(label),address,True)
shared.sqlLock.acquire() shared.sqlLock.acquire()
shared.sqlSubmitQueue.put( shared.sqlSubmitQueue.put('''INSERT INTO subscriptions VALUES (?,?,?)''')
'''INSERT INTO subscriptions VALUES (?,?,?)''')
shared.sqlSubmitQueue.put(t) shared.sqlSubmitQueue.put(t)
queryreturn = shared.sqlReturnQueue.get() queryreturn = shared.sqlReturnQueue.get()
shared.sqlSubmitQueue.put('commit') shared.sqlSubmitQueue.put('commit')
shared.sqlLock.release() shared.sqlLock.release()
self.rerenderInboxFromLabels() self.rerenderInboxFromLabels()
shared.reloadBroadcastSendersForWhichImWatching() shared.reloadBroadcastSendersForWhichImWatching()
else:
self.statusBar().showMessage(_translate( def click_pushButtonAddSubscription(self):
"MainWindow", "Error: You cannot add the same address to your subsciptions twice. Perhaps rename the existing one if you want.")) self.NewSubscriptionDialogInstance = NewSubscriptionDialog(self)
else: if self.NewSubscriptionDialogInstance.exec_():
self.statusBar().showMessage(_translate( if self.NewSubscriptionDialogInstance.ui.labelSubscriptionAddressCheck.text() != _translate("MainWindow", "Address is valid."):
"MainWindow", "The address you entered was invalid. Ignoring it.")) self.statusBar().showMessage(_translate("MainWindow", "The address you entered was invalid. Ignoring it."))
return
address = addBMIfNotPresent(str(self.NewSubscriptionDialogInstance.ui.lineEditSubscriptionAddress.text()))
# 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.
if shared.isAddressInMySubscriptionsList(address):
self.statusBar().showMessage(_translate("MainWindow", "Error: You cannot add the same address to your subsciptions twice. Perhaps rename the existing one if you want."))
return
label = self.NewSubscriptionDialogInstance.ui.newsubscriptionlabel.text().toUtf8()
self.addSubscription(label, address)
def loadBlackWhiteList(self): def loadBlackWhiteList(self):
# Initialize the Blacklist or Whitelist table # Initialize the Blacklist or Whitelist table
@ -2242,6 +2238,20 @@ class MyForm(QtGui.QMainWindow):
self.statusBar().showMessage('') self.statusBar().showMessage('')
self.ui.tabWidget.setCurrentIndex(1) self.ui.tabWidget.setCurrentIndex(1)
def on_action_AddressBookSubscribe(self):
listOfSelectedRows = {}
for i in range(len(self.ui.tableWidgetAddressBook.selectedIndexes())):
listOfSelectedRows[self.ui.tableWidgetAddressBook.selectedIndexes()[i].row()] = 0
for currentRow in listOfSelectedRows:
addressAtCurrentRow = str(self.ui.tableWidgetAddressBook.item(currentRow,1).text())
# Then subscribe to it... provided it's not already in the address book
if shared.isAddressInMySubscriptionsList(addressAtCurrentRow):
self.statusBar().showMessage(QtGui.QApplication.translate("MainWindow", "Error: You cannot add the same address to your subsciptions twice. Perhaps rename the existing one if you want."))
continue
labelAtCurrentRow = self.ui.tableWidgetAddressBook.item(currentRow,0).text().toUtf8()
self.addSubscription(labelAtCurrentRow, addressAtCurrentRow)
self.ui.tabWidget.setCurrentIndex(4)
def on_context_menuAddressBook(self, point): def on_context_menuAddressBook(self, point):
self.popMenuAddressBook.exec_( self.popMenuAddressBook.exec_(
self.ui.tableWidgetAddressBook.mapToGlobal(point)) self.ui.tableWidgetAddressBook.mapToGlobal(point))

80
src/build_osx.py Normal file
View File

@ -0,0 +1,80 @@
"""
py2app/py2exe build script for Bitmessage
Usage (Mac OS X):
python setup.py py2app
Usage (Windows):
python setup.py py2exe
"""
import sys, os, shutil, re
from setuptools import setup
name = "Bitmessage"
mainscript = 'bitmessagemain.py'
version = "0.3.3"
if sys.platform == 'darwin':
extra_options = dict(
setup_requires=['py2app'],
app=[mainscript],
options=dict(py2app=dict(argv_emulation=True,
includes = ['PyQt4.QtCore','PyQt4.QtGui', 'sip'],
packages = ['bitmessageqt'],
frameworks = ['/usr/local/opt/openssl/lib/libcrypto.dylib'],
iconfile='images/bitmessage.icns',
resources=["images"])),
)
elif sys.platform == 'win32':
extra_options = dict(
setup_requires=['py2exe'],
app=[mainscript],
)
else:
extra_options = dict(
# Normally unix-like platforms will use "setup.py install"
# and install the main script as such
scripts=[mainscript],
)
setup(
name = name,
version = version,
**extra_options
)
from distutils import dir_util
import glob
if sys.platform == 'darwin':
resource = "dist/" + name + ".app/Contents/Resources/"
framework = "dist/" + name + ".app/Contents/Frameworks/"
# The pyElliptive module only works with hardcoded libcrypto paths so rename it so it can actually find it.
libs = glob.glob(framework + "libcrypto*.dylib")
for lib in libs:
os.rename(lib, framework + "libcrypto.dylib")
break
# Try to locate qt_menu
# Let's try the port version first!
if os.path.isfile("/opt/local/lib/Resources/qt_menu.nib"):
qt_menu_location = "/opt/local/lib/Resources/qt_menu.nib"
else:
# No dice? Then let's try the brew version
qt_menu_location = os.popen("find /usr/local/Cellar -name qt_menu.nib | tail -n 1").read()
qt_menu_location = re.sub('\n','', qt_menu_location)
if(len(qt_menu_location) == 0):
print "Sorry couldn't find your qt_menu.nib this probably won't work"
else:
print "Found your qib: " + qt_menu_location
# Need to include a copy of qt_menu.nib
shutil.copytree(qt_menu_location, resource + "qt_menu.nib")
# Need to touch qt.conf to avoid loading 2 sets of Qt libraries
fname = resource + "qt.conf"
with file(fname, 'a'):
os.utime(fname, None)

BIN
src/images/bitmessage.icns Normal file

Binary file not shown.

View File

@ -417,6 +417,10 @@ except:
try: try:
# try homebrew installation # try homebrew installation
OpenSSL = _OpenSSL('/usr/local/opt/openssl/lib/libcrypto.dylib') OpenSSL = _OpenSSL('/usr/local/opt/openssl/lib/libcrypto.dylib')
except:
try:
# Load it from an Bitmessage.app on OSX
OpenSSL = _OpenSSL('./../Frameworks/libcrypto.dylib')
except: except:
try: try:
from os import path from os import path

View File

@ -59,6 +59,16 @@ def isAddressInMyAddressBook(address):
sqlLock.release() sqlLock.release()
return queryreturn != [] return queryreturn != []
#At this point we should really just have a isAddressInMy(book, address)...
def isAddressInMySubscriptionsList(address):
t = (str(address),) # As opposed to Qt str
sqlLock.acquire()
sqlSubmitQueue.put('''select * from subscriptions where address=?''')
sqlSubmitQueue.put(t)
queryreturn = sqlReturnQueue.get()
sqlLock.release()
return queryreturn != []
def isAddressInMyAddressBookSubscriptionsListOrWhitelist(address): def isAddressInMyAddressBookSubscriptionsListOrWhitelist(address):
if isAddressInMyAddressBook(address): if isAddressInMyAddressBook(address):
return True return True
@ -185,7 +195,7 @@ def doCleanShutdown():
printLock.release() printLock.release()
os._exit(0) os._exit(0)
#Wen you want to command a sendDataThread to do something, like shutdown or send some data, this function puts your data into the queues for each of the sendDataThreads. The sendDataThreads are responsible for putting their queue into (and out of) the sendDataQueues list. #When you want to command a sendDataThread to do something, like shutdown or send some data, this function puts your data into the queues for each of the sendDataThreads. The sendDataThreads are responsible for putting their queue into (and out of) the sendDataQueues list.
def broadcastToSendDataQueues(data): def broadcastToSendDataQueues(data):
#print 'running broadcastToSendDataQueues' #print 'running broadcastToSendDataQueues'
for q in sendDataQueues: for q in sendDataQueues: