def check_internet(): if is_internet(): return True logger.warn("No internet connection detected") os.system("kano-settings 12") return is_internet()
def share(filename): # TODO: Move this connection handling into a function in Kano Utils import subprocess if not is_internet(): subprocess.call(['sudo', 'kano-settings', '4']) if not is_internet(): return 'You have no internet' success, _ = login_using_token() if not success: os.system('kano-login 3') success, _ = login_using_token() if not success: return 'Cannot login' data = json.loads(request.data) filename, filepath = _save(data) success, msg = upload_share(filepath, filename, APP_NAME) if not success: return msg increment_app_state_variable_with_dialog(APP_NAME, 'shared', 1) return ''
def try_connect(): ''' Returns internet status. If connection fails the first time, the WiFi config will be launched ''' if is_internet(): return True run_cmd('sudo /usr/bin/kano-settings 12', localised=True) return is_internet()
def ensure_internet(): """Ensure there is an internet connection. Check for an internet connection and uses ``kano-settings`` to configure one if not setup. If the popup subsequently fails, the operation quits. Returns: bool: Whether there is an internet connection """ if not is_internet(): run_cmd('sudo kano-settings --label no-internet', localised=True) return is_internet() return True
def _launch_application(self, widget=None): # Decide whether application prompts user to plug in WiFi dongle # or tell them they have ethernet. # Don't want to call this function more than once self.wiface = get_wlan_device() has_internet = is_internet() ethernet_plugged = is_ethernet_plugged() dongle_is_plugged_in = is_device(self.wiface) if has_internet and ethernet_plugged and self.no_confirm_ether: sys.exit(0) # For testing # dongle_is_plugged_in = False # ethernet_plugged = True # has_internet = False if has_internet and ethernet_plugged: self._you_are_connected_via_ethernet() elif dongle_is_plugged_in: if has_internet: self._you_have_internet_screen(self.wiface) else: # Refresh the networks list self.refresh_networks() else: self._plug_in_wifi_dongle()
def login_screen(self, widget, event): self.win.remove_main_widget() if is_internet(): Login(win=self.win, prev_screen=None, first_boot=True) else: NoInternet(self.win)
def first_scene(self): if is_internet(): self._ctl.next_stage() return s1 = self._setup_first_scene() self._ctl.main_window.push(s1)
def install_pip_packages(progress, priority=Priority.NONE): # Urgent updates don't do PIP updates if priority == Priority.URGENT: return phase_name = progress.get_current_phase().name packages = read_file_contents_as_lines(PIP_PACKAGES_LIST) progress.init_steps(phase_name, len(packages)) for pkg in packages: progress.next_step(phase_name, "Installing {}".format(pkg)) success = run_pip_command( "install --upgrade --no-index --find-links=file://{} '{}'".format( PIP_CACHE_DIR, pkg) ) if not success: msg = "Installing the '{}' pip package failed".format(pkg) logger.error(msg) if not is_internet(): msg = "Network is down, aborting PIP install" logger.error(msg) raise IOError(msg) # Try with the failsafe method success_failsafe = run_pip_command( "install --upgrade '{}'".format(pkg) ) if not success_failsafe: msg = "Installing the '{}' pip package failed (fsafe)".format( pkg) logger.error(msg)
def install_pip_packages(progress, priority=Priority.NONE): # Urgent updates don't do PIP updates if priority == Priority.URGENT: return phase_name = progress.get_current_phase().name packages = read_file_contents_as_lines(PIP_PACKAGES_LIST) progress.init_steps(phase_name, len(packages)) for pkg in packages: progress.next_step(phase_name, "Installing {}".format(pkg)) success = run_pip_command( "install --upgrade --no-index --find-links=file://{} '{}'".format( PIP_CACHE_DIR, pkg)) if not success: msg = "Installing the '{}' pip package failed".format(pkg) logger.error(msg) if not is_internet(): msg = "Network is down, aborting PIP install" logger.error(msg) raise IOError(msg) # Try with the failsafe method success_failsafe = run_pip_command( "install --upgrade '{}'".format(pkg)) if not success_failsafe: msg = "Installing the '{}' pip package failed (fsafe)".format( pkg) logger.error(msg)
def first_scene(self): if not is_internet(): self.next_stage() return s = self._setup_first_scene() self._ctl.main_window.push(s)
def switch_to_home(self): self.prev_view = [] if is_internet(): self.view = HomeView() self.contents.set_contents(self.view) else: self.switch_view('no-internet')
def first_scene(self): if is_internet(): self._ctl.set_var("has_internet", True) self._ctl.next_stage() return s = self._setup_first_scene() self._ctl.main_window.push(s)
def login_screen(self, widget, event): self.win.remove_main_widget() if is_internet(): # Hand-off from the Gtk to the web view Gtk.main_quit() os.system('{} {} {}'.format(FirstScreen.webengine, AUTH_URL, FirstScreen.win_size)) else: NoInternet(self.win)
def second_scene(self): # TODO: uncomment before release # Jump directly at the end if we have internet if is_internet(): track_action('init-flow-connected-already') self.connected_scene() return s2 = self._setup_second_scene() self._ctl.main_window.push(s2)
def share_theme(): # Check for internet if not is_internet(): coloured_error, junk1, junk2 = run_cmd( 'colour_echo "{{8 x }} {{7 error: }}"') print "\n " + coloured_error.strip('\n') + _( 'You need internet connection') exit(2) # Check for login success, junk2 = login_using_token() if not success: coloured_error, junk1, junk2 = run_cmd( 'colour_echo "{{8 x }} {{7 error: }}"') print "\n " + coloured_error.strip('\n') + _( 'You need to login to Kano World') exit(2) # Print themes print_themes(False, False) # Select theme dialogue message = _(" 1) Select a theme: ") theme = raw_input(message) theme += '.xml' # Check theme exists check_valid_theme(theme) # Select title message = _(" 2) Write a title: ") title = raw_input(message) if title: # The API limits title to 200 characters (cut it here) title = title[:200] else: title = 'My snake' # Select description message = _(" 3) Write a description: ") description = raw_input(message) if description: # The API limits description to 500 characters (cut it here) description = description[:500] # Create json create_share_json(theme, title, description) # Share filepath = os.path.join(app_dir, theme) success, msg = upload_share(filepath, title, 'make-snake') if not success: coloured_error, junk1, junk2 = run_cmd( 'colour_echo "{{8 x }} {{7 error: }}"') print "\n " + coloured_error.strip( '\n') + _('Sharing of {} failed. {}\n') % (theme, msg) exit(2) message, junk1, junk2 = run_cmd( 'colour_echo "{{4 + }} {{3 You have shared your theme successfully }}"' ) print "\n " + message.strip('\n') increment_app_state_variable_with_dialog('make-snake', 'shared', 1) exit(2)
def share(filename): # TODO: Move this connection handling into a function in Kano Utils import subprocess if not is_internet(): subprocess.call(["sudo", "kano-settings", "4"]) if not is_internet(): return "You have no internet" data = json.loads(request.data) filename, filepath = _save(data) success, msg = login_and_share(filepath, filename, APP_NAME) if not success: return msg increment_app_state_variable_with_dialog(APP_NAME, "shared", 1) return ""
def log_user_in(self): if not is_internet(): title = _("You don't have internet!") description = _("Connect with wifi or ethernet and try again") return_value = 0 else: (title, description, return_value) = self.log_user_in_with_internet() GObject.idle_add(self.show_login_status_dialog, title, description, return_value)
def activate(self, _, event): """ Move to the first setup screen """ if not hasattr(event, 'keyval') or event.keyval == 65293: self.win.clear_win() if not detect_kano_keyboard(): KeyboardScreen(self.win) elif not is_internet(): InternetScreen(self.win) else: SettingsIntroScreen(self.win)
def log_user_in(self): if not is_internet(): title = _("You don't have internet!") description = _( "Connect with wifi or ethernet and try again" ) return_value = 0 else: (title, description, return_value) = self.log_user_in_with_internet() GObject.idle_add(self.show_login_status_dialog, title, description, return_value)
def switch_to_youtube(self, search_keyword=None, users=False, page=1): if is_internet(): cursor = Gdk.Cursor.new(Gdk.CursorType.WATCH) self.get_root_window().set_cursor(cursor) Gtk.main_iteration_do(True) self.prev_view = [] self.view = YoutubeView(search_keyword, users, page=page) self.contents.set_contents(self.view) cursor = Gdk.Cursor.new(Gdk.CursorType.ARROW) self.get_root_window().set_cursor(cursor) else: self.switch_view('no-internet')
def share_theme(): # Check for internet if not is_internet(): coloured_error, _, _ = run_cmd('colour_echo "{{8 x }} {{7 error: }}"') print "\n " + coloured_error.strip( '\n') + 'You need internet connection' exit(2) # Check for login success, _ = login_using_token() if not success: coloured_error, _, _ = run_cmd('colour_echo "{{8 x }} {{7 error: }}"') print "\n " + coloured_error.strip( '\n') + 'You need to login to Kano World' exit(2) # Print themes print_themes(False, False) # Select theme dialogue message = " 1) Select a theme: " theme = raw_input(message) theme += '.xml' # Check theme exists check_valid_theme(theme) # Select title message = " 2) Write a title: " title = raw_input(message) if not title: title = 'My snake' # Select description message = " 3) Write a description: " description = raw_input(message) # Create json create_share_json(theme, title, description) # Share filepath = os.path.join(app_dir, theme) success, msg = upload_share(filepath, title, 'make-snake') if not success: coloured_error, _, _ = run_cmd('colour_echo "{{8 x }} {{7 error: }}"') print "\n " + coloured_error.strip( '\n') + 'Sharing of %s failed. %s\n' % (theme, msg) exit(2) message, _, _ = run_cmd( 'colour_echo "{{4 + }} {{3 You have shared your theme successfully }}"' ) print "\n " + message.strip('\n') increment_app_state_variable_with_dialog('make-snake', 'shared', 1) exit(2)
def register_handler(self, widget=None, arg=None): if not is_internet(): internet_present = self.try_to_connect_to_internet() if not internet_present: quit_dialog = KanoDialog( _("The package was returned to sender"), _("I just tried to send your profile to Kano HQ, \n" \ "but it looks like I don't have any Internet! ") + \ "\n" + \ _("You can keep playing and I'll keep your \n" \ "profile safe in my brain until you connect.") ) quit_dialog.run() Gtk.main_quit() return self.register_user_with_gui()
def lengthy_process(): button_dict = {"OK": {"return_value": self.CLOSE_FEEDBACK}} if not is_internet(): title = "No internet connection" description = "Configure your connection" button_dict = {"OK": {"return_value": self.LAUNCH_WIFI}} else: success, error = self.send_user_info(body_title=body_title) if success: title = "Info" description = "Feedback sent correctly" button_dict = {"OK": {"return_value": self.CLOSE_FEEDBACK}} else: title = "Info" description = "Something went wrong, error: {}".format(error) button_dict = { "CLOSE FEEDBACK": {"return_value": self.CLOSE_FEEDBACK, "color": "red"}, "TRY AGAIN": {"return_value": self.KEEP_OPEN, "color": "green"}, } def done(title, description, button_dict): self.set_cursor_to_normal() self._send_button.stop_spinner() self._send_button.set_sensitive(True) self._text.set_sensitive(True) # If the user decides to launch the wifi config, # the window needs to be able to go below kano-settings self.set_keep_above(False) kdialog = KanoDialog(title, description, button_dict, parent_window=self) kdialog.dialog.set_keep_above(False) response = kdialog.run() if response == self.LAUNCH_WIFI: run_cmd("sudo /usr/bin/kano-settings 12") self.after_feedback_sent(completed=False) elif response == self.CLOSE_FEEDBACK: self.after_feedback_sent(completed=True) GObject.idle_add(done, title, description, button_dict)
def __init__(self, screen_number=None, screen_name=None, socket_id=0, onescreen=False): # Check for internet, if screen is 12 means no internet if screen_number == 12 or screen_name == 'no-internet': common.has_internet = False else: common.has_internet = is_internet() # Set combobox styling to the screen # Is done here so we don't attach the styling multiple times when # switching screens apply_styling_to_screen(self.CSS_PATH) apply_common_to_screen() KanoComboBox.apply_styling_to_screen() ScrolledWindow.apply_styling_to_screen(wide=True) # Set window base_class.__init__(self, _("Settings"), self.width, self.height, socket_id) self.set_decorated(True) self.top_bar = TopBar(_("Settings")) self.top_bar.set_close_callback(self.close_window) self.prev_handler = None self.set_icon_name('kano-settings') if self._base_name == "Window": self.set_titlebar(self.top_bar) self._onescreen = onescreen self.connect('delete-event', Gtk.main_quit) # In case we are called from kano-world-launcher, terminate splash os.system('kano-stop-splash') # Init to Home Screen HomeScreen(self, screen_number=screen_number, screen_name=screen_name)
def share_theme(): # Check for internet if not is_internet(): coloured_error, _, _ = run_cmd('colour_echo "{{8 x }} {{7 error: }}"') print "\n " + coloured_error.strip('\n') + 'You need internet connection' exit(2) # Check for login success, _ = login_using_token() if not success: coloured_error, _, _ = run_cmd('colour_echo "{{8 x }} {{7 error: }}"') print "\n " + coloured_error.strip('\n') + 'You need to login to Kano World' exit(2) # Print themes print_themes(False, False) # Select theme dialogue message = " 1) Select a theme: " theme = raw_input(message) theme += '.xml' # Check theme exists check_valid_theme(theme) # Select title message = " 2) Write a title: " title = raw_input(message) if not title: title = 'My snake' # Select description message = " 3) Write a description: " description = raw_input(message) # Create json create_share_json(theme, title, description) # Share filepath = os.path.join(app_dir, theme) success, msg = upload_share(filepath, title, 'make-snake') if not success: coloured_error, _, _ = run_cmd('colour_echo "{{8 x }} {{7 error: }}"') print "\n " + coloured_error.strip('\n') + 'Sharing of %s failed. %s\n' % (theme, msg) exit(2) message, _, _ = run_cmd('colour_echo "{{4 + }} {{3 You have shared your theme successfully }}"') print "\n " + message.strip('\n') increment_app_state_variable_with_dialog('make-snake', 'shared', 1) exit(2)
def _load_remote_prompts(self, num_retries=10): ''' Get the prompts/questions through a request, retrying <num_retries> if network is not up. ''' for attempt in xrange(0, num_retries): if attempt != 0: time.sleep(2) if not is_internet(): continue try: # Contact Kano questions API success, error, res = request_wrapper('get', '/questions') if not success: logger.warn( 'Error loading prompts from API (try {}): {}'.format( attempt, error)) continue prompts = sorted(res['questions'], key=lambda k: k['date_created']) if not len(prompts): return False self.prompts = prompts return True except Exception as exception: logger.error('Error loading prompts (try {}): {}'.format( attempt, exception)) return False
def try_to_connect_to_internet(self, attempt_no=1): """ Attempt to connect to the internet :param attempt_no: Number of connection attempts already tried :returns: If the attempt resulted in an Internet connection """ if attempt_no == 1: title = _("You don't have internet!") description = _("Connect to WiFi and try again.") else: title = _("Still not connected...") description = _("Seems like you're having trouble connecting.") + \ "\n" + _("Try again later at another point") connect_choice = self.connect_dialog(title, description) if connect_choice == 'connect': self.win.blur() while Gtk.events_pending(): Gtk.main_iteration() logger.debug("Launching WiFi GUI, attempt #{}".format(attempt_no)) os.system("sudo /usr/bin/kano-wifi-gui") logger.debug("Finished connection attempt #{}".format(attempt_no)) if is_internet(): return True if attempt_no >= 2: return False return self.try_to_connect_to_internet(attempt_no + 1) else: return False
def _load_remote_prompts(self, num_retries=10): ''' Get the prompts/questions through a request, retrying <num_retries> if network is not up. ''' for attempt in xrange(0, num_retries): if attempt != 0: time.sleep(2) if not is_internet(): continue try: # Contact Kano questions API success, error, res = request_wrapper('get', '/questions') if not success: logger.warn('Error loading prompts from API (try {}): {}' .format(attempt, error)) continue prompts = sorted(res['questions'], key=lambda k: k['date_created']) if not len(prompts): return False self.prompts = prompts return True except Exception as exception: logger.error('Error loading prompts (try {}): {}' .format(attempt, exception)) return False
def is_fulfilled(self): return is_internet()
def check_for_updates(min_time_between_checks=0, progress=None): status = UpdaterStatus.get_instance() # FIXME: FOR DEBUGGING ONLY #status.state = UpdaterStatus.UPDATES_AVAILABLE #status.last_check = int(time.time()) #status.save() #return True if not progress: progress = DummyProgress() if status.state != UpdaterStatus.NO_UPDATES: msg = _('No need to check for updates') logger.info(msg) progress.abort(msg) # Return True in all cases except when the state is UPDATES_INSTALLED # In that case, we've just updated and don't want to check for updates # again. return status.state != UpdaterStatus.UPDATES_INSTALLED if min_time_between_checks: target_delta = float(min_time_between_checks) * 60 * 60 time_now = time.time() delta = time_now - status.last_check if delta > target_delta: logger.info(_('Time check passed, doing update check!')) else: msg = _('Not enough time passed for a new update check!') logger.info(msg) progress.abort(msg) return False if not is_internet(): err_msg = _('Must have internet to check for updates') logger.error(err_msg) progress.fail(err_msg) return False if not is_server_available(): err_msg = _('Could not connect to the download server') logger.error(err_msg) progress.fail(err_msg) return False if _do_check(progress): status.state = UpdaterStatus.UPDATES_AVAILABLE logger.debug('Updates available') rv = True else: status.state = UpdaterStatus.NO_UPDATES logger.debug('No updates available') rv = False status.last_check = int(time.time()) status.save() return rv
def check_for_updates(progress=None, priority=Priority.NONE, is_gui=False): status = UpdaterStatus.get_instance() # FIXME: FOR DEBUGGING ONLY #status.state = UpdaterStatus.UPDATES_AVAILABLE #status.last_check = int(time.time()) #status.save() #return True if not progress: progress = DummyProgress() countdown = status.first_boot_countdown - int(time.time()) # block update checks when: # 1) three days have NOT passed since the first boot # 2) and not checking for URGENT updates # 3) and the check is triggered from background hooks (not by user) if (countdown > 0) and (priority is not Priority.URGENT) and (not is_gui): return False if status.state != UpdaterStatus.NO_UPDATES: msg = _('No need to check for updates') logger.info(msg) # This was a successful check, so we need to update the timestamp. status.last_check = int(time.time()) status.save() # Return True in all cases except when the state is UPDATES_INSTALLED # In that case, we've just updated and don't want to check for updates # again. return status.state != UpdaterStatus.UPDATES_INSTALLED if not is_internet(): err_msg = _('Must have internet to check for updates') logger.error(err_msg) progress.fail(err_msg) # Not updating the timestamp. The check failed. return False if not is_server_available(): err_msg = _('Could not connect to the download server') logger.error(err_msg) progress.fail(err_msg) # Not updating the timestamp. The check failed. return False update_type = _do_check(progress, priority=priority) if update_type == Priority.NONE: status.state = UpdaterStatus.NO_UPDATES logger.debug('No updates available') rv = False else: if update_type == Priority.URGENT: status.notifications_muted = True status.is_urgent = True status.state = UpdaterStatus.UPDATES_AVAILABLE logger.debug('Updates available') logger.debug('Found update of priority: {}'.format(priority.priority)) rv = True if priority <= Priority.STANDARD: status.last_check = int(time.time()) status.last_check_urgent = int(time.time()) status.save() return rv
def check_for_updates(progress=None, priority=Priority.NONE, is_gui=False): status = UpdaterStatus.get_instance() if not progress: progress = DummyProgress() countdown = status.first_boot_countdown - int(time.time()) # block update checks when: # 1) three days have NOT passed since the first boot # 2) and not checking for URGENT updates # 3) and the check is triggered from background hooks (not by user) if (countdown > 0) and (priority is not Priority.URGENT) and (not is_gui): return False if status.state not in [UpdaterStatus.NO_UPDATES, UpdaterStatus.UPDATES_DOWNLOADED]: msg = "No need to check for updates" logger.info(msg) # This was a successful check, so we need to update the timestamp. status.last_check = int(time.time()) status.save() # Return True in all cases except when the state is UPDATES_INSTALLED # In that case, we've just updated and don't want to check for updates # again. return status.state != UpdaterStatus.UPDATES_INSTALLED if not is_internet(): err_msg = N_("Must have internet to check for updates") logger.error(err_msg) progress.fail(_(err_msg)) RCState.get_instance().rc = RC.NO_NETWORK # Not updating the timestamp. The check failed. return False if not is_server_available(): err_msg = N_("Could not connect to the download server") logger.error(err_msg) progress.fail(_(err_msg)) RCState.get_instance().rc = RC.CANNOT_REACH_KANO # Not updating the timestamp. The check failed. return False update_type = _do_check(progress, priority=priority) if update_type == Priority.NONE: # If the Updater is running in recovery mode, do not update the state # out of the installing ones, otherwise the recovery flow will quit. if not status.is_recovery_needed(): status.state = UpdaterStatus.NO_UPDATES logger.info("No updates available") RCState.get_instance().rc = RC.NO_UPDATES_AVAILABLE rv = False else: if update_type == Priority.URGENT: status.notifications_muted = True status.is_urgent = True if not status.is_recovery_needed(): status.state = UpdaterStatus.UPDATES_AVAILABLE logger.info("Updates available") logger.info("Found update of priority: {}".format(priority.priority)) rv = True if priority <= Priority.STANDARD: status.last_check = int(time.time()) # always check independent packages as NONE as urgent updates to # these packages are dealt with by the main updater status.updatable_independent_packages = get_ind_packages(Priority.NONE) status.last_check_urgent = int(time.time()) status.save() return rv
def check_for_updates(progress=None, priority=Priority.NONE, is_gui=False): status = UpdaterStatus.get_instance() # FIXME: FOR DEBUGGING ONLY #status.state = UpdaterStatus.UPDATES_AVAILABLE #status.last_check = int(time.time()) #status.save() #return True if not progress: progress = DummyProgress() countdown = status.first_boot_countdown - int(time.time()) # block update checks when: # 1) three days have NOT passed since the first boot # 2) and not checking for URGENT updates # 3) and the check is triggered from background hooks (not by user) if (countdown > 0) and (priority is not Priority.URGENT) and (not is_gui): return False if status.state != UpdaterStatus.NO_UPDATES: msg = "No need to check for updates" logger.info(msg) # This was a successful check, so we need to update the timestamp. status.last_check = int(time.time()) status.save() # Return True in all cases except when the state is UPDATES_INSTALLED # In that case, we've just updated and don't want to check for updates # again. return status.state != UpdaterStatus.UPDATES_INSTALLED if not is_internet(): err_msg = N_("Must have internet to check for updates") logger.error(err_msg) progress.fail(_(err_msg)) # Not updating the timestamp. The check failed. return False if not is_server_available(): err_msg = N_("Could not connect to the download server") logger.error(err_msg) progress.fail(_(err_msg)) # Not updating the timestamp. The check failed. return False update_type = _do_check(progress, priority=priority) if update_type == Priority.NONE: status.state = UpdaterStatus.NO_UPDATES logger.debug("No updates available") rv = False else: if update_type == Priority.URGENT: status.notifications_muted = True status.is_urgent = True status.state = UpdaterStatus.UPDATES_AVAILABLE logger.debug("Updates available") logger.debug("Found update of priority: {}".format(priority.priority)) rv = True if priority <= Priority.STANDARD: status.last_check = int(time.time()) # always check independent packages as NONE as urgent updates to # these packages are dealt with by the main updater status.updatable_independent_packages = get_ind_packages(Priority.NONE) status.last_check_urgent = int(time.time()) status.save() return rv
def _on_register_button(self, widget=None): # TODO: refactor this """ """ if not is_internet(): self._show_not_internet_dialog() return # Get the username, password and birthday data = self.data_screen.get_widget_data() email = data['email'] username = data['username'] # Validate that the email address format is correct email_error = validate_email(email) if email_error: self._show_error_dialog(_("Incorrect Email address"), email_error) return if not self._is_username_available(username): self._show_username_taken_dialog(username) return # We can save the username to kano-profile # Don't save password as this is private self.data_screen.save_username_and_birthday() # TODO: rename this self.data_screen.cache_emails() data = self.data_screen.get_widget_data() # This means no threads are needed. while Gtk.events_pending(): # TODO: why is this needed? Gtk.main_iteration() # Try and register the account on the server password = data['password'] success, text = register_(email, username, password, marketing_enabled=True) # This should no longer be needed, since this is checked in the first # screen. However there is a small chance someone could take the # username while the user is in the process of registering if not success: if text.strip() == _("Cannot register, problem: " "Username already registered"): self._show_username_taken_dialog(username) else: logger.info("problem with registration: {}".format(text)) return_value = 'FAIL' self._create_dialog( title=_("Houston, we have a problem"), description=str(text) ) track_data('world-registration-failed', {'reason': text}) else: logger.info("registration successful") # saving hardware info and initial Kano version save_hardware_info() save_kano_version() # running kano-sync after registration logger.info("running kano-sync after successful registration") cmd = '{bin_dir}/kano-sync --sync -s'.format(bin_dir=bin_dir) run_bg(cmd) return_value = 'SUCCEED' self._create_dialog( title=_("Profile activated!"), description=_("Now you can share stuff, build your character, " "and connect with friends.") ) self.win.get_window().set_cursor(None) # Close the app if it was successful if return_value == 'SUCCEED': Gtk.main_quit()
def _cb_wrapper(self, widget, connected_cb, fail_cb): # if there is internet, then the user suceeded with connecting if is_internet(): connected_cb() else: fail_cb()
def next_page(self, widget): age, bday_date, error = self.data_screen.calculate_age() if age == -1: self._show_error_dialog(error[0], error[1]) return # Get the username, password and birthday data = self.data_screen.get_widget_data() username = data["username"] if not is_internet(): kd = KanoDialog( "You don't have internet", "Do you want to connect to WiFi?", [ { "label": "YES", "color": "green", "return_value": 0 }, { "label": "NO", "color": "red", "return_value": 1 } ], parent_window=self.win ) response = kd.run() # Close the dialog while Gtk.events_pending(): Gtk.main_iteration() if response == 0: subprocess.Popen("sudo kano-wifi-gui", shell=True) return if not self.is_username_available(username): track_data('world-registration-username-taken', {'username': username}) kd = KanoDialog( "This username is taken!", "Try another one", parent_window=self.win ) kd.run() self.data_screen.username.set_text("") self.data_screen.validate_username() self.data_screen.username.grab_focus() return self.win.data = data # We can save the username and birthday to kano-profile # Don't save password as this is private self.data_screen.save_username_and_birthday() self.win.remove_main_widget() # Pass the age to the third registration screen so we can show the # appropriate number of entries available RegistrationScreen2(self.win, age)
def __init__(self, win): Template.__init__(self, "", _("to be set"), _("COMPLETE")) self.win = win self.win.set_main_widget(self) self.kano_button.connect('button-release-event', self.win.go_to_home) internet_img = Gtk.Image() # Very hacky way to centre the Proxy button - put spaces in the label self.proxy_button = OrangeButton(_("Proxy ")) self.proxy_button.connect('button-release-event', self.go_to_proxy) self.disable_proxy = OrangeButton(_("Disable proxy")) self.win.change_prev_callback(self.win.go_to_home) self.win.top_bar.enable_prev() internet_status = Gtk.Label() internet_status_style = internet_status.get_style_context() internet_status.set_alignment(xalign=1, yalign=0.5) internet_action = Gtk.Label() internet_action_style = internet_action.get_style_context() internet_status_style.add_class('internet_status_top') internet_action_style.add_class('internet_status_bottom') internet_action.set_alignment(xalign=1, yalign=0.5) status_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0) status_box.props.valign = Gtk.Align.CENTER configure_container = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=0) container = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=0) container.pack_start(status_box, False, False, 2) container.pack_start(internet_img, False, False, 2) self.box.pack_start(container, False, False, 0) network_info_dict = network_info() common.has_internet = is_internet() if not common.has_internet or not network_info_dict: if network_info_dict: description = _("Use the browser to log in or configure proxy") else: description = _("Configure wireless") title = _("Get connected") self.add_connection = KanoButton(_("WIFI")) self.add_connection.connect('button_release_event', self.configure_wifi) # We removed the ability to use keyboard to click, so we also remove ability # to get keyboard focus self.add_connection.set_can_focus(False) # For now, this is removed as the event listener is interefering with the # kano-connect #self.add_connection.connect("key_release_event", self.configure_wifi) status_box.pack_start(self.add_connection, False, False, 0) internet_img.set_from_file(common.media + "/Graphics/Internet-noConnection.png") internet_status.set_text(_("No network found")) self.kano_button.set_label(_("BACK")) status_box.pack_start(configure_container, False, False, 3) go_to_portal_button = OrangeButton(_("Browser Login")) go_to_portal_button.connect('button-press-event', self.cb_launch_browser) configure_container.pack_start(go_to_portal_button, False, False, 0) divider_label = Gtk.Label("|") configure_container.pack_start(divider_label, False, False, 3) configure_container.pack_end(self.proxy_button, False, False, 0) else: self.kano_button.set_label(_("COMPLETE")) status_box.pack_start(internet_status, False, False, 3) status_box.pack_start(internet_action, False, False, 3) status_box.pack_start(configure_container, False, False, 3) network = network_info_dict.keys()[0] ip = network_info_dict[network]['address'] network_text = network_info_dict[network]['nice_name'] internet_img.set_from_file(common.media + "/Graphics/Internet-Connection.png") internet_status.set_text(network_text) internet_action.set_text(ip) go_to_portal_button = OrangeButton(_("Browser Login")) go_to_portal_button.connect('button-press-event', self.cb_launch_browser) configure_container.pack_start(go_to_portal_button, False, False, 0) if network_text == 'Ethernet': title = _("Connection found!") description = _("You're on a wired network") # Change to ethernet image here internet_img.set_from_file(common.media + "/Graphics/Internet-ethernetConnection.png") else: title = _("Connection found!") description = _("You're on a wireless network") divider_label = Gtk.Label("|") configure_container.pack_start(divider_label, False, False, 3) configure_button = OrangeButton(_("Configure")) configure_button.connect('button_press_event', self.configure_wifi) configure_container.pack_start(configure_button, False, False, 0) divider_label = Gtk.Label("|") configure_container.pack_start(divider_label, False, False, 3) configure_container.pack_end(self.proxy_button, False, False, 0) self.title.title.set_text(title) self.title.description.set_text(description) self.win.show_all()
def download(progress=None, gui=True): status = UpdaterStatus.get_instance() dialog_proc = None if not progress: progress = DummyProgress() if status.state == UpdaterStatus.NO_UPDATES: progress.split( Phase( 'checking', _("Checking for updates"), 10, is_main=True ), Phase( 'downloading', _("Downloading updates"), 90, is_main=True ) ) progress.start('checking') check_for_updates(progress=progress) if status.state == UpdaterStatus.NO_UPDATES: logger.info("No updates to download") progress.finish(_("No updates to download")) return False progress.start('downloading') elif status.state == UpdaterStatus.UPDATES_DOWNLOADED: err_msg = N_("Updates have been downloaded already") logger.error(err_msg) progress.abort(_(err_msg)) return True elif status.state == UpdaterStatus.DOWNLOADING_UPDATES: err_msg = N_("The download is already running") logger.error(err_msg) progress.abort(_(err_msg)) return False elif status.state == UpdaterStatus.INSTALLING_UPDATES: err_msg = N_("Updates are already being installed") logger.error(err_msg) progress.abort(_(err_msg)) return False if not is_internet(): err_msg = N_("Must have internet to download the updates") logger.error(err_msg) progress.fail(_(err_msg)) return False if not is_server_available(): err_msg = N_("Could not connect to the download server") logger.error(err_msg) progress.fail(_(err_msg)) return False # show a dialog informing the user of an automatic urgent download if status.is_urgent and not gui: # TODO: mute notifications? title = _("Updater") description = _("Kano HQ has just released a critical update that will repair" \ " some important things on your system! We'll download these automatically," \ " and ask you to schedule the install when they finish.") buttons = _("OK:green:1") dialog_proc = show_kano_dialog(title, description, buttons, blocking=False) status.state = UpdaterStatus.DOWNLOADING_UPDATES status.save() priority = Priority.NONE if status.is_urgent: priority = Priority.URGENT logger.info("Urgent update detected, bumping to normal priority") make_normal_prio() logger.debug("Downloading with priority {}".format(priority.priority)) try: success = do_download(progress, status, priority=priority, dialog_proc=dialog_proc) except Exception as err: progress.fail(err.message) logger.error(err.message) status.state = UpdaterStatus.UPDATES_AVAILABLE status.save() return False status.state = UpdaterStatus.UPDATES_DOWNLOADED status.save() return success
def download(progress=None, gui=True): status = UpdaterStatus.get_instance() dialog_proc = None if not progress: progress = DummyProgress() if status.state == UpdaterStatus.NO_UPDATES: progress.split( Phase( 'checking', _('Checking for updates'), 10, is_main=True ), Phase( 'downloading', _('Downloading updates'), 90, is_main=True ) ) progress.start('checking') check_for_updates(progress=progress) if status.state == UpdaterStatus.NO_UPDATES: progress.finish(_('No updates to download')) return False progress.start('downloading') elif status.state == UpdaterStatus.UPDATES_DOWNLOADED: err_msg = _('Updates have been downloaded already') logger.error(err_msg) progress.abort(err_msg) return True elif status.state == UpdaterStatus.DOWNLOADING_UPDATES: err_msg = _('The download is already running') logger.error(err_msg) progress.abort(err_msg) return False elif status.state == UpdaterStatus.INSTALLING_UPDATES: err_msg = _('Updates are already being installed') logger.error(err_msg) progress.abort(err_msg) return False if not is_internet(): err_msg = _('Must have internet to download the updates') logger.error(err_msg) progress.fail(err_msg) return False if not is_server_available(): err_msg = _('Could not connect to the download server') logger.error(err_msg) progress.fail(err_msg) return False # show a dialog informing the user of an automatic urgent download if status.is_urgent and not gui: # TODO: mute notifications? title = "Updater" description = "Kano HQ has just released a critical update that will repair" \ " some important things on your system! We'll download these automatically," \ " and ask you to schedule the install when they finish." buttons = "OK:green:1" dialog_proc = show_kano_dialog(title, description, buttons, blocking=False) status.state = UpdaterStatus.DOWNLOADING_UPDATES status.save() priority = Priority.NONE if status.is_urgent: priority = Priority.URGENT logger.info('Urgent update detected, bumping to normal priority') make_normal_prio() logger.debug('Downloading with priority {}'.format(priority.priority)) try: success = do_download(progress, status, priority=priority, dialog_proc=dialog_proc) except Exception as err: progress.fail(err.message) logger.error(err.message) status.state = UpdaterStatus.UPDATES_AVAILABLE status.save() return False status.state = UpdaterStatus.UPDATES_DOWNLOADED status.save() return success
def lengthy_process(): button_dict = {_("OK"): {"return_value": self.CLOSE_FEEDBACK}} if not is_internet(): title = _("No internet connection") description = _("Configure your connection") button_dict = {_("OK"): {"return_value": self.LAUNCH_WIFI}} else: success, error = self.send_user_info(body_title=body_title) if success: title = _("Info") description = _("Feedback sent correctly") button_dict = \ { _("OK"): { "return_value": self.CLOSE_FEEDBACK } } else: title = _("Info") description = _( "Something went wrong, error: {}").format(error) button_dict = \ { _("CLOSE FEEDBACK"): { "return_value": self.CLOSE_FEEDBACK, "color": "red" }, _("TRY AGAIN"): { "return_value": self.KEEP_OPEN, "color": "green" } } def done(title, description, button_dict): self.set_cursor_to_normal() self._send_button.stop_spinner() self._send_button.set_sensitive(True) self._text.set_sensitive(True) # If the user decides to launch the wifi config, # the window needs to be able to go below kano-settings self.set_keep_above(False) kdialog = KanoDialog(title, description, button_dict, parent_window=self) kdialog.dialog.set_keep_above(False) response = kdialog.run() if response == self.LAUNCH_WIFI: run_cmd('sudo /usr/bin/kano-settings 12', localised=True) self.after_feedback_sent(completed=False) elif response == self.CLOSE_FEEDBACK: self.after_feedback_sent(completed=True) GObject.idle_add(done, title, description, button_dict)
def download(progress=None, gui=True): status = UpdaterStatus.get_instance() dialog_proc = None if not progress: progress = DummyProgress() if status.state in [ UpdaterStatus.NO_UPDATES, UpdaterStatus.UPDATES_DOWNLOADED ]: progress.split( Phase('checking', _("Checking for updates"), 10, is_main=True), Phase('downloading', _("Downloading updates"), 90, is_main=True)) pre_check_state = status.state progress.start('checking') check_for_updates(progress=progress) if status.state == UpdaterStatus.NO_UPDATES: if pre_check_state == UpdaterStatus.NO_UPDATES: msg = N_("No updates to download") logger.info(msg) progress.finish(_(msg)) return False elif pre_check_state == UpdaterStatus.UPDATES_DOWNLOADED: err_msg = N_("Latest updates have been downloaded already") logger.info(err_msg) progress.abort(_(err_msg)) return True progress.start('downloading') elif status.state == UpdaterStatus.DOWNLOADING_UPDATES: err_msg = N_("The download is already running") logger.error(err_msg) progress.abort(_(err_msg)) return False if not is_internet(): err_msg = N_("Must have internet to download the updates") logger.error(err_msg) progress.fail(_(err_msg)) RCState.get_instance().rc = RC.NO_NETWORK return False if not is_server_available(): err_msg = N_("Could not connect to the download server") logger.error(err_msg) progress.fail(_(err_msg)) RCState.get_instance().rc = RC.CANNOT_REACH_KANO return False # show a dialog informing the user of an automatic urgent download if status.is_urgent and not gui: # TODO: mute notifications? title = _("Updater") description = _( "Kano HQ has just released a critical update that will repair" " some important things on your system! We'll download these" " automatically, and ask you to schedule the install when they finish." ) buttons = _("OK:green:1") dialog_proc = show_kano_dialog(title, description, buttons, blocking=False) # If the Updater is running in recovery mode, do not update the state # out of the installing ones, otherwise the recovery flow will quit. if not status.is_recovery_needed(): status.state = UpdaterStatus.DOWNLOADING_UPDATES status.save() priority = Priority.NONE if status.is_urgent: priority = Priority.URGENT logger.info("Urgent update detected, bumping to normal priority") make_normal_prio() logger.debug("Downloading with priority {}".format(priority.priority)) try: success = do_download(progress, status, priority=priority, dialog_proc=dialog_proc) except Exception as err: progress.fail(err.message) logger.error(err.message) RCState.get_instance().rc = RC.UNEXPECTED_ERROR status.state = UpdaterStatus.UPDATES_AVAILABLE status.save() return False if not status.is_recovery_needed(): status.state = UpdaterStatus.UPDATES_DOWNLOADED status.save() return success
def _on_register_button(self, widget=None): # TODO: refactor this """ """ if not is_internet(): self._show_not_internet_dialog() return # Get the username, password and birthday data = self.data_screen.get_widget_data() email = data['email'] username = data['username'] # Validate that the email address format is correct email_error = validate_email(email) if email_error: self._show_error_dialog(_("Incorrect Email address"), email_error) return if not self._is_username_available(username): self._show_username_taken_dialog(username) return # We can save the username to kano-profile # Don't save password as this is private self.data_screen.save_username_and_birthday() # TODO: rename this self.data_screen.cache_emails() data = self.data_screen.get_widget_data() # This means no threads are needed. while Gtk.events_pending(): # TODO: why is this needed? Gtk.main_iteration() # Try and register the account on the server password = data['password'] success, text = register_(email, username, password, marketing_enabled=True) # This should no longer be needed, since this is checked in the first # screen. However there is a small chance someone could take the # username while the user is in the process of registering if not success: if text.strip() == _("Cannot register, problem: " "Username already registered"): self._show_username_taken_dialog(username) else: logger.info("problem with registration: {}".format(text)) return_value = 'FAIL' self._create_dialog(title=_("Houston, we have a problem"), description=str(text)) track_data('world-registration-failed', {'reason': text}) else: logger.info("registration successful") # saving hardware info and initial Kano version save_hardware_info() save_kano_version() # running kano-sync after registration logger.info("running kano-sync after successful registration") cmd = '{bin_dir}/kano-sync --sync -s'.format(bin_dir=bin_dir) run_bg(cmd) return_value = 'SUCCEED' self._create_dialog( title=_("Profile activated!"), description=_("Now you can share stuff, build your character, " "and connect with friends.")) self.win.get_window().set_cursor(None) # Close the app if it was successful if return_value == 'SUCCEED': Gtk.main_quit()
def __init__(self, win): Template.__init__(self, "", _("to be set"), _("COMPLETE")) self.win = win self.win.set_main_widget(self) self.kano_button.connect('button-release-event', self.win.go_to_home) internet_img = Gtk.Image() # Very hacky way to centre the Proxy button - put spaces in the label self.proxy_button = OrangeButton(_("Proxy ")) self.proxy_button.connect('button-release-event', self.go_to_proxy) self.disable_proxy = OrangeButton(_("Disable proxy")) self.win.change_prev_callback(self.win.go_to_home) self.win.top_bar.enable_prev() internet_status = Gtk.Label() internet_status_style = internet_status.get_style_context() internet_status.set_alignment(xalign=1, yalign=0.5) internet_action = Gtk.Label() internet_action_style = internet_action.get_style_context() internet_status_style.add_class('internet_status_top') internet_action_style.add_class('internet_status_bottom') internet_action.set_alignment(xalign=1, yalign=0.5) status_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0) status_box.props.valign = Gtk.Align.CENTER configure_container = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=0) container = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=0) container.pack_start(status_box, False, False, 2) container.pack_start(internet_img, False, False, 2) self.box.pack_start(container, False, False, 0) network_info_dict = network_info() common.has_internet = is_internet() if not common.has_internet or not network_info_dict: if network_info_dict: description = _("Use the browser to log in or configure proxy") else: description = _("Configure wireless") title = _("Get connected") self.add_connection = KanoButton(_("WIFI")) self.add_connection.connect('button_release_event', self.configure_wifi) # We removed the ability to use keyboard to click, so we also remove ability # to get keyboard focus self.add_connection.set_can_focus(False) # For now, this is removed as the event listener is interefering with the # kano-connect #self.add_connection.connect("key_release_event", self.configure_wifi) status_box.pack_start(self.add_connection, False, False, 0) internet_img.set_from_file(common.media + "/Graphics/Internet-noConnection.png") internet_status.set_text(_("No network found")) self.kano_button.set_label(_("BACK")) status_box.pack_start(configure_container, False, False, 3) go_to_portal_button = OrangeButton(_("Browser Login")) go_to_portal_button.connect('button-press-event', self.cb_launch_browser) configure_container.pack_start(go_to_portal_button, False, False, 0) divider_label = Gtk.Label("|") configure_container.pack_start(divider_label, False, False, 3) configure_container.pack_end(self.proxy_button, False, False, 0) else: self.kano_button.set_label(_("COMPLETE")) status_box.pack_start(internet_status, False, False, 3) status_box.pack_start(internet_action, False, False, 3) status_box.pack_start(configure_container, False, False, 3) network = network_info_dict.keys()[0] ip = network_info_dict[network]['address'] network_text = network_info_dict[network]['nice_name'] internet_img.set_from_file(common.media + "/Graphics/Internet-Connection.png") internet_status.set_text(network_text) internet_action.set_text(ip) go_to_portal_button = OrangeButton(_("Browser Login")) go_to_portal_button.connect('button-press-event', self.cb_launch_browser) configure_container.pack_start(go_to_portal_button, False, False, 0) if network_text == 'Ethernet': title = _("Connection found!") description = _("You're on a wired network") # Change to ethernet image here internet_img.set_from_file( common.media + "/Graphics/Internet-ethernetConnection.png") else: title = _("Connection found!") description = _("You're on a wireless network") divider_label = Gtk.Label("|") configure_container.pack_start(divider_label, False, False, 3) configure_button = OrangeButton(_("Configure")) configure_button.connect('button_press_event', self.configure_wifi) configure_container.pack_start(configure_button, False, False, 0) divider_label = Gtk.Label("|") configure_container.pack_start(divider_label, False, False, 3) configure_container.pack_end(self.proxy_button, False, False, 0) self.title.title.set_text(title) self.title.description.set_text(description) self.win.show_all()
def download(progress=None): status = UpdaterStatus.get_instance() if not progress: progress = DummyProgress() if status.state == UpdaterStatus.NO_UPDATES: progress.split( Phase('checking', _('Checking for updates'), 10, is_main=True), Phase('downloading', _('Downloading updates'), 90, is_main=True)) progress.start('checking') check_for_updates(progress=progress) if status.state == UpdaterStatus.NO_UPDATES: progress.finish(_('No updates to download')) return False progress.start('downloading') elif status.state == UpdaterStatus.UPDATES_DOWNLOADED: err_msg = _('Updates have been downloaded already') logger.error(err_msg) progress.abort(err_msg) return True elif status.state == UpdaterStatus.DOWNLOADING_UPDATES: err_msg = _('The download is already running') logger.error(err_msg) progress.abort(err_msg) return False elif status.state == UpdaterStatus.INSTALLING_UPDATES: err_msg = _('Updates are already being installed') logger.error(err_msg) progress.abort(err_msg) return False if not is_internet(): err_msg = _('Must have internet to download the updates') logger.error(err_msg) progress.fail(err_msg) return False if not is_server_available(): err_msg = _('Could not connect to the download server') logger.error(err_msg) progress.fail(err_msg) return False status.state = UpdaterStatus.DOWNLOADING_UPDATES status.save() try: success = do_download(progress, status) except Exception as err: progress.fail(err.message) logger.error(err.message) status.state = UpdaterStatus.UPDATES_AVAILABLE status.save() return False status.state = UpdaterStatus.UPDATES_DOWNLOADED status.save() return success
def download(progress=None, gui=True): status = UpdaterStatus.get_instance() dialog_proc = None if not progress: progress = DummyProgress() if status.state in [UpdaterStatus.NO_UPDATES, UpdaterStatus.UPDATES_DOWNLOADED]: progress.split( Phase( 'checking', _("Checking for updates"), 10, is_main=True ), Phase( 'downloading', _("Downloading updates"), 90, is_main=True ) ) pre_check_state = status.state progress.start('checking') check_for_updates(progress=progress) if status.state == UpdaterStatus.NO_UPDATES: if pre_check_state == UpdaterStatus.NO_UPDATES: msg = N_("No updates to download") logger.info(msg) progress.finish(_(msg)) return False elif pre_check_state == UpdaterStatus.UPDATES_DOWNLOADED: err_msg = N_("Latest updates have been downloaded already") logger.info(err_msg) progress.abort(_(err_msg)) return True progress.start('downloading') elif status.state == UpdaterStatus.DOWNLOADING_UPDATES: err_msg = N_("The download is already running") logger.error(err_msg) progress.abort(_(err_msg)) return False if not is_internet(): err_msg = N_("Must have internet to download the updates") logger.error(err_msg) progress.fail(_(err_msg)) RCState.get_instance().rc = RC.NO_NETWORK return False priority = Priority.NONE if status.is_urgent: priority = Priority.URGENT if not is_server_available(): err_msg = N_("Could not connect to the download server") logger.error(err_msg) progress.fail(_(err_msg)) RCState.get_instance().rc = RC.CANNOT_REACH_KANO return False run_cmd('sudo kano-empty-trash') enough_space, space_msg = check_disk_space(priority) if not enough_space: logger.error(space_msg) progress.abort(_(space_msg)) RCState.get_instance().rc = RC.NOT_ENOUGH_SPACE return False # show a dialog informing the user of an automatic urgent download if status.is_urgent and not gui: # TODO: mute notifications? title = _("Updater") description = _( "Kano HQ has just released a critical update that will repair some" " important things on your system! We'll download these automatically," " and ask you to schedule the install when they finish." ) buttons = _("OK:green:1") dialog_proc = show_kano_dialog(title, description, buttons, blocking=False) # If the Updater is running in recovery mode, do not update the state # out of the installing ones, otherwise the recovery flow will quit. if not status.is_recovery_needed(): status.state = UpdaterStatus.DOWNLOADING_UPDATES status.save() priority = Priority.NONE if status.is_urgent: priority = Priority.URGENT logger.info("Urgent update detected, bumping to normal priority") make_normal_prio() logger.debug("Downloading with priority {}".format(priority.priority)) try: success = do_download( progress, status, priority=priority, dialog_proc=dialog_proc ) except Exception as err: progress.fail(err.message) logger.error(err.message) RCState.get_instance().rc = RC.UNEXPECTED_ERROR status.state = UpdaterStatus.UPDATES_AVAILABLE status.save() return False if not status.is_recovery_needed(): status.state = UpdaterStatus.UPDATES_DOWNLOADED status.save() return success