Beispiel #1
0
def download(iuid, ext):
    """Download the content of the dataset as JSON or CSV file.
    This is for use in the HTML pages, not for API calls.
    """
    try:
        dataset = get_dataset(iuid)
    except ValueError as error:
        utils.flash_error(str(error))
        return flask.redirect(utils.url_referrer())
    if not allow_view(dataset):
        utils.flash_error("View access to dataset is not allowed.")
        return flask.redirect(utils.url_referrer())
    if not dataset.get("_attachments", None):
        utils.flash_error("Dataset does not contain any data.")
        return flask.redirect(utils.url_referrer())
    if ext == "json":
        outfile = flask.g.db.get_attachment(dataset, "data.json")
        response = flask.make_response(outfile.read())
        response.headers.set("Content-Type", constants.JSON_MIMETYPE)
    elif ext == "csv":
        outfile = flask.g.db.get_attachment(dataset, "data.csv")
        response = flask.make_response(outfile.read())
        response.headers.set("Content-Type", constants.CSV_MIMETYPE)
    else:
        utils.flash_error("Invalid file type requested.")
        return flask.redirect(utils.url_referrer())
    slug = utils.slugify(dataset['title'])
    response.headers.set("Content-Disposition",
                         "attachment",
                         filename=f"{slug}.{ext}")
    return response
Beispiel #2
0
def stencil():
    "Select a stencil for the dataset given as form argument."
    try:
        iuid = flask.request.values.get("dataset")
        if not iuid:
            raise ValueError("No dataset IUID provided.")
        dataset = datagraphics.dataset.get_dataset(iuid)
    except ValueError as error:
        utils.flash_error(str(error))
        return flask.redirect(flask.url_for("home"))
    if not datagraphics.dataset.allow_view(dataset):
        utils.flash_error("View access to dataset not allowed.")
        return flask.redirect(utils.url_referrer())

    if utils.http_GET():
        stencils = []
        for name in flask.current_app.config["STENCILS"]:
            header = deepcopy(
                flask.current_app.config["STENCILS"][name]["header"])
            field_variables = [
                v for v in header["variables"] if v.get("class") == "field"
            ]
            header["combinations"] = combinations(field_variables,
                                                  dataset["meta"].items())
            if header["combinations"]:
                stencils.append(header)
        stencils.sort(key=lambda h: (h.get("weight", 0), h["title"]))
        return flask.render_template("graphic/stencil.html",
                                     dataset=dataset,
                                     stencils=stencils)
    elif utils.http_POST():
        try:
            spec = deepcopy(flask.current_app.config["STENCILS"]\
                            [flask.request.form["stencil"]])
            header = spec.pop("header")
            setfields = SetFields(flask.request.form["combination"])
            url = flask.url_for("api_dataset.content",
                                iuid=dataset["_id"],
                                ext="csv",
                                _external=True)
            for variable in header["variables"]:
                if variable.get("class") == "dataset":
                    setfields.lookup["/".join(variable["path"])] = url
            setfields.traverse(spec)
            with GraphicSaver() as saver:
                saver.set_dataset(dataset)
                saver.set_title(header["title"])
                saver.set_description(
                    f"Created from stencil {header['name']}.")
                saver.set_public(False)
                saver.set_specification(spec)
        except (KeyError, ValueError) as error:
            utils.flash_error(str(error))
            return flask.redirect(utils.url_referrer())
        return flask.redirect(flask.url_for(".display", iuid=saver.doc["_id"]))
Beispiel #3
0
def logs(iuid):
    "Display the log records of the given graphic."
    try:
        graphic = get_graphic(iuid)
    except ValueError as error:
        utils.flash_error(str(error))
        return flask.redirect(utils.url_referrer())
    if not allow_view(graphic):
        utils.flash_error("View access to graphic not allowed.")
        return flask.redirect(utils.url_referrer())
    return flask.render_template(
        "logs.html",
        title=f"Graphic {graphic['title']}",
        back_url=flask.url_for(".display", iuid=iuid),
        logs=utils.get_logs(iuid))
