Beispiel #1
0
def generate_tracker_token():
    """
        Generating the token is a simple md5hash of the current time.

        The token is saved to the `tracker_token_file`.

        :returns: The token.
        :rtype: str
    """

    token = hashlib.md5(str(time.time())).hexdigest()

    ensure_dir(tracker_dir)
    try:
        f = open_locked(tracker_token_file, "w")
    except IOError as e:
        logger.error(
            'Error opening tracker token file (generate) {}'.format(e))
    else:
        with f:
            f.write(token)
        if 'SUDO_USER' in os.environ:
            chown_path(tracker_token_file)

    # Make sure that the events file exist
    try:
        f = open(tracker_events_file, 'a')
    except IOError as e:
        logger.error('Error opening tracker events file {}'.format(e))
    else:
        f.close()
        if 'SUDO_USER' in os.environ:
            chown_path(tracker_events_file)

    return token
def copy_screenshot(filename):
    '''
    Copies screenshot 'filename' into SCREENSHOT_PATH
    '''
    ensure_dir(TMP_DIR)
    if os.path.isfile(filename):
        run_cmd("cp %s %s" % (filename, SCREENSHOT_PATH))
def take_screenshot():
    '''
    Takes a screenshot and saves it into SCREENSHOT_PATH
    '''
    ensure_dir(TMP_DIR)
    cmd = "kano-screenshot -w 1024 -p " + SCREENSHOT_PATH
    _, _, rc = run_cmd(cmd)
Beispiel #4
0
def _cache_pip_packages(progress, priority=Priority.NONE):
    """
        Downloads all updatable python modules and caches them in pip's
        internal pacakge cache.
    """

    # Urgent updates don't do PIP updates
    if priority == Priority.URGENT:
        return

    phase_name = 'downloading-pip-pkgs'
    progress.start(phase_name)

    ensure_dir(PIP_CACHE_DIR)

    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, _("Downloading {}").format(pkg))

        # The `--no-install` parameter has been deprecated in pip. However, the
        # version of pip in wheezy doesn't yet support the new approach which
        # is supposed to provide the same behaviour.
        args = "download --dest '{}' '{}'".format(PIP_CACHE_DIR, pkg)
        success = run_pip_command(args)

        # TODO: abort the install?
        if not success:
            msg = "Downloading the '{}' pip package failed.".format(pkg)
            logger.error(msg)
Beispiel #5
0
def copy_screenshot(filename):
    '''
    Copies screenshot 'filename' into SCREENSHOT_PATH
    '''
    ensure_dir(TMP_DIR)
    if os.path.isfile(filename):
        run_cmd("cp %s %s" % (filename, SCREENSHOT_PATH))
Beispiel #6
0
def take_screenshot():
    '''
    Takes a screenshot and saves it into SCREENSHOT_PATH
    '''
    ensure_dir(TMP_DIR)
    cmd = "kano-screenshot -w 1024 -p " + SCREENSHOT_PATH
    _, _, rc = run_cmd(cmd)
Beispiel #7
0
    def download_online_badges(self):
        profile = load_profile()
        if "kanoworld_id" in profile:
            user_id = profile["kanoworld_id"]
        else:
            return False, "Profile not registered!"

        success, text, data = request_wrapper("get", "/users/{}".format(user_id), session=self.session)

        if not success:
            return False, text

        if "user" not in data:
            return False, "Corrupt response (the 'user' key not found)"

        if "profile" not in data["user"]:
            return False, "Corrupt response (the 'user.profile' key not found)"

        if "badges" not in data["user"]["profile"]:
            msg = "Corrupt response (the 'user.profile.badges' key not found)"
            return False, msg

        online_badges_data = {}

        ensure_dir(online_badges_dir)

        badges = data["user"]["profile"]["badges"]
        for badge in badges:
            if "assigned" not in badge or not badge["assigned"]:
                continue

            if "image_url" not in badge:
                return False, "Couldn't find an image for the badge"

            image_loc = os.path.join(online_badges_dir, "{}.png".format(badge["id"]))
            download_url(badge["image_url"], image_loc)

            online_badges_data[badge["id"]] = {
                "achieved": True,
                "bg_color": badge["bg_color"].replace("#", ""),
                "desc_locked": badge["desc_locked"],
                "desc_unlocked": badge["desc_unlocked"],
                "title": badge["title"],
            }

        try:
            may_write = True
            txt = None
            f = open(online_badges_file, "w")
        except IOError as e:
            may_write = False
            txt = "Error opening badges file {}".format(str(e))
        else:
            with f:
                f.write(json.dumps(online_badges_data))
            if "SUDO_USER" in os.environ:
                chown_path(online_badges_dir)
                chown_path(online_badges_file)

        return may_write, txt
Beispiel #8
0
def _cache_pip_packages(progress, priority=Priority.NONE):
    """
        Downloads all updatable python modules and caches them in pip's
        internal pacakge cache.
    """

    # Urgent updates don't do PIP updates
    if priority == Priority.URGENT:
        return

    phase_name = 'downloading-pip-pkgs'
    progress.start(phase_name)

    ensure_dir(PIP_CACHE_DIR)

    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, "Downloading {}".format(pkg))

        # The `--no-install` parameter has been deprecated in pip. However, the
        # version of pip in wheezy doesn't yet support the new approach which
        # is supposed to provide the same behaviour.
        args = "install --upgrade --download '{}' '{}'".format(PIP_CACHE_DIR,
                                                               pkg)
        success = run_pip_command(args)

        # TODO: abort the install?
        if not success:
            msg = "Downloading the '{}' pip package failed.".format(pkg)
            logger.error(msg)
Beispiel #9
0
def get_metadata_archive():
    '''
    It creates a file (ARCHIVE_NAME) with all the information
    Returns the file
    '''
    ensure_dir(TMP_DIR)
    file_list = [
        {'name': 'kanux_version.txt', 'contents': get_version()},
        {'name': 'kanux_stamp.txt', 'contents': get_stamp()},
        {'name': 'process.txt', 'contents': get_processes()},
        {'name': 'packages.txt', 'contents': get_packages()},
        {'name': 'dmesg.txt', 'contents': get_dmesg()},
        {'name': 'syslog.txt', 'contents': get_syslog()},
        {'name': 'cmdline.txt', 'contents': read_file_contents('/boot/cmdline.txt')},
        {'name': 'config.txt', 'contents': read_file_contents('/boot/config.txt')},
        {'name': 'wifi-info.txt', 'contents': get_wifi_info()},
        {'name': 'usbdevices.txt', 'contents': get_usb_devices()},

        # TODO: Remove raw logs when json ones become stable
        {'name': 'app-logs.txt', 'contents': get_app_logs_raw()},

        {'name': 'app-logs-json.txt', 'contents': get_app_logs_json()},
        {'name': 'hdmi-info.txt', 'contents': get_hdmi_info()},
        {'name': 'edid.dat', 'contents': get_edid()},
        {'name': 'screen-log.txt', 'contents': get_screen_log()},
        {'name': 'xorg-log.txt', 'contents': get_xorg_log()},
        {'name': 'cpu-info.txt', 'contents': get_cpu_info()},
        {'name': 'lsof.txt', 'contents': get_lsof()},
        {'name': 'content-objects.txt', 'contents': get_co_list()}
    ]
    # Include the screenshot if it exists
    if os.path.isfile(SCREENSHOT_PATH):
        file_list.append({
                         'name': SCREENSHOT_NAME,
                         'contents': read_file_contents(SCREENSHOT_PATH)
                         })
    # Collect all coredumps, for applications that terminated unexpectedly
    for f in os.listdir('/var/tmp/'):
        if f.startswith('core-'):
            file_list.append({
                'name': f,
                'contents': read_file_contents(os.path.join('/var/tmp', f))
            })
    # create files for each non empty metadata info
    for file in file_list:
        if file['contents']:
            write_file_contents(TMP_DIR + file['name'], file['contents'])
    # archive all the metadata files
    # need to change dir to avoid tar subdirectories
    current_directory = os.getcwd()
    os.chdir(TMP_DIR)
    run_cmd("tar -zcvf {} *".format(ARCHIVE_NAME))
    # open the file and return it
    archive = open(ARCHIVE_NAME, 'rb')
    # restore the current working directory
    os.chdir(current_directory)

    return archive
