Merge pull request #11 from cis-navjot-g/UiChanges

Enhanced feature for kivy app
This commit is contained in:
surbhi 2019-09-21 17:04:52 +05:30 committed by GitHub
commit f544314640
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 1787 additions and 785 deletions

2
.gitignore vendored
View File

@ -18,3 +18,5 @@ dist
docs/_*/* docs/_*/*
docs/autodoc/ docs/autodoc/
pyan/ pyan/
.buildozer/
bin/

View File

@ -10,36 +10,14 @@ from pythonforandroid.recipe import PythonRecipe
class KivyMDRecipe(PythonRecipe): class KivyMDRecipe(PythonRecipe):
# This recipe installs KivyMD into the android dist from source # This recipe installs KivyMD into the android dist from source
version = 'master' version = 'master'
# url = 'https://gitlab.com/kivymd/KivyMD/repository/{version}/archive.zip' url = 'https://github.com/surbhicis/kivymd/archive/master.zip'
url = 'https://github.com/HeaTTheatR/KivyMD/archive/master.zip'
depends = ['kivy'] depends = ['kivy']
site_packages_name = 'kivymd' site_packages_name = 'kivymd'
call_hostpython_via_targetpython = False call_hostpython_via_targetpython = False
# patches = ['kivymd-fix-dev-compatibility.patch']
# Made commented as use different repo for updates
def should_build(self, arch): def should_build(self, arch):
return True return True
# def unpack(self, arch):
# info_main('Unpacking {} for {}'.format(self.name, arch))
#
# build_dir = self.get_build_container_dir(arch)
#
# user_dir = environ.get('P4A_{}_DIR'.format(self.name.lower()))
#
# if user_dir is not None:
# info("Installing KivyMD development version (from modded source)")
# self.clean_build()
# shprint(sh.rm, '-rf', build_dir)
# shprint(sh.mkdir, '-p', build_dir)
# shprint(sh.rmdir, build_dir)
# ensure_dir(build_dir)
# ensure_dir(build_dir + "/kivymd")
# shprint(sh.cp, user_dir + '/setup.py', self.get_build_dir(arch) + "/setup.py")
# shprint(sh.cp, '-a', user_dir + "/kivymd", self.get_build_dir(arch) + "/kivymd")
# return
def get_recipe_env(self, arch): def get_recipe_env(self, arch):
env = super(KivyMDRecipe, self).get_recipe_env(arch) env = super(KivyMDRecipe, self).get_recipe_env(arch)
env['PYTHON_ROOT'] = self.ctx.get_python_install_dir() env['PYTHON_ROOT'] = self.ctx.get_python_install_dir()

View File

@ -0,0 +1,92 @@
"""
src/identiconGeneration.py
=================================
"""
import hashlib
from PIL import Image
from kivy.core.image import Image as CoreImage
from kivy.uix.image import Image as kiImage
from io import BytesIO
""" Core classes for loading images and converting them to a Texture.
The raw image data can be keep in memory for further access """
# constants
RESOLUTION = 128, 128
V_RESOLUTION = 7, 7
BACKGROUND_COLOR = 255, 255, 255, 255
MODE = "RGB"
def generate(Generate_string=None):
"""Generating string"""
hash_string = generate_hash(Generate_string)
color = random_color(hash_string)
image = Image.new(MODE, V_RESOLUTION, BACKGROUND_COLOR)
image = generate_image(image, color, hash_string)
image = image.resize(RESOLUTION, 0)
data = BytesIO()
image.save(data, format='png')
data.seek(0)
# yes you actually need this
im = CoreImage(BytesIO(data.read()), ext='png')
beeld = kiImage()
# only use this line in first code instance
beeld.texture = im.texture
return beeld
# image.show()
def generate_hash(string):
"""Generating hash"""
try:
# make input case insensitive
string = str.lower(string)
hash_object = hashlib.md5(str.encode(string))
print hash_object.hexdigest()
# returned object is a hex string
return hash_object.hexdigest()
except IndexError:
print "Error: Please enter a string as an argument."
def random_color(hash_string):
"""Getting random color"""
# remove first three digits from hex string
split = 6
rgb = hash_string[:split]
split = 2
r = rgb[:split]
g = rgb[split:2 * split]
b = rgb[2 * split:3 * split]
color = (int(r, 16), int(g, 16),
int(b, 16), 0xFF)
return color
def generate_image(image, color, hash_string):
"""Generating images"""
hash_string = hash_string[6:]
lower_x = 1
lower_y = 1
upper_x = int(V_RESOLUTION[0] / 2) + 1
upper_y = V_RESOLUTION[1] - 1
limit_x = V_RESOLUTION[0] - 1
index = 0
for x in range(lower_x, upper_x):
for y in range(lower_y, upper_y):
if int(hash_string[index], 16) % 2 == 0:
image.putpixel((x, y), color)
image.putpixel((limit_x - x, y), color)
index = index + 1
return image

View File

