Merge branch 'master' into fix-seed-db
commit
62a7ef70ed
|
@ -1,5 +1,6 @@
|
||||||
|
image.png
|
||||||
image.gif
|
image.gif
|
||||||
dramacache/
|
cache/
|
||||||
__pycache__/
|
__pycache__/
|
||||||
*.py[cod]
|
*.py[cod]
|
||||||
*$py.class
|
*$py.class
|
||||||
|
|
|
@ -2,12 +2,12 @@ version: 0.0
|
||||||
os: linux
|
os: linux
|
||||||
files:
|
files:
|
||||||
- source: /
|
- source: /
|
||||||
destination: drama
|
destination: files
|
||||||
permissions:
|
permissions:
|
||||||
- object: drama/*
|
- object: files/*
|
||||||
mode: 4755
|
mode: 4755
|
||||||
hooks:
|
hooks:
|
||||||
AfterInstall:
|
AfterInstall:
|
||||||
- location: scripts/install_pip
|
- location: scripts/install_pip
|
||||||
ApplicationStart:
|
ApplicationStart:
|
||||||
- location: scripts/start_drama
|
- location: scripts/start_files
|
|
@ -1,7 +1,7 @@
|
||||||
for theme in ['midnight', 'dark', 'light', 'coffee', 'tron', '4chan']:
|
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()
|
text = t.read()
|
||||||
for color in ['ff66ac','805ad5','62ca56','38a169','80ffff','2a96f3','62ca56','eb4963','ff0000','f39731','30409f','3e98a7','e4432d','7b9ae4','ec72de','7f8fa6', 'f8db58']:
|
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)
|
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)
|
nt.write(newtext)
|
|
@ -1,36 +1,43 @@
|
||||||
version: '2.3'
|
version: '2.3'
|
||||||
|
|
||||||
services:
|
services:
|
||||||
drama:
|
files:
|
||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
volumes:
|
volumes:
|
||||||
- "./:/drama/service"
|
- "./:/service"
|
||||||
environment:
|
environment:
|
||||||
- PYTHONPATH="drama/service"
|
- PYTHONPATH="/service"
|
||||||
- REDIS_URL=redis://redis
|
- REDIS_URL=redis://redis
|
||||||
- DATABASE_URL=postgresql://postgres@postgres:5432/postgres
|
- DATABASE_URL=postgresql://postgres@postgres:5432/postgres
|
||||||
- DATABASE_CONNECTION_POOL_URL=postgresql://postgres@postgres:5432/postgres
|
- DATABASE_CONNECTION_POOL_URL=postgresql://postgres@postgres:5432/postgres
|
||||||
- MASTER_KEY=${MASTER_KEY:-KTVciAUQFpFh2WdJ/oiHJlxl6FvzRZp8kYzAAv3l2OA=}
|
- MASTER_KEY=${MASTER_KEY:-KTVciAUQFpFh2WdJ/oiHJlxl6FvzRZp8kYzAAv3l2OA=}
|
||||||
- domain=localhost
|
- DOMAIN=localhost
|
||||||
- SITE_NAME=Drama
|
- SITE_NAME=Drama
|
||||||
- CLOUDFLARE_ZONE=vcxvdfgfc6r554etrgd
|
- CLOUDFLARE_ZONE=vcxvdfgfc6r554etrgd
|
||||||
- CLOUDFLARE_KEY=vcxvdfgfc6r554etrgd
|
- CLOUDFLARE_KEY=vcxvdfgfc6r554etrgd
|
||||||
- TENOR_KEY=vcxvdfgfc6r554etrgd
|
- TENOR_KEY=vcxvdfgfc6r554etrgd
|
||||||
- MAILGUN_KEY=vcxvdfgfc6r554etrgd
|
- MAILGUN_KEY=vcxvdfgfc6r554etrgd
|
||||||
- MAILGUN_DOMAIN=rdrama.net
|
- MAILGUN_DOMAIN=rdrama.net
|
||||||
- admin_email=drama@rdrama.net
|
|
||||||
- FORCE_HTTPS=0
|
- FORCE_HTTPS=0
|
||||||
- DISCORD_SERVER_ID=vcxvdfgfc6r554etrgd
|
- DISCORD_SERVER_ID=vcxvdfgfc6r554etrgd
|
||||||
- DISCORD_CLIENT_ID=vcxvdfgfc6r554etrgd
|
- DISCORD_CLIENT_ID=vcxvdfgfc6r554etrgd
|
||||||
- DISCORD_CLIENT_SECRET=vcxvdfgfc6r554etrgd
|
- DISCORD_CLIENT_SECRET=vcxvdfgfc6r554etrgd
|
||||||
- DISCORD_BOT_TOKEN=vcxvdfgfc6r554etrgd
|
- DISCORD_BOT_TOKEN=vcxvdfgfc6r554etrgd
|
||||||
- imgurkey=vcxvdfgfc6r554etrgd
|
- IMGUR_KEY=vcxvdfgfc6r554etrgd
|
||||||
- FACEBOOK_TOKEN=vcxvdfgfc6r554etrgd
|
- FACEBOOK_TOKEN=vcxvdfgfc6r554etrgd
|
||||||
#- HCAPTCHA_SITEKEY=vcxvdfgfc6r554etrgd
|
#- HCAPTCHA_SITEKEY=vcxvdfgfc6r554etrgd
|
||||||
- HCAPTCHA_SECRET=vcxvdfgfc6r554etrgd
|
- HCAPTCHA_SECRET=vcxvdfgfc6r554etrgd
|
||||||
- youtubekey=vcxvdfgfc6r554etrgd
|
- YOUTUBE_KEY=vcxvdfgfc6r554etrgd
|
||||||
- PUSHER_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:
|
links:
|
||||||
- "redis"
|
- "redis"
|
||||||
- "postgres"
|
- "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.wsgi_app = ProxyFix(app.wsgi_app, x_for=3)
|
||||||
app.url_map.strict_slashes = False
|
app.url_map.strict_slashes = False
|
||||||
|
|
||||||
app.config["SITE_NAME"]=environ.get("SITE_NAME", "Drama").strip()
|
app.config["SITE_NAME"]=environ.get("SITE_NAME").strip()
|
||||||
|
app.config["COINS_NAME"]=environ.get("COINS_NAME").strip()
|
||||||
app.config["SITE_COLOR"]=environ.get("SITE_COLOR", "805ad5").strip()
|
|
||||||
|
|
||||||
app.config["DRAMAPATH"]=environ.get("DRAMAPATH", path.dirname(path.realpath(__file__)))
|
|
||||||
|
|
||||||
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
|
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
|
||||||
app.config['DATABASE_URL'] = environ.get(
|
app.config['DATABASE_URL'] = environ.get("DATABASE_CONNECTION_POOL_URL",environ.get("DATABASE_URL"))
|
||||||
"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['SECRET_KEY'] = environ.get('MASTER_KEY')
|
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_" + environ.get("SITE_NAME").strip().lower()
|
||||||
app.config["SESSION_COOKIE_NAME"] = "session_drama"
|
|
||||||
app.config["VERSION"] = "1.0.0"
|
app.config["VERSION"] = "1.0.0"
|
||||||
app.config['MAX_CONTENT_LENGTH'] = 64 * 1024 * 1024
|
app.config['MAX_CONTENT_LENGTH'] = 64 * 1024 * 1024
|
||||||
app.config["SESSION_COOKIE_SECURE"] = bool(int(environ.get("FORCE_HTTPS", 1)))
|
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["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["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 = {}
|
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"]:
|
if "localhost" in app.config["SERVER_NAME"]:
|
||||||
app.config["CACHE_TYPE"] = "null"
|
app.config["CACHE_TYPE"] = "null"
|
||||||
else:
|
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
|
# captcha configs
|
||||||
app.config["HCAPTCHA_SITEKEY"] = environ.get("HCAPTCHA_SITEKEY","").strip()
|
app.config["HCAPTCHA_SITEKEY"] = environ.get("HCAPTCHA_SITEKEY","").strip()
|
||||||
app.config["HCAPTCHA_SECRET"] = environ.get(
|
app.config["HCAPTCHA_SECRET"] = environ.get("HCAPTCHA_SECRET","").strip()
|
||||||
"HCAPTCHA_SECRET","").strip()
|
|
||||||
app.config["SIGNUP_HOURLY_LIMIT"]=int(environ.get("SIGNUP_HOURLY_LIMIT",0))
|
|
||||||
|
|
||||||
# antispam configs
|
# antispam configs
|
||||||
app.config["SPAM_SIMILARITY_THRESHOLD"] = float(
|
app.config["SPAM_SIMILARITY_THRESHOLD"] = float(environ.get("SPAM_SIMILARITY_THRESHOLD"))
|
||||||
environ.get("SPAM_SIMILARITY_THRESHOLD", 0.5))
|
app.config["SPAM_SIMILAR_COUNT_THRESHOLD"] = int(environ.get("SPAM_SIMILAR_COUNT_THRESHOLD"))
|
||||||
app.config["SPAM_SIMILAR_COUNT_THRESHOLD"] = int(
|
app.config["SPAM_URL_SIMILARITY_THRESHOLD"] = float(environ.get("SPAM_URL_SIMILARITY_THRESHOLD"))
|
||||||
environ.get("SPAM_SIMILAR_COUNT_THRESHOLD", 5))
|
app.config["COMMENT_SPAM_SIMILAR_THRESHOLD"] = float(environ.get("COMMENT_SPAM_SIMILAR_THRESHOLD"))
|
||||||
app.config["SPAM_URL_SIMILARITY_THRESHOLD"] = float(
|
app.config["COMMENT_SPAM_COUNT_THRESHOLD"] = int(environ.get("COMMENT_SPAM_COUNT_THRESHOLD"))
|
||||||
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["CACHE_REDIS_URL"] = environ.get(
|
app.config["CACHE_REDIS_URL"] = environ.get("REDIS_URL").strip()
|
||||||
"REDIS_URL").strip().lstrip() if environ.get("REDIS_URL") else None
|
|
||||||
app.config["CACHE_DEFAULT_TIMEOUT"] = 60
|
app.config["CACHE_DEFAULT_TIMEOUT"] = 60
|
||||||
app.config["CACHE_KEY_PREFIX"] = "flask_caching_"
|
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(
|
redispool=ConnectionPool(
|
||||||
max_connections=app.config["REDIS_POOL_SIZE"],
|
max_connections=app.config["REDIS_POOL_SIZE"],
|
||||||
|
@ -105,7 +83,7 @@ redispool=ConnectionPool(
|
||||||
) if app.config["CACHE_TYPE"]=="redis" else None
|
) if app.config["CACHE_TYPE"]=="redis" else None
|
||||||
app.config["CACHE_OPTIONS"]={'connection_pool':redispool} if app.config["CACHE_TYPE"]=="redis" else {}
|
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["BOT_DISABLE"]=bool(int(environ.get("BOT_DISABLE", False)))
|
||||||
|
|
||||||
app.config["TENOR_KEY"]=environ.get("TENOR_KEY",'').strip()
|
app.config["TENOR_KEY"]=environ.get("TENOR_KEY",'').strip()
|
||||||
|
@ -115,18 +93,15 @@ Markdown(app)
|
||||||
cache = Cache(app)
|
cache = Cache(app)
|
||||||
Compress(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_KEY_PREFIX"] = "flask_limiting_"
|
||||||
app.config["RATELIMIT_ENABLED"] = True
|
app.config["RATELIMIT_ENABLED"] = True
|
||||||
app.config["RATELIMIT_DEFAULTS_DEDUCT_WHEN"]=lambda:True
|
app.config["RATELIMIT_DEFAULTS_DEDUCT_WHEN"]=lambda:True
|
||||||
app.config["RATELIMIT_DEFAULTS_EXEMPT_WHEN"]=lambda:False
|
app.config["RATELIMIT_DEFAULTS_EXEMPT_WHEN"]=lambda:False
|
||||||
app.config["RATELIMIT_HEADERS_ENABLED"]=True
|
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(
|
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 and bind all routing functions
|
||||||
import drama.classes
|
import files.classes
|
||||||
from drama.routes import *
|
from files.routes import *
|
||||||
import drama.helpers.jinja2
|
import files.helpers.jinja2
|
||||||
|
|
||||||
@cache.memoize(UA_BAN_CACHE_TTL)
|
@cache.memoize(UA_BAN_CACHE_TTL)
|
||||||
def get_useragent_ban_response(user_agent_str):
|
def get_useragent_ban_response(user_agent_str):
|
||||||
|
@ -210,8 +185,8 @@ def get_useragent_ban_response(user_agent_str):
|
||||||
# return False, (None, None)
|
# return False, (None, None)
|
||||||
|
|
||||||
result = g.db.query(
|
result = g.db.query(
|
||||||
drama.classes.Agent).filter(
|
files.classes.Agent).filter(
|
||||||
drama.classes.Agent.kwd.in_(
|
files.classes.Agent.kwd.in_(
|
||||||
user_agent_str.split())).first()
|
user_agent_str.split())).first()
|
||||||
if result:
|
if result:
|
||||||
return True, (result.mock or "Follow the robots.txt, dumbass",
|
return True, (result.mock or "Follow the robots.txt, dumbass",
|
||||||
|
@ -267,26 +242,6 @@ def before_request():
|
||||||
else:
|
else:
|
||||||
g.system="other/other"
|
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
|
@app.after_request
|
||||||
def after_request(response):
|
def after_request(response):
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from sqlalchemy import *
|
from sqlalchemy import *
|
||||||
from drama.__main__ import Base
|
from files.__main__ import Base
|
||||||
|
|
||||||
class Agent(Base):
|
class Agent(Base):
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from sqlalchemy import *
|
from sqlalchemy import *
|
||||||
from drama.__main__ import Base
|
from files.__main__ import Base
|
||||||
|
|
||||||
|
|
||||||
class Alt(Base):
|
class Alt(Base):
|
|
@ -1,6 +1,6 @@
|
||||||
from sqlalchemy import *
|
from sqlalchemy import *
|
||||||
from sqlalchemy.orm import relationship
|
from sqlalchemy.orm import relationship
|
||||||
from drama.__main__ import Base
|
from files.__main__ import Base
|
||||||
|
|
||||||
AWARDS = {
|
AWARDS = {
|
||||||
"ban": {
|
"ban": {
|
|
@ -1,7 +1,7 @@
|
||||||
from sqlalchemy import *
|
from sqlalchemy import *
|
||||||
from sqlalchemy.orm import relationship
|
from sqlalchemy.orm import relationship
|
||||||
|
|
||||||
from drama.__main__ import Base, app
|
from files.__main__ import Base, app
|
||||||
|
|
||||||
|
|
||||||
class BadgeDef(Base):
|
class BadgeDef(Base):
|
|
@ -5,7 +5,7 @@ from sqlalchemy.orm import relationship, lazyload
|
||||||
from .mix_ins import Stndrd
|
from .mix_ins import Stndrd
|
||||||
from .submission import Submission
|
from .submission import Submission
|
||||||
from .comment import Comment
|
from .comment import Comment
|
||||||
from drama.__main__ import Base
|
from files.__main__ import Base
|
||||||
|
|
||||||
class OauthApp(Base, Stndrd):
|
class OauthApp(Base, Stndrd):
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
from flask import *
|
from flask import *
|
||||||
from sqlalchemy import *
|
from sqlalchemy import *
|
||||||
from sqlalchemy.orm import relationship, deferred
|
from sqlalchemy.orm import relationship, deferred
|
||||||
from drama.helpers.lazy import lazy
|
from files.helpers.lazy import lazy
|
||||||
from drama.__main__ import Base
|
from files.__main__ import Base
|
||||||
from .mix_ins import *
|
from .mix_ins import *
|
||||||
from .flags import CommentFlag
|
from .flags import CommentFlag
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from sqlalchemy import *
|
from sqlalchemy import *
|
||||||
from drama.__main__ import Base
|
from files.__main__ import Base
|
||||||
|
|
||||||
class BannedDomain(Base):
|
class BannedDomain(Base):
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
from sqlalchemy import *
|
from sqlalchemy import *
|
||||||
from sqlalchemy.orm import relationship
|
from sqlalchemy.orm import relationship
|
||||||
from drama.__main__ import Base
|
from files.__main__ import Base
|
||||||
from .mix_ins import *
|
from .mix_ins import *
|
||||||
|
|
||||||
class Flag(Base, Stndrd):
|
class Flag(Base, Stndrd):
|
|
@ -1,6 +1,6 @@
|
||||||
from sqlalchemy import *
|
from sqlalchemy import *
|
||||||
from flask import g
|
from flask import g
|
||||||
from drama.__main__ import Base
|
from files.__main__ import Base
|
||||||
|
|
||||||
|
|
||||||
class Image(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 math
|
||||||
import random
|
import random
|
||||||
import time
|
import time
|
|
@ -1,6 +1,6 @@
|
||||||
from sqlalchemy import *
|
from sqlalchemy import *
|
||||||
from sqlalchemy.orm import relationship
|
from sqlalchemy.orm import relationship
|
||||||
from drama.__main__ import Base
|
from files.__main__ import Base
|
||||||
from .mix_ins import *
|
from .mix_ins import *
|
||||||
import time
|
import time
|
||||||
|
|
|
@ -3,13 +3,13 @@ from sqlalchemy import *
|
||||||
from sqlalchemy.orm import relationship, deferred
|
from sqlalchemy.orm import relationship, deferred
|
||||||
import re, random
|
import re, random
|
||||||
from urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
from drama.helpers.lazy import lazy
|
from files.helpers.lazy import lazy
|
||||||
from drama.__main__ import Base
|
from files.__main__ import Base
|
||||||
from .mix_ins import *
|
from .mix_ins import *
|
||||||
from .flags import *
|
from .flags import *
|
||||||
from os import environ
|
from os import environ
|
||||||
|
|
||||||
site = environ.get("domain").strip()
|
site = environ.get("DOMAIN").strip()
|
||||||
|
|
||||||
class SubmissionAux(Base):
|
class SubmissionAux(Base):
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
from sqlalchemy import *
|
from sqlalchemy import *
|
||||||
from sqlalchemy.orm import relationship
|
from sqlalchemy.orm import relationship
|
||||||
from drama.__main__ import Base
|
from files.__main__ import Base
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,8 @@ from sqlalchemy.orm import deferred, contains_eager, aliased
|
||||||
from secrets import token_hex
|
from secrets import token_hex
|
||||||
import pyotp
|
import pyotp
|
||||||
|
|
||||||
from drama.helpers.discord import delete_role
|
from files.helpers.discord import delete_role
|
||||||
from drama.helpers.images import *
|
from files.helpers.images import *
|
||||||
from .alts import Alt
|
from .alts import Alt
|
||||||
from .submission import SaveRelationship
|
from .submission import SaveRelationship
|
||||||
from .comment import Notification
|
from .comment import Notification
|
||||||
|
@ -11,10 +11,10 @@ from .subscriptions import *
|
||||||
from .userblock import *
|
from .userblock import *
|
||||||
from .badges import *
|
from .badges import *
|
||||||
from .clients import *
|
from .clients import *
|
||||||
from drama.__main__ import Base, cache
|
from files.__main__ import Base, cache
|
||||||
from drama.helpers.security import *
|
from files.helpers.security import *
|
||||||
|
|
||||||
site = environ.get("domain").strip()
|
site = environ.get("DOMAIN").strip()
|
||||||
|
|
||||||
class User(Base, Stndrd, Age_times):
|
class User(Base, Stndrd, Age_times):
|
||||||
__tablename__ = "users"
|
__tablename__ = "users"
|
||||||
|
@ -79,7 +79,7 @@ class User(Base, Stndrd, Age_times):
|
||||||
ban_reason = Column(String, default="")
|
ban_reason = Column(String, default="")
|
||||||
login_nonce = Column(Integer, default=0)
|
login_nonce = Column(Integer, default=0)
|
||||||
reserved = Column(String(256))
|
reserved = Column(String(256))
|
||||||
dramacoins = Column(Integer, default=0)
|
coins = Column(Integer, default=0)
|
||||||
mfa_secret = deferred(Column(String(16)))
|
mfa_secret = deferred(Column(String(16)))
|
||||||
is_private = Column(Boolean, default=False)
|
is_private = Column(Boolean, default=False)
|
||||||
stored_subscriber_count = Column(Integer, default=0)
|
stored_subscriber_count = Column(Integer, default=0)
|
||||||
|
@ -491,7 +491,7 @@ class User(Base, Stndrd, Age_times):
|
||||||
data = self.json_core
|
data = self.json_core
|
||||||
|
|
||||||
data["badges"] = [x.json_core for x in self.badges]
|
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['post_count'] = self.post_count
|
||||||
data['comment_count'] = self.comment_count
|
data['comment_count'] = self.comment_count
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from sqlalchemy import *
|
from sqlalchemy import *
|
||||||
from sqlalchemy.orm import relationship
|
from sqlalchemy.orm import relationship
|
||||||
from .mix_ins import *
|
from .mix_ins import *
|
||||||
from drama.__main__ import Base
|
from files.__main__ import Base
|
||||||
|
|
||||||
class UserBlock(Base, Stndrd, Age_times):
|
class UserBlock(Base, Stndrd, Age_times):
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from flask import *
|
from flask import *
|
||||||
from sqlalchemy import *
|
from sqlalchemy import *
|
||||||
from sqlalchemy.orm import relationship
|
from sqlalchemy.orm import relationship
|
||||||
from drama.__main__ import Base
|
from files.__main__ import Base
|
||||||
|
|
||||||
class Vote(Base):
|
class Vote(Base):
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import mistletoe
|
import mistletoe
|
||||||
|
|
||||||
from drama.classes import *
|
from files.classes import *
|
||||||
from flask import g
|
from flask import g
|
||||||
from .markdown import *
|
from .markdown import *
|
||||||
from .sanitize import *
|
from .sanitize import *
|
|
@ -1,7 +1,7 @@
|
||||||
from bs4 import BeautifulSoup
|
from bs4 import BeautifulSoup
|
||||||
from flask import *
|
from flask import *
|
||||||
from urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
from drama.classes import BannedDomain
|
from files.classes import BannedDomain
|
||||||
|
|
||||||
def filter_comment_html(html_text):
|
def filter_comment_html(html_text):
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
from drama.classes import *
|
from files.classes import *
|
||||||
from flask import g
|
from flask import g
|
||||||
from sqlalchemy.orm import joinedload, aliased
|
from sqlalchemy.orm import joinedload, aliased
|
||||||
|
|
|
@ -2,11 +2,11 @@ import requests
|
||||||
from os import environ
|
from os import environ
|
||||||
from PIL import Image as IImage, ImageSequence
|
from PIL import Image as IImage, ImageSequence
|
||||||
import base64
|
import base64
|
||||||
from drama.classes.images import *
|
from files.classes.images import *
|
||||||
|
|
||||||
CF_KEY = environ.get("CLOUDFLARE_KEY").strip()
|
CF_KEY = environ.get("CLOUDFLARE_KEY").strip()
|
||||||
CF_ZONE = environ.get("CLOUDFLARE_ZONE").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):
|
def upload_file(file=None, resize=False, png=False):
|
||||||
|
@ -35,12 +35,10 @@ def upload_file(file=None, resize=False, png=False):
|
||||||
try:
|
try:
|
||||||
with open(filedir, 'rb') as f:
|
with open(filedir, 'rb') as f:
|
||||||
data={'image': base64.b64encode(f.read())}
|
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']
|
resp = req.json()['data']
|
||||||
url = resp['link'].replace(".png", "_d.png").replace(".jpg", "_d.jpg").replace(".jpeg", "_d.jpeg") + "?maxwidth=9999"
|
url = resp['link'].replace(".png", "_d.png").replace(".jpg", "_d.jpg").replace(".jpeg", "_d.jpeg") + "?maxwidth=9999"
|
||||||
except:
|
except: return
|
||||||
print(req.text)
|
|
||||||
return
|
|
||||||
|
|
||||||
new_image = Image(text=url, deletehash=resp["deletehash"])
|
new_image = Image(text=url, deletehash=resp["deletehash"])
|
||||||
g.db.add(new_image)
|
g.db.add(new_image)
|
|
@ -1,6 +1,6 @@
|
||||||
from os import environ, path
|
from os import environ, path
|
||||||
from .get import *
|
from .get import *
|
||||||
from drama.__main__ import app, cache
|
from files.__main__ import app, cache
|
||||||
|
|
||||||
|
|
||||||
@app.template_filter("total_users")
|
@app.template_filter("total_users")
|
||||||
|
@ -14,7 +14,7 @@ def total_users(x):
|
||||||
@cache.memoize(timeout=60 * 60 * 24)
|
@cache.memoize(timeout=60 * 60 * 24)
|
||||||
def source_code(file_name):
|
def source_code(file_name):
|
||||||
|
|
||||||
return open(path.expanduser('~') + '/drama/' +
|
return open(path.expanduser('~') + '/files/' +
|
||||||
file_name, mode="r+").read()
|
file_name, mode="r+").read()
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ from functools import partial
|
||||||
from .get import *
|
from .get import *
|
||||||
from os import path
|
from os import path
|
||||||
|
|
||||||
site = environ.get("domain").strip()
|
site = environ.get("DOMAIN").strip()
|
||||||
|
|
||||||
_allowed_tags = tags = ['b',
|
_allowed_tags = tags = ['b',
|
||||||
'blockquote',
|
'blockquote',
|
||||||
|
@ -72,7 +72,7 @@ def a_modify(attrs, new=False):
|
||||||
attrs[(None, "rel")] = "nofollow noopener"
|
attrs[(None, "rel")] = "nofollow noopener"
|
||||||
|
|
||||||
# Force https for all external links in comments
|
# 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",
|
new_url = ParseResult(scheme="https",
|
||||||
netloc=parsed_url.netloc,
|
netloc=parsed_url.netloc,
|
||||||
path=parsed_url.path,
|
path=parsed_url.path,
|
||||||
|
@ -178,12 +178,12 @@ def sanitize(text, linkgen=False, flair=False):
|
||||||
|
|
||||||
start = '<s>'
|
start = '<s>'
|
||||||
end = '</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
|
if flair: emojisize = 20
|
||||||
else: emojisize = 30
|
else: emojisize = 30
|
||||||
for i in re.finditer(':(.{1,30}?):', sanitized):
|
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(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/")
|
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 werkzeug.wrappers.response import Response as RespObj
|
||||||
from .get import *
|
from .get import *
|
||||||
from .alerts import send_notification
|
from .alerts import send_notification
|
||||||
from drama.__main__ import app
|
from files.__main__ import app
|
||||||
|
|
||||||
|
|
||||||
def get_logged_in_user():
|
def get_logged_in_user():
|
||||||
|
@ -48,7 +48,7 @@ def check_ban_evade(v):
|
||||||
|
|
||||||
if random.randint(0,30) < v.ban_evade:
|
if random.randint(0,30) < v.ban_evade:
|
||||||
v.ban(reason="ban evasion")
|
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():
|
for post in g.db.query(Submission).filter_by(author_id=v.id).all():
|
||||||
if post.is_banned:
|
if post.is_banned:
|
|
@ -4,16 +4,17 @@ import time
|
||||||
from flask import *
|
from flask import *
|
||||||
from urllib.parse import quote
|
from urllib.parse import quote
|
||||||
|
|
||||||
from drama.helpers.security import *
|
from files.helpers.security import *
|
||||||
from drama.helpers.wrappers import *
|
from files.helpers.wrappers import *
|
||||||
from drama.classes import *
|
from files.classes import *
|
||||||
from drama.__main__ import app
|
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()
|
mailgun_domain = environ.get("MAILGUN_DOMAIN").strip()
|
||||||
|
|
||||||
def send_mail(to_address, subject, html, plaintext=None, files={},
|
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"
|
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",
|
html=render_template("email/email_verify.html",
|
||||||
action_url=link,
|
action_url=link,
|
||||||
v=user),
|
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 os import remove
|
||||||
from PIL import Image as IMAGE
|
from PIL import Image as IMAGE
|
||||||
|
|
||||||
from drama.helpers.wrappers import *
|
from files.helpers.wrappers import *
|
||||||
from drama.helpers.alerts import *
|
from files.helpers.alerts import *
|
||||||
from drama.helpers.sanitize import *
|
from files.helpers.sanitize import *
|
||||||
from drama.helpers.markdown import *
|
from files.helpers.markdown import *
|
||||||
from drama.helpers.security import *
|
from files.helpers.security import *
|
||||||
from drama.helpers.get import *
|
from files.helpers.get import *
|
||||||
from drama.helpers.images import *
|
from files.helpers.images import *
|
||||||
from drama.classes import *
|
from files.classes import *
|
||||||
from flask import *
|
from flask import *
|
||||||
import matplotlib.pyplot as plt
|
import matplotlib.pyplot as plt
|
||||||
from drama.__main__ import app, cache
|
from files.__main__ import app, cache
|
||||||
from .front import frontlist
|
from .front import frontlist
|
||||||
|
|
||||||
@app.get("/admin/shadowbanned")
|
@app.get("/admin/shadowbanned")
|
||||||
|
@ -443,7 +443,7 @@ def admin_image_purge(v):
|
||||||
name = request.form.get("url")
|
name = request.form.get("url")
|
||||||
image = g.db.query(Image).filter(Image.text == name).first()
|
image = g.db.query(Image).filter(Image.text == name).first()
|
||||||
if image:
|
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"}
|
headers = {"Authorization": f"Bearer {CF_KEY}", "Content-Type": "application/json"}
|
||||||
data = {'files': [name]}
|
data = {'files': [name]}
|
||||||
url = f"https://api.cloudflare.com/client/v4/zones/{CF_ZONE}/purge_cache"
|
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 days > 0:
|
||||||
if message:
|
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:
|
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)
|
user.ban(admin=v, reason=reason, days=days)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
if message:
|
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:
|
else:
|
||||||
text = "Your Drama account has been permanently suspended."
|
text = "Your account has been permanently suspended."
|
||||||
|
|
||||||
user.ban(admin=v, reason=reason)
|
user.ban(admin=v, reason=reason)
|
||||||
|
|
||||||
|
@ -701,7 +701,7 @@ def unban_user(user_id, v):
|
||||||
x.unban()
|
x.unban()
|
||||||
|
|
||||||
send_notification(1046, user,
|
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(
|
ma=ModAction(
|
||||||
kind="unexile_user",
|
kind="unexile_user",
|
||||||
|
@ -907,7 +907,7 @@ def refund(v):
|
||||||
if u.id == 253: continue
|
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()])
|
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()])
|
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)
|
g.db.add(u)
|
||||||
return "sex"
|
return "sex"
|
||||||
|
|
||||||
|
@ -931,7 +931,7 @@ def admin_banned_domains(v):
|
||||||
@validate_formkey
|
@validate_formkey
|
||||||
def admin_toggle_ban_domain(v):
|
def admin_toggle_ban_domain(v):
|
||||||
|
|
||||||
domain=request.form.get("domain").strip()
|
domain=request.form.get("DOMAIN").strip()
|
||||||
if not domain: abort(400)
|
if not domain: abort(400)
|
||||||
|
|
||||||
reason=request.form.get("reason", "").strip()
|
reason=request.form.get("reason", "").strip()
|
|
@ -1,8 +1,8 @@
|
||||||
from drama.__main__ import app
|
from files.__main__ import app
|
||||||
from drama.helpers.wrappers import *
|
from files.helpers.wrappers import *
|
||||||
from drama.helpers.alerts import *
|
from files.helpers.alerts import *
|
||||||
from drama.helpers.get import *
|
from files.helpers.get import *
|
||||||
from drama.classes.award import *
|
from files.classes.award import *
|
||||||
from flask import g, request
|
from flask import g, request
|
||||||
|
|
||||||
|
|
||||||
|
@ -15,13 +15,12 @@ def banaward_trigger(post=None, comment=None):
|
||||||
if not author.is_suspended:
|
if not author.is_suspended:
|
||||||
author.ban(reason="1-day ban award used", days=1)
|
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:
|
elif author.unban_utc > 0:
|
||||||
author.unban_utc += 24*60*60
|
author.unban_utc += 24*60*60
|
||||||
g.db.add(author)
|
g.db.add(author)
|
||||||
|
|
||||||
send_notification(1046, author,
|
send_notification(1046, author, f"Your account has been suspended for yet another day for {link}. Seriously man?")
|
||||||
f"Your Drama account has been suspended for yet another day for {link}. Seriously man?")
|
|
||||||
|
|
||||||
|
|
||||||
ACTIONS = {
|
ACTIONS = {
|
|
@ -1,19 +1,19 @@
|
||||||
import traceback
|
import traceback
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from drama.helpers.wrappers import *
|
from files.helpers.wrappers import *
|
||||||
from drama.helpers.filters import *
|
from files.helpers.filters import *
|
||||||
from drama.helpers.alerts import *
|
from files.helpers.alerts import *
|
||||||
from drama.helpers.images import *
|
from files.helpers.images import *
|
||||||
from drama.helpers.session import *
|
from files.helpers.session import *
|
||||||
from drama.classes import *
|
from files.classes import *
|
||||||
from drama.routes.front import comment_idlist
|
from files.routes.front import comment_idlist
|
||||||
from pusher_push_notifications import PushNotifications, PusherAuthError
|
from pusher_push_notifications import PushNotifications, PusherAuthError
|
||||||
|
|
||||||
from flask import *
|
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."]
|
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
|
threshold *= 2
|
||||||
|
|
||||||
if len(similar_comments) > threshold:
|
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)
|
send_notification(1046, v, text)
|
||||||
|
|
||||||
v.ban(reason="Spamming.",
|
v.ban(reason="Spamming.",
|
||||||
|
@ -539,7 +539,7 @@ def api_comment(v):
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
except PusherAuthError as e:
|
except PusherAuthError as e:
|
||||||
traceback.print_tb(e.__traceback__)
|
sys.stderr.write(traceback.format_exc())
|
||||||
sys.stderr.flush()
|
sys.stderr.flush()
|
||||||
|
|
||||||
|
|
||||||
|
@ -656,7 +656,7 @@ def edit_comment(cid, v):
|
||||||
threshold *= 2
|
threshold *= 2
|
||||||
|
|
||||||
if len(similar_comments) > threshold:
|
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)
|
send_notification(1046, v, text)
|
||||||
|
|
||||||
v.ban(reason="Spamming.",
|
v.ban(reason="Spamming.",
|
|
@ -1,15 +1,14 @@
|
||||||
from drama.helpers.wrappers import *
|
from files.helpers.wrappers import *
|
||||||
from drama.helpers.security import *
|
from files.helpers.security import *
|
||||||
from drama.helpers.discord import add_role
|
from files.helpers.discord import add_role
|
||||||
from drama.__main__ import app
|
from files.__main__ import app
|
||||||
|
|
||||||
SERVER_ID = environ.get("DISCORD_SERVER_ID",'').strip()
|
SERVER_ID = environ.get("DISCORD_SERVER_ID",'').strip()
|
||||||
CLIENT_ID = environ.get("DISCORD_CLIENT_ID",'').strip()
|
CLIENT_ID = environ.get("DISCORD_CLIENT_ID",'').strip()
|
||||||
CLIENT_SECRET = environ.get("DISCORD_CLIENT_SECRET",'').strip()
|
CLIENT_SECRET = environ.get("DISCORD_CLIENT_SECRET",'').strip()
|
||||||
BOT_TOKEN = environ.get("DISCORD_BOT_TOKEN").strip()
|
BOT_TOKEN = environ.get("DISCORD_BOT_TOKEN").strip()
|
||||||
|
COINS_NAME = environ.get("COINS_NAME").strip()
|
||||||
DISCORD_ENDPOINT = "https://discordapp.com/api/v6"
|
DISCORD_ENDPOINT = "https://discordapp.com/api/v6"
|
||||||
|
|
||||||
|
|
||||||
WELCOME_CHANNEL="846509313941700618"
|
WELCOME_CHANNEL="846509313941700618"
|
||||||
|
|
||||||
@app.get("/discord")
|
@app.get("/discord")
|
||||||
|
@ -17,7 +16,7 @@ WELCOME_CHANNEL="846509313941700618"
|
||||||
def join_discord(v):
|
def join_discord(v):
|
||||||
|
|
||||||
if v.is_banned != 0: return "You're banned"
|
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())
|
now=int(time.time())
|
||||||
|
|
||||||
|
@ -126,7 +125,7 @@ def discord_redirect(v):
|
||||||
|
|
||||||
time.sleep(0.1)
|
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: add_role(v, "norep")
|
||||||
|
|
||||||
else:
|
else:
|
|
@ -1,11 +1,11 @@
|
||||||
import jinja2.exceptions
|
import jinja2.exceptions
|
||||||
|
|
||||||
from drama.helpers.wrappers import *
|
from files.helpers.wrappers import *
|
||||||
from drama.helpers.session import *
|
from files.helpers.session import *
|
||||||
from flask import *
|
from flask import *
|
||||||
from urllib.parse import quote, urlencode
|
from urllib.parse import quote, urlencode
|
||||||
import time
|
import time
|
||||||
from drama.__main__ import app
|
from files.__main__ import app
|
||||||
|
|
||||||
# Errors
|
# Errors
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import html
|
import html
|
||||||
from .front import frontlist
|
from .front import frontlist
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from drama.helpers.jinja2 import full_link
|
from files.helpers.jinja2 import full_link
|
||||||
from drama.helpers.get import *
|
from files.helpers.get import *
|
||||||
from yattag import Doc
|
from yattag import Doc
|
||||||
|
|
||||||
from drama.__main__ import app
|
from files.__main__ import app
|
||||||
|
|
||||||
@app.get('/rss/<sort>/<t>')
|
@app.get('/rss/<sort>/<t>')
|
||||||
def feeds_user(sort='hot', t='all'):
|
def feeds_user(sort='hot', t='all'):
|
|
@ -1,8 +1,8 @@
|
||||||
from drama.helpers.wrappers import *
|
from files.helpers.wrappers import *
|
||||||
from drama.helpers.get import *
|
from files.helpers.get import *
|
||||||
from flask import g
|
from flask import g
|
||||||
from drama.__main__ import app
|
from files.__main__ import app
|
||||||
from drama.helpers.sanitize import sanitize
|
from files.helpers.sanitize import sanitize
|
||||||
|
|
||||||
@app.post("/flag/post/<pid>")
|
@app.post("/flag/post/<pid>")
|
||||||
@auth_desired
|
@auth_desired
|
||||||
|
@ -11,11 +11,10 @@ def api_flag_post(pid, v):
|
||||||
post = get_post(pid)
|
post = get_post(pid)
|
||||||
|
|
||||||
if v:
|
if v:
|
||||||
existing = g.db.query(Flag).filter_by(
|
existing = g.db.query(Flag).filter_by(user_id=v.id, post_id=post.id).first()
|
||||||
user_id=v.id, post_id=post.id).first()
|
|
||||||
|
|
||||||
if existing: return "", 409
|
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,
|
flag = Flag(post_id=post.id,
|
||||||
user_id=v.id,
|
user_id=v.id,
|
|
@ -1,8 +1,8 @@
|
||||||
from drama.helpers.wrappers import *
|
from files.helpers.wrappers import *
|
||||||
from drama.helpers.get import *
|
from files.helpers.get import *
|
||||||
|
|
||||||
from drama.__main__ import app, cache
|
from files.__main__ import app, cache
|
||||||
from drama.classes.submission import Submission
|
from files.classes.submission import Submission
|
||||||
|
|
||||||
@app.get("/post/")
|
@app.get("/post/")
|
||||||
def slash_post():
|
def slash_post():
|
|
@ -1,6 +1,6 @@
|
||||||
from urllib.parse import urlencode
|
from urllib.parse import urlencode
|
||||||
from drama.mail import *
|
from files.mail import *
|
||||||
from drama.__main__ import app, limiter
|
from files.__main__ import app, limiter
|
||||||
|
|
||||||
valid_username_regex = re.compile("^[a-zA-Z0-9_\-]{3,25}$")
|
valid_username_regex = re.compile("^[a-zA-Z0-9_\-]{3,25}$")
|
||||||
valid_password_regex = re.compile("^.{8,100}$")
|
valid_password_regex = re.compile("^.{8,100}$")
|
||||||
|
@ -135,8 +135,8 @@ def login_post():
|
||||||
@app.get("/@me")
|
@app.get("/@me")
|
||||||
@auth_required
|
@auth_required
|
||||||
def me(v):
|
def me(v):
|
||||||
if request.headers.get("Authorization"): v.json
|
if request.headers.get("Authorization"): return v.json
|
||||||
else: redirect(v.url)
|
else: return redirect(v.url)
|
||||||
|
|
||||||
|
|
||||||
@app.post("/logout")
|
@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}"
|
url = f"https://{app.config['SERVER_NAME']}/reset?id={user.id}&time={now}&token={token}"
|
||||||
|
|
||||||
send_mail(to_address=user.email,
|
send_mail(to_address=user.email,
|
||||||
subject="Drama - Password Reset Request",
|
subject="Password Reset Request",
|
||||||
html=render_template("email/password_reset.html",
|
html=render_template("email/password_reset.html",
|
||||||
action_url=url,
|
action_url=url,
|
||||||
v=user)
|
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}"
|
action_url=f"https://{app.config['SERVER_NAME']}/reset_2fa?id={user.id}&t={valid}&token={token}"
|
||||||
|
|
||||||
send_mail(to_address=user.email,
|
send_mail(to_address=user.email,
|
||||||
subject="Drama - 2FA Removal Request",
|
subject="2FA Removal Request",
|
||||||
html=render_template("email/2fa_remove.html",
|
html=render_template("email/2fa_remove.html",
|
||||||
action_url=action_url,
|
action_url=action_url,
|
||||||
v=user)
|
v=user)
|
|
@ -1,9 +1,9 @@
|
||||||
from drama.helpers.wrappers import *
|
from files.helpers.wrappers import *
|
||||||
from drama.helpers.alerts import *
|
from files.helpers.alerts import *
|
||||||
from drama.helpers.get import *
|
from files.helpers.get import *
|
||||||
from drama.classes import *
|
from files.classes import *
|
||||||
from flask import *
|
from flask import *
|
||||||
from drama.__main__ import app
|
from files.__main__ import app
|
||||||
|
|
||||||
@app.get("/authorize")
|
@app.get("/authorize")
|
||||||
@auth_required
|
@auth_required
|
|
@ -3,22 +3,22 @@ import mistletoe
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
import gevent
|
import gevent
|
||||||
|
|
||||||
from drama.helpers.wrappers import *
|
from files.helpers.wrappers import *
|
||||||
from drama.helpers.sanitize import *
|
from files.helpers.sanitize import *
|
||||||
from drama.helpers.filters import *
|
from files.helpers.filters import *
|
||||||
from drama.helpers.markdown import *
|
from files.helpers.markdown import *
|
||||||
from drama.helpers.session import *
|
from files.helpers.session import *
|
||||||
from drama.helpers.thumbs import *
|
from files.helpers.thumbs import *
|
||||||
from drama.helpers.alerts import send_notification
|
from files.helpers.alerts import send_notification
|
||||||
from drama.helpers.discord import send_message
|
from files.helpers.discord import send_message
|
||||||
from drama.classes import *
|
from files.classes import *
|
||||||
from flask import *
|
from flask import *
|
||||||
from io import BytesIO
|
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 PIL import Image as PILimage
|
||||||
from .front import frontlist
|
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]}")
|
with open("snappy.txt", "r") as f: snappyquotes = f.read().split("{[para]}")
|
||||||
|
|
||||||
|
@ -266,7 +266,7 @@ def edit_post(pid, v):
|
||||||
BadLink.link)).first()
|
BadLink.link)).first()
|
||||||
if badlink:
|
if badlink:
|
||||||
if badlink.autoban:
|
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)
|
send_notification(1046, v, text)
|
||||||
v.ban(days=1, reason="spam")
|
v.ban(days=1, reason="spam")
|
||||||
|
|
||||||
|
@ -422,7 +422,6 @@ def thumbs(new_post):
|
||||||
|
|
||||||
#iterate through desired meta tags
|
#iterate through desired meta tags
|
||||||
meta_tags = [
|
meta_tags = [
|
||||||
"drama:thumbnail",
|
|
||||||
"twitter:image",
|
"twitter:image",
|
||||||
"og:image",
|
"og:image",
|
||||||
"thumbnail"
|
"thumbnail"
|
||||||
|
@ -508,6 +507,22 @@ def archiveorg(url):
|
||||||
except Exception as e: print(e)
|
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")
|
@app.post("/submit")
|
||||||
@limiter.limit("6/minute")
|
@limiter.limit("6/minute")
|
||||||
@is_not_banned
|
@is_not_banned
|
||||||
|
@ -604,7 +619,8 @@ 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
|
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:
|
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:
|
elif "youtu" in domain:
|
||||||
yt_id = re.match(re.compile("^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|shorts\/|\&v=)([^#\&\?]*).*"), url).group(2)
|
yt_id = re.match(re.compile("^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|shorts\/|\&v=)([^#\&\?]*).*"), url).group(2)
|
||||||
|
@ -616,7 +632,7 @@ def submit_post(v):
|
||||||
else: embed = f"https://youtube.com/embed/{yt_id}"
|
else: embed = f"https://youtube.com/embed/{yt_id}"
|
||||||
|
|
||||||
elif "instagram.com" in domain:
|
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:
|
elif app.config['SERVER_NAME'] in domain:
|
||||||
try:
|
try:
|
||||||
|
@ -681,7 +697,7 @@ def submit_post(v):
|
||||||
|
|
||||||
if max(len(similar_urls), len(similar_posts)) >= threshold:
|
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)
|
send_notification(1046, v, text)
|
||||||
|
|
||||||
v.ban(reason="Spamming.",
|
v.ban(reason="Spamming.",
|
||||||
|
@ -761,7 +777,7 @@ def submit_post(v):
|
||||||
BadLink.link)).first()
|
BadLink.link)).first()
|
||||||
if badlink:
|
if badlink:
|
||||||
if badlink.autoban:
|
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)
|
send_notification(1046, v, text)
|
||||||
v.ban(days=1, reason="spam")
|
v.ban(days=1, reason="spam")
|
||||||
|
|
||||||
|
@ -789,7 +805,7 @@ def submit_post(v):
|
||||||
|
|
||||||
url = url.replace("https://mobile.twitter.com", "https://twitter.com")
|
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)
|
title_html = sanitize(title, linkgen=True, flair=True)
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
from drama.helpers.wrappers import *
|
from files.helpers.wrappers import *
|
||||||
import re
|
import re
|
||||||
from sqlalchemy import *
|
from sqlalchemy import *
|
||||||
from flask import *
|
from flask import *
|
||||||
from drama.__main__ import app, cache
|
from files.__main__ import app, cache
|
||||||
import random
|
import random
|
||||||
|
|
||||||
query_regex=re.compile("(\w+):(\S+)")
|
query_regex=re.compile("(\w+):(\S+)")
|
|
@ -1,11 +1,11 @@
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
from drama.helpers.alerts import *
|
from files.helpers.alerts import *
|
||||||
from drama.helpers.sanitize import *
|
from files.helpers.sanitize import *
|
||||||
from drama.helpers.filters import filter_comment_html
|
from files.helpers.filters import filter_comment_html
|
||||||
from drama.helpers.markdown import *
|
from files.helpers.markdown import *
|
||||||
from drama.helpers.discord import remove_user, set_nick
|
from files.helpers.discord import remove_user, set_nick
|
||||||
from drama.mail import *
|
from files.mail import *
|
||||||
from drama.__main__ import app, cache
|
from files.__main__ import app, cache
|
||||||
import youtube_dl
|
import youtube_dl
|
||||||
from .front import frontlist
|
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_title_regex = re.compile("^((?!<).){3,100}$")
|
||||||
valid_password_regex = re.compile("^.{8,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")
|
@app.post("/settings/profile")
|
||||||
@auth_required
|
@auth_required
|
||||||
|
@ -51,7 +52,7 @@ def settings_profile_post(v):
|
||||||
|
|
||||||
if request.values.get("animatedname", v.animatedname) != v.animatedname:
|
if request.values.get("animatedname", v.animatedname) != v.animatedname:
|
||||||
if v.animatedname == False:
|
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]
|
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
|
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
|
updated = True
|
||||||
|
@ -425,13 +426,13 @@ def settings_css(v):
|
||||||
@auth_required
|
@auth_required
|
||||||
def settings_profilecss_get(v):
|
def settings_profilecss_get(v):
|
||||||
if v and v.is_banned and not v.unban_utc: return render_template("seized.html")
|
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)
|
return render_template("settings_profilecss.html", v=v)
|
||||||
|
|
||||||
@app.post("/settings/profilecss")
|
@app.post("/settings/profilecss")
|
||||||
@auth_required
|
@auth_required
|
||||||
def settings_profilecss(v):
|
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]
|
profilecss = request.form.get("profilecss").replace('\\', '')[:50000]
|
||||||
v.profilecss = profilecss
|
v.profilecss = profilecss
|
||||||
g.db.add(v)
|
g.db.add(v)
|
||||||
|
@ -454,7 +455,7 @@ def settings_block_user(v):
|
||||||
return {"error": f"You have already blocked @{user.username}."}, 409
|
return {"error": f"You have already blocked @{user.username}."}, 409
|
||||||
|
|
||||||
if user.id == 1046:
|
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,
|
new_block = UserBlock(user_id=v.id,
|
||||||
target_id=user.id,
|
target_id=user.id,
|
||||||
|
@ -613,7 +614,7 @@ def settings_song_change(v):
|
||||||
return redirect("/settings/profile")
|
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']
|
try: duration = req['items'][0]['contentDetails']['duration']
|
||||||
except:
|
except:
|
||||||
print(req)
|
print(req)
|
|
@ -1,8 +1,8 @@
|
||||||
from drama.mail import *
|
from files.mail import *
|
||||||
from drama.__main__ import app, limiter
|
from files.__main__ import app, limiter
|
||||||
from drama.helpers.alerts import *
|
from files.helpers.alerts import *
|
||||||
|
|
||||||
site = environ.get("domain").strip()
|
site = environ.get("DOMAIN").strip()
|
||||||
|
|
||||||
@app.get("/patrons")
|
@app.get("/patrons")
|
||||||
@auth_desired
|
@auth_desired
|
||||||
|
@ -14,7 +14,7 @@ def patrons(v):
|
||||||
@app.get("/badmins")
|
@app.get("/badmins")
|
||||||
@auth_desired
|
@auth_desired
|
||||||
def badmins(v):
|
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)
|
return render_template("badmins.html", v=v, badmins=badmins)
|
||||||
|
|
||||||
@app.get("/log")
|
@app.get("/log")
|
|
@ -4,16 +4,16 @@ import time
|
||||||
import traceback
|
import traceback
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from drama.classes.user import ViewerRelationship
|
from files.classes.user import ViewerRelationship
|
||||||
from drama.helpers.alerts import *
|
from files.helpers.alerts import *
|
||||||
from drama.helpers.sanitize import *
|
from files.helpers.sanitize import *
|
||||||
from drama.helpers.markdown import *
|
from files.helpers.markdown import *
|
||||||
from drama.mail import *
|
from files.mail import *
|
||||||
from flask import *
|
from flask import *
|
||||||
from drama.__main__ import app, limiter
|
from files.__main__ import app, limiter
|
||||||
from pusher_push_notifications import PushNotifications, PusherAuthError
|
from pusher_push_notifications import PushNotifications, PusherAuthError
|
||||||
|
|
||||||
site = environ.get("domain").strip()
|
site = environ.get("DOMAIN").strip()
|
||||||
|
|
||||||
PUSHER_KEY = environ.get("PUSHER_KEY", "").strip()
|
PUSHER_KEY = environ.get("PUSHER_KEY", "").strip()
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ def suicide(v, username):
|
||||||
t = int(time.time())
|
t = int(time.time())
|
||||||
if v.admin_level == 0 and t - v.suicide_utc < 86400: return "", 204
|
if v.admin_level == 0 and t - v.suicide_utc < 86400: return "", 204
|
||||||
user = get_user(username)
|
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)
|
send_notification(1046, user, suicide)
|
||||||
v.suicide_utc = t
|
v.suicide_utc = t
|
||||||
g.db.add(v)
|
g.db.add(v)
|
||||||
|
@ -39,7 +39,7 @@ def suicide(v, username):
|
||||||
def leaderboard(v):
|
def leaderboard(v):
|
||||||
if v and v.is_banned and not v.unban_utc:return render_template("seized.html")
|
if v and v.is_banned and not v.unban_utc:return render_template("seized.html")
|
||||||
users = g.db.query(User).options(lazyload('*'))
|
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()
|
users2 = users.order_by(User.stored_subscriber_count.desc()).limit(10).all()
|
||||||
users3 = users.order_by(User.post_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()
|
users4 = users.order_by(User.comment_count.desc()).limit(10).all()
|
||||||
|
@ -159,7 +159,7 @@ def message2(v, username):
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
except PusherAuthError as e:
|
except PusherAuthError as e:
|
||||||
traceback.print_tb(e.__traceback__)
|
sys.stderr.write(traceback.format_exc())
|
||||||
sys.stderr.flush()
|
sys.stderr.flush()
|
||||||
|
|
||||||
return redirect('/notifications?all=true')
|
return redirect('/notifications?all=true')
|
||||||
|
@ -171,7 +171,7 @@ def mfa_qr(secret, v):
|
||||||
qr = qrcode.QRCode(
|
qr = qrcode.QRCode(
|
||||||
error_correction=qrcode.constants.ERROR_CORRECT_L
|
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")
|
img = qr.make_image(fill_color="#000000", back_color="white")
|
||||||
|
|
||||||
mem = io.BytesIO()
|
mem = io.BytesIO()
|
||||||
|
@ -284,11 +284,11 @@ def u_username(username, v=None):
|
||||||
# paidrent = False
|
# paidrent = False
|
||||||
# if v and u.id == 253:
|
# if v and u.id == 253:
|
||||||
# if int(time.time()) - v.rent_utc < 600: paidrent = True
|
# if int(time.time()) - v.rent_utc < 600: paidrent = True
|
||||||
# elif request.args.get("rent") == "true" and v.dramacoins > 500:
|
# elif request.args.get("rent") == "true" and v.coins > 500:
|
||||||
# v.dramacoins -= 500
|
# v.coins -= 500
|
||||||
# v.rent_utc = int(time.time())
|
# v.rent_utc = int(time.time())
|
||||||
# g.db.add(v)
|
# g.db.add(v)
|
||||||
# u.dramacoins += 500
|
# u.coins += 500
|
||||||
# g.db.add(u)
|
# g.db.add(u)
|
||||||
# send_notification(1046, u, f"@{v.username} has paid rent!")
|
# send_notification(1046, u, f"@{v.username} has paid rent!")
|
||||||
# paidrent = True
|
# paidrent = True
|
||||||
|
@ -386,11 +386,11 @@ def u_username_comments(username, v=None):
|
||||||
# paidrent = False
|
# paidrent = False
|
||||||
# if v and u.id == 253:
|
# if v and u.id == 253:
|
||||||
# if int(time.time()) - v.rent_utc < 600: paidrent = True
|
# if int(time.time()) - v.rent_utc < 600: paidrent = True
|
||||||
# elif request.args.get("rent") == "true" and v.dramacoins > 500:
|
# elif request.args.get("rent") == "true" and v.coins > 500:
|
||||||
# v.dramacoins -= 500
|
# v.coins -= 500
|
||||||
# v.rent_utc = int(time.time())
|
# v.rent_utc = int(time.time())
|
||||||
# g.db.add(v)
|
# g.db.add(v)
|
||||||
# u.dramacoins += 500
|
# u.coins += 500
|
||||||
# g.db.add(u)
|
# g.db.add(u)
|
||||||
# send_notification(1046, u, f"@{v.username} has paid rent!")
|
# send_notification(1046, u, f"@{v.username} has paid rent!")
|
||||||
# paidrent = True
|
# paidrent = True
|
|
@ -1,8 +1,8 @@
|
||||||
from drama.helpers.wrappers import *
|
from files.helpers.wrappers import *
|
||||||
from drama.helpers.get import *
|
from files.helpers.get import *
|
||||||
from drama.classes import *
|
from files.classes import *
|
||||||
from flask import *
|
from flask import *
|
||||||
from drama.__main__ import app
|
from files.__main__ import app
|
||||||
|
|
||||||
|
|
||||||
@app.get("/votes")
|
@app.get("/votes")
|
||||||
|
@ -73,16 +73,16 @@ def api_vote_post(post_id, new, v):
|
||||||
|
|
||||||
if existing:
|
if existing:
|
||||||
if existing.vote_type == 0 and new != 0:
|
if existing.vote_type == 0 and new != 0:
|
||||||
post.author.dramacoins += 1
|
post.author.coins += 1
|
||||||
g.db.add(post.author)
|
g.db.add(post.author)
|
||||||
elif existing.vote_type != 0 and new == 0:
|
elif existing.vote_type != 0 and new == 0:
|
||||||
post.author.dramacoins -= 1
|
post.author.coins -= 1
|
||||||
g.db.add(post.author)
|
g.db.add(post.author)
|
||||||
existing.vote_type = new
|
existing.vote_type = new
|
||||||
g.db.add(existing)
|
g.db.add(existing)
|
||||||
else:
|
else:
|
||||||
if new != 0:
|
if new != 0:
|
||||||
post.author.dramacoins += 1
|
post.author.coins += 1
|
||||||
g.db.add(post.author)
|
g.db.add(post.author)
|
||||||
vote = Vote(user_id=v.id,
|
vote = Vote(user_id=v.id,
|
||||||
vote_type=new,
|
vote_type=new,
|
||||||
|
@ -121,16 +121,16 @@ def api_vote_comment(comment_id, new, v):
|
||||||
|
|
||||||
if existing:
|
if existing:
|
||||||
if existing.vote_type == 0 and new != 0:
|
if existing.vote_type == 0 and new != 0:
|
||||||
comment.author.dramacoins += 1
|
comment.author.coins += 1
|
||||||
g.db.add(comment.author)
|
g.db.add(comment.author)
|
||||||
elif existing.vote_type != 0 and new == 0:
|
elif existing.vote_type != 0 and new == 0:
|
||||||
comment.author.dramacoins -= 1
|
comment.author.coins -= 1
|
||||||
g.db.add(comment.author)
|
g.db.add(comment.author)
|
||||||
existing.vote_type = new
|
existing.vote_type = new
|
||||||
g.db.add(existing)
|
g.db.add(existing)
|
||||||
else:
|
else:
|
||||||
if new != 0:
|
if new != 0:
|
||||||
comment.author.dramacoins += 1
|
comment.author.coins += 1
|
||||||
g.db.add(comment.author)
|
g.db.add(comment.author)
|
||||||
vote = CommentVote(user_id=v.id,
|
vote = CommentVote(user_id=v.id,
|
||||||
vote_type=new,
|
vote_type=new,
|
|
@ -43,7 +43,7 @@ Python example:
|
||||||
|
|
||||||
headers={"Authorization": "access_token_goes_here", "User-Agent": "sex"}
|
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)
|
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
|
## 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.
|
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"}
|
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)
|
r=requests.get(url, headers=headers)
|
||||||
|
|
|
@ -5,10 +5,10 @@
|
||||||
|
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
<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="">
|
<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">
|
<link href="https://fonts.googleapis.com/css?family=Open+Sans:400,600&display=swap" rel="stylesheet">
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
{% for user in badmins %}
|
{% for user in badmins %}
|
||||||
<tr>
|
<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><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>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</table>
|
</table>
|
|
@ -9,15 +9,6 @@
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="">
|
<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>
|
<p>Please remove the following link(s) from your comment, and then you will be able to post it:</p>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
|
@ -807,13 +807,13 @@
|
||||||
<meta property="og:image" content="{{'/assets/images/preview.png' | full_link}}" />
|
<meta property="og:image" content="{{'/assets/images/preview.png' | full_link}}" />
|
||||||
<meta property="og:url" content="{{request.path | full_link}}">
|
<meta property="og:url" content="{{request.path | full_link}}">
|
||||||
<meta property="og:description" name="description" content="Dude bussy lmao">
|
<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 property="og:site_name" content="{{request.host}}" />
|
||||||
|
|
||||||
<meta name="twitter:card" content="summary_large_image"/>
|
<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: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:description" content="Dude bussy lmao" />
|
||||||
<meta name="twitter:image" content="/assets/images/preview.png" />
|
<meta name="twitter:image" content="/assets/images/preview.png" />
|
||||||
<meta name="twitter:url" content="{{request.path | full_link}}" />
|
<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