diff --git a/chat/src/hooks/useEmojis.ts b/chat/src/hooks/useEmojis.ts index d97c1500c..a3670cfec 100644 --- a/chat/src/hooks/useEmojis.ts +++ b/chat/src/hooks/useEmojis.ts @@ -33,7 +33,7 @@ export function useEmojis() { // Retrieve the list. useEffect(() => { - fetch("/marsey_list.json") + fetch("/emojis") .then((res) => res.json()) .then(setEmojis) .catch(setError); diff --git a/files/assets/js/emoji_modal.js b/files/assets/js/emoji_modal.js index aaeef18db..9daeb4b09 100644 --- a/files/assets/js/emoji_modal.js +++ b/files/assets/js/emoji_modal.js @@ -187,10 +187,9 @@ const emojisSearchDictionary = { // get public emojis list const emojiRequest = new XMLHttpRequest(); -emojiRequest.open("GET", '/marsey_list.json'); +emojiRequest.open("GET", '/emojis'); emojiRequest.setRequestHeader('xhr', 'xhr'); emojiRequest.onload = async (e) => { - console.log("HERE") let emojis = JSON.parse(emojiRequest.response); if(! (emojis instanceof Array )) throw new TypeError("[EMOJI DIALOG] rDrama's server should have sent a JSON-coded Array!"); diff --git a/files/assets/js/sort_table.js b/files/assets/js/sort_table.js index 60c5b80d8..40c299142 100644 --- a/files/assets/js/sort_table.js +++ b/files/assets/js/sort_table.js @@ -7,15 +7,24 @@ function sort_table(n) { for (let i = 1; i < rows.length; i++) { const ele = rows[i]; let x = rows[i].getElementsByTagName("TD")[n]; - x = x.getElementsByTagName('a')[0] || x; - const attr = x.dataset.time ? parseInt(x.dataset.time) : parseInt(x.innerHTML.replace(/,/g, '')); + if (!('sortKey' in x.dataset)) { + x = x.getElementsByTagName('a')[0] || x; + } + var attr; + if ('sortKey' in x.dataset) { + attr = x.dataset.sortKey; + } else if ('time' in x.dataset) { + attr = parseInt(x.dataset.time); + } else { + attr = parseInt(x.innerHTML.replace(/,/g, '')); + } items.push({ ele, attr }); } if (sortAscending[n]) { - items.sort((a, b) => a.attr - b.attr); + items.sort((a, b) => a.attr > b.attr); sortAscending[n] = false; } else { - items.sort((a, b) => b.attr - a.attr); + items.sort((a, b) => a.attr < b.attr); sortAscending[n] = true; } diff --git a/files/classes/marsey.py b/files/classes/marsey.py index 76899e469..222ce0b13 100644 --- a/files/classes/marsey.py +++ b/files/classes/marsey.py @@ -21,3 +21,17 @@ class Marsey(Base): def __repr__(self): return f"" + + def tags_list(self): + return self.tags.split(" ") + [self.name[len("marsey"):]] # type: ignore + + def json(self): + return { + "name": self.name, + "author_id": self.author_id, + "submitter_id": self.submitter_id, + "tags": self.tags_list(), + "count": self.count, + "created_utc": self.created_utc, + "class": "Marsey", + } diff --git a/files/helpers/const.py b/files/helpers/const.py index 6437e5e0e..528366c52 100644 --- a/files/helpers/const.py +++ b/files/helpers/const.py @@ -63,6 +63,9 @@ IS_LOCALHOST = SITE == "localhost" or SITE == "127.0.0.1" or SITE.startswith("19 if IS_LOCALHOST: SITE_FULL = 'http://' + SITE else: SITE_FULL = 'https://' + SITE +REDDIT_NOTIFS_CACHE_KEY = "reddit_notifications" +MARSEYS_CACHE_KEY = "marseys" +EMOJIS_CACHE_KEY = "emojis" if SITE_NAME == 'PCM': CC = "SPLASH MOUNTAIN" else: CC = "COUNTRY CLUB" @@ -284,6 +287,7 @@ PERMS = { # Minimum admin_level to perform action. } FEATURES = { + 'MARSEYS': True, 'MARSEYBUX': True, 'AWARDS': True, 'CHAT': True, @@ -373,7 +377,6 @@ ERROR_MARSEYS = { 500: "marseycarp3", } -EMOJI_MARSEYS = True EMOJI_SRCS = ['files/assets/emojis.json'] PIN_LIMIT = 3 diff --git a/files/helpers/get.py b/files/helpers/get.py index a84bd5be4..85c4c2056 100644 --- a/files/helpers/get.py +++ b/files/helpers/get.py @@ -95,6 +95,21 @@ def get_account(id:Union[str, int], v:Optional[User]=None, graceful=False, inclu return user +def get_accounts_dict(ids:Union[Iterable[str], Iterable[int]], v:Optional[User]=None, graceful=False, include_shadowbanned=True) -> Optional[dict[int, User]]: + if not ids: return {} + try: + ids = set([int(id) for id in ids]) + except: + if graceful: return None + abort(404) + + users = g.db.query(User).filter(User.id.in_(ids)) + if not (include_shadowbanned or (v and v.can_see_shadowbanned)): + users = users.filter(User.shadowbanned == None) + users = users.all() + if len(users) != len(ids) and not graceful: abort(404) + return {u.id:u for u in users} + def get_post(i:Union[str, int], v:Optional[User]=None, graceful=False) -> Optional[Submission]: try: i = int(i) except: diff --git a/files/helpers/offsitementions.py b/files/helpers/offsitementions.py index 701ca6979..c5004b0bd 100644 --- a/files/helpers/offsitementions.py +++ b/files/helpers/offsitementions.py @@ -40,12 +40,11 @@ def offsite_mentions_task(cache:Cache): notify_mentions([send_user], user_mentions, mention_str='mention of you') def get_mentions(cache:Cache, queries:Iterable[str], reddit_notifs_users=False): - CACHE_KEY = 'reddit_notifications' kinds = ['submission', 'comment'] mentions = [] exclude_subreddits = ['PokemonGoRaids', 'SubSimulatorGPT2', 'SubSimGPT2Interactive'] try: - after = int(cache.get(CACHE_KEY) or time.time()) + after = int(cache.get(const.REDDIT_NOTIFS_CACHE_KEY) or time.time()) except: print("Failed to retrieve last mention time from cache") after = time.time() diff --git a/files/routes/asset_submissions.py b/files/routes/asset_submissions.py index ef3506564..fa339620c 100644 --- a/files/routes/asset_submissions.py +++ b/files/routes/asset_submissions.py @@ -9,7 +9,6 @@ from files.helpers.const import * from files.helpers.get import * from files.helpers.media import * from files.helpers.useractions import * -from files.routes.static import marsey_list from files.routes.wrappers import * from files.__main__ import app, cache, limiter @@ -145,7 +144,8 @@ def approve_marsey(v, name): else: badge_grant(badge_id=17, user=author) purge_files_in_cache(f"https://{SITE}/e/{marsey.name}/webp") - cache.delete_memoized(marsey_list) + cache.delete(EMOJIS_CACHE_KEY) + cache.delete(MARSEYS_CACHE_KEY) move(f"/asset_submissions/marseys/{name}.webp", f"files/assets/images/emojis/{marsey.name}.webp") highquality = f"/asset_submissions/marseys/{name}" diff --git a/files/routes/static.py b/files/routes/static.py index a5db159bd..dde4590f6 100644 --- a/files/routes/static.py +++ b/files/routes/static.py @@ -26,51 +26,38 @@ def rdrama(id, title): @app.get("/marseys") @auth_required def marseys(v:User): - if SITE == 'rdrama.net': - marseys = g.db.query(Marsey, User).join(User, Marsey.author_id == User.id).filter(Marsey.submitter_id==None) - sort = request.values.get("sort", "usage") - if sort == "usage": - marseys = marseys.order_by(Marsey.count.desc(), User.username).all() - elif sort == "added": - marseys = marseys.order_by(nullslast(Marsey.created_utc.desc()), User.username).all() - else: # implied sort == "author" - marseys = marseys.order_by(User.username, Marsey.count.desc()).all() - - original = os.listdir("/asset_submissions/marseys/original") - for marsey, user in marseys: - for x in IMAGE_FORMATS: + marseys = get_marseys(g.db) + authors = get_accounts_dict([m.author_id for m in marseys], graceful=True, include_shadowbanned=False) + original = os.listdir("/asset_submissions/marseys/original") + for marsey in marseys: + marsey.user = authors.get(marsey.author_id) + for x in IMAGE_FORMATS: if f'{marsey.name}.{x}' in original: marsey.og = f'{marsey.name}.{x}' break - else: - marseys = g.db.query(Marsey).filter(Marsey.submitter_id==None).order_by(Marsey.count.desc()) - return render_template("marseys.html", v=v, marseys=marseys) -@app.get("/marsey_list.json") -@cache.memoize(timeout=600) -def marsey_list(): - emojis = [] +@app.get("/emojis") +def emoji_list(): + return jsonify(get_emojis(g.db)) - # From database - if EMOJI_MARSEYS: - emojis = [{ - "name": emoji.name, - "author": author if SITE == 'rdrama.net' or author == "anton-d" else None, - # yikes, I don't really like this DB schema. Next time be better - "tags": emoji.tags.split(" ") + [emoji.name[len("marsey"):] \ - if emoji.name.startswith("marsey") else emoji.name], - "count": emoji.count, - "class": "Marsey" - } for emoji, author in g.db.query(Marsey, User.username).join(User, Marsey.author_id == User.id).filter(Marsey.submitter_id==None) \ - .order_by(Marsey.count.desc())] +@cache.cached(timeout=86400, key_prefix=MARSEYS_CACHE_KEY) +def get_marseys(db:scoped_session): + if not FEATURES['MARSEYS']: return [] + marseys = [] + for marsey, author in db.query(Marsey, User).join(User, Marsey.author_id == User.id).filter(Marsey.submitter_id == None).order_by(Marsey.count.desc()): + marsey.author = author.username if FEATURES['ASSET_SUBMISSIONS'] or author == "anton-d" else None + setattr(marsey, "class", "Marsey") + marseys.append(marsey) + return marseys - # Static shit +@cache.cached(timeout=600, key_prefix=EMOJIS_CACHE_KEY) +def get_emojis(db:scoped_session): + emojis = [m.json() for m in get_marseys(db)] for src in EMOJI_SRCS: with open(src, "r", encoding="utf-8") as f: emojis = emojis + json.load(f) - - return jsonify(emojis) + return emojis @app.get('/sidebar') @auth_desired diff --git a/files/routes/wrappers.py b/files/routes/wrappers.py index 7a979058e..8fc202c00 100644 --- a/files/routes/wrappers.py +++ b/files/routes/wrappers.py @@ -18,6 +18,10 @@ def session_init(): session["session_id"] = secrets.token_hex(49) def calc_users(v): + if g.is_api_or_xhr: + g.loggedin_counter = 0 + g.loggedout_counter = 0 + return '' loggedin = cache.get(f'{SITE}_loggedin') or {} loggedout = cache.get(f'{SITE}_loggedout') or {} timestamp = int(time.time()) @@ -57,15 +61,14 @@ def get_logged_in_user(): id = int(lo_user) v = get_account(id, graceful=True) if not v: - session.clear() - return None + session.pop("lo_user") else: nonce = session.get("login_nonce", 0) if nonce < v.login_nonce or v.id != id: - session.clear() - return None + session.pop("lo_user") + v = None - if request.method != "GET": + if v and request.method != "GET": submitted_key = request.values.get("formkey") if not validate_formkey(v, submitted_key): abort(401) diff --git a/files/templates/marseys.html b/files/templates/marseys.html index 9d76c2852..e650daa6b 100644 --- a/files/templates/marseys.html +++ b/files/templates/marseys.html @@ -5,46 +5,41 @@
- - + + - - {% if SITE == 'rdrama.net' %} - - + + {% if FEATURES['ASSET_SUBMISSIONS'] %} + + {% endif %} + + {% if FEATURES['ASSET_SUBMISSIONS'] %} {% endif %} -{% if SITE == 'rdrama.net' %} - {% for marsey, user in marseys %} - - - - - - - - - - {% endfor %} -{% else %} - {% for marsey in marseys %} - - - - - - - {% endfor %} -{% endif %} - +{% for marsey in marseys %} + + + + + + {% if FEATURES['ASSET_SUBMISSIONS'] %} + {% set user = marsey.user %} + + {% endif %} + + {% if FEATURES['ASSET_SUBMISSIONS'] %} + + {% endif %} + +{% endfor %}
#Name#Name MarseyUsageAuthorAdded onUsageAuthorAdded onOriginal File
{{loop.index}}{{marsey.name}}:#{{marsey.name}}:{{marsey.count}}{% include "user_in_table.html" %} - {% if marsey.og %} - {{marsey.og}} - {% endif %} -
{{loop.index}}{{marsey.name}}:#{{marsey.name}}:{{marsey.count}}
{{loop.index}}{{marsey.name}}:#{{marsey.name}}:{{marsey.count}}{% include "user_in_table.html" %} + {% if marsey.og %} + {{marsey.og}} + {% endif %} +
- + {% endblock %}