@ -11,9 +11,12 @@ def search_sql(xAddress="toaddress", account=None, folder="inbox", where=None, w
sqlStatementBase = ''' sqlStatementBase = '''
SELECT toaddress, fromaddress, subject, message, status, ackdata, lastactiontime SELECT toaddress, fromaddress, subject, message, status, ackdata, lastactiontime
FROM sent ''' FROM sent '''
elif folder == "addressbook":
sqlStatementBase = '''SELECT label, address From addressbook '''
else: else:
sqlStatementBase = '''SELECT folder, msgid, toaddress, message, fromaddress, subject, received, read sqlStatementBase = '''SELECT folder, msgid, toaddress, message, fromaddress, subject, received, read
FROM inbox ''' FROM inbox '''
sqlStatementParts = [] sqlStatementParts = []
sqlArguments = [] sqlArguments = []
if account is not None: if account is not None:
@ -24,15 +27,16 @@ def search_sql(xAddress="toaddress", account=None, folder="inbox", where=None, w
else: else:
sqlStatementParts.append(xAddress + " = ? ") sqlStatementParts.append(xAddress + " = ? ")
sqlArguments.append(account) sqlArguments.append(account)
if folder is not None: if folder is not "addressbook":
if folder == "new": if folder is not None:
folder = "inbox" if folder == "new":
unreadOnly = True folder = "inbox"
sqlStatementParts.append("folder = ? ") unreadOnly = True
sqlArguments.append(folder) sqlStatementParts.append("folder = ? ")
else: sqlArguments.append(folder)
sqlStatementParts.append("folder != ?") else:
sqlArguments.append("trash") sqlStatementParts.append("folder != ?")
sqlArguments.append("trash")
if what is not None: if what is not None:
for colmns in where: for colmns in where:
if len(where) > 1: if len(where) > 1:
@ -49,5 +53,7 @@ def search_sql(xAddress="toaddress", account=None, folder="inbox", where=None, w
if len(sqlStatementParts) > 0: if len(sqlStatementParts) > 0:
sqlStatementBase += "WHERE " + " AND ".join(sqlStatementParts) sqlStatementBase += "WHERE " + " AND ".join(sqlStatementParts)
if folder == "sent": if folder == "sent":
sqlStatementBase += " ORDER BY lastactiontime" sqlStatementBase += " ORDER BY lastactiontime DESC"
elif folder == "inbox":
sqlStatementBase += " ORDER BY received DESC"
return sqlQuery(sqlStatementBase, sqlArguments) return sqlQuery(sqlStatementBase, sqlArguments)

View File

@ -53,74 +53,80 @@
color: color_font color: color_font
<ContentNavigationDrawer@Navigatorss>: <ContentNavigationDrawer@Navigatorss>:
drawer_logo: './images/drawer_logo1.png' drawer_logo: app.address_identicon()
NavigationDrawerDivider: NavigationDrawerDivider:
NavigationDrawerTwoLineListItem: NavigationDrawerTwoLineListItem:
text: "Accounts" text: "Accounts"
NavigationDrawerIconButton: NavigationDrawerIconButton:
CustomSpinner: CustomSpinner:
pos_hint:{"x":0,"y":.25}
id: btn id: btn
pos_hint:{"x":0,"y":.25}
option_cls: Factory.get("MySpinnerOption") option_cls: Factory.get("MySpinnerOption")
font_size: '12.5sp' font_size: '11.9sp'
text: app.getDefaultAccData() text: app.getDefaultAccData()
background_color: color_button if self.state == 'normal' else color_button_pressed background_color: color_button if self.state == 'normal' else color_button_pressed
background_down: 'atlas://data/images/defaulttheme/spinner' background_down: 'atlas://data/images/defaulttheme/spinner'
color: color_font color: color_font
values: app.variable_1 values: app.variable_1
on_text:app.getCurrentAccountData(self.text) on_text:app.getCurrentAccountData(self.text)
Image:
source: app.get_default_image()
x: self.width/4-2
y: self.parent.y + self.parent.height/2 - self.height + 14
size: 28, 28
ArrowImg: ArrowImg:
NavigationDrawerIconButton: NavigationDrawerIconButton:
id: inbox_cnt id: inbox_cnt
icon: 'email-open' icon: 'email-open'
text: "Inbox" text: "Inbox"
on_release: app.root.ids.scr_mngr.current = 'inbox' on_release: app.root.ids.scr_mngr.current = 'inbox'
badge_text: app.mail_count(self.text) badge_text: "0"
on_press: app.check_search_screen(self) on_press: app.check_search_screen(self)
NavigationDrawerIconButton: NavigationDrawerIconButton:
id: send_cnt id: send_cnt
icon: 'send' icon: 'send'
text: "Sent" text: "Sent"
on_release: app.root.ids.scr_mngr.current = 'sent' on_release: app.root.ids.scr_mngr.current = 'sent'
badge_text: app.mail_count(self.text) badge_text: "0"
on_press: app.check_search_screen(self) on_press: app.check_search_screen(self)
NavigationDrawerIconButton: NavigationDrawerIconButton:
id: draft_cnt id: draft_cnt
icon: 'message-draw' icon: 'message-draw'
text: "Draft" text: "Draft"
on_release: app.root.ids.scr_mngr.current = 'draft' on_release: app.root.ids.scr_mngr.current = 'draft'
badge_text: app.mail_count(self.text) badge_text: "0"
on_press: app.check_search_screen(self) on_press: app.check_search_screen(self)
NavigationDrawerIconButton: NavigationDrawerIconButton:
text: "Starred" text: "Starred"
icon:'star' icon:'star'
on_release: app.root.ids.scr_mngr.current = 'inbox' on_release: app.root.ids.scr_mngr.current = 'starred'
on_press: app.check_search_screen(self) on_press: app.check_search_screen(self)
NavigationDrawerIconButton: NavigationDrawerIconButton:
icon: 'archive' icon: 'archive'
text: "Archieve" text: "Archieve"
on_release: app.root.ids.scr_mngr.current = 'trash' on_release: app.root.ids.scr_mngr.current = 'archieve'
badge_text: "9+" badge_text: "0"
on_press: app.check_search_screen(self) on_press: app.check_search_screen(self)
NavigationDrawerIconButton: NavigationDrawerIconButton:
icon: 'email-open-outline' icon: 'email-open-outline'
text: "Spam" text: "Spam"
on_release: app.root.ids.scr_mngr.current = 'inbox' on_release: app.root.ids.scr_mngr.current = 'spam'
badge_text: "8+" badge_text: "0"
on_press: app.check_search_screen(self) on_press: app.check_search_screen(self)
NavigationDrawerIconButton: NavigationDrawerIconButton:
id: trash_cnt id: trash_cnt
icon: 'delete' icon: 'delete'
text: "Trash" text: "Trash"
on_release: app.root.ids.scr_mngr.current = 'trash' on_release: app.root.ids.scr_mngr.current = 'trash'
badge_text: app.mail_count(self.text) badge_text: "0"
on_press: app.check_search_screen(self) on_press: app.check_search_screen(self)
NavigationDrawerIconButton: NavigationDrawerIconButton:
id: allmail_cnt
text: "All Mails" text: "All Mails"
icon:'contact-mail' icon:'contact-mail'
on_release: app.root.ids.scr_mngr.current = 'inbox' on_release: app.root.ids.scr_mngr.current = 'allmails'
badge_text: "999+" badge_text: "0"
on_press: app.check_search_screen(self) on_press: app.check_search_screen(self)
NavigationDrawerDivider: NavigationDrawerDivider:
NavigationDrawerSubheader: NavigationDrawerSubheader:
@ -140,6 +146,11 @@
icon:'wallet' icon:'wallet'
on_release: app.root.ids.scr_mngr.current = 'payment' on_release: app.root.ids.scr_mngr.current = 'payment'
on_press: app.check_search_screen(self) on_press: app.check_search_screen(self)
NavigationDrawerIconButton:
text: "Credits"
icon:'wallet'
on_release: app.root.ids.scr_mngr.current = 'credits'
on_press: app.check_search_screen(self)
NavigationDrawerIconButton: NavigationDrawerIconButton:
text: "new address" text: "new address"
icon:'account-plus' icon:'account-plus'
@ -174,58 +185,20 @@ NavigationLayout:
background_palette: 'Primary' background_palette: 'Primary'
background_hue: '500' background_hue: '500'
left_action_items: [['menu', lambda x: app.root.toggle_nav_drawer()]] left_action_items: [['menu', lambda x: app.root.toggle_nav_drawer()]]
Button: right_action_items: [['account-plus', lambda x: app.addingtoaddressbook()]]
id: reset_navbar BoxLayout:
size_hint_y: 0.35 id: search_bar
size_hint_x: 0.2 size_hint_y: None
opacity: 0 height: self.minimum_height
disabled: True
pos_hint: {'x': .1, 'y': 0.3} MDIconButton:
color: 0,0,0,1 icon: 'magnify'
background_color: (0,0,0,0)
on_press:app.reset_navdrawer(self) MDTextField:
Image: id: search_field
source: './images/left_arrow.png' hint_text: 'Search'
center_x: self.parent.center_x on_text: app.searchQuery(self)
center_y: self.parent.center_y
size: 40, 40
TextInput:
id: search_input
hint_text: 'search'
opacity: 0
size_hint: 1,None
height: dp(32)
disabled: True
pos_hint: {'center_x':.565,'center_y': .5}
multiline: False
padding_y: [self.height / 2.0 - (self.line_height / 2.0) * len(self._lines), 0]
padding_x: 20,20
Button:
id: serch_btn
size_hint_y: 0.35
size_hint_x: 0.2
pos_hint: {'x': .1, 'y': 0.3}
color: 0,0,0,1
background_color: (0,0,0,0)
on_press:app.searchQuery(self, search_input.text)
Image:
source: './images/search_mail.png'
center_x: self.parent.center_x
center_y: self.parent.center_y
size: 55, 55
Button:
id: myButton
size_hint_y: 0.35
size_hint_x: 0.2
pos_hint: {'x': .1, 'y': 0.3}
color: 0,0,0,1
background_color: (0,0,0,0)
on_press:app.addingtoaddressbook()
Image:
source: './images/addressbookadd.png'
center_x: self.parent.center_x
center_y: self.parent.center_y
size: 55, 55
ScreenManager: ScreenManager:
id: scr_mngr id: scr_mngr
Inbox: Inbox:
@ -260,7 +233,16 @@ NavigationLayout:
id:sc15 id:sc15
Draft: Draft:
id:sc16 id:sc16
Allmails:
id:sc17
Credits:
id:sc18
Starred:
id:sc19
Archieve:
id:sc20
Spam:
id:sc21
<Inbox>: <Inbox>:
name: 'inbox' name: 'inbox'
@ -271,7 +253,7 @@ NavigationLayout:
root_layout: root root_layout: root
MDList: MDList:
id: ml id: ml
ComposerButton ComposerButton:
<Sent>: <Sent>:
name: 'sent' name: 'sent'
@ -297,6 +279,41 @@ NavigationLayout:
id: ml id: ml
ComposerButton: ComposerButton:
<Starred>:
name: 'starred'
ScrollView:
do_scroll_x: False
MDList:
id: ml
ComposerButton:
<Archieve>:
name: 'archieve'
ScrollView:
do_scroll_x: False
MDList:
id: ml
ComposerButton:
<Spam>:
name: 'spam'
ScrollView:
do_scroll_x: False
MDList:
id: ml
ComposerButton:
<Allmails>:
name: 'allmails'
FloatLayout:
MDScrollViewRefreshLayout:
id: refresh_layout
refresh_callback: root.refresh_callback
root_layout: root
MDList:
id: ml
ComposerButton:
<Test>: <Test>:
name: 'test' name: 'test'
Label: Label:
@ -312,12 +329,34 @@ NavigationLayout:
<Create>: <Create>:
name: 'create' name: 'create'
<Credits>:
name: 'credits'
ScrollView:
do_scroll_x: False
MDList:
id: ml
size_hint_y: None
height: dp(200)
OneLineListItem:
text: "Available Credits"
BoxLayout:
AnchorLayout:
MDRaisedButton:
size_hint: .6, .35
height: dp(40)
MDLabel:
font_style: 'Title'
text: root.available_credits
font_size: '13sp'
color: (1,1,1,1)
halign: 'center'
<DropDownWidget>: <DropDownWidget>:
ScrollView: ScrollView:
BoxLayout: BoxLayout:
orientation: 'vertical' orientation: 'vertical'
size_hint_y: None size_hint_y: None
height: dp(600) height: self.minimum_height + 2 * self.parent.height/4
padding: dp(32) padding: dp(32)
spacing: 15 spacing: 15
BoxLayout: BoxLayout:
@ -339,7 +378,7 @@ NavigationLayout:
background_color: app.theme_cls.primary_dark background_color: app.theme_cls.primary_dark
id: btn id: btn
values: app.variable_1 values: app.variable_1
on_text: ti.text = self.text if self.text != 'Select' else '' on_text: root.auto_fill_fromaddr() if self.text != 'Select' else ''
option_cls: Factory.get("MySpinnerOption") option_cls: Factory.get("MySpinnerOption")
background_color: color_button if self.state == 'normal' else color_button_pressed background_color: color_button if self.state == 'normal' else color_button_pressed
background_down: 'atlas://data/images/defaulttheme/spinner' background_down: 'atlas://data/images/defaulttheme/spinner'
@ -357,7 +396,7 @@ NavigationLayout:
id: txt_input id: txt_input
size_hint_y: None size_hint_y: None
font_size: '13sp' font_size: '13sp'
height: 100 height: self.parent.height/2
hint_text: 'type or search recipients address starting with BM-' hint_text: 'type or search recipients address starting with BM-'
RV: RV:
id: rv id: rv
@ -385,18 +424,7 @@ NavigationLayout:
MDRaisedButton: MDRaisedButton:
size_hint: 1, None size_hint: 1, None
height: dp(40) height: dp(40)
on_press: root.send() on_press: root.reset_composer()
MDLabel:
font_style: 'Title'
text: 'send'
font_size: '13sp'
color: (1,1,1,1)
halign: 'center'
AnchorLayout:
MDRaisedButton:
size_hint: 1, None
height: dp(40)
on_press: app.root.ids.scr_mngr.current = 'random'
MDLabel: MDLabel:
font_style: 'Title' font_style: 'Title'
text: 'reset' text: 'reset'
@ -538,7 +566,7 @@ NavigationLayout:
MDRaisedButton: MDRaisedButton:
size_hint: .5, None size_hint: .5, None
height: dp(40) height: dp(40)
on_release: root.generateaddress() on_release: root.generateaddress(app)
opposite_colors: True opposite_colors: True
MDLabel: MDLabel:
font_style: 'Title' font_style: 'Title'
@ -647,6 +675,148 @@ NavigationLayout:
<Payment>: <Payment>:
name: 'payment' name: 'payment'
ScrollView:
do_scroll_x: False
BoxLayout:
orientation: 'vertical'
padding: [dp(app.window_size[0]/16 if app.window_size[0] <= 720 else app.window_size[0]/4*1.1), dp(10)]
spacing: 12
size_hint_y: None
height: self.minimum_height + dp(app.window_size[1]) if app.window_size[1] > app.window_size[0] else dp(app.window_size[0])
BoxLayout:
orientation: 'vertical'
padding: dp(5)
canvas.before:
Color:
rgba: app.theme_cls.primary_dark
Rectangle:
# self here refers to the widget i.e FloatLayout
pos: self.pos
size: self.size
MDLabel:
size_hint_y: None
font_style: 'Headline'
theme_text_color: 'Primary'
text: 'Platinum'
halign: 'center'
color: 1,1,1,1
MDLabel:
font_style: 'Subhead'
theme_text_color: 'Primary'
text: 'We provide subscriptions for proof of work calculation for first month. '
halign: 'center'
color: 1,1,1,1
MDLabel:
id: free_pak
font_style: 'Headline'
theme_text_color: 'Primary'
text: '€ 50.0'
halign: 'center'
color: 1,1,1,1
MDRaisedButton:
canvas:
Color:
rgb: (0.93, 0.93, 0.93)
Rectangle:
pos: self.pos
size: self.size
size_hint: 1, None
height: dp(40)
on_press: root.get_available_credits(self)
MDLabel:
font_style: 'Title'
text: 'Get Free Credits'
font_size: '13sp'
color: (0,0,0,1)
halign: 'center'
BoxLayout:
orientation: 'vertical'
padding: dp(5)
canvas.before:
Color:
rgba: app.theme_cls.primary_dark
Rectangle:
# self here refers to the widget i.e FloatLayout
pos: self.pos
size: self.size
MDLabel:
size_hint_y: None
font_style: 'Headline'
theme_text_color: 'Primary'
text: 'Silver'
halign: 'center'
color: 1,1,1,1
MDLabel:
font_style: 'Subhead'
theme_text_color: 'Primary'
text: 'We provide for proof of work calculation for six month. '
halign: 'center'
color: 1,1,1,1
MDLabel:
font_style: 'Headline'
theme_text_color: 'Primary'
text: '€ 100.0'
halign: 'center'
color: 1,1,1,1
MDRaisedButton:
canvas:
Color:
rgb: (0.93, 0.93, 0.93)
Rectangle:
pos: self.pos
size: self.size
size_hint: 1, None
height: dp(40)
MDLabel:
font_style: 'Title'
text: 'Get Monthly Credits'
font_size: '13sp'
color: (0,0,0,1)
halign: 'center'
BoxLayout:
orientation: 'vertical'
padding: dp(5)
canvas.before:
Color:
rgba: app.theme_cls.primary_dark
Rectangle:
# self here refers to the widget i.e FloatLayout
pos: self.pos
size: self.size
MDLabel:
size_hint_y: None
font_style: 'Headline'
theme_text_color: 'Primary'
text: 'Gold'
halign: 'center'
color: 1,1,1,1
MDLabel:
font_style: 'Subhead'
theme_text_color: 'Primary'
text: 'We provide for proof of work calculation for 1years. '
halign: 'center'
color: 1,1,1,1
MDLabel:
font_style: 'Headline'
theme_text_color: 'Primary'
text: '€ 500.0'
halign: 'center'
color: 1,1,1,1
MDRaisedButton:
canvas:
Color:
rgb: (0.93, 0.93, 0.93)
Rectangle:
pos: self.pos
size: self.size
size_hint: 1, None
height: dp(40)
MDLabel:
font_style: 'Title'
text: 'Get Yearly Credits'
font_size: '13sp'
color: (0,0,0,1)
halign: 'center'
<GrashofPopup>: <GrashofPopup>:
@ -676,10 +846,12 @@ NavigationLayout:
hint_text: "Address" hint_text: "Address"
required: True required: True
helper_text_mode: "on_error" helper_text_mode: "on_error"
on_text: root.checkAddress_valid(self)
BoxLayout: BoxLayout:
spacing:5 spacing:5
orientation: 'horizontal' orientation: 'horizontal'
MDRaisedButton: MDRaisedButton:
id: save_addr
size_hint: 1.5, None size_hint: 1.5, None
height: dp(40) height: dp(40)
on_release: on_release:
@ -694,6 +866,7 @@ NavigationLayout:
size_hint: 1.5, None size_hint: 1.5, None
height: dp(40) height: dp(40)
on_press: root.dismiss() on_press: root.dismiss()
on_press: root.close_pop()
MDLabel: MDLabel:
font_style: 'Title' font_style: 'Title'
text: 'Cancel' text: 'Cancel'
@ -710,6 +883,7 @@ NavigationLayout:
color: (1,1,1,1) color: (1,1,1,1)
halign: 'center' halign: 'center'
<NetworkStat>: <NetworkStat>:
name: 'networkstat' name: 'networkstat'
MDTabbedPanel: MDTabbedPanel:
@ -807,23 +981,27 @@ NavigationLayout:
BoxLayout: BoxLayout:
orientation: 'vertical' orientation: 'vertical'
size_hint_y: None size_hint_y: None
height: dp(400) height: dp(500) + self.minimum_height
padding: dp(32) padding: dp(32)
MDLabel: MDLabel:
font_style: 'Headline' font_style: 'Headline'
theme_text_color: 'Primary' theme_text_color: 'Primary'
text: root.subject text: root.subject
halign: 'left' halign: 'left'
font_size: '20sp'
CopyTextBtn:
MDLabel: MDLabel:
font_style: 'Subhead' font_style: 'Subhead'
theme_text_color: 'Primary' theme_text_color: 'Primary'
text: "From: " + root.from_addr text: "From: " + root.from_addr
halign: 'left' halign: 'left'
CopyTextBtn:
MDLabel: MDLabel:
font_style: 'Subhead' font_style: 'Subhead'
theme_text_color: 'Primary' theme_text_color: 'Primary'
text: "To: " + root.to_addr text: "To: " + root.to_addr
halign: 'left' halign: 'left'
CopyTextBtn:
MDLabel: MDLabel:
font_style: 'Subhead' font_style: 'Subhead'
theme_text_color: 'Primary' theme_text_color: 'Primary'
@ -835,28 +1013,24 @@ NavigationLayout:
text: root.message text: root.message
halign: 'left' halign: 'left'
bold: True bold: True
CopyTextBtn:
BoxLayout: BoxLayout:
spacing:20 orientation: 'vertical'
MDRaisedButton: size_hint_y: None
size_hint: 1, None height: dp(100) + self.minimum_height
height: dp(40)
on_press: root.inbox_reply() if root.page_type == 'inbox' else root.copy_sent_mail() <CopyTextBtn@Button>:
MDLabel: id: cpyButton
font_style: 'Title' color: 0,0,0,1
text: 'Reply' if root.page_type == 'inbox' else 'Copy' background_color: (0,0,0,0)
font_size: '13sp' center_x: self.parent.center_x * 2 - self.parent.parent.padding[0]/2
color: (1,1,1,1) center_y: self.parent.center_y
halign: 'center' on_press:app.root.ids.sc14.copy_composer_text(self)
MDRaisedButton: Image:
size_hint: 1, None source: './images/copy_text.png'
height: dp(40) center_x: self.parent.center_x
on_press: root.delete_mail() center_y: self.parent.center_y
MDLabel: size: 20, 20
font_style: 'Title'
text: 'Delete'
font_size: '13sp'
color: (1,1,1,1)
halign: 'center'
<ComposerButton@BoxLayout>: <ComposerButton@BoxLayout>:
size_hint_y: None size_hint_y: None
@ -941,6 +1115,7 @@ NavigationLayout:
size_hint: 1.5, None size_hint: 1.5, None
height: dp(40) height: dp(40)
on_press: root.dismiss() on_press: root.dismiss()
on_press: root.close_pop()
MDLabel: MDLabel:
font_style: 'Title' font_style: 'Title'
text: 'Cancel' text: 'Cancel'
@ -1017,6 +1192,7 @@ NavigationLayout:
size_hint: 1.5, None size_hint: 1.5, None
height: dp(40) height: dp(40)
on_press: root.dismiss() on_press: root.dismiss()
on_press: root.close_pop()
MDLabel: MDLabel:
font_style: 'Title' font_style: 'Title'
text: 'Cancel' text: 'Cancel'

View File

@ -1,56 +1,79 @@
# -*- coding: utf-8 -*- """
src/bitmessagekivy/mpybit.py
=================================
"""
import os
import time
from functools import partial
from bmconfigparser import BMConfigParser
from helper_sql import sqlExecute, sqlQuery
from kivy.app import App from kivy.app import App
from kivy.clock import Clock
from kivy.core.clipboard import Clipboard
from kivy.core.window import Window
from kivy.lang import Builder from kivy.lang import Builder
from kivy.metrics import dp from kivy.metrics import dp
from kivy.properties import ObjectProperty from kivy.properties import (
BooleanProperty,
ListProperty,
NumericProperty,
ObjectProperty,
StringProperty)
from kivy.uix.behaviors import FocusBehavior
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.uix.carousel import Carousel
from kivy.uix.image import Image from kivy.uix.image import Image
from kivy.uix.screenmanager import Screen, NoTransition from kivy.uix.label import Label
from kivymd.bottomsheet import MDListBottomSheet, MDGridBottomSheet from kivy.uix.popup import Popup
from kivy.uix.recycleboxlayout import RecycleBoxLayout
from kivy.uix.recycleview import RecycleView
from kivy.uix.recycleview.layout import LayoutSelectionBehavior
from kivy.uix.recycleview.views import RecycleDataViewBehavior
from kivy.uix.screenmanager import Screen
from kivy.uix.spinner import Spinner
from kivy.uix.textinput import TextInput
from kivy.utils import platform
import kivy_helper_search
from kivymd.button import MDIconButton from kivymd.button import MDIconButton
from kivymd.date_picker import MDDatePicker
from kivymd.dialog import MDDialog from kivymd.dialog import MDDialog
from kivymd.label import MDLabel from kivymd.label import MDLabel
from kivymd.list import ILeftBody, ILeftBodyTouch, IRightBodyTouch, BaseListItem from kivymd.list import (
from kivymd.material_resources import DEVICE_TYPE ILeftBody,
from kivymd.navigationdrawer import MDNavigationDrawer, NavigationDrawerHeaderBase ILeftBodyTouch,
IRightBodyTouch,
ThreeLineAvatarIconListItem,
TwoLineAvatarIconListItem,
TwoLineListItem)
from kivymd.navigationdrawer import (
MDNavigationDrawer,
NavigationDrawerHeaderBase)
from kivymd.selectioncontrols import MDCheckbox from kivymd.selectioncontrols import MDCheckbox
from kivymd.snackbar import Snackbar from kivymd.textfields import MDTextField
from kivymd.theming import ThemeManager from kivymd.theming import ThemeManager
from kivymd.time_picker import MDTimePicker
from kivymd.list import ThreeLineAvatarIconListItem, TwoLineAvatarIconListItem, TwoLineListItem
from kivy.properties import ListProperty, StringProperty, BooleanProperty
from kivy.clock import Clock
from bmconfigparser import BMConfigParser
import state
import queues import queues
from kivy.uix.popup import Popup
from helper_sql import *
from kivy.uix.gridlayout import GridLayout
from kivy.app import App
from kivy.uix.textinput import TextInput
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.floatlayout import FloatLayout
from kivy.properties import NumericProperty, ListProperty, BooleanProperty, ObjectProperty
from kivy.uix.recycleview import RecycleView
from kivy.uix.recyclegridlayout import RecycleGridLayout
from kivy.uix.recycleview.views import RecycleDataViewBehavior
from kivy.uix.label import Label
from kivy.uix.recycleboxlayout import RecycleBoxLayout
from kivy.uix.behaviors import FocusBehavior
from kivy.uix.recycleview.layout import LayoutSelectionBehavior
import time
from uikivysignaler import UIkivySignaler
from semaphores import kivyuisignaler from semaphores import kivyuisignaler
from kivy.uix.button import Button import state
import kivy_helper_search from uikivysignaler import UIkivySignaler
from kivy.core.window import Window # pylint: disable=unused-argument, too-few-public-methods, import-error
from functools import partial
from kivy.uix.carousel import Carousel import identiconGeneration
from kivy.utils import platform import os
from kivy.uix.spinner import Spinner from kivy.core.clipboard import Clipboard
# pylint: disable=unused-argument, too-few-public-methods
def toast(text):
"""Method will display the toast message."""
if platform == 'linux':
from kivymd.toast.kivytoast import toast # pylint: disable=redefined-outer-name
toast(text)
return
class Navigatorss(MDNavigationDrawer): class Navigatorss(MDNavigationDrawer):
"""Navigators class contains image, title and logo."""
image_source = StringProperty('images/qidenticon_two.png') image_source = StringProperty('images/qidenticon_two.png')
title = StringProperty('Navigation') title = StringProperty('Navigation')
drawer_logo = StringProperty() drawer_logo = StringProperty()
@ -58,9 +81,11 @@ class Navigatorss(MDNavigationDrawer):
class Inbox(Screen): class Inbox(Screen):
"""Inbox Screen uses screen to show widgets of screens.""" """Inbox Screen uses screen to show widgets of screens."""
data = ListProperty() data = ListProperty()
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
"""Method Parsing the address."""
super(Inbox, self).__init__(*args, **kwargs) super(Inbox, self).__init__(*args, **kwargs)
if state.association == '': if state.association == '':
if BMConfigParser().addresses(): if BMConfigParser().addresses():
@ -70,7 +95,7 @@ class Inbox(Screen):
def init_ui(self, dt=0): def init_ui(self, dt=0):
"""Clock Schdule for method inbox accounts.""" """Clock Schdule for method inbox accounts."""
self.inboxaccounts() self.inboxaccounts()
print(dt) print dt
def inboxaccounts(self): def inboxaccounts(self):
"""Load inbox accounts.""" """Load inbox accounts."""
@ -79,6 +104,7 @@ class Inbox(Screen):
def loadMessagelist(self, account, where="", what=""): def loadMessagelist(self, account, where="", what=""):
"""Load Inbox list for Inbox messages.""" """Load Inbox list for Inbox messages."""
# pylint: disable=too-many-locals
if state.searcing_text: if state.searcing_text:
where = ['subject', 'message'] where = ['subject', 'message']
what = state.searcing_text what = state.searcing_text
@ -87,18 +113,32 @@ class Inbox(Screen):
queryreturn = kivy_helper_search.search_sql( queryreturn = kivy_helper_search.search_sql(
xAddress, account, "inbox", where, what, False) xAddress, account, "inbox", where, what, False)
if queryreturn: if queryreturn:
src_mng_obj = state.kivyapp.root.children[2].children[0].ids
src_mng_obj.inbox_cnt.badge_text = str(len(queryreturn))
state.inbox_count = str(len(queryreturn))
state.kivyapp.root.ids.sc17.clear_widgets()
state.kivyapp.root.ids.sc17.add_widget(Allmails())
for mail in queryreturn: for mail in queryreturn:
third_text = mail[3].replace('\n', ' ') third_text = mail[3].replace('\n', ' ')
data.append({'text': mail[4].strip(), 'secondary_text': mail[5][:10] + '...........' if len(mail[3]) > 10 else mail[3] + '\n' + " " + (third_text[:25] + '...!') if len(third_text) > 25 else third_text, 'receivedTime': mail[6] }) data.append({
'text': mail[4].strip(),
'secondary_text': mail[5][:50] + '........' if len(
mail[5]) >= 50 else (
mail[5] + ',' + mail[3].replace('\n', ''))[0:50] + '........',
'receivedTime': mail[6]})
for item in data: for item in data:
meny = ThreeLineAvatarIconListItem(text=item['text'], secondary_text=item['secondary_text'], theme_text_color= 'Custom', text_color=NavigateApp().theme_cls.primary_color) meny = TwoLineAvatarIconListItem(
meny.add_widget(AvatarSampleWidget(source='./images/text_images/{}.png'.format(item['secondary_text'][0].upper() if (item['secondary_text'][0].upper() >= 'A' and item['secondary_text'][0].upper() <= 'Z') else '!'))) text=item['text'],
meny.bind(on_press = partial(self.inbox_detail, item['receivedTime'])) secondary_text=item['secondary_text'],
theme_text_color='Custom',
text_color=NavigateApp().theme_cls.primary_color)
meny.add_widget(AvatarSampleWidget(
source='./images/text_images/{}.png'.format(
avatarImageFirstLetter(item['secondary_text'].strip()))))
meny.bind(on_press=partial(
self.inbox_detail, item['receivedTime']))
carousel = Carousel(direction='right') carousel = Carousel(direction='right')
if platform == 'android': carousel.height = meny.height
carousel.height = 150
elif platform == 'linux':
carousel.height = meny.height - 10
carousel.size_hint_y = None carousel.size_hint_y = None
carousel.ignore_perpendicular_swipes = True carousel.ignore_perpendicular_swipes = True
carousel.data_index = 0 carousel.data_index = 0
@ -106,77 +146,94 @@ class Inbox(Screen):
del_btn = Button(text='Delete') del_btn = Button(text='Delete')
del_btn.background_normal = '' del_btn.background_normal = ''
del_btn.background_color = (1, 0, 0, 1) del_btn.background_color = (1, 0, 0, 1)
del_btn.bind(on_press=partial(self.delete, item['receivedTime'])) del_btn.bind(on_press=partial(
self.delete, item['receivedTime']))
carousel.add_widget(del_btn) carousel.add_widget(del_btn)
carousel.add_widget(meny) carousel.add_widget(meny)
ach_btn = Button(text='Achieve') ach_btn = Button(text='Achieve')
ach_btn.background_color = (0,1,0,1) ach_btn.background_color = (0, 1, 0, 1)
ach_btn.bind(on_press=partial(self.archive, item['receivedTime'])) ach_btn.bind(on_press=partial(
self.archive, item['receivedTime']))
carousel.add_widget(ach_btn) carousel.add_widget(ach_btn)
carousel.index = 1 carousel.index = 1
self.ids.ml.add_widget(carousel) self.ids.ml.add_widget(carousel)
else: else:
content = MDLabel(font_style='Body1', content = MDLabel(
theme_text_color='Primary', font_style='Body1',
text="yet no message for this account!!!!!!!!!!!!!", theme_text_color='Primary',
halign='center', text="No message found!" if state.searcing_text
bold=True, else "yet no message for this account!!!!!!!!!!!!!",
size_hint_y=None, halign='center',
valign='top') bold=True,
size_hint_y=None,
valign='top')
self.ids.ml.add_widget(content) self.ids.ml.add_widget(content)
def inbox_detail(self, receivedTime, *args): def inbox_detail(self, receivedTime, *args):
"""Load inbox page details""" """Load inbox page details."""
remove_search_bar(self)
state.detailPageType = 'inbox' state.detailPageType = 'inbox'
state.sentMailTime = receivedTime state.sentMailTime = receivedTime
if self.manager: if self.manager:
src_mng_obj = self.manager src_mng_obj = self.manager
else: else:
src_mng_obj = self.parent.parent src_mng_obj = self.parent.parent
hide_search_btn(src_mng_obj)
src_mng_obj.screens[13].clear_widgets() src_mng_obj.screens[13].clear_widgets()
src_mng_obj.screens[13].add_widget(MailDetail()) src_mng_obj.screens[13].add_widget(MailDetail())
src_mng_obj.current = 'mailDetail' src_mng_obj.current = 'mailDetail'
def delete(self, data_index, instance, *args): def delete(self, data_index, instance, *args):
"""Delete inbox mail from inbox listing""" """Delete inbox mail from inbox listing."""
sqlExecute("UPDATE inbox SET folder = 'trash' WHERE received = {};".format(data_index)) sqlExecute(
msg_count_objs = self.parent.parent.parent.parent.children[2].children[0].ids "UPDATE inbox SET folder = 'trash' WHERE received = {};".format(
data_index))
msg_count_objs = \
self.parent.parent.parent.parent.parent.children[2].children[0].ids
if int(state.inbox_count) > 0: if int(state.inbox_count) > 0:
msg_count_objs.inbox_cnt.badge_text = str(int(state.inbox_count) - 1) msg_count_objs.inbox_cnt.badge_text = str(
msg_count_objs.trash_cnt.badge_text = str(int(state.trash_count) + 1) int(state.inbox_count) - 1)
state.inbox_count = str(int(state.inbox_count) - 1) msg_count_objs.trash_cnt.badge_text = str(
state.trash_count = str(int(state.trash_count) + 1) int(state.trash_count) + 1)
self.ids.ml.remove_widget(instance.parent.parent) msg_count_objs.allmail_cnt.badge_text = str(
int(state.all_count) - 1)
state.inbox_count = str(
int(state.inbox_count) - 1)
state.trash_count = str(
int(state.trash_count) + 1)
state.all_count = str(
int(state.all_count) - 1)
self.ids.ml.remove_widget(
instance.parent.parent)
toast('Deleted')
self.update_trash() self.update_trash()
def archive(self, data_index, instance, *args): def archive(self, data_index, instance, *args):
"""Archive inbox mail from inbox listing""" """Archive inbox mail from inbox listing."""
sqlExecute("UPDATE inbox SET folder = 'trash' WHERE received = {};".format(data_index)) sqlExecute(
"UPDATE inbox SET folder = 'trash' WHERE received = {};".format(
data_index))
self.ids.ml.remove_widget(instance.parent.parent) self.ids.ml.remove_widget(instance.parent.parent)
self.update_trash() self.update_trash()
def update_trash(self): def update_trash(self):
"""Update trash screen mails which is deleted from inbox""" """Update trash screen mails which is deleted from inbox."""
try: try:
self.parent.screens[4].clear_widgets() self.parent.screens[4].clear_widgets()
self.parent.screens[4].add_widget(Trash()) self.parent.screens[4].add_widget(Trash())
except Exception as e: except Exception:
self.parent.parent.screens[4].clear_widgets() self.parent.parent.screens[4].clear_widgets()
self.parent.parent.screens[4].add_widget(Trash()) self.parent.parent.screens[4].add_widget(Trash())
# pylint: disable=attribute-defined-outside-init
def refresh_callback(self, *args): def refresh_callback(self, *args):
"""A method that updates the state of your application """Method updates the state of application, While the spinner remains on the screen."""
while the spinner remains on the screen."""
def refresh_callback(interval): def refresh_callback(interval):
"""This methods is used for loading the inbox screen data""" """Method used for loading the inbox screen data."""
self.ids.ml.clear_widgets() self.ids.ml.clear_widgets()
self.remove_widget(self.children[1]) self.remove_widget(self.children[1])
try: try:
screens_obj = self.parent.screens[0] screens_obj = self.parent.screens[0]
except Exception as e: except Exception:
screens_obj = self.parent.parent.screens[0] screens_obj = self.parent.parent.screens[0]
screens_obj.add_widget(Inbox()) screens_obj.add_widget(Inbox())
self.ids.refresh_layout.refresh_done() self.ids.refresh_layout.refresh_done()
@ -187,78 +244,124 @@ class Inbox(Screen):
class MyAddress(Screen): class MyAddress(Screen):
"""MyAddress Screen uses screen to show widgets of screens.""" """MyAddress Screen uses screen to show widgets of screens."""
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
"""Clock Schdule for method inbox accounts."""
super(MyAddress, self).__init__(*args, **kwargs) super(MyAddress, self).__init__(*args, **kwargs)
Clock.schedule_once(self.init_ui, 0) Clock.schedule_once(self.init_ui, 0)
def init_ui(self, dt=0): def init_ui(self, dt=0):
"""Clock Schdule for method inbox accounts.""" """Clock Schdule for method inbox accounts."""
if BMConfigParser().addresses() or state.kivyapp.variable_1: # pylint: disable=unnecessary-lambda, deprecated-lambda
addresses_list = state.kivyapp.variable_1
if state.searcing_text:
filtered_list = filter(
lambda addr: self.filter_address(
addr), BMConfigParser().addresses())
addresses_list = filtered_list
if addresses_list:
data = [] data = []
for address in state.kivyapp.variable_1: for address in addresses_list:
data.append({'text': BMConfigParser().get(address, 'label'), 'secondary_text': address}) data.append({
'text': BMConfigParser().get(address, 'label'),
'secondary_text': address})
for item in data: for item in data:
meny = TwoLineAvatarIconListItem(text=item['text'], secondary_text=item['secondary_text'], theme_text_color= 'Custom',text_color=NavigateApp().theme_cls.primary_color) meny = TwoLineAvatarIconListItem(
meny.add_widget(AvatarSampleWidget(source='./images/text_images/{}.png'.format(item['text'][0].upper() if (item['text'][0].upper() >= 'A' and item['text'][0].upper() <= 'Z') else '!'))) text=item['text'],
meny.bind(on_press=partial(self.myadd_detail, item['secondary_text'], item['text'])) secondary_text=item['secondary_text'],
theme_text_color='Custom',
text_color=NavigateApp().theme_cls.primary_color)
meny.add_widget(AvatarSampleWidget(
source='./images/text_images/{}.png'.format(avatarImageFirstLetter(item['text'].strip()))))
meny.bind(on_press=partial(
self.myadd_detail, item['secondary_text'], item['text']))
self.ids.ml.add_widget(meny) self.ids.ml.add_widget(meny)
else: else:
content = MDLabel(font_style='Body1', content = MDLabel(
theme_text_color='Primary', font_style='Body1',
text="yet no address is created by user!!!!!!!!!!!!!", theme_text_color='Primary',
halign='center', text="No address found!" if state.searcing_text
bold=True, else "yet no address is created by user!!!!!!!!!!!!!",
size_hint_y=None, halign='center',
valign='top') bold=True,
size_hint_y=None,
valign='top')
self.ids.ml.add_widget(content) self.ids.ml.add_widget(content)
try: try:
self.manager.parent.parent\
.parent.ids.search_bar.clear_widgets()
self.manager.current = 'login' self.manager.current = 'login'
except Exception as e: except Exception:
pass pass
def myadd_detail(self, fromaddress, label, *args): @staticmethod
def myadd_detail(fromaddress, label, *args):
"""Myaddress Details."""
p = MyaddDetailPopup() p = MyaddDetailPopup()
p.open() p.open()
p.set_address(fromaddress, label) p.set_address(fromaddress, label)
# pylint: disable=attribute-defined-outside-init
def refresh_callback(self, *args): def refresh_callback(self, *args):
"""A method that updates the state of your application """Method updates the state of application, While the spinner remains on the screen."""
while the spinner remains on the screen."""
def refresh_callback(interval): def refresh_callback(interval):
"""This methods is used for loading the myaddress screen data""" """Method used for loading the myaddress screen data."""
self.ids.ml.clear_widgets() self.ids.ml.clear_widgets()
self.remove_widget(self.children[1]) self.remove_widget(self.children[1])
try: try:
screens_obj = self.parent.screens[9] screens_obj = self.parent.screens[9]
except Exception as e: except Exception:
screens_obj = self.parent.parent.screens[9] screens_obj = self.parent.parent.screens[9]
screens_obj.add_widget(MyAddress()) screens_obj.add_widget(MyAddress())
self.ids.refresh_layout.refresh_done() self.ids.refresh_layout.refresh_done()
self.tick = 0 self.tick = 0
Clock.schedule_once(refresh_callback, 1) Clock.schedule_once(refresh_callback, 1)
@staticmethod
def filter_address(address):
"""Method will filter the my address list data."""
# pylint: disable=deprecated-lambda
if filter(lambda x: (state.searcing_text).lower() in x, [
BMConfigParser().get(
address, 'label').lower(), address.lower()]):
return True
return False
class AddressBook(Screen): class AddressBook(Screen):
"""AddressBook Screen uses screen to show widgets of screens.""" """AddressBook Screen uses screen to show widgets of screens."""
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
"""Getting AddressBook Details."""
super(AddressBook, self).__init__(*args, **kwargs) super(AddressBook, self).__init__(*args, **kwargs)
Clock.schedule_once(self.init_ui, 0) Clock.schedule_once(self.init_ui, 0)
def init_ui(self, dt=0): def init_ui(self, dt=0):
"""Clock Schdule for method inbox accounts.""" """Clock Schdule for method AddressBook."""
data = sqlQuery("SELECT label, address from addressbook") self.loadAddresslist(None, 'All', '')
if data: print dt
for item in data:
meny = TwoLineAvatarIconListItem(text=item[0], secondary_text=item[1], theme_text_color='Custom',text_color=NavigateApp().theme_cls.primary_color) def loadAddresslist(self, account, where="", what=""):
meny.add_widget(AvatarSampleWidget(source='./images/text_images/{}.png'.format(item[0][0].upper() if (item[0][0].upper() >= 'A' and item[0][0].upper() <= 'Z') else '!'))) """Clock Schdule for method AddressBook."""
meny.bind(on_press = partial(self.addBook_detail, item[1], item[0])) if state.searcing_text:
where = ['label', 'address']
what = state.searcing_text
xAddress = ''
queryreturn = kivy_helper_search.search_sql(
xAddress, account, "addressbook", where, what, False)
if queryreturn:
for item in queryreturn:
meny = TwoLineAvatarIconListItem(
text=item[0],
secondary_text=item[1],
theme_text_color='Custom',
text_color=NavigateApp().theme_cls.primary_color)
meny.add_widget(AvatarSampleWidget(
source='./images/text_images/{}.png'.format(avatarImageFirstLetter(item[0].strip()))))
meny.bind(on_press=partial(
self.addBook_detail, item[1], item[0]))
carousel = Carousel(direction='right') carousel = Carousel(direction='right')
if platform == 'android': carousel.height = meny.height
carousel.height = 140
elif platform == 'linux':
carousel.height = meny.height - 10
carousel.size_hint_y = None carousel.size_hint_y = None
carousel.ignore_perpendicular_swipes = True carousel.ignore_perpendicular_swipes = True
carousel.data_index = 0 carousel.data_index = 0
@ -269,140 +372,172 @@ class AddressBook(Screen):
del_btn.bind(on_press=partial(self.delete_address, item[1])) del_btn.bind(on_press=partial(self.delete_address, item[1]))
carousel.add_widget(del_btn) carousel.add_widget(del_btn)
carousel.add_widget(meny) carousel.add_widget(meny)
carousel.index=1 carousel.index = 1
self.ids.ml.add_widget(carousel) self.ids.ml.add_widget(carousel)
else: else:
content = MDLabel(font_style='Body1', content = MDLabel(
theme_text_color='Primary', font_style='Body1',
text="No Contact Found yet...... ", theme_text_color='Primary',
halign='center', text="No contact found!" if state.searcing_text
bold=True, else "No contact found yet...... ",
size_hint_y=None, halign='center',
valign='top') bold=True,
size_hint_y=None,
valign='top')
self.ids.ml.add_widget(content) self.ids.ml.add_widget(content)
def refreshs(self, *args): @staticmethod
def refreshs(*args):
"""Refresh the Widget."""
state.navinstance.ids.sc11.clear_widgets() state.navinstance.ids.sc11.clear_widgets()
state.navinstance.ids.sc11.add_widget(AddressBook()) state.navinstance.ids.sc11.add_widget(AddressBook())
def addBook_detail(self, address, label, *args): @staticmethod
def addBook_detail(address, label, *args):
"""Addressbook Details."""
p = AddbookDetailPopup() p = AddbookDetailPopup()
p.open() p.open()
p.set_addbook_data(address, label) p.set_addbook_data(address, label)
def delete_address(self, address, instance, *args): def delete_address(self, address, instance, *args):
"""Delete inbox mail from inbox listing""" """Delete inbox mail from inbox listing."""
self.ids.ml.remove_widget(instance.parent.parent) self.ids.ml.remove_widget(instance.parent.parent)
sqlExecute("DELETE FROM addressbook WHERE address = '{}';".format(address)) sqlExecute(
"DELETE FROM addressbook WHERE address = '{}';".format(address))
class SelectableRecycleBoxLayout(FocusBehavior, LayoutSelectionBehavior, class SelectableRecycleBoxLayout(FocusBehavior, LayoutSelectionBehavior,
RecycleBoxLayout): RecycleBoxLayout):
''' Adds selection and focus behaviour to the view. ''' """Adds selection and focus behaviour to the view."""
pass pass
class SelectableLabel(RecycleDataViewBehavior, Label): class SelectableLabel(RecycleDataViewBehavior, Label):
''' Add selection support to the Label ''' """Add selection support to the Label."""
index = None index = None
selected = BooleanProperty(False) selected = BooleanProperty(False)
selectable = BooleanProperty(True) selectable = BooleanProperty(True)
def refresh_view_attrs(self, rv, index, data): def refresh_view_attrs(self, rv, index, data):
''' Catch and handle the view changes ''' """Catch and handle the view changes."""
self.index = index self.index = index
return super(SelectableLabel, self).refresh_view_attrs( return super(SelectableLabel, self).refresh_view_attrs(
rv, index, data) rv, index, data)
# pylint: disable=inconsistent-return-statements
def on_touch_down(self, touch): def on_touch_down(self, touch):
''' Add selection on touch down ''' """Add selection on touch down."""
if super(SelectableLabel, self).on_touch_down(touch): if super(SelectableLabel, self).on_touch_down(touch):
return True return True
if self.collide_point(*touch.pos) and self.selectable: if self.collide_point(*touch.pos) and self.selectable:
return self.parent.select_with_touch(self.index, touch) return self.parent.select_with_touch(self.index, touch)
def apply_selection(self, rv, index, is_selected): def apply_selection(self, rv, index, is_selected):
''' Respond to the selection of items in the view. ''' """Respond to the selection of items in the view."""
self.selected = is_selected self.selected = is_selected
if is_selected: if is_selected:
print("selection changed to {0}".format(rv.data[index])) print "selection changed to {0}".format(rv.data[index])
rv.parent.txt_input.text = rv.parent.txt_input.text.replace(rv.parent.txt_input.text, rv.data[index]['text']) rv.parent.txt_input.text = rv.parent.txt_input.text.replace(
rv.parent.txt_input.text, rv.data[index]['text'])
class RV(RecycleView): class RV(RecycleView):
def __init__(self, **kwargs): """Recycling View."""
def __init__(self, **kwargs): # pylint: disable=useless-super-delegation
"""Recycling Method."""
super(RV, self).__init__(**kwargs) super(RV, self).__init__(**kwargs)
class DropDownWidget(BoxLayout): class DropDownWidget(BoxLayout):
"""Adding Dropdown Widget."""
txt_input = ObjectProperty() txt_input = ObjectProperty()
rv = ObjectProperty() rv = ObjectProperty()
def send(self): def send(self, navApp): # pylint: disable=too-many-statements, inconsistent-return-statements
"""Send message from one address to another.""" """Send message from one address to another."""
# pylint: disable=too-many-locals
fromAddress = str(self.ids.ti.text) fromAddress = str(self.ids.ti.text)
toAddress = str(self.ids.txt_input.text) toAddress = str(self.ids.txt_input.text)
subject = str(self.ids.subject.text) subject = self.ids.subject.text.encode('utf-8').strip()
message = str(self.ids.body.text) message = self.ids.body.text.encode('utf-8').strip()
encoding = 3 encoding = 3
print("message: ", self.ids.body.text) print "message: ", self.ids.body.text
sendMessageToPeople = True sendMessageToPeople = True
if sendMessageToPeople: if sendMessageToPeople:
if toAddress != '' and subject and message: if toAddress != '' and subject and message:
from addresses import decodeAddress from addresses import decodeAddress
status, addressVersionNumber, streamNumber, ripe = decodeAddress( status, addressVersionNumber, streamNumber, ripe = \
toAddress) decodeAddress(toAddress)
if status == 'success': if status == 'success':
from addresses import * if state.detailPageType == 'draft' and state.send_draft_mail:
toAddress = addBMIfNotPresent(toAddress) sqlExecute(
statusIconColor = 'red' "UPDATE sent SET toaddress = '{0}' \
if addressVersionNumber > 4 or addressVersionNumber <= 1: , fromaddress ='{1}' , subject = '{2}'\
print("addressVersionNumber > 4 or addressVersionNumber <= 1") , message = '{3}', folder = 'sent'\
if streamNumber > 1 or streamNumber == 0: WHERE lastactiontime = '{4}';".format(
print("streamNumber > 1 or streamNumber == 0") toAddress,
if statusIconColor == 'red': fromAddress,
print("shared.statusIconColor == 'red'") subject,
stealthLevel = BMConfigParser().safeGetInt( message,
'bitmessagesettings', 'ackstealthlevel') state.send_draft_mail))
from helper_ackPayload import genAckPayload self.parent.parent.screens[15].clear_widgets()
ackdata = genAckPayload(streamNumber, stealthLevel) self.parent.parent.screens[15].add_widget(Draft())
t = () state.detailPageType = ''
sqlExecute( state.send_draft_mail = None
'''INSERT INTO sent VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)''', else:
'', from addresses import addBMIfNotPresent
toAddress, toAddress = addBMIfNotPresent(toAddress)
ripe, statusIconColor = 'red'
fromAddress, if addressVersionNumber > 4 or addressVersionNumber <= 1:
subject, print "addressVersionNumber > 4 \
message, or addressVersionNumber <= 1"
ackdata, if streamNumber > 1 or streamNumber == 0:
int(time.time()), print "streamNumber > 1 or streamNumber == 0"
int(time.time()), if statusIconColor == 'red':
0, print "shared.statusIconColor == 'red'"
'msgqueued', stealthLevel = BMConfigParser().safeGetInt(
0, 'bitmessagesettings', 'ackstealthlevel')
'sent', from helper_ackPayload import genAckPayload
encoding, ackdata = genAckPayload(streamNumber, stealthLevel)
BMConfigParser().getint('bitmessagesettings', 'ttl')) t = ()
sqlExecute(
'''INSERT INTO sent VALUES
(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)''',
'',
toAddress,
ripe,
fromAddress,
subject,
message,
ackdata,
int(time.time()),
int(time.time()),
0,
'msgqueued',
0,
'sent',
encoding,
BMConfigParser().getint(
'bitmessagesettings', 'ttl'))
state.check_sent_acc = fromAddress state.check_sent_acc = fromAddress
state.msg_counter_objs = self.parent.parent.parent.parent.parent.parent.children[0].children[2].children[0].ids state.msg_counter_objs = self.parent.parent.parent.parent\
# state.msg_counter_objs.send_cnt.badge_text = str(int(state.sent_count) + 1) .parent.parent.children[0].children[2].children[0].ids
# state.sent_count = str(int(state.sent_count) + 1)
self.parent.parent.screens[3].clear_widgets() self.parent.parent.screens[3].clear_widgets()
self.parent.parent.screens[3].add_widget(Sent()) self.parent.parent.screens[3].add_widget(Sent())
self.parent.parent.screens[16].clear_widgets()
self.parent.parent.screens[16].add_widget(Allmails())
toLabel = '' toLabel = ''
queues.workerQueue.put(('sendmessage', toAddress))
print("sqlExecute successfully #######################")
self.ids.body.text = ''
self.ids.ti.text = ''
self.ids.subject.text = ''
self.ids.txt_input.text = ''
self.parent.parent.current = 'sent'
self.ids.btn.text = 'select'
self.ids.ti.text = ''
self.parent.parent.parent.parent.parent.ids.serch_btn.opacity = 1
self.parent.parent.parent.parent.parent.ids.serch_btn.disabled = False
queues.workerQueue.put(('sendmessage', toAddress))
print "sqlExecute successfully #######################"
self.parent.parent.current = 'inbox'
state.in_composer = True
navApp.back_press()
toast('send')
return None return None
else: else:
msg = 'Enter a valid recipients address' msg = 'Enter a valid recipients address'
@ -412,70 +547,113 @@ class DropDownWidget(BoxLayout):
msg = 'Please fill the form' msg = 'Please fill the form'
self.address_error_message(msg) self.address_error_message(msg)
# pylint: disable=attribute-defined-outside-init
def address_error_message(self, msg): def address_error_message(self, msg):
self.box = FloatLayout() """Show Error Message."""
self.lab = (Label(text=msg, font_size=25, msg_dialog = MDDialog(
size_hint=(None, None), pos_hint={'x': .25, 'y': .6})) text=msg,
self.box.add_widget(self.lab) title='', size_hint=(.8, .25), text_button_ok='Ok',
self.but = (Button(text="dismiss", size_hint=(None, None), events_callback=self.callback_for_menu_items)
width=200, height=50, pos_hint={'x': .3, 'y': 0})) msg_dialog.open()
self.box.add_widget(self.but)
self.main_pop = Popup(title="Error", content=self.box, @staticmethod
size_hint=(None, None), size=(550, 400), auto_dismiss=False, title_size=30) def callback_for_menu_items(text_item):
self.but.bind(on_press=self.main_pop.dismiss) """Method is used for getting the callback of alert box"""
# self.main_pop.background = './images/popup.jpeg' toast(text_item)
self.main_pop.open()
def reset_composer(self):
"""Method will reset composer."""
self.ids.ti.text = ''
self.ids.btn.text = 'Select'
self.ids.txt_input.text = ''
self.ids.subject.text = ''
self.ids.body.text = ''
def auto_fill_fromaddr(self):
"""Mehtod used to fill the text automatically From Address."""
self.ids.ti.text = self.ids.btn.text
self.ids.ti.focus = True
class MyTextInput(TextInput): class MyTextInput(TextInput):
"""Takes the text input in the field."""
txt_input = ObjectProperty() txt_input = ObjectProperty()
flt_list = ObjectProperty() flt_list = ObjectProperty()
word_list = ListProperty() word_list = ListProperty()
# this is the variable storing the number to which the look-up will start
starting_no = NumericProperty(3) starting_no = NumericProperty(3)
suggestion_text = '' suggestion_text = ''
def __init__(self, **kwargs): def __init__(self, **kwargs): # pylint: disable=useless-super-delegation
"""Getting Text Input."""
super(MyTextInput, self).__init__(**kwargs) super(MyTextInput, self).__init__(**kwargs)
def on_text(self, instance, value): def on_text(self, instance, value):
# find all the occurrence of the word """Find all the occurrence of the word."""
self.parent.parent.parent.parent.ids.rv.data = [] self.parent.parent.parent.parent.ids.rv.data = []
matches = [self.word_list[i] for i in range(len(self.word_list)) if self.word_list[i][:self.starting_no] == value[:self.starting_no]] matches = [self.word_list[i] for i in range(
# display the data in the recycleview len(self.word_list)) if self.word_list[
i][:self.starting_no] == value[:self.starting_no]]
display_data = [] display_data = []
for i in matches: for i in matches:
display_data.append({'text': i}) display_data.append({'text': i})
self.parent.parent.parent.parent.ids.rv.data = display_data self.parent.parent.parent.parent.ids.rv.data = display_data
# ensure the size is okay
if len(matches) <= 10: if len(matches) <= 10:
self.parent.height = (250 + (len(matches) * 20)) self.parent.height = (250 + (len(matches) * 20))
else: else:
self.parent.height = 400 self.parent.height = 400
def keyboard_on_key_down(self, window, keycode, text, modifiers): def keyboard_on_key_down(self, window, keycode, text, modifiers):
"""Key Down."""
if self.suggestion_text and keycode[1] == 'tab': if self.suggestion_text and keycode[1] == 'tab':
self.insert_text(self.suggestion_text + ' ') self.insert_text(self.suggestion_text + ' ')
return True return True
return super(MyTextInput, self).keyboard_on_key_down(window, keycode, text, modifiers) return super(MyTextInput, self).keyboard_on_key_down(
window, keycode, text, modifiers)
class Payment(Screen): class Payment(Screen):
pass """Payment Method."""
def get_available_credits(self, instance): # pylint: disable=no-self-use
"""Method helps to get the available credits"""
state.availabe_credit = instance.parent.children[1].text
existing_credits = state.kivyapp.root.ids.sc18.ids.ml.children[0].children[0].children[0].children[0].text
if len(existing_credits.split(' ')) > 1:
toast('We already have added free coins for the subscription to your account!')
else:
toast('Coins added to your account!')
state.kivyapp.root.ids.sc18.ids.ml.children[0].children[0].children[
0].children[0].text = '{0}'.format(state.availabe_credit)
class Credits(Screen):
"""Credits Method"""
available_credits = StringProperty(
'{0}'.format('0'))
class Login(Screen): class Login(Screen):
"""Login Screeen."""
pass pass
class NetworkStat(Screen): class NetworkStat(Screen):
text_variable_1 = StringProperty('{0}::{1}'.format('Total Connections', '0')) """Method used to show network stat."""
text_variable_2 = StringProperty('Processed {0} per-to-per messages'.format('0'))
text_variable_3 = StringProperty('Processed {0} brodcast messages'.format('0')) text_variable_1 = StringProperty(
'{0}::{1}'.format('Total Connections', '0'))
text_variable_2 = StringProperty(
'Processed {0} per-to-per messages'.format('0'))
text_variable_3 = StringProperty(
'Processed {0} brodcast messages'.format('0'))
text_variable_4 = StringProperty('Processed {0} public keys'.format('0')) text_variable_4 = StringProperty('Processed {0} public keys'.format('0'))
text_variable_5 = StringProperty('Processed {0} object to be synced'.format('0')) text_variable_5 = StringProperty(
'Processed {0} object to be synced'.format('0'))
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
"""Init method for network stat."""
super(NetworkStat, self).__init__(*args, **kwargs) super(NetworkStat, self).__init__(*args, **kwargs)
Clock.schedule_interval(self.init_ui, 1) Clock.schedule_interval(self.init_ui, 1)
@ -484,58 +662,67 @@ class NetworkStat(Screen):
import network.stats import network.stats
import shared import shared
from network import objectracker from network import objectracker
self.text_variable_1 = '{0} :: {1}'.format('Total Connections', str(len(network.stats.connectedHostsList()))) self.text_variable_1 = '{0} :: {1}'.format(
self.text_variable_2 = 'Processed {0} per-to-per messages'.format(str(shared.numberOfMessagesProcessed)) 'Total Connections', str(len(network.stats.connectedHostsList())))
self.text_variable_3 = 'Processed {0} brodcast messages'.format(str(shared.numberOfBroadcastsProcessed)) self.text_variable_2 = 'Processed {0} per-to-per messages'.format(
self.text_variable_4 = 'Processed {0} public keys'.format(str(shared.numberOfPubkeysProcessed)) str(shared.numberOfMessagesProcessed))
self.text_variable_5 = '{0} object to be synced'.format(len(objectracker.missingObjects)) self.text_variable_3 = 'Processed {0} brodcast messages'.format(
str(shared.numberOfBroadcastsProcessed))
self.text_variable_4 = 'Processed {0} public keys'.format(
str(shared.numberOfPubkeysProcessed))
self.text_variable_5 = '{0} object to be synced'.format(
len(objectracker.missingObjects))
class ContentNavigationDrawer(Navigatorss): class ContentNavigationDrawer(Navigatorss):
"""Navigate Content Drawer."""
pass pass
class Random(Screen): class Random(Screen):
"""Generates Random Address."""
is_active = BooleanProperty(False) is_active = BooleanProperty(False)
checked = StringProperty("") checked = StringProperty("")
# self.manager.parent.ids.create.children[0].source = 'images/plus-4-xxl.png'
def generateaddress(self): def generateaddress(self, navApp):
import queues """Method for Address Generator."""
# queues.apiAddressGeneratorReturnQueue.queue.clear()
streamNumberForAddress = 1 streamNumberForAddress = 1
label = self.ids.label.text label = self.ids.label.text
eighteenByteRipe = False eighteenByteRipe = False
nonceTrialsPerByte = 1000 nonceTrialsPerByte = 1000
payloadLengthExtraBytes = 1000 payloadLengthExtraBytes = 1000
if self.ids.label.text: if str(self.ids.label.text).strip():
queues.addressGeneratorQueue.put(( queues.addressGeneratorQueue.put((
'createRandomAddress', 'createRandomAddress',
4, streamNumberForAddress, 4, streamNumberForAddress,
label, 1, "", eighteenByteRipe, label, 1, "", eighteenByteRipe,
nonceTrialsPerByte, nonceTrialsPerByte,
payloadLengthExtraBytes) payloadLengthExtraBytes))
)
# self.manager.current = 'add_sucess'
self.manager.current = 'myaddress' self.manager.current = 'myaddress'
self.ids.label.text = '' self.ids.label.text = ''
self.parent.parent.parent.parent.ids.toolbar.opacity = 1 self.parent.parent.parent.parent.ids.toolbar.opacity = 1
self.parent.parent.parent.parent.ids.toolbar.disabled = False self.parent.parent.parent.parent.ids.toolbar.disabled = False
# state.myAddressObj = self.parent.parent.parent.parent.ids.sc10
self.parent.parent.parent.parent.ids.sc10.clear_widgets() self.parent.parent.parent.parent.ids.sc10.clear_widgets()
self.parent.parent.parent.parent.ids.sc10.add_widget(MyAddress()) self.parent.parent.parent.parent.ids.sc10.add_widget(MyAddress())
navApp.add_search_bar()
toast('New address created')
class AddressSuccessful(Screen): class AddressSuccessful(Screen):
"""Getting Address Detail."""
pass pass
class Sent(Screen): class Sent(Screen):
"""Sent Screen uses screen to show widgets of screens.""" """Sent Screen uses screen to show widgets of screens."""
data = ListProperty() data = ListProperty()
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
"""Association with the screen."""
super(Sent, self).__init__(*args, **kwargs) super(Sent, self).__init__(*args, **kwargs)
if state.association == '': if state.association == '':
if BMConfigParser().addresses(): if BMConfigParser().addresses():
@ -545,7 +732,7 @@ class Sent(Screen):
def init_ui(self, dt=0): def init_ui(self, dt=0):
"""Clock Schdule for method sent accounts.""" """Clock Schdule for method sent accounts."""
self.sentaccounts() self.sentaccounts()
print(dt) print dt
def sentaccounts(self): def sentaccounts(self):
"""Load sent accounts.""" """Load sent accounts."""
@ -560,98 +747,133 @@ class Sent(Screen):
xAddress = 'fromaddress' xAddress = 'fromaddress'
queryreturn = kivy_helper_search.search_sql( queryreturn = kivy_helper_search.search_sql(
xAddress, account, "sent", where, what, False) xAddress, account, "sent", where, what, False)
if state.msg_counter_objs and state.association == state.check_sent_acc: if state.msg_counter_objs and state.association == \
state.check_sent_acc:
state.msg_counter_objs.send_cnt.badge_text = str(len(queryreturn)) state.msg_counter_objs.send_cnt.badge_text = str(len(queryreturn))
state.sent_count = str(int(state.sent_count) + 1) state.sent_count = str(int(state.sent_count) + 1)
state.all_count = str(int(state.all_count) + 1)
state.msg_counter_objs.allmail_cnt.badge_text = state.all_count
state.check_sent_acc = None state.check_sent_acc = None
if queryreturn: if queryreturn:
src_mng_obj = state.kivyapp.root.children[2].children[0].ids
src_mng_obj.send_cnt.badge_text = str(len(queryreturn))
state.sent_count = str(len(queryreturn))
for mail in queryreturn: for mail in queryreturn:
third_text = mail[3].replace('\n', ' ') self.data.append({
self.data.append({'text': mail[1].strip(), 'secondary_text': mail[2][:10] + '...........' if len(mail[2]) > 10 else mail[2] + '\n' + " " + (third_text[:25] + '...!') if len(third_text) > 25 else third_text, 'lastactiontime': mail[6]}) 'text': mail[1].strip(),
'secondary_text': mail[2][:50] + '........' if len(
mail[2]) >= 50 else (
mail[2] + ',' + mail[3].replace('\n', ''))[0:50] + '........',
'lastactiontime': mail[6]})
for item in self.data: for item in self.data:
meny = ThreeLineAvatarIconListItem(text=item['text'], secondary_text=item['secondary_text'], theme_text_color= 'Custom', text_color=NavigateApp().theme_cls.primary_color) meny = TwoLineAvatarIconListItem(
meny.add_widget(AvatarSampleWidget(source='./images/text_images/{}.png'.format(item['secondary_text'][0].upper() if (item['secondary_text'][0].upper() >= 'A' and item['secondary_text'][0].upper() <= 'Z') else '!'))) text=item['text'],
meny.bind(on_press = partial(self.sent_detail, item['lastactiontime'])) secondary_text=item['secondary_text'],
theme_text_color='Custom',
text_color=NavigateApp().theme_cls.primary_color)
meny.add_widget(AvatarSampleWidget(
source='./images/text_images/{}.png'.format(
avatarImageFirstLetter(item['secondary_text'].strip()))))
meny.bind(on_press=partial(
self.sent_detail, item['lastactiontime']))
carousel = Carousel(direction='right') carousel = Carousel(direction='right')
if platform == 'android': carousel.height = meny.height
carousel.height = 150
elif platform == 'linux':
carousel.height = meny.height - 10
carousel.size_hint_y = None carousel.size_hint_y = None
carousel.ignore_perpendicular_swipes = True carousel.ignore_perpendicular_swipes = True
carousel.data_index = 0 carousel.data_index = 0
carousel.min_move = 0.2 carousel.min_move = 0.2
del_btn = Button(text='Delete') del_btn = Button(text='Delete')
del_btn.background_normal = '' del_btn.background_normal = ''
del_btn.background_color = (1.0, 0.0, 0.0, 1.0) del_btn.background_color = (1, 0, 0, 1)
del_btn.bind(on_press=partial(self.delete, item['lastactiontime'])) del_btn.bind(on_press=partial(
self.delete, item['lastactiontime']))
carousel.add_widget(del_btn) carousel.add_widget(del_btn)
carousel.add_widget(meny) carousel.add_widget(meny)
ach_btn = Button(text='Achieve') ach_btn = Button(text='Achieve')
ach_btn.background_color = (0,1,0,1) ach_btn.background_color = (0, 1, 0, 1)
ach_btn.bind(on_press=partial(self.archive, item['lastactiontime'])) ach_btn.bind(on_press=partial(
self.archive, item['lastactiontime']))
carousel.add_widget(ach_btn) carousel.add_widget(ach_btn)
carousel.index=1 carousel.index = 1
self.ids.ml.add_widget(carousel) self.ids.ml.add_widget(carousel)
else: else:
content = MDLabel(font_style='Body1', content = MDLabel(
theme_text_color='Primary', font_style='Body1',
text="yet no message for this account!!!!!!!!!!!!!", theme_text_color='Primary',
halign='center', text="No message found!" if state.searcing_text
bold=True, else "yet no message for this account!!!!!!!!!!!!!",
size_hint_y=None, halign='center',
valign='top') bold=True,
size_hint_y=None,
valign='top')
self.ids.ml.add_widget(content) self.ids.ml.add_widget(content)
def sent_detail(self, lastsenttime, *args): def sent_detail(self, lastsenttime, *args):
"""Load sent mail details""" """Load sent mail details."""
remove_search_bar(self)
state.detailPageType = 'sent' state.detailPageType = 'sent'
state.sentMailTime = lastsenttime state.sentMailTime = lastsenttime
if self.manager: if self.manager:
src_mng_obj = self.manager src_mng_obj = self.manager
else: else:
src_mng_obj = self.parent.parent src_mng_obj = self.parent.parent
hide_search_btn(src_mng_obj)
src_mng_obj.screens[13].clear_widgets() src_mng_obj.screens[13].clear_widgets()
src_mng_obj.screens[13].add_widget(MailDetail()) src_mng_obj.screens[13].add_widget(MailDetail())
src_mng_obj.current = 'mailDetail' src_mng_obj.current = 'mailDetail'
def delete(self, data_index, instance, *args): def delete(self, data_index, instance, *args):
"""delete sent mail from sent mail listing""" """Delete sent mail from sent mail listing."""
try: try:
msg_count_objs = self.parent.parent.parent.parent.children[2].children[0].ids msg_count_objs = self.parent.parent.parent.parent.children[
except Exception as e: 2].children[0].ids
msg_count_objs = self.parent.parent.parent.parent.parent.children[2].children[0].ids except Exception:
msg_count_objs = self.parent.parent.parent.parent.parent.children[
2].children[0].ids
if int(state.sent_count) > 0: if int(state.sent_count) > 0:
msg_count_objs.send_cnt.badge_text = str(int(state.sent_count) - 1) msg_count_objs.send_cnt.badge_text = str(
msg_count_objs.trash_cnt.badge_text = str(int(state.trash_count) + 1) int(state.sent_count) - 1)
msg_count_objs.trash_cnt.badge_text = str(
int(state.trash_count) + 1)
msg_count_objs.allmail_cnt.badge_text = str(
int(state.all_count) - 1)
state.sent_count = str(int(state.sent_count) - 1) state.sent_count = str(int(state.sent_count) - 1)
state.trash_count = str(int(state.trash_count) + 1) state.trash_count = str(int(state.trash_count) + 1)
state.all_count = str(int(state.all_count) - 1)
sqlExecute("UPDATE sent SET folder = 'trash' WHERE lastactiontime = {};".format(data_index)) sqlExecute(
"UPDATE sent SET folder = 'trash' \
WHERE lastactiontime = {};".format(data_index))
self.ids.ml.remove_widget(instance.parent.parent) self.ids.ml.remove_widget(instance.parent.parent)
toast('Deleted')
self.update_trash() self.update_trash()
def archive(self, data_index, instance, *args): def archive(self, data_index, instance, *args):
"""archive sent mail from sent mail listing""" """Archive sent mail from sent mail listing."""
sqlExecute("UPDATE sent SET folder = 'trash' WHERE lastactiontime = {};".format(data_index)) sqlExecute(
"UPDATE sent SET folder = 'trash' \
WHERE lastactiontime = {};".format(data_index))
self.ids.ml.remove_widget(instance.parent.parent) self.ids.ml.remove_widget(instance.parent.parent)
self.update_trash() self.update_trash()
def update_trash(self): def update_trash(self):
"""Update trash screen mails which is deleted from inbox""" """Update trash screen mails which is deleted from inbox."""
try: try:
self.parent.screens[4].clear_widgets() self.parent.screens[4].clear_widgets()
self.parent.screens[4].add_widget(Trash()) self.parent.screens[4].add_widget(Trash())
except Exception as e: self.parent.screens[16].clear_widgets()
self.parent.screens[16].add_widget(Allmails())
except Exception:
self.parent.parent.screens[4].clear_widgets() self.parent.parent.screens[4].clear_widgets()
self.parent.parent.screens[4].add_widget(Trash()) self.parent.parent.screens[4].add_widget(Trash())
self.parent.parent.screens[16].clear_widgets()
self.parent.parent.screens[16].add_widget(Allmails())
class Trash(Screen): class Trash(Screen):
"""Trash Screen uses screen to show widgets of screens.""" """Trash Screen uses screen to show widgets of screens."""
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
"""Trash method, delete sent message and add in Trash."""
super(Trash, self).__init__(*args, **kwargs) super(Trash, self).__init__(*args, **kwargs)
Clock.schedule_once(self.init_ui, 0) Clock.schedule_once(self.init_ui, 0)
@ -661,44 +883,99 @@ class Trash(Screen):
if BMConfigParser().addresses(): if BMConfigParser().addresses():
state.association = BMConfigParser().addresses()[0] state.association = BMConfigParser().addresses()[0]
inbox = sqlQuery("SELECT toaddress, fromaddress, subject, message from inbox WHERE folder = 'trash' and fromaddress = '{}';".format(state.association)) inbox = sqlQuery(
sent = sqlQuery("SELECT toaddress, fromaddress, subject, message from sent WHERE folder = 'trash' and fromaddress = '{}';".format(state.association)) "SELECT toaddress, fromaddress, subject, message, folder, received from \
inbox WHERE folder = 'trash' and toaddress = '{}';".format(
state.association))
sent = sqlQuery(
"SELECT toaddress, fromaddress, subject, message, folder, lastactiontime from \
sent WHERE folder = 'trash' and fromaddress = '{}';".format(
state.association))
trash_data = inbox + sent trash_data = inbox + sent
for item in trash_data: if trash_data:
meny = ThreeLineAvatarIconListItem(text=item[1], secondary_text=item[2], theme_text_color= 'Custom',text_color=NavigateApp().theme_cls.primary_color) src_mng_obj = state.kivyapp.root.children[2].children[0].ids
meny.add_widget(AvatarSampleWidget(source='./images/text_images/{}.png'.format(item[2][0].upper() if (item[2][0].upper() >= 'A' and item[2][0].upper() <= 'Z') else '!'))) src_mng_obj.trash_cnt.badge_text = str(len(trash_data))
self.ids.ml.add_widget(meny) state.trash_count = str(len(trash_data))
for item in trash_data:
meny = TwoLineAvatarIconListItem(
text=item[1],
secondary_text=item[2][:50] + '........' if len(
item[2]) >= 50 else (
item[2] + ',' + item[3].replace('\n', ''))[0:50] + '........',
theme_text_color='Custom',
text_color=NavigateApp().theme_cls.primary_color)
img_latter = './images/text_images/{}.png'.format(
item[2][0].upper() if (item[2][0].upper() >= 'A' and item[
2][0].upper() <= 'Z') else '!')
meny.add_widget(AvatarSampleWidget(source=img_latter))
carousel = Carousel(direction='right')
carousel.height = meny.height
carousel.size_hint_y = None
carousel.ignore_perpendicular_swipes = True
carousel.data_index = 0
carousel.min_move = 0.2
del_btn = Button(text='Delete')
del_btn.background_normal = ''
del_btn.background_color = (1, 0, 0, 1)
del_btn.bind(on_press=partial(
self.delete_permanently, item[5]))
carousel.add_widget(del_btn)
carousel.add_widget(meny)
carousel.index = 1
self.ids.ml.add_widget(carousel)
else:
content = MDLabel(
font_style='Body1',
theme_text_color='Primary',
text="yet no trashed message for this account!!!!!!!!!!!!!",
halign='center',
bold=True,
size_hint_y=None,
valign='top')
self.ids.ml.add_widget(content)
def delete_permanently(self, data_index, instance, *args):
"""Deleting trash mail permanently."""
pass
class Page(Screen): class Page(Screen):
"""Page Screen show widgets of page."""
pass pass
class Create(Screen): class Create(Screen):
"""Creates the screen widgets."""
def __init__(self, **kwargs): def __init__(self, **kwargs):
"""Getting Labels and address from addressbook."""
super(Create, self).__init__(**kwargs) super(Create, self).__init__(**kwargs)
widget_1 = DropDownWidget() widget_1 = DropDownWidget()
from helper_sql import * widget_1.ids.txt_input.word_list = [
widget_1.ids.txt_input.word_list = [addr[1] for addr in sqlQuery("SELECT label, address from addressbook")] addr[1] for addr in sqlQuery(
"SELECT label, address from addressbook")]
widget_1.ids.txt_input.starting_no = 2 widget_1.ids.txt_input.starting_no = 2
self.add_widget(widget_1) self.add_widget(widget_1)
class AddressSuccessful(Screen):
pass
class Setting(Screen): class Setting(Screen):
"""Setting the Screen components."""
pass pass
class NavigateApp(App): class NavigateApp(App): # pylint: disable=too-many-public-methods
"""Navigation Layout of class."""
theme_cls = ThemeManager() theme_cls = ThemeManager()
previous_date = ObjectProperty() previous_date = ObjectProperty()
obj_1 = ObjectProperty() obj_1 = ObjectProperty()
variable_1 = ListProperty(BMConfigParser().addresses()) variable_1 = ListProperty(BMConfigParser().addresses())
nav_drawer = ObjectProperty() nav_drawer = ObjectProperty()
state.screen_density = Window.size state.screen_density = Window.size
window_size = state.screen_density
title = "PyBitmessage" title = "PyBitmessage"
imgstatus = False imgstatus = False
count = 0 count = 0
@ -720,7 +997,7 @@ class NavigateApp(App):
] ]
def build(self): def build(self):
import os """Method builds the widget."""
main_widget = Builder.load_file( main_widget = Builder.load_file(
os.path.join(os.path.dirname(__file__), 'main.kv')) os.path.join(os.path.dirname(__file__), 'main.kv'))
self.nav_drawer = Navigatorss() self.nav_drawer = Navigatorss()
@ -732,236 +1009,307 @@ class NavigateApp(App):
return main_widget return main_widget
def run(self): def run(self):
"""Running the widgets."""
kivyuisignaler.release() kivyuisignaler.release()
super(NavigateApp, self).run() super(NavigateApp, self).run()
def show_address_success(self): # pylint: disable=inconsistent-return-statements
content = MDLabel(font_style='Body1',
theme_text_color='Secondary',
text="Successfully Saved your contact address. "
"That's pretty awesome right!",
size_hint_y=None,
valign='top')
content.bind(texture_size=content.setter('size'))
self.dialog.open()
@staticmethod @staticmethod
def showmeaddresses(name="text"): def showmeaddresses(name="text"):
"""Show the addresses in spinner to make as dropdown.""" """Show the addresses in spinner to make as dropdown."""
if name == "text": if name == "text":
if bmconfigparserigParser().addresses(): if BMConfigParser().addresses():
return BMConfigParser().addresses()[0][:16] + '..' return BMConfigParser().addresses()[0][:16] + '..'
else: return "textdemo"
return "textdemo"
elif name == "values": elif name == "values":
if BMConfigParser().addresses(): if BMConfigParser().addresses():
return [address[:16] + '..' for address in BMConfigParser().addresses()] return [address[:16] + '..'
else: for address in BMConfigParser().addresses()]
return "valuesdemo" return "valuesdemo"
def getCurrentAccountData(self, text): def getCurrentAccountData(self, text):
"""Get Current Address Account Data.""" """Get Current Address Account Data."""
address_label = self.current_address_label(BMConfigParser().get(text, 'label')) self.set_identicon(text)
address_label = self.current_address_label(
BMConfigParser().get(text, 'label'), text)
self.root_window.children[1].ids.toolbar.title = address_label self.root_window.children[1].ids.toolbar.title = address_label
state.association = text state.association = text
self.root.ids.sc1.clear_widgets() self.root.ids.sc1.clear_widgets()
self.root.ids.sc4.clear_widgets()
self.root.ids.sc5.clear_widgets()
self.root.ids.sc16.clear_widgets()
self.root.ids.sc1.add_widget(Inbox()) self.root.ids.sc1.add_widget(Inbox())
self.root.ids.sc4.add_widget(Sent()) # self.root.ids.sc4.clear_widgets()
self.root.ids.sc5.add_widget(Trash()) # self.root.ids.sc5.clear_widgets()
self.root.ids.sc16.add_widget(Draft()) # self.root.ids.sc16.clear_widgets()
# self.root.ids.sc17.clear_widgets()
# self.root.ids.sc4.add_widget(Sent())
# self.root.ids.sc5.add_widget(Trash())
# self.root.ids.sc16.add_widget(Draft())
# self.root.ids.sc17.add_widget(Allmails())
self.root.ids.scr_mngr.current = 'inbox' self.root.ids.scr_mngr.current = 'inbox'
msg_counter_objs = self.root_window.children[1].children[2].children[0].ids msg_counter_objs = \
state.sent_count = str(sqlQuery("SELECT COUNT(*) FROM sent WHERE fromaddress = '{}' and folder = 'sent' ;".format(state.association))[0][0]) self.root_window.children[1].children[2].children[0].ids
state.inbox_count = str(sqlQuery("SELECT COUNT(*) FROM inbox WHERE fromaddress = '{}' and folder = 'inbox' ;".format(state.association))[0][0]) state.sent_count = str(
state.trash_count = str(sqlQuery("SELECT (SELECT count(*) FROM sent where fromaddress = '{0}' and folder = 'trash' )+(SELECT count(*) FROM inbox where fromaddress = '{0}' and folder = 'trash') AS SumCount".format(state.association))[0][0]) sqlQuery(
state.draft_count = str(sqlQuery("SELECT COUNT(*) FROM sent WHERE fromaddress = '{}' and folder = 'draft' ;".format(state.association))[0][0]) "SELECT COUNT(*) FROM sent WHERE fromaddress = '{}' and \
folder = 'sent' ;".format(state.association))[0][0])
state.inbox_count = str(
sqlQuery(
"SELECT COUNT(*) FROM inbox WHERE toaddress = '{}' and \
folder = 'inbox' ;".format(state.association))[0][0])
state.trash_count = str(sqlQuery("SELECT (SELECT count(*) FROM sent \
where fromaddress = '{0}' and folder = 'trash' ) \
+(SELECT count(*) FROM inbox where toaddress = '{0}' and \
folder = 'trash') AS SumCount".format(state.association))[0][0])
state.draft_count = str(
sqlQuery(
"SELECT COUNT(*) FROM sent WHERE fromaddress = '{}' and \
folder = 'draft' ;".format(state.association))[0][0])
state.all_count = str(int(state.sent_count) + int(state.inbox_count))
if msg_counter_objs: if msg_counter_objs:
msg_counter_objs.send_cnt.badge_text = state.sent_count msg_counter_objs.send_cnt.badge_text = state.sent_count
msg_counter_objs.inbox_cnt.badge_text = state.inbox_count msg_counter_objs.inbox_cnt.badge_text = state.inbox_count
msg_counter_objs.trash_cnt.badge_text = state.trash_count msg_counter_objs.trash_cnt.badge_text = state.trash_count
msg_counter_objs.draft_cnt.badge_text = state.draft_count msg_counter_objs.draft_cnt.badge_text = state.draft_count
msg_counter_objs.allmail_cnt.badge_text = state.all_count
def getInboxMessageDetail(self, instance):
"""It will get message detail after make selected message description."""
try:
self.root.ids._mngr.current = 'page'
except AttributeError:
self.parent.manager.current = 'page'
print('Message Clicked {}'.format(instance))
@staticmethod @staticmethod
def getCurrentAccount(): def getCurrentAccount():
"""It uses to get current account label.""" """It uses to get current account label."""
if state.association: if state.association:
return state.association return state.association
else: return "Bitmessage Login"
return "Bitmessage Login"
def addingtoaddressbook(self): @staticmethod
def addingtoaddressbook():
"""Adding to address Book."""
p = GrashofPopup() p = GrashofPopup()
p.open() p.open()
def getDefaultAccData(self): def getDefaultAccData(self):
"""Getting Default Account Data."""
if BMConfigParser().addresses(): if BMConfigParser().addresses():
img = identiconGeneration.generate(BMConfigParser().addresses()[0])
self.createFolder('./images/default_identicon/')
img.texture.save('./images/default_identicon/{}.png'.format(BMConfigParser().addresses()[0]))
return BMConfigParser().addresses()[0] return BMConfigParser().addresses()[0]
return 'Select Address' return 'Select Address'
def addressexist(self): @staticmethod
def createFolder(directory):
"""This method is used to create the directory when app starts"""
try:
if not os.path.exists(directory):
os.makedirs(directory)
except OSError:
print 'Error: Creating directory. ' + directory
@staticmethod
def get_default_image():
"""Getting default image on address"""
if BMConfigParser().addresses():
return './images/default_identicon/{}.png'.format(BMConfigParser().addresses()[0])
return ''
@staticmethod
def addressexist():
"""Checking address existence."""
if BMConfigParser().addresses(): if BMConfigParser().addresses():
return True return True
return False return False
def on_key(self, window, key, *args): def on_key(self, window, key, *args):
"""This method is used for going on previous screen""" """Method is used for going on previous screen."""
if key == 27: # the esc key if key == 27:
if self.root.ids.scr_mngr.current == "mailDetail": if self.root.ids.scr_mngr.current == "mailDetail":
self.root.ids.scr_mngr.current = 'sent' if state.detailPageType == 'sent' else 'inbox' self.root.ids.scr_mngr.current = 'sent'\
show_search_btn(self) if state.detailPageType == 'sent' else 'inbox' \
# this is for direction of the screen comesup if state.detailPageType == 'inbox' else 'draft'
# if state.detailPageType in ['sent', 'inbox']:
# self.add_search_bar()
self.back_press()
elif self.root.ids.scr_mngr.current == "create": elif self.root.ids.scr_mngr.current == "create":
composer_objs = self.root composer_objs = self.root
from_addr = str(self.root.children[1].children[0].children[0].children[0].children[0].ids.ti.text) from_addr = str(self.root.ids.sc3.children[0].ids.ti.text)
to_addr = str(self.root.children[1].children[0].children[0].children[0].children[0].ids.txt_input.text) to_addr = str(self.root.ids.sc3.children[0].ids.txt_input.text)
if from_addr and to_addr: if from_addr and to_addr and state.detailPageType != 'draft':
Draft().draft_msg(composer_objs) Draft().draft_msg(composer_objs)
self.root.ids.serch_btn.opacity = 1
self.root.ids.serch_btn.disabled = False
self.root.ids.scr_mngr.current = 'inbox' self.root.ids.scr_mngr.current = 'inbox'
self.back_press()
elif self.root.ids.scr_mngr.current == "showqrcode": elif self.root.ids.scr_mngr.current == "showqrcode":
self.root.ids.scr_mngr.current = 'myaddress' self.root.ids.scr_mngr.current = 'myaddress'
elif self.root.ids.scr_mngr.current == "random": elif self.root.ids.scr_mngr.current == "random":
self.root.ids.scr_mngr.current = 'login' self.root.ids.scr_mngr.current = 'login'
else: else:
self.root.ids.scr_mngr.current = 'inbox' self.root.ids.scr_mngr.current = 'inbox'
show_search_btn(self) self.add_search_bar()
self.root.ids.scr_mngr.transition.direction = 'right' self.root.ids.scr_mngr.transition.direction = 'right'
self.root.ids.scr_mngr.transition.bind(on_complete=self.restart) self.root.ids.scr_mngr.transition.bind(on_complete=self.reset)
return True return True
def restart(self, *args): def reset(self, *args):
"""this method is used to set transition direction""" """Method used to set transition direction."""
self.root.ids.scr_mngr.transition.direction = 'left' self.root.ids.scr_mngr.transition.direction = 'left'
self.root.ids.scr_mngr.transition.unbind(on_complete=self.restart) self.root.ids.scr_mngr.transition.unbind(on_complete=self.reset)
def status_dispatching(self, data): @staticmethod
def status_dispatching(data):
"""Method used for status dispatching acknowledgment."""
ackData, message = data ackData, message = data
if state.ackdata == ackData: if state.ackdata == ackData:
state.status.status = message state.status.status = message
def clear_composer(self): def clear_composer(self):
"""if slow down the nwe will make new composer edit screen""" """If slow down the nwe will make new composer edit screen."""
self.root.ids.serch_btn.opacity = 0 self.set_navbar_for_composer()
self.root.ids.serch_btn.disabled = True self.root.ids.search_bar.clear_widgets()
composer_obj = self.root.ids.sc3.children[0].ids composer_obj = self.root.ids.sc3.children[0].ids
composer_obj.ti.text = '' composer_obj.ti.text = ''
composer_obj.btn.text = 'Select' composer_obj.btn.text = 'Select'
composer_obj.txt_input.text = '' composer_obj.txt_input.text = ''
composer_obj.subject.text = '' composer_obj.subject.text = ''
composer_obj.body.text = ''
state.in_composer = True
def on_stop(self): def set_navbar_for_composer(self):
"""On stop methos is used for stoping the runing script""" """This method is used for clearing toolbar data when composer open"""
print("**************************EXITING FROM APPLICATION*****************************") self.root.ids.toolbar.left_action_items = [
['arrow-left', lambda x: self.back_press()]]
self.root.ids.toolbar.right_action_items = [
['send', lambda x: self.root.ids.sc3.children[0].send(self)]]
def back_press(self):
"""Method used for going back from composer to previous page."""
self.root.ids.toolbar.right_action_items = \
[['account-plus', lambda x: self.addingtoaddressbook()]]
self.root.ids.toolbar.left_action_items = \
[['menu', lambda x: self.root.toggle_nav_drawer()]]
self.root.ids.scr_mngr.current = 'inbox' \
if state.in_composer else 'allmails' if state.is_allmail else state.detailPageType
self.root.ids.scr_mngr.transition.direction = 'right'
self.root.ids.scr_mngr.transition.bind(on_complete=self.reset)
if state.is_allmail or state.detailPageType == 'draft':
state.is_allmail = False
else:
self.add_search_bar()
state.detailPageType = ''
state.in_composer = False
@staticmethod
def on_stop():
"""On stop methos is used for stoping the runing script."""
print "*******************EXITING FROM APPLICATION*******************"
import shutdown import shutdown
shutdown.doCleanShutdown() shutdown.doCleanShutdown()
def mail_count(self, text): @staticmethod
if state.association == '': def current_address_label(current_add_label=None, current_addr=None):
if BMConfigParser().addresses(): """Getting current address labels."""
state.association = BMConfigParser().addresses()[0] if BMConfigParser().addresses():
if text == 'Sent': if current_add_label:
state.sent_count = str(sqlQuery("SELECT COUNT(*) FROM {0} WHERE fromaddress = '{1}' and folder = '{0}' ;".format(text.lower(), state.association))[0][0]) first_name = current_add_label
return state.sent_count addr = current_addr
elif text == 'Inbox':
state.inbox_count = str(sqlQuery("SELECT COUNT(*) FROM {0} WHERE fromaddress = '{1}' and folder = '{0}' ;".format(text.lower(), state.association))[0][0])
return state.inbox_count
elif text == 'Trash':
state.trash_count = str(sqlQuery("SELECT (SELECT count(*) FROM sent where fromaddress = '{0}' and folder = 'trash' )+(SELECT count(*) FROM inbox where fromaddress = '{0}' and folder = 'trash') AS SumCount".format(state.association))[0][0])
return state.trash_count
elif text == 'Draft':
state.draft_count = str(sqlQuery("SELECT COUNT(*) FROM sent WHERE fromaddress = '{1}' and folder = '{0}' ;".format(text.lower(), state.association))[0][0])
return state.draft_count
def current_address_label(self, current_address=None):
if BMConfigParser().addresses() or current_address:
if current_address:
first_name = current_address
else: else:
first_name = BMConfigParser().get(BMConfigParser().addresses()[0], 'label') addr = BMConfigParser().addresses()[0]
first_name = BMConfigParser().get(addr, 'label')
f_name = first_name.split() f_name = first_name.split()
return f_name[0][:14]+ '...' if len(f_name[0])>15 else f_name[0] label = f_name[0][:14].capitalize() + '...' if len(f_name[0]) > 15 else f_name[0].capitalize()
address = ' (' + addr + '...)'
return label + address
return '' return ''
def searchQuery(self, instance, text): def searchQuery(self, instance, *args):
'''This method is used for showing searched mails''' """Method used for showing searched mails."""
if self.root.ids.search_input.opacity == 0: state.search_screen = self.root.ids.scr_mngr.current
self.root.ids.search_input.opacity = 1 state.searcing_text = str(instance.text).strip()
self.root.ids.search_input.size_hint = 4,None
# self.root.ids.serch_btn.opacity = 0
# self.root.ids.serch_btn.disabled = True
self.root.ids.search_input.disabled = False
self.root.ids.search_input.focus = True
self.root.ids.toolbar.left_action_items = []
self.root.ids.toolbar.title = ''
self.root.ids.myButton.opacity = 0
self.root.ids.myButton.disabled = True
self.root.ids.reset_navbar.opacity = 1
self.root.ids.reset_navbar.disabled = False
elif str(text):
state.search_screen = self.root.ids.scr_mngr.current
state.searcing_text = str(text).strip()
if state.search_screen == 'inbox':
self.root.ids.sc1.clear_widgets()
self.root.ids.sc1.add_widget(Inbox())
else:
self.root.ids.sc4.clear_widgets()
self.root.ids.sc4.add_widget(Sent())
self.root.ids.scr_mngr.current = state.search_screen
def reset_navdrawer(self, instance):
'''This methos is used for reseting navigation drawer'''
self.root.ids.search_input.text = ''
self.root.ids.search_input.opacity = 0
self.root.ids.search_input.size_hint = 1,None
self.root.ids.search_input.disabled = True
self.root.ids.toolbar.left_action_items = [['menu', lambda x: self.root.toggle_nav_drawer()]]
self.root.ids.toolbar.title = self.current_address_label()
self.root.ids.myButton.opacity = 1
self.root.ids.myButton.disabled = False
self.root.ids.reset_navbar.opacity = 0
self.root.ids.reset_navbar.disabled = True
state.searcing_text = ''
if state.search_screen == 'inbox': if state.search_screen == 'inbox':
self.root.ids.sc1.clear_widgets() self.root.ids.sc1.clear_widgets()
self.root.ids.sc1.add_widget(Inbox()) self.root.ids.sc1.add_widget(Inbox())
elif state.search_screen == 'addressbook':
self.root.ids.sc11.clear_widgets()
self.root.ids.sc11.add_widget(AddressBook())
elif state.search_screen == 'myaddress':
self.root.ids.sc10.clear_widgets()
self.root.ids.sc10.add_widget(MyAddress())
else: else:
self.root.ids.sc4.clear_widgets() self.root.ids.sc4.clear_widgets()
self.root.ids.sc4.add_widget(Sent()) self.root.ids.sc4.add_widget(Sent())
self.root.ids.scr_mngr.current = state.search_screen
def clearSreeen(self, text):
"""Method is used for clear screen"""
if text == 'Sent':
self.root.ids.sc4.clear_widgets()
self.root.ids.sc4.add_widget(Sent())
elif text == 'Draft':
self.root.ids.sc16.clear_widgets()
self.root.ids.sc16.add_widget(Draft())
elif text == 'Trash':
self.root.ids.sc5.clear_widgets()
self.root.ids.sc5.add_widget(Trash())
elif text == 'All Mails':
self.root.ids.sc17.clear_widgets()
self.root.ids.sc17.add_widget(Allmails())
def check_search_screen(self, instance): def check_search_screen(self, instance):
'''This method is used for showing search button only on inbox or sent screen''' """Method show search button only on inbox or sent screen."""
if instance.text == 'Inbox' or instance.text == 'Sent': if instance.text in ['Sent', 'Draft', 'Trash', 'All Mails']:
self.root.ids.serch_btn.opacity = 1 self.clearSreeen(instance.text)
self.root.ids.serch_btn.disabled = False if instance.text in ['Inbox', 'Sent', 'Address Book', 'My Addresses']:
state.searcing_text = '' if not self.root.ids.search_bar.children:
self.root.ids.sc1.clear_widgets() self.root.ids.search_bar.add_widget(
self.root.ids.sc4.clear_widgets() MDIconButton(icon='magnify'))
self.root.ids.sc1.add_widget(Inbox()) text_field = MDTextField(
self.root.ids.sc4.add_widget(Sent()) id='search_field', hint_text='Search')
text_field.bind(text=self.searchQuery)
self.root.ids.search_bar.add_widget(text_field)
self.root.ids.search_bar.children[0].text = ''
else: else:
self.root.ids.serch_btn.opacity = 0 self.root.ids.search_bar.clear_widgets()
self.root.ids.serch_btn.disabled = True state.searcing_text = ''
return return
def add_search_bar(self):
"""Method used for adding search function on screen"""
if not self.root.ids.search_bar.children:
self.root.ids.search_bar.add_widget(MDIconButton(icon='magnify'))
text_field = MDTextField(
id='search_field', hint_text='Search')
text_field.bind(text=self.searchQuery)
self.root.ids.search_bar.add_widget(text_field)
def set_identicon(self, text):
"""This method is use for showing identicon in address spinner"""
img = identiconGeneration.generate(text)
self.root.children[2].children[0].ids.btn.children[1].texture = img.texture
@staticmethod
def address_identicon():
"""Address identicon"""
return './images/drawer_logo1.png'
def set_mail_detail_header(self):
"""Method is used for setting the details of the page"""
toolbar_obj = self.root.ids.toolbar
toolbar_obj.left_action_items = [['arrow-left', lambda x: self.back_press()]]
delete_btn = ['delete-forever', lambda x: self.root.ids.sc14.delete_mail()]
dynamic_list = []
if state.detailPageType == 'inbox':
dynamic_list = [['reply', lambda x: self.root.ids.sc14.inbox_reply()], delete_btn]
elif state.detailPageType == 'sent':
dynamic_list = [delete_btn]
elif state.detailPageType == 'draft':
dynamic_list = [['pencil', lambda x: self.root.ids.sc14.write_msg(self)], delete_btn]
toolbar_obj.right_action_items = dynamic_list
class GrashofPopup(Popup): class GrashofPopup(Popup):
"""Methods for saving contacts, error messages."""
def __init__(self, **kwargs): def __init__(self, **kwargs):
"""Grash of pop screen settings."""
super(GrashofPopup, self).__init__(**kwargs) super(GrashofPopup, self).__init__(**kwargs)
print("sssssssssssssssssssiiiiiiiiiiiiiiizzzzzzzzzzeeeeee...............", state.screen_density)
if state.screen_density[0] <= 720: if state.screen_density[0] <= 720:
self.size_hint_y = 0.4 self.size_hint_y = 0.4
self.size_hint_x = 0.9 self.size_hint_x = 0.9
@ -970,33 +1318,37 @@ class GrashofPopup(Popup):
self.size_hint_x = 0.7 self.size_hint_x = 0.7
def savecontact(self): def savecontact(self):
my_addresses = self.parent.children[1].children[2].children[0].ids.btn.values """Method is used for Saving Contacts."""
entered_text = str(self.ids.label.text) label = self.ids.label.text.strip()
if entered_text in my_addresses: address = self.ids.address.text.strip()
if label == '' and address == '':
self.ids.label.focus = True self.ids.label.focus = True
self.ids.label.helper_text = 'Please Enter corrent address' self.ids.address.focus = True
elif entered_text == '': elif address == '':
self.ids.address.focus = True
elif label == '':
self.ids.label.focus = True self.ids.label.focus = True
self.ids.label.helper_text = 'This field is required'
label = self.ids.label.text stored_address = [addr[1] for addr in kivy_helper_search.search_sql(
address = self.ids.address.text folder="addressbook")]
if label and address: if label and address and address not in stored_address:
state.navinstance = self.parent.children[1] state.navinstance = self.parent.children[1]
queues.UISignalQueue.put(('rerenderAddressBook', '')) queues.UISignalQueue.put(('rerenderAddressBook', ''))
self.dismiss() self.dismiss()
sqlExecute("INSERT INTO addressbook VALUES(?,?)", label, address) sqlExecute("INSERT INTO addressbook VALUES(?,?)", label, address)
self.parent.children[1].ids.serch_btn.opacity = 0
self.parent.children[1].ids.serch_btn.disabled = True
self.parent.children[1].ids.scr_mngr.current = 'addressbook' self.parent.children[1].ids.scr_mngr.current = 'addressbook'
toast('Saved')
# pylint: disable=attribute-defined-outside-init
def show_error_message(self): def show_error_message(self):
content = MDLabel(font_style='Body1', """Showing error message."""
theme_text_color='Secondary', content = MDLabel(
text="Hey you are not allowed to save blank address contact. " font_style='Body1',
"That's wrong!", theme_text_color='Secondary',
size_hint_y=None, text="Hey you are not allowed to save blank address contact. "
valign='top') "That's wrong!",
size_hint_y=None,
valign='top')
content.bind(texture_size=content.setter('size')) content.bind(texture_size=content.setter('size'))
self.dialog = MDDialog(content=content, self.dialog = MDDialog(content=content,
size_hint=(.8, None), size_hint=(.8, None),
@ -1007,47 +1359,84 @@ class GrashofPopup(Popup):
action=lambda *x: self.dialog.dismiss()) action=lambda *x: self.dialog.dismiss())
self.dialog.open() self.dialog.open()
@staticmethod
def close_pop():
"""Pop is Canceled."""
toast('Canceled')
def checkAddress_valid(self, instance):
"""Checking is address is valid or not"""
my_addresses = self.parent.children[1].children[2].children[0].ids.btn.values
add_book = [addr[1] for addr in kivy_helper_search.search_sql(
folder="addressbook")]
entered_text = str(instance.text).strip()
if entered_text in add_book:
text = 'Address is already in the addressbook.'
elif entered_text in my_addresses:
text = 'You can not save your own address.'
if entered_text in my_addresses or entered_text in add_book:
if len(self.ids.popup_box.children) <= 2:
err_msg = MDLabel(
id='erro_msg',
font_style='Body2',
text=text,
font_size=5)
err_msg.color = 1, 0, 0, 1
self.ids.popup_box.add_widget(err_msg)
self.ids.save_addr.disabled = True
elif len(self.ids.popup_box.children) > 2:
self.ids.popup_box.remove_widget(self.ids.popup_box.children[0])
self.ids.save_addr.disabled = False
class AvatarSampleWidget(ILeftBody, Image): class AvatarSampleWidget(ILeftBody, Image):
"""Avatar Sample Widget."""
pass pass
class IconLeftSampleWidget(ILeftBodyTouch, MDIconButton): class IconLeftSampleWidget(ILeftBodyTouch, MDIconButton):
"""Left icon sample widget."""
pass pass
class IconRightSampleWidget(IRightBodyTouch, MDCheckbox): class IconRightSampleWidget(IRightBodyTouch, MDCheckbox):
"""Right icon sample widget."""
pass pass
class NavigationDrawerTwoLineListItem( class NavigationDrawerTwoLineListItem(
TwoLineListItem, NavigationDrawerHeaderBase): TwoLineListItem, NavigationDrawerHeaderBase):
"""Navigation Drawer in Listitems."""
address_property = StringProperty() address_property = StringProperty()
def __init__(self, **kwargs): def __init__(self, **kwargs):
"""Method for Navigation Drawer."""
super(NavigationDrawerTwoLineListItem, self).__init__(**kwargs) super(NavigationDrawerTwoLineListItem, self).__init__(**kwargs)
Clock.schedule_once(lambda dt: self.setup()) Clock.schedule_once(lambda dt: self.setup())
def setup(self): def setup(self):
""" """Bind Controller.current_account property."""
Binds Controller.current_account property.
"""
pass pass
def on_current_account(self, account): def on_current_account(self, account):
"""Account detail."""
pass pass
def _update_specific_text_color(self, instance, value): def _update_specific_text_color(self, instance, value):
pass pass
def _set_active(self, active, list): def _set_active(self, active, list): # pylint: disable=redefined-builtin
pass pass
class MailDetail(Screen): class MailDetail(Screen):
"""MailDetail Screen uses to show the detail of mails.""" """MailDetail Screen uses to show the detail of mails."""
to_addr = StringProperty() to_addr = StringProperty()
from_addr = StringProperty() from_addr = StringProperty()
subject = StringProperty() subject = StringProperty()
@ -1056,73 +1445,134 @@ class MailDetail(Screen):
page_type = StringProperty() page_type = StringProperty()
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
"""Mail Details method."""
super(MailDetail, self).__init__(*args, **kwargs) super(MailDetail, self).__init__(*args, **kwargs)
Clock.schedule_once(self.init_ui, 0) Clock.schedule_once(self.init_ui, 0)
def init_ui(self, dt=0): def init_ui(self, dt=0):
"""Clock Schdule for method MailDetail mails.""" """Clock Schdule for method MailDetail mails."""
self.page_type = state.detailPageType if state.detailPageType else '' self.page_type = state.detailPageType if state.detailPageType else ''
if state.detailPageType == 'sent': if state.detailPageType == 'sent' or state.detailPageType == 'draft':
data = sqlQuery("select toaddress, fromaddress, subject, message , status, ackdata from sent where lastactiontime = {};".format(state.sentMailTime)) data = sqlQuery(
"select toaddress, fromaddress, subject, message, status, \
ackdata from sent where lastactiontime = {};".format(
state.sentMailTime))
state.status = self state.status = self
state.ackdata = data[0][5] state.ackdata = data[0][5]
self.assign_mail_details(data) self.assign_mail_details(data)
state.kivyapp.set_mail_detail_header()
elif state.detailPageType == 'inbox': elif state.detailPageType == 'inbox':
data = sqlQuery("select toaddress, fromaddress, subject, message from inbox where received = {};".format(state.sentMailTime)) data = sqlQuery(
"select toaddress, fromaddress, subject, message from inbox \
where received = {};".format(state.sentMailTime))
self.assign_mail_details(data) self.assign_mail_details(data)
state.kivyapp.set_mail_detail_header()
def assign_mail_details(self, data): def assign_mail_details(self, data):
"""Assigning mail details."""
self.to_addr = data[0][0] self.to_addr = data[0][0]
self.from_addr = data[0][1] self.from_addr = data[0][1]
self.subject = data[0][2].upper() self.subject = data[0][2].upper(
) if data[0][2].upper() else '(no subject)'
self.message = data[0][3] self.message = data[0][3]
if len(data[0]) == 6: if len(data[0]) == 6:
self.status = data[0][4] self.status = data[0][4]
state.write_msg = {'to_addr': self.to_addr,
'from_addr': self.from_addr,
'subject': self.subject,
'message': self.message}
def delete_mail(self): def delete_mail(self):
msg_count_objs =self.parent.parent.parent.parent.parent.children[2].children[0].ids """Method for mail delete."""
msg_count_objs = state.kivyapp.root.children[2].children[0].ids
if state.detailPageType == 'sent': if state.detailPageType == 'sent':
sqlExecute("UPDATE sent SET folder = 'trash' WHERE lastactiontime = {};".format(state.sentMailTime)) sqlExecute(
"UPDATE sent SET folder = 'trash' WHERE \
lastactiontime = {};".format(state.sentMailTime))
msg_count_objs.send_cnt.badge_text = str(int(state.sent_count) - 1) msg_count_objs.send_cnt.badge_text = str(int(state.sent_count) - 1)
state.sent_count = str(int(state.sent_count) - 1) state.sent_count = str(int(state.sent_count) - 1)
self.parent.parent.screens[3].clear_widgets() self.parent.screens[3].clear_widgets()
self.parent.parent.screens[3].add_widget(Sent()) self.parent.screens[3].add_widget(Sent())
self.parent.parent.current = 'sent'
elif state.detailPageType == 'inbox': elif state.detailPageType == 'inbox':
sqlExecute("UPDATE inbox SET folder = 'trash' WHERE received = {};".format(state.sentMailTime)) sqlExecute(
msg_count_objs.inbox_cnt.badge_text = str(int(state.inbox_count) - 1) "UPDATE inbox SET folder = 'trash' WHERE \
state.inbox_count = str(int(state.inbox_count) - 1) received = {};".format(state.sentMailTime))
self.parent.parent.screens[0].clear_widgets() # msg_count_objs.inbox_cnt.badge_text = str(
self.parent.parent.screens[0].add_widget(Inbox()) # int(state.inbox_count) - 1)
self.parent.parent.current = 'inbox' # state.inbox_count = str(int(state.inbox_count) - 1)
msg_count_objs.trash_cnt.badge_text = str(int(state.trash_count) + 1) self.parent.screens[0].clear_widgets()
state.trash_count = str(int(state.trash_count) + 1) self.parent.screens[0].add_widget(Inbox())
self.parent.parent.screens[4].clear_widgets() elif state.detailPageType == 'draft':
self.parent.parent.screens[4].add_widget(Trash()) sqlExecute("DELETE FROM sent WHERE lastactiontime = '{}';".format(
self.parent.parent.parent.parent.parent.ids.serch_btn.opacity = 1 state.sentMailTime))
self.parent.parent.parent.parent.parent.ids.serch_btn.disabled = False msg_count_objs.draft_cnt.badge_text = str(int(state.draft_count) - 1)
state.draft_count = str(int(state.draft_count) - 1)
self.parent.screens[15].clear_widgets()
self.parent.screens[15].add_widget(Draft())
self.parent.current = 'allmails' if state.is_allmail else state.detailPageType
if state.detailPageType != 'draft':
msg_count_objs.trash_cnt.badge_text = str(int(state.trash_count) + 1)
msg_count_objs.allmail_cnt.badge_text = str(int(state.all_count) - 1)
state.trash_count = str(int(state.trash_count) + 1)
state.all_count = str(int(state.all_count) - 1)
self.parent.screens[4].clear_widgets()
self.parent.screens[4].add_widget(Trash())
self.parent.screens[16].clear_widgets()
self.parent.screens[16].add_widget(Allmails())
state.kivyapp.back_press()
toast('Deleted')
def inbox_reply(self): def inbox_reply(self):
"""This method is used for replying inbox messages""" """Method used for replying inbox messages."""
data = sqlQuery("select toaddress, fromaddress, subject, message from inbox where received = {};".format(state.sentMailTime)) data = sqlQuery(
composer_obj = self.parent.parent.screens[2].children[0].ids "select toaddress, fromaddress, subject, message from inbox where \
composer_obj.ti.text = data[0][1] received = {};".format(state.sentMailTime))
composer_obj.btn.text = data[0][1] composer_obj = self.parent.screens[2].children[0].ids
composer_obj.txt_input.text = data[0][0] composer_obj.ti.text = data[0][0]
composer_obj.btn.text = data[0][0]
composer_obj.txt_input.text = data[0][1]
composer_obj.subject.text = data[0][2] composer_obj.subject.text = data[0][2]
self.parent.parent.current = 'create' state.kivyapp.root.ids.sc3.children[0].ids.rv.data = ''
self.parent.current = 'create'
state.kivyapp.set_navbar_for_composer()
def copy_sent_mail(self): def copy_sent_mail(self):
"""This method is used for copying sent mail to the composer""" """Method used for copying sent mail to the composer."""
pass pass
def write_msg(self, navApp):
"""Method used to write on draft mail."""
state.send_draft_mail = state.sentMailTime
composer_ids = \
self.parent.parent.parent.parent.ids.sc3.children[0].ids
composer_ids.ti.text = state.write_msg['from_addr']
composer_ids.btn.text = state.write_msg['from_addr']
composer_ids.txt_input.text = state.write_msg['to_addr']
composer_ids.subject.text = state.write_msg['subject']
composer_ids.body.text = state.write_msg['message']
self.parent.current = 'create'
navApp.set_navbar_for_composer()
@staticmethod
def copy_composer_text(instance, *args):
"""This method is used for copying the data from mail detail page"""
if len(instance.parent.text.split(':')) > 1:
cpy_text = instance.parent.text.split(':')[1].strip()
else:
cpy_text = instance.parent.text
Clipboard.copy(cpy_text)
toast('Copied')
class MyaddDetailPopup(Popup): class MyaddDetailPopup(Popup):
"""MyaddDetailPopup pop is used for showing my address detail""" """MyaddDetailPopup pop is used for showing my address detail."""
address_label = StringProperty() address_label = StringProperty()
address = StringProperty() address = StringProperty()
def __init__(self, **kwargs): def __init__(self, **kwargs):
"""My Address Details screen setting."""
super(MyaddDetailPopup, self).__init__(**kwargs) super(MyaddDetailPopup, self).__init__(**kwargs)
if state.screen_density[0] <= 720: if state.screen_density[0] <= 720:
self.size_hint_y = 0.32 self.size_hint_y = 0.32
@ -1132,12 +1582,12 @@ class MyaddDetailPopup(Popup):
self.size_hint_x = 0.7 self.size_hint_x = 0.7
def set_address(self, address, label): def set_address(self, address, label):
"""Getting address for displaying details on popup""" """Getting address for displaying details on popup."""
self.address_label = label self.address_label = label
self.address = address self.address = address
def send_message_from(self): def send_message_from(self):
"""This method used to fill from address of composer autofield""" """Method used to fill from address of composer autofield."""
window_obj = self.parent.children[1].ids window_obj = self.parent.children[1].ids
window_obj.sc3.children[0].ids.ti.text = self.address window_obj.sc3.children[0].ids.ti.text = self.address
window_obj.sc3.children[0].ids.btn.text = self.address window_obj.sc3.children[0].ids.btn.text = self.address
@ -1147,12 +1597,20 @@ class MyaddDetailPopup(Popup):
window_obj.scr_mngr.current = 'create' window_obj.scr_mngr.current = 'create'
self.dismiss() self.dismiss()
@staticmethod
def close_pop():
"""Pop is Canceled."""
toast('Canceled')
class AddbookDetailPopup(Popup): class AddbookDetailPopup(Popup):
"""AddbookDetailPopup pop is used for showing my address detail""" """AddbookDetailPopup pop is used for showing my address detail."""
address_label = StringProperty() address_label = StringProperty()
address = StringProperty() address = StringProperty()
def __init__(self, **kwargs): def __init__(self, **kwargs):
"""Method used set screen of address detail page."""
super(AddbookDetailPopup, self).__init__(**kwargs) super(AddbookDetailPopup, self).__init__(**kwargs)
if state.screen_density[0] <= 720: if state.screen_density[0] <= 720:
self.size_hint_y = 0.35 self.size_hint_y = 0.35
@ -1162,20 +1620,22 @@ class AddbookDetailPopup(Popup):
self.size_hint_x = 0.7 self.size_hint_x = 0.7
def set_addbook_data(self, address, label): def set_addbook_data(self, address, label):
"""Getting address book data for detial dipaly""" """Getting address book data for detial dipaly."""
self.address_label = label self.address_label = label
self.address = address self.address = address
def update_addbook_label(self, address): def update_addbook_label(self, address):
"""Updating the label of address book address""" """Updating the label of address book address."""
if str(self.ids.add_label.text): if str(self.ids.add_label.text):
sqlExecute("UPDATE addressbook SET label = '{}' WHERE address = '{}';".format(str(self.ids.add_label.text), address)) sqlExecute("UPDATE addressbook SET label = '{}' WHERE \
address = '{}';".format(str(self.ids.add_label.text), address))
self.parent.children[1].ids.sc11.clear_widgets() self.parent.children[1].ids.sc11.clear_widgets()
self.parent.children[1].ids.sc11.add_widget(AddressBook()) self.parent.children[1].ids.sc11.add_widget(AddressBook())
self.dismiss() self.dismiss()
toast('Saved')
def send_message_to(self): def send_message_to(self):
"""This method used to fill to_address of composer autofield""" """Method used to fill to_address of composer autofield."""
window_obj = self.parent.children[1].ids window_obj = self.parent.children[1].ids
window_obj.sc3.children[0].ids.txt_input.text = self.address window_obj.sc3.children[0].ids.txt_input.text = self.address
window_obj.sc3.children[0].ids.ti.text = '' window_obj.sc3.children[0].ids.ti.text = ''
@ -1185,22 +1645,32 @@ class AddbookDetailPopup(Popup):
window_obj.scr_mngr.current = 'create' window_obj.scr_mngr.current = 'create'
self.dismiss() self.dismiss()
@staticmethod
def close_pop():
"""Pop is Canceled."""
toast('Canceled')
class ShowQRCode(Screen): class ShowQRCode(Screen):
"""ShowQRCode Screen uses to show the detail of mails.""" """ShowQRCode Screen uses to show the detail of mails."""
def qrdisplay(self): def qrdisplay(self):
"""Method used for showing QR Code."""
self.manager.parent.parent.parent.ids.search_bar.clear_widgets()
self.ids.qr.clear_widgets() self.ids.qr.clear_widgets()
if platform == 'android': from kivy.garden.qrcode import QRCodeWidget
from kivy.garden.qrcode import QRCodeWidget self.ids.qr.add_widget(QRCodeWidget(
self.ids.qr.add_widget(QRCodeWidget(data=self.manager.get_parent_window().children[0].address)) data=self.manager.get_parent_window().children[0].address))
toast('Show QR code')
class Draft(Screen): class Draft(Screen):
"""Draft screen is used to show the list of draft messages.""" """Draft screen is used to show the list of draft messages."""
data = ListProperty() data = ListProperty()
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
"""Method used for storing draft messages."""
super(Draft, self).__init__(*args, **kwargs) super(Draft, self).__init__(*args, **kwargs)
if state.association == '': if state.association == '':
if BMConfigParser().addresses(): if BMConfigParser().addresses():
@ -1210,7 +1680,7 @@ class Draft(Screen):
def init_ui(self, dt=0): def init_ui(self, dt=0):
"""Clock Schdule for method draft accounts.""" """Clock Schdule for method draft accounts."""
self.sentaccounts() self.sentaccounts()
print(dt) print dt
def sentaccounts(self): def sentaccounts(self):
"""Load draft accounts.""" """Load draft accounts."""
@ -1224,56 +1694,101 @@ class Draft(Screen):
xAddress, account, "draft", where, what, False) xAddress, account, "draft", where, what, False)
if state.msg_counter_objs: if state.msg_counter_objs:
state.msg_counter_objs.draft_cnt.badge_text = str(len(queryreturn)) state.msg_counter_objs.draft_cnt.badge_text = str(len(queryreturn))
# state.all_count = str(int(state.all_count) + 1)
# state.msg_counter_objs.allmail_cnt.badge_text = state.all_count
# state.msg_counter_objs = None
if queryreturn: if queryreturn:
src_mng_obj = state.kivyapp.root.children[2].children[0].ids
src_mng_obj.draft_cnt.badge_text = str(len(queryreturn))
state.draft_count = str(len(queryreturn))
for mail in queryreturn: for mail in queryreturn:
third_text = mail[3].replace('\n', ' ') third_text = mail[3].replace('\n', ' ')
self.data.append({'text': mail[1].strip(), 'secondary_text': mail[2][:10] + '...........' if len(mail[2]) > 10 else mail[2] + '\n' + " " + (third_text[:25] + '...!') if len(third_text) > 25 else third_text, 'lastactiontime': mail[6]}) self.data.append({
'text': mail[1].strip(),
'secondary_text': mail[2][:10] + '...........' if len(
mail[2]) > 10 else mail[2] + '\n' + " " + (
third_text[:25] + '...!') if len(
third_text) > 25 else third_text,
'lastactiontime': mail[6]})
for item in self.data: for item in self.data:
meny = TwoLineAvatarIconListItem(text='Draft', secondary_text=item['text'], theme_text_color= 'Custom',text_color=NavigateApp().theme_cls.primary_color) meny = TwoLineAvatarIconListItem(
meny.add_widget(AvatarSampleWidget(source='./images/avatar.png')) text='Draft',
secondary_text=item['text'],
theme_text_color='Custom',
text_color=NavigateApp().theme_cls.primary_color)
meny.add_widget(AvatarSampleWidget(
source='./images/avatar.png'))
meny.bind(on_press=partial(
self.draft_detail, item['lastactiontime']))
carousel = Carousel(direction='right') carousel = Carousel(direction='right')
if platform == 'android': carousel.height = meny.height
carousel.height = 150
elif platform == 'linux':
carousel.height = meny.height - 10
carousel.size_hint_y = None carousel.size_hint_y = None
carousel.ignore_perpendicular_swipes = True carousel.ignore_perpendicular_swipes = True
carousel.data_index = 0 carousel.data_index = 0
carousel.min_move = 0.2 carousel.min_move = 0.2
del_btn = Button(text='Delete') del_btn = Button(text='Delete')
del_btn.background_normal = '' del_btn.background_normal = ''
del_btn.background_color = (1.0, 0.0, 0.0, 1.0) del_btn.background_color = (1, 0, 0, 1)
del_btn.bind(on_press=partial(self.delete_draft, item['lastactiontime'])) del_btn.bind(on_press=partial(
self.delete_draft, item['lastactiontime']))
carousel.add_widget(del_btn) carousel.add_widget(del_btn)
carousel.add_widget(meny) carousel.add_widget(meny)
carousel.index=1 carousel.index = 1
self.ids.ml.add_widget(carousel) self.ids.ml.add_widget(carousel)
else: else:
content = MDLabel(font_style='Body1', content = MDLabel(
theme_text_color='Primary', font_style='Body1',
text="yet no message for this account!!!!!!!!!!!!!", theme_text_color='Primary',
halign='center', text="yet no message for this account!!!!!!!!!!!!!",
bold=True, halign='center',
size_hint_y=None, bold=True,
valign='top') size_hint_y=None,
valign='top')
self.ids.ml.add_widget(content) self.ids.ml.add_widget(content)
def delete_draft(self, data_index, instance, *args): def draft_detail(self, lastsenttime, *args):
"""This method is used to delete draft message permanently""" """Method used to show draft Details."""
sqlExecute("DELETE FROM sent WHERE lastactiontime = '{}';".format(data_index)) state.detailPageType = 'draft'
try: state.sentMailTime = lastsenttime
msg_count_objs = self.parent.parent.parent.parent.children[2].children[0].ids if self.manager:
except Exception as e: src_mng_obj = self.manager
msg_count_objs = self.parent.parent.parent.parent.parent.children[2].children[0].ids else:
if int(state.draft_count) > 0: src_mng_obj = self.parent.parent
msg_count_objs.draft_cnt.badge_text = str(int(state.draft_count) - 1) src_mng_obj.screens[13].clear_widgets()
state.draft_count = str(int(state.draft_count) - 1) src_mng_obj.screens[13].add_widget(MailDetail())
self.ids.ml.remove_widget(instance.parent.parent) src_mng_obj.current = 'mailDetail'
def draft_msg(self, src_object): def delete_draft(self, data_index, instance, *args):
"""This method is used for saving draft mails""" """Method used to delete draft message permanently."""
composer_object = src_object.children[1].children[0].children[0].children[0].children[0].ids sqlExecute("DELETE FROM sent WHERE lastactiontime = '{}';".format(
data_index))
try:
msg_count_objs = \
self.parent.parent.parent.parent.children[2].children[0].ids
except Exception:
msg_count_objs = self.parent.parent.parent.parent.parent.children[
2].children[0].ids
if int(state.draft_count) > 0:
msg_count_objs.draft_cnt.badge_text = str(
int(state.draft_count) - 1)
# msg_count_objs.allmail_cnt.badge_text = str(
# int(state.all_count) - 1)
# msg_count_objs.trash_cnt.badge_text = str(
# int(state.trash_count) + 1)
state.draft_count = str(int(state.draft_count) - 1)
# state.all_count = str(int(state.all_count) - 1)
# state.trash_count = str(int(state.trash_count) + 1)
self.ids.ml.remove_widget(instance.parent.parent)
toast('Deleted')
# pylint: disable=unused-variable
@staticmethod
def draft_msg(src_object):
"""Method used for saving draft mails."""
# pylint: disable=too-many-locals
composer_object = src_object.children[1].children[0].children[
0].children[0].children[0].ids
fromAddress = str(composer_object.ti.text) fromAddress = str(composer_object.ti.text)
toAddress = str(composer_object.txt_input.text) toAddress = str(composer_object.txt_input.text)
subject = str(composer_object.subject.text) subject = str(composer_object.subject.text)
@ -1282,9 +1797,9 @@ class Draft(Screen):
sendMessageToPeople = True sendMessageToPeople = True
if sendMessageToPeople: if sendMessageToPeople:
from addresses import decodeAddress from addresses import decodeAddress
status, addressVersionNumber, streamNumber, ripe = decodeAddress( status, addressVersionNumber, streamNumber, ripe = \
toAddress) decodeAddress(toAddress)
from addresses import * from addresses import addBMIfNotPresent
toAddress = addBMIfNotPresent(toAddress) toAddress = addBMIfNotPresent(toAddress)
statusIconColor = 'red' statusIconColor = 'red'
stealthLevel = BMConfigParser().safeGetInt( stealthLevel = BMConfigParser().safeGetInt(
@ -1293,7 +1808,8 @@ class Draft(Screen):
ackdata = genAckPayload(streamNumber, stealthLevel) ackdata = genAckPayload(streamNumber, stealthLevel)
t = () t = ()
sqlExecute( sqlExecute(
'''INSERT INTO sent VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)''', '''INSERT INTO sent VALUES
(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)''',
'', '',
toAddress, toAddress,
ripe, ripe,
@ -1314,34 +1830,203 @@ class Draft(Screen):
state.draft_count = str(int(state.draft_count) + 1) state.draft_count = str(int(state.draft_count) + 1)
src_object.ids.sc16.clear_widgets() src_object.ids.sc16.clear_widgets()
src_object.ids.sc16.add_widget(Draft()) src_object.ids.sc16.add_widget(Draft())
toast('Save draft')
return return
def show_search_btn(self):
'''This method is used to show search button'''
self.root.ids.serch_btn.opacity = 1
self.root.ids.serch_btn.disabled = False
def hide_search_btn(mgr_objs):
'''This method is used to hide search button and search box'''
mgr_objs.parent.parent.parent.ids.serch_btn.opacity = 0
mgr_objs.parent.parent.parent.ids.serch_btn.disabled = True
mgr_objs.parent.parent.parent.ids.search_input.size_hint = 1,None
mgr_objs.parent.parent.parent.ids.search_input.disabled = True
mgr_objs.parent.parent.parent.ids.search_input.opacity = 0
mgr_objs.parent.parent.parent.ids.toolbar.left_action_items = [['menu', lambda x: mgr_objs.parent.parent.parent.toggle_nav_drawer()]]
mgr_objs.parent.parent.parent.ids.toolbar.title = NavigateApp().current_address_label()
mgr_objs.parent.parent.parent.ids.myButton.opacity = 1
mgr_objs.parent.parent.parent.ids.myButton.disabled = False
mgr_objs.parent.parent.parent.ids.reset_navbar.opacity = 0
mgr_objs.parent.parent.parent.ids.reset_navbar.disabled = True
class CustomSpinner(Spinner): class CustomSpinner(Spinner):
'''This class is used for setting spinner size''' """This class is used for setting spinner size."""
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
'''This methods is used for setting size of spinner''' """Method used for setting size of spinner."""
super(CustomSpinner, self).__init__(*args, **kwargs) super(CustomSpinner, self).__init__(*args, **kwargs)
max = 2.8 # max_value = 2.8
self.dropdown_cls.max_height = self.height * max + max * 4 # self.dropdown_cls.max_height = self.height / 2 * max_value + max_value * 4
self.dropdown_cls.max_height = Window.size[1] / 3
def remove_search_bar(obj):
"""Remove search bar."""
try:
obj.parent.parent.parent.parent.parent.ids.search_bar.clear_widgets()
except Exception:
obj.parent.parent.parent.parent.ids.search_bar.clear_widgets()
class Allmails(Screen):
"""all mails Screen uses screen to show widgets of screens."""
data = ListProperty()
def __init__(self, *args, **kwargs):
"""Method Parsing the address."""
super(Allmails, self).__init__(*args, **kwargs)
if state.association == '':
if BMConfigParser().addresses():
state.association = BMConfigParser().addresses()[0]
Clock.schedule_once(self.init_ui, 0)
def init_ui(self, dt=0):
"""Clock Schdule for method all mails."""
self.mailaccounts()
print dt
def mailaccounts(self):
"""Load all mails for account."""
account = state.association
self.loadMessagelist(account, 'All', '')
def loadMessagelist(self, account, where="", what=""):
"""Load Inbox, Sent anf Draft list of messages."""
inbox = sqlQuery(
"SELECT toaddress, fromaddress, subject, message, folder, received from\
inbox WHERE folder = 'inbox' and toaddress = '{}';".format(
account))
sent_and_draft = sqlQuery(
"SELECT toaddress, fromaddress, subject, message, folder, lastactiontime from sent \
WHERE folder = 'sent' and fromaddress = '{}';".format(
account))
all_mails = inbox + sent_and_draft
if all_mails:
state.kivyapp.root.children[2].children[0].ids.allmail_cnt.badge_text = str(len(all_mails))
state.all_count = str(len(all_mails))
for item in all_mails:
meny = TwoLineAvatarIconListItem(
text=item[1],
secondary_text=item[2][:50] + '........' if len(
item[2]) >= 50 else (
item[2] + ',' + item[3].replace('\n', ''))[0:50] + '........',
theme_text_color='Custom',
text_color=NavigateApp().theme_cls.primary_color)
meny.add_widget(AvatarSampleWidget(
source='./images/text_images/{}.png'.format(
avatarImageFirstLetter(item[2].strip()))))
meny.bind(on_press=partial(
self.mail_detail, item[5], item[4]))
carousel = Carousel(direction='right')
carousel.height = meny.height
carousel.size_hint_y = None
carousel.ignore_perpendicular_swipes = True
carousel.data_index = 0
carousel.min_move = 0.2
del_btn = Button(text='Delete')
del_btn.background_normal = ''
del_btn.background_color = (1, 0, 0, 1)
del_btn.bind(on_press=partial(
self.swipe_delete, item[5], item[4]))
carousel.add_widget(del_btn)
carousel.add_widget(meny)
carousel.index = 1
self.ids.ml.add_widget(carousel)
else:
content = MDLabel(
font_style='Body1',
theme_text_color='Primary',
text="yet no message for this account!!!!!!!!!!!!!",
halign='center',
bold=True,
size_hint_y=None,
valign='top')
self.ids.ml.add_widget(content)
def mail_detail(self, unique_id, folder, *args):
"""Load sent and inbox mail details."""
remove_search_bar(self)
state.detailPageType = folder
state.is_allmail = True
state.sentMailTime = unique_id
if self.manager:
src_mng_obj = self.manager
else:
src_mng_obj = self.parent.parent
src_mng_obj.screens[13].clear_widgets()
src_mng_obj.screens[13].add_widget(MailDetail())
src_mng_obj.current = 'mailDetail'
def swipe_delete(self, unique_id, folder, instance, *args):
"""Delete inbox mail from all mail listing listing."""
if folder == 'inbox':
sqlExecute(
"UPDATE inbox SET folder = 'trash' WHERE received = {};".format(
unique_id))
else:
sqlExecute(
"UPDATE sent SET folder = 'trash' WHERE lastactiontime = {};".format(
unique_id))
self.ids.ml.remove_widget(instance.parent.parent)
try:
msg_count_objs = self.parent.parent.parent.parent.children[
2].children[0].ids
nav_lay_obj = self.parent.parent.parent.parent.ids
except Exception:
msg_count_objs = self.parent.parent.parent.parent.parent.children[
2].children[0].ids
nav_lay_obj = self.parent.parent.parent.parent.parent.ids
if folder == 'inbox':
msg_count_objs.inbox_cnt.badge_text = str(
int(state.inbox_count) - 1)
state.inbox_count = str(int(state.inbox_count) - 1)
nav_lay_obj.sc1.clear_widgets()
nav_lay_obj.sc1.add_widget(Inbox())
else:
msg_count_objs.send_cnt.badge_text = str(
int(state.sent_count) - 1)
state.sent_count = str(int(state.sent_count) - 1)
nav_lay_obj.sc4.clear_widgets()
nav_lay_obj.sc4.add_widget(Sent())
msg_count_objs.trash_cnt.badge_text = str(
int(state.trash_count) + 1)
msg_count_objs.allmail_cnt.badge_text = str(
int(state.all_count) - 1)
state.trash_count = str(int(state.trash_count) + 1)
state.all_count = str(int(state.all_count) - 1)
nav_lay_obj.sc5.clear_widgets()
nav_lay_obj.sc5.add_widget(Trash())
nav_lay_obj.sc17.clear_widgets()
nav_lay_obj.sc17.add_widget(Allmails())
# pylint: disable=attribute-defined-outside-init
def refresh_callback(self, *args):
"""Method updates the state of application, While the spinner remains on the screen."""
def refresh_callback(interval):
"""Method used for loading the allmails screen data."""
self.ids.ml.clear_widgets()
self.remove_widget(self.children[1])
try:
screens_obj = self.parent.screens[16]
except Exception:
screens_obj = self.parent.parent.screens[16]
screens_obj.add_widget(Allmails())
self.ids.refresh_layout.refresh_done()
self.tick = 0
Clock.schedule_once(refresh_callback, 1)
def avatarImageFirstLetter(letter_string):
"""This method is used to the first letter for the avatar image"""
if letter_string[0].upper() >= 'A' and letter_string[0].upper() <= 'Z':
img_latter = letter_string[0].upper()
elif int(letter_string[0]) >= 0 and int(letter_string[0]) <= 9:
img_latter = letter_string[0]
else:
img_latter = '!'
return img_latter
class Starred(Screen):
"""Starred Screen show widgets of page."""
pass
class Archieve(Screen):
"""Archieve Screen show widgets of page."""
pass
class Spam(Screen):
"""Spam Screen show widgets of page."""
pass

View File

@ -1,4 +1,8 @@
#!/usr/bin/python2.7 """
src/bitmessagemain.py
=================================
"""
# !/usr/bin/python2.7
# Copyright (c) 2012-2016 Jonathan Warren # Copyright (c) 2012-2016 Jonathan Warren
# Copyright (c) 2012-2019 The Bitmessage developers # Copyright (c) 2012-2019 The Bitmessage developers
# Distributed under the MIT/X11 software license. See the accompanying # Distributed under the MIT/X11 software license. See the accompanying
@ -11,16 +15,6 @@
import os import os
import sys import sys
app_dir = os.path.dirname(os.path.abspath(__file__))
os.chdir(app_dir)
sys.path.insert(0, app_dir)
import depends
depends.check_dependencies()
import ctypes import ctypes
import getopt import getopt
import multiprocessing import multiprocessing
@ -38,6 +32,7 @@ from helper_startup import (
from singleinstance import singleinstance from singleinstance import singleinstance
import defaults import defaults
import depends
import shared import shared
import knownnodes import knownnodes
import state import state
@ -67,8 +62,15 @@ from network.uploadthread import UploadThread
# Helper Functions # Helper Functions
import helper_threading import helper_threading
app_dir = os.path.dirname(os.path.abspath(__file__))
os.chdir(app_dir)
sys.path.insert(0, app_dir)
depends.check_dependencies()
def connectToStream(streamNumber): def connectToStream(streamNumber):
"""Method helps us to connect with the stream"""
state.streamsInWhichIAmParticipating.append(streamNumber) state.streamsInWhichIAmParticipating.append(streamNumber)
if isOurOperatingSystemLimitedToHavingVeryFewHalfOpenConnections(): if isOurOperatingSystemLimitedToHavingVeryFewHalfOpenConnections():
@ -109,6 +111,7 @@ def _fixSocket():
addressToString = ctypes.windll.ws2_32.WSAAddressToStringA addressToString = ctypes.windll.ws2_32.WSAAddressToStringA
def inet_ntop(family, host): def inet_ntop(family, host):
"""Method converts an IP address in packed binary format to string format"""
if family == socket.AF_INET: if family == socket.AF_INET:
if len(host) != 4: if len(host) != 4:
raise ValueError("invalid IPv4 host") raise ValueError("invalid IPv4 host")
@ -130,6 +133,7 @@ def _fixSocket():
stringToAddress = ctypes.windll.ws2_32.WSAStringToAddressA stringToAddress = ctypes.windll.ws2_32.WSAStringToAddressA
def inet_pton(family, host): def inet_pton(family, host):
"""Method converts an IP address in string format to a packed binary format"""
buf = "\0" * 28 buf = "\0" * 28
lengthBuf = pack("I", len(buf)) lengthBuf = pack("I", len(buf))
if stringToAddress(str(host), if stringToAddress(str(host),
@ -175,16 +179,18 @@ def signal_handler(signum, frame):
if shared.thisapp.daemon or not state.enableGUI: if shared.thisapp.daemon or not state.enableGUI:
shutdown.doCleanShutdown() shutdown.doCleanShutdown()
else: else:
print('# Thread: %s(%d)' % (thread.name, thread.ident)) print '# Thread: %s(%d)' % (thread.name, thread.ident)
for filename, lineno, name, line in traceback.extract_stack(frame): for filename, lineno, name, line in traceback.extract_stack(frame):
print('File: "%s", line %d, in %s' % (filename, lineno, name)) print 'File: "%s", line %d, in %s' % (filename, lineno, name)
if line: if line:
print(' %s' % line.strip()) print ' %s' % line.strip()
print('Unfortunately you cannot use Ctrl+C when running the UI' print 'Unfortunately you cannot use Ctrl+C when running the UI \
' because the UI captures the signal.') because the UI captures the signal.'
class Main: class Main: # pylint: disable=no-init, old-style-class
"""Method starts the proxy config plugin"""
@staticmethod @staticmethod
def start_proxyconfig(config): def start_proxyconfig(config):
"""Check socksproxytype and start any proxy configuration plugin""" """Check socksproxytype and start any proxy configuration plugin"""
@ -206,7 +212,8 @@ class Main:
'Started proxy config plugin %s in %s sec', 'Started proxy config plugin %s in %s sec',
proxy_type, time.time() - proxyconfig_start) proxy_type, time.time() - proxyconfig_start)
def start(self): def start(self): # pylint: disable=too-many-statements, too-many-branches, too-many-locals
"""This method helps to start the daemon"""
_fixSocket() _fixSocket()
config = BMConfigParser() config = BMConfigParser()
@ -267,11 +274,14 @@ class Main:
' \'-c\' as a commandline argument.' ' \'-c\' as a commandline argument.'
) )
# is the application already running? If yes then exit. # is the application already running? If yes then exit.
shared.thisapp = singleinstance("", daemon) try:
shared.thisapp = singleinstance("", daemon)
except Exception:
pass
if daemon: if daemon:
with shared.printLock: with shared.printLock:
print('Running as a daemon. Send TERM signal to end.') print 'Running as a daemon. Send TERM signal to end.'
self.daemonize() self.daemonize()
self.setSignalHandler() self.setSignalHandler()
@ -383,7 +393,6 @@ class Main:
state.uploadThread.start() state.uploadThread.start()
connectToStream(1) connectToStream(1)
if config.safeGetBoolean('bitmessagesettings', 'upnp'): if config.safeGetBoolean('bitmessagesettings', 'upnp'):
import upnp import upnp
upnpThread = upnp.uPnPThread() upnpThread = upnp.uPnPThread()
@ -395,7 +404,7 @@ class Main:
if state.curses: if state.curses:
if not depends.check_curses(): if not depends.check_curses():
sys.exit() sys.exit()
print('Running with curses') print 'Running with curses'
import bitmessagecurses import bitmessagecurses
bitmessagecurses.runwrapper() bitmessagecurses.runwrapper()
@ -413,8 +422,7 @@ class Main:
if daemon: if daemon:
while state.shutdown == 0: while state.shutdown == 0:
time.sleep(1) time.sleep(1)
if ( if (state.testmode and time.time() - state.last_api_response >= 30):
state.testmode and time.time() - state.last_api_response >= 30):
self.stop() self.stop()
elif not state.enableGUI: elif not state.enableGUI:
from tests import core as test_core # pylint: disable=relative-import from tests import core as test_core # pylint: disable=relative-import
@ -428,7 +436,9 @@ class Main:
else 0 else 0
) )
def daemonize(self): @staticmethod
def daemonize():
"""Running as a daemon. Send signal in end."""
grandfatherPid = os.getpid() grandfatherPid = os.getpid()
parentPid = None parentPid = None
try: try:
@ -438,7 +448,7 @@ class Main:
# wait until grandchild ready # wait until grandchild ready
while True: while True:
time.sleep(1) time.sleep(1)
os._exit(0) os._exit(0) # pylint: disable=protected-access
except AttributeError: except AttributeError:
# fork not implemented # fork not implemented
pass pass
@ -459,7 +469,7 @@ class Main:
# wait until child ready # wait until child ready
while True: while True:
time.sleep(1) time.sleep(1)
os._exit(0) os._exit(0) # pylint: disable=protected-access
except AttributeError: except AttributeError:
# fork not implemented # fork not implemented
pass pass
@ -480,12 +490,15 @@ class Main:
os.kill(parentPid, signal.SIGTERM) os.kill(parentPid, signal.SIGTERM)
os.kill(grandfatherPid, signal.SIGTERM) os.kill(grandfatherPid, signal.SIGTERM)
def setSignalHandler(self): def setSignalHandler(self): # pylint: disable=no-self-use
"""Setting the Signal Handler"""
signal.signal(signal.SIGINT, signal_handler) signal.signal(signal.SIGINT, signal_handler)
signal.signal(signal.SIGTERM, signal_handler) signal.signal(signal.SIGTERM, signal_handler)
# signal.signal(signal.SIGINT, signal.SIG_DFL) # signal.signal(signal.SIGINT, signal.SIG_DFL)
def usage(self): @staticmethod
def usage():
"""After passing argument, method displays the usages"""
print 'Usage: ' + sys.argv[0] + ' [OPTIONS]' print 'Usage: ' + sys.argv[0] + ' [OPTIONS]'
print ''' print '''
Options: Options:
@ -497,13 +510,15 @@ Options:
All parameters are optional. All parameters are optional.
''' '''
def stop(self): def stop(self): # pylint: disable=no-self-use
"""Method helps to stop the Bitmessage Deamon"""
with shared.printLock: with shared.printLock:
print('Stopping Bitmessage Deamon.') print 'Stopping Bitmessage Deamon.'
shutdown.doCleanShutdown() shutdown.doCleanShutdown()
# TODO: nice function but no one is using this # ..todo: nice function but no one is using this
def getApiAddress(self): def getApiAddress(self): # pylint: disable=no-self-use
"""This method returns the Api Addresses"""
if not BMConfigParser().safeGetBoolean( if not BMConfigParser().safeGetBoolean(
'bitmessagesettings', 'apienabled'): 'bitmessagesettings', 'apienabled'):
return None return None
@ -513,6 +528,7 @@ All parameters are optional.
def main(): def main():
"""Start of the main thread"""
mainprogram = Main() mainprogram = Main()
mainprogram.start() mainprogram.start()

View File

@ -78,7 +78,7 @@ void getnumthreads()
#ifdef _WIN32 #ifdef _WIN32
DWORD_PTR dwProcessAffinity, dwSystemAffinity; DWORD_PTR dwProcessAffinity, dwSystemAffinity;
#elif __linux__ #elif __linux__
// cpu_set_t dwProcessAffinity; cpu_set_t dwProcessAffinity;
#elif __OpenBSD__ #elif __OpenBSD__
int mib[2], core_count = 0; int mib[2], core_count = 0;
int dwProcessAffinity = 0; int dwProcessAffinity = 0;
@ -87,13 +87,13 @@ void getnumthreads()
int dwProcessAffinity = 0; int dwProcessAffinity = 0;
int32_t core_count = 0; int32_t core_count = 0;
#endif #endif
// size_t len = sizeof(dwProcessAffinity); size_t len = sizeof(dwProcessAffinity);
// if (numthreads > 0) if (numthreads > 0)
// return; return;
#ifdef _WIN32 #ifdef _WIN32
GetProcessAffinityMask(GetCurrentProcess(), &dwProcessAffinity, &dwSystemAffinity); GetProcessAffinityMask(GetCurrentProcess(), &dwProcessAffinity, &dwSystemAffinity);
#elif __linux__ #elif __linux__
// sched_getaffinity(0, len, &dwProcessAffinity); sched_getaffinity(0, len, &dwProcessAffinity);
#elif __OpenBSD__ #elif __OpenBSD__
len2 = sizeof(core_count); len2 = sizeof(core_count);
mib[0] = CTL_HW; mib[0] = CTL_HW;
@ -106,22 +106,22 @@ void getnumthreads()
else if (sysctlbyname("hw.ncpu", &core_count, &len, 0, 0) == 0) else if (sysctlbyname("hw.ncpu", &core_count, &len, 0, 0) == 0)
numthreads = core_count; numthreads = core_count;
#endif #endif
// for (unsigned int i = 0; i < len * 8; i++) for (unsigned int i = 0; i < len * 8; i++)
// #if defined(_WIN32) #if defined(_WIN32)
// #if defined(_MSC_VER) #if defined(_MSC_VER)
// if (dwProcessAffinity & (1i64 << i)) if (dwProcessAffinity & (1i64 << i))
// #else // CYGWIN/MINGW #else // CYGWIN/MINGW
// if (dwProcessAffinity & (1ULL << i)) if (dwProcessAffinity & (1ULL << i))
// #endif #endif
// #elif defined __linux__ #elif defined __linux__
// if (CPU_ISSET(i, &dwProcessAffinity)) if (CPU_ISSET(i, &dwProcessAffinity))
// #else #else
// if (dwProcessAffinity & (1 << i)) if (dwProcessAffinity & (1 << i))
// #endif #endif
// numthreads++; numthreads++;
// if (numthreads == 0) // something failed if (numthreads == 0) // something failed
// numthreads = 1; numthreads = 1;
// printf("Number of threads: %i\n", (int)numthreads); printf("Number of threads: %i\n", (int)numthreads);
} }
extern "C" EXPORT unsigned long long BitmessagePOW(unsigned char * starthash, unsigned long long target) extern "C" EXPORT unsigned long long BitmessagePOW(unsigned char * starthash, unsigned long long target)
@ -146,7 +146,7 @@ extern "C" EXPORT unsigned long long BitmessagePOW(unsigned char * starthash, un
# else # else
pthread_create(&threads[i], NULL, threadfunc, (void*)&threaddata[i]); pthread_create(&threads[i], NULL, threadfunc, (void*)&threaddata[i]);
# ifdef __linux__ # ifdef __linux__
pthread_setschedparam(threads[i], 0, &schparam); pthread_setschedparam(threads[i], SCHED_IDLE, &schparam);
# else # else
pthread_setschedparam(threads[i], SCHED_RR, &schparam); pthread_setschedparam(threads[i], SCHED_RR, &schparam);
# endif # endif

View File

@ -1,10 +1,10 @@
[app] [app]
# (str) Title of your application # (str) Title of your application
title = bluewhale title = bitapp
# (str) Package name # (str) Package name
package.name = bluewhale package.name = bitapp
# (str) Package domain (needed for android/ios packaging) # (str) Package domain (needed for android/ios packaging)
package.domain = org.test package.domain = org.test
@ -35,21 +35,31 @@ version = 0.1
# version.filename = %(source.dir)s/main.py # version.filename = %(source.dir)s/main.py
# (list) Application requirements # (list) Application requirements
# comma seperated e.g. requirements = sqlite3,kivy # comma separated e.g. requirements = sqlite3,kivy
requirements = python2, sqlite3, kivy, openssl, bitmsghash, libexpat, kivymd requirements =
openssl,
sqlite3,
python2,
kivy,
bitmsghash,
kivymd,
kivy-garden,
qrcode,
Pillow,
msgpack
# (str) Custom source folders for requirements # (str) Custom source folders for requirements
# Sets custom source for any requirements with recipes # Sets custom source for any requirements with recipes
# requirements.source.kivy = ../../kivy # requirements.source.kivy = ../../kivy
# (list) Garden requirements # (list) Garden requirements
#garden_requirements = garden_requirements = qrcode
# (str) Presplash of the application # (str) Presplash of the application
presplash.filename = "images/presplas.gif" #presplash.filename = %(source.dir)s/data/presplash.png
# (str) Icon of the application # (str) Icon of the application
icon.filename ='images/if_android_1220385.png' #icon.filename = %(source.dir)s/data/icon.png
# (str) Supported orientation (one of landscape, portrait or all) # (str) Supported orientation (one of landscape, portrait or all)
orientation = portrait orientation = portrait
@ -88,28 +98,28 @@ fullscreen = 0
android.permissions = INTERNET, WRITE_EXTERNAL_STORAGE, READ_EXTERNAL_STORAGE android.permissions = INTERNET, WRITE_EXTERNAL_STORAGE, READ_EXTERNAL_STORAGE
# (int) Android API to use # (int) Android API to use
android.api = 19 android.api = 27
# (int) Minimum API required # (int) Minimum API required
#android.minapi = 9 android.minapi = 21
# (int) Android SDK version to use # (int) Android SDK version to use
android.sdk = 20 android.sdk = 20
# (str) Android NDK version to use # (str) Android NDK version to use
android.ndk = 10e android.ndk = 17c
# (bool) Use --private data storage (True) or --dir public storage (False) # (bool) Use --private data storage (True) or --dir public storage (False)
#android.private_storage = True # android.private_storage = True
# (str) Android NDK directory (if empty, it will be automatically downloaded.) # (str) Android NDK directory (if empty, it will be automatically downloaded.)
android.ndk_path =/home/cis/Downloads/android-ndk-r10e #android.ndk_path =
# (str) Android SDK directory (if empty, it will be automatically downloaded.) # (str) Android SDK directory (if empty, it will be automatically downloaded.)
android.sdk_path =/home/cis/Android/Sdk #android.sdk_path =
# (str) ANT directory (if empty, it will be automatically downloaded.) # (str) ANT directory (if empty, it will be automatically downloaded.)
android.ant_path =/home/cis/apache-ant-1.10.5 #android.ant_path =
# (bool) If True, then skip trying to update the Android sdk # (bool) If True, then skip trying to update the Android sdk
# This can be useful to avoid excess Internet downloads or save time # This can be useful to avoid excess Internet downloads or save time
@ -146,7 +156,10 @@ android.ant_path =/home/cis/apache-ant-1.10.5
# bootstrap) # bootstrap)
#android.gradle_dependencies = #android.gradle_dependencies =
# (str) python-for-android branch to use, defaults to master # (list) Java classes to add as activities to the manifest.
#android.add_activites = com.example.ExampleActivity
# (str) python-for-android branch to use, defaults to stable
p4a.branch = master p4a.branch = master
# (str) OUYA Console category. Should be one of GAME or APP # (str) OUYA Console category. Should be one of GAME or APP
@ -159,7 +172,10 @@ p4a.branch = master
# (str) XML file to include as an intent filters in <activity> tag # (str) XML file to include as an intent filters in <activity> tag
#android.manifest.intent_filters = #android.manifest.intent_filters =
# (list) Android additionnal libraries to copy into libs/armeabi # (str) launchMode to set for the main activity
#android.manifest.launch_mode = standard
# (list) Android additional libraries to copy into libs/armeabi
#android.add_libs_armeabi = libs/android/*.so #android.add_libs_armeabi = libs/android/*.so
#android.add_libs_armeabi_v7a = libs/android-v7/*.so #android.add_libs_armeabi_v7a = libs/android-v7/*.so
#android.add_libs_x86 = libs/android-x86/*.so #android.add_libs_x86 = libs/android-x86/*.so
@ -193,7 +209,7 @@ android.arch = armeabi-v7a
#p4a.source_dir = #p4a.source_dir =
# (str) The directory in which python-for-android should look for your own build recipes (if any) # (str) The directory in which python-for-android should look for your own build recipes (if any)
p4a.local_recipes =/home/cis/Desktop/Mobileandroid/peter_android/PyBitmessage/src/bitmessagekivy/android/python-for-android/recipes/ p4a.local_recipes = /home/cis/navjotrepo/PyBitmessage/src/bitmessagekivy/android/python-for-android/recipes/
# (str) Filename to the hook for p4a # (str) Filename to the hook for p4a
#p4a.hook = #p4a.hook =
@ -201,6 +217,9 @@ p4a.local_recipes =/home/cis/Desktop/Mobileandroid/peter_android/PyBitmessage/sr
# (str) Bootstrap to use for android builds # (str) Bootstrap to use for android builds
# p4a.bootstrap = sdl2 # p4a.bootstrap = sdl2
# (int) port number to specify an explicit --port= p4a argument (eg for bootstrap flask)
#p4a.port =
# #
# iOS specific # iOS specific

View File

@ -92,7 +92,7 @@ class singleCleaner(StoppableThread):
queryreturn = sqlQuery( queryreturn = sqlQuery(
"SELECT toaddress, ackdata, status FROM sent" "SELECT toaddress, ackdata, status FROM sent"
" WHERE ((status='awaitingpubkey' OR status='msgsent')" " WHERE ((status='awaitingpubkey' OR status='msgsent')"
" AND folder='sent' AND sleeptill<? AND senttime>?)", " AND folder LIKE '%sent%' AND sleeptill<? AND senttime>?)",
int(time.time()), int(time.time()) - int(time.time()), int(time.time()) -
shared.maximumLengthOfTimeToBotherResendingMessages shared.maximumLengthOfTimeToBotherResendingMessages
) )

View File

@ -71,7 +71,7 @@ class singleWorker(StoppableThread):
# Initialize the neededPubkeys dictionary. # Initialize the neededPubkeys dictionary.
queryreturn = sqlQuery( queryreturn = sqlQuery(
'''SELECT DISTINCT toaddress FROM sent''' '''SELECT DISTINCT toaddress FROM sent'''
''' WHERE (status='awaitingpubkey' AND folder='sent')''') ''' WHERE (status='awaitingpubkey' AND folder LIKE '%sent%')''')
for row in queryreturn: for row in queryreturn:
toAddress, = row toAddress, = row
# toStatus # toStatus
@ -514,7 +514,7 @@ class singleWorker(StoppableThread):
queryreturn = sqlQuery( queryreturn = sqlQuery(
'''SELECT fromaddress, subject, message, ''' '''SELECT fromaddress, subject, message, '''
''' ackdata, ttl, encodingtype FROM sent ''' ''' ackdata, ttl, encodingtype FROM sent '''
''' WHERE status=? and folder='sent' ''', 'broadcastqueued') ''' WHERE status=? and folder LIKE '%sent%' ''', 'broadcastqueued')
for row in queryreturn: for row in queryreturn:
fromaddress, subject, body, ackdata, TTL, encoding = row fromaddress, subject, body, ackdata, TTL, encoding = row
@ -684,7 +684,7 @@ class singleWorker(StoppableThread):
'''SELECT toaddress, fromaddress, subject, message, ''' '''SELECT toaddress, fromaddress, subject, message, '''
''' ackdata, status, ttl, retrynumber, encodingtype FROM ''' ''' ackdata, status, ttl, retrynumber, encodingtype FROM '''
''' sent WHERE (status='msgqueued' or status='forcepow') ''' ''' sent WHERE (status='msgqueued' or status='forcepow') '''
''' and folder='sent' ''') ''' and folder LIKE '%sent%' ''')
# while we have a msg that needs some work # while we have a msg that needs some work
for row in queryreturn: for row in queryreturn:
toaddress, fromaddress, subject, message, \ toaddress, fromaddress, subject, message, \
@ -1213,6 +1213,7 @@ class singleWorker(StoppableThread):
powStartTime = time.time() powStartTime = time.time()
initialHash = hashlib.sha512(encryptedPayload).digest() initialHash = hashlib.sha512(encryptedPayload).digest()
trialValue, nonce = proofofwork.run(target, initialHash) trialValue, nonce = proofofwork.run(target, initialHash)
print("nonce calculated value#############################", nonce)
logger.info( logger.info(
'(For msg message) Found proof of work %s Nonce: %s', '(For msg message) Found proof of work %s Nonce: %s',
trialValue, nonce trialValue, nonce

BIN
src/images/copy_text.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 461 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 475 B

View File

@ -1,7 +1,10 @@
from importlib import import_module from importlib import import_module
from os import path, listdir from os import path, listdir
from string import lower from string import lower
try:
from kivy.utils import platform
except:
platform = ''
from debug import logger from debug import logger
import messagetypes import messagetypes
import paths import paths
@ -32,7 +35,7 @@ def constructObject(data):
else: else:
return returnObj return returnObj
if paths.frozen is not None: if paths.frozen is not None or platform == "android":
import messagetypes.message import messagetypes.message
import messagetypes.vote import messagetypes.vote
else: else:

View File

@ -42,8 +42,7 @@ def lookupAppdataFolder():
print stringToLog print stringToLog
sys.exit() sys.exit()
elif platform == 'android': elif platform == 'android':
# dataFolder = path.join(os.path.dirname(os.path.abspath("__file__")), "PyBitmessage") + '/' dataFolder = path.join(os.environ['ANDROID_PRIVATE'] + '/', APPNAME) + '/'
dataFolder = path.join('/sdcard/', 'DCIM/', APPNAME) + '/'
elif 'win32' in sys.platform or 'win64' in sys.platform: elif 'win32' in sys.platform or 'win64' in sys.platform:
dataFolder = path.join(environ['APPDATA'].decode(sys.getfilesystemencoding(), 'ignore'), APPNAME) + path.sep dataFolder = path.join(environ['APPDATA'].decode(sys.getfilesystemencoding(), 'ignore'), APPNAME) + path.sep

View File

@ -1,4 +1,14 @@
#!/usr/bin/env python """
src/pyelliptic/openssl.py
=================================
"""
import sys
import ctypes
from kivy.utils import platform
OpenSSL = None
# !/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2011 Yann GUIBET <yannguibet@gmail.com> # Copyright (C) 2011 Yann GUIBET <yannguibet@gmail.com>
@ -6,13 +16,10 @@
# #
# Software slightly changed by Jonathan Warren <bitmessage at-symbol jonwarren.org> # Software slightly changed by Jonathan Warren <bitmessage at-symbol jonwarren.org>
import sys
import ctypes
OpenSSL = None class CipherName: # pylint: disable=old-style-class
from kivy.utils import platform """Method helps to get pointers, name and blocksize"""
class CipherName:
def __init__(self, name, pointer, blocksize): def __init__(self, name, pointer, blocksize):
self._name = name self._name = name
self._pointer = pointer self._pointer = pointer
@ -24,16 +31,20 @@ class CipherName:
" | Function pointer : " + str(self._pointer) " | Function pointer : " + str(self._pointer)
def get_pointer(self): def get_pointer(self):
"""Method returns the pointer"""
return self._pointer() return self._pointer()
def get_name(self): def get_name(self):
"""Method returns the name"""
return self._name return self._name
def get_blocksize(self): def get_blocksize(self):
"""Method returns the blocksize"""
return self._blocksize return self._blocksize
def get_version(library): def get_version(library):
"""Method returns the version of the OpenSSL Library"""
version = None version = None
hexversion = None hexversion = None
cflags = None cflags = None
@ -64,14 +75,11 @@ def get_version(library):
return (version, hexversion, cflags) return (version, hexversion, cflags)
class _OpenSSL: class _OpenSSL: # pylint: disable=too-many-instance-attributes, old-style-class, too-many-statements
""" """Wrapper for OpenSSL using ctypes"""
Wrapper for OpenSSL using ctypes
"""
def __init__(self, library): def __init__(self, library):
""" """Build the wrapper"""
Build the wrapper
"""
self._lib = ctypes.CDLL(library) self._lib = ctypes.CDLL(library)
self._version, self._hexversion, self._cflags = get_version(self._lib) self._version, self._hexversion, self._cflags = get_version(self._lib)
self._libreSSL = self._version.startswith("LibreSSL") self._libreSSL = self._version.startswith("LibreSSL")
@ -594,6 +602,7 @@ class _OpenSSL:
""" """
returns the name of a elliptic curve with his id returns the name of a elliptic curve with his id
""" """
# pylint: disable=redefined-builtin
res = None res = None
for i in self.curves: for i in self.curves:
if self.curves[i] == id: if self.curves[i] == id:
@ -607,6 +616,7 @@ class _OpenSSL:
""" """
OpenSSL random function OpenSSL random function
""" """
# pylint: disable=redefined-builtin
buffer = self.malloc(0, size) buffer = self.malloc(0, size)
# This pyelliptic library, by default, didn't check the return value of RAND_bytes. It is # This pyelliptic library, by default, didn't check the return value of RAND_bytes. It is
# evidently possible that it returned an error and not-actually-random data. However, in # evidently possible that it returned an error and not-actually-random data. However, in
@ -623,6 +633,7 @@ class _OpenSSL:
""" """
returns a create_string_buffer (ctypes) returns a create_string_buffer (ctypes)
""" """
# pylint: disable=redefined-builtin
buffer = None buffer = None
if data != 0: if data != 0:
if sys.version_info.major == 3 and isinstance(data, type('')): if sys.version_info.major == 3 and isinstance(data, type('')):
@ -634,6 +645,8 @@ class _OpenSSL:
def loadOpenSSL(): def loadOpenSSL():
"""Method find and load the OpenSSL library"""
# pylint: disable=global-statement, protected-access, too-many-branches
global OpenSSL global OpenSSL
from os import path, environ from os import path, environ
from ctypes.util import find_library from ctypes.util import find_library
@ -673,14 +686,18 @@ def loadOpenSSL():
elif platform == "android": elif platform == "android":
libdir.append('libcrypto1.0.2p.so') libdir.append('libcrypto1.0.2p.so')
libdir.append('libssl1.0.2p.so') libdir.append('libssl1.0.2p.so')
libdir.append('libcrypto1.1.so')
libdir.append('libssl1.1.so')
else: else:
libdir.append('libcrypto.so') libdir.append('libcrypto.so')
libdir.append('libssl.so') libdir.append('libssl.so')
libdir.append('libcrypto.so.1.0.0') libdir.append('libcrypto.so.1.0.0')
libdir.append('libssl.so.1.0.0') libdir.append('libssl.so.1.0.0')
if 'linux' in sys.platform or 'darwin' in sys.platform or 'bsd' in sys.platform: if 'linux' in sys.platform or 'darwin' in sys.platform or 'bsd' in sys.platform:
libdir.append(find_library('ssl')) try:
libdir.append(find_library('ssl'))
except OSError:
pass
elif 'win32' in sys.platform or 'win64' in sys.platform: elif 'win32' in sys.platform or 'win64' in sys.platform:
libdir.append(find_library('libeay32')) libdir.append(find_library('libeay32'))
for library in libdir: for library in libdir:

View File

@ -98,6 +98,18 @@ trash_count = 0
draft_count = 0 draft_count = 0
all_count = 0
searcing_text = '' searcing_text = ''
search_screen = '' search_screen = ''
send_draft_mail = None
is_allmail = False
in_composer = False
write_msg = {}
availabe_credit = 0

View File

@ -13,28 +13,24 @@ class translateClass:
else: else:
return self.text return self.text
# def _translate(context, text, disambiguation = None, encoding = None, n = None):
# return translateText(context, text, n)
def _translate(context, text, disambiguation = None, encoding = None, n = None): def _translate(context, text, disambiguation = None, encoding = None, n = None):
return text return translateText(context, text, n)
# def _translate(context, text, disambiguation = None, encoding = None, n = None):
# return translateClass(context, text.replace('%','',1))
def translateText(context, text, n = None): def translateText(context, text, n = None):
try: try:
enableGUI = state.enableGUI enableGUI = state.enableGUI
except AttributeError: # inside the plugin except AttributeError: # inside the plugin
enableGUI = True enableGUI = True
if enableGUI: if not state.kivy and enableGUI:
try: try:
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
except Exception as err: except Exception as err:
try: print 'PyBitmessage requires PyQt unless you want to run it as a daemon and interact with it using the API. You can download PyQt from http://www.riverbankcomputing.com/software/pyqt/download or by searching Google for \'PyQt Download\'. If you want to run in daemon mode, see https://bitmessage.org/wiki/Daemon'
if state.kivy: print 'Error message:', err
pass os._exit(0)
except Exception as err:
print 'PyBitmessage requires PyQt unless you want to run it as a daemon and interact with it using the API. You can download PyQt from http://www.riverbankcomputing.com/software/pyqt/download or by searching Google for \'PyQt Download\'. If you want to run in daemon mode, see https://bitmessage.org/wiki/Daemon'
print 'Error message:', err
os._exit(0)
if n is None: if n is None:
return QtGui.QApplication.translate(context, text) return QtGui.QApplication.translate(context, text)
else: else: