feat: implemented overview

Hazel 2024-05-07 10:36:28 +02:00
parent 7afaacf0e6
commit 727a7b639f

82
overview.md Normal file

@ -0,0 +1,82 @@
# Overview
Here are some basic concepts of the program.
## Data Model
Music metadata can be easily abstracted to a few main Entities with some relations between them. This enables the easy scraping and aggregation of the correct metadata for each Song. Those Entities are `Song`, `Album`, `Artist` and `Label`.
<details>
This is convenient because then I can just use for example one Artist, which adds its metadata shared and consistently to each of its song. This exactly was the reason why piracy was such a mess in the past. Metadata has a lot of redundancy, but the relational databases of streaming services don't. THIS is the main reason for this program, and in my opinion also the reason for the widespread adoption of streaming services.
</details>
### Relations
This is a diagram, showing the relations between the Entities. The objects that connect to the other object always has an attribute, containing a list of the other object. It has the name that can be seen on the lines in the diagram.
```mermaid
---
title: music kraken - data model
---
erDiagram
Song {}
Album {}
Artist {}
Label {}
Song ||--o{ Album : album_collection
Song ||--o{ Artist : main_artist_collection
Song ||--o{ Artist : feature_artist_collection
Album ||--o{ Song : song_collection
Album ||--o{ Artist : artist_collection
Album ||--o{ Label : label_collection
Artist ||--o{ Song : feature_song_collection
Artist ||--o{ Album : main_album_collection
Artist ||--o{ Label : label_collection
Label ||--o{ Album : album_collection
Label ||--o{ Artist : current_artist_collection
```
### Managing complex Relations
The issue those data object have is simple. If you for example add an `Artist` to `feature_artist_collection` of a `Song`, you also have to add the `Song` to the `feature_song_collection` of the `Artist`. This would get messy really quickly and defeating the purpose of having data objects instead of just a database or dictionary in the first place.
To solve those issues I spend to much time, and now those relations are managed completely automatically.
This is made possible by the two function `DataObject.merge(other)` and `Collection.append(other)`.
If two `DataObject`s are merged, the attributes will be copied to one with minimal data loss and both objects will refer to the same data. (change something in one object, it will be changed everywhere)
```python
from music_kraken.objects import Song
a = Song()
b = Song(title="test")
a.merge(b)
print(a.title) # test
a.title = "test2"
print(b.title) # test2
```
If the collection would append a `DataObject` to itself, but it already has a similar `DataObject` in it, it would just merge the two `DataObject`s.
```python
from music_kraken.objects import Song, Artist
a = Song(
title="test",
main_artist_collection=[
Artist(name="test")
]
)
a.main_artist_collection.append(Artist(name="test", lyrical_themes=["test"]))
print(a.main_artist_collection[0].lyrical_themes) # ["test"]
```