def test_snap_not_stable(self):
        channel_maps_list = [
            {"map": [{"channel": "not stable", "info": None}]}
        ]

        result = logic.is_snap_on_stable(channel_maps_list)
        self.assertFalse(result)
    def test_snap_not_stable(self):
        channel_maps_list = [
            {"map": [{"channel": "not stable", "info": None}]}
        ]

        result = logic.is_snap_on_stable(channel_maps_list)
        self.assertFalse(result)
Beispiel #3
0
def get_listing_snap(snap_name):
    try:
        snap_details = api.get_snap_info(snap_name, flask.session)
    except ApiResponseErrorList as api_response_error_list:
        if api_response_error_list.status_code == 404:
            return flask.abort(404, "No snap named {}".format(snap_name))
        else:
            return _handle_error_list(api_response_error_list.errors)
    except ApiError as api_error:
        return _handle_errors(api_error)

    details_metrics_enabled = snap_details["public_metrics_enabled"]
    details_blacklist = snap_details["public_metrics_blacklist"]

    is_on_stable = logic.is_snap_on_stable(snap_details["channel_maps_list"])

    # Filter icon & screenshot urls from the media set.
    icon_urls = [
        m["url"] for m in snap_details["media"] if m["type"] == "icon"
    ]
    screenshot_urls = [
        m["url"] for m in snap_details["media"] if m["type"] == "screenshot"
    ]

    licenses = []
    for license in get_licenses():
        licenses.append({"key": license["licenseId"], "name": license["name"]})

    license = snap_details["license"]
    license_type = "custom"

    if " AND " not in license.upper() and " WITH " not in license.upper():
        license_type = "simple"

    context = {
        "snap_id": snap_details["snap_id"],
        "snap_name": snap_details["snap_name"],
        "snap_title": snap_details["title"],
        "summary": snap_details["summary"],
        "description": snap_details["description"],
        "icon_url": icon_urls[0] if icon_urls else None,
        "publisher_name": snap_details["publisher"]["display-name"],
        "username": snap_details["publisher"]["username"],
        "screenshot_urls": screenshot_urls,
        "contact": snap_details["contact"],
        "private": snap_details["private"],
        "website": snap_details["website"] or "",
        "public_metrics_enabled": details_metrics_enabled,
        "public_metrics_blacklist": details_blacklist,
        "license": license,
        "license_type": license_type,
        "licenses": licenses,
        "video_urls": snap_details["video_urls"],
        "is_on_stable": is_on_stable,
    }

    return flask.render_template("publisher/listing.html", **context)
    def test_snap_not_stable(self):
        channel_maps_list = [{
            'map': [{
                'channel': 'not stable',
                'info': None
            }]
        }]

        result = logic.is_snap_on_stable(channel_maps_list)
        self.assertFalse(result)
Beispiel #5
0
def get_listing_snap(snap_name):
    try:
        snap_details = api.get_snap_info(snap_name, flask.session)
    except ApiResponseErrorList as api_response_error_list:
        if api_response_error_list.status_code == 404:
            return flask.abort(404, "No snap named {}".format(snap_name))
        else:
            return _handle_error_list(api_response_error_list.errors)
    except ApiError as api_error:
        return _handle_errors(api_error)

    is_on_stable = logic.is_snap_on_stable(snap_details["channel_maps_list"])

    # Filter icon & screenshot urls from the media set.
    icon_urls = [
        m["url"] for m in snap_details["media"] if m["type"] == "icon"
    ]
    screenshot_urls = [
        m["url"] for m in snap_details["media"] if m["type"] == "screenshot"
    ]

    licenses = get_licenses()
    countries = []
    for country in pycountry.countries:
        countries.append({"alpha_2": country.alpha_2, "name": country.name})

    context = {
        "snap_id": snap_details["snap_id"],
        "snap_name": snap_details["snap_name"],
        "snap_title": snap_details["title"],
        "summary": snap_details["summary"],
        "description": snap_details["description"],
        "license": snap_details["license"],
        "icon_url": icon_urls[0] if icon_urls else None,
        "publisher_name": snap_details["publisher"]["display-name"],
        "username": snap_details["publisher"]["username"],
        "screenshot_urls": screenshot_urls,
        "contact": snap_details["contact"],
        "private": snap_details["private"],
        "website": snap_details["website"] or "",
        "public_metrics_enabled": snap_details["public_metrics_enabled"],
        "public_metrics_blacklist": snap_details["public_metrics_blacklist"],
        "is_on_stable": is_on_stable,
        "licenses": licenses,
        "countries": countries,
    }

    return flask.render_template("publisher/listing.html", **context)
Beispiel #6
0
def get_listing_snap(snap_name):
    try:
        snap_details = api.get_snap_info(snap_name, flask.session)
    except ApiResponseErrorList as api_response_error_list:
        if api_response_error_list.status_code == 404:
            return flask.abort(404, 'No snap named {}'.format(snap_name))
        else:
            return _handle_error_list(api_response_error_list.errors)
    except ApiError as api_error:
        return _handle_errors(api_error)

    is_on_stable = logic.is_snap_on_stable(snap_details['channel_maps_list'])

    # Filter icon & screenshot urls from the media set.
    icon_urls = [
        m['url'] for m in snap_details['media'] if m['type'] == 'icon'
    ]
    screenshot_urls = [
        m['url'] for m in snap_details['media'] if m['type'] == 'screenshot'
    ]

    context = {
        "snap_id": snap_details['snap_id'],
        "snap_name": snap_details['snap_name'],
        "snap_title": snap_details['title'],
        "summary": snap_details['summary'],
        "description": snap_details['description'],
        "license": snap_details['license'],
        "icon_url": icon_urls[0] if icon_urls else None,
        "publisher_name": snap_details['publisher']['display-name'],
        "screenshot_urls": screenshot_urls,
        "contact": snap_details['contact'],
        "private": snap_details['private'],
        "website": snap_details['website'] or '',
        "public_metrics_enabled": snap_details['public_metrics_enabled'],
        "public_metrics_blacklist": snap_details['public_metrics_blacklist'],
        "is_on_stable": is_on_stable,
    }

    return flask.render_template('publisher/listing.html', **context)
    def test_snap_stable(self):
        channel_maps_list = [{"map": [{"channel": "stable", "info": "info"}]}]

        result = logic.is_snap_on_stable(channel_maps_list)
        self.assertTrue(result)
Beispiel #8
0
def post_listing_snap(snap_name):
    changes = None
    changed_fields = flask.request.form.get("changes")

    if changed_fields:
        changes = loads(changed_fields)

    if changes:
        snap_id = flask.request.form.get("snap_id")
        error_list = []

        if "images" in changes:
            # Add existing screenshots
            try:
                current_screenshots = api.snap_screenshots(
                    snap_id, flask.session)
            except ApiResponseErrorList as api_response_error_list:
                if api_response_error_list.status_code == 404:
                    return flask.abort(404,
                                       "No snap named {}".format(snap_name))
                else:
                    return _handle_error_list(api_response_error_list.errors)
            except ApiError as api_error:
                return _handle_error(api_error)

            images_json, images_files = logic.build_changed_images(
                changes["images"],
                current_screenshots,
                flask.request.files.get("icon"),
                flask.request.files.getlist("screenshots"),
                flask.request.files.get("banner-image"),
            )

            try:
                api.snap_screenshots(snap_id, flask.session, images_json,
                                     images_files)
            except ApiResponseErrorList as api_response_error_list:
                if api_response_error_list.status_code == 404:
                    return flask.abort(404,
                                       "No snap named {}".format(snap_name))
                else:
                    error_list = error_list + api_response_error_list.errors
            except ApiError as api_error:
                return _handle_error(api_error)

        body_json = logic.filter_changes_data(changes)

        if body_json:
            if "description" in body_json:
                body_json["description"] = logic.remove_invalid_characters(
                    body_json["description"])

            try:
                api.snap_metadata(snap_id, flask.session, body_json)
            except ApiResponseErrorList as api_response_error_list:
                if api_response_error_list.status_code == 404:
                    return flask.abort(404,
                                       "No snap named {}".format(snap_name))
                else:
                    error_list = error_list + api_response_error_list.errors
            except ApiError as api_error:
                return _handle_error(api_error)

        if error_list:
            try:
                snap_details = api.get_snap_info(snap_name, flask.session)
            except ApiResponseErrorList as api_response_error_list:
                if api_response_error_list.status_code == 404:
                    return flask.abort(404,
                                       "No snap named {}".format(snap_name))
                else:
                    error_list = error_list + api_response_error_list.errors
            except ApiError as api_error:
                return _handle_error(api_error)

            field_errors, other_errors = logic.invalid_field_errors(error_list)

            details_metrics_enabled = snap_details["public_metrics_enabled"]
            details_blacklist = snap_details["public_metrics_blacklist"]

            is_on_stable = logic.is_snap_on_stable(
                snap_details["channel_maps_list"])

            # Filter icon & screenshot urls from the media set.
            icon_urls, screenshot_urls, banner_urls = logic.categorise_media(
                snap_details["media"])

            licenses = []
            for license in get_licenses():
                licenses.append({
                    "key": license["licenseId"],
                    "name": license["name"]
                })

            license = snap_details["license"]
            license_type = "custom"

            if (" AND " not in license.upper()
                    and " WITH " not in license.upper()):
                license_type = "simple"

            try:
                categories_results = store_api.get_categories()
            except StoreApiError:
                categories_results = []

            categories = get_categories(categories_results)

            snap_categories = logic.replace_reserved_categories_key(
                snap_details["categories"])

            snap_categories = logic.filter_categories(snap_categories)

            filename = f"publisher/content/listing_tour.yaml"
            tour_steps = helpers.get_yaml(filename, typ="rt")

            context = {
                # read-only values from details API
                "snap_id":
                snap_details["snap_id"],
                "snap_name":
                snap_details["snap_name"],
                "snap_categories":
                snap_categories,
                "icon_url":
                icon_urls[0] if icon_urls else None,
                "publisher_name":
                snap_details["publisher"]["display-name"],
                "username":
                snap_details["publisher"]["username"],
                "screenshot_urls":
                screenshot_urls,
                "banner_urls":
                banner_urls,
                "display_title":
                snap_details["title"],
                # values posted by user
                "snap_title": (changes["title"] if "title" in changes else
                               snap_details["title"] or ""),
                "summary": (changes["summary"] if "summary" in changes else
                            snap_details["summary"] or ""),
                "description":
                (changes["description"] if "description" in changes else
                 snap_details["description"] or ""),
                "contact": (changes["contact"] if "contact" in changes else
                            snap_details["contact"] or ""),
                "private":
                snap_details["private"],
                "website": (changes["website"] if "website" in changes else
                            snap_details["website"] or ""),
                "public_metrics_enabled":
                details_metrics_enabled,
                "video_urls": ([changes["video_urls"]] if "video_urls"
                               in changes else snap_details["video_urls"]),
                "public_metrics_blacklist":
                details_blacklist,
                "license":
                license,
                "license_type":
                license_type,
                "licenses":
                licenses,
                "is_on_stable":
                is_on_stable,
                "categories":
                categories,
                # errors
                "error_list":
                error_list,
                "field_errors":
                field_errors,
                "other_errors":
                other_errors,
                "tour_steps":
                tour_steps,
            }

            return flask.render_template("publisher/listing.html", **context)

        flask.flash("Changes applied successfully.", "positive")
    else:
        flask.flash("No changes to save.", "information")

    return flask.redirect(
        flask.url_for(".get_listing_snap", snap_name=snap_name))
