def _save_level(world, challengeNo): old_xp = calculate_xp() needsToSave = False groups = load_app_state_variable(APP_NAME, 'groups') # We might need to load the worlds file here so that we're sure that # no one is abusing the API from the OS if groups is None: groups = {} if world in groups: if groups[world]['challengeNo'] < challengeNo: groups[world]['challengeNo'] = challengeNo needsToSave = True else: groups[world] = {'challengeNo': challengeNo} needsToSave = True if needsToSave: save_app_state_variable_with_dialog(APP_NAME, 'groups', groups) new_xp = calculate_xp() return str(new_xp - old_xp)
def _show_icon_tutorial(self): try: from kano_profile.apps import save_app_state_variable, load_app_state_variable if load_app_state_variable('kano-apps', 'icon-tutorial-shown'): return else: save_app_state_variable('kano-apps', 'icon-tutorial-shown', True) except ImportError: # ignore problems importing kano_profile, as we don't want it to # be a dependency pass kdialog = KanoDialog( _("Add more apps to the desktop"), _("Click the '+' button to the right of the app name to " "make it appear on the desktop. You can remove it again " "by clicking on 'x'."), {_("OK, GOT IT"): { "return_value": 0, "color": "green" }}, parent_window=self) kdialog.set_action_background("grey") kdialog.title.description.set_max_width_chars(40) kdialog.run()
def __init__(self): Gtk.Alignment.__init__( self, xalign=0.5, yalign=0.5, xscale=0, yscale=0 ) self.background = Gtk.EventBox() self.background.get_style_context().add_class("menu_background") self.background.set_size_request(self.width, self.height) self.add(self.background) # Find the greatest challenge that has been created according to # kano profile self.max_challenge = get_max_challenge_number() # Get the last unlocked challenge. self.last_unlocked_challenge = load_app_state_variable( 'linux-story', 'level' ) if self.last_unlocked_challenge: # If the last unlocked challenge is less than the max_challenge, # add one so the user can access the first locked-challenge. if self.last_unlocked_challenge < self.max_challenge: self.last_unlocked_challenge += 1 # With this data, we need to decide which chapters are locked. self.last_unlocked_chapter = challenges[self.last_unlocked_challenge]['chapter'] self.continue_story_or_select_chapter_menu()
def __init__(self): Gtk.Alignment.__init__(self, xalign=0.5, yalign=0.5, xscale=0, yscale=0) self.background = Gtk.EventBox() self.background.get_style_context().add_class("menu_background") self.background.set_size_request(self.width, self.height) self.add(self.background) # Find the greatest challenge that has been created according to # kano profile self.max_challenge = get_max_challenge_number() # Get the last unlocked challenge. self.last_unlocked_challenge = load_app_state_variable( 'linux-story', 'level') if self.last_unlocked_challenge: # If the last unlocked challenge is less than the max_challenge, # add one so the user can access the first locked-challenge. if self.last_unlocked_challenge < self.max_challenge: self.last_unlocked_challenge += 1 # With this data, we need to decide which chapters are locked. self.last_unlocked_chapter = challenges[ self.last_unlocked_challenge]['chapter'] self.continue_story_or_select_chapter_menu()
def _show_icon_tutorial(self): try: from kano_profile.apps import save_app_state_variable, load_app_state_variable if load_app_state_variable('kano-apps', 'icon-tutorial-shown'): return else: save_app_state_variable('kano-apps', 'icon-tutorial-shown', True) except ImportError: # ignore problems importing kano_profile, as we don't want it to # be a dependency pass kdialog = KanoDialog( _("Add more apps to the desktop"), _( "Click the '+' button to the right of the app name to " "make it appear on the desktop. You can remove it again " "by clicking on 'x'." ), { _("OK, GOT IT"): { "return_value": 0, "color": "green" } }, parent_window=self ) kdialog.set_action_background("grey") kdialog.title.description.set_max_width_chars(40) kdialog.run()
def record_user_interaction(instance, base_name): ''' This is to store some of the user actions, so we can determine if the user does the optional side quests. Args: The class instance. base_name (str): a string for the identity of the command. ''' class_instance = instance.__class__.__name__ challenge_number = instance.challenge_number profile_var_name = "{} {} {}".format(base_name, challenge_number, class_instance) # First, try loading the profile variable name # If the value is None, then make it True and increment the total. already_done = load_app_state_variable("linux-story", profile_var_name) # If the command has not been done yet in this class, then increment the # total if not already_done: save_app_state_variable("linux-story", profile_var_name, True) total_name = "{} total".format(base_name) increment_app_state_variable("linux-story", total_name, 1)
def completed_at_least_one_challenge(app_name): """ Returns True if the user has successfully completed a challenge of the specified app. ** WARNING **: This only works with the new scheme of tracking progress i.e. where there are challenge groups and not a single level :param app_name: Name of the app to test progress on :type app_name: str :returns: True iff user has successfully completed at least one challenge :rtype: bool """ prof_var = load_app_state_variable(app_name, 'groups') level = 0 if prof_var: try: for group in prof_var.itervalues(): try: level = max(level, group.get('challengeNo', 0)) except (KeyError, AttributeError, TypeError): continue except AttributeError: pass return level > 0
def record_user_interaction(instance, base_name): ''' This is to store some of the user actions, so we can determine if the user does the optional side quests. Args: The class instance. base_name (str): a string for the identity of the command. ''' class_instance = instance.__class__.__name__ challenge_number = instance.challenge_number profile_var_name = "{} {} {}".format( base_name, challenge_number, class_instance ) # First, try loading the profile variable name # If the value is None, then make it True and increment the total. already_done = load_app_state_variable("linux-story", profile_var_name) # If the command has not been done yet in this class, then increment the # total if not already_done: save_app_state_variable("linux-story", profile_var_name, True) total_name = "{} total".format(base_name) increment_app_state_variable("linux-story", total_name, 1)
def _load_level(): value = { 'groups': load_app_state_variable(APP_NAME, 'groups'), 'challenge': load_app_state_variable(APP_NAME, 'challenge') } # Previously we used to save the progress as "level" level = load_app_state_variable(APP_NAME, 'level') if value['groups'] is None: value['groups'] = {} # Replace the Challege var here. if level > value['challenge']: value['challenge'] = level value = json.dumps(value) return Response(value, content_type='application/json')
def check_command(self, line): checked_diary = load_app_state_variable("linux-story", "checked_mums_diary") if line == 'cat .safe/mums-diary' and not checked_diary: self.send_hint(_("\n{{rb:You read your Mum\'s diary!}} {{ob:Your nosiness has been recorded.}}")) save_app_state_variable("linux-story", "checked_mums_diary", True) return False return StepTemplateMv.check_command(self, line)
def _load_level(): value = { "groups": load_app_state_variable(APP_NAME, "groups"), "challenge": load_app_state_variable(APP_NAME, "challenge"), } # Previously we used to save the progress as "level" level = load_app_state_variable(APP_NAME, "level") if value["groups"] is None: value["groups"] = {} # Replace the Challege var here. if level > value["challenge"]: value["challenge"] = level value = json.dumps(value) return Response(value, content_type="application/json")
def save_challenge(self): '''Integration with kano world ''' level = load_app_state_variable("linux-story", "level") if self.challenge_number > level: save_app_state_variable_with_dialog("linux-story", "level", self.challenge_number) self.get_xp()
def _load_level(): value = load_app_state_variable(APP_NAME, 'level') # If every challenge is unlocked, value is 999 if value is not None: return str(value + 1) else: _save_level(1) return Response('1')
def check_command(self, line): checked_diary = load_app_state_variable("linux-story", "checked_mums_diary") if line == 'cat .safe/mums-diary' and not checked_diary: self.send_hint( _("\n{{rb:You read your Mum\'s diary!}} {{ob:Your nosiness has been recorded.}}" )) save_app_state_variable("linux-story", "checked_mums_diary", True) return False return StepTemplateMv.check_command(self, line)
def __get_xp(challenge): level = load_app_state_variable("linux-story", "level") if level is None: save_app_state_variable("linux-story", "level", 0) return "" if challenge > level + 1: xp = get_app_xp_for_challenge("linux-story", str(challenge)) if xp > 0: return _("{{gb:Congratulations, you earned %d XP!}}\n\n") % xp return ""
def play_intro(): level = load_app_state_variable(APP_NAME, 'level') # Skip the intro in case the user progressed past level 1 if level > 0: return try: from kano_video.logic.player import play_video # stop the splash screen before the video starts os.system('/usr/bin/kano-stop-splash') play_video(localfile=VIDEO_PATH) except ImportError: pass
def check_command(self): checked_diary = load_app_state_variable( "linux-story", "checked_mums_diary" ) # Check to see if the kid reads his/her Mum's journal if self.last_user_input == 'cat .safe/mums-diary' and \ not checked_diary: self.send_hint( _("\n{{rb:You read your Mum\'s diary!}} {{ob:Your nosiness has been recorded.}}") ) save_app_state_variable("linux-story", "checked_mums_diary", True) return False return StepTemplateMv.check_command(self)
def play_intro(): # Skip the intro in case the user progressed level 1 has_progressed = False groups = load_app_state_variable(APP_NAME, 'groups') if groups is not None and isinstance(groups, dict): for group in groups.itervalues(): if 'challengeNo' in group and group['challengeNo'] > 0: has_progressed = True break else: level = load_app_state_variable(APP_NAME, 'level') if level > 0: has_progressed = True if not has_progressed: try: from kano_video.logic.player import play_video # stop the splash screen before the video starts os.system('/usr/bin/kano-stop-splash') play_video(localfile=VIDEO_PATH) except ImportError: pass
def check_command(self): checked_diary = load_app_state_variable( "linux-story", "checked_mums_diary" ) # Check to see if the kid reads his/her Mum's journal if self.last_user_input == 'cat .safe/mums-diary' and \ not checked_diary: self.send_hint( "\n{{rb:You read your Mum\'s diary!}} " "{{ob:Your nosiness has been recorded.}}" ) save_app_state_variable("linux-story", "checked_mums_diary", True) return False return StepTemplateMv.check_command(self)
def check_command(self): checked_diary = load_app_state_variable( "linux-story", "checked_mums_diary" ) # Check to see if the kid reads his/her Mum's journal if self.last_user_input == 'cat .cassaforte/diario-della-mamma' and \ not checked_diary: self.send_hint( "\n{{rb:Hai letto il diario della mamma!}} " "{{ob:Hai fatto rumore, ti hanno sentito.}}" ) save_app_state_variable("linux-story", "checked_mums_diary", True) return False return StepTemplateMv.check_command(self)
def save_kano_version(): """Saves a dict of os-version: time values, to keep track of the users update process""" updates = load_app_state_variable('kano-tracker', 'versions') if not updates: updates = dict() version_now = read_file_contents('/etc/kanux_version') if not version_now: return version_now = version_now.replace('.', '_') time_now = datetime.datetime.utcnow().isoformat() updates[version_now] = time_now save_app_state_variable('kano-tracker', 'versions', updates)
def _show_icon_tutorial(self): if load_app_state_variable('kano-apps', 'icon-tutorial-shown'): return else: save_app_state_variable('kano-apps', 'icon-tutorial-shown', True) kdialog = KanoDialog( _("Add more apps to the desktop"), _("Click the '+' button to the right of the app name to " "make it appear on the desktop. You can remove it again " "by clicking on 'x'."), {_("OK, GOT IT"): { "return_value": 0, "color": "green" }}, parent_window=self) kdialog.set_action_background("grey") kdialog.title.description.set_max_width_chars(40) kdialog.run()
def _show_icon_tutorial(self): if load_app_state_variable('kano-apps', 'icon-tutorial-shown'): return else: save_app_state_variable('kano-apps', 'icon-tutorial-shown', True) kdialog = KanoDialog( "Add more apps to the desktop", "Click the '+' button to the right of the app name to " "make it appear on the desktop. You can remove it again " "by clicking on 'x'.", { "OK, GOT IT": { "return_value": 0, "color": "green" } }, parent_window=self ) kdialog.set_action_background("grey") kdialog.title.description.set_max_width_chars(40) kdialog.run()
def is_fulfilled(self): return False return load_app_state_variable('hacker', 'code') == 'judoka'
def is_fulfilled(self): return load_app_state_variable("kano-world-launcher", "opened")
def get_cached_data(category): return load_app_state_variable('kano-avatar-registration', category)
def __save_challenge(new_challenge, challenge): if new_challenge > challenge or not new_challenge: level = load_app_state_variable("linux-story", "level") if challenge > level: save_app_state_variable_with_dialog("linux-story", "level", challenge)
def is_fulfilled(self): return False return load_app_state_variable('hacker', 'kano-website') == 1
def save_point_exists(): return load_app_state_variable('linux-story', 'level')
def is_fulfilled(self): return load_app_state_variable('kano-world-launcher', 'opened')
def add_runtime_to_app(app, runtime): """ Saves the tracking data for a given application. Appends a time period to a given app's runtime stats and raises starts by one. Apart from the total values, it also updates the weekly stats. This function uses advisory file locks (see flock(2)) to avoid races between different applications saving their tracking data at the same time. :param app: The name of the application. :type app: str :param runtime: For how long was the app running. :type runtime: number """ if not app or app == 'kano-tracker': return if not is_number(runtime): return runtime = float(runtime) app = app.replace('.', '_') # Make sure no one else is accessing this file app_state_file = get_app_state_file('kano-tracker') try: tracker_store = open_locked(app_state_file, 'r') except IOError as e: logger.error("Error opening app state file {}".format(e)) else: app_stats = load_app_state_variable('kano-tracker', 'app_stats') if not app_stats: app_stats = dict() try: app_stats[app]['starts'] += 1 app_stats[app]['runtime'] += runtime except Exception: app_stats[app] = { 'starts': 1, 'runtime': runtime, } # Record usage data on per-week basis if 'weekly' not in app_stats[app]: app_stats[app]['weekly'] = {} week = str(get_nearest_previous_monday()) if week not in app_stats[app]['weekly']: app_stats[app]['weekly'][week] = { 'starts': 0, 'runtime': 0 } app_stats[app]['weekly'][week]['starts'] += 1 app_stats[app]['weekly'][week]['runtime'] += runtime save_app_state_variable('kano-tracker', 'app_stats', app_stats) # Close the lock tracker_store.close()
def add_runtime_to_app(app, runtime): """ Saves the tracking data for a given application. Appends a time period to a given app's runtime stats and raises starts by one. Apart from the total values, it also updates the weekly stats. This function uses advisory file locks (see flock(2)) to avoid races between different applications saving their tracking data at the same time. :param app: The name of the application. :type app: str :param runtime: For how long was the app running. :type runtime: number """ if not app or app == 'kano-tracker': return if not is_number(runtime): return runtime = float(runtime) app = app.replace('.', '_') # Make sure no one else is accessing this file app_state_file = get_app_state_file('kano-tracker') try: tracker_store = open_locked(app_state_file, "r") except IOError as e: logger.error('Error opening app state file {}'.format(e)) else: app_stats = load_app_state_variable('kano-tracker', 'app_stats') if not app_stats: app_stats = dict() try: app_stats[app]['starts'] += 1 app_stats[app]['runtime'] += runtime except Exception: app_stats[app] = { 'starts': 1, 'runtime': runtime, } # Record usage data on per-week basis if 'weekly' not in app_stats[app]: app_stats[app]['weekly'] = {} week = str(_get_nearest_previous_monday()) if week not in app_stats[app]['weekly']: app_stats[app]['weekly'][week] = { 'starts': 0, 'runtime': 0 } app_stats[app]['weekly'][week]['starts'] += 1 app_stats[app]['weekly'][week]['runtime'] += runtime save_app_state_variable('kano-tracker', 'app_stats', app_stats) # Close the lock tracker_store.close()
def get_cached_data(category): return load_app_state_variable("kano-avatar-registration", category)