Merge branch 'youtube' into experimental
This commit is contained in:
commit
1d64aab778
@ -1,78 +0,0 @@
|
|||||||
# Details
|
|
||||||
|
|
||||||
Date : 2023-02-27 12:22:06
|
|
||||||
|
|
||||||
Directory /home/lars/Projects/music-downloader/src
|
|
||||||
|
|
||||||
Total : 63 files, 4095 codes, 1060 comments, 1216 blanks, all 6371 lines
|
|
||||||
|
|
||||||
[Summary](results.md) / Details / [Diff Summary](diff.md) / [Diff Details](diff-details.md)
|
|
||||||
|
|
||||||
## Files
|
|
||||||
| filename | language | code | comment | blank | total |
|
|
||||||
| :--- | :--- | ---: | ---: | ---: | ---: |
|
|
||||||
| [src/__init__.py](/src/__init__.py) | Python | 0 | 0 | 1 | 1 |
|
|
||||||
| [src/create_custom_objects.py](/src/create_custom_objects.py) | Python | 80 | 3 | 18 | 101 |
|
|
||||||
| [src/metal_archives.py](/src/metal_archives.py) | Python | 48 | 4 | 15 | 67 |
|
|
||||||
| [src/music_kraken/__init__.py](/src/music_kraken/__init__.py) | Python | 57 | 8 | 25 | 90 |
|
|
||||||
| [src/music_kraken/__main__.py](/src/music_kraken/__main__.py) | Python | 3 | 2 | 3 | 8 |
|
|
||||||
| [src/music_kraken/database/__init__.py](/src/music_kraken/database/__init__.py) | Python | 18 | 0 | 5 | 23 |
|
|
||||||
| [src/music_kraken/database/data_models.py](/src/music_kraken/database/data_models.py) | Python | 116 | 23 | 49 | 188 |
|
|
||||||
| [src/music_kraken/database/database.py](/src/music_kraken/database/database.py) | Python | 84 | 48 | 26 | 158 |
|
|
||||||
| [src/music_kraken/database/object_cache.py](/src/music_kraken/database/object_cache.py) | Python | 35 | 56 | 16 | 107 |
|
|
||||||
| [src/music_kraken/database/old_database.py](/src/music_kraken/database/old_database.py) | Python | 432 | 154 | 115 | 701 |
|
|
||||||
| [src/music_kraken/database/read.py](/src/music_kraken/database/read.py) | Python | 0 | 0 | 1 | 1 |
|
|
||||||
| [src/music_kraken/database/temp_database.py](/src/music_kraken/database/temp_database.py) | Python | 12 | 0 | 8 | 20 |
|
|
||||||
| [src/music_kraken/database/write.py](/src/music_kraken/database/write.py) | Python | 168 | 62 | 55 | 285 |
|
|
||||||
| [src/music_kraken/not_used_anymore/__init__.py](/src/music_kraken/not_used_anymore/__init__.py) | Python | 0 | 0 | 3 | 3 |
|
|
||||||
| [src/music_kraken/not_used_anymore/fetch_audio.py](/src/music_kraken/not_used_anymore/fetch_audio.py) | Python | 75 | 12 | 20 | 107 |
|
|
||||||
| [src/music_kraken/not_used_anymore/fetch_source.py](/src/music_kraken/not_used_anymore/fetch_source.py) | Python | 54 | 1 | 16 | 71 |
|
|
||||||
| [src/music_kraken/not_used_anymore/metadata/__init__.py](/src/music_kraken/not_used_anymore/metadata/__init__.py) | Python | 6 | 0 | 2 | 8 |
|
|
||||||
| [src/music_kraken/not_used_anymore/metadata/metadata_fetch.py](/src/music_kraken/not_used_anymore/metadata/metadata_fetch.py) | Python | 257 | 24 | 65 | 346 |
|
|
||||||
| [src/music_kraken/not_used_anymore/metadata/metadata_search.py](/src/music_kraken/not_used_anymore/metadata/metadata_search.py) | Python | 253 | 40 | 72 | 365 |
|
|
||||||
| [src/music_kraken/not_used_anymore/metadata/sources/__init__.py](/src/music_kraken/not_used_anymore/metadata/sources/__init__.py) | Python | 3 | 0 | 2 | 5 |
|
|
||||||
| [src/music_kraken/not_used_anymore/metadata/sources/musicbrainz.py](/src/music_kraken/not_used_anymore/metadata/sources/musicbrainz.py) | Python | 42 | 6 | 12 | 60 |
|
|
||||||
| [src/music_kraken/not_used_anymore/sources/__init__.py](/src/music_kraken/not_used_anymore/sources/__init__.py) | Python | 0 | 0 | 1 | 1 |
|
|
||||||
| [src/music_kraken/not_used_anymore/sources/genius.py](/src/music_kraken/not_used_anymore/sources/genius.py) | Python | 115 | 16 | 42 | 173 |
|
|
||||||
| [src/music_kraken/not_used_anymore/sources/local_files.py](/src/music_kraken/not_used_anymore/sources/local_files.py) | Python | 40 | 0 | 18 | 58 |
|
|
||||||
| [src/music_kraken/not_used_anymore/sources/musify.py](/src/music_kraken/not_used_anymore/sources/musify.py) | Python | 136 | 9 | 37 | 182 |
|
|
||||||
| [src/music_kraken/not_used_anymore/sources/source.py](/src/music_kraken/not_used_anymore/sources/source.py) | Python | 11 | 5 | 8 | 24 |
|
|
||||||
| [src/music_kraken/not_used_anymore/sources/youtube.py](/src/music_kraken/not_used_anymore/sources/youtube.py) | Python | 71 | 4 | 24 | 99 |
|
|
||||||
| [src/music_kraken/objects/__init__.py](/src/music_kraken/objects/__init__.py) | Python | 23 | 0 | 7 | 30 |
|
|
||||||
| [src/music_kraken/objects/album.py](/src/music_kraken/objects/album.py) | Python | 15 | 6 | 5 | 26 |
|
|
||||||
| [src/music_kraken/objects/artist.py](/src/music_kraken/objects/artist.py) | Python | 18 | 0 | 5 | 23 |
|
|
||||||
| [src/music_kraken/objects/collection.py](/src/music_kraken/objects/collection.py) | Python | 52 | 15 | 24 | 91 |
|
|
||||||
| [src/music_kraken/objects/formatted_text.py](/src/music_kraken/objects/formatted_text.py) | Python | 53 | 57 | 20 | 130 |
|
|
||||||
| [src/music_kraken/objects/lyrics.py](/src/music_kraken/objects/lyrics.py) | Python | 21 | 0 | 7 | 28 |
|
|
||||||
| [src/music_kraken/objects/metadata.py](/src/music_kraken/objects/metadata.py) | Python | 262 | 68 | 63 | 393 |
|
|
||||||
| [src/music_kraken/objects/parents.py](/src/music_kraken/objects/parents.py) | Python | 22 | 15 | 12 | 49 |
|
|
||||||
| [src/music_kraken/objects/song.py](/src/music_kraken/objects/song.py) | Python | 332 | 81 | 89 | 502 |
|
|
||||||
| [src/music_kraken/objects/source.py](/src/music_kraken/objects/source.py) | Python | 116 | 38 | 41 | 195 |
|
|
||||||
| [src/music_kraken/objects/target.py](/src/music_kraken/objects/target.py) | Python | 22 | 7 | 7 | 36 |
|
|
||||||
| [src/music_kraken/pages/__init__.py](/src/music_kraken/pages/__init__.py) | Python | 7 | 0 | 5 | 12 |
|
|
||||||
| [src/music_kraken/pages/abstract.py](/src/music_kraken/pages/abstract.py) | Python | 73 | 68 | 27 | 168 |
|
|
||||||
| [src/music_kraken/pages/encyclopaedia_metallum.py](/src/music_kraken/pages/encyclopaedia_metallum.py) | Python | 341 | 66 | 91 | 498 |
|
|
||||||
| [src/music_kraken/pages/youtube.py](/src/music_kraken/pages/youtube.py) | Python | 25 | 16 | 6 | 47 |
|
|
||||||
| [src/music_kraken/static_files/new_db.sql](/src/music_kraken/static_files/new_db.sql) | SQLite | 72 | 0 | 10 | 82 |
|
|
||||||
| [src/music_kraken/static_files/temp_database_structure.sql](/src/music_kraken/static_files/temp_database_structure.sql) | SQLite | 135 | 0 | 10 | 145 |
|
|
||||||
| [src/music_kraken/tagging/__init__.py](/src/music_kraken/tagging/__init__.py) | Python | 8 | 0 | 2 | 10 |
|
|
||||||
| [src/music_kraken/tagging/id3.py](/src/music_kraken/tagging/id3.py) | Python | 51 | 4 | 20 | 75 |
|
|
||||||
| [src/music_kraken/target/__init__.py](/src/music_kraken/target/__init__.py) | Python | 4 | 0 | 2 | 6 |
|
|
||||||
| [src/music_kraken/target/set_target.py](/src/music_kraken/target/set_target.py) | Python | 37 | 7 | 18 | 62 |
|
|
||||||
| [src/music_kraken/utils/__init__.py](/src/music_kraken/utils/__init__.py) | Python | 1 | 1 | 1 | 3 |
|
|
||||||
| [src/music_kraken/utils/functions.py](/src/music_kraken/utils/functions.py) | Python | 3 | 0 | 1 | 4 |
|
|
||||||
| [src/music_kraken/utils/object_handeling.py](/src/music_kraken/utils/object_handeling.py) | Python | 19 | 0 | 6 | 25 |
|
|
||||||
| [src/music_kraken/utils/phonetic_compares.py](/src/music_kraken/utils/phonetic_compares.py) | Python | 39 | 2 | 17 | 58 |
|
|
||||||
| [src/music_kraken/utils/shared.py](/src/music_kraken/utils/shared.py) | Python | 62 | 3 | 10 | 75 |
|
|
||||||
| [src/music_kraken/utils/string_processing.py](/src/music_kraken/utils/string_processing.py) | Python | 2 | 5 | 2 | 9 |
|
|
||||||
| [src/music_kraken_cli.py](/src/music_kraken_cli.py) | Python | 3 | 0 | 3 | 6 |
|
|
||||||
| [src/music_kraken_gtk.py](/src/music_kraken_gtk.py) | Python | 3 | 0 | 2 | 5 |
|
|
||||||
| [src/test.db](/src/test.db) | Database | 91 | 0 | 1 | 92 |
|
|
||||||
| [src/tests/__init__.py](/src/tests/__init__.py) | Python | 0 | 0 | 1 | 1 |
|
|
||||||
| [src/tests/conftest.py](/src/tests/conftest.py) | Python | 3 | 1 | 2 | 6 |
|
|
||||||
| [src/tests/example_data_objects.py](/src/tests/example_data_objects.py) | Python | 36 | 5 | 6 | 47 |
|
|
||||||
| [src/try-programming-interface.py](/src/try-programming-interface.py) | Python | 14 | 98 | 22 | 134 |
|
|
||||||
| [src/try.py](/src/try.py) | Python | 1 | 0 | 3 | 4 |
|
|
||||||
| [src/try_python.py](/src/try_python.py) | Python | 13 | 20 | 9 | 42 |
|
|
||||||
|
|
||||||
[Summary](results.md) / Details / [Diff Summary](diff.md) / [Diff Details](diff-details.md)
|
|
@ -1,49 +0,0 @@
|
|||||||
# Diff Details
|
|
||||||
|
|
||||||
Date : 2023-02-27 12:22:06
|
|
||||||
|
|
||||||
Directory /home/lars/Projects/music-downloader/src
|
|
||||||
|
|
||||||
Total : 34 files, 520 codes, 285 comments, 188 blanks, all 993 lines
|
|
||||||
|
|
||||||
[Summary](results.md) / [Details](details.md) / [Diff Summary](diff.md) / Diff Details
|
|
||||||
|
|
||||||
## Files
|
|
||||||
| filename | language | code | comment | blank | total |
|
|
||||||
| :--- | :--- | ---: | ---: | ---: | ---: |
|
|
||||||
| [src/metal_archives.py](/src/metal_archives.py) | Python | 3 | -2 | -2 | -1 |
|
|
||||||
| [src/music_kraken/__init__.py](/src/music_kraken/__init__.py) | Python | -6 | -18 | -8 | -32 |
|
|
||||||
| [src/music_kraken/database/data_models.py](/src/music_kraken/database/data_models.py) | Python | 116 | 23 | 49 | 188 |
|
|
||||||
| [src/music_kraken/database/database.py](/src/music_kraken/database/database.py) | Python | -345 | -64 | -85 | -494 |
|
|
||||||
| [src/music_kraken/database/object_cache.py](/src/music_kraken/database/object_cache.py) | Python | 35 | 56 | 16 | 107 |
|
|
||||||
| [src/music_kraken/database/objects/__init__.py](/src/music_kraken/database/objects/__init__.py) | Python | -20 | 0 | -7 | -27 |
|
|
||||||
| [src/music_kraken/database/objects/artist.py](/src/music_kraken/database/objects/artist.py) | Python | -18 | 0 | -5 | -23 |
|
|
||||||
| [src/music_kraken/database/objects/formatted_text.py](/src/music_kraken/database/objects/formatted_text.py) | Python | -48 | -57 | -16 | -121 |
|
|
||||||
| [src/music_kraken/database/objects/metadata.py](/src/music_kraken/database/objects/metadata.py) | Python | -251 | -68 | -61 | -380 |
|
|
||||||
| [src/music_kraken/database/objects/parents.py](/src/music_kraken/database/objects/parents.py) | Python | -40 | -8 | -19 | -67 |
|
|
||||||
| [src/music_kraken/database/objects/song.py](/src/music_kraken/database/objects/song.py) | Python | -323 | -64 | -85 | -472 |
|
|
||||||
| [src/music_kraken/database/objects/source.py](/src/music_kraken/database/objects/source.py) | Python | -116 | -38 | -41 | -195 |
|
|
||||||
| [src/music_kraken/database/old_database.py](/src/music_kraken/database/old_database.py) | Python | 432 | 154 | 115 | 701 |
|
|
||||||
| [src/music_kraken/database/read.py](/src/music_kraken/database/read.py) | Python | 0 | 0 | 1 | 1 |
|
|
||||||
| [src/music_kraken/database/write.py](/src/music_kraken/database/write.py) | Python | 168 | 62 | 55 | 285 |
|
|
||||||
| [src/music_kraken/objects/__init__.py](/src/music_kraken/objects/__init__.py) | Python | 23 | 0 | 7 | 30 |
|
|
||||||
| [src/music_kraken/objects/album.py](/src/music_kraken/objects/album.py) | Python | 15 | 6 | 5 | 26 |
|
|
||||||
| [src/music_kraken/objects/artist.py](/src/music_kraken/objects/artist.py) | Python | 18 | 0 | 5 | 23 |
|
|
||||||
| [src/music_kraken/objects/collection.py](/src/music_kraken/objects/collection.py) | Python | 52 | 15 | 24 | 91 |
|
|
||||||
| [src/music_kraken/objects/formatted_text.py](/src/music_kraken/objects/formatted_text.py) | Python | 53 | 57 | 20 | 130 |
|
|
||||||
| [src/music_kraken/objects/lyrics.py](/src/music_kraken/objects/lyrics.py) | Python | 21 | 0 | 7 | 28 |
|
|
||||||
| [src/music_kraken/objects/metadata.py](/src/music_kraken/objects/metadata.py) | Python | 262 | 68 | 63 | 393 |
|
|
||||||
| [src/music_kraken/objects/parents.py](/src/music_kraken/objects/parents.py) | Python | 22 | 15 | 12 | 49 |
|
|
||||||
| [src/music_kraken/objects/song.py](/src/music_kraken/objects/song.py) | Python | 332 | 81 | 89 | 502 |
|
|
||||||
| [src/music_kraken/objects/source.py](/src/music_kraken/objects/source.py) | Python | 116 | 38 | 41 | 195 |
|
|
||||||
| [src/music_kraken/objects/target.py](/src/music_kraken/objects/target.py) | Python | 22 | 7 | 7 | 36 |
|
|
||||||
| [src/music_kraken/pages/abstract.py](/src/music_kraken/pages/abstract.py) | Python | 3 | 0 | 0 | 3 |
|
|
||||||
| [src/music_kraken/pages/encyclopaedia_metallum.py](/src/music_kraken/pages/encyclopaedia_metallum.py) | Python | 42 | 6 | 15 | 63 |
|
|
||||||
| [src/music_kraken_cli.py](/src/music_kraken_cli.py) | Python | -88 | -9 | -29 | -126 |
|
|
||||||
| [src/tests/__init__.py](/src/tests/__init__.py) | Python | 0 | 0 | 1 | 1 |
|
|
||||||
| [src/tests/conftest.py](/src/tests/conftest.py) | Python | 3 | 1 | 2 | 6 |
|
|
||||||
| [src/tests/example_data_objects.py](/src/tests/example_data_objects.py) | Python | 36 | 5 | 6 | 47 |
|
|
||||||
| [src/try.py](/src/try.py) | Python | 1 | 0 | 3 | 4 |
|
|
||||||
| [src/try_python.py](/src/try_python.py) | Python | 0 | 19 | 3 | 22 |
|
|
||||||
|
|
||||||
[Summary](results.md) / [Details](details.md) / [Diff Summary](diff.md) / Diff Details
|
|
@ -1,36 +0,0 @@
|
|||||||
"filename", "language", "Python", "comment", "blank", "total"
|
|
||||||
"/home/lars/Projects/music-downloader/src/metal_archives.py", "Python", 3, -2, -2, -1
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/__init__.py", "Python", -6, -18, -8, -32
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/database/data_models.py", "Python", 116, 23, 49, 188
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/database/database.py", "Python", -345, -64, -85, -494
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/database/object_cache.py", "Python", 35, 56, 16, 107
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/database/objects/__init__.py", "Python", -20, 0, -7, -27
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/database/objects/artist.py", "Python", -18, 0, -5, -23
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/database/objects/formatted_text.py", "Python", -48, -57, -16, -121
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/database/objects/metadata.py", "Python", -251, -68, -61, -380
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/database/objects/parents.py", "Python", -40, -8, -19, -67
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/database/objects/song.py", "Python", -323, -64, -85, -472
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/database/objects/source.py", "Python", -116, -38, -41, -195
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/database/old_database.py", "Python", 432, 154, 115, 701
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/database/read.py", "Python", 0, 0, 1, 1
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/database/write.py", "Python", 168, 62, 55, 285
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/objects/__init__.py", "Python", 23, 0, 7, 30
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/objects/album.py", "Python", 15, 6, 5, 26
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/objects/artist.py", "Python", 18, 0, 5, 23
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/objects/collection.py", "Python", 52, 15, 24, 91
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/objects/formatted_text.py", "Python", 53, 57, 20, 130
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/objects/lyrics.py", "Python", 21, 0, 7, 28
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/objects/metadata.py", "Python", 262, 68, 63, 393
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/objects/parents.py", "Python", 22, 15, 12, 49
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/objects/song.py", "Python", 332, 81, 89, 502
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/objects/source.py", "Python", 116, 38, 41, 195
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/objects/target.py", "Python", 22, 7, 7, 36
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/pages/abstract.py", "Python", 3, 0, 0, 3
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/pages/encyclopaedia_metallum.py", "Python", 42, 6, 15, 63
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken_cli.py", "Python", -88, -9, -29, -126
|
|
||||||
"/home/lars/Projects/music-downloader/src/tests/__init__.py", "Python", 0, 0, 1, 1
|
|
||||||
"/home/lars/Projects/music-downloader/src/tests/conftest.py", "Python", 3, 1, 2, 6
|
|
||||||
"/home/lars/Projects/music-downloader/src/tests/example_data_objects.py", "Python", 36, 5, 6, 47
|
|
||||||
"/home/lars/Projects/music-downloader/src/try.py", "Python", 1, 0, 3, 4
|
|
||||||
"/home/lars/Projects/music-downloader/src/try_python.py", "Python", 0, 19, 3, 22
|
|
||||||
"Total", "-", 520, 285, 188, 993
|
|
|
@ -1,30 +0,0 @@
|
|||||||
# Diff Summary
|
|
||||||
|
|
||||||
Date : 2023-02-27 12:22:06
|
|
||||||
|
|
||||||
Directory /home/lars/Projects/music-downloader/src
|
|
||||||
|
|
||||||
Total : 34 files, 520 codes, 285 comments, 188 blanks, all 993 lines
|
|
||||||
|
|
||||||
[Summary](results.md) / [Details](details.md) / Diff Summary / [Diff Details](diff-details.md)
|
|
||||||
|
|
||||||
## Languages
|
|
||||||
| language | files | code | comment | blank | total |
|
|
||||||
| :--- | ---: | ---: | ---: | ---: | ---: |
|
|
||||||
| Python | 34 | 520 | 285 | 188 | 993 |
|
|
||||||
|
|
||||||
## Directories
|
|
||||||
| path | files | code | comment | blank | total |
|
|
||||||
| :--- | ---: | ---: | ---: | ---: | ---: |
|
|
||||||
| . | 34 | 520 | 285 | 188 | 993 |
|
|
||||||
| . (Files) | 4 | -84 | 8 | -25 | -101 |
|
|
||||||
| music_kraken | 27 | 565 | 271 | 204 | 1,040 |
|
|
||||||
| music_kraken (Files) | 1 | -6 | -18 | -8 | -32 |
|
|
||||||
| music_kraken/database | 13 | -410 | -4 | -83 | -497 |
|
|
||||||
| music_kraken/database (Files) | 6 | 406 | 231 | 151 | 788 |
|
|
||||||
| music_kraken/database/objects | 7 | -816 | -235 | -234 | -1,285 |
|
|
||||||
| music_kraken/objects | 11 | 936 | 287 | 280 | 1,503 |
|
|
||||||
| music_kraken/pages | 2 | 45 | 6 | 15 | 66 |
|
|
||||||
| tests | 3 | 39 | 6 | 9 | 54 |
|
|
||||||
|
|
||||||
[Summary](results.md) / [Details](details.md) / Diff Summary / [Diff Details](diff-details.md)
|
|
@ -1,67 +0,0 @@
|
|||||||
Date : 2023-02-27 12:22:06
|
|
||||||
Directory : /home/lars/Projects/music-downloader/src
|
|
||||||
Total : 34 files, 520 codes, 285 comments, 188 blanks, all 993 lines
|
|
||||||
|
|
||||||
Languages
|
|
||||||
+----------+------------+------------+------------+------------+------------+
|
|
||||||
| language | files | code | comment | blank | total |
|
|
||||||
+----------+------------+------------+------------+------------+------------+
|
|
||||||
| Python | 34 | 520 | 285 | 188 | 993 |
|
|
||||||
+----------+------------+------------+------------+------------+------------+
|
|
||||||
|
|
||||||
Directories
|
|
||||||
+------------------------------------------------------------------------------------------+------------+------------+------------+------------+------------+
|
|
||||||
| path | files | code | comment | blank | total |
|
|
||||||
+------------------------------------------------------------------------------------------+------------+------------+------------+------------+------------+
|
|
||||||
| . | 34 | 520 | 285 | 188 | 993 |
|
|
||||||
| . (Files) | 4 | -84 | 8 | -25 | -101 |
|
|
||||||
| music_kraken | 27 | 565 | 271 | 204 | 1,040 |
|
|
||||||
| music_kraken (Files) | 1 | -6 | -18 | -8 | -32 |
|
|
||||||
| music_kraken/database | 13 | -410 | -4 | -83 | -497 |
|
|
||||||
| music_kraken/database (Files) | 6 | 406 | 231 | 151 | 788 |
|
|
||||||
| music_kraken/database/objects | 7 | -816 | -235 | -234 | -1,285 |
|
|
||||||
| music_kraken/objects | 11 | 936 | 287 | 280 | 1,503 |
|
|
||||||
| music_kraken/pages | 2 | 45 | 6 | 15 | 66 |
|
|
||||||
| tests | 3 | 39 | 6 | 9 | 54 |
|
|
||||||
+------------------------------------------------------------------------------------------+------------+------------+------------+------------+------------+
|
|
||||||
|
|
||||||
Files
|
|
||||||
+------------------------------------------------------------------------------------------+----------+------------+------------+------------+------------+
|
|
||||||
| filename | language | code | comment | blank | total |
|
|
||||||
+------------------------------------------------------------------------------------------+----------+------------+------------+------------+------------+
|
|
||||||
| /home/lars/Projects/music-downloader/src/metal_archives.py | Python | 3 | -2 | -2 | -1 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/__init__.py | Python | -6 | -18 | -8 | -32 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/database/data_models.py | Python | 116 | 23 | 49 | 188 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/database/database.py | Python | -345 | -64 | -85 | -494 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/database/object_cache.py | Python | 35 | 56 | 16 | 107 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/database/objects/__init__.py | Python | -20 | 0 | -7 | -27 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/database/objects/artist.py | Python | -18 | 0 | -5 | -23 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/database/objects/formatted_text.py | Python | -48 | -57 | -16 | -121 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/database/objects/metadata.py | Python | -251 | -68 | -61 | -380 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/database/objects/parents.py | Python | -40 | -8 | -19 | -67 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/database/objects/song.py | Python | -323 | -64 | -85 | -472 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/database/objects/source.py | Python | -116 | -38 | -41 | -195 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/database/old_database.py | Python | 432 | 154 | 115 | 701 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/database/read.py | Python | 0 | 0 | 1 | 1 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/database/write.py | Python | 168 | 62 | 55 | 285 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/objects/__init__.py | Python | 23 | 0 | 7 | 30 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/objects/album.py | Python | 15 | 6 | 5 | 26 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/objects/artist.py | Python | 18 | 0 | 5 | 23 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/objects/collection.py | Python | 52 | 15 | 24 | 91 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/objects/formatted_text.py | Python | 53 | 57 | 20 | 130 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/objects/lyrics.py | Python | 21 | 0 | 7 | 28 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/objects/metadata.py | Python | 262 | 68 | 63 | 393 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/objects/parents.py | Python | 22 | 15 | 12 | 49 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/objects/song.py | Python | 332 | 81 | 89 | 502 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/objects/source.py | Python | 116 | 38 | 41 | 195 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/objects/target.py | Python | 22 | 7 | 7 | 36 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/pages/abstract.py | Python | 3 | 0 | 0 | 3 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/pages/encyclopaedia_metallum.py | Python | 42 | 6 | 15 | 63 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken_cli.py | Python | -88 | -9 | -29 | -126 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/tests/__init__.py | Python | 0 | 0 | 1 | 1 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/tests/conftest.py | Python | 3 | 1 | 2 | 6 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/tests/example_data_objects.py | Python | 36 | 5 | 6 | 47 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/try.py | Python | 1 | 0 | 3 | 4 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/try_python.py | Python | 0 | 19 | 3 | 22 |
|
|
||||||
| Total | | 520 | 285 | 188 | 993 |
|
|
||||||
+------------------------------------------------------------------------------------------+----------+------------+------------+------------+------------+
|
|
@ -1,65 +0,0 @@
|
|||||||
"filename", "language", "Python", "SQLite", "Database", "comment", "blank", "total"
|
|
||||||
"/home/lars/Projects/music-downloader/src/__init__.py", "Python", 0, 0, 0, 0, 1, 1
|
|
||||||
"/home/lars/Projects/music-downloader/src/create_custom_objects.py", "Python", 80, 0, 0, 3, 18, 101
|
|
||||||
"/home/lars/Projects/music-downloader/src/metal_archives.py", "Python", 48, 0, 0, 4, 15, 67
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/__init__.py", "Python", 57, 0, 0, 8, 25, 90
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/__main__.py", "Python", 3, 0, 0, 2, 3, 8
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/database/__init__.py", "Python", 18, 0, 0, 0, 5, 23
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/database/data_models.py", "Python", 116, 0, 0, 23, 49, 188
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/database/database.py", "Python", 84, 0, 0, 48, 26, 158
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/database/object_cache.py", "Python", 35, 0, 0, 56, 16, 107
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/database/old_database.py", "Python", 432, 0, 0, 154, 115, 701
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/database/read.py", "Python", 0, 0, 0, 0, 1, 1
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/database/temp_database.py", "Python", 12, 0, 0, 0, 8, 20
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/database/write.py", "Python", 168, 0, 0, 62, 55, 285
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/__init__.py", "Python", 0, 0, 0, 0, 3, 3
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/fetch_audio.py", "Python", 75, 0, 0, 12, 20, 107
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/fetch_source.py", "Python", 54, 0, 0, 1, 16, 71
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/metadata/__init__.py", "Python", 6, 0, 0, 0, 2, 8
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/metadata/metadata_fetch.py", "Python", 257, 0, 0, 24, 65, 346
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/metadata/metadata_search.py", "Python", 253, 0, 0, 40, 72, 365
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/metadata/sources/__init__.py", "Python", 3, 0, 0, 0, 2, 5
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/metadata/sources/musicbrainz.py", "Python", 42, 0, 0, 6, 12, 60
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/sources/__init__.py", "Python", 0, 0, 0, 0, 1, 1
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/sources/genius.py", "Python", 115, 0, 0, 16, 42, 173
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/sources/local_files.py", "Python", 40, 0, 0, 0, 18, 58
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/sources/musify.py", "Python", 136, 0, 0, 9, 37, 182
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/sources/source.py", "Python", 11, 0, 0, 5, 8, 24
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/sources/youtube.py", "Python", 71, 0, 0, 4, 24, 99
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/objects/__init__.py", "Python", 23, 0, 0, 0, 7, 30
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/objects/album.py", "Python", 15, 0, 0, 6, 5, 26
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/objects/artist.py", "Python", 18, 0, 0, 0, 5, 23
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/objects/collection.py", "Python", 52, 0, 0, 15, 24, 91
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/objects/formatted_text.py", "Python", 53, 0, 0, 57, 20, 130
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/objects/lyrics.py", "Python", 21, 0, 0, 0, 7, 28
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/objects/metadata.py", "Python", 262, 0, 0, 68, 63, 393
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/objects/parents.py", "Python", 22, 0, 0, 15, 12, 49
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/objects/song.py", "Python", 332, 0, 0, 81, 89, 502
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/objects/source.py", "Python", 116, 0, 0, 38, 41, 195
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/objects/target.py", "Python", 22, 0, 0, 7, 7, 36
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/pages/__init__.py", "Python", 7, 0, 0, 0, 5, 12
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/pages/abstract.py", "Python", 73, 0, 0, 68, 27, 168
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/pages/encyclopaedia_metallum.py", "Python", 341, 0, 0, 66, 91, 498
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/pages/youtube.py", "Python", 25, 0, 0, 16, 6, 47
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/static_files/new_db.sql", "SQLite", 0, 72, 0, 0, 10, 82
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/static_files/temp_database_structure.sql", "SQLite", 0, 135, 0, 0, 10, 145
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/tagging/__init__.py", "Python", 8, 0, 0, 0, 2, 10
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/tagging/id3.py", "Python", 51, 0, 0, 4, 20, 75
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/target/__init__.py", "Python", 4, 0, 0, 0, 2, 6
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/target/set_target.py", "Python", 37, 0, 0, 7, 18, 62
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/utils/__init__.py", "Python", 1, 0, 0, 1, 1, 3
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/utils/functions.py", "Python", 3, 0, 0, 0, 1, 4
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/utils/object_handeling.py", "Python", 19, 0, 0, 0, 6, 25
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/utils/phonetic_compares.py", "Python", 39, 0, 0, 2, 17, 58
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/utils/shared.py", "Python", 62, 0, 0, 3, 10, 75
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/utils/string_processing.py", "Python", 2, 0, 0, 5, 2, 9
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken_cli.py", "Python", 3, 0, 0, 0, 3, 6
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken_gtk.py", "Python", 3, 0, 0, 0, 2, 5
|
|
||||||
"/home/lars/Projects/music-downloader/src/test.db", "Database", 0, 0, 91, 0, 1, 92
|
|
||||||
"/home/lars/Projects/music-downloader/src/tests/__init__.py", "Python", 0, 0, 0, 0, 1, 1
|
|
||||||
"/home/lars/Projects/music-downloader/src/tests/conftest.py", "Python", 3, 0, 0, 1, 2, 6
|
|
||||||
"/home/lars/Projects/music-downloader/src/tests/example_data_objects.py", "Python", 36, 0, 0, 5, 6, 47
|
|
||||||
"/home/lars/Projects/music-downloader/src/try-programming-interface.py", "Python", 14, 0, 0, 98, 22, 134
|
|
||||||
"/home/lars/Projects/music-downloader/src/try.py", "Python", 1, 0, 0, 0, 3, 4
|
|
||||||
"/home/lars/Projects/music-downloader/src/try_python.py", "Python", 13, 0, 0, 20, 9, 42
|
|
||||||
"Total", "-", 3797, 207, 91, 1060, 1216, 6371
|
|
|
File diff suppressed because one or more lines are too long
@ -1,40 +0,0 @@
|
|||||||
# Summary
|
|
||||||
|
|
||||||
Date : 2023-02-27 12:22:06
|
|
||||||
|
|
||||||
Directory /home/lars/Projects/music-downloader/src
|
|
||||||
|
|
||||||
Total : 63 files, 4095 codes, 1060 comments, 1216 blanks, all 6371 lines
|
|
||||||
|
|
||||||
Summary / [Details](details.md) / [Diff Summary](diff.md) / [Diff Details](diff-details.md)
|
|
||||||
|
|
||||||
## Languages
|
|
||||||
| language | files | code | comment | blank | total |
|
|
||||||
| :--- | ---: | ---: | ---: | ---: | ---: |
|
|
||||||
| Python | 60 | 3,797 | 1,060 | 1,195 | 6,052 |
|
|
||||||
| SQLite | 2 | 207 | 0 | 20 | 227 |
|
|
||||||
| Database | 1 | 91 | 0 | 1 | 92 |
|
|
||||||
|
|
||||||
## Directories
|
|
||||||
| path | files | code | comment | blank | total |
|
|
||||||
| :--- | ---: | ---: | ---: | ---: | ---: |
|
|
||||||
| . | 63 | 4,095 | 1,060 | 1,216 | 6,371 |
|
|
||||||
| . (Files) | 9 | 253 | 125 | 74 | 452 |
|
|
||||||
| music_kraken | 51 | 3,803 | 929 | 1,133 | 5,865 |
|
|
||||||
| music_kraken (Files) | 2 | 60 | 10 | 28 | 98 |
|
|
||||||
| music_kraken/database | 8 | 865 | 343 | 275 | 1,483 |
|
|
||||||
| music_kraken/not_used_anymore | 14 | 1,063 | 117 | 322 | 1,502 |
|
|
||||||
| music_kraken/not_used_anymore (Files) | 3 | 129 | 13 | 39 | 181 |
|
|
||||||
| music_kraken/not_used_anymore/metadata | 5 | 561 | 70 | 153 | 784 |
|
|
||||||
| music_kraken/not_used_anymore/metadata (Files) | 3 | 516 | 64 | 139 | 719 |
|
|
||||||
| music_kraken/not_used_anymore/metadata/sources | 2 | 45 | 6 | 14 | 65 |
|
|
||||||
| music_kraken/not_used_anymore/sources | 6 | 373 | 34 | 130 | 537 |
|
|
||||||
| music_kraken/objects | 11 | 936 | 287 | 280 | 1,503 |
|
|
||||||
| music_kraken/pages | 4 | 446 | 150 | 129 | 725 |
|
|
||||||
| music_kraken/static_files | 2 | 207 | 0 | 20 | 227 |
|
|
||||||
| music_kraken/tagging | 2 | 59 | 4 | 22 | 85 |
|
|
||||||
| music_kraken/target | 2 | 41 | 7 | 20 | 68 |
|
|
||||||
| music_kraken/utils | 6 | 126 | 11 | 37 | 174 |
|
|
||||||
| tests | 3 | 39 | 6 | 9 | 54 |
|
|
||||||
|
|
||||||
Summary / [Details](details.md) / [Diff Summary](diff.md) / [Diff Details](diff-details.md)
|
|
@ -1,106 +0,0 @@
|
|||||||
Date : 2023-02-27 12:22:06
|
|
||||||
Directory : /home/lars/Projects/music-downloader/src
|
|
||||||
Total : 63 files, 4095 codes, 1060 comments, 1216 blanks, all 6371 lines
|
|
||||||
|
|
||||||
Languages
|
|
||||||
+----------+------------+------------+------------+------------+------------+
|
|
||||||
| language | files | code | comment | blank | total |
|
|
||||||
+----------+------------+------------+------------+------------+------------+
|
|
||||||
| Python | 60 | 3,797 | 1,060 | 1,195 | 6,052 |
|
|
||||||
| SQLite | 2 | 207 | 0 | 20 | 227 |
|
|
||||||
| Database | 1 | 91 | 0 | 1 | 92 |
|
|
||||||
+----------+------------+------------+------------+------------+------------+
|
|
||||||
|
|
||||||
Directories
|
|
||||||
+--------------------------------------------------------------------------------------------------------+------------+------------+------------+------------+------------+
|
|
||||||
| path | files | code | comment | blank | total |
|
|
||||||
+--------------------------------------------------------------------------------------------------------+------------+------------+------------+------------+------------+
|
|
||||||
| . | 63 | 4,095 | 1,060 | 1,216 | 6,371 |
|
|
||||||
| . (Files) | 9 | 253 | 125 | 74 | 452 |
|
|
||||||
| music_kraken | 51 | 3,803 | 929 | 1,133 | 5,865 |
|
|
||||||
| music_kraken (Files) | 2 | 60 | 10 | 28 | 98 |
|
|
||||||
| music_kraken/database | 8 | 865 | 343 | 275 | 1,483 |
|
|
||||||
| music_kraken/not_used_anymore | 14 | 1,063 | 117 | 322 | 1,502 |
|
|
||||||
| music_kraken/not_used_anymore (Files) | 3 | 129 | 13 | 39 | 181 |
|
|
||||||
| music_kraken/not_used_anymore/metadata | 5 | 561 | 70 | 153 | 784 |
|
|
||||||
| music_kraken/not_used_anymore/metadata (Files) | 3 | 516 | 64 | 139 | 719 |
|
|
||||||
| music_kraken/not_used_anymore/metadata/sources | 2 | 45 | 6 | 14 | 65 |
|
|
||||||
| music_kraken/not_used_anymore/sources | 6 | 373 | 34 | 130 | 537 |
|
|
||||||
| music_kraken/objects | 11 | 936 | 287 | 280 | 1,503 |
|
|
||||||
| music_kraken/pages | 4 | 446 | 150 | 129 | 725 |
|
|
||||||
| music_kraken/static_files | 2 | 207 | 0 | 20 | 227 |
|
|
||||||
| music_kraken/tagging | 2 | 59 | 4 | 22 | 85 |
|
|
||||||
| music_kraken/target | 2 | 41 | 7 | 20 | 68 |
|
|
||||||
| music_kraken/utils | 6 | 126 | 11 | 37 | 174 |
|
|
||||||
| tests | 3 | 39 | 6 | 9 | 54 |
|
|
||||||
+--------------------------------------------------------------------------------------------------------+------------+------------+------------+------------+------------+
|
|
||||||
|
|
||||||
Files
|
|
||||||
+--------------------------------------------------------------------------------------------------------+----------+------------+------------+------------+------------+
|
|
||||||
| filename | language | code | comment | blank | total |
|
|
||||||
+--------------------------------------------------------------------------------------------------------+----------+------------+------------+------------+------------+
|
|
||||||
| /home/lars/Projects/music-downloader/src/__init__.py | Python | 0 | 0 | 1 | 1 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/create_custom_objects.py | Python | 80 | 3 | 18 | 101 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/metal_archives.py | Python | 48 | 4 | 15 | 67 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/__init__.py | Python | 57 | 8 | 25 | 90 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/__main__.py | Python | 3 | 2 | 3 | 8 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/database/__init__.py | Python | 18 | 0 | 5 | 23 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/database/data_models.py | Python | 116 | 23 | 49 | 188 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/database/database.py | Python | 84 | 48 | 26 | 158 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/database/object_cache.py | Python | 35 | 56 | 16 | 107 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/database/old_database.py | Python | 432 | 154 | 115 | 701 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/database/read.py | Python | 0 | 0 | 1 | 1 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/database/temp_database.py | Python | 12 | 0 | 8 | 20 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/database/write.py | Python | 168 | 62 | 55 | 285 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/__init__.py | Python | 0 | 0 | 3 | 3 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/fetch_audio.py | Python | 75 | 12 | 20 | 107 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/fetch_source.py | Python | 54 | 1 | 16 | 71 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/metadata/__init__.py | Python | 6 | 0 | 2 | 8 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/metadata/metadata_fetch.py | Python | 257 | 24 | 65 | 346 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/metadata/metadata_search.py | Python | 253 | 40 | 72 | 365 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/metadata/sources/__init__.py | Python | 3 | 0 | 2 | 5 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/metadata/sources/musicbrainz.py | Python | 42 | 6 | 12 | 60 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/sources/__init__.py | Python | 0 | 0 | 1 | 1 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/sources/genius.py | Python | 115 | 16 | 42 | 173 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/sources/local_files.py | Python | 40 | 0 | 18 | 58 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/sources/musify.py | Python | 136 | 9 | 37 | 182 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/sources/source.py | Python | 11 | 5 | 8 | 24 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/sources/youtube.py | Python | 71 | 4 | 24 | 99 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/objects/__init__.py | Python | 23 | 0 | 7 | 30 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/objects/album.py | Python | 15 | 6 | 5 | 26 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/objects/artist.py | Python | 18 | 0 | 5 | 23 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/objects/collection.py | Python | 52 | 15 | 24 | 91 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/objects/formatted_text.py | Python | 53 | 57 | 20 | 130 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/objects/lyrics.py | Python | 21 | 0 | 7 | 28 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/objects/metadata.py | Python | 262 | 68 | 63 | 393 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/objects/parents.py | Python | 22 | 15 | 12 | 49 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/objects/song.py | Python | 332 | 81 | 89 | 502 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/objects/source.py | Python | 116 | 38 | 41 | 195 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/objects/target.py | Python | 22 | 7 | 7 | 36 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/pages/__init__.py | Python | 7 | 0 | 5 | 12 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/pages/abstract.py | Python | 73 | 68 | 27 | 168 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/pages/encyclopaedia_metallum.py | Python | 341 | 66 | 91 | 498 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/pages/youtube.py | Python | 25 | 16 | 6 | 47 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/static_files/new_db.sql | SQLite | 72 | 0 | 10 | 82 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/static_files/temp_database_structure.sql | SQLite | 135 | 0 | 10 | 145 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/tagging/__init__.py | Python | 8 | 0 | 2 | 10 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/tagging/id3.py | Python | 51 | 4 | 20 | 75 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/target/__init__.py | Python | 4 | 0 | 2 | 6 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/target/set_target.py | Python | 37 | 7 | 18 | 62 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/utils/__init__.py | Python | 1 | 1 | 1 | 3 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/utils/functions.py | Python | 3 | 0 | 1 | 4 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/utils/object_handeling.py | Python | 19 | 0 | 6 | 25 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/utils/phonetic_compares.py | Python | 39 | 2 | 17 | 58 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/utils/shared.py | Python | 62 | 3 | 10 | 75 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/utils/string_processing.py | Python | 2 | 5 | 2 | 9 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken_cli.py | Python | 3 | 0 | 3 | 6 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken_gtk.py | Python | 3 | 0 | 2 | 5 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/test.db | Database | 91 | 0 | 1 | 92 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/tests/__init__.py | Python | 0 | 0 | 1 | 1 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/tests/conftest.py | Python | 3 | 1 | 2 | 6 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/tests/example_data_objects.py | Python | 36 | 5 | 6 | 47 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/try-programming-interface.py | Python | 14 | 98 | 22 | 134 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/try.py | Python | 1 | 0 | 3 | 4 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/try_python.py | Python | 13 | 20 | 9 | 42 |
|
|
||||||
| Total | | 4,095 | 1,060 | 1,216 | 6,371 |
|
|
||||||
+--------------------------------------------------------------------------------------------------------+----------+------------+------------+------------+------------+
|
|
@ -1,78 +0,0 @@
|
|||||||
# Details
|
|
||||||
|
|
||||||
Date : 2023-02-28 10:10:37
|
|
||||||
|
|
||||||
Directory /home/lars/Projects/music-downloader/src
|
|
||||||
|
|
||||||
Total : 63 files, 4150 codes, 1060 comments, 1228 blanks, all 6438 lines
|
|
||||||
|
|
||||||
[Summary](results.md) / Details / [Diff Summary](diff.md) / [Diff Details](diff-details.md)
|
|
||||||
|
|
||||||
## Files
|
|
||||||
| filename | language | code | comment | blank | total |
|
|
||||||
| :--- | :--- | ---: | ---: | ---: | ---: |
|
|
||||||
| [src/__init__.py](/src/__init__.py) | Python | 0 | 0 | 1 | 1 |
|
|
||||||
| [src/create_custom_objects.py](/src/create_custom_objects.py) | Python | 80 | 3 | 18 | 101 |
|
|
||||||
| [src/metal_archives.py](/src/metal_archives.py) | Python | 48 | 4 | 15 | 67 |
|
|
||||||
| [src/music_kraken/__init__.py](/src/music_kraken/__init__.py) | Python | 57 | 8 | 25 | 90 |
|
|
||||||
| [src/music_kraken/__main__.py](/src/music_kraken/__main__.py) | Python | 3 | 2 | 3 | 8 |
|
|
||||||
| [src/music_kraken/database/__init__.py](/src/music_kraken/database/__init__.py) | Python | 18 | 0 | 5 | 23 |
|
|
||||||
| [src/music_kraken/database/data_models.py](/src/music_kraken/database/data_models.py) | Python | 123 | 23 | 52 | 198 |
|
|
||||||
| [src/music_kraken/database/database.py](/src/music_kraken/database/database.py) | Python | 84 | 48 | 26 | 158 |
|
|
||||||
| [src/music_kraken/database/object_cache.py](/src/music_kraken/database/object_cache.py) | Python | 35 | 56 | 16 | 107 |
|
|
||||||
| [src/music_kraken/database/old_database.py](/src/music_kraken/database/old_database.py) | Python | 432 | 154 | 115 | 701 |
|
|
||||||
| [src/music_kraken/database/read.py](/src/music_kraken/database/read.py) | Python | 0 | 0 | 1 | 1 |
|
|
||||||
| [src/music_kraken/database/temp_database.py](/src/music_kraken/database/temp_database.py) | Python | 12 | 0 | 8 | 20 |
|
|
||||||
| [src/music_kraken/database/write.py](/src/music_kraken/database/write.py) | Python | 210 | 62 | 63 | 335 |
|
|
||||||
| [src/music_kraken/not_used_anymore/__init__.py](/src/music_kraken/not_used_anymore/__init__.py) | Python | 0 | 0 | 3 | 3 |
|
|
||||||
| [src/music_kraken/not_used_anymore/fetch_audio.py](/src/music_kraken/not_used_anymore/fetch_audio.py) | Python | 75 | 12 | 20 | 107 |
|
|
||||||
| [src/music_kraken/not_used_anymore/fetch_source.py](/src/music_kraken/not_used_anymore/fetch_source.py) | Python | 54 | 1 | 16 | 71 |
|
|
||||||
| [src/music_kraken/not_used_anymore/metadata/__init__.py](/src/music_kraken/not_used_anymore/metadata/__init__.py) | Python | 6 | 0 | 2 | 8 |
|
|
||||||
| [src/music_kraken/not_used_anymore/metadata/metadata_fetch.py](/src/music_kraken/not_used_anymore/metadata/metadata_fetch.py) | Python | 257 | 24 | 65 | 346 |
|
|
||||||
| [src/music_kraken/not_used_anymore/metadata/metadata_search.py](/src/music_kraken/not_used_anymore/metadata/metadata_search.py) | Python | 253 | 40 | 72 | 365 |
|
|
||||||
| [src/music_kraken/not_used_anymore/metadata/sources/__init__.py](/src/music_kraken/not_used_anymore/metadata/sources/__init__.py) | Python | 3 | 0 | 2 | 5 |
|
|
||||||
| [src/music_kraken/not_used_anymore/metadata/sources/musicbrainz.py](/src/music_kraken/not_used_anymore/metadata/sources/musicbrainz.py) | Python | 42 | 6 | 12 | 60 |
|
|
||||||
| [src/music_kraken/not_used_anymore/sources/__init__.py](/src/music_kraken/not_used_anymore/sources/__init__.py) | Python | 0 | 0 | 1 | 1 |
|
|
||||||
| [src/music_kraken/not_used_anymore/sources/genius.py](/src/music_kraken/not_used_anymore/sources/genius.py) | Python | 115 | 16 | 42 | 173 |
|
|
||||||
| [src/music_kraken/not_used_anymore/sources/local_files.py](/src/music_kraken/not_used_anymore/sources/local_files.py) | Python | 40 | 0 | 18 | 58 |
|
|
||||||
| [src/music_kraken/not_used_anymore/sources/musify.py](/src/music_kraken/not_used_anymore/sources/musify.py) | Python | 136 | 9 | 37 | 182 |
|
|
||||||
| [src/music_kraken/not_used_anymore/sources/source.py](/src/music_kraken/not_used_anymore/sources/source.py) | Python | 11 | 5 | 8 | 24 |
|
|
||||||
| [src/music_kraken/not_used_anymore/sources/youtube.py](/src/music_kraken/not_used_anymore/sources/youtube.py) | Python | 71 | 4 | 24 | 99 |
|
|
||||||
| [src/music_kraken/objects/__init__.py](/src/music_kraken/objects/__init__.py) | Python | 24 | 0 | 7 | 31 |
|
|
||||||
| [src/music_kraken/objects/album.py](/src/music_kraken/objects/album.py) | Python | 15 | 6 | 5 | 26 |
|
|
||||||
| [src/music_kraken/objects/artist.py](/src/music_kraken/objects/artist.py) | Python | 18 | 0 | 5 | 23 |
|
|
||||||
| [src/music_kraken/objects/collection.py](/src/music_kraken/objects/collection.py) | Python | 52 | 15 | 24 | 91 |
|
|
||||||
| [src/music_kraken/objects/formatted_text.py](/src/music_kraken/objects/formatted_text.py) | Python | 53 | 57 | 20 | 130 |
|
|
||||||
| [src/music_kraken/objects/lyrics.py](/src/music_kraken/objects/lyrics.py) | Python | 21 | 0 | 7 | 28 |
|
|
||||||
| [src/music_kraken/objects/metadata.py](/src/music_kraken/objects/metadata.py) | Python | 262 | 68 | 63 | 393 |
|
|
||||||
| [src/music_kraken/objects/parents.py](/src/music_kraken/objects/parents.py) | Python | 22 | 15 | 12 | 49 |
|
|
||||||
| [src/music_kraken/objects/song.py](/src/music_kraken/objects/song.py) | Python | 337 | 81 | 90 | 508 |
|
|
||||||
| [src/music_kraken/objects/source.py](/src/music_kraken/objects/source.py) | Python | 116 | 38 | 41 | 195 |
|
|
||||||
| [src/music_kraken/objects/target.py](/src/music_kraken/objects/target.py) | Python | 22 | 7 | 7 | 36 |
|
|
||||||
| [src/music_kraken/pages/__init__.py](/src/music_kraken/pages/__init__.py) | Python | 7 | 0 | 5 | 12 |
|
|
||||||
| [src/music_kraken/pages/abstract.py](/src/music_kraken/pages/abstract.py) | Python | 73 | 68 | 27 | 168 |
|
|
||||||
| [src/music_kraken/pages/encyclopaedia_metallum.py](/src/music_kraken/pages/encyclopaedia_metallum.py) | Python | 341 | 66 | 91 | 498 |
|
|
||||||
| [src/music_kraken/pages/youtube.py](/src/music_kraken/pages/youtube.py) | Python | 25 | 16 | 6 | 47 |
|
|
||||||
| [src/music_kraken/static_files/new_db.sql](/src/music_kraken/static_files/new_db.sql) | SQLite | 72 | 0 | 10 | 82 |
|
|
||||||
| [src/music_kraken/static_files/temp_database_structure.sql](/src/music_kraken/static_files/temp_database_structure.sql) | SQLite | 135 | 0 | 10 | 145 |
|
|
||||||
| [src/music_kraken/tagging/__init__.py](/src/music_kraken/tagging/__init__.py) | Python | 8 | 0 | 2 | 10 |
|
|
||||||
| [src/music_kraken/tagging/id3.py](/src/music_kraken/tagging/id3.py) | Python | 51 | 4 | 20 | 75 |
|
|
||||||
| [src/music_kraken/target/__init__.py](/src/music_kraken/target/__init__.py) | Python | 4 | 0 | 2 | 6 |
|
|
||||||
| [src/music_kraken/target/set_target.py](/src/music_kraken/target/set_target.py) | Python | 37 | 7 | 18 | 62 |
|
|
||||||
| [src/music_kraken/utils/__init__.py](/src/music_kraken/utils/__init__.py) | Python | 1 | 1 | 1 | 3 |
|
|
||||||
| [src/music_kraken/utils/functions.py](/src/music_kraken/utils/functions.py) | Python | 3 | 0 | 1 | 4 |
|
|
||||||
| [src/music_kraken/utils/object_handeling.py](/src/music_kraken/utils/object_handeling.py) | Python | 19 | 0 | 6 | 25 |
|
|
||||||
| [src/music_kraken/utils/phonetic_compares.py](/src/music_kraken/utils/phonetic_compares.py) | Python | 39 | 2 | 17 | 58 |
|
|
||||||
| [src/music_kraken/utils/shared.py](/src/music_kraken/utils/shared.py) | Python | 62 | 3 | 10 | 75 |
|
|
||||||
| [src/music_kraken/utils/string_processing.py](/src/music_kraken/utils/string_processing.py) | Python | 2 | 5 | 2 | 9 |
|
|
||||||
| [src/music_kraken_cli.py](/src/music_kraken_cli.py) | Python | 3 | 0 | 3 | 6 |
|
|
||||||
| [src/music_kraken_gtk.py](/src/music_kraken_gtk.py) | Python | 3 | 0 | 2 | 5 |
|
|
||||||
| [src/test.db](/src/test.db) | Database | 91 | 0 | 1 | 92 |
|
|
||||||
| [src/tests/__init__.py](/src/tests/__init__.py) | Python | 0 | 0 | 1 | 1 |
|
|
||||||
| [src/tests/conftest.py](/src/tests/conftest.py) | Python | 3 | 1 | 2 | 6 |
|
|
||||||
| [src/tests/example_data_objects.py](/src/tests/example_data_objects.py) | Python | 36 | 5 | 6 | 47 |
|
|
||||||
| [src/try-programming-interface.py](/src/try-programming-interface.py) | Python | 14 | 98 | 22 | 134 |
|
|
||||||
| [src/try.py](/src/try.py) | Python | 1 | 0 | 3 | 4 |
|
|
||||||
| [src/try_python.py](/src/try_python.py) | Python | 13 | 20 | 9 | 42 |
|
|
||||||
|
|
||||||
[Summary](results.md) / Details / [Diff Summary](diff.md) / [Diff Details](diff-details.md)
|
|
@ -1,19 +0,0 @@
|
|||||||
# Diff Details
|
|
||||||
|
|
||||||
Date : 2023-02-28 10:10:37
|
|
||||||
|
|
||||||
Directory /home/lars/Projects/music-downloader/src
|
|
||||||
|
|
||||||
Total : 4 files, 55 codes, 0 comments, 12 blanks, all 67 lines
|
|
||||||
|
|
||||||
[Summary](results.md) / [Details](details.md) / [Diff Summary](diff.md) / Diff Details
|
|
||||||
|
|
||||||
## Files
|
|
||||||
| filename | language | code | comment | blank | total |
|
|
||||||
| :--- | :--- | ---: | ---: | ---: | ---: |
|
|
||||||
| [src/music_kraken/database/data_models.py](/src/music_kraken/database/data_models.py) | Python | 7 | 0 | 3 | 10 |
|
|
||||||
| [src/music_kraken/database/write.py](/src/music_kraken/database/write.py) | Python | 42 | 0 | 8 | 50 |
|
|
||||||
| [src/music_kraken/objects/__init__.py](/src/music_kraken/objects/__init__.py) | Python | 1 | 0 | 0 | 1 |
|
|
||||||
| [src/music_kraken/objects/song.py](/src/music_kraken/objects/song.py) | Python | 5 | 0 | 1 | 6 |
|
|
||||||
|
|
||||||
[Summary](results.md) / [Details](details.md) / [Diff Summary](diff.md) / Diff Details
|
|
@ -1,6 +0,0 @@
|
|||||||
"filename", "language", "Python", "comment", "blank", "total"
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/database/data_models.py", "Python", 7, 0, 3, 10
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/database/write.py", "Python", 42, 0, 8, 50
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/objects/__init__.py", "Python", 1, 0, 0, 1
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/objects/song.py", "Python", 5, 0, 1, 6
|
|
||||||
"Total", "-", 55, 0, 12, 67
|
|
|
@ -1,24 +0,0 @@
|
|||||||
# Diff Summary
|
|
||||||
|
|
||||||
Date : 2023-02-28 10:10:37
|
|
||||||
|
|
||||||
Directory /home/lars/Projects/music-downloader/src
|
|
||||||
|
|
||||||
Total : 4 files, 55 codes, 0 comments, 12 blanks, all 67 lines
|
|
||||||
|
|
||||||
[Summary](results.md) / [Details](details.md) / Diff Summary / [Diff Details](diff-details.md)
|
|
||||||
|
|
||||||
## Languages
|
|
||||||
| language | files | code | comment | blank | total |
|
|
||||||
| :--- | ---: | ---: | ---: | ---: | ---: |
|
|
||||||
| Python | 4 | 55 | 0 | 12 | 67 |
|
|
||||||
|
|
||||||
## Directories
|
|
||||||
| path | files | code | comment | blank | total |
|
|
||||||
| :--- | ---: | ---: | ---: | ---: | ---: |
|
|
||||||
| . | 4 | 55 | 0 | 12 | 67 |
|
|
||||||
| music_kraken | 4 | 55 | 0 | 12 | 67 |
|
|
||||||
| music_kraken/database | 2 | 49 | 0 | 11 | 60 |
|
|
||||||
| music_kraken/objects | 2 | 6 | 0 | 1 | 7 |
|
|
||||||
|
|
||||||
[Summary](results.md) / [Details](details.md) / Diff Summary / [Diff Details](diff-details.md)
|
|
@ -1,31 +0,0 @@
|
|||||||
Date : 2023-02-28 10:10:37
|
|
||||||
Directory : /home/lars/Projects/music-downloader/src
|
|
||||||
Total : 4 files, 55 codes, 0 comments, 12 blanks, all 67 lines
|
|
||||||
|
|
||||||
Languages
|
|
||||||
+----------+------------+------------+------------+------------+------------+
|
|
||||||
| language | files | code | comment | blank | total |
|
|
||||||
+----------+------------+------------+------------+------------+------------+
|
|
||||||
| Python | 4 | 55 | 0 | 12 | 67 |
|
|
||||||
+----------+------------+------------+------------+------------+------------+
|
|
||||||
|
|
||||||
Directories
|
|
||||||
+-------------------------------------------------------------------------------+------------+------------+------------+------------+------------+
|
|
||||||
| path | files | code | comment | blank | total |
|
|
||||||
+-------------------------------------------------------------------------------+------------+------------+------------+------------+------------+
|
|
||||||
| . | 4 | 55 | 0 | 12 | 67 |
|
|
||||||
| music_kraken | 4 | 55 | 0 | 12 | 67 |
|
|
||||||
| music_kraken/database | 2 | 49 | 0 | 11 | 60 |
|
|
||||||
| music_kraken/objects | 2 | 6 | 0 | 1 | 7 |
|
|
||||||
+-------------------------------------------------------------------------------+------------+------------+------------+------------+------------+
|
|
||||||
|
|
||||||
Files
|
|
||||||
+-------------------------------------------------------------------------------+----------+------------+------------+------------+------------+
|
|
||||||
| filename | language | code | comment | blank | total |
|
|
||||||
+-------------------------------------------------------------------------------+----------+------------+------------+------------+------------+
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/database/data_models.py | Python | 7 | 0 | 3 | 10 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/database/write.py | Python | 42 | 0 | 8 | 50 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/objects/__init__.py | Python | 1 | 0 | 0 | 1 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/objects/song.py | Python | 5 | 0 | 1 | 6 |
|
|
||||||
| Total | | 55 | 0 | 12 | 67 |
|
|
||||||
+-------------------------------------------------------------------------------+----------+------------+------------+------------+------------+
|
|
@ -1,65 +0,0 @@
|
|||||||
"filename", "language", "Python", "Database", "SQLite", "comment", "blank", "total"
|
|
||||||
"/home/lars/Projects/music-downloader/src/__init__.py", "Python", 0, 0, 0, 0, 1, 1
|
|
||||||
"/home/lars/Projects/music-downloader/src/create_custom_objects.py", "Python", 80, 0, 0, 3, 18, 101
|
|
||||||
"/home/lars/Projects/music-downloader/src/metal_archives.py", "Python", 48, 0, 0, 4, 15, 67
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/__init__.py", "Python", 57, 0, 0, 8, 25, 90
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/__main__.py", "Python", 3, 0, 0, 2, 3, 8
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/database/__init__.py", "Python", 18, 0, 0, 0, 5, 23
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/database/data_models.py", "Python", 123, 0, 0, 23, 52, 198
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/database/database.py", "Python", 84, 0, 0, 48, 26, 158
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/database/object_cache.py", "Python", 35, 0, 0, 56, 16, 107
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/database/old_database.py", "Python", 432, 0, 0, 154, 115, 701
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/database/read.py", "Python", 0, 0, 0, 0, 1, 1
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/database/temp_database.py", "Python", 12, 0, 0, 0, 8, 20
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/database/write.py", "Python", 210, 0, 0, 62, 63, 335
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/__init__.py", "Python", 0, 0, 0, 0, 3, 3
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/fetch_audio.py", "Python", 75, 0, 0, 12, 20, 107
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/fetch_source.py", "Python", 54, 0, 0, 1, 16, 71
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/metadata/__init__.py", "Python", 6, 0, 0, 0, 2, 8
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/metadata/metadata_fetch.py", "Python", 257, 0, 0, 24, 65, 346
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/metadata/metadata_search.py", "Python", 253, 0, 0, 40, 72, 365
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/metadata/sources/__init__.py", "Python", 3, 0, 0, 0, 2, 5
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/metadata/sources/musicbrainz.py", "Python", 42, 0, 0, 6, 12, 60
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/sources/__init__.py", "Python", 0, 0, 0, 0, 1, 1
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/sources/genius.py", "Python", 115, 0, 0, 16, 42, 173
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/sources/local_files.py", "Python", 40, 0, 0, 0, 18, 58
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/sources/musify.py", "Python", 136, 0, 0, 9, 37, 182
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/sources/source.py", "Python", 11, 0, 0, 5, 8, 24
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/sources/youtube.py", "Python", 71, 0, 0, 4, 24, 99
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/objects/__init__.py", "Python", 24, 0, 0, 0, 7, 31
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/objects/album.py", "Python", 15, 0, 0, 6, 5, 26
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/objects/artist.py", "Python", 18, 0, 0, 0, 5, 23
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/objects/collection.py", "Python", 52, 0, 0, 15, 24, 91
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/objects/formatted_text.py", "Python", 53, 0, 0, 57, 20, 130
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/objects/lyrics.py", "Python", 21, 0, 0, 0, 7, 28
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/objects/metadata.py", "Python", 262, 0, 0, 68, 63, 393
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/objects/parents.py", "Python", 22, 0, 0, 15, 12, 49
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/objects/song.py", "Python", 337, 0, 0, 81, 90, 508
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/objects/source.py", "Python", 116, 0, 0, 38, 41, 195
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/objects/target.py", "Python", 22, 0, 0, 7, 7, 36
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/pages/__init__.py", "Python", 7, 0, 0, 0, 5, 12
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/pages/abstract.py", "Python", 73, 0, 0, 68, 27, 168
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/pages/encyclopaedia_metallum.py", "Python", 341, 0, 0, 66, 91, 498
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/pages/youtube.py", "Python", 25, 0, 0, 16, 6, 47
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/static_files/new_db.sql", "SQLite", 0, 0, 72, 0, 10, 82
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/static_files/temp_database_structure.sql", "SQLite", 0, 0, 135, 0, 10, 145
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/tagging/__init__.py", "Python", 8, 0, 0, 0, 2, 10
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/tagging/id3.py", "Python", 51, 0, 0, 4, 20, 75
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/target/__init__.py", "Python", 4, 0, 0, 0, 2, 6
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/target/set_target.py", "Python", 37, 0, 0, 7, 18, 62
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/utils/__init__.py", "Python", 1, 0, 0, 1, 1, 3
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/utils/functions.py", "Python", 3, 0, 0, 0, 1, 4
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/utils/object_handeling.py", "Python", 19, 0, 0, 0, 6, 25
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/utils/phonetic_compares.py", "Python", 39, 0, 0, 2, 17, 58
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/utils/shared.py", "Python", 62, 0, 0, 3, 10, 75
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken/utils/string_processing.py", "Python", 2, 0, 0, 5, 2, 9
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken_cli.py", "Python", 3, 0, 0, 0, 3, 6
|
|
||||||
"/home/lars/Projects/music-downloader/src/music_kraken_gtk.py", "Python", 3, 0, 0, 0, 2, 5
|
|
||||||
"/home/lars/Projects/music-downloader/src/test.db", "Database", 0, 91, 0, 0, 1, 92
|
|
||||||
"/home/lars/Projects/music-downloader/src/tests/__init__.py", "Python", 0, 0, 0, 0, 1, 1
|
|
||||||
"/home/lars/Projects/music-downloader/src/tests/conftest.py", "Python", 3, 0, 0, 1, 2, 6
|
|
||||||
"/home/lars/Projects/music-downloader/src/tests/example_data_objects.py", "Python", 36, 0, 0, 5, 6, 47
|
|
||||||
"/home/lars/Projects/music-downloader/src/try-programming-interface.py", "Python", 14, 0, 0, 98, 22, 134
|
|
||||||
"/home/lars/Projects/music-downloader/src/try.py", "Python", 1, 0, 0, 0, 3, 4
|
|
||||||
"/home/lars/Projects/music-downloader/src/try_python.py", "Python", 13, 0, 0, 20, 9, 42
|
|
||||||
"Total", "-", 3852, 91, 207, 1060, 1228, 6438
|
|
|
File diff suppressed because one or more lines are too long
@ -1,40 +0,0 @@
|
|||||||
# Summary
|
|
||||||
|
|
||||||
Date : 2023-02-28 10:10:37
|
|
||||||
|
|
||||||
Directory /home/lars/Projects/music-downloader/src
|
|
||||||
|
|
||||||
Total : 63 files, 4150 codes, 1060 comments, 1228 blanks, all 6438 lines
|
|
||||||
|
|
||||||
Summary / [Details](details.md) / [Diff Summary](diff.md) / [Diff Details](diff-details.md)
|
|
||||||
|
|
||||||
## Languages
|
|
||||||
| language | files | code | comment | blank | total |
|
|
||||||
| :--- | ---: | ---: | ---: | ---: | ---: |
|
|
||||||
| Python | 60 | 3,852 | 1,060 | 1,207 | 6,119 |
|
|
||||||
| SQLite | 2 | 207 | 0 | 20 | 227 |
|
|
||||||
| Database | 1 | 91 | 0 | 1 | 92 |
|
|
||||||
|
|
||||||
## Directories
|
|
||||||
| path | files | code | comment | blank | total |
|
|
||||||
| :--- | ---: | ---: | ---: | ---: | ---: |
|
|
||||||
| . | 63 | 4,150 | 1,060 | 1,228 | 6,438 |
|
|
||||||
| . (Files) | 9 | 253 | 125 | 74 | 452 |
|
|
||||||
| music_kraken | 51 | 3,858 | 929 | 1,145 | 5,932 |
|
|
||||||
| music_kraken (Files) | 2 | 60 | 10 | 28 | 98 |
|
|
||||||
| music_kraken/database | 8 | 914 | 343 | 286 | 1,543 |
|
|
||||||
| music_kraken/not_used_anymore | 14 | 1,063 | 117 | 322 | 1,502 |
|
|
||||||
| music_kraken/not_used_anymore (Files) | 3 | 129 | 13 | 39 | 181 |
|
|
||||||
| music_kraken/not_used_anymore/metadata | 5 | 561 | 70 | 153 | 784 |
|
|
||||||
| music_kraken/not_used_anymore/metadata (Files) | 3 | 516 | 64 | 139 | 719 |
|
|
||||||
| music_kraken/not_used_anymore/metadata/sources | 2 | 45 | 6 | 14 | 65 |
|
|
||||||
| music_kraken/not_used_anymore/sources | 6 | 373 | 34 | 130 | 537 |
|
|
||||||
| music_kraken/objects | 11 | 942 | 287 | 281 | 1,510 |
|
|
||||||
| music_kraken/pages | 4 | 446 | 150 | 129 | 725 |
|
|
||||||
| music_kraken/static_files | 2 | 207 | 0 | 20 | 227 |
|
|
||||||
| music_kraken/tagging | 2 | 59 | 4 | 22 | 85 |
|
|
||||||
| music_kraken/target | 2 | 41 | 7 | 20 | 68 |
|
|
||||||
| music_kraken/utils | 6 | 126 | 11 | 37 | 174 |
|
|
||||||
| tests | 3 | 39 | 6 | 9 | 54 |
|
|
||||||
|
|
||||||
Summary / [Details](details.md) / [Diff Summary](diff.md) / [Diff Details](diff-details.md)
|
|
@ -1,106 +0,0 @@
|
|||||||
Date : 2023-02-28 10:10:37
|
|
||||||
Directory : /home/lars/Projects/music-downloader/src
|
|
||||||
Total : 63 files, 4150 codes, 1060 comments, 1228 blanks, all 6438 lines
|
|
||||||
|
|
||||||
Languages
|
|
||||||
+----------+------------+------------+------------+------------+------------+
|
|
||||||
| language | files | code | comment | blank | total |
|
|
||||||
+----------+------------+------------+------------+------------+------------+
|
|
||||||
| Python | 60 | 3,852 | 1,060 | 1,207 | 6,119 |
|
|
||||||
| SQLite | 2 | 207 | 0 | 20 | 227 |
|
|
||||||
| Database | 1 | 91 | 0 | 1 | 92 |
|
|
||||||
+----------+------------+------------+------------+------------+------------+
|
|
||||||
|
|
||||||
Directories
|
|
||||||
+--------------------------------------------------------------------------------------------------------+------------+------------+------------+------------+------------+
|
|
||||||
| path | files | code | comment | blank | total |
|
|
||||||
+--------------------------------------------------------------------------------------------------------+------------+------------+------------+------------+------------+
|
|
||||||
| . | 63 | 4,150 | 1,060 | 1,228 | 6,438 |
|
|
||||||
| . (Files) | 9 | 253 | 125 | 74 | 452 |
|
|
||||||
| music_kraken | 51 | 3,858 | 929 | 1,145 | 5,932 |
|
|
||||||
| music_kraken (Files) | 2 | 60 | 10 | 28 | 98 |
|
|
||||||
| music_kraken/database | 8 | 914 | 343 | 286 | 1,543 |
|
|
||||||
| music_kraken/not_used_anymore | 14 | 1,063 | 117 | 322 | 1,502 |
|
|
||||||
| music_kraken/not_used_anymore (Files) | 3 | 129 | 13 | 39 | 181 |
|
|
||||||
| music_kraken/not_used_anymore/metadata | 5 | 561 | 70 | 153 | 784 |
|
|
||||||
| music_kraken/not_used_anymore/metadata (Files) | 3 | 516 | 64 | 139 | 719 |
|
|
||||||
| music_kraken/not_used_anymore/metadata/sources | 2 | 45 | 6 | 14 | 65 |
|
|
||||||
| music_kraken/not_used_anymore/sources | 6 | 373 | 34 | 130 | 537 |
|
|
||||||
| music_kraken/objects | 11 | 942 | 287 | 281 | 1,510 |
|
|
||||||
| music_kraken/pages | 4 | 446 | 150 | 129 | 725 |
|
|
||||||
| music_kraken/static_files | 2 | 207 | 0 | 20 | 227 |
|
|
||||||
| music_kraken/tagging | 2 | 59 | 4 | 22 | 85 |
|
|
||||||
| music_kraken/target | 2 | 41 | 7 | 20 | 68 |
|
|
||||||
| music_kraken/utils | 6 | 126 | 11 | 37 | 174 |
|
|
||||||
| tests | 3 | 39 | 6 | 9 | 54 |
|
|
||||||
+--------------------------------------------------------------------------------------------------------+------------+------------+------------+------------+------------+
|
|
||||||
|
|
||||||
Files
|
|
||||||
+--------------------------------------------------------------------------------------------------------+----------+------------+------------+------------+------------+
|
|
||||||
| filename | language | code | comment | blank | total |
|
|
||||||
+--------------------------------------------------------------------------------------------------------+----------+------------+------------+------------+------------+
|
|
||||||
| /home/lars/Projects/music-downloader/src/__init__.py | Python | 0 | 0 | 1 | 1 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/create_custom_objects.py | Python | 80 | 3 | 18 | 101 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/metal_archives.py | Python | 48 | 4 | 15 | 67 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/__init__.py | Python | 57 | 8 | 25 | 90 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/__main__.py | Python | 3 | 2 | 3 | 8 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/database/__init__.py | Python | 18 | 0 | 5 | 23 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/database/data_models.py | Python | 123 | 23 | 52 | 198 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/database/database.py | Python | 84 | 48 | 26 | 158 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/database/object_cache.py | Python | 35 | 56 | 16 | 107 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/database/old_database.py | Python | 432 | 154 | 115 | 701 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/database/read.py | Python | 0 | 0 | 1 | 1 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/database/temp_database.py | Python | 12 | 0 | 8 | 20 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/database/write.py | Python | 210 | 62 | 63 | 335 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/__init__.py | Python | 0 | 0 | 3 | 3 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/fetch_audio.py | Python | 75 | 12 | 20 | 107 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/fetch_source.py | Python | 54 | 1 | 16 | 71 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/metadata/__init__.py | Python | 6 | 0 | 2 | 8 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/metadata/metadata_fetch.py | Python | 257 | 24 | 65 | 346 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/metadata/metadata_search.py | Python | 253 | 40 | 72 | 365 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/metadata/sources/__init__.py | Python | 3 | 0 | 2 | 5 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/metadata/sources/musicbrainz.py | Python | 42 | 6 | 12 | 60 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/sources/__init__.py | Python | 0 | 0 | 1 | 1 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/sources/genius.py | Python | 115 | 16 | 42 | 173 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/sources/local_files.py | Python | 40 | 0 | 18 | 58 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/sources/musify.py | Python | 136 | 9 | 37 | 182 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/sources/source.py | Python | 11 | 5 | 8 | 24 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/sources/youtube.py | Python | 71 | 4 | 24 | 99 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/objects/__init__.py | Python | 24 | 0 | 7 | 31 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/objects/album.py | Python | 15 | 6 | 5 | 26 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/objects/artist.py | Python | 18 | 0 | 5 | 23 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/objects/collection.py | Python | 52 | 15 | 24 | 91 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/objects/formatted_text.py | Python | 53 | 57 | 20 | 130 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/objects/lyrics.py | Python | 21 | 0 | 7 | 28 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/objects/metadata.py | Python | 262 | 68 | 63 | 393 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/objects/parents.py | Python | 22 | 15 | 12 | 49 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/objects/song.py | Python | 337 | 81 | 90 | 508 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/objects/source.py | Python | 116 | 38 | 41 | 195 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/objects/target.py | Python | 22 | 7 | 7 | 36 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/pages/__init__.py | Python | 7 | 0 | 5 | 12 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/pages/abstract.py | Python | 73 | 68 | 27 | 168 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/pages/encyclopaedia_metallum.py | Python | 341 | 66 | 91 | 498 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/pages/youtube.py | Python | 25 | 16 | 6 | 47 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/static_files/new_db.sql | SQLite | 72 | 0 | 10 | 82 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/static_files/temp_database_structure.sql | SQLite | 135 | 0 | 10 | 145 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/tagging/__init__.py | Python | 8 | 0 | 2 | 10 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/tagging/id3.py | Python | 51 | 4 | 20 | 75 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/target/__init__.py | Python | 4 | 0 | 2 | 6 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/target/set_target.py | Python | 37 | 7 | 18 | 62 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/utils/__init__.py | Python | 1 | 1 | 1 | 3 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/utils/functions.py | Python | 3 | 0 | 1 | 4 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/utils/object_handeling.py | Python | 19 | 0 | 6 | 25 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/utils/phonetic_compares.py | Python | 39 | 2 | 17 | 58 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/utils/shared.py | Python | 62 | 3 | 10 | 75 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken/utils/string_processing.py | Python | 2 | 5 | 2 | 9 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken_cli.py | Python | 3 | 0 | 3 | 6 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/music_kraken_gtk.py | Python | 3 | 0 | 2 | 5 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/test.db | Database | 91 | 0 | 1 | 92 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/tests/__init__.py | Python | 0 | 0 | 1 | 1 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/tests/conftest.py | Python | 3 | 1 | 2 | 6 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/tests/example_data_objects.py | Python | 36 | 5 | 6 | 47 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/try-programming-interface.py | Python | 14 | 98 | 22 | 134 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/try.py | Python | 1 | 0 | 3 | 4 |
|
|
||||||
| /home/lars/Projects/music-downloader/src/try_python.py | Python | 13 | 20 | 9 | 42 |
|
|
||||||
| Total | | 4,150 | 1,060 | 1,228 | 6,438 |
|
|
||||||
+--------------------------------------------------------------------------------------------------------+----------+------------+------------+------------+------------+
|
|
104
.VSCodeCounter/2023-05-24_11-17-57/details.md
Normal file
104
.VSCodeCounter/2023-05-24_11-17-57/details.md
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
# Details
|
||||||
|
|
||||||
|
Date : 2023-05-24 11:17:57
|
||||||
|
|
||||||
|
Directory /home/lars/Projects/music-downloader/src
|
||||||
|
|
||||||
|
Total : 89 files, 6536 codes, 1157 comments, 1980 blanks, all 9673 lines
|
||||||
|
|
||||||
|
[Summary](results.md) / Details / [Diff Summary](diff.md) / [Diff Details](diff-details.md)
|
||||||
|
|
||||||
|
## Files
|
||||||
|
| filename | language | code | comment | blank | total |
|
||||||
|
| :--- | :--- | ---: | ---: | ---: | ---: |
|
||||||
|
| [src/__init__.py](/src/__init__.py) | Python | 0 | 0 | 1 | 1 |
|
||||||
|
| [src/actual_donwload.py](/src/actual_donwload.py) | Python | 43 | 2 | 18 | 63 |
|
||||||
|
| [src/create_custom_objects.py](/src/create_custom_objects.py) | Python | 58 | 0 | 6 | 64 |
|
||||||
|
| [src/metal_archives.py](/src/metal_archives.py) | Python | 30 | 0 | 12 | 42 |
|
||||||
|
| [src/music_kraken/__init__.py](/src/music_kraken/__init__.py) | Python | 189 | 21 | 60 | 270 |
|
||||||
|
| [src/music_kraken/__main__.py](/src/music_kraken/__main__.py) | Python | 88 | 3 | 21 | 112 |
|
||||||
|
| [src/music_kraken/audio/__init__.py](/src/music_kraken/audio/__init__.py) | Python | 7 | 0 | 3 | 10 |
|
||||||
|
| [src/music_kraken/audio/codec.py](/src/music_kraken/audio/codec.py) | Python | 25 | 0 | 8 | 33 |
|
||||||
|
| [src/music_kraken/audio/metadata.py](/src/music_kraken/audio/metadata.py) | Python | 60 | 4 | 24 | 88 |
|
||||||
|
| [src/music_kraken/connection/__init__.py](/src/music_kraken/connection/__init__.py) | Python | 1 | 0 | 1 | 2 |
|
||||||
|
| [src/music_kraken/connection/connection.py](/src/music_kraken/connection/connection.py) | Python | 162 | 1 | 30 | 193 |
|
||||||
|
| [src/music_kraken/connection/rotating.py](/src/music_kraken/connection/rotating.py) | Python | 27 | 3 | 14 | 44 |
|
||||||
|
| [src/music_kraken/database/__init__.py](/src/music_kraken/database/__init__.py) | Python | 0 | 0 | 1 | 1 |
|
||||||
|
| [src/music_kraken/database/data_models.py](/src/music_kraken/database/data_models.py) | Python | 122 | 24 | 52 | 198 |
|
||||||
|
| [src/music_kraken/database/database.py](/src/music_kraken/database/database.py) | Python | 104 | 47 | 38 | 189 |
|
||||||
|
| [src/music_kraken/download/__init__.py](/src/music_kraken/download/__init__.py) | Python | 2 | 0 | 1 | 3 |
|
||||||
|
| [src/music_kraken/download/download.py](/src/music_kraken/download/download.py) | Python | 35 | 0 | 14 | 49 |
|
||||||
|
| [src/music_kraken/download/multiple_options.py](/src/music_kraken/download/multiple_options.py) | Python | 69 | 0 | 31 | 100 |
|
||||||
|
| [src/music_kraken/download/page_attributes.py](/src/music_kraken/download/page_attributes.py) | Python | 21 | 1 | 10 | 32 |
|
||||||
|
| [src/music_kraken/download/search.py](/src/music_kraken/download/search.py) | Python | 130 | 24 | 56 | 210 |
|
||||||
|
| [src/music_kraken/not_used_anymore/__init__.py](/src/music_kraken/not_used_anymore/__init__.py) | Python | 0 | 0 | 3 | 3 |
|
||||||
|
| [src/music_kraken/not_used_anymore/fetch_audio.py](/src/music_kraken/not_used_anymore/fetch_audio.py) | Python | 75 | 12 | 20 | 107 |
|
||||||
|
| [src/music_kraken/not_used_anymore/fetch_source.py](/src/music_kraken/not_used_anymore/fetch_source.py) | Python | 54 | 1 | 16 | 71 |
|
||||||
|
| [src/music_kraken/not_used_anymore/metadata/__init__.py](/src/music_kraken/not_used_anymore/metadata/__init__.py) | Python | 6 | 0 | 2 | 8 |
|
||||||
|
| [src/music_kraken/not_used_anymore/metadata/metadata_fetch.py](/src/music_kraken/not_used_anymore/metadata/metadata_fetch.py) | Python | 257 | 24 | 65 | 346 |
|
||||||
|
| [src/music_kraken/not_used_anymore/metadata/metadata_search.py](/src/music_kraken/not_used_anymore/metadata/metadata_search.py) | Python | 253 | 40 | 72 | 365 |
|
||||||
|
| [src/music_kraken/not_used_anymore/metadata/sources/__init__.py](/src/music_kraken/not_used_anymore/metadata/sources/__init__.py) | Python | 3 | 0 | 2 | 5 |
|
||||||
|
| [src/music_kraken/not_used_anymore/metadata/sources/musicbrainz.py](/src/music_kraken/not_used_anymore/metadata/sources/musicbrainz.py) | Python | 42 | 6 | 12 | 60 |
|
||||||
|
| [src/music_kraken/not_used_anymore/sources/__init__.py](/src/music_kraken/not_used_anymore/sources/__init__.py) | Python | 0 | 0 | 1 | 1 |
|
||||||
|
| [src/music_kraken/not_used_anymore/sources/genius.py](/src/music_kraken/not_used_anymore/sources/genius.py) | Python | 115 | 16 | 42 | 173 |
|
||||||
|
| [src/music_kraken/not_used_anymore/sources/local_files.py](/src/music_kraken/not_used_anymore/sources/local_files.py) | Python | 40 | 0 | 18 | 58 |
|
||||||
|
| [src/music_kraken/not_used_anymore/sources/musify.py](/src/music_kraken/not_used_anymore/sources/musify.py) | Python | 136 | 9 | 37 | 182 |
|
||||||
|
| [src/music_kraken/not_used_anymore/sources/source.py](/src/music_kraken/not_used_anymore/sources/source.py) | Python | 11 | 5 | 8 | 24 |
|
||||||
|
| [src/music_kraken/not_used_anymore/sources/youtube.py](/src/music_kraken/not_used_anymore/sources/youtube.py) | Python | 71 | 4 | 24 | 99 |
|
||||||
|
| [src/music_kraken/objects/__init__.py](/src/music_kraken/objects/__init__.py) | Python | 14 | 0 | 5 | 19 |
|
||||||
|
| [src/music_kraken/objects/cache.py](/src/music_kraken/objects/cache.py) | Python | 37 | 56 | 18 | 111 |
|
||||||
|
| [src/music_kraken/objects/collection.py](/src/music_kraken/objects/collection.py) | Python | 91 | 31 | 39 | 161 |
|
||||||
|
| [src/music_kraken/objects/formatted_text.py](/src/music_kraken/objects/formatted_text.py) | Python | 50 | 10 | 19 | 79 |
|
||||||
|
| [src/music_kraken/objects/lyrics.py](/src/music_kraken/objects/lyrics.py) | Python | 25 | 0 | 7 | 32 |
|
||||||
|
| [src/music_kraken/objects/metadata.py](/src/music_kraken/objects/metadata.py) | Python | 261 | 62 | 61 | 384 |
|
||||||
|
| [src/music_kraken/objects/option.py](/src/music_kraken/objects/option.py) | Python | 28 | 0 | 13 | 41 |
|
||||||
|
| [src/music_kraken/objects/parents.py](/src/music_kraken/objects/parents.py) | Python | 65 | 33 | 33 | 131 |
|
||||||
|
| [src/music_kraken/objects/song.py](/src/music_kraken/objects/song.py) | Python | 473 | 113 | 115 | 701 |
|
||||||
|
| [src/music_kraken/objects/source.py](/src/music_kraken/objects/source.py) | Python | 90 | 16 | 32 | 138 |
|
||||||
|
| [src/music_kraken/objects/target.py](/src/music_kraken/objects/target.py) | Python | 63 | 15 | 23 | 101 |
|
||||||
|
| [src/music_kraken/pages/__init__.py](/src/music_kraken/pages/__init__.py) | Python | 3 | 0 | 1 | 4 |
|
||||||
|
| [src/music_kraken/pages/abstract.py](/src/music_kraken/pages/abstract.py) | Python | 357 | 34 | 103 | 494 |
|
||||||
|
| [src/music_kraken/pages/encyclopaedia_metallum.py](/src/music_kraken/pages/encyclopaedia_metallum.py) | Python | 432 | 90 | 127 | 649 |
|
||||||
|
| [src/music_kraken/pages/musify.py](/src/music_kraken/pages/musify.py) | Python | 629 | 289 | 187 | 1,105 |
|
||||||
|
| [src/music_kraken/pages/preset.py](/src/music_kraken/pages/preset.py) | Python | 43 | 1 | 16 | 60 |
|
||||||
|
| [src/music_kraken/pages/youtube.py](/src/music_kraken/pages/youtube.py) | Python | 25 | 16 | 6 | 47 |
|
||||||
|
| [src/music_kraken/static_files/new_db.sql](/src/music_kraken/static_files/new_db.sql) | SQLite | 72 | 0 | 10 | 82 |
|
||||||
|
| [src/music_kraken/static_files/temp_database_structure.sql](/src/music_kraken/static_files/temp_database_structure.sql) | SQLite | 135 | 0 | 10 | 145 |
|
||||||
|
| [src/music_kraken/utils/__init__.py](/src/music_kraken/utils/__init__.py) | Python | 2 | 1 | 2 | 5 |
|
||||||
|
| [src/music_kraken/utils/config/__init__.py](/src/music_kraken/utils/config/__init__.py) | Python | 7 | 0 | 4 | 11 |
|
||||||
|
| [src/music_kraken/utils/config/audio.py](/src/music_kraken/utils/config/audio.py) | Python | 152 | 15 | 28 | 195 |
|
||||||
|
| [src/music_kraken/utils/config/base_classes.py](/src/music_kraken/utils/config/base_classes.py) | Python | 136 | 35 | 61 | 232 |
|
||||||
|
| [src/music_kraken/utils/config/config.py](/src/music_kraken/utils/config/config.py) | Python | 92 | 16 | 30 | 138 |
|
||||||
|
| [src/music_kraken/utils/config/connection.py](/src/music_kraken/utils/config/connection.py) | Python | 81 | 2 | 15 | 98 |
|
||||||
|
| [src/music_kraken/utils/config/logging.py](/src/music_kraken/utils/config/logging.py) | Python | 104 | 4 | 17 | 125 |
|
||||||
|
| [src/music_kraken/utils/config/misc.py](/src/music_kraken/utils/config/misc.py) | Python | 40 | 0 | 9 | 49 |
|
||||||
|
| [src/music_kraken/utils/config/paths.py](/src/music_kraken/utils/config/paths.py) | Python | 40 | 0 | 13 | 53 |
|
||||||
|
| [src/music_kraken/utils/enums/__init__.py](/src/music_kraken/utils/enums/__init__.py) | Python | 0 | 0 | 1 | 1 |
|
||||||
|
| [src/music_kraken/utils/enums/album.py](/src/music_kraken/utils/enums/album.py) | Python | 16 | 6 | 5 | 27 |
|
||||||
|
| [src/music_kraken/utils/enums/source.py](/src/music_kraken/utils/enums/source.py) | Python | 40 | 1 | 8 | 49 |
|
||||||
|
| [src/music_kraken/utils/exception/__init__.py](/src/music_kraken/utils/exception/__init__.py) | Python | 1 | 0 | 1 | 2 |
|
||||||
|
| [src/music_kraken/utils/exception/config.py](/src/music_kraken/utils/exception/config.py) | Python | 14 | 8 | 7 | 29 |
|
||||||
|
| [src/music_kraken/utils/functions.py](/src/music_kraken/utils/functions.py) | Python | 3 | 0 | 1 | 4 |
|
||||||
|
| [src/music_kraken/utils/object_handeling.py](/src/music_kraken/utils/object_handeling.py) | Python | 19 | 0 | 6 | 25 |
|
||||||
|
| [src/music_kraken/utils/path_manager/__init__.py](/src/music_kraken/utils/path_manager/__init__.py) | Python | 2 | 0 | 2 | 4 |
|
||||||
|
| [src/music_kraken/utils/path_manager/config_directory.py](/src/music_kraken/utils/path_manager/config_directory.py) | Python | 4 | 0 | 4 | 8 |
|
||||||
|
| [src/music_kraken/utils/path_manager/locations.py](/src/music_kraken/utils/path_manager/locations.py) | Python | 16 | 0 | 9 | 25 |
|
||||||
|
| [src/music_kraken/utils/path_manager/music_directory.py](/src/music_kraken/utils/path_manager/music_directory.py) | Python | 36 | 9 | 14 | 59 |
|
||||||
|
| [src/music_kraken/utils/phonetic_compares.py](/src/music_kraken/utils/phonetic_compares.py) | Python | 39 | 2 | 17 | 58 |
|
||||||
|
| [src/music_kraken/utils/regex.py](/src/music_kraken/utils/regex.py) | Python | 1 | 0 | 2 | 3 |
|
||||||
|
| [src/music_kraken/utils/shared.py](/src/music_kraken/utils/shared.py) | Python | 63 | 22 | 21 | 106 |
|
||||||
|
| [src/music_kraken/utils/string_processing.py](/src/music_kraken/utils/string_processing.py) | Python | 16 | 5 | 11 | 32 |
|
||||||
|
| [src/music_kraken/utils/support_classes/__init__.py](/src/music_kraken/utils/support_classes/__init__.py) | Python | 3 | 0 | 1 | 4 |
|
||||||
|
| [src/music_kraken/utils/support_classes/default_target.py](/src/music_kraken/utils/support_classes/default_target.py) | Python | 56 | 0 | 15 | 71 |
|
||||||
|
| [src/music_kraken/utils/support_classes/download_result.py](/src/music_kraken/utils/support_classes/download_result.py) | Python | 69 | 0 | 21 | 90 |
|
||||||
|
| [src/music_kraken/utils/support_classes/query.py](/src/music_kraken/utils/support_classes/query.py) | Python | 24 | 0 | 9 | 33 |
|
||||||
|
| [src/music_kraken_cli.py](/src/music_kraken_cli.py) | Python | 3 | 0 | 3 | 6 |
|
||||||
|
| [src/music_kraken_gtk.py](/src/music_kraken_gtk.py) | Python | 3 | 0 | 2 | 5 |
|
||||||
|
| [src/musify_search.py](/src/musify_search.py) | Python | 38 | 0 | 14 | 52 |
|
||||||
|
| [src/tests/__init__.py](/src/tests/__init__.py) | Python | 0 | 0 | 1 | 1 |
|
||||||
|
| [src/tests/conftest.py](/src/tests/conftest.py) | Python | 3 | 1 | 2 | 6 |
|
||||||
|
| [src/tests/test_building_objects.py](/src/tests/test_building_objects.py) | Python | 81 | 1 | 13 | 95 |
|
||||||
|
| [src/tests/test_download.py](/src/tests/test_download.py) | Python | 30 | 1 | 12 | 43 |
|
||||||
|
| [src/tests/test_objects.py](/src/tests/test_objects.py) | Python | 173 | 15 | 51 | 239 |
|
||||||
|
|
||||||
|
[Summary](results.md) / Details / [Diff Summary](diff.md) / [Diff Details](diff-details.md)
|
76
.VSCodeCounter/2023-05-24_11-17-57/diff-details.md
Normal file
76
.VSCodeCounter/2023-05-24_11-17-57/diff-details.md
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
# Diff Details
|
||||||
|
|
||||||
|
Date : 2023-05-24 11:17:57
|
||||||
|
|
||||||
|
Directory /home/lars/Projects/music-downloader/src
|
||||||
|
|
||||||
|
Total : 61 files, 1280 codes, 157 comments, 437 blanks, all 1874 lines
|
||||||
|
|
||||||
|
[Summary](results.md) / [Details](details.md) / [Diff Summary](diff.md) / Diff Details
|
||||||
|
|
||||||
|
## Files
|
||||||
|
| filename | language | code | comment | blank | total |
|
||||||
|
| :--- | :--- | ---: | ---: | ---: | ---: |
|
||||||
|
| [src/actual_donwload.py](/src/actual_donwload.py) | Python | 6 | 2 | 1 | 9 |
|
||||||
|
| [src/music_kraken/__init__.py](/src/music_kraken/__init__.py) | Python | 103 | 9 | 32 | 144 |
|
||||||
|
| [src/music_kraken/__main__.py](/src/music_kraken/__main__.py) | Python | 85 | 3 | 18 | 106 |
|
||||||
|
| [src/music_kraken/audio/__init__.py](/src/music_kraken/audio/__init__.py) | Python | 7 | 0 | 3 | 10 |
|
||||||
|
| [src/music_kraken/audio/codec.py](/src/music_kraken/audio/codec.py) | Python | 25 | 0 | 8 | 33 |
|
||||||
|
| [src/music_kraken/audio/metadata.py](/src/music_kraken/audio/metadata.py) | Python | 60 | 4 | 24 | 88 |
|
||||||
|
| [src/music_kraken/connection/__init__.py](/src/music_kraken/connection/__init__.py) | Python | 1 | 0 | 1 | 2 |
|
||||||
|
| [src/music_kraken/connection/connection.py](/src/music_kraken/connection/connection.py) | Python | 162 | 1 | 30 | 193 |
|
||||||
|
| [src/music_kraken/connection/rotating.py](/src/music_kraken/connection/rotating.py) | Python | 27 | 3 | 14 | 44 |
|
||||||
|
| [src/music_kraken/download/__init__.py](/src/music_kraken/download/__init__.py) | Python | 2 | 0 | 1 | 3 |
|
||||||
|
| [src/music_kraken/download/download.py](/src/music_kraken/download/download.py) | Python | 35 | 0 | 14 | 49 |
|
||||||
|
| [src/music_kraken/download/multiple_options.py](/src/music_kraken/download/multiple_options.py) | Python | 69 | 0 | 31 | 100 |
|
||||||
|
| [src/music_kraken/download/page_attributes.py](/src/music_kraken/download/page_attributes.py) | Python | 21 | 1 | 10 | 32 |
|
||||||
|
| [src/music_kraken/download/search.py](/src/music_kraken/download/search.py) | Python | 130 | 24 | 56 | 210 |
|
||||||
|
| [src/music_kraken/objects/__init__.py](/src/music_kraken/objects/__init__.py) | Python | -15 | 0 | -3 | -18 |
|
||||||
|
| [src/music_kraken/objects/album.py](/src/music_kraken/objects/album.py) | Python | -16 | -6 | -5 | -27 |
|
||||||
|
| [src/music_kraken/objects/option.py](/src/music_kraken/objects/option.py) | Python | 5 | 0 | 2 | 7 |
|
||||||
|
| [src/music_kraken/objects/parents.py](/src/music_kraken/objects/parents.py) | Python | 3 | 2 | 2 | 7 |
|
||||||
|
| [src/music_kraken/objects/song.py](/src/music_kraken/objects/song.py) | Python | 37 | 20 | 16 | 73 |
|
||||||
|
| [src/music_kraken/objects/source.py](/src/music_kraken/objects/source.py) | Python | -30 | -1 | -9 | -40 |
|
||||||
|
| [src/music_kraken/objects/target.py](/src/music_kraken/objects/target.py) | Python | 5 | 4 | 2 | 11 |
|
||||||
|
| [src/music_kraken/pages/__init__.py](/src/music_kraken/pages/__init__.py) | Python | -3 | 0 | -4 | -7 |
|
||||||
|
| [src/music_kraken/pages/abstract.py](/src/music_kraken/pages/abstract.py) | Python | -71 | -10 | 0 | -81 |
|
||||||
|
| [src/music_kraken/pages/download_center/__init__.py](/src/music_kraken/pages/download_center/__init__.py) | Python | -4 | 0 | -2 | -6 |
|
||||||
|
| [src/music_kraken/pages/download_center/download.py](/src/music_kraken/pages/download_center/download.py) | Python | -33 | 0 | -13 | -46 |
|
||||||
|
| [src/music_kraken/pages/download_center/multiple_options.py](/src/music_kraken/pages/download_center/multiple_options.py) | Python | -69 | 0 | -31 | -100 |
|
||||||
|
| [src/music_kraken/pages/download_center/page_attributes.py](/src/music_kraken/pages/download_center/page_attributes.py) | Python | -24 | -1 | -9 | -34 |
|
||||||
|
| [src/music_kraken/pages/download_center/search.py](/src/music_kraken/pages/download_center/search.py) | Python | -85 | -23 | -38 | -146 |
|
||||||
|
| [src/music_kraken/pages/encyclopaedia_metallum.py](/src/music_kraken/pages/encyclopaedia_metallum.py) | Python | -19 | 7 | 10 | -2 |
|
||||||
|
| [src/music_kraken/pages/musify.py](/src/music_kraken/pages/musify.py) | Python | 65 | 30 | 32 | 127 |
|
||||||
|
| [src/music_kraken/pages/preset.py](/src/music_kraken/pages/preset.py) | Python | 43 | 1 | 16 | 60 |
|
||||||
|
| [src/music_kraken/pages/support_classes/__init__.py](/src/music_kraken/pages/support_classes/__init__.py) | Python | 0 | 0 | -1 | -1 |
|
||||||
|
| [src/music_kraken/pages/support_classes/default_target.py](/src/music_kraken/pages/support_classes/default_target.py) | Python | -55 | 0 | -15 | -70 |
|
||||||
|
| [src/music_kraken/pages/support_classes/download_result.py](/src/music_kraken/pages/support_classes/download_result.py) | Python | -51 | 0 | -15 | -66 |
|
||||||
|
| [src/music_kraken/tagging/__init__.py](/src/music_kraken/tagging/__init__.py) | Python | -5 | 0 | -2 | -7 |
|
||||||
|
| [src/music_kraken/tagging/id3.py](/src/music_kraken/tagging/id3.py) | Python | -60 | -4 | -24 | -88 |
|
||||||
|
| [src/music_kraken/utils/__init__.py](/src/music_kraken/utils/__init__.py) | Python | 1 | 0 | 1 | 2 |
|
||||||
|
| [src/music_kraken/utils/config/__init__.py](/src/music_kraken/utils/config/__init__.py) | Python | 7 | 0 | 4 | 11 |
|
||||||
|
| [src/music_kraken/utils/config/audio.py](/src/music_kraken/utils/config/audio.py) | Python | 152 | 15 | 28 | 195 |
|
||||||
|
| [src/music_kraken/utils/config/base_classes.py](/src/music_kraken/utils/config/base_classes.py) | Python | 136 | 35 | 61 | 232 |
|
||||||
|
| [src/music_kraken/utils/config/config.py](/src/music_kraken/utils/config/config.py) | Python | 92 | 16 | 30 | 138 |
|
||||||
|
| [src/music_kraken/utils/config/connection.py](/src/music_kraken/utils/config/connection.py) | Python | 81 | 2 | 15 | 98 |
|
||||||
|
| [src/music_kraken/utils/config/logging.py](/src/music_kraken/utils/config/logging.py) | Python | 104 | 4 | 17 | 125 |
|
||||||
|
| [src/music_kraken/utils/config/misc.py](/src/music_kraken/utils/config/misc.py) | Python | 40 | 0 | 9 | 49 |
|
||||||
|
| [src/music_kraken/utils/config/paths.py](/src/music_kraken/utils/config/paths.py) | Python | 40 | 0 | 13 | 53 |
|
||||||
|
| [src/music_kraken/utils/enums/__init__.py](/src/music_kraken/utils/enums/__init__.py) | Python | 0 | 0 | 1 | 1 |
|
||||||
|
| [src/music_kraken/utils/enums/album.py](/src/music_kraken/utils/enums/album.py) | Python | 16 | 6 | 5 | 27 |
|
||||||
|
| [src/music_kraken/utils/enums/source.py](/src/music_kraken/utils/enums/source.py) | Python | 40 | 1 | 8 | 49 |
|
||||||
|
| [src/music_kraken/utils/exception/__init__.py](/src/music_kraken/utils/exception/__init__.py) | Python | 1 | 0 | 1 | 2 |
|
||||||
|
| [src/music_kraken/utils/exception/config.py](/src/music_kraken/utils/exception/config.py) | Python | 14 | 8 | 7 | 29 |
|
||||||
|
| [src/music_kraken/utils/path_manager/__init__.py](/src/music_kraken/utils/path_manager/__init__.py) | Python | 2 | 0 | 2 | 4 |
|
||||||
|
| [src/music_kraken/utils/path_manager/config_directory.py](/src/music_kraken/utils/path_manager/config_directory.py) | Python | 4 | 0 | 4 | 8 |
|
||||||
|
| [src/music_kraken/utils/path_manager/locations.py](/src/music_kraken/utils/path_manager/locations.py) | Python | 16 | 0 | 9 | 25 |
|
||||||
|
| [src/music_kraken/utils/path_manager/music_directory.py](/src/music_kraken/utils/path_manager/music_directory.py) | Python | 36 | 9 | 14 | 59 |
|
||||||
|
| [src/music_kraken/utils/regex.py](/src/music_kraken/utils/regex.py) | Python | 1 | 0 | 2 | 3 |
|
||||||
|
| [src/music_kraken/utils/shared.py](/src/music_kraken/utils/shared.py) | Python | -12 | -5 | 4 | -13 |
|
||||||
|
| [src/music_kraken/utils/string_processing.py](/src/music_kraken/utils/string_processing.py) | Python | 6 | 0 | 4 | 10 |
|
||||||
|
| [src/music_kraken/utils/support_classes/__init__.py](/src/music_kraken/utils/support_classes/__init__.py) | Python | 3 | 0 | 1 | 4 |
|
||||||
|
| [src/music_kraken/utils/support_classes/default_target.py](/src/music_kraken/utils/support_classes/default_target.py) | Python | 56 | 0 | 15 | 71 |
|
||||||
|
| [src/music_kraken/utils/support_classes/download_result.py](/src/music_kraken/utils/support_classes/download_result.py) | Python | 69 | 0 | 21 | 90 |
|
||||||
|
| [src/music_kraken/utils/support_classes/query.py](/src/music_kraken/utils/support_classes/query.py) | Python | 24 | 0 | 9 | 33 |
|
||||||
|
|
||||||
|
[Summary](results.md) / [Details](details.md) / [Diff Summary](diff.md) / Diff Details
|
63
.VSCodeCounter/2023-05-24_11-17-57/diff.csv
Normal file
63
.VSCodeCounter/2023-05-24_11-17-57/diff.csv
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
"filename", "language", "Python", "comment", "blank", "total"
|
||||||
|
"/home/lars/Projects/music-downloader/src/actual_donwload.py", "Python", 6, 2, 1, 9
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/__init__.py", "Python", 103, 9, 32, 144
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/__main__.py", "Python", 85, 3, 18, 106
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/audio/__init__.py", "Python", 7, 0, 3, 10
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/audio/codec.py", "Python", 25, 0, 8, 33
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/audio/metadata.py", "Python", 60, 4, 24, 88
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/connection/__init__.py", "Python", 1, 0, 1, 2
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/connection/connection.py", "Python", 162, 1, 30, 193
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/connection/rotating.py", "Python", 27, 3, 14, 44
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/download/__init__.py", "Python", 2, 0, 1, 3
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/download/download.py", "Python", 35, 0, 14, 49
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/download/multiple_options.py", "Python", 69, 0, 31, 100
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/download/page_attributes.py", "Python", 21, 1, 10, 32
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/download/search.py", "Python", 130, 24, 56, 210
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/objects/__init__.py", "Python", -15, 0, -3, -18
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/objects/album.py", "Python", -16, -6, -5, -27
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/objects/option.py", "Python", 5, 0, 2, 7
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/objects/parents.py", "Python", 3, 2, 2, 7
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/objects/song.py", "Python", 37, 20, 16, 73
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/objects/source.py", "Python", -30, -1, -9, -40
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/objects/target.py", "Python", 5, 4, 2, 11
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/pages/__init__.py", "Python", -3, 0, -4, -7
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/pages/abstract.py", "Python", -71, -10, 0, -81
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/pages/download_center/__init__.py", "Python", -4, 0, -2, -6
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/pages/download_center/download.py", "Python", -33, 0, -13, -46
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/pages/download_center/multiple_options.py", "Python", -69, 0, -31, -100
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/pages/download_center/page_attributes.py", "Python", -24, -1, -9, -34
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/pages/download_center/search.py", "Python", -85, -23, -38, -146
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/pages/encyclopaedia_metallum.py", "Python", -19, 7, 10, -2
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/pages/musify.py", "Python", 65, 30, 32, 127
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/pages/preset.py", "Python", 43, 1, 16, 60
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/pages/support_classes/__init__.py", "Python", 0, 0, -1, -1
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/pages/support_classes/default_target.py", "Python", -55, 0, -15, -70
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/pages/support_classes/download_result.py", "Python", -51, 0, -15, -66
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/tagging/__init__.py", "Python", -5, 0, -2, -7
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/tagging/id3.py", "Python", -60, -4, -24, -88
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/__init__.py", "Python", 1, 0, 1, 2
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/config/__init__.py", "Python", 7, 0, 4, 11
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/config/audio.py", "Python", 152, 15, 28, 195
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/config/base_classes.py", "Python", 136, 35, 61, 232
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/config/config.py", "Python", 92, 16, 30, 138
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/config/connection.py", "Python", 81, 2, 15, 98
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/config/logging.py", "Python", 104, 4, 17, 125
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/config/misc.py", "Python", 40, 0, 9, 49
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/config/paths.py", "Python", 40, 0, 13, 53
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/enums/__init__.py", "Python", 0, 0, 1, 1
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/enums/album.py", "Python", 16, 6, 5, 27
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/enums/source.py", "Python", 40, 1, 8, 49
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/exception/__init__.py", "Python", 1, 0, 1, 2
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/exception/config.py", "Python", 14, 8, 7, 29
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/path_manager/__init__.py", "Python", 2, 0, 2, 4
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/path_manager/config_directory.py", "Python", 4, 0, 4, 8
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/path_manager/locations.py", "Python", 16, 0, 9, 25
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/path_manager/music_directory.py", "Python", 36, 9, 14, 59
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/regex.py", "Python", 1, 0, 2, 3
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/shared.py", "Python", -12, -5, 4, -13
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/string_processing.py", "Python", 6, 0, 4, 10
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/support_classes/__init__.py", "Python", 3, 0, 1, 4
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/support_classes/default_target.py", "Python", 56, 0, 15, 71
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/support_classes/download_result.py", "Python", 69, 0, 21, 90
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/support_classes/query.py", "Python", 24, 0, 9, 33
|
||||||
|
"Total", "-", 1280, 157, 437, 1874
|
|
40
.VSCodeCounter/2023-05-24_11-17-57/diff.md
Normal file
40
.VSCodeCounter/2023-05-24_11-17-57/diff.md
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
# Diff Summary
|
||||||
|
|
||||||
|
Date : 2023-05-24 11:17:57
|
||||||
|
|
||||||
|
Directory /home/lars/Projects/music-downloader/src
|
||||||
|
|
||||||
|
Total : 61 files, 1280 codes, 157 comments, 437 blanks, all 1874 lines
|
||||||
|
|
||||||
|
[Summary](results.md) / [Details](details.md) / Diff Summary / [Diff Details](diff-details.md)
|
||||||
|
|
||||||
|
## Languages
|
||||||
|
| language | files | code | comment | blank | total |
|
||||||
|
| :--- | ---: | ---: | ---: | ---: | ---: |
|
||||||
|
| Python | 61 | 1,280 | 157 | 437 | 1,874 |
|
||||||
|
|
||||||
|
## Directories
|
||||||
|
| path | files | code | comment | blank | total |
|
||||||
|
| :--- | ---: | ---: | ---: | ---: | ---: |
|
||||||
|
| . | 61 | 1,280 | 157 | 437 | 1,874 |
|
||||||
|
| . (Files) | 1 | 6 | 2 | 1 | 9 |
|
||||||
|
| music_kraken | 60 | 1,274 | 155 | 436 | 1,865 |
|
||||||
|
| music_kraken (Files) | 2 | 188 | 12 | 50 | 250 |
|
||||||
|
| music_kraken/audio | 3 | 92 | 4 | 35 | 131 |
|
||||||
|
| music_kraken/connection | 3 | 190 | 4 | 45 | 239 |
|
||||||
|
| music_kraken/download | 5 | 257 | 25 | 112 | 394 |
|
||||||
|
| music_kraken/objects | 7 | -11 | 19 | 5 | 13 |
|
||||||
|
| music_kraken/pages | 13 | -306 | 4 | -70 | -372 |
|
||||||
|
| music_kraken/pages (Files) | 5 | 15 | 28 | 54 | 97 |
|
||||||
|
| music_kraken/pages/download_center | 5 | -215 | -24 | -93 | -332 |
|
||||||
|
| music_kraken/pages/support_classes | 3 | -106 | 0 | -31 | -137 |
|
||||||
|
| music_kraken/tagging | 2 | -65 | -4 | -26 | -95 |
|
||||||
|
| music_kraken/utils | 25 | 929 | 91 | 285 | 1,305 |
|
||||||
|
| music_kraken/utils (Files) | 4 | -4 | -5 | 11 | 2 |
|
||||||
|
| music_kraken/utils/config | 8 | 652 | 72 | 177 | 901 |
|
||||||
|
| music_kraken/utils/enums | 3 | 56 | 7 | 14 | 77 |
|
||||||
|
| music_kraken/utils/exception | 2 | 15 | 8 | 8 | 31 |
|
||||||
|
| music_kraken/utils/path_manager | 4 | 58 | 9 | 29 | 96 |
|
||||||
|
| music_kraken/utils/support_classes | 4 | 152 | 0 | 46 | 198 |
|
||||||
|
|
||||||
|
[Summary](results.md) / [Details](details.md) / Diff Summary / [Diff Details](diff-details.md)
|
104
.VSCodeCounter/2023-05-24_11-17-57/diff.txt
Normal file
104
.VSCodeCounter/2023-05-24_11-17-57/diff.txt
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
Date : 2023-05-24 11:17:57
|
||||||
|
Directory : /home/lars/Projects/music-downloader/src
|
||||||
|
Total : 61 files, 1280 codes, 157 comments, 437 blanks, all 1874 lines
|
||||||
|
|
||||||
|
Languages
|
||||||
|
+----------+------------+------------+------------+------------+------------+
|
||||||
|
| language | files | code | comment | blank | total |
|
||||||
|
+----------+------------+------------+------------+------------+------------+
|
||||||
|
| Python | 61 | 1,280 | 157 | 437 | 1,874 |
|
||||||
|
+----------+------------+------------+------------+------------+------------+
|
||||||
|
|
||||||
|
Directories
|
||||||
|
+-------------------------------------------------------------------------------------------------+------------+------------+------------+------------+------------+
|
||||||
|
| path | files | code | comment | blank | total |
|
||||||
|
+-------------------------------------------------------------------------------------------------+------------+------------+------------+------------+------------+
|
||||||
|
| . | 61 | 1,280 | 157 | 437 | 1,874 |
|
||||||
|
| . (Files) | 1 | 6 | 2 | 1 | 9 |
|
||||||
|
| music_kraken | 60 | 1,274 | 155 | 436 | 1,865 |
|
||||||
|
| music_kraken (Files) | 2 | 188 | 12 | 50 | 250 |
|
||||||
|
| music_kraken/audio | 3 | 92 | 4 | 35 | 131 |
|
||||||
|
| music_kraken/connection | 3 | 190 | 4 | 45 | 239 |
|
||||||
|
| music_kraken/download | 5 | 257 | 25 | 112 | 394 |
|
||||||
|
| music_kraken/objects | 7 | -11 | 19 | 5 | 13 |
|
||||||
|
| music_kraken/pages | 13 | -306 | 4 | -70 | -372 |
|
||||||
|
| music_kraken/pages (Files) | 5 | 15 | 28 | 54 | 97 |
|
||||||
|
| music_kraken/pages/download_center | 5 | -215 | -24 | -93 | -332 |
|
||||||
|
| music_kraken/pages/support_classes | 3 | -106 | 0 | -31 | -137 |
|
||||||
|
| music_kraken/tagging | 2 | -65 | -4 | -26 | -95 |
|
||||||
|
| music_kraken/utils | 25 | 929 | 91 | 285 | 1,305 |
|
||||||
|
| music_kraken/utils (Files) | 4 | -4 | -5 | 11 | 2 |
|
||||||
|
| music_kraken/utils/config | 8 | 652 | 72 | 177 | 901 |
|
||||||
|
| music_kraken/utils/enums | 3 | 56 | 7 | 14 | 77 |
|
||||||
|
| music_kraken/utils/exception | 2 | 15 | 8 | 8 | 31 |
|
||||||
|
| music_kraken/utils/path_manager | 4 | 58 | 9 | 29 | 96 |
|
||||||
|
| music_kraken/utils/support_classes | 4 | 152 | 0 | 46 | 198 |
|
||||||
|
+-------------------------------------------------------------------------------------------------+------------+------------+------------+------------+------------+
|
||||||
|
|
||||||
|
Files
|
||||||
|
+-------------------------------------------------------------------------------------------------+----------+------------+------------+------------+------------+
|
||||||
|
| filename | language | code | comment | blank | total |
|
||||||
|
+-------------------------------------------------------------------------------------------------+----------+------------+------------+------------+------------+
|
||||||
|
| /home/lars/Projects/music-downloader/src/actual_donwload.py | Python | 6 | 2 | 1 | 9 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/__init__.py | Python | 103 | 9 | 32 | 144 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/__main__.py | Python | 85 | 3 | 18 | 106 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/audio/__init__.py | Python | 7 | 0 | 3 | 10 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/audio/codec.py | Python | 25 | 0 | 8 | 33 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/audio/metadata.py | Python | 60 | 4 | 24 | 88 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/connection/__init__.py | Python | 1 | 0 | 1 | 2 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/connection/connection.py | Python | 162 | 1 | 30 | 193 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/connection/rotating.py | Python | 27 | 3 | 14 | 44 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/download/__init__.py | Python | 2 | 0 | 1 | 3 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/download/download.py | Python | 35 | 0 | 14 | 49 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/download/multiple_options.py | Python | 69 | 0 | 31 | 100 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/download/page_attributes.py | Python | 21 | 1 | 10 | 32 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/download/search.py | Python | 130 | 24 | 56 | 210 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/objects/__init__.py | Python | -15 | 0 | -3 | -18 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/objects/album.py | Python | -16 | -6 | -5 | -27 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/objects/option.py | Python | 5 | 0 | 2 | 7 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/objects/parents.py | Python | 3 | 2 | 2 | 7 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/objects/song.py | Python | 37 | 20 | 16 | 73 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/objects/source.py | Python | -30 | -1 | -9 | -40 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/objects/target.py | Python | 5 | 4 | 2 | 11 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/pages/__init__.py | Python | -3 | 0 | -4 | -7 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/pages/abstract.py | Python | -71 | -10 | 0 | -81 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/pages/download_center/__init__.py | Python | -4 | 0 | -2 | -6 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/pages/download_center/download.py | Python | -33 | 0 | -13 | -46 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/pages/download_center/multiple_options.py | Python | -69 | 0 | -31 | -100 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/pages/download_center/page_attributes.py | Python | -24 | -1 | -9 | -34 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/pages/download_center/search.py | Python | -85 | -23 | -38 | -146 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/pages/encyclopaedia_metallum.py | Python | -19 | 7 | 10 | -2 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/pages/musify.py | Python | 65 | 30 | 32 | 127 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/pages/preset.py | Python | 43 | 1 | 16 | 60 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/pages/support_classes/__init__.py | Python | 0 | 0 | -1 | -1 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/pages/support_classes/default_target.py | Python | -55 | 0 | -15 | -70 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/pages/support_classes/download_result.py | Python | -51 | 0 | -15 | -66 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/tagging/__init__.py | Python | -5 | 0 | -2 | -7 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/tagging/id3.py | Python | -60 | -4 | -24 | -88 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/__init__.py | Python | 1 | 0 | 1 | 2 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/config/__init__.py | Python | 7 | 0 | 4 | 11 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/config/audio.py | Python | 152 | 15 | 28 | 195 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/config/base_classes.py | Python | 136 | 35 | 61 | 232 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/config/config.py | Python | 92 | 16 | 30 | 138 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/config/connection.py | Python | 81 | 2 | 15 | 98 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/config/logging.py | Python | 104 | 4 | 17 | 125 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/config/misc.py | Python | 40 | 0 | 9 | 49 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/config/paths.py | Python | 40 | 0 | 13 | 53 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/enums/__init__.py | Python | 0 | 0 | 1 | 1 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/enums/album.py | Python | 16 | 6 | 5 | 27 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/enums/source.py | Python | 40 | 1 | 8 | 49 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/exception/__init__.py | Python | 1 | 0 | 1 | 2 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/exception/config.py | Python | 14 | 8 | 7 | 29 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/path_manager/__init__.py | Python | 2 | 0 | 2 | 4 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/path_manager/config_directory.py | Python | 4 | 0 | 4 | 8 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/path_manager/locations.py | Python | 16 | 0 | 9 | 25 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/path_manager/music_directory.py | Python | 36 | 9 | 14 | 59 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/regex.py | Python | 1 | 0 | 2 | 3 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/shared.py | Python | -12 | -5 | 4 | -13 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/string_processing.py | Python | 6 | 0 | 4 | 10 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/support_classes/__init__.py | Python | 3 | 0 | 1 | 4 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/support_classes/default_target.py | Python | 56 | 0 | 15 | 71 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/support_classes/download_result.py | Python | 69 | 0 | 21 | 90 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/support_classes/query.py | Python | 24 | 0 | 9 | 33 |
|
||||||
|
| Total | | 1,280 | 157 | 437 | 1,874 |
|
||||||
|
+-------------------------------------------------------------------------------------------------+----------+------------+------------+------------+------------+
|
91
.VSCodeCounter/2023-05-24_11-17-57/results.csv
Normal file
91
.VSCodeCounter/2023-05-24_11-17-57/results.csv
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
"filename", "language", "Python", "SQLite", "comment", "blank", "total"
|
||||||
|
"/home/lars/Projects/music-downloader/src/__init__.py", "Python", 0, 0, 0, 1, 1
|
||||||
|
"/home/lars/Projects/music-downloader/src/actual_donwload.py", "Python", 43, 0, 2, 18, 63
|
||||||
|
"/home/lars/Projects/music-downloader/src/create_custom_objects.py", "Python", 58, 0, 0, 6, 64
|
||||||
|
"/home/lars/Projects/music-downloader/src/metal_archives.py", "Python", 30, 0, 0, 12, 42
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/__init__.py", "Python", 189, 0, 21, 60, 270
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/__main__.py", "Python", 88, 0, 3, 21, 112
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/audio/__init__.py", "Python", 7, 0, 0, 3, 10
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/audio/codec.py", "Python", 25, 0, 0, 8, 33
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/audio/metadata.py", "Python", 60, 0, 4, 24, 88
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/connection/__init__.py", "Python", 1, 0, 0, 1, 2
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/connection/connection.py", "Python", 162, 0, 1, 30, 193
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/connection/rotating.py", "Python", 27, 0, 3, 14, 44
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/database/__init__.py", "Python", 0, 0, 0, 1, 1
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/database/data_models.py", "Python", 122, 0, 24, 52, 198
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/database/database.py", "Python", 104, 0, 47, 38, 189
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/download/__init__.py", "Python", 2, 0, 0, 1, 3
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/download/download.py", "Python", 35, 0, 0, 14, 49
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/download/multiple_options.py", "Python", 69, 0, 0, 31, 100
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/download/page_attributes.py", "Python", 21, 0, 1, 10, 32
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/download/search.py", "Python", 130, 0, 24, 56, 210
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/__init__.py", "Python", 0, 0, 0, 3, 3
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/fetch_audio.py", "Python", 75, 0, 12, 20, 107
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/fetch_source.py", "Python", 54, 0, 1, 16, 71
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/metadata/__init__.py", "Python", 6, 0, 0, 2, 8
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/metadata/metadata_fetch.py", "Python", 257, 0, 24, 65, 346
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/metadata/metadata_search.py", "Python", 253, 0, 40, 72, 365
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/metadata/sources/__init__.py", "Python", 3, 0, 0, 2, 5
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/metadata/sources/musicbrainz.py", "Python", 42, 0, 6, 12, 60
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/sources/__init__.py", "Python", 0, 0, 0, 1, 1
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/sources/genius.py", "Python", 115, 0, 16, 42, 173
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/sources/local_files.py", "Python", 40, 0, 0, 18, 58
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/sources/musify.py", "Python", 136, 0, 9, 37, 182
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/sources/source.py", "Python", 11, 0, 5, 8, 24
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/sources/youtube.py", "Python", 71, 0, 4, 24, 99
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/objects/__init__.py", "Python", 14, 0, 0, 5, 19
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/objects/cache.py", "Python", 37, 0, 56, 18, 111
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/objects/collection.py", "Python", 91, 0, 31, 39, 161
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/objects/formatted_text.py", "Python", 50, 0, 10, 19, 79
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/objects/lyrics.py", "Python", 25, 0, 0, 7, 32
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/objects/metadata.py", "Python", 261, 0, 62, 61, 384
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/objects/option.py", "Python", 28, 0, 0, 13, 41
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/objects/parents.py", "Python", 65, 0, 33, 33, 131
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/objects/song.py", "Python", 473, 0, 113, 115, 701
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/objects/source.py", "Python", 90, 0, 16, 32, 138
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/objects/target.py", "Python", 63, 0, 15, 23, 101
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/pages/__init__.py", "Python", 3, 0, 0, 1, 4
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/pages/abstract.py", "Python", 357, 0, 34, 103, 494
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/pages/encyclopaedia_metallum.py", "Python", 432, 0, 90, 127, 649
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/pages/musify.py", "Python", 629, 0, 289, 187, 1105
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/pages/preset.py", "Python", 43, 0, 1, 16, 60
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/pages/youtube.py", "Python", 25, 0, 16, 6, 47
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/static_files/new_db.sql", "SQLite", 0, 72, 0, 10, 82
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/static_files/temp_database_structure.sql", "SQLite", 0, 135, 0, 10, 145
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/__init__.py", "Python", 2, 0, 1, 2, 5
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/config/__init__.py", "Python", 7, 0, 0, 4, 11
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/config/audio.py", "Python", 152, 0, 15, 28, 195
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/config/base_classes.py", "Python", 136, 0, 35, 61, 232
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/config/config.py", "Python", 92, 0, 16, 30, 138
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/config/connection.py", "Python", 81, 0, 2, 15, 98
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/config/logging.py", "Python", 104, 0, 4, 17, 125
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/config/misc.py", "Python", 40, 0, 0, 9, 49
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/config/paths.py", "Python", 40, 0, 0, 13, 53
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/enums/__init__.py", "Python", 0, 0, 0, 1, 1
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/enums/album.py", "Python", 16, 0, 6, 5, 27
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/enums/source.py", "Python", 40, 0, 1, 8, 49
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/exception/__init__.py", "Python", 1, 0, 0, 1, 2
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/exception/config.py", "Python", 14, 0, 8, 7, 29
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/functions.py", "Python", 3, 0, 0, 1, 4
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/object_handeling.py", "Python", 19, 0, 0, 6, 25
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/path_manager/__init__.py", "Python", 2, 0, 0, 2, 4
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/path_manager/config_directory.py", "Python", 4, 0, 0, 4, 8
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/path_manager/locations.py", "Python", 16, 0, 0, 9, 25
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/path_manager/music_directory.py", "Python", 36, 0, 9, 14, 59
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/phonetic_compares.py", "Python", 39, 0, 2, 17, 58
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/regex.py", "Python", 1, 0, 0, 2, 3
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/shared.py", "Python", 63, 0, 22, 21, 106
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/string_processing.py", "Python", 16, 0, 5, 11, 32
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/support_classes/__init__.py", "Python", 3, 0, 0, 1, 4
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/support_classes/default_target.py", "Python", 56, 0, 0, 15, 71
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/support_classes/download_result.py", "Python", 69, 0, 0, 21, 90
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/support_classes/query.py", "Python", 24, 0, 0, 9, 33
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken_cli.py", "Python", 3, 0, 0, 3, 6
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken_gtk.py", "Python", 3, 0, 0, 2, 5
|
||||||
|
"/home/lars/Projects/music-downloader/src/musify_search.py", "Python", 38, 0, 0, 14, 52
|
||||||
|
"/home/lars/Projects/music-downloader/src/tests/__init__.py", "Python", 0, 0, 0, 1, 1
|
||||||
|
"/home/lars/Projects/music-downloader/src/tests/conftest.py", "Python", 3, 0, 1, 2, 6
|
||||||
|
"/home/lars/Projects/music-downloader/src/tests/test_building_objects.py", "Python", 81, 0, 1, 13, 95
|
||||||
|
"/home/lars/Projects/music-downloader/src/tests/test_download.py", "Python", 30, 0, 1, 12, 43
|
||||||
|
"/home/lars/Projects/music-downloader/src/tests/test_objects.py", "Python", 173, 0, 15, 51, 239
|
||||||
|
"Total", "-", 6329, 207, 1157, 1980, 9673
|
|
1
.VSCodeCounter/2023-05-24_11-17-57/results.json
Normal file
1
.VSCodeCounter/2023-05-24_11-17-57/results.json
Normal file
File diff suppressed because one or more lines are too long
46
.VSCodeCounter/2023-05-24_11-17-57/results.md
Normal file
46
.VSCodeCounter/2023-05-24_11-17-57/results.md
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
# Summary
|
||||||
|
|
||||||
|
Date : 2023-05-24 11:17:57
|
||||||
|
|
||||||
|
Directory /home/lars/Projects/music-downloader/src
|
||||||
|
|
||||||
|
Total : 89 files, 6536 codes, 1157 comments, 1980 blanks, all 9673 lines
|
||||||
|
|
||||||
|
Summary / [Details](details.md) / [Diff Summary](diff.md) / [Diff Details](diff-details.md)
|
||||||
|
|
||||||
|
## Languages
|
||||||
|
| language | files | code | comment | blank | total |
|
||||||
|
| :--- | ---: | ---: | ---: | ---: | ---: |
|
||||||
|
| Python | 87 | 6,329 | 1,157 | 1,960 | 9,446 |
|
||||||
|
| SQLite | 2 | 207 | 0 | 20 | 227 |
|
||||||
|
|
||||||
|
## Directories
|
||||||
|
| path | files | code | comment | blank | total |
|
||||||
|
| :--- | ---: | ---: | ---: | ---: | ---: |
|
||||||
|
| . | 89 | 6,536 | 1,157 | 1,980 | 9,673 |
|
||||||
|
| . (Files) | 7 | 175 | 2 | 56 | 233 |
|
||||||
|
| music_kraken | 77 | 6,074 | 1,137 | 1,845 | 9,056 |
|
||||||
|
| music_kraken (Files) | 2 | 277 | 24 | 81 | 382 |
|
||||||
|
| music_kraken/audio | 3 | 92 | 4 | 35 | 131 |
|
||||||
|
| music_kraken/connection | 3 | 190 | 4 | 45 | 239 |
|
||||||
|
| music_kraken/database | 3 | 226 | 71 | 91 | 388 |
|
||||||
|
| music_kraken/download | 5 | 257 | 25 | 112 | 394 |
|
||||||
|
| music_kraken/not_used_anymore | 14 | 1,063 | 117 | 322 | 1,502 |
|
||||||
|
| music_kraken/not_used_anymore (Files) | 3 | 129 | 13 | 39 | 181 |
|
||||||
|
| music_kraken/not_used_anymore/metadata | 5 | 561 | 70 | 153 | 784 |
|
||||||
|
| music_kraken/not_used_anymore/metadata (Files) | 3 | 516 | 64 | 139 | 719 |
|
||||||
|
| music_kraken/not_used_anymore/metadata/sources | 2 | 45 | 6 | 14 | 65 |
|
||||||
|
| music_kraken/not_used_anymore/sources | 6 | 373 | 34 | 130 | 537 |
|
||||||
|
| music_kraken/objects | 11 | 1,197 | 336 | 365 | 1,898 |
|
||||||
|
| music_kraken/pages | 6 | 1,489 | 430 | 440 | 2,359 |
|
||||||
|
| music_kraken/static_files | 2 | 207 | 0 | 20 | 227 |
|
||||||
|
| music_kraken/utils | 28 | 1,076 | 126 | 334 | 1,536 |
|
||||||
|
| music_kraken/utils (Files) | 7 | 143 | 30 | 60 | 233 |
|
||||||
|
| music_kraken/utils/config | 8 | 652 | 72 | 177 | 901 |
|
||||||
|
| music_kraken/utils/enums | 3 | 56 | 7 | 14 | 77 |
|
||||||
|
| music_kraken/utils/exception | 2 | 15 | 8 | 8 | 31 |
|
||||||
|
| music_kraken/utils/path_manager | 4 | 58 | 9 | 29 | 96 |
|
||||||
|
| music_kraken/utils/support_classes | 4 | 152 | 0 | 46 | 198 |
|
||||||
|
| tests | 5 | 287 | 18 | 79 | 384 |
|
||||||
|
|
||||||
|
Summary / [Details](details.md) / [Diff Summary](diff.md) / [Diff Details](diff-details.md)
|
138
.VSCodeCounter/2023-05-24_11-17-57/results.txt
Normal file
138
.VSCodeCounter/2023-05-24_11-17-57/results.txt
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
Date : 2023-05-24 11:17:57
|
||||||
|
Directory : /home/lars/Projects/music-downloader/src
|
||||||
|
Total : 89 files, 6536 codes, 1157 comments, 1980 blanks, all 9673 lines
|
||||||
|
|
||||||
|
Languages
|
||||||
|
+----------+------------+------------+------------+------------+------------+
|
||||||
|
| language | files | code | comment | blank | total |
|
||||||
|
+----------+------------+------------+------------+------------+------------+
|
||||||
|
| Python | 87 | 6,329 | 1,157 | 1,960 | 9,446 |
|
||||||
|
| SQLite | 2 | 207 | 0 | 20 | 227 |
|
||||||
|
+----------+------------+------------+------------+------------+------------+
|
||||||
|
|
||||||
|
Directories
|
||||||
|
+--------------------------------------------------------------------------------------------------------+------------+------------+------------+------------+------------+
|
||||||
|
| path | files | code | comment | blank | total |
|
||||||
|
+--------------------------------------------------------------------------------------------------------+------------+------------+------------+------------+------------+
|
||||||
|
| . | 89 | 6,536 | 1,157 | 1,980 | 9,673 |
|
||||||
|
| . (Files) | 7 | 175 | 2 | 56 | 233 |
|
||||||
|
| music_kraken | 77 | 6,074 | 1,137 | 1,845 | 9,056 |
|
||||||
|
| music_kraken (Files) | 2 | 277 | 24 | 81 | 382 |
|
||||||
|
| music_kraken/audio | 3 | 92 | 4 | 35 | 131 |
|
||||||
|
| music_kraken/connection | 3 | 190 | 4 | 45 | 239 |
|
||||||
|
| music_kraken/database | 3 | 226 | 71 | 91 | 388 |
|
||||||
|
| music_kraken/download | 5 | 257 | 25 | 112 | 394 |
|
||||||
|
| music_kraken/not_used_anymore | 14 | 1,063 | 117 | 322 | 1,502 |
|
||||||
|
| music_kraken/not_used_anymore (Files) | 3 | 129 | 13 | 39 | 181 |
|
||||||
|
| music_kraken/not_used_anymore/metadata | 5 | 561 | 70 | 153 | 784 |
|
||||||
|
| music_kraken/not_used_anymore/metadata (Files) | 3 | 516 | 64 | 139 | 719 |
|
||||||
|
| music_kraken/not_used_anymore/metadata/sources | 2 | 45 | 6 | 14 | 65 |
|
||||||
|
| music_kraken/not_used_anymore/sources | 6 | 373 | 34 | 130 | 537 |
|
||||||
|
| music_kraken/objects | 11 | 1,197 | 336 | 365 | 1,898 |
|
||||||
|
| music_kraken/pages | 6 | 1,489 | 430 | 440 | 2,359 |
|
||||||
|
| music_kraken/static_files | 2 | 207 | 0 | 20 | 227 |
|
||||||
|
| music_kraken/utils | 28 | 1,076 | 126 | 334 | 1,536 |
|
||||||
|
| music_kraken/utils (Files) | 7 | 143 | 30 | 60 | 233 |
|
||||||
|
| music_kraken/utils/config | 8 | 652 | 72 | 177 | 901 |
|
||||||
|
| music_kraken/utils/enums | 3 | 56 | 7 | 14 | 77 |
|
||||||
|
| music_kraken/utils/exception | 2 | 15 | 8 | 8 | 31 |
|
||||||
|
| music_kraken/utils/path_manager | 4 | 58 | 9 | 29 | 96 |
|
||||||
|
| music_kraken/utils/support_classes | 4 | 152 | 0 | 46 | 198 |
|
||||||
|
| tests | 5 | 287 | 18 | 79 | 384 |
|
||||||
|
+--------------------------------------------------------------------------------------------------------+------------+------------+------------+------------+------------+
|
||||||
|
|
||||||
|
Files
|
||||||
|
+--------------------------------------------------------------------------------------------------------+----------+------------+------------+------------+------------+
|
||||||
|
| filename | language | code | comment | blank | total |
|
||||||
|
+--------------------------------------------------------------------------------------------------------+----------+------------+------------+------------+------------+
|
||||||
|
| /home/lars/Projects/music-downloader/src/__init__.py | Python | 0 | 0 | 1 | 1 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/actual_donwload.py | Python | 43 | 2 | 18 | 63 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/create_custom_objects.py | Python | 58 | 0 | 6 | 64 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/metal_archives.py | Python | 30 | 0 | 12 | 42 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/__init__.py | Python | 189 | 21 | 60 | 270 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/__main__.py | Python | 88 | 3 | 21 | 112 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/audio/__init__.py | Python | 7 | 0 | 3 | 10 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/audio/codec.py | Python | 25 | 0 | 8 | 33 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/audio/metadata.py | Python | 60 | 4 | 24 | 88 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/connection/__init__.py | Python | 1 | 0 | 1 | 2 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/connection/connection.py | Python | 162 | 1 | 30 | 193 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/connection/rotating.py | Python | 27 | 3 | 14 | 44 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/database/__init__.py | Python | 0 | 0 | 1 | 1 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/database/data_models.py | Python | 122 | 24 | 52 | 198 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/database/database.py | Python | 104 | 47 | 38 | 189 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/download/__init__.py | Python | 2 | 0 | 1 | 3 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/download/download.py | Python | 35 | 0 | 14 | 49 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/download/multiple_options.py | Python | 69 | 0 | 31 | 100 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/download/page_attributes.py | Python | 21 | 1 | 10 | 32 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/download/search.py | Python | 130 | 24 | 56 | 210 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/__init__.py | Python | 0 | 0 | 3 | 3 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/fetch_audio.py | Python | 75 | 12 | 20 | 107 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/fetch_source.py | Python | 54 | 1 | 16 | 71 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/metadata/__init__.py | Python | 6 | 0 | 2 | 8 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/metadata/metadata_fetch.py | Python | 257 | 24 | 65 | 346 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/metadata/metadata_search.py | Python | 253 | 40 | 72 | 365 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/metadata/sources/__init__.py | Python | 3 | 0 | 2 | 5 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/metadata/sources/musicbrainz.py | Python | 42 | 6 | 12 | 60 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/sources/__init__.py | Python | 0 | 0 | 1 | 1 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/sources/genius.py | Python | 115 | 16 | 42 | 173 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/sources/local_files.py | Python | 40 | 0 | 18 | 58 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/sources/musify.py | Python | 136 | 9 | 37 | 182 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/sources/source.py | Python | 11 | 5 | 8 | 24 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/sources/youtube.py | Python | 71 | 4 | 24 | 99 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/objects/__init__.py | Python | 14 | 0 | 5 | 19 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/objects/cache.py | Python | 37 | 56 | 18 | 111 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/objects/collection.py | Python | 91 | 31 | 39 | 161 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/objects/formatted_text.py | Python | 50 | 10 | 19 | 79 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/objects/lyrics.py | Python | 25 | 0 | 7 | 32 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/objects/metadata.py | Python | 261 | 62 | 61 | 384 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/objects/option.py | Python | 28 | 0 | 13 | 41 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/objects/parents.py | Python | 65 | 33 | 33 | 131 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/objects/song.py | Python | 473 | 113 | 115 | 701 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/objects/source.py | Python | 90 | 16 | 32 | 138 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/objects/target.py | Python | 63 | 15 | 23 | 101 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/pages/__init__.py | Python | 3 | 0 | 1 | 4 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/pages/abstract.py | Python | 357 | 34 | 103 | 494 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/pages/encyclopaedia_metallum.py | Python | 432 | 90 | 127 | 649 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/pages/musify.py | Python | 629 | 289 | 187 | 1,105 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/pages/preset.py | Python | 43 | 1 | 16 | 60 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/pages/youtube.py | Python | 25 | 16 | 6 | 47 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/static_files/new_db.sql | SQLite | 72 | 0 | 10 | 82 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/static_files/temp_database_structure.sql | SQLite | 135 | 0 | 10 | 145 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/__init__.py | Python | 2 | 1 | 2 | 5 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/config/__init__.py | Python | 7 | 0 | 4 | 11 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/config/audio.py | Python | 152 | 15 | 28 | 195 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/config/base_classes.py | Python | 136 | 35 | 61 | 232 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/config/config.py | Python | 92 | 16 | 30 | 138 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/config/connection.py | Python | 81 | 2 | 15 | 98 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/config/logging.py | Python | 104 | 4 | 17 | 125 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/config/misc.py | Python | 40 | 0 | 9 | 49 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/config/paths.py | Python | 40 | 0 | 13 | 53 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/enums/__init__.py | Python | 0 | 0 | 1 | 1 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/enums/album.py | Python | 16 | 6 | 5 | 27 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/enums/source.py | Python | 40 | 1 | 8 | 49 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/exception/__init__.py | Python | 1 | 0 | 1 | 2 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/exception/config.py | Python | 14 | 8 | 7 | 29 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/functions.py | Python | 3 | 0 | 1 | 4 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/object_handeling.py | Python | 19 | 0 | 6 | 25 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/path_manager/__init__.py | Python | 2 | 0 | 2 | 4 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/path_manager/config_directory.py | Python | 4 | 0 | 4 | 8 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/path_manager/locations.py | Python | 16 | 0 | 9 | 25 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/path_manager/music_directory.py | Python | 36 | 9 | 14 | 59 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/phonetic_compares.py | Python | 39 | 2 | 17 | 58 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/regex.py | Python | 1 | 0 | 2 | 3 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/shared.py | Python | 63 | 22 | 21 | 106 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/string_processing.py | Python | 16 | 5 | 11 | 32 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/support_classes/__init__.py | Python | 3 | 0 | 1 | 4 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/support_classes/default_target.py | Python | 56 | 0 | 15 | 71 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/support_classes/download_result.py | Python | 69 | 0 | 21 | 90 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/support_classes/query.py | Python | 24 | 0 | 9 | 33 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken_cli.py | Python | 3 | 0 | 3 | 6 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken_gtk.py | Python | 3 | 0 | 2 | 5 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/musify_search.py | Python | 38 | 0 | 14 | 52 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/tests/__init__.py | Python | 0 | 0 | 1 | 1 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/tests/conftest.py | Python | 3 | 1 | 2 | 6 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/tests/test_building_objects.py | Python | 81 | 1 | 13 | 95 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/tests/test_download.py | Python | 30 | 1 | 12 | 43 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/tests/test_objects.py | Python | 173 | 15 | 51 | 239 |
|
||||||
|
| Total | | 6,536 | 1,157 | 1,980 | 9,673 |
|
||||||
|
+--------------------------------------------------------------------------------------------------------+----------+------------+------------+------------+------------+
|
98
.VSCodeCounter/2023-06-14_07-47-51/details.md
Normal file
98
.VSCodeCounter/2023-06-14_07-47-51/details.md
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
# Details
|
||||||
|
|
||||||
|
Date : 2023-06-14 07:47:51
|
||||||
|
|
||||||
|
Directory /home/lars/Projects/music-downloader/src
|
||||||
|
|
||||||
|
Total : 83 files, 5827 codes, 1152 comments, 1825 blanks, all 8804 lines
|
||||||
|
|
||||||
|
[Summary](results.md) / Details / [Diff Summary](diff.md) / [Diff Details](diff-details.md)
|
||||||
|
|
||||||
|
## Files
|
||||||
|
| filename | language | code | comment | blank | total |
|
||||||
|
| :--- | :--- | ---: | ---: | ---: | ---: |
|
||||||
|
| [src/__init__.py](/src/__init__.py) | Python | 0 | 0 | 1 | 1 |
|
||||||
|
| [src/actual_donwload.py](/src/actual_donwload.py) | Python | 16 | 0 | 6 | 22 |
|
||||||
|
| [src/create_custom_objects.py](/src/create_custom_objects.py) | Python | 58 | 0 | 6 | 64 |
|
||||||
|
| [src/metal_archives.py](/src/metal_archives.py) | Python | 30 | 0 | 12 | 42 |
|
||||||
|
| [src/music_kraken/__init__.py](/src/music_kraken/__init__.py) | Python | 112 | 6 | 33 | 151 |
|
||||||
|
| [src/music_kraken/__main__.py](/src/music_kraken/__main__.py) | Python | 98 | 3 | 23 | 124 |
|
||||||
|
| [src/music_kraken/audio/__init__.py](/src/music_kraken/audio/__init__.py) | Python | 7 | 0 | 3 | 10 |
|
||||||
|
| [src/music_kraken/audio/codec.py](/src/music_kraken/audio/codec.py) | Python | 25 | 0 | 8 | 33 |
|
||||||
|
| [src/music_kraken/audio/metadata.py](/src/music_kraken/audio/metadata.py) | Python | 60 | 4 | 24 | 88 |
|
||||||
|
| [src/music_kraken/cli/__init__.py](/src/music_kraken/cli/__init__.py) | Python | 2 | 0 | 0 | 2 |
|
||||||
|
| [src/music_kraken/cli/download/__init__.py](/src/music_kraken/cli/download/__init__.py) | Python | 0 | 0 | 1 | 1 |
|
||||||
|
| [src/music_kraken/cli/download/shell.py](/src/music_kraken/cli/download/shell.py) | Python | 199 | 86 | 78 | 363 |
|
||||||
|
| [src/music_kraken/cli/options/__init__.py](/src/music_kraken/cli/options/__init__.py) | Python | 3 | 0 | 1 | 4 |
|
||||||
|
| [src/music_kraken/cli/options/invidious/__init__.py](/src/music_kraken/cli/options/invidious/__init__.py) | Python | 0 | 0 | 1 | 1 |
|
||||||
|
| [src/music_kraken/cli/options/invidious/shell.py](/src/music_kraken/cli/options/invidious/shell.py) | Python | 66 | 7 | 28 | 101 |
|
||||||
|
| [src/music_kraken/connection/__init__.py](/src/music_kraken/connection/__init__.py) | Python | 1 | 0 | 1 | 2 |
|
||||||
|
| [src/music_kraken/connection/connection.py](/src/music_kraken/connection/connection.py) | Python | 168 | 1 | 30 | 199 |
|
||||||
|
| [src/music_kraken/connection/rotating.py](/src/music_kraken/connection/rotating.py) | Python | 27 | 3 | 14 | 44 |
|
||||||
|
| [src/music_kraken/database/__init__.py](/src/music_kraken/database/__init__.py) | Python | 0 | 0 | 1 | 1 |
|
||||||
|
| [src/music_kraken/database/data_models.py](/src/music_kraken/database/data_models.py) | Python | 122 | 24 | 52 | 198 |
|
||||||
|
| [src/music_kraken/database/database.py](/src/music_kraken/database/database.py) | Python | 104 | 47 | 38 | 189 |
|
||||||
|
| [src/music_kraken/download/__init__.py](/src/music_kraken/download/__init__.py) | Python | 1 | 0 | 1 | 2 |
|
||||||
|
| [src/music_kraken/download/multiple_options.py](/src/music_kraken/download/multiple_options.py) | Python | 69 | 0 | 31 | 100 |
|
||||||
|
| [src/music_kraken/download/page_attributes.py](/src/music_kraken/download/page_attributes.py) | Python | 67 | 1 | 29 | 97 |
|
||||||
|
| [src/music_kraken/download/results.py](/src/music_kraken/download/results.py) | Python | 62 | 7 | 26 | 95 |
|
||||||
|
| [src/music_kraken/download/search.py](/src/music_kraken/download/search.py) | Python | 124 | 24 | 56 | 204 |
|
||||||
|
| [src/music_kraken/objects/__init__.py](/src/music_kraken/objects/__init__.py) | Python | 14 | 0 | 5 | 19 |
|
||||||
|
| [src/music_kraken/objects/cache.py](/src/music_kraken/objects/cache.py) | Python | 37 | 56 | 18 | 111 |
|
||||||
|
| [src/music_kraken/objects/collection.py](/src/music_kraken/objects/collection.py) | Python | 91 | 31 | 39 | 161 |
|
||||||
|
| [src/music_kraken/objects/formatted_text.py](/src/music_kraken/objects/formatted_text.py) | Python | 50 | 10 | 19 | 79 |
|
||||||
|
| [src/music_kraken/objects/lyrics.py](/src/music_kraken/objects/lyrics.py) | Python | 25 | 0 | 7 | 32 |
|
||||||
|
| [src/music_kraken/objects/metadata.py](/src/music_kraken/objects/metadata.py) | Python | 272 | 62 | 63 | 397 |
|
||||||
|
| [src/music_kraken/objects/option.py](/src/music_kraken/objects/option.py) | Python | 28 | 0 | 13 | 41 |
|
||||||
|
| [src/music_kraken/objects/parents.py](/src/music_kraken/objects/parents.py) | Python | 71 | 35 | 35 | 141 |
|
||||||
|
| [src/music_kraken/objects/song.py](/src/music_kraken/objects/song.py) | Python | 480 | 113 | 120 | 713 |
|
||||||
|
| [src/music_kraken/objects/source.py](/src/music_kraken/objects/source.py) | Python | 93 | 16 | 33 | 142 |
|
||||||
|
| [src/music_kraken/objects/target.py](/src/music_kraken/objects/target.py) | Python | 65 | 15 | 24 | 104 |
|
||||||
|
| [src/music_kraken/pages/__init__.py](/src/music_kraken/pages/__init__.py) | Python | 4 | 0 | 2 | 6 |
|
||||||
|
| [src/music_kraken/pages/abstract.py](/src/music_kraken/pages/abstract.py) | Python | 234 | 46 | 93 | 373 |
|
||||||
|
| [src/music_kraken/pages/encyclopaedia_metallum.py](/src/music_kraken/pages/encyclopaedia_metallum.py) | Python | 432 | 90 | 127 | 649 |
|
||||||
|
| [src/music_kraken/pages/musify.py](/src/music_kraken/pages/musify.py) | Python | 576 | 275 | 166 | 1,017 |
|
||||||
|
| [src/music_kraken/pages/preset.py](/src/music_kraken/pages/preset.py) | Python | 47 | 1 | 17 | 65 |
|
||||||
|
| [src/music_kraken/pages/youtube.py](/src/music_kraken/pages/youtube.py) | Python | 254 | 45 | 79 | 378 |
|
||||||
|
| [src/music_kraken/static_files/new_db.sql](/src/music_kraken/static_files/new_db.sql) | SQLite | 72 | 0 | 10 | 82 |
|
||||||
|
| [src/music_kraken/static_files/temp_database_structure.sql](/src/music_kraken/static_files/temp_database_structure.sql) | SQLite | 135 | 0 | 10 | 145 |
|
||||||
|
| [src/music_kraken/utils/__init__.py](/src/music_kraken/utils/__init__.py) | Python | 2 | 1 | 2 | 5 |
|
||||||
|
| [src/music_kraken/utils/config/__init__.py](/src/music_kraken/utils/config/__init__.py) | Python | 7 | 0 | 4 | 11 |
|
||||||
|
| [src/music_kraken/utils/config/audio.py](/src/music_kraken/utils/config/audio.py) | Python | 152 | 15 | 28 | 195 |
|
||||||
|
| [src/music_kraken/utils/config/base_classes.py](/src/music_kraken/utils/config/base_classes.py) | Python | 136 | 35 | 61 | 232 |
|
||||||
|
| [src/music_kraken/utils/config/config.py](/src/music_kraken/utils/config/config.py) | Python | 92 | 16 | 30 | 138 |
|
||||||
|
| [src/music_kraken/utils/config/connection.py](/src/music_kraken/utils/config/connection.py) | Python | 80 | 2 | 15 | 97 |
|
||||||
|
| [src/music_kraken/utils/config/logging.py](/src/music_kraken/utils/config/logging.py) | Python | 104 | 4 | 17 | 125 |
|
||||||
|
| [src/music_kraken/utils/config/misc.py](/src/music_kraken/utils/config/misc.py) | Python | 40 | 0 | 9 | 49 |
|
||||||
|
| [src/music_kraken/utils/config/paths.py](/src/music_kraken/utils/config/paths.py) | Python | 40 | 0 | 13 | 53 |
|
||||||
|
| [src/music_kraken/utils/enums/__init__.py](/src/music_kraken/utils/enums/__init__.py) | Python | 0 | 0 | 1 | 1 |
|
||||||
|
| [src/music_kraken/utils/enums/album.py](/src/music_kraken/utils/enums/album.py) | Python | 16 | 6 | 5 | 27 |
|
||||||
|
| [src/music_kraken/utils/enums/source.py](/src/music_kraken/utils/enums/source.py) | Python | 40 | 1 | 8 | 49 |
|
||||||
|
| [src/music_kraken/utils/exception/__init__.py](/src/music_kraken/utils/exception/__init__.py) | Python | 1 | 0 | 1 | 2 |
|
||||||
|
| [src/music_kraken/utils/exception/config.py](/src/music_kraken/utils/exception/config.py) | Python | 14 | 8 | 7 | 29 |
|
||||||
|
| [src/music_kraken/utils/exception/download.py](/src/music_kraken/utils/exception/download.py) | Python | 8 | 0 | 4 | 12 |
|
||||||
|
| [src/music_kraken/utils/functions.py](/src/music_kraken/utils/functions.py) | Python | 3 | 0 | 1 | 4 |
|
||||||
|
| [src/music_kraken/utils/object_handeling.py](/src/music_kraken/utils/object_handeling.py) | Python | 19 | 0 | 6 | 25 |
|
||||||
|
| [src/music_kraken/utils/path_manager/__init__.py](/src/music_kraken/utils/path_manager/__init__.py) | Python | 2 | 0 | 2 | 4 |
|
||||||
|
| [src/music_kraken/utils/path_manager/config_directory.py](/src/music_kraken/utils/path_manager/config_directory.py) | Python | 4 | 0 | 4 | 8 |
|
||||||
|
| [src/music_kraken/utils/path_manager/locations.py](/src/music_kraken/utils/path_manager/locations.py) | Python | 16 | 0 | 9 | 25 |
|
||||||
|
| [src/music_kraken/utils/path_manager/music_directory.py](/src/music_kraken/utils/path_manager/music_directory.py) | Python | 36 | 9 | 14 | 59 |
|
||||||
|
| [src/music_kraken/utils/phonetic_compares.py](/src/music_kraken/utils/phonetic_compares.py) | Python | 39 | 2 | 17 | 58 |
|
||||||
|
| [src/music_kraken/utils/regex.py](/src/music_kraken/utils/regex.py) | Python | 1 | 0 | 2 | 3 |
|
||||||
|
| [src/music_kraken/utils/shared.py](/src/music_kraken/utils/shared.py) | Python | 66 | 22 | 22 | 110 |
|
||||||
|
| [src/music_kraken/utils/string_processing.py](/src/music_kraken/utils/string_processing.py) | Python | 16 | 5 | 11 | 32 |
|
||||||
|
| [src/music_kraken/utils/support_classes/__init__.py](/src/music_kraken/utils/support_classes/__init__.py) | Python | 4 | 0 | 1 | 5 |
|
||||||
|
| [src/music_kraken/utils/support_classes/default_target.py](/src/music_kraken/utils/support_classes/default_target.py) | Python | 56 | 0 | 15 | 71 |
|
||||||
|
| [src/music_kraken/utils/support_classes/download_result.py](/src/music_kraken/utils/support_classes/download_result.py) | Python | 69 | 0 | 21 | 90 |
|
||||||
|
| [src/music_kraken/utils/support_classes/query.py](/src/music_kraken/utils/support_classes/query.py) | Python | 24 | 0 | 9 | 33 |
|
||||||
|
| [src/music_kraken/utils/support_classes/thread_classes.py](/src/music_kraken/utils/support_classes/thread_classes.py) | Python | 8 | 0 | 4 | 12 |
|
||||||
|
| [src/music_kraken_cli.py](/src/music_kraken_cli.py) | Python | 3 | 0 | 3 | 6 |
|
||||||
|
| [src/music_kraken_gtk.py](/src/music_kraken_gtk.py) | Python | 3 | 0 | 2 | 5 |
|
||||||
|
| [src/musify_search.py](/src/musify_search.py) | Python | 38 | 0 | 14 | 52 |
|
||||||
|
| [src/tests/__init__.py](/src/tests/__init__.py) | Python | 0 | 0 | 1 | 1 |
|
||||||
|
| [src/tests/conftest.py](/src/tests/conftest.py) | Python | 3 | 1 | 2 | 6 |
|
||||||
|
| [src/tests/test_building_objects.py](/src/tests/test_building_objects.py) | Python | 81 | 1 | 13 | 95 |
|
||||||
|
| [src/tests/test_download.py](/src/tests/test_download.py) | Python | 30 | 1 | 12 | 43 |
|
||||||
|
| [src/tests/test_objects.py](/src/tests/test_objects.py) | Python | 173 | 15 | 51 | 239 |
|
||||||
|
|
||||||
|
[Summary](results.md) / Details / [Diff Summary](diff.md) / [Diff Details](diff-details.md)
|
59
.VSCodeCounter/2023-06-14_07-47-51/diff-details.md
Normal file
59
.VSCodeCounter/2023-06-14_07-47-51/diff-details.md
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
# Diff Details
|
||||||
|
|
||||||
|
Date : 2023-06-14 07:47:51
|
||||||
|
|
||||||
|
Directory /home/lars/Projects/music-downloader/src
|
||||||
|
|
||||||
|
Total : 44 files, -709 codes, -5 comments, -155 blanks, all -869 lines
|
||||||
|
|
||||||
|
[Summary](results.md) / [Details](details.md) / [Diff Summary](diff.md) / Diff Details
|
||||||
|
|
||||||
|
## Files
|
||||||
|
| filename | language | code | comment | blank | total |
|
||||||
|
| :--- | :--- | ---: | ---: | ---: | ---: |
|
||||||
|
| [src/actual_donwload.py](/src/actual_donwload.py) | Python | -27 | -2 | -12 | -41 |
|
||||||
|
| [src/music_kraken/__init__.py](/src/music_kraken/__init__.py) | Python | -77 | -15 | -27 | -119 |
|
||||||
|
| [src/music_kraken/__main__.py](/src/music_kraken/__main__.py) | Python | 10 | 0 | 2 | 12 |
|
||||||
|
| [src/music_kraken/cli/__init__.py](/src/music_kraken/cli/__init__.py) | Python | 2 | 0 | 0 | 2 |
|
||||||
|
| [src/music_kraken/cli/download/__init__.py](/src/music_kraken/cli/download/__init__.py) | Python | 0 | 0 | 1 | 1 |
|
||||||
|
| [src/music_kraken/cli/download/shell.py](/src/music_kraken/cli/download/shell.py) | Python | 199 | 86 | 78 | 363 |
|
||||||
|
| [src/music_kraken/cli/options/__init__.py](/src/music_kraken/cli/options/__init__.py) | Python | 3 | 0 | 1 | 4 |
|
||||||
|
| [src/music_kraken/cli/options/invidious/__init__.py](/src/music_kraken/cli/options/invidious/__init__.py) | Python | 0 | 0 | 1 | 1 |
|
||||||
|
| [src/music_kraken/cli/options/invidious/shell.py](/src/music_kraken/cli/options/invidious/shell.py) | Python | 66 | 7 | 28 | 101 |
|
||||||
|
| [src/music_kraken/connection/connection.py](/src/music_kraken/connection/connection.py) | Python | 6 | 0 | 0 | 6 |
|
||||||
|
| [src/music_kraken/download/__init__.py](/src/music_kraken/download/__init__.py) | Python | -1 | 0 | 0 | -1 |
|
||||||
|
| [src/music_kraken/download/download.py](/src/music_kraken/download/download.py) | Python | -35 | 0 | -14 | -49 |
|
||||||
|
| [src/music_kraken/download/page_attributes.py](/src/music_kraken/download/page_attributes.py) | Python | 46 | 0 | 19 | 65 |
|
||||||
|
| [src/music_kraken/download/results.py](/src/music_kraken/download/results.py) | Python | 62 | 7 | 26 | 95 |
|
||||||
|
| [src/music_kraken/download/search.py](/src/music_kraken/download/search.py) | Python | -6 | 0 | 0 | -6 |
|
||||||
|
| [src/music_kraken/not_used_anymore/__init__.py](/src/music_kraken/not_used_anymore/__init__.py) | Python | 0 | 0 | -3 | -3 |
|
||||||
|
| [src/music_kraken/not_used_anymore/fetch_audio.py](/src/music_kraken/not_used_anymore/fetch_audio.py) | Python | -75 | -12 | -20 | -107 |
|
||||||
|
| [src/music_kraken/not_used_anymore/fetch_source.py](/src/music_kraken/not_used_anymore/fetch_source.py) | Python | -54 | -1 | -16 | -71 |
|
||||||
|
| [src/music_kraken/not_used_anymore/metadata/__init__.py](/src/music_kraken/not_used_anymore/metadata/__init__.py) | Python | -6 | 0 | -2 | -8 |
|
||||||
|
| [src/music_kraken/not_used_anymore/metadata/metadata_fetch.py](/src/music_kraken/not_used_anymore/metadata/metadata_fetch.py) | Python | -257 | -24 | -65 | -346 |
|
||||||
|
| [src/music_kraken/not_used_anymore/metadata/metadata_search.py](/src/music_kraken/not_used_anymore/metadata/metadata_search.py) | Python | -253 | -40 | -72 | -365 |
|
||||||
|
| [src/music_kraken/not_used_anymore/metadata/sources/__init__.py](/src/music_kraken/not_used_anymore/metadata/sources/__init__.py) | Python | -3 | 0 | -2 | -5 |
|
||||||
|
| [src/music_kraken/not_used_anymore/metadata/sources/musicbrainz.py](/src/music_kraken/not_used_anymore/metadata/sources/musicbrainz.py) | Python | -42 | -6 | -12 | -60 |
|
||||||
|
| [src/music_kraken/not_used_anymore/sources/__init__.py](/src/music_kraken/not_used_anymore/sources/__init__.py) | Python | 0 | 0 | -1 | -1 |
|
||||||
|
| [src/music_kraken/not_used_anymore/sources/genius.py](/src/music_kraken/not_used_anymore/sources/genius.py) | Python | -115 | -16 | -42 | -173 |
|
||||||
|
| [src/music_kraken/not_used_anymore/sources/local_files.py](/src/music_kraken/not_used_anymore/sources/local_files.py) | Python | -40 | 0 | -18 | -58 |
|
||||||
|
| [src/music_kraken/not_used_anymore/sources/musify.py](/src/music_kraken/not_used_anymore/sources/musify.py) | Python | -136 | -9 | -37 | -182 |
|
||||||
|
| [src/music_kraken/not_used_anymore/sources/source.py](/src/music_kraken/not_used_anymore/sources/source.py) | Python | -11 | -5 | -8 | -24 |
|
||||||
|
| [src/music_kraken/not_used_anymore/sources/youtube.py](/src/music_kraken/not_used_anymore/sources/youtube.py) | Python | -71 | -4 | -24 | -99 |
|
||||||
|
| [src/music_kraken/objects/metadata.py](/src/music_kraken/objects/metadata.py) | Python | 11 | 0 | 2 | 13 |
|
||||||
|
| [src/music_kraken/objects/parents.py](/src/music_kraken/objects/parents.py) | Python | 6 | 2 | 2 | 10 |
|
||||||
|
| [src/music_kraken/objects/song.py](/src/music_kraken/objects/song.py) | Python | 7 | 0 | 5 | 12 |
|
||||||
|
| [src/music_kraken/objects/source.py](/src/music_kraken/objects/source.py) | Python | 3 | 0 | 1 | 4 |
|
||||||
|
| [src/music_kraken/objects/target.py](/src/music_kraken/objects/target.py) | Python | 2 | 0 | 1 | 3 |
|
||||||
|
| [src/music_kraken/pages/__init__.py](/src/music_kraken/pages/__init__.py) | Python | 1 | 0 | 1 | 2 |
|
||||||
|
| [src/music_kraken/pages/abstract.py](/src/music_kraken/pages/abstract.py) | Python | -123 | 12 | -10 | -121 |
|
||||||
|
| [src/music_kraken/pages/musify.py](/src/music_kraken/pages/musify.py) | Python | -53 | -14 | -21 | -88 |
|
||||||
|
| [src/music_kraken/pages/preset.py](/src/music_kraken/pages/preset.py) | Python | 4 | 0 | 1 | 5 |
|
||||||
|
| [src/music_kraken/pages/youtube.py](/src/music_kraken/pages/youtube.py) | Python | 229 | 29 | 73 | 331 |
|
||||||
|
| [src/music_kraken/utils/config/connection.py](/src/music_kraken/utils/config/connection.py) | Python | -1 | 0 | 0 | -1 |
|
||||||
|
| [src/music_kraken/utils/exception/download.py](/src/music_kraken/utils/exception/download.py) | Python | 8 | 0 | 4 | 12 |
|
||||||
|
| [src/music_kraken/utils/shared.py](/src/music_kraken/utils/shared.py) | Python | 3 | 0 | 1 | 4 |
|
||||||
|
| [src/music_kraken/utils/support_classes/__init__.py](/src/music_kraken/utils/support_classes/__init__.py) | Python | 1 | 0 | 0 | 1 |
|
||||||
|
| [src/music_kraken/utils/support_classes/thread_classes.py](/src/music_kraken/utils/support_classes/thread_classes.py) | Python | 8 | 0 | 4 | 12 |
|
||||||
|
|
||||||
|
[Summary](results.md) / [Details](details.md) / [Diff Summary](diff.md) / Diff Details
|
46
.VSCodeCounter/2023-06-14_07-47-51/diff.csv
Normal file
46
.VSCodeCounter/2023-06-14_07-47-51/diff.csv
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
"filename", "language", "Python", "comment", "blank", "total"
|
||||||
|
"/home/lars/Projects/music-downloader/src/actual_donwload.py", "Python", -27, -2, -12, -41
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/__init__.py", "Python", -77, -15, -27, -119
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/__main__.py", "Python", 10, 0, 2, 12
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/cli/__init__.py", "Python", 2, 0, 0, 2
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/cli/download/__init__.py", "Python", 0, 0, 1, 1
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/cli/download/shell.py", "Python", 199, 86, 78, 363
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/cli/options/__init__.py", "Python", 3, 0, 1, 4
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/cli/options/invidious/__init__.py", "Python", 0, 0, 1, 1
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/cli/options/invidious/shell.py", "Python", 66, 7, 28, 101
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/connection/connection.py", "Python", 6, 0, 0, 6
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/download/__init__.py", "Python", -1, 0, 0, -1
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/download/download.py", "Python", -35, 0, -14, -49
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/download/page_attributes.py", "Python", 46, 0, 19, 65
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/download/results.py", "Python", 62, 7, 26, 95
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/download/search.py", "Python", -6, 0, 0, -6
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/__init__.py", "Python", 0, 0, -3, -3
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/fetch_audio.py", "Python", -75, -12, -20, -107
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/fetch_source.py", "Python", -54, -1, -16, -71
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/metadata/__init__.py", "Python", -6, 0, -2, -8
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/metadata/metadata_fetch.py", "Python", -257, -24, -65, -346
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/metadata/metadata_search.py", "Python", -253, -40, -72, -365
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/metadata/sources/__init__.py", "Python", -3, 0, -2, -5
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/metadata/sources/musicbrainz.py", "Python", -42, -6, -12, -60
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/sources/__init__.py", "Python", 0, 0, -1, -1
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/sources/genius.py", "Python", -115, -16, -42, -173
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/sources/local_files.py", "Python", -40, 0, -18, -58
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/sources/musify.py", "Python", -136, -9, -37, -182
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/sources/source.py", "Python", -11, -5, -8, -24
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/sources/youtube.py", "Python", -71, -4, -24, -99
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/objects/metadata.py", "Python", 11, 0, 2, 13
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/objects/parents.py", "Python", 6, 2, 2, 10
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/objects/song.py", "Python", 7, 0, 5, 12
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/objects/source.py", "Python", 3, 0, 1, 4
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/objects/target.py", "Python", 2, 0, 1, 3
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/pages/__init__.py", "Python", 1, 0, 1, 2
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/pages/abstract.py", "Python", -123, 12, -10, -121
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/pages/musify.py", "Python", -53, -14, -21, -88
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/pages/preset.py", "Python", 4, 0, 1, 5
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/pages/youtube.py", "Python", 229, 29, 73, 331
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/config/connection.py", "Python", -1, 0, 0, -1
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/exception/download.py", "Python", 8, 0, 4, 12
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/shared.py", "Python", 3, 0, 1, 4
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/support_classes/__init__.py", "Python", 1, 0, 0, 1
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/support_classes/thread_classes.py", "Python", 8, 0, 4, 12
|
||||||
|
"Total", "-", -709, -5, -155, -869
|
|
45
.VSCodeCounter/2023-06-14_07-47-51/diff.md
Normal file
45
.VSCodeCounter/2023-06-14_07-47-51/diff.md
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
# Diff Summary
|
||||||
|
|
||||||
|
Date : 2023-06-14 07:47:51
|
||||||
|
|
||||||
|
Directory /home/lars/Projects/music-downloader/src
|
||||||
|
|
||||||
|
Total : 44 files, -709 codes, -5 comments, -155 blanks, all -869 lines
|
||||||
|
|
||||||
|
[Summary](results.md) / [Details](details.md) / Diff Summary / [Diff Details](diff-details.md)
|
||||||
|
|
||||||
|
## Languages
|
||||||
|
| language | files | code | comment | blank | total |
|
||||||
|
| :--- | ---: | ---: | ---: | ---: | ---: |
|
||||||
|
| Python | 44 | -709 | -5 | -155 | -869 |
|
||||||
|
|
||||||
|
## Directories
|
||||||
|
| path | files | code | comment | blank | total |
|
||||||
|
| :--- | ---: | ---: | ---: | ---: | ---: |
|
||||||
|
| . | 44 | -709 | -5 | -155 | -869 |
|
||||||
|
| . (Files) | 1 | -27 | -2 | -12 | -41 |
|
||||||
|
| music_kraken | 43 | -682 | -3 | -143 | -828 |
|
||||||
|
| music_kraken (Files) | 2 | -67 | -15 | -25 | -107 |
|
||||||
|
| music_kraken/cli | 6 | 270 | 93 | 109 | 472 |
|
||||||
|
| music_kraken/cli (Files) | 1 | 2 | 0 | 0 | 2 |
|
||||||
|
| music_kraken/cli/download | 2 | 199 | 86 | 79 | 364 |
|
||||||
|
| music_kraken/cli/options | 3 | 69 | 7 | 30 | 106 |
|
||||||
|
| music_kraken/cli/options (Files) | 1 | 3 | 0 | 1 | 4 |
|
||||||
|
| music_kraken/cli/options/invidious | 2 | 66 | 7 | 29 | 102 |
|
||||||
|
| music_kraken/connection | 1 | 6 | 0 | 0 | 6 |
|
||||||
|
| music_kraken/download | 5 | 66 | 7 | 31 | 104 |
|
||||||
|
| music_kraken/not_used_anymore | 14 | -1,063 | -117 | -322 | -1,502 |
|
||||||
|
| music_kraken/not_used_anymore (Files) | 3 | -129 | -13 | -39 | -181 |
|
||||||
|
| music_kraken/not_used_anymore/metadata | 5 | -561 | -70 | -153 | -784 |
|
||||||
|
| music_kraken/not_used_anymore/metadata (Files) | 3 | -516 | -64 | -139 | -719 |
|
||||||
|
| music_kraken/not_used_anymore/metadata/sources | 2 | -45 | -6 | -14 | -65 |
|
||||||
|
| music_kraken/not_used_anymore/sources | 6 | -373 | -34 | -130 | -537 |
|
||||||
|
| music_kraken/objects | 5 | 29 | 2 | 11 | 42 |
|
||||||
|
| music_kraken/pages | 5 | 58 | 27 | 44 | 129 |
|
||||||
|
| music_kraken/utils | 5 | 19 | 0 | 9 | 28 |
|
||||||
|
| music_kraken/utils (Files) | 1 | 3 | 0 | 1 | 4 |
|
||||||
|
| music_kraken/utils/config | 1 | -1 | 0 | 0 | -1 |
|
||||||
|
| music_kraken/utils/exception | 1 | 8 | 0 | 4 | 12 |
|
||||||
|
| music_kraken/utils/support_classes | 2 | 9 | 0 | 4 | 13 |
|
||||||
|
|
||||||
|
[Summary](results.md) / [Details](details.md) / Diff Summary / [Diff Details](diff-details.md)
|
92
.VSCodeCounter/2023-06-14_07-47-51/diff.txt
Normal file
92
.VSCodeCounter/2023-06-14_07-47-51/diff.txt
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
Date : 2023-06-14 07:47:51
|
||||||
|
Directory : /home/lars/Projects/music-downloader/src
|
||||||
|
Total : 44 files, -709 codes, -5 comments, -155 blanks, all -869 lines
|
||||||
|
|
||||||
|
Languages
|
||||||
|
+----------+------------+------------+------------+------------+------------+
|
||||||
|
| language | files | code | comment | blank | total |
|
||||||
|
+----------+------------+------------+------------+------------+------------+
|
||||||
|
| Python | 44 | -709 | -5 | -155 | -869 |
|
||||||
|
+----------+------------+------------+------------+------------+------------+
|
||||||
|
|
||||||
|
Directories
|
||||||
|
+--------------------------------------------------------------------------------------------------------+------------+------------+------------+------------+------------+
|
||||||
|
| path | files | code | comment | blank | total |
|
||||||
|
+--------------------------------------------------------------------------------------------------------+------------+------------+------------+------------+------------+
|
||||||
|
| . | 44 | -709 | -5 | -155 | -869 |
|
||||||
|
| . (Files) | 1 | -27 | -2 | -12 | -41 |
|
||||||
|
| music_kraken | 43 | -682 | -3 | -143 | -828 |
|
||||||
|
| music_kraken (Files) | 2 | -67 | -15 | -25 | -107 |
|
||||||
|
| music_kraken/cli | 6 | 270 | 93 | 109 | 472 |
|
||||||
|
| music_kraken/cli (Files) | 1 | 2 | 0 | 0 | 2 |
|
||||||
|
| music_kraken/cli/download | 2 | 199 | 86 | 79 | 364 |
|
||||||
|
| music_kraken/cli/options | 3 | 69 | 7 | 30 | 106 |
|
||||||
|
| music_kraken/cli/options (Files) | 1 | 3 | 0 | 1 | 4 |
|
||||||
|
| music_kraken/cli/options/invidious | 2 | 66 | 7 | 29 | 102 |
|
||||||
|
| music_kraken/connection | 1 | 6 | 0 | 0 | 6 |
|
||||||
|
| music_kraken/download | 5 | 66 | 7 | 31 | 104 |
|
||||||
|
| music_kraken/not_used_anymore | 14 | -1,063 | -117 | -322 | -1,502 |
|
||||||
|
| music_kraken/not_used_anymore (Files) | 3 | -129 | -13 | -39 | -181 |
|
||||||
|
| music_kraken/not_used_anymore/metadata | 5 | -561 | -70 | -153 | -784 |
|
||||||
|
| music_kraken/not_used_anymore/metadata (Files) | 3 | -516 | -64 | -139 | -719 |
|
||||||
|
| music_kraken/not_used_anymore/metadata/sources | 2 | -45 | -6 | -14 | -65 |
|
||||||
|
| music_kraken/not_used_anymore/sources | 6 | -373 | -34 | -130 | -537 |
|
||||||
|
| music_kraken/objects | 5 | 29 | 2 | 11 | 42 |
|
||||||
|
| music_kraken/pages | 5 | 58 | 27 | 44 | 129 |
|
||||||
|
| music_kraken/utils | 5 | 19 | 0 | 9 | 28 |
|
||||||
|
| music_kraken/utils (Files) | 1 | 3 | 0 | 1 | 4 |
|
||||||
|
| music_kraken/utils/config | 1 | -1 | 0 | 0 | -1 |
|
||||||
|
| music_kraken/utils/exception | 1 | 8 | 0 | 4 | 12 |
|
||||||
|
| music_kraken/utils/support_classes | 2 | 9 | 0 | 4 | 13 |
|
||||||
|
+--------------------------------------------------------------------------------------------------------+------------+------------+------------+------------+------------+
|
||||||
|
|
||||||
|
Files
|
||||||
|
+--------------------------------------------------------------------------------------------------------+----------+------------+------------+------------+------------+
|
||||||
|
| filename | language | code | comment | blank | total |
|
||||||
|
+--------------------------------------------------------------------------------------------------------+----------+------------+------------+------------+------------+
|
||||||
|
| /home/lars/Projects/music-downloader/src/actual_donwload.py | Python | -27 | -2 | -12 | -41 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/__init__.py | Python | -77 | -15 | -27 | -119 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/__main__.py | Python | 10 | 0 | 2 | 12 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/cli/__init__.py | Python | 2 | 0 | 0 | 2 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/cli/download/__init__.py | Python | 0 | 0 | 1 | 1 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/cli/download/shell.py | Python | 199 | 86 | 78 | 363 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/cli/options/__init__.py | Python | 3 | 0 | 1 | 4 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/cli/options/invidious/__init__.py | Python | 0 | 0 | 1 | 1 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/cli/options/invidious/shell.py | Python | 66 | 7 | 28 | 101 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/connection/connection.py | Python | 6 | 0 | 0 | 6 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/download/__init__.py | Python | -1 | 0 | 0 | -1 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/download/download.py | Python | -35 | 0 | -14 | -49 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/download/page_attributes.py | Python | 46 | 0 | 19 | 65 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/download/results.py | Python | 62 | 7 | 26 | 95 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/download/search.py | Python | -6 | 0 | 0 | -6 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/__init__.py | Python | 0 | 0 | -3 | -3 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/fetch_audio.py | Python | -75 | -12 | -20 | -107 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/fetch_source.py | Python | -54 | -1 | -16 | -71 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/metadata/__init__.py | Python | -6 | 0 | -2 | -8 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/metadata/metadata_fetch.py | Python | -257 | -24 | -65 | -346 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/metadata/metadata_search.py | Python | -253 | -40 | -72 | -365 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/metadata/sources/__init__.py | Python | -3 | 0 | -2 | -5 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/metadata/sources/musicbrainz.py | Python | -42 | -6 | -12 | -60 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/sources/__init__.py | Python | 0 | 0 | -1 | -1 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/sources/genius.py | Python | -115 | -16 | -42 | -173 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/sources/local_files.py | Python | -40 | 0 | -18 | -58 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/sources/musify.py | Python | -136 | -9 | -37 | -182 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/sources/source.py | Python | -11 | -5 | -8 | -24 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/not_used_anymore/sources/youtube.py | Python | -71 | -4 | -24 | -99 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/objects/metadata.py | Python | 11 | 0 | 2 | 13 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/objects/parents.py | Python | 6 | 2 | 2 | 10 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/objects/song.py | Python | 7 | 0 | 5 | 12 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/objects/source.py | Python | 3 | 0 | 1 | 4 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/objects/target.py | Python | 2 | 0 | 1 | 3 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/pages/__init__.py | Python | 1 | 0 | 1 | 2 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/pages/abstract.py | Python | -123 | 12 | -10 | -121 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/pages/musify.py | Python | -53 | -14 | -21 | -88 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/pages/preset.py | Python | 4 | 0 | 1 | 5 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/pages/youtube.py | Python | 229 | 29 | 73 | 331 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/config/connection.py | Python | -1 | 0 | 0 | -1 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/exception/download.py | Python | 8 | 0 | 4 | 12 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/shared.py | Python | 3 | 0 | 1 | 4 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/support_classes/__init__.py | Python | 1 | 0 | 0 | 1 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/support_classes/thread_classes.py | Python | 8 | 0 | 4 | 12 |
|
||||||
|
| Total | | -709 | -5 | -155 | -869 |
|
||||||
|
+--------------------------------------------------------------------------------------------------------+----------+------------+------------+------------+------------+
|
85
.VSCodeCounter/2023-06-14_07-47-51/results.csv
Normal file
85
.VSCodeCounter/2023-06-14_07-47-51/results.csv
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
"filename", "language", "Python", "SQLite", "comment", "blank", "total"
|
||||||
|
"/home/lars/Projects/music-downloader/src/__init__.py", "Python", 0, 0, 0, 1, 1
|
||||||
|
"/home/lars/Projects/music-downloader/src/actual_donwload.py", "Python", 16, 0, 0, 6, 22
|
||||||
|
"/home/lars/Projects/music-downloader/src/create_custom_objects.py", "Python", 58, 0, 0, 6, 64
|
||||||
|
"/home/lars/Projects/music-downloader/src/metal_archives.py", "Python", 30, 0, 0, 12, 42
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/__init__.py", "Python", 112, 0, 6, 33, 151
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/__main__.py", "Python", 98, 0, 3, 23, 124
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/audio/__init__.py", "Python", 7, 0, 0, 3, 10
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/audio/codec.py", "Python", 25, 0, 0, 8, 33
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/audio/metadata.py", "Python", 60, 0, 4, 24, 88
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/cli/__init__.py", "Python", 2, 0, 0, 0, 2
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/cli/download/__init__.py", "Python", 0, 0, 0, 1, 1
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/cli/download/shell.py", "Python", 199, 0, 86, 78, 363
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/cli/options/__init__.py", "Python", 3, 0, 0, 1, 4
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/cli/options/invidious/__init__.py", "Python", 0, 0, 0, 1, 1
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/cli/options/invidious/shell.py", "Python", 66, 0, 7, 28, 101
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/connection/__init__.py", "Python", 1, 0, 0, 1, 2
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/connection/connection.py", "Python", 168, 0, 1, 30, 199
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/connection/rotating.py", "Python", 27, 0, 3, 14, 44
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/database/__init__.py", "Python", 0, 0, 0, 1, 1
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/database/data_models.py", "Python", 122, 0, 24, 52, 198
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/database/database.py", "Python", 104, 0, 47, 38, 189
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/download/__init__.py", "Python", 1, 0, 0, 1, 2
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/download/multiple_options.py", "Python", 69, 0, 0, 31, 100
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/download/page_attributes.py", "Python", 67, 0, 1, 29, 97
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/download/results.py", "Python", 62, 0, 7, 26, 95
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/download/search.py", "Python", 124, 0, 24, 56, 204
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/objects/__init__.py", "Python", 14, 0, 0, 5, 19
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/objects/cache.py", "Python", 37, 0, 56, 18, 111
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/objects/collection.py", "Python", 91, 0, 31, 39, 161
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/objects/formatted_text.py", "Python", 50, 0, 10, 19, 79
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/objects/lyrics.py", "Python", 25, 0, 0, 7, 32
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/objects/metadata.py", "Python", 272, 0, 62, 63, 397
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/objects/option.py", "Python", 28, 0, 0, 13, 41
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/objects/parents.py", "Python", 71, 0, 35, 35, 141
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/objects/song.py", "Python", 480, 0, 113, 120, 713
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/objects/source.py", "Python", 93, 0, 16, 33, 142
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/objects/target.py", "Python", 65, 0, 15, 24, 104
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/pages/__init__.py", "Python", 4, 0, 0, 2, 6
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/pages/abstract.py", "Python", 234, 0, 46, 93, 373
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/pages/encyclopaedia_metallum.py", "Python", 432, 0, 90, 127, 649
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/pages/musify.py", "Python", 576, 0, 275, 166, 1017
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/pages/preset.py", "Python", 47, 0, 1, 17, 65
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/pages/youtube.py", "Python", 254, 0, 45, 79, 378
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/static_files/new_db.sql", "SQLite", 0, 72, 0, 10, 82
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/static_files/temp_database_structure.sql", "SQLite", 0, 135, 0, 10, 145
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/__init__.py", "Python", 2, 0, 1, 2, 5
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/config/__init__.py", "Python", 7, 0, 0, 4, 11
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/config/audio.py", "Python", 152, 0, 15, 28, 195
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/config/base_classes.py", "Python", 136, 0, 35, 61, 232
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/config/config.py", "Python", 92, 0, 16, 30, 138
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/config/connection.py", "Python", 80, 0, 2, 15, 97
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/config/logging.py", "Python", 104, 0, 4, 17, 125
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/config/misc.py", "Python", 40, 0, 0, 9, 49
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/config/paths.py", "Python", 40, 0, 0, 13, 53
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/enums/__init__.py", "Python", 0, 0, 0, 1, 1
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/enums/album.py", "Python", 16, 0, 6, 5, 27
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/enums/source.py", "Python", 40, 0, 1, 8, 49
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/exception/__init__.py", "Python", 1, 0, 0, 1, 2
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/exception/config.py", "Python", 14, 0, 8, 7, 29
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/exception/download.py", "Python", 8, 0, 0, 4, 12
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/functions.py", "Python", 3, 0, 0, 1, 4
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/object_handeling.py", "Python", 19, 0, 0, 6, 25
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/path_manager/__init__.py", "Python", 2, 0, 0, 2, 4
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/path_manager/config_directory.py", "Python", 4, 0, 0, 4, 8
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/path_manager/locations.py", "Python", 16, 0, 0, 9, 25
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/path_manager/music_directory.py", "Python", 36, 0, 9, 14, 59
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/phonetic_compares.py", "Python", 39, 0, 2, 17, 58
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/regex.py", "Python", 1, 0, 0, 2, 3
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/shared.py", "Python", 66, 0, 22, 22, 110
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/string_processing.py", "Python", 16, 0, 5, 11, 32
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/support_classes/__init__.py", "Python", 4, 0, 0, 1, 5
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/support_classes/default_target.py", "Python", 56, 0, 0, 15, 71
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/support_classes/download_result.py", "Python", 69, 0, 0, 21, 90
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/support_classes/query.py", "Python", 24, 0, 0, 9, 33
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken/utils/support_classes/thread_classes.py", "Python", 8, 0, 0, 4, 12
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken_cli.py", "Python", 3, 0, 0, 3, 6
|
||||||
|
"/home/lars/Projects/music-downloader/src/music_kraken_gtk.py", "Python", 3, 0, 0, 2, 5
|
||||||
|
"/home/lars/Projects/music-downloader/src/musify_search.py", "Python", 38, 0, 0, 14, 52
|
||||||
|
"/home/lars/Projects/music-downloader/src/tests/__init__.py", "Python", 0, 0, 0, 1, 1
|
||||||
|
"/home/lars/Projects/music-downloader/src/tests/conftest.py", "Python", 3, 0, 1, 2, 6
|
||||||
|
"/home/lars/Projects/music-downloader/src/tests/test_building_objects.py", "Python", 81, 0, 1, 13, 95
|
||||||
|
"/home/lars/Projects/music-downloader/src/tests/test_download.py", "Python", 30, 0, 1, 12, 43
|
||||||
|
"/home/lars/Projects/music-downloader/src/tests/test_objects.py", "Python", 173, 0, 15, 51, 239
|
||||||
|
"Total", "-", 5620, 207, 1152, 1825, 8804
|
|
1
.VSCodeCounter/2023-06-14_07-47-51/results.json
Normal file
1
.VSCodeCounter/2023-06-14_07-47-51/results.json
Normal file
File diff suppressed because one or more lines are too long
46
.VSCodeCounter/2023-06-14_07-47-51/results.md
Normal file
46
.VSCodeCounter/2023-06-14_07-47-51/results.md
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
# Summary
|
||||||
|
|
||||||
|
Date : 2023-06-14 07:47:51
|
||||||
|
|
||||||
|
Directory /home/lars/Projects/music-downloader/src
|
||||||
|
|
||||||
|
Total : 83 files, 5827 codes, 1152 comments, 1825 blanks, all 8804 lines
|
||||||
|
|
||||||
|
Summary / [Details](details.md) / [Diff Summary](diff.md) / [Diff Details](diff-details.md)
|
||||||
|
|
||||||
|
## Languages
|
||||||
|
| language | files | code | comment | blank | total |
|
||||||
|
| :--- | ---: | ---: | ---: | ---: | ---: |
|
||||||
|
| Python | 81 | 5,620 | 1,152 | 1,805 | 8,577 |
|
||||||
|
| SQLite | 2 | 207 | 0 | 20 | 227 |
|
||||||
|
|
||||||
|
## Directories
|
||||||
|
| path | files | code | comment | blank | total |
|
||||||
|
| :--- | ---: | ---: | ---: | ---: | ---: |
|
||||||
|
| . | 83 | 5,827 | 1,152 | 1,825 | 8,804 |
|
||||||
|
| . (Files) | 7 | 148 | 0 | 44 | 192 |
|
||||||
|
| music_kraken | 71 | 5,392 | 1,134 | 1,702 | 8,228 |
|
||||||
|
| music_kraken (Files) | 2 | 210 | 9 | 56 | 275 |
|
||||||
|
| music_kraken/audio | 3 | 92 | 4 | 35 | 131 |
|
||||||
|
| music_kraken/cli | 6 | 270 | 93 | 109 | 472 |
|
||||||
|
| music_kraken/cli (Files) | 1 | 2 | 0 | 0 | 2 |
|
||||||
|
| music_kraken/cli/download | 2 | 199 | 86 | 79 | 364 |
|
||||||
|
| music_kraken/cli/options | 3 | 69 | 7 | 30 | 106 |
|
||||||
|
| music_kraken/cli/options (Files) | 1 | 3 | 0 | 1 | 4 |
|
||||||
|
| music_kraken/cli/options/invidious | 2 | 66 | 7 | 29 | 102 |
|
||||||
|
| music_kraken/connection | 3 | 196 | 4 | 45 | 245 |
|
||||||
|
| music_kraken/database | 3 | 226 | 71 | 91 | 388 |
|
||||||
|
| music_kraken/download | 5 | 323 | 32 | 143 | 498 |
|
||||||
|
| music_kraken/objects | 11 | 1,226 | 338 | 376 | 1,940 |
|
||||||
|
| music_kraken/pages | 6 | 1,547 | 457 | 484 | 2,488 |
|
||||||
|
| music_kraken/static_files | 2 | 207 | 0 | 20 | 227 |
|
||||||
|
| music_kraken/utils | 30 | 1,095 | 126 | 343 | 1,564 |
|
||||||
|
| music_kraken/utils (Files) | 7 | 146 | 30 | 61 | 237 |
|
||||||
|
| music_kraken/utils/config | 8 | 651 | 72 | 177 | 900 |
|
||||||
|
| music_kraken/utils/enums | 3 | 56 | 7 | 14 | 77 |
|
||||||
|
| music_kraken/utils/exception | 3 | 23 | 8 | 12 | 43 |
|
||||||
|
| music_kraken/utils/path_manager | 4 | 58 | 9 | 29 | 96 |
|
||||||
|
| music_kraken/utils/support_classes | 5 | 161 | 0 | 50 | 211 |
|
||||||
|
| tests | 5 | 287 | 18 | 79 | 384 |
|
||||||
|
|
||||||
|
Summary / [Details](details.md) / [Diff Summary](diff.md) / [Diff Details](diff-details.md)
|
132
.VSCodeCounter/2023-06-14_07-47-51/results.txt
Normal file
132
.VSCodeCounter/2023-06-14_07-47-51/results.txt
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
Date : 2023-06-14 07:47:51
|
||||||
|
Directory : /home/lars/Projects/music-downloader/src
|
||||||
|
Total : 83 files, 5827 codes, 1152 comments, 1825 blanks, all 8804 lines
|
||||||
|
|
||||||
|
Languages
|
||||||
|
+----------+------------+------------+------------+------------+------------+
|
||||||
|
| language | files | code | comment | blank | total |
|
||||||
|
+----------+------------+------------+------------+------------+------------+
|
||||||
|
| Python | 81 | 5,620 | 1,152 | 1,805 | 8,577 |
|
||||||
|
| SQLite | 2 | 207 | 0 | 20 | 227 |
|
||||||
|
+----------+------------+------------+------------+------------+------------+
|
||||||
|
|
||||||
|
Directories
|
||||||
|
+------------------------------------------------------------------------------------------------+------------+------------+------------+------------+------------+
|
||||||
|
| path | files | code | comment | blank | total |
|
||||||
|
+------------------------------------------------------------------------------------------------+------------+------------+------------+------------+------------+
|
||||||
|
| . | 83 | 5,827 | 1,152 | 1,825 | 8,804 |
|
||||||
|
| . (Files) | 7 | 148 | 0 | 44 | 192 |
|
||||||
|
| music_kraken | 71 | 5,392 | 1,134 | 1,702 | 8,228 |
|
||||||
|
| music_kraken (Files) | 2 | 210 | 9 | 56 | 275 |
|
||||||
|
| music_kraken/audio | 3 | 92 | 4 | 35 | 131 |
|
||||||
|
| music_kraken/cli | 6 | 270 | 93 | 109 | 472 |
|
||||||
|
| music_kraken/cli (Files) | 1 | 2 | 0 | 0 | 2 |
|
||||||
|
| music_kraken/cli/download | 2 | 199 | 86 | 79 | 364 |
|
||||||
|
| music_kraken/cli/options | 3 | 69 | 7 | 30 | 106 |
|
||||||
|
| music_kraken/cli/options (Files) | 1 | 3 | 0 | 1 | 4 |
|
||||||
|
| music_kraken/cli/options/invidious | 2 | 66 | 7 | 29 | 102 |
|
||||||
|
| music_kraken/connection | 3 | 196 | 4 | 45 | 245 |
|
||||||
|
| music_kraken/database | 3 | 226 | 71 | 91 | 388 |
|
||||||
|
| music_kraken/download | 5 | 323 | 32 | 143 | 498 |
|
||||||
|
| music_kraken/objects | 11 | 1,226 | 338 | 376 | 1,940 |
|
||||||
|
| music_kraken/pages | 6 | 1,547 | 457 | 484 | 2,488 |
|
||||||
|
| music_kraken/static_files | 2 | 207 | 0 | 20 | 227 |
|
||||||
|
| music_kraken/utils | 30 | 1,095 | 126 | 343 | 1,564 |
|
||||||
|
| music_kraken/utils (Files) | 7 | 146 | 30 | 61 | 237 |
|
||||||
|
| music_kraken/utils/config | 8 | 651 | 72 | 177 | 900 |
|
||||||
|
| music_kraken/utils/enums | 3 | 56 | 7 | 14 | 77 |
|
||||||
|
| music_kraken/utils/exception | 3 | 23 | 8 | 12 | 43 |
|
||||||
|
| music_kraken/utils/path_manager | 4 | 58 | 9 | 29 | 96 |
|
||||||
|
| music_kraken/utils/support_classes | 5 | 161 | 0 | 50 | 211 |
|
||||||
|
| tests | 5 | 287 | 18 | 79 | 384 |
|
||||||
|
+------------------------------------------------------------------------------------------------+------------+------------+------------+------------+------------+
|
||||||
|
|
||||||
|
Files
|
||||||
|
+------------------------------------------------------------------------------------------------+----------+------------+------------+------------+------------+
|
||||||
|
| filename | language | code | comment | blank | total |
|
||||||
|
+------------------------------------------------------------------------------------------------+----------+------------+------------+------------+------------+
|
||||||
|
| /home/lars/Projects/music-downloader/src/__init__.py | Python | 0 | 0 | 1 | 1 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/actual_donwload.py | Python | 16 | 0 | 6 | 22 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/create_custom_objects.py | Python | 58 | 0 | 6 | 64 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/metal_archives.py | Python | 30 | 0 | 12 | 42 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/__init__.py | Python | 112 | 6 | 33 | 151 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/__main__.py | Python | 98 | 3 | 23 | 124 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/audio/__init__.py | Python | 7 | 0 | 3 | 10 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/audio/codec.py | Python | 25 | 0 | 8 | 33 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/audio/metadata.py | Python | 60 | 4 | 24 | 88 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/cli/__init__.py | Python | 2 | 0 | 0 | 2 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/cli/download/__init__.py | Python | 0 | 0 | 1 | 1 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/cli/download/shell.py | Python | 199 | 86 | 78 | 363 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/cli/options/__init__.py | Python | 3 | 0 | 1 | 4 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/cli/options/invidious/__init__.py | Python | 0 | 0 | 1 | 1 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/cli/options/invidious/shell.py | Python | 66 | 7 | 28 | 101 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/connection/__init__.py | Python | 1 | 0 | 1 | 2 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/connection/connection.py | Python | 168 | 1 | 30 | 199 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/connection/rotating.py | Python | 27 | 3 | 14 | 44 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/database/__init__.py | Python | 0 | 0 | 1 | 1 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/database/data_models.py | Python | 122 | 24 | 52 | 198 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/database/database.py | Python | 104 | 47 | 38 | 189 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/download/__init__.py | Python | 1 | 0 | 1 | 2 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/download/multiple_options.py | Python | 69 | 0 | 31 | 100 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/download/page_attributes.py | Python | 67 | 1 | 29 | 97 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/download/results.py | Python | 62 | 7 | 26 | 95 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/download/search.py | Python | 124 | 24 | 56 | 204 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/objects/__init__.py | Python | 14 | 0 | 5 | 19 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/objects/cache.py | Python | 37 | 56 | 18 | 111 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/objects/collection.py | Python | 91 | 31 | 39 | 161 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/objects/formatted_text.py | Python | 50 | 10 | 19 | 79 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/objects/lyrics.py | Python | 25 | 0 | 7 | 32 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/objects/metadata.py | Python | 272 | 62 | 63 | 397 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/objects/option.py | Python | 28 | 0 | 13 | 41 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/objects/parents.py | Python | 71 | 35 | 35 | 141 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/objects/song.py | Python | 480 | 113 | 120 | 713 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/objects/source.py | Python | 93 | 16 | 33 | 142 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/objects/target.py | Python | 65 | 15 | 24 | 104 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/pages/__init__.py | Python | 4 | 0 | 2 | 6 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/pages/abstract.py | Python | 234 | 46 | 93 | 373 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/pages/encyclopaedia_metallum.py | Python | 432 | 90 | 127 | 649 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/pages/musify.py | Python | 576 | 275 | 166 | 1,017 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/pages/preset.py | Python | 47 | 1 | 17 | 65 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/pages/youtube.py | Python | 254 | 45 | 79 | 378 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/static_files/new_db.sql | SQLite | 72 | 0 | 10 | 82 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/static_files/temp_database_structure.sql | SQLite | 135 | 0 | 10 | 145 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/__init__.py | Python | 2 | 1 | 2 | 5 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/config/__init__.py | Python | 7 | 0 | 4 | 11 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/config/audio.py | Python | 152 | 15 | 28 | 195 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/config/base_classes.py | Python | 136 | 35 | 61 | 232 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/config/config.py | Python | 92 | 16 | 30 | 138 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/config/connection.py | Python | 80 | 2 | 15 | 97 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/config/logging.py | Python | 104 | 4 | 17 | 125 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/config/misc.py | Python | 40 | 0 | 9 | 49 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/config/paths.py | Python | 40 | 0 | 13 | 53 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/enums/__init__.py | Python | 0 | 0 | 1 | 1 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/enums/album.py | Python | 16 | 6 | 5 | 27 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/enums/source.py | Python | 40 | 1 | 8 | 49 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/exception/__init__.py | Python | 1 | 0 | 1 | 2 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/exception/config.py | Python | 14 | 8 | 7 | 29 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/exception/download.py | Python | 8 | 0 | 4 | 12 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/functions.py | Python | 3 | 0 | 1 | 4 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/object_handeling.py | Python | 19 | 0 | 6 | 25 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/path_manager/__init__.py | Python | 2 | 0 | 2 | 4 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/path_manager/config_directory.py | Python | 4 | 0 | 4 | 8 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/path_manager/locations.py | Python | 16 | 0 | 9 | 25 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/path_manager/music_directory.py | Python | 36 | 9 | 14 | 59 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/phonetic_compares.py | Python | 39 | 2 | 17 | 58 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/regex.py | Python | 1 | 0 | 2 | 3 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/shared.py | Python | 66 | 22 | 22 | 110 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/string_processing.py | Python | 16 | 5 | 11 | 32 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/support_classes/__init__.py | Python | 4 | 0 | 1 | 5 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/support_classes/default_target.py | Python | 56 | 0 | 15 | 71 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/support_classes/download_result.py | Python | 69 | 0 | 21 | 90 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/support_classes/query.py | Python | 24 | 0 | 9 | 33 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken/utils/support_classes/thread_classes.py | Python | 8 | 0 | 4 | 12 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken_cli.py | Python | 3 | 0 | 3 | 6 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/music_kraken_gtk.py | Python | 3 | 0 | 2 | 5 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/musify_search.py | Python | 38 | 0 | 14 | 52 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/tests/__init__.py | Python | 0 | 0 | 1 | 1 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/tests/conftest.py | Python | 3 | 1 | 2 | 6 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/tests/test_building_objects.py | Python | 81 | 1 | 13 | 95 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/tests/test_download.py | Python | 30 | 1 | 12 | 43 |
|
||||||
|
| /home/lars/Projects/music-downloader/src/tests/test_objects.py | Python | 173 | 15 | 51 | 239 |
|
||||||
|
| Total | | 5,827 | 1,152 | 1,825 | 8,804 |
|
||||||
|
+------------------------------------------------------------------------------------------------+----------+------------+------------+------------+------------+
|
@ -4,6 +4,7 @@
|
|||||||
<modules>
|
<modules>
|
||||||
<module fileurl="file://$PROJECT_DIR$/.idea/music-downloader.iml" filepath="$PROJECT_DIR$/.idea/music-downloader.iml" />
|
<module fileurl="file://$PROJECT_DIR$/.idea/music-downloader.iml" filepath="$PROJECT_DIR$/.idea/music-downloader.iml" />
|
||||||
<module fileurl="file://$PROJECT_DIR$/../rythmbox-id3-lyrics-support/.idea/rythmbox-id3-lyrics-support.iml" filepath="$PROJECT_DIR$/../rythmbox-id3-lyrics-support/.idea/rythmbox-id3-lyrics-support.iml" />
|
<module fileurl="file://$PROJECT_DIR$/../rythmbox-id3-lyrics-support/.idea/rythmbox-id3-lyrics-support.iml" filepath="$PROJECT_DIR$/../rythmbox-id3-lyrics-support/.idea/rythmbox-id3-lyrics-support.iml" />
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/../forks/sponsorblock.py/.idea/sponsorblock.py.iml" filepath="$PROJECT_DIR$/../forks/sponsorblock.py/.idea/sponsorblock.py.iml" />
|
||||||
</modules>
|
</modules>
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
@ -8,5 +8,6 @@
|
|||||||
<orderEntry type="inheritedJdk" />
|
<orderEntry type="inheritedJdk" />
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
<orderEntry type="module" module-name="rythmbox-id3-lyrics-support" />
|
<orderEntry type="module" module-name="rythmbox-id3-lyrics-support" />
|
||||||
|
<orderEntry type="module" module-name="sponsorblock.py" />
|
||||||
</component>
|
</component>
|
||||||
</module>
|
</module>
|
@ -1,6 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="SqlDialectMappings">
|
|
||||||
<file url="file://$PROJECT_DIR$/src/music_kraken/static_files/new_db.sql" dialect="SQLite" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
@ -2,5 +2,6 @@
|
|||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="VcsDirectoryMappings">
|
<component name="VcsDirectoryMappings">
|
||||||
<mapping directory="" vcs="Git" />
|
<mapping directory="" vcs="Git" />
|
||||||
|
<mapping directory="$PROJECT_DIR$/../forks/sponsorblock.py" vcs="Git" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
20
README.md
20
README.md
@ -1,6 +1,6 @@
|
|||||||
# Music Kraken
|
# Music Kraken
|
||||||
|
|
||||||
<img align="right" src="assets/logo.svg" width=300>
|
<img src="assets/logo.svg" width=300 alt="music kraken logo"/>
|
||||||
|
|
||||||
- [Music Kraken](#music-kraken)
|
- [Music Kraken](#music-kraken)
|
||||||
- [Installation](#installation)
|
- [Installation](#installation)
|
||||||
@ -52,9 +52,19 @@ If you choose to run it in WSL, make sure ` ~/.local/bin` is added to your `$PAT
|
|||||||
|
|
||||||
## Quick-Guide
|
## Quick-Guide
|
||||||
|
|
||||||
**Genre:** First, the cli asks you to input a genre you want to download to. The options it gives you (if it gives you any) are all the folders you have in the music directory. You can also just input a new one.
|
The **Genre** you define at the start is the folder, my programm will download the files into, AS WELL as the value of the ID3 genre field.
|
||||||
|
|
||||||
**What to download:** After that it prompts you for a search. Here are a couple examples how you can search:
|
When it drops you into the **shell** 2 main things are important:
|
||||||
|
|
||||||
|
1. You search with `s: <query/url>`
|
||||||
|
2. You choose an option with just the index number of the option
|
||||||
|
3. You download with `d: <options/url>`, where the options are comma seperated
|
||||||
|
|
||||||
|
Trust me it WILL make sense, once you see it.
|
||||||
|
|
||||||
|
### Query
|
||||||
|
|
||||||
|
The syntax for the query is like really simple.
|
||||||
|
|
||||||
```
|
```
|
||||||
> #a <any artist>
|
> #a <any artist>
|
||||||
@ -67,9 +77,9 @@ searches for the release (album) <any release> by the artist <any artist>
|
|||||||
searches for the track <any track> from the release <any relaese>
|
searches for the track <any track> from the release <any relaese>
|
||||||
```
|
```
|
||||||
|
|
||||||
After searching with this syntax, it prompts you with multiple results. You can either choose one of those by inputing its id `int`, or you can search for a new query.
|
For a more detailed guid of the downloading shell, see [here](documentation/shell.md).
|
||||||
|
|
||||||
After you chose either an artist, a release group, a release, or a track by its id, download it by inputting the string `ok`. My downloader will download it automatically for you.
|
LOVE YALL *(except nazis ;-;)*
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
> IMPORTANT NOTE: heavily outdated sorryyyyy
|
||||||
|
|
||||||
# How to contribute
|
# How to contribute
|
||||||
|
|
||||||
I am always happy about pull requests.
|
I am always happy about pull requests.
|
||||||
|
7
documentation/connections.md
Normal file
7
documentation/connections.md
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# Connections
|
||||||
|
|
||||||
|
## Functions
|
||||||
|
|
||||||
|
A class, that gives me the options, to make web request
|
||||||
|
|
||||||
|
|
3
documentation/html/musify/details.md
Normal file
3
documentation/html/musify/details.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
title | url
|
||||||
|
--- | ---
|
||||||
|
song | https://musify.club/track/linkin-park-numb-210765
|
204
documentation/html/musify/song_details.html
Normal file
204
documentation/html/musify/song_details.html
Normal file
@ -0,0 +1,204 @@
|
|||||||
|
<body data-ma-theme="blue-grey">
|
||||||
|
<main class="main main--alt">
|
||||||
|
<section class="content content--full">
|
||||||
|
<div class="row content__inner">
|
||||||
|
<div id="bodyContent" class="content__inner--sm col-md-12 col-lg-9">
|
||||||
|
|
||||||
|
<!-- breadcrumbs -->
|
||||||
|
|
||||||
|
<!--
|
||||||
|
- static
|
||||||
|
- static
|
||||||
|
- artist
|
||||||
|
- album
|
||||||
|
- song
|
||||||
|
-->
|
||||||
|
|
||||||
|
<ol class="breadcrumb" itemscope itemtype="http://schema.org/BreadcrumbList">
|
||||||
|
<li class="breadcrumb-item" itemscope itemprop="itemListElement"
|
||||||
|
itemtype="http://schema.org/ListItem">
|
||||||
|
<a href="/" itemprop="item">
|
||||||
|
<span itemprop="name">Главная</span>
|
||||||
|
<meta itemprop="position" content="1">
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="breadcrumb-item" itemscope itemprop="itemListElement"
|
||||||
|
itemtype="http://schema.org/ListItem">
|
||||||
|
<a href="/artist" itemprop="item">
|
||||||
|
<span itemprop="name">Исполнители</span>
|
||||||
|
<meta itemprop="position" content="2">
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<!--2-->
|
||||||
|
<li class="breadcrumb-item" itemscope itemprop="itemListElement"
|
||||||
|
itemtype="http://schema.org/ListItem">
|
||||||
|
<a href="/artist/linkin-park-5" itemprop="item">
|
||||||
|
<span itemprop="name">Linkin Park</span>
|
||||||
|
<meta itemprop="position" content="3">
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<!--3-->
|
||||||
|
<li class="breadcrumb-item" itemscope itemprop="itemListElement"
|
||||||
|
itemtype="http://schema.org/ListItem">
|
||||||
|
<a href="/release/linkin-park-numb-2003-15363" itemprop="item">
|
||||||
|
<span itemprop="name">Numb</span>
|
||||||
|
<meta itemprop="position" content="4">
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<!--4-->
|
||||||
|
<li class="breadcrumb-item active">Numb</li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div itemprop="tracks" itemscope itemtype="http://schema.org/MusicRecording">
|
||||||
|
<div class="row justify-content-center">
|
||||||
|
<!-- album artwork -->
|
||||||
|
<div class="col-auto">
|
||||||
|
<img alt="Numb" data-src="https://41s-a.musify.club/img/70/738270/40650635.jpg" class="album-img lozad mb-2" />
|
||||||
|
<noscript><img src="https://41s-a.musify.club/img/70/738270/40650635.jpg" alt="Numb" /></noscript>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-7">
|
||||||
|
<div class="playlist artist mt-0 mb-2">
|
||||||
|
<div class="artist" data-artist="Linkin Park" data-name="Numb">
|
||||||
|
<div class="playlist__actions track_page">
|
||||||
|
<button
|
||||||
|
class="btn btn-lg btn-outline-primary btn--icon-text songplay_btn play mb-0"
|
||||||
|
data-url="/track/play/210765/linkin-park-numb.mp3"
|
||||||
|
data-title="Linkin Park - Numb" title="Слушать Linkin Park - Numb"><i
|
||||||
|
class="zmdi zmdi-play zmdi-hc-3x"></i>Слушать</button>
|
||||||
|
<a target="_blank"
|
||||||
|
class="no-ajaxy yaBrowser btn btn-lg btn-outline-primary btn--icon-text songplay_btn mb-0"
|
||||||
|
itemprop="audio" download="Linkin Park - Numb.mp3"
|
||||||
|
href="/track/dl/210765/linkin-park-numb.mp3" id="dl_210765"
|
||||||
|
title="Скачать Linkin Park - Numb"><i
|
||||||
|
class="zmdi zmdi-download zmdi-hc-3x"></i>Скачать MP3</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<ul class="icon-list album-info">
|
||||||
|
<li>
|
||||||
|
<i class="zmdi zmdi-accounts zmdi-hc-fw" title="Исполнитель"></i>
|
||||||
|
|
||||||
|
<a href="/artist/linkin-park-5" itemprop="byArtist" itemscope="itemscope"
|
||||||
|
itemtype="http://schema.org/MusicGroup">
|
||||||
|
<meta content="/artist/linkin-park-5" itemprop="url" />
|
||||||
|
<meta content="Linkin Park" itemprop="name" />
|
||||||
|
Linkin Park
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<i class="zmdi zmdi-playlist-audio zmdi-hc-fw" title="Альбом"></i>
|
||||||
|
<a href="/release/linkin-park-numb-2003-15363" itemprop="inAlbum"
|
||||||
|
itemscope="itemscope" itemtype="http://schema.org/MusicAlbum">
|
||||||
|
<meta content="/release/linkin-park-numb-2003-15363" itemprop="url" />
|
||||||
|
<meta content="Numb" itemprop="name" />
|
||||||
|
Numb
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<i class="zmdi zmdi-hourglass-alt zmdi-hc-fw" title="Длительность"></i>
|
||||||
|
<meta itemprop="duration" content="PT03M08S" />03:08
|
||||||
|
<i class="zmdi zmdi-file zmdi-hc-fw" title="Размер"></i>
|
||||||
|
5,73 Мб
|
||||||
|
<i class="zmdi zmdi-equalizer zmdi-hc-fw" title="Битрейт"></i>
|
||||||
|
256 Кб/с
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<i class="zmdi zmdi-star-circle zmdi-hc-fw" title="Рейтинг"></i>
|
||||||
|
<meta itemprop="interactionCount" content="UserPlays:19791" />19791
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<p class="genre__labels">
|
||||||
|
<a href="/genre/alternative-19">#Alternative</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tab-container">
|
||||||
|
<ul class="nav nav-tabs nav-fill" role="tablist">
|
||||||
|
<li class="nav-item"><a href="#tabLyrics" role="tab" data-toggle="tab"
|
||||||
|
class="nav-link no-ajaxy">текст</a></li>
|
||||||
|
<li class="nav-item"><a href="#tabVideo" role="tab" data-toggle="tab"
|
||||||
|
class="nav-link active show no-ajaxy">видео</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div class="tab-content">
|
||||||
|
<div id="tabLyrics" class="tab-pane fade card" itemprop="text">
|
||||||
|
<div class="card-body row">
|
||||||
|
<div class="col-12">
|
||||||
|
<h2 class="song-content-title">Текст "Linkin Park - Numb"</h2>
|
||||||
|
<div style="white-space: pre-line">
|
||||||
|
I'm tired of being what you want me to be
|
||||||
|
Feeling so faithless lost under the surface
|
||||||
|
Don't know what you're expecting of me
|
||||||
|
Put under the pressure of walking in your shoes
|
||||||
|
(Caught in the undertone just caught in the undertone)
|
||||||
|
Every step I take is another mistake to you
|
||||||
|
(Caught in the undertone just caught in the undertone)
|
||||||
|
|
||||||
|
I've become so numb I can't feel you there
|
||||||
|
I've become so tired so much more aware
|
||||||
|
I've becoming this all I want to do
|
||||||
|
Is be more like me and be less like you
|
||||||
|
|
||||||
|
Can't you see that you're smothering me
|
||||||
|
Holding too tightly afraid to lose control
|
||||||
|
Cause everything that you thought I would be
|
||||||
|
Has fallen apart right in front of you
|
||||||
|
(Caught in the undertone just caught in the undertone)
|
||||||
|
Every step that I take is another mistake to you
|
||||||
|
(Caught in the undertone just caught in the undertone)
|
||||||
|
And every second I waste is more than I can take
|
||||||
|
|
||||||
|
I've become so numb I can't feel you there
|
||||||
|
I've become so tired so much more aware
|
||||||
|
I've becoming this all I want to do
|
||||||
|
Is be more like me and be less like you
|
||||||
|
|
||||||
|
And I know
|
||||||
|
I may end up failing too
|
||||||
|
But I know
|
||||||
|
You were just like me with someone disappointed in you
|
||||||
|
|
||||||
|
I've become so numb I can't feel you there
|
||||||
|
I've become so tired so much more aware
|
||||||
|
I've becoming this all I want to do
|
||||||
|
Is be more like me and be less like you
|
||||||
|
|
||||||
|
I've become so numb I can't feel you there
|
||||||
|
Is everything what you want me to be
|
||||||
|
I've become so numb I can't feel you there
|
||||||
|
Is everything what you want me to be
|
||||||
|
</div>
|
||||||
|
<a data-ma-action="aside-open" data-ma-target=".user-login-summary follow"
|
||||||
|
class="btn btn-block" style="margin-bottom: 0.5rem;">Обновить текст</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="tabVideo" class="tab-pane active show card">
|
||||||
|
<div class="card-body">
|
||||||
|
<h2 class="song-content-title">Смотреть видео клип "Linkin Park -
|
||||||
|
Numb" онлайн</h2>
|
||||||
|
<div class="video-wrap embed-responsive embed-responsive-16by9">
|
||||||
|
<center>
|
||||||
|
<iframe class="embed-responsive-item"
|
||||||
|
src="//www.youtube.com/embed/kXYiU_JCYtU"></iframe>
|
||||||
|
</center>
|
||||||
|
</div>
|
||||||
|
<a data-ma-action="aside-open" data-ma-target=".user-login-summary"
|
||||||
|
class="btn btn-block follow">Обновить видеоклип</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</main>
|
||||||
|
<div id="addMenu" class="playlist-popup hidePop"></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
471
documentation/html/youtube/channel_api.md
Normal file
471
documentation/html/youtube/channel_api.md
Normal file
@ -0,0 +1,471 @@
|
|||||||
|
# Zombiez
|
||||||
|
|
||||||
|
|
||||||
|
https://www.youtube.com/youtubei/v1/browse?key=AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8&prettyPrint=false
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"responseContext": {
|
||||||
|
...
|
||||||
|
},
|
||||||
|
"contents": {
|
||||||
|
"twoColumnBrowseResultsRenderer": {
|
||||||
|
"tabs": [
|
||||||
|
{
|
||||||
|
"tabRenderer": {
|
||||||
|
"endpoint": {
|
||||||
|
"clickTrackingParams": "CBAQ8JMBGAUiEwj_3NqFrcX_AhVCxxEIHV5sBYg=",
|
||||||
|
"commandMetadata": {
|
||||||
|
"webCommandMetadata": {
|
||||||
|
"url": "/channel/UCV0Ntl3lVR7xDXKoCU6uUXA/featured",
|
||||||
|
"webPageType": "WEB_PAGE_TYPE_CHANNEL",
|
||||||
|
"rootVe": 3611,
|
||||||
|
"apiUrl": "/youtubei/v1/browse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"browseEndpoint": {
|
||||||
|
"browseId": "UCV0Ntl3lVR7xDXKoCU6uUXA",
|
||||||
|
"params": "EghmZWF0dXJlZPIGBAoCMgA%3D",
|
||||||
|
"canonicalBaseUrl": "/channel/UCV0Ntl3lVR7xDXKoCU6uUXA"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"title": "Home",
|
||||||
|
"selected": true,
|
||||||
|
"content": {
|
||||||
|
"sectionListRenderer": {
|
||||||
|
"contents": [
|
||||||
|
{
|
||||||
|
"itemSectionRenderer": {
|
||||||
|
"contents": [
|
||||||
|
{
|
||||||
|
"shelfRenderer": {
|
||||||
|
"title": {
|
||||||
|
"runs": [
|
||||||
|
{
|
||||||
|
"text": "Albums & Singles",
|
||||||
|
"navigationEndpoint": {
|
||||||
|
"clickTrackingParams": "CBMQ3BwYACITCP_c2oWtxf8CFULHEQgdXmwFiA==",
|
||||||
|
"commandMetadata": {
|
||||||
|
"webCommandMetadata": {
|
||||||
|
"url": "/channel/UCV0Ntl3lVR7xDXKoCU6uUXA/playlists?view=50&sort=dd&shelf_id=17666223384013636040",
|
||||||
|
"webPageType": "WEB_PAGE_TYPE_CHANNEL",
|
||||||
|
"rootVe": 3611,
|
||||||
|
"apiUrl": "/youtubei/v1/browse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"browseEndpoint": {
|
||||||
|
"browseId": "UCVQK_XpXPuE8xcIpWp_JtlA",
|
||||||
|
"params": "EglwbGF5bGlzdHMYAyAycMiD1PaWksKV9QHyBgkKB0IAogECCAE%3D",
|
||||||
|
"canonicalBaseUrl": "/channel/UCV0Ntl3lVR7xDXKoCU6uUXA"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"endpoint": {
|
||||||
|
...
|
||||||
|
},
|
||||||
|
"content": {
|
||||||
|
"horizontalListRenderer": {
|
||||||
|
"items": [
|
||||||
|
|
||||||
|
/* first playlist */
|
||||||
|
{
|
||||||
|
"gridPlaylistRenderer": {
|
||||||
|
"playlistId": "OLAK5uy_nbvQeskr8nbIuzeLxoceNLuCL_KjAmzVw",
|
||||||
|
"thumbnail": {
|
||||||
|
"thumbnails": [
|
||||||
|
{
|
||||||
|
"url": "https://i.ytimg.com/vi/-OPkZtrBlVM/hqdefault.jpg?sqp=-oaymwEXCOADEI4CSFryq4qpAwkIARUAAIhCGAE=&rs=AOn4CLASssT7fLkqB10cML8k_Tv5qoF4hg",
|
||||||
|
"width": 480,
|
||||||
|
"height": 270
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"sampledThumbnailColor": {
|
||||||
|
"red": 62,
|
||||||
|
"green": 21,
|
||||||
|
"blue": 114
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"title": {
|
||||||
|
"runs": [
|
||||||
|
{
|
||||||
|
"text": "KATHARZIZ",
|
||||||
|
"navigationEndpoint": {
|
||||||
|
"clickTrackingParams": "CCIQljUYACITCP_c2oWtxf8CFULHEQgdXmwFiDIGZy1oaWdoWhhVQ1YwTnRsM2xWUjd4RFhLb0NVNnVVWEGaAQYQ8jgYlwE=",
|
||||||
|
"commandMetadata": {
|
||||||
|
"webCommandMetadata": {
|
||||||
|
"url": "/watch?v=-OPkZtrBlVM&list=OLAK5uy_nbvQeskr8nbIuzeLxoceNLuCL_KjAmzVw",
|
||||||
|
"webPageType": "WEB_PAGE_TYPE_WATCH",
|
||||||
|
"rootVe": 3832
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"watchEndpoint": {
|
||||||
|
"videoId": "-OPkZtrBlVM",
|
||||||
|
"playlistId": "OLAK5uy_nbvQeskr8nbIuzeLxoceNLuCL_KjAmzVw",
|
||||||
|
"params": "OAI%3D",
|
||||||
|
"loggingContext": {
|
||||||
|
"vssLoggingContext": {
|
||||||
|
"serializedContextData": "GilPTEFLNXV5X25idlFlc2tyOG5iSXV6ZUx4b2NlTkx1Q0xfS2pBbXpWdw%3D%3D"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"watchEndpointSupportedOnesieConfig": {
|
||||||
|
"html5PlaybackOnesieConfig": {
|
||||||
|
"commonConfig": {
|
||||||
|
"url": "https://rr6---sn-8xgn5uxa-4g5l.googlevideo.com/initplayback?source=youtube&oeis=1&c=WEB&oad=3200&ovd=3200&oaad=11000&oavd=11000&ocs=700&oewis=1&oputc=1&ofpcc=1&beids=24350018&msp=1&odepv=1&id=f8e3e466dac19553&ip=87.123.241.91&initcwndbps=2165000&mt=1686834329&oweuc="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"shortBylineText": {
|
||||||
|
...
|
||||||
|
},
|
||||||
|
"videoCountText": {
|
||||||
|
"runs": [
|
||||||
|
{
|
||||||
|
"text": "16"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": " videos"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"navigationEndpoint": {
|
||||||
|
...
|
||||||
|
},
|
||||||
|
"publishedTimeText": {
|
||||||
|
"simpleText": "Updated today"
|
||||||
|
},
|
||||||
|
"videoCountShortText": {
|
||||||
|
"simpleText": "16"
|
||||||
|
},
|
||||||
|
"trackingParams": "CCIQljUYACITCP_c2oWtxf8CFULHEQgdXmwFiA==",
|
||||||
|
"sidebarThumbnails": [
|
||||||
|
...
|
||||||
|
],
|
||||||
|
"thumbnailText": {
|
||||||
|
"runs": [
|
||||||
|
{
|
||||||
|
"text": "16",
|
||||||
|
"bold": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": " videos"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"longBylineText": {
|
||||||
|
"runs": [
|
||||||
|
{
|
||||||
|
"text": "Album"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": " · "
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "ZOMBIEZ",
|
||||||
|
"navigationEndpoint": {
|
||||||
|
"clickTrackingParams": "CCIQljUYACITCP_c2oWtxf8CFULHEQgdXmwFiA==",
|
||||||
|
"commandMetadata": {
|
||||||
|
"webCommandMetadata": {
|
||||||
|
"url": "/channel/UCVQK_XpXPuE8xcIpWp_JtlA",
|
||||||
|
"webPageType": "WEB_PAGE_TYPE_CHANNEL",
|
||||||
|
"rootVe": 3611,
|
||||||
|
"apiUrl": "/youtubei/v1/browse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"browseEndpoint": {
|
||||||
|
"browseId": "UCVQK_XpXPuE8xcIpWp_JtlA",
|
||||||
|
"canonicalBaseUrl": "/channel/UCVQK_XpXPuE8xcIpWp_JtlA"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"thumbnailOverlays": [
|
||||||
|
...
|
||||||
|
],
|
||||||
|
"viewPlaylistText": {
|
||||||
|
"runs": [
|
||||||
|
{
|
||||||
|
"text": "View full playlist",
|
||||||
|
"navigationEndpoint": {
|
||||||
|
"clickTrackingParams": "CCIQljUYACITCP_c2oWtxf8CFULHEQgdXmwFiDIGZy1oaWdo",
|
||||||
|
"commandMetadata": {
|
||||||
|
"webCommandMetadata": {
|
||||||
|
"url": "/playlist?list=OLAK5uy_nbvQeskr8nbIuzeLxoceNLuCL_KjAmzVw",
|
||||||
|
"webPageType": "WEB_PAGE_TYPE_PLAYLIST",
|
||||||
|
"rootVe": 5754,
|
||||||
|
"apiUrl": "/youtubei/v1/browse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"browseEndpoint": {
|
||||||
|
"browseId": "VLOLAK5uy_nbvQeskr8nbIuzeLxoceNLuCL_KjAmzVw"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/* next playlist (same format as first one) */
|
||||||
|
{
|
||||||
|
...
|
||||||
|
},
|
||||||
|
|
||||||
|
/* many more playlists */
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
],
|
||||||
|
...
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"trackingParams": "CBMQ3BwYACITCP_c2oWtxf8CFULHEQgdXmwFiA=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"trackingParams": "CBIQuy8YACITCP_c2oWtxf8CFULHEQgdXmwFiA=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"trackingParams": "CBEQui8iEwj_3NqFrcX_AhVCxxEIHV5sBYg=",
|
||||||
|
"targetId": "browse-feedUCV0Ntl3lVR7xDXKoCU6uUXA",
|
||||||
|
"disablePullToRefresh": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"trackingParams": "CBAQ8JMBGAUiEwj_3NqFrcX_AhVCxxEIHV5sBYg="
|
||||||
|
}
|
||||||
|
},
|
||||||
|
...
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/* Some probably irrelevant stuff */
|
||||||
|
|
||||||
|
"header": {
|
||||||
|
...
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"channelMetadataRenderer": {
|
||||||
|
"title": "ZOMBIEZ - Topic",
|
||||||
|
"description": "",
|
||||||
|
"rssUrl": "https://www.youtube.com/feeds/videos.xml?channel_id=UCV0Ntl3lVR7xDXKoCU6uUXA",
|
||||||
|
"externalId": "UCV0Ntl3lVR7xDXKoCU6uUXA",
|
||||||
|
"keywords": "",
|
||||||
|
"ownerUrls": [
|
||||||
|
"http://www.youtube.com/channel/UCV0Ntl3lVR7xDXKoCU6uUXA"
|
||||||
|
],
|
||||||
|
"avatar": {
|
||||||
|
"thumbnails": [
|
||||||
|
{
|
||||||
|
"url": "https://yt3.googleusercontent.com/nGpgytnZ-gQ8bcmUvqQ4UQruCRqWiQiujnAaHD6jSlLMMPGbl2J7V-j8iD1ZGj2iUEylvsFkNQ=s900-c-k-c0x00ffffff-no-rj",
|
||||||
|
"width": 900,
|
||||||
|
"height": 900
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"channelUrl": "https://www.youtube.com/channel/UCV0Ntl3lVR7xDXKoCU6uUXA",
|
||||||
|
"isFamilySafe": true,
|
||||||
|
"availableCountryCodes": [
|
||||||
|
],
|
||||||
|
"musicArtistName": "ZOMBIEZ",
|
||||||
|
"androidDeepLink": "android-app://com.google.android.youtube/http/www.youtube.com/channel/UCV0Ntl3lVR7xDXKoCU6uUXA",
|
||||||
|
"androidAppindexingLink": "android-app://com.google.android.youtube/http/www.youtube.com/channel/UCV0Ntl3lVR7xDXKoCU6uUXA",
|
||||||
|
"iosAppindexingLink": "ios-app://544007664/vnd.youtube/www.youtube.com/channel/UCV0Ntl3lVR7xDXKoCU6uUXA",
|
||||||
|
"vanityChannelUrl": "http://www.youtube.com/channel/UCV0Ntl3lVR7xDXKoCU6uUXA"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"trackingParams": "CAAQhGciEwj_3NqFrcX_AhVCxxEIHV5sBYg=",
|
||||||
|
"topbar": {
|
||||||
|
...
|
||||||
|
},
|
||||||
|
"microformat": {
|
||||||
|
....
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
# Eminem
|
||||||
|
|
||||||
|
https://www.youtube.com/youtubei/v1/browse?key=AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8&prettyPrint=false
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"responseContext": {
|
||||||
|
...
|
||||||
|
},
|
||||||
|
"contents": {
|
||||||
|
"twoColumnBrowseResultsRenderer": {
|
||||||
|
"tabs": [
|
||||||
|
{
|
||||||
|
"tabRenderer": {
|
||||||
|
"endpoint": {
|
||||||
|
"clickTrackingParams": "CDEQ8JMBGAUiEwiSlomurMX_AhWhiTgKHeKqA0o=",
|
||||||
|
"commandMetadata": {
|
||||||
|
"webCommandMetadata": {
|
||||||
|
"url": "/channel/UCedvOgsKFzcK3hA5taf3KoQ/featured",
|
||||||
|
"webPageType": "WEB_PAGE_TYPE_CHANNEL",
|
||||||
|
"rootVe": 3611,
|
||||||
|
"apiUrl": "/youtubei/v1/browse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"browseEndpoint": {
|
||||||
|
"browseId": "UCedvOgsKFzcK3hA5taf3KoQ",
|
||||||
|
"params": "EghmZWF0dXJlZPIGBAoCMgA%3D",
|
||||||
|
"canonicalBaseUrl": "/channel/UCedvOgsKFzcK3hA5taf3KoQ"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"title": "Home",
|
||||||
|
"trackingParams": "CDEQ8JMBGAUiEwiSlomurMX_AhWhiTgKHeKqA0o="
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tabRenderer": {
|
||||||
|
"endpoint": {
|
||||||
|
"clickTrackingParams": "CA8Q8JMBGAYiEwiSlomurMX_AhWhiTgKHeKqA0o=",
|
||||||
|
"commandMetadata": {
|
||||||
|
"webCommandMetadata": {
|
||||||
|
"url": "/channel/UCedvOgsKFzcK3hA5taf3KoQ/playlists",
|
||||||
|
"webPageType": "WEB_PAGE_TYPE_CHANNEL",
|
||||||
|
"rootVe": 3611,
|
||||||
|
"apiUrl": "/youtubei/v1/browse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"browseEndpoint": {
|
||||||
|
"browseId": "UCedvOgsKFzcK3hA5taf3KoQ",
|
||||||
|
"params": "EglwbGF5bGlzdHPyBgQKAkIA",
|
||||||
|
"canonicalBaseUrl": "/channel/UCedvOgsKFzcK3hA5taf3KoQ"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"title": "Playlists",
|
||||||
|
"selected": true,
|
||||||
|
"content": {
|
||||||
|
"sectionListRenderer": {
|
||||||
|
"contents": [
|
||||||
|
{
|
||||||
|
"itemSectionRenderer": {
|
||||||
|
"contents": [
|
||||||
|
{
|
||||||
|
"gridRenderer": {
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"gridPlaylistRenderer": {
|
||||||
|
"playlistId": "OLAK5uy_mHmQtAojdO4PRMxhyG_9FR2cScq52Z_ww",
|
||||||
|
"thumbnail": {
|
||||||
|
"thumbnails": [
|
||||||
|
{
|
||||||
|
"url": "https://i.ytimg.com/vi/r_0JjYUe5jo/hqdefault.jpg?sqp=-oaymwEXCOADEI4CSFryq4qpAwkIARUAAIhCGAE=&rs=AOn4CLBDE5zUUu7bOlXU1uOhaNxJl5zIbQ",
|
||||||
|
"width": 480,
|
||||||
|
"height": 270
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"sampledThumbnailColor": {
|
||||||
|
"red": 74,
|
||||||
|
"green": 89,
|
||||||
|
"blue": 88
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"title": {
|
||||||
|
"runs": [
|
||||||
|
{
|
||||||
|
"text": "Curtain Call 2",
|
||||||
|
"navigationEndpoint": {
|
||||||
|
"clickTrackingParams": "CDAQljUYACITCJKWia6sxf8CFaGJOAod4qoDSjIGZy1oaWdoWhhVQ2Vkdk9nc0tGemNLM2hBNXRhZjNLb1GaAQYQ8jgYlwE=",
|
||||||
|
"commandMetadata": {
|
||||||
|
"webCommandMetadata": {
|
||||||
|
"url": "/watch?v=r_0JjYUe5jo&list=OLAK5uy_mHmQtAojdO4PRMxhyG_9FR2cScq52Z_ww",
|
||||||
|
"webPageType": "WEB_PAGE_TYPE_WATCH",
|
||||||
|
"rootVe": 3832
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"watchEndpoint": {
|
||||||
|
"videoId": "r_0JjYUe5jo",
|
||||||
|
"playlistId": "OLAK5uy_mHmQtAojdO4PRMxhyG_9FR2cScq52Z_ww",
|
||||||
|
"params": "OAI%3D",
|
||||||
|
"loggingContext": {
|
||||||
|
"vssLoggingContext": {
|
||||||
|
"serializedContextData": "GilPTEFLNXV5X21IbVF0QW9qZE80UFJNeGh5R185RlIyY1NjcTUyWl93dw%3D%3D"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"watchEndpointSupportedOnesieConfig": {
|
||||||
|
"html5PlaybackOnesieConfig": {
|
||||||
|
"commonConfig": {
|
||||||
|
"url": "https://rr2---sn-8xgn5uxa-4g5s.googlevideo.com/initplayback?source=youtube&oeis=1&c=WEB&oad=3200&ovd=3200&oaad=11000&oavd=11000&ocs=700&oewis=1&oputc=1&ofpcc=1&beids=24350018&msp=1&odepv=1&id=affd098d851ee63a&ip=87.123.241.91&initcwndbps=1772500&mt=1686834084&oweuc="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"shortBylineText": {
|
||||||
|
"runs": [
|
||||||
|
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"videoCountText": {
|
||||||
|
"runs": [
|
||||||
|
{
|
||||||
|
"text": "35"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": " videos"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"navigationEndpoint": {
|
||||||
|
...
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"publishedTimeText": {
|
||||||
|
"simpleText": "Updated today"
|
||||||
|
},
|
||||||
|
"videoCountShortText": {
|
||||||
|
"simpleText": "35"
|
||||||
|
},
|
||||||
|
...
|
||||||
|
],
|
||||||
|
"thumbnailText": {
|
||||||
|
"runs": [
|
||||||
|
{
|
||||||
|
"text": "35",
|
||||||
|
"bold": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": " videos"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
...
|
||||||
|
"viewPlaylistText": {
|
||||||
|
"runs": [
|
||||||
|
{
|
||||||
|
"text": "View full playlist",
|
||||||
|
"navigationEndpoint": {
|
||||||
|
"clickTrackingParams": "CDAQljUYACITCJKWia6sxf8CFaGJOAod4qoDSjIGZy1oaWdo",
|
||||||
|
"commandMetadata": {
|
||||||
|
"webCommandMetadata": {
|
||||||
|
"url": "/playlist?list=OLAK5uy_mHmQtAojdO4PRMxhyG_9FR2cScq52Z_ww",
|
||||||
|
"webPageType": "WEB_PAGE_TYPE_PLAYLIST",
|
||||||
|
"rootVe": 5754,
|
||||||
|
"apiUrl": "/youtubei/v1/browse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"browseEndpoint": {
|
||||||
|
"browseId": "VLOLAK5uy_mHmQtAojdO4PRMxhyG_9FR2cScq52Z_ww"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
```
|
204
documentation/html/youtube/channel_api_request.md
Normal file
204
documentation/html/youtube/channel_api_request.md
Normal file
@ -0,0 +1,204 @@
|
|||||||
|
# Results
|
||||||
|
|
||||||
|
## Request
|
||||||
|
|
||||||
|
```curl
|
||||||
|
curl 'https://www.youtube.com/youtubei/v1/browse?key=AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8&prettyPrint=false' \
|
||||||
|
-H 'authority: www.youtube.com' \
|
||||||
|
-H 'accept: */*' \
|
||||||
|
-H 'accept-language: en-US,en;q=0.7' \
|
||||||
|
-H 'authorization: SAPISIDHASH 1686916263_e46803ac72f6036ba3b55e6edb0e45218c2d9222' \
|
||||||
|
-H 'cache-control: no-cache' \
|
||||||
|
-H 'content-type: application/json' \
|
||||||
|
-H 'cookie: CONSENT=PENDING+359; SOCS=CAESEwgDEgk1MDQzNzQ2NDAaAmVuIAEaBgiAhceeBg; DEVICE_INFO=ChxOekU1Tnprd056a3lOalUxTURJd01EQTNOdz09EJ+2kJ8GGJ+2kJ8G; HSID=ACaGQ6WFrIz4Ip9MQ; SSID=AkEQqNjJYkdquRRu6; APISID=c9DHm8ianHgc4LdY/AQMhE_0ECWj0r_orU; SAPISID=a_vNFJhvrDylguw8/Ann5G_jsanpFtW0Pu; __Secure-1PAPISID=a_vNFJhvrDylguw8/Ann5G_jsanpFtW0Pu; __Secure-3PAPISID=a_vNFJhvrDylguw8/Ann5G_jsanpFtW0Pu; LOGIN_INFO=AFmmF2swRQIhANli-SWeYk6WvtIgBzsX4XMeuzlvdXMVtbfJTdhUJPRAAiAlG7PiNiEuUynQLUz5y-t7IvHPtpbmp0sU7_1B8ebQBw:QUQ3MjNmejhuWW5EZV9OVklIOTNxYXpEMXYwQWVvM1ptYTc2OWtObE9TcllyOEc4VndOR0tXVVRUOUhmT2hRbFRkNVZjeVhDRUJ0bmwxcTJTU3ZKWWhvX1hKMFdFbDVBYTdOS2tNMU41ZDI1Y3pIQ2NTVjNrdzJNVGFENDROT2IwdDBTTlV6cmh2RGFWaXpCWndGTHUxMzZBM1NGNk5FbVZn; VISITOR_INFO1_LIVE=swm2xaU6T4s; SID=WwivRnpt9CjuCydglBkAPlpoMnou9Djmu9MIggo5NnkT1-6N69ULSrjryLwj4ZSvzfy6qA.; __Secure-1PSID=WwivRnpt9CjuCydglBkAPlpoMnou9Djmu9MIggo5NnkT1-6NcKwuUDKgPPeuOmwXW3uZUg.; __Secure-3PSID=WwivRnpt9CjuCydglBkAPlpoMnou9Djmu9MIggo5NnkT1-6NIh3P5codR8w_2O6jDK4PVw.; PREF=tz=Europe.Berlin&f6=40000000&f7=100; YSC=nVbKyjjk8dw; __Secure-YEC=CgtuQ2lKWWg3NFhTVSidmbGkBg%3D%3D; SIDCC=AP8dLty32FdokPf_5Qg2eA8TWwebRgwg1n55TG2yQUd-mJkLvroZJj9QGMOIbE33Q2ovqK10H_uA; __Secure-1PSIDCC=AP8dLtz5c8aDk1Gw5VFhcM6EuUcQiZP50kH2XnUIx0PF4bDPWTPwLEq1LhVvadHnHwagqV8DXJI; __Secure-3PSIDCC=AP8dLtzfSXJb4bJhF8czo12Tuc90ONVeuOVXtinx8-_tXE7D4HW1XwHwDfspIBZItbz0aYCjgYDO; ST-txiubb=itct=CCgQ8JMBGAciEwjq7bzg3Mf_AhWjRHoFHezzDzw%3D&csn=MC45MTAyMTY0NjM3ODQ2MTUz&endpoint=%7B%22clickTrackingParams%22%3A%22CCgQ8JMBGAciEwjq7bzg3Mf_AhWjRHoFHezzDzw%3D%22%2C%22commandMetadata%22%3A%7B%22webCommandMetadata%22%3A%7B%22url%22%3A%22%2Fchannel%2FUC8JxlMZ9VPddCuQGwB49fYg%2Fplaylists%22%2C%22webPageType%22%3A%22WEB_PAGE_TYPE_CHANNEL%22%2C%22rootVe%22%3A3611%2C%22apiUrl%22%3A%22%2Fyoutubei%2Fv1%2Fbrowse%22%7D%7D%2C%22browseEndpoint%22%3A%7B%22browseId%22%3A%22UC8JxlMZ9VPddCuQGwB49fYg%22%2C%22params%22%3A%22EglwbGF5bGlzdHPyBgQKAkIA%22%2C%22canonicalBaseUrl%22%3A%22%2Fchannel%2FUC8JxlMZ9VPddCuQGwB49fYg%22%7D%7D; ST-plcuz1=' \
|
||||||
|
-H 'origin: https://www.youtube.com' \
|
||||||
|
-H 'pragma: no-cache' \
|
||||||
|
-H 'referer: https://www.youtube.com/channel/UC8JxlMZ9VPddCuQGwB49fYg/playlists' \
|
||||||
|
-H 'sec-fetch-dest: empty' \
|
||||||
|
-H 'sec-fetch-mode: same-origin' \
|
||||||
|
-H 'sec-fetch-site: same-origin' \
|
||||||
|
-H 'sec-gpc: 1' \
|
||||||
|
-H 'user-agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36' \
|
||||||
|
-H 'x-goog-authuser: 0' \
|
||||||
|
-H 'x-goog-visitor-id: CgtuQ2lKWWg3NFhTVSidmbGkBg%3D%3D' \
|
||||||
|
-H 'x-origin: https://www.youtube.com' \
|
||||||
|
-H 'x-youtube-bootstrap-logged-in: true' \
|
||||||
|
-H 'x-youtube-client-name: 1' \
|
||||||
|
-H 'x-youtube-client-version: 2.20230613.01.00' \
|
||||||
|
--data-raw '{
|
||||||
|
"context":{
|
||||||
|
"client":{
|
||||||
|
"hl":"de",
|
||||||
|
"gl":"DE",
|
||||||
|
"remoteHost":"87.123.241.79",
|
||||||
|
"deviceMake":"",
|
||||||
|
"deviceModel":"",
|
||||||
|
"visitorData":"CgtuQ2lKWWg3NFhTVSidmbGkBg%3D%3D",
|
||||||
|
"userAgent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36,gzip(gfe)",
|
||||||
|
"clientName":"WEB",
|
||||||
|
"clientVersion":"2.20230613.01.00",
|
||||||
|
"osName":"X11",
|
||||||
|
"osVersion":"",
|
||||||
|
"originalUrl":"https://www.youtube.com/channel/UC8JxlMZ9VPddCuQGwB49fYg/playlists",
|
||||||
|
"platform":"DESKTOP",
|
||||||
|
"clientFormFactor":"UNKNOWN_FORM_FACTOR",
|
||||||
|
"configInfo":{
|
||||||
|
"appInstallData":"CJ2ZsaQGEKXC_hIQzLf-EhDftq8FELq0rwUQvbauBRDbr68FEPOorwUQ4tSuBRDj0f4SEMzfrgUQ7NH-EhDrk64FEI_DrwUQorSvBRDUoa8FEKqy_hIQpZmvBRC4i64FEMyu_hIQscavBRDnuq8FEN62rwUQouyuBRCCna8FEMO3_hIQ1bavBRCMt68FEJCjrwUQ7qKvBRDpw68FEInorgUQl9L-EhD4ta8FEOf3rgUQrLevBRD-ta8FEOSz_hIQ_u6uBQ%3D%3D"
|
||||||
|
},
|
||||||
|
"userInterfaceTheme":"USER_INTERFACE_THEME_DARK",
|
||||||
|
"timeZone":"Europe/Berlin",
|
||||||
|
"browserName":"Chrome",
|
||||||
|
"browserVersion":"114.0.0.0",
|
||||||
|
"acceptHeader":"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8",
|
||||||
|
"deviceExperimentId":"ChxOekU1Tnprd056a3lOalUxTURJd01EQTNOdz09EJ2ZsaQGGJ-2kJ8G",
|
||||||
|
"screenWidthPoints":1090,
|
||||||
|
"screenHeightPoints":980,
|
||||||
|
"screenPixelDensity":1,
|
||||||
|
"screenDensityFloat":1,
|
||||||
|
"utcOffsetMinutes":120,
|
||||||
|
"memoryTotalKbytes":"500000",
|
||||||
|
"mainAppWebInfo":{
|
||||||
|
"graftUrl":"/channel/UC8JxlMZ9VPddCuQGwB49fYg/playlists",
|
||||||
|
"pwaInstallabilityStatus":"PWA_INSTALLABILITY_STATUS_CAN_BE_INSTALLED",
|
||||||
|
"webDisplayMode":"WEB_DISPLAY_MODE_BROWSER",
|
||||||
|
"isWebNativeShareAvailable":false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"user":{
|
||||||
|
"lockedSafetyMode":false
|
||||||
|
},
|
||||||
|
"request":{
|
||||||
|
"useSsl":true,
|
||||||
|
"internalExperimentFlags":[
|
||||||
|
|
||||||
|
],
|
||||||
|
"consistencyTokenJars":[
|
||||||
|
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"clickTracking":{
|
||||||
|
"clickTrackingParams":"CCgQ8JMBGAciEwjq7bzg3Mf_AhWjRHoFHezzDzw="
|
||||||
|
},
|
||||||
|
"adSignalsInfo":{
|
||||||
|
"params":[{"key":"dt","value":"1686916254647"},{"key":"flash","value":"0"},{"key":"frm","value":"0"},{"key":"u_tz","value":"120"},{"key":"u_his","value":"14"},{"key":"u_h","value":"1080"},{"key":"u_w","value":"1920"},{"key":"u_ah","value":"1049"},{"key":"u_aw","value":"1866"},{"key":"u_cd","value":"24"},{"key":"bc","value":"31"},{"key":"bih","value":"980"},{"key":"biw","value":"1075"},{"key":"brdim","value":"1280,31,1280,31,1866,31,1866,1049,1090,980"},{"key":"vis","value":"1"},{"key":"wgl","value":"true"},{"key":"ca_type","value":"image"}]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"browseId":"UC8JxlMZ9VPddCuQGwB49fYg",
|
||||||
|
"params":"EglwbGF5bGlzdHPyBgQKAkIA"
|
||||||
|
}' \
|
||||||
|
--compressed
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
# No Results
|
||||||
|
|
||||||
|
## Request
|
||||||
|
|
||||||
|
```curl
|
||||||
|
curl 'https://www.youtube.com/youtubei/v1/browse?key=AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8&prettyPrint=false' \
|
||||||
|
-H 'authority: www.youtube.com' \
|
||||||
|
-H 'accept: */*' \
|
||||||
|
-H 'accept-language: en-US,en;q=0.7' \
|
||||||
|
-H 'authorization: SAPISIDHASH 1686916270_9e68abaf319d6994e84c3b64f46a2f6b91258f26' \
|
||||||
|
-H 'cache-control: no-cache' \
|
||||||
|
-H 'content-type: application/json' \
|
||||||
|
-H 'cookie: CONSENT=PENDING+359; SOCS=CAESEwgDEgk1MDQzNzQ2NDAaAmVuIAEaBgiAhceeBg; DEVICE_INFO=ChxOekU1Tnprd056a3lOalUxTURJd01EQTNOdz09EJ+2kJ8GGJ+2kJ8G; HSID=ACaGQ6WFrIz4Ip9MQ; SSID=AkEQqNjJYkdquRRu6; APISID=c9DHm8ianHgc4LdY/AQMhE_0ECWj0r_orU; SAPISID=a_vNFJhvrDylguw8/Ann5G_jsanpFtW0Pu; __Secure-1PAPISID=a_vNFJhvrDylguw8/Ann5G_jsanpFtW0Pu; __Secure-3PAPISID=a_vNFJhvrDylguw8/Ann5G_jsanpFtW0Pu; LOGIN_INFO=AFmmF2swRQIhANli-SWeYk6WvtIgBzsX4XMeuzlvdXMVtbfJTdhUJPRAAiAlG7PiNiEuUynQLUz5y-t7IvHPtpbmp0sU7_1B8ebQBw:QUQ3MjNmejhuWW5EZV9OVklIOTNxYXpEMXYwQWVvM1ptYTc2OWtObE9TcllyOEc4VndOR0tXVVRUOUhmT2hRbFRkNVZjeVhDRUJ0bmwxcTJTU3ZKWWhvX1hKMFdFbDVBYTdOS2tNMU41ZDI1Y3pIQ2NTVjNrdzJNVGFENDROT2IwdDBTTlV6cmh2RGFWaXpCWndGTHUxMzZBM1NGNk5FbVZn; VISITOR_INFO1_LIVE=swm2xaU6T4s; SID=WwivRnpt9CjuCydglBkAPlpoMnou9Djmu9MIggo5NnkT1-6N69ULSrjryLwj4ZSvzfy6qA.; __Secure-1PSID=WwivRnpt9CjuCydglBkAPlpoMnou9Djmu9MIggo5NnkT1-6NcKwuUDKgPPeuOmwXW3uZUg.; __Secure-3PSID=WwivRnpt9CjuCydglBkAPlpoMnou9Djmu9MIggo5NnkT1-6NIh3P5codR8w_2O6jDK4PVw.; PREF=tz=Europe.Berlin&f6=40000000&f7=100; YSC=nVbKyjjk8dw; __Secure-YEC=CgtuQ2lKWWg3NFhTVSidmbGkBg%3D%3D; SIDCC=AP8dLtxamg1oLrM-gw2tCtJfMUighwYfCtCfwGT6G39nrxXXhtRoBcacfSPMOQwAOIN0xyOUSLyb; __Secure-1PSIDCC=AP8dLtxZ3YHCdW5cYDDaNKO8wvAGqqy4Kp7_xZtEYQW5bryvlEuU2iuJArAJskwLMwqiCznn038; __Secure-3PSIDCC=AP8dLtywHnuXOD7p59fWeUsQXp6MpPsJgZiUgW5ydTzajVvM6w64k4u7aE5WIuB5InMlTNJzKGGK; ST-plcuz1=; ST-ximm1t=csn=MC43NjY5NTkyNzczNjg1NjUy&itct=CCkQui8iEwi3hYnl3Mf_AhU7zBEIHQ_pA8o%3D&endpoint=%7B%22clickTrackingParams%22%3A%22CCkQui8iEwi3hYnl3Mf_AhU7zBEIHQ_pA8o%3D%22%2C%22commandMetadata%22%3A%7B%22webCommandMetadata%22%3A%7B%22url%22%3A%22%2Fchannel%2FUC8JxlMZ9VPddCuQGwB49fYg%2Fplaylists%3Fview%3D1%22%2C%22webPageType%22%3A%22WEB_PAGE_TYPE_CHANNEL%22%2C%22rootVe%22%3A3611%2C%22apiUrl%22%3A%22%2Fyoutubei%2Fv1%2Fbrowse%22%7D%7D%2C%22browseEndpoint%22%3A%7B%22browseId%22%3A%22UC8JxlMZ9VPddCuQGwB49fYg%22%2C%22params%22%3A%22EglwbGF5bGlzdHMgAQ%253D%253D%22%2C%22canonicalBaseUrl%22%3A%22%2Fchannel%2FUC8JxlMZ9VPddCuQGwB49fYg%22%7D%7D' \
|
||||||
|
-H 'origin: https://www.youtube.com' \
|
||||||
|
-H 'pragma: no-cache' \
|
||||||
|
-H 'referer: https://www.youtube.com/channel/UC8JxlMZ9VPddCuQGwB49fYg/playlists?view=1' \
|
||||||
|
-H 'sec-fetch-dest: empty' \
|
||||||
|
-H 'sec-fetch-mode: same-origin' \
|
||||||
|
-H 'sec-fetch-site: same-origin' \
|
||||||
|
-H 'sec-gpc: 1' \
|
||||||
|
-H 'user-agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36' \
|
||||||
|
-H 'x-goog-authuser: 0' \
|
||||||
|
-H 'x-goog-visitor-id: CgtuQ2lKWWg3NFhTVSidmbGkBg%3D%3D' \
|
||||||
|
-H 'x-origin: https://www.youtube.com' \
|
||||||
|
-H 'x-youtube-bootstrap-logged-in: true' \
|
||||||
|
-H 'x-youtube-client-name: 1' \
|
||||||
|
-H 'x-youtube-client-version: 2.20230613.01.00' \
|
||||||
|
--data-raw '{
|
||||||
|
"context":{
|
||||||
|
"client":{
|
||||||
|
"hl":"de",
|
||||||
|
"gl":"DE",
|
||||||
|
"remoteHost":"87.123.241.79",
|
||||||
|
"deviceMake":"",
|
||||||
|
"deviceModel":"",
|
||||||
|
"visitorData":"CgtuQ2lKWWg3NFhTVSidmbGkBg%3D%3D",
|
||||||
|
"userAgent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36,gzip(gfe)",
|
||||||
|
"clientName":"WEB",
|
||||||
|
"clientVersion":"2.20230613.01.00",
|
||||||
|
"osName":"X11",
|
||||||
|
"osVersion":"",
|
||||||
|
"originalUrl":"https://www.youtube.com/channel/UC8JxlMZ9VPddCuQGwB49fYg/playlists?view=1",
|
||||||
|
"platform":"DESKTOP",
|
||||||
|
"clientFormFactor":"UNKNOWN_FORM_FACTOR",
|
||||||
|
"configInfo":{
|
||||||
|
"appInstallData":"CJ2ZsaQGEKXC_hIQzLf-EhDftq8FELq0rwUQvbauBRDbr68FEPOorwUQ4tSuBRDj0f4SEMzfrgUQ7NH-EhDrk64FEI_DrwUQorSvBRDUoa8FEKqy_hIQpZmvBRC4i64FEMyu_hIQscavBRDnuq8FEN62rwUQouyuBRCCna8FEMO3_hIQ1bavBRCMt68FEJCjrwUQ7qKvBRDpw68FEInorgUQl9L-EhD4ta8FEOf3rgUQrLevBRD-ta8FEOSz_hIQ_u6uBQ%3D%3D"
|
||||||
|
},
|
||||||
|
"userInterfaceTheme":"USER_INTERFACE_THEME_DARK",
|
||||||
|
"timeZone":"Europe/Berlin",
|
||||||
|
"browserName":"Chrome",
|
||||||
|
"browserVersion":"114.0.0.0",
|
||||||
|
"acceptHeader":"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8",
|
||||||
|
"deviceExperimentId":"ChxOekU1Tnprd056a3lOalUxTURJd01EQTNOdz09EJ2ZsaQGGJ-2kJ8G",
|
||||||
|
"screenWidthPoints":1090,
|
||||||
|
"screenHeightPoints":980,
|
||||||
|
"screenPixelDensity":1,
|
||||||
|
"screenDensityFloat":1,
|
||||||
|
"utcOffsetMinutes":120,
|
||||||
|
"memoryTotalKbytes":"500000",
|
||||||
|
"mainAppWebInfo":{
|
||||||
|
"graftUrl":"/channel/UC8JxlMZ9VPddCuQGwB49fYg/playlists?view=1",
|
||||||
|
"pwaInstallabilityStatus":"PWA_INSTALLABILITY_STATUS_CAN_BE_INSTALLED",
|
||||||
|
"webDisplayMode":"WEB_DISPLAY_MODE_BROWSER",
|
||||||
|
"isWebNativeShareAvailable":false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"user":{
|
||||||
|
"lockedSafetyMode":false
|
||||||
|
},
|
||||||
|
"request":{
|
||||||
|
"useSsl":true,
|
||||||
|
"internalExperimentFlags":[
|
||||||
|
|
||||||
|
],
|
||||||
|
"consistencyTokenJars":[
|
||||||
|
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"clickTracking":{
|
||||||
|
"clickTrackingParams":"CCkQui8iEwi3hYnl3Mf_AhU7zBEIHQ_pA8o="
|
||||||
|
},
|
||||||
|
"adSignalsInfo":{
|
||||||
|
"params":[{"key":"dt","value":"1686916254647"},{"key":"flash","value":"0"},{"key":"frm","value":"0"},{"key":"u_tz","value":"120"},{"key":"u_his","value":"15"},{"key":"u_h","value":"1080"},{"key":"u_w","value":"1920"},{"key":"u_ah","value":"1049"},{"key":"u_aw","value":"1866"},{"key":"u_cd","value":"24"},{"key":"bc","value":"31"},{"key":"bih","value":"980"},{"key":"biw","value":"1075"},{"key":"brdim","value":"1280,31,1280,31,1866,31,1866,1049,1090,980"},{"key":"vis","value":"1"},{"key":"wgl","value":"true"},{"key":"ca_type","value":"image"}]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"browseId":"UC8JxlMZ9VPddCuQGwB49fYg",
|
||||||
|
"params":"EglwbGF5bGlzdHMgAQ%3D%3D"
|
||||||
|
}' \
|
||||||
|
--compressed
|
||||||
|
```
|
||||||
|
|
||||||
|
# Potentially relevant difference
|
||||||
|
|
||||||
|
difference | Result | No Result
|
||||||
|
referer | https://www.youtube.com/channel/UC8JxlMZ9VPddCuQGwB49fYg/playlists | https://www.youtube.com/channel/UC8JxlMZ9VPddCuQGwB49fYg/playlists?view=1
|
||||||
|
`"originalURL"` | https://www.youtube.com/channel/UC8JxlMZ9VPddCuQGwB49fYg/playlists | https://www.youtube.com/channel/UC8JxlMZ9VPddCuQGwB49fYg/playlists?view=1
|
||||||
|
|
||||||
|
## What I think the problem is
|
||||||
|
|
||||||
|
I think the problem arises, because the request is made in the wrong manner. Refering to the by the endpoint returned data from earlier, the data is given in pretty much the same format.
|
||||||
|
|
||||||
|
Now the thing is, that there are some Topic Channels, where you can't switch the playlist type.
|
||||||
|
|
||||||
|
- https://www.youtube.com/channel/UCPOUrPpYMpxQU_gKtBQZroQ/playlists
|
||||||
|
- https://www.youtube.com/channel/UCV0Ntl3lVR7xDXKoCU6uUXA/playlists
|
||||||
|
|
||||||
|
But then there are those Topic Channels, where you actually can switch the playlist type. These are usually the bigger ones. I haven't found why that difference exists though.
|
||||||
|
|
||||||
|
- https://www.youtube.com/channel/UC8JxlMZ9VPddCuQGwB49fYg/playlists
|
||||||
|
- https://www.youtube.com/channel/UCedvOgsKFzcK3hA5taf3KoQ/playlists
|
||||||
|
|
||||||
|
So modifying the requests from one of those channels, that currently do yield results, to have the `?view=1` parameter in the url, they still yield results. So my bet right now would be, that the reasons some channels do yield results and some don't is, because invidious makes the requests with `?view=1`, or does something simmilar, which causes the same behaviour.
|
19
documentation/html/youtube/youtube.md
Normal file
19
documentation/html/youtube/youtube.md
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
# YouTube
|
||||||
|
|
||||||
|
I can get data from youtube with either calling:
|
||||||
|
|
||||||
|
- invidious
|
||||||
|
- youtube
|
||||||
|
|
||||||
|
I will only get the structured data from youtube music => `{artist} - Topic`. Maybe other stuff will be implemented
|
||||||
|
|
||||||
|
## Functionality
|
||||||
|
|
||||||
|
Every search results, where the channel name doesnt end with ` - Topic` will be ignored.
|
||||||
|
|
||||||
|
### ISRC search
|
||||||
|
|
||||||
|
### YT music
|
||||||
|
|
||||||
|
If searchin for artist, the query should be:
|
||||||
|
`{artist} - Topic`
|
22
documentation/program_structure.md
Normal file
22
documentation/program_structure.md
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
# Downloading
|
||||||
|
|
||||||
|
## Query
|
||||||
|
|
||||||
|
- parsing query into music objects
|
||||||
|
|
||||||
|
# Pages
|
||||||
|
|
||||||
|
## from music objects to query
|
||||||
|
|
||||||
|
```
|
||||||
|
song: artist1, artist2
|
||||||
|
|
||||||
|
1. artist1 - song
|
||||||
|
2. artist2 - song
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
artist: song1, song2
|
||||||
|
|
||||||
|
1. artist
|
||||||
|
```
|
57
documentation/shell.md
Normal file
57
documentation/shell.md
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
# Shell
|
||||||
|
|
||||||
|
## Searching
|
||||||
|
|
||||||
|
```mkshell
|
||||||
|
> s: {querry or url}
|
||||||
|
|
||||||
|
# examples
|
||||||
|
> s: https://musify.club/release/some-random-release-183028492
|
||||||
|
> s: r: #a an Artist #r some random Release
|
||||||
|
```
|
||||||
|
|
||||||
|
Searches for an url, or an query
|
||||||
|
|
||||||
|
### Query Syntax
|
||||||
|
|
||||||
|
```
|
||||||
|
#a {artist} #r {release} #t {track}
|
||||||
|
```
|
||||||
|
|
||||||
|
You can escape stuff like `#` doing this: `\#`
|
||||||
|
|
||||||
|
## Downloading
|
||||||
|
|
||||||
|
To download something, you either need a direct link, or you need to have already searched for options
|
||||||
|
|
||||||
|
```mkshell
|
||||||
|
> d: {option ids or direct url}
|
||||||
|
|
||||||
|
# examples
|
||||||
|
> d: 0, 3, 4
|
||||||
|
> d: 1
|
||||||
|
> d: https://musify.club/release/some-random-release-183028492
|
||||||
|
```
|
||||||
|
|
||||||
|
## Misc
|
||||||
|
|
||||||
|
### Exit
|
||||||
|
|
||||||
|
```mkshell
|
||||||
|
> q
|
||||||
|
> quit
|
||||||
|
> exit
|
||||||
|
> abort
|
||||||
|
```
|
||||||
|
|
||||||
|
### Current Options
|
||||||
|
|
||||||
|
```mkshell
|
||||||
|
> .
|
||||||
|
```
|
||||||
|
|
||||||
|
### Previous Options
|
||||||
|
|
||||||
|
```
|
||||||
|
> ..
|
||||||
|
```
|
@ -15,30 +15,5 @@ peewee~=3.15.4
|
|||||||
ffmpeg-python~=0.2.0
|
ffmpeg-python~=0.2.0
|
||||||
platformdirs~=3.2.0
|
platformdirs~=3.2.0
|
||||||
transliterate~=1.10.2
|
transliterate~=1.10.2
|
||||||
pathvalidate~=2.5.2
|
sponsorblock~=0.1.3
|
||||||
pytest~=7.2.1
|
|
||||||
soupsieve~=2.3.2.post1
|
|
||||||
pip~=21.3.1
|
|
||||||
build~=0.9.0
|
|
||||||
wheel~=0.37.1
|
|
||||||
future~=0.18.3
|
|
||||||
pytz~=2022.4
|
|
||||||
attrs~=22.2.0
|
|
||||||
pep517~=0.13.0
|
|
||||||
tomli~=2.0.1
|
|
||||||
numpy~=1.23.4
|
|
||||||
regex~=2022.9.13
|
regex~=2022.9.13
|
||||||
pandas~=1.5.0
|
|
||||||
ply~=3.11
|
|
||||||
plumbum~=1.8.1
|
|
||||||
wcwidth~=0.2.5
|
|
||||||
pluggy~=1.0.0
|
|
||||||
exceptiongroup~=1.1.0
|
|
||||||
iniconfig~=2.0.0
|
|
||||||
six~=1.16.0
|
|
||||||
greenlet~=2.0.2
|
|
||||||
Pygments~=2.13.0
|
|
||||||
idna~=3.4
|
|
||||||
urllib3~=1.26.12
|
|
||||||
pyparsing~=3.0.9
|
|
||||||
progressbar~=2.5
|
|
@ -1,59 +1,31 @@
|
|||||||
import music_kraken
|
import music_kraken
|
||||||
from music_kraken import pages
|
|
||||||
from music_kraken.utils.enums.source import SourcePages
|
|
||||||
from music_kraken.objects import Song, Target, Source, Album
|
|
||||||
|
|
||||||
|
|
||||||
def search_pages():
|
|
||||||
search = pages.Search()
|
|
||||||
print("metadata", search.pages)
|
|
||||||
print("audio", search.audio_pages)
|
|
||||||
|
|
||||||
print()
|
|
||||||
print(search)
|
|
||||||
|
|
||||||
search.choose_page(pages.Musify)
|
|
||||||
|
|
||||||
print()
|
|
||||||
print(search)
|
|
||||||
|
|
||||||
search.choose_index(0)
|
|
||||||
print(search)
|
|
||||||
|
|
||||||
|
|
||||||
def direct_download():
|
|
||||||
search = pages.Search()
|
|
||||||
|
|
||||||
search.search_url("https://www.metal-archives.com/bands/Ghost_Bath/3540372489")
|
|
||||||
print(search)
|
|
||||||
|
|
||||||
search.search_url("https://musify.club/artist/ghost-bath-280348")
|
|
||||||
print(search)
|
|
||||||
|
|
||||||
|
|
||||||
def download_audio():
|
|
||||||
song = Song(
|
|
||||||
source_list=[
|
|
||||||
Source(SourcePages.MUSIFY, "https://musify.club/track/im-in-a-coffin-life-never-was-waste-of-skin-16360302")
|
|
||||||
],
|
|
||||||
target_list=[
|
|
||||||
Target(relative_to_music_dir=True, path="example", file="waste_of_skin_1"),
|
|
||||||
Target(relative_to_music_dir=True, path="example", file="waste_of_skin_2")
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
pages.Musify.download_song(song)
|
|
||||||
|
|
||||||
|
|
||||||
def real_download():
|
|
||||||
search = pages.Search()
|
|
||||||
search.search_url("https://musify.club/release/children-of-the-night-2018-1079829")
|
|
||||||
search.download_chosen()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
music_kraken.cli(genre="test", command_list=[
|
normally_download = [
|
||||||
"#a Molchat Doma",
|
"s: #a Ghost Bath",
|
||||||
"0",
|
"1",
|
||||||
"ok"
|
"d: 1, 5"
|
||||||
])
|
]
|
||||||
|
|
||||||
|
direct_download = [
|
||||||
|
"d: https://musify.club/release/crystal-f-x-2012-795181"
|
||||||
|
]
|
||||||
|
|
||||||
|
fetch_musify_song = [
|
||||||
|
"s: https://musify.club/track/blokkmonsta-schwartz-crystal-f-purer-hass-8369115"
|
||||||
|
]
|
||||||
|
|
||||||
|
fetch_youtube_playlist = [
|
||||||
|
"s: https://yt.artemislena.eu/playlist?list=OLAK5uy_kcUBiDv5ATbl-R20OjNaZ5G28XFanQOmM"
|
||||||
|
]
|
||||||
|
|
||||||
|
download_youtube_playlist = ["d: https://www.youtube.com/playlist?list=OLAK5uy_lqI_c6aDF9q4DWJ4TBzt1AFQYx_FXfU4E"]
|
||||||
|
|
||||||
|
youtube_search = [
|
||||||
|
"s: #a Zombiez",
|
||||||
|
"10",
|
||||||
|
"d: 5"
|
||||||
|
]
|
||||||
|
|
||||||
|
music_kraken.cli.download(genre="test", command_list=download_youtube_playlist, process_metadata_anyway=True)
|
||||||
|
@ -3,7 +3,7 @@ from music_kraken.pages import EncyclopaediaMetallum
|
|||||||
|
|
||||||
|
|
||||||
def search():
|
def search():
|
||||||
results = EncyclopaediaMetallum.search_by_query("#a Ghost Bath")
|
results = EncyclopaediaMetallum._raw_search("#a Ghost Bath")
|
||||||
print(results)
|
print(results)
|
||||||
print(results[0].source_collection)
|
print(results[0].source_collection)
|
||||||
|
|
||||||
|
@ -1,17 +1,11 @@
|
|||||||
import logging
|
import logging
|
||||||
import re
|
|
||||||
from pathlib import Path
|
|
||||||
from typing import List
|
|
||||||
|
|
||||||
import gc
|
import gc
|
||||||
import musicbrainzngs
|
import musicbrainzngs
|
||||||
|
|
||||||
from . import objects, pages
|
from .utils.config import read_config
|
||||||
from .utils import exception, shared, path_manager
|
from .utils.shared import MODIFY_GC
|
||||||
from .utils.config import config, read, write, PATHS_SECTION
|
from . import cli
|
||||||
from .utils.shared import MUSIC_DIR, MODIFY_GC, NOT_A_GENRE_REGEX, get_random_message
|
|
||||||
from .utils.string_processing import fit_to_file_system
|
|
||||||
|
|
||||||
|
|
||||||
if MODIFY_GC:
|
if MODIFY_GC:
|
||||||
"""
|
"""
|
||||||
@ -30,241 +24,3 @@ if MODIFY_GC:
|
|||||||
|
|
||||||
logging.getLogger("musicbrainzngs").setLevel(logging.WARNING)
|
logging.getLogger("musicbrainzngs").setLevel(logging.WARNING)
|
||||||
musicbrainzngs.set_useragent("metadata receiver", "0.1", "https://github.com/HeIIow2/music-downloader")
|
musicbrainzngs.set_useragent("metadata receiver", "0.1", "https://github.com/HeIIow2/music-downloader")
|
||||||
|
|
||||||
URL_REGEX = 'https?://(?:[-\w.]|(?:%[\da-fA-F]{2}))+'
|
|
||||||
DOWNLOAD_COMMANDS = {
|
|
||||||
"ok",
|
|
||||||
"download",
|
|
||||||
"\\d",
|
|
||||||
"hs"
|
|
||||||
}
|
|
||||||
|
|
||||||
EXIT_COMMANDS = {
|
|
||||||
"exit",
|
|
||||||
"quit"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def print_cute_message():
|
|
||||||
message = get_random_message()
|
|
||||||
try:
|
|
||||||
print(message)
|
|
||||||
except UnicodeEncodeError:
|
|
||||||
message = str(c for c in message if 0 < ord(c) < 127)
|
|
||||||
print(message)
|
|
||||||
|
|
||||||
|
|
||||||
def exit_message():
|
|
||||||
print()
|
|
||||||
print_cute_message()
|
|
||||||
print("See you soon! :3")
|
|
||||||
|
|
||||||
|
|
||||||
def paths():
|
|
||||||
print(f"Temp dir:\t{shared.TEMP_DIR}\n"
|
|
||||||
f"Music dir:\t{shared.MUSIC_DIR}\n"
|
|
||||||
f"Log file:\t{shared.LOG_PATH}\n"
|
|
||||||
f"Config file:\t{shared.CONFIG_FILE}")
|
|
||||||
print()
|
|
||||||
print_cute_message()
|
|
||||||
print()
|
|
||||||
|
|
||||||
|
|
||||||
def settings(
|
|
||||||
name: str = None,
|
|
||||||
value: str = None,
|
|
||||||
):
|
|
||||||
def modify_setting(_name: str, _value: str, invalid_ok: bool = True) -> bool:
|
|
||||||
try:
|
|
||||||
config.set_name_to_value(_name, _value)
|
|
||||||
except exception.config.SettingException as e:
|
|
||||||
if invalid_ok:
|
|
||||||
print(e)
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
raise e
|
|
||||||
|
|
||||||
write()
|
|
||||||
return True
|
|
||||||
|
|
||||||
def print_settings():
|
|
||||||
for i, attribute in enumerate(config):
|
|
||||||
print(f"{i:0>2}: {attribute.name}={attribute.value}")
|
|
||||||
|
|
||||||
def modify_setting_by_index(index: int) -> bool:
|
|
||||||
attribute = list(config)[index]
|
|
||||||
|
|
||||||
print()
|
|
||||||
print(attribute)
|
|
||||||
|
|
||||||
input__ = input(f"{attribute.name}=")
|
|
||||||
if not modify_setting(attribute.name, input__.strip()):
|
|
||||||
return modify_setting_by_index(index)
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
if name is not None and value is not None:
|
|
||||||
modify_setting(name, value, invalid_ok=True)
|
|
||||||
|
|
||||||
print()
|
|
||||||
print_cute_message()
|
|
||||||
print()
|
|
||||||
return
|
|
||||||
|
|
||||||
while True:
|
|
||||||
print_settings()
|
|
||||||
|
|
||||||
input_ = input("Id of setting to modify: ")
|
|
||||||
print()
|
|
||||||
if input_.isdigit() and int(input_) < len(config):
|
|
||||||
if modify_setting_by_index(int(input_)):
|
|
||||||
print()
|
|
||||||
print_cute_message()
|
|
||||||
print()
|
|
||||||
return
|
|
||||||
else:
|
|
||||||
print("Please input a valid ID.")
|
|
||||||
print()
|
|
||||||
|
|
||||||
|
|
||||||
def cli(
|
|
||||||
genre: str = None,
|
|
||||||
download_all: bool = False,
|
|
||||||
direct_download_url: str = None,
|
|
||||||
command_list: List[str] = None
|
|
||||||
):
|
|
||||||
def get_existing_genre() -> List[str]:
|
|
||||||
"""
|
|
||||||
gets the name of all subdirectories of shared.MUSIC_DIR,
|
|
||||||
but filters out all directories, where the name matches with any patern
|
|
||||||
from shared.NOT_A_GENRE_REGEX.
|
|
||||||
"""
|
|
||||||
existing_genres: List[str] = []
|
|
||||||
|
|
||||||
# get all subdirectories of MUSIC_DIR, not the files in the dir.
|
|
||||||
existing_subdirectories: List[Path] = [f for f in MUSIC_DIR.iterdir() if f.is_dir()]
|
|
||||||
|
|
||||||
for subdirectory in existing_subdirectories:
|
|
||||||
name: str = subdirectory.name
|
|
||||||
|
|
||||||
if not any(re.match(regex_pattern, name) for regex_pattern in NOT_A_GENRE_REGEX):
|
|
||||||
existing_genres.append(name)
|
|
||||||
|
|
||||||
existing_genres.sort()
|
|
||||||
|
|
||||||
return existing_genres
|
|
||||||
|
|
||||||
def get_genre():
|
|
||||||
existing_genres = get_existing_genre()
|
|
||||||
for i, genre_option in enumerate(existing_genres):
|
|
||||||
print(f"{i + 1:0>2}: {genre_option}")
|
|
||||||
|
|
||||||
while True:
|
|
||||||
genre = input("Id or new genre: ")
|
|
||||||
|
|
||||||
if genre.isdigit():
|
|
||||||
genre_id = int(genre) - 1
|
|
||||||
if genre_id >= len(existing_genres):
|
|
||||||
print(f"No genre under the id {genre_id + 1}.")
|
|
||||||
continue
|
|
||||||
|
|
||||||
return existing_genres[genre_id]
|
|
||||||
|
|
||||||
new_genre = fit_to_file_system(genre)
|
|
||||||
|
|
||||||
agree_inputs = {"y", "yes", "ok"}
|
|
||||||
verification = input(f"create new genre \"{new_genre}\"? (Y/N): ").lower()
|
|
||||||
if verification in agree_inputs:
|
|
||||||
return new_genre
|
|
||||||
|
|
||||||
def next_search(_search: pages.Search, query: str) -> bool:
|
|
||||||
"""
|
|
||||||
:param _search:
|
|
||||||
:param query:
|
|
||||||
:return exit in the next step:
|
|
||||||
"""
|
|
||||||
nonlocal genre
|
|
||||||
nonlocal download_all
|
|
||||||
|
|
||||||
query: str = query.strip()
|
|
||||||
parsed: str = query.lower()
|
|
||||||
|
|
||||||
if parsed in EXIT_COMMANDS:
|
|
||||||
return True
|
|
||||||
|
|
||||||
if parsed == ".":
|
|
||||||
return False
|
|
||||||
if parsed == "..":
|
|
||||||
_search.goto_previous()
|
|
||||||
return False
|
|
||||||
|
|
||||||
if parsed.isdigit():
|
|
||||||
_search.choose_index(int(parsed))
|
|
||||||
return False
|
|
||||||
|
|
||||||
if parsed in DOWNLOAD_COMMANDS:
|
|
||||||
r = _search.download_chosen(genre=genre, download_all=download_all)
|
|
||||||
|
|
||||||
print()
|
|
||||||
print(r)
|
|
||||||
print()
|
|
||||||
|
|
||||||
return not r.is_mild_failure
|
|
||||||
|
|
||||||
url = re.match(URL_REGEX, query)
|
|
||||||
if url is not None:
|
|
||||||
if not _search.search_url(url.string):
|
|
||||||
print("The given url couldn't be found.")
|
|
||||||
return False
|
|
||||||
|
|
||||||
page = _search.get_page_from_query(parsed)
|
|
||||||
if page is not None:
|
|
||||||
_search.choose_page(page)
|
|
||||||
return False
|
|
||||||
|
|
||||||
# if everything else is not valid search
|
|
||||||
_search.search(query)
|
|
||||||
return False
|
|
||||||
|
|
||||||
if genre is None:
|
|
||||||
genre = get_genre()
|
|
||||||
print()
|
|
||||||
|
|
||||||
print_cute_message()
|
|
||||||
print()
|
|
||||||
print(f"Downloading to: \"{genre}\"")
|
|
||||||
print()
|
|
||||||
|
|
||||||
search = pages.Search()
|
|
||||||
|
|
||||||
# directly download url
|
|
||||||
if direct_download_url is not None:
|
|
||||||
if search.search_url(direct_download_url):
|
|
||||||
r = search.download_chosen(genre=genre, download_all=download_all)
|
|
||||||
print()
|
|
||||||
print(r)
|
|
||||||
print()
|
|
||||||
else:
|
|
||||||
print(f"Sorry, could not download the url: {direct_download_url}")
|
|
||||||
|
|
||||||
exit_message()
|
|
||||||
return
|
|
||||||
|
|
||||||
# run one command after another from the command list
|
|
||||||
if command_list is not None:
|
|
||||||
for command in command_list:
|
|
||||||
print(f">> {command}")
|
|
||||||
if next_search(search, command):
|
|
||||||
break
|
|
||||||
print(search)
|
|
||||||
|
|
||||||
exit_message()
|
|
||||||
return
|
|
||||||
|
|
||||||
# the actual cli
|
|
||||||
while True:
|
|
||||||
if next_search(search, input(">> ")):
|
|
||||||
break
|
|
||||||
print(search)
|
|
||||||
|
|
||||||
exit_message()
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
if __name__ == "__main__":
|
def cli():
|
||||||
import argparse
|
import argparse
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
@ -16,10 +16,16 @@ if __name__ == "__main__":
|
|||||||
help="Sets the logging level to debug."
|
help="Sets the logging level to debug."
|
||||||
)
|
)
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
'-m', '--force-post-process',
|
||||||
|
action="store_true",
|
||||||
|
help="If a to downloaded thing is skipped due to being found on disc,\nit will still update the metadata accordingly."
|
||||||
|
)
|
||||||
|
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-t', '--test',
|
'-t', '--test',
|
||||||
action="store_true",
|
action="store_true",
|
||||||
help="For the sake of testing. Equals: '-v -g test'"
|
help="For the sake of testing. Equals: '-vp -g test'"
|
||||||
)
|
)
|
||||||
|
|
||||||
# general arguments
|
# general arguments
|
||||||
@ -65,6 +71,13 @@ if __name__ == "__main__":
|
|||||||
help="Resets the config file to the default one.",
|
help="Resets the config file to the default one.",
|
||||||
action="store_true"
|
action="store_true"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
"--frontend",
|
||||||
|
"-f",
|
||||||
|
help="Set a good and fast invidious/piped instance from your homecountry, to reduce the latency.",
|
||||||
|
action="store_true"
|
||||||
|
)
|
||||||
|
|
||||||
arguments = parser.parse_args()
|
arguments = parser.parse_args()
|
||||||
|
|
||||||
@ -73,39 +86,44 @@ if __name__ == "__main__":
|
|||||||
print("Setting logging-level to DEBUG")
|
print("Setting logging-level to DEBUG")
|
||||||
logging.getLogger().setLevel(logging.DEBUG)
|
logging.getLogger().setLevel(logging.DEBUG)
|
||||||
|
|
||||||
import music_kraken
|
from . import cli
|
||||||
|
from .utils.config import read_config
|
||||||
music_kraken.read()
|
from .utils import shared
|
||||||
|
|
||||||
if arguments.setting is not None:
|
|
||||||
music_kraken.settings(*arguments.setting)
|
|
||||||
exit()
|
|
||||||
|
|
||||||
if arguments.settings:
|
|
||||||
music_kraken.settings()
|
|
||||||
exit()
|
|
||||||
|
|
||||||
if arguments.paths:
|
|
||||||
music_kraken.paths()
|
|
||||||
exit()
|
|
||||||
|
|
||||||
if arguments.r:
|
if arguments.r:
|
||||||
import os
|
import os
|
||||||
if os.path.exists(music_kraken.shared.CONFIG_FILE):
|
if os.path.exists(shared.CONFIG_FILE):
|
||||||
os.remove(music_kraken.shared.CONFIG_FILE)
|
os.remove(shared.CONFIG_FILE)
|
||||||
music_kraken.read()
|
read_config()
|
||||||
|
|
||||||
|
exit()
|
||||||
|
|
||||||
|
read_config()
|
||||||
|
|
||||||
|
if arguments.setting is not None:
|
||||||
|
cli.settings(*arguments.setting)
|
||||||
|
|
||||||
|
if arguments.settings:
|
||||||
|
cli.settings()
|
||||||
|
|
||||||
|
if arguments.paths:
|
||||||
|
cli.print_paths()
|
||||||
|
|
||||||
|
if arguments.frontend:
|
||||||
|
cli.set_frontend(silent=False)
|
||||||
|
|
||||||
# getting the genre
|
# getting the genre
|
||||||
genre: str = arguments.genre
|
genre: str = arguments.genre
|
||||||
if arguments.test:
|
if arguments.test:
|
||||||
genre = "test"
|
genre = "test"
|
||||||
|
|
||||||
try:
|
cli.download(
|
||||||
music_kraken.cli(
|
genre=genre,
|
||||||
genre=genre,
|
download_all=arguments.all,
|
||||||
download_all=arguments.all,
|
direct_download_url=arguments.url,
|
||||||
direct_download_url=arguments.url
|
process_metadata_anyway=arguments.force_post_process or arguments.test
|
||||||
)
|
)
|
||||||
except KeyboardInterrupt:
|
|
||||||
print("\n\nRaise an issue if I fucked up:\nhttps://github.com/HeIIow2/music-downloader/issues")
|
|
||||||
music_kraken.exit_message()
|
if __name__ == "__main__":
|
||||||
|
cli()
|
||||||
|
@ -1,13 +1,18 @@
|
|||||||
import ffmpeg
|
from typing import List, Tuple
|
||||||
|
from tqdm import tqdm
|
||||||
|
from ffmpeg_progress_yield import FfmpegProgress
|
||||||
|
import subprocess
|
||||||
|
|
||||||
from ..utils.shared import BITRATE, AUDIO_FORMAT, CODEX_LOGGER as LOGGER
|
from ..utils.shared import BITRATE, AUDIO_FORMAT, CODEX_LOGGER as LOGGER
|
||||||
from ..objects import Target
|
from ..objects import Target
|
||||||
|
|
||||||
|
|
||||||
def correct_codec(target: Target, bitrate_kb: int = BITRATE, audio_format: str = AUDIO_FORMAT):
|
def correct_codec(target: Target, bitrate_kb: int = BITRATE, audio_format: str = AUDIO_FORMAT, interval_list: List[Tuple[float, float]] = None):
|
||||||
if not target.exists:
|
if not target.exists:
|
||||||
LOGGER.warning(f"Target doesn't exist: {target.file_path}")
|
LOGGER.warning(f"Target doesn't exist: {target.file_path}")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
interval_list = interval_list or []
|
||||||
|
|
||||||
bitrate_b = int(bitrate_kb / 1024)
|
bitrate_b = int(bitrate_kb / 1024)
|
||||||
|
|
||||||
@ -15,18 +20,36 @@ def correct_codec(target: Target, bitrate_kb: int = BITRATE, audio_format: str =
|
|||||||
path=target._path,
|
path=target._path,
|
||||||
file=str(target._file) + "." + audio_format
|
file=str(target._file) + "." + audio_format
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# get the select thingie
|
||||||
|
# https://stackoverflow.com/questions/50594412/cut-multiple-parts-of-a-video-with-ffmpeg
|
||||||
|
aselect_list: List[str] = []
|
||||||
|
|
||||||
|
start = 0
|
||||||
|
next_start = 0
|
||||||
|
for end, next_start in interval_list:
|
||||||
|
aselect_list.append(f"between(t,{start},{end})")
|
||||||
|
start = next_start
|
||||||
|
aselect_list.append(f"gte(t,{next_start})")
|
||||||
|
|
||||||
|
select = f"aselect='{'+'.join(aselect_list)}',asetpts=N/SR/TB"
|
||||||
|
|
||||||
|
# build the ffmpeg command
|
||||||
|
ffmpeg_command = [
|
||||||
|
"ffmpeg",
|
||||||
|
"-i", str(target.file_path),
|
||||||
|
"-af", select,
|
||||||
|
"-b", str(bitrate_b),
|
||||||
|
str(output_target.file_path)
|
||||||
|
]
|
||||||
|
|
||||||
stream = ffmpeg.input(target.file_path)
|
# run the ffmpeg command with a progressbar
|
||||||
stream = stream.audio
|
ff = FfmpegProgress(ffmpeg_command)
|
||||||
stream = ffmpeg.output(
|
with tqdm(total=100, desc=f"removing {len(interval_list)} segments") as pbar:
|
||||||
stream,
|
for progress in ff.run_command_with_progress():
|
||||||
str(output_target.file_path),
|
pbar.update(progress-pbar.n)
|
||||||
audio_bitrate=bitrate_b,
|
|
||||||
format=audio_format
|
LOGGER.debug(ff.stderr)
|
||||||
)
|
|
||||||
out, err = ffmpeg.run(stream, quiet=True, overwrite_output=True)
|
|
||||||
if err != "":
|
|
||||||
LOGGER.debug(err)
|
|
||||||
|
|
||||||
output_target.copy_content(target)
|
output_target.copy_content(target)
|
||||||
output_target.file_path.unlink()
|
output_target.delete()
|
||||||
|
5
src/music_kraken/cli/__init__.py
Normal file
5
src/music_kraken/cli/__init__.py
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
from .informations import print_paths
|
||||||
|
from .main_downloader import download
|
||||||
|
from .options.settings import settings
|
||||||
|
from .options.frontend import set_frontend
|
||||||
|
|
1
src/music_kraken/cli/informations/__init__.py
Normal file
1
src/music_kraken/cli/informations/__init__.py
Normal file
@ -0,0 +1 @@
|
|||||||
|
from .paths import print_paths
|
20
src/music_kraken/cli/informations/paths.py
Normal file
20
src/music_kraken/cli/informations/paths.py
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
from ..utils import cli_function
|
||||||
|
|
||||||
|
from ...utils.path_manager import LOCATIONS
|
||||||
|
from ...utils import shared
|
||||||
|
|
||||||
|
|
||||||
|
def all_paths():
|
||||||
|
return {
|
||||||
|
"Temp dir": LOCATIONS.TEMP_DIRECTORY,
|
||||||
|
"Music dir": LOCATIONS.MUSIC_DIRECTORY,
|
||||||
|
"Log file": shared.LOG_PATH,
|
||||||
|
"Conf dir": LOCATIONS.CONFIG_DIRECTORY,
|
||||||
|
"Conf file": LOCATIONS.CONFIG_FILE
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@cli_function
|
||||||
|
def print_paths():
|
||||||
|
for name, path in all_paths().items():
|
||||||
|
print(f"{name}:\t{path}")
|
405
src/music_kraken/cli/main_downloader.py
Normal file
405
src/music_kraken/cli/main_downloader.py
Normal file
@ -0,0 +1,405 @@
|
|||||||
|
from typing import Set, Type, Dict, List
|
||||||
|
from pathlib import Path
|
||||||
|
import re
|
||||||
|
|
||||||
|
from .utils import cli_function
|
||||||
|
|
||||||
|
from ..utils.shared import MUSIC_DIR, NOT_A_GENRE_REGEX, ENABLE_RESULT_HISTORY, HISTORY_LENGTH, HELP_MESSAGE
|
||||||
|
from ..utils.regex import URL_PATTERN
|
||||||
|
from ..utils.string_processing import fit_to_file_system
|
||||||
|
from ..utils.support_classes import Query, DownloadResult
|
||||||
|
from ..utils.exception.download import UrlNotFoundException
|
||||||
|
from ..download.results import Results, Option, PageResults
|
||||||
|
from ..download.page_attributes import Pages
|
||||||
|
from ..pages import Page
|
||||||
|
from ..objects import Song, Album, Artist, DatabaseObject
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
This is the implementation of the Shell
|
||||||
|
|
||||||
|
# Behaviour
|
||||||
|
|
||||||
|
## Searching
|
||||||
|
|
||||||
|
```mkshell
|
||||||
|
> s: {querry or url}
|
||||||
|
|
||||||
|
# examples
|
||||||
|
> s: https://musify.club/release/some-random-release-183028492
|
||||||
|
> s: r: #a an Artist #r some random Release
|
||||||
|
```
|
||||||
|
|
||||||
|
Searches for an url, or an query
|
||||||
|
|
||||||
|
### Query Syntax
|
||||||
|
|
||||||
|
```
|
||||||
|
#a {artist} #r {release} #t {track}
|
||||||
|
```
|
||||||
|
|
||||||
|
You can escape stuff like `#` doing this: `\#`
|
||||||
|
|
||||||
|
## Downloading
|
||||||
|
|
||||||
|
To download something, you either need a direct link, or you need to have already searched for options
|
||||||
|
|
||||||
|
```mkshell
|
||||||
|
> d: {option ids or direct url}
|
||||||
|
|
||||||
|
# examples
|
||||||
|
> d: 0, 3, 4
|
||||||
|
> d: 1
|
||||||
|
> d: https://musify.club/release/some-random-release-183028492
|
||||||
|
```
|
||||||
|
|
||||||
|
## Misc
|
||||||
|
|
||||||
|
### Exit
|
||||||
|
|
||||||
|
```mkshell
|
||||||
|
> q
|
||||||
|
> quit
|
||||||
|
> exit
|
||||||
|
> abort
|
||||||
|
```
|
||||||
|
|
||||||
|
### Current Options
|
||||||
|
|
||||||
|
```mkshell
|
||||||
|
> .
|
||||||
|
```
|
||||||
|
|
||||||
|
### Previous Options
|
||||||
|
|
||||||
|
```
|
||||||
|
> ..
|
||||||
|
```
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
EXIT_COMMANDS = {"q", "quit", "exit", "abort"}
|
||||||
|
ALPHABET = "abcdefghijklmnopqrstuvwxyz"
|
||||||
|
PAGE_NAME_FILL = "-"
|
||||||
|
MAX_PAGE_LEN = 21
|
||||||
|
|
||||||
|
|
||||||
|
def get_existing_genre() -> List[str]:
|
||||||
|
"""
|
||||||
|
gets the name of all subdirectories of shared.MUSIC_DIR,
|
||||||
|
but filters out all directories, where the name matches with any patern
|
||||||
|
from shared.NOT_A_GENRE_REGEX.
|
||||||
|
"""
|
||||||
|
existing_genres: List[str] = []
|
||||||
|
|
||||||
|
# get all subdirectories of MUSIC_DIR, not the files in the dir.
|
||||||
|
existing_subdirectories: List[Path] = [f for f in MUSIC_DIR.iterdir() if f.is_dir()]
|
||||||
|
|
||||||
|
for subdirectory in existing_subdirectories:
|
||||||
|
name: str = subdirectory.name
|
||||||
|
|
||||||
|
if not any(re.match(regex_pattern, name) for regex_pattern in NOT_A_GENRE_REGEX):
|
||||||
|
existing_genres.append(name)
|
||||||
|
|
||||||
|
existing_genres.sort()
|
||||||
|
|
||||||
|
return existing_genres
|
||||||
|
|
||||||
|
def get_genre():
|
||||||
|
existing_genres = get_existing_genre()
|
||||||
|
for i, genre_option in enumerate(existing_genres):
|
||||||
|
print(f"{i + 1:0>2}: {genre_option}")
|
||||||
|
|
||||||
|
while True:
|
||||||
|
genre = input("Id or new genre: ")
|
||||||
|
|
||||||
|
if genre.isdigit():
|
||||||
|
genre_id = int(genre) - 1
|
||||||
|
if genre_id >= len(existing_genres):
|
||||||
|
print(f"No genre under the id {genre_id + 1}.")
|
||||||
|
continue
|
||||||
|
|
||||||
|
return existing_genres[genre_id]
|
||||||
|
|
||||||
|
new_genre = fit_to_file_system(genre)
|
||||||
|
|
||||||
|
agree_inputs = {"y", "yes", "ok"}
|
||||||
|
verification = input(f"create new genre \"{new_genre}\"? (Y/N): ").lower()
|
||||||
|
if verification in agree_inputs:
|
||||||
|
return new_genre
|
||||||
|
|
||||||
|
|
||||||
|
def help_message():
|
||||||
|
print()
|
||||||
|
print(HELP_MESSAGE)
|
||||||
|
print()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class Downloader:
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
exclude_pages: Set[Type[Page]] = None,
|
||||||
|
exclude_shady: bool = False,
|
||||||
|
max_displayed_options: int = 10,
|
||||||
|
option_digits: int = 3,
|
||||||
|
genre: str = None,
|
||||||
|
process_metadata_anyway: bool = False,
|
||||||
|
) -> None:
|
||||||
|
self.pages: Pages = Pages(exclude_pages=exclude_pages, exclude_shady=exclude_shady)
|
||||||
|
|
||||||
|
self.page_dict: Dict[str, Type[Page]] = dict()
|
||||||
|
|
||||||
|
self.max_displayed_options = max_displayed_options
|
||||||
|
self.option_digits: int = option_digits
|
||||||
|
|
||||||
|
self.current_results: Results = None
|
||||||
|
self._result_history: List[Results] = []
|
||||||
|
|
||||||
|
self.genre = genre or get_genre()
|
||||||
|
self.process_metadata_anyway = process_metadata_anyway
|
||||||
|
|
||||||
|
print()
|
||||||
|
print(f"Downloading to: \"{self.genre}\"")
|
||||||
|
print()
|
||||||
|
|
||||||
|
|
||||||
|
def print_current_options(self):
|
||||||
|
self.page_dict = dict()
|
||||||
|
|
||||||
|
print()
|
||||||
|
|
||||||
|
page_count = 0
|
||||||
|
for option in self.current_results.formated_generator(max_items_per_page=self.max_displayed_options):
|
||||||
|
if isinstance(option, Option):
|
||||||
|
print(f"{option.index:0{self.option_digits}} {option.music_object.option_string}")
|
||||||
|
else:
|
||||||
|
prefix = ALPHABET[page_count%len(ALPHABET)]
|
||||||
|
print(f"({prefix}) ------------------------{option.__name__:{PAGE_NAME_FILL}<{MAX_PAGE_LEN}}------------")
|
||||||
|
|
||||||
|
self.page_dict[prefix] = option
|
||||||
|
self.page_dict[option.__name__] = option
|
||||||
|
|
||||||
|
page_count += 1
|
||||||
|
|
||||||
|
print()
|
||||||
|
|
||||||
|
def set_current_options(self, current_options: Results):
|
||||||
|
if ENABLE_RESULT_HISTORY:
|
||||||
|
self._result_history.append(current_options)
|
||||||
|
|
||||||
|
if HISTORY_LENGTH != -1:
|
||||||
|
if len(self._result_history) > HISTORY_LENGTH:
|
||||||
|
self._result_history.pop(0)
|
||||||
|
|
||||||
|
self.current_results = current_options
|
||||||
|
|
||||||
|
def previous_option(self) -> bool:
|
||||||
|
if not ENABLE_RESULT_HISTORY:
|
||||||
|
print("History is turned of.\nGo to settings, and change the value at 'result_history' to 'true'.")
|
||||||
|
return False
|
||||||
|
|
||||||
|
if len(self._result_history) <= 1:
|
||||||
|
print(f"No results in history.")
|
||||||
|
return False
|
||||||
|
self._result_history.pop()
|
||||||
|
self.current_results = self._result_history[-1]
|
||||||
|
return True
|
||||||
|
|
||||||
|
def _process_parsed(self, key_text: Dict[str, str], query: str) -> Query:
|
||||||
|
song = None if not "t" in key_text else Song(title=key_text["t"], dynamic=True)
|
||||||
|
album = None if not "r" in key_text else Album(title=key_text["r"], dynamic=True)
|
||||||
|
artist = None if not "a" in key_text else Artist(name=key_text["a"], dynamic=True)
|
||||||
|
|
||||||
|
if song is not None:
|
||||||
|
song.album_collection.append(album)
|
||||||
|
song.main_artist_collection.append(artist)
|
||||||
|
return Query(raw_query=query, music_object=song)
|
||||||
|
|
||||||
|
if album is not None:
|
||||||
|
album.artist_collection.append(artist)
|
||||||
|
return Query(raw_query=query, music_object=album)
|
||||||
|
|
||||||
|
if artist is not None:
|
||||||
|
return Query(raw_query=query, music_object=artist)
|
||||||
|
|
||||||
|
return Query(raw_query=query)
|
||||||
|
|
||||||
|
def search(self, query: str):
|
||||||
|
if re.match(URL_PATTERN, query) is not None:
|
||||||
|
try:
|
||||||
|
page, data_object = self.pages.fetch_url(query)
|
||||||
|
except UrlNotFoundException as e:
|
||||||
|
print(f"{e.url} could not be attributed/parsed to any yet implemented site.\n"
|
||||||
|
f"PR appreciated if the site isn't implemented.\n"
|
||||||
|
f"Recommendations and suggestions on sites to implement appreciated.\n"
|
||||||
|
f"But don't be a bitch if I don't end up implementing it.")
|
||||||
|
return
|
||||||
|
self.set_current_options(PageResults(page, data_object.options))
|
||||||
|
self.print_current_options()
|
||||||
|
return
|
||||||
|
|
||||||
|
special_characters = "#\\"
|
||||||
|
query = query + " "
|
||||||
|
|
||||||
|
key_text = {}
|
||||||
|
|
||||||
|
skip_next = False
|
||||||
|
escape_next = False
|
||||||
|
new_text = ""
|
||||||
|
latest_key: str = None
|
||||||
|
for i in range(len(query) - 1):
|
||||||
|
current_char = query[i]
|
||||||
|
next_char = query[i+1]
|
||||||
|
|
||||||
|
if skip_next:
|
||||||
|
skip_next = False
|
||||||
|
continue
|
||||||
|
|
||||||
|
if escape_next:
|
||||||
|
new_text += current_char
|
||||||
|
escape_next = False
|
||||||
|
|
||||||
|
# escaping
|
||||||
|
if current_char == "\\":
|
||||||
|
if next_char in special_characters:
|
||||||
|
escape_next = True
|
||||||
|
continue
|
||||||
|
|
||||||
|
if current_char == "#":
|
||||||
|
if latest_key is not None:
|
||||||
|
key_text[latest_key] = new_text
|
||||||
|
new_text = ""
|
||||||
|
|
||||||
|
latest_key = next_char
|
||||||
|
skip_next = True
|
||||||
|
continue
|
||||||
|
|
||||||
|
new_text += current_char
|
||||||
|
|
||||||
|
if latest_key is not None:
|
||||||
|
key_text[latest_key] = new_text
|
||||||
|
|
||||||
|
|
||||||
|
parsed_query: Query = self._process_parsed(key_text, query)
|
||||||
|
|
||||||
|
self.set_current_options(self.pages.search(parsed_query))
|
||||||
|
self.print_current_options()
|
||||||
|
|
||||||
|
def goto(self, index: int):
|
||||||
|
page: Type[Page]
|
||||||
|
music_object: DatabaseObject
|
||||||
|
|
||||||
|
if self.current_results is not None:
|
||||||
|
self.current_results.delete_details(index)
|
||||||
|
|
||||||
|
try:
|
||||||
|
page, music_object = self.current_results.get_music_object_by_index(index)
|
||||||
|
except KeyError:
|
||||||
|
print()
|
||||||
|
print(f"The option {index} doesn't exist.")
|
||||||
|
print()
|
||||||
|
return
|
||||||
|
|
||||||
|
self.pages.fetch_details(music_object)
|
||||||
|
|
||||||
|
self.set_current_options(PageResults(page, music_object.options))
|
||||||
|
|
||||||
|
self.print_current_options()
|
||||||
|
|
||||||
|
|
||||||
|
def download(self, download_str: str, download_all: bool = False) -> bool:
|
||||||
|
to_download: List[DatabaseObject] = []
|
||||||
|
|
||||||
|
if re.match(URL_PATTERN, download_str) is not None:
|
||||||
|
_, music_objects = self.pages.fetch_url(download_str)
|
||||||
|
to_download.append(music_objects)
|
||||||
|
|
||||||
|
else:
|
||||||
|
index: str
|
||||||
|
for index in download_str.split(", "):
|
||||||
|
if not index.strip().isdigit():
|
||||||
|
print()
|
||||||
|
print(f"Every download thingie has to be an index, not {index}.")
|
||||||
|
print()
|
||||||
|
return False
|
||||||
|
|
||||||
|
for index in download_str.split(", "):
|
||||||
|
to_download.append(self.current_results.get_music_object_by_index(int(index))[1])
|
||||||
|
|
||||||
|
print()
|
||||||
|
print("Downloading:")
|
||||||
|
for download_object in to_download:
|
||||||
|
print(download_object.option_string)
|
||||||
|
print()
|
||||||
|
|
||||||
|
_result_map: Dict[DatabaseObject, DownloadResult] = dict()
|
||||||
|
|
||||||
|
for database_object in to_download:
|
||||||
|
r = self.pages.download(music_object=database_object, genre=self.genre, download_all=download_all, process_metadata_anyway=self.process_metadata_anyway)
|
||||||
|
_result_map[database_object] = r
|
||||||
|
|
||||||
|
for music_object, result in _result_map.items():
|
||||||
|
print()
|
||||||
|
print(music_object.option_string)
|
||||||
|
print(result)
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
def process_input(self, input_str: str) -> bool:
|
||||||
|
input_str = input_str.strip()
|
||||||
|
processed_input: str = input_str.lower()
|
||||||
|
|
||||||
|
if processed_input in EXIT_COMMANDS:
|
||||||
|
return True
|
||||||
|
|
||||||
|
if processed_input == ".":
|
||||||
|
self.print_current_options()
|
||||||
|
return False
|
||||||
|
|
||||||
|
if processed_input == "..":
|
||||||
|
if self.previous_option():
|
||||||
|
self.print_current_options()
|
||||||
|
return False
|
||||||
|
|
||||||
|
if processed_input.startswith("s: "):
|
||||||
|
self.search(input_str[3:])
|
||||||
|
return False
|
||||||
|
|
||||||
|
if processed_input.startswith("d: "):
|
||||||
|
return self.download(input_str[3:])
|
||||||
|
|
||||||
|
if processed_input.isdigit():
|
||||||
|
self.goto(int(processed_input))
|
||||||
|
return False
|
||||||
|
|
||||||
|
if processed_input != "help":
|
||||||
|
print("Invalid input.")
|
||||||
|
help_message()
|
||||||
|
return False
|
||||||
|
|
||||||
|
def mainloop(self):
|
||||||
|
while True:
|
||||||
|
if self.process_input(input("> ")):
|
||||||
|
return
|
||||||
|
|
||||||
|
@cli_function
|
||||||
|
def download(
|
||||||
|
genre: str = None,
|
||||||
|
download_all: bool = False,
|
||||||
|
direct_download_url: str = None,
|
||||||
|
command_list: List[str] = None,
|
||||||
|
process_metadata_anyway: bool = False,
|
||||||
|
):
|
||||||
|
shell = Downloader(genre=genre, process_metadata_anyway=process_metadata_anyway)
|
||||||
|
|
||||||
|
if command_list is not None:
|
||||||
|
for command in command_list:
|
||||||
|
shell.process_input(command)
|
||||||
|
return
|
||||||
|
|
||||||
|
if direct_download_url is not None:
|
||||||
|
if shell.download(direct_download_url, download_all=download_all):
|
||||||
|
return
|
||||||
|
|
||||||
|
shell.mainloop()
|
185
src/music_kraken/cli/options/frontend.py
Normal file
185
src/music_kraken/cli/options/frontend.py
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
from typing import Dict, List
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from collections import defaultdict
|
||||||
|
|
||||||
|
from ..utils import cli_function
|
||||||
|
|
||||||
|
from ...objects import Country
|
||||||
|
from ...utils import config, write_config
|
||||||
|
from ...connection import Connection
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Instance:
|
||||||
|
"""
|
||||||
|
Attributes which influence the quality of an instance:
|
||||||
|
|
||||||
|
- users
|
||||||
|
"""
|
||||||
|
name: str
|
||||||
|
uri: str
|
||||||
|
regions: List[Country]
|
||||||
|
users: int = 0
|
||||||
|
|
||||||
|
def __str__(self) -> str:
|
||||||
|
return f"{self.name} with {self.users} users."
|
||||||
|
|
||||||
|
|
||||||
|
class FrontendInstance:
|
||||||
|
SETTING_NAME = "placeholder"
|
||||||
|
|
||||||
|
def __init__(self) -> None:
|
||||||
|
self.region_instances: Dict[Country, List[Instance]] = defaultdict(list)
|
||||||
|
self.all_instances: List[Instance] = []
|
||||||
|
|
||||||
|
def add_instance(self, instance: Instance):
|
||||||
|
self.all_instances.append(instance)
|
||||||
|
|
||||||
|
config.set_name_to_value("youtube_url", instance.uri)
|
||||||
|
|
||||||
|
for region in instance.regions:
|
||||||
|
self.region_instances[region].append(instance)
|
||||||
|
|
||||||
|
def fetch(self, silent: bool = False):
|
||||||
|
if not silent:
|
||||||
|
print(f"Downloading {type(self).__name__} instances...")
|
||||||
|
|
||||||
|
def set_instance(self, instance: Instance):
|
||||||
|
config.set_name_to_value(self.SETTING_NAME, instance.uri)
|
||||||
|
write_config()
|
||||||
|
|
||||||
|
def _choose_country(self) -> List[Instance]:
|
||||||
|
print("Input the country code, an example would be \"US\"")
|
||||||
|
print('\n'.join(f'{region.name} ({region.alpha_2})' for region in self.region_instances))
|
||||||
|
print()
|
||||||
|
|
||||||
|
|
||||||
|
available_instances = set(i.alpha_2 for i in self.region_instances)
|
||||||
|
|
||||||
|
chosen_region = ""
|
||||||
|
|
||||||
|
while chosen_region not in available_instances:
|
||||||
|
chosen_region = input("nearest country: ").strip().upper()
|
||||||
|
|
||||||
|
return self.region_instances[Country.by_alpha_2(chosen_region)]
|
||||||
|
|
||||||
|
def choose(self, silent: bool = False):
|
||||||
|
instances = self.all_instances if silent else self._choose_country()
|
||||||
|
instances.sort(key=lambda x: x.users, reverse=True)
|
||||||
|
|
||||||
|
if silent:
|
||||||
|
self.set_instance(instances[0])
|
||||||
|
return
|
||||||
|
|
||||||
|
# output the options
|
||||||
|
print("Choose your instance (input needs to be a digit):")
|
||||||
|
for i, instance in enumerate(instances):
|
||||||
|
print(f"{i}) {instance}")
|
||||||
|
|
||||||
|
print()
|
||||||
|
|
||||||
|
# ask for index
|
||||||
|
index = ""
|
||||||
|
while not index.isdigit() or int(index) >= len(instances):
|
||||||
|
index = input("> ").strip()
|
||||||
|
|
||||||
|
instance = instances[int(index)]
|
||||||
|
print()
|
||||||
|
print(f"Setting the instance to {instance}")
|
||||||
|
|
||||||
|
self.set_instance(instance)
|
||||||
|
|
||||||
|
|
||||||
|
class Invidious(FrontendInstance):
|
||||||
|
SETTING_NAME = "invidious_instance"
|
||||||
|
|
||||||
|
def __init__(self) -> None:
|
||||||
|
self.connection = Connection(host="https://api.invidious.io/")
|
||||||
|
self.endpoint = "https://api.invidious.io/instances.json"
|
||||||
|
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
|
|
||||||
|
def _process_instance(self, all_instance_data: dict):
|
||||||
|
instance_data = all_instance_data[1]
|
||||||
|
stats = instance_data["stats"]
|
||||||
|
|
||||||
|
if not instance_data["api"]:
|
||||||
|
return
|
||||||
|
if instance_data["type"] != "https":
|
||||||
|
return
|
||||||
|
|
||||||
|
region = instance_data["region"]
|
||||||
|
|
||||||
|
instance = Instance(
|
||||||
|
name=all_instance_data[0],
|
||||||
|
uri=instance_data["uri"],
|
||||||
|
regions=[Country.by_alpha_2(region)],
|
||||||
|
users=stats["usage"]["users"]["total"]
|
||||||
|
)
|
||||||
|
|
||||||
|
self.add_instance(instance)
|
||||||
|
|
||||||
|
def fetch(self, silent: bool):
|
||||||
|
r = self.connection.get(self.endpoint)
|
||||||
|
if r is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
for instance in r.json():
|
||||||
|
self._process_instance(all_instance_data=instance)
|
||||||
|
|
||||||
|
|
||||||
|
class Piped(FrontendInstance):
|
||||||
|
SETTING_NAME = "piped_instance"
|
||||||
|
|
||||||
|
def __init__(self) -> None:
|
||||||
|
self.connection = Connection(host="https://raw.githubusercontent.com")
|
||||||
|
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
|
def process_instance(self, instance_data: str):
|
||||||
|
cells = instance_data.split(" | ")
|
||||||
|
|
||||||
|
instance = Instance(
|
||||||
|
name=cells[0].strip(),
|
||||||
|
uri=cells[1].strip(),
|
||||||
|
regions=[Country.by_emoji(flag) for flag in cells[2].split(", ")]
|
||||||
|
)
|
||||||
|
|
||||||
|
self.add_instance(instance)
|
||||||
|
|
||||||
|
def fetch(self, silent: bool = False):
|
||||||
|
r = self.connection.get("https://raw.githubusercontent.com/wiki/TeamPiped/Piped-Frontend/Instances.md")
|
||||||
|
if r is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
process = False
|
||||||
|
|
||||||
|
for line in r.content.decode("utf-8").split("\n"):
|
||||||
|
line = line.strip()
|
||||||
|
|
||||||
|
if line != "" and process:
|
||||||
|
self.process_instance(line)
|
||||||
|
|
||||||
|
if line.startswith("---"):
|
||||||
|
process = True
|
||||||
|
|
||||||
|
|
||||||
|
class FrontendSelection:
|
||||||
|
def __init__(self):
|
||||||
|
self.invidious = Invidious()
|
||||||
|
self.piped = Piped()
|
||||||
|
|
||||||
|
def choose(self, silent: bool = False):
|
||||||
|
self.invidious.fetch(silent)
|
||||||
|
self.invidious.choose(silent)
|
||||||
|
|
||||||
|
self.piped.fetch(silent)
|
||||||
|
self.piped.choose(silent)
|
||||||
|
|
||||||
|
|
||||||
|
@cli_function
|
||||||
|
def set_frontend(silent: bool = False):
|
||||||
|
shell = FrontendSelection()
|
||||||
|
shell.choose(silent=silent)
|
||||||
|
|
71
src/music_kraken/cli/options/settings.py
Normal file
71
src/music_kraken/cli/options/settings.py
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
from ..utils import cli_function
|
||||||
|
|
||||||
|
from ...utils.config import config, write_config
|
||||||
|
from ...utils import exception
|
||||||
|
|
||||||
|
|
||||||
|
def modify_setting(_name: str, _value: str, invalid_ok: bool = True) -> bool:
|
||||||
|
try:
|
||||||
|
config.set_name_to_value(_name, _value)
|
||||||
|
except exception.config.SettingException as e:
|
||||||
|
if invalid_ok:
|
||||||
|
print(e)
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
raise e
|
||||||
|
|
||||||
|
write_config()
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def print_settings():
|
||||||
|
for i, attribute in enumerate(config):
|
||||||
|
print(f"{i:0>2}: {attribute.name}={attribute.value}")
|
||||||
|
|
||||||
|
|
||||||
|
def modify_setting_by_index(index: int) -> bool:
|
||||||
|
attribute = list(config)[index]
|
||||||
|
|
||||||
|
print()
|
||||||
|
print(attribute)
|
||||||
|
|
||||||
|
input__ = input(f"{attribute.name}=")
|
||||||
|
if not modify_setting(attribute.name, input__.strip()):
|
||||||
|
return modify_setting_by_index(index)
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def modify_setting_by_index(index: int) -> bool:
|
||||||
|
attribute = list(config)[index]
|
||||||
|
|
||||||
|
print()
|
||||||
|
print(attribute)
|
||||||
|
|
||||||
|
input__ = input(f"{attribute.name}=")
|
||||||
|
if not modify_setting(attribute.name, input__.strip()):
|
||||||
|
return modify_setting_by_index(index)
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
@cli_function
|
||||||
|
def settings(
|
||||||
|
name: str = None,
|
||||||
|
value: str = None,
|
||||||
|
):
|
||||||
|
if name is not None and value is not None:
|
||||||
|
modify_setting(name, value, invalid_ok=True)
|
||||||
|
return
|
||||||
|
|
||||||
|
while True:
|
||||||
|
print_settings()
|
||||||
|
|
||||||
|
input_ = input("Id of setting to modify: ")
|
||||||
|
print()
|
||||||
|
if input_.isdigit() and int(input_) < len(config):
|
||||||
|
if modify_setting_by_index(int(input_)):
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
print("Please input a valid ID.")
|
||||||
|
print()
|
32
src/music_kraken/cli/utils.py
Normal file
32
src/music_kraken/cli/utils.py
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
from ..utils.shared import get_random_message
|
||||||
|
|
||||||
|
|
||||||
|
def cli_function(function):
|
||||||
|
def wrapper(*args, **kwargs):
|
||||||
|
print_cute_message()
|
||||||
|
print()
|
||||||
|
try:
|
||||||
|
function(*args, **kwargs)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print("\n\nRaise an issue if I fucked up:\nhttps://github.com/HeIIow2/music-downloader/issues")
|
||||||
|
|
||||||
|
finally:
|
||||||
|
print()
|
||||||
|
print_cute_message()
|
||||||
|
print("See you soon! :3")
|
||||||
|
|
||||||
|
exit()
|
||||||
|
|
||||||
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
|
def print_cute_message():
|
||||||
|
message = get_random_message()
|
||||||
|
try:
|
||||||
|
print(message)
|
||||||
|
except UnicodeEncodeError:
|
||||||
|
message = str(c for c in message if 0 < ord(c) < 127)
|
||||||
|
print(message)
|
||||||
|
|
||||||
|
|
||||||
|
|
1
src/music_kraken/connection/__init__.py
Normal file
1
src/music_kraken/connection/__init__.py
Normal file
@ -0,0 +1 @@
|
|||||||
|
from .connection import Connection
|
295
src/music_kraken/connection/connection.py
Normal file
295
src/music_kraken/connection/connection.py
Normal file
@ -0,0 +1,295 @@
|
|||||||
|
import time
|
||||||
|
from typing import List, Dict, Callable, Optional, Set
|
||||||
|
from urllib.parse import urlparse, urlunsplit, ParseResult
|
||||||
|
import logging
|
||||||
|
|
||||||
|
import requests
|
||||||
|
from tqdm import tqdm
|
||||||
|
|
||||||
|
from .rotating import RotatingProxy
|
||||||
|
from ..utils.shared import PROXIES_LIST, CHUNK_SIZE
|
||||||
|
from ..utils.support_classes import DownloadResult
|
||||||
|
from ..objects import Target
|
||||||
|
|
||||||
|
|
||||||
|
class Connection:
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
host: str,
|
||||||
|
proxies: List[dict] = None,
|
||||||
|
tries: int = (len(PROXIES_LIST) + 1) * 4,
|
||||||
|
timeout: int = 7,
|
||||||
|
logger: logging.Logger = logging.getLogger("connection"),
|
||||||
|
header_values: Dict[str, str] = None,
|
||||||
|
accepted_response_codes: Set[int] = None,
|
||||||
|
semantic_not_found: bool = True
|
||||||
|
):
|
||||||
|
if proxies is None:
|
||||||
|
proxies = PROXIES_LIST
|
||||||
|
if header_values is None:
|
||||||
|
header_values = dict()
|
||||||
|
|
||||||
|
self.HEADER_VALUES = header_values
|
||||||
|
|
||||||
|
self.LOGGER = logger
|
||||||
|
self.HOST = urlparse(host)
|
||||||
|
self.TRIES = tries
|
||||||
|
self.TIMEOUT = timeout
|
||||||
|
self.rotating_proxy = RotatingProxy(proxy_list=proxies)
|
||||||
|
|
||||||
|
self.ACCEPTED_RESPONSE_CODES = accepted_response_codes or {200}
|
||||||
|
self.SEMANTIC_NOT_FOUND = semantic_not_found
|
||||||
|
|
||||||
|
self.session = requests.Session()
|
||||||
|
self.session.headers = self.get_header(**self.HEADER_VALUES)
|
||||||
|
self.session.proxies = self.rotating_proxy.current_proxy
|
||||||
|
|
||||||
|
def base_url(self, url: ParseResult = None):
|
||||||
|
if url is None:
|
||||||
|
url = self.HOST
|
||||||
|
|
||||||
|
return urlunsplit((url.scheme, url.netloc, "", "", ""))
|
||||||
|
|
||||||
|
def get_header(self, **header_values) -> Dict[str, str]:
|
||||||
|
return {
|
||||||
|
"user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36",
|
||||||
|
"Connection": "keep-alive",
|
||||||
|
# "Host": self.HOST.netloc,
|
||||||
|
"Referer": self.base_url(),
|
||||||
|
**header_values
|
||||||
|
}
|
||||||
|
|
||||||
|
def rotate(self):
|
||||||
|
self.session.proxies = self.rotating_proxy.rotate()
|
||||||
|
|
||||||
|
def _update_headers(
|
||||||
|
self,
|
||||||
|
headers: Optional[dict],
|
||||||
|
refer_from_origin: bool,
|
||||||
|
url: ParseResult
|
||||||
|
) -> Dict[str, str]:
|
||||||
|
if headers is None:
|
||||||
|
headers = dict()
|
||||||
|
|
||||||
|
if not refer_from_origin:
|
||||||
|
headers["Referer"] = self.base_url(url=url)
|
||||||
|
|
||||||
|
return headers
|
||||||
|
|
||||||
|
def _request(
|
||||||
|
self,
|
||||||
|
request: Callable,
|
||||||
|
try_count: int,
|
||||||
|
accepted_response_codes: set,
|
||||||
|
url: str,
|
||||||
|
timeout: float,
|
||||||
|
headers: dict,
|
||||||
|
refer_from_origin: bool = True,
|
||||||
|
raw_url: bool = False,
|
||||||
|
wait_on_403: bool = True,
|
||||||
|
**kwargs
|
||||||
|
) -> Optional[requests.Response]:
|
||||||
|
if try_count >= self.TRIES:
|
||||||
|
return
|
||||||
|
|
||||||
|
if timeout is None:
|
||||||
|
timeout = self.TIMEOUT
|
||||||
|
|
||||||
|
parsed_url = urlparse(url)
|
||||||
|
|
||||||
|
headers = self._update_headers(
|
||||||
|
headers=headers,
|
||||||
|
refer_from_origin=refer_from_origin,
|
||||||
|
url=parsed_url
|
||||||
|
)
|
||||||
|
|
||||||
|
request_url = parsed_url.geturl() if not raw_url else url
|
||||||
|
|
||||||
|
connection_failed = False
|
||||||
|
try:
|
||||||
|
r: requests.Response = request(request_url, timeout=timeout, headers=headers, **kwargs)
|
||||||
|
|
||||||
|
if r.status_code in accepted_response_codes:
|
||||||
|
return r
|
||||||
|
|
||||||
|
if self.SEMANTIC_NOT_FOUND and r.status_code == 404:
|
||||||
|
self.LOGGER.warning(f"Couldn't find url (404): {request_url}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
except requests.exceptions.Timeout:
|
||||||
|
self.LOGGER.warning(f"Request timed out at \"{request_url}\": ({try_count}-{self.TRIES})")
|
||||||
|
connection_failed = True
|
||||||
|
except requests.exceptions.ConnectionError:
|
||||||
|
self.LOGGER.warning(f"Couldn't connect to \"{request_url}\": ({try_count}-{self.TRIES})")
|
||||||
|
connection_failed = True
|
||||||
|
|
||||||
|
if not connection_failed:
|
||||||
|
self.LOGGER.warning(f"{self.HOST.netloc} responded wit {r.status_code} "
|
||||||
|
f"at {url}. ({try_count}-{self.TRIES})")
|
||||||
|
self.LOGGER.debug(r.content)
|
||||||
|
if wait_on_403:
|
||||||
|
self.LOGGER.warning(f"Waiting for 5 seconds.")
|
||||||
|
time.sleep(5)
|
||||||
|
|
||||||
|
self.rotate()
|
||||||
|
|
||||||
|
return self._request(
|
||||||
|
request=request,
|
||||||
|
try_count=try_count+1,
|
||||||
|
accepted_response_codes=accepted_response_codes,
|
||||||
|
url=url,
|
||||||
|
timeout=timeout,
|
||||||
|
headers=headers,
|
||||||
|
**kwargs
|
||||||
|
)
|
||||||
|
|
||||||
|
def get(
|
||||||
|
self,
|
||||||
|
url: str,
|
||||||
|
refer_from_origin: bool = True,
|
||||||
|
stream: bool = False,
|
||||||
|
accepted_response_codes: set = None,
|
||||||
|
timeout: float = None,
|
||||||
|
headers: dict = None,
|
||||||
|
raw_url: bool = False,
|
||||||
|
**kwargs
|
||||||
|
) -> Optional[requests.Response]:
|
||||||
|
if accepted_response_codes is None:
|
||||||
|
accepted_response_codes = self.ACCEPTED_RESPONSE_CODES
|
||||||
|
|
||||||
|
r = self._request(
|
||||||
|
request=self.session.get,
|
||||||
|
try_count=0,
|
||||||
|
accepted_response_codes=accepted_response_codes,
|
||||||
|
url=url,
|
||||||
|
timeout=timeout,
|
||||||
|
headers=headers,
|
||||||
|
raw_url=raw_url,
|
||||||
|
refer_from_origin=refer_from_origin,
|
||||||
|
stream=stream,
|
||||||
|
**kwargs
|
||||||
|
)
|
||||||
|
if r is None:
|
||||||
|
self.LOGGER.warning(f"Max attempts ({self.TRIES}) exceeded for: GET:{url}")
|
||||||
|
return r
|
||||||
|
|
||||||
|
def post(
|
||||||
|
self,
|
||||||
|
url: str,
|
||||||
|
json: dict,
|
||||||
|
refer_from_origin: bool = True,
|
||||||
|
stream: bool = False,
|
||||||
|
accepted_response_codes: set = None,
|
||||||
|
timeout: float = None,
|
||||||
|
headers: dict = None,
|
||||||
|
raw_url: bool = False,
|
||||||
|
**kwargs
|
||||||
|
) -> Optional[requests.Response]:
|
||||||
|
r = self._request(
|
||||||
|
request=self.session.post,
|
||||||
|
try_count=0,
|
||||||
|
accepted_response_codes=accepted_response_codes or self.ACCEPTED_RESPONSE_CODES,
|
||||||
|
url=url,
|
||||||
|
timeout=timeout,
|
||||||
|
headers=headers,
|
||||||
|
refer_from_origin=refer_from_origin,
|
||||||
|
raw_url=raw_url,
|
||||||
|
json=json,
|
||||||
|
stream=stream,
|
||||||
|
**kwargs
|
||||||
|
)
|
||||||
|
if r is None:
|
||||||
|
self.LOGGER.warning(f"Max attempts ({self.TRIES}) exceeded for: GET:{url}")
|
||||||
|
self.LOGGER.warning(f"payload: {json}")
|
||||||
|
return r
|
||||||
|
|
||||||
|
def stream_into(
|
||||||
|
self,
|
||||||
|
url: str,
|
||||||
|
target: Target,
|
||||||
|
description: str = "download",
|
||||||
|
refer_from_origin: bool = True,
|
||||||
|
accepted_response_codes: set = None,
|
||||||
|
timeout: float = None,
|
||||||
|
headers: dict = None,
|
||||||
|
raw_url: bool = False,
|
||||||
|
chunk_size: int = CHUNK_SIZE,
|
||||||
|
try_count: int = 0,
|
||||||
|
progress: int = 0,
|
||||||
|
**kwargs
|
||||||
|
) -> DownloadResult:
|
||||||
|
|
||||||
|
if progress > 0:
|
||||||
|
if headers is None:
|
||||||
|
headers = dict()
|
||||||
|
headers["Range"] = f"bytes={target.size}-"
|
||||||
|
|
||||||
|
if accepted_response_codes is None:
|
||||||
|
accepted_response_codes = self.ACCEPTED_RESPONSE_CODES
|
||||||
|
|
||||||
|
r = self._request(
|
||||||
|
request=self.session.get,
|
||||||
|
try_count=0,
|
||||||
|
accepted_response_codes=accepted_response_codes,
|
||||||
|
url=url,
|
||||||
|
timeout=timeout,
|
||||||
|
headers=headers,
|
||||||
|
raw_url=raw_url,
|
||||||
|
refer_from_origin=refer_from_origin,
|
||||||
|
stream=True,
|
||||||
|
**kwargs
|
||||||
|
)
|
||||||
|
|
||||||
|
if r is None:
|
||||||
|
return DownloadResult(error_message=f"Could not establish connection to: {url}")
|
||||||
|
|
||||||
|
target.create_path()
|
||||||
|
total_size = int(r.headers.get('content-length'))
|
||||||
|
progress = 0
|
||||||
|
|
||||||
|
retry = False
|
||||||
|
|
||||||
|
with target.open("ab") as f:
|
||||||
|
"""
|
||||||
|
https://en.wikipedia.org/wiki/Kilobyte
|
||||||
|
> The internationally recommended unit symbol for the kilobyte is kB.
|
||||||
|
"""
|
||||||
|
|
||||||
|
with tqdm(total=total_size-target.size, unit='B', unit_scale=True, unit_divisor=1024, desc=description) as t:
|
||||||
|
try:
|
||||||
|
for chunk in r.iter_content(chunk_size=chunk_size):
|
||||||
|
size = f.write(chunk)
|
||||||
|
progress += size
|
||||||
|
t.update(size)
|
||||||
|
|
||||||
|
except requests.exceptions.ConnectionError:
|
||||||
|
if try_count >= self.TRIES:
|
||||||
|
self.LOGGER.warning(f"Stream timed out at \"{url}\": to many retries, aborting.")
|
||||||
|
return DownloadResult(error_message=f"Stream timed out from {url}, reducing the chunksize might help.")
|
||||||
|
|
||||||
|
self.LOGGER.warning(f"Stream timed out at \"{url}\": ({try_count}-{self.TRIES})")
|
||||||
|
retry = True
|
||||||
|
|
||||||
|
if total_size > progress:
|
||||||
|
retry = True
|
||||||
|
|
||||||
|
|
||||||
|
if retry:
|
||||||
|
self.LOGGER.warning(f"Retrying stream...")
|
||||||
|
accepted_response_codes.add(206)
|
||||||
|
return self.stream_into(
|
||||||
|
url = url,
|
||||||
|
target = target,
|
||||||
|
description = description,
|
||||||
|
try_count=try_count+1,
|
||||||
|
progress=progress,
|
||||||
|
accepted_response_codes=accepted_response_codes,
|
||||||
|
timeout=timeout,
|
||||||
|
headers=headers,
|
||||||
|
raw_url=raw_url,
|
||||||
|
refer_from_origin=refer_from_origin,
|
||||||
|
chunk_size=chunk_size,
|
||||||
|
**kwargs
|
||||||
|
)
|
||||||
|
|
||||||
|
return DownloadResult()
|
43
src/music_kraken/connection/rotating.py
Normal file
43
src/music_kraken/connection/rotating.py
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
from typing import Dict, List
|
||||||
|
|
||||||
|
import requests
|
||||||
|
|
||||||
|
|
||||||
|
class RotatingObject:
|
||||||
|
"""
|
||||||
|
This will be used for RotatingProxies and invidious instances.
|
||||||
|
"""
|
||||||
|
def __init__(self, object_list: list):
|
||||||
|
self._object_list: list = object_list
|
||||||
|
|
||||||
|
if len(self._object_list) <= 0:
|
||||||
|
raise ValueError("There needs to be at least one item in a Rotating structure.")
|
||||||
|
|
||||||
|
self._current_index = 0
|
||||||
|
|
||||||
|
@property
|
||||||
|
def object(self):
|
||||||
|
return self._object_list[self._current_index]
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
return len(self._object_list)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def next(self):
|
||||||
|
self._current_index = (self._current_index + 1) % len(self._object_list)
|
||||||
|
|
||||||
|
return self._object_list[self._current_index]
|
||||||
|
|
||||||
|
|
||||||
|
class RotatingProxy(RotatingObject):
|
||||||
|
def __init__(self, proxy_list: List[Dict[str, str]]):
|
||||||
|
super().__init__(
|
||||||
|
proxy_list if len(proxy_list) > 0 else [None]
|
||||||
|
)
|
||||||
|
|
||||||
|
def rotate(self) -> Dict[str, str]:
|
||||||
|
return self.next
|
||||||
|
|
||||||
|
@property
|
||||||
|
def current_proxy(self) -> Dict[str, str]:
|
||||||
|
return super().object
|
97
src/music_kraken/download/page_attributes.py
Normal file
97
src/music_kraken/download/page_attributes.py
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
from typing import Tuple, Type, Dict, List, Set
|
||||||
|
|
||||||
|
from .results import SearchResults
|
||||||
|
from ..objects import DatabaseObject, Source
|
||||||
|
from ..utils.enums.source import SourcePages
|
||||||
|
from ..utils.support_classes import Query, DownloadResult
|
||||||
|
from ..utils.exception.download import UrlNotFoundException
|
||||||
|
from ..pages import Page, EncyclopaediaMetallum, Musify, YouTube, INDEPENDENT_DB_OBJECTS
|
||||||
|
|
||||||
|
ALL_PAGES: Set[Type[Page]] = {
|
||||||
|
EncyclopaediaMetallum,
|
||||||
|
Musify,
|
||||||
|
YouTube,
|
||||||
|
}
|
||||||
|
|
||||||
|
AUDIO_PAGES: Set[Type[Page]] = {
|
||||||
|
Musify,
|
||||||
|
YouTube,
|
||||||
|
}
|
||||||
|
|
||||||
|
SHADY_PAGES: Set[Type[Page]] = {
|
||||||
|
Musify,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class Pages:
|
||||||
|
def __init__(self, exclude_pages: Set[Type[Page]] = None, exclude_shady: bool = False) -> None:
|
||||||
|
# initialize all page instances
|
||||||
|
self._page_instances: Dict[Type[Page], Page] = dict()
|
||||||
|
self._source_to_page: Dict[SourcePages, Type[Page]] = dict()
|
||||||
|
|
||||||
|
exclude_pages = exclude_pages if exclude_pages is not None else set()
|
||||||
|
|
||||||
|
if exclude_shady:
|
||||||
|
exclude_pages = exclude_pages.union(SHADY_PAGES)
|
||||||
|
|
||||||
|
if not exclude_pages.issubset(ALL_PAGES):
|
||||||
|
raise ValueError(f"The excluded pages have to be a subset of all pages: {exclude_pages} | {ALL_PAGES}")
|
||||||
|
|
||||||
|
def _set_to_tuple(page_set: Set[Type[Page]]) -> Tuple[Type[Page], ...]:
|
||||||
|
return tuple(sorted(page_set, key=lambda page: page.__name__))
|
||||||
|
|
||||||
|
self._pages_set: Set[Type[Page]] = ALL_PAGES.difference(exclude_pages)
|
||||||
|
self.pages: Tuple[Type[Page], ...] = _set_to_tuple(self._pages_set)
|
||||||
|
|
||||||
|
self._audio_pages_set: Set[Type[Page]] = self._pages_set.intersection(AUDIO_PAGES)
|
||||||
|
self.audio_pages: Tuple[Type[Page], ...] = _set_to_tuple(self._audio_pages_set)
|
||||||
|
|
||||||
|
for page_type in self.pages:
|
||||||
|
self._page_instances[page_type] = page_type()
|
||||||
|
self._source_to_page[page_type.SOURCE_TYPE] = page_type
|
||||||
|
|
||||||
|
def search(self, query: Query) -> SearchResults:
|
||||||
|
result = SearchResults()
|
||||||
|
|
||||||
|
for page_type in self.pages:
|
||||||
|
result.add(
|
||||||
|
page=page_type,
|
||||||
|
search_result=self._page_instances[page_type].search(query=query)
|
||||||
|
)
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
def fetch_details(self, music_object: DatabaseObject, stop_at_level: int = 1) -> DatabaseObject:
|
||||||
|
if not isinstance(music_object, INDEPENDENT_DB_OBJECTS):
|
||||||
|
return music_object
|
||||||
|
|
||||||
|
for source_page in music_object.source_collection.source_pages:
|
||||||
|
page_type = self._source_to_page[source_page]
|
||||||
|
|
||||||
|
if page_type in self._pages_set:
|
||||||
|
music_object.merge(self._page_instances[page_type].fetch_details(music_object=music_object, stop_at_level=stop_at_level))
|
||||||
|
|
||||||
|
return music_object
|
||||||
|
|
||||||
|
def download(self, music_object: DatabaseObject, genre: str, download_all: bool = False, process_metadata_anyway: bool = False) -> DownloadResult:
|
||||||
|
if not isinstance(music_object, INDEPENDENT_DB_OBJECTS):
|
||||||
|
return DownloadResult(error_message=f"{type(music_object).__name__} can't be downloaded.")
|
||||||
|
|
||||||
|
_page_types = set(self._source_to_page[src] for src in music_object.source_collection.source_pages)
|
||||||
|
audio_pages = self._audio_pages_set.intersection(_page_types)
|
||||||
|
|
||||||
|
for download_page in audio_pages:
|
||||||
|
return self._page_instances[download_page].download(music_object=music_object, genre=genre, download_all=download_all, process_metadata_anyway=process_metadata_anyway)
|
||||||
|
|
||||||
|
return DownloadResult(error_message=f"No audio source has been found for {music_object}.")
|
||||||
|
|
||||||
|
def fetch_url(self, url: str, stop_at_level: int = 2) -> Tuple[Type[Page], DatabaseObject]:
|
||||||
|
source = Source.match_url(url, SourcePages.MANUAL)
|
||||||
|
|
||||||
|
if source is None:
|
||||||
|
raise UrlNotFoundException(url=url)
|
||||||
|
|
||||||
|
_actual_page = self._source_to_page[source.page_enum]
|
||||||
|
|
||||||
|
return _actual_page, self._page_instances[_actual_page].fetch_object_from_source(source=source, stop_at_level=stop_at_level)
|
101
src/music_kraken/download/results.py
Normal file
101
src/music_kraken/download/results.py
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
from typing import Tuple, Type, Dict, List, Generator, Union
|
||||||
|
from dataclasses import dataclass
|
||||||
|
|
||||||
|
from ..objects import DatabaseObject
|
||||||
|
from ..utils.enums.source import SourcePages
|
||||||
|
from ..pages import Page, EncyclopaediaMetallum, Musify
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Option:
|
||||||
|
index: int
|
||||||
|
music_object: DatabaseObject
|
||||||
|
|
||||||
|
|
||||||
|
class Results:
|
||||||
|
def __init__(self) -> None:
|
||||||
|
self._by_index: Dict[int, DatabaseObject] = dict()
|
||||||
|
self._page_by_index: Dict[int: Type[Page]] = dict()
|
||||||
|
|
||||||
|
def __iter__(self) -> Generator[DatabaseObject, None, None]:
|
||||||
|
for option in self.formated_generator():
|
||||||
|
if isinstance(option, Option):
|
||||||
|
yield option.music_object
|
||||||
|
|
||||||
|
def formated_generator(self, max_items_per_page: int = 10) -> Generator[Union[Type[Page], Option], None, None]:
|
||||||
|
self._by_index = dict()
|
||||||
|
self._page_by_index = dict()
|
||||||
|
|
||||||
|
def get_music_object_by_index(self, index: int) -> Tuple[Type[Page], DatabaseObject]:
|
||||||
|
# if this throws a key error, either the formated generator needs to be iterated, or the option doesn't exist.
|
||||||
|
return self._page_by_index[index], self._by_index[index]
|
||||||
|
|
||||||
|
def delete_details(self, exclude_index: int):
|
||||||
|
for index, music_object in self._by_index.items():
|
||||||
|
if index == exclude_index:
|
||||||
|
continue
|
||||||
|
|
||||||
|
music_object.strip_details()
|
||||||
|
|
||||||
|
|
||||||
|
class SearchResults(Results):
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
pages: Tuple[Type[Page], ...] = None
|
||||||
|
|
||||||
|
) -> None:
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
|
self.pages = pages or []
|
||||||
|
# this would initialize a list for every page, which I don't think I want
|
||||||
|
# self.results = Dict[Type[Page], List[DatabaseObject]] = {page: [] for page in self.pages}
|
||||||
|
self.results: Dict[Type[Page], List[DatabaseObject]] = {}
|
||||||
|
|
||||||
|
def add(self, page: Type[Page], search_result: List[DatabaseObject]):
|
||||||
|
"""
|
||||||
|
adds a list of found music objects to the according page
|
||||||
|
WARNING: if a page already has search results, they are just gonna be overwritten
|
||||||
|
"""
|
||||||
|
|
||||||
|
self.results[page] = search_result
|
||||||
|
|
||||||
|
def get_page_results(self, page: Type[Page]) -> "PageResults":
|
||||||
|
return PageResults(page, self.results.get(page, []))
|
||||||
|
|
||||||
|
def formated_generator(self, max_items_per_page: int = 10):
|
||||||
|
super().formated_generator()
|
||||||
|
i = 0
|
||||||
|
|
||||||
|
for page in self.results:
|
||||||
|
yield page
|
||||||
|
|
||||||
|
j = 0
|
||||||
|
for option in self.results[page]:
|
||||||
|
yield Option(i, option)
|
||||||
|
self._by_index[i] = option
|
||||||
|
self._page_by_index[i] = page
|
||||||
|
i += 1
|
||||||
|
j += 1
|
||||||
|
|
||||||
|
if j >= max_items_per_page:
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
class PageResults(Results):
|
||||||
|
def __init__(self, page: Type[Page], results: List[DatabaseObject]) -> None:
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
|
self.page: Type[Page] = page
|
||||||
|
self.results: List[DatabaseObject] = results
|
||||||
|
|
||||||
|
def formated_generator(self, max_items_per_page: int = 10):
|
||||||
|
super().formated_generator()
|
||||||
|
i = 0
|
||||||
|
|
||||||
|
yield self.page
|
||||||
|
|
||||||
|
for option in self.results:
|
||||||
|
yield Option(i, option)
|
||||||
|
self._by_index[i] = option
|
||||||
|
self._page_by_index[i] = self.page
|
||||||
|
i += 1
|
@ -1,2 +0,0 @@
|
|||||||
|
|
||||||
|
|
@ -1,106 +0,0 @@
|
|||||||
from typing import List
|
|
||||||
import mutagen.id3
|
|
||||||
import requests
|
|
||||||
import os.path
|
|
||||||
from mutagen.easyid3 import EasyID3
|
|
||||||
from pydub import AudioSegment
|
|
||||||
|
|
||||||
from ..utils.shared import *
|
|
||||||
from .sources import (
|
|
||||||
youtube,
|
|
||||||
musify,
|
|
||||||
local_files
|
|
||||||
)
|
|
||||||
from ..database.song import (
|
|
||||||
Song as song_object,
|
|
||||||
Target as target_object,
|
|
||||||
Source as source_object
|
|
||||||
)
|
|
||||||
from ..database.temp_database import temp_database
|
|
||||||
|
|
||||||
logger = DOWNLOAD_LOGGER
|
|
||||||
|
|
||||||
# maps the classes to get data from to the source name
|
|
||||||
sources = {
|
|
||||||
'Youtube': youtube.Youtube,
|
|
||||||
'Musify': musify.Musify
|
|
||||||
}
|
|
||||||
|
|
||||||
"""
|
|
||||||
https://en.wikipedia.org/wiki/ID3
|
|
||||||
https://mutagen.readthedocs.io/en/latest/user/id3.html
|
|
||||||
|
|
||||||
# to get all valid keys
|
|
||||||
from mutagen.easyid3 import EasyID3
|
|
||||||
print("\n".join(EasyID3.valid_keys.keys()))
|
|
||||||
print(EasyID3.valid_keys.keys())
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
class Download:
|
|
||||||
def __init__(self):
|
|
||||||
Download.fetch_audios(temp_database.get_tracks_to_download())
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def fetch_audios(cls, songs: List[song_object], override_existing: bool = False):
|
|
||||||
for song in songs:
|
|
||||||
if not cls.path_stuff(song.target) and not override_existing:
|
|
||||||
cls.write_metadata(song)
|
|
||||||
continue
|
|
||||||
|
|
||||||
is_downloaded = False
|
|
||||||
for source in song.sources:
|
|
||||||
download_success = Download.download_from_src(song, source)
|
|
||||||
|
|
||||||
if download_success == -1:
|
|
||||||
logger.warning(f"couldn't download {song['url']} from {song['src']}")
|
|
||||||
else:
|
|
||||||
is_downloaded = True
|
|
||||||
break
|
|
||||||
|
|
||||||
if is_downloaded:
|
|
||||||
cls.write_metadata(song)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def download_from_src(cls, song: song_object, source: source_object):
|
|
||||||
if source.src not in sources:
|
|
||||||
raise ValueError(f"source {source.src} seems to not exist")
|
|
||||||
source_subclass = sources[source.src]
|
|
||||||
|
|
||||||
return source_subclass.fetch_audio(song, source)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def write_metadata(cls, song: song_object):
|
|
||||||
if not os.path.exists(song.target.file):
|
|
||||||
logger.warning(f"file {song.target.file} doesn't exist")
|
|
||||||
return False
|
|
||||||
|
|
||||||
# only convert the file to the proper format if mutagen doesn't work with it due to time
|
|
||||||
try:
|
|
||||||
audiofile = EasyID3(song.target.file)
|
|
||||||
except mutagen.id3.ID3NoHeaderError:
|
|
||||||
AudioSegment.from_file(song.target.file).export(song.target.file, format="mp3")
|
|
||||||
audiofile = EasyID3(song.target.file)
|
|
||||||
|
|
||||||
for key, value in song.get_metadata():
|
|
||||||
if type(value) != list:
|
|
||||||
value = str(value)
|
|
||||||
audiofile[key] = value
|
|
||||||
|
|
||||||
logger.info("saving")
|
|
||||||
audiofile.save(song.target.file, v1=2)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def path_stuff(cls, target: target_object) -> bool:
|
|
||||||
# returns true if it should be downloaded
|
|
||||||
if os.path.exists(target.file):
|
|
||||||
logger.info(f"'{target.file}' does already exist, thus not downloading.")
|
|
||||||
return False
|
|
||||||
os.makedirs(target.path, exist_ok=True)
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
logging.basicConfig(level=logging.DEBUG)
|
|
||||||
s = requests.Session()
|
|
||||||
Download()
|
|
@ -1,70 +0,0 @@
|
|||||||
from typing import List
|
|
||||||
|
|
||||||
from ..utils.shared import *
|
|
||||||
from .sources import (
|
|
||||||
youtube,
|
|
||||||
musify,
|
|
||||||
local_files
|
|
||||||
)
|
|
||||||
from ..database.song import Song as song_object
|
|
||||||
from ..database.temp_database import temp_database
|
|
||||||
|
|
||||||
logger = URL_DOWNLOAD_LOGGER
|
|
||||||
|
|
||||||
# maps the classes to get data from to the source name
|
|
||||||
sources = {
|
|
||||||
'Youtube': youtube.Youtube,
|
|
||||||
'Musify': musify.Musify
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class Download:
|
|
||||||
def __init__(self) -> None:
|
|
||||||
for song in temp_database.get_tracks_without_src():
|
|
||||||
id_ = song['id']
|
|
||||||
if os.path.exists(song.target.file):
|
|
||||||
logger.info(f"skipping the fetching of the download links, cuz {song.target.file} already exists.")
|
|
||||||
continue
|
|
||||||
|
|
||||||
success = False
|
|
||||||
for src in AUDIO_SOURCES:
|
|
||||||
res = Download.fetch_from_src(song, src)
|
|
||||||
if res is not None:
|
|
||||||
success = True
|
|
||||||
Download.add_url(res, src, id_)
|
|
||||||
|
|
||||||
if not success:
|
|
||||||
logger.warning(f"Didn't find any sources for {song}")
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def fetch_sources(cls, songs: List[song_object], skip_existing_files: bool = False):
|
|
||||||
for song in songs:
|
|
||||||
if song.target.exists_on_disc and skip_existing_files:
|
|
||||||
logger.info(f"skipping the fetching of the download links, cuz {song.target.file} already exists.")
|
|
||||||
continue
|
|
||||||
|
|
||||||
success = False
|
|
||||||
for src in AUDIO_SOURCES:
|
|
||||||
res = cls.fetch_from_src(song, src)
|
|
||||||
if res is not None:
|
|
||||||
success = True
|
|
||||||
cls.add_url(res, src, song.id)
|
|
||||||
|
|
||||||
if not success:
|
|
||||||
logger.warning(f"Didn't find any sources for {song}")
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def fetch_from_src(cls, song, src):
|
|
||||||
if src not in sources:
|
|
||||||
raise ValueError(f"source {src} seems to not exist")
|
|
||||||
|
|
||||||
source_subclass = sources[src]
|
|
||||||
return source_subclass.fetch_source(song)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def add_url(cls, url: str, src: str, id_: str):
|
|
||||||
temp_database.set_download_data(id_, url, src)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
download = Download()
|
|
@ -1,7 +0,0 @@
|
|||||||
from . import (
|
|
||||||
metadata_search,
|
|
||||||
metadata_fetch
|
|
||||||
)
|
|
||||||
|
|
||||||
MetadataSearch = metadata_search.Search
|
|
||||||
MetadataDownload = metadata_fetch.MetadataDownloader
|
|
@ -1,345 +0,0 @@
|
|||||||
from src.music_kraken.utils.shared import *
|
|
||||||
from src.music_kraken.utils.object_handeling import get_elem_from_obj, parse_music_brainz_date
|
|
||||||
|
|
||||||
from src.music_kraken.database.temp_database import temp_database
|
|
||||||
|
|
||||||
from typing import List
|
|
||||||
import musicbrainzngs
|
|
||||||
import logging
|
|
||||||
|
|
||||||
# I don't know if it would be feesable to set up my own mb instance
|
|
||||||
# https://github.com/metabrainz/musicbrainz-docker
|
|
||||||
|
|
||||||
|
|
||||||
# IMPORTANT DOCUMENTATION WHICH CONTAINS FOR EXAMPLE THE INCLUDES
|
|
||||||
# https://python-musicbrainzngs.readthedocs.io/en/v0.7.1/api/#getting-data
|
|
||||||
|
|
||||||
logger = METADATA_DOWNLOAD_LOGGER
|
|
||||||
|
|
||||||
|
|
||||||
class MetadataDownloader:
|
|
||||||
def __init__(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
class Artist:
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
musicbrainz_artistid: str,
|
|
||||||
release_groups: List = [],
|
|
||||||
new_release_groups: bool = True
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
release_groups: list
|
|
||||||
"""
|
|
||||||
self.release_groups = release_groups
|
|
||||||
|
|
||||||
self.musicbrainz_artistid = musicbrainz_artistid
|
|
||||||
|
|
||||||
try:
|
|
||||||
result = musicbrainzngs.get_artist_by_id(self.musicbrainz_artistid, includes=["release-groups", "releases"])
|
|
||||||
except musicbrainzngs.musicbrainz.NetworkError:
|
|
||||||
return
|
|
||||||
artist_data = get_elem_from_obj(result, ['artist'], return_if_none={})
|
|
||||||
|
|
||||||
self.artist = get_elem_from_obj(artist_data, ['name'])
|
|
||||||
|
|
||||||
self.save()
|
|
||||||
|
|
||||||
# STARTING TO FETCH' RELEASE GROUPS. IMPORTANT: DON'T WRITE ANYTHING BESIDES THAT HERE
|
|
||||||
if not new_release_groups:
|
|
||||||
return
|
|
||||||
# sort all release groups by date and add album sort to have them in chronological order.
|
|
||||||
release_groups = artist_data['release-group-list']
|
|
||||||
for i, release_group in enumerate(release_groups):
|
|
||||||
release_groups[i]['first-release-date'] = parse_music_brainz_date(release_group['first-release-date'])
|
|
||||||
release_groups.sort(key=lambda x: x['first-release-date'])
|
|
||||||
|
|
||||||
for i, release_group in enumerate(release_groups):
|
|
||||||
self.release_groups.append(MetadataDownloader.ReleaseGroup(
|
|
||||||
musicbrainz_releasegroupid=release_group['id'],
|
|
||||||
artists=[self],
|
|
||||||
albumsort=i + 1
|
|
||||||
))
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
newline = "\n"
|
|
||||||
return f"artist: \"{self.artist}\""
|
|
||||||
|
|
||||||
def save(self):
|
|
||||||
logger.info(f"caching {self}")
|
|
||||||
temp_database.add_artist(
|
|
||||||
musicbrainz_artistid=self.musicbrainz_artistid,
|
|
||||||
artist=self.artist
|
|
||||||
)
|
|
||||||
|
|
||||||
class ReleaseGroup:
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
musicbrainz_releasegroupid: str,
|
|
||||||
artists=[],
|
|
||||||
albumsort: int = None,
|
|
||||||
only_download_distinct_releases: bool = True,
|
|
||||||
fetch_further: bool = True
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
split_artists: list -> if len > 1: album_artist=VariousArtists
|
|
||||||
releases: list
|
|
||||||
"""
|
|
||||||
|
|
||||||
self.musicbrainz_releasegroupid = musicbrainz_releasegroupid
|
|
||||||
self.artists = artists
|
|
||||||
self.releases = []
|
|
||||||
|
|
||||||
try:
|
|
||||||
result = musicbrainzngs.get_release_group_by_id(musicbrainz_releasegroupid,
|
|
||||||
includes=["artist-credits", "releases"])
|
|
||||||
except musicbrainzngs.musicbrainz.NetworkError:
|
|
||||||
return
|
|
||||||
release_group_data = get_elem_from_obj(result, ['release-group'], return_if_none={})
|
|
||||||
artist_datas = get_elem_from_obj(release_group_data, ['artist-credit'], return_if_none={})
|
|
||||||
release_datas = get_elem_from_obj(release_group_data, ['release-list'], return_if_none={})
|
|
||||||
|
|
||||||
# only for printing the release
|
|
||||||
self.name = get_elem_from_obj(release_group_data, ['title'])
|
|
||||||
|
|
||||||
for artist_data in artist_datas:
|
|
||||||
artist_id = get_elem_from_obj(artist_data, ['artist', 'id'])
|
|
||||||
if artist_id is None:
|
|
||||||
continue
|
|
||||||
self.append_artist(artist_id)
|
|
||||||
self.albumartist = "Various Artists" if len(self.artists) > 1 else self.artists[0].artist
|
|
||||||
self.album_artist_id = None if self.albumartist == "Various Artists" else self.artists[
|
|
||||||
0].musicbrainz_artistid
|
|
||||||
|
|
||||||
self.albumsort = albumsort
|
|
||||||
self.musicbrainz_albumtype = get_elem_from_obj(release_group_data, ['primary-type'])
|
|
||||||
self.compilation = "1" if self.musicbrainz_albumtype == "Compilation" else None
|
|
||||||
|
|
||||||
self.save()
|
|
||||||
|
|
||||||
if not fetch_further:
|
|
||||||
return
|
|
||||||
|
|
||||||
if only_download_distinct_releases:
|
|
||||||
self.append_distinct_releases(release_datas)
|
|
||||||
else:
|
|
||||||
self.append_all_releases(release_datas)
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return f"release group: \"{self.name}\""
|
|
||||||
|
|
||||||
def save(self):
|
|
||||||
logger.info(f"caching {self}")
|
|
||||||
temp_database.add_release_group(
|
|
||||||
musicbrainz_releasegroupid=self.musicbrainz_releasegroupid,
|
|
||||||
artist_ids=[artist.musicbrainz_artistid for artist in self.artists],
|
|
||||||
albumartist=self.albumartist,
|
|
||||||
albumsort=self.albumsort,
|
|
||||||
musicbrainz_albumtype=self.musicbrainz_albumtype,
|
|
||||||
compilation=self.compilation,
|
|
||||||
album_artist_id=self.album_artist_id
|
|
||||||
)
|
|
||||||
|
|
||||||
def append_artist(self, artist_id: str):
|
|
||||||
for existing_artist in self.artists:
|
|
||||||
if artist_id == existing_artist.musicbrainz_artistid:
|
|
||||||
return existing_artist
|
|
||||||
new_artist = MetadataDownloader.Artist(artist_id, release_groups=[self],
|
|
||||||
new_release_groups=False)
|
|
||||||
self.artists.append(new_artist)
|
|
||||||
return new_artist
|
|
||||||
|
|
||||||
def append_release(self, release_data: dict):
|
|
||||||
musicbrainz_albumid = get_elem_from_obj(release_data, ['id'])
|
|
||||||
if musicbrainz_albumid is None:
|
|
||||||
return
|
|
||||||
self.releases.append(
|
|
||||||
MetadataDownloader.Release(musicbrainz_albumid, release_group=self))
|
|
||||||
|
|
||||||
def append_distinct_releases(self, release_datas: List[dict]):
|
|
||||||
titles = {}
|
|
||||||
|
|
||||||
for release_data in release_datas:
|
|
||||||
title = get_elem_from_obj(release_data, ['title'])
|
|
||||||
if title is None:
|
|
||||||
continue
|
|
||||||
titles[title] = release_data
|
|
||||||
|
|
||||||
for key in titles:
|
|
||||||
self.append_release(titles[key])
|
|
||||||
|
|
||||||
def append_all_releases(self, release_datas: List[dict]):
|
|
||||||
for release_data in release_datas:
|
|
||||||
self.append_release(release_data)
|
|
||||||
|
|
||||||
class Release:
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
musicbrainz_albumid: str,
|
|
||||||
release_group=None,
|
|
||||||
fetch_furter: bool = True
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
release_group: ReleaseGroup
|
|
||||||
tracks: list
|
|
||||||
"""
|
|
||||||
self.musicbrainz_albumid = musicbrainz_albumid
|
|
||||||
self.release_group = release_group
|
|
||||||
self.tracklist = []
|
|
||||||
|
|
||||||
try:
|
|
||||||
result = musicbrainzngs.get_release_by_id(self.musicbrainz_albumid,
|
|
||||||
includes=["recordings", "labels", "release-groups"])
|
|
||||||
except musicbrainzngs.musicbrainz.NetworkError:
|
|
||||||
return
|
|
||||||
release_data = get_elem_from_obj(result, ['release'], return_if_none={})
|
|
||||||
label_data = get_elem_from_obj(release_data, ['label-info-list'], return_if_none={})
|
|
||||||
recording_datas = get_elem_from_obj(release_data, ['medium-list', 0, 'track-list'], return_if_none=[])
|
|
||||||
release_group_data = get_elem_from_obj(release_data, ['release-group'], return_if_none={})
|
|
||||||
if self.release_group is None:
|
|
||||||
self.release_group = MetadataDownloader.ReleaseGroup(
|
|
||||||
musicbrainz_releasegroupid=get_elem_from_obj(
|
|
||||||
release_group_data, ['id']),
|
|
||||||
fetch_further=False)
|
|
||||||
|
|
||||||
self.title = get_elem_from_obj(release_data, ['title'])
|
|
||||||
self.copyright = get_elem_from_obj(label_data, [0, 'label', 'name'])
|
|
||||||
|
|
||||||
self.album_status = get_elem_from_obj(release_data, ['status'])
|
|
||||||
self.language = get_elem_from_obj(release_data, ['text-representation', 'language'])
|
|
||||||
self.year = get_elem_from_obj(release_data, ['date'], lambda x: x.split("-")[0])
|
|
||||||
self.date = get_elem_from_obj(release_data, ['date'])
|
|
||||||
self.country = get_elem_from_obj(release_data, ['country'])
|
|
||||||
self.barcode = get_elem_from_obj(release_data, ['barcode'])
|
|
||||||
|
|
||||||
self.save()
|
|
||||||
if fetch_furter:
|
|
||||||
self.append_recordings(recording_datas)
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return f"release: {self.title} ©{self.copyright} {self.album_status}"
|
|
||||||
|
|
||||||
def save(self):
|
|
||||||
logger.info(f"caching {self}")
|
|
||||||
temp_database.add_release(
|
|
||||||
musicbrainz_albumid=self.musicbrainz_albumid,
|
|
||||||
release_group_id=self.release_group.musicbrainz_releasegroupid,
|
|
||||||
title=self.title,
|
|
||||||
copyright_=self.copyright,
|
|
||||||
album_status=self.album_status,
|
|
||||||
language=self.language,
|
|
||||||
year=self.year,
|
|
||||||
date=self.date,
|
|
||||||
country=self.country,
|
|
||||||
barcode=self.barcode
|
|
||||||
)
|
|
||||||
|
|
||||||
def append_recordings(self, recording_datas: dict):
|
|
||||||
for i, recording_data in enumerate(recording_datas):
|
|
||||||
musicbrainz_releasetrackid = get_elem_from_obj(recording_data, ['recording', 'id'])
|
|
||||||
if musicbrainz_releasetrackid is None:
|
|
||||||
continue
|
|
||||||
|
|
||||||
self.tracklist.append(
|
|
||||||
MetadataDownloader.Track(musicbrainz_releasetrackid, self,
|
|
||||||
track_number=str(i + 1)))
|
|
||||||
|
|
||||||
class Track:
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
musicbrainz_releasetrackid: str,
|
|
||||||
release=None,
|
|
||||||
track_number: str = None
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
release: Release
|
|
||||||
feature_artists: list
|
|
||||||
"""
|
|
||||||
|
|
||||||
self.musicbrainz_releasetrackid = musicbrainz_releasetrackid
|
|
||||||
self.release = release
|
|
||||||
self.artists = []
|
|
||||||
|
|
||||||
self.track_number = track_number
|
|
||||||
|
|
||||||
try:
|
|
||||||
result = musicbrainzngs.get_recording_by_id(self.musicbrainz_releasetrackid,
|
|
||||||
includes=["artists", "releases", "recording-rels", "isrcs",
|
|
||||||
"work-level-rels"])
|
|
||||||
except musicbrainzngs.musicbrainz.NetworkError:
|
|
||||||
return
|
|
||||||
recording_data = result['recording']
|
|
||||||
release_data = get_elem_from_obj(recording_data, ['release-list', -1])
|
|
||||||
if self.release is None:
|
|
||||||
self.release = MetadataDownloader.Release(get_elem_from_obj(release_data, ['id']), fetch_furter=False)
|
|
||||||
|
|
||||||
for artist_data in get_elem_from_obj(recording_data, ['artist-credit'], return_if_none=[]):
|
|
||||||
self.append_artist(get_elem_from_obj(artist_data, ['artist', 'id']))
|
|
||||||
|
|
||||||
self.isrc = get_elem_from_obj(recording_data, ['isrc-list', 0])
|
|
||||||
self.title = recording_data['title']
|
|
||||||
|
|
||||||
self.lenth = get_elem_from_obj(recording_data, ['length'])
|
|
||||||
|
|
||||||
self.save()
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return f"track: \"{self.title}\" {self.isrc or ''}"
|
|
||||||
|
|
||||||
def save(self):
|
|
||||||
logger.info(f"caching {self}")
|
|
||||||
|
|
||||||
temp_database.add_track(
|
|
||||||
musicbrainz_releasetrackid=self.musicbrainz_releasetrackid,
|
|
||||||
musicbrainz_albumid=self.release.musicbrainz_albumid,
|
|
||||||
feature_aritsts=[artist.musicbrainz_artistid for artist in self.artists],
|
|
||||||
tracknumber=self.track_number,
|
|
||||||
track=self.title,
|
|
||||||
isrc=self.isrc,
|
|
||||||
length=int(self.lenth)
|
|
||||||
)
|
|
||||||
|
|
||||||
def append_artist(self, artist_id: str):
|
|
||||||
if artist_id is None:
|
|
||||||
return
|
|
||||||
|
|
||||||
for existing_artist in self.artists:
|
|
||||||
if artist_id == existing_artist.musicbrainz_artistid:
|
|
||||||
return existing_artist
|
|
||||||
new_artist = MetadataDownloader.Artist(artist_id, new_release_groups=False)
|
|
||||||
self.artists.append(new_artist)
|
|
||||||
return new_artist
|
|
||||||
|
|
||||||
def download(self, option: dict):
|
|
||||||
type_ = option['type']
|
|
||||||
mb_id = option['id']
|
|
||||||
|
|
||||||
if type_ == "artist":
|
|
||||||
return self.Artist(mb_id)
|
|
||||||
if type_ == "release_group":
|
|
||||||
return self.ReleaseGroup(mb_id)
|
|
||||||
if type_ == "release":
|
|
||||||
return self.Release(mb_id)
|
|
||||||
if type_ == "recording":
|
|
||||||
return self.Track(mb_id)
|
|
||||||
|
|
||||||
logger.error(f"download type {type_} doesn't exists :(")
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
logging.basicConfig(
|
|
||||||
level=logging.INFO,
|
|
||||||
format="%(asctime)s [%(levelname)s] %(message)s",
|
|
||||||
handlers=[
|
|
||||||
logging.FileHandler(os.path.join(TEMP_DIR, LOG_FILE)),
|
|
||||||
logging.StreamHandler()
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
downloader = MetadataDownloader()
|
|
||||||
|
|
||||||
downloader.download({'id': 'd2006339-9e98-4624-a386-d503328eb854', 'type': 'recording'})
|
|
||||||
downloader.download({'id': 'cdd16860-35fd-46af-bd8c-5de7b15ebc31', 'type': 'release'})
|
|
||||||
# download({'id': '4b9af532-ef7e-42ab-8b26-c466327cb5e0', 'type': 'release'})
|
|
||||||
#download({'id': 'c24ed9e7-6df9-44de-8570-975f1a5a75d1', 'type': 'track'})
|
|
@ -1,364 +0,0 @@
|
|||||||
from typing import List
|
|
||||||
import musicbrainzngs
|
|
||||||
|
|
||||||
from src.music_kraken.utils.shared import *
|
|
||||||
from src.music_kraken.utils.object_handeling import get_elem_from_obj, parse_music_brainz_date
|
|
||||||
|
|
||||||
logger = SEARCH_LOGGER
|
|
||||||
|
|
||||||
MAX_PARAMETERS = 3
|
|
||||||
OPTION_TYPES = ['artist', 'release_group', 'release', 'recording']
|
|
||||||
|
|
||||||
|
|
||||||
class Option:
|
|
||||||
def __init__(self, type_: str, id_: str, name: str, additional_info: str = "") -> None:
|
|
||||||
# print(type_, id_, name)
|
|
||||||
if type_ not in OPTION_TYPES:
|
|
||||||
raise ValueError(f"type: {type_} doesn't exist. Legal Values: {OPTION_TYPES}")
|
|
||||||
self.type = type_
|
|
||||||
self.name = name
|
|
||||||
self.id = id_
|
|
||||||
|
|
||||||
self.additional_info = additional_info
|
|
||||||
|
|
||||||
def __getitem__(self, item):
|
|
||||||
map_ = {
|
|
||||||
"id": self.id,
|
|
||||||
"type": self.type,
|
|
||||||
"kind": self.type,
|
|
||||||
"name": self.name
|
|
||||||
}
|
|
||||||
return map_[item]
|
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
|
||||||
type_repr = {
|
|
||||||
'artist': 'artist\t\t',
|
|
||||||
'release_group': 'release group\t',
|
|
||||||
'release': 'release\t\t',
|
|
||||||
'recording': 'recording\t'
|
|
||||||
}
|
|
||||||
return f"{type_repr[self.type]}: \"{self.name}\"{self.additional_info}"
|
|
||||||
|
|
||||||
|
|
||||||
class MultipleOptions:
|
|
||||||
def __init__(self, option_list: List[Option]) -> None:
|
|
||||||
self.option_list = option_list
|
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
|
||||||
return "\n".join([f"{str(i).zfill(2)}) {choice.__repr__()}" for i, choice in enumerate(self.option_list)])
|
|
||||||
|
|
||||||
|
|
||||||
class Search:
|
|
||||||
def __init__(self) -> None:
|
|
||||||
self.options_history = []
|
|
||||||
self.current_option: Option
|
|
||||||
|
|
||||||
def append_new_choices(self, new_choices: List[Option]) -> MultipleOptions:
|
|
||||||
self.options_history.append(new_choices)
|
|
||||||
return MultipleOptions(new_choices)
|
|
||||||
|
|
||||||
def get_previous_options(self):
|
|
||||||
self.options_history.pop(-1)
|
|
||||||
return MultipleOptions(self.options_history[-1])
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def fetch_new_options_from_artist(artist: Option):
|
|
||||||
"""
|
|
||||||
returning list of artist and every release group
|
|
||||||
"""
|
|
||||||
result = musicbrainzngs.get_artist_by_id(artist.id, includes=["release-groups", "releases"])
|
|
||||||
artist_data = get_elem_from_obj(result, ['artist'], return_if_none={})
|
|
||||||
|
|
||||||
result = [artist]
|
|
||||||
|
|
||||||
# sort all release groups by date and add album sort to have them in chronological order.
|
|
||||||
release_group_list = artist_data['release-group-list']
|
|
||||||
for i, release_group in enumerate(release_group_list):
|
|
||||||
release_group_list[i]['first-release-date'] = parse_music_brainz_date(release_group['first-release-date'])
|
|
||||||
release_group_list.sort(key=lambda x: x['first-release-date'])
|
|
||||||
release_group_list = [Option("release_group", get_elem_from_obj(release_group_, ['id']),
|
|
||||||
get_elem_from_obj(release_group_, ['title']),
|
|
||||||
additional_info=f" ({get_elem_from_obj(release_group_, ['type'])}) from {get_elem_from_obj(release_group_, ['first-release-date'])}")
|
|
||||||
for release_group_ in release_group_list]
|
|
||||||
|
|
||||||
result.extend(release_group_list)
|
|
||||||
return result
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def fetch_new_options_from_release_group(release_group: Option):
|
|
||||||
"""
|
|
||||||
returning list including the artists, the releases and the tracklist of the first release
|
|
||||||
"""
|
|
||||||
results = []
|
|
||||||
|
|
||||||
result = musicbrainzngs.get_release_group_by_id(release_group.id,
|
|
||||||
includes=["artist-credits", "releases"])
|
|
||||||
release_group_data = get_elem_from_obj(result, ['release-group'], return_if_none={})
|
|
||||||
artist_datas = get_elem_from_obj(release_group_data, ['artist-credit'], return_if_none={})
|
|
||||||
release_datas = get_elem_from_obj(release_group_data, ['release-list'], return_if_none={})
|
|
||||||
|
|
||||||
# appending all the artists to results
|
|
||||||
for artist_data in artist_datas:
|
|
||||||
results.append(Option('artist', get_elem_from_obj(artist_data, ['artist', 'id']),
|
|
||||||
get_elem_from_obj(artist_data, ['artist', 'name'])))
|
|
||||||
|
|
||||||
# appending initial release group
|
|
||||||
results.append(release_group)
|
|
||||||
|
|
||||||
# appending all releases
|
|
||||||
first_release = None
|
|
||||||
for i, release_data in enumerate(release_datas):
|
|
||||||
results.append(
|
|
||||||
Option('release', get_elem_from_obj(release_data, ['id']), get_elem_from_obj(release_data, ['title']),
|
|
||||||
additional_info=f" ({get_elem_from_obj(release_data, ['status'])})"))
|
|
||||||
if i == 0:
|
|
||||||
first_release = results[-1]
|
|
||||||
|
|
||||||
# append tracklist of first release
|
|
||||||
if first_release is not None:
|
|
||||||
results.extend(Search.fetch_new_options_from_release(first_release, only_tracklist=True))
|
|
||||||
|
|
||||||
return results
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def fetch_new_options_from_release(release: Option, only_tracklist: bool = False):
|
|
||||||
"""
|
|
||||||
artists
|
|
||||||
release group
|
|
||||||
release
|
|
||||||
tracklist
|
|
||||||
"""
|
|
||||||
results = []
|
|
||||||
result = musicbrainzngs.get_release_by_id(release.id,
|
|
||||||
includes=["recordings", "labels", "release-groups", "artist-credits"])
|
|
||||||
release_data = get_elem_from_obj(result, ['release'], return_if_none={})
|
|
||||||
label_data = get_elem_from_obj(release_data, ['label-info-list'], return_if_none={})
|
|
||||||
recording_datas = get_elem_from_obj(release_data, ['medium-list', 0, 'track-list'], return_if_none=[])
|
|
||||||
release_group_data = get_elem_from_obj(release_data, ['release-group'], return_if_none={})
|
|
||||||
artist_datas = get_elem_from_obj(release_data, ['artist-credit'], return_if_none={})
|
|
||||||
|
|
||||||
# appending all the artists to results
|
|
||||||
for artist_data in artist_datas:
|
|
||||||
results.append(Option('artist', get_elem_from_obj(artist_data, ['artist', 'id']),
|
|
||||||
get_elem_from_obj(artist_data, ['artist', 'name'])))
|
|
||||||
|
|
||||||
# appending the according release group
|
|
||||||
results.append(Option("release_group", get_elem_from_obj(release_group_data, ['id']),
|
|
||||||
get_elem_from_obj(release_group_data, ['title']),
|
|
||||||
additional_info=f" ({get_elem_from_obj(release_group_data, ['type'])}) from {get_elem_from_obj(release_group_data, ['first-release-date'])}"))
|
|
||||||
|
|
||||||
# appending the release
|
|
||||||
results.append(release)
|
|
||||||
|
|
||||||
# appending the tracklist, but first putting it in a list, in case of only_tracklist being True to
|
|
||||||
# return this instead
|
|
||||||
tracklist = []
|
|
||||||
for i, recording_data in enumerate(recording_datas):
|
|
||||||
recording_data = recording_data['recording']
|
|
||||||
tracklist.append(Option('recording', get_elem_from_obj(recording_data, ['id']),
|
|
||||||
get_elem_from_obj(recording_data, ['title']),
|
|
||||||
f" ({get_elem_from_obj(recording_data, ['length'])}) from {get_elem_from_obj(recording_data, ['artist-credit-phrase'])}"))
|
|
||||||
|
|
||||||
if only_tracklist:
|
|
||||||
return tracklist
|
|
||||||
results.extend(tracklist)
|
|
||||||
return results
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def fetch_new_options_from_record(recording: Option):
|
|
||||||
"""
|
|
||||||
artists, release, record
|
|
||||||
"""
|
|
||||||
results = []
|
|
||||||
|
|
||||||
result = musicbrainzngs.get_recording_by_id(recording.id, includes=["artists", "releases"])
|
|
||||||
recording_data = result['recording']
|
|
||||||
release_datas = get_elem_from_obj(recording_data, ['release-list'])
|
|
||||||
artist_datas = get_elem_from_obj(recording_data, ['artist-credit'], return_if_none={})
|
|
||||||
|
|
||||||
# appending all the artists to results
|
|
||||||
for artist_data in artist_datas:
|
|
||||||
results.append(Option('artist', get_elem_from_obj(artist_data, ['artist', 'id']),
|
|
||||||
get_elem_from_obj(artist_data, ['artist', 'name'])))
|
|
||||||
|
|
||||||
# appending all releases
|
|
||||||
for i, release_data in enumerate(release_datas):
|
|
||||||
results.append(
|
|
||||||
Option('release', get_elem_from_obj(release_data, ['id']), get_elem_from_obj(release_data, ['title']),
|
|
||||||
additional_info=f" ({get_elem_from_obj(release_data, ['status'])})"))
|
|
||||||
|
|
||||||
results.append(recording)
|
|
||||||
|
|
||||||
return results
|
|
||||||
|
|
||||||
def fetch_new_options(self) -> MultipleOptions:
|
|
||||||
if self.current_option is None:
|
|
||||||
return -1
|
|
||||||
|
|
||||||
result = []
|
|
||||||
if self.current_option.type == 'artist':
|
|
||||||
result = self.fetch_new_options_from_artist(self.current_option)
|
|
||||||
elif self.current_option.type == 'release_group':
|
|
||||||
result = self.fetch_new_options_from_release_group(self.current_option)
|
|
||||||
elif self.current_option.type == 'release':
|
|
||||||
result = self.fetch_new_options_from_release(self.current_option)
|
|
||||||
elif self.current_option.type == 'recording':
|
|
||||||
result = self.fetch_new_options_from_record(self.current_option)
|
|
||||||
|
|
||||||
return self.append_new_choices(result)
|
|
||||||
|
|
||||||
def choose(self, index: int) -> MultipleOptions:
|
|
||||||
if len(self.options_history) == 0:
|
|
||||||
logging.error("initial query neaded before choosing")
|
|
||||||
return MultipleOptions([])
|
|
||||||
|
|
||||||
latest_options = self.options_history[-1]
|
|
||||||
if index >= len(latest_options):
|
|
||||||
logging.error("index outside of options")
|
|
||||||
return MultipleOptions([])
|
|
||||||
|
|
||||||
self.current_option = latest_options[index]
|
|
||||||
return self.fetch_new_options()
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def search_recording_from_text(artist: str = None, release_group: str = None, recording: str = None,
|
|
||||||
query: str = None):
|
|
||||||
result = musicbrainzngs.search_recordings(artist=artist, release=release_group, recording=recording,
|
|
||||||
query=query)
|
|
||||||
recording_list = get_elem_from_obj(result, ['recording-list'], return_if_none=[])
|
|
||||||
|
|
||||||
resulting_options = [
|
|
||||||
Option("recording", get_elem_from_obj(recording_, ['id']), get_elem_from_obj(recording_, ['title']),
|
|
||||||
additional_info=f" of {get_elem_from_obj(recording_, ['release-list', 0, 'title'])} by {get_elem_from_obj(recording_, ['artist-credit', 0, 'name'])}")
|
|
||||||
for recording_ in recording_list]
|
|
||||||
return resulting_options
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def search_release_group_from_text(artist: str = None, release_group: str = None, query: str = None):
|
|
||||||
result = musicbrainzngs.search_release_groups(artist=artist, releasegroup=release_group, query=query)
|
|
||||||
release_group_list = get_elem_from_obj(result, ['release-group-list'], return_if_none=[])
|
|
||||||
|
|
||||||
resulting_options = [Option("release_group", get_elem_from_obj(release_group_, ['id']),
|
|
||||||
get_elem_from_obj(release_group_, ['title']),
|
|
||||||
additional_info=f" by {get_elem_from_obj(release_group_, ['artist-credit', 0, 'name'])}")
|
|
||||||
for release_group_ in release_group_list]
|
|
||||||
return resulting_options
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def search_artist_from_text(artist: str = None, query: str = None):
|
|
||||||
result = musicbrainzngs.search_artists(artist=artist, query=query)
|
|
||||||
artist_list = get_elem_from_obj(result, ['artist-list'], return_if_none=[])
|
|
||||||
|
|
||||||
resulting_options = [Option("artist", get_elem_from_obj(artist_, ['id']), get_elem_from_obj(artist_, ['name']),
|
|
||||||
additional_info=f": {', '.join([i['name'] for i in get_elem_from_obj(artist_, ['tag-list'], return_if_none=[])])}")
|
|
||||||
for artist_ in artist_list]
|
|
||||||
return resulting_options
|
|
||||||
|
|
||||||
def search_from_text(self, artist: str = None, release_group: str = None, recording: str = None) -> MultipleOptions:
|
|
||||||
logger.info(
|
|
||||||
f"searching specified artist: \"{artist}\", release group: \"{release_group}\", recording: \"{recording}\"")
|
|
||||||
if artist is None and release_group is None and recording is None:
|
|
||||||
logger.error("either artist, release group or recording has to be set")
|
|
||||||
return MultipleOptions([])
|
|
||||||
|
|
||||||
if recording is not None:
|
|
||||||
logger.info("search for recording")
|
|
||||||
results = self.search_recording_from_text(artist=artist, release_group=release_group, recording=recording)
|
|
||||||
elif release_group is not None:
|
|
||||||
logger.info("search for release group")
|
|
||||||
results = self.search_release_group_from_text(artist=artist, release_group=release_group)
|
|
||||||
else:
|
|
||||||
logger.info("search for artist")
|
|
||||||
results = self.search_artist_from_text(artist=artist)
|
|
||||||
|
|
||||||
return self.append_new_choices(results)
|
|
||||||
|
|
||||||
def search_from_text_unspecified(self, query: str) -> MultipleOptions:
|
|
||||||
logger.info(f"searching unspecified: \"{query}\"")
|
|
||||||
|
|
||||||
results = []
|
|
||||||
results.extend(self.search_artist_from_text(query=query))
|
|
||||||
results.extend(self.search_release_group_from_text(query=query))
|
|
||||||
results.extend(self.search_recording_from_text(query=query))
|
|
||||||
|
|
||||||
return self.append_new_choices(results)
|
|
||||||
|
|
||||||
def search_from_query(self, query: str) -> MultipleOptions:
|
|
||||||
if query is None:
|
|
||||||
return MultipleOptions([])
|
|
||||||
"""
|
|
||||||
mit # wird ein neuer Parameter gestartet
|
|
||||||
der Buchstabe dahinter legt die Art des Parameters fest
|
|
||||||
"#a Psychonaut 4 #r Tired, Numb and #t Drop by Drop"
|
|
||||||
if no # is in the query it gets treated as "unspecified query"
|
|
||||||
:param query:
|
|
||||||
:return:
|
|
||||||
"""
|
|
||||||
|
|
||||||
if not '#' in query:
|
|
||||||
return self.search_from_text_unspecified(query)
|
|
||||||
|
|
||||||
artist = None
|
|
||||||
release_group = None
|
|
||||||
recording = None
|
|
||||||
|
|
||||||
query = query.strip()
|
|
||||||
parameters = query.split('#')
|
|
||||||
parameters.remove('')
|
|
||||||
|
|
||||||
if len(parameters) > MAX_PARAMETERS:
|
|
||||||
raise ValueError(f"too many parameters. Only {MAX_PARAMETERS} are allowed")
|
|
||||||
|
|
||||||
for parameter in parameters:
|
|
||||||
splitted = parameter.split(" ")
|
|
||||||
type_ = splitted[0]
|
|
||||||
input_ = " ".join(splitted[1:]).strip()
|
|
||||||
|
|
||||||
if type_ == "a":
|
|
||||||
artist = input_
|
|
||||||
continue
|
|
||||||
if type_ == "r":
|
|
||||||
release_group = input_
|
|
||||||
continue
|
|
||||||
if type_ == "t":
|
|
||||||
recording = input_
|
|
||||||
continue
|
|
||||||
|
|
||||||
return self.search_from_text(artist=artist, release_group=release_group, recording=recording)
|
|
||||||
|
|
||||||
|
|
||||||
def automated_demo():
|
|
||||||
search = Search()
|
|
||||||
search.search_from_text(artist="I Prevail")
|
|
||||||
|
|
||||||
# choose an artist
|
|
||||||
search.choose(0)
|
|
||||||
# choose a release group
|
|
||||||
search.choose(9)
|
|
||||||
# choose a release
|
|
||||||
search.choose(2)
|
|
||||||
# choose a recording
|
|
||||||
search.choose(4)
|
|
||||||
|
|
||||||
|
|
||||||
def interactive_demo():
|
|
||||||
search = Search()
|
|
||||||
while True:
|
|
||||||
input_ = input(
|
|
||||||
"q to quit, .. for previous options, int for this element, str to search for query, ok to download: ")
|
|
||||||
input_.strip()
|
|
||||||
if input_.lower() == "ok":
|
|
||||||
break
|
|
||||||
if input_.lower() == "q":
|
|
||||||
break
|
|
||||||
if input_.lower() == "..":
|
|
||||||
search.get_previous_options()
|
|
||||||
continue
|
|
||||||
if input_.isdigit():
|
|
||||||
search.choose(int(input_))
|
|
||||||
continue
|
|
||||||
search.search_from_query(input_)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
interactive_demo()
|
|
@ -1,4 +0,0 @@
|
|||||||
from enum import Enum
|
|
||||||
|
|
||||||
class Providers(Enum):
|
|
||||||
musicbrainz = "musicbrainz"
|
|
@ -1,59 +0,0 @@
|
|||||||
from typing import List
|
|
||||||
import musicbrainzngs
|
|
||||||
|
|
||||||
from src.music_kraken.database import (
|
|
||||||
Artist,
|
|
||||||
Album,
|
|
||||||
Song
|
|
||||||
)
|
|
||||||
from src.music_kraken.utils.object_handeling import (
|
|
||||||
get_elem_from_obj
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def get_artist(flat: bool = False) -> Artist:
|
|
||||||
# getting the flat artist
|
|
||||||
artist_object = Artist()
|
|
||||||
if flat:
|
|
||||||
return artist_object
|
|
||||||
# get additional stuff like discography
|
|
||||||
return artist_object
|
|
||||||
|
|
||||||
|
|
||||||
def get_album(flat: bool = False) -> Album:
|
|
||||||
# getting the flat album object
|
|
||||||
album_object = Album()
|
|
||||||
if flat:
|
|
||||||
return album_object
|
|
||||||
# get additional stuff like tracklist
|
|
||||||
return album_object
|
|
||||||
|
|
||||||
|
|
||||||
def get_song(mb_id: str, flat: bool = False) -> Song:
|
|
||||||
# getting the flat song object
|
|
||||||
try:
|
|
||||||
result = musicbrainzngs.get_recording_by_id(mb_id,
|
|
||||||
includes=["artists", "releases", "recording-rels", "isrcs",
|
|
||||||
"work-level-rels"])
|
|
||||||
except musicbrainzngs.musicbrainz.NetworkError:
|
|
||||||
return
|
|
||||||
|
|
||||||
recording_data = result['recording']
|
|
||||||
|
|
||||||
song_object = Song(
|
|
||||||
mb_id=mb_id,
|
|
||||||
title=recording_data['title'],
|
|
||||||
length=get_elem_from_obj(recording_data, ['length']),
|
|
||||||
isrc=get_elem_from_obj(recording_data, ['isrc-list', 0])
|
|
||||||
)
|
|
||||||
if flat:
|
|
||||||
return song_object
|
|
||||||
|
|
||||||
# fetch additional stuff
|
|
||||||
artist_data_list = get_elem_from_obj(recording_data, ['artist-credit'], return_if_none=[])
|
|
||||||
for artist_data in artist_data_list:
|
|
||||||
mb_artist_id = get_elem_from_obj(artist_data, ['artist', 'id'])
|
|
||||||
|
|
||||||
release_data = get_elem_from_obj(recording_data, ['release-list', -1])
|
|
||||||
mb_release_id = get_elem_from_obj(release_data, ['id'])
|
|
||||||
return song_object
|
|
@ -1,172 +0,0 @@
|
|||||||
import requests
|
|
||||||
from typing import List
|
|
||||||
from bs4 import BeautifulSoup
|
|
||||||
import pycountry
|
|
||||||
|
|
||||||
from src.music_kraken.database import (
|
|
||||||
Lyrics,
|
|
||||||
Song,
|
|
||||||
Artist
|
|
||||||
)
|
|
||||||
from src.music_kraken.utils.shared import *
|
|
||||||
from src.music_kraken.utils import phonetic_compares
|
|
||||||
from src.music_kraken.utils.object_handeling import get_elem_from_obj
|
|
||||||
|
|
||||||
TIMEOUT = 10
|
|
||||||
|
|
||||||
# search doesn't support isrc
|
|
||||||
# https://genius.com/api/search/multi?q=I Prevail - Breaking Down
|
|
||||||
# https://genius.com/api/songs/6192944
|
|
||||||
# https://docs.genius.com/
|
|
||||||
|
|
||||||
session = requests.Session()
|
|
||||||
session.headers = {
|
|
||||||
"Connection": "keep-alive",
|
|
||||||
"Referer": "https://genius.com/search/embed"
|
|
||||||
}
|
|
||||||
session.proxies = proxies
|
|
||||||
|
|
||||||
logger = GENIUS_LOGGER
|
|
||||||
|
|
||||||
|
|
||||||
class LyricsSong:
|
|
||||||
def __init__(self, raw_data: dict, desirered_data: dict):
|
|
||||||
self.raw_data = raw_data
|
|
||||||
self.desired_data = desirered_data
|
|
||||||
|
|
||||||
song_data = get_elem_from_obj(self.raw_data, ['result'], return_if_none={})
|
|
||||||
self.id = get_elem_from_obj(song_data, ['id'])
|
|
||||||
self.artist = get_elem_from_obj(song_data, ['primary_artist', 'name'])
|
|
||||||
self.title = get_elem_from_obj(song_data, ['title'])
|
|
||||||
|
|
||||||
lang_code = get_elem_from_obj(song_data, ['language']) or "en"
|
|
||||||
self.language = pycountry.languages.get(alpha_2=lang_code)
|
|
||||||
self.lang = self.language.alpha_3
|
|
||||||
self.url = get_elem_from_obj(song_data, ['url'])
|
|
||||||
|
|
||||||
# maybe could be implemented
|
|
||||||
self.lyricist: str
|
|
||||||
|
|
||||||
if get_elem_from_obj(song_data, ['lyrics_state']) != "complete":
|
|
||||||
logger.warning(
|
|
||||||
f"lyrics state of {self.title} by {self.artist} is not complete but {get_elem_from_obj(song_data, ['lyrics_state'])}")
|
|
||||||
|
|
||||||
self.valid = self.is_valid()
|
|
||||||
if self.valid:
|
|
||||||
logger.info(f"found lyrics for \"{self.__repr__()}\"")
|
|
||||||
else:
|
|
||||||
return
|
|
||||||
|
|
||||||
self.lyrics = self.fetch_lyrics()
|
|
||||||
if self.lyrics is None:
|
|
||||||
self.valid = False
|
|
||||||
|
|
||||||
def is_valid(self) -> bool:
|
|
||||||
title_match, title_distance = phonetic_compares.match_titles(self.title, self.desired_data['track'])
|
|
||||||
artist_match, artist_distance = phonetic_compares.match_artists(self.desired_data['artist'], self.artist)
|
|
||||||
|
|
||||||
return not title_match and not artist_match
|
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
|
||||||
return f"{self.title} by {self.artist} ({self.url})"
|
|
||||||
|
|
||||||
def fetch_lyrics(self) -> str | None:
|
|
||||||
if not self.valid:
|
|
||||||
logger.warning(f"{self.__repr__()} is invalid but the lyrics still get fetched. Something could be wrong.")
|
|
||||||
|
|
||||||
try:
|
|
||||||
r = session.get(self.url, timeout=TIMEOUT)
|
|
||||||
except requests.exceptions.Timeout:
|
|
||||||
logger.warning(f"{self.url} timed out after {TIMEOUT} seconds")
|
|
||||||
return None
|
|
||||||
if r.status_code != 200:
|
|
||||||
logger.warning(f"{r.url} returned {r.status_code}:\n{r.content}")
|
|
||||||
return None
|
|
||||||
|
|
||||||
soup = BeautifulSoup(r.content, "html.parser")
|
|
||||||
lyrics_soups = soup.find_all('div', {'data-lyrics-container': "true"})
|
|
||||||
if len(lyrics_soups) == 0:
|
|
||||||
logger.warning(f"didn't found lyrics on {self.url}")
|
|
||||||
return None
|
|
||||||
# if len(lyrics_soups) != 1:
|
|
||||||
# logger.warning(f"number of lyrics_soups doesn't equals 1, but {len(lyrics_soups)} on {self.url}")
|
|
||||||
|
|
||||||
lyrics = "\n".join([lyrics_soup.getText(separator="\n", strip=True) for lyrics_soup in lyrics_soups])
|
|
||||||
|
|
||||||
# <div data-lyrics-container="true" class="Lyrics__Container-sc-1ynbvzw-6 YYrds">With the soundle
|
|
||||||
self.lyrics = lyrics
|
|
||||||
return lyrics
|
|
||||||
|
|
||||||
def get_lyrics_object(self) -> Lyrics | None:
|
|
||||||
if self.lyrics is None:
|
|
||||||
return None
|
|
||||||
return Lyrics(text=self.lyrics, language=self.lang or "en")
|
|
||||||
|
|
||||||
lyrics_object = property(fget=get_lyrics_object)
|
|
||||||
|
|
||||||
|
|
||||||
def process_multiple_songs(song_datas: list, desired_data: dict) -> List[LyricsSong]:
|
|
||||||
all_songs = [LyricsSong(song_data, desired_data) for song_data in song_datas]
|
|
||||||
return all_songs
|
|
||||||
|
|
||||||
|
|
||||||
def search_song_list(artist: str, track: str) -> List[LyricsSong]:
|
|
||||||
endpoint = "https://genius.com/api/search/multi?q="
|
|
||||||
url = f"{endpoint}{artist} - {track}"
|
|
||||||
logging.info(f"requesting {url}")
|
|
||||||
|
|
||||||
desired_data = {
|
|
||||||
'artist': artist,
|
|
||||||
'track': track
|
|
||||||
}
|
|
||||||
|
|
||||||
try:
|
|
||||||
r = session.get(url, timeout=TIMEOUT)
|
|
||||||
except requests.exceptions.Timeout:
|
|
||||||
logger.warning(f"{url} timed out after {TIMEOUT} seconds")
|
|
||||||
return []
|
|
||||||
if r.status_code != 200:
|
|
||||||
logging.warning(f"{r.url} returned {r.status_code}:\n{r.content}")
|
|
||||||
return []
|
|
||||||
content = r.json()
|
|
||||||
if get_elem_from_obj(content, ['meta', 'status']) != 200:
|
|
||||||
logging.warning(f"{r.url} returned {get_elem_from_obj(content, ['meta', 'status'])}:\n{content}")
|
|
||||||
return []
|
|
||||||
|
|
||||||
sections = get_elem_from_obj(content, ['response', 'sections'])
|
|
||||||
for section in sections:
|
|
||||||
section_type = get_elem_from_obj(section, ['type'])
|
|
||||||
if section_type == "song":
|
|
||||||
return process_multiple_songs(get_elem_from_obj(section, ['hits'], return_if_none=[]), desired_data)
|
|
||||||
|
|
||||||
return []
|
|
||||||
|
|
||||||
|
|
||||||
def fetch_lyrics_from_artist(song: Song, artist: Artist) -> List[Lyrics]:
|
|
||||||
lyrics_list: List[Lyrics] = []
|
|
||||||
lyrics_song_list = search_song_list(artist.name, song.title)
|
|
||||||
|
|
||||||
for lyrics_song in lyrics_song_list:
|
|
||||||
if lyrics_song.valid:
|
|
||||||
lyrics_list.append(lyrics_song.lyrics_object)
|
|
||||||
|
|
||||||
return lyrics_list
|
|
||||||
|
|
||||||
|
|
||||||
def fetch_lyrics(song: Song) -> List[Lyrics]:
|
|
||||||
lyrics: List[Lyrics] = []
|
|
||||||
|
|
||||||
for artist in song.artists:
|
|
||||||
lyrics.extend(fetch_lyrics_from_artist(song, artist))
|
|
||||||
|
|
||||||
return lyrics
|
|
||||||
|
|
||||||
|
|
||||||
"""
|
|
||||||
if __name__ == "__main__":
|
|
||||||
logging.basicConfig(level=logging.DEBUG)
|
|
||||||
|
|
||||||
songs = search("Zombiez", "WALL OF Z")
|
|
||||||
for song in songs:
|
|
||||||
print(song)
|
|
||||||
"""
|
|
@ -1,57 +0,0 @@
|
|||||||
import os
|
|
||||||
|
|
||||||
from ...utils.shared import *
|
|
||||||
from ...utils import phonetic_compares
|
|
||||||
|
|
||||||
|
|
||||||
def is_valid(a1, a2, t1, t2) -> bool:
|
|
||||||
title_match, title_distance = phonetic_compares.match_titles(t1, t2)
|
|
||||||
artist_match, artist_distance = phonetic_compares.match_artists(a1, a2)
|
|
||||||
|
|
||||||
return not title_match and not artist_match
|
|
||||||
|
|
||||||
|
|
||||||
def get_metadata(file):
|
|
||||||
artist = None
|
|
||||||
title = None
|
|
||||||
|
|
||||||
audiofile = EasyID3(file)
|
|
||||||
artist = audiofile['artist']
|
|
||||||
title = audiofile['title']
|
|
||||||
|
|
||||||
return artist, title
|
|
||||||
|
|
||||||
|
|
||||||
def check_for_song(folder, artists, title):
|
|
||||||
if not os.path.exists(folder):
|
|
||||||
return False
|
|
||||||
files = [os.path.join(folder, i) for i in os.listdir(folder)]
|
|
||||||
|
|
||||||
for file in files:
|
|
||||||
artists_, title_ = get_metadata(file)
|
|
||||||
if is_valid(artists, artists_, title, title_):
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def get_path(row):
|
|
||||||
title = row['title']
|
|
||||||
artists = row['artists']
|
|
||||||
path_ = os.path.join(MUSIC_DIR, row['path'])
|
|
||||||
|
|
||||||
print(artists, title, path_)
|
|
||||||
check_for_song(path_, artists, title)
|
|
||||||
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
row = {'artists': ['Psychonaut 4'], 'id': '6b40186b-6678-4328-a4b8-eb7c9806a9fb', 'tracknumber': None,
|
|
||||||
'titlesort ': None, 'musicbrainz_releasetrackid': '6b40186b-6678-4328-a4b8-eb7c9806a9fb',
|
|
||||||
'musicbrainz_albumid': '0d229a02-74f6-4c77-8c20-6612295870ae', 'title': 'Sweet Decadance', 'isrc': None,
|
|
||||||
'album': 'Neurasthenia', 'copyright': 'Talheim Records', 'album_status': 'Official', 'language': 'eng',
|
|
||||||
'year': '2016', 'date': '2016-10-07', 'country': 'AT', 'barcode': None, 'albumartist': 'Psychonaut 4',
|
|
||||||
'albumsort': None, 'musicbrainz_albumtype': 'Album', 'compilation': None,
|
|
||||||
'album_artist_id': 'c0c720b5-012f-4204-a472-981403f37b12', 'path': 'dsbm/Psychonaut 4/Neurasthenia',
|
|
||||||
'file': 'dsbm/Psychonaut 4/Neurasthenia/Sweet Decadance.mp3', 'genre': 'dsbm', 'url': None, 'src': None}
|
|
||||||
print(get_path(row))
|
|
@ -1,181 +0,0 @@
|
|||||||
import time
|
|
||||||
|
|
||||||
import requests
|
|
||||||
import bs4
|
|
||||||
|
|
||||||
from ...utils.shared import *
|
|
||||||
from ...utils import phonetic_compares
|
|
||||||
|
|
||||||
from .source import AudioSource
|
|
||||||
from ...database import song as song_objects
|
|
||||||
|
|
||||||
|
|
||||||
TRIES = 5
|
|
||||||
TIMEOUT = 10
|
|
||||||
|
|
||||||
logger = MUSIFY_LOGGER
|
|
||||||
|
|
||||||
session = requests.Session()
|
|
||||||
session.headers = {
|
|
||||||
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:106.0) Gecko/20100101 Firefox/106.0",
|
|
||||||
"Connection": "keep-alive",
|
|
||||||
"Referer": "https://musify.club/"
|
|
||||||
}
|
|
||||||
session.proxies = proxies
|
|
||||||
|
|
||||||
|
|
||||||
class Musify(AudioSource):
|
|
||||||
@classmethod
|
|
||||||
def fetch_source(cls, song: dict) -> str | None:
|
|
||||||
super().fetch_source(song)
|
|
||||||
|
|
||||||
title = song.title
|
|
||||||
artists = song.get_artist_names()
|
|
||||||
|
|
||||||
# trying to get a download link via the autocomplete api
|
|
||||||
for artist in artists:
|
|
||||||
url = cls.fetch_source_from_autocomplete(title=title, artist=artist)
|
|
||||||
if url is not None:
|
|
||||||
logger.info(f"found download link {url}")
|
|
||||||
return url
|
|
||||||
|
|
||||||
# trying to get a download link via the html of the direct search page
|
|
||||||
for artist in artists:
|
|
||||||
url = cls.fetch_source_from_search(title=title, artist=artist)
|
|
||||||
if url is not None:
|
|
||||||
logger.info(f"found download link {url}")
|
|
||||||
return url
|
|
||||||
|
|
||||||
logger.warning(f"Didn't find the audio on {cls.__name__}")
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def get_download_link(cls, track_url: str) -> str | None:
|
|
||||||
# https://musify.club/track/dl/18567672/rauw-alejandro-te-felicito-feat-shakira.mp3
|
|
||||||
# /track/sundenklang-wenn-mein-herz-schreit-3883217'
|
|
||||||
|
|
||||||
file_ = track_url.split("/")[-1]
|
|
||||||
if len(file_) == 0:
|
|
||||||
return None
|
|
||||||
musify_id = file_.split("-")[-1]
|
|
||||||
musify_name = "-".join(file_.split("-")[:-1])
|
|
||||||
|
|
||||||
return f"https://musify.club/track/dl/{musify_id}/{musify_name}.mp3"
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def fetch_source_from_autocomplete(cls, title: str, artist: str) -> str | None:
|
|
||||||
url = f"https://musify.club/search/suggestions?term={artist} - {title}"
|
|
||||||
|
|
||||||
try:
|
|
||||||
logger.info(f"calling {url}")
|
|
||||||
r = session.get(url=url)
|
|
||||||
except requests.exceptions.ConnectionError:
|
|
||||||
logger.info("connection error occurred")
|
|
||||||
return None
|
|
||||||
if r.status_code == 200:
|
|
||||||
autocomplete = r.json()
|
|
||||||
for song in autocomplete:
|
|
||||||
if artist in song['label'] and "/track" in song['url']:
|
|
||||||
return cls.get_download_link(song['url'])
|
|
||||||
|
|
||||||
return None
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def get_soup_of_search(cls, query: str, trie=0) -> bs4.BeautifulSoup | None:
|
|
||||||
url = f"https://musify.club/search?searchText={query}"
|
|
||||||
logger.debug(f"Trying to get soup from {url}")
|
|
||||||
try:
|
|
||||||
r = session.get(url, timeout=15)
|
|
||||||
except requests.exceptions.Timeout:
|
|
||||||
return None
|
|
||||||
if r.status_code != 200:
|
|
||||||
if r.status_code in [503] and trie < TRIES:
|
|
||||||
logging.warning(f"youtube blocked downloading. ({trie}-{TRIES})")
|
|
||||||
logging.warning(f"retrying in {TIMEOUT} seconds again")
|
|
||||||
time.sleep(TIMEOUT)
|
|
||||||
return cls.get_soup_of_search(query, trie=trie + 1)
|
|
||||||
|
|
||||||
logging.warning("too many tries, returning")
|
|
||||||
return None
|
|
||||||
return bs4.BeautifulSoup(r.content, features="html.parser")
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def fetch_source_from_search(cls, title: str, artist: str) -> str | None:
|
|
||||||
query: str = f"{artist[0]} - {title}"
|
|
||||||
search_soup = cls.get_soup_of_search(query=query)
|
|
||||||
if search_soup is None:
|
|
||||||
return None
|
|
||||||
|
|
||||||
# get the soup of the container with all track results
|
|
||||||
tracklist_container_soup = search_soup.find_all("div", {"class": "playlist"})
|
|
||||||
if len(tracklist_container_soup) == 0:
|
|
||||||
return None
|
|
||||||
if len(tracklist_container_soup) != 1:
|
|
||||||
logger.warning("HTML Layout of https://musify.club changed. (or bug)")
|
|
||||||
tracklist_container_soup = tracklist_container_soup[0]
|
|
||||||
|
|
||||||
tracklist_soup = tracklist_container_soup.find_all("div", {"class": "playlist__details"})
|
|
||||||
|
|
||||||
def parse_track_soup(_track_soup):
|
|
||||||
anchor_soups = _track_soup.find_all("a")
|
|
||||||
artist_ = anchor_soups[0].text.strip()
|
|
||||||
track_ = anchor_soups[1].text.strip()
|
|
||||||
url_ = anchor_soups[1]['href']
|
|
||||||
return artist_, track_, url_
|
|
||||||
|
|
||||||
# check each track in the container, if they match
|
|
||||||
for track_soup in tracklist_soup:
|
|
||||||
artist_option, title_option, track_url = parse_track_soup(track_soup)
|
|
||||||
|
|
||||||
title_match, title_distance = phonetic_compares.match_titles(title, title_option)
|
|
||||||
artist_match, artist_distance = phonetic_compares.match_artists(artist, artist_option)
|
|
||||||
|
|
||||||
logging.debug(f"{(title, title_option, title_match, title_distance)}")
|
|
||||||
logging.debug(f"{(artist, artist_option, artist_match, artist_distance)}")
|
|
||||||
|
|
||||||
if not title_match and not artist_match:
|
|
||||||
return cls.get_download_link(track_url)
|
|
||||||
|
|
||||||
return None
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def download_from_musify(cls, target: song_objects.Target, url):
|
|
||||||
# returns if target hasn't been set
|
|
||||||
if target.path is None or target.file is None:
|
|
||||||
logger.warning(f"target hasn't been set. Can't download. Most likely a bug.")
|
|
||||||
return False
|
|
||||||
|
|
||||||
# download the audio data
|
|
||||||
logger.info(f"downloading: '{url}'")
|
|
||||||
try:
|
|
||||||
r = session.get(url, timeout=TIMEOUT)
|
|
||||||
except requests.exceptions.ConnectionError:
|
|
||||||
return False
|
|
||||||
except requests.exceptions.ReadTimeout:
|
|
||||||
logger.warning(f"musify server didn't respond after {TIMEOUT} seconds")
|
|
||||||
return False
|
|
||||||
if r.status_code != 200:
|
|
||||||
if r.status_code == 404:
|
|
||||||
logger.warning(f"{r.url} was not found")
|
|
||||||
return False
|
|
||||||
if r.status_code == 503:
|
|
||||||
logger.warning(f"{r.url} raised an internal server error")
|
|
||||||
return False
|
|
||||||
logger.error(f"\"{url}\" returned {r.status_code}: {r.text}")
|
|
||||||
return False
|
|
||||||
|
|
||||||
# write to the file and create folder if it doesn't exist
|
|
||||||
if not os.path.exists(target.path):
|
|
||||||
os.makedirs(target.path, exist_ok=True)
|
|
||||||
with open(target.file, "wb") as mp3_file:
|
|
||||||
mp3_file.write(r.content)
|
|
||||||
logger.info("finished")
|
|
||||||
return True
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def fetch_audio(cls, song: song_objects.Song, src: song_objects.Source):
|
|
||||||
super().fetch_audio(song, src)
|
|
||||||
return cls.download_from_musify(song.target, src.url)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
pass
|
|
@ -1,23 +0,0 @@
|
|||||||
from ...utils.shared import *
|
|
||||||
from typing import Tuple
|
|
||||||
|
|
||||||
from ...database import song as song_objects
|
|
||||||
|
|
||||||
|
|
||||||
logger = URL_DOWNLOAD_LOGGER
|
|
||||||
|
|
||||||
"""
|
|
||||||
The class "Source" is the superclass every class for specific audio
|
|
||||||
sources inherits from. This gives the advantage of a consistent
|
|
||||||
calling of the functions do search for a song and to download it.
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
class AudioSource:
|
|
||||||
@classmethod
|
|
||||||
def fetch_source(cls, row: dict):
|
|
||||||
logger.info(f"try getting source {row.title} from {cls.__name__}")
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def fetch_audio(cls, song: song_objects.Song, src: song_objects.Source):
|
|
||||||
logger.info(f"downloading {song}: {cls.__name__} {src.url} -> {song.target.file}")
|
|
@ -1,98 +0,0 @@
|
|||||||
from typing import List
|
|
||||||
|
|
||||||
import youtube_dl
|
|
||||||
import time
|
|
||||||
|
|
||||||
from ...utils.shared import *
|
|
||||||
from ...utils import phonetic_compares
|
|
||||||
from .source import AudioSource
|
|
||||||
|
|
||||||
from ...database import song as song_objects
|
|
||||||
|
|
||||||
|
|
||||||
logger = YOUTUBE_LOGGER
|
|
||||||
|
|
||||||
YDL_OPTIONS = {'format': 'bestaudio', 'noplaylist': 'True'}
|
|
||||||
YOUTUBE_URL_KEY = 'webpage_url'
|
|
||||||
YOUTUBE_TITLE_KEY = 'title'
|
|
||||||
WAIT_BETWEEN_BLOCK = 10
|
|
||||||
MAX_TRIES = 3
|
|
||||||
|
|
||||||
def youtube_length_to_mp3_length(youtube_len: float) -> int:
|
|
||||||
return int(youtube_len * 1000)
|
|
||||||
|
|
||||||
|
|
||||||
class Youtube(AudioSource):
|
|
||||||
@classmethod
|
|
||||||
def get_youtube_from_isrc(cls, isrc: str) -> List[dict]:
|
|
||||||
# https://stackoverflow.com/questions/63388364/searching-youtube-videos-using-youtube-dl
|
|
||||||
with youtube_dl.YoutubeDL(YDL_OPTIONS) as ydl:
|
|
||||||
try:
|
|
||||||
videos = ydl.extract_info(f"ytsearch:{isrc}", download=False)['entries']
|
|
||||||
except youtube_dl.utils.DownloadError:
|
|
||||||
return []
|
|
||||||
|
|
||||||
return [{
|
|
||||||
'url': video[YOUTUBE_URL_KEY],
|
|
||||||
'title': video[YOUTUBE_TITLE_KEY],
|
|
||||||
'length': youtube_length_to_mp3_length(float(videos[0]['duration']))
|
|
||||||
} for video in videos]
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def fetch_source(cls, song: song_objects.Song):
|
|
||||||
# https://stackoverflow.com/questions/63388364/searching-youtube-videos-using-youtube-dl
|
|
||||||
super().fetch_source(song)
|
|
||||||
|
|
||||||
if not song.has_isrc():
|
|
||||||
return None
|
|
||||||
|
|
||||||
real_title = song.title.lower()
|
|
||||||
|
|
||||||
final_result = None
|
|
||||||
results = cls.get_youtube_from_isrc(song.isrc)
|
|
||||||
for result in results:
|
|
||||||
video_title = result['title'].lower()
|
|
||||||
match, distance = phonetic_compares.match_titles(video_title, real_title)
|
|
||||||
|
|
||||||
if match:
|
|
||||||
continue
|
|
||||||
|
|
||||||
if not phonetic_compares.match_length(song.length, result['length']):
|
|
||||||
logger.warning(f"{song.length} doesn't match with {result}")
|
|
||||||
continue
|
|
||||||
|
|
||||||
final_result = result
|
|
||||||
|
|
||||||
if final_result is None:
|
|
||||||
return None
|
|
||||||
logger.info(f"found video {final_result}")
|
|
||||||
return final_result['url']
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def fetch_audio(cls, song: song_objects.Song, src: song_objects.Source, trie: int=0):
|
|
||||||
super().fetch_audio(song, src)
|
|
||||||
if song.target.file is None or song.target.path is None:
|
|
||||||
logger.warning(f"target hasn't been set. Can't download. Most likely a bug.")
|
|
||||||
return False
|
|
||||||
|
|
||||||
options = {
|
|
||||||
'format': 'bestaudio/best',
|
|
||||||
'keepvideo': False,
|
|
||||||
'outtmpl': song.target.file
|
|
||||||
}
|
|
||||||
|
|
||||||
# downloading
|
|
||||||
try:
|
|
||||||
with youtube_dl.YoutubeDL(options) as ydl:
|
|
||||||
ydl.download([src.url])
|
|
||||||
|
|
||||||
except youtube_dl.utils.DownloadError:
|
|
||||||
# retry when failing
|
|
||||||
logger.warning(f"youtube blocked downloading. ({trie}-{MAX_TRIES})")
|
|
||||||
if trie >= MAX_TRIES:
|
|
||||||
logger.warning("too many tries, returning")
|
|
||||||
return False
|
|
||||||
logger.warning(f"retrying in {WAIT_BETWEEN_BLOCK} seconds again")
|
|
||||||
time.sleep(WAIT_BETWEEN_BLOCK)
|
|
||||||
return cls.fetch_audio(song, src, trie=trie + 1)
|
|
||||||
|
|
@ -1,32 +1,20 @@
|
|||||||
from ..utils.enums import album
|
from .option import Options
|
||||||
from . import (
|
from .parents import DatabaseObject
|
||||||
song,
|
|
||||||
metadata,
|
from .metadata import Metadata, Mapping as ID3Mapping, ID3Timestamp
|
||||||
source,
|
|
||||||
parents,
|
from .source import Source, SourcePages, SourceTypes
|
||||||
formatted_text,
|
|
||||||
option,
|
from .song import (
|
||||||
collection
|
Song,
|
||||||
|
Album,
|
||||||
|
Artist,
|
||||||
|
Target,
|
||||||
|
Lyrics,
|
||||||
|
Label
|
||||||
)
|
)
|
||||||
|
|
||||||
DatabaseObject = parents.DatabaseObject
|
from .formatted_text import FormattedText
|
||||||
|
from .collection import Collection
|
||||||
|
|
||||||
Metadata = metadata.Metadata
|
from .country import Country
|
||||||
ID3Mapping = metadata.Mapping
|
|
||||||
ID3Timestamp = metadata.ID3Timestamp
|
|
||||||
|
|
||||||
Source = source.Source
|
|
||||||
|
|
||||||
Song = song.Song
|
|
||||||
Artist = song.Artist
|
|
||||||
Source = source.Source
|
|
||||||
Target = song.Target
|
|
||||||
Lyrics = song.Lyrics
|
|
||||||
Label = song.Label
|
|
||||||
|
|
||||||
Album = song.Album
|
|
||||||
|
|
||||||
FormattedText = formatted_text.FormattedText
|
|
||||||
|
|
||||||
Options = option.Options
|
|
||||||
Collection = collection.Collection
|
|
||||||
|
@ -96,7 +96,7 @@ class Collection:
|
|||||||
return AppendResult(True, existing_object, False)
|
return AppendResult(True, existing_object, False)
|
||||||
|
|
||||||
# if the object does already exist
|
# if the object does already exist
|
||||||
# thus merging and don't add it afterwards
|
# thus merging and don't add it afterward
|
||||||
if merge_into_existing:
|
if merge_into_existing:
|
||||||
existing_object.merge(element)
|
existing_object.merge(element)
|
||||||
# in case any relevant data has been added (e.g. it remaps the old object)
|
# in case any relevant data has been added (e.g. it remaps the old object)
|
||||||
@ -158,3 +158,6 @@ class Collection:
|
|||||||
@property
|
@property
|
||||||
def empty(self) -> bool:
|
def empty(self) -> bool:
|
||||||
return len(self._data) == 0
|
return len(self._data) == 0
|
||||||
|
|
||||||
|
def clear(self):
|
||||||
|
self.__init__(element_type=self.element_type)
|
||||||
|
66
src/music_kraken/objects/country.py
Normal file
66
src/music_kraken/objects/country.py
Normal file
File diff suppressed because one or more lines are too long
@ -17,7 +17,7 @@ class Lyrics(DatabaseObject):
|
|||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
text: FormattedText,
|
text: FormattedText,
|
||||||
language: pycountry.Languages,
|
language: pycountry.Languages = pycountry.languages.get(alpha_2="en"),
|
||||||
_id: str = None,
|
_id: str = None,
|
||||||
dynamic: bool = False,
|
dynamic: bool = False,
|
||||||
source_list: List[Source] = None,
|
source_list: List[Source] = None,
|
||||||
|
@ -16,7 +16,11 @@ class Mapping(Enum):
|
|||||||
TITLE = "TIT2"
|
TITLE = "TIT2"
|
||||||
ISRC = "TSRC"
|
ISRC = "TSRC"
|
||||||
LENGTH = "TLEN" # in milliseconds
|
LENGTH = "TLEN" # in milliseconds
|
||||||
DATE = "TYER"
|
# The 'Date' frame is a numeric string in the DDMM format containing the date for the recording. This field is always four characters long.
|
||||||
|
DATE = "TDAT"
|
||||||
|
# The 'Time' frame is a numeric string in the HHMM format containing the time for the recording. This field is always four characters long.
|
||||||
|
TIME = "TIME"
|
||||||
|
YEAR = "TYER"
|
||||||
TRACKNUMBER = "TRCK"
|
TRACKNUMBER = "TRCK"
|
||||||
TOTALTRACKS = "TRCK" # Stored in the same frame with TRACKNUMBER, separated by '/': e.g. '4/9'.
|
TOTALTRACKS = "TRCK" # Stored in the same frame with TRACKNUMBER, separated by '/': e.g. '4/9'.
|
||||||
TITLESORTORDER = "TSOT"
|
TITLESORTORDER = "TSOT"
|
||||||
@ -205,6 +209,19 @@ class ID3Timestamp:
|
|||||||
time_format = self.get_time_format()
|
time_format = self.get_time_format()
|
||||||
return time_format, self.date_obj.strftime(time_format)
|
return time_format, self.date_obj.strftime(time_format)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def fromtimestamp(cls, utc_timestamp: int):
|
||||||
|
date_obj = datetime.datetime.fromtimestamp(utc_timestamp)
|
||||||
|
|
||||||
|
return cls(
|
||||||
|
year=date_obj.year,
|
||||||
|
month=date_obj.month,
|
||||||
|
day=date_obj.day,
|
||||||
|
hour=date_obj.hour,
|
||||||
|
minute=date_obj.minute,
|
||||||
|
second=date_obj.second
|
||||||
|
)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def strptime(cls, time_stamp: str, format: str):
|
def strptime(cls, time_stamp: str, format: str):
|
||||||
"""
|
"""
|
||||||
@ -285,7 +302,7 @@ class Metadata:
|
|||||||
if id3_dict is not None:
|
if id3_dict is not None:
|
||||||
self.add_metadata_dict(id3_dict)
|
self.add_metadata_dict(id3_dict)
|
||||||
|
|
||||||
def __setitem__(self, frame, value_list: list, override_existing: bool = True):
|
def __setitem__(self, frame: Mapping, value_list: list, override_existing: bool = True):
|
||||||
if type(value_list) != list:
|
if type(value_list) != list:
|
||||||
raise ValueError(f"can only set attribute to list, not {type(value_list)}")
|
raise ValueError(f"can only set attribute to list, not {type(value_list)}")
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
from typing import TYPE_CHECKING, List
|
from typing import TYPE_CHECKING, List, Iterable
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from .parents import DatabaseObject
|
from .parents import DatabaseObject
|
||||||
@ -14,6 +14,13 @@ class Options:
|
|||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
for database_object in self._data:
|
for database_object in self._data:
|
||||||
yield database_object
|
yield database_object
|
||||||
|
|
||||||
|
def append(self, element: 'DatabaseObject'):
|
||||||
|
self._data.append(element)
|
||||||
|
|
||||||
|
def extend(self, iterable: Iterable['DatabaseObject']):
|
||||||
|
for element in iterable:
|
||||||
|
self.append(element)
|
||||||
|
|
||||||
def get_next_options(self, index: int) -> 'Options':
|
def get_next_options(self, index: int) -> 'Options':
|
||||||
if index >= len(self._data):
|
if index >= len(self._data):
|
||||||
|
@ -11,6 +11,11 @@ class DatabaseObject:
|
|||||||
COLLECTION_ATTRIBUTES: tuple = tuple()
|
COLLECTION_ATTRIBUTES: tuple = tuple()
|
||||||
SIMPLE_ATTRIBUTES: dict = dict()
|
SIMPLE_ATTRIBUTES: dict = dict()
|
||||||
|
|
||||||
|
# contains all collection attributes, which describe something "smaller"
|
||||||
|
# e.g. album has songs, but not artist.
|
||||||
|
DOWNWARDS_COLLECTION_ATTRIBUTES: tuple = tuple()
|
||||||
|
UPWARDS_COLLECTION_ATTRIBUTES: tuple = tuple()
|
||||||
|
|
||||||
def __init__(self, _id: int = None, dynamic: bool = False, **kwargs) -> None:
|
def __init__(self, _id: int = None, dynamic: bool = False, **kwargs) -> None:
|
||||||
self.automatic_id: bool = False
|
self.automatic_id: bool = False
|
||||||
|
|
||||||
@ -31,6 +36,11 @@ class DatabaseObject:
|
|||||||
|
|
||||||
self.build_version = -1
|
self.build_version = -1
|
||||||
|
|
||||||
|
def __hash__(self):
|
||||||
|
if self.dynamic:
|
||||||
|
raise TypeError("Dynamic DatabaseObjects are unhashable.")
|
||||||
|
return self.id
|
||||||
|
|
||||||
def __eq__(self, other) -> bool:
|
def __eq__(self, other) -> bool:
|
||||||
if not isinstance(other, type(self)):
|
if not isinstance(other, type(self)):
|
||||||
return False
|
return False
|
||||||
@ -65,6 +75,9 @@ class DatabaseObject:
|
|||||||
return list()
|
return list()
|
||||||
|
|
||||||
def merge(self, other, override: bool = False):
|
def merge(self, other, override: bool = False):
|
||||||
|
if other is None:
|
||||||
|
return
|
||||||
|
|
||||||
if self is other:
|
if self is other:
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -82,13 +95,17 @@ class DatabaseObject:
|
|||||||
if override or getattr(self, simple_attribute) == default_value:
|
if override or getattr(self, simple_attribute) == default_value:
|
||||||
setattr(self, simple_attribute, getattr(other, simple_attribute))
|
setattr(self, simple_attribute, getattr(other, simple_attribute))
|
||||||
|
|
||||||
|
def strip_details(self):
|
||||||
|
for collection in type(self).DOWNWARDS_COLLECTION_ATTRIBUTES:
|
||||||
|
getattr(self, collection).clear()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def metadata(self) -> Metadata:
|
def metadata(self) -> Metadata:
|
||||||
return Metadata()
|
return Metadata()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def options(self) -> Options:
|
def options(self) -> List["DatabaseObject"]:
|
||||||
return Options([self])
|
return [self]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def option_string(self) -> str:
|
def option_string(self) -> str:
|
||||||
|
@ -14,7 +14,7 @@ from .metadata import (
|
|||||||
Metadata
|
Metadata
|
||||||
)
|
)
|
||||||
from .option import Options
|
from .option import Options
|
||||||
from .parents import MainObject
|
from .parents import MainObject, DatabaseObject
|
||||||
from .source import Source, SourceCollection
|
from .source import Source, SourceCollection
|
||||||
from .target import Target
|
from .target import Target
|
||||||
from ..utils.string_processing import unify
|
from ..utils.string_processing import unify
|
||||||
@ -46,6 +46,8 @@ class Song(MainObject):
|
|||||||
"genre": None,
|
"genre": None,
|
||||||
"notes": FormattedText()
|
"notes": FormattedText()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UPWARDS_COLLECTION_ATTRIBUTES = ("album_collection", "main_artist_collection", "feature_artist_collection")
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
@ -160,7 +162,7 @@ class Song(MainObject):
|
|||||||
f"feat. Artist({OPTION_STRING_DELIMITER.join(artist.name for artist in self.feature_artist_collection)})"
|
f"feat. Artist({OPTION_STRING_DELIMITER.join(artist.name for artist in self.feature_artist_collection)})"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def options(self) -> Options:
|
def options(self) -> List[DatabaseObject]:
|
||||||
"""
|
"""
|
||||||
Return a list of related objects including the song object, album object, main artist objects, and
|
Return a list of related objects including the song object, album object, main artist objects, and
|
||||||
feature artist objects.
|
feature artist objects.
|
||||||
@ -171,7 +173,7 @@ class Song(MainObject):
|
|||||||
options.extend(self.feature_artist_collection)
|
options.extend(self.feature_artist_collection)
|
||||||
options.extend(self.album_collection)
|
options.extend(self.album_collection)
|
||||||
options.append(self)
|
options.append(self)
|
||||||
return Options(options)
|
return options
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def tracksort_str(self) -> str:
|
def tracksort_str(self) -> str:
|
||||||
@ -204,6 +206,9 @@ class Album(MainObject):
|
|||||||
"notes": FormattedText()
|
"notes": FormattedText()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DOWNWARDS_COLLECTION_ATTRIBUTES = ("song_collection", )
|
||||||
|
UPWARDS_COLLECTION_ATTRIBUTES = ("artist_collection", "label_collection")
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
_id: int = None,
|
_id: int = None,
|
||||||
@ -290,7 +295,11 @@ class Album(MainObject):
|
|||||||
id3Mapping.COPYRIGHT: [self.copyright],
|
id3Mapping.COPYRIGHT: [self.copyright],
|
||||||
id3Mapping.LANGUAGE: [self.iso_639_2_lang],
|
id3Mapping.LANGUAGE: [self.iso_639_2_lang],
|
||||||
id3Mapping.ALBUM_ARTIST: [a.name for a in self.artist_collection],
|
id3Mapping.ALBUM_ARTIST: [a.name for a in self.artist_collection],
|
||||||
id3Mapping.DATE: [self.date.timestamp],
|
id3Mapping.DATE: [self.date.strftime("%d%m")] if self.date.has_year and self.date.has_month else [],
|
||||||
|
id3Mapping.TIME: [self.date.strftime(("%H%M"))] if self.date.has_hour and self.date.has_minute else [],
|
||||||
|
id3Mapping.YEAR: [str(self.date.year).zfill(4)] if self.date.has_year else [],
|
||||||
|
id3Mapping.RELEASE_DATE: [self.date.timestamp],
|
||||||
|
id3Mapping.ORIGINAL_RELEASE_DATE: [self.date.timestamp],
|
||||||
id3Mapping.ALBUMSORTORDER: [str(self.albumsort)] if self.albumsort is not None else []
|
id3Mapping.ALBUMSORTORDER: [str(self.albumsort)] if self.albumsort is not None else []
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -304,12 +313,12 @@ class Album(MainObject):
|
|||||||
f"under Label({OPTION_STRING_DELIMITER.join([label.name for label in self.label_collection])})"
|
f"under Label({OPTION_STRING_DELIMITER.join([label.name for label in self.label_collection])})"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def options(self) -> Options:
|
def options(self) -> List[DatabaseObject]:
|
||||||
options = self.artist_collection.shallow_list
|
options = self.artist_collection.shallow_list
|
||||||
options.append(self)
|
options.append(self)
|
||||||
options.extend(self.song_collection)
|
options.extend(self.song_collection)
|
||||||
|
|
||||||
return Options(options)
|
return options
|
||||||
|
|
||||||
def update_tracksort(self):
|
def update_tracksort(self):
|
||||||
"""
|
"""
|
||||||
@ -398,6 +407,10 @@ class Album(MainObject):
|
|||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
return len(self.artist_collection) > 1
|
return len(self.artist_collection) > 1
|
||||||
|
|
||||||
|
@property
|
||||||
|
def album_type_string(self) -> str:
|
||||||
|
return self.album_type.value
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@ -422,6 +435,9 @@ class Artist(MainObject):
|
|||||||
"general_genre": ""
|
"general_genre": ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DOWNWARDS_COLLECTION_ATTRIBUTES = ("feature_song_collection", "main_album_collection")
|
||||||
|
UPWARDS_COLLECTION_ATTRIBUTES = ("label_collection", )
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
_id: int = None,
|
_id: int = None,
|
||||||
@ -592,11 +608,11 @@ class Artist(MainObject):
|
|||||||
f"under Label({OPTION_STRING_DELIMITER.join([label.name for label in self.label_collection])})"
|
f"under Label({OPTION_STRING_DELIMITER.join([label.name for label in self.label_collection])})"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def options(self) -> Options:
|
def options(self) -> List[DatabaseObject]:
|
||||||
options = [self]
|
options = [self]
|
||||||
options.extend(self.main_album_collection)
|
options.extend(self.main_album_collection)
|
||||||
options.extend(self.feature_song_collection)
|
options.extend(self.feature_song_collection)
|
||||||
return Options(options)
|
return options
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def country_string(self):
|
def country_string(self):
|
||||||
@ -646,6 +662,8 @@ class Label(MainObject):
|
|||||||
"notes": FormattedText()
|
"notes": FormattedText()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DOWNWARDS_COLLECTION_ATTRIBUTES = COLLECTION_ATTRIBUTES
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
_id: int = None,
|
_id: int = None,
|
||||||
@ -694,7 +712,9 @@ class Label(MainObject):
|
|||||||
]
|
]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def options(self) -> Options:
|
def options(self) -> List[DatabaseObject]:
|
||||||
options = [self]
|
options = [self]
|
||||||
options.extend(self.current_artist_collection.shallow_list)
|
options.extend(self.current_artist_collection.shallow_list)
|
||||||
options.extend(self.album_collection.shallow_list)
|
options.extend(self.album_collection.shallow_list)
|
||||||
|
|
||||||
|
return options
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
from typing import List, Dict, Tuple, Optional
|
from typing import List, Dict, Set, Tuple, Optional
|
||||||
from urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
|
|
||||||
from ..utils.enums.source import SourcePages, SourceTypes
|
from ..utils.enums.source import SourcePages, SourceTypes
|
||||||
|
from ..utils.shared import ALL_YOUTUBE_URLS
|
||||||
from .metadata import Mapping, Metadata
|
from .metadata import Mapping, Metadata
|
||||||
from .parents import DatabaseObject
|
from .parents import DatabaseObject
|
||||||
from .collection import Collection
|
from .collection import Collection
|
||||||
@ -53,7 +54,7 @@ class Source(DatabaseObject):
|
|||||||
if "musify" in parsed.netloc:
|
if "musify" in parsed.netloc:
|
||||||
return cls(SourcePages.MUSIFY, url, referer_page=referer_page)
|
return cls(SourcePages.MUSIFY, url, referer_page=referer_page)
|
||||||
|
|
||||||
if url.startswith("https://www.youtube"):
|
if parsed.netloc in [_url.netloc for _url in ALL_YOUTUBE_URLS]:
|
||||||
return cls(SourcePages.YOUTUBE, url, referer_page=referer_page)
|
return cls(SourcePages.YOUTUBE, url, referer_page=referer_page)
|
||||||
|
|
||||||
if url.startswith("https://www.deezer"):
|
if url.startswith("https://www.deezer"):
|
||||||
@ -128,6 +129,10 @@ class SourceCollection(Collection):
|
|||||||
super().map_element(source)
|
super().map_element(source)
|
||||||
|
|
||||||
self._page_to_source_list[source.page_enum].append(source)
|
self._page_to_source_list[source.page_enum].append(source)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def source_pages(self) -> Set[SourcePages]:
|
||||||
|
return set(source.page_enum for source in self._data)
|
||||||
|
|
||||||
def get_sources_from_page(self, source_page: SourcePages) -> List[Source]:
|
def get_sources_from_page(self, source_page: SourcePages) -> List[Source]:
|
||||||
"""
|
"""
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import List, Tuple
|
from typing import List, Tuple, TextIO
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
from tqdm import tqdm
|
from tqdm import tqdm
|
||||||
@ -98,3 +98,9 @@ class Target(DatabaseObject):
|
|||||||
except requests.exceptions.Timeout:
|
except requests.exceptions.Timeout:
|
||||||
shared.DOWNLOAD_LOGGER.error("Stream timed out.")
|
shared.DOWNLOAD_LOGGER.error("Stream timed out.")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def open(self, file_mode: str, **kwargs) -> TextIO:
|
||||||
|
return self.file_path.open(file_mode, **kwargs)
|
||||||
|
|
||||||
|
def delete(self):
|
||||||
|
self.file_path.unlink(missing_ok=True)
|
||||||
|
@ -1,10 +1,5 @@
|
|||||||
from .encyclopaedia_metallum import EncyclopaediaMetallum
|
from .encyclopaedia_metallum import EncyclopaediaMetallum
|
||||||
from .musify import Musify
|
from .musify import Musify
|
||||||
|
from .youtube import YouTube
|
||||||
|
|
||||||
EncyclopaediaMetallum = EncyclopaediaMetallum
|
from .abstract import Page, INDEPENDENT_DB_OBJECTS
|
||||||
Musify = Musify
|
|
||||||
|
|
||||||
from . import download_center
|
|
||||||
|
|
||||||
Search = download_center.Search
|
|
||||||
|
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
import logging
|
import logging
|
||||||
import random
|
import random
|
||||||
from copy import copy
|
from copy import copy
|
||||||
from typing import Optional, Union, Type, Dict, Set
|
from typing import Optional, Union, Type, Dict, Set, List, Tuple
|
||||||
|
from string import Formatter
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
from bs4 import BeautifulSoup
|
from bs4 import BeautifulSoup
|
||||||
|
|
||||||
from .support_classes.default_target import DefaultTarget
|
from ..connection import Connection
|
||||||
from .support_classes.download_result import DownloadResult
|
|
||||||
from ..objects import (
|
from ..objects import (
|
||||||
Song,
|
Song,
|
||||||
Source,
|
Source,
|
||||||
@ -23,6 +23,143 @@ from ..utils.enums.source import SourcePages
|
|||||||
from ..utils.enums.album import AlbumType
|
from ..utils.enums.album import AlbumType
|
||||||
from ..audio import write_metadata_to_target, correct_codec
|
from ..audio import write_metadata_to_target, correct_codec
|
||||||
from ..utils import shared
|
from ..utils import shared
|
||||||
|
from ..utils.shared import DOWNLOAD_PATH, DOWNLOAD_FILE, AUDIO_FORMAT
|
||||||
|
from ..utils.support_classes import Query, DownloadResult
|
||||||
|
|
||||||
|
INDEPENDENT_DB_OBJECTS = Union[Label, Album, Artist, Song]
|
||||||
|
INDEPENDENT_DB_TYPES = Union[Type[Song], Type[Album], Type[Artist], Type[Label]]
|
||||||
|
|
||||||
|
|
||||||
|
class NamingDict(dict):
|
||||||
|
CUSTOM_KEYS: Dict[str, str] = {
|
||||||
|
"label": "label.name",
|
||||||
|
"artist": "artist.name",
|
||||||
|
"song": "song.title",
|
||||||
|
"isrc": "song.isrc",
|
||||||
|
"album": "album.title",
|
||||||
|
"album_type": "album.album_type_string"
|
||||||
|
}
|
||||||
|
|
||||||
|
def __init__(self, values: dict, object_mappings: Dict[str, DatabaseObject] = None):
|
||||||
|
self.object_mappings: Dict[str, DatabaseObject] = object_mappings or dict()
|
||||||
|
|
||||||
|
super().__init__(values)
|
||||||
|
self["audio_format"] = AUDIO_FORMAT
|
||||||
|
|
||||||
|
def add_object(self, music_object: DatabaseObject):
|
||||||
|
self.object_mappings[type(music_object).__name__.lower()] = music_object
|
||||||
|
|
||||||
|
def copy(self) -> dict:
|
||||||
|
return type(self)(super().copy(), self.object_mappings.copy())
|
||||||
|
|
||||||
|
def __getitem__(self, key: str) -> str:
|
||||||
|
return super().__getitem__(key)
|
||||||
|
|
||||||
|
def default_value_for_name(self, name: str) -> str:
|
||||||
|
return f'Various {name.replace("_", " ").title()}'
|
||||||
|
|
||||||
|
def __missing__(self, key: str) -> str:
|
||||||
|
"""
|
||||||
|
TODO
|
||||||
|
add proper logging
|
||||||
|
"""
|
||||||
|
|
||||||
|
if "." not in key:
|
||||||
|
if key not in self.CUSTOM_KEYS:
|
||||||
|
return self.default_value_for_name(key)
|
||||||
|
|
||||||
|
key = self.CUSTOM_KEYS[key]
|
||||||
|
|
||||||
|
frag_list = key.split(".")
|
||||||
|
|
||||||
|
object_name = frag_list[0].strip().lower()
|
||||||
|
attribute_name = frag_list[-1].strip().lower()
|
||||||
|
|
||||||
|
if object_name not in self.object_mappings:
|
||||||
|
return self.default_value_for_name(attribute_name)
|
||||||
|
|
||||||
|
music_object = self.object_mappings[object_name]
|
||||||
|
try:
|
||||||
|
value = getattr(music_object, attribute_name)
|
||||||
|
if value is None:
|
||||||
|
return self.default_value_for_name(attribute_name)
|
||||||
|
|
||||||
|
return str(value)
|
||||||
|
|
||||||
|
except AttributeError:
|
||||||
|
return self.default_value_for_name(attribute_name)
|
||||||
|
|
||||||
|
|
||||||
|
def _clean_music_object(music_object: INDEPENDENT_DB_OBJECTS, collections: Dict[INDEPENDENT_DB_TYPES, Collection]):
|
||||||
|
if type(music_object) == Label:
|
||||||
|
return _clean_label(label=music_object, collections=collections)
|
||||||
|
if type(music_object) == Artist:
|
||||||
|
return _clean_artist(artist=music_object, collections=collections)
|
||||||
|
if type(music_object) == Album:
|
||||||
|
return _clean_album(album=music_object, collections=collections)
|
||||||
|
if type(music_object) == Song:
|
||||||
|
return _clean_song(song=music_object, collections=collections)
|
||||||
|
|
||||||
|
|
||||||
|
def _clean_collection(collection: Collection, collection_dict: Dict[INDEPENDENT_DB_TYPES, Collection]):
|
||||||
|
if collection.element_type not in collection_dict:
|
||||||
|
return
|
||||||
|
|
||||||
|
for i, element in enumerate(collection):
|
||||||
|
r = collection_dict[collection.element_type].append(element, merge_into_existing=True)
|
||||||
|
collection[i] = r.current_element
|
||||||
|
|
||||||
|
if not r.was_the_same:
|
||||||
|
_clean_music_object(r.current_element, collection_dict)
|
||||||
|
|
||||||
|
|
||||||
|
def _clean_label(label: Label, collections: Dict[INDEPENDENT_DB_TYPES, Collection]):
|
||||||
|
_clean_collection(label.current_artist_collection, collections)
|
||||||
|
_clean_collection(label.album_collection, collections)
|
||||||
|
|
||||||
|
|
||||||
|
def _clean_artist(artist: Artist, collections: Dict[INDEPENDENT_DB_TYPES, Collection]):
|
||||||
|
_clean_collection(artist.main_album_collection, collections)
|
||||||
|
_clean_collection(artist.feature_song_collection, collections)
|
||||||
|
_clean_collection(artist.label_collection, collections)
|
||||||
|
|
||||||
|
|
||||||
|
def _clean_album(album: Album, collections: Dict[INDEPENDENT_DB_TYPES, Collection]):
|
||||||
|
_clean_collection(album.label_collection, collections)
|
||||||
|
_clean_collection(album.song_collection, collections)
|
||||||
|
_clean_collection(album.artist_collection, collections)
|
||||||
|
|
||||||
|
|
||||||
|
def _clean_song(song: Song, collections: Dict[INDEPENDENT_DB_TYPES, Collection]):
|
||||||
|
_clean_collection(song.album_collection, collections)
|
||||||
|
_clean_collection(song.feature_artist_collection, collections)
|
||||||
|
_clean_collection(song.main_artist_collection, collections)
|
||||||
|
|
||||||
|
def clean_object(dirty_object: DatabaseObject) -> DatabaseObject:
|
||||||
|
if isinstance(dirty_object, INDEPENDENT_DB_OBJECTS):
|
||||||
|
collections = {
|
||||||
|
Label: Collection(element_type=Label),
|
||||||
|
Artist: Collection(element_type=Artist),
|
||||||
|
Album: Collection(element_type=Album),
|
||||||
|
Song: Collection(element_type=Song)
|
||||||
|
}
|
||||||
|
|
||||||
|
_clean_music_object(dirty_object, collections)
|
||||||
|
return dirty_object
|
||||||
|
|
||||||
|
def build_new_object(new_object: DatabaseObject) -> DatabaseObject:
|
||||||
|
new_object = clean_object(new_object)
|
||||||
|
new_object.compile(merge_into=False)
|
||||||
|
|
||||||
|
return new_object
|
||||||
|
|
||||||
|
def merge_together(old_object: DatabaseObject, new_object: DatabaseObject) -> DatabaseObject:
|
||||||
|
new_object = clean_object(new_object)
|
||||||
|
|
||||||
|
old_object.merge(new_object)
|
||||||
|
old_object.compile(merge_into=False)
|
||||||
|
|
||||||
|
return old_object
|
||||||
|
|
||||||
|
|
||||||
class Page:
|
class Page:
|
||||||
@ -30,151 +167,90 @@ class Page:
|
|||||||
This is an abstract class, laying out the
|
This is an abstract class, laying out the
|
||||||
functionality for every other class fetching something
|
functionality for every other class fetching something
|
||||||
"""
|
"""
|
||||||
API_SESSION: requests.Session = requests.Session()
|
|
||||||
API_SESSION.proxies = shared.proxies
|
|
||||||
TIMEOUT = 5
|
|
||||||
POST_TIMEOUT = TIMEOUT
|
|
||||||
TRIES = 5
|
|
||||||
LOGGER = logging.getLogger("this shouldn't be used")
|
|
||||||
|
|
||||||
SOURCE_TYPE: SourcePages
|
SOURCE_TYPE: SourcePages
|
||||||
|
LOGGER = logging.getLogger("this shouldn't be used")
|
||||||
|
|
||||||
|
# set this to true, if all song details can also be fetched by fetching album details
|
||||||
|
NO_ADDITIONAL_DATA_FROM_SONG = False
|
||||||
|
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
|
"""
|
||||||
|
CODE I NEED WHEN I START WITH MULTITHREADING
|
||||||
|
|
||||||
|
def __init__(self, end_event: EndThread, search_queue: Queue, search_result_queue: Queue):
|
||||||
|
self.end_event = end_event
|
||||||
|
|
||||||
|
self.search_queue = search_queue
|
||||||
|
self.search_result_queue = search_result_queue
|
||||||
|
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def _empty_working_queues(self):
|
||||||
|
return self.search_queue.empty()
|
||||||
|
|
||||||
@classmethod
|
def run(self) -> None:
|
||||||
def get_request(
|
while bool(self.end_event) and self._empty_working_queues:
|
||||||
cls,
|
if not self.search_queue.empty():
|
||||||
url: str,
|
self.search(self.search_queue.get())
|
||||||
stream: bool = False,
|
self.search_result_queue.put(FinishedSearch())
|
||||||
accepted_response_codes: set = {200},
|
continue
|
||||||
trie: int = 0
|
"""
|
||||||
) -> Optional[requests.Response]:
|
|
||||||
|
def get_source_type(self, source: Source) -> Optional[Type[DatabaseObject]]:
|
||||||
retry = False
|
return None
|
||||||
try:
|
|
||||||
r = cls.API_SESSION.get(url, timeout=cls.TIMEOUT, stream=stream)
|
def get_soup_from_response(self, r: requests.Response) -> BeautifulSoup:
|
||||||
except requests.exceptions.Timeout:
|
|
||||||
cls.LOGGER.warning(f"request timed out at \"{url}\": ({trie}-{cls.TRIES})")
|
|
||||||
retry = True
|
|
||||||
except requests.exceptions.ConnectionError:
|
|
||||||
cls.LOGGER.warning(f"couldn't connect to \"{url}\": ({trie}-{cls.TRIES})")
|
|
||||||
retry = True
|
|
||||||
|
|
||||||
if not retry and r.status_code in accepted_response_codes:
|
|
||||||
return r
|
|
||||||
|
|
||||||
if not retry:
|
|
||||||
cls.LOGGER.warning(f"{cls.__name__} responded wit {r.status_code} at GET:{url}. ({trie}-{cls.TRIES})")
|
|
||||||
cls.LOGGER.debug(r.content)
|
|
||||||
|
|
||||||
if trie >= cls.TRIES:
|
|
||||||
cls.LOGGER.warning("to many tries. Aborting.")
|
|
||||||
return None
|
|
||||||
|
|
||||||
return cls.get_request(url=url, stream=stream, accepted_response_codes=accepted_response_codes, trie=trie + 1)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def post_request(cls, url: str, json: dict, accepted_response_codes: set = {200}, trie: int = 0) -> Optional[
|
|
||||||
requests.Response]:
|
|
||||||
retry = False
|
|
||||||
try:
|
|
||||||
r = cls.API_SESSION.post(url, json=json, timeout=cls.POST_TIMEOUT)
|
|
||||||
except requests.exceptions.Timeout:
|
|
||||||
cls.LOGGER.warning(f"request timed out at \"{url}\": ({trie}-{cls.TRIES})")
|
|
||||||
retry = True
|
|
||||||
except requests.exceptions.ConnectionError:
|
|
||||||
cls.LOGGER.warning(f"couldn't connect to \"{url}\": ({trie}-{cls.TRIES})")
|
|
||||||
retry = True
|
|
||||||
|
|
||||||
if not retry and r.status_code in accepted_response_codes:
|
|
||||||
return r
|
|
||||||
|
|
||||||
if not retry:
|
|
||||||
cls.LOGGER.warning(f"{cls.__name__} responded wit {r.status_code} at POST:{url}. ({trie}-{cls.TRIES})")
|
|
||||||
cls.LOGGER.debug(r.content)
|
|
||||||
|
|
||||||
if trie >= cls.TRIES:
|
|
||||||
cls.LOGGER.warning("to many tries. Aborting.")
|
|
||||||
return None
|
|
||||||
|
|
||||||
cls.LOGGER.warning(f"payload: {json}")
|
|
||||||
return cls.post_request(url=url, json=json, accepted_response_codes=accepted_response_codes, trie=trie + 1)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def get_soup_from_response(cls, r: requests.Response) -> BeautifulSoup:
|
|
||||||
return BeautifulSoup(r.content, "html.parser")
|
return BeautifulSoup(r.content, "html.parser")
|
||||||
|
|
||||||
class Query:
|
# to search stuff
|
||||||
def __init__(self, query: str):
|
def search(self, query: Query) -> List[DatabaseObject]:
|
||||||
self.query = query
|
music_object = query.music_object
|
||||||
self.is_raw = False
|
|
||||||
|
search_functions = {
|
||||||
|
Song: self.song_search,
|
||||||
|
Album: self.album_search,
|
||||||
|
Artist: self.artist_search,
|
||||||
|
Label: self.label_search
|
||||||
|
}
|
||||||
|
|
||||||
|
if type(music_object) in search_functions:
|
||||||
|
r = search_functions[type(music_object)](music_object)
|
||||||
|
if len(r) > 0:
|
||||||
|
return r
|
||||||
|
|
||||||
|
r = []
|
||||||
|
for default_query in query.default_search:
|
||||||
|
for single_option in self.general_search(default_query):
|
||||||
|
r.append(single_option)
|
||||||
|
|
||||||
|
return r
|
||||||
|
|
||||||
|
def general_search(self, search_query: str) -> List[DatabaseObject]:
|
||||||
|
return []
|
||||||
|
|
||||||
|
def label_search(self, label: Label) -> List[Label]:
|
||||||
|
return []
|
||||||
|
|
||||||
|
def artist_search(self, artist: Artist) -> List[Artist]:
|
||||||
|
return []
|
||||||
|
|
||||||
|
def album_search(self, album: Album) -> List[Album]:
|
||||||
|
return []
|
||||||
|
|
||||||
|
def song_search(self, song: Song) -> List[Song]:
|
||||||
|
return []
|
||||||
|
|
||||||
|
|
||||||
self.artist = None
|
def fetch_details(self, music_object: DatabaseObject, stop_at_level: int = 1) -> DatabaseObject:
|
||||||
self.album = None
|
|
||||||
self.song = None
|
|
||||||
|
|
||||||
self.parse_query(query=query)
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
if self.is_raw:
|
|
||||||
return self.query
|
|
||||||
return f"{self.artist}; {self.album}; {self.song}"
|
|
||||||
|
|
||||||
def parse_query(self, query: str):
|
|
||||||
if not '#' in query:
|
|
||||||
self.is_raw = True
|
|
||||||
return
|
|
||||||
|
|
||||||
query = query.strip()
|
|
||||||
parameters = query.split('#')
|
|
||||||
parameters.remove('')
|
|
||||||
|
|
||||||
for parameter in parameters:
|
|
||||||
splitted = parameter.split(" ")
|
|
||||||
type_ = splitted[0]
|
|
||||||
input_ = " ".join(splitted[1:]).strip()
|
|
||||||
|
|
||||||
if type_ == "a":
|
|
||||||
self.artist = input_
|
|
||||||
continue
|
|
||||||
if type_ == "r":
|
|
||||||
self.album = input_
|
|
||||||
continue
|
|
||||||
if type_ == "t":
|
|
||||||
self.song = input_
|
|
||||||
continue
|
|
||||||
|
|
||||||
def get_str(self, string):
|
|
||||||
if string is None:
|
|
||||||
return ""
|
|
||||||
return string
|
|
||||||
|
|
||||||
artist_str = property(fget=lambda self: self.get_str(self.artist))
|
|
||||||
album_str = property(fget=lambda self: self.get_str(self.album))
|
|
||||||
song_str = property(fget=lambda self: self.get_str(self.song))
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def search_by_query(cls, query: str) -> Options:
|
|
||||||
"""
|
"""
|
||||||
# The Query
|
when a music object with lacking data is passed in, it returns
|
||||||
You can define a new parameter with "#",
|
|
||||||
the letter behind it defines the *type* of parameter, followed by a space
|
|
||||||
"#a Psychonaut 4 #r Tired, Numb and #t Drop by Drop"
|
|
||||||
if no # is in the query it gets treated as "unspecified query"
|
|
||||||
|
|
||||||
# Functionality
|
|
||||||
Returns the best matches from this page for the query, passed in.
|
|
||||||
|
|
||||||
:param query:
|
|
||||||
:return possible_music_objects:
|
|
||||||
"""
|
|
||||||
|
|
||||||
return Options()
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def fetch_details(cls, music_object: Union[Song, Album, Artist, Label], stop_at_level: int = 1) -> DatabaseObject:
|
|
||||||
"""
|
|
||||||
when a music object with laccing data is passed in, it returns
|
|
||||||
the SAME object **(no copy)** with more detailed data.
|
the SAME object **(no copy)** with more detailed data.
|
||||||
If you for example put in an album, it fetches the tracklist
|
If you for example put in, an album, it fetches the tracklist
|
||||||
|
|
||||||
:param music_object:
|
:param music_object:
|
||||||
:param stop_at_level:
|
:param stop_at_level:
|
||||||
@ -187,362 +263,177 @@ class Page:
|
|||||||
:return detailed_music_object: IT MODIFIES THE INPUT OBJ
|
:return detailed_music_object: IT MODIFIES THE INPUT OBJ
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# creating a new object, of the same type
|
||||||
new_music_object: DatabaseObject = type(music_object)()
|
new_music_object: DatabaseObject = type(music_object)()
|
||||||
|
|
||||||
had_sources = False
|
# only certain database objects, have a source list
|
||||||
|
if isinstance(music_object, INDEPENDENT_DB_OBJECTS):
|
||||||
|
source: Source
|
||||||
|
for source in music_object.source_collection.get_sources_from_page(self.SOURCE_TYPE):
|
||||||
|
new_music_object.merge(
|
||||||
|
self.fetch_object_from_source(
|
||||||
|
source=source,
|
||||||
|
enforce_type=type(music_object),
|
||||||
|
stop_at_level=stop_at_level,
|
||||||
|
post_process=False
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
source: Source
|
return merge_together(music_object, new_music_object)
|
||||||
for source in music_object.source_collection.get_sources_from_page(cls.SOURCE_TYPE):
|
|
||||||
new_music_object.merge(
|
|
||||||
cls._fetch_object_from_source(source=source, obj_type=type(music_object), stop_at_level=stop_at_level))
|
|
||||||
had_sources = True
|
|
||||||
|
|
||||||
if not had_sources:
|
def fetch_object_from_source(self, source: Source, stop_at_level: int = 2, enforce_type: Type[DatabaseObject] = None, post_process: bool = True) -> Optional[DatabaseObject]:
|
||||||
music_object.compile(merge_into=True)
|
obj_type = self.get_source_type(source)
|
||||||
return music_object
|
|
||||||
|
|
||||||
collections = {
|
|
||||||
Label: Collection(element_type=Label),
|
|
||||||
Artist: Collection(element_type=Artist),
|
|
||||||
Album: Collection(element_type=Album),
|
|
||||||
Song: Collection(element_type=Song)
|
|
||||||
}
|
|
||||||
|
|
||||||
cls._clean_music_object(new_music_object, collections)
|
|
||||||
|
|
||||||
music_object.merge(new_music_object)
|
|
||||||
|
|
||||||
music_object.compile(merge_into=True)
|
|
||||||
|
|
||||||
return music_object
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def fetch_object_from_source(cls, source: Source, stop_at_level: int = 2):
|
|
||||||
obj_type = cls._get_type_of_url(source.url)
|
|
||||||
if obj_type is None:
|
if obj_type is None:
|
||||||
return None
|
return None
|
||||||
|
if enforce_type != obj_type and enforce_type is not None:
|
||||||
music_object = cls._fetch_object_from_source(source=source, obj_type=obj_type, stop_at_level=stop_at_level)
|
self.LOGGER.warning(f"Object type isn't type to enforce: {enforce_type}, {obj_type}")
|
||||||
|
return None
|
||||||
collections = {
|
|
||||||
Label: Collection(element_type=Label),
|
music_object: DatabaseObject = None
|
||||||
Artist: Collection(element_type=Artist),
|
|
||||||
Album: Collection(element_type=Album),
|
fetch_map = {
|
||||||
Song: Collection(element_type=Song)
|
Song: self.fetch_song,
|
||||||
|
Album: self.fetch_album,
|
||||||
|
Artist: self.fetch_artist,
|
||||||
|
Label: self.fetch_label
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if obj_type in fetch_map:
|
||||||
|
music_object = fetch_map[obj_type](source, stop_at_level)
|
||||||
|
else:
|
||||||
|
self.LOGGER.warning(f"Can't fetch details of type: {obj_type}")
|
||||||
|
return None
|
||||||
|
|
||||||
cls._clean_music_object(music_object, collections)
|
if post_process and music_object:
|
||||||
|
return build_new_object(music_object)
|
||||||
|
|
||||||
music_object.compile(merge_into=True)
|
|
||||||
return music_object
|
return music_object
|
||||||
|
|
||||||
|
def fetch_song(self, source: Source, stop_at_level: int = 1) -> Song:
|
||||||
|
return Song()
|
||||||
|
|
||||||
@classmethod
|
def fetch_album(self, source: Source, stop_at_level: int = 1) -> Album:
|
||||||
def _fetch_object_from_source(cls, source: Source,
|
return Album()
|
||||||
obj_type: Union[Type[Song], Type[Album], Type[Artist], Type[Label]],
|
|
||||||
stop_at_level: int = 1) -> Union[Song, Album, Artist, Label]:
|
|
||||||
if obj_type == Artist:
|
|
||||||
return cls._fetch_artist_from_source(source=source, stop_at_level=stop_at_level)
|
|
||||||
|
|
||||||
if obj_type == Song:
|
def fetch_artist(self, source: Source, stop_at_level: int = 1) -> Artist:
|
||||||
return cls._fetch_song_from_source(source=source, stop_at_level=stop_at_level)
|
return Artist()
|
||||||
|
|
||||||
if obj_type == Album:
|
def fetch_label(self, source: Source, stop_at_level: int = 1) -> Label:
|
||||||
return cls._fetch_album_from_source(source=source, stop_at_level=stop_at_level)
|
return Label()
|
||||||
|
|
||||||
if obj_type == Label:
|
def download(self, music_object: DatabaseObject, genre: str, download_all: bool = False, process_metadata_anyway: bool = False) -> DownloadResult:
|
||||||
return cls._fetch_label_from_source(source=source, stop_at_level=stop_at_level)
|
naming_dict: NamingDict = NamingDict({"genre": genre})
|
||||||
|
|
||||||
@classmethod
|
def fill_naming_objects(naming_music_object: DatabaseObject):
|
||||||
def _clean_music_object(cls, music_object: Union[Label, Album, Artist, Song],
|
nonlocal naming_dict
|
||||||
collections: Dict[Union[Type[Song], Type[Album], Type[Artist], Type[Label]], Collection]):
|
|
||||||
if type(music_object) == Label:
|
|
||||||
return cls._clean_label(label=music_object, collections=collections)
|
|
||||||
if type(music_object) == Artist:
|
|
||||||
return cls._clean_artist(artist=music_object, collections=collections)
|
|
||||||
if type(music_object) == Album:
|
|
||||||
return cls._clean_album(album=music_object, collections=collections)
|
|
||||||
if type(music_object) == Song:
|
|
||||||
return cls._clean_song(song=music_object, collections=collections)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _clean_collection(cls, collection: Collection,
|
|
||||||
collection_dict: Dict[Union[Type[Song], Type[Album], Type[Artist], Type[Label]], Collection]):
|
|
||||||
if collection.element_type not in collection_dict:
|
|
||||||
return
|
|
||||||
|
|
||||||
for i, element in enumerate(collection):
|
|
||||||
r = collection_dict[collection.element_type].append(element, merge_into_existing=True)
|
|
||||||
collection[i] = r.current_element
|
|
||||||
|
|
||||||
if not r.was_the_same:
|
|
||||||
cls._clean_music_object(r.current_element, collection_dict)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _clean_label(cls, label: Label,
|
|
||||||
collections: Dict[Union[Type[Song], Type[Album], Type[Artist], Type[Label]], Collection]):
|
|
||||||
cls._clean_collection(label.current_artist_collection, collections)
|
|
||||||
cls._clean_collection(label.album_collection, collections)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _clean_artist(cls, artist: Artist,
|
|
||||||
collections: Dict[Union[Type[Song], Type[Album], Type[Artist], Type[Label]], Collection]):
|
|
||||||
cls._clean_collection(artist.main_album_collection, collections)
|
|
||||||
cls._clean_collection(artist.feature_song_collection, collections)
|
|
||||||
cls._clean_collection(artist.label_collection, collections)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _clean_album(cls, album: Album,
|
|
||||||
collections: Dict[Union[Type[Song], Type[Album], Type[Artist], Type[Label]], Collection]):
|
|
||||||
cls._clean_collection(album.label_collection, collections)
|
|
||||||
cls._clean_collection(album.song_collection, collections)
|
|
||||||
cls._clean_collection(album.artist_collection, collections)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _clean_song(cls, song: Song,
|
|
||||||
collections: Dict[Union[Type[Song], Type[Album], Type[Artist], Type[Label]], Collection]):
|
|
||||||
cls._clean_collection(song.album_collection, collections)
|
|
||||||
cls._clean_collection(song.feature_artist_collection, collections)
|
|
||||||
cls._clean_collection(song.main_artist_collection, collections)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def download(
|
|
||||||
cls,
|
|
||||||
music_object: Union[Song, Album, Artist, Label],
|
|
||||||
download_features: bool = True,
|
|
||||||
default_target: DefaultTarget = None,
|
|
||||||
genre: str = None,
|
|
||||||
override_existing: bool = False,
|
|
||||||
create_target_on_demand: bool = True,
|
|
||||||
download_all: bool = False,
|
|
||||||
exclude_album_type: Set[AlbumType] = shared.ALBUM_TYPE_BLACKLIST
|
|
||||||
) -> DownloadResult:
|
|
||||||
"""
|
|
||||||
|
|
||||||
:param genre: The downloader will download to THIS folder (set the value of default_target.genre to genre)
|
|
||||||
:param music_object:
|
|
||||||
:param download_features:
|
|
||||||
:param default_target:
|
|
||||||
:param override_existing:
|
|
||||||
:param create_target_on_demand:
|
|
||||||
:param download_all:
|
|
||||||
:param exclude_album_type:
|
|
||||||
:return total downloads, failed_downloads:
|
|
||||||
"""
|
|
||||||
if default_target is None:
|
|
||||||
default_target = DefaultTarget()
|
|
||||||
|
|
||||||
if download_all:
|
|
||||||
exclude_album_type: Set[AlbumType] = set()
|
|
||||||
elif exclude_album_type is None:
|
|
||||||
exclude_album_type = {
|
|
||||||
AlbumType.COMPILATION_ALBUM,
|
|
||||||
AlbumType.LIVE_ALBUM,
|
|
||||||
AlbumType.MIXTAPE
|
|
||||||
}
|
|
||||||
|
|
||||||
if type(music_object) is Song:
|
|
||||||
return cls.download_song(
|
|
||||||
music_object,
|
|
||||||
override_existing=override_existing,
|
|
||||||
create_target_on_demand=create_target_on_demand,
|
|
||||||
genre=genre
|
|
||||||
)
|
|
||||||
if type(music_object) is Album:
|
|
||||||
return cls.download_album(
|
|
||||||
music_object,
|
|
||||||
default_target=default_target,
|
|
||||||
override_existing=override_existing,
|
|
||||||
genre=genre
|
|
||||||
)
|
|
||||||
if type(music_object) is Artist:
|
|
||||||
return cls.download_artist(
|
|
||||||
music_object,
|
|
||||||
default_target=default_target,
|
|
||||||
download_features=download_features,
|
|
||||||
exclude_album_type=exclude_album_type,
|
|
||||||
genre=genre
|
|
||||||
)
|
|
||||||
if type(music_object) is Label:
|
|
||||||
return cls.download_label(
|
|
||||||
music_object,
|
|
||||||
download_features=download_features,
|
|
||||||
default_target=default_target,
|
|
||||||
exclude_album_type=exclude_album_type,
|
|
||||||
genre=genre
|
|
||||||
)
|
|
||||||
|
|
||||||
return DownloadResult(error_message=f"{type(music_object)} can't be downloaded.")
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def download_label(
|
|
||||||
cls,
|
|
||||||
label: Label,
|
|
||||||
exclude_album_type: Set[AlbumType],
|
|
||||||
download_features: bool = True,
|
|
||||||
override_existing: bool = False,
|
|
||||||
default_target: DefaultTarget = None,
|
|
||||||
genre: str = None
|
|
||||||
) -> DownloadResult:
|
|
||||||
|
|
||||||
default_target = DefaultTarget() if default_target is None else copy(default_target)
|
|
||||||
default_target.label_object(label)
|
|
||||||
|
|
||||||
r = DownloadResult()
|
|
||||||
|
|
||||||
cls.fetch_details(label)
|
|
||||||
for artist in label.current_artist_collection:
|
|
||||||
r.merge(cls.download_artist(
|
|
||||||
artist,
|
|
||||||
download_features=download_features,
|
|
||||||
override_existing=override_existing,
|
|
||||||
default_target=default_target,
|
|
||||||
exclude_album_type=exclude_album_type,
|
|
||||||
genre=genre
|
|
||||||
))
|
|
||||||
|
|
||||||
album: Album
|
|
||||||
for album in label.album_collection:
|
|
||||||
if album.album_type == AlbumType.OTHER:
|
|
||||||
cls.fetch_details(album)
|
|
||||||
|
|
||||||
if album.album_type in exclude_album_type:
|
|
||||||
cls.LOGGER.info(f"Skipping {album.option_string} due to the filter. ({album.album_type})")
|
|
||||||
continue
|
|
||||||
|
|
||||||
r.merge(cls.download_album(
|
for collection_name in naming_music_object.UPWARDS_COLLECTION_ATTRIBUTES:
|
||||||
album,
|
collection: Collection = getattr(naming_music_object, collection_name)
|
||||||
override_existing=override_existing,
|
|
||||||
default_target=default_target,
|
if collection.empty:
|
||||||
genre=genre
|
continue
|
||||||
))
|
|
||||||
|
dom_ordered_music_object: DatabaseObject = collection[0]
|
||||||
|
naming_dict.add_object(dom_ordered_music_object)
|
||||||
|
return fill_naming_objects(dom_ordered_music_object)
|
||||||
|
|
||||||
|
fill_naming_objects(music_object)
|
||||||
|
|
||||||
|
return self._download(music_object, naming_dict, download_all, process_metadata_anyway=process_metadata_anyway)
|
||||||
|
|
||||||
return r
|
|
||||||
|
|
||||||
@classmethod
|
def _download(self, music_object: DatabaseObject, naming_dict: NamingDict, download_all: bool = False, skip_details: bool = False, process_metadata_anyway: bool = False) -> DownloadResult:
|
||||||
def download_artist(
|
skip_next_details = skip_details
|
||||||
cls,
|
|
||||||
artist: Artist,
|
# Skips all releases, that are defined in shared.ALBUM_TYPE_BLACKLIST, if download_all is False
|
||||||
exclude_album_type: Set[AlbumType],
|
if isinstance(music_object, Album):
|
||||||
download_features: bool = True,
|
if self.NO_ADDITIONAL_DATA_FROM_SONG:
|
||||||
override_existing: bool = False,
|
skip_next_details = True
|
||||||
default_target: DefaultTarget = None,
|
|
||||||
genre: str = None
|
|
||||||
) -> DownloadResult:
|
|
||||||
|
|
||||||
default_target = DefaultTarget() if default_target is None else copy(default_target)
|
|
||||||
default_target.artist_object(artist)
|
|
||||||
|
|
||||||
r = DownloadResult()
|
|
||||||
|
|
||||||
cls.fetch_details(artist)
|
|
||||||
|
|
||||||
album: Album
|
|
||||||
for album in artist.main_album_collection:
|
|
||||||
if album.album_type in exclude_album_type:
|
|
||||||
cls.LOGGER.info(f"Skipping {album.option_string} due to the filter. ({album.album_type})")
|
|
||||||
continue
|
|
||||||
|
|
||||||
r.merge(cls.download_album(
|
if not download_all and music_object.album_type in shared.ALBUM_TYPE_BLACKLIST:
|
||||||
album,
|
return DownloadResult()
|
||||||
override_existing=override_existing,
|
|
||||||
default_target=default_target,
|
|
||||||
genre=genre
|
|
||||||
))
|
|
||||||
|
|
||||||
if download_features:
|
if not isinstance(music_object, Song) or not self.NO_ADDITIONAL_DATA_FROM_SONG:
|
||||||
for song in artist.feature_album.song_collection:
|
self.fetch_details(music_object=music_object, stop_at_level=2)
|
||||||
r.merge(cls.download_song(
|
|
||||||
song,
|
naming_dict.add_object(music_object)
|
||||||
override_existing=override_existing,
|
|
||||||
default_target=default_target,
|
|
||||||
genre=genre
|
|
||||||
))
|
|
||||||
|
|
||||||
return r
|
if isinstance(music_object, Song):
|
||||||
|
return self._download_song(music_object, naming_dict, process_metadata_anyway=process_metadata_anyway)
|
||||||
|
|
||||||
@classmethod
|
download_result: DownloadResult = DownloadResult()
|
||||||
def download_album(
|
|
||||||
cls,
|
|
||||||
album: Album,
|
|
||||||
override_existing: bool = False,
|
|
||||||
default_target: DefaultTarget = None,
|
|
||||||
genre: str = None
|
|
||||||
) -> DownloadResult:
|
|
||||||
|
|
||||||
default_target = DefaultTarget() if default_target is None else copy(default_target)
|
for collection_name in music_object.DOWNWARDS_COLLECTION_ATTRIBUTES:
|
||||||
default_target.album_object(album)
|
collection: Collection = getattr(music_object, collection_name)
|
||||||
|
|
||||||
r = DownloadResult()
|
sub_ordered_music_object: DatabaseObject
|
||||||
|
for sub_ordered_music_object in collection:
|
||||||
|
download_result.merge(self._download(sub_ordered_music_object, naming_dict.copy(), download_all, skip_details=skip_next_details, process_metadata_anyway=process_metadata_anyway))
|
||||||
|
|
||||||
cls.fetch_details(album)
|
return download_result
|
||||||
|
|
||||||
album.update_tracksort()
|
def _download_song(self, song: Song, naming_dict: NamingDict, process_metadata_anyway: bool = False):
|
||||||
|
if "genre" not in naming_dict and song.genre is not None:
|
||||||
|
naming_dict["genre"] = song.genre
|
||||||
|
|
||||||
cls.LOGGER.info(f"downloading album: {album.title}")
|
if song.genre is None:
|
||||||
for song in album.song_collection:
|
song.genre = naming_dict["genre"]
|
||||||
r.merge(cls.download_song(
|
|
||||||
song,
|
|
||||||
override_existing=override_existing,
|
|
||||||
default_target=default_target,
|
|
||||||
genre=genre
|
|
||||||
))
|
|
||||||
|
|
||||||
return r
|
path_parts = Formatter().parse(DOWNLOAD_PATH)
|
||||||
|
file_parts = Formatter().parse(DOWNLOAD_FILE)
|
||||||
|
new_target = Target(
|
||||||
|
relative_to_music_dir=True,
|
||||||
|
path=DOWNLOAD_PATH.format(**{part[1]: naming_dict[part[1]] for part in path_parts}),
|
||||||
|
file=DOWNLOAD_FILE.format(**{part[1]: naming_dict[part[1]] for part in file_parts})
|
||||||
|
)
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def download_song(
|
|
||||||
cls,
|
|
||||||
song: Song,
|
|
||||||
override_existing: bool = False,
|
|
||||||
create_target_on_demand: bool = True,
|
|
||||||
default_target: DefaultTarget = None,
|
|
||||||
genre: str = None
|
|
||||||
) -> DownloadResult:
|
|
||||||
cls.LOGGER.debug(f"Setting genre of {song.option_string} to {genre}")
|
|
||||||
song.genre = genre
|
|
||||||
|
|
||||||
default_target = DefaultTarget() if default_target is None else copy(default_target)
|
|
||||||
default_target.song_object(song)
|
|
||||||
|
|
||||||
cls.fetch_details(song)
|
|
||||||
|
|
||||||
if song.target_collection.empty:
|
if song.target_collection.empty:
|
||||||
if create_target_on_demand and not song.main_artist_collection.empty and not song.album_collection.empty:
|
song.target_collection.append(new_target)
|
||||||
song.target_collection.append(default_target.target)
|
|
||||||
else:
|
|
||||||
return DownloadResult(error_message=f"No target exists for {song.title}, but create_target_on_demand is False.")
|
|
||||||
|
|
||||||
target: Target
|
sources = song.source_collection.get_sources_from_page(self.SOURCE_TYPE)
|
||||||
if any(target.exists for target in song.target_collection) and not override_existing:
|
|
||||||
r = DownloadResult(total=1, fail=0)
|
|
||||||
|
|
||||||
existing_target: Target
|
|
||||||
for existing_target in song.target_collection:
|
|
||||||
if existing_target.exists:
|
|
||||||
r.merge(cls._post_process_targets(song=song, temp_target=existing_target))
|
|
||||||
break
|
|
||||||
|
|
||||||
return r
|
|
||||||
|
|
||||||
sources = song.source_collection.get_sources_from_page(cls.SOURCE_TYPE)
|
|
||||||
if len(sources) == 0:
|
if len(sources) == 0:
|
||||||
return DownloadResult(error_message=f"No source found for {song.title} as {cls.__name__}.")
|
return DownloadResult(error_message=f"No source found for {song.title} as {self.__class__.__name__}.")
|
||||||
|
|
||||||
temp_target: Target = Target(
|
temp_target: Target = Target(
|
||||||
path=shared.TEMP_DIR,
|
path=shared.TEMP_DIR,
|
||||||
file=str(random.randint(0, 999999))
|
file=str(random.randint(0, 999999))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
r = DownloadResult(1)
|
||||||
|
|
||||||
r = cls._download_song_to_targets(source=sources[0], target=temp_target, desc=song.title)
|
found_on_disc = False
|
||||||
|
target: Target
|
||||||
|
for target in song.target_collection:
|
||||||
|
if target.exists:
|
||||||
|
if process_metadata_anyway:
|
||||||
|
target.copy_content(temp_target)
|
||||||
|
found_on_disc = True
|
||||||
|
|
||||||
|
r.found_on_disk += 1
|
||||||
|
r.add_target(target)
|
||||||
|
|
||||||
|
if found_on_disc and not process_metadata_anyway:
|
||||||
|
self.LOGGER.info(f"{song.option_string} already exists, thus not downloading again.")
|
||||||
|
return r
|
||||||
|
|
||||||
|
source = sources[0]
|
||||||
|
|
||||||
|
if not found_on_disc:
|
||||||
|
r = self.download_song_to_target(source=source, target=temp_target, desc=song.title)
|
||||||
|
|
||||||
|
|
||||||
if not r.is_fatal_error:
|
if not r.is_fatal_error:
|
||||||
r.merge(cls._post_process_targets(song, temp_target))
|
r.merge(self._post_process_targets(song, temp_target, [] if found_on_disc else self.get_skip_intervals(song, source)))
|
||||||
|
|
||||||
return r
|
return r
|
||||||
|
|
||||||
@classmethod
|
def _post_process_targets(self, song: Song, temp_target: Target, interval_list: List) -> DownloadResult:
|
||||||
def _post_process_targets(cls, song: Song, temp_target: Target) -> DownloadResult:
|
correct_codec(temp_target, interval_list=interval_list)
|
||||||
correct_codec(temp_target)
|
|
||||||
|
self.post_process_hook(song, temp_target)
|
||||||
|
|
||||||
write_metadata_to_target(song.metadata, temp_target)
|
write_metadata_to_target(song.metadata, temp_target)
|
||||||
|
|
||||||
r = DownloadResult()
|
r = DownloadResult()
|
||||||
@ -552,29 +443,17 @@ class Page:
|
|||||||
if temp_target is not target:
|
if temp_target is not target:
|
||||||
temp_target.copy_content(target)
|
temp_target.copy_content(target)
|
||||||
r.add_target(target)
|
r.add_target(target)
|
||||||
|
|
||||||
|
temp_target.delete()
|
||||||
|
r.sponsor_segments += len(interval_list)
|
||||||
|
|
||||||
return r
|
return r
|
||||||
|
|
||||||
@classmethod
|
def get_skip_intervals(self, song: Song, source: Source) -> List[Tuple[float, float]]:
|
||||||
def _fetch_song_from_source(cls, source: Source, stop_at_level: int = 1) -> Song:
|
return []
|
||||||
return Song()
|
|
||||||
|
def post_process_hook(self, song: Song, temp_target: Target, **kwargs):
|
||||||
@classmethod
|
pass
|
||||||
def _fetch_album_from_source(cls, source: Source, stop_at_level: int = 1) -> Album:
|
|
||||||
return Album()
|
def download_song_to_target(self, source: Source, target: Target, desc: str = None) -> DownloadResult:
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _fetch_artist_from_source(cls, source: Source, stop_at_level: int = 1) -> Artist:
|
|
||||||
return Artist()
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _fetch_label_from_source(cls, source: Source, stop_at_level: int = 1) -> Label:
|
|
||||||
return Label()
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _get_type_of_url(cls, url: str) -> Optional[Union[Type[Song], Type[Album], Type[Artist], Type[Label]]]:
|
|
||||||
return None
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _download_song_to_targets(cls, source: Source, target: Target, desc: str = None) -> DownloadResult:
|
|
||||||
return DownloadResult()
|
return DownloadResult()
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
from . import search
|
|
||||||
from . import download
|
|
||||||
|
|
||||||
Download = download.Download
|
|
||||||
Search = search.Search
|
|
@ -1,45 +0,0 @@
|
|||||||
from typing import Optional, Tuple, Type, Set, Union, List
|
|
||||||
|
|
||||||
from . import page_attributes
|
|
||||||
from ..abstract import Page
|
|
||||||
from ...objects import Song, Album, Artist, Label, Source
|
|
||||||
|
|
||||||
MusicObject = Union[Song, Album, Artist, Label]
|
|
||||||
|
|
||||||
|
|
||||||
class Download:
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
pages: Tuple[Type[Page]] = page_attributes.ALL_PAGES,
|
|
||||||
exclude_pages: Set[Type[Page]] = set(),
|
|
||||||
exclude_shady: bool = False,
|
|
||||||
) -> None:
|
|
||||||
_page_list: List[Type[Page]] = []
|
|
||||||
_audio_page_list: List[Type[Page]] = []
|
|
||||||
|
|
||||||
for page in pages:
|
|
||||||
if exclude_shady and page in page_attributes.SHADY_PAGES:
|
|
||||||
continue
|
|
||||||
if page in exclude_pages:
|
|
||||||
continue
|
|
||||||
|
|
||||||
_page_list.append(page)
|
|
||||||
|
|
||||||
if page in page_attributes.AUDIO_PAGES:
|
|
||||||
_audio_page_list.append(page)
|
|
||||||
|
|
||||||
self.pages: Tuple[Type[Page]] = tuple(_page_list)
|
|
||||||
self.audio_pages: Tuple[Type[Page]] = tuple(_audio_page_list)
|
|
||||||
|
|
||||||
def fetch_details(self, music_object: MusicObject) -> MusicObject:
|
|
||||||
for page in self.pages:
|
|
||||||
page.fetch_details(music_object=music_object)
|
|
||||||
return music_object
|
|
||||||
|
|
||||||
def fetch_source(self, source: Source) -> Optional[MusicObject]:
|
|
||||||
source_page = page_attributes.SOURCE_PAGE_MAP[source.page_enum]
|
|
||||||
|
|
||||||
if source_page not in self.pages:
|
|
||||||
return
|
|
||||||
|
|
||||||
return source_page.fetch_object_from_source(source)
|
|
@ -1,100 +0,0 @@
|
|||||||
from collections import defaultdict
|
|
||||||
from typing import Tuple, List, Dict, Type
|
|
||||||
|
|
||||||
from . import page_attributes
|
|
||||||
from ..abstract import Page
|
|
||||||
from ...objects import Options, DatabaseObject, Source
|
|
||||||
|
|
||||||
|
|
||||||
class MultiPageOptions:
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
max_displayed_options: int = 10,
|
|
||||||
option_digits: int = 3,
|
|
||||||
derived_from: DatabaseObject = None
|
|
||||||
) -> None:
|
|
||||||
self.max_displayed_options = max_displayed_options
|
|
||||||
self.option_digits: int = option_digits
|
|
||||||
|
|
||||||
self._length = 0
|
|
||||||
self._current_option_dict: Dict[Type[Page], Options] = defaultdict(lambda: Options())
|
|
||||||
|
|
||||||
self._derive_from = derived_from
|
|
||||||
|
|
||||||
def __getitem__(self, key: Type[Page]):
|
|
||||||
return self._current_option_dict[key]
|
|
||||||
|
|
||||||
def __setitem__(self, key: Type[Page], value: Options):
|
|
||||||
self._current_option_dict[key] = value
|
|
||||||
|
|
||||||
self._length = 0
|
|
||||||
for key in self._current_option_dict:
|
|
||||||
self._length += 1
|
|
||||||
|
|
||||||
def __len__(self) -> int:
|
|
||||||
return self._length
|
|
||||||
|
|
||||||
def get_page_str(self, page: Type[Page]) -> str:
|
|
||||||
page_name_fill = "-"
|
|
||||||
max_page_len = 21
|
|
||||||
|
|
||||||
return f"({page_attributes.PAGE_NAME_MAP[page]}) ------------------------{page.__name__:{page_name_fill}<{max_page_len}}------------"
|
|
||||||
|
|
||||||
def string_from_all_pages(self) -> str:
|
|
||||||
if self._length == 1:
|
|
||||||
for key in self._current_option_dict:
|
|
||||||
return self.string_from_single_page(key)
|
|
||||||
|
|
||||||
lines: List[str] = []
|
|
||||||
|
|
||||||
j = 0
|
|
||||||
for page, options in self._current_option_dict.items():
|
|
||||||
lines.append(self.get_page_str(page))
|
|
||||||
|
|
||||||
i = -1
|
|
||||||
|
|
||||||
option_obj: DatabaseObject
|
|
||||||
for i, option_obj in enumerate(options):
|
|
||||||
if i >= self.max_displayed_options:
|
|
||||||
lines.append("...")
|
|
||||||
break
|
|
||||||
|
|
||||||
lines.append(f"{j + i:0{self.option_digits}} {option_obj.option_string}")
|
|
||||||
|
|
||||||
j += i + 1
|
|
||||||
|
|
||||||
return "\n".join(lines)
|
|
||||||
|
|
||||||
def choose_from_all_pages(self, index: int) -> Tuple[DatabaseObject, Type[Page]]:
|
|
||||||
if self._length == 1:
|
|
||||||
for key in self._current_option_dict:
|
|
||||||
return self.choose_from_single_page(key, index), key
|
|
||||||
|
|
||||||
sum_of_length = 0
|
|
||||||
for page, options in self._current_option_dict.items():
|
|
||||||
option_len = min((len(options), self.max_displayed_options))
|
|
||||||
|
|
||||||
index_of_list = index - sum_of_length
|
|
||||||
|
|
||||||
if index_of_list < option_len:
|
|
||||||
return options[index_of_list], page
|
|
||||||
|
|
||||||
sum_of_length += option_len
|
|
||||||
|
|
||||||
raise IndexError("index is out of range")
|
|
||||||
|
|
||||||
def string_from_single_page(self, page: Type[Page]) -> str:
|
|
||||||
lines: List[str] = [self.get_page_str(page)]
|
|
||||||
|
|
||||||
option_obj: DatabaseObject
|
|
||||||
for i, option_obj in enumerate(self._current_option_dict[page]):
|
|
||||||
lines.append(f"{i:0{self.option_digits}} {option_obj.option_string}")
|
|
||||||
|
|
||||||
return "\n".join(lines)
|
|
||||||
|
|
||||||
def choose_from_single_page(self, page: Type[Page], index: int) -> DatabaseObject:
|
|
||||||
return self._current_option_dict[page][index]
|
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
|
||||||
return self.string_from_all_pages()
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
|||||||
from typing import Tuple, Type, Dict
|
|
||||||
|
|
||||||
from ...utils.enums.source import SourcePages
|
|
||||||
from ..abstract import Page
|
|
||||||
from ..encyclopaedia_metallum import EncyclopaediaMetallum
|
|
||||||
from ..musify import Musify
|
|
||||||
|
|
||||||
NAME_PAGE_MAP: Dict[str, Type[Page]] = dict()
|
|
||||||
PAGE_NAME_MAP: Dict[Type[Page], str] = dict()
|
|
||||||
SOURCE_PAGE_MAP: Dict[SourcePages, Type[Page]] = dict()
|
|
||||||
|
|
||||||
ALL_PAGES: Tuple[Type[Page]] = (
|
|
||||||
EncyclopaediaMetallum,
|
|
||||||
Musify
|
|
||||||
)
|
|
||||||
|
|
||||||
AUDIO_PAGES: Tuple[Type[Page]] = (
|
|
||||||
Musify,
|
|
||||||
)
|
|
||||||
|
|
||||||
SHADY_PAGES: Tuple[Type[Page]] = (
|
|
||||||
Musify,
|
|
||||||
)
|
|
||||||
|
|
||||||
# this needs to be case insensitive
|
|
||||||
SHORTHANDS = ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z')
|
|
||||||
for i, page in enumerate(ALL_PAGES):
|
|
||||||
NAME_PAGE_MAP[page.__name__.lower()] = page
|
|
||||||
NAME_PAGE_MAP[SHORTHANDS[i].lower()] = page
|
|
||||||
|
|
||||||
PAGE_NAME_MAP[page] = SHORTHANDS[i]
|
|
||||||
|
|
||||||
SOURCE_PAGE_MAP[page.SOURCE_TYPE] = page
|
|
||||||
|
|
@ -1,145 +0,0 @@
|
|||||||
from typing import Tuple, List, Set, Type, Optional
|
|
||||||
|
|
||||||
from . import page_attributes
|
|
||||||
from .download import Download
|
|
||||||
from .multiple_options import MultiPageOptions
|
|
||||||
from ..abstract import Page
|
|
||||||
from ..support_classes.download_result import DownloadResult
|
|
||||||
from ...objects import DatabaseObject, Source
|
|
||||||
|
|
||||||
|
|
||||||
class Search(Download):
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
pages: Tuple[Type[Page]] = page_attributes.ALL_PAGES,
|
|
||||||
exclude_pages: Set[Type[Page]] = set(),
|
|
||||||
exclude_shady: bool = False,
|
|
||||||
max_displayed_options: int = 10,
|
|
||||||
option_digits: int = 3,
|
|
||||||
) -> None:
|
|
||||||
super().__init__(
|
|
||||||
pages=pages,
|
|
||||||
exclude_pages=exclude_pages,
|
|
||||||
exclude_shady=exclude_shady
|
|
||||||
)
|
|
||||||
|
|
||||||
self.max_displayed_options = max_displayed_options
|
|
||||||
self.option_digits: int = option_digits
|
|
||||||
|
|
||||||
self._option_history: List[MultiPageOptions] = []
|
|
||||||
|
|
||||||
self._current_option: MultiPageOptions = self.next_options()
|
|
||||||
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
return self._current_option.__repr__()
|
|
||||||
|
|
||||||
def next_options(self, derive_from: DatabaseObject = None) -> MultiPageOptions:
|
|
||||||
mpo = MultiPageOptions(
|
|
||||||
max_displayed_options=self.max_displayed_options,
|
|
||||||
option_digits=self.option_digits,
|
|
||||||
derived_from=derive_from
|
|
||||||
)
|
|
||||||
|
|
||||||
self._option_history.append(mpo)
|
|
||||||
self._current_option = mpo
|
|
||||||
|
|
||||||
return mpo
|
|
||||||
|
|
||||||
def _previous_options(self) -> MultiPageOptions:
|
|
||||||
self._option_history.pop()
|
|
||||||
self._current_option = self._option_history[-1]
|
|
||||||
|
|
||||||
return self._option_history[-1]
|
|
||||||
|
|
||||||
def search(self, query: str):
|
|
||||||
"""
|
|
||||||
# The Query
|
|
||||||
|
|
||||||
You can define a new parameter with "#",
|
|
||||||
the letter behind it defines the *type* of parameter,
|
|
||||||
followed by a space "#a Psychonaut 4 #r Tired, Numb and #t Drop by Drop"
|
|
||||||
if no # is in the query it gets treated as "unspecified query"
|
|
||||||
|
|
||||||
doesn't set derived_from thus,
|
|
||||||
can't download right after
|
|
||||||
"""
|
|
||||||
|
|
||||||
for page in self.pages:
|
|
||||||
self._current_option[page] = page.search_by_query(query=query)
|
|
||||||
|
|
||||||
def choose_page(self, page: Type[Page]):
|
|
||||||
"""
|
|
||||||
doesn't set derived_from thus,
|
|
||||||
can't download right after
|
|
||||||
"""
|
|
||||||
|
|
||||||
if page not in page_attributes.ALL_PAGES:
|
|
||||||
raise ValueError(f"Page \"{page.__name__}\" does not exist in page_attributes.ALL_PAGES")
|
|
||||||
|
|
||||||
prev_mpo = self._current_option
|
|
||||||
mpo = self.next_options()
|
|
||||||
|
|
||||||
mpo[page] = prev_mpo[page]
|
|
||||||
|
|
||||||
def get_page_from_query(self, query: str) -> Optional[Type[Page]]:
|
|
||||||
"""
|
|
||||||
query can be for example:
|
|
||||||
"a" or "EncyclopaediaMetallum" to choose a page
|
|
||||||
"""
|
|
||||||
|
|
||||||
page = page_attributes.NAME_PAGE_MAP.get(query.lower().strip())
|
|
||||||
|
|
||||||
if page in self.pages:
|
|
||||||
return page
|
|
||||||
|
|
||||||
def _get_page_from_source(self, source: Source) -> Optional[Type[Page]]:
|
|
||||||
return page_attributes.SOURCE_PAGE_MAP.get(source.page_enum)
|
|
||||||
|
|
||||||
def choose_index(self, index: int):
|
|
||||||
db_object, page = self._current_option.choose_from_all_pages(index=index)
|
|
||||||
|
|
||||||
music_object = self.fetch_details(db_object)
|
|
||||||
mpo = self.next_options(derive_from=music_object)
|
|
||||||
|
|
||||||
mpo[page] = music_object.options
|
|
||||||
|
|
||||||
def goto_previous(self):
|
|
||||||
try:
|
|
||||||
self._previous_options()
|
|
||||||
except IndexError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def search_url(self, url: str) -> bool:
|
|
||||||
"""
|
|
||||||
sets derived_from, thus
|
|
||||||
can download directly after
|
|
||||||
"""
|
|
||||||
|
|
||||||
source = Source.match_url(url=url)
|
|
||||||
if source is None:
|
|
||||||
return False
|
|
||||||
|
|
||||||
new_object = self.fetch_source(source)
|
|
||||||
if new_object is None:
|
|
||||||
return False
|
|
||||||
|
|
||||||
page = page_attributes.SOURCE_PAGE_MAP[source.page_enum]
|
|
||||||
mpo = self.next_options(derive_from=new_object)
|
|
||||||
mpo[page] = new_object.options
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
def download_chosen(self, genre: str = None, download_all: bool = False, **kwargs) -> DownloadResult:
|
|
||||||
if self._current_option._derive_from is None:
|
|
||||||
return DownloadResult(error_message="No option has been chosen yet.")
|
|
||||||
|
|
||||||
source: Source
|
|
||||||
for source in self._current_option._derive_from.source_collection:
|
|
||||||
page = self._get_page_from_source(source=source)
|
|
||||||
|
|
||||||
if page in self.audio_pages:
|
|
||||||
return page.download(music_object=self._current_option._derive_from, genre=genre, download_all=download_all, **kwargs)
|
|
||||||
|
|
||||||
return DownloadResult(error_message=f"Didn't find a source for {self._current_option._derive_from.option_string}.")
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user