~comcloudway/melon

8b18d6164375abae5f65e81ab3d2fe921435530e — Jakob Meier 3 months ago aba97f0
Add option to delete playlist to context menu

FIXES: bug where the video playlist position was ignored and not
properly created

Allows you to put the same video multiple times in the same playlist
6 files changed, 129 insertions(+), 83 deletions(-)

M melon/models/__init__.py
M melon/playlist/__init__.py
M po/de.po
M po/fa.po
M po/melon.pot
M po/nl.po
M melon/models/__init__.py => melon/models/__init__.py +37 -8
@@ 20,7 20,7 @@ class LocalPlaylist():
    description: str = ""
    # preview image url (None if non existend)
    thumbnail: str = None
    content: list[Resource] = []
    content: list[(Resource, int)] = []
    def __init__(self, id, title, desc):
        self.id = id
        self.title = title


@@ 75,7 75,7 @@ def execute_sql(conn:sqlite3.Connection, sql, *sqlargs, many=False) -> bool:
    else:
        return True

VERSION = 2
VERSION = 3

app_conf_template = {
    # NOTE: they are set to False to save bandwidth


@@ 208,7 208,7 @@ def init_db():
        video_server,
        position,
        FOREIGN KEY(video_id, video_server) REFERENCES videos(id, server),
        PRIMARY KEY(id, video_id, video_server, position)
        PRIMARY KEY(id, position)
        )
        """) or die()
        # history


@@ 276,6 276,27 @@ def init_db():
        FOREIGN KEY(video_id, video_server) REFERENCES videos(id, server)
        )
        """)
    if version < 3:
        # video_id and video_server are no longer part of the primary key
        execute_sql(conn, """
        CREATE TABLE lpc2(
        id,
        video_id,
        video_server,
        position,
        FOREIGN KEY(video_id, video_server) REFERENCES videos(id, server),
        PRIMARY KEY(id, position)
        )""")
        execute_sql(conn, """
        INSERT INTO lpc2(id, video_id, video_server, position)
        SELECT id, video_id, video_server, position FROM local_playlist_content
        """)
        execute_sql(conn, """
        DROP TABLE local_playlist_content
        """)
        execute_sql(conn, """
        ALTER TABLE lpc2 RENAME TO local_playlist_content
        """)

    # MIGRATIONS FINISHED
    execute_sql(conn, f"PRAGMA user_version = {VERSION}") or die()


@@ 596,17 617,25 @@ def add_to_local_playlist(playlist_id:int, vid, pos=None):
    conn = connect_to_db()
    if pos is None:
        vids = conn.execute("""
        SELECT server, videos.id, url, title, description, thumbnail, channel_id, channel_name
        SELECT MAX(position)
        FROM local_playlist_content, videos
        WHERE local_playlist_content.id = ? AND local_playlist_content.video_id = videos.id AND local_playlist_content.video_server = videos.server
        """, (playlist_id,)).fetchall()
        pos = len(vids)
        """, (playlist_id,)).fetchone()
        pos = vids[0]+1
    execute_sql(conn, """
    INSERT INTO local_playlist_content
    VALUES (?, ?, ?, ?)
    """, (playlist_id, vid.id, vid.server, pos))
    conn.close()
    notify("playlists_changed")
def delete_from_local_playlist(playlist_id: int, pos:int):
    conn = connect_to_db()
    execute_sql(conn, """
    DELETE FROM local_playlist_content
    WHERE id = ? AND position = ?
    """, (playlist_id, pos))
    conn.close()
    notify("playlists_changed")
def get_local_playlist(playlist_id:int) -> LocalPlaylist:
    conn = connect_to_db()
    resp = conn.execute("""


@@ 617,12 646,12 @@ def get_local_playlist(playlist_id:int) -> LocalPlaylist:
    p = LocalPlaylist(resp[0], resp[1], resp[2])
    p.thumbnail = resp[3]
    vids = conn.execute("""
    SELECT server, videos.id, url, title, description, thumbnail, channel_id, channel_name
    SELECT server, videos.id, url, title, description, thumbnail, channel_id, channel_name, position
    FROM local_playlist_content, videos
    WHERE local_playlist_content.id = ? AND local_playlist_content.video_id = videos.id AND local_playlist_content.video_server = videos.server
    ORDER BY position
    """, (playlist_id,)).fetchall()
    p.content = [ Video(d[0], d[2], d[1], d[3], (d[7], d[6]), d[4], d[5]) for d in vids ]
    p.content = [ (Video(srv, url, vid, title, (cname, cid), desc, thumb), pos) for (srv, vid, url, title, desc, thumb, cid, cname, pos) in vids ]
    return p
def set_local_playlist_thumbnail(playlist_id: int, thumb: str):
    conn = connect_to_db()

M melon/playlist/__init__.py => melon/playlist/__init__.py +4 -3
@@ 11,7 11,7 @@ from melon.servers import Preference, PreferenceType
from melon.widgets.iconbutton import IconButton
from melon.widgets.feeditem import AdaptiveFeedItem
from melon.widgets.simpledialog import SimpleDialog
from melon.models import get_app_settings, get_local_playlist, PlaylistWrapper, ensure_playlist, ensure_delete_local_playlist, set_local_playlist_thumbnail
from melon.models import get_app_settings, get_local_playlist, PlaylistWrapper, ensure_playlist, ensure_delete_local_playlist, set_local_playlist_thumbnail, delete_from_local_playlist
from melon.models import is_server_enabled, ensure_server_disabled, ensure_server_enabled, register_callback
from melon.utils import pass_me



@@ 81,10 81,11 @@ class LocalPlaylistScreen(Adw.NavigationPage):
            app_conf = get_app_settings()
            self.box.add(group)
            # add playlist content to group as well
            for entry in playlist.content:
            for (entry, index) in sorted(playlist.content, key=lambda x:x[1]):
                item = AdaptiveFeedItem(entry)
                item.menuitems = [
                        (_("Set as playlist thumbnail"), pass_me(lambda pid, thumb: set_local_playlist_thumbnail(pid, thumb), self.playlist_id, entry.thumbnail))
                        (_("Set as playlist thumbnail"), pass_me(lambda pid, thumb: set_local_playlist_thumbnail(pid, thumb), self.playlist_id, entry.thumbnail)),
                        (_("Remove from playlist"), pass_me(lambda pid, pos: delete_from_local_playlist(pid, pos), self.playlist_id, index))
                ]
                group.add(item)


M po/de.po => po/de.po +22 -18
@@ 7,7 7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Melon 0.1.2\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-06-12 20:38+0200\n"
"POT-Creation-Date: 2024-06-12 21:13+0200\n"
"PO-Revision-Date: 2024-04-20 14:18+0000\n"
"Last-Translator: hurzelchen <hurzelchen@users.noreply.translate.codeberg."
"org>\n"


@@ 447,77 447,81 @@ msgstr "Videos anschauen"
msgid "Set as playlist thumbnail"
msgstr ""

#: ../melon/playlist/__init__.py:98
#: ../melon/playlist/__init__.py:88
msgid "Remove from playlist"
msgstr ""

#: ../melon/playlist/__init__.py:99
msgid "Edit Playlist"
msgstr "Wiedergabeliste bearbeiten"

#: ../melon/playlist/__init__.py:104
#: ../melon/playlist/__init__.py:105
msgid "Playlist details"
msgstr "Wiedergabelistendetails"

#: ../melon/playlist/__init__.py:105
#: ../melon/playlist/__init__.py:106
msgid "Change playlist information"
msgstr "Wiedergabelistendetails ändern"

#: ../melon/playlist/__init__.py:107 ../melon/playlist/create.py:37
#: ../melon/playlist/__init__.py:108 ../melon/playlist/create.py:37
msgid "Playlist name"
msgstr "Name der Wiedergabeliste"

#: ../melon/playlist/__init__.py:110 ../melon/playlist/create.py:40
#: ../melon/playlist/__init__.py:111 ../melon/playlist/create.py:40
msgid "Playlist description"
msgstr "Beschreibung der Wiedergabeliste"

#: ../melon/playlist/__init__.py:115
#: ../melon/playlist/__init__.py:116
msgid "Save details"
msgstr "Details speichern"

#: ../melon/playlist/__init__.py:116
#: ../melon/playlist/__init__.py:117
msgid "Change playlist title and description. (Closes the dialog)"
msgstr ""
"Titel und Beschreibung der Wiedergabeliste ändern. (Schließt den Dialog)"

#: ../melon/playlist/__init__.py:126 ../melon/playlist/__init__.py:168
#: ../melon/playlist/__init__.py:127 ../melon/playlist/__init__.py:169
msgid "Delete Playlist"
msgstr "Wiedergabeliste löschen"

#: ../melon/playlist/__init__.py:127
#: ../melon/playlist/__init__.py:128
msgid "Delete this playlist and it's content. This can NOT be undone."
msgstr ""
"Diese Wiedergabeliste und ihren Inhalt löschen. Diese Aktion kann nicht "
"rückgängig gemacht werden."

#: ../melon/playlist/__init__.py:138
#: ../melon/playlist/__init__.py:139
msgid "Close"
msgstr "Schließen"

#: ../melon/playlist/__init__.py:138
#: ../melon/playlist/__init__.py:139
msgid "Close without changing anything"
msgstr ""

#: ../melon/playlist/__init__.py:171
#: ../melon/playlist/__init__.py:172
msgid "Do you really want to delete this playlist?"
msgstr "Möchtest du diese Wiedergabeliste wirklich löschen?"

#: ../melon/playlist/__init__.py:172
#: ../melon/playlist/__init__.py:173
msgid "This cannot be undone"
msgstr "Dies kann nicht rückgängig gemacht werden"

#: ../melon/playlist/__init__.py:176 ../melon/playlist/create.py:47
#: ../melon/playlist/__init__.py:177 ../melon/playlist/create.py:47
#: ../melon/playlist/pick.py:70 ../melon/widgets/preferencerow.py:175
#: ../melon/widgets/preferencerow.py:218
msgid "Cancel"
msgstr "Abbruch"

#: ../melon/playlist/__init__.py:176
#: ../melon/playlist/__init__.py:177
msgid "Do not delete the playlist"
msgstr "Wiedergabeliste nicht löschen"

#: ../melon/playlist/__init__.py:177 ../melon/widgets/preferencerow.py:207
#: ../melon/playlist/__init__.py:178 ../melon/widgets/preferencerow.py:207
#: ../melon/widgets/preferencerow.py:219
msgid "Delete"
msgstr "Löschen"

#: ../melon/playlist/__init__.py:177
#: ../melon/playlist/__init__.py:178
msgid "Delete this playlist"
msgstr "Diese Wiedergabeliste löschen"


M po/fa.po => po/fa.po +22 -18
@@ 7,7 7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Melon 0.1.2\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-06-12 20:38+0200\n"
"POT-Creation-Date: 2024-06-12 21:13+0200\n"
"PO-Revision-Date: 2024-05-30 09:18+0000\n"
"Last-Translator: sohrabbehdani <sohrabbehdani@users.noreply.translate."
"codeberg.org>\n"


@@ 447,74 447,78 @@ msgstr "شروع به تماشا کنید"
msgid "Set as playlist thumbnail"
msgstr ""

#: ../melon/playlist/__init__.py:98
#: ../melon/playlist/__init__.py:88
msgid "Remove from playlist"
msgstr ""

