def show_example_time_picker(self): from kivymd.time_picker import MDTimePicker time_dialog = MDTimePicker() time_dialog.bind(time=self.get_time_picker_data) if self.pickers.ids.time_picker_use_previous_time.active: try: time_dialog.set_time(self.previous_time) except AttributeError: pass time_dialog.open()
class KitchenSink(App): theme_cls = ThemeManager() previous_date = ObjectProperty() title = "KivyMD Kitchen Sink" 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): main_widget = Builder.load_string(main_widget_kv) # self.theme_cls.theme_style = 'Dark' main_widget.ids.text_field_error.bind( on_text_validate=self.set_error_message, on_focus=self.set_error_message) self.bottom_navigation_remove_mobile(main_widget) return main_widget def bottom_navigation_remove_mobile(self, widget): # Removes some items from bottom-navigation demo when on mobile if DEVICE_TYPE == 'mobile': widget.ids.bottom_navigation_demo.remove_widget( widget.ids.bottom_navigation_desktop_2) if DEVICE_TYPE == 'mobile' or DEVICE_TYPE == 'tablet': widget.ids.bottom_navigation_demo.remove_widget( widget.ids.bottom_navigation_desktop_1) def show_example_snackbar(self, snack_type): if snack_type == 'simple': Snackbar(text="This is a snackbar!").show() elif snack_type == 'button': Snackbar(text="This is a snackbar", button_text="with a button!", button_callback=lambda *args: 2).show() elif snack_type == 'verylong': Snackbar( text= "This is a very very very very very very very long snackbar!" ).show() def show_example_dialog(self): content = MDLabel(font_style='Body1', theme_text_color='Secondary', text="This is a dialog with a title and some text. " "That's pretty awesome right!", size_hint_y=None, valign='top') content.bind(texture_size=content.setter('size')) self.dialog = MDDialog(title="This is a test dialog", content=content, size_hint=(.8, None), height=dp(200), auto_dismiss=False) self.dialog.add_action_button("Dismiss", action=lambda *x: self.dialog.dismiss()) self.dialog.open() def show_example_long_dialog(self): content = MDLabel(font_style='Body1', theme_text_color='Secondary', text="Lorem ipsum dolor sit amet, consectetur " "adipiscing elit, sed do eiusmod tempor " "incididunt ut labore et dolore magna aliqua. " "Ut enim ad minim veniam, quis nostrud " "exercitation ullamco laboris nisi ut aliquip " "ex ea commodo consequat. Duis aute irure " "dolor in reprehenderit in voluptate velit " "esse cillum dolore eu fugiat nulla pariatur. " "Excepteur sint occaecat cupidatat non " "proident, sunt in culpa qui officia deserunt " "mollit anim id est laborum.", size_hint_y=None, valign='top') content.bind(texture_size=content.setter('size')) self.dialog = MDDialog(title="This is a long test dialog", content=content, size_hint=(.8, None), height=dp(200), auto_dismiss=False) self.dialog.add_action_button("Dismiss", action=lambda *x: self.dialog.dismiss()) self.dialog.open() def get_time_picker_data(self, instance, time): self.root.ids.time_picker_label.text = str(time) self.previous_time = time def show_example_time_picker(self): self.time_dialog = MDTimePicker() self.time_dialog.bind(time=self.get_time_picker_data) if self.root.ids.time_picker_use_previous_time.active: try: self.time_dialog.set_time(self.previous_time) except AttributeError: pass self.time_dialog.open() def set_previous_date(self, date_obj): self.previous_date = date_obj self.root.ids.date_picker_label.text = str(date_obj) def show_example_date_picker(self): if self.root.ids.date_picker_use_previous_date.active: pd = self.previous_date try: MDDatePicker(self.set_previous_date, pd.year, pd.month, pd.day).open() except AttributeError: MDDatePicker(self.set_previous_date).open() else: MDDatePicker(self.set_previous_date).open() def show_example_bottom_sheet(self): bs = MDListBottomSheet() bs.add_item("Here's an item with text only", lambda x: x) bs.add_item("Here's an item with an icon", lambda x: x, icon='clipboard-account') bs.add_item("Here's another!", lambda x: x, icon='nfc') bs.open() def show_example_grid_bottom_sheet(self): bs = MDGridBottomSheet() bs.add_item("Facebook", lambda x: x, icon_src='./assets/facebook-box.png') bs.add_item("YouTube", lambda x: x, icon_src='./assets/youtube-play.png') bs.add_item("Twitter", lambda x: x, icon_src='./assets/twitter.png') bs.add_item("Da Cloud", lambda x: x, icon_src='./assets/cloud-upload.png') bs.add_item("Camera", lambda x: x, icon_src='./assets/camera.png') bs.open() def set_error_message(self, *args): if len(self.root.ids.text_field_error.text) == 2: self.root.ids.text_field_error.error = True else: self.root.ids.text_field_error.error = False def on_pause(self): return True def on_stop(self): pass
class MobileInsightApp(App): Logger.info("build MI Class") theme_cls = ThemeManager() previous_date = ObjectProperty() title = "MobileInsight" index = NumericProperty(0) current_title = StringProperty() screen_names = ListProperty([]) use_kivy_settings = False Logger.info("Finish build MI Class") def __init__(self, **kwargs): Logger.info("Initializing APP") super(MobileInsightApp, self).__init__(**kwargs) self.title = 'MobileInsight' self.screens = {} self.available_screens = screens.__all__ self.home_screen = None self.log_viewer_screen = None if not create_folder(): # MobileInsight folders unavailable. Add warnings Logger.error("main: SDcard is unavailable. Please check.") main_utils.init_libs() main_utils.check_security_policy() COORDINATOR.start() # FIXME: DEADLOCK HERE!!! def __del__(self): Logger.error("__del__") def __popup_dismiss(self, instance, answer): self.popup.dismiss() self.stop() return True def build_settings(self, settings): with open("settings.json", "r") as settings_json: settings.add_json_panel('General', self.config, data=settings_json.read()) self.create_app_settings(self.config, settings) def create_app_settings(self, config, settings): app_list = get_plugins_list() for app in app_list: APP_NAME = app APP_DIR = app_list[app][0] setting_path = os.path.join(APP_DIR, "settings.json") if os.path.exists(setting_path): with open(setting_path, "r") as settings_json: raw_data = settings_json.read() # Regulate the config into the format that kivy can accept tmp = eval(raw_data) result = "[" default_val = {} for index in range(len(tmp)): if tmp[index]['type'] == 'title': result = result + '{"type": "title","title": ""},' elif tmp[index]['type'] == 'options': default_val[tmp[index] ['key']] = tmp[index]['default'] result = result + '{"type": "' + tmp[index]['type'] \ + '","title":"' + tmp[index]['title'] \ + '","desc":"' + tmp[index]['desc'] \ + '","section":"' + APP_NAME \ + '","key":"' + tmp[index]['key'] \ + '","options":' + json.dumps(tmp[index]['options']) \ + '},' else: default_val[tmp[index] ['key']] = tmp[index]['default'] result = result + '{"type": "' + tmp[index]['type'] \ + '","title":"' + tmp[index]['title'] \ + '","desc":"' + tmp[index]['desc'] \ + '","section":"' + APP_NAME \ + '","key":"' + tmp[index]['key'] \ + '"},' result = result[0:-1] + "]" # Update the default value and setting menu settings.add_json_panel(APP_NAME, config, data=result) def build_config(self, config): # Yuanjie: the ordering of the following options MUST be the same as # those in settings.json!!! config.read('/sdcard/.mobileinsight.ini') config.setdefaults( 'mi_general', { 'bcheck_update': 0, 'log_level': 'info', 'bstartup': 0, 'bstartup_service': 0, 'bgps': 1, 'start_service': 'KPIAnalyzer', 'privacy': 1, }) self.create_app_default_config(config) config.write() def create_app_default_config(self, config): app_list = get_plugins_list() for app in app_list: APP_NAME = app APP_DIR = app_list[app][0] setting_path = os.path.join(APP_DIR, "settings.json") if os.path.exists(setting_path): Logger.info("default path:" + setting_path) with open(setting_path, "r") as settings_json: raw_data = settings_json.read() # Regulate the config into the format that kivy can accept tmp = eval(raw_data) default_val = {} for index in range(len(tmp)): if tmp[index]['type'] == 'title': pass elif 'default' in tmp[index]: default_val[tmp[index] ['key']] = tmp[index]['default'] # Update the default value and setting menu config.setdefaults(APP_NAME, default_val) def build(self): # Force to initialize all configs in .mobileinsight.ini # This prevents missing config due to existence of older-version .mobileinsight.ini # Work-around: force on_config_change, which would update config.ini # Logger.info("Building APP") # config = self.load_config() config = self.config # val = int(config.get('mi_general', 'bcheck_update')) # config.set('mi_general', 'bcheck_update', int(not val)) config.set('mi_general', 'bcheck_update', 0) config.write() Window.borderless = False self.screens = {} self.available_screens = screens.__all__ self.screen_names = self.available_screens for i in range(len(self.available_screens)): self.screens[i] = getattr(screens, self.available_screens[i])() self.home_screen = self.screens[0] COORDINATOR.setup_analyzers() COORDINATOR.send_control('START') self.root.ids.scr_mngr.switch_to(self.screens[0]) def go_screen(self, idx): if self.index == idx: return self.index = idx self.root.ids.scr_mngr.switch_to(self.load_screen(idx), direction='left') def load_screen(self, index): return self.screens[index] def get_time_picker_data(self, instance, time): self.root.ids.time_picker_label.text = str(time) self.previous_time = time def show_example_time_picker(self): self.time_dialog = MDTimePicker() self.time_dialog.bind(time=self.get_time_picker_data) if self.root.ids.time_picker_use_previous_time.active: try: self.time_dialog.set_time(self.previous_time) except AttributeError: pass self.time_dialog.open() def set_previous_date(self, date_obj): self.previous_date = date_obj self.root.ids.date_picker_label.text = str(date_obj) def show_example_date_picker(self): if self.root.ids.date_picker_use_previous_date.active: pd = self.previous_date try: MDDatePicker(self.set_previous_date, pd.year, pd.month, pd.day).open() except AttributeError: MDDatePicker(self.set_previous_date).open() else: MDDatePicker(self.set_previous_date).open() def set_error_message(self, *args): if len(self.root.ids.text_field_error.text) == 2: self.root.ids.text_field_error.error = True else: self.root.ids.text_field_error.error = False def on_pause(self): # Yuanjie: The following code prevents screen freeze when screen off -> # screen on try: pm = current_activity.getSystemService( autoclass('android.content.Context').POWER_SERVICE) if not pm.isInteractive(): current_activity.moveTaskToBack(True) except Exception as e: try: # API 20: pm.isScreenOn is depreciated pm = current_activity.getSystemService( autoclass('android.content.Context').POWER_SERVICE) if not pm.isScreenOn(): current_activity.moveTaskToBack(True) except Exception as e: Logger.exception(traceback.format_exc()) # print "on_pause" return True # go into Pause mode def on_resume(self): # print "on_resume" pass def check_update(self): """ Check if new update is available """ try: config = self.config # config = ConfigParser() # config.read('/sdcard/.mobileinsight.ini') bcheck_update = config.get("mi_general", "bcheck_update") if bcheck_update == "1": from . import check_update check_update.check_update() except Exception as e: Logger.exception(traceback.format_exc()) def privacy_check(self): """ Check if new update is available """ try: # config = ConfigParser() # config.read('/sdcard/.mobileinsight.ini') config = self.config privacy_agreed = int(config.get("mi_general", "privacy")) if privacy_agreed == 0: import privacy_app privacy_app.PrivacyApp().run() # if privacy_app.disagree_privacy: # self.stop() except Exception as e: Logger.exception(traceback.format_exc()) def on_start(self): # android.stop_service() # Kill zombine service from previous app instances Config.set('kivy', 'exit_on_escape', 0) if not main_utils.is_rooted(): err_str = "MobileInsight requires root privilege. Please root your device for correct functioning." Logger.error(err_str) self.home_screen.log_error(err_str) elif not main_utils.check_diag_mode(): err_str = "The diagnostic mode is disabled. Please check your phone settings." Logger.error(err_str) self.home_screen.log_error(err_str) # content = ConfirmPopup(text=err_str) # content.bind(on_answer=self.__popup_dismiss) # self.popup = Popup(title='Diagnostic mode is not available', # content=content, # size_hint=(None, None), # size=(1200, 400), # auto_dismiss=False) # self.popup.open() else: self.privacy_check() self.check_update() def on_stop(self): Logger.error("on_stop") COORDINATOR.stop()
class MainApp(App): theme_cls = ThemeManager() previous_date = ObjectProperty() title = "Decentralize oil field" mnemonic = StringProperty() address = StringProperty() passphrase = StringProperty() repeat_passphrase = StringProperty() enabled_mnemonic = BooleanProperty(True) enabled_address = BooleanProperty(True) instagram_last_fetched = StringProperty() def __init__(self, **kwargs): super(MainApp, self).__init__(**kwargs) #Window.bind(on_close=self.on_stop) def stop(self, *largs): # Open the popup you want to open and declare callback if user pressed `Yes` # popup = ExitPopup(title=TEXT_ON_CLOSE_APPLICATION, # content=Button(text=TEXT_ON_CLOSE_APPLICATION_BUTTON_CLOSE), # size=(400, 400), size_hint=(None, None) # ) # popup.bind(on_confirm=partial(self.close_app, *largs)) # popup.open() return def build(self): self.main_widget = Builder.load_file( os.path.join(os.path.dirname(__file__), "./latest.kv")) self.theme_cls.theme_style = 'Dark' # self.theme_cls.theme_style = 'Dark' # self.main_widget.ids.text_field_error.bind( # on_text_validate=self.set_error_message, # on_focus=self.set_error_message) self.update_instagram_images_list() self.bottom_navigation_remove_mobile(self.main_widget) #__list = Factory.Lists() return self.main_widget def update_instagram_images_list(self): thumbnails = get_instagram_thumbnails() for image in thumbnails: item = TwoLineAvatarIconListItem( text=f"Top Liker [ {image['top_likers'][0]} ]", secondary_text=f"Total likes {image['likes']}") item.add_widget(ContactPhoto(source=image["disk_name"])) item.add_widget(MessageButton(id=image["id"])) self.main_widget.ids.scroll.add_widget(item) # new_widget = Factory.ThreeLineAvatarIconListItemCheckbox( # text=f'id-{image["id"]}') # new_widget.add_widget(AvatarSampleWidget(source=image["disk_name"])) self.instagram_last_fetched = "Last Fetched from Instagram " + self.instagram_last( ) return def bottom_navigation_remove_mobile(self, widget): # Removes some items from bottom-navigation demo when on mobile if DEVICE_TYPE == 'mobile': widget.ids.bottom_navigation_demo.remove_widget( widget.ids.bottom_navigation_desktop_2) if DEVICE_TYPE == 'mobile' or DEVICE_TYPE == 'tablet': widget.ids.bottom_navigation_demo.remove_widget( widget.ids.bottom_navigation_desktop_1) def show_example_snackbar(self, snack_type): if snack_type == 'simple': Snackbar(text="This is a snackbar!").show() elif snack_type == 'button': Snackbar(text="This is a snackbar", button_text="with a button!", button_callback=lambda *args: 2).show() elif snack_type == 'verylong': Snackbar( text= "This is a very very very very very very very long snackbar!" ).show() def show_example_dialog(self): content = MDLabel(font_style='Body1', theme_text_color='Secondary', text="This is a dialog with a title and some text. " "That's pretty awesome right!", size_hint_y=None, valign='top') content.bind(texture_size=content.setter('size')) self.dialog = MDDialog(title="This is a test dialog", content=content, size_hint=(.8, None), height=dp(200), auto_dismiss=False) self.dialog.add_action_button("Dismiss", action=lambda *x: self.dialog.dismiss()) self.dialog.open() def loading_box(self): content = MDLabel( font_style='Body1', theme_text_color='Secondary', text= "Please wait while we are fetching your instagram, Hang tight!!!", size_hint_y=None, valign='top') content.bind(texture_size=content.setter('size')) self.dialog = MDDialog(title="This is a long test dialog", content=content, size_hint=(.8, None), height=dp(200), auto_dismiss=True) # self.dialog.add_action_button("Dismiss", # action=lambda *x: self.dialog.dismiss()) self.dialog.open() return def get_time_picker_data(self, instance, time): self.root.ids.time_picker_label.text = str(time) self.previous_time = time def show_example_time_picker(self): self.time_dialog = MDTimePicker() self.time_dialog.bind(time=self.get_time_picker_data) if self.root.ids.time_picker_use_previous_time.active: try: self.time_dialog.set_time(self.previous_time) except AttributeError: pass self.time_dialog.open() def set_previous_date(self, date_obj): self.previous_date = date_obj self.root.ids.date_picker_label.text = str(date_obj) def show_example_date_picker(self): if self.root.ids.date_picker_use_previous_date.active: pd = self.previous_date try: MDDatePicker(self.set_previous_date, pd.year, pd.month, pd.day).open() except AttributeError: MDDatePicker(self.set_previous_date).open() else: MDDatePicker(self.set_previous_date).open() def show_example_bottom_sheet(self): bs = MDListBottomSheet() bs.add_item("Here's an item with text only", lambda x: x) bs.add_item("Here's an item with an icon", lambda x: x, icon='clipboard-account') bs.add_item("Here's another!", lambda x: x, icon='nfc') bs.open() def show_example_grid_bottom_sheet(self): bs = MDGridBottomSheet() bs.add_item("Facebook", lambda x: x, icon_src='./assets/facebook-box.png') bs.add_item("YouTube", lambda x: x, icon_src='./assets/youtube-play.png') bs.add_item("Twitter", lambda x: x, icon_src='./assets/twitter.png') bs.add_item("Da Cloud", lambda x: x, icon_src='./assets/cloud-upload.png') bs.add_item("Camera", lambda x: x, icon_src='./assets/camera.png') bs.open() def set_error_message(self, *args): if len(self.root.ids.text_field_error.text) == 2: self.root.ids.text_field_error.error = True else: self.root.ids.text_field_error.error = False def on_close(self): print("Clicked on closing application") Window.close() return True def on_start(self): print(self.main_widget.ids.scr_mngr) if store.get("mnemonic"): self.main_widget.ids.login_box.remove_widget( self.main_widget.ids.button_mnemonic) self.main_widget.ids.login_box.remove_widget( self.main_widget.ids.button_save_mnemonic) #self.main_widget.ids.login_box.remove_widget(self.main_widget.ids.address) self.main_widget.ids.login_box.remove_widget( self.main_widget.ids.repeat_passphrase) self.main_widget.ids.login_box.remove_widget( self.main_widget.ids.mnemonic) #self.main_widget.ids.login_box.add_widget(self.main_widget.ids.repeat_passphrase) else: self.main_widget.ids.login_box.remove_widget( self.main_widget.ids.button_login) return def on_instagram_login(self, username, password): try: instagram_object = instagram_login(username.text, password.text) #self.loading_box() #Snackbar(text="Please wait for sometime, lets us fetch your Insta Handle").show() max_id, posts = get_all_posts(instagram_object) Logger.info("Now fetching images from instagram") save_instagram(posts) # with open("instagram.data","wb") as f: # pickle.dump(posts, f) store.put("instagram", max_id=max_id, time_zone=time.tzname, last_fetch_utc=datetime.datetime.utcnow().timestamp(), last_fetch_local=datetime.datetime.now( datetime.timezone.utc).astimezone().isoformat()) except Exception as e: Logger.error(e) Snackbar( text="Please check your instragram username and password again" ).show() return def instagram_last(self): try: data = store.get("instagram") print(f"Instagram data stored in local storage {data}") print( f"Instagram Last fectehd locally is {data['last_fetch_local']}" ) result = datetime.datetime.fromtimestamp( data["last_fetch_utc"]).strftime("%d %B, %Y") print(f"Human readable last fecthed {result}") return result except Exception as e: print(f"Error in lest fecthed dtiem stamp UTC {e.__str__()}") return "" def on_show_mnemonic(self): """ Show mnemonic after fetching it from local storage """ self.main_widget.ids.login_box.add_widget( self.main_widget.ids.mnemonic) def on_login(self, passphrase): encrypted = store.get("mnemonic") encrypted_mnemonic = encrypted["value"] salt = encrypted["salt"] scrypt_key, salt = generate_scrypt_key(passphrase.text, bytes.fromhex(salt)) print( f"scrypt_key from password {scrypt_key.hex()} and salt is {salt.hex()}" ) print(f"Encrypted Mnemonic is {encrypted_mnemonic}") try: result = aes_decrypt(scrypt_key, bytes.fromhex(encrypted_mnemonic)) except Exception as e: print("Error ") print(e) Snackbar(text="Password entered is wrong").show() print(result) store.put("password", value=passphrase.text) return def on_save(self, passphrase, repeat_passphrase): if not self.mnemonic: Snackbar(text="PLease generate a New mnemonic").show() return if passphrase.text != repeat_passphrase.text or not passphrase.text: Snackbar(text="Passphrases must match").show() return if len(passphrase.text) < 8: Snackbar( text="Passphrases must be at least 8 characters long").show() return scrypt_key, salt = generate_scrypt_key(passphrase.text) encrypted_mnemonic = aes_encrypt(scrypt_key, self.mnemonic) store.put("mnemonic", value=encrypted_mnemonic.hex(), salt=salt.hex()) store.put("address", value=self.address) return def generate_mnemonic(self): """ Make an api request with the data to confirm the user registraion After succesful registration reset the form """ #TODO form validation with cerberus #TODO Check if macid is available from the host or not #TODO check if ip address r = requests.get(f"http://{store.get('GO_API')}/get_mnemonic") mnemonic = r.json()["data"]["mnemonic"] zeroth_private_key = r.json()["data"]["zeroth_private_key"] zeroth_public_key = r.json()["data"]["zeroth_public_key"] master_private_key = r.json()["data"]["master_private_key"] master_public_key = r.json()["data"]["master_public_key"] self.mnemonic = mnemonic self.address = hashlib.sha256(zeroth_public_key.encode()).hexdigest() return
class IRC(App): userid = '' error_dialog = None theme_cls = ThemeManager() previous_date = ObjectProperty() title = "P2PChater" msg = StringProperty('') login_conn = None friendlist_conn = None chat_conn = None file_conn = None friend_list = None curr_proc_friend = None login_status = False host = '166.111.140.14' server_port = 8000 msg_port = 12500 file_port = 12600 widget_shape = None # [0] for userid # [1] for filename filerecv_flag = [] # [0] for userid # [1] for filepath filesend_flag = [] pwd = '' friend_list_fn = '' # parameters for test test_listen_port1 = 8000 test_write_port1 = 8100 test_listen_port2 = 8100 test_write_port2 = 8000 test_file_listen_port1 = 8200 test_file_listen_port2 = 8300 test_file_write_port1 = 8300 test_file_write_port2 = 8200 test_agent = 2 # in [1, 2] 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): main_widget = Builder.load_string(main_widget_kv) self.bottom_navigation_remove_mobile(main_widget) self.comm2server(self.host, self.server_port) self.comm2friendlist(self.host, self.server_port) if self.test_agent == 1: reactor.listenUDP(self.test_listen_port1, ChatClient(self)) reactor.listenTCP(self.test_file_listen_port1, FileServerFactory(self)) else: reactor.listenUDP(self.test_listen_port2, ChatClient(self)) reactor.listenTCP(self.test_file_listen_port2, FileServerFactory(self)) return main_widget # Network def login(self, username, password, *args): if self.login_conn: self.login_conn.write('{}_{}'.format(username, password).encode('utf-8')) else: self.show_dialog('connection') return def login_callback(self, FLAG): if FLAG: self.login_status = True self.root.ids.qr.data = self.userid self.root.ids.scr_mngr.current = 'mainpage' self.get_friendlist() Clock.schedule_interval(self.get_friendlist, 1) print("Current login account: {}".format(self.userid)) else: self.show_dialog('connection') def logout(self): self.login_conn.write('logout{}'.format(self.userid)) pass def logout_callback(self, FLAG): if FLAG: self.root.ids.username.text = '' self.root.ids.password.text = '' self.login_status = False self.root.ids.scr_mngr.current = 'login' self.userid = '' self.friend_list_fn = '' else: self.show_dialog('logout') def add_friend(self): pass def get_friendlist(self, *args): if self.friend_list is None: if not os.path.exists(os.path.join('./user', self.userid)): os.system('mkdir -p {}'.format( os.path.join('./user', self.userid))) if not os.path.exists( os.path.join('./user', self.userid, 'friend_list')): os.system('touch {}'.format( os.path.join('./user', self.userid, 'friend_list'))) self.friend_list_fn = os.path.join('./user', self.userid, 'friend_list') with file(self.friend_list_fn, 'r') as f: flt = f.readlines() flt = [x[0:-1] for x in flt if re.match(pattern_id, x) is not None] self.friend_list = [] for i in flt: self.friend_list.append(Friends(name=i)) self.curr_proc_friend = 0 if len(self.friend_list) > 0: self.friendlist_conn.write('q{}'.format(self.friend_list[0].name)) def query_friend(self, id): self.friendlist_conn.write(id.encode('utf-8')) self.friendlist_conn.loseConnection() return def proc_friend_list(self, flag, msg=None): self.friend_list[self.curr_proc_friend].is_online = flag if flag: self.friend_list[self.curr_proc_friend].ip = msg else: if self.friend_list[self.curr_proc_friend].is_online is True: # your friend disconnect from you self.chat_disconnect(self.curr_proc_friend) self.curr_proc_friend += 1 if self.curr_proc_friend < len(self.friend_list): self.friendlist_conn.write('q{}'.format( self.friend_list[self.curr_proc_friend].name)) else: self.show_friend_card() return def chat_disconnect(self, idx): # save log with open('log_{}'.format(self.friend_list[idx].name), 'a') as f: f.writelines(self.friend_list[idx].msg) self.friend_list[idx].clear_connection_info() def back_to_mainpage(self, *args): self.root.ids.scr_mngr.current = 'mainpage' return def update_chat_window(self, *args): if self.root.ids.scr_mngr.current == 'chatroom': userid = self.root.ids.chatroom_toolbar.title.split(' ')[2] for idx, i in enumerate(self.friend_list): if i.name == userid: self.show_chat_window(idx) def show_friend_card(self): self.root.ids.ml.clear_widgets() for i in self.friend_list: if i.is_online: listwidget = OneLineListItem(text=i.name, theme_text_color='Custom', text_color=get_color_from_hex( colors['Amber']['700']), on_release=self.chatwith) iconwidget = IconLeftSampleWidget(icon='account') self.root.ids.ml.add_widget(listwidget) else: listwidget = OneLineListItem(text=i.name, theme_text_color='Custom', on_release=self.chatwith) iconwidget = IconLeftSampleWidget(icon='account-off') self.root.ids.ml.add_widget(listwidget) return def chatwith(self, instance): print('Widget {} are pressed'.format(instance.text)) for i in range(len(self.friend_list)): if self.friend_list[i].name == instance.text: if self.friend_list[i].is_online is False: self.show_dialog('offline') return self.show_chat_window(i) return def show_chat_window(self, idx): self.root.ids.chatroom_toolbar.title = 'Chat With {}'.format( self.friend_list[idx].name) self.root.ids.chatroom_msg.clear_widgets() # sort msg by timestamp print('MSG from {}: {}'.format(self.friend_list[idx].name, self.friend_list[idx].msg)) sorted_idx = argsort([x[0] for x in self.friend_list[idx].msg]) total_msg = len(self.friend_list[idx].msg) num = 0 # parent_shape in [width, height] parent_shape = [self.root.ids.scr_mngr.width, 100 + 100 * total_msg] print('parent shape: {}'.format(parent_shape)) self.root.ids.chatroom_msg.height = parent_shape[1] for i in sorted_idx: if self.friend_list[idx].msg[i][1] == 0: # income message self.root.ids.chatroom_msg.add_widget( MessageCard('left', self.friend_list[idx].name, self.friend_list[idx].msg[i][2], num, parent_shape).get_card()) else: # output message self.root.ids.chatroom_msg.add_widget( MessageCard('right', self.friend_list[idx].name, self.friend_list[idx].msg[i][2], num, parent_shape).get_card()) num += 1 self.root.ids.scr_mngr.current = 'chatroom' return def send_msg(self): if self.root.ids.chatroom_input.text is None: return client_name = self.root.ids.chatroom_toolbar.title.split(' ')[-1] for idx, i in enumerate(self.friend_list): if i.name == client_name: msg = self.root.ids.chatroom_input.text # 0 for in-msg, 1 for out-msg self.friend_list[idx].msg.append([time.time(), 1, msg]) if self.chat_conn is not None: if self.test_agent == 1: self.chat_conn.write( '{}_{}_{}'.format('MSG', self.userid, msg), ('127.0.0.1', self.test_write_port1)) else: self.chat_conn.write( '{}_{}_{}'.format('MSG', self.userid, msg), ('127.0.0.1', self.test_write_port2)) self.root.ids.chatroom_input.text = '' if self.root.ids.scr_mngr.current == 'chatroom': self.show_chat_window(idx) else: print('UDP Client Not setup, cannot chat') return def send_file(self): client_name = self.root.ids.chatroom_toolbar.title.split(' ')[-1] if sys.platform == 'win': user_path = dirname(expanduser('~')) + sep + 'Documents' else: user_path = expanduser('~') + sep + 'Documents' browser = FileBrowser(select_string='Select', favorites=[(user_path, 'Documents')]) browser.bind( on_success=lambda x: self._fbrowser_success(browser, client_name), on_canceled=lambda x: self._fbrowser_canceled(browser)) self.root.ids.filebrowser.add_widget(browser) self.root.ids.scr_mngr.current = 'filebrowser' return def _fbrowser_canceled(self, instance): self.root.ids.scr_mngr.current = 'chatroom' print 'cancelled, Close self.' def _fbrowser_success(self, instance, client_name): print('Send file {} to {}'.format(instance.selection, client_name)) self.root.ids.scr_mngr.current = 'chatroom' self.filesend_flag.append([client_name, instance.selection]) for idx, i in enumerate(self.friend_list): i.display() if i.name == client_name and i.is_online: self.chat_conn.write( 'FILE_{}_REQUEST_{}'.format( self.userid, os.path.basename(instance.selection[0])), ('127.0.0.1', self.test_write_port1 if self.test_agent == 1 else self.test_write_port2)) if self.test_agent == 1: reactor.connectTCP(i.ip, self.test_file_write_port1, FileClientFactory(self)) else: reactor.connectTCP(i.ip, self.test_file_write_port2, FileClientFactory(self)) break # Send Request def get_username_passwd(self): username = self.root.ids.username.text password = self.root.ids.password.text if password == 'net2017': if re.match(pattern_id, username): self.userid = username self.login(username, password) else: self.show_dialog('login') # connection_wrapper def comm2server(self, dst_host, dst_port): reactor.connectTCP(dst_host, dst_port, LoginClientFactory(self)) return def comm2friendlist(self, dst_host, dst_port): reactor.connectTCP(dst_host, dst_port, FriendlistClientFactory(self)) return # connection handle def on_login_conn(self, conn): self.login_conn = conn def on_friendlist_conn(self, conn): self.friendlist_conn = conn def on_chatclient_connection(self, conn): self.chat_conn = conn def on_file_conn(self, conn): self.file_conn = conn # dialogs def show_dialog(self, dialog_type, userid='', filename=''): """ :param dialog_type: offline, login, connection, file_request, refused, logout, add_friend :return: None """ if dialog_type == 'offline': label_text = 'This friend is currently offline' dialog_text = 'Friend is offline' elif dialog_type == 'login': label_text = 'Please Check your username and password' dialog_text = 'Wrong username/password!' elif dialog_type == 'connection': label_text = 'Please Check your Internet Connection' dialog_text = 'Connection Failed' elif dialog_type == 'file_request': label_text = 'Your Friend {} want to send file {} to you, do you want to accept?'.format( userid, filename) dialog_text = 'Sending File Request' elif dialog_type == 'refused': label_text = 'Your request to send file are refused' dialog_text = 'Request Refused' elif dialog_type == 'logout': label_text = 'Cannot connect to server, logout failed' dialog_text = 'Logout Error' elif dialog_type == 'add_friend': label_text = '' dialog_text = "Please Input your friend's userid" else: raise Exception, 'No such dialog_type' if dialog_type == 'add_friend': content = MDTextField(id='friend_name', hint_text='friend name', required=True, color_mode='accent', helper_text='your friend userid', helper_text_mode='on_focus') else: content = MDLabel(font_style='Body1', theme_text_color='Secondary', text=label_text, size_hint_y=None, valign='top') content.bind(texture_size=content.setter('size')) self.error_dialog = MDDialog(title=dialog_text, content=content, size_hint=(.8, None), height=dp(200), auto_dismiss=False) self.error_dialog.add_action_button( "OK", action=lambda *x: self.dialog_dismiss(dialog_type, userid, filename )) if dialog_type == 'file_request': self.error_dialog.add_action_button( "NO", action=lambda *x: self.dialog_dismiss('{}_no'.format( dialog_type))) if dialog_type == 'add_friend': self.error_dialog.add_action_button( "Cancel", action=lambda *x: self.dialog_dismiss('{}_cancel'.format( dialog_type))) self.error_dialog.open() def dialog_dismiss(self, dialog_type, userid='', filename=''): if dialog_type == 'login': self.root.ids.username.text = '' self.root.ids.password.text = '' elif dialog_type == 'connection': self.comm2server(self.host, self.server_port) self.comm2friendlist(self.host, self.server_port) reactor.listenUDP(self.msg_port, ChatClient(self)) elif dialog_type == 'file_request': # Send ACK to friend, in format self.filerecv_flag.append([userid, filename]) print('Agree to receive file from {}'.format(userid)) for i in self.friend_list: i.display() if i.name == userid and i.is_online: print('Send {}'.format('FILE_{}_ACK'.format(self.userid))) if self.test_agent == 1: self.chat_conn.write('FILE_{}_ACK'.format( self.userid), ('127.0.0.1', self.test_write_port1)) else: self.chat_conn.write('FILE_{}_ACK'.format( self.userid), ('127.0.0.1', self.test_write_port2)) break elif dialog_type == 'add_friend': if self.root.ids.friend_name.text is None: return else: with open(self.friend_list_fn, 'a') as f: f.write(self.root.ids.friend_name.text) self.error_dialog.dismiss() def get_time_picker_data(self, instance, time): self.root.ids.time_picker_label.text = str(time) self.previous_time = time def show_example_time_picker(self): self.time_dialog = MDTimePicker() self.time_dialog.bind(time=self.get_time_picker_data) if self.root.ids.time_picker_use_previous_time.active: try: self.time_dialog.set_time(self.previous_time) except AttributeError: pass self.time_dialog.open() def set_previous_date(self, date_obj): self.previous_date = date_obj self.root.ids.date_picker_label.text = str(date_obj) def show_example_date_picker(self): if self.root.ids.date_picker_use_previous_date.active: pd = self.previous_date try: MDDatePicker(self.set_previous_date, pd.year, pd.month, pd.day).open() except AttributeError: MDDatePicker(self.set_previous_date).open() else: MDDatePicker(self.set_previous_date).open() def show_example_bottom_sheet(self): bs = MDListBottomSheet() bs.add_item("Here's an item with text only", lambda x: x) bs.add_item("Here's an item with an icon", lambda x: x, icon='clipboard-account') bs.add_item("Here's another!", lambda x: x, icon='nfc') bs.open() def show_example_grid_bottom_sheet(self): bs = MDGridBottomSheet() bs.add_item("Facebook", lambda x: x, icon_src='./assets/facebook-box.png') bs.add_item("YouTube", lambda x: x, icon_src='./assets/youtube-play.png') bs.add_item("Twitter", lambda x: x, icon_src='./assets/twitter.png') bs.add_item("Da Cloud", lambda x: x, icon_src='./assets/cloud-upload.png') bs.add_item("Camera", lambda x: x, icon_src='./assets/camera.png') bs.open() def bottom_navigation_remove_mobile(self, widget): # Removes some items from bottom-navigation demo when on mobile if DEVICE_TYPE == 'mobile': widget.ids.main_navigation.remove_widget( widget.ids.bottom_navigation_desktop_2) if DEVICE_TYPE == 'mobile' or DEVICE_TYPE == 'tablet': widget.ids.main_navigation.remove_widget( widget.ids.bottom_navigation_desktop_1) def show_example_snackbar(self, snack_type): if snack_type == 'simple': Snackbar(text="This is a snackbar!").show() elif snack_type == 'button': Snackbar(text="This is a snackbar", button_text="with a button!", button_callback=lambda *args: 2).show() elif snack_type == 'verylong': Snackbar( text= "This is a very very very very very very very long snackbar!" ).show() def on_pause(self): return True def on_stop(self): pass
def on_release(self): time_picker = MDTimePicker() time_picker.set_time(datetime.datetime.strptime(self.value, '%H:%M')) time_picker.bind(time=self._set_value) time_picker.open()