Beispiel #4
0
def logs(iuid):
    "Display the log records of the given dataset."
    try:
        dataset = get_dataset(iuid)
    except ValueError as error:
        utils.flash_error(str(error))
        return flask.redirect(utils.url_referrer())
    if not allow_view(dataset):
        utils.flash_error("View access to dataset not allowed.")
        return flask.redirect(utils.url_referrer())
    return flask.render_template(
        "logs.html",
        title=f"Dataset {dataset['title'] or 'No title'}",
        cancel_url=flask.url_for(".display", iuid=iuid),
        logs=utils.get_logs(iuid))
Beispiel #5
0
def display(iuid):
    "Display the graphic."
    try:
        graphic = get_graphic(iuid)
    except ValueError as error:
        utils.flash_error(str(error))
        return flask.redirect(flask.url_for("home"))
    if not allow_view(graphic):
        utils.flash_error("View access to graphic not allowed.")
        return flask.redirect(utils.url_referrer())
    dataset = get_dataset(graphic)
    if dataset:
        other_graphics = [gr 
                          for gr in datagraphics.dataset.get_graphics(dataset)
                          if gr["_id"] != graphic["_id"]]
    else:
        other_graphics = []
    if flask.g.current_user and \
       flask.g.current_user["username"] == graphic["owner"] and \
       dataset["owner"] != graphic["owner"]:
        utils.flash_warning("The dataset is not owned by you."
                            " This graphic may become invalid if the owner of"
                            " the dataset deletes it or makes it inaccessible.")
    return flask.render_template("graphic/display.html",
                                 graphic=graphic,
                                 slug=utils.slugify(graphic['title']),
                                 dataset=dataset,
                                 other_graphics=other_graphics,
                                 am_owner=am_owner(graphic),
                                 allow_edit=allow_edit(graphic),
                                 allow_delete=allow_delete(graphic))
Beispiel #6
0
def copy(iuid):
    "Copy the graphic."
    try:
        graphic = get_graphic(iuid)
    except ValueError as error:
        utils.flash_error(str(error))
        return flask.redirect(utils.url_referrer())
    if not allow_view(graphic):
        utils.flash_error("View access to graphic not allowed.")
        return flask.redirect(flask.url_for(".display", iuid=iuid))
    try:
        with GraphicSaver() as saver:
            saver.copy(graphic)
    except ValueError as error:
        utils.flash_error(str(error))
        return flask.redirect(utils.url_referrer())
    return flask.redirect(flask.url_for(".display", iuid=saver.doc["_id"]))
Beispiel #7
0
def copy(iuid):
    "Copy the dataset, including its data content."
    try:
        dataset = get_dataset(iuid)
    except ValueError as error:
        utils.flash_error(str(error))
        return flask.redirect(utils.url_referrer())
    if not allow_view(dataset):
        utils.flash_error("View access to dataset not allowed.")
        return flask.redirect(flask.url_for(".display", iuid=iuid))
    try:
        with DatasetSaver() as saver:
            saver.copy(dataset)
    except ValueError as error:
        utils.flash_error(str(error))
        return flask.redirect(utils.url_referrer())
    return flask.redirect(flask.url_for(".display", iuid=saver.doc["_id"]))
Beispiel #8
0
def download(iuid, ext):
    "Download the JSON or JavaScript specification of the Vega-Lite graphic."
    try:
        graphic = get_graphic(iuid)
    except ValueError as error:
        utils.flash_error(str(error))
        return flask.redirect(utils.url_referrer())
    if not allow_view(graphic):
        utils.flash_error("View access to graphic not allowed.")
        return flask.redirect(utils.url_referrer())
    dataset = get_dataset(graphic)
    if not dataset:
        utils.flash_error("View access to dataset not allowed.")
        return flask.redirect(utils.url_referrer())

    spec = graphic["specification"]
    slug = utils.slugify(graphic['title'])
    id = flask.request.args.get("id") or "graphic"

    if utils.to_bool(flask.request.args.get("inline")):
        outfile = flask.g.db.get_attachment(dataset, "data.json")
        spec["data"] = {"values": json.load(outfile)}
    if ext == "json":
        response = flask.jsonify(spec)
        response.headers.set("Content-Type", constants.JSON_MIMETYPE)
    elif ext == "js":
        spec = json.dumps(spec, ensure_ascii=False)
        response = flask.make_response(f'vegaEmbed("#{id}", {spec},'
                                       f' {{downloadFileName: "{slug}"}})'
                                       '.then(result=>console.log(result))'
                                       '.catch(console.warn);')
        response.headers.set("Content-Type", constants.JS_MIMETYPE)
    elif ext == "html":
        html = flask.render_template("graphic/vega_lite.html",
                                     graphic=graphic,
                                     id=id,
                                     slug=slug)
        response = flask.make_response(html)
        response.headers.set("Content-Type", constants.HTML_MIMETYPE)
    else:
        utils.flash_error("Invalid file type requested.")
        return flask.redirect(utils.url_referrer())
    response.headers.set("Content-Disposition",
                         "attachment",
                         filename=f"{slug}.{ext}")
    return response
