From b15002b131c98b206aa2e76a30d3f4d37de82e03 Mon Sep 17 00:00:00 2001 From: Hellow <74311245+HeIIow2@users.noreply.github.com> Date: Fri, 23 Jun 2023 13:31:49 +0200 Subject: [PATCH] updated documentation --- README.md | 163 +++++---------------------------------- contribute.md | 31 +++++--- documentation/objects.md | 64 ++++++++++++++- 3 files changed, 104 insertions(+), 154 deletions(-) diff --git a/README.md b/README.md index 8bccd6d..0588553 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,20 @@ -# Music Kraken +# Music Kraken music kraken logo - [Music Kraken](#music-kraken) - [Installation](#installation) - [Dependencies](#dependencies) - - [Notes for Python 3.9](#notes-for-python-39) - [Notes for WSL](#notes-for-wsl) - [Quick-Guide](#quick-guide) - [CONTRIBUTE](#contribute) - [Matrix Space](#matrix-space) + - [TODO till the next release](#todo-till-the-next-release) - [Programming Interface / Use as Library](#programming-interface--use-as-library) - [Quick Overview](#quick-overview) - [Data Model](#data-model) - [Data Objects](#data-objects) - [Creation](#creation) - - [Appending and Merging data](#appending-and-merging-data) --- @@ -38,14 +37,8 @@ music-kraken You will need to install these two programms. -- ffmpeg - pandoc -### Notes for Python 3.9 - -Unfortunately I use features that newly git introduced in [Python 3.10](https://docs.python.org/3/library/types.html#types.UnionType). -So unfortunately you **CAN'T** run this programm with python 3.9. [#10][i10] - ### Notes for WSL If you choose to run it in WSL, make sure ` ~/.local/bin` is added to your `$PATH` [#2][i2] @@ -59,6 +52,7 @@ When it drops you into the **shell** 2 main things are important: 1. You search with `s: ` 2. You choose an option with just the index number of the option 3. You download with `d: `, where the options are comma seperated +4. You support me by making a pr, or starring my repo. Trust me it WILL make sense, once you see it. @@ -67,13 +61,13 @@ Trust me it WILL make sense, once you see it. The syntax for the query is like really simple. ``` -> #a +> s: #a searches for the artist -> #a #r +> s: #a #r searches for the release (album) by the artist -> #r Me #t +> s: #r Me #t searches for the track from the release ``` @@ -87,7 +81,7 @@ LOVE YALL *(except nazis ;-;)* I am happy about every pull request. To contribute look [here](contribute.md). -## Matrix Space +## Matrix Space @@ -95,11 +89,19 @@ I decided against creating a discord server, due to piracy communities get often **Click [this link](https://matrix.to/#/#music-kraken:matrix.org) _([https://matrix.to/#/#music-kraken:matrix.org](https://matrix.to/#/#music-kraken:matrix.org))_ to join.** +## TODO till the next release + +> These Points will most likely be in the changelogs. + +- [x] Update the Documentation of the new cli. +- [ ] Migrate away from pandoc, to a more lightweight alternative, that can be installed over PiPY. +- [ ] Update the Documentation of the internal structure. _(could be pushed back one release)_ + --- # Programming Interface / Use as Library -This application is $100\%$ centered around Data. Thus the most important thing for working with musik kraken is, to understand how I structured the data. +This application is $100\%$ centered around Data. Thus, the most important thing for working with musik kraken is, to understand how I structured the data. ## Quick Overview @@ -110,7 +112,7 @@ This application is $100\%$ centered around Data. Thus the most important thing ```mermaid --- -title: Quick Overview +title: Quick Overview (outdated) --- sequenceDiagram @@ -245,139 +247,14 @@ Every Service models Data a bit different, and projecting a one-to-many relation ### Creation ```python -# importing the libraries I build on -from music_kraken import objects - -import pycountry - - -song = objects.Song( - genre="HS Core", - title="Vein Deep in the Solution", - length=666, - isrc="US-S1Z-99-00001", - tracksort=2, - target=[ - objects.Target(file="song.mp3", path="example") - ], - lyrics_list=[ - objects.Lyrics(text="these are some depressive lyrics", language="en"), - objects.Lyrics(text="Dies sind depressive Lyrics", language="de") - ], - source_list=[ - objects.Source(objects.SourcePages.YOUTUBE, "https://youtu.be/dfnsdajlhkjhsd"), - objects.Source(objects.SourcePages.MUSIFY, "https://ln.topdf.de/Music-Kraken/") - ], - album_list=[ - objects.Album( - title="One Final Action", - date=objects.ID3Timestamp(year=1986, month=3, day=1), - language=pycountry.languages.get(alpha_2="en"), - label_list=[ - objects.Label(name="an album label") - ], - source_list=[ - objects.Source(objects.SourcePages.ENCYCLOPAEDIA_METALLUM, "https://www.metal-archives.com/albums/I%27m_in_a_Coffin/One_Final_Action/207614") - ] - ), - ], - main_artist_list=[ - objects.Artist( - name="I'm in a coffin", - source_list=[ - objects.Source( - objects.SourcePages.ENCYCLOPAEDIA_METALLUM, - "https://www.metal-archives.com/bands/I%27m_in_a_Coffin/127727" - ) - ] - ), - objects.Artist(name="some_split_artist") - ], - feature_artist_list=[ - objects.Artist( - name="Ruffiction", - label_list=[ - objects.Label(name="Ruffiction Productions") - ] - ) - ], -) - -print(song.option_string) -for album in song.album_collection: - print(album.option_string) -for artist in song.main_artist_collection: - print(artist.option_string) +# needs to be added ``` -If you just want to start implementing, then just use the code example, I don't care. -For those who don't want any bugs and use it as intended *(which is recommended, cuz I am only one person so there are defs bugs)* continue reading. +If you just want to start implementing, then just use the code example I provided, I don't care. +For those who don't want any bugs and use it as intended *(which is recommended, cuz I am only one person so there are defs bugs)* continue reading, and read the whole documentation, which may exist in the future xD -## Appending and Merging data - -If you want to append for example a Song to an Album, you obviously need to check beforehand if the Song already exists in the Album, and if so, you need to merge their data in one Song object, to not loose any Information. - -This is how I solve this problem: - -```mermaid ---- -title: "Collection.append(music_object: MusicObject)" ---- -flowchart TD - exist(""" -Check if music_object already exists. -
-Gets all indexing values with music_object.indexing_values. -If any returned value exists in Collection._attribute_to_object_map, -the music_object exists - """) - - subgraph merge["Merging"] - - _merge("""merges the passed in object in the already - existing whith existing.merge(new)""") - - _map("""In case a new source or something simmilar - has been addet, it maps the existing object again. - """) - - _merge --> _map - - end - - subgraph add["Adding"] - - __map("""map the values from music_object.indexing_values - to Collection._attribute_to_object_map by writing - those values in the map as keys, and the class I wanna add as values. - """) - - _add("""add the new music object to _data""") - - __map --> _add - - end - - exist-->|"if it doesn't exist"|add --> return - exist-->|"if already exists"|merge --> return -``` - -This is Implemented in [music_kraken.objects.Collection.append()](documentation/objects.md#collection). The merging which is mentioned in the flowchart is explained in the documentation of [DatabaseObject.merge()](documentation/objects.md#databaseobjectmerge). - -The indexing values are defined in the superclass [DatabaseObject](documentation/objects.md#databaseobject) and get implemented for each Object seperately. I will just give as example its implementation for the `Song` class: - -```python -@property -def indexing_values(self) -> List[Tuple[str, object]]: - return [ - ('id', self.id), - ('title', self.unified_title), - ('barcode', self.barcode), - *[('url', source.url) for source in self.source_collection] - ] -``` [i10]: https://github.com/HeIIow2/music-downloader/issues/10 [i2]: https://github.com/HeIIow2/music-downloader/issues/2 diff --git a/contribute.md b/contribute.md index 34ba719..ecfba9b 100644 --- a/contribute.md +++ b/contribute.md @@ -1,18 +1,31 @@ -> IMPORTANT NOTE: heavily outdated sorryyyyy - # How to contribute I am always happy about pull requests. -If something is missing, like attributes for an object feel free to either add it youreself or open an issue :3 +If something is missing, like attributes for an object feel free to either add it yourself or open an issue, if you choose to just change it, beware that something may have to change. :3 -If you wanna contribute, this is for you. Some options will follow: +So here is a List of what you can do: -## Add an audio/metadata source +1. [implement a new page like e.g. Soundcloud](#add-a-new-page) -The audio and Metadata Sources all inherint the class `Page` in [abstract.py](src/music_kraken/pages/abstract.py) +## Add a new Page -You can create a subclass of this class for for example youtube or musify or whatever. -I documented the function it should have in the docstrings of [abstract.py](src/music_kraken/pages/abstract.py). If you are unsure about how it works, look at either the doccumentation *(will get more detailed soon)* or an [example](src/music_kraken/pages/encyclopaedia_metallum.py). For trying you're class you can make a skript simmilar to [this one](src/metal_archives.py). Make sure it is in the same directory though. +The audio and Metadata Sources all inherit from the class `Page`, which can be found in [abstract.py](src/music_kraken/pages/abstract.py). -> Read the part of the documentation, I already have written. +You can create a subclass of this class for, for example `YouTube` or `Musify` or whatever. + +1. Just create a new file with the name `your_page.py` +in the [page module](src/music_kraken/pages). +2. Then you can simply copy the contents of the [preset](src/music_kraken/pages/preset.py) over to your file. +3. All the functions you need to implement, can be found in the [preset](src/music_kraken/pages/preset.py). + +### Important notes + +- There is no need to check if you for example added a source of a song twice. I do much post-processing to the data you scrape in the page classes. You can see what exactly I do in [abstract.py](src/music_kraken/pages/abstract.py). +- Use the connection class how it is laid out in the preset to make the request. This will take care of retrying requests, rotating proxies, consistent use of tor (if selected in the config). You have: + - `connection.get()` + - `connection.post()` +- Look at the code of the pages I already have implemented. Namely: + - [musify.club](src/music_kraken/pages/musify.py) _(heavily making use of web scraping)_ + - [YouTube](src/music_kraken/pages/youtube.py) _(using both invidious and piped)_ + - [Metal Archives](src/music_kraken/pages/youtube.py) diff --git a/documentation/objects.md b/documentation/objects.md index dd8de45..3891898 100644 --- a/documentation/objects.md +++ b/documentation/objects.md @@ -56,9 +56,69 @@ Function | Explanation `sort()` | takes the same arguments than `list.sort`, and does the same `__iter__()` | allows you to use collections e.g. a for loop -## Options +### Appending and Merging data -## Metadata +If you want to append for example a Song to an Album, you obviously need to check beforehand if the Song already exists in the Album, and if so, you need to merge their data in one Song object, to not loose any Information. + +This is how I solve this problem: + +```mermaid +--- +title: "Collection.append(music_object: MusicObject)" +--- +flowchart TD + exist(""" +Check if music_object already exists. +
+Gets all indexing values with music_object.indexing_values. +If any returned value exists in Collection._attribute_to_object_map, +the music_object exists + """) + + subgraph merge["Merging"] + + _merge("""merges the passed in object in the already + existing whith existing.merge(new)""") + + _map("""In case a new source or something simmilar + has been addet, it maps the existing object again. + """) + + _merge --> _map + + end + + subgraph add["Adding"] + + __map("""map the values from music_object.indexing_values + to Collection._attribute_to_object_map by writing + those values in the map as keys, and the class I wanna add as values. + """) + + _add("""add the new music object to _data""") + + __map --> _add + + end + + exist-->|"if it doesn't exist"|add --> return + exist-->|"if already exists"|merge --> return +``` + +This is Implemented in [music_kraken.objects.Collection.append()](documentation/objects.md#collection). The merging which is mentioned in the flowchart is explained in the documentation of [DatabaseObject.merge()](documentation/objects.md#databaseobjectmerge). + +The indexing values are defined in the superclass [DatabaseObject](documentation/objects.md#databaseobject) and get implemented for each Object seperately. I will just give as example its implementation for the `Song` class: + +```python +@property +def indexing_values(self) -> List[Tuple[str, object]]: + return [ + ('id', self.id), + ('title', self.unified_title), + ('barcode', self.barcode), + *[('url', source.url) for source in self.source_collection] + ] +``` ## Song