decouple pack functions from flask

This commit is contained in:
Kentai Radiquum 2025-05-15 00:30:20 +05:00
parent f4d15c5eaf
commit 69fb1584e5
Signed by: Radiquum
GPG key ID: 858E8EE696525EED
4 changed files with 141 additions and 93 deletions

View file

@ -52,8 +52,10 @@ export default function PackPage() {
const res = await fetch(PACK_ENDPOINT("getPack", id)); const res = await fetch(PACK_ENDPOINT("getPack", id));
if (!res.ok) router.push("/404"); if (!res.ok) router.push("/404");
const data: Pack = await res.json(); const data: Pack = await res.json();
setPackData(data); if (data._id) {
setPackDataLoading(false); setPackData(data);
setPackDataLoading(false);
}
} }
useEffect(() => { useEffect(() => {

View file

@ -1,26 +1,19 @@
import os import os
import re import re
from . import apiPack from . import apiPack
from flask import request, jsonify, send_file, redirect, url_for, abort from flask import request, jsonify, send_file, redirect, url_for
from config import PACKS_FOLDER, IMG_ALLOWED_MIME from config import PACKS_FOLDER, IMG_ALLOWED_MIME
from PIL import Image from PIL import Image
from io import BytesIO from io import BytesIO
import base64 import base64
import json from shared.pack import getPack, addMod, deleteMod
from .source import Modrinth, CurseForge
@apiPack.route("/<id>", methods=["GET"]) @apiPack.route("/<id>", methods=["GET"])
def getPack(id): def getPackEndpoint(id):
if not os.path.exists(f"{PACKS_FOLDER}/{id}/packfile.json"): pack = getPack(id)
if pack is None:
return jsonify({"status": "error", "message": "pack not found"}), 404 return jsonify({"status": "error", "message": "pack not found"}), 404
pack = {}
with open(f"{PACKS_FOLDER}/{id}/packfile.json") as fp:
pack = json.load(fp)
pack["_id"] = id
fp.close()
return jsonify(pack) return jsonify(pack)
@ -63,73 +56,35 @@ def editPackImage(id):
@apiPack.route("/<id>/mod/add", methods=["POST"]) @apiPack.route("/<id>/mod/add", methods=["POST"])
def addMod(id): def addModEndpoint(id):
source = request.json.get("source", None) source = request.json.get("source", None)
slug = request.json.get("slug", None) slug = request.json.get("slug", None)
version = request.json.get("version", None) version = request.json.get("version", None)
pack = {} mod = addMod(id, source, slug, version)
mod = {}
if not os.path.exists(f"{PACKS_FOLDER}/{id}/packfile.json"): if mod == "err_404":
return jsonify({"status": "error", "message": "pack not found"}) return jsonify({"status": "error", "message": "pack not found"})
with open(f"{PACKS_FOLDER}/{id}/packfile.json") as fp: elif mod == "err_source":
pack = json.load(fp)
fp.close()
mod_loader = pack.get("modloader").lower()
game_version = pack.get("version")
if not source:
return jsonify({"status": "error", "message": "mod source is required"}) return jsonify({"status": "error", "message": "mod source is required"})
if not slug: elif mod == "err_slug":
return jsonify({"status": "error", "message": "mod slug is required"}) return jsonify({"status": "error", "message": "mod slug is required"})
elif mod == "err_exists":
for mod in pack["mods"]: return jsonify({"status": "error", "message": "mod already exists"})
if mod.get("slug") == slug: elif isinstance(mod, str):
return jsonify({"status": "error", "message": "mod already exists"}) return jsonify({"status": "error", "message": mod})
if source == "Modrinth":
mod = Modrinth.getModrinthMod(slug, version, mod_loader, game_version)
elif source == "CurseForge":
mod = CurseForge.getCurseForgeMod(slug, version, mod_loader, game_version)
if mod.get("status") != "ok":
return jsonify({"status": "error", "message": mod.get("message")})
pack["modpackVersion"] += 1
pack["mods"].append(mod.get("mod"))
with open(f"{PACKS_FOLDER}/{id}/packfile.json", mode="w", encoding="utf-8") as fp:
json.dump(pack, fp)
fp.close()
return jsonify( return jsonify(
{ {
"status": "ok", "status": "ok",
"message": f"mod {mod.get("mod").get('title')} ({slug}) has been added", "message": f"mod {mod.get("title")} ({slug}) has been added",
"mod": mod.get("mod"), "mod": mod,
} }
) )
@apiPack.route("/<id>/mod/<slug>/delete", methods=["GET"]) @apiPack.route("/<id>/mod/<slug>/delete", methods=["GET"])
def deleteMod(id, slug): def deleteModEndpoint(id, slug):
pack = {} deleteMod(id, slug)
with open(f"{PACKS_FOLDER}/{id}/packfile.json") as fp:
pack = json.load(fp)
fp.close()
for mod in pack.get("mods"):
if mod.get("slug") == slug:
pack["mods"].remove(mod)
pack["modpackVersion"] += 1
if os.path.exists(
f"{PACKS_FOLDER}/{id}/mods/{mod.get('file').get('filename')}"
):
os.remove(f"{PACKS_FOLDER}/{id}/mods/{mod.get('file').get('filename')}")
with open(f"{PACKS_FOLDER}/{id}/packfile.json", mode="w", encoding="utf-8") as fp:
json.dump(pack, fp)
fp.close()
return jsonify( return jsonify(
{ {
"status": "ok", "status": "ok",
@ -138,34 +93,34 @@ def deleteMod(id, slug):
) )
@apiPack.route("/<id>/mods/delete", methods=["POST"]) # @apiPack.route("/<id>/mods/delete", methods=["POST"])
def deleteModBulk(id): # def deleteModBulk(id):
pack = {} # pack = {}
slugs = request.json # slugs = request.json
with open(f"{PACKS_FOLDER}/{id}/packfile.json") as fp: # with open(f"{PACKS_FOLDER}/{id}/packfile.json") as fp:
pack = json.load(fp) # pack = json.load(fp)
fp.close() # fp.close()
for slug in slugs: # for slug in slugs:
for mod in pack.get("mods"): # for mod in pack.get("mods"):
if mod.get("slug") == slug: # if mod.get("slug") == slug:
pack["mods"].remove(mod) # pack["mods"].remove(mod)
pack["modpackVersion"] += 1 # pack["modpackVersion"] += 1
if os.path.exists( # if os.path.exists(
f"{PACKS_FOLDER}/{id}/mods/{mod.get('file').get('filename')}" # f"{PACKS_FOLDER}/{id}/mods/{mod.get('file').get('filename')}"
): # ):
os.remove( # os.remove(
f"{PACKS_FOLDER}/{id}/mods/{mod.get('file').get('filename')}" # f"{PACKS_FOLDER}/{id}/mods/{mod.get('file').get('filename')}"
) # )
with open(f"{PACKS_FOLDER}/{id}/packfile.json", mode="w", encoding="utf-8") as fp: # with open(f"{PACKS_FOLDER}/{id}/packfile.json", mode="w", encoding="utf-8") as fp:
json.dump(pack, fp) # json.dump(pack, fp)
fp.close() # fp.close()
return jsonify( # return jsonify(
{ # {
"status": "ok", # "status": "ok",
"message": f"mods has been removed", # "message": f"mods has been removed",
} # }
) # )

91
src/shared/pack.py Normal file
View file

@ -0,0 +1,91 @@
import os
from config import PACKS_FOLDER
import json
from type.pack import Pack
from type.mod import Mod
from typing import Literal
from api.source import Modrinth, CurseForge
def getPack(id: str) -> Pack | None:
if not os.path.exists(f"{PACKS_FOLDER}/{id}/packfile.json"):
return None
pack: Pack = {}
with open(f"{PACKS_FOLDER}/{id}/packfile.json") as fp:
pack = json.load(fp)
pack["_id"] = id
fp.close()
return pack
def addMod(
pack_id: str, source: str, slug: str, version: str | None
) -> (
Mod
| Literal["err_404"]
| Literal["err_source"]
| Literal["err_slug"]
| Literal["err_exists"]
| str
):
pack: Pack = {}
mod: Mod = {}
if not os.path.exists(f"{PACKS_FOLDER}/{pack_id}/packfile.json"):
return "err_404"
with open(f"{PACKS_FOLDER}/{pack_id}/packfile.json") as fp:
pack = json.load(fp)
fp.close()
mod_loader = pack.get("modloader").lower()
game_version = pack.get("version")
if not source:
return "err_source"
if not slug:
return "err_slug"
for mod in pack["mods"]:
if mod.get("slug") == slug:
return "err_exists"
if source == "Modrinth":
mod = Modrinth.getModrinthMod(slug, version, mod_loader, game_version)
elif source == "CurseForge":
mod = CurseForge.getCurseForgeMod(slug, version, mod_loader, game_version)
if mod.get("status") != "ok":
return mod.get("message")
pack["modpackVersion"] += 1
pack["mods"].append(mod.get("mod"))
with open(
f"{PACKS_FOLDER}/{pack_id}/packfile.json", mode="w", encoding="utf-8"
) as fp:
json.dump(pack, fp)
fp.close()
return mod.get("mod")
def deleteMod(id: str, slug: str) -> Literal[True]:
pack = {}
with open(f"{PACKS_FOLDER}/{id}/packfile.json") as fp:
pack = json.load(fp)
fp.close()
for mod in pack.get("mods"):
if mod.get("slug") == slug:
pack["mods"].remove(mod)
pack["modpackVersion"] += 1
if os.path.exists(
f"{PACKS_FOLDER}/{id}/mods/{mod.get('file').get('filename')}"
):
os.remove(f"{PACKS_FOLDER}/{id}/mods/{mod.get('file').get('filename')}")
with open(f"{PACKS_FOLDER}/{id}/packfile.json", mode="w", encoding="utf-8") as fp:
json.dump(pack, fp)
fp.close()
return True

View file

@ -31,7 +31,7 @@ def getPacks() -> list[Pack]:
def createPack( def createPack(
title: str, author: str, game_version: str, mod_loader: str title: str, author: str, game_version: str, mod_loader: str
) -> Pack | bool: ) -> tuple[Pack, bool]:
""" """
Creates a new pack. Creates a new pack.
If pack exists returns tuple[Pack, True], if pack was created returns tuple[Pack, False] If pack exists returns tuple[Pack, True], if pack was created returns tuple[Pack, False]