Beispiel #9
0
def edit(iuid):
    "Edit the graphic, or delete it."
    try:
        graphic = get_graphic(iuid)
    except ValueError as error:
        utils.flash_error(str(error))
        return flask.redirect(utils.url_referrer())

    if utils.http_GET():
        if not allow_edit(graphic):
            utils.flash_error("Edit access to graphic not allowed.")
            return flask.redirect(flask.url_for(".display", iuid=iuid))
        return flask.render_template("graphic/edit.html",
                                     am_owner=am_owner(graphic),
                                     graphic=graphic)

    elif utils.http_POST():
        if not allow_edit(graphic):
            utils.flash_error("Edit access to graphic not allowed.")
            return flask.redirect(flask.url_for(".display", iuid=iuid))
        try:
            with GraphicSaver(graphic) as saver:
                saver.set_title()
                if flask.g.am_admin:
                    saver.change_owner()
                if am_owner(graphic):
                    saver.set_editors()
                saver.set_description()
                saver.set_specification()
        except ValueError as error:
            utils.flash_error(str(error))
            return flask.redirect(utils.url_referrer())
        return flask.redirect(flask.url_for(".display", iuid=saver.doc["_id"]))

    elif utils.http_DELETE():
        if not allow_delete(graphic):
            utils.flash_error("Delete access to graphic not allowed.")
            return flask.redirect(flask.url_for(".display", iuid=iuid))
        flask.g.db.delete(graphic)
        for log in utils.get_logs(graphic["_id"], cleanup=False):
            flask.g.db.delete(log)
        utils.flash_message("The graphic was deleted.")
        return flask.redirect(
            flask.url_for("dataset.display", iuid=graphic["dataset"]))
Beispiel #10
0
def create():
    "Create a new graphic for dataset given as form argument."
    try:
        iuid = flask.request.values.get("dataset")
        if not iuid:
            raise ValueError("No dataset IUID provided.")
        dataset = datagraphics.dataset.get_dataset(iuid)
    except ValueError as error:
        utils.flash_error(str(error))
        return flask.redirect(flask.url_for("home"))
    if not datagraphics.dataset.allow_view(dataset):
        utils.flash_error("View access to dataset not allowed.")
        return flask.redirect(utils.url_referrer())

    if utils.http_GET():
        graphic = {
            "$schema": constants.VEGA_LITE_SCHEMA_URL,
            "data": {
                "url":
                flask.url_for("api_dataset.content",
                              iuid=dataset["_id"],
                              ext="csv",
                              _external=True)
            }
        }
        return flask.render_template("graphic/create.html",
                                     dataset=dataset,
                                     graphic=graphic)

    elif utils.http_POST():
        try:
            with GraphicSaver() as saver:
                saver.set_dataset(dataset)
                saver.set_title()
                saver.set_description()
                saver.set_public(False)
                saver.set_specification()
        except ValueError as error:
            utils.flash_error(str(error))
            return flask.redirect(utils.url_referrer())
        return flask.redirect(flask.url_for(".display", iuid=saver.doc["_id"]))
Beispiel #11
0
def private(iuid):
    "Set the graphic to private access."
    try:
        graphic = get_graphic(iuid)
    except ValueError as error:
        utils.flash_error(str(error))
        return flask.redirect(utils.url_referrer())
    if am_owner(graphic):
        if graphic["public"]:
            with GraphicSaver(graphic) as saver:
                saver.set_public(False)
    else:
        utils.flash_error("Only owner may make graphic private.")
    return flask.redirect(flask.url_for(".display", iuid=iuid))