Beispiel #10
0
def init():
    # Copy custom-theme from /usr/share if necessary
    if not os.path.exists(theme_file):
        src_file = '/usr/share/make-snake/%s' % CUSTOM_THEME
        if not os.path.exists(src_file):
            sys.exit('Error: custom-theme.xml missing from home and /usr/share/make-snake')
        ensure_dir(THEMES_DIR)
        shutil.copyfile(src_file, theme_file)
    load_theme()
    menus.update_naming()
Beispiel #11
0
def get_metadata_archive():
    '''
    It creates a file (ARCHIVE_NAME) with all the information
    Returns the file
    '''
    ensure_dir(TMP_DIR)
    file_list = [
        {'name': 'kanux_version.txt', 'contents': get_version()},
        {'name': 'process.txt', 'contents': get_processes()},
        {'name': 'packages.txt', 'contents': get_packages()},
        {'name': 'dmesg.txt', 'contents': get_dmesg()},
        {'name': 'syslog.txt', 'contents': get_syslog()},
        {'name': 'cmdline.txt', 'contents': read_file_contents('/boot/cmdline.txt')},
        {'name': 'config.txt', 'contents': read_file_contents('/boot/config.txt')},
        {'name': 'wifi-info.txt', 'contents': get_wifi_info()},
        {'name': 'usbdevices.txt', 'contents': get_usb_devices()},

        # TODO: Remove raw logs when json ones become stable
        {'name': 'app-logs.txt', 'contents': get_app_logs_raw()},

        {'name': 'app-logs-json.txt', 'contents': get_app_logs_json()},
        {'name': 'hdmi-info.txt', 'contents': get_hdmi_info()},
        {'name': 'xorg-log.txt', 'contents': get_xorg_log()},
        {'name': 'cpu-info.txt', 'contents': get_cpu_info()},
        {'name': 'lsof.txt', 'contents': get_lsof()},
        {'name': 'content-objects.txt', 'contents': get_co_list()}
    ]
    # Include the screenshot if it exists
    if os.path.isfile(SCREENSHOT_PATH):
        file_list.append({
                         'name': SCREENSHOT_NAME,
                         'contents': read_file_contents(SCREENSHOT_PATH)
                         })
    # create files for each non empty metadata info
    for file in file_list:
        if file['contents']:
            write_file_contents(TMP_DIR + file['name'], file['contents'])
    # Collect all coredumps, for applications that terminated unexpectedly
    for f in os.listdir('/var/tmp/'):
        if f.startswith('core-'):
            file_list.append({
                'name': f,
                'contents': read_file_contents(os.path.join('/var/tmp', f))
            })
    # archive all the metadata files
    # need to change dir to avoid tar subdirectories
    current_directory = os.getcwd()
    os.chdir(TMP_DIR)
    run_cmd("tar -zcvf {} *".format(ARCHIVE_NAME))
    # open the file and return it
    archive = open(ARCHIVE_NAME, 'rb')
    # restore the current working directory
    os.chdir(current_directory)

    return archive
Beispiel #12
0
def set_chromium_policies(policies):
    if not os.path.exists(chromium_policy_file):
        ensure_dir(os.path.dirname(chromium_policy_file))
        policy_config = {}
    else:
        policy_config = read_json(chromium_policy_file)

    for policy in policies:
        policy_config[policy[0]] = policy[1]

    write_json(chromium_policy_file, policy_config)
def copy_archive_report(target_archive):
    '''
    Copies source archive (TMP_DIR/ARCHIVE_NAME) into target_archive
    '''
    ensure_dir(TMP_DIR)
    source_archive = os.path.join(TMP_DIR, ARCHIVE_NAME)
    if os.path.isfile(source_archive):
        _, _, rc = run_cmd("cp %s %s" % (source_archive, target_archive))
        return (rc == 0)
    else:
        return False
def set_chromium_policies(policies):
    if not os.path.exists(chromium_policy_file):
        ensure_dir(os.path.dirname(chromium_policy_file))
        policy_config = {}
    else:
        policy_config = read_json(chromium_policy_file)

    for policy in policies:
        policy_config[policy[0]] = policy[1]

    write_json(chromium_policy_file, policy_config)
Beispiel #15
0
def copy_archive_report(target_archive):
    '''
    Copies source archive (TMP_DIR/ARCHIVE_NAME) into target_archive
    '''
    ensure_dir(TMP_DIR)
    source_archive = os.path.join(TMP_DIR, ARCHIVE_NAME)
    if os.path.isfile(source_archive):
        _, _, rc = run_cmd("cp %s %s" % (source_archive, target_archive))
        return (rc == 0)
    else:
        return False
Beispiel #16
0
def init():
    # Copy custom-theme from /usr/share if necessary
    if not os.path.exists(theme_file):
        src_file = '/usr/share/make-snake/%s' % CUSTOM_THEME
        if not os.path.exists(src_file):
            sys.exit(
                'Error: custom-theme.xml missing from home and /usr/share/make-snake'
            )
        ensure_dir(THEMES_DIR)
        shutil.copyfile(src_file, theme_file)
    load_theme()
    menus.update_naming()
Beispiel #17
0
    def _save_state(self):
        ensure_dir(os.path.dirname(QUESTS_STORE))
        if os.path.exists(QUESTS_STORE):
            with open(QUESTS_STORE, 'r') as quest_store_f:
                store = json.load(quest_store_f)
        else:
            store = {}

        if self._id not in store:
            store[self._id] = {}
        store[self._id]['state'] = self._state

        with open(QUESTS_STORE, 'w') as quest_store_f:
            json.dump(store, quest_store_f)
Beispiel #18
0
    def _save_state(self):
        ensure_dir(os.path.dirname(QUESTS_STORE))
        if os.path.exists(QUESTS_STORE):
            with open(QUESTS_STORE, 'r') as quest_store_f:
                store = json.load(quest_store_f)
        else:
            store = {}

        if self._id not in store:
            store[self._id] = {}
        store[self._id]['state'] = self._state

        with open(QUESTS_STORE, 'w') as quest_store_f:
            json.dump(store, quest_store_f)
Beispiel #19
0
    def __init__(self):
        if UpdaterStatus._singleton_instance:
            raise Exception('This class is a singleton!')
        else:
            UpdaterStatus._singleton_instance = self

        self._state = self.NO_UPDATES
        self._last_check = 0
        self._last_update = 0

        ensure_dir(os.path.dirname(self._status_file))
        if not os.path.exists(self._status_file):
            self.save()
        else:
            self.load()
Beispiel #20
0
    def __init__(self):
        if Status._singleton_instance:
            raise Exception('This class is a singleton!')
        else:
            Status._singleton_instance = self

        self._location = None
        self._completed = False

        # Initialise as True, and change if debug mode is set
        self._saving_enabled = True

        ensure_dir(os.path.dirname(self._status_file))
        if not os.path.exists(self._status_file):
            self.save()
        else:
            self.load()
Beispiel #21
0
    def __init__(self):
        if Status._singleton_instance:
            raise Exception('This class is a singleton!')
        else:
            Status._singleton_instance = self

        self._location = None
        self._completed = False

        # Initialise as True, and change if debug mode is set
        self._saving_enabled = True

        ensure_dir(os.path.dirname(self._status_file))
        if not os.path.exists(self._status_file):
            self.save()
        else:
            self.load()
Beispiel #22
0
def init():
    global theme, colors_map

    if parser.args.theme in DEFAULT_THEMES:
        try:
            theme = themes.game_themes[parser.args.theme]
        except:
            theme = themes.game_themes['minimal']
    else:
        # copy custom-theme.xml if it doesn't exist
        if not os.path.exists(CUSTOM_FILE):
            if not os.path.exists(CUSTOM_THEME_PATH):
                sys.exit('Error: custom-theme.xml missing from home and /usr/share/make-snake')
            ensure_dir(app_dir)
            shutil.copyfile(CUSTOM_THEME_PATH, CUSTOM_FILE)
        # Load the customn theme
        load_theme()

    colors_map = get_colors_map()
Beispiel #23
0
def save_profile(data):
    ''' Write profile data to file
    :param data: JSON serialisable data about the profile
    '''
    logger.debug('save_profile')

    data.pop('cpu_id', None)
    data.pop('mac_addr', None)
    data['save_date'] = get_date_now()
    ensure_dir(profile_dir)
    write_json(profile_file, data)

    if 'SUDO_USER' in os.environ:
        chown_path(kanoprofile_dir)
        chown_path(profile_dir)
        chown_path(profile_file)

    if os.path.exists('/usr/bin/kdesk') and not is_running('kano-sync'):
        logger.info('refreshing kdesk from save_profile')
        run_bg('kdesk -a profile')
Beispiel #24
0
def save_app_state(app_name, data):
    """ Save a state of an application to the user's Kano profile.

        :param app_name: The application that this data are associated with.
        :type app_name: str

        :param data: The data to be stored.
        :type data: dict
    """

    logger.debug("save_app_state {}".format(app_name))

    app_state_file = get_app_state_file(app_name)
    data['save_date'] = get_date_now()
    ensure_dir(get_app_dir(app_name))
    write_json(app_state_file, data)
    if 'SUDO_USER' in os.environ:
        chown_path(kanoprofile_dir)
        chown_path(apps_dir)
        chown_path(get_app_dir(app_name))
        chown_path(app_state_file)
def save_app_state(app_name, data):
    """ Save a state of an application to the user's Kano profile.

        :param app_name: The application that this data are associated with.
        :type app_name: str

        :param data: The data to be stored.
        :type data: dict
    """

    logger.debug('save_app_state {}'.format(app_name))

    app_state_file = get_app_state_file(app_name)
    data['save_date'] = get_date_now()
    ensure_dir(get_app_dir(app_name))
    write_json(app_state_file, data)
    if 'SUDO_USER' in os.environ:
        chown_path(kanoprofile_dir)
        chown_path(apps_dir)
        chown_path(get_app_dir(app_name))
        chown_path(app_state_file)
Beispiel #26
0
def init():
    global theme, colors_map

    if parser.args.theme in DEFAULT_THEMES:
        try:
            theme = themes.game_themes[parser.args.theme]
        except:
            theme = themes.game_themes['minimal']
    else:
        # copy custom-theme.xml if it doesn't exist
        if not os.path.exists(CUSTOM_FILE):
            if not os.path.exists(CUSTOM_THEME_PATH):
                sys.exit(
                    'Error: custom-theme.xml missing from home and /usr/share/make-snake'
                )
            ensure_dir(app_dir)
            shutil.copyfile(CUSTOM_THEME_PATH, CUSTOM_FILE)
        # Load the customn theme
        load_theme()

    colors_map = get_colors_map()
Beispiel #27
0
    def __init__(self):
        if UpdaterStatus._singleton_instance:
            raise Exception('This class is a singleton!')
        else:
            UpdaterStatus._singleton_instance = self

        self._state = self.NO_UPDATES
        self._last_check = 0
        self._last_check_urgent = 0
        self._last_update = 0
        self._first_boot_countdown = 0
        self._is_urgent = False
        self._is_scheduled = False
        self._notifications_muted = False
        self._is_shutdown = False

        ensure_dir(os.path.dirname(self._status_file))
        if not os.path.exists(self._status_file):
            self.save()
        else:
            self.load()
Beispiel #28
0
def save_profile(data, skip_kdesk_refresh=False):
    ''' Write profile data to file
    :param data: JSON serialisable data about the profile
    '''
    logger.debug('save_profile')

    data.pop('cpu_id', None)
    data.pop('mac_addr', None)
    data['save_date'] = get_date_now()
    ensure_dir(profile_dir)
    write_json(profile_file, data)

    if 'SUDO_USER' in os.environ:
        chown_path(kanoprofile_dir)
        chown_path(profile_dir)
        chown_path(profile_file)

    if (not skip_kdesk_refresh and
            os.path.exists('/usr/bin/kdesk') and
            not is_running('kano-sync')):
        logger.info("refreshing kdesk from save_profile")
        run_bg('kdesk -a profile')
Beispiel #29
0
    def __init__(self):
        logger.debug("Creating new status instance")
        if UpdaterStatus._singleton_instance:
            raise Exception("This class is a singleton!")
        else:
            UpdaterStatus._singleton_instance = self

        self._state = self.NO_UPDATES
        self._last_check = 0
        self._updatable_independent_packages = []
        self._last_check_urgent = 0
        self._last_update = 0
        self._first_boot_countdown = 0
        self._is_urgent = False
        self._is_scheduled = False
        self._notifications_muted = False
        self._is_shutdown = False

        ensure_dir(os.path.dirname(self._status_file))
        if not os.path.exists(self._status_file):
            self.save()
        else:
            self.load()
Beispiel #30
0
    def __init__(self):
        logger.debug("Creating new status instance")
        if UpdaterStatus._singleton_instance:
            raise Exception("This class is a singleton!")
        else:
            UpdaterStatus._singleton_instance = self

        self._state = self.NO_UPDATES
        self._last_check = 0
        self._updatable_independent_packages = []
        self._last_check_urgent = 0
        self._last_update = 0
        self._first_boot_countdown = 0
        self._is_urgent = False
        self._is_scheduled = False
        self._notifications_muted = False
        self._is_shutdown = False

        ensure_dir(os.path.dirname(self._status_file))
        if not os.path.exists(self._status_file):
            self.save()
        else:
            self.load()
