From 9c37b028f8f55a3ff6bf115b672680f11acc00e5 Mon Sep 17 00:00:00 2001 From: cube Date: Mon, 23 Mar 2026 22:27:54 +0000 Subject: [PATCH] implement #19 --- .gitignore | 1 + README.md | 3 + myriad/manage.py | 145 +++++++++++++++++++++++++++++- myriad/templates/manage/edit.html | 8 ++ 4 files changed, 154 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 2a919ee..cc8e6be 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,4 @@ build/ /myriad/static/icons /myriad/static/blinkies /myriad/static/stamps +myriad/static/tmp diff --git a/README.md b/README.md index 1e7813f..fb9cd2f 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,8 @@ in the blog view, member privacy outweighs individual post privacy. if a private the blinkies and stamps stuff is literally just because i want an easy way to upload them when i find them. and im the dev so i get to decide mwa ha ha +make sure blinkies are actually blinkie-sized, and stamps are likewise stamp-sized. too much variation in size will make the layout weird. there's not validation because its designed just to make uploading the images not require ftp + manual code as i had been doing before. + # dev set up (windows) - after cloning, run `py -3 -m venv .venv` in the root directory and then `.venv\Scripts\activate` @@ -38,6 +40,7 @@ STAMPS_UPLOAD_FOLDER = 'myriad/static/stamps' # where site assets "stamps" will INLINE_UPLOAD_FOLDER = 'myriad/static/inline' # where site assets "misc inline" will be stored MISC_UPLOAD_FOLDER = 'myriad/static/misc' # where other small images will be stored THEMES_FOLDER = 'myriad/static/themes' # where theme choices will be stored +TMP_FOLDER = 'myriad/static/tmp' # folder for creating export files ``` # usage diff --git a/myriad/manage.py b/myriad/manage.py index a52eac0..d3d969d 100644 --- a/myriad/manage.py +++ b/myriad/manage.py @@ -1,8 +1,8 @@ from flask import ( - Blueprint, flash, g, redirect, render_template, request, session, url_for, current_app + Blueprint, flash, g, redirect, render_template, request, session, url_for, current_app, send_file, send_from_directory ) from werkzeug.utils import secure_filename -import os, uuid +import os, uuid, json, zipfile from myriad.auth import login_required from myriad.db import get_db @@ -214,6 +214,140 @@ def remove_home(mid,location): return redirect(url_for('index')) else: return redirect(url_for('home.full_list')) + +# DATA EXPORTS + +@bp.route("/export_fields/") +@login_required +def export_fields(mid): + db = get_db() + member = db.execute("SELECT * FROM member WHERE id=(?)",(mid,)).fetchone() + + if member[9] == 1: + privacy = "public" + else: + privacy = "private" + + date_created = member[2].strftime("%d/%m/%Y, %H:%M:%S") + + data = { + "date-created":date_created, + "date-format":"d/m/Y, H:M:S", + "name":member[3], + "subtitle":member[4], + "description":member[5], + "privacy":privacy + } + + filename = str(member[0]) + "-" + member[3] + ".json" + full_path = current_app.config["TMP_FOLDER"] + "/" + filename + with open(full_path, 'w') as f: + json.dump(data, f) + + return send_file("static/tmp/"+filename, as_attachment=True) + +# THIS TECHNICALLY WORKS BUT I DONT LIKE IT RN +@bp.route("/export_icons/") +@login_required +def export_icons(mid): + db = get_db() + member = db.execute("SELECT * FROM member WHERE id=(?)",(mid,)).fetchone() + icons = db.execute("SELECT icon_location FROM icons WHERE member_id=(?)",(mid,)).fetchall() + + zip_name = str(member[0]) + "-" + member[3] + "-icons.zip" + full_path = current_app.config["TMP_FOLDER"] + "/" + zip_name + with zipfile.ZipFile(full_path, "w") as zipf: + for icon in icons: + filename = icon[0] + zipf.write(current_app.config["ICON_UPLOAD_FOLDER"] + "/" + filename) + + return send_file("static/tmp/"+zip_name, as_attachment=True) + +# THIS TECHNICALLY WORKS BUT I DONT LIKE IT RN +@bp.route("/export_blinkies/") +@login_required +def export_blinkies(mid): + db = get_db() + member = db.execute("SELECT * FROM member WHERE id=(?)",(mid,)).fetchone() + blinkies = db.execute("SELECT blinkie_location FROM blinkies WHERE member_id=(?)",(mid,)).fetchall() + + zip_name = str(member[0]) + "-" + member[3] + "-blinkies.zip" + full_path = current_app.config["TMP_FOLDER"] + "/" + zip_name + with zipfile.ZipFile(full_path, "w") as zipf: + for blinkie in blinkies: + filename = blinkie[0] + zipf.write(current_app.config["BLINKIES_UPLOAD_FOLDER"] + "/" + filename) + + return send_file("static/tmp/"+zip_name, as_attachment=True) + +# THIS TECHNICALLY WORKS BUT I DONT LIKE IT RN +@bp.route("/export_stamps/") +@login_required +def export_stamps(mid): + db = get_db() + member = db.execute("SELECT * FROM member WHERE id=(?)",(mid,)).fetchone() + stamps = db.execute("SELECT stamp_location FROM stamps WHERE member_id=(?)",(mid,)).fetchall() + + zip_name = str(member[0]) + "-" + member[3] + "-stamps.zip" + full_path = current_app.config["TMP_FOLDER"] + "/" + zip_name + with zipfile.ZipFile(full_path, "w") as zipf: + for stamp in stamps: + filename = stamp[0] + zipf.write(current_app.config["STAMPS_UPLOAD_FOLDER"] + "/" + filename) + + return send_file("static/tmp/"+zip_name, as_attachment=True) + + +# THIS TECHNICALLY WORKS BUT I DONT LIKE IT RN +@bp.route("/export_member/") +@login_required +def export_member(mid): + db = get_db() + member = db.execute("SELECT * FROM member WHERE id=(?)",(mid,)).fetchone() + icons = db.execute("SELECT icon_location FROM icons WHERE member_id=(?)",(mid,)).fetchall() + blinkies = db.execute("SELECT blinkie_location FROM blinkies WHERE member_id=(?)",(mid,)).fetchall() + stamps = db.execute("SELECT stamp_location FROM stamps WHERE member_id=(?)",(mid,)).fetchall() + + if member[9] == 1: + privacy = "public" + else: + privacy = "private" + + date_created = member[2].strftime("%d/%m/%Y, %H:%M:%S") + + data = { + "date-created":date_created, + "date-format":"d/m/Y, H:M:S", + "name":member[3], + "subtitle":member[4], + "description":member[5], + "privacy":privacy + } + + data_name = str(member[0]) + "-" + member[3] + ".json" + data_full_path = current_app.config["TMP_FOLDER"] + "/" + data_name + with open(data_full_path, 'w') as f: + json.dump(data, f) + + + zip_name = str(member[0]) + "-" + member[3] + ".zip" + zip_path = current_app.config["TMP_FOLDER"] + "/" + zip_name + with zipfile.ZipFile(zip_path, "w") as zipf: + zipf.write(data_full_path) + for icon in icons: + iname = icon[0] + zipf.write(current_app.config["ICON_UPLOAD_FOLDER"] + "/" + iname) + for blinkie in blinkies: + bname = blinkie[0] + zipf.write(current_app.config["BLINKIES_UPLOAD_FOLDER"] + "/" + bname) + for stamp in stamps: + sname = stamp[0] + zipf.write(current_app.config["STAMPS_UPLOAD_FOLDER"] + "/" + sname) + + return send_file("static/tmp/"+zip_name, as_attachment=True) + + +# ASSETS @bp.route("/assets", methods=('GET', 'POST')) @@ -290,6 +424,11 @@ def delete_ifiles(): return redirect(url_for("manage.assets")) + + +# GROUPS + + @bp.route("/groups", methods=('GET', 'POST')) @login_required def groups(): @@ -328,4 +467,4 @@ def group_delete(gid): db.execute("DELETE FROM group_members WHERE group_id=(?)",(gid,)) db.commit() - return redirect(url_for("manage.groups")) \ No newline at end of file + return redirect(url_for("manage.groups")) diff --git a/myriad/templates/manage/edit.html b/myriad/templates/manage/edit.html index ae609f7..0ec4a3b 100644 --- a/myriad/templates/manage/edit.html +++ b/myriad/templates/manage/edit.html @@ -114,6 +114,14 @@ {% endfor %} + + +
Manage Member Data
+ Export Fields
+ Export icons
+ Export blinkies
+ Export stamps
+ Export all member data