diff --git a/files/assets/css/dark.css b/files/assets/css/dark.css index 40c8701f9..fa2083434 100644 --- a/files/assets/css/dark.css +++ b/files/assets/css/dark.css @@ -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; } diff --git a/files/assets/css/light.css b/files/assets/css/light.css index 5f250b6dd..849dc7425 100644 --- a/files/assets/css/light.css +++ b/files/assets/css/light.css @@ -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; } diff --git a/files/assets/css/main.css b/files/assets/css/main.css index fdd490ad5..f5cec6710 100644 --- a/files/assets/css/main.css +++ b/files/assets/css/main.css @@ -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); diff --git a/files/assets/css/transparent.css b/files/assets/css/transparent.css index 40755b11c..ba8400d4f 100644 --- a/files/assets/css/transparent.css +++ b/files/assets/css/transparent.css @@ -38,7 +38,7 @@ border-color: var(--primary) !important; } -.form-control:disabled, .form-control[readonly] { +.form-control:disabled, [readonly] { border-color: var(--primary) !important; } diff --git a/files/assets/css/tron.css b/files/assets/css/tron.css index ec3a527b4..e836276ef 100644 --- a/files/assets/css/tron.css +++ b/files/assets/css/tron.css @@ -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; } diff --git a/files/assets/css/win98.css b/files/assets/css/win98.css index 7fd01ba5d..883c4a53d 100644 --- a/files/assets/css/win98.css +++ b/files/assets/css/win98.css @@ -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 } diff --git a/files/assets/js/bootstrap.js b/files/assets/js/bootstrap.js index 075fb575c..14d55a2b4 100644 --- a/files/assets/js/bootstrap.js +++ b/files/assets/js/bootstrap.js @@ -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, "&").replace(//g, ">").replace(/"/g, """).replace(/'/g, "'"); } diff --git a/files/assets/js/userpage_v.js b/files/assets/js/userpage_v.js index 33421ad5d..dd647503b 100644 --- a/files/assets/js/userpage_v.js +++ b/files/assets/js/userpage_v.js @@ -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) { diff --git a/files/classes/__init__.py b/files/classes/__init__.py index 9badd9b4b..93cb4ee5a 100644 --- a/files/classes/__init__.py +++ b/files/classes/__init__.py @@ -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 * \ No newline at end of file diff --git a/files/classes/marsey.py b/files/classes/marsey.py index 0f1a8d0b6..872efff24 100644 --- a/files/classes/marsey.py +++ b/files/classes/marsey.py @@ -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"" \ No newline at end of file diff --git a/files/helpers/const.py b/files/helpers/const.py index a26c2fafb..b17011295 100644 --- a/files/helpers/const.py +++ b/files/helpers/const.py @@ -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"} diff --git a/files/helpers/sanitize.py b/files/helpers/sanitize.py index 885e59ea4..be0313092 100644 --- a/files/helpers/sanitize.py +++ b/files/helpers/sanitize.py @@ -327,7 +327,7 @@ def sanitize(sanitized, edit=False, limit_pings=0, showmore=True, marsified=Fals sanitized = audio_sub_regex.sub(r'\1', 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) diff --git a/files/helpers/stats.py b/files/helpers/stats.py index b4a4dcbb3..4b40ba6b4 100644 --- a/files/helpers/stats.py +++ b/files/helpers/stats.py @@ -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(), diff --git a/files/routes/comments.py b/files/routes/comments.py index 21966504e..87fca2533 100644 --- a/files/routes/comments.py +++ b/files/routes/comments.py @@ -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) diff --git a/files/routes/static.py b/files/routes/static.py index 8b779f728..93642d32d 100644 --- a/files/routes/static.py +++ b/files/routes/static.py @@ -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//") @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 \ No newline at end of file diff --git a/files/routes/users.py b/files/routes/users.py index 04ed66399..0256a88ab 100644 --- a/files/routes/users.py +++ b/files/routes/users.py @@ -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]) diff --git a/files/templates/submit_marseys.html b/files/templates/submit_marseys.html new file mode 100644 index 000000000..13fbe08a4 --- /dev/null +++ b/files/templates/submit_marseys.html @@ -0,0 +1,152 @@ +{% extends "default.html" %} + +{% block title %} +<title>Submit Marseys + +{% endblock %} + +{% block content %} +
+

Submit Marsey

+
+
+
+
+ + +
+
+ + + +
+ + + + + + + + + + + +
+
+
+
+
+ + + +

Current Applications

+
+
+
+ {% for marsey in marseys %} +
+
+
+ + +
+ + +
+ + + + + + + + + + +
+
+ {% if v.admin_level > 2 %} +
+ Approve + Reject +
+ {% endif %} +
+ {% endfor %} +
+
+
+{% endblock %} diff --git a/files/templates/util/assetcache.html b/files/templates/util/assetcache.html index 72568864d..5c4b9e23b 100644 --- a/files/templates/util/assetcache.html +++ b/files/templates/util/assetcache.html @@ -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, } diff --git a/sql/20220909-marsey-submissin-ui.sql b/sql/20220909-marsey-submissin-ui.sql new file mode 100644 index 000000000..50ea9b715 --- /dev/null +++ b/sql/20220909-marsey-submissin-ui.sql @@ -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); \ No newline at end of file diff --git a/ubuntu_setup.sh b/ubuntu_setup.sh index e17851f4f..c15210559 100644 --- a/ubuntu_setup.sh +++ b/ubuntu_setup.sh @@ -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