Beispiel #9
0
def get_listing_snap(snap_name):
    try:
        snap_details = api.get_snap_info(snap_name, flask.session)
    except ApiResponseErrorList as api_response_error_list:
        if api_response_error_list.status_code == 404:
            return flask.abort(404, "No snap named {}".format(snap_name))
        else:
            return _handle_error_list(api_response_error_list.errors)
    except ApiError as api_error:
        return _handle_error(api_error)

    details_metrics_enabled = snap_details["public_metrics_enabled"]
    details_blacklist = snap_details["public_metrics_blacklist"]

    is_on_stable = logic.is_snap_on_stable(snap_details["channel_maps_list"])

    # Filter icon & screenshot urls from the media set.
    icon_urls, screenshot_urls, banner_urls = logic.categorise_media(
        snap_details["media"])

    licenses = []
    for license in get_licenses():
        licenses.append({"key": license["licenseId"], "name": license["name"]})

    license = snap_details["license"]
    license_type = "custom"

    if " AND " not in license.upper() and " WITH " not in license.upper():
        license_type = "simple"

    referrer = None

    if flask.request.args.get("from"):
        referrer = flask.request.args.get("from")

    try:
        categories_results = store_api.get_categories()
    except StoreApiError:
        categories_results = []

    categories = sorted(
        get_categories(categories_results),
        key=lambda category: category["slug"],
    )

    snap_categories = logic.replace_reserved_categories_key(
        snap_details["categories"])

    snap_categories = logic.filter_categories(snap_categories)

    snap_categories["categories"] = [
        category["name"] for category in snap_categories["categories"]
    ]

    filename = f"publisher/content/listing_tour.yaml"
    tour_steps = helpers.get_yaml(filename, typ="rt")

    context = {
        "snap_id": snap_details["snap_id"],
        "snap_name": snap_details["snap_name"],
        "snap_title": snap_details["title"],
        "snap_categories": snap_categories,
        "summary": snap_details["summary"],
        "description": snap_details["description"],
        "icon_url": icon_urls[0] if icon_urls else None,
        "publisher_name": snap_details["publisher"]["display-name"],
        "username": snap_details["publisher"]["username"],
        "screenshot_urls": screenshot_urls,
        "banner_urls": banner_urls,
        "contact": snap_details["contact"],
        "private": snap_details["private"],
        "website": snap_details["website"] or "",
        "public_metrics_enabled": details_metrics_enabled,
        "public_metrics_blacklist": details_blacklist,
        "license": license,
        "license_type": license_type,
        "licenses": licenses,
        "video_urls": snap_details["video_urls"],
        "is_on_stable": is_on_stable,
        "from": referrer,
        "categories": categories,
        "tour_steps": tour_steps,
    }

    return flask.render_template("publisher/listing.html", **context)
