diff --git a/.gitignore b/.gitignore index 4258305d1..46b4e3be0 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,8 @@ chart.png video.mp4 video.webm cache/ +images/ +songs/ __pycache__/ disablesignups *rules.html diff --git a/files/helpers/markdown.py b/files/helpers/markdown.py index d909ff73a..55caa7432 100644 --- a/files/helpers/markdown.py +++ b/files/helpers/markdown.py @@ -81,7 +81,7 @@ class CustomRenderer(HTMLRenderer): if not user: return f"{space}@{target}" - return f'{space}@{user.username}' + return f'''{space}@{username}'s profile picture@{user.username}''' def render_sub_mention(self, token): space = token.target[0] diff --git a/files/helpers/sanitize.py b/files/helpers/sanitize.py index 789d68efb..cead16499 100644 --- a/files/helpers/sanitize.py +++ b/files/helpers/sanitize.py @@ -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"): - tag["target"] = "_blank" - if site not in tag["href"] and not tag["href"].startswith('/'): tag["rel"] = "nofollow noopener noreferrer" + if site not in tag["href"] and not tag["href"].startswith('/'): + tag["target"] = "_blank" + 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'(?', new, flags=re.I) + new = re.sub(f'(?', 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'(?', sanitized, flags=re.I) + sanitized = re.sub(f'(?', sanitized, flags=re.I) elif path.isfile(f'./files/assets/images/emojis/{emoji}.webp'): - sanitized = re.sub(f'(?', sanitized, flags=re.I) + sanitized = re.sub(f'(?', 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\=(.*?))', sanitized): url = i.group(1) yt_id = i.group(2).split('&')[0].split('%')[0] - replacing = f'{url}' + replacing = f'{url}' 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'(?', title, flags=re.I) + title = re.sub(f'(?', title, flags=re.I) elif path.isfile(f'./files/assets/images/emojis/{emoji}.webp'): - title = re.sub(f'(?', title, flags=re.I) + title = re.sub(f'(?', title, flags=re.I) if len(title) > 1500: abort(400) else: return title \ No newline at end of file diff --git a/files/routes/comments.py b/files/routes/comments.py index 522d9601a..0957bb6c7 100644 --- a/files/routes/comments.py +++ b/files/routes/comments.py @@ -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![]({url})" @@ -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![]({url})" body_md = CustomRenderer().render(mistletoe.Document(body)) diff --git a/files/routes/feeds.py b/files/routes/feeds.py index f2ed56b31..dd72df67f 100644 --- a/files/routes/feeds.py +++ b/files/routes/feeds.py @@ -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'
{post.body_html}') + doc.cdata(f'''{post.title}
{post.body_html}''') return Response( ""+ doc.getvalue(), mimetype="application/xml") \ No newline at end of file diff --git a/files/routes/posts.py b/files/routes/posts.py index 00c6a346a..0a2c61337 100644 --- a/files/routes/posts.py +++ b/files/routes/posts.py @@ -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![]({url})" @@ -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![]({url})" @@ -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") diff --git a/files/routes/settings.py b/files/routes/settings.py index c871aa284..98c6f64ff 100644 --- a/files/routes/settings.py +++ b/files/routes/settings.py @@ -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![]({url})" @@ -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![]({url})" @@ -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) diff --git a/files/routes/static.py b/files/routes/static.py index f29a8b411..1dad043fb 100644 --- a/files/routes/static.py +++ b/files/routes/static.py @@ -266,7 +266,7 @@ def static_service(path): @app.get('/hostedimages/') @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'): diff --git a/files/routes/users.py b/files/routes/users.py index adc32dca1..5b6eba904 100644 --- a/files/routes/users.py +++ b/files/routes/users.py @@ -307,7 +307,7 @@ def songs(id): @app.get("/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 diff --git a/files/templates/authforms.html b/files/templates/authforms.html index a55eb2d02..804ebf0ee 100644 --- a/files/templates/authforms.html +++ b/files/templates/authforms.html @@ -14,11 +14,11 @@ {% if v %} - + {% if v.agendaposter %}{% elif v.css %}{% endif %} {% else %} - + {% endif %} diff --git a/files/templates/changelog.html b/files/templates/changelog.html index 92a76a72e..3f44d78f6 100644 --- a/files/templates/changelog.html +++ b/files/templates/changelog.html @@ -34,7 +34,7 @@