idk i added a bunch of stuff like a month ago
This commit is contained in:
parent
95c4dc96f6
commit
851d5ebb35
@ -19,8 +19,16 @@ class Album:
|
|||||||
def from_row(cls, row: tuple[int, str, str | None, str | None]) -> Self:
|
def from_row(cls, row: tuple[int, str, str | None, str | None]) -> Self:
|
||||||
return cls(*row)
|
return cls(*row)
|
||||||
|
|
||||||
|
@dataclass
|
||||||
class Artist:
|
class Artist:
|
||||||
pass
|
id: int
|
||||||
|
name: str
|
||||||
|
mbid: str | None = None
|
||||||
|
icon_url: str | None = None
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_row(cls, row: tuple[int, str, str | None, str | None]) -> Self:
|
||||||
|
return cls(*row)
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class Song:
|
class Song:
|
||||||
@ -64,7 +72,7 @@ class Connect:
|
|||||||
def _load_query(path: str) -> str:
|
def _load_query(path: str) -> str:
|
||||||
return open(path, 'r').read()
|
return open(path, 'r').read()
|
||||||
|
|
||||||
def execute_query(query_path: str, qargs: list | tuple) -> list:
|
def execute_query(query_path: str, *args) -> list:
|
||||||
if not os.path.exists(query_path):
|
if not os.path.exists(query_path):
|
||||||
logging.error(f'Query Path "{query_path}" does not exist')
|
logging.error(f'Query Path "{query_path}" does not exist')
|
||||||
return []
|
return []
|
||||||
@ -72,26 +80,40 @@ def execute_query(query_path: str, qargs: list | tuple) -> list:
|
|||||||
query: str = _load_query(query_path)
|
query: str = _load_query(query_path)
|
||||||
|
|
||||||
with Connect(DATABASE) as (conn, cur):
|
with Connect(DATABASE) as (conn, cur):
|
||||||
cur.execute(query, qargs)
|
cur.execute(query, [arg for arg in args])
|
||||||
|
|
||||||
return cur.fetchall()
|
return cur.fetchall()
|
||||||
|
|
||||||
|
def execute_insertion_query(query_path: str, *args) -> int | None:
|
||||||
|
if not os.path.exists(query_path):
|
||||||
|
logging.error(f'Query Path "{query_path}" does not exist')
|
||||||
|
return None
|
||||||
|
|
||||||
|
query: str = _load_query(query_path)
|
||||||
|
|
||||||
|
with Connect(DATABASE) as (conn, cur):
|
||||||
|
cur.execute(query, [arg for arg in args])
|
||||||
|
|
||||||
|
return cur.lastrowid
|
||||||
|
|
||||||
def insert_listen_event(song_id: int, user_id: int, date: int | datetime.datetime, time: int):
|
def insert_listen_event(song_id: int, user_id: int, date: int | datetime.datetime, time: int):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def search_song_mbid(mbid: str) -> Song | None:
|
def search_song_mbid(mbid: str) -> Song | None:
|
||||||
results: list = execute_query('sql/get_song_by_mbid.sql', (mbid,))
|
results: list = execute_query('sql/get_song_by_mbid.sql', mbid)
|
||||||
|
|
||||||
if results:
|
if results:
|
||||||
return Song.from_rows(results)
|
return Song.from_rows(results)
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def search_song_name(name: str) -> list[Song] | None:
|
def search_song_name(name: str) -> list[Song]:
|
||||||
results: list = execute_query('sql/get_song_by_name.sql', (name,))
|
name = '%' + name + '%'
|
||||||
|
|
||||||
|
results: list = execute_query('sql/get_song_by_name.sql', name)
|
||||||
|
|
||||||
if not results:
|
if not results:
|
||||||
return None
|
return []
|
||||||
|
|
||||||
songs: list[Song] = []
|
songs: list[Song] = []
|
||||||
|
|
||||||
@ -113,7 +135,7 @@ def search_song_name(name: str) -> list[Song] | None:
|
|||||||
return songs
|
return songs
|
||||||
|
|
||||||
def search_song_by_id(id: int) -> Song | None:
|
def search_song_by_id(id: int) -> Song | None:
|
||||||
results: list = execute_query('sql/get_song_by_id.sql', (id,))
|
results: list = execute_query('sql/get_song_by_id.sql', id)
|
||||||
|
|
||||||
if results:
|
if results:
|
||||||
return Song.from_rows(results)
|
return Song.from_rows(results)
|
||||||
@ -121,42 +143,61 @@ def search_song_by_id(id: int) -> Song | None:
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
def insert_song(id: int, name: str, length: int, album_id: int, artist_id: int, mbid: str | None = None) -> None:
|
def insert_song(id: int, name: str, length: int, album_id: int, artist_id: int, mbid: str | None = None) -> None:
|
||||||
execute_query('sql/insert_song.sql', (id, name, length, album_id, artist_id, mbid))
|
execute_query('sql/insert_song.sql', id, name, length, album_id, artist_id, mbid)
|
||||||
|
|
||||||
def get_last_song_id() -> int:
|
def get_last_song_id() -> int:
|
||||||
return execute_query('sql/get_last_song_id.sql', [])[0][0]
|
return execute_query('sql/get_last_song_id.sql')[0][0]
|
||||||
|
|
||||||
def search_album_by_name(name: str) -> list[Album] | None:
|
def search_album_by_name(name: str) -> list[Album]:
|
||||||
results: list = execute_query('sql/get_album_by_name.sql', (name,))
|
name = '%' + name + '%'
|
||||||
|
|
||||||
|
results: list = execute_query('sql/get_album_by_name.sql', name)
|
||||||
|
|
||||||
if not results:
|
if not results:
|
||||||
return None
|
return []
|
||||||
|
|
||||||
albums: list[Album] = []
|
albums: list[Album] = []
|
||||||
for row in results:
|
for row in results:
|
||||||
albums.append(Album.from_row(row))
|
albums.append(Album.from_row(row))
|
||||||
|
|
||||||
|
return albums
|
||||||
|
|
||||||
def search_album_by_mbid(mbid: str) -> Album | None:
|
def search_album_by_mbid(mbid: str) -> Album | None:
|
||||||
pass
|
results: list = execute_query('sql/get_album_by_mbid.sql', mbid)
|
||||||
|
|
||||||
|
return Album.from_row(results[0]) if results else None
|
||||||
|
|
||||||
def search_album_by_id(id: int) -> Album | None:
|
def search_album_by_id(id: int) -> Album | None:
|
||||||
pass
|
results: list = execute_query('sql/get_album_by_id.sql', id)
|
||||||
|
|
||||||
def insert_album(name: str, mbid: str | None, cover_art_url: str | None) -> None:
|
return Album.from_row(results[0]) if results else None
|
||||||
pass
|
|
||||||
|
|
||||||
def search_artist_by_name(name: str) -> list[Artist] | None:
|
def insert_album(name: str, mbid: str | None = None, cover_art_url: str | None = None) -> Album:
|
||||||
pass
|
return search_album_by_id(execute_insertion_query('sql/insert_album.sql', name, mbid, cover_art_url))
|
||||||
|
|
||||||
|
def search_artist_by_name(name: str) -> list[Artist]:
|
||||||
|
name = '%' + name + '%'
|
||||||
|
|
||||||
|
results: list = execute_query('sql/get_artist_by_name.sql', name)
|
||||||
|
|
||||||
|
if not results:
|
||||||
|
return []
|
||||||
|
|
||||||
|
artists: list[Artist] = []
|
||||||
|
for row in results:
|
||||||
|
artists.append(Artist.from_row(row))
|
||||||
|
|
||||||
|
return artists
|
||||||
|
|
||||||
def search_artist_by_mbid(mbid: str) -> Artist | None:
|
def search_artist_by_mbid(mbid: str) -> Artist | None:
|
||||||
pass
|
results: list = execute_query('sql/get_artist_by_mbid.sql', mbid)
|
||||||
|
|
||||||
|
return Artist.from_row(results[0]) if results else None
|
||||||
|
|
||||||
def search_artist_by_id(id: int) -> Artist | None:
|
def search_artist_by_id(id: int) -> Artist | None:
|
||||||
pass
|
results: list = execute_query('sql/get_artist_by_id.sql', id)
|
||||||
|
|
||||||
|
return Artist.from_row(results[0]) if results else None
|
||||||
|
|
||||||
def insert_artist(name: str, mbid: str | None = None, icon_url: str | None = None) -> None:
|
def insert_artist(name: str, mbid: str | None = None, icon_url: str | None = None) -> None:
|
||||||
pass
|
return search_artist_by_id(execute_insertion_query('sql/insert_artist.sql', name, mbid, icon_url))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
4908
listen-brain-request.json
Normal file
4908
listen-brain-request.json
Normal file
File diff suppressed because it is too large
Load Diff
35
main.py
35
main.py
@ -1,9 +1,12 @@
|
|||||||
|
|
||||||
import time
|
import time
|
||||||
import json
|
import json
|
||||||
import configparser
|
import configparser
|
||||||
|
|
||||||
import SubSonic
|
import SubSonic
|
||||||
|
import ListenBrainz
|
||||||
|
import MusicDatabase
|
||||||
|
|
||||||
|
import scrobble
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
config = configparser.ConfigParser()
|
config = configparser.ConfigParser()
|
||||||
@ -17,17 +20,35 @@ def main():
|
|||||||
|
|
||||||
now_playing = conn.getNowPlaying()
|
now_playing = conn.getNowPlaying()
|
||||||
|
|
||||||
print(json.dumps(now_playing, indent=4))
|
# print(json.dumps(now_playing, indent=4))
|
||||||
|
|
||||||
# album_id = now_playing['nowPlaying']['entry'][0]['albumId']
|
|
||||||
|
track_id = now_playing['nowPlaying']['entry'][0]['id']
|
||||||
# album_info = conn.getAlbum(album_id)
|
track_mbid = now_playing['nowPlaying']['entry'][0]['musicBrainzId']
|
||||||
|
track_name = now_playing['nowPlaying']['entry'][0]['title']
|
||||||
|
album_id = now_playing['nowPlaying']['entry'][0]['albumId']
|
||||||
|
|
||||||
|
album_info = conn.getAlbum(album_id)
|
||||||
|
album_mbid = album_info['album']['musicBrainzId']
|
||||||
|
album_name = album_info['album']['name']
|
||||||
|
|
||||||
# print(json.dumps(album_info, indent=4))
|
# print(json.dumps(album_info, indent=4))
|
||||||
|
artist_id = now_playing['nowPlaying']['entry'][0]['artistId']
|
||||||
|
|
||||||
artist_info = conn.getArtist(now_playing['nowPlaying']['entry'][0]['artistId'], raw_json=True)
|
artist_info = conn.getArtist(artist_id, raw_json=True)
|
||||||
|
artist_mbid = artist_info['artist']['musicBrainzId']
|
||||||
|
artist_name = artist_info['artist']['name']
|
||||||
|
|
||||||
print(json.dumps(artist_info, indent=4))
|
# print(json.dumps(artist_info, indent=4))
|
||||||
|
|
||||||
|
print(f'{track_name=} {album_name=} {artist_name=}')
|
||||||
|
|
||||||
|
dummy_scrobble = ListenBrainz.ListenBrainzScrobble(artist_name, album_name, track_name)
|
||||||
|
|
||||||
|
listenBrainz_match = scrobble.get_mbid(dummy_scrobble)
|
||||||
|
print(listenBrainz_match)
|
||||||
|
print(album_mbid)
|
||||||
|
assert album_mbid == listenBrainz_match[1]
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|||||||
35
scrobble.py
35
scrobble.py
@ -6,6 +6,7 @@ import musicbrainzngs
|
|||||||
import flask
|
import flask
|
||||||
|
|
||||||
import ListenBrainz
|
import ListenBrainz
|
||||||
|
import MusicDatabase
|
||||||
|
|
||||||
logging.basicConfig(
|
logging.basicConfig(
|
||||||
format="%(levelname)s %(module)s::%(filename)s::%(funcName)s %(asctime)s - %(message)s",
|
format="%(levelname)s %(module)s::%(filename)s::%(funcName)s %(asctime)s - %(message)s",
|
||||||
@ -27,14 +28,42 @@ def get_mbid(scrobble: ListenBrainz.ListenBrainzScrobble) -> tuple[str, str, lis
|
|||||||
|
|
||||||
result = musicbrainzngs.search_recordings(f"{scrobble.track_name} {scrobble.release_name}", artist=scrobble.artist_name, **optional_args)
|
result = musicbrainzngs.search_recordings(f"{scrobble.track_name} {scrobble.release_name}", artist=scrobble.artist_name, **optional_args)
|
||||||
|
|
||||||
|
# logging.debug(json.dumps(result, indent=4))
|
||||||
|
with open('listen-brain-request.json', 'w') as file:
|
||||||
|
file.write(json.dumps(result, indent=4))
|
||||||
|
|
||||||
top_result: dict = result['recording-list'][0]
|
top_result: dict = result['recording-list'][0]
|
||||||
|
|
||||||
track_mbid: str = top_result['id']
|
# print(json.dumps(top_result, indent=4))
|
||||||
album_mbid: str = top_result['release-list'][0]['id']
|
|
||||||
artist_mbids: list[str] = [artist['artist']['id'] for artist in top_result['artist-credit']]
|
|
||||||
|
|
||||||
|
track_mbid: str = top_result['id']
|
||||||
|
track_name: str = top_result['title']
|
||||||
|
album_mbid: str = top_result['release-list'][0]['id']
|
||||||
|
album_name: str = top_result['release-list'][0]['title']
|
||||||
|
# print(json.dumps(top_result['']))
|
||||||
|
artist_mbids: list[str] = [artist['artist']['id'] for artist in top_result['artist-credit']]
|
||||||
|
artist_names: list[str] = [artist['name'] for artist in top_result['artist-credit']]
|
||||||
|
|
||||||
|
logging.debug(f'Matched scrobble with {track_name=} {album_name=} {artist_names=}')
|
||||||
return (track_mbid, album_mbid, artist_mbids)
|
return (track_mbid, album_mbid, artist_mbids)
|
||||||
|
|
||||||
|
def record_scrobble(scrobble: ListenBrainz.ListenBrainzScrobble) -> None:
|
||||||
|
track_mbid, album_mbid, artist_mbids = get_mbid(scrobble)
|
||||||
|
|
||||||
|
if not (album := MusicDatabase.search_album_by_mbid(album_mbid)):
|
||||||
|
album = MusicDatabase.insert_album(scrobble.release_name, album_mbid)
|
||||||
|
|
||||||
|
artists: list[MusicDatabase.Artist] = []
|
||||||
|
for artist_mbid in artist_mbids:
|
||||||
|
if not (artist := MusicDatabase.search_artist_by_mbid(artist_mbid)):
|
||||||
|
artists.append(MusicDatabase.insert_artist(scrobble.artist_name, artist_mbid))
|
||||||
|
|
||||||
|
if not (track := MusicDatabase.search_song_mbid(track_mbid)) and scrobble.duration_ms:
|
||||||
|
song_id: int = MusicDatabase.get_last_song_id() + 1
|
||||||
|
MusicDatabase.insert_song(song_id, scrobble.track_name, scrobble.duration_ms, album.id, artist.id, track_mbid)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# See https://listenbrainz.readthedocs.io/en/latest/users/json.html#json-doc
|
# See https://listenbrainz.readthedocs.io/en/latest/users/json.html#json-doc
|
||||||
@app.route('/1/submit-listens', methods=["POST"])
|
@app.route('/1/submit-listens', methods=["POST"])
|
||||||
def submit_listens():
|
def submit_listens():
|
||||||
|
|||||||
1
sql/get_album_by_id.sql
Normal file
1
sql/get_album_by_id.sql
Normal file
@ -0,0 +1 @@
|
|||||||
|
SELECT * FROM albums WHERE id = ?;
|
||||||
1
sql/get_album_by_mbid.sql
Normal file
1
sql/get_album_by_mbid.sql
Normal file
@ -0,0 +1 @@
|
|||||||
|
SELECT * FROM albums WHERE musicBrainzId = ?;
|
||||||
@ -1 +1 @@
|
|||||||
SELECT * FROM albums WHERE name = ?;
|
SELECT * FROM albums WHERE name LIKE ?;
|
||||||
1
sql/get_artist_by_id.sql
Normal file
1
sql/get_artist_by_id.sql
Normal file
@ -0,0 +1 @@
|
|||||||
|
SELECT * FROM artists WHERE id = ?;
|
||||||
1
sql/get_artist_by_mbid.sql
Normal file
1
sql/get_artist_by_mbid.sql
Normal file
@ -0,0 +1 @@
|
|||||||
|
SELECT * FROM artists WHERE musicBrainzId = ?;
|
||||||
1
sql/get_artist_by_name.sql
Normal file
1
sql/get_artist_by_name.sql
Normal file
@ -0,0 +1 @@
|
|||||||
|
SELECT * FROM artists WHERE name LIKE ?;
|
||||||
@ -1 +1 @@
|
|||||||
SELECT * FROM songs WHERE name = ? ORDER BY id ASC;
|
SELECT * FROM songs WHERE name LIKE ? ORDER BY id ASC;
|
||||||
@ -1 +1 @@
|
|||||||
INSERT INTO albums (id, name, musicBrainzId, cover_art_url) VALUES (?, ?, ?, ?);
|
INSERT INTO albums (name, musicBrainzId, cover_art_url) VALUES (?, ?, ?);
|
||||||
@ -1 +1 @@
|
|||||||
INSERT INTO artists (id, name, musicBrainzId, icon_url) VALUES (?, ?, ?, ?);
|
INSERT INTO artists (name, musicBrainzId, icon_url) VALUES (?, ?, ?);
|
||||||
Loading…
x
Reference in New Issue
Block a user