Beispiel #10
0
def post_listing_snap(snap_name):
    changes = None
    changed_fields = flask.request.form.get('changes')

    if changed_fields:
        changes = loads(changed_fields)

    if changes:
        snap_id = flask.request.form.get('snap_id')
        error_list = []

        if 'images' in changes:
            # Add existing screenshots
            try:
                current_screenshots = api.snap_screenshots(
                    snap_id, flask.session)
            except ApiResponseErrorList as api_response_error_list:
                if api_response_error_list.status_code == 404:
                    return flask.abort(404,
                                       'No snap named {}'.format(snap_name))
                else:
                    return _handle_error_list(api_response_error_list.errors)
            except ApiError as api_error:
                return _handle_errors(api_error)

            images_json, images_files = logic.build_changed_images(
                changes['images'], current_screenshots,
                flask.request.files.get('icon'),
                flask.request.files.getlist('screenshots'))

            try:
                api.snap_screenshots(snap_id, flask.session, images_json,
                                     images_files)
            except ApiResponseErrorList as api_response_error_list:
                if api_response_error_list.status_code == 404:
                    return flask.abort(404,
                                       'No snap named {}'.format(snap_name))
                else:
                    error_list = error_list + api_response_error_list.errors
            except ApiError as api_error:
                return _handle_errors(api_error)

        body_json = logic.filter_changes_data(changes)

        if body_json:
            if 'public_metrics_blacklist' in body_json:
                converted_metrics = logic.convert_metrics_blacklist(
                    body_json['public_metrics_blacklist'])
                body_json['public_metrics_blacklist'] = converted_metrics

            if 'description' in body_json:
                body_json['description'] = logic.remove_invalid_characters(
                    body_json['description'])

            try:
                api.snap_metadata(snap_id, flask.session, body_json)
            except ApiResponseErrorList as api_response_error_list:
                if api_response_error_list.status_code == 404:
                    return flask.abort(404,
                                       'No snap named {}'.format(snap_name))
                else:
                    error_list = error_list + api_response_error_list.errors
            except ApiError as api_error:
                return _handle_errors(api_error)

        if error_list:
            try:
                snap_details = api.get_snap_info(snap_name, flask.session)
            except ApiResponseErrorList as api_response_error_list:
                if api_response_error_list.status_code == 404:
                    return flask.abort(404,
                                       'No snap named {}'.format(snap_name))
                else:
                    error_list = error_list + api_response_error_list.errors
            except ApiError as api_error:
                return _handle_errors(api_error)

            details_metrics_enabled = snap_details['public_metrics_enabled']
            details_blacklist = snap_details['public_metrics_blacklist']

            field_errors, other_errors = logic.invalid_field_errors(error_list)

            is_on_stable = logic.is_snap_on_stable(
                snap_details['channel_maps_list'])

            # Filter icon & screenshot urls from the media set.
            icon_urls = [
                m['url'] for m in snap_details['media'] if m['type'] == 'icon'
            ]
            screenshot_urls = [
                m['url'] for m in snap_details['media']
                if m['type'] == 'screenshot'
            ]

            context = {
                # read-only values from details API
                "snap_id":
                snap_details['snap_id'],
                "snap_name":
                snap_details['snap_name'],
                "license":
                snap_details['license'],
                "icon_url":
                icon_urls[0] if icon_urls else None,
                "publisher_name":
                snap_details['publisher']['display-name'],
                "screenshot_urls":
                screenshot_urls,
                "public_metrics_enabled":
                details_metrics_enabled,
                "public_metrics_blacklist":
                details_blacklist,
                "display_title":
                snap_details['title'],
                # values posted by user
                "snap_title": (changes['title'] if 'title' in changes else
                               snap_details['title'] or ''),
                "summary": (changes['summary'] if 'summary' in changes else
                            snap_details['summary'] or ''),
                "description":
                (changes['description'] if 'description' in changes else
                 snap_details['description'] or ''),
                "contact": (changes['contact'] if 'contact' in changes else
                            snap_details['contact'] or ''),
                "private":
                snap_details['private'],
                "website": (changes['website'] if 'website' in changes else
                            snap_details['website'] or ''),
                "is_on_stable":
                is_on_stable,
                # errors
                "error_list":
                error_list,
                "field_errors":
                field_errors,
                "other_errors":
                other_errors
            }

            return flask.render_template('publisher/listing.html', **context)

        flask.flash("Changes applied successfully.", 'positive')
    else:
        flask.flash("No changes to save.", 'information')

    return flask.redirect(
        flask.url_for('.get_listing_snap', snap_name=snap_name))
    def test_snap_stable(self):
        channel_maps_list = [{'map': [{'channel': 'stable', 'info': 'info'}]}]

        result = logic.is_snap_on_stable(channel_maps_list)
        self.assertTrue(result)
    def test_snap_stable(self):
        channel_maps_list = [{"map": [{"channel": "stable", "info": "info"}]}]

        result = logic.is_snap_on_stable(channel_maps_list)
        self.assertTrue(result)
Beispiel #13
0
def post_listing_snap(snap_name):
    changes = None
    changed_fields = flask.request.form.get("changes")

    if changed_fields:
        changes = loads(changed_fields)

    if changes:
        snap_id = flask.request.form.get("snap_id")
        error_list = []

        if "images" in changes:
            # Add existing screenshots
            try:
                current_screenshots = api.snap_screenshots(
                    snap_id, flask.session
                )
            except ApiResponseErrorList as api_response_error_list:
                if api_response_error_list.status_code == 404:
                    return flask.abort(
                        404, "No snap named {}".format(snap_name)
                    )
                else:
                    return _handle_error_list(api_response_error_list.errors)
            except ApiError as api_error:
                return _handle_errors(api_error)

            images_json, images_files = logic.build_changed_images(
                changes["images"],
                current_screenshots,
                flask.request.files.get("icon"),
                flask.request.files.getlist("screenshots"),
            )

            try:
                api.snap_screenshots(
                    snap_id, flask.session, images_json, images_files
                )
            except ApiResponseErrorList as api_response_error_list:
                if api_response_error_list.status_code == 404:
                    return flask.abort(
                        404, "No snap named {}".format(snap_name)
                    )
                else:
                    error_list = error_list + api_response_error_list.errors
            except ApiError as api_error:
                return _handle_errors(api_error)

        body_json = logic.filter_changes_data(changes)

        if body_json:
            if "description" in body_json:
                body_json["description"] = logic.remove_invalid_characters(
                    body_json["description"]
                )

            try:
                api.snap_metadata(snap_id, flask.session, body_json)
            except ApiResponseErrorList as api_response_error_list:
                if api_response_error_list.status_code == 404:
                    return flask.abort(
                        404, "No snap named {}".format(snap_name)
                    )
                else:
                    error_list = error_list + api_response_error_list.errors
            except ApiError as api_error:
                return _handle_errors(api_error)

        if error_list:
            try:
                snap_details = api.get_snap_info(snap_name, flask.session)
            except ApiResponseErrorList as api_response_error_list:
                if api_response_error_list.status_code == 404:
                    return flask.abort(
                        404, "No snap named {}".format(snap_name)
                    )
                else:
                    error_list = error_list + api_response_error_list.errors
            except ApiError as api_error:
                return _handle_errors(api_error)

            field_errors, other_errors = logic.invalid_field_errors(error_list)

            details_metrics_enabled = snap_details["public_metrics_enabled"]
            details_blacklist = snap_details["public_metrics_blacklist"]

            is_on_stable = logic.is_snap_on_stable(
                snap_details["channel_maps_list"]
            )

            # Filter icon & screenshot urls from the media set.
            icon_urls = [
                m["url"] for m in snap_details["media"] if m["type"] == "icon"
            ]
            screenshot_urls = [
                m["url"]
                for m in snap_details["media"]
                if m["type"] == "screenshot"
            ]

            licenses = []
            for license in get_licenses():
                licenses.append(
                    {"key": license["licenseId"], "name": license["name"]}
                )

            license = snap_details["license"]
            license_type = "custom"

            if (
                " AND " not in license.upper()
                and " WITH " not in license.upper()
            ):
                license_type = "simple"

            try:
                categories_results = store_api.get_categories()
            except ApiError:
                categories_results = []

            categories = get_categories(categories_results)

            snap_categories = logic.replace_reserved_categories_key(
                snap_details["categories"]
            )

            snap_categories = logic.filter_categories(snap_categories)

            context = {
                # read-only values from details API
                "snap_id": snap_details["snap_id"],
                "snap_name": snap_details["snap_name"],
                "snap_categories": snap_categories,
                "icon_url": icon_urls[0] if icon_urls else None,
                "publisher_name": snap_details["publisher"]["display-name"],
                "username": snap_details["publisher"]["username"],
                "screenshot_urls": screenshot_urls,
                "display_title": snap_details["title"],
                # values posted by user
                "snap_title": (
                    changes["title"]
                    if "title" in changes
                    else snap_details["title"] or ""
                ),
                "summary": (
                    changes["summary"]
                    if "summary" in changes
                    else snap_details["summary"] or ""
                ),
                "description": (
                    changes["description"]
                    if "description" in changes
                    else snap_details["description"] or ""
                ),
                "contact": (
                    changes["contact"]
                    if "contact" in changes
                    else snap_details["contact"] or ""
                ),
                "private": snap_details["private"],
                "website": (
                    changes["website"]
                    if "website" in changes
                    else snap_details["website"] or ""
                ),
                "public_metrics_enabled": details_metrics_enabled,
                "video_urls": (
                    [changes["video_urls"]]
                    if "video_urls" in changes
                    else snap_details["video_urls"]
                ),
                "public_metrics_blacklist": details_blacklist,
                "license": license,
                "license_type": license_type,
                "licenses": licenses,
                "is_on_stable": is_on_stable,
                "categories": categories,
                # errors
                "error_list": error_list,
                "field_errors": field_errors,
                "other_errors": other_errors,
            }

            return flask.render_template("publisher/listing.html", **context)

        flask.flash("Changes applied successfully.", "positive")
    else:
        flask.flash("No changes to save.", "information")

    return flask.redirect(
        flask.url_for(".get_listing_snap", snap_name=snap_name)
    )
