diff --git a/files/assets/css/classic.css b/files/assets/css/classic.css index 9eaef1c72..33e705548 100644 --- a/files/assets/css/classic.css +++ b/files/assets/css/classic.css @@ -530,4 +530,13 @@ a.nav-link:hover { background-color: #f3f3f3 !important; border-radius: 0px; margin-top: 5px; -} \ No newline at end of file +} + +/* award modal text legibility */ +#awardModalBody .text-muted { + color: var(--black3) !important; +} + +#awardModalBody .card .pt-2 { + color: var(--black3) !important; +} diff --git a/files/assets/css/main.css b/files/assets/css/main.css index 806619bf1..35e49dd8e 100644 --- a/files/assets/css/main.css +++ b/files/assets/css/main.css @@ -4582,6 +4582,13 @@ div.deleted.banned { .patron[style="background-color:#FFFFFF;"] { color: black !important; } +.post--category-tag { + padding: 2px 5px 3px 5px; + border-radius: 5px; + font-size: 12px; + font-weight: 700; + margin-right: 0.25rem; +} .container, .container-fluid { background-color: var(--background) !important; } @@ -5267,6 +5274,10 @@ li > .sidebar { width: 13rem; } +.shop-table-actions a { + display: flex; +} + .userbanner { object-fit: cover !important; } @@ -5686,6 +5697,19 @@ g { border-radius:.35rem; } +.category--tag-button { + display: inline-block; + cursor: pointer; +} + +#submit-categories input { + display: none; +} + +#submit-categories input:checked + label { + border: 5px var(--black) double; +} + /* ------- Font Awesome ------- */ @font-face{ font-family:"Font Awesome 6 Pro"; @@ -6038,6 +6062,7 @@ g { .fa-circle-info:before{content:"\f05a"} .fa-comment-question:before{content:"\e14b"} .fa-sitemap:before{content:"\f0e8"} +.fa-grid:before{content:"\e195"} .pronouns { font-size: 9px; diff --git a/files/assets/images/rDrama/banners/105.webp b/files/assets/images/rDrama/banners/105.webp index 52901e9c0..d86d694e8 100644 Binary files a/files/assets/images/rDrama/banners/105.webp and b/files/assets/images/rDrama/banners/105.webp differ diff --git a/files/assets/images/rDrama/sidebar/699.webp b/files/assets/images/rDrama/sidebar/699.webp new file mode 100644 index 000000000..1f8a501f6 Binary files /dev/null and b/files/assets/images/rDrama/sidebar/699.webp differ diff --git a/files/assets/images/rDrama/sidebar/700.webp b/files/assets/images/rDrama/sidebar/700.webp new file mode 100644 index 000000000..b56835ccf Binary files /dev/null and b/files/assets/images/rDrama/sidebar/700.webp differ diff --git a/files/assets/js/bootstrap.js b/files/assets/js/bootstrap.js index 32bd45875..072b44be3 100644 --- a/files/assets/js/bootstrap.js +++ b/files/assets/js/bootstrap.js @@ -178,7 +178,9 @@ if (document.readyState === "complete" || } function post_toast(t, url, button1, button2, classname) { - if (t.id != "buy1-go" && t.id != "buy2-go") + let isShopConfirm = t.id.startsWith('buy1-go') || t.id.startsWith('buy2-go'); + + if (!isShopConfirm) { t.disabled = true; t.classList.add("disabled"); @@ -212,7 +214,7 @@ function post_toast(t, url, button1, button2, classname) { if (data && data["error"]) document.getElementById('toast-post-error-text').innerText = data["error"]; bootstrap.Toast.getOrCreateInstance(document.getElementById('toast-post-error')).show(); } - if (t.id != "buy1-go" && t.id != "buy2-go") + if (!isShopConfirm) { setTimeout(() => { t.disabled = false; diff --git a/files/assets/js/category_modal.js b/files/assets/js/category_modal.js new file mode 100644 index 000000000..5f353cecc --- /dev/null +++ b/files/assets/js/category_modal.js @@ -0,0 +1,41 @@ +function category_modal(id, title, sub) { + document.getElementById("category-modal-title").innerHTML = `Category: ${title}`; + + xhrCategories = new XMLHttpRequest(); + xhrCategories.open("GET", "/categories.json"); + xhrCategories.onload = function () { + let data; + try { + data = JSON.parse(xhrCategories.response); + } catch(e) { console.log(e) } + + categories = [{id: '', name: 'None', sub: sub, color_text: '#000', color_bg: '#FFF'}]; + categories = [].concat(categories, data[sub]); + + document.getElementById("category-modal-body").innerHTML = ''; + categories.forEach(function (c) { + document.getElementById("category-modal-body").innerHTML += + `
` + + `${c.name}` + + `
`; + }); + + document.querySelectorAll('.category--tag-button').forEach(tag => + tag.addEventListener('click', function (e) { + reqBody = new FormData(); + reqBody.append('formkey', formkey()); + reqBody.append('post_id', id); + reqBody.append('category_id', tag.dataset.category); + + xhrSubmit = new XMLHttpRequest(); + xhrSubmit.open('POST', `/post_recategorize`); + xhrSubmit.onload = function () { + window.location.reload(); + } + xhrSubmit.send(reqBody); + }) + ); + } + xhrCategories.send(); +} diff --git a/files/assets/js/submit.js b/files/assets/js/submit.js index e9196bd8a..63982e9ba 100644 --- a/files/assets/js/submit.js +++ b/files/assets/js/submit.js @@ -169,6 +169,31 @@ function checkRepost() { } } +function updateCategories() { + if (document.getElementById("submit-categories") == null) { + return; + } + sub = document.getElementById("sub").value; + + xhrCategories = new XMLHttpRequest(); + xhrCategories.open("GET", "/categories.json"); + xhrCategories.onload = function () { + let data; + try { + data = JSON.parse(xhrCategories.response); + } catch(e) { console.log(e) } + + document.getElementById("submit-categories").innerHTML = ''; + data[sub].forEach(function (c) { + document.getElementById("submit-categories").innerHTML += + `` + + ``; + }); + } + xhrCategories.send(); +} document.addEventListener('keydown', (e) => { if(!((e.ctrlKey || e.metaKey) && e.key === "Enter")) @@ -179,4 +204,5 @@ document.addEventListener('keydown', (e) => { submitButton.click(); }); -checkRepost() \ No newline at end of file +checkRepost(); +updateCategories(); diff --git a/files/classes/__init__.py b/files/classes/__init__.py index 6723e92a2..1fd0f795c 100644 --- a/files/classes/__init__.py +++ b/files/classes/__init__.py @@ -8,6 +8,7 @@ from .user import * from .userblock import * from .submission import * from .votes import * +from .category import * from .domains import * from .subscriptions import * from files.__main__ import app @@ -20,4 +21,4 @@ from .saves import * from .views import * from .notifications import * from .follows import * -from .lottery import * \ No newline at end of file +from .lottery import * diff --git a/files/classes/category.py b/files/classes/category.py new file mode 100644 index 000000000..655e711d6 --- /dev/null +++ b/files/classes/category.py @@ -0,0 +1,22 @@ +from sqlalchemy import * +from sqlalchemy.orm import relationship +from files.__main__ import Base + +class Category(Base): + __tablename__ = "category" + + id = Column(Integer, primary_key=True, nullable=False) + name = Column(String(128), nullable=False) + sub = Column(String(20), ForeignKey("subs.name")) + color_text = Column(String(6)) + color_bg = Column(String(6)) + + def as_json(self): + data = { + 'id': self.id, + 'name': self.name, + 'sub': self.sub if self.sub else '', + 'color_text': '#' + self.color_text, + 'color_bg': '#' + self.color_bg, + } + return data diff --git a/files/classes/mod_logs.py b/files/classes/mod_logs.py index 4ac311a8c..a6aef3dfe 100644 --- a/files/classes/mod_logs.py +++ b/files/classes/mod_logs.py @@ -303,6 +303,11 @@ ACTIONTYPES = { "icon": 'fa-thumbtack fa-rotate--45', "color": 'bg-success' }, + 'post_recategorize': { + "str": 'changed category of {self.target_link}', + "icon": 'fa-grid', + "color": 'bg-primary' + }, 'purge_cache': { "str": 'purged cache', "icon": 'fa-memory', diff --git a/files/classes/submission.py b/files/classes/submission.py index 786096345..b0a493457 100644 --- a/files/classes/submission.py +++ b/files/classes/submission.py @@ -53,6 +53,7 @@ class Submission(Base): body = Column(String) body_html = Column(String) flair = Column(String) + category_id = Column(Integer, ForeignKey("category.id")) ban_reason = Column(String) embed_url = Column(String) new = Column(Boolean) @@ -65,6 +66,7 @@ class Submission(Base): comments = relationship("Comment", primaryjoin="Comment.parent_submission==Submission.id", back_populates="post") subr = relationship("Sub", primaryjoin="foreign(Submission.sub)==remote(Sub.name)") options = relationship("SubmissionOption", order_by="SubmissionOption.id") + category = relationship("Category", primaryjoin="Submission.category_id==Category.id") bump_utc = deferred(Column(Integer, server_default=FetchedValue())) diff --git a/files/helpers/const.py b/files/helpers/const.py index 1e639ca8f..e40b3f461 100644 --- a/files/helpers/const.py +++ b/files/helpers/const.py @@ -100,6 +100,20 @@ if SITE_NAME == 'rDrama': " pedo ": " libertarian ", " pedos ": " libertarians ", } +elif SITE_NAME == 'WPD': + SLURS = { + "nigger": "BIPOC", + "niglet": "young BIPOC", + "faggot": "cute twink", + "fag": "cute twink", + "spic ": "hard-working American ", + "tranny": "valid woman", + "trannie": "valid woman", + "dyke": "cute lesbian", + "gook": "superior IQ Asian", + "kike": "jewish chad", + "daisy's destruction": "Cars 2", + } else: SLURS = { "faggot": "cute twink", @@ -132,6 +146,8 @@ AGENDAPOSTER_MSG_HTML = """

Hi Your fortune: Allah Wills It','Your fortune: Inshallah, Only Good Things Shall Come To Pass','Your fortune: Allah Smiles At You This Day','Your fortune: Your Bussy Is In For A Blasting','Your fortune: You Will Be Propositioned By A High-Tier Twink','Your fortune: Repent, You Have Displeased Allah And His Vengeance Is Nigh','Your fortune: Reply Hazy, Try Again','Your fortune: lmao you just lost 100 coins','Your fortune: Yikes 😬','Your fortune: You Will Be Blessed With Many Black Bulls','Your fortune: NEETmax, The Day Is Lost If You Venture Outside','Your fortune: A Taste Of Jannah Awaits You Today','Your fortune: Watch Your Back','Your fortune: Outlook good','Your fortune: Godly Luck','Your fortune: Good Luck','Your fortune: Bad Luck','Your fortune: Good news will come to you by mail','Your fortune: Very Bad Luck','Your fortune: キタ━━━━━━(οΎŸβˆ€οΎŸ)━━━━━━ !!!!','Your fortune: Better not tell you now','Your fortune: You will meet a dark handsome stranger','Your fortune: οΌˆγ€€Β΄_ゝ`οΌ‰οΎŒο½°οΎ','Your fortune: Excellent Luck','Your fortune: Average Luck') FACTCHECK_REPLIES = ('Factcheck: This claim has been confirmed as correct by experts. ','Factcheck: This claim has been classified as misogynistic.','Factcheck: This claim is currently being debunked.','Factcheck: This claim is 100% true.','Factcheck: This claim hurts trans lives.','Factcheck: [REDACTED].','Factcheck: This claim is both true and false.','Factcheck: You really believe that shit? Lmao dumbass nigga 🀣','Factcheck: None of this is real.','Factcheck: Yes.','Factcheck: This claim has not been approved by experts.','Factcheck: This claim is a gross exageration of reality.','Factcheck: WARNING! THIS CLAIM HAS BEEN CLASSIFIED AS DANGEROUS. PLEASE REMAIN STILL, AN AGENT WILL COME TO MEET YOU SHORTLY.') @@ -1049,5 +1074,6 @@ DISCORD_WELCOME_CHANNEL = "846509313941700618" has_sidebar = path.exists(f'files/templates/sidebar_{SITE_NAME}.html') has_logo = path.exists(f'files/assets/images/{SITE_NAME}/logo.webp') +has_app = path.exists(f'files/assets/app_{SITE_NAME}_v2.4.apk') -GLOBAL = environ.get("GLOBAL") \ No newline at end of file +GLOBAL = environ.get("GLOBAL") diff --git a/files/helpers/get.py b/files/helpers/get.py index fbc44fb34..77d04a308 100644 --- a/files/helpers/get.py +++ b/files/helpers/get.py @@ -1,5 +1,6 @@ from files.classes import * from flask import g +from sqlalchemy.orm import joinedload def get_id(username, v=None, graceful=False): @@ -136,6 +137,8 @@ def get_post(i, v=None, graceful=False): Submission, vt.c.vote_type, blocking.c.target_id, + ).options( + joinedload(Submission.category) ) post=post.filter(Submission.id == i @@ -189,6 +192,8 @@ def get_posts(pids, v=None): blocked.c.target_id, ).filter( Submission.id.in_(pids) + ).options( + joinedload(Submission.category) ).join( vt, vt.c.submission_id==Submission.id, isouter=True ).join( diff --git a/files/helpers/jinja2.py b/files/helpers/jinja2.py index 54b9b9686..3f12dac3c 100644 --- a/files/helpers/jinja2.py +++ b/files/helpers/jinja2.py @@ -57,5 +57,5 @@ def inject_constants(): "HOLE_NAME": HOLE_NAME, "HOLE_STYLE_FLAIR": HOLE_STYLE_FLAIR, "HOLE_REQUIRED": HOLE_REQUIRED, "LOTTERY_ENABLED": LOTTERY_ENABLED, "GUMROAD_LINK": GUMROAD_LINK, "DEFAULT_THEME": DEFAULT_THEME, "DESCRIPTION": DESCRIPTION, - "has_sidebar": has_sidebar, "has_logo": has_logo, + "has_sidebar": has_sidebar, "has_logo": has_logo, "has_app": has_app, "FP": FP, "NOTIF_MODACTION_JL_MIN": NOTIF_MODACTION_JL_MIN} diff --git a/files/helpers/sanitize.py b/files/helpers/sanitize.py index 6a16f42d6..b8b0ecb94 100644 --- a/files/helpers/sanitize.py +++ b/files/helpers/sanitize.py @@ -214,7 +214,7 @@ def with_sigalrm_timeout(timeout: int): @with_sigalrm_timeout(2) -def sanitize(sanitized, edit=False, limit_pings=False): +def sanitize(sanitized, edit=False, limit_pings=False, showmore=True): sanitized = sanitized.strip() sanitized = normalize_url(sanitized) @@ -388,7 +388,7 @@ def sanitize(sanitized, edit=False, limit_pings=False): if '

' not in sanitized:
 		sanitized = sanitized.replace('\n','')
 
-	if len(sanitized) > 5000:
+	if showmore and len(sanitized) > 5000:
 		sanitized = showmore_regex.sub(r'\1

\2', sanitized) return sanitized.strip() diff --git a/files/routes/admin.py b/files/routes/admin.py index aea047ae1..30b799949 100644 --- a/files/routes/admin.py +++ b/files/routes/admin.py @@ -1428,6 +1428,85 @@ def admin_toggle_ban_domain(v): return redirect("/admin/banned_domains/") +@app.get("/admin/categories") +@admin_level_required(PERMS['ADMIN_CATEGORIES_MANAGE']) +def admin_categories(v): + if not FEATURES['CATEGORIES']: + abort(404) + + categories = g.db.query(Category).order_by(nullsfirst(Category.sub), Category.name).all() + return render_template("admin/categories.html", v=v, categories=categories) + +@app.post("/admin/categories/add") +@admin_level_required(PERMS['ADMIN_CATEGORIES_MANAGE']) +def admin_categories_add(v): + if not FEATURES['CATEGORIES']: + abort(404) + + cat_name = request.values.get("name").strip() + cat_sub = request.values.get("sub").strip().lower() + cat_color_text = request.values.get("color_text").strip().strip('#').lower() + cat_color_bg = request.values.get("color_bg").strip().strip('#').lower() + + if cat_sub == '': + cat_sub = None + + cat = Category( + name=cat_name, + sub=cat_sub, + color_text=cat_color_text, + color_bg=cat_color_bg + ) + + g.db.add(cat) + g.db.commit() + + return redirect("/admin/categories") + +@app.post("/admin/categories/update/") +@admin_level_required(PERMS['ADMIN_CATEGORIES_MANAGE']) +def admin_categories_update(v, cid): + if not FEATURES['CATEGORIES']: + abort(404) + + cat_name = request.values.get("name").strip() + cat_color_text = request.values.get("color_text").strip().strip('#').lower() + cat_color_bg = request.values.get("color_bg").strip().strip('#').lower() + + try: + cat_id = int(cid) + except: + abort(400) + + cat = g.db.query(Category).filter(Category.id == cat_id).one_or_none() + if not cat: + abort(400) + + cat.name = cat_name + cat.color_text = cat_color_text + cat.color_bg = cat_color_bg + + g.db.add(cat) + g.db.commit() + + return redirect("/admin/categories") + +@app.post("/admin/categories/delete/") +@admin_level_required(PERMS['ADMIN_CATEGORIES_MANAGE']) +def admin_categories_delete(v, cid): + if not FEATURES['CATEGORIES']: + abort(404) + + try: + cat_id = int(cid) + except: + abort(400) + + cat = g.db.query(Category).filter(Category.id == cat_id).one_or_none() + g.db.delete(cat) + g.db.commit() + + return redirect("/admin/categories") @app.post("/admin/nuke_user") @limiter.limit("1/second;30/minute;200/hour;1000/day") diff --git a/files/routes/posts.py b/files/routes/posts.py index 7b4e5c87b..da071eac3 100644 --- a/files/routes/posts.py +++ b/files/routes/posts.py @@ -225,11 +225,18 @@ def post_id(pid, anything=None, v=None, sub=None): post.views += 1 g.db.add(post) - if request.headers.get("Authorization"): return post.json - else: - if post.is_banned and not (v and (v.admin_level > 1 or post.author_id == v.id)): template = "submission_banned.html" - else: template = "submission.html" - return render_template(template, v=v, p=post, ids=list(ids), sort=sort, render_replies=True, offset=offset, sub=post.subr, fart=app.config['SETTINGS']['Fart mode']) + + if request.headers.get("Authorization"): + return post.json + + template = "submission.html" + if (post.is_banned or post.author.shadowbanned) \ + and not (v and (v.admin_level >= 2 or post.author_id == v.id)): + template = "submission_banned.html" + + return render_template(template, v=v, p=post, ids=list(ids), + sort=sort, render_replies=True, offset=offset, sub=post.subr, + fart=app.config['SETTINGS']['Fart mode']) @app.get("/viewmore///") @limiter.limit("1/second;30/minute;200/hour;1000/day") @@ -432,7 +439,7 @@ def edit_post(pid, v): g.db.add(option) - body_html = sanitize(body, edit=True, limit_pings=True) + body_html = sanitize(body, edit=True, limit_pings=True, showmore=False) if v.id == p.author_id and v.marseyawarded and marseyaward_body_regex.search(body_html): return {"error":"You can only type marseys!"}, 403 @@ -697,6 +704,14 @@ def submit_post(v, sub=None): if not sub and HOLE_REQUIRED: return error(f"You must choose a {HOLE_NAME} for your post!") + category = None + if FEATURES['CATEGORIES']: + category_id = request.values.get('category', '') + try: + category = int(category_id) + except: + category = None + if v.is_suspended: return error("You can't perform this action while banned.") if v.agendaposter and not v.marseyawarded: title = torture_ap(title, v.username) @@ -875,7 +890,7 @@ def submit_post(v, sub=None): body = body.strip() - body_html = sanitize(body, limit_pings=True) + body_html = sanitize(body, limit_pings=True, showmore=False) if v.marseyawarded and marseyaward_body_regex.search(body_html): return error("You can only type marseys!") @@ -912,6 +927,7 @@ def submit_post(v, sub=None): title=title[:500], title_html=title_html, sub=sub, + category_id=category, ghost=ghost ) @@ -1207,6 +1223,42 @@ def toggle_post_nsfw(pid, v): if post.over_18: return {"message": "Post has been marked as +18!"} else: return {"message": "Post has been unmarked as +18!"} +@app.post("/post_recategorize") +@auth_required +def post_recategorize(v): + if not FEATURES['CATEGORIES']: + abort(404) + if v.admin_level < PERMS['ADMIN_CATEGORIES_CHANGE']: + abort(403) + + post_id = request.values.get("post_id") + category_id = request.values.get("category_id") + try: + pid = int(post_id) + cid = None + if category_id != '': + cid = int(category_id) + except: + abort(400) + + post = g.db.get(Submission, pid) + post.category_id = cid + g.db.add(post) + + category_new_name = '<none>' + if category_id != '': + category_new_name = g.db.get(Category, cid).name + ma = ModAction( + kind='post_recategorize', + user_id=v.id, + target_submission_id=post.id, + _note=category_new_name + ) + g.db.add(ma) + + g.db.commit() + return {"message": "Success!"} + @app.post("/save_post/") @limiter.limit("1/second;30/minute;200/hour;1000/day") @limiter.limit("1/second;30/minute;200/hour;1000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') diff --git a/files/routes/search.py b/files/routes/search.py index f33caa8a1..3711f3e56 100644 --- a/files/routes/search.py +++ b/files/routes/search.py @@ -48,16 +48,19 @@ def searchposts(v): criteria=searchparse(query) - - - posts = g.db.query(Submission.id).filter(Submission.author_id.notin_(v.userblocks)) + posts = g.db.query(Submission.id) \ + .join(Submission.author) \ + .filter(Submission.author_id.notin_(v.userblocks)) - if not v.paid_dues: posts = posts.filter_by(club=False) + if not v.paid_dues: + posts = posts.filter(Submission.club == False) if v.admin_level < 2: - posts = posts.filter(Submission.deleted_utc == 0, Submission.is_banned == False, Submission.private == False) - - + posts = posts.filter( + Submission.deleted_utc == 0, + Submission.is_banned == False, + Submission.private == False, + User.shadowbanned == None) if 'author' in criteria: posts = posts.filter(Submission.ghost == False) @@ -239,6 +242,9 @@ def searchusers(v): ) ) + if v.admin_level < 2: + users = users.filter(User.shadowbanned == None) + users=users.order_by(User.username.ilike(term).desc(), User.stored_subscriber_count.desc()) total=users.count() diff --git a/files/routes/static.py b/files/routes/static.py index 244f1ef5e..d04f63dad 100644 --- a/files/routes/static.py +++ b/files/routes/static.py @@ -419,3 +419,15 @@ def knowledgebase(v, page): abort(404) return render_template(template_path, v=v) + +@app.get("/categories.json") +def categories_json(): + categories = g.db.query(Category).all() + + data = {} + for c in categories: + sub = c.sub if c.sub else '' + sub_cats = (data[sub] if sub in data else []) + [c.as_json()] + data.update({sub: sub_cats}) + + return jsonify(data) diff --git a/files/routes/users.py b/files/routes/users.py index 970e94733..4f4523bbb 100644 --- a/files/routes/users.py +++ b/files/routes/users.py @@ -11,6 +11,7 @@ from files.mail import * from flask import * from files.__main__ import app, limiter, db_session import sqlalchemy +from sqlalchemy.orm import aliased from sqlalchemy import text from collections import Counter import gevent @@ -1055,14 +1056,24 @@ def u_username_comments(username, v=None): sort=request.values.get("sort","new") t=request.values.get("t","all") - - comments = g.db.query(Comment.id).filter(Comment.author_id == u.id, Comment.parent_submission != None) + comment_post_author = aliased(User) + comments = g.db.query(Comment.id) \ + .join(Comment.post) \ + .join(comment_post_author, Submission.author) \ + .filter( + Comment.author_id == u.id, + Comment.parent_submission != None + ) if not v or (v.id != u.id and v.admin_level < 2): - comments = comments.filter(Comment.is_banned == False, Comment.ghost == False) + comments = comments.filter( + Comment.is_banned == False, + Comment.ghost == False, + comment_post_author.shadowbanned == None + ) if not (v and v.admin_level > 1): - comments = comments.filter_by(deleted_utc=0) + comments = comments.filter(Comment.deleted_utc == 0) comments = apply_time_filter(t, comments, Comment) diff --git a/files/templates/admin/admin_home.html b/files/templates/admin/admin_home.html index ba418c031..3bee53266 100644 --- a/files/templates/admin/admin_home.html +++ b/files/templates/admin/admin_home.html @@ -53,11 +53,6 @@ {%- endif %} -

API Access Control

-
- {% if LOTTERY_ENABLED -%}

Lottery

- {% endblock %} \ No newline at end of file + {% endblock %} diff --git a/files/templates/shop.html b/files/templates/shop.html index 405530575..637b3eabc 100644 --- a/files/templates/shop.html +++ b/files/templates/shop.html @@ -27,12 +27,6 @@ {% endblock %} {% block content %} - - {% if error %}