forked from rDrama/rDrama
marseys: cache marseys and emojis and fun stuff (#15)
Co-authored-by: justcool393 <justcool393@gmail.com> Reviewed-on: rDrama/rDrama#15 Co-authored-by: justcool393 <justcool393@noreply.fsdfsd.net> Co-committed-by: justcool393 <justcool393@noreply.fsdfsd.net>master
parent
77bdb6e87f
commit
767cc467bb
|
@ -33,7 +33,7 @@ export function useEmojis() {
|
||||||
|
|
||||||
// Retrieve the list.
|
// Retrieve the list.
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetch("/marsey_list.json")
|
fetch("/emojis")
|
||||||
.then((res) => res.json())
|
.then((res) => res.json())
|
||||||
.then(setEmojis)
|
.then(setEmojis)
|
||||||
.catch(setError);
|
.catch(setError);
|
||||||
|
|
|
@ -187,10 +187,9 @@ const emojisSearchDictionary = {
|
||||||
|
|
||||||
// get public emojis list
|
// get public emojis list
|
||||||
const emojiRequest = new XMLHttpRequest();
|
const emojiRequest = new XMLHttpRequest();
|
||||||
emojiRequest.open("GET", '/marsey_list.json');
|
emojiRequest.open("GET", '/emojis');
|
||||||
emojiRequest.setRequestHeader('xhr', 'xhr');
|
emojiRequest.setRequestHeader('xhr', 'xhr');
|
||||||
emojiRequest.onload = async (e) => {
|
emojiRequest.onload = async (e) => {
|
||||||
console.log("HERE")
|
|
||||||
let emojis = JSON.parse(emojiRequest.response);
|
let emojis = JSON.parse(emojiRequest.response);
|
||||||
if(! (emojis instanceof Array ))
|
if(! (emojis instanceof Array ))
|
||||||
throw new TypeError("[EMOJI DIALOG] rDrama's server should have sent a JSON-coded Array!");
|
throw new TypeError("[EMOJI DIALOG] rDrama's server should have sent a JSON-coded Array!");
|
||||||
|
|
|
@ -7,15 +7,24 @@ function sort_table(n) {
|
||||||
for (let i = 1; i < rows.length; i++) {
|
for (let i = 1; i < rows.length; i++) {
|
||||||
const ele = rows[i];
|
const ele = rows[i];
|
||||||
let x = rows[i].getElementsByTagName("TD")[n];
|
let x = rows[i].getElementsByTagName("TD")[n];
|
||||||
x = x.getElementsByTagName('a')[0] || x;
|
if (!('sortKey' in x.dataset)) {
|
||||||
const attr = x.dataset.time ? parseInt(x.dataset.time) : parseInt(x.innerHTML.replace(/,/g, ''));
|
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 });
|
items.push({ ele, attr });
|
||||||
}
|
}
|
||||||
if (sortAscending[n]) {
|
if (sortAscending[n]) {
|
||||||
items.sort((a, b) => a.attr - b.attr);
|
items.sort((a, b) => a.attr > b.attr);
|
||||||
sortAscending[n] = false;
|
sortAscending[n] = false;
|
||||||
} else {
|
} else {
|
||||||
items.sort((a, b) => b.attr - a.attr);
|
items.sort((a, b) => a.attr < b.attr);
|
||||||
sortAscending[n] = true;
|
sortAscending[n] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,3 +21,17 @@ class Marsey(Base):
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"<Marsey(name={self.name})>"
|
return f"<Marsey(name={self.name})>"
|
||||||
|
|
||||||
|
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",
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
if IS_LOCALHOST: SITE_FULL = 'http://' + SITE
|
||||||
else: SITE_FULL = 'https://' + 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"
|
if SITE_NAME == 'PCM': CC = "SPLASH MOUNTAIN"
|
||||||
else: CC = "COUNTRY CLUB"
|
else: CC = "COUNTRY CLUB"
|
||||||
|
@ -284,6 +287,7 @@ PERMS = { # Minimum admin_level to perform action.
|
||||||
}
|
}
|
||||||
|
|
||||||
FEATURES = {
|
FEATURES = {
|
||||||
|
'MARSEYS': True,
|
||||||
'MARSEYBUX': True,
|
'MARSEYBUX': True,
|
||||||
'AWARDS': True,
|
'AWARDS': True,
|
||||||
'CHAT': True,
|
'CHAT': True,
|
||||||
|
@ -373,7 +377,6 @@ ERROR_MARSEYS = {
|
||||||
500: "marseycarp3",
|
500: "marseycarp3",
|
||||||
}
|
}
|
||||||
|
|
||||||
EMOJI_MARSEYS = True
|
|
||||||
EMOJI_SRCS = ['files/assets/emojis.json']
|
EMOJI_SRCS = ['files/assets/emojis.json']
|
||||||
|
|
||||||
PIN_LIMIT = 3
|
PIN_LIMIT = 3
|
||||||
|
|
|
@ -95,6 +95,21 @@ def get_account(id:Union[str, int], v:Optional[User]=None, graceful=False, inclu
|
||||||
return user
|
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]:
|
def get_post(i:Union[str, int], v:Optional[User]=None, graceful=False) -> Optional[Submission]:
|
||||||
try: i = int(i)
|
try: i = int(i)
|
||||||
except:
|
except:
|
||||||
|
|
|
@ -40,12 +40,11 @@ def offsite_mentions_task(cache:Cache):
|
||||||
notify_mentions([send_user], user_mentions, mention_str='mention of you')
|
notify_mentions([send_user], user_mentions, mention_str='mention of you')
|
||||||
|
|
||||||
def get_mentions(cache:Cache, queries:Iterable[str], reddit_notifs_users=False):
|
def get_mentions(cache:Cache, queries:Iterable[str], reddit_notifs_users=False):
|
||||||
CACHE_KEY = 'reddit_notifications'
|
|
||||||
kinds = ['submission', 'comment']
|
kinds = ['submission', 'comment']
|
||||||
mentions = []
|
mentions = []
|
||||||
exclude_subreddits = ['PokemonGoRaids', 'SubSimulatorGPT2', 'SubSimGPT2Interactive']
|
exclude_subreddits = ['PokemonGoRaids', 'SubSimulatorGPT2', 'SubSimGPT2Interactive']
|
||||||
try:
|
try:
|
||||||
after = int(cache.get(CACHE_KEY) or time.time())
|
after = int(cache.get(const.REDDIT_NOTIFS_CACHE_KEY) or time.time())
|
||||||
except:
|
except:
|
||||||
print("Failed to retrieve last mention time from cache")
|
print("Failed to retrieve last mention time from cache")
|
||||||
after = time.time()
|
after = time.time()
|
||||||
|
|
|
@ -9,7 +9,6 @@ from files.helpers.const import *
|
||||||
from files.helpers.get import *
|
from files.helpers.get import *
|
||||||
from files.helpers.media import *
|
from files.helpers.media import *
|
||||||
from files.helpers.useractions import *
|
from files.helpers.useractions import *
|
||||||
from files.routes.static import marsey_list
|
|
||||||
from files.routes.wrappers import *
|
from files.routes.wrappers import *
|
||||||
from files.__main__ import app, cache, limiter
|
from files.__main__ import app, cache, limiter
|
||||||
|
|
||||||
|
@ -145,7 +144,8 @@ def approve_marsey(v, name):
|
||||||
else:
|
else:
|
||||||
badge_grant(badge_id=17, user=author)
|
badge_grant(badge_id=17, user=author)
|
||||||
purge_files_in_cache(f"https://{SITE}/e/{marsey.name}/webp")
|
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")
|
move(f"/asset_submissions/marseys/{name}.webp", f"files/assets/images/emojis/{marsey.name}.webp")
|
||||||
|
|
||||||
highquality = f"/asset_submissions/marseys/{name}"
|
highquality = f"/asset_submissions/marseys/{name}"
|
||||||
|
|
|
@ -26,51 +26,38 @@ def rdrama(id, title):
|
||||||
@app.get("/marseys")
|
@app.get("/marseys")
|
||||||
@auth_required
|
@auth_required
|
||||||
def marseys(v:User):
|
def marseys(v:User):
|
||||||
if SITE == 'rdrama.net':
|
marseys = get_marseys(g.db)
|
||||||
marseys = g.db.query(Marsey, User).join(User, Marsey.author_id == User.id).filter(Marsey.submitter_id==None)
|
authors = get_accounts_dict([m.author_id for m in marseys], graceful=True, include_shadowbanned=False)
|
||||||
sort = request.values.get("sort", "usage")
|
original = os.listdir("/asset_submissions/marseys/original")
|
||||||
if sort == "usage":
|
for marsey in marseys:
|
||||||
marseys = marseys.order_by(Marsey.count.desc(), User.username).all()
|
marsey.user = authors.get(marsey.author_id)
|
||||||
elif sort == "added":
|
for x in IMAGE_FORMATS:
|
||||||
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:
|
|
||||||
if f'{marsey.name}.{x}' in original:
|
if f'{marsey.name}.{x}' in original:
|
||||||
marsey.og = f'{marsey.name}.{x}'
|
marsey.og = f'{marsey.name}.{x}'
|
||||||
break
|
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)
|
return render_template("marseys.html", v=v, marseys=marseys)
|
||||||
|
|
||||||
@app.get("/marsey_list.json")
|
@app.get("/emojis")
|
||||||
@cache.memoize(timeout=600)
|
def emoji_list():
|
||||||
def marsey_list():
|
return jsonify(get_emojis(g.db))
|
||||||
emojis = []
|
|
||||||
|
|
||||||
# From database
|
@cache.cached(timeout=86400, key_prefix=MARSEYS_CACHE_KEY)
|
||||||
if EMOJI_MARSEYS:
|
def get_marseys(db:scoped_session):
|
||||||
emojis = [{
|
if not FEATURES['MARSEYS']: return []
|
||||||
"name": emoji.name,
|
marseys = []
|
||||||
"author": author if SITE == 'rdrama.net' or author == "anton-d" else None,
|
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()):
|
||||||
# yikes, I don't really like this DB schema. Next time be better
|
marsey.author = author.username if FEATURES['ASSET_SUBMISSIONS'] or author == "anton-d" else None
|
||||||
"tags": emoji.tags.split(" ") + [emoji.name[len("marsey"):] \
|
setattr(marsey, "class", "Marsey")
|
||||||
if emoji.name.startswith("marsey") else emoji.name],
|
marseys.append(marsey)
|
||||||
"count": emoji.count,
|
return marseys
|
||||||
"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())]
|
|
||||||
|
|
||||||
# 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:
|
for src in EMOJI_SRCS:
|
||||||
with open(src, "r", encoding="utf-8") as f:
|
with open(src, "r", encoding="utf-8") as f:
|
||||||
emojis = emojis + json.load(f)
|
emojis = emojis + json.load(f)
|
||||||
|
return emojis
|
||||||
return jsonify(emojis)
|
|
||||||
|
|
||||||
@app.get('/sidebar')
|
@app.get('/sidebar')
|
||||||
@auth_desired
|
@auth_desired
|
||||||
|
|
|
@ -18,6 +18,10 @@ def session_init():
|
||||||
session["session_id"] = secrets.token_hex(49)
|
session["session_id"] = secrets.token_hex(49)
|
||||||
|
|
||||||
def calc_users(v):
|
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 {}
|
loggedin = cache.get(f'{SITE}_loggedin') or {}
|
||||||
loggedout = cache.get(f'{SITE}_loggedout') or {}
|
loggedout = cache.get(f'{SITE}_loggedout') or {}
|
||||||
timestamp = int(time.time())
|
timestamp = int(time.time())
|
||||||
|
@ -57,15 +61,14 @@ def get_logged_in_user():
|
||||||
id = int(lo_user)
|
id = int(lo_user)
|
||||||
v = get_account(id, graceful=True)
|
v = get_account(id, graceful=True)
|
||||||
if not v:
|
if not v:
|
||||||
session.clear()
|
session.pop("lo_user")
|
||||||
return None
|
|
||||||
else:
|
else:
|
||||||
nonce = session.get("login_nonce", 0)
|
nonce = session.get("login_nonce", 0)
|
||||||
if nonce < v.login_nonce or v.id != id:
|
if nonce < v.login_nonce or v.id != id:
|
||||||
session.clear()
|
session.pop("lo_user")
|
||||||
return None
|
v = None
|
||||||
|
|
||||||
if request.method != "GET":
|
if v and request.method != "GET":
|
||||||
submitted_key = request.values.get("formkey")
|
submitted_key = request.values.get("formkey")
|
||||||
if not validate_formkey(v, submitted_key): abort(401)
|
if not validate_formkey(v, submitted_key): abort(401)
|
||||||
|
|
||||||
|
|
|
@ -5,46 +5,41 @@
|
||||||
<div class="overflow-x-auto mt-3"><table class="table table-striped mb-5">
|
<div class="overflow-x-auto mt-3"><table class="table table-striped mb-5">
|
||||||
<thead class="bg-primary text-white">
|
<thead class="bg-primary text-white">
|
||||||
<tr>
|
<tr>
|
||||||
<th>#</th>
|
<th onclick="sort_table(0)">#</th>
|
||||||
<th>Name</th>
|
<th onclick="sort_table(1)">Name</th>
|
||||||
<th>Marsey</th>
|
<th>Marsey</th>
|
||||||
<th>Usage</th>
|
<th onclick="sort_table(3)">Usage</th>
|
||||||
{% if SITE == 'rdrama.net' %}
|
{% if FEATURES['ASSET_SUBMISSIONS'] %}
|
||||||
<th><a href="?sort=author">Author</a></th>
|
<th onclick="sort_table(4)">Author</th>
|
||||||
<th><a href="?sort=added">Added on</a></th>
|
{% endif %}
|
||||||
|
<th onclick="sort_table(5)">Added on</th>
|
||||||
|
{% if FEATURES['ASSET_SUBMISSIONS'] %}
|
||||||
<th>Original File</th>
|
<th>Original File</th>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody id="marseys-table">
|
<tbody id="marseys-table">
|
||||||
{% if SITE == 'rdrama.net' %}
|
{% for marsey in marseys %}
|
||||||
{% for marsey, user in marseys %}
|
<tr>
|
||||||
<tr>
|
<td>{{loop.index}}</td>
|
||||||
<td>{{loop.index}}</td>
|
<td data-sort-key="{{marsey.name}}">{{marsey.name}}</td>
|
||||||
<td>{{marsey.name}}</td>
|
<td><img class="marsey" loading="lazy" data-bs-toggle="tooltip" alt=":#{{marsey.name}}:" title=":{{marsey.name}}:" src="/e/{{marsey.name}}.webp"></td>
|
||||||
<td><img class="marsey" loading="lazy" data-bs-toggle="tooltip" alt=":#{{marsey.name}}:" title=":{{marsey.name}}:" src="/e/{{marsey.name}}.webp"></td>
|
<td>{{marsey.count}}</td>
|
||||||
<td>{{marsey.count}}</td>
|
{% if FEATURES['ASSET_SUBMISSIONS'] %}
|
||||||
<td>{% include "user_in_table.html" %}</td>
|
{% set user = marsey.user %}
|
||||||
<td {% if marsey.created_utc != None %}data-time="{{marsey.created_utc}}"{% endif %}></td>
|
<td data-sort-key="{{user.username}}">{% include "user_in_table.html" %}</td>
|
||||||
<td>
|
{% endif %}
|
||||||
{% if marsey.og %}
|
<td data-sort-key="{{marsey.created_utc or 0}}" {% if marsey.created_utc != None %}data-time="{{marsey.created_utc}}"{% endif %}></td>
|
||||||
<a href="/asset_submissions/marseys/original/{{marsey.og}}">{{marsey.og}}</a>
|
{% if FEATURES['ASSET_SUBMISSIONS'] %}
|
||||||
{% endif %}
|
<td>
|
||||||
</td>
|
{% if marsey.og %}
|
||||||
</tr>
|
<a href="/asset_submissions/marseys/original/{{marsey.og}}">{{marsey.og}}</a>
|
||||||
{% endfor %}
|
{% endif %}
|
||||||
{% else %}
|
</td>
|
||||||
{% for marsey in marseys %}
|
{% endif %}
|
||||||
<tr>
|
</tr>
|
||||||
<td>{{loop.index}}</td>
|
{% endfor %}
|
||||||
<td>{{marsey.name}}</td>
|
|
||||||
<td><img class="marsey" loading="lazy" data-bs-toggle="tooltip" alt=":#{{marsey.name}}:" title=":{{marsey.name}}:" src="/e/{{marsey.name}}.webp"></td>
|
|
||||||
<td>{{marsey.count}}</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
<script defer src="{{'js/sort_table.js' | asset}}"></script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
Loading…
Reference in New Issue