Beispiel #14
0
def get_listing_snap(snap_name):
    try:
        snap_details = api.get_snap_info(snap_name, flask.session)
    except ApiResponseErrorList as api_response_error_list:
        if api_response_error_list.status_code == 404:
            return flask.abort(404, "No snap named {}".format(snap_name))
        else:
            return _handle_error_list(api_response_error_list.errors)
    except ApiError as api_error:
        return _handle_errors(api_error)

    details_metrics_enabled = snap_details["public_metrics_enabled"]
    details_blacklist = snap_details["public_metrics_blacklist"]

    is_on_stable = logic.is_snap_on_stable(snap_details["channel_maps_list"])

    # Filter icon & screenshot urls from the media set.
    icon_urls = [
        m["url"] for m in snap_details["media"] if m["type"] == "icon"
    ]
    screenshot_urls = [
        m["url"] for m in snap_details["media"] if m["type"] == "screenshot"
    ]

    licenses = []
    for license in get_licenses():
        licenses.append({"key": license["licenseId"], "name": license["name"]})

    license = snap_details["license"]
    license_type = "custom"

    if " AND " not in license.upper() and " WITH " not in license.upper():
        license_type = "simple"

    referrer = None

    if flask.request.args.get("from"):
        referrer = flask.request.args.get("from")

    try:
        categories_results = store_api.get_categories()
    except ApiError:
        categories_results = []

    categories = sorted(
        get_categories(categories_results),
        key=lambda category: category["slug"],
    )

    snap_categories = logic.replace_reserved_categories_key(
        snap_details["categories"]
    )

    snap_categories = logic.filter_categories(snap_categories)

    context = {
        "snap_id": snap_details["snap_id"],
        "snap_name": snap_details["snap_name"],
        "snap_title": snap_details["title"],
        "snap_categories": snap_categories,
        "summary": snap_details["summary"],
        "description": snap_details["description"],
        "icon_url": icon_urls[0] if icon_urls else None,
        "publisher_name": snap_details["publisher"]["display-name"],
        "username": snap_details["publisher"]["username"],
        "screenshot_urls": screenshot_urls,
        "contact": snap_details["contact"],
        "private": snap_details["private"],
        "website": snap_details["website"] or "",
        "public_metrics_enabled": details_metrics_enabled,
        "public_metrics_blacklist": details_blacklist,
        "license": license,
        "license_type": license_type,
        "licenses": licenses,
        "video_urls": snap_details["video_urls"],
        "is_on_stable": is_on_stable,
        "from": referrer,
        "categories": categories,
    }

    return flask.render_template("publisher/listing.html", **context)