#: ../melon/playlist/__init__.py:99
msgid "Edit Playlist"
msgstr "حذف لیست‌پخش"

#: ../melon/playlist/__init__.py:104
#: ../melon/playlist/__init__.py:105
msgid "Playlist details"
msgstr "جزئیات لیست‌پخش"

#: ../melon/playlist/__init__.py:105
#: ../melon/playlist/__init__.py:106
msgid "Change playlist information"
msgstr "تغییر اطلاعات لیست پخش"

#: ../melon/playlist/__init__.py:107 ../melon/playlist/create.py:37
#: ../melon/playlist/__init__.py:108 ../melon/playlist/create.py:37
msgid "Playlist name"
msgstr "نام لیست‌پخش"

#: ../melon/playlist/__init__.py:110 ../melon/playlist/create.py:40
#: ../melon/playlist/__init__.py:111 ../melon/playlist/create.py:40
msgid "Playlist description"
msgstr "اطلاعات سیاههٔ پخش"

#: ../melon/playlist/__init__.py:115
#: ../melon/playlist/__init__.py:116
msgid "Save details"
msgstr "ذخیره جزئیات"

#: ../melon/playlist/__init__.py:116
#: ../melon/playlist/__init__.py:117
msgid "Change playlist title and description. (Closes the dialog)"
msgstr "تغییر عنوان و توضیحات لیست پخش (این پنجره بسته می شود)"

#: ../melon/playlist/__init__.py:126 ../melon/playlist/__init__.py:168
#: ../melon/playlist/__init__.py:127 ../melon/playlist/__init__.py:169
msgid "Delete Playlist"
msgstr "حذف لیست پخش"

#: ../melon/playlist/__init__.py:127
#: ../melon/playlist/__init__.py:128
msgid "Delete this playlist and it's content. This can NOT be undone."
msgstr "این عملیات این لیست‌پخش و محتویات آن را حذف می‌کند و قابل بازگشت نیست."

#: ../melon/playlist/__init__.py:138
#: ../melon/playlist/__init__.py:139
msgid "Close"
msgstr "بستن"

#: ../melon/playlist/__init__.py:138
#: ../melon/playlist/__init__.py:139
msgid "Close without changing anything"
msgstr "بستن بدون تغییر دادن چیزی"

#: ../melon/playlist/__init__.py:171
#: ../melon/playlist/__init__.py:172
msgid "Do you really want to delete this playlist?"
msgstr "آیا از حذف این لیست‌پخش اطمینان دارید؟"

#: ../melon/playlist/__init__.py:172
#: ../melon/playlist/__init__.py:173
msgid "This cannot be undone"
msgstr ""

#: ../melon/playlist/__init__.py:176 ../melon/playlist/create.py:47
#: ../melon/playlist/__init__.py:177 ../melon/playlist/create.py:47
#: ../melon/playlist/pick.py:70 ../melon/widgets/preferencerow.py:175
#: ../melon/widgets/preferencerow.py:218
msgid "Cancel"
msgstr "لغو"

#: ../melon/playlist/__init__.py:176
#: ../melon/playlist/__init__.py:177
msgid "Do not delete the playlist"
msgstr "لیست‌پخش را حذف نکن."

#: ../melon/playlist/__init__.py:177 ../melon/widgets/preferencerow.py:207
#: ../melon/playlist/__init__.py:178 ../melon/widgets/preferencerow.py:207
#: ../melon/widgets/preferencerow.py:219
msgid "Delete"
msgstr "حذف"

#: ../melon/playlist/__init__.py:177
#: ../melon/playlist/__init__.py:178
msgid "Delete this playlist"
msgstr "حذف این لیست‌پخش"


M po/melon.pot => po/melon.pot +22 -18
@@ 8,7 8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Melon 0.2.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-06-12 20:38+0200\n"
"POT-Creation-Date: 2024-06-12 21:13+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"


@@ 432,74 432,78 @@ msgstr ""
msgid "Set as playlist thumbnail"
msgstr ""

#: ../melon/playlist/__init__.py:98
#: ../melon/playlist/__init__.py:88
msgid "Remove from playlist"
msgstr ""

#: ../melon/playlist/__init__.py:99
msgid "Edit Playlist"
msgstr ""

#: ../melon/playlist/__init__.py:104
#: ../melon/playlist/__init__.py:105
msgid "Playlist details"
msgstr ""

#: ../melon/playlist/__init__.py:105
#: ../melon/playlist/__init__.py:106
msgid "Change playlist information"
msgstr ""

#: ../melon/playlist/__init__.py:107 ../melon/playlist/create.py:37
#: ../melon/playlist/__init__.py:108 ../melon/playlist/create.py:37
msgid "Playlist name"
msgstr ""

#: ../melon/playlist/__init__.py:110 ../melon/playlist/create.py:40
#: ../melon/playlist/__init__.py:111 ../melon/playlist/create.py:40
msgid "Playlist description"
msgstr ""

#: ../melon/playlist/__init__.py:115
#: ../melon/playlist/__init__.py:116
msgid "Save details"
msgstr ""

#: ../melon/playlist/__init__.py:116
#: ../melon/playlist/__init__.py:117
msgid "Change playlist title and description. (Closes the dialog)"
msgstr ""

#: ../melon/playlist/__init__.py:126 ../melon/playlist/__init__.py:168
#: ../melon/playlist/__init__.py:127 ../melon/playlist/__init__.py:169
msgid "Delete Playlist"
msgstr ""

#: ../melon/playlist/__init__.py:127
#: ../melon/playlist/__init__.py:128
msgid "Delete this playlist and it's content. This can NOT be undone."
msgstr ""

#: ../melon/playlist/__init__.py:138
#: ../melon/playlist/__init__.py:139
msgid "Close"
msgstr ""

#: ../melon/playlist/__init__.py:138
#: ../melon/playlist/__init__.py:139
msgid "Close without changing anything"
msgstr ""

#: ../melon/playlist/__init__.py:171
#: ../melon/playlist/__init__.py:172
msgid "Do you really want to delete this playlist?"
msgstr ""

#: ../melon/playlist/__init__.py:172
#: ../melon/playlist/__init__.py:173
msgid "This cannot be undone"
msgstr ""

#: ../melon/playlist/__init__.py:176 ../melon/playlist/create.py:47
#: ../melon/playlist/__init__.py:177 ../melon/playlist/create.py:47
#: ../melon/playlist/pick.py:70 ../melon/widgets/preferencerow.py:175
#: ../melon/widgets/preferencerow.py:218
msgid "Cancel"
msgstr ""

#: ../melon/playlist/__init__.py:176
#: ../melon/playlist/__init__.py:177
msgid "Do not delete the playlist"
msgstr ""

#: ../melon/playlist/__init__.py:177 ../melon/widgets/preferencerow.py:207
#: ../melon/playlist/__init__.py:178 ../melon/widgets/preferencerow.py:207
#: ../melon/widgets/preferencerow.py:219
msgid "Delete"
msgstr ""

#: ../melon/playlist/__init__.py:177
#: ../melon/playlist/__init__.py:178
msgid "Delete this playlist"
msgstr ""


M po/nl.po => po/nl.po +22 -18
@@ 7,7 7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Melon 0.2.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-06-12 20:38+0200\n"
"POT-Creation-Date: 2024-06-12 21:13+0200\n"
"PO-Revision-Date: 2024-04-23 12:18+0000\n"
"Last-Translator: Vistaus <Vistaus@users.noreply.translate.codeberg.org>\n"
"Language-Team: Dutch <https://translate.codeberg.org/projects/melon/melon-"


@@ 449,77 449,81 @@ msgstr "Beginnen met kijken"
msgid "Set as playlist thumbnail"
msgstr ""