Beispiel #31
0
def do_white_rabbit_stage(flow_params):
    init_status = Status.get_instance()

    if not flow_params.get('skip', False):
        clear_screen()
        try:
            rabbit(1, 'left-to-right')
        except:
            pass
        clear_screen()

        msg = _("{string_username}, follow the white rabbit").format(
            string_username=init_status.username)
        typewriter_echo(msg, trailing_linebreaks=2)

        command = decorate_with_preset('cd rabbithole', 'code')
        typewriter_echo(_("Type {string_code_to_type}, then [ENTER]").format(
            string_code_to_type=command),
                        trailing_linebreaks=2)

        # TODO: open shell
        rabbithole = "/home/{}/rabbithole".format(init_status.username)
        ensure_dir(rabbithole)
        cmd = "sudo -u {} -H bash --init-file {}".format(
            init_status.username, SUBSHELLRC_PATH)
        os.system(cmd)
        delete_dir(rabbithole)

        reset_overscan()
        matrix_binary(1, False)
        set_overscan()

        clear_screen()

    init_status.stage = Status.LOVE_STAGE
    init_status.save()
Beispiel #32
0
    def download_online_badges(self):
        profile = load_profile()
        if 'kanoworld_id' in profile:
            user_id = profile['kanoworld_id']
        else:
            return False, 'Profile not registered!'

        success, text, data = request_wrapper('get',
                                              '/users/{}'.format(user_id),
                                              session=self.session)

        if not success:
            return False, text

        if 'user' not in data:
            return False, _("Corrupt response (the 'user' key not found)")

        if 'profile' not in data['user']:
            return False, _(
                "Corrupt response (the 'user.profile' key not found)")

        if 'badges' not in data['user']['profile']:
            return False, _(
                "Corrupt response (the 'user.profile.badges' key not found)")

        online_badges_data = {}

        ensure_dir(online_badges_dir)

        badges = data['user']['profile']['badges']
        for badge in badges:
            if 'assigned' not in badge or not badge['assigned']:
                continue

            if 'image_url' not in badge:
                return False, _("Couldn't find an image for the badge")

            image_loc = os.path.join(online_badges_dir,
                                     "{}.png".format(badge['id']))
            download_url(badge['image_url'], image_loc)

            online_badges_data[badge['id']] = {
                'achieved': True,
                'bg_color': badge['bg_color'].replace("#", ""),
                'desc_locked': badge['desc_locked'],
                'desc_unlocked': badge['desc_unlocked'],
                'title': badge['title']
            }

        try:
            may_write = True
            txt = None
            f = open(online_badges_file, 'w')
        except IOError as e:
            may_write = False
            txt = 'Error opening badges file {}'.format(str(e))
        else:
            with f:
                f.write(json.dumps(online_badges_data))
            if 'SUDO_USER' in os.environ:
                chown_path(online_badges_dir)
                chown_path(online_badges_file)

        return may_write, txt
def get_metadata_archive(title='', desc=''):
    '''
    It creates a file (ARCHIVE_NAME) with all the information
    Returns the file
    '''
    ensure_dir(TMP_DIR)
    file_list = [
        {
            'name': 'metadata.json',
            'contents': json.dumps({
                'title': title,
                'description': desc
            })
        },
        {
            'name': 'kanux_version.txt',
            'contents': get_version()
        },
        {
            'name': 'kanux_stamp.txt',
            'contents': get_stamp()
        },
        {
            'name': 'process.txt',
            'contents': get_processes()
        },
        {
            'name': 'process-tree.txt',
            'contents': get_process_tree()
        },
        {
            'name': 'packages.txt',
            'contents': get_packages()
        },
        {
            'name': 'dmesg.txt',
            'contents': get_dmesg()
        },
        {
            'name': 'syslog.txt',
            'contents': get_syslog()
        },
        {
            'name': 'cmdline.txt',
            'contents': read_file_contents('/boot/cmdline.txt')
        },
        {
            'name': 'config.txt',
            'contents': read_file_contents('/boot/config.txt')
        },
        {
            'name': 'wifi-info.txt',
            'contents': get_wifi_info()
        },
        {
            'name': 'usbdevices.txt',
            'contents': get_usb_devices()
        },

        # TODO: Remove raw logs when json ones become stable
        {
            'name': 'app-logs.txt',
            'contents': get_app_logs_raw()
        },
        {
            'name': 'app-logs-json.txt',
            'contents': get_app_logs_json()
        },
        {
            'name': 'hdmi-info.txt',
            'contents': get_hdmi_info()
        },
        {
            'name': 'edid.dat',
            'contents': get_edid()
        },
        {
            'name': 'screen-log.txt',
            'contents': get_screen_log()
        },
        {
            'name': 'xorg-log.txt',
            'contents': get_xorg_log()
        },
        {
            'name': 'cpu-info.txt',
            'contents': get_cpu_info()
        },
        {
            'name': 'mem-stats.txt',
            'contents': get_mem_stats()
        },
        {
            'name': 'lsof.txt',
            'contents': get_lsof()
        },
        {
            'name': 'content-objects.txt',
            'contents': get_co_list()
        },
        {
            'name': 'disk-space.txt',
            'contents': get_disk_space()
        },
        {
            'name': 'lsblk.txt',
            'contents': get_lsblk()
        },
        {
            'name': 'sources-list.txt',
            'contents': get_sources_list()
        },
    ]
    file_list += get_install_logs()

    # Include the screenshot if it exists
    if os.path.isfile(SCREENSHOT_PATH):
        file_list.append({
            'name': SCREENSHOT_NAME,
            'contents': read_file_contents(SCREENSHOT_PATH)
        })
    # Collect all coredumps, for applications that terminated unexpectedly
    for f in os.listdir('/var/tmp/'):
        if f.startswith('core-'):
            file_list.append({
                'name':
                f,
                'contents':
                read_file_contents(os.path.join('/var/tmp', f))
            })
    # create files for each non empty metadata info
    for file in file_list:
        if file['contents']:
            write_file_contents(os.path.join(TMP_DIR, file['name']),
                                file['contents'])
    # archive all the metadata files
    import tarfile
    with tarfile.open(ARCHIVE_PATH, mode='w') as archive:
        for f in os.listdir(TMP_DIR):
            archive.add(os.path.join(TMP_DIR, f), arcname=f)

    # open the file and return it
    archive = open(ARCHIVE_PATH, 'rb')

    return archive