Beispiel #12
0
def private(iuid):
    "Set the dataset to private access."
    try:
        dataset = get_dataset(iuid)
    except ValueError as error:
        utils.flash_error(str(error))
        return flask.redirect(utils.url_referrer())
    if am_owner(dataset):
        if dataset["public"]:
            with DatasetSaver(dataset) as saver:
                saver.set_public(False)
    else:
        utils.flash_error("Only owner may make dataset private.")
    return flask.redirect(flask.url_for(".display", iuid=iuid))
Beispiel #13
0
def create():
    "Create a new dataset, from file or URL."
    if utils.http_GET():
        return flask.render_template("dataset/create.html")

    elif utils.http_POST():
        try:
            with DatasetSaver() as saver:
                saver.set_title()
                saver.set_description()
                saver.set_public(False)
                if not saver.upload_file():
                    saver.get_url_data()
        except ValueError as error:
            utils.flash_error(str(error))
            return flask.redirect(utils.url_referrer())
        return flask.redirect(flask.url_for(".display", iuid=saver.doc["_id"]))
Beispiel #14
0
def edit(iuid):
    "Edit the dataset, or delete it."
    try:
        dataset = get_dataset(iuid)
    except ValueError as error:
        utils.flash_error(str(error))
        return flask.redirect(utils.url_referrer())

    if utils.http_GET():
        if not allow_edit(dataset):
            utils.flash_error("Edit access to dataset not allowed.")
            return flask.redirect(flask.url_for(".display", iuid=iuid))
        return flask.render_template("dataset/edit.html",
                                     am_owner=am_owner(dataset),
                                     dataset=dataset)

    elif utils.http_POST():
        if not allow_edit(dataset):
            utils.flash_error("Edit access to dataset not allowed.")
            return flask.redirect(flask.url_for(".display", iuid=iuid))
        try:
            with DatasetSaver(dataset) as saver:
                saver.set_title()
                if flask.g.am_admin:
                    saver.change_owner()
                if am_owner(dataset):
                    saver.set_editors()
                saver.set_description()
                saver.upload_file()
                saver.set_vega_lite_types()
        except ValueError as error:
            utils.flash_error(str(error))
        return flask.redirect(flask.url_for(".display", iuid=iuid))

    elif utils.http_DELETE():
        if not possible_delete(dataset):
            utils.flash_error("Dataset cannot be deleted; use by graphics.")
            return flask.redirect(flask.url_for(".display", iuid=iuid))
        if not allow_delete(dataset):
            utils.flash_error("Delete access to dataset not allowed.")
            return flask.redirect(flask.url_for(".display", iuid=iuid))
        flask.g.db.delete(dataset)
        for log in utils.get_logs(dataset["_id"], cleanup=False):
            flask.g.db.delete(log)
        utils.flash_message("The dataset was deleted.")
        return flask.redirect(flask.url_for("datasets.display"))
Beispiel #15
0
def data(iuid):
    "Display the data contents of the dataset."
    try:
        dataset = get_dataset(iuid)
    except ValueError as error:
        utils.flash_error(str(error))
        return flask.redirect(flask.url_for("home"))
    if not allow_view(dataset):
        utils.flash_error("View access to dataset not allowed.")
        return flask.redirect(utils.url_referrer())
    outfile = flask.g.db.get_attachment(dataset, "data.json")
    data = json.load(outfile)
    max_records = flask.current_app.config["MAX_RECORDS_INSPECT"]
    if len(data) > max_records:
        data = data[:max_records]
        utils.flash_message(
            f"Only the first {max_records} records are displayed.")
    return flask.render_template("dataset/data.html",
                                 dataset=dataset,
                                 data=data)
Beispiel #16
0
def display(iuid):
    "Display the dataset."
    try:
        dataset = get_dataset(iuid)
    except ValueError as error:
        utils.flash_error(str(error))
        return flask.redirect(flask.url_for("home"))
    if not allow_view(dataset):
        utils.flash_error("View access to dataset not allowed.")
        return flask.redirect(utils.url_referrer())
    storage = sum(
        [s['length'] for s in dataset.get('_attachments', {}).values()])
    return flask.render_template("dataset/display.html",
                                 dataset=dataset,
                                 graphics=get_graphics(dataset),
                                 storage=storage,
                                 am_owner=am_owner(dataset),
                                 allow_edit=allow_edit(dataset),
                                 allow_delete=allow_delete(dataset),
                                 possible_delete=possible_delete(dataset),
                                 commands=get_commands(dataset))