mirror of
https://codeberg.org/catask-org/catask.git
synced 2025-04-19 13:23:41 -05:00
119 lines
3.1 KiB
Python
119 lines
3.1 KiB
Python
from markupsafe import Markup
|
|
from bleach.sanitizer import Cleaner
|
|
from datetime import datetime
|
|
import mistune
|
|
import humanize
|
|
import mysql.connector
|
|
import config as cfg
|
|
import os
|
|
import random
|
|
import constants as const
|
|
|
|
def formatRelativeTime(date_str):
|
|
date_format = "%Y-%m-%d %H:%M:%S"
|
|
past_date = datetime.strptime(date_str, date_format)
|
|
|
|
now = datetime.now()
|
|
time_difference = now - past_date
|
|
|
|
return humanize.naturaltime(time_difference)
|
|
|
|
dbHost = os.environ.get("DB_HOST")
|
|
dbUser = os.environ.get("DB_USER")
|
|
dbPass = os.environ.get("DB_PASS")
|
|
dbName = os.environ.get("DB_NAME")
|
|
|
|
def createDatabase(cursor, dbName):
|
|
try:
|
|
cursor.execute("CREATE DATABASE {} DEFAULT CHARACTER SET 'utf8'".format(dbName))
|
|
print(f"Database {dbName} created successfully")
|
|
except mysql.connector.Error as error:
|
|
print("Failed to create database:", error)
|
|
exit(1)
|
|
|
|
def connectToDb():
|
|
conn = mysql.connector.connect(
|
|
host=dbHost,
|
|
user=dbUser,
|
|
password=dbPass,
|
|
database=dbName,
|
|
pool_name=f"{const.appName}-pool",
|
|
pool_size=32,
|
|
autocommit=True
|
|
)
|
|
return conn
|
|
|
|
def getQuestion(question_id: int):
|
|
conn = connectToDb()
|
|
cursor = conn.cursor(dictionary=True)
|
|
cursor.execute("SELECT * FROM questions WHERE id=%s", (question_id,))
|
|
question = cursor.fetchone()
|
|
cursor.close()
|
|
conn.close()
|
|
return question
|
|
|
|
def getAnswer(question_id: int):
|
|
conn = connectToDb()
|
|
cursor = conn.cursor(dictionary=True)
|
|
cursor.execute("SELECT * FROM answers WHERE question_id=%s", (question_id,))
|
|
answer = cursor.fetchone()
|
|
cursor.close()
|
|
conn.close()
|
|
return answer
|
|
|
|
def readPlainFile(file, split=False):
|
|
if os.path.exists(file):
|
|
with open(file, 'r', encoding="utf-8") as file:
|
|
if split == False:
|
|
return file.read()
|
|
if split == True:
|
|
return file.read().splitlines()
|
|
else:
|
|
return []
|
|
|
|
def getRandomWord():
|
|
items = readPlainFile(const.antiSpamFile, split=True)
|
|
return random.choice(items)
|
|
|
|
def trimContent(var, trim):
|
|
return var[:trim] + '...' if len(var) > trim else var
|
|
|
|
def renderMarkdown(text):
|
|
plugins = [
|
|
'strikethrough'
|
|
]
|
|
allowed_tags = [
|
|
'p',
|
|
'em',
|
|
'b',
|
|
'strong',
|
|
'i',
|
|
'br',
|
|
's',
|
|
'del'
|
|
]
|
|
allowed_attrs = {}
|
|
# hard_wrap=True means that newlines will be
|
|
# converted into <br> tags
|
|
#
|
|
# yes, markdown usually lets you make line breaks only
|
|
# with 2 spaces or <br> tag, but hard_wrap is enabled to keep
|
|
# sanity of whoever will use this software
|
|
# (after all, not everyone knows markdown syntax)
|
|
md = mistune.create_markdown(
|
|
escape=True,
|
|
plugins=plugins,
|
|
hard_wrap=True
|
|
)
|
|
html = md(text)
|
|
cleaner = Cleaner(tags=allowed_tags, attributes=allowed_attrs)
|
|
clean_html = cleaner.clean(html)
|
|
return Markup(clean_html)
|
|
|
|
def generateMetadata(question=None):
|
|
metadata = {
|
|
'title': cfg.instanceTitle,
|
|
'description': cfg.instanceDesc,
|
|
'url': cfg.fullBaseUrl,
|
|
'image': cfg.instanceImage
|
|
}
|