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
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"]))
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))
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))
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))
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"]))
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"]))
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
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"]))
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"]))
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))
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))
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"]))
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"))
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)
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))