Beispiel #34
0
def download_share(entry):
    app = entry['app']
    title = entry['title']
    description = entry['description']
    attachment_url = entry['attachment_url']
    cover_url = entry['cover_url']
    resource_url = entry['resource_url']

    data = {'title': title, 'description': description}

    app_profiles = read_json(app_profiles_file)

    if app not in app_profiles:
        logger.error("Cannot download share, app not found in app-profiles")
        return

    app_profile = app_profiles[app]

    folder = os.path.join(get_home(), app_profile['dir'], 'webload')
    ensure_dir(folder)

    title_slugified = slugify(title)

    # Download attachment
    attachment_ext = attachment_url.split('.')[-1]
    attachment_name = '{}.{}'.format(title_slugified, attachment_ext)
    attachment_path = os.path.join(folder, attachment_name)

    success, text = download_url(attachment_url, attachment_path)
    if not success:
        msg = "Error with downloading share file: {}".format(text)
        logger.error(msg)
        return False, msg

    # Download screenshot
    if cover_url:
        cover_ext = cover_url.split('.')[-1]
        cover_name = '{}.{}'.format(title_slugified, cover_ext)
        cover_path = os.path.join(folder, cover_name)

        success, text = download_url(cover_url, cover_path)
        if not success:
            msg = "Error with downloading cover file: {}".format(text)
            logger.error(msg)
            return False, msg

    # Download resource file
    if resource_url:
        resource_ext = resource_url.split('.')[-1]
        # Make sure we don't remove the tar from gz
        if 'tar.gz' in resource_url:
            resource_ext = 'tar.' + resource_ext
        resource_name = '{}.{}'.format(title_slugified, resource_ext)
        resource_path = os.path.join(folder, resource_name)

        success, text = download_url(resource_url, resource_path)
        if not success:
            msg = "Error with downloading resource file: {}".format(text)
            logger.error(msg)
            return False, msg

    # JSON file
    json_name = '{}.{}'.format(title_slugified, 'json')
    json_path = os.path.join(folder, json_name)
    write_json(json_path, data)
    return True, [title, attachment_path, app, attachment_name, folder]
    def _process_notification(self, entry):
        """ Cherry picks information from a Kano World notification
            based on its type and returns it in a dict.

            :param entry: A notification entry from the World API
            :returns: A dict that can be passed to the notification widget
        """

        MINECRAFT_SHARE_IMG = media_dir + \
            '/images/notification/280x170/share-pong.png'
        PONG_SHARE_IMG = media_dir + \
            '/images/notification/280x170/share-minecraft.png'
        SP_IMG = media_dir + \
            '/images/notification/280x170/saturday-project.png'
        FOLLOWER_IMG = media_dir + \
            '/images/notification/280x170/follower.png'
        GENERIC_ALERT_IMG = media_dir + \
            '/images/notification/280x170/notification.png'

        n = {
            'id': entry['id'],
            'title': 'Kano World',
            'byline': '',
            'image': GENERIC_ALERT_IMG,
            'command': 'kano-world-launcher /notifications/open/{}'.format(
                       entry['id'])
        }

        # Customise settings for known types
        if entry['category'] == 'follows':
            n['title'] = 'New follower!'
            n['byline'] = entry['title']
            n['image'] = FOLLOWER_IMG

            # Link to whomever followed this user
            user = self._get_dict_value(entry, ['meta', 'author', 'username'])
            if user:
                n['command'] = "kano-world-launcher /users/{}".format(user)

        elif entry['category'] in ['share-items', 'shares']:
            n['title'] = 'New share!'
            n['byline'] = entry['title']

            if entry['type'] == 'make-minecraft':
                n['image'] = MINECRAFT_SHARE_IMG
            elif entry['type'] == 'make-pong':
                n['image'] = PONG_SHARE_IMG

            # Link to the share
            share_id = self._get_dict_value(entry, ['meta', 'item', 'id'])
            if share_id:
                n['command'] = "kano-world-launcher /shared/{}".format(
                    share_id)

        elif entry['category'] == 'comments':
            n['title'] = 'New comment!'
            n['byline'] = entry['title']

            slug = self._get_dict_value(entry, ['meta', 'item', 'slug'])
            if slug:
                obj_type = entry['meta']['item']['type']
                if obj_type == "app":
                    n['command'] = "kano-world-launcher /apps/{}".format(slug)
                elif obj_type == "share":
                    n['command'] = "kano-world-launcher /shared/{}".format(
                        slug)
                elif obj_type == "project":
                    n['command'] = "kano-world-launcher /projects/{}".format(
                        slug)

        # If a notification has both the title and text, override the default
        if 'title' in entry and entry['title'] and \
                'text' in entry and entry['text']:
            n['title'] = entry['title']
            n['byline'] = entry['text']

        # Some notifications may have images
        # If so, we need to download them and resize
        if 'image_url' in entry and entry['image_url']:
            filename = os.path.basename(entry['image_url'])

            img_path = "{}/notifications/{}".format(profile_dir, filename)
            ensure_dir(os.path.dirname(img_path))

            rv, e = download_url(entry['image_url'], img_path)
            if rv:
                # Resize image to 280x170
                # FIXME: We import GdkPixbuf locally to make sure not to
                # bugger up anything else, but we should move it up to the top.
                from gi.repository import GdkPixbuf

                pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(
                    img_path, 280, 170)
                pixbuf.savev(img_path, 'png', [None], [None])

                n['image'] = img_path
            else:
                msg = "Notifications image failed to download ({}).".format(e)
                logger.error(msg)

        # Certain notifications may come with a command as well.
        # If so, override the default one.
        cmd = self._get_dict_value(entry, ['meta', 'cmd'])
        if cmd:
            n['command'] = cmd

        return n
import os
import re
import shutil
from kano.utils import ensure_dir, get_user_unsudoed, read_json, write_json, chown_path
from kano.logging import logger
from kano_settings.common import settings_dir
from kano.utils import is_model_2_b

USER = None
USER_ID = None

username = get_user_unsudoed()
if username != 'root':
    if os.path.exists(settings_dir) and os.path.isfile(settings_dir):
        os.rename(settings_dir, settings_dir + '.bak')
    ensure_dir(settings_dir)
    chown_path(settings_dir)
    settings_file = os.path.join(settings_dir, 'settings')

