Merge branch 'master' into mistletoe
This commit is contained in:
commit
b398a378a4
18 changed files with 73 additions and 78 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -3,6 +3,8 @@ chart.png
|
|||
video.mp4
|
||||
video.webm
|
||||
cache/
|
||||
images/
|
||||
songs/
|
||||
__pycache__/
|
||||
disablesignups
|
||||
*rules.html
|
||||
|
|
|
@ -32,17 +32,12 @@ function popovertrigger() {
|
|||
|
||||
popovertrigger()
|
||||
|
||||
var usernames = document.querySelectorAll("a.user-name");
|
||||
usernames.forEach(eventasdf);
|
||||
|
||||
document.addEventListener("click", function(e){dfgh(e)});
|
||||
|
||||
function popclick(author) {
|
||||
let badges = ''
|
||||
for (const x of author["badges"]) {
|
||||
badges += `<img width="32" loading="lazy" src="${x}">`
|
||||
}
|
||||
for (let i = 0; i < document.getElementsByClassName('pop-banner').length; i++) {
|
||||
i = document.getElementsByClassName('pop-banner').length - 1
|
||||
document.getElementsByClassName('pop-banner')[i].src = author["bannerurl"]
|
||||
document.getElementsByClassName('pop-picture')[i].src = author["profile_url"]
|
||||
document.getElementsByClassName('pop-username')[i].innerHTML = author["username"]
|
||||
|
@ -53,4 +48,3 @@ function popclick(author) {
|
|||
document.getElementsByClassName('pop-viewmore')[i].href = author["url"]
|
||||
document.getElementsByClassName('pop-badges')[i].innerHTML = badges
|
||||
}
|
||||
}
|
|
@ -81,7 +81,7 @@ class CustomRenderer(HTMLRenderer):
|
|||
|
||||
if not user: return f"{space}@{target}"
|
||||
|
||||
return f'{space}<a href="{user.url}"><img loading="lazy" src="/uid/{user.id}/pic" class="pp20">@{user.username}</a>'
|
||||
return f'''{space}<a href="{user.url}"><img alt="@{username}'s profile picture" loading="lazy" src="/uid/{user.id}/pic" class="pp20">@{user.username}</a>'''
|
||||
|
||||
def render_sub_mention(self, token):
|
||||
space = token.target[0]
|
||||
|
|
|
@ -142,7 +142,6 @@ def sanitize(sanitized, noimages=False):
|
|||
link = soup.new_tag("a")
|
||||
link["href"] = tag["data-src"]
|
||||
if site not in link["href"] and not link["href"].startswith('/'): link["rel"] = "nofollow noopener noreferrer"
|
||||
link["target"] = "_blank"
|
||||
link["onclick"] = f"expandDesktopImage('{tag['data-src']}');"
|
||||
link["data-bs-toggle"] = "modal"
|
||||
link["data-bs-target"] = "#expandImageModal"
|
||||
|
@ -151,8 +150,9 @@ def sanitize(sanitized, noimages=False):
|
|||
|
||||
for tag in soup.find_all("a"):
|
||||
if tag.get("href"):
|
||||
if site not in tag["href"] and not tag["href"].startswith('/'):
|
||||
tag["target"] = "_blank"
|
||||
if site not in tag["href"] and not tag["href"].startswith('/'): tag["rel"] = "nofollow noopener noreferrer"
|
||||
tag["rel"] = "nofollow noopener noreferrer"
|
||||
|
||||
if re.match("https?://\S+", str(tag.string)):
|
||||
try: tag.string = tag["href"]
|
||||
|
@ -183,7 +183,7 @@ def sanitize(sanitized, noimages=False):
|
|||
remoji = emoji
|
||||
|
||||
if path.isfile(f'./files/assets/images/emojis/{remoji}.webp'):
|
||||
new = re.sub(f'(?<!"):{emoji}:', f'<img loading="lazy" data-bs-toggle="tooltip" alt=":{emoji}:" title=":{emoji}:" delay="0" {classes}src="https://{site}/assets/images/emojis/{remoji}.webp" >', new, flags=re.I)
|
||||
new = re.sub(f'(?<!"):{emoji}:', f'<img loading="lazy" data-bs-toggle="tooltip" alt=":{emoji}: emoji" title=":{emoji}:" delay="0" {classes}src="https://{site}/assets/images/emojis/{remoji}.webp" >', new, flags=re.I)
|
||||
|
||||
sanitized = sanitized.replace(old, new)
|
||||
|
||||
|
@ -193,10 +193,10 @@ def sanitize(sanitized, noimages=False):
|
|||
if emoji.startswith("!"):
|
||||
emoji = emoji[1:]
|
||||
if path.isfile(f'./files/assets/images/emojis/{emoji}.webp'):
|
||||
sanitized = re.sub(f'(?<!"):!{emoji}:', f'<img loading="lazy" data-bs-toggle="tooltip" alt=":!{emoji}:" title=":!{emoji}:" delay="0" height=30 class="emj mirrored" src="https://{site}/assets/images/emojis/{emoji}.webp">', sanitized, flags=re.I)
|
||||
sanitized = re.sub(f'(?<!"):!{emoji}:', f'<img loading="lazy" data-bs-toggle="tooltip" alt=":!{emoji}: emoji" title=":!{emoji}:" delay="0" height=30 class="emj mirrored" src="https://{site}/assets/images/emojis/{emoji}.webp">', sanitized, flags=re.I)
|
||||
|
||||
elif path.isfile(f'./files/assets/images/emojis/{emoji}.webp'):
|
||||
sanitized = re.sub(f'(?<!"):{emoji}:', f'<img loading="lazy" data-bs-toggle="tooltip" alt=":{emoji}:" title=":{emoji}:" delay="0" height=30 class="emj" src="https://{site}/assets/images/emojis/{emoji}.webp">', sanitized, flags=re.I)
|
||||
sanitized = re.sub(f'(?<!"):{emoji}:', f'<img loading="lazy" data-bs-toggle="tooltip" alt=":{emoji}: emoji" title=":{emoji}:" delay="0" height=30 class="emj" src="https://{site}/assets/images/emojis/{emoji}.webp">', sanitized, flags=re.I)
|
||||
|
||||
sanitized = sanitized.replace("https://www.", "https://").replace("https://youtu.be/", "https://youtube.com/watch?v=").replace("https://music.youtube.com/watch?v=", "https://youtube.com/watch?v=").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/watch?v=").replace("https://mobile.twitter", "https://twitter").replace("https://m.facebook", "https://facebook").replace("https://m.wikipedia", "https://wikipedia").replace("https://m.youtube", "https://youtube")
|
||||
|
||||
|
@ -205,7 +205,7 @@ def sanitize(sanitized, noimages=False):
|
|||
for i in re.finditer('" target="_blank">(https://youtube\.com/watch\?v\=(.*?))</a>', sanitized):
|
||||
url = i.group(1)
|
||||
yt_id = i.group(2).split('&')[0].split('%')[0]
|
||||
replacing = f'<a href="{url}" rel="nofollow noopener noreferrer" target="_blank">{url}</a>'
|
||||
replacing = f'<a href="{url}" rel="nofollow noopener noreferrer">{url}</a>'
|
||||
|
||||
params = parse_qs(urlparse(url.replace('&','&')).query)
|
||||
t = params.get('t', params.get('start', [0]))[0]
|
||||
|
@ -240,10 +240,10 @@ def filter_emojis_only(title):
|
|||
if emoji.startswith("!"):
|
||||
emoji = emoji[1:]
|
||||
if path.isfile(f'./files/assets/images/emojis/{emoji}.webp'):
|
||||
title = re.sub(f'(?<!"):!{emoji}:', f'<img loading="lazy" data-bs-toggle="tooltip" alt=":!{emoji}:" title=":!{emoji}:" delay="0" height=30 src="https://{site}/assets/images/emojis/{emoji}.webp" class="emj mirrored">', title, flags=re.I)
|
||||
title = re.sub(f'(?<!"):!{emoji}:', f'<img loading="lazy" data-bs-toggle="tooltip" alt=":!{emoji}: emoji" title=":!{emoji}:" delay="0" height=30 src="https://{site}/assets/images/emojis/{emoji}.webp" class="emj mirrored">', title, flags=re.I)
|
||||
|
||||
elif path.isfile(f'./files/assets/images/emojis/{emoji}.webp'):
|
||||
title = re.sub(f'(?<!"):{emoji}:', f'<img loading="lazy" data-bs-toggle="tooltip" alt=":{emoji}:" title=":{emoji}:" delay="0" height=30 class="emj" src="https://{site}/assets/images/emojis/{emoji}.webp">', title, flags=re.I)
|
||||
title = re.sub(f'(?<!"):{emoji}:', f'<img loading="lazy" data-bs-toggle="tooltip" alt=":{emoji}: emoji" title=":{emoji}:" delay="0" height=30 class="emj" src="https://{site}/assets/images/emojis/{emoji}.webp">', title, flags=re.I)
|
||||
|
||||
if len(title) > 1500: abort(400)
|
||||
else: return title
|
|
@ -192,9 +192,9 @@ def api_comment(v):
|
|||
file=request.files["file"]
|
||||
if not file.content_type.startswith('image/'): return {"error": "That wasn't an image!"}, 400
|
||||
|
||||
name = f'/images/{time.time()}'.replace('.','')[:-5] + '.webp'
|
||||
name = f'images/{time.time()}'.replace('.','')[:-5] + '.webp'
|
||||
file.save(name)
|
||||
url = request.host_url[:-1] + process_image(name)
|
||||
url = request.host_url + process_image(name)
|
||||
|
||||
body += f"\n\n"
|
||||
|
||||
|
@ -722,9 +722,9 @@ def edit_comment(cid, v):
|
|||
file=request.files["file"]
|
||||
if not file.content_type.startswith('image/'): return {"error": "That wasn't an image!"}, 400
|
||||
|
||||
name = f'/images/{time.time()}'.replace('.','')[:-5] + '.webp'
|
||||
name = f'images/{time.time()}'.replace('.','')[:-5] + '.webp'
|
||||
file.save(name)
|
||||
url = request.host_url[:-1] + process_image(name)
|
||||
url = request.host_url + process_image(name)
|
||||
|
||||
body += f"\n\n"
|
||||
body_md = CustomRenderer().render(mistletoe.Document(body))
|
||||
|
|
|
@ -61,6 +61,6 @@ def feeds_user(sort='hot', t='all'):
|
|||
|
||||
if len(post.body_html) > 0:
|
||||
with tag("content", type="html"):
|
||||
doc.cdata(f'<img loading="lazy" src={image_url}><br>{post.body_html}')
|
||||
doc.cdata(f'''<img alt="{post.title}" loading="lazy" src={image_url}><br>{post.body_html}''')
|
||||
|
||||
return Response( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"+ doc.getvalue(), mimetype="application/xml")
|
|
@ -422,9 +422,9 @@ def edit_post(pid, v):
|
|||
file=request.files["file"]
|
||||
if not file.content_type.startswith('image/'): return {"error": "That wasn't an image!"}, 400
|
||||
|
||||
name = f'/images/{time.time()}'.replace('.','')[:-5] + '.webp'
|
||||
name = f'images/{time.time()}'.replace('.','')[:-5] + '.webp'
|
||||
file.save(name)
|
||||
url = request.host_url[:-1] + process_image(name)
|
||||
url = request.host_url + process_image(name)
|
||||
|
||||
body += f"\n\n"
|
||||
|
||||
|
@ -691,7 +691,7 @@ def thumbnail_thread(pid):
|
|||
db.close()
|
||||
return
|
||||
|
||||
name = f'/images/{time.time()}'.replace('.','')[:-5] + '.webp'
|
||||
name = f'images/{time.time()}'.replace('.','')[:-5] + '.webp'
|
||||
|
||||
with open(name, "wb") as file:
|
||||
for chunk in image_req.iter_content(1024):
|
||||
|
@ -916,9 +916,9 @@ def submit_post(v):
|
|||
file=request.files["file2"]
|
||||
if not file.content_type.startswith('image/'): return {"error": "That wasn't an image!"}, 400
|
||||
|
||||
name = f'/images/{time.time()}'.replace('.','')[:-5] + '.webp'
|
||||
name = f'images/{time.time()}'.replace('.','')[:-5] + '.webp'
|
||||
file.save(name)
|
||||
url = request.host_url[:-1] + process_image(name)
|
||||
url = request.host_url + process_image(name)
|
||||
|
||||
body += f"\n\n"
|
||||
|
||||
|
@ -1015,9 +1015,9 @@ def submit_post(v):
|
|||
), 403
|
||||
|
||||
if file.content_type.startswith('image/'):
|
||||
name = f'/images/{time.time()}'.replace('.','')[:-5] + '.webp'
|
||||
name = f'images/{time.time()}'.replace('.','')[:-5] + '.webp'
|
||||
file.save(name)
|
||||
new_post.url = request.host_url[:-1] + process_image(name)
|
||||
new_post.url = request.host_url + process_image(name)
|
||||
|
||||
elif file.content_type.startswith('video/'):
|
||||
file.save("video.mp4")
|
||||
|
|
|
@ -124,9 +124,9 @@ def settings_profile_post(v):
|
|||
if request.headers.get("Authorization"): return {"error": f"Image files only"}, 400
|
||||
else: return render_template("settings_profile.html", v=v, error=f"Image files only."), 400
|
||||
|
||||
name = f'/images/{time.time()}'.replace('.','')[:-5] + '.webp'
|
||||
name = f'images/{time.time()}'.replace('.','')[:-5] + '.webp'
|
||||
file.save(name)
|
||||
url = request.host_url[:-1] + process_image(name)
|
||||
url = request.host_url + process_image(name)
|
||||
|
||||
bio += f"\n\n"
|
||||
|
||||
|
@ -314,9 +314,9 @@ def settings_profile_post(v):
|
|||
if request.headers.get("Authorization"): return {"error": f"Image files only"}, 400
|
||||
else: return render_template("settings_profile.html", v=v, error=f"Image files only."), 400
|
||||
|
||||
name = f'/images/{time.time()}'.replace('.','')[:-5] + '.webp'
|
||||
name = f'images/{time.time()}'.replace('.','')[:-5] + '.webp'
|
||||
file.save(name)
|
||||
url = request.host_url[:-1] + process_image(name)
|
||||
url = request.host_url + process_image(name)
|
||||
|
||||
bio += f"\n\n"
|
||||
|
||||
|
@ -720,20 +720,20 @@ def settings_images_profile(v):
|
|||
|
||||
file = request.files["profile"]
|
||||
|
||||
name = f'/images/{time.time()}'.replace('.','')[:-5] + '.webp'
|
||||
name = f'images/{time.time()}'.replace('.','')[:-5] + '.webp'
|
||||
file.save(name)
|
||||
highres = request.host_url[:-1] + process_image(name)
|
||||
highres = request.host_url + process_image(name)
|
||||
|
||||
if not highres: abort(400)
|
||||
|
||||
name2 = name.replace('.webp', 'r.webp')
|
||||
copyfile(name, name2)
|
||||
imageurl = request.host_url[:-1] + process_image(name2, True)
|
||||
imageurl = request.host_url + process_image(name2, True)
|
||||
|
||||
if not imageurl: abort(400)
|
||||
|
||||
if v.highres and '/images/' in v.highres : os.remove('/images/' + v.highres.split('/images/')[1])
|
||||
if v.profileurl and '/images/' in v.profileurl : os.remove('/images/' + v.profileurl.split('/images/')[1])
|
||||
if v.highres and '/images/' in v.highres : os.remove('images/' + v.highres.split('/images/')[1])
|
||||
if v.profileurl and '/images/' in v.profileurl : os.remove('images/' + v.profileurl.split('/images/')[1])
|
||||
v.highres = highres
|
||||
v.profileurl = imageurl
|
||||
g.db.add(v)
|
||||
|
@ -756,12 +756,12 @@ def settings_images_banner(v):
|
|||
|
||||
file = request.files["banner"]
|
||||
|
||||
name = f'/images/{time.time()}'.replace('.','')[:-5] + '.webp'
|
||||
name = f'images/{time.time()}'.replace('.','')[:-5] + '.webp'
|
||||
file.save(name)
|
||||
bannerurl = request.host_url[:-1] + process_image(name)
|
||||
bannerurl = request.host_url + process_image(name)
|
||||
|
||||
if bannerurl:
|
||||
if v.bannerurl and '/images/' in v.bannerurl : os.remove('/images/' + v.bannerurl.split('/images/')[1])
|
||||
if v.bannerurl and '/images/' in v.bannerurl : os.remove('images/' + v.bannerurl.split('/images/')[1])
|
||||
v.bannerurl = bannerurl
|
||||
g.db.add(v)
|
||||
g.db.commit()
|
||||
|
@ -986,8 +986,8 @@ def settings_name_change(v):
|
|||
def settings_song_change(v):
|
||||
song=request.values.get("song").strip()
|
||||
|
||||
if song == "" and v.song and path.isfile(f"/songs/{v.song}.mp3") and g.db.query(User.id).filter_by(song=v.song).count() == 1:
|
||||
os.remove(f"/songs/{v.song}.mp3")
|
||||
if song == "" and v.song and path.isfile(f"songs/{v.song}.mp3") and g.db.query(User.id).filter_by(song=v.song).count() == 1:
|
||||
os.remove(f"songs/{v.song}.mp3")
|
||||
v.song = None
|
||||
g.db.add(v)
|
||||
g.db.commit()
|
||||
|
@ -1006,7 +1006,7 @@ def settings_song_change(v):
|
|||
if "?" in id: id = id.split("?")[0]
|
||||
if "&" in id: id = id.split("&")[0]
|
||||
|
||||
if path.isfile(f'/songs/{id}.mp3'):
|
||||
if path.isfile(f'songs/{id}.mp3'):
|
||||
v.song = id
|
||||
g.db.add(v)
|
||||
g.db.commit()
|
||||
|
@ -1028,11 +1028,11 @@ def settings_song_change(v):
|
|||
error=f"Duration of the video must not exceed 10 minutes.")
|
||||
|
||||
|
||||
if v.song and path.isfile(f"/songs/{v.song}.mp3") and g.db.query(User.id).filter_by(song=v.song).count() == 1:
|
||||
os.remove(f"/songs/{v.song}.mp3")
|
||||
if v.song and path.isfile(f"songs/{v.song}.mp3") and g.db.query(User.id).filter_by(song=v.song).count() == 1:
|
||||
os.remove(f"songs/{v.song}.mp3")
|
||||
|
||||
ydl_opts = {
|
||||
'outtmpl': '/songs/%(title)s.%(ext)s',
|
||||
'outtmpl': 'songs/%(title)s.%(ext)s',
|
||||
'format': 'bestaudio/best',
|
||||
'postprocessors': [{
|
||||
'key': 'FFmpegExtractAudio',
|
||||
|
@ -1049,10 +1049,10 @@ def settings_song_change(v):
|
|||
v=v,
|
||||
error=f"Age-restricted videos aren't allowed.")
|
||||
|
||||
files = os.listdir("/songs/")
|
||||
paths = [path.join("/songs/", basename) for basename in files]
|
||||
files = os.listdir("songs/")
|
||||
paths = [path.join("songs/", basename) for basename in files]
|
||||
songfile = max(paths, key=path.getctime)
|
||||
os.rename(songfile, f"/songs/{id}.mp3")
|
||||
os.rename(songfile, f"songs/{id}.mp3")
|
||||
|
||||
v.song = id
|
||||
g.db.add(v)
|
||||
|
|
|
@ -266,7 +266,7 @@ def static_service(path):
|
|||
@app.get('/hostedimages/<path:path>')
|
||||
@limiter.exempt
|
||||
def images(path):
|
||||
resp = make_response(send_from_directory('/images', path.replace('.WEBP','.webp')))
|
||||
resp = make_response(send_from_directory('images', path.replace('.WEBP','.webp')))
|
||||
resp.headers.remove("Cache-Control")
|
||||
resp.headers.add("Cache-Control", "public, max-age=2628000")
|
||||
if request.path.endswith('.webp'):
|
||||
|
|
|
@ -307,7 +307,7 @@ def songs(id):
|
|||
|
||||
@app.get("/song/<song>")
|
||||
def song(song):
|
||||
resp = make_response(send_from_directory('/songs/', song))
|
||||
resp = make_response(send_from_directory('songs/', song))
|
||||
resp.headers.remove("Cache-Control")
|
||||
resp.headers.add("Cache-Control", "public, max-age=2628000")
|
||||
return resp
|
||||
|
|
|
@ -14,11 +14,11 @@
|
|||
|
||||
{% if v %}
|
||||
<style>:root{--primary:#{{v.themecolor}}}</style>
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=146"><link rel="stylesheet" href="/assets/css/{{v.theme}}.css?v=125">
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=151"><link rel="stylesheet" href="/assets/css/{{v.theme}}.css?v=125">
|
||||
{% if v.agendaposter %}<link rel="stylesheet" href="/assets/css/agendaposter.css?v=125">{% elif v.css %}<link rel="stylesheet" href="/@{{v.username}}/css">{% endif %}
|
||||
{% else %}
|
||||
<style>:root{--primary:#{{'DEFAULT_COLOR' | app_config}}</style>
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=145"><link rel="stylesheet" href="/assets/css/{{'DEFAULT_THEME' | app_config}}.css?v=125">
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=151"><link rel="stylesheet" href="/assets/css/{{'DEFAULT_THEME' | app_config}}.css?v=125">
|
||||
{% endif %}
|
||||
|
||||
</head>
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
|
||||
<div class="text-small font-weight-bold ml-3 mr-2"></div>
|
||||
<div class="dropdown dropdown-actions">
|
||||
<button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton2" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
{% if sort=="hot" %}<i class="fas fa-fire mr-1"></i>{% endif %}
|
||||
{% if sort=="top" %}<i class="fas fa-arrow-alt-circle-up mr-1"></i>{% endif %}
|
||||
{% if sort=="bottom" %}<i class="fas fa-arrow-alt-circle-down mr-1"></i>{% endif %}
|
||||
|
@ -44,7 +44,7 @@
|
|||
{% if sort=="comments" %}<i class="fas fa-comments mr-1"></i>{% endif %}
|
||||
{{sort | capitalize}}
|
||||
</button>
|
||||
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton" x-placement="bottom-start" style="position: absolute; will-change: transform; top: 0px; left: 0px; transform: translate3d(0px, 31px, 0px);">
|
||||
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton2" x-placement="bottom-start" style="position: absolute; will-change: transform; top: 0px; left: 0px; transform: translate3d(0px, 31px, 0px);">
|
||||
{% if sort != "hot" %}<a class="dropdown-item" href="?sort=hot&t={{t}}"><i class="fas fa-fire mr-2"></i>Hot</a>{% endif %}
|
||||
{% if sort != "top" %}<a class="dropdown-item" href="?sort=top&t={{t}}"><i class="fas fa-arrow-alt-circle-up mr-2"></i>Top</a>{% endif %}
|
||||
{% if sort != "bottom" %}<a class="dropdown-item" href="?sort=bottom&t={{t}}"><i class="fas fa-arrow-alt-circle-down mr-2"></i>Bottom</a>{% endif %}
|
||||
|
|
|
@ -90,7 +90,7 @@
|
|||
|
||||
<li class="nav-item d-flex align-items-center justify-content-center text-center">
|
||||
<div class="dropdown">
|
||||
<a class="nav-link bg-transparent py-0 pr-0" href="{{v.url}}" role="button" id="dropdownMenuLink" data-bs-toggle="dropdown"
|
||||
<a class="nav-link bg-transparent py-0 pr-0" href="javascript:void(0)" role="button" id="dropdownMenuLink" data-bs-toggle="dropdown"
|
||||
aria-haspopup="true" aria-expanded="false">
|
||||
<div class="d-flex">
|
||||
<div><img loading="lazy" src="{{v.profile_url}}" class="profile-pic-35"></div>
|
||||
|
@ -101,8 +101,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</a>
|
||||
<div class="dropdown-menu dropdown-menu-right dropdown-menu-lg-left border-0 shadow fade px-0 mt-2"
|
||||
aria-labelledby="dropdownMenuButton">
|
||||
<div class="dropdown-menu dropdown-menu-right dropdown-menu-lg-left border-0 shadow fade px-0 mt-2">
|
||||
<div class="px-2">
|
||||
<a class="dropdown-item" href="{{v.url}}"><i class="fas fa-user-circle fa-fw text-left mr-3"></i>My
|
||||
profile</a>
|
||||
|
|
|
@ -6,11 +6,11 @@
|
|||
{% block content %}
|
||||
{% if v %}
|
||||
<style>:root{--primary:#{{v.themecolor}}}</style>
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=146"><link rel="stylesheet" href="/assets/css/{{v.theme}}.css?v=125">
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=151"><link rel="stylesheet" href="/assets/css/{{v.theme}}.css?v=125">
|
||||
{% if v.agendaposter %}<link rel="stylesheet" href="/assets/css/agendaposter.css?v=125">{% elif v.css %}<link rel="stylesheet" href="/@{{v.username}}/css">{% endif %}
|
||||
{% else %}
|
||||
<style>:root{--primary:#{{'DEFAULT_COLOR' | app_config}}</style>
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=146"><link rel="stylesheet" href="/assets/css/{{'DEFAULT_THEME' | app_config}}.css?v=125">
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=151"><link rel="stylesheet" href="/assets/css/{{'DEFAULT_THEME' | app_config}}.css?v=125">
|
||||
{% endif %}
|
||||
|
||||
<div class="row justify-content-around">
|
||||
|
@ -49,10 +49,10 @@
|
|||
<div class="text-small font-weight-bold mr-2"></div>
|
||||
<div class="dropdown dropdown-actions">
|
||||
|
||||
<button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton2" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
{% if type %}<i class="fas {{types[type]['icon']}} mr-2"></i>{{type}}{% else %}<i class="fas fa-broom mr-2"></i>All{% endif %}
|
||||
</button>
|
||||
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton" x-placement="bottom-start" style="position: absolute; will-change: transform; top: 0px; left: 0px; transform: translate3d(0px, 31px, 0px);">
|
||||
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton2s" x-placement="bottom-start" style="position: absolute; will-change: transform; top: 0px; left: 0px; transform: translate3d(0px, 31px, 0px);">
|
||||
<a class="dropdown-item" href="/log{% if admin %}?admin={{admin}}{% endif %}"><i class="fas fa-broom mr-2"></i>All</a>
|
||||
{% for t, v in types.items() %}
|
||||
<a class="dropdown-item" href="?{% if admin %}admin={{admin}}&{% endif %}kind={{t}}"><i class="fas {{v['icon']}} mr-2"></i>{{t}}</a>
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
<title>2-Step Login - {{'SITE_NAME' | app_config}}</title>
|
||||
|
||||
<style>:root{--primary:#{{'DEFAULT_COLOR' | app_config}}</style>
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=146"><link rel="stylesheet" href="/assets/css/{{'DEFAULT_THEME' | app_config}}.css?v=125">
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=151"><link rel="stylesheet" href="/assets/css/{{'DEFAULT_THEME' | app_config}}.css?v=125">
|
||||
|
||||
</head>
|
||||
|
||||
|
|
|
@ -38,10 +38,10 @@
|
|||
|
||||
{% if v %}
|
||||
<style>:root{--primary:#{{v.themecolor}}}</style>
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=146"><link rel="stylesheet" href="/assets/css/{{v.theme}}.css?v=125">
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=151"><link rel="stylesheet" href="/assets/css/{{v.theme}}.css?v=125">
|
||||
{% else %}
|
||||
<style>:root{--primary:#{{'DEFAULT_COLOR' | app_config}}</style>
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=146"><link rel="stylesheet" href="/assets/css/{{'DEFAULT_THEME' | app_config}}.css?v=125">
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=151"><link rel="stylesheet" href="/assets/css/{{'DEFAULT_THEME' | app_config}}.css?v=125">
|
||||
{% endif %}
|
||||
|
||||
<link href="/assets/css/fa.css?v=55" rel="stylesheet">
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
<title>{% if ref_user %}{{ref_user.username}} invites you to {{'SITE_NAME' | app_config}}{% else %}{{'SITE_NAME' | app_config}}{% endif %}</title>
|
||||
|
||||
<style>:root{--primary:#{{'DEFAULT_COLOR' | app_config}}</style>
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=146"><link rel="stylesheet" href="/assets/css/{{'DEFAULT_THEME' | app_config}}.css?v=125">
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=151"><link rel="stylesheet" href="/assets/css/{{'DEFAULT_THEME' | app_config}}.css?v=125">
|
||||
|
||||
</head>
|
||||
|
||||
|
|
4
setup
4
setup
|
@ -11,8 +11,8 @@ sudo apt -y install python3-pip
|
|||
sudo pip3 install -r requirements.txt
|
||||
sudo apt -y install gunicorn
|
||||
sudo apt -y install ffmpeg
|
||||
mkdir /songs
|
||||
mkdir /images
|
||||
mkdir /drama/songs
|
||||
mkdir /drama/images
|
||||
cp ./env /env
|
||||
. /env
|
||||
gunicorn files.__main__:app -k gevent -w 2 --reload -b localhost:80 --max-requests 1000 --max-requests-jitter 500
|
Loading…
Add table
Add a link
Reference in a new issue