remove profile songs (ref #470) (#499)

* removes profile songs (ref #470)

* Remove ffmpeg, remaining song subsystem

  - Remove references to User.song in userpage* templates
  - Generate migration to drop column
  - Remove ffmpeg dependency in Docker

* remove python 2 era __future__ import

---------

Co-authored-by: TLSM <duolsm@outlook.com>
This commit is contained in:
justcool393 2023-02-10 11:56:04 -08:00 committed by GitHub
parent f8f55be8b0
commit 1817008a91
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 30 additions and 203 deletions

View file

@ -4,7 +4,7 @@ FROM python:3.10 AS base
ARG DEBIAN_FRONTEND=noninteractive
RUN apt update && apt -y upgrade && apt install -y supervisor ffmpeg
RUN apt update && apt -y upgrade && apt install -y supervisor
# we'll end up blowing away this directory via docker-compose
WORKDIR /service
@ -13,7 +13,7 @@ COPY poetry.lock .
RUN pip install 'poetry==1.2.2'
RUN poetry config virtualenvs.create false && poetry install
RUN mkdir /images && mkdir /songs
RUN mkdir /images
EXPOSE 80/tcp

View file

@ -1,53 +0,0 @@
let u_username = document.getElementById('u_username')
if (u_username)
{
u_username = u_username.innerHTML
let audio = new Audio(`/@${u_username}/song`);
audio.loop=true;
function toggle() {
if (audio.paused) audio.play()
else audio.pause()
}
audio.play();
document.getElementById('userpage').addEventListener('click', () => {
if (audio.paused) audio.play();
}, {once : true});
}
else
{
let v_username = document.getElementById('v_username')
if (v_username)
{
v_username = v_username.innerHTML
const paused = localStorage.getItem("paused")
let audio = new Audio(`/@${v_username}/song`);
audio.loop=true;
function toggle() {
if (audio.paused)
{
audio.play()
localStorage.setItem("paused", "")
}
else
{
audio.pause()
localStorage.setItem("paused", "1")
}
}
if (!paused)
{
audio.play();
window.addEventListener('click', () => {
if (audio.paused) audio.play();
}, {once : true});
}
}
}

View file

@ -47,7 +47,6 @@ class User(Base):
theme = Column(String, default=defaulttheme, nullable=False)
themecolor = Column(String, default=DEFAULT_COLOR, nullable=False)
cardview = Column(Boolean, default=cardview, nullable=False)
song = Column(String)
highres = Column(String)
profileurl = Column(String)
bannerurl = Column(String)

View file

@ -1,10 +1,8 @@
from __future__ import unicode_literals
from files.helpers.alerts import *
from files.helpers.sanitize import *
from files.helpers.const import *
from files.mail import *
from files.__main__ import app, cache, limiter
import youtube_dl
from .front import frontlist
import os
from files.helpers.sanitize import filter_emojis_only
@ -634,85 +632,6 @@ def settings_name_change(v):
return redirect("/settings/profile")
@app.post("/settings/song_change")
@limiter.limit("2/second;10/day")
@auth_required
def settings_song_change(v):
song=request.values.get("song").strip()
if song == "" and v.song:
if 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()
return redirect("/settings/profile")
song = song.replace("https://music.youtube.com", "https://youtube.com")
if song.startswith(("https://www.youtube.com/watch?v=", "https://youtube.com/watch?v=", "https://m.youtube.com/watch?v=")):
id = song.split("v=")[1]
elif song.startswith("https://youtu.be/"):
id = song.split("https://youtu.be/")[1]
else:
return render_template("settings_profile.html", v=v, error="Not a youtube link.")
if "?" in id: id = id.split("?")[0]
if "&" in id: id = id.split("&")[0]
if path.isfile(f'/songs/{id}.mp3'):
v.song = id
g.db.add(v)
g.db.commit()
return redirect("/settings/profile")
req = requests.get(f"https://www.googleapis.com/youtube/v3/videos?id={id}&key={YOUTUBE_KEY}&part=contentDetails", timeout=5).json()
duration = req['items'][0]['contentDetails']['duration']
if duration == 'P0D':
return render_template("settings_profile.html", v=v, error="Can't use a live youtube video!")
if "H" in duration:
return render_template("settings_profile.html", v=v, error="Duration of the video must not exceed 15 minutes.")
if "M" in duration:
duration = int(duration.split("PT")[1].split("M")[0])
if duration > 15:
return render_template("settings_profile.html", v=v, error="Duration of the video must not exceed 15 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")
ydl_opts = {
'outtmpl': '/songs/%(title)s.%(ext)s',
'format': 'bestaudio/best',
'postprocessors': [{
'key': 'FFmpegExtractAudio',
'preferredcodec': 'mp3',
'preferredquality': '192',
}],
}
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
try: ydl.download([f"https://youtube.com/watch?v={id}"])
except Exception as e:
print(e)
return render_template("settings_profile.html",
v=v,
error="Age-restricted videos aren't allowed.")
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")
v.song = id
g.db.add(v)
g.db.commit()
return redirect("/settings/profile")
@app.post("/settings/title_change")
@limiter.limit("1/second;30/minute;200/hour;1000/day")
@auth_required

View file

@ -495,20 +495,6 @@ def get_profilecss(username):
resp.headers.add("Content-Type", "text/css")
return resp
@app.get("/@<username>/song")
def usersong(username):
user = get_user(username)
if user.song: return redirect(f"/song/{user.song}.mp3")
else: abort(404)
@app.get("/song/<song>")
@app.get("/static/song/<song>")
def song(song):
resp = make_response(send_from_directory('/songs', song))
resp.headers.remove("Cache-Control")
resp.headers.add("Cache-Control", "public, max-age=3153600")
return resp
@app.post("/subscribe/<post_id>")
@limiter.limit("1/second;30/minute;200/hour;1000/day")
@auth_required

View file

@ -190,10 +190,6 @@
<a href="/views" class="btn btn-secondary">Profile views</a>
{% endif %}
{% if u.song and v and (v.id == u.id) %}
<a class="btn btn-secondary" role="button" onclick="toggle()">Toggle anthem</a>
{% endif %}
{% if v and v.id != u.id and v.admin_level > 1 %}
<br><br>
<div class="body d-lg-flex border-bottom">
@ -416,10 +412,6 @@
<a href="/views" class="btn btn-secondary">Profile views</a>
{% endif %}
{% if u.song and v and (v.id == u.id) %}
<a class="btn btn-secondary" role="button" onclick="toggle()">Toggle anthem</a>
{% endif %}
{% if v and v.id != u.id %}
<a id="button-unsub2" class="btn btn-secondary {% if not is_following %}d-none{% endif %}" role="button" onclick="post_toast2(this,'/unfollow/{{u.username}}','button-unsub2','button-sub2')">Unfollow</a>
@ -636,22 +628,12 @@
</div>
{% if u.song %}
{% if v and v.id == u.id %}
<div id="v_username" class="d-none">{{v.username}}</div>
{% else %}
<div id="u_username" class="d-none">{{u.username}}</div>
{% endif %}
{% endif %}
{% if v %}
<div id='tax' class="d-none">{% if v.patron or u.patron or v.alts_patron or u.alts_patron %}0{% else %}0.03{% endif %}</div>
<script src="{{ 'js/userpage_v.js' | asset }}"></script>
<div id="username" class="d-none">{{u.username}}</div>
{% endif %}
<script src="{{ 'js/userpage.js' | asset }}"></script>
{% endblock %}
{% block pagenav %}

View file

@ -104,19 +104,10 @@
</div>
</div>
{% if u.song %}
{% if v and v.id == u.id %}
<div id="v_username" class="d-none">{{v.username}}</div>
{% else %}
<div id="u_username" class="d-none">{{u.username}}</div>
{% endif %}
{% endif %}
{% if v %}
<div id='tax' class="d-none">{% if v.patron or u.patron %}0{% else %}0.03{% endif %}</div>
<script src="{{ 'js/userpage_v.js' | asset }}"></script>
<div id="username" class="d-none">{{u.username}}</div>
{% endif %}
<script src="{{ 'js/userpage.js' | asset }}"></script>
{% endblock %}

View file

@ -15,20 +15,9 @@
</div>
</div>
{% if u.song %}
{% if v and v.id == u.id %}
<div id="v_username" class="d-none">{{v.username}}</div>
{% else %}
<div id="u_username" class="d-none">{{u.username}}</div>
{% endif %}
{% endif %}
{% endblock %}
{% block pagenav %}
{% if u.song %}
<div id="uid" class="d-none">{{u.id}}</div>
{% endif %}
{% if v %}
<div id='tax' class="d-none">{% if v.patron or u.patron %}0{% else %}0.03{% endif %}</div>
@ -36,5 +25,4 @@
<div id="username" class="d-none">{{u.username}}</div>
{% endif %}
<script src="{{ 'js/userpage.js' | asset }}"></script>
{% endblock %}

View file

@ -0,0 +1,28 @@
"""remove users.song
Revision ID: ba8a214736eb
Revises: 1f30a37b08a0
Create Date: 2023-02-08 22:04:15.901498+00:00
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = 'ba8a214736eb'
down_revision = '1f30a37b08a0'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column('users', 'song')
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('users', sa.Column('song', sa.VARCHAR(length=50), autoincrement=False, nullable=True))
# ### end Alembic commands ###

12
poetry.lock generated
View file

@ -1006,14 +1006,6 @@ category = "main"
optional = false
python-versions = "*"
[[package]]
name = "youtube-dl"
version = "2021.12.17"
description = "YouTube video downloader"
category = "main"
optional = false
python-versions = "*"
[[package]]
name = "zope.event"
version = "4.5.0"
@ -2228,10 +2220,6 @@ wrapt = [
yattag = [
{file = "yattag-1.14.0.tar.gz", hash = "sha256:5731a31cb7452c0c6930dd1a284e0170b39eee959851a2aceb8d6af4134a5fa8"},
]
youtube-dl = [
{file = "youtube_dl-2021.12.17-py2.py3-none-any.whl", hash = "sha256:f1336d5de68647e0364a47b3c0712578e59ec76f02048ff5c50ef1c69d79cd55"},
{file = "youtube_dl-2021.12.17.tar.gz", hash = "sha256:bc59e86c5d15d887ac590454511f08ce2c47698d5a82c27bfe27b5d814bbaed2"},
]
"zope.event" = [
{file = "zope.event-4.5.0-py2.py3-none-any.whl", hash = "sha256:2666401939cdaa5f4e0c08cf7f20c9b21423b95e88f4675b1443973bdb080c42"},
{file = "zope.event-4.5.0.tar.gz", hash = "sha256:5e76517f5b9b119acf37ca8819781db6c16ea433f7e2062c4afc2b6fbedb1330"},

View file

@ -34,7 +34,6 @@ SQLAlchemy = "^1.4.43"
user-agents = "*"
psycopg2-binary = "*"
pusher_push_notifications = "*"
youtube-dl = "*"
yattag = "*"
webptools = "*"
pytest = "*"