Merge branch 'v0.6' of https://github.com/surbhicis/PyBitmessage into UiChanges

This commit is contained in:
surbhi 2019-09-24 17:48:17 +05:30
commit a4565d169d
No known key found for this signature in database
GPG Key ID: 88928762974D3618

View File

@ -1,40 +1,40 @@
"""
src/bitmessagecurses/__init__.py
================================
"""
# Copyright (c) 2014 Luke Montalvo <lukemontalvo@gmail.com> # Copyright (c) 2014 Luke Montalvo <lukemontalvo@gmail.com>
# This file adds a alternative commandline interface, feel free to critique and fork # This file adds a alternative commandline interface, feel free to critique and fork
# #
# This has only been tested on Arch Linux and Linux Mint # This has only been tested on Arch Linux and Linux Mint
# Dependencies: # Dependencies:
# * from python2-pip # * from python2-pip
# * python2-pythondialog # * python2-pythondialog
# * dialog # * dialog
import ConfigParser
import curses
import os import os
import sys import sys
import StringIO
from textwrap import *
import time import time
from time import strftime, localtime from textwrap import fill
from threading import Timer from threading import Timer
import curses from addresses import addBMIfNotPresent, decodeAddress
import dialog
from dialog import Dialog
from helper_sql import *
from helper_ackPayload import genAckPayload
from addresses import *
import ConfigParser
from bmconfigparser import BMConfigParser from bmconfigparser import BMConfigParser
from dialog import Dialog
from helper_ackPayload import genAckPayload
from helper_sql import sqlExecute, sqlQuery
from inventory import Inventory from inventory import Inventory
import l10n import l10n
import network.stats
from pyelliptic.openssl import OpenSSL from pyelliptic.openssl import OpenSSL
import queues import queues
import shared import shared
import shutdown import shutdown
import network.stats
quit = False quit = False # pylint: disable=redefined-builtin
menutab = 1 menutab = 1
menu = ["Inbox", "Send", "Sent", "Your Identities", "Subscriptions", "Address Book", "Blacklist", "Network Status"] menu = ["Inbox", "Send", "Sent", "Your Identities", "Subscriptions", "Address Book", "Blacklist", "Network Status"]
naptime = 100 naptime = 100
@ -60,156 +60,189 @@ bwtype = "black"
BROADCAST_STR = "[Broadcast subscribers]" BROADCAST_STR = "[Broadcast subscribers]"
class printLog:
class printLog: # pylint: disable=no-self-use, no-init, old-style-class
"""Printing logs"""
def write(self, output): def write(self, output):
# pylint: disable=global-statement
global log global log
log += output log += output
def flush(self): def flush(self):
pass pass
class errLog:
class errLog: # pylint: disable=no-self-use, no-init, old-style-class
"""Error logs"""
def write(self, output): def write(self, output):
# pylint: disable=global-statement
global log global log
log += "!"+output log += "!" + output
def flush(self): def flush(self):
pass pass
printlog = printLog() printlog = printLog()
errlog = errLog() errlog = errLog()
def cpair(a): def cpair(a):
"""Color pairs"""
r = curses.color_pair(a) r = curses.color_pair(a)
if r not in range(1, curses.COLOR_PAIRS-1): if r not in range(1, curses.COLOR_PAIRS - 1):
r = curses.color_pair(0) r = curses.color_pair(0)
return r return r
def ascii(s): def ascii(s):
"""ASCII values"""
r = "" r = ""
for c in s: for c in s:
if ord(c) in range(128): if ord(c) in range(128):
r += c r += c
return r return r
def drawmenu(stdscr): def drawmenu(stdscr):
"""Creating menu's"""
menustr = " " menustr = " "
for i in range(0, len(menu)): for i, _ in enumerate(menu):
if menutab == i+1: if menutab == i + 1:
menustr = menustr[:-1] menustr = menustr[:-1]
menustr += "[" menustr += "["
menustr += str(i+1)+menu[i] menustr += str(i + 1) + menu[i]
if menutab == i+1: if menutab == i + 1:
menustr += "] " menustr += "] "
elif i != len(menu)-1: elif i != len(menu) - 1:
menustr += " " menustr += " "
stdscr.addstr(2, 5, menustr, curses.A_UNDERLINE) stdscr.addstr(2, 5, menustr, curses.A_UNDERLINE)
def set_background_title(d, title): def set_background_title(d, title):
"""Setting background title"""
try: try:
d.set_background_title(title) d.set_background_title(title)
except: except:
d.add_persistent_args(("--backtitle", title)) d.add_persistent_args(("--backtitle", title))
def scrollbox(d, text, height=None, width=None): def scrollbox(d, text, height=None, width=None):
"""Setting scroll box"""
try: try:
d.scrollbox(text, height, width, exit_label = "Continue") d.scrollbox(text, height, width, exit_label="Continue")
except: except:
d.msgbox(text, height or 0, width or 0, ok_label = "Continue") d.msgbox(text, height or 0, width or 0, ok_label="Continue")
def resetlookups(): def resetlookups():
global inventorydata """Reset the Inventory Lookups"""
global inventorydata # pylint: disable=global-statement
inventorydata = Inventory().numberOfInventoryLookupsPerformed inventorydata = Inventory().numberOfInventoryLookupsPerformed
Inventory().numberOfInventoryLookupsPerformed = 0 Inventory().numberOfInventoryLookupsPerformed = 0
Timer(1, resetlookups, ()).start() Timer(1, resetlookups, ()).start()
def drawtab(stdscr):
if menutab in range(1, len(menu)+1):
if menutab == 1: # Inbox def drawtab(stdscr): # pylint: disable=too-many-branches, too-many-statements
"""Method for drawing different tabs"""
if menutab in range(1, len(menu) + 1):
if menutab == 1: # Inbox
stdscr.addstr(3, 5, "To", curses.A_BOLD) stdscr.addstr(3, 5, "To", curses.A_BOLD)
stdscr.addstr(3, 40, "From", curses.A_BOLD) stdscr.addstr(3, 40, "From", curses.A_BOLD)
stdscr.addstr(3, 80, "Subject", curses.A_BOLD) stdscr.addstr(3, 80, "Subject", curses.A_BOLD)
stdscr.addstr(3, 120, "Time Received", curses.A_BOLD) stdscr.addstr(3, 120, "Time Received", curses.A_BOLD)
stdscr.hline(4, 5, '-', 121) stdscr.hline(4, 5, '-', 121)
for i, item in enumerate(inbox[max(min(len(inbox)-curses.LINES+6, inboxcur-5), 0):]): for i, item in enumerate(inbox[max(min(len(inbox) - curses.LINES + 6, inboxcur - 5), 0):]):
if 6+i < curses.LINES: if 6 + i < curses.LINES:
a = 0 a = 0
if i == inboxcur - max(min(len(inbox)-curses.LINES+6, inboxcur-5), 0): # Highlight current address if i == inboxcur - max(min(len(inbox) - curses.LINES + 6, inboxcur - 5), 0):
# Highlight current address
a = a | curses.A_REVERSE a = a | curses.A_REVERSE
if item[7] == False: # If not read, highlight if item[7] is False: # If not read, highlight
a = a | curses.A_BOLD a = a | curses.A_BOLD
stdscr.addstr(5+i, 5, item[1][:34], a) stdscr.addstr(5 + i, 5, item[1][:34], a)
stdscr.addstr(5+i, 40, item[3][:39], a) stdscr.addstr(5 + i, 40, item[3][:39], a)
stdscr.addstr(5+i, 80, item[5][:39], a) stdscr.addstr(5 + i, 80, item[5][:39], a)
stdscr.addstr(5+i, 120, item[6][:39], a) stdscr.addstr(5 + i, 120, item[6][:39], a)
elif menutab == 3: # Sent elif menutab == 3: # Sent
stdscr.addstr(3, 5, "To", curses.A_BOLD) stdscr.addstr(3, 5, "To", curses.A_BOLD)
stdscr.addstr(3, 40, "From", curses.A_BOLD) stdscr.addstr(3, 40, "From", curses.A_BOLD)
stdscr.addstr(3, 80, "Subject", curses.A_BOLD) stdscr.addstr(3, 80, "Subject", curses.A_BOLD)
stdscr.addstr(3, 120, "Status", curses.A_BOLD) stdscr.addstr(3, 120, "Status", curses.A_BOLD)
stdscr.hline(4, 5, '-', 121) stdscr.hline(4, 5, '-', 121)
for i, item in enumerate(sentbox[max(min(len(sentbox)-curses.LINES+6, sentcur-5), 0):]): for i, item in enumerate(sentbox[max(min(len(sentbox) - curses.LINES + 6, sentcur - 5), 0):]):
if 6+i < curses.LINES: if 6 + i < curses.LINES:
a = 0 a = 0
if i == sentcur - max(min(len(sentbox)-curses.LINES+6, sentcur-5), 0): # Highlight current address if i == sentcur - max(min(len(sentbox) - curses.LINES + 6, sentcur - 5), 0):
# Highlight current address
a = a | curses.A_REVERSE a = a | curses.A_REVERSE
stdscr.addstr(5+i, 5, item[0][:34], a) stdscr.addstr(5 + i, 5, item[0][:34], a)
stdscr.addstr(5+i, 40, item[2][:39], a) stdscr.addstr(5 + i, 40, item[2][:39], a)
stdscr.addstr(5+i, 80, item[4][:39], a) stdscr.addstr(5 + i, 80, item[4][:39], a)
stdscr.addstr(5+i, 120, item[5][:39], a) stdscr.addstr(5 + i, 120, item[5][:39], a)
elif menutab == 2 or menutab == 4: # Send or Identities elif menutab == 2 or menutab == 4: # Send or Identities
stdscr.addstr(3, 5, "Label", curses.A_BOLD) stdscr.addstr(3, 5, "Label", curses.A_BOLD)
stdscr.addstr(3, 40, "Address", curses.A_BOLD) stdscr.addstr(3, 40, "Address", curses.A_BOLD)
stdscr.addstr(3, 80, "Stream", curses.A_BOLD) stdscr.addstr(3, 80, "Stream", curses.A_BOLD)
stdscr.hline(4, 5, '-', 81) stdscr.hline(4, 5, '-', 81)
for i, item in enumerate(addresses[max(min(len(addresses)-curses.LINES+6, addrcur-5), 0):]): for i, item in enumerate(addresses[max(min(len(addresses) - curses.LINES + 6, addrcur - 5), 0):]):
if 6+i < curses.LINES: if 6 + i < curses.LINES:
a = 0 a = 0
if i == addrcur - max(min(len(addresses)-curses.LINES+6, addrcur-5), 0): # Highlight current address if i == addrcur - max(min(len(addresses) - curses.LINES + 6, addrcur - 5), 0):
# Highlight current address
a = a | curses.A_REVERSE a = a | curses.A_REVERSE
if item[1] == True and item[3] not in [8,9]: # Embolden enabled, non-special addresses if item[1] and item[3] not in [8, 9]: # Embolden enabled, non-special addresses
a = a | curses.A_BOLD a = a | curses.A_BOLD
stdscr.addstr(5+i, 5, item[0][:34], a) stdscr.addstr(5 + i, 5, item[0][:34], a)
stdscr.addstr(5+i, 40, item[2][:39], cpair(item[3]) | a) stdscr.addstr(5 + i, 40, item[2][:39], cpair(item[3]) | a)
stdscr.addstr(5+i, 80, str(1)[:39], a) stdscr.addstr(5 + i, 80, str(1)[:39], a)
elif menutab == 5: # Subscriptions elif menutab == 5: # Subscriptions
stdscr.addstr(3, 5, "Label", curses.A_BOLD) stdscr.addstr(3, 5, "Label", curses.A_BOLD)
stdscr.addstr(3, 80, "Address", curses.A_BOLD) stdscr.addstr(3, 80, "Address", curses.A_BOLD)
stdscr.addstr(3, 120, "Enabled", curses.A_BOLD) stdscr.addstr(3, 120, "Enabled", curses.A_BOLD)
stdscr.hline(4, 5, '-', 121) stdscr.hline(4, 5, '-', 121)
for i, item in enumerate(subscriptions[max(min(len(subscriptions)-curses.LINES+6, subcur-5), 0):]): for i, item in enumerate(subscriptions[max(min(len(subscriptions) - curses.LINES + 6, subcur - 5), 0):]):
if 6+i < curses.LINES: if 6 + i < curses.LINES:
a = 0 a = 0
if i == subcur - max(min(len(subscriptions)-curses.LINES+6, subcur-5), 0): # Highlight current address if i == subcur - max(min(len(subscriptions) - curses.LINES + 6, subcur - 5), 0):
# Highlight current address
a = a | curses.A_REVERSE a = a | curses.A_REVERSE
if item[2] == True: # Embolden enabled subscriptions if item[2]: # Embolden enabled subscriptions
a = a | curses.A_BOLD a = a | curses.A_BOLD
stdscr.addstr(5+i, 5, item[0][:74], a) stdscr.addstr(5 + i, 5, item[0][:74], a)
stdscr.addstr(5+i, 80, item[1][:39], a) stdscr.addstr(5 + i, 80, item[1][:39], a)
stdscr.addstr(5+i, 120, str(item[2]), a) stdscr.addstr(5 + i, 120, str(item[2]), a)
elif menutab == 6: # Address book elif menutab == 6: # Address book
stdscr.addstr(3, 5, "Label", curses.A_BOLD) stdscr.addstr(3, 5, "Label", curses.A_BOLD)
stdscr.addstr(3, 40, "Address", curses.A_BOLD) stdscr.addstr(3, 40, "Address", curses.A_BOLD)
stdscr.hline(4, 5, '-', 41) stdscr.hline(4, 5, '-', 41)
for i, item in enumerate(addrbook[max(min(len(addrbook)-curses.LINES+6, abookcur-5), 0):]): for i, item in enumerate(addrbook[max(min(len(addrbook) - curses.LINES + 6, abookcur - 5), 0):]):
if 6+i < curses.LINES: if 6 + i < curses.LINES:
a = 0 a = 0
if i == abookcur - max(min(len(addrbook)-curses.LINES+6, abookcur-5), 0): # Highlight current address if i == abookcur - max(min(len(addrbook) - curses.LINES + 6, abookcur - 5), 0):
# Highlight current address
a = a | curses.A_REVERSE a = a | curses.A_REVERSE
stdscr.addstr(5+i, 5, item[0][:34], a) stdscr.addstr(5 + i, 5, item[0][:34], a)
stdscr.addstr(5+i, 40, item[1][:39], a) stdscr.addstr(5 + i, 40, item[1][:39], a)
elif menutab == 7: # Blacklist elif menutab == 7: # Blacklist
stdscr.addstr(3, 5, "Type: "+bwtype) stdscr.addstr(3, 5, "Type: " + bwtype)
stdscr.addstr(4, 5, "Label", curses.A_BOLD) stdscr.addstr(4, 5, "Label", curses.A_BOLD)
stdscr.addstr(4, 80, "Address", curses.A_BOLD) stdscr.addstr(4, 80, "Address", curses.A_BOLD)
stdscr.addstr(4, 120, "Enabled", curses.A_BOLD) stdscr.addstr(4, 120, "Enabled", curses.A_BOLD)
stdscr.hline(5, 5, '-', 121) stdscr.hline(5, 5, '-', 121)
for i, item in enumerate(blacklist[max(min(len(blacklist)-curses.LINES+6, blackcur-5), 0):]): for i, item in enumerate(blacklist[max(min(len(blacklist) - curses.LINES + 6, blackcur - 5), 0):]):
if 7+i < curses.LINES: if 7 + i < curses.LINES:
a = 0 a = 0
if i == blackcur - max(min(len(blacklist)-curses.LINES+6, blackcur-5), 0): # Highlight current address if i == blackcur - max(min(len(blacklist) - curses.LINES + 6, blackcur - 5), 0):
# Highlight current address
a = a | curses.A_REVERSE a = a | curses.A_REVERSE
if item[2] == True: # Embolden enabled subscriptions if item[2]: # Embolden enabled subscriptions
a = a | curses.A_BOLD a = a | curses.A_BOLD
stdscr.addstr(6+i, 5, item[0][:74], a) stdscr.addstr(6 + i, 5, item[0][:74], a)
stdscr.addstr(6+i, 80, item[1][:39], a) stdscr.addstr(6 + i, 80, item[1][:39], a)
stdscr.addstr(6+i, 120, str(item[2]), a) stdscr.addstr(6 + i, 120, str(item[2]), a)
elif menutab == 8: # Network status elif menutab == 8: # Network status
# Connection data # Connection data
connected_hosts = network.stats.connectedHostsList() connected_hosts = network.stats.connectedHostsList()
stdscr.addstr( stdscr.addstr(
@ -228,51 +261,63 @@ def drawtab(stdscr):
for i, item in enumerate(streamcount): for i, item in enumerate(streamcount):
if i < 4: if i < 4:
if i == 0: if i == 0:
stdscr.addstr(8+i, 6, "?") stdscr.addstr(8 + i, 6, "?")
else: else:
stdscr.addstr(8+i, 6, str(i)) stdscr.addstr(8 + i, 6, str(i))
stdscr.addstr(8+i, 18, str(item).ljust(2)) stdscr.addstr(8 + i, 18, str(item).ljust(2))
# Uptime and processing data # Uptime and processing data
stdscr.addstr(6, 35, "Since startup on "+l10n.formatTimestamp(startuptime, False)) stdscr.addstr(6, 35, "Since startup on " + l10n.formatTimestamp(startuptime, False))
stdscr.addstr(7, 40, "Processed "+str(shared.numberOfMessagesProcessed).ljust(4)+" person-to-person messages.") stdscr.addstr(7, 40, "Processed " + str(
stdscr.addstr(8, 40, "Processed "+str(shared.numberOfBroadcastsProcessed).ljust(4)+" broadcast messages.") shared.numberOfMessagesProcessed).ljust(4) + " person-to-person messages.")
stdscr.addstr(9, 40, "Processed "+str(shared.numberOfPubkeysProcessed).ljust(4)+" public keys.") stdscr.addstr(8, 40, "Processed " + str(
shared.numberOfBroadcastsProcessed).ljust(4) + " broadcast messages.")
stdscr.addstr(9, 40, "Processed " + str(
shared.numberOfPubkeysProcessed).ljust(4) + " public keys.")
# Inventory data # Inventory data
stdscr.addstr(11, 35, "Inventory lookups per second: "+str(inventorydata).ljust(3)) stdscr.addstr(11, 35, "Inventory lookups per second: " + str(inventorydata).ljust(3))
# Log # Log
stdscr.addstr(13, 6, "Log", curses.A_BOLD) stdscr.addstr(13, 6, "Log", curses.A_BOLD)
n = log.count('\n') n = log.count('\n')
if n > 0: if n > 0:
l = log.split('\n') l = log.split('\n')
if n > 512: if n > 512:
del l[:(n-256)] del l[:(n - 256)]
logpad.erase() logpad.erase()
n = len(l) n = len(l)
for i, item in enumerate(l): for i, item in enumerate(l):
a = 0 a = 0
if len(item) > 0 and item[0] == '!': if item and item[0] == '!':
a = curses.color_pair(1) a = curses.color_pair(1)
item = item[1:] item = item[1:]
logpad.addstr(i, 0, item, a) logpad.addstr(i, 0, item, a)
logpad.refresh(n-curses.LINES+2, 0, 14, 6, curses.LINES-2, curses.COLS-7) logpad.refresh(n - curses.LINES + 2, 0, 14, 6, curses.LINES - 2, curses.COLS - 7)
stdscr.refresh() stdscr.refresh()
def redraw(stdscr): def redraw(stdscr):
"""Redraw menu"""
stdscr.erase() stdscr.erase()
stdscr.border() stdscr.border()
drawmenu(stdscr) drawmenu(stdscr)
stdscr.refresh() stdscr.refresh()
def dialogreset(stdscr): def dialogreset(stdscr):
"""Resetting dialogue"""
stdscr.clear() stdscr.clear()
stdscr.keypad(1) stdscr.keypad(1)
curses.curs_set(0) curses.curs_set(0)
# pylint: disable=too-many-branches, too-many-statements
def handlech(c, stdscr): def handlech(c, stdscr):
# pylint: disable=redefined-outer-name, too-many-nested-blocks, too-many-locals, global-statement
if c != curses.ERR: if c != curses.ERR:
global inboxcur, addrcur, sentcur, subcur, abookcur, blackcur global inboxcur, addrcur, sentcur, subcur, abookcur, blackcur
if c in range(256): if c in range(256):
if chr(c) in '12345678': if chr(c) in '12345678':
global menutab global menutab
menutab = int(chr(c)) menutab = int(chr(c))
@ -284,17 +329,27 @@ def handlech(c, stdscr):
d = Dialog(dialog="dialog") d = Dialog(dialog="dialog")
if menutab == 1: if menutab == 1:
set_background_title(d, "Inbox Message Dialog Box") set_background_title(d, "Inbox Message Dialog Box")
r, t = d.menu("Do what with \""+inbox[inboxcur][5]+"\" from \""+inbox[inboxcur][3]+"\"?", r, t = d.menu(
choices=[("1", "View message"), "Do what with \"" + inbox[inboxcur][5] + "\" from \"" + inbox[inboxcur][3] + "\"?",
choices=[
("1", "View message"),
("2", "Mark message as unread"), ("2", "Mark message as unread"),
("3", "Reply"), ("3", "Reply"),
("4", "Add sender to Address Book"), ("4", "Add sender to Address Book"),
("5", "Save message as text file"), ("5", "Save message as text file"),
("6", "Move to trash")]) ("6", "Move to trash")])
if r == d.DIALOG_OK: if r == d.DIALOG_OK:
if t == "1": # View if t == "1": # View
set_background_title(d, "\""+inbox[inboxcur][5]+"\" from \""+inbox[inboxcur][3]+"\" to \""+inbox[inboxcur][1]+"\"") set_background_title(
data = "" d,
"\"" +
inbox[inboxcur][5] +
"\" from \"" +
inbox[inboxcur][3] +
"\" to \"" +
inbox[inboxcur][1] +
"\"")
data = "" # pyint: disable=redefined-outer-name
ret = sqlQuery("SELECT message FROM inbox WHERE msgid=?", inbox[inboxcur][0]) ret = sqlQuery("SELECT message FROM inbox WHERE msgid=?", inbox[inboxcur][0])
if ret != []: if ret != []:
for row in ret: for row in ret:
@ -302,16 +357,16 @@ def handlech(c, stdscr):
data = shared.fixPotentiallyInvalidUTF8Data(data) data = shared.fixPotentiallyInvalidUTF8Data(data)
msg = "" msg = ""
for i, item in enumerate(data.split("\n")): for i, item in enumerate(data.split("\n")):
msg += fill(item, replace_whitespace=False)+"\n" msg += fill(item, replace_whitespace=False) + "\n"
scrollbox(d, unicode(ascii(msg)), 30, 80) scrollbox(d, unicode(ascii(msg)), 30, 80)
sqlExecute("UPDATE inbox SET read=1 WHERE msgid=?", inbox[inboxcur][0]) sqlExecute("UPDATE inbox SET read=1 WHERE msgid=?", inbox[inboxcur][0])
inbox[inboxcur][7] = 1 inbox[inboxcur][7] = 1
else: else:
scrollbox(d, unicode("Could not fetch message.")) scrollbox(d, unicode("Could not fetch message."))
elif t == "2": # Mark unread elif t == "2": # Mark unread
sqlExecute("UPDATE inbox SET read=0 WHERE msgid=?", inbox[inboxcur][0]) sqlExecute("UPDATE inbox SET read=0 WHERE msgid=?", inbox[inboxcur][0])
inbox[inboxcur][7] = 0 inbox[inboxcur][7] = 0
elif t == "3": # Reply elif t == "3": # Reply
curses.curs_set(1) curses.curs_set(1)
m = inbox[inboxcur] m = inbox[inboxcur]
fromaddr = m[4] fromaddr = m[4]
@ -320,29 +375,31 @@ def handlech(c, stdscr):
if fromaddr == item[2] and item[3] != 0: if fromaddr == item[2] and item[3] != 0:
ischan = True ischan = True
break break
if not addresses[i][1]: if not addresses[i][1]: # pylint: disable=undefined-loop-variable
scrollbox(d, unicode("Sending address disabled, please either enable it or choose a different address.")) scrollbox(d, unicode(
"Sending address disabled, please either enable it"
"or choose a different address."))
return return
toaddr = m[2] toaddr = m[2]
if ischan: if ischan:
toaddr = fromaddr toaddr = fromaddr
subject = m[5] subject = m[5]
if not m[5][:4] == "Re: ": if not m[5][:4] == "Re: ":
subject = "Re: "+m[5] subject = "Re: " + m[5]
body = "" body = ""
ret = sqlQuery("SELECT message FROM inbox WHERE msgid=?", m[0]) ret = sqlQuery("SELECT message FROM inbox WHERE msgid=?", m[0])
if ret != []: if ret != []:
body = "\n\n------------------------------------------------------\n" body = "\n\n------------------------------------------------------\n"
for row in ret: for row in ret:
body, = row body, = row
sendMessage(fromaddr, toaddr, ischan, subject, body, True) sendMessage(fromaddr, toaddr, ischan, subject, body, True)
dialogreset(stdscr) dialogreset(stdscr)
elif t == "4": # Add to Address Book elif t == "4": # Add to Address Book
addr = inbox[inboxcur][4] addr = inbox[inboxcur][4]
if addr not in [item[1] for i,item in enumerate(addrbook)]: if addr not in [item[1] for i, item in enumerate(addrbook)]:
r, t = d.inputbox("Label for address \""+addr+"\"") r, t = d.inputbox("Label for address \"" + addr + "\"")
if r == d.DIALOG_OK: if r == d.DIALOG_OK:
label = t label = t
sqlExecute("INSERT INTO addressbook VALUES (?,?)", label, addr) sqlExecute("INSERT INTO addressbook VALUES (?,?)", label, addr)
@ -352,61 +409,85 @@ def handlech(c, stdscr):
addrbook.reverse() addrbook.reverse()
else: else:
scrollbox(d, unicode("The selected address is already in the Address Book.")) scrollbox(d, unicode("The selected address is already in the Address Book."))
elif t == "5": # Save message elif t == "5": # Save message
set_background_title(d, "Save \""+inbox[inboxcur][5]+"\" as text file") set_background_title(d, "Save \"" + inbox[inboxcur][5] + "\" as text file")
r, t = d.inputbox("Filename", init=inbox[inboxcur][5]+".txt") r, t = d.inputbox("Filename", init=inbox[inboxcur][5] + ".txt")
if r == d.DIALOG_OK: if r == d.DIALOG_OK:
msg = "" msg = ""
ret = sqlQuery("SELECT message FROM inbox WHERE msgid=?", inbox[inboxcur][0]) ret = sqlQuery("SELECT message FROM inbox WHERE msgid=?", inbox[inboxcur][0])
if ret != []: if ret != []:
for row in ret: for row in ret:
msg, = row msg, = row
fh = open(t, "a") # Open in append mode just in case fh = open(t, "a") # Open in append mode just in case
fh.write(msg) fh.write(msg)
fh.close() fh.close()
else: else:
scrollbox(d, unicode("Could not fetch message.")) scrollbox(d, unicode("Could not fetch message."))
elif t == "6": # Move to trash elif t == "6": # Move to trash
sqlExecute("UPDATE inbox SET folder='trash' WHERE msgid=?", inbox[inboxcur][0]) sqlExecute("UPDATE inbox SET folder='trash' WHERE msgid=?", inbox[inboxcur][0])
del inbox[inboxcur] del inbox[inboxcur]
scrollbox(d, unicode("Message moved to trash. There is no interface to view your trash, \nbut the message is still on disk if you are desperate to recover it.")) scrollbox(d, unicode(
"Message moved to trash. There is no interface to view your trash,"
" \nbut the message is still on disk if you are desperate to recover it."))
elif menutab == 2: elif menutab == 2:
a = "" a = ""
if addresses[addrcur][3] != 0: # if current address is a chan if addresses[addrcur][3] != 0: # if current address is a chan
a = addresses[addrcur][2] a = addresses[addrcur][2]
sendMessage(addresses[addrcur][2], a) sendMessage(addresses[addrcur][2], a)
elif menutab == 3: elif menutab == 3:
set_background_title(d, "Sent Messages Dialog Box") set_background_title(d, "Sent Messages Dialog Box")
r, t = d.menu("Do what with \""+sentbox[sentcur][4]+"\" to \""+sentbox[sentcur][0]+"\"?", r, t = d.menu(
choices=[("1", "View message"), "Do what with \"" + sentbox[sentcur][4] + "\" to \"" + sentbox[sentcur][0] + "\"?",
choices=[
("1", "View message"),
("2", "Move to trash")]) ("2", "Move to trash")])
if r == d.DIALOG_OK: if r == d.DIALOG_OK:
if t == "1": # View if t == "1": # View
set_background_title(d, "\""+sentbox[sentcur][4]+"\" from \""+sentbox[sentcur][3]+"\" to \""+sentbox[sentcur][1]+"\"") set_background_title(
d,
"\"" +
sentbox[sentcur][4] +
"\" from \"" +
sentbox[sentcur][3] +
"\" to \"" +
sentbox[sentcur][1] +
"\"")
data = "" data = ""
ret = sqlQuery("SELECT message FROM sent WHERE subject=? AND ackdata=?", sentbox[sentcur][4], sentbox[sentcur][6]) ret = sqlQuery(
"SELECT message FROM sent WHERE subject=? AND ackdata=?",
sentbox[sentcur][4],
sentbox[sentcur][6])
if ret != []: if ret != []:
for row in ret: for row in ret:
data, = row data, = row
data = shared.fixPotentiallyInvalidUTF8Data(data) data = shared.fixPotentiallyInvalidUTF8Data(data)
msg = "" msg = ""
for i, item in enumerate(data.split("\n")): for i, item in enumerate(data.split("\n")):
msg += fill(item, replace_whitespace=False)+"\n" msg += fill(item, replace_whitespace=False) + "\n"
scrollbox(d, unicode(ascii(msg)), 30, 80) scrollbox(d, unicode(ascii(msg)), 30, 80)
else: else:
scrollbox(d, unicode("Could not fetch message.")) scrollbox(d, unicode("Could not fetch message."))
elif t == "2": # Move to trash elif t == "2": # Move to trash
sqlExecute("UPDATE sent SET folder='trash' WHERE subject=? AND ackdata=?", sentbox[sentcur][4], sentbox[sentcur][6]) sqlExecute(
"UPDATE sent SET folder='trash' WHERE subject=? AND ackdata=?",
sentbox[sentcur][4],
sentbox[sentcur][6])
del sentbox[sentcur] del sentbox[sentcur]
scrollbox(d, unicode("Message moved to trash. There is no interface to view your trash, \nbut the message is still on disk if you are desperate to recover it.")) scrollbox(d, unicode(
"Message moved to trash. There is no interface to view your trash"
" \nbut the message is still on disk if you are desperate to recover it."))
elif menutab == 4: elif menutab == 4:
set_background_title(d, "Your Identities Dialog Box") set_background_title(d, "Your Identities Dialog Box")
if len(addresses) <= addrcur: if len(addresses) <= addrcur:
r, t = d.menu("Do what with addresses?", r, t = d.menu(
choices=[("1", "Create new address")]) "Do what with addresses?",
choices=[
("1", "Create new address")])
else: else:
r, t = d.menu("Do what with \""+addresses[addrcur][0]+"\" : \""+addresses[addrcur][2]+"\"?", r, t = d.menu(
choices=[("1", "Create new address"), "Do what with \"" + addresses[addrcur][0] + "\" : \"" + addresses[addrcur][2] + "\"?",
choices=[
("1", "Create new address"),
("2", "Send a message from this address"), ("2", "Send a message from this address"),
("3", "Rename"), ("3", "Rename"),
("4", "Enable"), ("4", "Enable"),
@ -414,31 +495,41 @@ def handlech(c, stdscr):
("6", "Delete"), ("6", "Delete"),
("7", "Special address behavior")]) ("7", "Special address behavior")])
if r == d.DIALOG_OK: if r == d.DIALOG_OK:
if t == "1": # Create new address if t == "1": # Create new address
set_background_title(d, "Create new address") set_background_title(d, "Create new address")
scrollbox(d, unicode("Here you may generate as many addresses as you like.\n" scrollbox(
"Indeed, creating and abandoning addresses is encouraged.\n" d, unicode(
"Deterministic addresses have several pros and cons:\n" "Here you may generate as many addresses as you like.\n"
"\nPros:\n" "Indeed, creating and abandoning addresses is encouraged.\n"
" * You can recreate your addresses on any computer from memory\n" "Deterministic addresses have several pros and cons:\n"
" * You need not worry about backing up your keys.dat file as long as you \n can remember your passphrase\n" "\nPros:\n"
"Cons:\n" " * You can recreate your addresses on any computer from memory\n"
" * You must remember (or write down) your passphrase in order to recreate \n your keys if they are lost\n" " * You need not worry about backing up your keys.dat file as long as you"
" * You must also remember the address version and stream numbers\n" " \n can remember your passphrase\n"
" * If you choose a weak passphrase someone may be able to brute-force it \n and then send and receive messages as you")) "Cons:\n"
r, t = d.menu("Choose an address generation technique", " * You must remember (or write down) your passphrase in order to recreate"
choices=[("1", "Use a random number generator"), " \n your keys if they are lost\n"
" * You must also remember the address version and stream numbers\n"
" * If you choose a weak passphrase someone may be able to brute-force it"
" \n and then send and receive messages as you"))
r, t = d.menu(
"Choose an address generation technique",
choices=[
("1", "Use a random number generator"),
("2", "Use a passphrase")]) ("2", "Use a passphrase")])
if r == d.DIALOG_OK: if r == d.DIALOG_OK:
if t == "1": if t == "1":
set_background_title(d, "Randomly generate address") set_background_title(d, "Randomly generate address")
r, t = d.inputbox("Label (not shown to anyone except you)") r, t = d.inputbox("Label (not shown to anyone except you)")
label = "" label = ""
if r == d.DIALOG_OK and len(t) > 0: if r == d.DIALOG_OK and t:
label = t label = t
r, t = d.menu("Choose a stream", r, t = d.menu(
choices=[("1", "Use the most available stream"),("", "(Best if this is the first of many addresses you will create)"), "Choose a stream",
("2", "Use the same stream as an existing address"),("", "(Saves you some bandwidth and processing power)")]) choices=[("1", "Use the most available stream"),
("", "(Best if this is the first of many addresses you will create)"),
("2", "Use the same stream as an existing address"),
("", "(Saves you some bandwidth and processing power)")])
if r == d.DIALOG_OK: if r == d.DIALOG_OK:
if t == "1": if t == "1":
stream = 1 stream = 1
@ -450,42 +541,69 @@ def handlech(c, stdscr):
if r == d.DIALOG_OK: if r == d.DIALOG_OK:
stream = decodeAddress(addrs[int(t)][1])[2] stream = decodeAddress(addrs[int(t)][1])[2]
shorten = False shorten = False
r, t = d.checklist("Miscellaneous options", r, t = d.checklist(
choices=[("1", "Spend time shortening the address", 1 if shorten else 0)]) "Miscellaneous options",
choices=[(
"1",
"Spend time shortening the address",
1 if shorten else 0)])
if r == d.DIALOG_OK and "1" in t: if r == d.DIALOG_OK and "1" in t:
shorten = True shorten = True
queues.addressGeneratorQueue.put(("createRandomAddress", 4, stream, label, 1, "", shorten)) queues.addressGeneratorQueue.put((
"createRandomAddress",
4,
stream,
label,
1,
"",
shorten))
elif t == "2": elif t == "2":
set_background_title(d, "Make deterministic addresses") set_background_title(d, "Make deterministic addresses")
r, t = d.passwordform("Enter passphrase", r, t = d.passwordform(
[("Passphrase", 1, 1, "", 2, 1, 64, 128), "Enter passphrase",
("Confirm passphrase", 3, 1, "", 4, 1, 64, 128)], [
("Passphrase", 1, 1, "", 2, 1, 64, 128),
("Confirm passphrase", 3, 1, "", 4, 1, 64, 128)],
form_height=4, insecure=True) form_height=4, insecure=True)
if r == d.DIALOG_OK: if r == d.DIALOG_OK:
if t[0] == t[1]: if t[0] == t[1]:
passphrase = t[0] passphrase = t[0]
r, t = d.rangebox("Number of addresses to generate", r, t = d.rangebox(
width=48, min=1, max=99, init=8) "Number of addresses to generate",
width=48,
min=1,
max=99,
init=8)
if r == d.DIALOG_OK: if r == d.DIALOG_OK:
number = t number = t
stream = 1 stream = 1
shorten = False shorten = False
r, t = d.checklist("Miscellaneous options", r, t = d.checklist(
choices=[("1", "Spend time shortening the address", 1 if shorten else 0)]) "Miscellaneous options",
choices=[(
"1",
"Spend time shortening the address",
1 if shorten else 0)])
if r == d.DIALOG_OK and "1" in t: if r == d.DIALOG_OK and "1" in t:
shorten = True shorten = True
scrollbox(d, unicode("In addition to your passphrase, be sure to remember the following numbers:\n" scrollbox(
"\n * Address version number: "+str(4)+"\n" d, unicode(
" * Stream number: "+str(stream))) "In addition to your passphrase, be sure to remember the"
queues.addressGeneratorQueue.put(('createDeterministicAddresses', 4, stream, "unused deterministic address", number, str(passphrase), shorten)) " following numbers:\n"
"\n * Address version number: " + str(4) + "\n"
" * Stream number: " + str(stream)))
queues.addressGeneratorQueue.put(
('createDeterministicAddresses', 4, stream,
"unused deterministic address", number,
str(passphrase), shorten))
else: else:
scrollbox(d, unicode("Passphrases do not match")) scrollbox(d, unicode("Passphrases do not match"))
elif t == "2": # Send a message elif t == "2": # Send a message
a = "" a = ""
if addresses[addrcur][3] != 0: # if current address is a chan if addresses[addrcur][3] != 0: # if current address is a chan
a = addresses[addrcur][2] a = addresses[addrcur][2]
sendMessage(addresses[addrcur][2], a) sendMessage(addresses[addrcur][2], a)
elif t == "3": # Rename address label elif t == "3": # Rename address label
a = addresses[addrcur][2] a = addresses[addrcur][2]
label = addresses[addrcur][0] label = addresses[addrcur][0]
r, t = d.inputbox("New address label", init=label) r, t = d.inputbox("New address label", init=label)
@ -495,72 +613,79 @@ def handlech(c, stdscr):
# Write config # Write config
BMConfigParser().save() BMConfigParser().save()
addresses[addrcur][0] = label addresses[addrcur][0] = label
elif t == "4": # Enable address elif t == "4": # Enable address
a = addresses[addrcur][2] a = addresses[addrcur][2]
BMConfigParser().set(a, "enabled", "true") # Set config BMConfigParser().set(a, "enabled", "true") # Set config
# Write config # Write config
BMConfigParser().save() BMConfigParser().save()
# Change color # Change color
if BMConfigParser().safeGetBoolean(a, 'chan'): if BMConfigParser().safeGetBoolean(a, 'chan'):
addresses[addrcur][3] = 9 # orange addresses[addrcur][3] = 9 # orange
elif BMConfigParser().safeGetBoolean(a, 'mailinglist'): elif BMConfigParser().safeGetBoolean(a, 'mailinglist'):
addresses[addrcur][3] = 5 # magenta addresses[addrcur][3] = 5 # magenta
else: else:
addresses[addrcur][3] = 0 # black addresses[addrcur][3] = 0 # black
addresses[addrcur][1] = True addresses[addrcur][1] = True
shared.reloadMyAddressHashes() # Reload address hashes shared.reloadMyAddressHashes() # Reload address hashes
elif t == "5": # Disable address elif t == "5": # Disable address
a = addresses[addrcur][2] a = addresses[addrcur][2]
BMConfigParser().set(a, "enabled", "false") # Set config BMConfigParser().set(a, "enabled", "false") # Set config
addresses[addrcur][3] = 8 # Set color to gray addresses[addrcur][3] = 8 # Set color to gray
# Write config # Write config
BMConfigParser().save() BMConfigParser().save()
addresses[addrcur][1] = False addresses[addrcur][1] = False
shared.reloadMyAddressHashes() # Reload address hashes shared.reloadMyAddressHashes() # Reload address hashes
elif t == "6": # Delete address elif t == "6": # Delete address
r, t = d.inputbox("Type in \"I want to delete this address\"", width=50) r, t = d.inputbox("Type in \"I want to delete this address\"", width=50)
if r == d.DIALOG_OK and t == "I want to delete this address": if r == d.DIALOG_OK and t == "I want to delete this address":
BMConfigParser().remove_section(addresses[addrcur][2]) BMConfigParser().remove_section(addresses[addrcur][2])
BMConfigParser().save() BMConfigParser().save()
del addresses[addrcur] del addresses[addrcur]
elif t == "7": # Special address behavior elif t == "7": # Special address behavior
a = addresses[addrcur][2] a = addresses[addrcur][2]
set_background_title(d, "Special address behavior") set_background_title(d, "Special address behavior")
if BMConfigParser().safeGetBoolean(a, "chan"): if BMConfigParser().safeGetBoolean(a, "chan"):
scrollbox(d, unicode("This is a chan address. You cannot use it as a pseudo-mailing list.")) scrollbox(d, unicode(
"This is a chan address. You cannot use it as a pseudo-mailing list."))
else: else:
m = BMConfigParser().safeGetBoolean(a, "mailinglist") m = BMConfigParser().safeGetBoolean(a, "mailinglist")
r, t = d.radiolist("Select address behavior", r, t = d.radiolist(
choices=[("1", "Behave as a normal address", not m), "Select address behavior",
choices=[
("1", "Behave as a normal address", not m),
("2", "Behave as a pseudo-mailing-list address", m)]) ("2", "Behave as a pseudo-mailing-list address", m)])
if r == d.DIALOG_OK: if r == d.DIALOG_OK:
if t == "1" and m == True: if t == "1" and m:
BMConfigParser().set(a, "mailinglist", "false") BMConfigParser().set(a, "mailinglist", "false")
if addresses[addrcur][1]: if addresses[addrcur][1]:
addresses[addrcur][3] = 0 # Set color to black addresses[addrcur][3] = 0 # Set color to black
else: else:
addresses[addrcur][3] = 8 # Set color to gray addresses[addrcur][3] = 8 # Set color to gray
elif t == "2" and m == False: elif t == "2" and m is False:
try: try:
mn = BMConfigParser().get(a, "mailinglistname") mn = BMConfigParser().get(a, "mailinglistname")
except ConfigParser.NoOptionError: except ConfigParser.NoOptionError:
mn = "" mn = ""
r, t = d.inputbox("Mailing list name", init=mn) r, t = d.inputbox("Mailing list name", init=mn)
if r == d.DIALOG_OK: if r == d.DIALOG_OK:
mn = t mn = t
BMConfigParser().set(a, "mailinglist", "true") BMConfigParser().set(a, "mailinglist", "true")
BMConfigParser().set(a, "mailinglistname", mn) BMConfigParser().set(a, "mailinglistname", mn)
addresses[addrcur][3] = 6 # Set color to magenta addresses[addrcur][3] = 6 # Set color to magenta
# Write config # Write config
BMConfigParser().save() BMConfigParser().save()
elif menutab == 5: elif menutab == 5:
set_background_title(d, "Subscriptions Dialog Box") set_background_title(d, "Subscriptions Dialog Box")
if len(subscriptions) <= subcur: if len(subscriptions) <= subcur:
r, t = d.menu("Do what with subscription to \""+subscriptions[subcur][0]+"\"?", r, t = d.menu(
choices=[("1", "Add new subscription")]) "Do what with subscription to \"" + subscriptions[subcur][0] + "\"?",
choices=[
("1", "Add new subscription")])
else: else:
r, t = d.menu("Do what with subscription to \""+subscriptions[subcur][0]+"\"?", r, t = d.menu(
choices=[("1", "Add new subscription"), "Do what with subscription to \"" + subscriptions[subcur][0] + "\"?",
choices=[
("1", "Add new subscription"),
("2", "Delete this subscription"), ("2", "Delete this subscription"),
("3", "Enable"), ("3", "Enable"),
("4", "Disable")]) ("4", "Disable")])
@ -581,27 +706,39 @@ def handlech(c, stdscr):
sqlExecute("INSERT INTO subscriptions VALUES (?,?,?)", label, addr, True) sqlExecute("INSERT INTO subscriptions VALUES (?,?,?)", label, addr, True)
shared.reloadBroadcastSendersForWhichImWatching() shared.reloadBroadcastSendersForWhichImWatching()
elif t == "2": elif t == "2":
r, t = d.inpuxbox("Type in \"I want to delete this subscription\"") r, t = d.inputbox("Type in \"I want to delete this subscription\"")
if r == d.DIALOG_OK and t == "I want to delete this subscription": if r == d.DIALOG_OK and t == "I want to delete this subscription":
sqlExecute("DELETE FROM subscriptions WHERE label=? AND address=?", subscriptions[subcur][0], subscriptions[subcur][1]) sqlExecute(
shared.reloadBroadcastSendersForWhichImWatching() "DELETE FROM subscriptions WHERE label=? AND address=?",
del subscriptions[subcur] subscriptions[subcur][0],
subscriptions[subcur][1])
shared.reloadBroadcastSendersForWhichImWatching()
del subscriptions[subcur]
elif t == "3": elif t == "3":
sqlExecute("UPDATE subscriptions SET enabled=1 WHERE label=? AND address=?", subscriptions[subcur][0], subscriptions[subcur][1]) sqlExecute(
"UPDATE subscriptions SET enabled=1 WHERE label=? AND address=?",
subscriptions[subcur][0],
subscriptions[subcur][1])
shared.reloadBroadcastSendersForWhichImWatching() shared.reloadBroadcastSendersForWhichImWatching()
subscriptions[subcur][2] = True subscriptions[subcur][2] = True
elif t == "4": elif t == "4":
sqlExecute("UPDATE subscriptions SET enabled=0 WHERE label=? AND address=?", subscriptions[subcur][0], subscriptions[subcur][1]) sqlExecute(
"UPDATE subscriptions SET enabled=0 WHERE label=? AND address=?",
subscriptions[subcur][0],
subscriptions[subcur][1])
shared.reloadBroadcastSendersForWhichImWatching() shared.reloadBroadcastSendersForWhichImWatching()
subscriptions[subcur][2] = False subscriptions[subcur][2] = False
elif menutab == 6: elif menutab == 6:
set_background_title(d, "Address Book Dialog Box") set_background_title(d, "Address Book Dialog Box")
if len(addrbook) <= abookcur: if len(addrbook) <= abookcur:
r, t = d.menu("Do what with addressbook?", r, t = d.menu(
"Do what with addressbook?",
choices=[("3", "Add new address to Address Book")]) choices=[("3", "Add new address to Address Book")])
else: else:
r, t = d.menu("Do what with \""+addrbook[abookcur][0]+"\" : \""+addrbook[abookcur][1]+"\"", r, t = d.menu(
choices=[("1", "Send a message to this address"), "Do what with \"" + addrbook[abookcur][0] + "\" : \"" + addrbook[abookcur][1] + "\"",
choices=[
("1", "Send a message to this address"),
("2", "Subscribe to this address"), ("2", "Subscribe to this address"),
("3", "Add new address to Address Book"), ("3", "Add new address to Address Book"),
("4", "Delete this address")]) ("4", "Delete this address")])
@ -623,8 +760,8 @@ def handlech(c, stdscr):
r, t = d.inputbox("Input new address") r, t = d.inputbox("Input new address")
if r == d.DIALOG_OK: if r == d.DIALOG_OK:
addr = t addr = t
if addr not in [item[1] for i,item in enumerate(addrbook)]: if addr not in [item[1] for i, item in enumerate(addrbook)]:
r, t = d.inputbox("Label for address \""+addr+"\"") r, t = d.inputbox("Label for address \"" + addr + "\"")
if r == d.DIALOG_OK: if r == d.DIALOG_OK:
sqlExecute("INSERT INTO addressbook VALUES (?,?)", t, addr) sqlExecute("INSERT INTO addressbook VALUES (?,?)", t, addr)
# Prepend entry # Prepend entry
@ -636,25 +773,39 @@ def handlech(c, stdscr):
elif t == "4": elif t == "4":
r, t = d.inputbox("Type in \"I want to delete this Address Book entry\"") r, t = d.inputbox("Type in \"I want to delete this Address Book entry\"")
if r == d.DIALOG_OK and t == "I want to delete this Address Book entry": if r == d.DIALOG_OK and t == "I want to delete this Address Book entry":
sqlExecute("DELETE FROM addressbook WHERE label=? AND address=?", addrbook[abookcur][0], addrbook[abookcur][1]) sqlExecute(
"DELETE FROM addressbook WHERE label=? AND address=?",
addrbook[abookcur][0],
addrbook[abookcur][1])
del addrbook[abookcur] del addrbook[abookcur]
elif menutab == 7: elif menutab == 7:
set_background_title(d, "Blacklist Dialog Box") set_background_title(d, "Blacklist Dialog Box")
r, t = d.menu("Do what with \""+blacklist[blackcur][0]+"\" : \""+blacklist[blackcur][1]+"\"?", r, t = d.menu(
choices=[("1", "Delete"), "Do what with \"" + blacklist[blackcur][0] + "\" : \"" + blacklist[blackcur][1] + "\"?",
choices=[
("1", "Delete"),
("2", "Enable"), ("2", "Enable"),
("3", "Disable")]) ("3", "Disable")])
if r == d.DIALOG_OK: if r == d.DIALOG_OK:
if t == "1": if t == "1":
r, t = d.inputbox("Type in \"I want to delete this Blacklist entry\"") r, t = d.inputbox("Type in \"I want to delete this Blacklist entry\"")
if r == d.DIALOG_OK and t == "I want to delete this Blacklist entry": if r == d.DIALOG_OK and t == "I want to delete this Blacklist entry":
sqlExecute("DELETE FROM blacklist WHERE label=? AND address=?", blacklist[blackcur][0], blacklist[blackcur][1]) sqlExecute(
"DELETE FROM blacklist WHERE label=? AND address=?",
blacklist[blackcur][0],
blacklist[blackcur][1])
del blacklist[blackcur] del blacklist[blackcur]
elif t == "2": elif t == "2":
sqlExecute("UPDATE blacklist SET enabled=1 WHERE label=? AND address=?", blacklist[blackcur][0], blacklist[blackcur][1]) sqlExecute(
"UPDATE blacklist SET enabled=1 WHERE label=? AND address=?",
blacklist[blackcur][0],
blacklist[blackcur][1])
blacklist[blackcur][2] = True blacklist[blackcur][2] = True
elif t== "3": elif t == "3":
sqlExecute("UPDATE blacklist SET enabled=0 WHERE label=? AND address=?", blacklist[blackcur][0], blacklist[blackcur][1]) sqlExecute(
"UPDATE blacklist SET enabled=0 WHERE label=? AND address=?",
blacklist[blackcur][0],
blacklist[blackcur][1])
blacklist[blackcur][2] = False blacklist[blackcur][2] = False
dialogreset(stdscr) dialogreset(stdscr)
else: else:
@ -672,17 +823,17 @@ def handlech(c, stdscr):
if menutab == 7 and blackcur > 0: if menutab == 7 and blackcur > 0:
blackcur -= 1 blackcur -= 1
elif c == curses.KEY_DOWN: elif c == curses.KEY_DOWN:
if menutab == 1 and inboxcur < len(inbox)-1: if menutab == 1 and inboxcur < len(inbox) - 1:
inboxcur += 1 inboxcur += 1
if (menutab == 2 or menutab == 4) and addrcur < len(addresses)-1: if (menutab == 2 or menutab == 4) and addrcur < len(addresses) - 1:
addrcur += 1 addrcur += 1
if menutab == 3 and sentcur < len(sentbox)-1: if menutab == 3 and sentcur < len(sentbox) - 1:
sentcur += 1 sentcur += 1
if menutab == 5 and subcur < len(subscriptions)-1: if menutab == 5 and subcur < len(subscriptions) - 1:
subcur += 1 subcur += 1
if menutab == 6 and abookcur < len(addrbook)-1: if menutab == 6 and abookcur < len(addrbook) - 1:
abookcur += 1 abookcur += 1
if menutab == 7 and blackcur < len(blacklist)-1: if menutab == 7 and blackcur < len(blacklist) - 1:
blackcur += 1 blackcur += 1
elif c == curses.KEY_HOME: elif c == curses.KEY_HOME:
if menutab == 1: if menutab == 1:
@ -699,38 +850,47 @@ def handlech(c, stdscr):
blackcur = 0 blackcur = 0
elif c == curses.KEY_END: elif c == curses.KEY_END:
if menutab == 1: if menutab == 1:
inboxcur = len(inbox)-1 inboxcur = len(inbox) - 1
if menutab == 2 or menutab == 4: if menutab == 2 or menutab == 4:
addrcur = len(addresses)-1 addrcur = len(addresses) - 1
if menutab == 3: if menutab == 3:
sentcur = len(sentbox)-1 sentcur = len(sentbox) - 1
if menutab == 5: if menutab == 5:
subcur = len(subscriptions)-1 subcur = len(subscriptions) - 1
if menutab == 6: if menutab == 6:
abookcur = len(addrbook)-1 abookcur = len(addrbook) - 1
if menutab == 7: if menutab == 7:
blackcur = len(blackcur)-1 blackcur = len(blackcur) - 1
redraw(stdscr) redraw(stdscr)
# pylint: disable=too-many-locals, too-many-arguments
def sendMessage(sender="", recv="", broadcast=None, subject="", body="", reply=False): def sendMessage(sender="", recv="", broadcast=None, subject="", body="", reply=False):
"""Method for message sending"""
if sender == "": if sender == "":
return return
d = Dialog(dialog="dialog") d = Dialog(dialog="dialog")
set_background_title(d, "Send a message") set_background_title(d, "Send a message")
if recv == "": if recv == "":
r, t = d.inputbox("Recipient address (Cancel to load from the Address Book or leave blank to broadcast)", 10, 60) r, t = d.inputbox(
"Recipient address (Cancel to load from the Address Book or leave blank to broadcast)",
10,
60)
if r != d.DIALOG_OK: if r != d.DIALOG_OK:
global menutab global menutab # pylint: disable=global-statement
menutab = 6 menutab = 6
return return
recv = t recv = t
if broadcast == None and sender != recv: if broadcast is None and sender != recv:
r, t = d.radiolist("How to send the message?", r, t = d.radiolist(
choices=[("1", "Send to one or more specific people", 1), "How to send the message?",
choices=[
("1", "Send to one or more specific people", 1),
("2", "Broadcast to everyone who is subscribed to your address", 0)]) ("2", "Broadcast to everyone who is subscribed to your address", 0)])
if r != d.DIALOG_OK: if r != d.DIALOG_OK:
return return
broadcast = False broadcast = False
if t == "2": # Broadcast if t == "2": # Broadcast
broadcast = True broadcast = True
if subject == "" or reply: if subject == "" or reply:
r, t = d.inputbox("Message subject", width=60, init=subject) r, t = d.inputbox("Message subject", width=60, init=subject)
@ -748,9 +908,10 @@ def sendMessage(sender="", recv="", broadcast=None, subject="", body="", reply=F
recvlist = [] recvlist = []
for i, item in enumerate(recv.replace(",", ";").split(";")): for i, item in enumerate(recv.replace(",", ";").split(";")):
recvlist.append(item.strip()) recvlist.append(item.strip())
list(set(recvlist)) # Remove exact duplicates list(set(recvlist)) # Remove exact duplicates
for addr in recvlist: for addr in recvlist:
if addr != "": if addr != "":
# pylint: disable=redefined-outer-name
status, version, stream, ripe = decodeAddress(addr) status, version, stream, ripe = decodeAddress(addr)
if status != "success": if status != "success":
set_background_title(d, "Recipient address error") set_background_title(d, "Recipient address error")
@ -762,13 +923,17 @@ def sendMessage(sender="", recv="", broadcast=None, subject="", body="", reply=F
elif status == "invalidcharacters": elif status == "invalidcharacters":
err += "The address contains invalid characters." err += "The address contains invalid characters."
elif status == "versiontoohigh": elif status == "versiontoohigh":
err += "The address version is too high. Either you need to upgrade your Bitmessage software or your acquaintance is doing something clever." err += ("The address version is too high. Either you need to upgrade your Bitmessage software"
" or your acquaintance is doing something clever.")
elif status == "ripetooshort": elif status == "ripetooshort":
err += "Some data encoded in the address is too short. There might be something wrong with the software of your acquaintance." err += ("Some data encoded in the address is too short. There might be something wrong with"
" the software of your acquaintance.")
elif status == "ripetoolong": elif status == "ripetoolong":
err += "Some data encoded in the address is too long. There might be something wrong with the software of your acquaintance." err += ("Some data encoded in the address is too long. There might be something wrong with"
" the software of your acquaintance.")
elif status == "varintmalformed": elif status == "varintmalformed":
err += "Some data encoded in the address is malformed. There might be something wrong with the software of your acquaintance." err += ("Some data encoded in the address is malformed. There might be something wrong with"
" the software of your acquaintance.")
else: else:
err += "It is unknown what is wrong with the address." err += "It is unknown what is wrong with the address."
scrollbox(d, unicode(err)) scrollbox(d, unicode(err))
@ -776,17 +941,24 @@ def sendMessage(sender="", recv="", broadcast=None, subject="", body="", reply=F
addr = addBMIfNotPresent(addr) addr = addBMIfNotPresent(addr)
if version > 4 or version <= 1: if version > 4 or version <= 1:
set_background_title(d, "Recipient address error") set_background_title(d, "Recipient address error")
scrollbox(d, unicode("Could not understand version number " + version + "of address" + addr + ".")) scrollbox(d, unicode(
"Could not understand version number " +
version +
"of address" +
addr +
"."))
continue continue
if stream > 1 or stream == 0: if stream > 1 or stream == 0:
set_background_title(d, "Recipient address error") set_background_title(d, "Recipient address error")
scrollbox(d, unicode("Bitmessage currently only supports stream numbers of 1, unlike as requested for address " + addr + ".")) scrollbox(d, unicode(
"Bitmessage currently only supports stream numbers of 1,"
"unlike as requested for address " + addr + "."))
continue continue
if not network.stats.connectedHostsList(): if not network.stats.connectedHostsList():
set_background_title(d, "Not connected warning") set_background_title(d, "Not connected warning")
scrollbox(d, unicode("Because you are not currently connected to the network, ")) scrollbox(d, unicode("Because you are not currently connected to the network, "))
stealthLevel = BMConfigParser().safeGetInt('bitmessagesettings', 'ackstealthlevel') stealthLevel = BMConfigParser().safeGetInt('bitmessagesettings', 'ackstealthlevel')
ackdata = genAckPayload(streamNumber, stealthLevel) ackdata = genAckPayload(decodeAddress(addr)[2], stealthLevel)
sqlExecute( sqlExecute(
"INSERT INTO sent VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", "INSERT INTO sent VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",
"", "",
@ -796,22 +968,22 @@ def sendMessage(sender="", recv="", broadcast=None, subject="", body="", reply=F
subject, subject,
body, body,
ackdata, ackdata,
int(time.time()), # sentTime (this will never change) int(time.time()), # sentTime (this will never change)
int(time.time()), # lastActionTime int(time.time()), # lastActionTime
0, # sleepTill time. This will get set when the POW gets done. 0, # sleepTill time. This will get set when the POW gets done.
"msgqueued", "msgqueued",
0, # retryNumber 0, # retryNumber
"sent", "sent",
2, # encodingType 2, # encodingType
BMConfigParser().getint('bitmessagesettings', 'ttl')) BMConfigParser().getint('bitmessagesettings', 'ttl'))
queues.workerQueue.put(("sendmessage", addr)) queues.workerQueue.put(("sendmessage", addr))
else: # Broadcast else: # Broadcast
if recv == "": if recv == "":
set_background_title(d, "Empty sender error") set_background_title(d, "Empty sender error")
scrollbox(d, unicode("You must specify an address to send the message from.")) scrollbox(d, unicode("You must specify an address to send the message from."))
else: else:
# dummy ackdata, no need for stealth # dummy ackdata, no need for stealth
ackdata = genAckPayload(streamNumber, 0) ackdata = genAckPayload(decodeAddress(addr)[2], 0)
recv = BROADCAST_STR recv = BROADCAST_STR
ripe = "" ripe = ""
sqlExecute( sqlExecute(
@ -823,21 +995,24 @@ def sendMessage(sender="", recv="", broadcast=None, subject="", body="", reply=F
subject, subject,
body, body,
ackdata, ackdata,
int(time.time()), # sentTime (this will never change) int(time.time()), # sentTime (this will never change)
int(time.time()), # lastActionTime int(time.time()), # lastActionTime
0, # sleepTill time. This will get set when the POW gets done. 0, # sleepTill time. This will get set when the POW gets done.
"broadcastqueued", "broadcastqueued",
0, # retryNumber 0, # retryNumber
"sent", # folder "sent", # folder
2, # encodingType 2, # encodingType
BMConfigParser().getint('bitmessagesettings', 'ttl')) BMConfigParser().getint('bitmessagesettings', 'ttl'))
queues.workerQueue.put(('sendbroadcast', '')) queues.workerQueue.put(('sendbroadcast', ''))
# pylint: disable=redefined-outer-name, too-many-locals
def loadInbox(): def loadInbox():
"""Load the list of messages"""
sys.stdout = sys.__stdout__ sys.stdout = sys.__stdout__
print("Loading inbox messages...") print "Loading inbox messages..."
sys.stdout = printlog sys.stdout = printlog
where = "toaddress || fromaddress || subject || message" where = "toaddress || fromaddress || subject || message"
what = "%%" what = "%%"
ret = sqlQuery("""SELECT msgid, toaddress, fromaddress, subject, received, read ret = sqlQuery("""SELECT msgid, toaddress, fromaddress, subject, received, read
@ -847,7 +1022,7 @@ def loadInbox():
for row in ret: for row in ret:
msgid, toaddr, fromaddr, subject, received, read = row msgid, toaddr, fromaddr, subject, received, read = row
subject = ascii(shared.fixPotentiallyInvalidUTF8Data(subject)) subject = ascii(shared.fixPotentiallyInvalidUTF8Data(subject))
# Set label for to address # Set label for to address
try: try:
if toaddr == BROADCAST_STR: if toaddr == BROADCAST_STR:
@ -859,17 +1034,17 @@ def loadInbox():
if tolabel == "": if tolabel == "":
tolabel = toaddr tolabel = toaddr
tolabel = shared.fixPotentiallyInvalidUTF8Data(tolabel) tolabel = shared.fixPotentiallyInvalidUTF8Data(tolabel)
# Set label for from address # Set label for from address
fromlabel = "" fromlabel = ""
if BMConfigParser().has_section(fromaddr): if BMConfigParser().has_section(fromaddr):
fromlabel = BMConfigParser().get(fromaddr, "label") fromlabel = BMConfigParser().get(fromaddr, "label")
if fromlabel == "": # Check Address Book if fromlabel == "": # Check Address Book
qr = sqlQuery("SELECT label FROM addressbook WHERE address=?", fromaddr) qr = sqlQuery("SELECT label FROM addressbook WHERE address=?", fromaddr)
if qr != []: if qr != []:
for r in qr: for r in qr:
fromlabel, = r fromlabel, = r
if fromlabel == "": # Check Subscriptions if fromlabel == "": # Check Subscriptions
qr = sqlQuery("SELECT label FROM subscriptions WHERE address=?", fromaddr) qr = sqlQuery("SELECT label FROM subscriptions WHERE address=?", fromaddr)
if qr != []: if qr != []:
for r in qr: for r in qr:
@ -877,16 +1052,19 @@ def loadInbox():
if fromlabel == "": if fromlabel == "":
fromlabel = fromaddr fromlabel = fromaddr
fromlabel = shared.fixPotentiallyInvalidUTF8Data(fromlabel) fromlabel = shared.fixPotentiallyInvalidUTF8Data(fromlabel)
# Load into array # Load into array
inbox.append([msgid, tolabel, toaddr, fromlabel, fromaddr, subject, inbox.append([msgid, tolabel, toaddr, fromlabel, fromaddr, subject, l10n.formatTimestamp(
l10n.formatTimestamp(received, False), read]) received, False), read])
inbox.reverse() inbox.reverse()
def loadSent(): def loadSent():
"""Load the messages that sent"""
sys.stdout = sys.__stdout__ sys.stdout = sys.__stdout__
print("Loading sent messages...") print "Loading sent messages..."
sys.stdout = printlog sys.stdout = printlog
where = "toaddress || fromaddress || subject || message" where = "toaddress || fromaddress || subject || message"
what = "%%" what = "%%"
ret = sqlQuery("""SELECT toaddress, fromaddress, subject, status, ackdata, lastactiontime ret = sqlQuery("""SELECT toaddress, fromaddress, subject, status, ackdata, lastactiontime
@ -896,7 +1074,7 @@ def loadSent():
for row in ret: for row in ret:
toaddr, fromaddr, subject, status, ackdata, lastactiontime = row toaddr, fromaddr, subject, status, ackdata, lastactiontime = row
subject = ascii(shared.fixPotentiallyInvalidUTF8Data(subject)) subject = ascii(shared.fixPotentiallyInvalidUTF8Data(subject))
# Set label for to address # Set label for to address
tolabel = "" tolabel = ""
qr = sqlQuery("SELECT label FROM addressbook WHERE address=?", toaddr) qr = sqlQuery("SELECT label FROM addressbook WHERE address=?", toaddr)
@ -913,14 +1091,14 @@ def loadSent():
tolabel = BMConfigParser().get(toaddr, "label") tolabel = BMConfigParser().get(toaddr, "label")
if tolabel == "": if tolabel == "":
tolabel = toaddr tolabel = toaddr
# Set label for from address # Set label for from address
fromlabel = "" fromlabel = ""
if BMConfigParser().has_section(fromaddr): if BMConfigParser().has_section(fromaddr):
fromlabel = BMConfigParser().get(fromaddr, "label") fromlabel = BMConfigParser().get(fromaddr, "label")
if fromlabel == "": if fromlabel == "":
fromlabel = fromaddr fromlabel = fromaddr
# Set status string # Set status string
if status == "awaitingpubkey": if status == "awaitingpubkey":
statstr = "Waiting for their public key. Will request it again soon" statstr = "Waiting for their public key. Will request it again soon"
@ -930,20 +1108,20 @@ def loadSent():
statstr = "Message queued" statstr = "Message queued"
elif status == "msgsent": elif status == "msgsent":
t = l10n.formatTimestamp(lastactiontime, False) t = l10n.formatTimestamp(lastactiontime, False)
statstr = "Message sent at "+t+".Waiting for acknowledgement." statstr = "Message sent at " + t + ".Waiting for acknowledgement."
elif status == "msgsentnoackexpected": elif status == "msgsentnoackexpected":
t = l10n.formatTimestamp(lastactiontime, False) t = l10n.formatTimestamp(lastactiontime, False)
statstr = "Message sent at "+t+"." statstr = "Message sent at " + t + "."
elif status == "doingmsgpow": elif status == "doingmsgpow":
statstr = "The proof of work required to send the message has been queued." statstr = "The proof of work required to send the message has been queued."
elif status == "ackreceived": elif status == "ackreceived":
t = l10n.formatTimestamp(lastactiontime, False) t = l10n.formatTimestamp(lastactiontime, False)
statstr = "Acknowledgment of the message received at "+t+"." statstr = "Acknowledgment of the message received at " + t + "."
elif status == "broadcastqueued": elif status == "broadcastqueued":
statstr = "Broadcast queued." statstr = "Broadcast queued."
elif status == "broadcastsent": elif status == "broadcastsent":
t = l10n.formatTimestamp(lastactiontime, False) t = l10n.formatTimestamp(lastactiontime, False)
statstr = "Broadcast sent at "+t+"." statstr = "Broadcast sent at " + t + "."
elif status == "forcepow": elif status == "forcepow":
statstr = "Forced difficulty override. Message will start sending soon." statstr = "Forced difficulty override. Message will start sending soon."
elif status == "badkey": elif status == "badkey":
@ -952,31 +1130,47 @@ def loadSent():
statstr = "Error: The work demanded by the recipient is more difficult than you are willing to do." statstr = "Error: The work demanded by the recipient is more difficult than you are willing to do."
else: else:
t = l10n.formatTimestamp(lastactiontime, False) t = l10n.formatTimestamp(lastactiontime, False)
statstr = "Unknown status "+status+" at "+t+"." statstr = "Unknown status " + status + " at " + t + "."
# Load into array # Load into array
sentbox.append([tolabel, toaddr, fromlabel, fromaddr, subject, statstr, ackdata, sentbox.append([
tolabel,
toaddr,
fromlabel,
fromaddr,
subject,
statstr,
ackdata,
l10n.formatTimestamp(lastactiontime, False)]) l10n.formatTimestamp(lastactiontime, False)])
sentbox.reverse() sentbox.reverse()
def loadAddrBook(): def loadAddrBook():
"""Load address book"""
sys.stdout = sys.__stdout__ sys.stdout = sys.__stdout__
print("Loading address book...") print "Loading address book..."
sys.stdout = printlog sys.stdout = printlog
ret = sqlQuery("SELECT label, address FROM addressbook") ret = sqlQuery("SELECT label, address FROM addressbook")
for row in ret: for row in ret:
label, addr = row label, addr = row
label = shared.fixPotentiallyInvalidUTF8Data(label) label = shared.fixPotentiallyInvalidUTF8Data(label)
addrbook.append([label, addr]) addrbook.append([label, addr])
addrbook.reverse() addrbook.reverse()
def loadSubscriptions(): def loadSubscriptions():
"""Load subscription functionality"""
ret = sqlQuery("SELECT label, address, enabled FROM subscriptions") ret = sqlQuery("SELECT label, address, enabled FROM subscriptions")
for row in ret: for row in ret:
label, address, enabled = row label, address, enabled = row
subscriptions.append([label, address, enabled]) subscriptions.append([label, address, enabled])
subscriptions.reverse() subscriptions.reverse()
def loadBlackWhiteList(): def loadBlackWhiteList():
global bwtype """load black/white list"""
global bwtype # pylint: disable=global-statement
bwtype = BMConfigParser().get("bitmessagesettings", "blackwhitelist") bwtype = BMConfigParser().get("bitmessagesettings", "blackwhitelist")
if bwtype == "black": if bwtype == "black":
ret = sqlQuery("SELECT label, address, enabled FROM blacklist") ret = sqlQuery("SELECT label, address, enabled FROM blacklist")
@ -987,51 +1181,53 @@ def loadBlackWhiteList():
blacklist.append([label, address, enabled]) blacklist.append([label, address, enabled])
blacklist.reverse() blacklist.reverse()
def runwrapper(): def runwrapper():
sys.stdout = printlog sys.stdout = printlog
#sys.stderr = errlog # sys.stderr = errlog
# Load messages from database # Load messages from database
loadInbox() loadInbox()
loadSent() loadSent()
loadAddrBook() loadAddrBook()
loadSubscriptions() loadSubscriptions()
loadBlackWhiteList() loadBlackWhiteList()
stdscr = curses.initscr() stdscr = curses.initscr()
global logpad global logpad # pylint: disable=global-statement
logpad = curses.newpad(1024, curses.COLS) logpad = curses.newpad(1024, curses.COLS)
stdscr.nodelay(0) stdscr.nodelay(0)
curses.curs_set(0) curses.curs_set(0)
stdscr.timeout(1000) stdscr.timeout(1000)
curses.wrapper(run) curses.wrapper(run)
doShutdown() doShutdown()
def run(stdscr): def run(stdscr):
# Schedule inventory lookup data # Schedule inventory lookup data
resetlookups() resetlookups()
# Init color pairs # Init color pairs
if curses.has_colors(): if curses.has_colors():
curses.init_pair(1, curses.COLOR_RED, curses.COLOR_BLACK) # red curses.init_pair(1, curses.COLOR_RED, curses.COLOR_BLACK) # red
curses.init_pair(2, curses.COLOR_GREEN, curses.COLOR_BLACK) # green curses.init_pair(2, curses.COLOR_GREEN, curses.COLOR_BLACK) # green
curses.init_pair(3, curses.COLOR_YELLOW, curses.COLOR_BLACK) # yellow curses.init_pair(3, curses.COLOR_YELLOW, curses.COLOR_BLACK) # yellow
curses.init_pair(4, curses.COLOR_BLUE, curses.COLOR_BLACK) # blue curses.init_pair(4, curses.COLOR_BLUE, curses.COLOR_BLACK) # blue
curses.init_pair(5, curses.COLOR_MAGENTA, curses.COLOR_BLACK) # magenta curses.init_pair(5, curses.COLOR_MAGENTA, curses.COLOR_BLACK) # magenta
curses.init_pair(6, curses.COLOR_CYAN, curses.COLOR_BLACK) # cyan curses.init_pair(6, curses.COLOR_CYAN, curses.COLOR_BLACK) # cyan
curses.init_pair(7, curses.COLOR_WHITE, curses.COLOR_BLACK) # white curses.init_pair(7, curses.COLOR_WHITE, curses.COLOR_BLACK) # white
if curses.can_change_color(): if curses.can_change_color():
curses.init_color(8, 500, 500, 500) # gray curses.init_color(8, 500, 500, 500) # gray
curses.init_pair(8, 8, 0) curses.init_pair(8, 8, 0)
curses.init_color(9, 844, 465, 0) # orange curses.init_color(9, 844, 465, 0) # orange
curses.init_pair(9, 9, 0) curses.init_pair(9, 9, 0)
else: else:
curses.init_pair(8, curses.COLOR_WHITE, curses.COLOR_BLACK) # grayish curses.init_pair(8, curses.COLOR_WHITE, curses.COLOR_BLACK) # grayish
curses.init_pair(9, curses.COLOR_YELLOW, curses.COLOR_BLACK) # orangish curses.init_pair(9, curses.COLOR_YELLOW, curses.COLOR_BLACK) # orangish
# Init list of address in 'Your Identities' tab # Init list of address in 'Your Identities' tab
configSections = BMConfigParser().addresses() configSections = BMConfigParser().addresses()
for addressInKeysFile in configSections: for addressInKeysFile in configSections:
@ -1039,27 +1235,29 @@ def run(stdscr):
addresses.append([BMConfigParser().get(addressInKeysFile, "label"), isEnabled, addressInKeysFile]) addresses.append([BMConfigParser().get(addressInKeysFile, "label"), isEnabled, addressInKeysFile])
# Set address color # Set address color
if not isEnabled: if not isEnabled:
addresses[len(addresses)-1].append(8) # gray addresses[len(addresses) - 1].append(8) # gray
elif BMConfigParser().safeGetBoolean(addressInKeysFile, 'chan'): elif BMConfigParser().safeGetBoolean(addressInKeysFile, 'chan'):
addresses[len(addresses)-1].append(9) # orange addresses[len(addresses) - 1].append(9) # orange
elif BMConfigParser().safeGetBoolean(addressInKeysFile, 'mailinglist'): elif BMConfigParser().safeGetBoolean(addressInKeysFile, 'mailinglist'):
addresses[len(addresses)-1].append(5) # magenta addresses[len(addresses) - 1].append(5) # magenta
else: else:
addresses[len(addresses)-1].append(0) # black addresses[len(addresses) - 1].append(0) # black
addresses.reverse() addresses.reverse()
stdscr.clear() stdscr.clear()
redraw(stdscr) redraw(stdscr)
while quit == False: while quit is False:
drawtab(stdscr) drawtab(stdscr)
handlech(stdscr.getch(), stdscr) handlech(stdscr.getch(), stdscr)
def doShutdown(): def doShutdown():
"""Shutting the app down"""
sys.stdout = sys.__stdout__ sys.stdout = sys.__stdout__
print("Shutting down...") print "Shutting down..."
sys.stdout = printlog sys.stdout = printlog
shutdown.doCleanShutdown() shutdown.doCleanShutdown()
sys.stdout = sys.__stdout__ sys.stdout = sys.__stdout__
sys.stderr = sys.__stderr__ sys.stderr = sys.__stderr__
os._exit(0) os._exit(0) # pylint: disable=protected-access