spooky-22
parent
8fb6067701
commit
6b10d097a2
@ -1,4 +1,4 @@ |
||||
*.css linguist-detectable=false |
||||
*.js linguist-detectable=true |
||||
*.html linguist-detectable=false |
||||
*.py linguist-detectable=true |
||||
*.css linguist-detectable=false |
||||
*.js linguist-detectable=true |
||||
*.html linguist-detectable=false |
||||
*.py linguist-detectable=true |
||||
|
@ -1,17 +1,17 @@ |
||||
FROM ubuntu:20.04 |
||||
|
||||
ARG DEBIAN_FRONTEND=noninteractive |
||||
|
||||
RUN apt update && apt -y upgrade && apt install -y supervisor python3-pip libenchant1c2a ffmpeg |
||||
|
||||
COPY supervisord.conf /etc/supervisord.conf |
||||
|
||||
COPY requirements.txt /etc/requirements.txt |
||||
|
||||
RUN pip3 install -r /etc/requirements.txt |
||||
|
||||
RUN mkdir /images && mkdir /songs |
||||
|
||||
EXPOSE 80/tcp |
||||
|
||||
CMD [ "/usr/bin/supervisord", "-c", "/etc/supervisord.conf" ] |
||||
FROM ubuntu:20.04 |
||||
|
||||
ARG DEBIAN_FRONTEND=noninteractive |
||||
|
||||
RUN apt update && apt -y upgrade && apt install -y supervisor python3-pip libenchant1c2a ffmpeg |
||||
|
||||
COPY supervisord.conf /etc/supervisord.conf |
||||
|
||||
COPY requirements.txt /etc/requirements.txt |
||||
|
||||
RUN pip3 install -r /etc/requirements.txt |
||||
|
||||
RUN mkdir /images && mkdir /songs |
||||
|
||||
EXPOSE 80/tcp |
||||
|
||||
CMD [ "/usr/bin/supervisord", "-c", "/etc/supervisord.conf" ] |
||||
|
@ -1,6 +1,6 @@ |
||||
version: 2 |
||||
updates: |
||||
- package-ecosystem: "pip" |
||||
directory: "/" |
||||
schedule: |
||||
version: 2 |
||||
updates: |
||||
- package-ecosystem: "pip" |
||||
directory: "/" |
||||
schedule: |
||||
interval: "daily" |
@ -1,126 +1,126 @@ |
||||
import gevent.monkey |
||||
gevent.monkey.patch_all() |
||||
from os import environ, path |
||||
import secrets |
||||
from flask import * |
||||
from flask_caching import Cache |
||||
from flask_limiter import Limiter |
||||
from flask_compress import Compress |
||||
from flask_mail import Mail |
||||
from sqlalchemy.ext.declarative import declarative_base |
||||
from sqlalchemy.orm import sessionmaker, scoped_session |
||||
from sqlalchemy import * |
||||
import gevent |
||||
import redis |
||||
import time |
||||
from sys import stdout, argv |
||||
import faulthandler |
||||
import json |
||||
|
||||
app = Flask(__name__, template_folder='templates') |
||||
app.url_map.strict_slashes = False |
||||
app.jinja_env.cache = {} |
||||
app.jinja_env.auto_reload = True |
||||
faulthandler.enable() |
||||
|
||||
app.config["SITE_NAME"]=environ.get("SITE_NAME").strip() |
||||
app.config["GUMROAD_LINK"]=environ.get("GUMROAD_LINK", "https://marsey1.gumroad.com/l/tfcvri").strip() |
||||
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False |
||||
app.config['DATABASE_URL'] = environ.get("DATABASE_URL", "postgresql://postgres@localhost:5432") |
||||
app.config['SECRET_KEY'] = environ.get('MASTER_KEY') |
||||
app.config["SERVER_NAME"] = environ.get("DOMAIN").strip() |
||||
app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 3153600 |
||||
app.config["SESSION_COOKIE_NAME"] = "session_" + environ.get("SITE_NAME").strip().lower() |
||||
app.config["VERSION"] = "1.0.0" |
||||
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024 |
||||
app.config["SESSION_COOKIE_SECURE"] = True |
||||
app.config["SESSION_COOKIE_SAMESITE"] = "Lax" |
||||
app.config["PERMANENT_SESSION_LIFETIME"] = 60 * 60 * 24 * 365 |
||||
app.config["DEFAULT_COLOR"] = environ.get("DEFAULT_COLOR", "ff0000").strip() |
||||
app.config["DEFAULT_THEME"] = environ.get("DEFAULT_THEME", "midnight").strip() |
||||
app.config["FORCE_HTTPS"] = 1 |
||||
app.config["UserAgent"] = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36" |
||||
app.config["HCAPTCHA_SITEKEY"] = environ.get("HCAPTCHA_SITEKEY","").strip() |
||||
app.config["HCAPTCHA_SECRET"] = environ.get("HCAPTCHA_SECRET","").strip() |
||||
app.config["SPAM_SIMILARITY_THRESHOLD"] = float(environ.get("SPAM_SIMILARITY_THRESHOLD", 0.5)) |
||||
app.config["SPAM_URL_SIMILARITY_THRESHOLD"] = float(environ.get("SPAM_URL_SIMILARITY_THRESHOLD", 0.1)) |
||||
app.config["SPAM_SIMILAR_COUNT_THRESHOLD"] = int(environ.get("SPAM_SIMILAR_COUNT_THRESHOLD", 10)) |
||||
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", 10)) |
||||
app.config["CACHE_TYPE"] = "RedisCache" |
||||
app.config["CACHE_REDIS_URL"] = environ.get("REDIS_URL", "redis://localhost") |
||||
app.config['MAIL_SERVER'] = 'smtp.gmail.com' |
||||
app.config['MAIL_PORT'] = 587 |
||||
app.config['MAIL_USE_TLS'] = True |
||||
app.config['MAIL_USERNAME'] = environ.get("MAIL_USERNAME", "").strip() |
||||
app.config['MAIL_PASSWORD'] = environ.get("MAIL_PASSWORD", "").strip() |
||||
app.config['DESCRIPTION'] = environ.get("DESCRIPTION", "rdrama.net caters to drama in all forms such as: Real life, videos, photos, gossip, rumors, news sites, Reddit, and Beyondโข. There isn't drama we won't touch, and we want it all!").strip() |
||||
app.config['SETTINGS'] = {} |
||||
|
||||
r=redis.Redis(host=environ.get("REDIS_URL", "redis://localhost"), decode_responses=True, ssl_cert_reqs=None) |
||||
|
||||
def get_CF(): |
||||
with app.app_context(): |
||||
return request.headers.get('CF-Connecting-IP') |
||||
|
||||
limiter = Limiter( |
||||
app, |
||||
key_func=get_CF, |
||||
default_limits=["3/second;30/minute;200/hour;1000/day"], |
||||
application_limits=["10/second;200/minute;5000/hour;10000/day"], |
||||
storage_uri=environ.get("REDIS_URL", "redis://localhost") |
||||
) |
||||
|
||||
Base = declarative_base() |
||||
|
||||
engine = create_engine(app.config['DATABASE_URL']) |
||||
|
||||
db_session = scoped_session(sessionmaker(bind=engine, autoflush=False)) |
||||
|
||||
cache = Cache(app) |
||||
Compress(app) |
||||
mail = Mail(app) |
||||
|
||||
@app.before_request |
||||
def before_request(): |
||||
|
||||
with open('site_settings.json', 'r') as f: |
||||
app.config['SETTINGS'] = json.load(f) |
||||
|
||||
if request.host != app.config["SERVER_NAME"]: return {"error":"Unauthorized host provided."}, 401 |
||||
if request.headers.get("CF-Worker"): return {"error":"Cloudflare workers are not allowed to access this website."}, 401 |
||||
|
||||
if not app.config['SETTINGS']['Bots'] and request.headers.get("Authorization"): abort(503) |
||||
|
||||
g.db = db_session() |
||||
|
||||
ua = request.headers.get("User-Agent","").lower() |
||||
|
||||
if '; wv) ' in ua: g.webview = True |
||||
else: g.webview = False |
||||
|
||||
if 'iphone' in ua or 'ipad' in ua or 'ipod' in ua or 'mac os' in ua or ' firefox/' in ua: g.inferior_browser = True |
||||
else: g.inferior_browser = False |
||||
|
||||
g.timestamp = int(time.time()) |
||||
|
||||
|
||||
@app.teardown_appcontext |
||||
def teardown_request(error): |
||||
if hasattr(g, 'db') and g.db: |
||||
g.db.close() |
||||
stdout.flush() |
||||
|
||||
@app.after_request |
||||
def after_request(response): |
||||
response.headers.add("Strict-Transport-Security", "max-age=31536000") |
||||
response.headers.add("X-Frame-Options", "deny") |
||||
return response |
||||
|
||||
if app.config["SERVER_NAME"] == 'localhost': |
||||
from files.routes import * |
||||
from files.routes.chat import * |
||||
elif "load_chat" in argv: |
||||
from files.routes.chat import * |
||||
else: |
||||
import gevent.monkey |
||||
gevent.monkey.patch_all() |
||||
from os import environ, path |
||||
import secrets |
||||
from flask import * |
||||
from flask_caching import Cache |
||||
from flask_limiter import Limiter |
||||
from flask_compress import Compress |
||||
from flask_mail import Mail |
||||
from sqlalchemy.ext.declarative import declarative_base |
||||
from sqlalchemy.orm import sessionmaker, scoped_session |
||||
from sqlalchemy import * |
||||
import gevent |
||||
import redis |
||||
import time |
||||
from sys import stdout, argv |
||||
import faulthandler |
||||
import json |
||||
|
||||
app = Flask(__name__, template_folder='templates') |
||||
app.url_map.strict_slashes = False |
||||
app.jinja_env.cache = {} |
||||
app.jinja_env.auto_reload = True |
||||
faulthandler.enable() |
||||
|
||||
app.config["SITE_NAME"]=environ.get("SITE_NAME").strip() |
||||
app.config["GUMROAD_LINK"]=environ.get("GUMROAD_LINK", "https://marsey1.gumroad.com/l/tfcvri").strip() |
||||
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False |
||||
app.config['DATABASE_URL'] = environ.get("DATABASE_URL", "postgresql://postgres@localhost:5432") |
||||
app.config['SECRET_KEY'] = environ.get('MASTER_KEY') |
||||
app.config["SERVER_NAME"] = environ.get("DOMAIN").strip() |
||||
app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 3153600 |
||||
app.config["SESSION_COOKIE_NAME"] = "session_" + environ.get("SITE_NAME").strip().lower() |
||||
app.config["VERSION"] = "1.0.0" |
||||
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024 |
||||
app.config["SESSION_COOKIE_SECURE"] = True |
||||
app.config["SESSION_COOKIE_SAMESITE"] = "Lax" |
||||
app.config["PERMANENT_SESSION_LIFETIME"] = 60 * 60 * 24 * 365 |
||||
app.config["DEFAULT_COLOR"] = environ.get("DEFAULT_COLOR", "ff0000").strip() |
||||
app.config["DEFAULT_THEME"] = environ.get("DEFAULT_THEME", "midnight").strip() |
||||
app.config["FORCE_HTTPS"] = 1 |
||||
app.config["UserAgent"] = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36" |
||||
app.config["HCAPTCHA_SITEKEY"] = environ.get("HCAPTCHA_SITEKEY","").strip() |
||||
app.config["HCAPTCHA_SECRET"] = environ.get("HCAPTCHA_SECRET","").strip() |
||||
app.config["SPAM_SIMILARITY_THRESHOLD"] = float(environ.get("SPAM_SIMILARITY_THRESHOLD", 0.5)) |
||||
app.config["SPAM_URL_SIMILARITY_THRESHOLD"] = float(environ.get("SPAM_URL_SIMILARITY_THRESHOLD", 0.1)) |
||||
app.config["SPAM_SIMILAR_COUNT_THRESHOLD"] = int(environ.get("SPAM_SIMILAR_COUNT_THRESHOLD", 10)) |
||||
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", 10)) |
||||
app.config["CACHE_TYPE"] = "RedisCache" |
||||
app.config["CACHE_REDIS_URL"] = environ.get("REDIS_URL", "redis://localhost") |
||||
app.config['MAIL_SERVER'] = 'smtp.gmail.com' |
||||
app.config['MAIL_PORT'] = 587 |
||||
app.config['MAIL_USE_TLS'] = True |
||||
app.config['MAIL_USERNAME'] = environ.get("MAIL_USERNAME", "").strip() |
||||
app.config['MAIL_PASSWORD'] = environ.get("MAIL_PASSWORD", "").strip() |
||||
app.config['DESCRIPTION'] = environ.get("DESCRIPTION", "rdrama.net caters to drama in all forms such as: Real life, videos, photos, gossip, rumors, news sites, Reddit, and Beyondโข. There isn't drama we won't touch, and we want it all!").strip() |
||||
app.config['SETTINGS'] = {} |
||||
|
||||
r=redis.Redis(host=environ.get("REDIS_URL", "redis://localhost"), decode_responses=True, ssl_cert_reqs=None) |
||||
|
||||
def get_CF(): |
||||
with app.app_context(): |
||||
return request.headers.get('CF-Connecting-IP') |
||||
|
||||
limiter = Limiter( |
||||
app, |
||||
key_func=get_CF, |
||||
default_limits=["3/second;30/minute;200/hour;1000/day"], |
||||
application_limits=["10/second;200/minute;5000/hour;10000/day"], |
||||
storage_uri=environ.get("REDIS_URL", "redis://localhost") |
||||
) |
||||
|
||||
Base = declarative_base() |
||||
|
||||
engine = create_engine(app.config['DATABASE_URL']) |
||||
|
||||
db_session = scoped_session(sessionmaker(bind=engine, autoflush=False)) |
||||
|
||||
cache = Cache(app) |
||||
Compress(app) |
||||
mail = Mail(app) |
||||
|
||||
@app.before_request |
||||
def before_request(): |
||||
|
||||
with open('site_settings.json', 'r') as f: |
||||
app.config['SETTINGS'] = json.load(f) |
||||
|
||||
if request.host != app.config["SERVER_NAME"]: return {"error":"Unauthorized host provided."}, 401 |
||||
if request.headers.get("CF-Worker"): return {"error":"Cloudflare workers are not allowed to access this website."}, 401 |
||||
|
||||
if not app.config['SETTINGS']['Bots'] and request.headers.get("Authorization"): abort(503) |
||||
|
||||
g.db = db_session() |
||||
|
||||
ua = request.headers.get("User-Agent","").lower() |
||||
|
||||
if '; wv) ' in ua: g.webview = True |
||||
else: g.webview = False |
||||
|
||||
if 'iphone' in ua or 'ipad' in ua or 'ipod' in ua or 'mac os' in ua or ' firefox/' in ua: g.inferior_browser = True |
||||
else: g.inferior_browser = False |
||||
|
||||
g.timestamp = int(time.time()) |
||||
|
||||
|
||||
@app.teardown_appcontext |
||||
def teardown_request(error): |
||||
if hasattr(g, 'db') and g.db: |
||||
g.db.close() |
||||
stdout.flush() |
||||
|
||||
@app.after_request |
||||
def after_request(response): |
||||
response.headers.add("Strict-Transport-Security", "max-age=31536000") |
||||
response.headers.add("X-Frame-Options", "deny") |
||||
return response |
||||
|
||||
if app.config["SERVER_NAME"] == 'localhost': |
||||
from files.routes import * |
||||
from files.routes.chat import * |
||||
elif "load_chat" in argv: |
||||
from files.routes.chat import * |
||||
else: |
||||
from files.routes import * |
@ -1,21 +1,21 @@ |
||||
from .alts import * |
||||
from .badges import * |
||||
from .clients import * |
||||
from .comment import * |
||||
from .domains import * |
||||
from .flags import * |
||||
from .user import * |
||||
from .userblock import * |
||||
from .submission import * |
||||
from .votes import * |
||||
from .domains import * |
||||
from .subscriptions import * |
||||
from files.__main__ import app |
||||
from .mod_logs import * |
||||
from .award import * |
||||
from .marsey import * |
||||
from .sub_block import * |
||||
from .saves import * |
||||
from .views import * |
||||
from .notifications import * |
||||
from .alts import * |
||||
from .badges import * |
||||
from .clients import * |
||||
from .comment import * |
||||
from .domains import * |
||||
from .flags import * |
||||
from .user import * |
||||
from .userblock import * |
||||
from .submission import * |
||||
from .votes import * |
||||
from .domains import * |
||||
from .subscriptions import * |
||||
from files.__main__ import app |
||||
from .mod_logs import * |
||||
from .award import * |
||||
from .marsey import * |
||||
from .sub_block import * |
||||
from .saves import * |
||||
from .views import * |
||||
from .notifications import * |
||||
from .follows import * |
@ -1,14 +1,14 @@ |
||||
from sqlalchemy import * |
||||
from files.__main__ import Base |
||||
|
||||
|
||||
class Alt(Base): |
||||
__tablename__ = "alts" |
||||
|
||||
user1 = Column(Integer, ForeignKey("users.id"), primary_key=True) |
||||
user2 = Column(Integer, ForeignKey("users.id"), primary_key=True) |
||||
is_manual = Column(Boolean, default=False) |
||||
|
||||
def __repr__(self): |
||||
|
||||
return f"<Alt(id={self.id})>" |
||||
from sqlalchemy import * |
||||
from files.__main__ import Base |
||||
|
||||
|
||||
class Alt(Base): |
||||
__tablename__ = "alts" |
||||
|
||||
user1 = Column(Integer, ForeignKey("users.id"), primary_key=True) |
||||
user2 = Column(Integer, ForeignKey("users.id"), primary_key=True) |
||||
is_manual = Column(Boolean, default=False) |
||||
|
||||
def __repr__(self): |
||||
|
||||
return f"<Alt(id={self.id})>" |
||||
|
@ -1,36 +1,36 @@ |
||||
from sqlalchemy import * |
||||
from sqlalchemy.orm import relationship |
||||
from files.__main__ import Base |
||||
from os import environ |
||||
from files.helpers.lazy import lazy |
||||
from files.helpers.const import * |
||||
|
||||
class AwardRelationship(Base): |
||||
|
||||
__tablename__ = "award_relationships" |
||||
|
||||
id = Column(Integer, primary_key=True) |
||||
user_id = Column(Integer, ForeignKey("users.id")) |
||||
submission_id = Column(Integer, ForeignKey("submissions.id")) |
||||
comment_id = Column(Integer, ForeignKey("comments.id")) |
||||
kind = Column(String) |
||||
|
||||
user = relationship("User", primaryjoin="AwardRelationship.user_id==User.id", viewonly=True) |
||||
post = relationship("Submission", primaryjoin="AwardRelationship.submission_id==Submission.id", viewonly=True) |
||||
comment = relationship("Comment", primaryjoin="AwardRelationship.comment_id==Comment.id", viewonly=True) |
||||
|
||||
|
||||
@property |
||||
@lazy |
||||
def type(self): |
||||
return AWARDS[self.kind] |
||||
|
||||
@property |
||||
@lazy |
||||
def title(self): |
||||
return self.type['title'] |
||||
|
||||
@property |
||||
@lazy |
||||
def class_list(self): |
||||
return self.type['icon']+' '+self.type['color'] |
||||
from sqlalchemy import * |
||||
from sqlalchemy.orm import relationship |
||||
from files.__main__ import Base |
||||
from os import environ |
||||
from files.helpers.lazy import lazy |
||||
from files.helpers.const import * |
||||
|
||||
class AwardRelationship(Base): |
||||
|
||||
__tablename__ = "award_relationships" |
||||
|
||||
id = Column(Integer, primary_key=True) |
||||
user_id = Column(Integer, ForeignKey("users.id")) |
||||
submission_id = Column(Integer, ForeignKey("submissions.id")) |
||||
comment_id = Column(Integer, ForeignKey("comments.id")) |
||||
kind = Column(String) |
||||
|
||||
user = relationship("User", primaryjoin="AwardRelationship.user_id==User.id", viewonly=True) |
||||
post = relationship("Submission", primaryjoin="AwardRelationship.submission_id==Submission.id", viewonly=True) |
||||
comment = relationship("Comment", primaryjoin="AwardRelationship.comment_id==Comment.id", viewonly=True) |
||||
|
||||
|
||||
@property |
||||
@lazy |
||||
def type(self): |
||||
return AWARDS[self.kind] |
||||
|
||||
@property |
||||
@lazy |
||||
def title(self): |
||||
return self.type['title'] |
||||
|
||||
@property |
||||
@lazy |
||||
def class_list(self): |
||||
return self.type['icon']+' '+self.type['color'] |
||||
|
@ -1,73 +1,73 @@ |
||||
from sqlalchemy import * |
||||
from sqlalchemy.orm import relationship |
||||
from files.__main__ import Base, app |
||||
from os import environ |
||||
from files.helpers.lazy import lazy |
||||
from files.helpers.const import * |
||||
from datetime import datetime |
||||
from json import loads |
||||
|
||||
class BadgeDef(Base): |
||||
__tablename__ = "badge_defs" |
||||
|
||||
id = Column(Integer, primary_key=True, autoincrement=True) |
||||
name = Column(String) |
||||
description = Column(String) |
||||
|
||||
def __repr__(self): |
||||
return f"<BadgeDef(id={self.id})>" |
||||
|
||||
|
||||
class Badge(Base): |
||||
|
||||
__tablename__ = "badges" |
||||
|
||||
user_id = Column(Integer, ForeignKey('users.id'), primary_key=True) |
||||
badge_id = Column(Integer, ForeignKey('badge_defs.id'), primary_key=True) |
||||
description = Column(String) |
||||
url = Column(String) |
||||
|
||||
user = relationship("User", viewonly=True) |
||||
badge = relationship("BadgeDef", primaryjoin="foreign(Badge.badge_id) == remote(BadgeDef.id)", viewonly=True) |
||||
|
||||
def __repr__(self): |
||||
return f"<Badge(user_id={self.user_id}, badge_id={self.badge_id})>" |
||||
|
||||
@property |
||||
@lazy |
||||
def text(self): |
||||
if self.name == "Chud": |
||||
ti = self.user.agendaposter |
||||
if ti: text = self.badge.description + " until " + datetime.utcfromtimestamp(ti).strftime('%Y-%m-%d %H:%M:%S') |
||||
else: text = self.badge.description + " permanently" |
||||
elif self.badge_id in {94,95,96,97,98,109}: |
||||
if self.badge_id == 94: ti = self.user.progressivestack |
||||
elif self.badge_id == 95: ti = self.user.bird |
||||
elif self.badge_id == 96: ti = self.user.flairchanged |
||||
elif self.badge_id == 97: ti = self.user.longpost |
||||
elif self.badge_id == 98: ti = self.user.marseyawarded |
||||
elif self.badge_id == 109: ti = self.user.rehab |
||||
text = self.badge.description + " until " + datetime.utcfromtimestamp(ti).strftime('%Y-%m-%d %H:%M:%S') |
||||
elif self.description: text = self.description |
||||
elif self.badge.description: text = self.badge.description |
||||
else: return self.name |
||||
return f'{self.name} - {text}' |
||||
|
||||
@property |
||||
@lazy |
||||
def name(self): |
||||
return self.badge.name |
||||
|
||||
@property |
||||
@lazy |
||||
def path(self): |
||||
return f"/assets/images/badges/{self.badge_id}.webp" |
||||
|
||||
@property |
||||
@lazy |
||||
def json(self): |
||||
return {'text': self.text, |
||||
'name': self.name, |
||||
'url': self.url, |
||||
'icon_url':self.path |
||||
} |
||||
from sqlalchemy import * |
||||
from sqlalchemy.orm import relationship |
||||
from files.__main__ import Base, app |
||||
from os import environ |
||||
from files.helpers.lazy import lazy |
||||
from files.helpers.const import * |
||||
from datetime import datetime |
||||
from json import loads |
||||
|
||||
class BadgeDef(Base): |
||||
__tablename__ = "badge_defs" |
||||
|
||||
id = Column(Integer, primary_key=True, autoincrement=True) |
||||
name = Column(String) |
||||
description = Column(String) |
||||
|
||||
def __repr__(self): |
||||
return f"<BadgeDef(id={self.id})>" |
||||
|
||||
|
||||
class Badge(Base): |
||||
|
||||
__tablename__ = "badges" |
||||
|
||||
user_id = Column(Integer, ForeignKey('users.id'), primary_key=True) |
||||
badge_id = Column(Integer, ForeignKey('badge_defs.id'), primary_key=True) |
||||
description = Column(String) |
||||
url = Column(String) |
||||
|
||||
user = relationship("User", viewonly=True) |
||||
badge = relationship("BadgeDef", primaryjoin="foreign(Badge.badge_id) == remote(BadgeDef.id)", viewonly=True) |
||||
|
||||
def __repr__(self): |
||||
return f"<Badge(user_id={self.user_id}, badge_id={self.badge_id})>" |
||||
|
||||
@property |
||||
@lazy |
||||
def text(self): |
||||
if self.name == "Chud": |
||||
ti = self.user.agendaposter |
||||
if ti: text = self.badge.description + " until " + datetime.utcfromtimestamp(ti).strftime('%Y-%m-%d %H:%M:%S') |
||||
else: text = self.badge.description + " permanently" |
||||
elif self.badge_id in {94,95,96,97,98,109}: |
||||
if self.badge_id == 94: ti = self.user.progressivestack |
||||
elif self.badge_id == 95: ti = self.user.bird |
||||
elif self.badge_id == 96: ti = self.user.flairchanged |
||||
elif self.badge_id == 97: ti = self.user.longpost |
||||
elif self.badge_id == 98: ti = self.user.marseyawarded |
||||
elif self.badge_id == 109: ti = self.user.rehab |
||||
text = self.badge.description + " until " + datetime.utcfromtimestamp(ti).strftime('%Y-%m-%d %H:%M:%S') |
||||
elif self.description: text = self.description |
||||
elif self.badge.description: text = self.badge.description |
||||
else: return self.name |
||||
return f'{self.name} - {text}' |
||||
|
||||
@property |
||||
@lazy |
||||
def name(self): |
||||
return self.badge.name |
||||
|
||||
@property |
||||
@lazy |
||||
def path(self): |
||||
return f"/assets/images/badges/{self.badge_id}.webp" |
||||
|
||||
@property |
||||
@lazy |
||||
def json(self): |
||||
return {'text': self.text, |
||||
'name': self.name, |
||||
'url': self.url, |
||||
'icon_url':self.path |
||||
} |
||||
|
@ -1,84 +1,84 @@ |
||||
from flask import * |
||||
from sqlalchemy import * |
||||
from sqlalchemy.orm import relationship |
||||
from .submission import Submission |
||||
from .comment import Comment |
||||
from files.__main__ import Base |
||||
from files.helpers.lazy import lazy |
||||
from files.helpers.const import * |
||||
import time |
||||
|
||||
class OauthApp(Base): |
||||
|
||||
__tablename__ = "oauth_apps" |
||||
|
||||
id = Column(Integer, primary_key=True) |
||||
client_id = Column(String) |
||||
app_name = Column(String) |
||||
redirect_uri = Column(String) |
||||
description = Column(String) |
||||
author_id = Column(Integer, ForeignKey("users.id")) |
||||
|
||||
author = relationship("User", viewonly=True) |
||||
|
||||
def __repr__(self): return f"<OauthApp(id={self.id})>" |
||||
|
||||
|
||||
@property |
||||
@lazy |
||||
def created_date(self): |
||||
return time.strftime("%d %B %Y", time.gmtime(self.created_utc)) |
||||
|
||||
@property |
||||
@lazy |
||||
def created_datetime(self): |
||||
return str(time.strftime("%d/%B/%Y %H:%M:%S UTC", time.gmtime(self.created_utc))) |
||||
|
||||
@property |
||||
@lazy |
||||
def permalink(self): return f"/admin/app/{self.id}" |
||||
|
||||
@lazy |
||||
def idlist(self, page=1): |
||||
|
||||
posts = g.db.query(Submission.id).filter_by(app_id=self.id) |
||||
|
||||
posts=posts.order_by(Submission.created_utc.desc()) |
||||
|
||||
posts=posts.offset(100*(page-1)).limit(101) |
||||
|
||||
return [x[0] for x in posts.all()] |
||||
|
||||
@lazy |
||||
def comments_idlist(self, page=1): |
||||
|
||||
posts = g.db.query(Comment.id).filter_by(app_id=self.id) |
||||
|
||||
posts=posts.order_by(Comment.created_utc.desc()) |
||||
|
||||
posts=posts.offset(100*(page-1)).limit(101) |
||||
|
||||
return [x[0] for x in posts.all()] |
||||
|
||||
|
||||
|
||||
class ClientAuth(Base): |
||||
|
||||
__tablename__ = "client_auths" |
||||
|
||||
user_id = Column(Integer, ForeignKey("users.id"), primary_key=True) |
||||
oauth_client = Column(Integer, ForeignKey("oauth_apps.id"), primary_key=True) |
||||
access_token = Column(String) |
||||
|
||||
user = relationship("User", viewonly=True) |
||||
application = relationship("OauthApp", viewonly=True) |
||||
|
||||
@property |
||||
@lazy |
||||
def created_date(self): |
||||
return time.strftime("%d %B %Y", time.gmtime(self.created_utc)) |
||||
|
||||
@property |
||||
@lazy |
||||
def created_datetime(self): |
||||
from flask import * |
||||
from sqlalchemy import * |
||||
from sqlalchemy.orm import relationship |
||||
from .submission import Submission |
||||
from .comment import Comment |
||||
from files.__main__ import Base |
||||
from files.helpers.lazy import lazy |
||||
from files.helpers.const import * |
||||
import time |
||||
|
||||
class OauthApp(Base): |
||||
|
||||
__tablename__ = "oauth_apps" |
||||
|
||||
id = Column(Integer, primary_key=True) |
||||
client_id = Column(String) |
||||
app_name = Column(String) |
||||
redirect_uri = Column(String) |
||||
description = Column(String) |
||||
author_id = Column(Integer, ForeignKey("users.id")) |
||||
|
||||
author = relationship("User", viewonly=True) |
||||
|
||||
def __repr__(self): return f"<OauthApp(id={self.id})>" |
||||
|
||||
|
||||
@property |
||||
@lazy |
||||
def created_date(self): |
||||
return time.strftime("%d %B %Y", time.gmtime(self.created_utc)) |
||||
|
||||
@property |
||||
@lazy |
||||
def created_datetime(self): |
||||
return str(time.strftime("%d/%B/%Y %H:%M:%S UTC", time.gmtime(self.created_utc))) |
||||
|
||||
@property |
||||
@lazy |
||||
def permalink(self): return f"/admin/app/{self.id}" |
||||
|
||||
@lazy |
||||
def idlist(self, page=1): |
||||
|
||||
posts = g.db.query(Submission.id).filter_by(app_id=self.id) |
||||
|
||||
posts=posts.order_by(Submission.created_utc.desc()) |
||||
|
||||
posts=posts.offset(100*(page-1)).limit(101) |
||||
|
||||
return [x[0] for x in posts.all()] |
||||
|
||||
@lazy |
||||
def comments_idlist(self, page=1): |
||||
|
||||
posts = g.db.query(Comment.id).filter_by(app_id=self.id) |
||||
|
||||
posts=posts.order_by(Comment.created_utc.desc()) |
||||
|
||||
posts=posts.offset(100*(page-1)).limit(101) |
||||
|
||||
return [x[0] for x in posts.all()] |
||||
|
||||
|
||||
|
||||
class ClientAuth(Base): |
||||
|
||||
__tablename__ = "client_auths" |
||||
|
||||
user_id = Column(Integer, ForeignKey("users.id"), primary_key=True) |
||||
oauth_client = Column(Integer, ForeignKey("oauth_apps.id"), primary_key=True) |
||||
access_token = Column(String) |
||||
|
||||
user = relationship("User", viewonly=True) |
||||
application = relationship("OauthApp", viewonly=True) |
||||
|
||||
@property |
||||
@lazy |
||||
def created_date(self): |
||||
return time.strftime("%d %B %Y", time.gmtime(self.created_utc)) |
||||
|
||||
@property |
||||
@lazy |
||||
def created_datetime(self): |
||||
return str(time.strftime("%d/%B/%Y %H:%M:%S UTC", time.gmtime(self.created_utc))) |
@ -1,8 +1,8 @@ |
||||
from sqlalchemy import * |
||||
from files.__main__ import Base |
||||
|
||||
class BannedDomain(Base): |
||||
|
||||
__tablename__ = "banneddomains" |
||||
domain = Column(String, primary_key=True) |
||||
from sqlalchemy import * |
||||
from files.__main__ import Base |
||||
|
||||
class BannedDomain(Base): |
||||
|
||||
__tablename__ = "banneddomains" |
||||
domain = Column(String, primary_key=True) |
||||
reason = Column(String) |
@ -1,71 +1,71 @@ |
||||
from sqlalchemy import * |
||||
from sqlalchemy.orm import relationship |
||||
from files.__main__ import Base |
||||
from files.helpers.lazy import lazy |
||||
from files.helpers.const import * |
||||
import time |
||||
|
||||
class Flag(Base): |
||||
|
||||
__tablename__ = "flags" |
||||
|
||||
post_id = Column(Integer, ForeignKey("submissions.id"), primary_key=True) |
||||
user_id = Column(Integer, ForeignKey("users.id"), primary_key=True) |
||||
reason = Column(String) |
||||
created_utc = Column(Integer) |
||||
|
||||
user = relationship("User", primaryjoin = "Flag.user_id == User.id", uselist = False, viewonly=True) |
||||
|
||||
def __init__(self, *args, **kwargs): |
||||
if "created_utc" not in kwargs: kwargs["created_utc"] = int(time.time()) |
||||
super().__init__(*args, **kwargs) |
||||
|
||||
def __repr__(self): |
||||
return f"<Flag(id={self.id})>" |
||||
|
||||
@property |
||||
@lazy |
||||
def created_date(self): |
||||
return time.strftime("%d %B %Y", time.gmtime(self.created_utc)) |
||||
|
||||
@property |
||||
@lazy |
||||
def created_datetime(self): |
||||
return str(time.strftime("%d/%B/%Y %H:%M:%S UTC", time.gmtime(self.created_utc))) |
||||
|
||||
@lazy |
||||
def realreason(self, v): |
||||
return censor_slurs(self.reason, v) |
||||
|
||||
|
||||
class CommentFlag(Base): |
||||
|
||||
__tablename__ = "commentflags" |
||||
|
||||
comment_id = Column(Integer, ForeignKey("comments.id"), primary_key=True) |
||||
user_id = Column(Integer, ForeignKey("users.id"), primary_key=True) |
||||
reason = Column(String) |
||||
created_utc = Column(Integer) |
||||
|
||||
user = relationship("User", primaryjoin = "CommentFlag.user_id == User.id", uselist = False, viewonly=True) |
||||
|
||||
def __init__(self, *args, **kwargs): |
||||
if "created_utc" not in kwargs: kwargs["created_utc"] = int(time.time()) |
||||
super().__init__(*args, **kwargs) |
||||
|
||||
def __repr__(self): |
||||
return f"<CommentFlag(id={self.id})>" |
||||
|
||||
@property |
||||
@lazy |
||||
def created_date(self): |
||||
return time.strftime("%d %B %Y", time.gmtime(self.created_utc)) |
||||
|
||||
@property |
||||
@lazy |
||||
def created_datetime(self): |
||||
return str(time.strftime("%d/%B/%Y %H:%M:%S UTC", time.gmtime(self.created_utc))) |
||||
|
||||
@lazy |
||||
def realreason(self, v): |
||||
from sqlalchemy import * |
||||
from sqlalchemy.orm import relationship |
||||
from files.__main__ import Base |
||||
from files.helpers.lazy import lazy |
||||
from files.helpers.const import * |
||||
import time |
||||
|
||||
class Flag(Base): |
||||
|
||||
__tablename__ = "flags" |
||||
|
||||
post_id = Column(Integer, ForeignKey("submissions.id"), primary_key=True) |
||||
user_id = Column(Integer, ForeignKey("users.id"), primary_key=True) |
||||
reason = Column(String) |
||||
created_utc = Column(Integer) |
||||
|
||||
user = relationship("User", primaryjoin = "Flag.user_id == User.id", uselist = False, viewonly=True) |
||||
|
||||
def __init__(self, *args, **kwargs): |
||||
if "created_utc" not in kwargs: kwargs["created_utc"] = int(time.time()) |
||||
super().__init__(*args, **kwargs) |
||||
|
||||
def __repr__(self): |
||||
return f"<Flag(id={self.id})>" |
||||
|
||||
@property |
||||
@lazy |
||||
def created_date(self): |
||||
return time.strftime("%d %B %Y", time.gmtime(self.created_utc)) |
||||
|
||||
@property |
||||
@lazy |
||||
def created_datetime(self): |
||||
return str(time.strftime("%d/%B/%Y %H:%M:%S UTC", time.gmtime(self.created_utc))) |
||||
|
||||
@lazy |
||||
def realreason(self, v): |
||||
return censor_slurs(self.reason, v) |
||||
|
||||
|
||||
class CommentFlag(Base): |
||||
|
||||
__tablename__ = "commentflags" |
||||
|
||||
comment_id = Column(Integer, ForeignKey("comments.id"), primary_key=True) |
||||
user_id = Column(Integer, ForeignKey("users.id"), primary_key=True) |
||||
reason = Column(String) |
||||
created_utc = Column(Integer) |
||||
|
||||
user = relationship("User", primaryjoin = "CommentFlag.user_id == User.id", uselist = False, viewonly=True) |
||||
|
||||
def __init__(self, *args, **kwargs): |
||||
if "created_utc" not in kwargs: kwargs["created_utc"] = int(time.time()) |
||||
super().__init__(*args, **kwargs) |
||||
|
||||
def __repr__(self): |
||||
return f"<CommentFlag(id={self.id})>" |
||||
|
||||
@property |
||||
@lazy |
||||
def created_date(self): |
||||
return time.strftime("%d %B %Y", time.gmtime(self.created_utc)) |
||||
|
||||
@property |
||||
@lazy |
||||
def created_datetime(self): |
||||
return str(time.strftime("%d/%B/%Y %H:%M:%S UTC", time.gmtime(self.created_utc))) |
||||
|
||||
@lazy |
||||
def realreason(self, v): |
||||
return censor_slurs(self.reason, v) |
@ -1,424 +1,424 @@ |
||||
from sqlalchemy import * |
||||
from sqlalchemy.orm import relationship |
||||
from files.__main__ import Base |
||||
import time |
||||
from files.helpers.lazy import lazy |
||||
from os import environ |
||||
from copy import deepcopy |
||||
from files.helpers.const import * |
||||
|
||||
class ModAction(Base): |
||||
__tablename__ = "modactions" |
||||
id = Column(Integer, primary_key=True) |
||||
user_id = Column(Integer, ForeignKey("users.id")) |
||||
kind = Column(String) |
||||
target_user_id = Column(Integer, ForeignKey("users.id")) |
||||
target_submission_id = Column(Integer, ForeignKey("submissions.id")) |
||||
target_comment_id = Column(Integer, ForeignKey("comments.id")) |
||||
_note=Column(String) |
||||
created_utc = Column(Integer) |
||||
|
||||
user = relationship("User", primaryjoin="User.id==ModAction.user_id", viewonly=True) |
||||
target_user = relationship("User", primaryjoin="User.id==ModAction.target_user_id", viewonly=True) |
||||
target_post = relationship("Submission", viewonly=True) |
||||
|
||||
def __init__(self, *args, **kwargs): |
||||
if "created_utc" not in kwargs: kwargs["created_utc"] = int(time.time()) |
||||
super().__init__(*args, **kwargs) |
||||
|
||||
def __repr__(self): |
||||
return f"<ModAction(id={self.id})>" |
||||
|
||||
@property |
||||
@lazy |
||||
def age_string(self): |
||||
|
||||
age = int(time.time()) - self.created_utc |
||||
|
||||
if age < 60: |
||||
return "just now" |
||||
elif age < 3600: |
||||
minutes = int(age / 60) |
||||
return f"{minutes}m ago" |
||||
elif age < 86400: |
||||
hours = int(age / 3600) |
||||
return f"{hours}hr ago" |
||||
elif age < 2678400: |
||||
days = int(age / 86400) |
||||
return f"{days}d ago" |
||||
|
||||
now = time.gmtime() |
||||
ctd = time.gmtime(self.created_utc) |
||||
|
||||
months = now.tm_mon - ctd.tm_mon + 12 * (now.tm_year - ctd.tm_year) |
||||
if now.tm_mday < ctd.tm_mday: |
||||
months -= 1 |
||||
|
||||
if months < 12: |
||||
return f"{months}mo ago" |
||||
else: |
||||
years = int(months / 12) |
||||
return f"{years}yr ago" |
||||
|
||||
|
||||
@property |
||||
def note(self): |
||||
|
||||
if self.kind=="ban_user": |
||||
if self.target_post: return f'for <a href="{self.target_post.permalink}">post</a>' |
||||
elif self.target_comment_id: return f'for <a href="/comment/{self.target_comment_id}">comment</a>' |
||||
else: return self._note |
||||
else: |
||||
return self._note or "" |
||||
|
||||
@note.setter |
||||
def note(self, x): |
||||
self._note=x |
||||
|
||||
@property |
||||
@lazy |
||||
def string(self): |
||||
|
||||
output = ACTIONTYPES[self.kind]["str"].format(self=self, cc=CC_TITLE) |
||||
|
||||
if self.note: output += f" <i>({self.note})</i>" |
||||
|
||||
return output |
||||
|
||||
@property |
||||
@lazy |
||||
def target_link(self): |
||||
if self.target_user: return f'<a href="{self.target_user.url}">{self.target_user.username}</a>' |
||||
elif self.target_post: |
||||
if self.target_post.club: return f'<a href="{self.target_post.permalink}">{CC} ONLY</a>' |
||||
return f'<a href="{self.target_post.permalink}">{self.target_post.title_html}</a>' |
||||
elif self.target_comment_id: return f'<a href="/comment/{self.target_comment_id}?context=8#context">comment</a>' |
||||
|
||||
@property |
||||
@lazy |
||||
def icon(self): |
||||
return ACTIONTYPES[self.kind]['icon'] |
||||
|
||||
@property |
||||
@lazy |
||||
def color(self): |
||||
return ACTIONTYPES[self.kind]['color'] |
||||
|
||||
@property |
||||
@lazy |
||||
def permalink(self): |
||||
return f"/log/{self.id}" |
||||
|
||||
ACTIONTYPES = { |
||||
'agendaposter': { |
||||
"str": 'set chud theme on {self.target_link}', |
||||
"icon": 'fa-snooze', |
||||
"color": 'bg-danger' |
||||
}, |
||||
'approve_app': { |
||||
"str": 'approved an application by {self.target_link}', |
||||
"icon": 'fa-robot', |
||||
"color": 'bg-success' |
||||
}, |
||||
'badge_grant': { |
||||
"str": 'granted badge to {self.target_link}', |
||||
"icon": 'fa-badge', |
||||
"color": 'bg-success' |
||||
}, |
||||
'badge_remove': { |
||||
"str": 'removed badge from {self.target_link}', |
||||
"icon": 'fa-badge', |
||||
"color": 'bg-danger' |
||||
}, |
||||
'ban_comment': { |
||||
"str": 'removed {self.target_link}', |
||||
"icon": 'fa-comment', |
||||
"color": 'bg-danger' |
||||
}, |
||||
'ban_domain': { |
||||
"str": 'banned a domain', |
||||
"icon": 'fa-globe', |
||||
"color": 'bg-danger' |
||||
}, |
||||
'ban_post': { |
||||
"str": 'removed post {self.target_link}', |
||||
"icon": 'fa-feather-alt', |
||||
"color": 'bg-danger' |
||||
}, |
||||
'ban_user': { |
||||
"str": 'banned user {self.target_link}', |
||||
"icon": 'fa-user-slash', |
||||
"color": 'bg-danger' |
||||
}, |
||||
'change_sidebar': { |
||||
"str": 'changed the sidebar', |
||||
"icon": 'fa-columns', |
||||
"color": 'bg-primary' |
||||
}, |
||||
'check': { |
||||
"str": 'gave {self.target_link} a checkmark', |
||||
"icon": 'fa-badge-check', |
||||
"color": 'bg-success' |
||||
}, |
||||
'club_allow': { |
||||
"str": 'allowed user {self.target_link} into the {cc}', |
||||
"icon": 'fa-golf-club', |
||||
"color": 'bg-success' |
||||
}, |
||||
'club_ban': { |
||||
"str": 'disallowed user {self.target_link} from the {cc}', |
||||
"icon": 'fa-golf-club', |
||||
"color": 'bg-danger' |
||||
}, |
||||
'delete_report': { |
||||
"str": 'deleted report on {self.target_link}', |
||||
"icon": 'fa-flag', |
||||
"color": 'bg-danger' |
||||
}, |
||||
'disable_Bots': { |
||||
"str": 'disabled Bots', |
||||
"icon": 'fa-robot', |
||||
"color": 'bg-danger' |
||||
}, |
||||
'disable_Fart mode': { |
||||
"str": 'disabled fart mode', |
||||
"icon": 'fa-gas-pump-slash', |
||||
"color": 'bg-danger' |
||||
}, |
||||
'disable_Read-only mode': { |
||||
"str": 'disabled readonly mode', |
||||
"icon": 'fa-book', |
||||
"color": 'bg-danger' |
||||
}, |
||||
'disable_Signups': { |
||||
"str": 'disabled Signups', |
||||
"icon": 'fa-users', |
||||
"color": 'bg-danger' |
||||
}, |
||||
'disable_under_attack': { |
||||
"str": 'disabled under attack mode', |
||||
"icon": 'fa-shield', |
||||
"color": 'bg-muted' |
||||
}, |
||||
'distinguish_comment': { |
||||
"str": 'distinguished {self.target_link}', |
||||
"icon": 'fa-crown', |
||||
"color": 'bg-success' |
||||
}, |
||||
'distinguish_post': { |
||||
"str": 'distinguished {self.target_link}', |
||||
"icon": 'fa-crown', |
||||
"color": 'bg-success' |
||||
}, |
||||
'distribute': { |
||||
"str": 'distributed bet winnings to voters on {self.target_link}', |
||||
"icon": 'fa-dollar-sign', |
||||
"color": 'bg-success' |
||||
}, |
||||
'dump_cache': { |
||||
"str": 'dumped cache', |
||||
"icon": 'fa-trash-alt', |
||||
"color": 'bg-muted' |
||||
}, |
||||
'edit_post': { |
||||
"str": 'edited {self.target_link}', |
||||
"icon": 'fa-edit', |
||||
"color": 'bg-primary' |
||||
}, |
||||
'enable_Bots': { |
||||
"str": 'enabled Bots', |
||||
"icon": 'fa-robot', |
||||
"color": 'bg-success' |
||||
}, |
||||
'enable_Fart mode': { |
||||
"str": 'enabled fart mode', |
||||
"icon": 'fa-gas-pump', |
||||
"color": 'bg-success' |
||||
}, |
||||
'enable_Read-only mode': { |
||||
"str": 'enabled readonly mode', |
||||
"icon": 'fa-book', |
||||
"color": 'bg-success' |
||||
}, |
||||
'enable_Signups': { |
||||
"str": 'enabled Signups', |
||||
"icon": 'fa-users', |
||||
"color": 'bg-success' |
||||
}, |
||||
'enable_under_attack': { |
||||
"str": 'enabled under attack mode', |
||||
"icon": 'fa-shield', |
||||
"color": 'bg-success' |
||||
}, |
||||
'flair_post': { |
||||
"str": 'set a flair on {self.target_link}', |
||||
"icon": 'fa-tag', |
||||
"color": 'bg-primary' |
||||
}, |
||||
'grant_awards': { |
||||
"str": 'granted awards to {self.target_link}', |
||||
"icon": 'fa-gift', |
||||
"color": 'bg-primary' |
||||
}, |
||||
'link_accounts': { |
||||
"str": 'linked {self.target_link}', |
||||
"icon": 'fa-link', |
||||
"color": 'bg-success' |
||||
}, |
||||
'make_admin': { |
||||
"str": 'made {self.target_link} admin', |
||||
"icon": 'fa-user-crown', |
||||
"color": 'bg-success' |
||||
}, |
||||
'make_meme_admin': { |
||||
"str": 'made {self.target_link} meme admin', |
||||
"icon": 'fa-user-crown', |
||||
"color": 'bg-success' |
||||
}, |
||||
'monthly': { |
||||
"str": 'distributed monthly marseybux', |
||||
"icon": 'fa-sack-dollar', |
||||
"color": 'bg-success' |
||||
}, |
||||
'move_hole': { |
||||
"str": 'moved {self.target_link} to <a href="/h/{self.target_post.sub}">/h/{self.target_post.sub}</a>', |
||||
"icon": 'fa-manhole', |
||||
"color": 'bg-primary' |
||||
}, |
||||
'nuke_user': { |
||||
"str": 'removed all content of {self.target_link}', |
||||
"icon": 'fa-radiation-alt', |
||||
"color": 'bg-danger' |
||||
}, |
||||
'pin_comment': { |
||||
"str": 'pinned a {self.target_link}', |
||||
"icon": 'fa-thumbtack fa-rotate--45', |
||||
"color": 'bg-success' |
||||
}, |
||||
'pin_post': { |
||||
"str": 'pinned post {self.target_link}', |
||||
"icon": 'fa-thumbtack fa-rotate--45', |
||||
"color": 'bg-success' |
||||
}, |
||||
'purge_cache': { |
||||
"str": 'purged cache', |
||||
"icon": 'fa-memory', |
||||
"color": 'bg-muted' |
||||
}, |
||||
'reject_app': { |
||||