From 14f1fe4b16b390ad25bd4bd4a8f930d629efe9b6 Mon Sep 17 00:00:00 2001
From: Hellow <74311245+HeIIow2@users.noreply.github.com>
Date: Thu, 25 Apr 2024 20:35:36 +0200
Subject: [PATCH 01/20] feat: embedded own sponsorblock in youtube
---
.vscode/settings.json | 1 +
music_kraken/pages/youtube.py | 12 ++++-----
.../pages/youtube_music/super_youtube.py | 12 ++++-----
pyproject.toml | 2 +-
requirements.txt | 25 -------------------
5 files changed, 13 insertions(+), 39 deletions(-)
delete mode 100644 requirements.txt
diff --git a/.vscode/settings.json b/.vscode/settings.json
index aca8e78..9dfbaa3 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -25,6 +25,7 @@
"musify",
"OKBLUE",
"Referer",
+ "sponsorblock",
"tracksort",
"unmap",
"youtube"
diff --git a/music_kraken/pages/youtube.py b/music_kraken/pages/youtube.py
index 4ce6633..73b92ad 100644
--- a/music_kraken/pages/youtube.py
+++ b/music_kraken/pages/youtube.py
@@ -2,8 +2,7 @@ from typing import List, Optional, Type, Tuple
from urllib.parse import urlparse, urlunparse, parse_qs
from enum import Enum
-import sponsorblock
-from sponsorblock.errors import HTTPException, NotFoundException
+import python_sponsorblock
from ..objects import Source, DatabaseObject, Song, Target
from .abstract import Page
@@ -63,8 +62,9 @@ class YouTube(SuperYouTube):
)
# the stuff with the connection is, to ensure sponsorblock uses the proxies, my programm does
- _sponsorblock_connection: Connection = Connection(host="https://sponsor.ajay.app/")
- self.sponsorblock_client = sponsorblock.Client(session=_sponsorblock_connection.session)
+ _sponsorblock_connection: Connection = Connection()
+ self.sponsorblock = python_sponsorblock.SponsorBlock(silent=True, session=_sponsorblock_connection.session)
+
super().__init__(*args, **kwargs)
@@ -344,10 +344,10 @@ class YouTube(SuperYouTube):
segments = []
try:
- segments = self.sponsorblock_client.get_skip_segments(parsed.id)
+ segments = self.sponsorblock.get_segments(parsed.id)
except NotFoundException:
self.LOGGER.debug(f"No sponsor found for the video {parsed.id}.")
except HTTPException as e:
self.LOGGER.warning(f"{e}")
- return [(segment.start, segment.end) for segment in segments]
+ return [(segment.segment[0], segment.segment[1]) for segment in segments]
diff --git a/music_kraken/pages/youtube_music/super_youtube.py b/music_kraken/pages/youtube_music/super_youtube.py
index d391370..420c46d 100644
--- a/music_kraken/pages/youtube_music/super_youtube.py
+++ b/music_kraken/pages/youtube_music/super_youtube.py
@@ -3,8 +3,7 @@ from urllib.parse import urlparse, urlunparse, parse_qs
from enum import Enum
import requests
-import sponsorblock
-from sponsorblock.errors import HTTPException, NotFoundException
+import python_sponsorblock
from ...objects import Source, DatabaseObject, Song, Target
from ..abstract import Page
@@ -143,9 +142,8 @@ class SuperYouTube(Page):
)
# the stuff with the connection is, to ensure sponsorblock uses the proxies, my programm does
- _sponsorblock_connection: Connection = Connection(host="https://sponsor.ajay.app/")
- self.sponsorblock_client = sponsorblock.Client(session=_sponsorblock_connection.session)
-
+ _sponsorblock_connection: Connection = Connection()
+ self.sponsorblock = python_sponsorblock.SponsorBlock(silent=True, session=_sponsorblock_connection.session)
def get_source_type(self, source: Source) -> Optional[Type[DatabaseObject]]:
_url_type = {
@@ -213,10 +211,10 @@ class SuperYouTube(Page):
segments = []
try:
- segments = self.sponsorblock_client.get_skip_segments(parsed.id)
+ segments = self.sponsorblock.get_segments(parsed.id)
except NotFoundException:
self.LOGGER.debug(f"No sponsor found for the video {parsed.id}.")
except HTTPException as e:
self.LOGGER.warning(f"{e}")
- return [(segment.start, segment.end) for segment in segments]
+ return [(segment.segment[0], segment.segment[1]) for segment in segments]
diff --git a/pyproject.toml b/pyproject.toml
index 16fac20..9c8232b 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -69,7 +69,7 @@ dependencies = [
"toml~=0.10.2",
"typing_extensions~=4.7.1",
- "sponsorblock~=0.1.3",
+ "python-sponsorblock~=0.0.0",
"youtube_dl",
]
dynamic = [
diff --git a/requirements.txt b/requirements.txt
deleted file mode 100644
index 7ba18a1..0000000
--- a/requirements.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-requests~=2.31.0
-mutagen~=1.46.0
-musicbrainzngs~=0.7.1
-jellyfish~=0.9.0
-beautifulsoup4~=4.11.1
-pycountry~=24.0.1
-python-dateutil~=2.8.2
-pandoc~=2.3
-SQLAlchemy~=2.0.7
-setuptools~=68.2.0
-tqdm~=4.65.0
-ffmpeg-python~=0.2.0
-platformdirs~=4.2.0
-transliterate~=1.10.2
-sponsorblock~=0.1.3
-regex~=2022.9.13
-pyffmpeg~=2.4.2.18
-ffmpeg-progress-yield~=0.7.8
-pathvalidate~=2.5.2
-guppy3~=3.1.3
-toml~=0.10.2
-typing_extensions~=4.7.1
-responses~=0.24.1
-youtube_dl
-merge_args~=0.1.5
\ No newline at end of file
--
2.45.2
From 60e84a063887d2d134679ed743e9e3b7bc5bea8a Mon Sep 17 00:00:00 2001
From: Hellow <74311245+HeIIow2@users.noreply.github.com>
Date: Thu, 25 Apr 2024 22:29:43 +0200
Subject: [PATCH 02/20] fix: if request fails in a connection without host it
raised an exception
---
assets/database_structure.sql | 66 ---------
assets/logo.svg | 102 ++++---------
assets/logos/.png | Bin 309491 -> 0 bytes
assets/logos/00.jpg | Bin 31191 -> 0 bytes
assets/logos/01.png | Bin 299406 -> 0 bytes
assets/logos/01.svg | 76 ----------
assets/logos/02.png | Bin 172567 -> 0 bytes
assets/logos/02.svg | 73 ----------
...wearing_headphones__svg__cute__octupus.png | Bin 604580 -> 0 bytes
...wearing_headphones__svg__cute__octupus.svg | 137 ------------------
...ng_headphones__svg__cute__in_frame__ce.png | Bin 309491 -> 0 bytes
assets/temp_database_structure.sql | 66 ---------
music_kraken/connection/connection.py | 4 +-
13 files changed, 34 insertions(+), 490 deletions(-)
delete mode 100644 assets/database_structure.sql
delete mode 100644 assets/logos/.png
delete mode 100644 assets/logos/00.jpg
delete mode 100644 assets/logos/01.png
delete mode 100644 assets/logos/01.svg
delete mode 100644 assets/logos/02.png
delete mode 100644 assets/logos/02.svg
delete mode 100644 assets/logos/craiyon_142854_simplistic_black_and_white_logo_of_an_octopus_wearing_headphones__svg__cute__octupus.png
delete mode 100644 assets/logos/craiyon_142854_simplistic_black_and_white_logo_of_an_octopus_wearing_headphones__svg__cute__octupus.svg
delete mode 100644 assets/logos/craiyon_144924_simplistic__black_and_white_logo__octopus_wearing_headphones__svg__cute__in_frame__ce.png
delete mode 100644 assets/temp_database_structure.sql
diff --git a/assets/database_structure.sql b/assets/database_structure.sql
deleted file mode 100644
index 293f428..0000000
--- a/assets/database_structure.sql
+++ /dev/null
@@ -1,66 +0,0 @@
-DROP TABLE IF EXISTS artist;
-CREATE TABLE artist (
- id TEXT PRIMARY KEY NOT NULL,
- name TEXT
-);
-
-DROP TABLE IF EXISTS artist_release_group;
-CREATE TABLE artist_release_group (
- artist_id TEXT NOT NULL,
- release_group_id TEXT NOT NULL
-);
-
-DROP TABLE IF EXISTS artist_track;
-CREATE TABLE artist_track (
- artist_id TEXT NOT NULL,
- track_id TEXT NOT NULL
-);
-
-DROP TABLE IF EXISTS release_group;
-CREATE TABLE release_group (
- id TEXT PRIMARY KEY NOT NULL,
- albumartist TEXT,
- albumsort INT,
- musicbrainz_albumtype TEXT,
- compilation TEXT,
- album_artist_id TEXT
-);
-
-DROP TABLE IF EXISTS release_;
-CREATE TABLE release_ (
- id TEXT PRIMARY KEY NOT NULL,
- release_group_id TEXT NOT NULL,
- title TEXT,
- copyright TEXT,
- album_status TEXT,
- language TEXT,
- year TEXT,
- date TEXT,
- country TEXT,
- barcode TEXT
-);
-
-DROP TABLE IF EXISTS track;
-CREATE TABLE track (
- id TEXT PRIMARY KEY NOT NULL,
- downloaded BOOLEAN NOT NULL DEFAULT 0,
- release_id TEXT NOT NULL,
- track TEXT,
- length INT,
- tracknumber TEXT,
- isrc TEXT,
- genre TEXT,
- lyrics TEXT,
- path TEXT,
- file TEXT,
- url TEXT,
- src TEXT
-);
-
-DROP TABLE IF EXISTS source;
-CREATE TABLE source (
- track_id TEXT NOT NULL,
- src TEXT NOT NULL,
- url TEXT NOT NULL,
- valid BOOLEAN NOT NULL DEFAULT 1
-);
diff --git a/assets/logo.svg b/assets/logo.svg
index 49738fc..eb043bc 100644
--- a/assets/logo.svg
+++ b/assets/logo.svg
@@ -1,73 +1,35 @@
-
diff --git a/assets/logos/.png b/assets/logos/.png
deleted file mode 100644
index df2154484e6a513c604f1fcfa1826fbf9448b371..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 309491
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