add Marsey Submission UI

remotes/1693045480750635534/spooky-22
Aevann1 2022-09-09 11:13:50 +02:00
parent d75fcc4bdc
commit 47890d771d
20 changed files with 361 additions and 134 deletions

View File

@ -38,7 +38,7 @@
border-color: var(--primary) !important;
}
.form-control:disabled, .form-control[readonly] {
.form-control:disabled, [readonly] {
background: transparent;
border-color: var(--primary) !important;
}

View File

@ -39,7 +39,7 @@
border-color: var(--primary) !important;
}
.form-control:disabled, .form-control[readonly] {
.form-control:disabled, [readonly] {
background: transparent;
border-color: var(--primary) !important;
}

View File

@ -487,7 +487,7 @@ pre code {
color: #6c757d;
opacity: 1;
}
.form-control:disabled, .form-control[readonly] {
.form-control:disabled, [readonly] {
background-color: #e9ecef;
opacity: 1;
}
@ -2965,7 +2965,7 @@ label.color-radio span {
background-color: var(--gray-900);
color: var(--black);
}
.form-inline.search .form-control, .form-control[readonly] {
.form-inline.search .form-control, [readonly] {
background-color: var(--gray-800);
font-size: 1rem;
color: var(--white);
@ -2998,8 +2998,8 @@ label.color-radio span {
background: #dee2e6;
transition: none;
}
.form-control:disabled, .form-control[readonly] {
background-color: var(--dark);
.form-control:disabled, [readonly] {
background-color: var(--dark) !important;
}
.form-control:hover {
color: var(--black);

View File

@ -38,7 +38,7 @@
border-color: var(--primary) !important;
}
.form-control:disabled, .form-control[readonly] {
.form-control:disabled, [readonly] {
border-color: var(--primary) !important;
}

View File

@ -215,7 +215,7 @@
border: 1px solid var(--primary) !important;
}
#frontpage .pseudo-submit-form.card, .form-inline.search .form-control, .form-control[readonly] {
#frontpage .pseudo-submit-form.card, .form-inline.search .form-control, [readonly] {
border: 2px solid var(--gray-200) !important;
}

View File

@ -102,7 +102,7 @@ blockquote {
background-color: var(--white) !important;
}
.form-control, .form-control:disabled, .form-control[readonly] {
.form-control, .form-control:disabled, [readonly] {
background: white !important;
color: black !important
}

View File

@ -240,6 +240,63 @@ function post_toast(t, url, button1, button2, classname, extra_actions) {
}
function post_toast_callback(url, data, callback) {
const xhr = new XMLHttpRequest();
xhr.open("POST", url);
xhr.setRequestHeader('xhr', 'xhr');
const form = new FormData()
form.append("formkey", formkey());
if(typeof data === 'object' && data !== null) {
for(let k of Object.keys(data)) {
form.append(k, data[k]);
}
}
form.append("formkey", formkey());
xhr.onload = function() {
let result = callback(xhr);
if (xhr.status >= 200 && xhr.status < 300) {
var myToast = bootstrap.Toast.getOrCreateInstance(document.getElementById('toast-post-error'));
myToast.hide();
var myToast = bootstrap.Toast.getOrCreateInstance(document.getElementById('toast-post-success'));
myToast.show();
try {
if(typeof result == "string") {
document.getElementById('toast-post-success-text').innerText = result;
} else {
document.getElementById('toast-post-success-text').innerText = JSON.parse(xhr.response)["message"];
}
} catch(e) {
}
return true;
} else {
var myToast = bootstrap.Toast.getOrCreateInstance(document.getElementById('toast-post-success'));
myToast.hide();
var myToast = bootstrap.Toast.getOrCreateInstance(document.getElementById('toast-post-error'));
myToast.show();
try {
if(typeof result == "string") {
document.getElementById('toast-post-error-text').innerText = result;
} else {
document.getElementById('toast-post-error-text').innerText = JSON.parse(xhr.response)["error"];
}
return false
} catch(e) {console.log(e)}
return false;
}
};
xhr.send(form);
}
function escapeHTML(unsafe) {
return unsafe.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;");
}

View File

@ -1,60 +1,3 @@
function post_toast_callback(url, data, callback) {
const xhr = new XMLHttpRequest();
xhr.open("POST", url);
xhr.setRequestHeader('xhr', 'xhr');
const form = new FormData()
form.append("formkey", formkey());
if(typeof data === 'object' && data !== null) {
for(let k of Object.keys(data)) {
form.append(k, data[k]);
}
}
form.append("formkey", formkey());
xhr.onload = function() {
let result = callback(xhr);
if (xhr.status >= 200 && xhr.status < 300) {
var myToast = bootstrap.Toast.getOrCreateInstance(document.getElementById('toast-post-error'));
myToast.hide();
var myToast = bootstrap.Toast.getOrCreateInstance(document.getElementById('toast-post-success'));
myToast.show();
try {
if(typeof result == "string") {
document.getElementById('toast-post-success-text').innerText = result;
} else {
document.getElementById('toast-post-success-text').innerText = JSON.parse(xhr.response)["message"];
}
} catch(e) {
}
return true;
} else {
var myToast = bootstrap.Toast.getOrCreateInstance(document.getElementById('toast-post-success'));
myToast.hide();
var myToast = bootstrap.Toast.getOrCreateInstance(document.getElementById('toast-post-error'));
myToast.show();
try {
if(typeof result == "string") {
document.getElementById('toast-post-error-text').innerText = result;
} else {
document.getElementById('toast-post-error-text').innerText = JSON.parse(xhr.response)["error"];
}
return false
} catch(e) {console.log(e)}
return false;
}
};
xhr.send(form);
}
function toggleElement(id, id2) {
for(let el of document.getElementsByClassName('toggleable')) {
if(el.id != id) {

View File

@ -14,7 +14,6 @@ from .subscriptions import *
from files.__main__ import app
from .mod_logs import *
from .award import *
from .marsey import *
from .sub_block import *
from .sub_subscription import *
from .sub_join import *
@ -25,3 +24,4 @@ from .follows import *
from .lottery import *
from .casino_game import *
from .hats import *
from .marsey import *

View File

@ -1,4 +1,5 @@
from sqlalchemy import *
from sqlalchemy.orm import relationship
from files.__main__ import Base
class Marsey(Base):
@ -8,6 +9,7 @@ class Marsey(Base):
author_id = Column(Integer, ForeignKey("users.id"))
tags = Column(String)
count = Column(Integer, default=0)
submitter_id = Column(Integer, ForeignKey("users.id"))
def __repr__(self):
return f"<Marsey(name={self.name})>"

View File

@ -212,7 +212,6 @@ SIDEBAR_THREAD = 0
BANNER_THREAD = 0
BADGE_THREAD = 0
SNAPPY_THREAD = 0
MARSEY_THREAD = 0
HAT_THREAD = 0
if SITE == 'rdrama.net':
@ -223,7 +222,6 @@ if SITE == 'rdrama.net':
BANNER_THREAD = 37697
BADGE_THREAD = 37833
SNAPPY_THREAD = 37749
MARSEY_THREAD = 37838
HAT_THREAD = 100210
HOLE_COST = 50000
@ -313,7 +311,6 @@ elif SITE == 'watchpeopledie.co':
SNAKES_ID = 32
SIDEBAR_THREAD = 5403
MARSEY_THREAD = 5743
else: # localhost or testing environment implied
FEATURES['PRONOUNS'] = True
FEATURES['HOUSES'] = True
@ -920,10 +917,10 @@ christian_emojis = [':#marseyjesus:',':#marseyimmaculate:',':#marseymothermary:'
':#marseyorthodoxsmug:',':#marseypastor:',':#marseypope:',]
db = db_session()
marseys_const = [x[0] for x in db.query(Marsey.name).filter(Marsey.name!='chudsey').all()]
marseys_const = [x[0] for x in db.query(Marsey.name).filter(Marsey.submitter_id==None, Marsey.name!='chudsey').all()]
marseys_const2 = marseys_const + ['chudsey','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','0','1','2','3','4','5','6','7','8','9','exclamationpoint','period','questionmark']
marseys = db.query(Marsey).all()
marseys = db.query(Marsey).filter(Marsey.submitter_id==None).all()
marsey_mappings = {}
for marsey in marseys:
for tag in marsey.tags.split():
@ -944,7 +941,7 @@ if path.isfile(f'snappy_{SITE_NAME}.txt'):
YOUTUBE_KEY = environ.get("YOUTUBE_KEY", "").strip()
ADMIGGERS = {SIDEBAR_THREAD,BANNER_THREAD,BADGE_THREAD,SNAPPY_THREAD,MARSEY_THREAD,HAT_THREAD}
ADMIGGERS = {SIDEBAR_THREAD, BANNER_THREAD, BADGE_THREAD, SNAPPY_THREAD, HAT_THREAD}
proxies = {"http":"http://127.0.0.1:18080","https":"http://127.0.0.1:18080"}

View File

@ -327,7 +327,7 @@ def sanitize(sanitized, edit=False, limit_pings=0, showmore=True, marsified=Fals
sanitized = audio_sub_regex.sub(r'\1<audio controls preload="metadata" src="\2"></audio>', sanitized)
if not edit and not marsified:
for marsey in g.db.query(Marsey).filter(Marsey.name.in_(marseys_used)).all():
for marsey in g.db.query(Marsey).filter(Marsey.submitter_id==None, Marsey.name.in_(marseys_used)).all():
marsey.count += 1
g.db.add(marsey)
@ -416,7 +416,7 @@ def filter_emojis_only(title, edit=False, graceful=False, torture=False):
title = render_emoji(title, emoji_regex3, edit, marseys_used)
if not edit:
for marsey in g.db.query(Marsey).filter(Marsey.name.in_(marseys_used)).all():
for marsey in g.db.query(Marsey).filter(Marsey.submitter_id==None, Marsey.name.in_(marseys_used)).all():
marsey.count += 1
g.db.add(marsey)

View File

@ -100,7 +100,7 @@ def stats(site=None):
active_users = set(posters) | set(commenters) | set(voters) | set(commentvoters)
stats = {
"marseys": g.db.query(Marsey).count(),
"marseys": g.db.query(Marsey).filter(Marsey.submitter_id==None).count(),
"users": g.db.query(User).count(),
"private users": g.db.query(User).filter_by(is_private=True).count(),
"banned users": g.db.query(User).filter(User.is_banned > 0).count(),

View File

@ -10,7 +10,6 @@ from files.helpers.actions import *
from files.helpers.get import *
from files.classes import *
from files.routes.front import comment_idlist
from files.routes.static import marsey_list
from flask import *
from files.__main__ import app, limiter
from files.helpers.sanitize import filter_emojis_only
@ -232,44 +231,6 @@ def comment(v):
data=f'{{"files": ["https://{SITE}/assets/images/badges/{badge.id}.webp"]}}', timeout=5)
except Exception as e:
return {"error": str(e)}, 400
elif v.admin_level > 2 and parent_post.id == MARSEY_THREAD:
try:
marsey = loads(body.lower())
name = marsey["name"]
if not marsey_regex.fullmatch(name): return {"error": "Invalid name!"}, 400
existing = g.db.query(Marsey.name).filter_by(name=name).one_or_none()
if existing: return {"error": "A marsey with this name already exists!"}, 403
tags = marsey["tags"]
if not tags_regex.fullmatch(tags): return {"error": "Invalid tags!"}, 400
if "author" in marsey: user = get_user(marsey["author"])
elif "author_id" in marsey: user = get_account(marsey["author_id"])
else: abort(400)
filename = f'files/assets/images/emojis/{name}.webp'
copyfile(oldname, filename)
process_image(filename, 200)
marsey = Marsey(name=name, author_id=user.id, tags=tags, count=0)
g.db.add(marsey)
all_by_author = g.db.query(Marsey).filter_by(author_id=user.id).count()
# off-by-one: newly added marsey isn't counted
if all_by_author >= 99:
badge_grant(badge_id=143, user=user)
elif all_by_author >= 9:
badge_grant(badge_id=16, user=user)
else:
badge_grant(badge_id=17, user=user)
requests.post(f'https://api.cloudflare.com/client/v4/zones/{CF_ZONE}/purge_cache', headers=CF_HEADERS,
data=f'{{"files": ["https://{SITE}/e/{name}.webp"]}}', timeout=5)
cache.delete_memoized(marsey_list)
except Exception as e:
return {"error": str(e)}, 400
elif v.admin_level > 2 and parent_post.id == HAT_THREAD:
try:
hat = loads(body)

View File

@ -2,12 +2,14 @@ from files.mail import *
from files.__main__ import app, limiter, mail
from files.helpers.alerts import *
from files.helpers.const import *
from files.helpers.actions import *
from files.classes.award import AWARDS
from sqlalchemy import func
import os
from files.classes.mod_logs import ACTIONTYPES, ACTIONTYPES2
from files.classes.badges import BadgeDef
import files.helpers.stats as statshelper
from shutil import move
@app.get("/r/drama/comments/<id>/<title>")
@app.get("/r/Drama/comments/<id>/<title>")
@ -20,12 +22,13 @@ def rdrama(id, title):
@auth_required
def marseys(v):
if SITE == 'rdrama.net':
marseys = g.db.query(Marsey, User).join(User)
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)
else: marseys = marseys.order_by(User.username, Marsey.count.desc())
else:
marseys = g.db.query(Marsey).order_by(Marsey.count.desc())
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")
@ -43,7 +46,7 @@ def marsey_list():
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) \
} 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
@ -178,11 +181,12 @@ def api(v):
return render_template("api.html", v=v)
@app.get("/contact")
@app.get("/contactus")
@app.get("/contact_us")
@app.get("/press")
@app.get("/media")
@auth_required
def contact(v):
return render_template("contact.html", v=v)
@app.post("/send_admin")
@ -433,3 +437,107 @@ def categories_json():
data.update({sub: sub_cats})
return jsonify(data)
@app.get("/submit/marseys")
@auth_required
def submit_marseys(v):
if v.admin_level > 2:
marseys = g.db.query(Marsey).filter(Marsey.submitter_id != None).all()
else:
marseys = g.db.query(Marsey).filter(Marsey.submitter_id == v.id).all()
for marsey in marseys:
marsey.author = g.db.query(User.username).filter_by(id=marsey.author_id).one()[0]
marsey.submitter = g.db.query(User.username).filter_by(id=marsey.submitter_id).one()[0]
return render_template("submit_marseys.html", v=v, marseys=marseys)
@app.post("/submit/marsey")
@auth_required
def submit_marsey(v):
if request.headers.get("cf-ipcountry") == "T1":
return {"error":"Image uploads are not allowed through TOR."}
file = request.files["image"]
if not file: return {"error": "You need to submit an image!"}
name = request.values.get('name').lower()
if not marsey_regex.fullmatch(name):
return {"error": "Invalid name!"}
existing = g.db.query(Marsey.name).filter_by(name=name).one_or_none()
if existing:
return {"error": "A marsey with this name already exists!"}
tags = request.values.get('tags').lower()
if not tags_regex.fullmatch(tags):
return {"error": "Invalid tags!"}
author = request.values.get('author')
author = get_user(author)
filename = f'/asset_submissions/{name}.webp'
file.save(filename)
process_image(filename, 200)
marsey = Marsey(name=name, author_id=author.id, tags=tags, count=0, submitter_id=v.id)
g.db.add(marsey)
return redirect('/submit/marseys')
@app.post("/admin/approve/marsey/<name>")
@admin_level_required(3)
def approve_marsey(v, name):
marsey = g.db.query(Marsey).filter_by(name=name).one_or_none()
if not marsey: abort(404)
tags = request.values.get('tags')
if not tags: abort(400)
marsey.submitter_id = None
marsey.tags = tags
g.db.add(marsey)
move(f"/asset_submissions/{name}.webp", f"files/assets/images/emojis/{name}.webp")
author = get_account(marsey.author_id)
all_by_author = g.db.query(Marsey).filter_by(author_id=author.id).count()
if all_by_author >= 99:
badge_grant(badge_id=143, user=author)
elif all_by_author >= 9:
badge_grant(badge_id=16, user=author)
else:
badge_grant(badge_id=17, user=author)
requests.post(f'https://api.cloudflare.com/client/v4/zones/{CF_ZONE}/purge_cache', headers=CF_HEADERS,
data=f'{{"files": ["https://{SITE}/e/{name}.webp"]}}', timeout=5)
cache.delete_memoized(marsey_list)
return {"message": f"{name} approved!"}
@app.post("/admin/reject/marsey/<name>")
@admin_level_required(3)
def reject_marsey(v, name):
marsey = g.db.query(Marsey).filter_by(name=name).one_or_none()
if not marsey: abort(404)
g.db.delete(marsey)
os.remove(f"/asset_submissions/{name}.webp")
return {"message": f"{name} rejected!"}
@app.get('/asset_submissions/<image>')
@limiter.exempt
def asset_submissions(image):
if not image.endswith('.webp'): abort(404)
resp = make_response(send_from_directory('/asset_submissions', image))
resp.headers.remove("Cache-Control")
resp.headers.add("Cache-Control", "public, max-age=3153600")
resp.headers.remove("Content-Type")
resp.headers.add("Content-Type", "image/webp")
return resp

View File

@ -566,7 +566,7 @@ def leaderboard(v):
users11 = users11.limit(25).all()
if SITE_NAME == 'rDrama':
sq = g.db.query(Marsey.author_id, func.count(Marsey.author_id).label("count"), func.rank().over(order_by=func.count(Marsey.author_id).desc()).label("rank")).group_by(Marsey.author_id).subquery()
sq = g.db.query(Marsey.author_id, func.count(Marsey.author_id).label("count"), func.rank().over(order_by=func.count(Marsey.author_id).desc()).label("rank")).filter(Marsey.submitter_id==None).group_by(Marsey.author_id).subquery()
users12 = g.db.query(User, sq.c.count).join(sq, User.id==sq.c.author_id).order_by(sq.c.count.desc())
pos12 = g.db.query(User.id, sq.c.rank, sq.c.count).join(sq, User.id==sq.c.author_id).filter(User.id == v.id).one_or_none()
if pos12: pos12 = (pos12[1],pos12[2])

View File

@ -0,0 +1,152 @@
{% extends "default.html" %}
{% block title %}
<title>Submit Marseys</title>
{% endblock %}
{% block content %}
<div class="mx-4">
<h2 class="mt-5">Submit Marsey</h2>
<div class="settings-section rounded">
<div class="d-lg-flex">
<div class="body w-lg-100">
<form action="/submit/marsey" method="post" enctype="multipart/form-data">
<input type="hidden" name="formkey" value="{{v.formkey}}">
<div id="image-upload-block">
<div><label class="mt-3">Image</label></div>
<img loading="lazy" id="image-preview" style="max-width:50%">
<label class="btn btn-secondary m-0" for="file-upload">
<div id="filename-show">Select File</div>
<input autocomplete="off" id="file-upload" accept="image/*" type="file" name="image" {% if request.headers.get('cf-ipcountry')=="T1" %}disabled{% endif %} hidden>
</label>
</div>
<label class="mt-3" for="name">Name</label>
<input autocomplete="off" type="text" id="name" class="form-control" name="name" maxlength="30" required>
<label class="mt-3" for="author">Author</label>
<input autocomplete="off" type="text" id="author" class="form-control" name="author" value="{{v.username}}" maxlength="30" required>
<label class="mt-3" for="tags">Tags</label>
<input autocomplete="off" type="text" id="tags" class="form-control" name="tags" maxlength="200" required>
<div class="footer mt-5">
<div class="d-flex">
<input id="submit-marsey" disabled type="submit" onclick="disable(this)" class="btn btn-primary ml-auto" value="Submit Marsey">
</div>
</div>
</form>
</div>
</div>
</div>
</div>
<script>
document.onpaste = function(event) {
files = event.clipboardData.files
filename = files[0]
if (filename)
{
filename = filename.name.toLowerCase()
if (document.activeElement.id == 'post-text') {
let filename = ''
for (const file of files)
filename += file.name + ', '
filename = filename.toLowerCase().slice(0, -2)
document.getElementById('file-upload-submit').files = files;
document.getElementById('filename-show-submit').textContent = filename;
}
else {
f=document.getElementById('file-upload');
f.files = files;
document.getElementById('filename-show').textContent = filename;
document.getElementById('urlblock').classList.add('d-none');
if (filename.endsWith(".jpg") || filename.endsWith(".jpeg") || filename.endsWith(".png") || filename.endsWith(".gif") || filename.endsWith(".webp"))
{
var fileReader = new FileReader();
fileReader.readAsDataURL(f.files[0]);
fileReader.addEventListener("load", function () {document.getElementById('image-preview').setAttribute('src', this.result);});
}
document.getElementById('file-upload').setAttribute('required', 'false');
}
document.getElementById('post-url').value = null;
localStorage.setItem("post-url", "")
}
}
document.getElementById('file-upload').addEventListener('change', function(){
f=document.getElementById('file-upload');
document.getElementById('filename-show').textContent = document.getElementById('file-upload').files[0].name.substr(0, 20);
filename = f.files[0].name.toLowerCase()
if (filename.endsWith(".jpg") || filename.endsWith(".jpeg") || filename.endsWith(".png") || filename.endsWith(".gif") || filename.endsWith(".webp"))
{
var fileReader = new FileReader();
fileReader.readAsDataURL(f.files[0]);
fileReader.addEventListener("load", function () {document.getElementById('image-preview').setAttribute('src', this.result);});
document.getElementById('submit-marsey').disabled = false;
}
})
function approve_marsey(t, name) {
t.disabled = true;
t.classList.add("disabled");
post_toast_callback(`/admin/approve/marsey/${name}`,
{
"tags": document.getElementById(`${name}-tags`).value,
},
(xhr) => {
if(xhr.status == 200) {
document.getElementById(`${name}-marsey`).classList.add('d-none')
}
}
);
setTimeout(() => {
t.disabled = false;
t.classList.remove("disabled");
}, 2000);
}
</script>
<h2 class="mt-5 mx-4">Current Applications</h2>
<div class="row mt-5 mx-4">
<div class="col px-0">
<div class="settings">
{% for marsey in marseys %}
<div id="{{marsey.name}}-marsey" class="settings-section rounded">
<div class="d-lg-flex">
<div class="body w-lg-100">
<input type="hidden" name="formkey" value="{{v.formkey}}">
<div><label class="mt-3">Image</label></div>
<img loading="lazy" src="/asset_submissions/{{marsey.name}}.webp" style="max-width:50%">
<div><label class="mt-3" for="{{marsey.name}}-name">Name</label></div>
<input autocomplete="off" type="text" id="{{marsey.name}}-name" class="form-control" maxlength="30" value="{{marsey.name}}" readonly>
<label class="mt-3" for="{{marsey.name}}-author">Author</label>
<input autocomplete="off" type="text" id="{{marsey.name}}-author" class="form-control" maxlength="30" value="{{marsey.author}}" readonly>
<label class="mt-3" for="{{marsey.name}}-tags">Tags</label>
<input autocomplete="off" type="text" id="{{marsey.name}}-tags" class="form-control" name="tags" maxlength="200" value="{{marsey.tags}}" required>
<label class="mt-3" for="{{marsey.name}}-submitter">Submitter</label>
<input autocomplete="off" type="text" id="{{marsey.name}}-submitter" class="form-control" maxlength="30" value="{{marsey.submitter}}" readonly>
</div>
</div>
{% if v.admin_level > 2 %}
<div class="d-flex my-4 mx-3">
<a role="button" class="btn btn-primary ml-auto mr-2" onclick="approve_marsey(this, '{{marsey.name}}')">Approve</a>
<a role="button" class="btn btn-secondary mr-0" onclick="post_toast(this,'/admin/reject/marsey/{{marsey.name}}', true)">Reject</a>
</div>
{% endif %}
</div>
{% endfor %}
</div>
</div>
</div>
{% endblock %}

View File

@ -1,22 +1,22 @@
{%-
set CACHE_VER = {
'css/main.css': 4020,
'css/catalog.css': 4004,
'css/4chan.css': 4004,
'css/main.css': 4021,
'css/catalog.css': 4005,
'css/4chan.css': 4005,
'css/classic.css': 4005,
'css/classic_dark.css': 4005,
'css/coffee.css': 4004,
'css/dark.css': 4004,
'css/dramblr.css': 4004,
'css/light.css': 4004,
'css/midnight.css': 4004,
'css/reddit.css': 4004,
'css/transparent.css': 4004,
'css/tron.css': 4004,
'css/win98.css': 4004,
'css/coffee.css': 4005,
'css/dark.css': 4005,
'css/dramblr.css': 4005,
'css/light.css': 4005,
'css/midnight.css': 4005,
'css/reddit.css': 4005,
'css/transparent.css': 4005,
'css/tron.css': 4005,
'css/win98.css': 4005,
'js/award_modal.js': 4001,
'js/bootstrap.js': 4002,
'js/bootstrap.js': 4003,
'js/category_modal.js': 4000,
'js/comments_admin.js': 4000,
'js/comments_v.js': 4001,
@ -28,7 +28,7 @@ set CACHE_VER = {
'js/search.js': 4000,
'js/submit.js': 4000,
'js/userpage.js': 4000,
'js/userpage_v.js': 4000,
'js/userpage_v.js': 4001,
'js/lozad.js': 4000,
'js/sort_table.js': 4000,
}

View File

@ -0,0 +1,6 @@
alter table marseys add column submitter_id int;
ALTER TABLE ONLY public.marseys
ADD CONSTRAINT marsey_submitter_fkey FOREIGN KEY (submitter_id) REFERENCES public.users(id);
CREATE INDEX marseys_idx4 ON public.marseys USING btree (submitter_id);

View File

@ -35,6 +35,7 @@ mkdir /songs
mkdir /images
mkdir /videos
mkdir /audio
mkdir /asset_submissions
git config --global --add safe.directory /songs
git config --global --add safe.directory /images
git config --global --add safe.directory /videos