Merge branch 'master' into fix-seed-db
commit
62a7ef70ed
|
@ -1,5 +1,6 @@
|
|||
image.png
|
||||
image.gif
|
||||
dramacache/
|
||||
cache/
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
|
|
@ -2,12 +2,12 @@ version: 0.0
|
|||
os: linux
|
||||
files:
|
||||
- source: /
|
||||
destination: drama
|
||||
destination: files
|
||||
permissions:
|
||||
- object: drama/*
|
||||
- object: files/*
|
||||
mode: 4755
|
||||
hooks:
|
||||
AfterInstall:
|
||||
- location: scripts/install_pip
|
||||
ApplicationStart:
|
||||
- location: scripts/start_drama
|
||||
- location: scripts/start_files
|
|
@ -1,7 +1,7 @@
|
|||
for theme in ['midnight', 'dark', 'light', 'coffee', 'tron', '4chan']:
|
||||
with open(f"./drama/assets/style/{theme}_ff66ac.css", encoding='utf-8') as t:
|
||||
with open(f"./files/assets/style/{theme}_ff66ac.css", encoding='utf-8') as t:
|
||||
text = t.read()
|
||||
for color in ['ff66ac','805ad5','62ca56','38a169','80ffff','2a96f3','62ca56','eb4963','ff0000','f39731','30409f','3e98a7','e4432d','7b9ae4','ec72de','7f8fa6', 'f8db58']:
|
||||
newtext = text.replace("ff66ac", color).replace("ff4097", color).replace("ff1a83", color).replace("ff3390", color).replace("rgba(255, 102, 172, 0.25)", color)
|
||||
with open(f"./drama/assets/style/{theme}_{color}.css", encoding='utf-8', mode='w') as nt:
|
||||
with open(f"./files/assets/style/{theme}_{color}.css", encoding='utf-8', mode='w') as nt:
|
||||
nt.write(newtext)
|
|
@ -1,36 +1,43 @@
|
|||
version: '2.3'
|
||||
|
||||
services:
|
||||
drama:
|
||||
files:
|
||||
build:
|
||||
context: .
|
||||
volumes:
|
||||
- "./:/drama/service"
|
||||
- "./:/service"
|
||||
environment:
|
||||
- PYTHONPATH="drama/service"
|
||||
- PYTHONPATH="/service"
|
||||
- REDIS_URL=redis://redis
|
||||
- DATABASE_URL=postgresql://postgres@postgres:5432/postgres
|
||||
- DATABASE_CONNECTION_POOL_URL=postgresql://postgres@postgres:5432/postgres
|
||||
- MASTER_KEY=${MASTER_KEY:-KTVciAUQFpFh2WdJ/oiHJlxl6FvzRZp8kYzAAv3l2OA=}
|
||||
- domain=localhost
|
||||
- DOMAIN=localhost
|
||||
- SITE_NAME=Drama
|
||||
- CLOUDFLARE_ZONE=vcxvdfgfc6r554etrgd
|
||||
- CLOUDFLARE_KEY=vcxvdfgfc6r554etrgd
|
||||
- TENOR_KEY=vcxvdfgfc6r554etrgd
|
||||
- MAILGUN_KEY=vcxvdfgfc6r554etrgd
|
||||
- MAILGUN_DOMAIN=rdrama.net
|
||||
- admin_email=drama@rdrama.net
|
||||
- FORCE_HTTPS=0
|
||||
- DISCORD_SERVER_ID=vcxvdfgfc6r554etrgd
|
||||
- DISCORD_CLIENT_ID=vcxvdfgfc6r554etrgd
|
||||
- DISCORD_CLIENT_SECRET=vcxvdfgfc6r554etrgd
|
||||
- DISCORD_BOT_TOKEN=vcxvdfgfc6r554etrgd
|
||||
- imgurkey=vcxvdfgfc6r554etrgd
|
||||
- IMGUR_KEY=vcxvdfgfc6r554etrgd
|
||||
- FACEBOOK_TOKEN=vcxvdfgfc6r554etrgd
|
||||
#- HCAPTCHA_SITEKEY=vcxvdfgfc6r554etrgd
|
||||
#- HCAPTCHA_SITEKEY=vcxvdfgfc6r554etrgd
|
||||
- HCAPTCHA_SECRET=vcxvdfgfc6r554etrgd
|
||||
- youtubekey=vcxvdfgfc6r554etrgd
|
||||
- YOUTUBE_KEY=vcxvdfgfc6r554etrgd
|
||||
- PUSHER_KEY=vcxvdfgfc6r554etrgd
|
||||
- SPAM_SIMILARITY_THRESHOLD=0.5
|
||||
- SPAM_SIMILAR_COUNT_THRESHOLD=5
|
||||
- SPAM_URL_SIMILARITY_THRESHOLD=0.1
|
||||
- COMMENT_SPAM_SIMILAR_THRESHOLD=0.5
|
||||
- COMMENT_SPAM_COUNT_THRESHOLD=5
|
||||
- READ_ONLY=0
|
||||
- BOT_DISABLE=0
|
||||
- COINS_NAME=Dramacoins
|
||||
links:
|
||||
- "redis"
|
||||
- "postgres"
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
|
||||
from drama.__main__ import Base, app
|
|
@ -30,28 +30,15 @@ app = Flask(__name__,
|
|||
app.wsgi_app = ProxyFix(app.wsgi_app, x_for=3)
|
||||
app.url_map.strict_slashes = False
|
||||
|
||||
app.config["SITE_NAME"]=environ.get("SITE_NAME", "Drama").strip()
|
||||
|
||||
app.config["SITE_COLOR"]=environ.get("SITE_COLOR", "805ad5").strip()
|
||||
|
||||
app.config["DRAMAPATH"]=environ.get("DRAMAPATH", path.dirname(path.realpath(__file__)))
|
||||
|
||||
app.config["SITE_NAME"]=environ.get("SITE_NAME").strip()
|
||||
app.config["COINS_NAME"]=environ.get("COINS_NAME").strip()
|
||||
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
|
||||
app.config['DATABASE_URL'] = environ.get(
|
||||
"DATABASE_CONNECTION_POOL_URL",
|
||||
environ.get("DATABASE_URL"))
|
||||
|
||||
app.config['SQLALCHEMY_READ_URIS'] = [
|
||||
environ.get("DATABASE_CONNECTION_READ_01_URL"),
|
||||
environ.get("DATABASE_CONNECTION_READ_02_URL"),
|
||||
environ.get("DATABASE_CONNECTION_READ_03_URL")
|
||||
]
|
||||
app.config['DATABASE_URL'] = environ.get("DATABASE_CONNECTION_POOL_URL",environ.get("DATABASE_URL"))
|
||||
|
||||
app.config['SECRET_KEY'] = environ.get('MASTER_KEY')
|
||||
app.config["SERVER_NAME"] = environ.get("domain").strip()
|
||||
app.config["SERVER_NAME"] = environ.get("DOMAIN").strip()
|
||||
|
||||
app.config["SHORT_DOMAIN"]=environ.get("SHORT_DOMAIN","").strip()
|
||||
app.config["SESSION_COOKIE_NAME"] = "session_drama"
|
||||
app.config["SESSION_COOKIE_NAME"] = "session_" + environ.get("SITE_NAME").strip().lower()
|
||||
app.config["VERSION"] = "1.0.0"
|
||||
app.config['MAX_CONTENT_LENGTH'] = 64 * 1024 * 1024
|
||||
app.config["SESSION_COOKIE_SECURE"] = bool(int(environ.get("FORCE_HTTPS", 1)))
|
||||
|
@ -61,7 +48,6 @@ app.config["PERMANENT_SESSION_LIFETIME"] = 60 * 60 * 24 * 365
|
|||
app.config["SESSION_REFRESH_EACH_REQUEST"] = True
|
||||
|
||||
app.config["FORCE_HTTPS"] = int(environ.get("FORCE_HTTPS", 1)) if ("localhost" not in app.config["SERVER_NAME"] and "127.0.0.1" not in app.config["SERVER_NAME"]) else 0
|
||||
app.config["DISABLE_SIGNUPS"]=int(environ.get("DISABLE_SIGNUPS",0))
|
||||
|
||||
app.jinja_env.cache = {}
|
||||
|
||||
|
@ -70,34 +56,26 @@ app.config["UserAgent"] = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit
|
|||
if "localhost" in app.config["SERVER_NAME"]:
|
||||
app.config["CACHE_TYPE"] = "null"
|
||||
else:
|
||||
app.config["CACHE_TYPE"] = environ.get("CACHE_TYPE", 'filesystem').strip()
|
||||
app.config["CACHE_TYPE"] = "filesystem"
|
||||
|
||||
app.config["CACHE_DIR"] = environ.get("CACHE_DIR", "dramacache")
|
||||
app.config["CACHE_DIR"] = environ.get("CACHE_DIR", "cache")
|
||||
|
||||
# captcha configs
|
||||
app.config["HCAPTCHA_SITEKEY"] = environ.get("HCAPTCHA_SITEKEY","").strip()
|
||||
app.config["HCAPTCHA_SECRET"] = environ.get(
|
||||
"HCAPTCHA_SECRET","").strip()
|
||||
app.config["SIGNUP_HOURLY_LIMIT"]=int(environ.get("SIGNUP_HOURLY_LIMIT",0))
|
||||
app.config["HCAPTCHA_SECRET"] = environ.get("HCAPTCHA_SECRET","").strip()
|
||||
|
||||
# antispam configs
|
||||
app.config["SPAM_SIMILARITY_THRESHOLD"] = float(
|
||||
environ.get("SPAM_SIMILARITY_THRESHOLD", 0.5))
|
||||
app.config["SPAM_SIMILAR_COUNT_THRESHOLD"] = int(
|
||||
environ.get("SPAM_SIMILAR_COUNT_THRESHOLD", 5))
|
||||
app.config["SPAM_URL_SIMILARITY_THRESHOLD"] = float(
|
||||
environ.get("SPAM_URL_SIMILARITY_THRESHOLD", 0.1))
|
||||
app.config["COMMENT_SPAM_SIMILAR_THRESHOLD"] = float(
|
||||
environ.get("COMMENT_SPAM_SIMILAR_THRESHOLD", 0.5))
|
||||
app.config["COMMENT_SPAM_COUNT_THRESHOLD"] = int(
|
||||
environ.get("COMMENT_SPAM_COUNT_THRESHOLD", 5))
|
||||
app.config["SPAM_SIMILARITY_THRESHOLD"] = float(environ.get("SPAM_SIMILARITY_THRESHOLD"))
|
||||
app.config["SPAM_SIMILAR_COUNT_THRESHOLD"] = int(environ.get("SPAM_SIMILAR_COUNT_THRESHOLD"))
|
||||
app.config["SPAM_URL_SIMILARITY_THRESHOLD"] = float(environ.get("SPAM_URL_SIMILARITY_THRESHOLD"))
|
||||
app.config["COMMENT_SPAM_SIMILAR_THRESHOLD"] = float(environ.get("COMMENT_SPAM_SIMILAR_THRESHOLD"))
|
||||
app.config["COMMENT_SPAM_COUNT_THRESHOLD"] = int(environ.get("COMMENT_SPAM_COUNT_THRESHOLD"))
|
||||
|
||||
app.config["CACHE_REDIS_URL"] = environ.get(
|
||||
"REDIS_URL").strip().lstrip() if environ.get("REDIS_URL") else None
|
||||
app.config["CACHE_REDIS_URL"] = environ.get("REDIS_URL").strip()
|
||||
app.config["CACHE_DEFAULT_TIMEOUT"] = 60
|
||||
app.config["CACHE_KEY_PREFIX"] = "flask_caching_"
|
||||
|
||||
app.config["REDIS_POOL_SIZE"]=int(environ.get("REDIS_POOL_SIZE", 10))
|
||||
app.config["REDIS_POOL_SIZE"] = 10
|
||||
|
||||
redispool=ConnectionPool(
|
||||
max_connections=app.config["REDIS_POOL_SIZE"],
|
||||
|
@ -105,7 +83,7 @@ redispool=ConnectionPool(
|
|||
) if app.config["CACHE_TYPE"]=="redis" else None
|
||||
app.config["CACHE_OPTIONS"]={'connection_pool':redispool} if app.config["CACHE_TYPE"]=="redis" else {}
|
||||
|
||||
app.config["READ_ONLY"]=bool(int(environ.get("READ_ONLY", False)))
|
||||
app.config["READ_ONLY"]=bool(int(environ.get("READ_ONLY")))
|
||||
app.config["BOT_DISABLE"]=bool(int(environ.get("BOT_DISABLE", False)))
|
||||
|
||||
app.config["TENOR_KEY"]=environ.get("TENOR_KEY",'').strip()
|
||||
|
@ -115,18 +93,15 @@ Markdown(app)
|
|||
cache = Cache(app)
|
||||
Compress(app)
|
||||
|
||||
app.config["RATELIMIT_STORAGE_URL"] = environ.get("REDIS_URL").strip() if environ.get("REDIS_URL") else 'memory://'
|
||||
app.config["RATELIMIT_STORAGE_URL"] = environ.get("REDIS_URL").strip()
|
||||
app.config["RATELIMIT_KEY_PREFIX"] = "flask_limiting_"
|
||||
app.config["RATELIMIT_ENABLED"] = True
|
||||
app.config["RATELIMIT_DEFAULTS_DEDUCT_WHEN"]=lambda:True
|
||||
app.config["RATELIMIT_DEFAULTS_EXEMPT_WHEN"]=lambda:False
|
||||
app.config["RATELIMIT_HEADERS_ENABLED"]=True
|
||||
|
||||
#app.config["DISABLESIGNUPS"] = bool(int(environ.get("DISABLESIGNUPS", "0")))
|
||||
|
||||
|
||||
def limiter_key_func():
|
||||
return request.remote_addr
|
||||
def limiter_key_func(): return request.remote_addr
|
||||
|
||||
|
||||
limiter = Limiter(
|
||||
|
@ -196,9 +171,9 @@ UA_BAN_CACHE_TTL = int(environ.get("UA_BAN_CACHE_TTL", 3600))
|
|||
|
||||
|
||||
# import and bind all routing functions
|
||||
import drama.classes
|
||||
from drama.routes import *
|
||||
import drama.helpers.jinja2
|
||||
import files.classes
|
||||
from files.routes import *
|
||||
import files.helpers.jinja2
|
||||
|
||||
@cache.memoize(UA_BAN_CACHE_TTL)
|
||||
def get_useragent_ban_response(user_agent_str):
|
||||
|
@ -210,8 +185,8 @@ def get_useragent_ban_response(user_agent_str):
|
|||
# return False, (None, None)
|
||||
|
||||
result = g.db.query(
|
||||
drama.classes.Agent).filter(
|
||||
drama.classes.Agent.kwd.in_(
|
||||
files.classes.Agent).filter(
|
||||
files.classes.Agent.kwd.in_(
|
||||
user_agent_str.split())).first()
|
||||
if result:
|
||||
return True, (result.mock or "Follow the robots.txt, dumbass",
|
||||
|
@ -267,26 +242,6 @@ def before_request():
|
|||
else:
|
||||
g.system="other/other"
|
||||
|
||||
|
||||
def log_event(name, link):
|
||||
|
||||
x = requests.get(link)
|
||||
|
||||
if x.status_code != 200:
|
||||
return
|
||||
|
||||
text = f'> **{name}**\r> {link}'
|
||||
|
||||
url = environ.get("DISCORD_WEBHOOK")
|
||||
headers = {"Content-Type": "application/json"}
|
||||
data = {"username": "drama",
|
||||
"content": text
|
||||
}
|
||||
|
||||
x = requests.post(url, headers=headers, json=data)
|
||||
print(x.status_code)
|
||||
|
||||
|
||||
@app.after_request
|
||||
def after_request(response):
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
from sqlalchemy import *
|
||||
from drama.__main__ import Base
|
||||
from files.__main__ import Base
|
||||
|
||||
class Agent(Base):
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
from sqlalchemy import *
|
||||
from drama.__main__ import Base
|
||||
from files.__main__ import Base
|
||||
|
||||
|
||||
class Alt(Base):
|
|
@ -1,6 +1,6 @@
|
|||
from sqlalchemy import *
|
||||
from sqlalchemy.orm import relationship
|
||||
from drama.__main__ import Base
|
||||
from files.__main__ import Base
|
||||
|
||||
AWARDS = {
|
||||
"ban": {
|
|
@ -1,7 +1,7 @@
|
|||
from sqlalchemy import *
|
||||
from sqlalchemy.orm import relationship
|
||||
|
||||
from drama.__main__ import Base, app
|
||||
from files.__main__ import Base, app
|
||||
|
||||
|
||||
class BadgeDef(Base):
|
|
@ -5,7 +5,7 @@ from sqlalchemy.orm import relationship, lazyload
|
|||
from .mix_ins import Stndrd
|
||||
from .submission import Submission
|
||||
from .comment import Comment
|
||||
from drama.__main__ import Base
|
||||
from files.__main__ import Base
|
||||
|
||||
class OauthApp(Base, Stndrd):
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
from flask import *
|
||||
from sqlalchemy import *
|
||||
from sqlalchemy.orm import relationship, deferred
|
||||
from drama.helpers.lazy import lazy
|
||||
from drama.__main__ import Base
|
||||
from files.helpers.lazy import lazy
|
||||
from files.__main__ import Base
|
||||
from .mix_ins import *
|
||||
from .flags import CommentFlag
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
from sqlalchemy import *
|
||||
from drama.__main__ import Base
|
||||
from files.__main__ import Base
|
||||
|
||||
class BannedDomain(Base):
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
from sqlalchemy import *
|
||||
from sqlalchemy.orm import relationship
|
||||
from drama.__main__ import Base
|
||||
from files.__main__ import Base
|
||||
from .mix_ins import *
|
||||
|
||||
class Flag(Base, Stndrd):
|
|
@ -1,6 +1,6 @@
|
|||
from sqlalchemy import *
|
||||
from flask import g
|
||||
from drama.__main__ import Base
|
||||
from files.__main__ import Base
|
||||
|
||||
|
||||
class Image(Base):
|
|
@ -0,0 +1,2 @@
|
|||
|
||||
from files.__main__ import Base, app
|
|
@ -1,4 +1,4 @@
|
|||
from drama.helpers.lazy import lazy
|
||||
from files.helpers.lazy import lazy
|
||||
import math
|
||||
import random
|
||||
import time
|
|
@ -1,6 +1,6 @@
|
|||
from sqlalchemy import *
|
||||
from sqlalchemy.orm import relationship
|
||||
from drama.__main__ import Base
|
||||
from files.__main__ import Base
|
||||
from .mix_ins import *
|
||||
import time
|
||||
|
|
@ -3,13 +3,13 @@ from sqlalchemy import *
|
|||
from sqlalchemy.orm import relationship, deferred
|
||||
import re, random
|
||||
from urllib.parse import urlparse
|
||||
from drama.helpers.lazy import lazy
|
||||
from drama.__main__ import Base
|
||||
from files.helpers.lazy import lazy
|
||||
from files.__main__ import Base
|
||||
from .mix_ins import *
|
||||
from .flags import *
|
||||
from os import environ
|
||||
|
||||
site = environ.get("domain").strip()
|
||||
site = environ.get("DOMAIN").strip()
|
||||
|
||||
class SubmissionAux(Base):
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
from sqlalchemy import *
|
||||
from sqlalchemy.orm import relationship
|
||||
from drama.__main__ import Base
|
||||
from files.__main__ import Base
|
||||
import time
|
||||
|
||||
|
|
@ -2,8 +2,8 @@ from sqlalchemy.orm import deferred, contains_eager, aliased
|
|||
from secrets import token_hex
|
||||
import pyotp
|
||||
|
||||
from drama.helpers.discord import delete_role
|
||||
from drama.helpers.images import *
|
||||
from files.helpers.discord import delete_role
|
||||
from files.helpers.images import *
|
||||
from .alts import Alt
|
||||
from .submission import SaveRelationship
|
||||
from .comment import Notification
|
||||
|
@ -11,10 +11,10 @@ from .subscriptions import *
|
|||
from .userblock import *
|
||||
from .badges import *
|
||||
from .clients import *
|
||||
from drama.__main__ import Base, cache
|
||||
from drama.helpers.security import *
|
||||
from files.__main__ import Base, cache
|
||||
from files.helpers.security import *
|
||||
|
||||
site = environ.get("domain").strip()
|
||||
site = environ.get("DOMAIN").strip()
|
||||
|
||||
class User(Base, Stndrd, Age_times):
|
||||
__tablename__ = "users"
|
||||
|
@ -79,7 +79,7 @@ class User(Base, Stndrd, Age_times):
|
|||
ban_reason = Column(String, default="")
|
||||
login_nonce = Column(Integer, default=0)
|
||||
reserved = Column(String(256))
|
||||
dramacoins = Column(Integer, default=0)
|
||||
coins = Column(Integer, default=0)
|
||||
mfa_secret = deferred(Column(String(16)))
|
||||
is_private = Column(Boolean, default=False)
|
||||
stored_subscriber_count = Column(Integer, default=0)
|
||||
|
@ -491,7 +491,7 @@ class User(Base, Stndrd, Age_times):
|
|||
data = self.json_core
|
||||
|
||||
data["badges"] = [x.json_core for x in self.badges]
|
||||
data['dramacoins'] = int(self.dramacoins)
|
||||
data['coins'] = int(self.coins)
|
||||
data['post_count'] = self.post_count
|
||||
data['comment_count'] = self.comment_count
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
from sqlalchemy import *
|
||||
from sqlalchemy.orm import relationship
|
||||
from .mix_ins import *
|
||||
from drama.__main__ import Base
|
||||
from files.__main__ import Base
|
||||
|
||||
class UserBlock(Base, Stndrd, Age_times):
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
from flask import *
|
||||
from sqlalchemy import *
|
||||
from sqlalchemy.orm import relationship
|
||||
from drama.__main__ import Base
|
||||
from files.__main__ import Base
|
||||
|
||||
class Vote(Base):
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import mistletoe
|
||||
|
||||
from drama.classes import *
|
||||
from files.classes import *
|
||||
from flask import g
|
||||
from .markdown import *
|
||||
from .sanitize import *
|
|
@ -1,7 +1,7 @@
|
|||
from bs4 import BeautifulSoup
|
||||
from flask import *
|
||||
from urllib.parse import urlparse
|
||||
from drama.classes import BannedDomain
|
||||
from files.classes import BannedDomain
|
||||
|
||||
def filter_comment_html(html_text):
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
from drama.classes import *
|
||||
from files.classes import *
|
||||
from flask import g
|
||||
from sqlalchemy.orm import joinedload, aliased
|
||||
|
|
@ -2,11 +2,11 @@ import requests
|
|||
from os import environ
|
||||
from PIL import Image as IImage, ImageSequence
|
||||
import base64
|
||||
from drama.classes.images import *
|
||||
from files.classes.images import *
|
||||
|
||||
CF_KEY = environ.get("CLOUDFLARE_KEY").strip()
|
||||
CF_ZONE = environ.get("CLOUDFLARE_ZONE").strip()
|
||||
imgurkey = environ.get("imgurkey").strip()
|
||||
IMGUR_KEY = environ.get("IMGUR_KEY").strip()
|
||||
|
||||
|
||||
def upload_file(file=None, resize=False, png=False):
|
||||
|
@ -35,12 +35,10 @@ def upload_file(file=None, resize=False, png=False):
|
|||
try:
|
||||
with open(filedir, 'rb') as f:
|
||||
data={'image': base64.b64encode(f.read())}
|
||||
req = requests.post('https://api.imgur.com/3/upload.json', headers = {"Authorization": f"Client-ID {imgurkey}"}, data=data)
|
||||
req = requests.post('https://api.imgur.com/3/upload.json', headers = {"Authorization": f"Client-ID {IMGUR_KEY}"}, data=data)
|
||||
resp = req.json()['data']
|
||||
url = resp['link'].replace(".png", "_d.png").replace(".jpg", "_d.jpg").replace(".jpeg", "_d.jpeg") + "?maxwidth=9999"
|
||||
except:
|
||||
print(req.text)
|
||||
return
|
||||
except: return
|
||||
|
||||
new_image = Image(text=url, deletehash=resp["deletehash"])
|
||||
g.db.add(new_image)
|
|
@ -1,6 +1,6 @@
|
|||
from os import environ, path
|
||||
from .get import *
|
||||
from drama.__main__ import app, cache
|
||||
from files.__main__ import app, cache
|
||||
|
||||
|
||||
@app.template_filter("total_users")
|
||||
|
@ -14,7 +14,7 @@ def total_users(x):
|
|||
@cache.memoize(timeout=60 * 60 * 24)
|
||||
def source_code(file_name):
|
||||
|
||||
return open(path.expanduser('~') + '/drama/' +
|
||||
return open(path.expanduser('~') + '/files/' +
|
||||
file_name, mode="r+").read()
|
||||
|
||||
|
|
@ -6,7 +6,7 @@ from functools import partial
|
|||
from .get import *
|
||||
from os import path
|
||||
|
||||
site = environ.get("domain").strip()
|
||||
site = environ.get("DOMAIN").strip()
|
||||
|
||||
_allowed_tags = tags = ['b',
|
||||
'blockquote',
|
||||
|
@ -72,7 +72,7 @@ def a_modify(attrs, new=False):
|
|||
attrs[(None, "rel")] = "nofollow noopener"
|
||||
|
||||
# Force https for all external links in comments
|
||||
# (Drama already forces its own https)
|
||||
# (Website already forces its own https)
|
||||
new_url = ParseResult(scheme="https",
|
||||
netloc=parsed_url.netloc,
|
||||
path=parsed_url.path,
|
||||
|
@ -178,12 +178,12 @@ def sanitize(text, linkgen=False, flair=False):
|
|||
|
||||
start = '<s>'
|
||||
end = '</s>'
|
||||
if start in sanitized and end in sanitized and start in sanitized.split(end)[0] and end in sanitized.split(start)[1]: sanitized = sanitized.replace(start, '<span class="spoiler">').replace(end, '</span>')
|
||||
if start in sanitized and end in sanitized and start in sanitized.split(end)[0] and end in sanitized.split(start)[1]: sanitized = sanitized.replace(start, '<span class="spoiler">').replace(end, '</span>')
|
||||
|
||||
if flair: emojisize = 20
|
||||
else: emojisize = 30
|
||||
for i in re.finditer(':(.{1,30}?):', sanitized):
|
||||
if path.isfile(f'./drama/assets/images/emojis/{i.group(1)}.gif'):
|
||||
if path.isfile(f'./files/assets/images/emojis/{i.group(1)}.gif'):
|
||||
sanitized = sanitized.replace(f':{i.group(1)}:', f'<img data-toggle="tooltip" title="{i.group(1)}" delay="0" height={emojisize} src="https://{site}/assets/images/emojis/{i.group(1)}.gif"<span>')
|
||||
|
||||
sanitized = sanitized.replace("https://www.", "https://").replace("https://youtu.be/", "https://youtube.com/embed/").replace("https://music.youtube.com/watch?v=", "https://youtube.com/embed/").replace("/watch?v=", "/embed/").replace("https://open.spotify.com/", "https://open.spotify.com/embed/").replace("https://streamable.com/", "https://streamable.com/e/").replace("https://youtube.com/shorts/", "https://youtube.com/embed/")
|
|
@ -3,7 +3,7 @@ from sqlalchemy.sql import visitors
|
|||
from werkzeug.wrappers.response import Response as RespObj
|
||||
from .get import *
|
||||
from .alerts import send_notification
|
||||
from drama.__main__ import app
|
||||
from files.__main__ import app
|
||||
|
||||
|
||||
def get_logged_in_user():
|
||||
|
@ -48,7 +48,7 @@ def check_ban_evade(v):
|
|||
|
||||
if random.randint(0,30) < v.ban_evade:
|
||||
v.ban(reason="ban evasion")
|
||||
send_notification(1046, v, "Your Drama account has been permanently suspended for the following reason:\n\n> ban evasion")
|
||||
send_notification(1046, v, "Your account has been permanently suspended for the following reason:\n\n> ban evasion")
|
||||
|
||||
for post in g.db.query(Submission).filter_by(author_id=v.id).all():
|
||||
if post.is_banned:
|
|
@ -4,16 +4,17 @@ import time
|
|||
from flask import *
|
||||
from urllib.parse import quote
|
||||
|
||||
from drama.helpers.security import *
|
||||
from drama.helpers.wrappers import *
|
||||
from drama.classes import *
|
||||
from drama.__main__ import app
|
||||
from files.helpers.security import *
|
||||
from files.helpers.wrappers import *
|
||||
from files.classes import *
|
||||
from files.__main__ import app
|
||||
|
||||
site = environ.get("domain").strip()
|
||||
site = environ.get("DOMAIN").strip()
|
||||
name = environ.get("SITE_NAME").strip()
|
||||
mailgun_domain = environ.get("MAILGUN_DOMAIN").strip()
|
||||
|
||||
def send_mail(to_address, subject, html, plaintext=None, files={},
|
||||
from_address=f"Drama <noreply@mail.{site}>"):
|
||||
from_address=f"{name} <noreply@mail.{site}>"):
|
||||
|
||||
url = f"https://api.mailgun.net/v3/{mailgun_domain}/messages"
|
||||
|
||||
|
@ -49,7 +50,7 @@ def send_verification_email(user, email=None):
|
|||
html=render_template("email/email_verify.html",
|
||||
action_url=link,
|
||||
v=user),
|
||||
subject="Validate your Drama account email."
|
||||
subject=f"Validate your {name} account email."
|
||||
)
|
||||
|
||||
|
|
@ -5,17 +5,17 @@ import imagehash
|
|||
from os import remove
|
||||
from PIL import Image as IMAGE
|
||||
|
||||
from drama.helpers.wrappers import *
|
||||
from drama.helpers.alerts import *
|
||||
from drama.helpers.sanitize import *
|
||||
from drama.helpers.markdown import *
|
||||
from drama.helpers.security import *
|
||||
from drama.helpers.get import *
|
||||
from drama.helpers.images import *
|
||||
from drama.classes import *
|
||||
from files.helpers.wrappers import *
|
||||
from files.helpers.alerts import *
|
||||
from files.helpers.sanitize import *
|
||||
from files.helpers.markdown import *
|
||||
from files.helpers.security import *
|
||||
from files.helpers.get import *
|
||||
from files.helpers.images import *
|
||||
from files.classes import *
|
||||
from flask import *
|
||||
import matplotlib.pyplot as plt
|
||||
from drama.__main__ import app, cache
|
||||
from files.__main__ import app, cache
|
||||
from .front import frontlist
|
||||
|
||||
@app.get("/admin/shadowbanned")
|
||||
|
@ -443,7 +443,7 @@ def admin_image_purge(v):
|
|||
name = request.form.get("url")
|
||||
image = g.db.query(Image).filter(Image.text == name).first()
|
||||
if image:
|
||||
requests.delete(f'https://api.imgur.com/3/image/{image.deletehash}', headers = {"Authorization": f"Client-ID {imgurkey}"})
|
||||
requests.delete(f'https://api.imgur.com/3/image/{image.deletehash}', headers = {"Authorization": f"Client-ID {IMGUR_KEY}"})
|
||||
headers = {"Authorization": f"Bearer {CF_KEY}", "Content-Type": "application/json"}
|
||||
data = {'files': [name]}
|
||||
url = f"https://api.cloudflare.com/client/v4/zones/{CF_ZONE}/purge_cache"
|
||||
|
@ -646,16 +646,16 @@ def ban_user(user_id, v):
|
|||
|
||||
if days > 0:
|
||||
if message:
|
||||
text = f"Your Drama account has been suspended for {days} days for the following reason:\n\n> {message}"
|
||||
text = f"Your account has been suspended for {days} days for the following reason:\n\n> {message}"
|
||||
else:
|
||||
text = f"Your Drama account has been suspended for {days} days."
|
||||
text = f"Your account has been suspended for {days} days."
|
||||
user.ban(admin=v, reason=reason, days=days)
|
||||
|
||||
else:
|
||||
if message:
|
||||
text = f"Your Drama account has been permanently suspended for the following reason:\n\n> {message}"
|
||||
text = f"Your account has been permanently suspended for the following reason:\n\n> {message}"
|
||||
else:
|
||||
text = "Your Drama account has been permanently suspended."
|
||||
text = "Your account has been permanently suspended."
|
||||
|
||||
user.ban(admin=v, reason=reason)
|
||||
|
||||
|
@ -701,7 +701,7 @@ def unban_user(user_id, v):
|
|||
x.unban()
|
||||
|
||||
send_notification(1046, user,
|
||||
"Your Drama account has been reinstated. Please carefully review and abide by the [rules](/post/2510) to ensure that you don't get suspended again.")
|
||||
"Your account has been reinstated. Please carefully review and abide by the [rules](/post/2510) to ensure that you don't get suspended again.")
|
||||
|
||||
ma=ModAction(
|
||||
kind="unexile_user",
|
||||
|
@ -907,7 +907,7 @@ def refund(v):
|
|||
if u.id == 253: continue
|
||||
posts=sum([x[0]+x[1]-1 for x in g.db.query(Submission.upvotes, Submission.downvotes).options(lazyload('*')).filter_by(author_id = u.id, is_banned = False, deleted_utc = 0).all()])
|
||||
comments=sum([x[0]+x[1]-1 for x in g.db.query(Comment.upvotes, Comment.downvotes).options(lazyload('*')).filter_by(author_id = u.id, is_banned = False, deleted_utc = 0).all()])
|
||||
u.dramacoins = int(posts+comments)
|
||||
u.coins = int(posts+comments)
|
||||
g.db.add(u)
|
||||
return "sex"
|
||||
|
||||
|
@ -931,7 +931,7 @@ def admin_banned_domains(v):
|
|||
@validate_formkey
|
||||
def admin_toggle_ban_domain(v):
|
||||
|
||||
domain=request.form.get("domain").strip()
|
||||
domain=request.form.get("DOMAIN").strip()
|
||||
if not domain: abort(400)
|
||||
|
||||
reason=request.form.get("reason", "").strip()
|
|
@ -1,8 +1,8 @@
|
|||
from drama.__main__ import app
|
||||
from drama.helpers.wrappers import *
|
||||
from drama.helpers.alerts import *
|
||||
from drama.helpers.get import *
|
||||
from drama.classes.award import *
|
||||
from files.__main__ import app
|
||||
from files.helpers.wrappers import *
|
||||
from files.helpers.alerts import *
|
||||
from files.helpers.get import *
|
||||
from files.classes.award import *
|
||||
from flask import g, request
|
||||
|
||||
|
||||
|
@ -15,13 +15,12 @@ def banaward_trigger(post=None, comment=None):
|
|||
if not author.is_suspended:
|
||||
author.ban(reason="1-day ban award used", days=1)
|
||||
|
||||
send_notification(1046, author, f"Your Drama account has been suspended for a day for {link}. It sucked and you should feel bad.")
|
||||
send_notification(1046, author, f"Your account has been suspended for a day for {link}. It sucked and you should feel bad.")
|
||||
elif author.unban_utc > 0:
|
||||
author.unban_utc += 24*60*60
|
||||
g.db.add(author)
|
||||
|
||||
send_notification(1046, author,
|
||||
f"Your Drama account has been suspended for yet another day for {link}. Seriously man?")
|
||||
send_notification(1046, author, f"Your account has been suspended for yet another day for {link}. Seriously man?")
|
||||
|
||||
|
||||
ACTIONS = {
|
|
@ -1,19 +1,19 @@
|
|||
import traceback
|
||||
import sys
|
||||
|
||||
from drama.helpers.wrappers import *
|
||||
from drama.helpers.filters import *
|
||||
from drama.helpers.alerts import *
|
||||
from drama.helpers.images import *
|
||||
from drama.helpers.session import *
|
||||
from drama.classes import *
|
||||
from drama.routes.front import comment_idlist
|
||||
from files.helpers.wrappers import *
|
||||
from files.helpers.filters import *
|
||||
from files.helpers.alerts import *
|
||||
from files.helpers.images import *
|
||||
from files.helpers.session import *
|
||||
from files.classes import *
|
||||
from files.routes.front import comment_idlist
|
||||
from pusher_push_notifications import PushNotifications, PusherAuthError
|
||||
|
||||
from flask import *
|
||||
from drama.__main__ import app, limiter
|
||||
from files.__main__ import app, limiter
|
||||
|
||||
site = environ.get("domain").strip()
|
||||
site = environ.get("DOMAIN").strip()
|
||||
|
||||
choices = ['Wow, you must be a JP fan.', 'This is one of the worst posts I have EVER seen. Delete it.', "No, don't reply like this, please do another wall of unhinged rant please.", '# 😴😴😴', "Ma'am we've been over this before. You need to stop.", "I've known more coherent downies.", "Your pulitzer's in the mail", "That's great and all, but I asked for my burger without cheese.", 'That degree finally paying off', "That's nice sweaty. Why don't you have a seat in the time out corner with Pizzashill until you calm down, then you can have your Capri Sun.", "All them words won't bring your pa back.", "You had a chance to not be completely worthless, but it looks like you threw it away. At least you're consistent.", 'Some people are able to display their intelligence by going on at length on a subject and never actually saying anything. This ability is most common in trades such as politics, public relations, and law. You have impressed me by being able to best them all, while still coming off as an absolute idiot.', "You can type 10,000 characters and you decided that these were the one's that you wanted.", 'Have you owned the libs yet?', "I don't know what you said, because I've seen another human naked.", 'Impressive. Normally people with such severe developmental disabilities struggle to write much more than a sentence or two. He really has exceded our expectations for the writing portion. Sadly the coherency of his writing, along with his abilities in the social skills and reading portions, are far behind his peers with similar disabilities.', "This is a really long way of saying you don't fuck.", "Sorry ma'am, looks like his delusions have gotten worse. We'll have to admit him,", '![](https://i.kym-cdn.com/photos/images/newsfeed/001/038/094/0a1.jpg)', 'If only you could put that energy into your relationships', 'Posts like this is why I do Heroine.', 'still unemployed then?', 'K', 'look im gunna have 2 ask u 2 keep ur giant dumps in the toilet not in my replys 😷😷😷', "Mommy is soooo proud of you, sweaty. Let's put this sperg out up on the fridge with all your other failures.", "Good job bobby, here's a star", "That was a mistake. You're about to find out the hard way why.", 'You sat down and wrote all this shit. You could have done so many other things with your life. What happened to your life that made you decide writing novels of bullshit on reddit was the best option?', "I don't have enough spoons to read this shit", "All those words won't bring daddy back.", 'OUT!', "Mommy is soooo proud of you, sweaty. Let's put this sperg out up on the fridge with all your other failures."]
|
||||
|
||||
|
@ -259,7 +259,7 @@ def api_comment(v):
|
|||
threshold *= 2
|
||||
|
||||
if len(similar_comments) > threshold:
|
||||
text = "Your Drama account has been suspended for 1 day for the following reason:\n\n> Too much spam!"
|
||||
text = "Your account has been suspended for 1 day for the following reason:\n\n> Too much spam!"
|
||||
send_notification(1046, v, text)
|
||||
|
||||
v.ban(reason="Spamming.",
|
||||
|
@ -539,7 +539,7 @@ def api_comment(v):
|
|||
},
|
||||
)
|
||||
except PusherAuthError as e:
|
||||
traceback.print_tb(e.__traceback__)
|
||||
sys.stderr.write(traceback.format_exc())
|
||||
sys.stderr.flush()
|
||||
|
||||
|
||||
|
@ -656,7 +656,7 @@ def edit_comment(cid, v):
|
|||
threshold *= 2
|
||||
|
||||
if len(similar_comments) > threshold:
|
||||
text = "Your Drama account has been suspended for 1 day for the following reason:\n\n> Too much spam!"
|
||||
text = "Your account has been suspended for 1 day for the following reason:\n\n> Too much spam!"
|
||||
send_notification(1046, v, text)
|
||||
|
||||
v.ban(reason="Spamming.",
|
|
@ -1,15 +1,14 @@
|
|||
from drama.helpers.wrappers import *
|
||||
from drama.helpers.security import *
|
||||
from drama.helpers.discord import add_role
|
||||
from drama.__main__ import app
|
||||
from files.helpers.wrappers import *
|
||||
from files.helpers.security import *
|
||||
from files.helpers.discord import add_role
|
||||
from files.__main__ import app
|
||||
|
||||
SERVER_ID = environ.get("DISCORD_SERVER_ID",'').strip()
|
||||
CLIENT_ID = environ.get("DISCORD_CLIENT_ID",'').strip()
|
||||
CLIENT_SECRET = environ.get("DISCORD_CLIENT_SECRET",'').strip()
|
||||
BOT_TOKEN = environ.get("DISCORD_BOT_TOKEN").strip()
|
||||
COINS_NAME = environ.get("COINS_NAME").strip()
|
||||
DISCORD_ENDPOINT = "https://discordapp.com/api/v6"
|
||||
|
||||
|
||||
WELCOME_CHANNEL="846509313941700618"
|
||||
|
||||
@app.get("/discord")
|
||||
|
@ -17,7 +16,7 @@ WELCOME_CHANNEL="846509313941700618"
|
|||
def join_discord(v):
|
||||
|
||||
if v.is_banned != 0: return "You're banned"
|
||||
if v.admin_level == 0 and v.dramacoins < 150: return "You must earn 150 dramacoins before entering the Discord server. You earn dramacoins by making posts/comments and getting upvoted."
|
||||
if v.admin_level == 0 and v.coins < 150: return f"You must earn 150 {COINS_NAME} before entering the Discord server. You earn {COINS_NAME} by making posts/comments and getting upvoted."
|
||||
|
||||
now=int(time.time())
|
||||
|
||||
|
@ -126,7 +125,7 @@ def discord_redirect(v):
|
|||
|
||||
time.sleep(0.1)
|
||||
|
||||
if v.dramacoins > 100: add_role(v, "linked")
|
||||
if v.coins > 100: add_role(v, "linked")
|
||||
else: add_role(v, "norep")
|
||||
|
||||
else:
|
|
@ -1,11 +1,11 @@
|
|||
import jinja2.exceptions
|
||||
|
||||
from drama.helpers.wrappers import *
|
||||
from drama.helpers.session import *
|
||||
from files.helpers.wrappers import *
|
||||
from files.helpers.session import *
|
||||
from flask import *
|
||||
from urllib.parse import quote, urlencode
|
||||
import time
|
||||
from drama.__main__ import app
|
||||
from files.__main__ import app
|
||||
|
||||
# Errors
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
import html
|
||||
from .front import frontlist
|
||||
from datetime import datetime
|
||||
from drama.helpers.jinja2 import full_link
|
||||
from drama.helpers.get import *
|
||||
from files.helpers.jinja2 import full_link
|
||||
from files.helpers.get import *
|
||||
from yattag import Doc
|
||||
|
||||
from drama.__main__ import app
|
||||
from files.__main__ import app
|
||||
|
||||
@app.get('/rss/<sort>/<t>')
|
||||
def feeds_user(sort='hot', t='all'):
|
|
@ -1,8 +1,8 @@
|
|||
from drama.helpers.wrappers import *
|
||||
from drama.helpers.get import *
|
||||
from files.helpers.wrappers import *
|
||||
from files.helpers.get import *
|
||||
from flask import g
|
||||
from drama.__main__ import app
|
||||
from drama.helpers.sanitize import sanitize
|
||||
from files.__main__ import app
|
||||
from files.helpers.sanitize import sanitize
|
||||
|
||||
@app.post("/flag/post/<pid>")
|
||||
@auth_desired
|
||||
|
@ -11,11 +11,10 @@ def api_flag_post(pid, v):
|
|||
post = get_post(pid)
|
||||
|
||||
if v:
|
||||
existing = g.db.query(Flag).filter_by(
|
||||
user_id=v.id, post_id=post.id).first()
|
||||
existing = g.db.query(Flag).filter_by(user_id=v.id, post_id=post.id).first()
|
||||
|
||||
if existing: return "", 409
|
||||
reason = sanitize(request.form.get("reason", "")[:100].strip(), flair=True)
|
||||
reason = sanitize(request.form.get("reason", "").strip()[:100], flair=True)
|
||||
|
||||
flag = Flag(post_id=post.id,
|
||||
user_id=v.id,
|
|
@ -1,8 +1,8 @@
|
|||
from drama.helpers.wrappers import *
|
||||
from drama.helpers.get import *
|
||||
from files.helpers.wrappers import *
|
||||
from files.helpers.get import *
|
||||
|
||||
from drama.__main__ import app, cache
|
||||
from drama.classes.submission import Submission
|
||||
from files.__main__ import app, cache
|
||||
from files.classes.submission import Submission
|
||||
|
||||
@app.get("/post/")
|
||||
def slash_post():
|
|
@ -1,6 +1,6 @@
|
|||
from urllib.parse import urlencode
|
||||
from drama.mail import *
|
||||
from drama.__main__ import app, limiter
|
||||
from files.mail import *
|
||||
from files.__main__ import app, limiter
|
||||
|
||||
valid_username_regex = re.compile("^[a-zA-Z0-9_\-]{3,25}$")
|
||||
valid_password_regex = re.compile("^.{8,100}$")
|
||||
|
@ -135,8 +135,8 @@ def login_post():
|
|||
@app.get("/@me")
|
||||
@auth_required
|
||||
def me(v):
|
||||
if request.headers.get("Authorization"): v.json
|
||||
else: redirect(v.url)
|
||||
if request.headers.get("Authorization"): return v.json
|
||||
else: return redirect(v.url)
|
||||
|
||||
|
||||
@app.post("/logout")
|
||||
|
@ -404,7 +404,7 @@ def post_forgot():
|
|||
url = f"https://{app.config['SERVER_NAME']}/reset?id={user.id}&time={now}&token={token}"
|
||||
|
||||
send_mail(to_address=user.email,
|
||||
subject="Drama - Password Reset Request",
|
||||
subject="Password Reset Request",
|
||||
html=render_template("email/password_reset.html",
|
||||
action_url=url,
|
||||
v=user)
|
||||
|
@ -537,7 +537,7 @@ def request_2fa_disable():
|
|||
action_url=f"https://{app.config['SERVER_NAME']}/reset_2fa?id={user.id}&t={valid}&token={token}"
|
||||
|
||||
send_mail(to_address=user.email,
|
||||
subject="Drama - 2FA Removal Request",
|
||||
subject="2FA Removal Request",
|
||||
html=render_template("email/2fa_remove.html",
|
||||
action_url=action_url,
|
||||
v=user)
|
|
@ -1,9 +1,9 @@
|
|||
from drama.helpers.wrappers import *
|
||||
from drama.helpers.alerts import *
|
||||
from drama.helpers.get import *
|
||||
from drama.classes import *
|
||||
from files.helpers.wrappers import *
|
||||
from files.helpers.alerts import *
|
||||
from files.helpers.get import *
|
||||
from files.classes import *
|
||||
from flask import *
|
||||
from drama.__main__ import app
|
||||
from files.__main__ import app
|
||||
|
||||
@app.get("/authorize")
|
||||
@auth_required
|
|
@ -3,22 +3,22 @@ import mistletoe
|
|||
import urllib.parse
|
||||
import gevent
|
||||
|
||||
from drama.helpers.wrappers import *
|
||||
from drama.helpers.sanitize import *
|
||||
from drama.helpers.filters import *
|
||||
from drama.helpers.markdown import *
|
||||
from drama.helpers.session import *
|
||||
from drama.helpers.thumbs import *
|
||||
from drama.helpers.alerts import send_notification
|
||||
from drama.helpers.discord import send_message
|
||||
from drama.classes import *
|
||||
from files.helpers.wrappers import *
|
||||
from files.helpers.sanitize import *
|
||||
from files.helpers.filters import *
|
||||
from files.helpers.markdown import *
|
||||
from files.helpers.session import *
|
||||
from files.helpers.thumbs import *
|
||||
from files.helpers.alerts import send_notification
|
||||
from files.helpers.discord import send_message
|
||||
from files.classes import *
|
||||
from flask import *
|
||||
from io import BytesIO
|
||||
from drama.__main__ import app, limiter, cache
|
||||
from files.__main__ import app, limiter, cache
|
||||
from PIL import Image as PILimage
|
||||
from .front import frontlist
|
||||
|
||||
site = environ.get("domain").strip()
|
||||
site = environ.get("DOMAIN").strip()
|
||||
|
||||
with open("snappy.txt", "r") as f: snappyquotes = f.read().split("{[para]}")
|
||||
|
||||
|
@ -266,7 +266,7 @@ def edit_post(pid, v):
|
|||
BadLink.link)).first()
|
||||
if badlink:
|
||||
if badlink.autoban:
|
||||
text = "Your Drama account has been suspended for 1 day for the following reason:\n\n> Too much spam!"
|
||||
text = "Your account has been suspended for 1 day for the following reason:\n\n> Too much spam!"
|
||||
send_notification(1046, v, text)
|
||||
v.ban(days=1, reason="spam")
|
||||
|
||||
|
@ -422,7 +422,6 @@ def thumbs(new_post):
|
|||
|
||||
#iterate through desired meta tags
|
||||
meta_tags = [
|
||||
"drama:thumbnail",
|
||||
"twitter:image",
|
||||
"og:image",
|
||||
"thumbnail"
|
||||
|
@ -508,6 +507,22 @@ def archiveorg(url):
|
|||
except Exception as e: print(e)
|
||||
|
||||
|
||||
@app.route("/embed/post/<pid>", methods=["GET"])
|
||||
def embed_post_pid(pid):
|
||||
|
||||
post = get_post(pid)
|
||||
|
||||
return render_template("embeds/post.html", p=post)
|
||||
|
||||
|
||||
@app.route("/embed/comment/<cid>", methods=["GET"])
|
||||
def embed_comment_cid(cid, pid=None):
|
||||
|
||||
comment = get_comment(cid)
|
||||
|
||||
return render_template("embeds/comment.html", c=comment)
|
||||
|
||||
|
||||
@app.post("/submit")
|
||||
@limiter.limit("6/minute")
|
||||
@is_not_banned
|
||||
|
@ -604,8 +619,9 @@ def submit_post(v):
|
|||
else: return render_template("submit.html", v=v, error="ToS Violation", title=title, url=url, body=request.form.get("body", "")), 400
|
||||
|
||||
if "twitter.com" in domain:
|
||||
embed = requests.get("https://publish.twitter.com/oembed", params={"url":url, "omit_script":"t"}).json()["html"]
|
||||
|
||||
try: embed = requests.get("https://publish.twitter.com/oembed", params={"url":url, "omit_script":"t"}).json()["html"]
|
||||
except: embed = None
|
||||
|
||||
elif "youtu" in domain:
|
||||
yt_id = re.match(re.compile("^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|shorts\/|\&v=)([^#\&\?]*).*"), url).group(2)
|
||||
if not yt_id or len(yt_id) != 11: embed = None
|
||||
|
@ -616,7 +632,7 @@ def submit_post(v):
|
|||
else: embed = f"https://youtube.com/embed/{yt_id}"
|
||||
|
||||
elif "instagram.com" in domain:
|
||||
embed = requests.get("https://graph.facebook.com/v9.0/instagram_oembed", params={"url":url,"access_token":environ.get("FACEBOOK_TOKEN","").strip(),"omitscript":'true'}, headers={"User-Agent":"Instagram embedder for Drama"}).json()["html"]
|
||||
embed = requests.get("https://graph.facebook.com/v9.0/instagram_oembed", params={"url":url,"access_token":environ.get("FACEBOOK_TOKEN","").strip(),"omitscript":'true'}, headers={"User-Agent": app.config["UserAgent"]}).json()["html"]
|
||||
|
||||
elif app.config['SERVER_NAME'] in domain:
|
||||
try:
|
||||
|
@ -681,7 +697,7 @@ def submit_post(v):
|
|||
|
||||
if max(len(similar_urls), len(similar_posts)) >= threshold:
|
||||
|
||||
text = "Your Drama account has been suspended for 1 day for the following reason:\n\n> Too much spam!"
|
||||
text = "Your account has been suspended for 1 day for the following reason:\n\n> Too much spam!"
|
||||
send_notification(1046, v, text)
|
||||
|
||||
v.ban(reason="Spamming.",
|
||||
|
@ -761,7 +777,7 @@ def submit_post(v):
|
|||
BadLink.link)).first()
|
||||
if badlink:
|
||||
if badlink.autoban:
|
||||
text = "Your Drama account has been suspended for 1 day for the following reason:\n\n> Too much spam!"
|
||||
text = "Your account has been suspended for 1 day for the following reason:\n\n> Too much spam!"
|
||||
send_notification(1046, v, text)
|
||||
v.ban(days=1, reason="spam")
|
||||
|
||||
|
@ -789,7 +805,7 @@ def submit_post(v):
|
|||
|
||||
url = url.replace("https://mobile.twitter.com", "https://twitter.com")
|
||||
|
||||
if url.startswith("https://old.reddit.com/") and '/comments/' in url and '?sort=' not in url: url += "?sort=controversial"
|
||||
# if url.startswith("https://old.reddit.com/") and '/comments/' in url and '?' not in url: url += "?sort=controversial"
|
||||
|
||||
title_html = sanitize(title, linkgen=True, flair=True)
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
from drama.helpers.wrappers import *
|
||||
from files.helpers.wrappers import *
|
||||
import re
|
||||
from sqlalchemy import *
|
||||
from flask import *
|
||||
from drama.__main__ import app, cache
|
||||
from files.__main__ import app, cache
|
||||
import random
|
||||
|
||||
query_regex=re.compile("(\w+):(\S+)")
|
|
@ -1,11 +1,11 @@
|
|||
from __future__ import unicode_literals
|
||||
from drama.helpers.alerts import *
|
||||
from drama.helpers.sanitize import *
|
||||
from drama.helpers.filters import filter_comment_html
|
||||
from drama.helpers.markdown import *
|
||||
from drama.helpers.discord import remove_user, set_nick
|
||||
from drama.mail import *
|
||||
from drama.__main__ import app, cache
|
||||
from files.helpers.alerts import *
|
||||
from files.helpers.sanitize import *
|
||||
from files.helpers.filters import filter_comment_html
|
||||
from files.helpers.markdown import *
|
||||
from files.helpers.discord import remove_user, set_nick
|
||||
from files.mail import *
|
||||
from files.__main__ import app, cache
|
||||
import youtube_dl
|
||||
from .front import frontlist
|
||||
|
||||
|
@ -13,7 +13,8 @@ valid_username_regex = re.compile("^[a-zA-Z0-9_\-]{3,25}$")
|
|||
valid_title_regex = re.compile("^((?!<).){3,100}$")
|
||||
valid_password_regex = re.compile("^.{8,100}$")
|
||||
|
||||
youtubekey = environ.get("youtubekey").strip()
|
||||
YOUTUBE_KEY = environ.get("YOUTUBE_KEY").strip()
|
||||
COINS_NAME = environ.get("COINS_NAME").strip()
|
||||
|
||||
@app.post("/settings/profile")
|
||||
@auth_required
|
||||
|
@ -51,7 +52,7 @@ def settings_profile_post(v):
|
|||
|
||||
if request.values.get("animatedname", v.animatedname) != v.animatedname:
|
||||
if v.animatedname == False:
|
||||
users = g.db.query(User.id).options(lazyload('*')).order_by(User.dramacoins.desc()).limit(25).all()
|
||||
users = g.db.query(User.id).options(lazyload('*')).order_by(User.coins.desc()).limit(25).all()
|
||||
users = [x[0] for x in users]
|
||||
if v.id not in users: return {"error": "You must be in the top 25 leaderboard or be a patron to apply an animated name!"}, 403
|
||||
updated = True
|
||||
|
@ -425,13 +426,13 @@ def settings_css(v):
|
|||
@auth_required
|
||||
def settings_profilecss_get(v):
|
||||
if v and v.is_banned and not v.unban_utc: return render_template("seized.html")
|
||||
if v.dramacoins < 1000 and not v.patron: return "You must have +1000 dramacoins or be a patron to set profile css."
|
||||
if v.coins < 1000 and not v.patron: return f"You must have +1000 {COINS_NAME} or be a patron to set profile css."
|
||||
return render_template("settings_profilecss.html", v=v)
|
||||
|
||||
@app.post("/settings/profilecss")
|
||||
@auth_required
|
||||
def settings_profilecss(v):
|
||||
if v.dramacoins < 1000 and not v.patron: return "You must have +1000 dramacoins or be a patron to set profile css."
|
||||
if v.coins < 1000 and not v.patron: return f"You must have +1000 {COINS_NAME} or be a patron to set profile css."
|
||||
profilecss = request.form.get("profilecss").replace('\\', '')[:50000]
|
||||
v.profilecss = profilecss
|
||||
g.db.add(v)
|
||||
|
@ -454,7 +455,7 @@ def settings_block_user(v):
|
|||
return {"error": f"You have already blocked @{user.username}."}, 409
|
||||
|
||||
if user.id == 1046:
|
||||
return {"error": "You can't block @Drama."}, 409
|
||||
return {"error": "You can't block @files."}, 409
|
||||
|
||||
new_block = UserBlock(user_id=v.id,
|
||||
target_id=user.id,
|
||||
|
@ -613,7 +614,7 @@ def settings_song_change(v):
|
|||
return redirect("/settings/profile")
|
||||
|
||||
|
||||
req = requests.get(f"https://www.googleapis.com/youtube/v3/videos?id={id}&key={youtubekey}&part=contentDetails").json()
|
||||
req = requests.get(f"https://www.googleapis.com/youtube/v3/videos?id={id}&key={YOUTUBE_KEY}&part=contentDetails").json()
|
||||
try: duration = req['items'][0]['contentDetails']['duration']
|
||||
except:
|
||||
print(req)
|
|
@ -1,8 +1,8 @@
|
|||
from drama.mail import *
|
||||
from drama.__main__ import app, limiter
|
||||
from drama.helpers.alerts import *
|
||||
from files.mail import *
|
||||
from files.__main__ import app, limiter
|
||||
from files.helpers.alerts import *
|
||||
|
||||
site = environ.get("domain").strip()
|
||||
site = environ.get("DOMAIN").strip()
|
||||
|
||||
@app.get("/patrons")
|
||||
@auth_desired
|
||||
|
@ -14,7 +14,7 @@ def patrons(v):
|
|||
@app.get("/badmins")
|
||||
@auth_desired
|
||||
def badmins(v):
|
||||
badmins = g.db.query(User).filter_by(admin_level=6).order_by(User.dramacoins.desc()).all()
|
||||
badmins = g.db.query(User).filter_by(admin_level=6).order_by(User.coins.desc()).all()
|
||||
return render_template("badmins.html", v=v, badmins=badmins)
|
||||
|
||||
@app.get("/log")
|
|
@ -4,16 +4,16 @@ import time
|
|||
import traceback
|
||||
import sys
|
||||
|
||||
from drama.classes.user import ViewerRelationship
|
||||
from drama.helpers.alerts import *
|
||||
from drama.helpers.sanitize import *
|
||||
from drama.helpers.markdown import *
|
||||
from drama.mail import *
|
||||
from files.classes.user import ViewerRelationship
|
||||
from files.helpers.alerts import *
|
||||
from files.helpers.sanitize import *
|
||||
from files.helpers.markdown import *
|
||||
from files.mail import *
|
||||
from flask import *
|
||||
from drama.__main__ import app, limiter
|
||||
from files.__main__ import app, limiter
|
||||
from pusher_push_notifications import PushNotifications, PusherAuthError
|
||||
|
||||
site = environ.get("domain").strip()
|
||||
site = environ.get("DOMAIN").strip()
|
||||
|
||||
PUSHER_KEY = environ.get("PUSHER_KEY", "").strip()
|
||||
|
||||
|
@ -28,7 +28,7 @@ def suicide(v, username):
|
|||
t = int(time.time())
|
||||
if v.admin_level == 0 and t - v.suicide_utc < 86400: return "", 204
|
||||
user = get_user(username)
|
||||
suicide = f"Hi there,\n\nA [concerned dramatard]({v.url}) reached out to us about you.\n\nWhen you're in the middle of something painful, it may feel like you don't have a lot of options. But whatever you're going through, you deserve help and there are people who are here for you.\n\nThere are resources available in your area that are free, confidential, and available 24/7:\n\n- Call, Text, or Chat with Canada's [Crisis Services Canada](https://www.crisisservicescanada.ca/en/)\n- Call, Email, or Visit the UK's [Samaritans](https://www.samaritans.org/)\n- Text CHAT to America's [Crisis Text Line](https://www.crisistextline.org/) at 741741.\nIf you don't see a resource in your area above, the moderators at r/SuicideWatch keep a comprehensive list of resources and hotlines for people organized by location. Find Someone Now\n\nIf you think you may be depressed or struggling in another way, don't ignore it or brush it aside. Take yourself and your feelings seriously, and reach out to someone.\n\nIt may not feel like it, but you have options. There are people available to listen to you, and ways to move forward.\n\nYour fellow dramatards care about you and there are people who want to help."
|
||||
suicide = f"Hi there,\n\nA [concerned user]({v.url}) reached out to us about you.\n\nWhen you're in the middle of something painful, it may feel like you don't have a lot of options. But whatever you're going through, you deserve help and there are people who are here for you.\n\nThere are resources available in your area that are free, confidential, and available 24/7:\n\n- Call, Text, or Chat with Canada's [Crisis Services Canada](https://www.crisisservicescanada.ca/en/)\n- Call, Email, or Visit the UK's [Samaritans](https://www.samaritans.org/)\n- Text CHAT to America's [Crisis Text Line](https://www.crisistextline.org/) at 741741.\nIf you don't see a resource in your area above, the moderators at r/SuicideWatch keep a comprehensive list of resources and hotlines for people organized by location. Find Someone Now\n\nIf you think you may be depressed or struggling in another way, don't ignore it or brush it aside. Take yourself and your feelings seriously, and reach out to someone.\n\nIt may not feel like it, but you have options. There are people available to listen to you, and ways to move forward.\n\nYour fellow users care about you and there are people who want to help."
|
||||
send_notification(1046, user, suicide)
|
||||
v.suicide_utc = t
|
||||
g.db.add(v)
|
||||
|
@ -39,7 +39,7 @@ def suicide(v, username):
|
|||
def leaderboard(v):
|
||||
if v and v.is_banned and not v.unban_utc:return render_template("seized.html")
|
||||
users = g.db.query(User).options(lazyload('*'))
|
||||
users1 = users.order_by(User.dramacoins.desc()).limit(25).all()
|
||||
users1 = users.order_by(User.coins.desc()).limit(25).all()
|
||||
users2 = users.order_by(User.stored_subscriber_count.desc()).limit(10).all()
|
||||
users3 = users.order_by(User.post_count.desc()).limit(10).all()
|
||||
users4 = users.order_by(User.comment_count.desc()).limit(10).all()
|
||||
|
@ -159,7 +159,7 @@ def message2(v, username):
|
|||
},
|
||||
)
|
||||
except PusherAuthError as e:
|
||||
traceback.print_tb(e.__traceback__)
|
||||
sys.stderr.write(traceback.format_exc())
|
||||
sys.stderr.flush()
|
||||
|
||||
return redirect('/notifications?all=true')
|
||||
|
@ -171,7 +171,7 @@ def mfa_qr(secret, v):
|
|||
qr = qrcode.QRCode(
|
||||
error_correction=qrcode.constants.ERROR_CORRECT_L
|
||||
)
|
||||
qr.add_data(x.provisioning_uri(v.username, issuer_name="Drama"))
|
||||
qr.add_data(x.provisioning_uri(v.username, issuer_name=app.config["SITE_NAME"]))
|
||||
img = qr.make_image(fill_color="#000000", back_color="white")
|
||||
|
||||
mem = io.BytesIO()
|
||||
|
@ -284,11 +284,11 @@ def u_username(username, v=None):
|
|||
# paidrent = False
|
||||
# if v and u.id == 253:
|
||||
# if int(time.time()) - v.rent_utc < 600: paidrent = True
|
||||
# elif request.args.get("rent") == "true" and v.dramacoins > 500:
|
||||
# v.dramacoins -= 500
|
||||
# elif request.args.get("rent") == "true" and v.coins > 500:
|
||||
# v.coins -= 500
|
||||
# v.rent_utc = int(time.time())
|
||||
# g.db.add(v)
|
||||
# u.dramacoins += 500
|
||||
# u.coins += 500
|
||||
# g.db.add(u)
|
||||
# send_notification(1046, u, f"@{v.username} has paid rent!")
|
||||
# paidrent = True
|
||||
|
@ -386,11 +386,11 @@ def u_username_comments(username, v=None):
|
|||
# paidrent = False
|
||||
# if v and u.id == 253:
|
||||
# if int(time.time()) - v.rent_utc < 600: paidrent = True
|
||||
# elif request.args.get("rent") == "true" and v.dramacoins > 500:
|
||||
# v.dramacoins -= 500
|
||||
# elif request.args.get("rent") == "true" and v.coins > 500:
|
||||
# v.coins -= 500
|
||||
# v.rent_utc = int(time.time())
|
||||
# g.db.add(v)
|
||||
# u.dramacoins += 500
|
||||
# u.coins += 500
|
||||
# g.db.add(u)
|
||||
# send_notification(1046, u, f"@{v.username} has paid rent!")
|
||||
# paidrent = True
|
|
@ -1,8 +1,8 @@
|
|||
from drama.helpers.wrappers import *
|
||||
from drama.helpers.get import *
|
||||
from drama.classes import *
|
||||
from files.helpers.wrappers import *
|
||||
from files.helpers.get import *
|
||||
from files.classes import *
|
||||
from flask import *
|
||||
from drama.__main__ import app
|
||||
from files.__main__ import app
|
||||
|
||||
|
||||
@app.get("/votes")
|
||||
|
@ -73,16 +73,16 @@ def api_vote_post(post_id, new, v):
|
|||
|
||||
if existing:
|
||||
if existing.vote_type == 0 and new != 0:
|
||||
post.author.dramacoins += 1
|
||||
post.author.coins += 1
|
||||
g.db.add(post.author)
|
||||
elif existing.vote_type != 0 and new == 0:
|
||||
post.author.dramacoins -= 1
|
||||
post.author.coins -= 1
|
||||
g.db.add(post.author)
|
||||
existing.vote_type = new
|
||||
g.db.add(existing)
|
||||
else:
|
||||
if new != 0:
|
||||
post.author.dramacoins += 1
|
||||
post.author.coins += 1
|
||||
g.db.add(post.author)
|
||||
vote = Vote(user_id=v.id,
|
||||
vote_type=new,
|
||||
|
@ -121,16 +121,16 @@ def api_vote_comment(comment_id, new, v):
|
|||
|
||||
if existing:
|
||||
if existing.vote_type == 0 and new != 0:
|
||||
comment.author.dramacoins += 1
|
||||
comment.author.coins += 1
|
||||
g.db.add(comment.author)
|
||||
elif existing.vote_type != 0 and new == 0:
|
||||
comment.author.dramacoins -= 1
|
||||
comment.author.coins -= 1
|
||||
g.db.add(comment.author)
|
||||
existing.vote_type = new
|
||||
g.db.add(existing)
|
||||
else:
|
||||
if new != 0:
|
||||
comment.author.dramacoins += 1
|
||||
comment.author.coins += 1
|
||||
g.db.add(comment.author)
|
||||
vote = CommentVote(user_id=v.id,
|
||||
vote_type=new,
|
|
@ -43,7 +43,7 @@ Python example:
|
|||
|
||||
headers={"Authorization": "access_token_goes_here", "User-Agent": "sex"}
|
||||
|
||||
url="https://rdrama.net/@carpathianflorist"
|
||||
url="{{request.host_url}}@carpathianflorist"
|
||||
|
||||
r=requests.get(url, headers=headers)
|
||||
|
||||
|
@ -93,7 +93,7 @@ DO NOT reveal your Client ID or Access Token. Anyone with these information will
|
|||
|
||||
## Step 2: Prompt Your User for Authorization
|
||||
|
||||
Send your user to `https://rdrama.net/authorize/?client_id=YOUR_CLIENT_ID`
|
||||
Send your user to `{{request.host_url}}authorize/?client_id=YOUR_CLIENT_ID`
|
||||
|
||||
If done correctly, the user will see that your application wants to access their {{"SITE_NAME" | app_config}} account, and be prompted to approve or deny the request.
|
||||
|
||||
|
@ -112,7 +112,7 @@ Python example:
|
|||
|
||||
headers={"Authorization": "access_token_goes_here", "User-Agent": "sex"}
|
||||
|
||||
url="https://rdrama.net/@carpathianflorist"
|
||||
url="{{request.host_url}}@carpathianflorist"
|
||||
|
||||
r=requests.get(url, headers=headers)
|
||||
|
|
@ -5,10 +5,10 @@
|
|||
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta name="description" content="{% block pagedesc %}{{"SITE_NAME" | app_config}} - the free speech social platform{% endblock %}">
|
||||
<meta name="description" content="{% block pagedesc %}{{"SITE_NAME" | app_config}}{% endblock %}">
|
||||
<meta name="author" content="">
|
||||
|
||||
<title>{% block pagetitle %}{{"SITE_NAME" | app_config}} - the open, free-speech social platform{% endblock %}</title>
|
||||
<title>{% block pagetitle %}{{"SITE_NAME" | app_config}}{% endblock %}</title>
|
||||
|
||||
<link href="https://fonts.googleapis.com/css?family=Open+Sans:400,600&display=swap" rel="stylesheet">
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
{% for user in badmins %}
|
||||
<tr>
|
||||
<td><a {% if user.animatedname %}class="{% if user.patron %}patron{% else %}leaderboard{% endif %}"{% endif %} style="color:#{{user.namecolor}}; font-weight:bold;" href="/@{{user.username}}"><img src="/uid/{{user.id}}/pic/profile" class="profile-pic-20 mr-1">{{user.username}}</a></td>
|
||||
<td style="font-weight:bold; text-align:right;">{{user.dramacoins}}</td>
|
||||
<td style="font-weight:bold; text-align:right;">{{user.coins}}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
|
@ -9,15 +9,6 @@
|
|||
{% block content %}
|
||||
<div class="">
|
||||
|
||||
<h1>Whoops!</h1>
|
||||
<p class="text-left">Although {{"SITE_NAME" | app_config}} puts your freedom of speech first, there are a few things that we don't allow here:</p>
|
||||
<ul>
|
||||
<li>Digitally malicious content</li>
|
||||
<li>URL shorteners</li>
|
||||
<li>Copyright infringement</li>
|
||||
<li>Spam</li>
|
||||
</ul>
|
||||
|
||||
<p>Please remove the following link(s) from your comment, and then you will be able to post it:</p>
|
||||
|
||||
<ul>
|
|
@ -807,13 +807,13 @@
|
|||
<meta property="og:image" content="{{'/assets/images/preview.png' | full_link}}" />
|
||||
<meta property="og:url" content="{{request.path | full_link}}">
|
||||
<meta property="og:description" name="description" content="Dude bussy lmao">
|
||||
<meta property="og:author" name="author" content="@drama" />
|
||||
<meta property="og:author" name="author" content="@{{request.host_url}}" />
|
||||
<meta property="og:site_name" content="{{request.host}}" />
|
||||
|
||||
<meta name="twitter:card" content="summary_large_image"/>
|
||||
<meta name="twitter:site" content="@drama">
|
||||
<meta name="twitter:site" content="@{{request.host_url}}">
|
||||
<meta name="twitter:title" content="{{"SITE_NAME" | app_config}}" />
|
||||
<meta name="twitter:creator" content="@drama">
|
||||
<meta name="twitter:creator" content="@{{request.host_url}}">
|
||||
<meta name="twitter:description" content="Dude bussy lmao" />
|
||||
<meta name="twitter:image" content="/assets/images/preview.png" />
|
||||
<meta name="twitter:url" content="{{request.path | full_link}}" />
|
|
@ -0,0 +1,122 @@
|
|||
{% extends "embeds/embed_default.html" %}
|
||||
|
||||
{% set score=c.score_fuzzed %}
|
||||
|
||||
{% block title %}
|
||||
<title>@{{ c.author.username }} comments on "{{ c.post.title }}"</title>
|
||||
<meta name="description" content="{{ c.body }}">
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block content %}
|
||||
<div class="post-info font-weight-bold">
|
||||
<span class="align-top"><a href="{{ c.permalink }}?context=1">{{ c.post.title | safe }}</a></span>
|
||||
</div>
|
||||
|
||||
<div id="comment-{{ c.base36id }}" class="comment rounded">
|
||||
|
||||
<span class="mr-2 d-block d-md-none"><a href="{{ c.author.permalink }}"><img src="{{ c.author.profile_url }}" class="profile-pic-25"></a></span>
|
||||
|
||||
<span class="comment-collapse d-md-block d-none" onclick="collapse_comment('{{ c.base36id }}')"></span>
|
||||
|
||||
<div class="comment-body">
|
||||
|
||||
<div id="comment-{{ c.base36id }}-only">
|
||||
|
||||
<div class="user-info">{% if c.over_18 %}<span class="badge badge-danger">nsfw</span> {% endif %}{% if c.author.title and c.author.title.is_before %}<span style="color:#{{ c.author.title.color }}">{{ c.author.title.text }}</span> {% endif %}<a href="{{ c.author.permalink }}" class="user-name {% if c.post.author_id==c.author_id %}text-info{% endif %}">{{ c.author.username }}</a>{% if c.author.title and not c.author.title.is_before %}<span style="color:#{{ c.author.title.color }}">{{ c.author.title.text }}</span>{% endif %}
|
||||
{% if c.distinguish_level or c.author_id==c.post.author_id %}
|
||||
<span> </span>
|
||||
{% if c.distinguish_level %}
|
||||
<i class="fas fa-shield text-admin" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="Administrator, speaking officially"></i>
|
||||
{% endif %}
|
||||
{% if c.post.author_id==c.author_id %}
|
||||
<i class="fas fa-microphone-stand text-info" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="Submitter"></i>
|
||||
{% endif %}
|
||||
<span> </span>
|
||||
{% endif %}
|
||||
<span class="time-stamp" data-toggle="tooltip" data-placement="bottom" data-delay='{"show":"700", "hide":"300"}' title="{{ c.created_datetime }}"><span>·</span> {{ c.age_string }}</span>
|
||||
{% if c.edited_utc %}
|
||||
<span class="time-edited" data-toggle="tooltip" data-placement="bottom" data-delay='{"show":"700", "hide":"300"}' title="{{ p.edited_datetime }}"><span>·</span> <span class="font-italic">Edited {{ c.edited_string }}</span></span>
|
||||
{% endif %}
|
||||
|
||||
<span class="comment-collapse d-md-none" onclick="collapse_comment('{{ c.base36id }}')"></span>
|
||||
|
||||
</div>
|
||||
|
||||
<div id="comment-text-{{ c.base36id }}" class="comment-text">
|
||||
{{ c.body_html | safe }}
|
||||
</div>
|
||||
|
||||
|
||||
<div id="comment-{{ c.base36id }}-actions" class="comment-actions">
|
||||
<ul class="list-inline text-right text-md-left">
|
||||
|
||||
|
||||
|
||||
<li id="comment-{{ c.base36id }}-up" class="list-inline-item arrow-up d-none d-md-inline-block mr-2">
|
||||
</li>
|
||||
|
||||
|
||||
<li class="list-inline-item d-none d-md-inline-block mr-2">
|
||||
<span id="comment-{{ c.base36id }}-score-none"class="d-none text-black">{{ score }}</span> </li>
|
||||
|
||||
<li class="list-inline-item text-muted d-none d-md-inline-block"><a href="javascript:void(0);" role="button" class="copy-link" data-clipboard-text="{{ c.permalink | full_link}}"><i class="fas fa-link"></i><span>Copy link</span></a>
|
||||
</li>
|
||||
<li class="list-inline-item d-none d-md-inline-block">
|
||||
<div class="dropdown show">
|
||||
<a href="#" role="button" id="dropdownMoreLink" data-toggle="dropdown" aria-haspopup="true"
|
||||
aria-expanded="false">
|
||||
<i class="fas fa-ellipsis-h"></i>
|
||||
</a>
|
||||
|
||||
<div class="dropdown-menu border-0 shadow" aria-labelledby="dropdownMoreLink">
|
||||
<a class="dropdown-item" href="{{ c.parent.permalink }}"><i class="fas fa-dna"></i>Parent</a>
|
||||
<a class="dropdown-item d-none" href="#"><i class="fas fa-save"></i>Save</a>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="list-inline-item d-inline-block d-md-none">
|
||||
<a href="#" data-toggle="modal" data-target="#actionsModal-{{ c.base36id }}" data-focus="false"><i class="fas fa-ellipsis-h"></i></a>
|
||||
</li>
|
||||
|
||||
<li id="comment-{{ c.base36id }}-up" class="list-inline-item arrow-up d-inline-block d-md-none mr-2">
|
||||
</li>
|
||||
<li class="list-inline-item d-inline-block d-md-none mr-2">
|
||||
<span id="comment-{{ c.base36id }}-score-none" class="d-none text-black">{{ score }}</span>
|
||||
</li>
|
||||
|
||||
<li id="comment-{{ c.base36id }}-down" class="list-inline-item arrow-down d-inline-block d-md-none">
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Comment Actions Modal -->
|
||||
<div class="modal fade d-md-none" id="actionsModal-{{ c.base36id }}" tabindex="-1" role="dialog" aria-labelledby="actionsModalTitle" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title h6">More options</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true"><i class="far fa-times"></i></span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<ul class="list-group comment-actions">
|
||||
<li class="list-group-item"><a href="javascript:void(0);" role="button" class="d-block copy-link" data-dismiss="modal" data-clipboard-text="{{ c.permalink | full_link}}"><i class="fas fa-link"></i><span>Share</span></a>
|
||||
<li class="list-group-item"><a class="d-block" href="{{ c.parent.permalink }}"><i class="fas fa-dna"></i>Parent</a></li>
|
||||
<li class="list-group-item d-none"><a href="#" class="d-block"><i class="fas fa-save"></i>Save</a></li>
|
||||
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
{% endblock %}
|
|
@ -0,0 +1,111 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
|
||||
<meta name="author" content="">
|
||||
|
||||
{% block title %}
|
||||
{% endblock %}
|
||||
|
||||
<!-- Bootstrap core CSS -->
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
|
||||
integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
|
||||
|
||||
|
||||
{% block stylesheets %}
|
||||
|
||||
{% if v %}
|
||||
<link rel="stylesheet" href="/assets/style/{{v.theme}}_{{v.themecolor}}.css">
|
||||
{% if v.agendaposter %}<link rel="stylesheet" href="/assets/style/agendaposter.css">{% elif v.css %}<link rel="stylesheet" href="/@{{v.username}}/css">{% endif %}
|
||||
{% else %}
|
||||
<link rel="stylesheet" href="/assets/style/dark_ff66ac.css">
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
<!-- Font Awesome -->
|
||||
<link href="/assets/fontawesome/css/all.css" rel="stylesheet"> <!--load all styles -->
|
||||
|
||||
|
||||
|
||||
</head>
|
||||
|
||||
<body id="{% block pagetype %}frontpage{% endblock %}" class="p-1">
|
||||
|
||||
|
||||
<div class="container">
|
||||
<div class="row justify-content-around" id="main-content-row">
|
||||
|
||||
<div class="col h-100 custom-gutters" id="main-content-col">
|
||||
|
||||
|
||||
{% block content %}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Clipboard Toast -->
|
||||
|
||||
<div class="toast clipboard" id="toast-success" role="alert" aria-live="assertive" aria-atomic="true" data-animation="true" data-autohide="true" data-delay="5000">
|
||||
<div class="toast-body text-center">
|
||||
<i class="fas fa-check-circle text-success mr-2"></i>Link copied to clipboard
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="toast clipboard" id="toast-error" role="alert" aria-live="assertive" aria-atomic="true" data-animation="true" data-autohide="true" data-delay="5000">
|
||||
<div class="toast-body text-center">
|
||||
<i class="fas fa-exclamation-circle text-danger mr-2"></i>Unable to copy link
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% include "bootstrap.html" %}
|
||||
|
||||
|
||||
|
||||
<!-- ClipboardJS -->
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/clipboard@2/dist/clipboard.min.js"></script>
|
||||
|
||||
<!-- Instantiate clipboard by passing a string selector -->
|
||||
<script type="text/javascript">
|
||||
var clipboard = new ClipboardJS('.copy-link');
|
||||
clipboard.on('success', function(e) {
|
||||
|
||||
jQuery(function($) {
|
||||
$('#toast-success').toast('show');
|
||||
})
|
||||
console.log(e);
|
||||
});
|
||||
clipboard.on('error', function(e) {
|
||||
|
||||
jQuery(function($) {
|
||||
$('#toast-error').toast('show');
|
||||
})
|
||||
console.log(e);
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
{% block enlargeThumbJS %}
|
||||
{% endblock %}
|
||||
|
||||
{% block toggleView %}
|
||||
{% endblock %}
|
||||
|
||||
{% block embedJS %}
|
||||
{% endblock %}
|
||||
|
||||
{% block formatJS %}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
<script src="/assets/js/all_js.js"></script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -0,0 +1,21 @@
|
|||
{% extends "embeds/embed_default.html" %}
|
||||
|
||||
{% block title %}
|
||||
<title>{{ p.title | safe}}</title>
|
||||
<meta name="description" content="posted {{ p.age_string }} by @{{ p.author.username }}">
|
||||
{% endblock %}
|
||||
|
||||
{% block pagetype %}thread{% endblock %}
|
||||
|
||||
|
||||
{% block content %}
|
||||
<div class="row no-gutters mt-md-3">
|
||||
<div class="col-12">
|
||||
<div class="posts" id="posts">
|
||||
{% with listing = [p] %}
|
||||
{% include "submission_listing.html" %}
|
||||
{% endwith %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue