""" Bitmessage kivy interface """ # pylint: disable=relative-import, import-error, no-name-in-module # pylint: disable=too-few-public-methods, too-many-lines, unused-argument 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.clock import Clock from kivy.core.clipboard import Clipboard from kivy.core.window import Window from kivy.lang import Builder from kivy.metrics import dp 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.label import Label 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.dialog import MDDialog from kivymd.label import MDLabel from kivymd.list import ( ILeftBody, ILeftBodyTouch, IRightBodyTouch, TwoLineAvatarIconListItem, TwoLineListItem ) from kivymd.navigationdrawer import ( MDNavigationDrawer, NavigationDrawerHeaderBase ) from kivymd.selectioncontrols import MDCheckbox from kivymd.theming import ThemeManager import queues from semaphores import kivyuisignaler import state from uikivysignaler import UIkivySignaler import identiconGeneration def toast(text): """Function displays toast message.""" # pylint: disable=redefined-outer-name from kivymd.toast.kivytoast import toast toast(text) return class Navigatorss(MDNavigationDrawer): """Navigator class contains image, title and logo.""" image_source = StringProperty('images/qidenticon_two.png') title = StringProperty('Navigation') drawer_logo = StringProperty() class Inbox(Screen): """Inbox Screen uses screen to show widgets of screens.""" queryreturn = ListProperty() has_refreshed = True def __init__(self, *args, **kwargs): """Method Parsing the address.""" super(Inbox, 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 inbox accounts.""" self.inboxaccounts() print dt def inboxaccounts(self): """Load inbox accounts.""" account = state.association self.loadMessagelist(account, 'All', '') def loadMessagelist(self, account, where="", what=""): """Load Inbox list for Inbox messages.""" # pylint: disable=too-many-locals if state.searcing_text: self.children[2].children[0].children[0].scroll_y = 1.0 where = ['subject', 'message'] what = state.searcing_text xAddress = 'toaddress' data = [] self.queryreturn = kivy_helper_search.search_sql( xAddress, account, "inbox", where, what, False) if self.queryreturn: src_mng_obj = state.kivyapp.root.children[2].children[0].ids src_mng_obj.inbox_cnt.badge_text = str(len(self.queryreturn)) state.inbox_count = str(len(self.queryreturn)) for mail in self.queryreturn[:20]: # third_text = mail[3].replace('\n', ' ') 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] + '........', 'msgid': mail[1]}) self.has_refreshed = True self.set_mdList(data) self.children[2].children[0].children[0].bind( scroll_y=self.check_scroll_y) else: content = MDLabel( font_style='Body1', theme_text_color='Primary', text="No message found!" if state.searcing_text else "yet no message for this account!!!!!!!!!!!!!", halign='center', bold=True, size_hint_y=None, valign='top') self.ids.ml.add_widget(content) def set_mdList(self, data): """This method is used to create the mdList""" 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.add_widget(AvatarSampleWidget( source='./images/text_images/{}.png'.format( avatarImageFirstLetter(item['secondary_text'].strip())))) meny.bind(on_press=partial( self.inbox_detail, item['msgid'])) 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, item['msgid'])) carousel.add_widget(del_btn) carousel.add_widget(meny) ach_btn = Button(text='Achieve') ach_btn.background_color = (0, 1, 0, 1) ach_btn.bind(on_press=partial( self.archive, item['msgid'])) carousel.add_widget(ach_btn) carousel.index = 1 self.ids.ml.add_widget(carousel) def check_scroll_y(self, instance, somethingelse): """This method is used to load data on scroll""" if self.children[2].children[0].children[ 0].scroll_y <= -0.0 and self.has_refreshed: self.children[2].children[0].children[0].scroll_y = 0.06 total_message = len(self.ids.ml.children) if total_message != len(self.queryreturn): self.update_inbox_screen_on_scroll(total_message) self.has_refreshed = True if total_message != len( self.queryreturn) else False else: pass def update_inbox_screen_on_scroll(self, total_message): """This method is used to load more data on scroll down""" data = [] for mail in self.queryreturn[total_message:total_message + 5]: # third_text = mail[3].replace('\n', ' ') 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] + '........', 'msgid': mail[1]}) self.set_mdList(data) def inbox_detail(self, msg_id, *args): """Load inbox page details.""" state.detailPageType = 'inbox' state.mail_id = msg_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 delete(self, data_index, instance, *args): """Delete inbox mail from inbox listing.""" sqlExecute( "UPDATE inbox SET folder = 'trash' WHERE msgid = ?;", str( 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.inbox_count) > 0: msg_count_objs.inbox_cnt.badge_text = str( int(state.inbox_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.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() def archive(self, data_index, instance, *args): """Archive inbox mail from inbox listing.""" sqlExecute( "UPDATE inbox SET folder = 'trash' WHERE msgid = ?;", str( data_index)) self.ids.ml.remove_widget(instance.parent.parent) self.update_trash() def update_trash(self): """Update trash screen mails which is deleted from inbox.""" try: self.parent.screens[4].clear_widgets() self.parent.screens[4].add_widget(Trash()) except Exception: self.parent.parent.screens[4].clear_widgets() self.parent.parent.screens[4].add_widget(Trash()) # 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 inbox screen data.""" state.searcing_text = '' self.children[2].children[1].ids.search_field.text = '' self.ids.ml.clear_widgets() self.loadMessagelist(state.association) self.has_refreshed = True self.ids.refresh_layout.refresh_done() self.tick = 0 Clock.schedule_once(refresh_callback, 1) def set_root_layout(self): """Setting root layout""" return self.parent.parent.parent class MyAddress(Screen): """MyAddress Screen uses screen to show widgets of screens.""" addresses_list = ListProperty() has_refreshed = True def __init__(self, *args, **kwargs): """Clock Schdule for method inbox accounts.""" super(MyAddress, self).__init__(*args, **kwargs) Clock.schedule_once(self.init_ui, 0) def init_ui(self, dt=0): """Clock Schdule for method inbox accounts.""" # pylint: disable=unnecessary-lambda, deprecated-lambda self.addresses_list = state.kivyapp.variable_1 if state.searcing_text: self.ids.refresh_layout.scroll_y = 1.0 filtered_list = filter( lambda addr: self.filter_address( addr), BMConfigParser().addresses()) self.addresses_list = filtered_list self.addresses_list = [obj for obj in reversed(self.addresses_list)] if self.addresses_list: self.has_refreshed = True self.set_mdList(0, 15) self.ids.refresh_layout.bind(scroll_y=self.check_scroll_y) else: content = MDLabel( font_style='Body1', theme_text_color='Primary', text="No address found!" if state.searcing_text else "yet no address is created by user!!!!!!!!!!!!!", halign='center', bold=True, size_hint_y=None, valign='top') self.ids.ml.add_widget(content) if not state.searcing_text: try: self.manager.current = 'login' except Exception: pass def set_mdList(self, first_index, last_index): """This method is used to create the mdlist""" data = [] for address in self.addresses_list[first_index:last_index]: data.append({ 'text': BMConfigParser().get(address, 'label'), 'secondary_text': address}) 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.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) def check_scroll_y(self, instance, somethingelse): """This method is used to load data on scroll""" if self.ids.refresh_layout.scroll_y <= -0.0 and self.has_refreshed: self.ids.refresh_layout.scroll_y = 0.06 my_addresses = len(self.ids.ml.children) if my_addresses != len(self.addresses_list): self.update_addressBook_on_scroll(my_addresses) self.has_refreshed = True if my_addresses != len( self.addresses_list) else False else: pass def update_addressBook_on_scroll(self, my_addresses): """This method is used to load more data on scroll down""" self.set_mdList(my_addresses, my_addresses + 20) @staticmethod def myadd_detail(fromaddress, label, *args): """Myaddress Details.""" p = MyaddDetailPopup() p.open() p.set_address(fromaddress, label) # 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 myaddress screen data.""" state.searcing_text = '' state.kivyapp.root.ids.sc10.children[2].active = False self.children[2].children[1].ids.search_field.text = '' self.has_refreshed = True self.ids.ml.clear_widgets() self.init_ui() self.ids.refresh_layout.refresh_done() self.tick = 0 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 def set_root_layout(self): """Setting root layout""" return self.manager.parent.parent class AddressBook(Screen): """AddressBook Screen uses screen to show widgets of screens.""" queryreturn = ListProperty() has_refreshed = True def __init__(self, *args, **kwargs): """Getting AddressBook Details.""" super(AddressBook, self).__init__(*args, **kwargs) Clock.schedule_once(self.init_ui, 0) def init_ui(self, dt=0): """Clock Schdule for method AddressBook.""" self.loadAddresslist(None, 'All', '') print dt def loadAddresslist(self, account, where="", what=""): """Clock Schdule for method AddressBook.""" if state.searcing_text: self.ids.scroll_y.scroll_y = 1.0 where = ['label', 'address'] what = state.searcing_text xAddress = '' self.queryreturn = kivy_helper_search.search_sql( xAddress, account, "addressbook", where, what, False) self.queryreturn = [obj for obj in reversed(self.queryreturn)] if self.queryreturn: self.has_refreshed = True self.set_mdList(0, 20) self.ids.scroll_y.bind(scroll_y=self.check_scroll_y) else: content = MDLabel( font_style='Body1', theme_text_color='Primary', text="No contact found!" if state.searcing_text else "No contact found yet...... ", halign='center', bold=True, size_hint_y=None, valign='top') self.ids.ml.add_widget(content) def set_mdList(self, start_index, end_index): """This method is used to create the mdList""" for item in self.queryreturn[start_index:end_index]: 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.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_address, item[1])) carousel.add_widget(del_btn) carousel.add_widget(meny) carousel.index = 1 self.ids.ml.add_widget(carousel) def check_scroll_y(self, instance, somethingelse): """This method is used to load data on scroll""" if self.ids.scroll_y.scroll_y <= -0.0 and self.has_refreshed: self.ids.scroll_y.scroll_y = 0.06 exist_addresses = len(self.ids.ml.children) if exist_addresses != len(self.queryreturn): self.update_addressBook_on_scroll(exist_addresses) self.has_refreshed = True if exist_addresses != len( self.queryreturn) else False else: pass def update_addressBook_on_scroll(self, exist_addresses): """This method is used to load more data on scroll down""" self.set_mdList(exist_addresses, exist_addresses + 5) @staticmethod def refreshs(*args): """Refresh the Widget.""" # state.navinstance.ids.sc11.ids.ml.clear_widgets() # state.navinstance.ids.sc11.loadAddresslist(None, 'All', '') pass @staticmethod def addBook_detail(address, label, *args): """Addressbook Details.""" p = AddbookDetailPopup() p.open() p.set_addbook_data(address, label) def delete_address(self, address, instance, *args): """Delete inbox mail from inbox listing.""" self.ids.ml.remove_widget(instance.parent.parent) sqlExecute( "DELETE FROM addressbook WHERE address = '{}';".format(address)) class SelectableRecycleBoxLayout( FocusBehavior, LayoutSelectionBehavior, RecycleBoxLayout): """Adds selection and focus behaviour to the view.""" # pylint: disable = too-many-ancestors pass class SelectableLabel(RecycleDataViewBehavior, Label): """Add selection support to the Label.""" index = None selected = BooleanProperty(False) selectable = BooleanProperty(True) def refresh_view_attrs(self, rv, index, data): """Catch and handle the view changes.""" self.index = index return super(SelectableLabel, self).refresh_view_attrs( rv, index, data) # pylint: disable=inconsistent-return-statements def on_touch_down(self, touch): """Add selection on touch down.""" if super(SelectableLabel, self).on_touch_down(touch): return True if self.collide_point(*touch.pos) and self.selectable: return self.parent.select_with_touch(self.index, touch) def apply_selection(self, rv, index, is_selected): """Respond to the selection of items in the view.""" self.selected = is_selected if is_selected: 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']) class RV(RecycleView): """Recycling View.""" def __init__(self, **kwargs): """Recycling Method.""" # pylint: disable=useless-super-delegation super(RV, self).__init__(**kwargs) class DropDownWidget(BoxLayout): """Adding Dropdown Widget.""" # pylint: disable=too-many-statements, too-many-locals # pylint: disable=inconsistent-return-statements txt_input = ObjectProperty() rv = ObjectProperty() def send(self, navApp): """Send message from one address to another.""" fromAddress = str(self.ids.ti.text) toAddress = str(self.ids.txt_input.text) subject = self.ids.subject.text.encode('utf-8').strip() message = self.ids.body.text.encode('utf-8').strip() encoding = 3 print "message: ", self.ids.body.text sendMessageToPeople = True if sendMessageToPeople: if toAddress != '' and subject and message: from addresses import decodeAddress status, addressVersionNumber, streamNumber, ripe = ( decodeAddress(toAddress)) if status == 'success': navApp.root.ids.sc3.children[0].active = True if state.detailPageType == 'draft' \ and state.send_draft_mail: sqlExecute( "UPDATE sent SET toaddress = ?" ", fromaddress = ? , subject = ?" ", message = ?, folder = 'sent'" " WHERE ackdata = ?;", toAddress, fromAddress, subject, message, str(state.send_draft_mail)) self.parent.parent.screens[15].clear_widgets() self.parent.parent.screens[15].add_widget(Draft()) state.detailPageType = '' state.send_draft_mail = None else: from addresses import addBMIfNotPresent toAddress = addBMIfNotPresent(toAddress) statusIconColor = 'red' if (addressVersionNumber > 4) or ( addressVersionNumber <= 1): print "addressVersionNumber > 4"\ " or addressVersionNumber <= 1" if streamNumber > 1 or streamNumber == 0: print "streamNumber > 1 or streamNumber == 0" if statusIconColor == 'red': print "shared.statusIconColor == 'red'" stealthLevel = BMConfigParser().safeGetInt( 'bitmessagesettings', 'ackstealthlevel') from helper_ackPayload import genAckPayload ackdata = genAckPayload(streamNumber, stealthLevel) # 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.msg_counter_objs = self.parent.parent.parent.parent\ .parent.parent.children[2].children[0].ids # self.parent.parent.screens[0].ids.ml.clear_widgets() # self.parent.parent.screens[0].loadMessagelist(state.association) self.parent.parent.screens[3].update_sent_messagelist() self.parent.parent.screens[16].clear_widgets() self.parent.parent.screens[16].add_widget(Allmails()) Clock.schedule_once(self.callback_for_msgsend, 3) queues.workerQueue.put(('sendmessage', toAddress)) print "sqlExecute successfully #######################" state.in_composer = True return else: msg = 'Enter a valid recipients address' elif not toAddress: msg = 'Please fill the form' else: msg = 'Please fill the form' self.address_error_message(msg) @staticmethod def callback_for_msgsend(dt=0): """Callback method for messagesend""" state.kivyapp.root.ids.sc3.children[0].active = False state.in_sent_method = True state.kivyapp.back_press() toast('sent') # pylint: disable=attribute-defined-outside-init def address_error_message(self, msg): """Show Error Message.""" msg_dialog = MDDialog( text=msg, title='', size_hint=(.8, .25), text_button_ok='Ok', events_callback=self.callback_for_menu_items) msg_dialog.open() @staticmethod def callback_for_menu_items(text_item): """Method is used for getting the callback of alert box""" toast(text_item) 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 = '' toast("Reset message") 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): """Takes the text input in the field.""" txt_input = ObjectProperty() flt_list = ObjectProperty() word_list = ListProperty() starting_no = NumericProperty(3) suggestion_text = '' def __init__(self, **kwargs): """Getting Text Input.""" # pylint: disable=useless-super-delegation super(MyTextInput, self).__init__(**kwargs) def on_text(self, instance, value): """Find all the occurrence of the word.""" 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]] display_data = [] for i in matches: display_data.append({'text': i}) self.parent.parent.parent.parent.ids.rv.data = display_data if len(matches) <= 10: self.parent.height = (250 + (len(matches) * 20)) else: self.parent.height = 400 def keyboard_on_key_down(self, window, keycode, text, modifiers): """Key Down.""" if self.suggestion_text and keycode[1] == 'tab': self.insert_text(self.suggestion_text + ' ') return True return super(MyTextInput, self).keyboard_on_key_down( window, keycode, text, modifiers) class Payment(Screen): """Payment Method.""" def get_available_credits(self, instance): """Method helps to get the available credits""" # pylint: disable=no-self-use 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): """Login Screeen.""" pass class NetworkStat(Screen): """Method used to show network stat.""" 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_5 = StringProperty( 'Processed {0} object to be synced'.format('0')) def __init__(self, *args, **kwargs): """Init method for network stat.""" super(NetworkStat, self).__init__(*args, **kwargs) Clock.schedule_interval(self.init_ui, 1) def init_ui(self, dt=0): """Clock Schdule for method inbox accounts.""" import network.stats import shared from network import objectracker self.text_variable_1 = '{0} :: {1}'.format( 'Total Connections', str(len(network.stats.connectedHostsList()))) self.text_variable_2 = 'Processed {0} per-to-per messages'.format( str(shared.numberOfMessagesProcessed)) 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): """Navigate Content Drawer.""" pass class Random(Screen): """Generates Random Address.""" is_active = BooleanProperty(False) checked = StringProperty("") def generateaddress(self, navApp): """Method for Address Generator.""" entered_label = str(self.ids.label.text).strip() streamNumberForAddress = 1 label = self.ids.label.text eighteenByteRipe = False nonceTrialsPerByte = 1000 payloadLengthExtraBytes = 1000 lables = [BMConfigParser().get(obj, 'label') for obj in BMConfigParser().addresses()] if entered_label and entered_label not in lables: toast('Address Creating...') queues.addressGeneratorQueue.put(( 'createRandomAddress', 4, streamNumberForAddress, label, 1, "", eighteenByteRipe, nonceTrialsPerByte, payloadLengthExtraBytes)) self.ids.label.text = '' self.parent.parent.children[1].opacity = 1 self.parent.parent.children[1].disabled = False state.kivyapp.root.ids.sc10.children[1].active = True self.manager.current = 'myaddress' Clock.schedule_once(self.address_created_callback, 6) def address_created_callback(self, dt=0): """New address created""" state.kivyapp.root.ids.sc10.children[1].active = False state.kivyapp.root.ids.sc10.ids.ml.clear_widgets() state.kivyapp.root.ids.sc10.init_ui() self.manager.current = 'myaddress' toast('New address created') def add_validation(self, instance): """Checking validation at address creation time.""" entered_label = str(instance.text.strip()) lables = [BMConfigParser().get(obj, 'label') for obj in BMConfigParser().addresses()] if entered_label in lables: self.ids.label.error = True self.ids.label.helper_text = 'Label name is already exist you can try this Ex. ( {0}_1, {0}_2 )'.format(entered_label) elif entered_label: self.ids.label.error = False else: self.ids.label.error = False self.ids.label.helper_text = 'This field is required' def reset_address_label(self): self.ids.label.text = '' class Sent(Screen): """Sent Screen uses screen to show widgets of screens.""" queryreturn = ListProperty() has_refreshed = True def __init__(self, *args, **kwargs): """Association with the screen.""" super(Sent, 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 sent accounts.""" self.sentaccounts() print dt def sentaccounts(self): """Load sent accounts.""" account = state.association self.loadSent(account, 'All', '') def loadSent(self, account, where="", what=""): """Load Sent list for Sent messages.""" if state.searcing_text: self.ids.scroll_y.scroll_y = 1.0 where = ['subject', 'message'] what = state.searcing_text xAddress = 'fromaddress' data = [] self.queryreturn = kivy_helper_search.search_sql( xAddress, account, "sent", where, what, False) if state.msg_counter_objs and state.association == ( state.check_sent_acc): state.msg_counter_objs.send_cnt.badge_text = str( len(self.queryreturn)) 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 if self.queryreturn: self.set_sentCount(len(self.queryreturn)) for mail in self.queryreturn[0:20]: data.append({ 'text': mail[1].strip(), 'secondary_text': mail[2][:50] + '........' if len( mail[2]) >= 50 else (mail[2] + ',' + mail[3].replace( '\n', ''))[0:50] + '........', 'ackdata': mail[5]}) self.set_mdlist(data, 0) self.has_refreshed = True self.ids.scroll_y.bind(scroll_y=self.check_scroll_y) else: content = MDLabel( font_style='Body1', theme_text_color='Primary', text="No message found!" if state.searcing_text else "yet no message for this account!!!!!!!!!!!!!", halign='center', bold=True, size_hint_y=None, valign='top') self.ids.ml.add_widget(content) def set_mdlist(self, data, set_index): """This method is used to create the mdList""" 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.add_widget(AvatarSampleWidget( source='./images/text_images/{}.png'.format( avatarImageFirstLetter(item['secondary_text'].strip())))) meny.bind(on_press=partial( self.sent_detail, item['ackdata'])) 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, item['ackdata'])) carousel.add_widget(del_btn) carousel.add_widget(meny) ach_btn = Button(text='Achieve') ach_btn.background_color = (0, 1, 0, 1) ach_btn.bind(on_press=partial( self.archive, item['ackdata'])) carousel.add_widget(ach_btn) carousel.index = 1 self.ids.ml.add_widget(carousel, index=set_index) def update_sent_messagelist(self): """This method is used to update screen when new mail is sent""" if len(self.ids.ml.children) < 3: self.ids.ml.clear_widgets() self.loadSent(state.association) else: account = state.association data = [] self.queryreturn = kivy_helper_search.search_sql( 'fromaddress', account, "sent", '', '', False) total_sent = len(self.queryreturn) self.set_sentCount(total_sent) for mail in self.queryreturn[:1]: data.append({ 'text': mail[1].strip(), 'secondary_text': mail[2][:50] + '........' if len( mail[2]) >= 50 else (mail[2] + ',' + mail[3].replace( '\n', ''))[0:50] + '........', 'ackdata': mail[5]}) self.set_mdlist(data, total_sent - 1) def check_scroll_y(self, instance, somethingelse): """This method is used to load data on scroll""" if self.ids.scroll_y.scroll_y <= -0.0 and self.has_refreshed: self.ids.scroll_y.scroll_y = 0.06 total_sent_msg = len(self.ids.ml.children) if total_sent_msg != len(self.queryreturn): self.update_sent_screen_on_scroll(total_sent_msg) self.has_refreshed = True if total_sent_msg != len( self.queryreturn) else False else: pass def update_sent_screen_on_scroll(self, total_sent_msg): """This method is used to load more data on scroll down""" data = [] for mail in self.queryreturn[total_sent_msg:total_sent_msg + 5]: data.append({ 'text': mail[1].strip(), 'secondary_text': mail[2][:50] + '........' if len( mail[2]) >= 50 else (mail[2] + ',' + mail[3].replace( '\n', ''))[0:50] + '........', 'ackdata': mail[5]}) self.set_mdlist(data, 0) @staticmethod def set_sentCount(total_sent): """Set the total no. of sent message count""" src_mng_obj = state.kivyapp.root.children[2].children[0].ids src_mng_obj.send_cnt.badge_text = str(total_sent) state.sent_count = str(total_sent) def sent_detail(self, ackdata, *args): """Load sent mail details.""" state.detailPageType = 'sent' state.mail_id = ackdata 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 delete(self, data_index, instance, *args): """Delete sent mail from sent mail listing.""" 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.sent_count) > 0: msg_count_objs.send_cnt.badge_text = str( 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.trash_count = str(int(state.trash_count) + 1) state.all_count = str(int(state.all_count) - 1) sqlExecute( "UPDATE sent SET folder = 'trash'" " WHERE ackdata = ?;", str(data_index)) self.ids.ml.remove_widget(instance.parent.parent) toast('Deleted') self.update_trash() def archive(self, data_index, instance, *args): """Archive sent mail from sent mail listing.""" sqlExecute( "UPDATE sent SET folder = 'trash'" " WHERE ackdata = ?;", str(data_index)) self.ids.ml.remove_widget(instance.parent.parent) self.update_trash() def update_trash(self): """Update trash screen mails which is deleted from inbox.""" try: 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()) except Exception: self.parent.parent.screens[4].clear_widgets() 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): """Trash Screen uses screen to show widgets of screens.""" trash_messages = ListProperty() has_refreshed = True delete_index = StringProperty() table_name = StringProperty() def __init__(self, *args, **kwargs): """Trash method, delete sent message and add in Trash.""" super(Trash, self).__init__(*args, **kwargs) Clock.schedule_once(self.init_ui, 0) def init_ui(self, dt=0): """Clock Schdule for method inbox accounts.""" if state.association == '': if BMConfigParser().addresses(): state.association = BMConfigParser().addresses()[0] self.trash_messages = sqlQuery( "SELECT toaddress, fromaddress, subject, message," " folder ||',' || 'sent' as folder, ackdata As id," " DATE(lastactiontime) As actionTime FROM sent" " WHERE folder = 'trash' and fromaddress = '{0}' UNION" " SELECT toaddress, fromaddress, subject, message," " folder ||',' || 'inbox' as folder, msgid As id," " DATE(received) As actionTime FROM inbox WHERE" " folder = 'trash' and toaddress = '{0}'" " ORDER BY actionTime DESC".format(state.association)) if self.trash_messages: src_mng_obj = state.kivyapp.root.children[2].children[0].ids src_mng_obj.trash_cnt.badge_text = str(len(self.trash_messages)) state.trash_count = str(len(self.trash_messages)) self.set_mdList(0, 20) self.ids.scroll_y.bind(scroll_y=self.check_scroll_y) 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 set_mdList(self, first_index, last_index): """This method is used to create the mdlist""" for item in self.trash_messages[first_index:last_index]: 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], item[4])) carousel.add_widget(del_btn) carousel.add_widget(meny) carousel.index = 1 self.ids.ml.add_widget(carousel) def check_scroll_y(self, instance, somethingelse): """This method is used to load data on scroll""" if self.ids.scroll_y.scroll_y <= -0.0 and self.has_refreshed: self.ids.scroll_y.scroll_y = 0.06 total_trash_msg = len(self.ids.ml.children) if total_trash_msg != len(self.trash_messages): self.update_trash_screen_on_scroll(total_trash_msg) self.has_refreshed = True if total_trash_msg != len( self.trash_messages) else False else: pass def update_trash_screen_on_scroll(self, total_trash_msg): """This method is used to load more data on scroll down""" self.set_mdList(total_trash_msg, total_trash_msg + 5) def delete_permanently(self, data_index, folder, instance, *args): """Deleting trash mail permanently.""" self.table_name = folder.split(',')[1] self.delete_index = data_index self.delete_confirmation() def callback_for_screen_load(self, dt=0): """This methos is for loading screen""" self.ids.ml.clear_widgets() self.init_ui(0) self.children[1].active = False toast('Message is permanently deleted') def delete_confirmation(self): """This method is used to show delete confirmation popup""" delete_msg_dialog = MDDialog( text='Are you sure you want to delete this' / ' message permanently from trash?', title='', size_hint=(.8, .25), text_button_ok='Yes', text_button_cancel='No', events_callback=self.callback_for_delete_msg) delete_msg_dialog.open() def callback_for_delete_msg(self, text_item): """Method is used for getting the callback of alert box""" if text_item == 'Yes': self.delete_message_from_trash() else: toast(text_item) def delete_message_from_trash(self): """This method is used to delete """ self.children[1].active = True if self.table_name == 'inbox': sqlExecute("DELETE FROM inbox WHERE msgid = ?;", str( self.delete_index)) elif self.table_name == 'sent': sqlExecute("DELETE FROM sent WHERE ackdata = ?;", str( self.delete_index)) msg_count_objs = state.kivyapp.root.children[2].children[0].ids if int(state.trash_count) > 0: msg_count_objs.trash_cnt.badge_text = str( int(state.trash_count) - 1) state.trash_count = str(int(state.trash_count) - 1) Clock.schedule_once(self.callback_for_screen_load, 1) class Page(Screen): """Page Screen show widgets of page.""" pass class Create(Screen): """Creates the screen widgets.""" def __init__(self, **kwargs): """Getting Labels and address from addressbook.""" super(Create, self).__init__(**kwargs) widget_1 = DropDownWidget() widget_1.ids.txt_input.word_list = [ addr[1] for addr in sqlQuery( "SELECT label, address from addressbook")] widget_1.ids.txt_input.starting_no = 2 self.add_widget(widget_1) class Setting(Screen): """Setting the Screen components.""" pass class NavigateApp(App): """Navigation Layout of class.""" # pylint: disable=too-many-public-methods theme_cls = ThemeManager() previous_date = ObjectProperty() obj_1 = ObjectProperty() variable_1 = ListProperty(BMConfigParser().addresses()) nav_drawer = ObjectProperty() state.screen_density = Window.size window_size = state.screen_density title = "PyBitmessage" imgstatus = False count = 0 menu_items = [ {'viewclass': 'MDMenuItem', 'text': 'Example item'}, {'viewclass': 'MDMenuItem', 'text': 'Example item'}, {'viewclass': 'MDMenuItem', 'text': 'Example item'}, {'viewclass': 'MDMenuItem', 'text': 'Example item'}, {'viewclass': 'MDMenuItem', 'text': 'Example item'}, {'viewclass': 'MDMenuItem', 'text': 'Example item'}, {'viewclass': 'MDMenuItem', 'text': 'Example item'}, ] def build(self): """Method builds the widget.""" main_widget = Builder.load_file( os.path.join(os.path.dirname(__file__), 'main.kv')) self.nav_drawer = Navigatorss() self.obj_1 = AddressBook() kivysignalthread = UIkivySignaler() kivysignalthread.daemon = True kivysignalthread.start() Window.bind(on_keyboard=self.on_key) return main_widget def run(self): """Running the widgets.""" kivyuisignaler.release() super(NavigateApp, self).run() # pylint: disable=inconsistent-return-statements @staticmethod def showmeaddresses(name="text"): """Show the addresses in spinner to make as dropdown.""" if name == "text": if BMConfigParser().addresses(): return BMConfigParser().addresses()[0][:16] + '..' return "textdemo" elif name == "values": if BMConfigParser().addresses(): return [address[:16] + '..' for address in BMConfigParser().addresses()] return "valuesdemo" def getCurrentAccountData(self, text): """Get Current Address Account Data.""" 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 state.association = text state.searcing_text = '' LoadingPopup().open() self.root.ids.sc1.ids.ml.clear_widgets() self.root.ids.sc1.loadMessagelist(state.association) self.root.ids.sc4.ids.ml.clear_widgets() self.root.ids.sc4.children[2].children[1].ids.search_field.text = '' self.root.ids.sc4.loadSent(state.association) self.root.ids.sc16.clear_widgets() self.root.ids.sc16.add_widget(Draft()) self.root.ids.sc5.clear_widgets() self.root.ids.sc5.add_widget(Trash()) self.root.ids.sc17.clear_widgets() self.root.ids.sc17.add_widget(Allmails()) self.root.ids.scr_mngr.current = 'inbox' msg_counter_objs = ( self.root_window.children[2].children[2].children[0].ids) state.sent_count = str( sqlQuery( "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: msg_counter_objs.send_cnt.badge_text = state.sent_count msg_counter_objs.inbox_cnt.badge_text = state.inbox_count msg_counter_objs.trash_cnt.badge_text = state.trash_count msg_counter_objs.draft_cnt.badge_text = state.draft_count msg_counter_objs.allmail_cnt.badge_text = state.all_count @staticmethod def getCurrentAccount(): """It uses to get current account label.""" if state.association: return state.association return "Bitmessage Login" @staticmethod def addingtoaddressbook(): """Adding to address Book.""" p = GrashofPopup() p.open() def getDefaultAccData(self): """Getting Default Account Data.""" if BMConfigParser().addresses(): img = identiconGeneration.generate(BMConfigParser().addresses()[0]) self.createFolder('./images/default_identicon/') if platform == 'android': # android_path = os.path.expanduser # ("~/user/0/org.test.bitapp/files/app/") android_path = os.path.join( os.environ['ANDROID_PRIVATE'] + '/app/') img.texture.save('{1}/images/default_identicon/{0}.png'.format( BMConfigParser().addresses()[0], android_path)) else: img.texture.save( './images/default_identicon/{}.png'.format( BMConfigParser().addresses()[0])) return BMConfigParser().addresses()[0] return 'Select Address' @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 './images/no_identicons.png' @staticmethod def addressexist(): """Checking address existence.""" if BMConfigParser().addresses(): return True return False def on_key(self, window, key, *args): """Method is used for going on previous screen.""" if key == 27: if state.in_search_mode and self.root.ids.scr_mngr.current != ( "mailDetail"): self.closeSearchScreen() elif self.root.ids.scr_mngr.current == "mailDetail": self.root.ids.scr_mngr.current = 'sent'\ if state.detailPageType == 'sent' else 'inbox' \ if state.detailPageType == 'inbox' else 'draft' self.back_press() elif self.root.ids.scr_mngr.current == "create": self.save_draft() self.set_common_header() state.in_composer = False self.root.ids.scr_mngr.current = 'inbox' elif self.root.ids.scr_mngr.current == "showqrcode": self.root.ids.scr_mngr.current = 'myaddress' elif self.root.ids.scr_mngr.current == "random": self.root.ids.scr_mngr.current = 'login' else: self.root.ids.scr_mngr.current = 'inbox' self.root.ids.scr_mngr.transition.direction = 'right' self.root.ids.scr_mngr.transition.bind(on_complete=self.reset) return True elif key == 13: if state.search_screen == 'inbox' and state.searcing_text: self.root.ids.sc1.children[1].active = True Clock.schedule_once(self.search_callback, 0.5) elif state.search_screen == 'addressbook': self.root.ids.sc11.children[1].active = True Clock.schedule_once(self.search_callback, 0.5) elif state.search_screen == 'myaddress': self.root.ids.sc10.children[1].active = True Clock.schedule_once(self.search_callback, 0.5) elif state.search_screen == 'sent': self.root.ids.sc4.children[1].active = True Clock.schedule_once(self.search_callback, 0.5) def search_callback(self, dt=0): """This method is used to show data after loader is loaded""" if state.search_screen == 'inbox': self.root.ids.sc1.ids.ml.clear_widgets() self.root.ids.sc1.loadMessagelist(state.association) self.root.ids.sc1.children[1].active = False elif state.search_screen == 'addressbook': self.root.ids.sc11.ids.ml.clear_widgets() self.root.ids.sc11.loadAddresslist(None, 'All', '') self.root.ids.sc11.children[1].active = False elif state.search_screen == 'myaddress': self.root.ids.sc10.ids.ml.clear_widgets() self.root.ids.sc10.init_ui() self.root.ids.sc10.children[1].active = False else: self.root.ids.sc4.ids.ml.clear_widgets() self.root.ids.sc4.loadSent(state.association) self.root.ids.sc4.children[1].active = False self.root.ids.scr_mngr.current = state.search_screen def save_draft(self): """Saving drafts messages""" composer_objs = self.root from_addr = str(self.root.ids.sc3.children[1].ids.ti.text) to_addr = str(self.root.ids.sc3.children[1].ids.txt_input.text) if from_addr and to_addr and state.detailPageType != 'draft' \ and not state.in_sent_method: Draft().draft_msg(composer_objs) return def reset(self, *args): """Method used to set transition direction.""" self.root.ids.scr_mngr.transition.direction = 'left' self.root.ids.scr_mngr.transition.unbind(on_complete=self.reset) @staticmethod def status_dispatching(data): """Method used for status dispatching acknowledgment.""" ackData, message = data if state.ackdata == ackData: state.status.status = message def clear_composer(self): """If slow down the nwe will make new composer edit screen.""" self.set_navbar_for_composer() composer_obj = self.root.ids.sc3.children[1].ids composer_obj.ti.text = '' composer_obj.btn.text = 'Select' composer_obj.txt_input.text = '' composer_obj.subject.text = '' composer_obj.body.text = '' state.in_composer = True state.in_sent_method = False def set_navbar_for_composer(self): """This method is used for clearing toolbar data when composer open""" self.root.ids.toolbar.left_action_items = [ ['arrow-left', lambda x: self.back_press()]] self.root.ids.toolbar.right_action_items = [ ['refresh', lambda x: self.root.ids.sc3.children[1].reset_composer()], ['send', lambda x: self.root.ids.sc3.children[1].send(self)]] def set_common_header(self): """Common for all window""" 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()]] return def back_press(self): """Method used for going back from composer to previous page.""" self.save_draft() if self.root.ids.scr_mngr.current == 'mailDetail' \ and state.in_search_mode: toolbar_obj = self.root.ids.toolbar toolbar_obj.left_action_items = [ ['arrow-left', lambda x: self.closeSearchScreen()]] toolbar_obj.right_action_items = [] self.root.ids.toolbar.title = '' else: self.set_common_header() self.root.ids.scr_mngr.current = 'inbox' \ if state.in_composer else 'allmails'\ if state.is_allmail else state.detailPageType\ if state.detailPageType else 'inbox' 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 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 shutdown.doCleanShutdown() @staticmethod def current_address_label(current_add_label=None, current_addr=None): """Getting current address labels.""" if BMConfigParser().addresses(): if current_add_label: first_name = current_add_label addr = current_addr else: addr = BMConfigParser().addresses()[0] first_name = BMConfigParser().get(addr, 'label') f_name = first_name.split() label = f_name[0][:14].capitalize() + '...' if len( f_name[0]) > 15 else f_name[0].capitalize() address = ' (' + addr + '...)' return label + address return '' def searchQuery(self, instance): """Method used for showing searched mails.""" state.search_screen = self.root.ids.scr_mngr.current state.searcing_text = str(instance.text).strip() if instance.focus and state.searcing_text: toolbar_obj = self.root.ids.toolbar toolbar_obj.left_action_items = [ ['arrow-left', lambda x: self.closeSearchScreen()]] toolbar_obj.right_action_items = [] self.root.ids.toolbar.title = '' state.in_search_mode = True def closeSearchScreen(self): """Function for close search screen""" self.set_common_header() address_label = self.current_address_label( BMConfigParser().get( state.association, 'label'), state.association) self.root.ids.toolbar.title = address_label state.searcing_text = '' self.refreshScreen() state.in_search_mode = False def refreshScreen(self): # pylint: disable=unused-variable """Method show search button only on inbox or sent screen.""" state.searcing_text = '' if state.search_screen == 'inbox': try: self.root.ids.sc1.children[ 3].children[1].ids.search_field.text = '' except Exception: self.root.ids.sc1.children[ 2].children[1].ids.search_field.text = '' self.root.ids.sc1.children[1].active = True Clock.schedule_once(self.search_callback, 0.5) elif state.search_screen == 'addressbook': self.root.ids.sc11.children[ 2].children[1].ids.search_field.text = '' self.root.ids.sc11.children[ 1].active = True Clock.schedule_once(self.search_callback, 0.5) elif state.search_screen == 'myaddress': try: self.root.ids.sc10.children[ 3].children[1].ids.search_field.text = '' except Exception: self.root.ids.sc10.children[ 2].children[1].ids.search_field.text = '' self.root.ids.sc10.children[1].active = True Clock.schedule_once(self.search_callback, 0.5) else: self.root.ids.sc4.children[ 2].children[1].ids.search_field.text = '' self.root.ids.sc4.children[1].active = True Clock.schedule_once(self.search_callback, 0.5) return 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) 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 def load_screen(self, instance): """This method is used for loading screen on every click""" if instance.text == 'Inbox': self.root.ids.scr_mngr.current = 'inbox' self.root.ids.sc1.children[1].active = True self.root.ids.sc1.ids.ml.clear_widgets() Clock.schedule_once(partial(self.load_screen_callback, instance), 0.5) def load_screen_callback(self, instance, dt=0): """This method is rotating loader for few seconds""" if instance.text == 'Inbox': self.root.ids.sc1.loadMessagelist(state.association) self.root.ids.sc1.children[1].active = False class GrashofPopup(Popup): """Methods for saving contacts, error messages.""" def __init__(self, **kwargs): """Grash of pop screen settings.""" # pylint: disable=useless-super-delegation super(GrashofPopup, self).__init__(**kwargs) def savecontact(self): """Method is used for Saving Contacts.""" label = self.ids.label.text.strip() address = self.ids.address.text.strip() if label == '' and address == '': self.ids.label.focus = True self.ids.address.focus = True elif address == '': self.ids.address.focus = True elif label == '': self.ids.label.focus = True stored_address = [addr[1] for addr in kivy_helper_search.search_sql( folder="addressbook")] stored_labels = [labels[0] for labels in kivy_helper_search.search_sql( folder="addressbook")] if label and address and address not in stored_address \ and label not in stored_labels: # state.navinstance = self.parent.children[1] queues.UISignalQueue.put(('rerenderAddressBook', '')) self.dismiss() sqlExecute("INSERT INTO addressbook VALUES(?,?)", label, address) self.parent.children[1].ids.sc11.ids.ml.clear_widgets() self.parent.children[1].ids.sc11.loadAddresslist(None, 'All', '') self.parent.children[1].ids.scr_mngr.current = 'addressbook' toast('Saved') # pylint: disable=attribute-defined-outside-init def show_error_message(self): """Showing error message.""" content = MDLabel( font_style='Body1', theme_text_color='Secondary', text="Hey you are not allowed to save blank address contact. " "That's wrong!", size_hint_y=None, valign='top') content.bind(texture_size=content.setter('size')) self.dialog = MDDialog(content=content, size_hint=(.8, None), height=dp(200), auto_dismiss=False) self.dialog.add_action_button("ok", action=lambda *x: self.dialog.dismiss()) self.dialog.open() @staticmethod def close_pop(): """Pop is Canceled.""" toast('Canceled') def checkAddress_valid(self, instance): """Checking 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: self.ids.address.error = True self.ids.address.helper_text = text elif entered_text: self.ids.address.error = False else: self.ids.address.error = False self.ids.address.helper_text = 'This field is required' def checkLabel_valid(self, instance): """Checking address label is unique of not""" entered_label = instance.text.strip() addr_labels = [labels[0] for labels in kivy_helper_search.search_sql( folder="addressbook")] if entered_label in addr_labels: self.ids.label.error = True self.ids.label.helper_text = 'label name already exists.' elif entered_label: self.ids.label.error = False else: self.ids.label.error = False self.ids.label.helper_text = 'This field is required' class AvatarSampleWidget(ILeftBody, Image): """Avatar Sample Widget.""" pass class IconLeftSampleWidget(ILeftBodyTouch, MDIconButton): """Left icon sample widget.""" pass class IconRightSampleWidget(IRightBodyTouch, MDCheckbox): """Right icon sample widget.""" pass class NavigationDrawerTwoLineListItem( TwoLineListItem, NavigationDrawerHeaderBase): """Navigation Drawer in Listitems.""" address_property = StringProperty() def __init__(self, **kwargs): """Method for Navigation Drawer.""" super(NavigationDrawerTwoLineListItem, self).__init__(**kwargs) Clock.schedule_once(lambda dt: self.setup()) def setup(self): """Bind Controller.current_account property.""" pass def on_current_account(self, account): """Account detail.""" pass def _update_specific_text_color(self, instance, value): pass def _set_active(self, active, list_): pass class MailDetail(Screen): """MailDetail Screen uses to show the detail of mails.""" to_addr = StringProperty() from_addr = StringProperty() subject = StringProperty() message = StringProperty() status = StringProperty() page_type = StringProperty() def __init__(self, *args, **kwargs): """Mail Details method.""" super(MailDetail, self).__init__(*args, **kwargs) Clock.schedule_once(self.init_ui, 0) def init_ui(self, dt=0): """Clock Schdule for method MailDetail mails.""" self.page_type = state.detailPageType if state.detailPageType else '' if state.detailPageType == 'sent' or state.detailPageType == 'draft': data = sqlQuery( "select toaddress, fromaddress, subject, message, status," " ackdata from sent where ackdata = ?;", state.mail_id) state.status = self state.ackdata = data[0][5] self.assign_mail_details(data) state.kivyapp.set_mail_detail_header() elif state.detailPageType == 'inbox': data = sqlQuery( "select toaddress, fromaddress, subject, message from inbox" " where msgid = ?;", str(state.mail_id)) self.assign_mail_details(data) state.kivyapp.set_mail_detail_header() def assign_mail_details(self, data): """Assigning mail details.""" self.to_addr = data[0][0] self.from_addr = data[0][1] self.subject = data[0][2].upper( ) if data[0][2].upper() else '(no subject)' self.message = data[0][3] if len(data[0]) == 6: 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): """Method for mail delete.""" msg_count_objs = state.kivyapp.root.children[2].children[0].ids state.searcing_text = '' self.children[0].children[0].active = True if state.detailPageType == 'sent': state.kivyapp.root.ids.sc4.children[ 2].children[1].ids.search_field.text = '' sqlExecute( "UPDATE sent SET folder = 'trash' WHERE" " ackdata = ?;", str(state.mail_id)) msg_count_objs.send_cnt.badge_text = str(int(state.sent_count) - 1) state.sent_count = str(int(state.sent_count) - 1) self.parent.screens[3].ids.ml.clear_widgets() self.parent.screens[3].loadSent(state.association) elif state.detailPageType == 'inbox': state.kivyapp.root.ids.sc1.children[ 2].children[1].ids.search_field.text = '' self.parent.screens[0].children[2].children[ 1].ids.search_field.text = '' sqlExecute( "UPDATE inbox SET folder = 'trash' WHERE" " msgid = ?;", str(state.mail_id)) msg_count_objs.inbox_cnt.badge_text = str( int(state.inbox_count) - 1) state.inbox_count = str(int(state.inbox_count) - 1) self.parent.screens[0].ids.ml.clear_widgets() self.parent.screens[0].loadMessagelist(state.association) elif state.detailPageType == 'draft': sqlExecute("DELETE FROM sent WHERE ackdata = ?;", str( state.mail_id)) 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].ids.ml.clear_widgets() self.parent.screens[4].init_ui(dt=0) self.parent.screens[16].ids.ml.clear_widgets() self.parent.screens[16].init_ui(dt=0) Clock.schedule_once(self.callback_for_delete, 4) def callback_for_delete(self, dt=0): """Delete method from allmails""" self.children[0].children[0].active = False state.kivyapp.set_common_header() self.parent.current = 'allmails' \ if state.is_allmail else state.detailPageType state.detailPageType = '' toast('Deleted') def inbox_reply(self): """Method used for replying inbox messages.""" data = sqlQuery( "select toaddress, fromaddress, subject, message from inbox where" " msgid = ?;", str(state.mail_id)) composer_obj = self.parent.screens[2].children[1].ids 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.body.text = '' state.kivyapp.root.ids.sc3.children[1].ids.rv.data = '' self.parent.current = 'create' state.kivyapp.set_navbar_for_composer() def write_msg(self, navApp): """Method used to write on draft mail.""" state.send_draft_mail = state.mail_id composer_ids = ( self.parent.parent.parent.parent.parent.ids.sc3.children[1].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'] if state.write_msg['subject'] != '(no subject)' else '' 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): """MyaddDetailPopup pop is used for showing my address detail.""" address_label = StringProperty() address = StringProperty() def __init__(self, **kwargs): """My Address Details screen setting.""" # pylint: disable=useless-super-delegation super(MyaddDetailPopup, self).__init__(**kwargs) def set_address(self, address, label): """Getting address for displaying details on popup.""" self.address_label = label self.address = address def send_message_from(self): """Method used to fill from address of composer autofield.""" state.kivyapp.set_navbar_for_composer() window_obj = self.parent.children[1].ids window_obj.sc3.children[1].ids.ti.text = self.address window_obj.sc3.children[1].ids.btn.text = self.address window_obj.sc3.children[1].ids.txt_input.text = '' window_obj.sc3.children[1].ids.subject.text = '' window_obj.sc3.children[1].ids.body.text = '' window_obj.scr_mngr.current = 'create' self.dismiss() @staticmethod def close_pop(): """Pop is Canceled.""" toast('Canceled') class AddbookDetailPopup(Popup): """AddbookDetailPopup pop is used for showing my address detail.""" address_label = StringProperty() address = StringProperty() def __init__(self, **kwargs): """Method used set screen of address detail page.""" # pylint: disable=useless-super-delegation super(AddbookDetailPopup, self).__init__(**kwargs) def set_addbook_data(self, address, label): """Getting address book data for detial dipaly.""" self.address_label = label self.address = address def update_addbook_label(self, address): """Updating the label of address book address.""" address_list = kivy_helper_search.search_sql(folder="addressbook") stored_labels = [labels[0] for labels in address_list] add_dict = dict(address_list) label = str(self.ids.add_label.text) if label in stored_labels and self.address == add_dict[label]: stored_labels.remove(label) if label and label not in stored_labels: sqlExecute( "UPDATE addressbook SET label = '{}' WHERE" " address = '{}';".format( str(self.ids.add_label.text), address)) self.parent.children[1].ids.sc11.ids.ml.clear_widgets() self.parent.children[1].ids.sc11.loadAddresslist(None, 'All', '') self.dismiss() toast('Saved') def send_message_to(self): """Method used to fill to_address of composer autofield.""" state.kivyapp.set_navbar_for_composer() window_obj = self.parent.children[1].ids window_obj.sc3.children[1].ids.txt_input.text = self.address window_obj.sc3.children[1].ids.ti.text = '' window_obj.sc3.children[1].ids.btn.text = 'Select' window_obj.sc3.children[1].ids.subject.text = '' window_obj.sc3.children[1].ids.body.text = '' window_obj.scr_mngr.current = 'create' self.dismiss() @staticmethod def close_pop(): """Pop is Canceled.""" toast('Canceled') def checkLabel_valid(self, instance): """Checking address label is unique of not""" entered_label = str(instance.text.strip()) address_list = kivy_helper_search.search_sql(folder="addressbook") addr_labels = [labels[0] for labels in address_list] add_dict = dict(address_list) if self.address and entered_label in addr_labels \ and self.address != add_dict[entered_label]: self.ids.add_label.error = True self.ids.add_label.helper_text = 'label name already exists.' elif entered_label: self.ids.add_label.error = False else: self.ids.add_label.error = False self.ids.add_label.helper_text = 'This field is required' class ShowQRCode(Screen): """ShowQRCode Screen uses to show the detail of mails.""" def qrdisplay(self): """Method used for showing QR Code.""" # self.manager.parent.parent.parent.ids.search_bar.clear_widgets() self.ids.qr.clear_widgets() from kivy.garden.qrcode import QRCodeWidget self.ids.qr.add_widget(QRCodeWidget( data=self.manager.get_parent_window().children[0].address)) toast('Show QR code') class Draft(Screen): """Draft screen is used to show the list of draft messages.""" data = ListProperty() queryreturn = ListProperty() has_refreshed = True def __init__(self, *args, **kwargs): """Method used for storing draft messages.""" super(Draft, 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 draft accounts.""" self.sentaccounts() print dt def sentaccounts(self): """Load draft accounts.""" account = state.association self.loadDraft(account, 'All', '') def loadDraft(self, account, where="", what=""): """Load draft list for Draft messages.""" xAddress = 'fromaddress' self.queryreturn = kivy_helper_search.search_sql( xAddress, account, "draft", where, what, False) if state.msg_counter_objs: state.msg_counter_objs.draft_cnt.badge_text = str( len(self.queryreturn)) if self.queryreturn: src_mng_obj = state.kivyapp.root.children[2].children[0].ids src_mng_obj.draft_cnt.badge_text = str(len(self.queryreturn)) state.draft_count = str(len(self.queryreturn)) self.set_mdList(0, 20) self.ids.scroll_y.bind(scroll_y=self.check_scroll_y) 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 set_mdList(self, first_index, last_index): """This method is used to create mdlist""" data = [] for mail in self.queryreturn[first_index:last_index]: third_text = mail[3].replace('\n', ' ') 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, 'ackdata': mail[5]}) for item in data: meny = TwoLineAvatarIconListItem( 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['ackdata'])) 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_draft, item['ackdata'])) carousel.add_widget(del_btn) carousel.add_widget(meny) carousel.index = 1 self.ids.ml.add_widget(carousel) def check_scroll_y(self, instance, somethingelse): """This method is used to load data on scroll""" if self.ids.scroll_y.scroll_y <= -0.0 and self.has_refreshed: self.ids.scroll_y.scroll_y = 0.06 total_draft_msg = len(self.ids.ml.children) if total_draft_msg != len(self.queryreturn): self.update_draft_screen_on_scroll(total_draft_msg) self.has_refreshed = True if total_draft_msg != len( self.queryreturn) else False else: pass def update_draft_screen_on_scroll(self, total_draft_msg): """This method is used to load more data on scroll down""" self.set_mdList(total_draft_msg, total_draft_msg + 5) def draft_detail(self, ackdata, *args): """Method used to show draft Details.""" state.detailPageType = 'draft' state.mail_id = ackdata 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 delete_draft(self, data_index, instance, *args): """Method used to delete draft message permanently.""" sqlExecute("DELETE FROM sent WHERE ackdata = ?;", str( 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) state.draft_count = str(int(state.draft_count) - 1) self.ids.ml.remove_widget(instance.parent.parent) toast('Deleted') @staticmethod def draft_msg(src_object): """Method used for saving draft mails.""" # pylint: disable=too-many-locals composer_object = state.kivyapp.root.ids.sc3.children[1].ids fromAddress = str(composer_object.ti.text) toAddress = str(composer_object.txt_input.text) subject = str(composer_object.subject.text) message = str(composer_object.body.text) encoding = 3 sendMessageToPeople = True if sendMessageToPeople: from addresses import decodeAddress streamNumber, ripe = decodeAddress(toAddress)[2:] from addresses import addBMIfNotPresent toAddress = addBMIfNotPresent(toAddress) stealthLevel = BMConfigParser().safeGetInt( 'bitmessagesettings', 'ackstealthlevel') from helper_ackPayload import genAckPayload ackdata = genAckPayload(streamNumber, stealthLevel) sqlExecute( '''INSERT INTO sent VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)''', '', toAddress, ripe, fromAddress, subject, message, ackdata, int(time.time()), int(time.time()), 0, 'msgqueued', 0, 'draft', encoding, BMConfigParser().getint('bitmessagesettings', 'ttl')) state.msg_counter_objs = src_object.children[2].children[0].ids state.draft_count = str(int(state.draft_count) + 1) src_object.ids.sc16.clear_widgets() src_object.ids.sc16.add_widget(Draft()) toast('Save draft') return class CustomSpinner(Spinner): """This class is used for setting spinner size.""" def __init__(self, *args, **kwargs): """Method used for setting size of spinner.""" super(CustomSpinner, self).__init__(*args, **kwargs) self.dropdown_cls.max_height = Window.size[1] / 3 class Allmails(Screen): """all mails Screen uses screen to show widgets of screens.""" data = ListProperty() has_refreshed = True all_mails = 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.""" self.all_mails = sqlQuery( "SELECT toaddress, fromaddress, subject, message, folder, ackdata" " As id, DATE(lastactiontime) As actionTime FROM sent WHERE" " folder = 'sent' and fromaddress = '{0}' UNION SELECT toaddress," " fromaddress, subject, message, folder, msgid As id," " DATE(received) As actionTime FROM inbox WHERE" " folder = 'inbox' and toaddress = '{0}'" " ORDER BY actionTime DESC".format(account)) if self.all_mails: state.kivyapp.root.children[2].children[ 0].ids.allmail_cnt.badge_text = str( len(self.all_mails)) state.all_count = str(len(self.all_mails)) self.set_mdlist(0, 20) self.ids.refresh_layout.bind(scroll_y=self.check_scroll_y) 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 set_mdlist(self, start_pnt, end_pnt): """This method is used to create mdList for allmaills""" for item in self.all_mails[start_pnt:end_pnt]: 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) def check_scroll_y(self, instance, somethingelse): """This method is used for scrolling on fixing length""" if self.ids.refresh_layout.scroll_y <= -0.00 and self.has_refreshed: self.ids.refresh_layout.scroll_y = .06 load_more = len(self.ids.ml.children) self.updating_allmail(load_more) else: pass def updating_allmail(self, load_more): """This method is used to update the all mail listing value on the scroll of screen""" if self.all_mails and load_more != len(self.all_mails): state.all_count = str(len(self.all_mails)) self.set_mdlist(load_more, load_more + 5) self.has_refreshed = True if load_more != len( self.all_mails) else False def mail_detail(self, unique_id, folder, *args): """Load sent and inbox mail details.""" state.detailPageType = folder state.is_allmail = True state.mail_id = 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.""" if folder == 'inbox': sqlExecute( "UPDATE inbox SET folder = 'trash' WHERE msgid = ?;", str( unique_id)) else: sqlExecute( "UPDATE sent SET folder = 'trash' WHERE ackdata = ?;", str( 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.ids.ml.clear_widgets() nav_lay_obj.sc1.loadMessagelist(state.association) 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.ids.ml.clear_widgets() nav_lay_obj.sc4.loadSent(state.association) 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 set_root_layout(self): """Setting root layout""" try: return self.manager.parent.parent except Exception: return state.kivyapp.root.ids.float_box def avatarImageFirstLetter(letter_string): """This function 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 class LoadingPopup(Popup): """Class for loading Popup""" def __init__(self, **kwargs): super(LoadingPopup, self).__init__(**kwargs) # call dismiss_popup in 2 seconds Clock.schedule_once(self.dismiss_popup, 0.5) def dismiss_popup(self, dt): """Dismiss popups""" self.dismiss()