1
0
Fork 0
mirror of https://github.com/YunoHost/apps.git synced 2024-09-03 20:06:07 +02:00
apps/store/utils.py

189 lines
5.7 KiB
Python

import time
import base64
import os
import json
import toml
import subprocess
import pycmarkgfm
from emoji import emojize
from flask import request
from hashlib import md5
AVAILABLE_LANGUAGES = ["en"] + os.listdir("translations")
def get_locale():
# try to guess the language from the user accept
# The best match wins.
return request.accept_languages.best_match(AVAILABLE_LANGUAGES) or "en"
def get_catalog():
path = "../builds/default/v3/apps.json"
mtime = os.path.getmtime(path)
if get_catalog.mtime_catalog != mtime:
get_catalog.mtime_catalog = mtime
catalog = json.load(open(path))
catalog["categories"] = {c["id"]: c for c in catalog["categories"]}
catalog["antifeatures"] = {c["id"]: c for c in catalog["antifeatures"]}
category_color = {
"synchronization": "sky",
"publishing": "yellow",
"communication": "amber",
"office": "lime",
"productivity_and_management": "purple",
"small_utilities": "black",
"reading": "emerald",
"multimedia": "fuchsia",
"social_media": "rose",
"games": "violet",
"dev": "stone",
"system_tools": "black",
"iot": "orange",
"wat": "teal",
}
for id_, category in catalog["categories"].items():
category["color"] = category_color[id_]
get_catalog.cache_catalog = catalog
return get_catalog.cache_catalog
get_catalog.mtime_catalog = None
get_catalog()
def get_wishlist():
path = "../wishlist.toml"
mtime = os.path.getmtime(path)
if get_wishlist.mtime_wishlist != mtime:
get_wishlist.mtime_wishlist = mtime
get_wishlist.cache_wishlist = toml.load(open(path))
return get_wishlist.cache_wishlist
get_wishlist.mtime_wishlist = None
get_wishlist()
def get_stars():
checksum = (
subprocess.check_output("find . -type f -printf '%T@,' | md5sum", shell=True)
.decode()
.split()[0]
)
if get_stars.cache_checksum != checksum:
stars = {}
for folder, _, files in os.walk(".stars/"):
app_id = folder.split("/")[-1]
if not app_id:
continue
stars[app_id] = set(files)
get_stars.cache_stars = stars
get_stars.cache_checksum = checksum
return get_stars.cache_stars
get_stars.cache_checksum = None
get_stars()
def check_wishlist_submit_ratelimit(user):
dir_ = os.path.join(".wishlist_ratelimit")
if not os.path.exists(dir_):
os.mkdir(dir_)
f = os.path.join(dir_, md5(user.encode()).hexdigest())
return not os.path.exists(f) or (time.time() - os.path.getmtime(f)) > (15 * 24 * 3600) # 15 days
def save_wishlist_submit_for_ratelimit(user):
dir_ = os.path.join(".wishlist_ratelimit")
if not os.path.exists(dir_):
os.mkdir(dir_)
f = os.path.join(dir_, md5(user.encode()).hexdigest())
open(f, "w").write("")
def human_to_binary(size: str) -> int:
symbols = ("K", "M", "G", "T", "P", "E", "Z", "Y")
factor = {}
for i, s in enumerate(symbols):
factor[s] = 1 << (i + 1) * 10
suffix = size[-1]
size = size[:-1]
if suffix not in symbols:
raise Exception(f"Invalid size suffix '{suffix}', expected one of {symbols}")
try:
size_ = float(size)
except Exception:
raise Exception(f"Failed to convert size {size} to float")
return int(size_ * factor[suffix])
def get_app_md_and_screenshots(app_folder, infos):
locale = get_locale()
if locale != "en" and os.path.exists(
os.path.join(app_folder, "doc", f"DESCRIPTION_{locale}.md")
):
description_path = os.path.join(app_folder, "doc", f"DESCRIPTION_{locale}.md")
elif os.path.exists(os.path.join(app_folder, "doc", "DESCRIPTION.md")):
description_path = os.path.join(app_folder, "doc", "DESCRIPTION.md")
else:
description_path = None
if description_path:
with open(description_path) as f:
infos["full_description_html"] = emojize(
pycmarkgfm.gfm_to_html(f.read()), language="alias"
)
else:
infos["full_description_html"] = infos["manifest"]["description"][locale]
if locale != "en" and os.path.exists(
os.path.join(app_folder, "doc", f"PRE_INSTALL_{locale}.md")
):
pre_install_path = os.path.join(app_folder, "doc", f"PRE_INSTALL_{locale}.md")
elif os.path.exists(os.path.join(app_folder, "doc", "PRE_INSTALL.md")):
pre_install_path = os.path.join(app_folder, "doc", "PRE_INSTALL.md")
else:
pre_install_path = None
if pre_install_path:
with open(pre_install_path) as f:
infos["pre_install_html"] = emojize(
pycmarkgfm.gfm_to_html(f.read()), language="alias"
)
infos["screenshot"] = None
screenshots_folder = os.path.join(app_folder, "doc", "screenshots")
if os.path.exists(screenshots_folder):
with os.scandir(screenshots_folder) as it:
for entry in it:
ext = os.path.splitext(entry.name)[1].replace(".", "").lower()
if entry.is_file() and ext in ("png", "jpg", "jpeg", "webp", "gif"):
with open(entry.path, "rb") as img_file:
data = base64.b64encode(img_file.read()).decode("utf-8")
infos[
"screenshot"
] = f"data:image/{ext};charset=utf-8;base64,{data}"
break
ram_build_requirement = infos["manifest"]["integration"]["ram"]["build"]
infos["manifest"]["integration"]["ram"]["build_binary"] = human_to_binary(
ram_build_requirement
)