defaults = {
    'pi1': {
        'Keyboard-continent-index': 1,
        'Keyboard-country-index': 21,
        'Keyboard-variant-index': 0,
        'Keyboard-continent-human': 'america',
        'Keyboard-country-human': 'United States',
        'Keyboard-variant-human': 'Generic',
        'Audio': 'Analogue',
        'Wifi': '',
        'Wifi-connection-attempted': False,
        'Overclocking': 'High',
Beispiel #37
0
    def _process_notification(self, entry):
        """ Cherry picks information from a Kano World notification
            based on its type and returns it in a dict.

            :param entry: A notification entry from the World API
            :returns: A dict that can be passed to the notification widget
        """

        notification_dir = os.path.join(
            media_dir, 'images', 'notification', '280x170'
        )

        FEATURED_SHARE_IMG = os.path.join(notification_dir, 'featured.png')
        PONG_SHARE_IMG = os.path.join(notification_dir, 'share-pong.png')
        MUSIC_SHARE_IMG = os.path.join(notification_dir, 'share-music.png')
        LIGHT_SHARE_IMG = os.path.join(notification_dir, 'share-light.png')
        ART_SHARE_IMG = os.path.join(notification_dir, 'share-art.png')
        SNAKE_SHARE_IMG = os.path.join(notification_dir, 'snake-art.png')
        MINECRAFT_SHARE_IMG = os.path.join(notification_dir,
                                           'share-minecraft.png')
        FOLLOWER_IMG = os.path.join(notification_dir, 'follower.png')
        COMMENT_IMG = os.path.join(notification_dir, 'comment.png')
        LIKE_IMG = os.path.join(notification_dir, 'like.png')
        GENERIC_ALERT_IMG = os.path.join(notification_dir, 'notification.png')

        n = {
            'id': entry['id'],
            'title': 'Kano World',
            'byline': '',
            'image': GENERIC_ALERT_IMG,
            'command': 'kano-world-launcher /notifications/open/{}'.format(
                       entry['id'])
        }

        # Some notifications may have images
        # If so, we need to download them and resize
        if 'image_url' in entry and entry['image_url']:
            filename = os.path.basename(entry['image_url'])

            img_path = "{}/notifications/{}".format(profile_dir, filename)
            ensure_dir(os.path.dirname(img_path))

            rv, e = download_url(entry['image_url'], img_path)
            if rv:
                # Resize image to 280x170
                # FIXME: We import GdkPixbuf locally to make sure not to
                # bugger up anything else, but we should move it up to the top.
                from gi.repository import GdkPixbuf

                pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(
                    img_path, 280, 170)
                pixbuf.savev(img_path, 'png', [None], [None])

                n['image'] = img_path
            else:
                msg = "Notifications image failed to download ({}).".format(e)
                logger.error(msg)

        # Certain notifications may come with a command as well.
        # If so, override the default one.
        cmd = self._get_dict_value(entry, ['meta', 'cmd'])
        if cmd:
            n['command'] = cmd

        # Customise settings for known types
        if entry['category'] == 'follows':
            n['title'] = 'New follower!'
            n['byline'] = entry['title']
            n['image'] = FOLLOWER_IMG

        elif entry['category'] in ['share-items', 'shares']:
            n['title'] = 'New share!'
            n['byline'] = entry['title']

            if entry['type'] == 'make-minecraft':
                n['image'] = MINECRAFT_SHARE_IMG
            elif entry['type'] == 'make-pong':
                n['image'] = PONG_SHARE_IMG
            elif entry['type'] == 'make-music':
                n['image'] = MUSIC_SHARE_IMG
            elif entry['type'] == 'make-light':
                n['image'] = LIGHT_SHARE_IMG
            elif entry['type'] == 'kano-draw':
                n['image'] = ART_SHARE_IMG
            elif entry['type'] == 'featured':
                n['title'] = 'Staff picked!'
                n['image'] = FEATURED_SHARE_IMG

        elif entry['category'] == 'comments':
            n['title'] = 'New comment!'
            n['byline'] = entry['title']
            n['image'] = COMMENT_IMG

        elif entry['category'] == 'likes':
            n['title'] = 'New like!'
            n['byline'] = entry['title']
            n['image'] = LIKE_IMG
        else:
            return None

        return n
Beispiel #38
0
    def _process_notification(self, entry):
        """ Cherry picks information from a Kano World notification
            based on its type and returns it in a dict.

            :param entry: A notification entry from the World API
            :returns: A dict that can be passed to the notification widget
        """

        MINECRAFT_SHARE_IMG = media_dir + "/images/notification/280x170/share-pong.png"
        PONG_SHARE_IMG = media_dir + "/images/notification/280x170/share-minecraft.png"
        SP_IMG = media_dir + "/images/notification/280x170/saturday-project.png"
        FOLLOWER_IMG = media_dir + "/images/notification/280x170/follower.png"
        GENERIC_ALERT_IMG = media_dir + "/images/notification/280x170/notification.png"

        n = {
            "id": entry["id"],
            "title": "Kano World",
            "byline": "",
            "image": GENERIC_ALERT_IMG,
            "command": "kano-world-launcher /notifications/open/{}".format(entry["id"]),
        }

        # Customise settings for known types
        if entry["category"] == "follows":
            n["title"] = "New follower!"
            n["byline"] = entry["title"]
            n["image"] = FOLLOWER_IMG

            # Link to whomever followed this user
            user = self._get_dict_value(entry, ["meta", "author", "username"])
            if user:
                n["command"] = "kano-world-launcher /users/{}".format(user)

        elif entry["category"] in ["share-items", "shares"]:
            n["title"] = "New share!"
            n["byline"] = entry["title"]

            if entry["type"] == "make-minecraft":
                n["image"] = MINECRAFT_SHARE_IMG
            elif entry["type"] == "make-pong":
                n["image"] = PONG_SHARE_IMG

            # Link to the share
            share_id = self._get_dict_value(entry, ["meta", "item", "id"])
            if share_id:
                n["command"] = "kano-world-launcher /shared/{}".format(share_id)

        elif entry["category"] == "comments":
            n["title"] = "New comment!"
            n["byline"] = entry["title"]

            slug = self._get_dict_value(entry, ["meta", "item", "slug"])
            if slug:
                obj_type = entry["meta"]["item"]["type"]
                if obj_type == "app":
                    n["command"] = "kano-world-launcher /apps/{}".format(slug)
                elif obj_type == "share":
                    n["command"] = "kano-world-launcher /shared/{}".format(slug)
                elif obj_type == "project":
                    n["command"] = "kano-world-launcher /projects/{}".format(slug)

        # If a notification has both the title and text, override the default
        if "title" in entry and entry["title"] and "text" in entry and entry["text"]:
            n["title"] = entry["title"]
            n["byline"] = entry["text"]

        # Some notifications may have images
        # If so, we need to download them and resize
        if "image_url" in entry and entry["image_url"]:
            filename = os.path.basename(entry["image_url"])

            img_path = "{}/notifications/{}".format(profile_dir, filename)
            ensure_dir(os.path.dirname(img_path))

            rv, e = download_url(entry["image_url"], img_path)
            if rv:
                # Resize image to 280x170
                # FIXME: We import GdkPixbuf locally to make sure not to
                # bugger up anything else, but we should move it up to the top.
                from gi.repository import GdkPixbuf

                pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(img_path, 280, 170)
                pixbuf.savev(img_path, "png", [None], [None])

                n["image"] = img_path
            else:
                msg = "Notifications image failed to download ({}).".format(e)
                logger.error(msg)

        # Certain notifications may come with a command as well.
        # If so, override the default one.
        cmd = self._get_dict_value(entry, ["meta", "cmd"])
        if cmd:
            n["command"] = cmd

        return n
def get_metadata_archive(title='', desc=''):
    '''
    It creates a file (ARCHIVE_NAME) with all the information
    Returns the file
    '''
    ensure_dir(TMP_DIR)
    file_list = [
        {
            'name': 'metadata.json',
            'contents': json.dumps({'title': title, 'description': desc})
        },
        {'name': 'kanux_version.txt', 'contents': get_version()},
        {'name': 'kanux_stamp.txt', 'contents': get_stamp()},
        {'name': 'process.txt', 'contents': get_processes()},
        {'name': 'process-tree.txt', 'contents': get_process_tree()},
        {'name': 'packages.txt', 'contents': get_packages()},
        {'name': 'dmesg.txt', 'contents': get_dmesg()},
        {'name': 'syslog.txt', 'contents': get_syslog()},
        {
            'name': 'cmdline.txt',
            'contents': read_file_contents('/boot/cmdline.txt')
        },
        {
            'name': 'config.txt',
            'contents': read_file_contents('/boot/config.txt')
        },
        {'name': 'wifi-info.txt', 'contents': get_wifi_info()},
        {'name': 'usbdevices.txt', 'contents': get_usb_devices()},

        # TODO: Remove raw logs when json ones become stable
        {'name': 'app-logs.txt', 'contents': get_app_logs_raw()},

        {'name': 'app-logs-json.txt', 'contents': get_app_logs_json()},
        {'name': 'hdmi-info.txt', 'contents': get_hdmi_info()},
        {'name': 'edid.dat', 'contents': get_edid()},
        {'name': 'screen-log.txt', 'contents': get_screen_log()},
        {'name': 'xorg-log.txt', 'contents': get_xorg_log()},
        {'name': 'cpu-info.txt', 'contents': get_cpu_info()},
        {'name': 'mem-stats.txt', 'contents': get_mem_stats()},
        {'name': 'lsof.txt', 'contents': get_lsof()},
        {'name': 'content-objects.txt', 'contents': get_co_list()},
        {'name': 'disk-space.txt', 'contents': get_disk_space()},
        {'name': 'lsblk.txt', 'contents': get_lsblk()},
        {'name': 'sources-list.txt', 'contents': get_sources_list()},
    ]
    file_list += get_install_logs()

    # Include the screenshot if it exists
    if os.path.isfile(SCREENSHOT_PATH):
        file_list.append({
            'name': SCREENSHOT_NAME,
            'contents': read_file_contents(SCREENSHOT_PATH)
        })
    # Collect all coredumps, for applications that terminated unexpectedly
    for f in os.listdir('/var/tmp/'):
        if f.startswith('core-'):
            file_list.append({
                'name': f,
                'contents': read_file_contents(os.path.join('/var/tmp', f))
            })
    # create files for each non empty metadata info
    for file in file_list:
        if file['contents']:
            write_file_contents(
                os.path.join(TMP_DIR, file['name']), file['contents']
            )
    # archive all the metadata files
    import tarfile
    with tarfile.open(ARCHIVE_PATH, mode='w') as archive:
        for f in os.listdir(TMP_DIR):
            archive.add(os.path.join(TMP_DIR, f), arcname=f)

    # open the file and return it
    archive = open(ARCHIVE_PATH, 'rb')

    return archive
def create_tmp_dir():
    '''
    Creates TMP_DIR directory
    '''
    ensure_dir(TMP_DIR)
Beispiel #41
0
from kano_world.functions import login_using_token
from kano_world.share import upload_share
from kano.network import is_internet
from kano.utils import play_sound
from kano.logging import logger


APP_NAME = 'kano-draw'
PARENT_PID = None

CHALLENGE_DIR = os.path.expanduser('~/Draw-content')
WALLPAPER_DIR = os.path.join(CHALLENGE_DIR, 'wallpapers')
STATIC_ASSET_DIR = os.path.join(os.path.expanduser('~'),
                                '.make-art-assets')

ensure_dir(CHALLENGE_DIR)
ensure_dir(WALLPAPER_DIR)
ensure_dir(STATIC_ASSET_DIR)


def _copy_package_assets():
    # Use abs paths for both src and dest for subsequent replacements to work
    src_dir = os.path.abspath(_get_package_static_dir())
    dest_dir = os.path.abspath(STATIC_ASSET_DIR)

    # First Clear this cache
    for existing_file in os.listdir(dest_dir):
        cur_file = os.path.abspath(os.path.join(dest_dir, existing_file))
        if os.path.islink(cur_file):
            os.unlink(cur_file)
        else:
Beispiel #42
0
def download_share(entry):
    app = entry['app']
    title = entry['title']
    description = entry['description']
    attachment_url = entry['attachment_url']
    cover_url = entry['cover_url']
    resource_url = entry['resource_url']

    data = {
        'title': title,
        'description': description
    }

    app_profiles = read_json(app_profiles_file)

    if app not in app_profiles:
        logger.error("Cannot download share, app not found in app-profiles")
        return

    app_profile = app_profiles[app]

    folder = os.path.join(get_home(), app_profile['dir'], 'webload')
    ensure_dir(folder)

    title_slugified = slugify(title)

    # Download attachment
    attachment_ext = attachment_url.split('.')[-1]
    attachment_name = '{}.{}'.format(title_slugified, attachment_ext)
    attachment_path = os.path.join(folder, attachment_name)

    success, text = download_url(attachment_url, attachment_path)
    if not success:
        msg = "Error with downloading share file: {}".format(text)
        logger.error(msg)
        return False, msg

    # Download screenshot
    if cover_url:
        cover_ext = cover_url.split('.')[-1]
        cover_name = '{}.{}'.format(title_slugified, cover_ext)
        cover_path = os.path.join(folder, cover_name)

        success, text = download_url(cover_url, cover_path)
        if not success:
            msg = "Error with downloading cover file: {}".format(text)
            logger.error(msg)
            return False, msg

    # Download resource file
    if resource_url:
        resource_ext = resource_url.split('.')[-1]
        # Make sure we don't remove the tar from gz
        if 'tar.gz' in resource_url:
            resource_ext = 'tar.' + resource_ext
        resource_name = '{}.{}'.format(title_slugified, resource_ext)
        resource_path = os.path.join(folder, resource_name)

        success, text = download_url(resource_url, resource_path)
        if not success:
            msg = "Error with downloading resource file: {}".format(text)
            logger.error(msg)
            return False, msg

    # JSON file
    json_name = '{}.{}'.format(title_slugified, 'json')
    json_path = os.path.join(folder, json_name)
    write_json(json_path, data)
    return True, [title, attachment_path, app, attachment_name, folder]
Beispiel #43
0
from kano_profile.apps import load_app_state_variable
from kano_profile.badges import increment_app_state_variable_with_dialog
from kano_world.functions import login_using_token
from kano_world.share import upload_share
from kano.network import is_internet
from kano.utils import play_sound
from kano.logging import logger

APP_NAME = 'kano-draw'
PARENT_PID = None

CHALLENGE_DIR = os.path.expanduser('~/Draw-content')
WALLPAPER_DIR = os.path.join(CHALLENGE_DIR, 'wallpapers')
STATIC_ASSET_DIR = os.path.join(os.path.expanduser('~'), '.make-art-assets')

ensure_dir(CHALLENGE_DIR)
ensure_dir(WALLPAPER_DIR)
ensure_dir(STATIC_ASSET_DIR)


def _copy_package_assets():
    # Use abs paths for both src and dest for subsequent replacements to work
    src_dir = os.path.abspath(_get_package_static_dir())
    dest_dir = os.path.abspath(STATIC_ASSET_DIR)

    # First Clear this cache
    for existing_file in os.listdir(dest_dir):
        cur_file = os.path.abspath(os.path.join(dest_dir, existing_file))
        if os.path.islink(cur_file):
            os.unlink(cur_file)
        else:
Beispiel #44
0
    def download_online_badges(self):
        profile = load_profile()
        if 'kanoworld_id' in profile:
            user_id = profile['kanoworld_id']
        else:
            return False, 'Profile not registered!'

        success, text, data = request_wrapper(
            'get', '/users/{}'.format(user_id),
            session=self.session
        )

        if not success:
            return False, text

        if 'user' not in data:
            return False, _("Corrupt response (the 'user' key not found)")

        if 'profile' not in data['user']:
            return False, _("Corrupt response (the 'user.profile' key not found)")

        if 'badges' not in data['user']['profile']:
            return False, _("Corrupt response (the 'user.profile.badges' key not found)")

        online_badges_data = {}

        ensure_dir(online_badges_dir)

        badges = data['user']['profile']['badges']
        for badge in badges:
            if 'assigned' not in badge or not badge['assigned']:
                continue

            if 'image_url' not in badge:
                return False, _("Couldn't find an image for the badge")

            image_loc = os.path.join(online_badges_dir,
                                     "{}.png".format(badge['id']))
            download_url(badge['image_url'], image_loc)

            online_badges_data[badge['id']] = {
                'achieved': True,
                'bg_color': badge['bg_color'].replace("#", ""),
                'desc_locked': badge['desc_locked'],
                'desc_unlocked': badge['desc_unlocked'],
                'title': badge['title']
            }

        try:
            may_write = True
            txt = None
            f = open(online_badges_file, 'w')
        except IOError as e:
            may_write = False
            txt = 'Error opening badges file {}'.format(str(e))
        else:
            with f:
                f.write(json.dumps(online_badges_data))
            if 'SUDO_USER' in os.environ:
                chown_path(online_badges_dir)
                chown_path(online_badges_file)

        return may_write, txt
Beispiel #45
0
    def _process_notification(self, entry):
        """ Cherry picks information from a Kano World notification
            based on its type and returns it in a dict.

            :param entry: A notification entry from the World API
            :returns: A dict that can be passed to the notification widget
        """

        notification_dir = os.path.join(media_dir, 'images', 'notification',
                                        '280x170')

        FEATURED_SHARE_IMG = os.path.join(notification_dir, 'featured.png')
        PONG_SHARE_IMG = os.path.join(notification_dir, 'share-pong.png')
        MUSIC_SHARE_IMG = os.path.join(notification_dir, 'share-music.png')
        LIGHT_SHARE_IMG = os.path.join(notification_dir, 'share-light.png')
        ART_SHARE_IMG = os.path.join(notification_dir, 'share-art.png')
        SNAKE_SHARE_IMG = os.path.join(notification_dir, 'snake-art.png')
        MINECRAFT_SHARE_IMG = os.path.join(notification_dir,
                                           'share-minecraft.png')
        FOLLOWER_IMG = os.path.join(notification_dir, 'follower.png')
        COMMENT_IMG = os.path.join(notification_dir, 'comment.png')
        LIKE_IMG = os.path.join(notification_dir, 'like.png')
        GENERIC_ALERT_IMG = os.path.join(notification_dir, 'notification.png')

        n = {
            'id':
            entry['id'],
            'title':
            'Kano World',
            'byline':
            '',
            'image':
            GENERIC_ALERT_IMG,
            'command':
            'kano-world-launcher /notifications/open/{}'.format(entry['id'])
        }

        # Some notifications may have images
        # If so, we need to download them and resize
        if 'image_url' in entry and entry['image_url']:
            filename = os.path.basename(entry['image_url'])

            img_path = "{}/notifications/{}".format(profile_dir, filename)
            ensure_dir(os.path.dirname(img_path))

            rv, e = download_url(entry['image_url'], img_path)
            if rv:
                # Resize image to 280x170
                # FIXME: We import GdkPixbuf locally to make sure not to
                # bugger up anything else, but we should move it up to the top.
                from gi.repository import GdkPixbuf

                pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(
                    img_path, 280, 170)
                pixbuf.savev(img_path, 'png', [None], [None])

                n['image'] = img_path
            else:
                msg = "Notifications image failed to download ({}).".format(e)
                logger.error(msg)

        # Certain notifications may come with a command as well.
        # If so, override the default one.
        cmd = self._get_dict_value(entry, ['meta', 'cmd'])
        if cmd:
            n['command'] = cmd

        # Customise settings for known types
        if entry['category'] == 'follows':
            n['title'] = 'New follower!'
            n['byline'] = entry['title']
            n['image'] = FOLLOWER_IMG

        elif entry['category'] in ['share-items', 'shares']:
            n['title'] = 'New share!'
            n['byline'] = entry['title']

            if entry['type'] == 'make-minecraft':
                n['image'] = MINECRAFT_SHARE_IMG
            elif entry['type'] == 'make-pong':
                n['image'] = PONG_SHARE_IMG
            elif entry['type'] == 'make-music':
                n['image'] = MUSIC_SHARE_IMG
            elif entry['type'] == 'make-light':
                n['image'] = LIGHT_SHARE_IMG
            elif entry['type'] == 'kano-draw':
                n['image'] = ART_SHARE_IMG
            elif entry['type'] == 'featured':
                n['title'] = 'Staff picked!'
                n['image'] = FEATURED_SHARE_IMG

        elif entry['category'] == 'comments':
            n['title'] = 'New comment!'
            n['byline'] = entry['title']
            n['image'] = COMMENT_IMG

        elif entry['category'] == 'likes':
            n['title'] = 'New like!'
            n['byline'] = entry['title']
            n['image'] = LIKE_IMG
        else:
            return None

        return n
Beispiel #46
0
    calculate_xp
from kano_profile.apps import load_app_state_variable
from kano_profile.badges import increment_app_state_variable_with_dialog
from kano_world.functions import login_using_token
from kano_world.share import upload_share
from kano.network import is_internet
from kano.utils import play_sound


APP_NAME = 'kano-draw'
PARENT_PID = None

CHALLENGE_DIR = os.path.expanduser('~/Draw-content')
WALLPAPER_DIR = os.path.join(CHALLENGE_DIR, 'wallpapers')

ensure_dir(CHALLENGE_DIR)
ensure_dir(WALLPAPER_DIR)


def _get_static_dir():
    bin_path = os.path.abspath(os.path.dirname(__file__))

    if bin_path.startswith('/usr'):
        return '/usr/share/kano-draw'
    else:
        return os.path.abspath(os.path.join(bin_path, '../www'))

def _get_image_from_str(img_str):
    import base64

    image_b64 = img_str.split(',')[-1]
Beispiel #47
0
 def _initialise_status_file(self):
     ensure_dir(os.path.dirname(self._status_file))
     if not os.path.exists(self._status_file):
         self.save()
     else:
         self.load()
Beispiel #48
0
from kano_profile.badges import save_app_state_variable_with_dialog, \
    calculate_xp
from kano_profile.apps import load_app_state_variable
from kano_profile.badges import increment_app_state_variable_with_dialog
from kano_world.functions import login_using_token
from kano_world.share import upload_share
from kano.network import is_internet


APP_NAME = 'kano-draw'
PARENT_PID = None

CHALLENGE_DIR = os.path.expanduser('~/Draw-content')
WALLPAPER_DIR = os.path.join(CHALLENGE_DIR, 'wallpapers')

ensure_dir(CHALLENGE_DIR)
ensure_dir(WALLPAPER_DIR)


def _get_static_dir():
    bin_path = os.path.abspath(os.path.dirname(__file__))

    if bin_path.startswith('/usr'):
        return '/usr/share/kano-draw'
    else:
        return os.path.abspath(os.path.join(bin_path, '../www'))

def _get_image_from_str(img_str):
    import base64

    image_b64 = img_str.split(',')[-1]
Beispiel #49
0
def create_tmp_dir():
    '''
    Creates TMP_DIR directory
    '''
    ensure_dir(TMP_DIR)