#: ../melon/playlist/__init__.py:98
#: ../melon/playlist/__init__.py:88
msgid "Remove from playlist"
msgstr ""

#: ../melon/playlist/__init__.py:99
msgid "Edit Playlist"
msgstr "Afspeellijst bewerken"

#: ../melon/playlist/__init__.py:104
#: ../melon/playlist/__init__.py:105
msgid "Playlist details"
msgstr "Afspeellijstinformatie"

#: ../melon/playlist/__init__.py:105
#: ../melon/playlist/__init__.py:106
msgid "Change playlist information"
msgstr "Afspeellijstinformatie wijzigen"

#: ../melon/playlist/__init__.py:107 ../melon/playlist/create.py:37
#: ../melon/playlist/__init__.py:108 ../melon/playlist/create.py:37
msgid "Playlist name"
msgstr "Afspeellijstnaam"

#: ../melon/playlist/__init__.py:110 ../melon/playlist/create.py:40
#: ../melon/playlist/__init__.py:111 ../melon/playlist/create.py:40
msgid "Playlist description"
msgstr "Afspeellijstbeschrijving"

#: ../melon/playlist/__init__.py:115
#: ../melon/playlist/__init__.py:116
msgid "Save details"
msgstr "Informatie opslaan"

#: ../melon/playlist/__init__.py:116
#: ../melon/playlist/__init__.py:117
msgid "Change playlist title and description. (Closes the dialog)"
msgstr ""
"Wijzig de afspeellijsttitel en -beschrijving (het venster wordt gesloten)"

#: ../melon/playlist/__init__.py:126 ../melon/playlist/__init__.py:168
#: ../melon/playlist/__init__.py:127 ../melon/playlist/__init__.py:169
msgid "Delete Playlist"
msgstr "Afspeellijst verwijderen"

#: ../melon/playlist/__init__.py:127
#: ../melon/playlist/__init__.py:128
msgid "Delete this playlist and it's content. This can NOT be undone."
msgstr ""
"Verwijder deze afspeellijst en alle bijbehorende inhoud. Let op: dit is "
"onomkeerbaar."

#: ../melon/playlist/__init__.py:138
#: ../melon/playlist/__init__.py:139
msgid "Close"
msgstr "Sluiten"

#: ../melon/playlist/__init__.py:138
#: ../melon/playlist/__init__.py:139
msgid "Close without changing anything"
msgstr "Sluiten zonder opslaan"

#: ../melon/playlist/__init__.py:171
#: ../melon/playlist/__init__.py:172
msgid "Do you really want to delete this playlist?"
msgstr "Weet u zeker dat u deze afspeellijst wilt verwijderen?"

#: ../melon/playlist/__init__.py:172
#: ../melon/playlist/__init__.py:173
msgid "This cannot be undone"
msgstr "Dit is onomkeerbaar"

#: ../melon/playlist/__init__.py:176 ../melon/playlist/create.py:47
#: ../melon/playlist/__init__.py:177 ../melon/playlist/create.py:47
#: ../melon/playlist/pick.py:70 ../melon/widgets/preferencerow.py:175
#: ../melon/widgets/preferencerow.py:218
msgid "Cancel"
msgstr "Annuleren"

#: ../melon/playlist/__init__.py:176
#: ../melon/playlist/__init__.py:177
msgid "Do not delete the playlist"
msgstr "Afspeellijst niet verwijderen"

#: ../melon/playlist/__init__.py:177 ../melon/widgets/preferencerow.py:207
#: ../melon/playlist/__init__.py:178 ../melon/widgets/preferencerow.py:207
#: ../melon/widgets/preferencerow.py:219
msgid "Delete"
msgstr "Verwijderen"

#: ../melon/playlist/__init__.py:177
#: ../melon/playlist/__init__.py:178
msgid "Delete this playlist"
msgstr "Afspeellijst verwijderen"