added tags and tag update
This commit is contained in:
parent
2acbad120c
commit
1aee2feb16
21
main.py
21
main.py
@ -1,6 +1,27 @@
|
||||
from music import app
|
||||
from music.tasks.update_tag import update_tag as do_update_tag
|
||||
|
||||
app = app
|
||||
|
||||
|
||||
def update_tag(event, context):
|
||||
import base64
|
||||
import logging
|
||||
import json
|
||||
|
||||
logger = logging.getLogger('music')
|
||||
|
||||
if 'data' in event:
|
||||
body = json.loads(base64.b64decode(event['data']).decode('utf-8'))
|
||||
|
||||
if 'username' not in body or 'tag_id' not in body:
|
||||
logger.error('malformed body')
|
||||
return
|
||||
|
||||
do_update_tag(username=body["username"], tag_id=body["tag_id"])
|
||||
else:
|
||||
logger.error('no data in event')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(host='127.0.0.1', port=8080, debug=True)
|
||||
|
@ -9,6 +9,7 @@ from fmframework.net.network import Network as FmNetwork
|
||||
from music.db.user import DatabaseUser
|
||||
from music.model.user import User
|
||||
from music.model.playlist import Playlist, RecentsPlaylist, LastFMChartPlaylist, Sort
|
||||
from music.model.tag import Tag
|
||||
|
||||
db = firestore.Client()
|
||||
|
||||
@ -324,3 +325,98 @@ def delete_playlist(username: str, name: str) -> None:
|
||||
playlist.db_ref.delete()
|
||||
else:
|
||||
logger.error(f'playlist {name} not found for {username}')
|
||||
|
||||
|
||||
def get_user_tags(username: str) -> List[Tag]:
|
||||
logger.info(f'getting tags for {username}')
|
||||
|
||||
user = get_user(username)
|
||||
|
||||
if user:
|
||||
tag_refs = [i for i in user.db_ref.collection(u'tags').stream()]
|
||||
|
||||
return [parse_tag_reference(username=username, tag_snapshot=i) for i in tag_refs]
|
||||
else:
|
||||
logger.error(f'user {username} not found')
|
||||
|
||||
|
||||
def get_tag(username: str = None, tag_id: str = None) -> Optional[Tag]:
|
||||
logger.info(f'retrieving {tag_id} for {username}')
|
||||
|
||||
user = get_user(username)
|
||||
|
||||
if user:
|
||||
|
||||
tags = [i for i in user.db_ref.collection(u'tags').where(u'tag_id', u'==', tag_id).stream()]
|
||||
|
||||
if len(tags) == 0:
|
||||
logger.error(f'tag {tag_id} for {user} not found')
|
||||
return None
|
||||
if len(tags) > 1:
|
||||
logger.critical(f"multiple {tag_id}'s for {user} found")
|
||||
return None
|
||||
|
||||
return parse_tag_reference(username=username, tag_snapshot=tags[0])
|
||||
else:
|
||||
logger.error(f'user {username} not found')
|
||||
|
||||
|
||||
def parse_tag_reference(username, tag_ref=None, tag_snapshot=None) -> Tag:
|
||||
if tag_ref is None and tag_snapshot is None:
|
||||
raise ValueError('no tag object supplied')
|
||||
|
||||
if tag_ref is None:
|
||||
tag_ref = tag_snapshot.reference
|
||||
|
||||
if tag_snapshot is None:
|
||||
tag_snapshot = tag_ref.get()
|
||||
|
||||
tag_dict = tag_snapshot.to_dict()
|
||||
|
||||
return Tag(tag_id=tag_dict['tag_id'],
|
||||
name=tag_dict.get('name', 'n/a'),
|
||||
username=username,
|
||||
|
||||
db_ref=tag_ref,
|
||||
|
||||
tracks=tag_dict.get('tracks', []),
|
||||
albums=tag_dict.get('albums', []),
|
||||
artists=tag_dict.get('artists', []),
|
||||
|
||||
count=tag_dict.get('count', 0),
|
||||
proportion=tag_dict.get('proportion', 0.0),
|
||||
total_user_scrobbles=tag_dict.get('total_user_scrobbles', 0),
|
||||
|
||||
last_updated=tag_dict.get('last_updated'))
|
||||
|
||||
|
||||
def update_tag(username: str, tag_id: str, updates: dict) -> None:
|
||||
if len(updates) > 0:
|
||||
logger.debug(f'updating {tag_id} for {username}')
|
||||
|
||||
user = get_user(username)
|
||||
|
||||
tags = [i for i in user.db_ref.collection(u'tags').where(u'tag_id', u'==', tag_id).stream()]
|
||||
|
||||
if len(tags) == 0:
|
||||
logger.error(f'tag {tag_id} for {username} not found')
|
||||
return None
|
||||
if len(tags) > 1:
|
||||
logger.critical(f"multiple {tag_id}'s for {username} found")
|
||||
return None
|
||||
|
||||
tag = tags[0].reference
|
||||
tag.update(updates)
|
||||
else:
|
||||
logger.debug(f'nothing to update for {tag_id} for {username}')
|
||||
|
||||
|
||||
def delete_tag(username: str, tag_id: str) -> None:
|
||||
logger.info(f'deleting {tag_id} for {username}')
|
||||
|
||||
tag = get_tag(username=username, tag_id=tag_id)
|
||||
|
||||
if tag:
|
||||
tag.db_ref.delete()
|
||||
else:
|
||||
logger.error(f'playlist {tag_id} not found for {username}')
|
||||
|
128
music/model/tag.py
Normal file
128
music/model/tag.py
Normal file
@ -0,0 +1,128 @@
|
||||
from datetime import datetime
|
||||
import music.db.database as db
|
||||
|
||||
|
||||
class Tag:
|
||||
|
||||
def __init__(self,
|
||||
tag_id: str,
|
||||
name: str,
|
||||
username: str,
|
||||
|
||||
db_ref,
|
||||
|
||||
tracks,
|
||||
albums,
|
||||
artists,
|
||||
|
||||
count: int,
|
||||
proportion: float,
|
||||
total_user_scrobbles: int,
|
||||
|
||||
last_updated: datetime):
|
||||
self.tag_id = tag_id
|
||||
self._name = name
|
||||
self.username = username
|
||||
|
||||
self.db_ref = db_ref
|
||||
|
||||
self._tracks = tracks
|
||||
self._albums = albums
|
||||
self._artists = artists
|
||||
|
||||
self._count = count
|
||||
self._proportion = proportion
|
||||
self._total_user_scrobbles = total_user_scrobbles
|
||||
|
||||
self._last_updated = last_updated
|
||||
|
||||
def to_dict(self):
|
||||
return {
|
||||
'tag_id': self.tag_id,
|
||||
'name': self.name,
|
||||
'username': self.username,
|
||||
|
||||
'tracks': self.tracks,
|
||||
'albums': self.albums,
|
||||
'artists': self.artists,
|
||||
|
||||
'count': self.count,
|
||||
'proportion': self.proportion,
|
||||
|
||||
'last_updated': self.last_updated
|
||||
}
|
||||
|
||||
def update_database(self, updates):
|
||||
db.update_tag(username=self.username, tag_id=self.tag_id, updates=updates)
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return self._name
|
||||
|
||||
@name.setter
|
||||
def name(self, value):
|
||||
db.update_tag(username=self.username, tag_id=self.tag_id, updates={'name': value})
|
||||
self._name = value
|
||||
|
||||
@property
|
||||
def tracks(self):
|
||||
return self._tracks
|
||||
|
||||
@tracks.setter
|
||||
def tracks(self, value):
|
||||
db.update_tag(username=self.username, tag_id=self.tag_id, updates={'tracks': value})
|
||||
self._tracks = value
|
||||
|
||||
@property
|
||||
def albums(self):
|
||||
return self._albums
|
||||
|
||||
@albums.setter
|
||||
def albums(self, value):
|
||||
db.update_tag(username=self.username, tag_id=self.tag_id, updates={'albums': value})
|
||||
self._albums = value
|
||||
|
||||
@property
|
||||
def artists(self):
|
||||
return self._artists
|
||||
|
||||
@artists.setter
|
||||
def artists(self, value):
|
||||
db.update_tag(username=self.username, tag_id=self.tag_id, updates={'artists': value})
|
||||
self._artists = value
|
||||
|
||||
@property
|
||||
def count(self):
|
||||
return self._count
|
||||
|
||||
@count.setter
|
||||
def count(self, value):
|
||||
db.update_tag(username=self.username, tag_id=self.tag_id, updates={'count': value})
|
||||
self._count = value
|
||||
|
||||
@property
|
||||
def proportion(self):
|
||||
return self._proportion
|
||||
|
||||
@proportion.setter
|
||||
def proportion(self, value):
|
||||
db.update_tag(username=self.username, tag_id=self.tag_id, updates={'proportion': value})
|
||||
self._proportion = value
|
||||
|
||||
@property
|
||||
def total_user_scrobbles(self):
|
||||
return self._total_user_scrobbles
|
||||
|
||||
@total_user_scrobbles.setter
|
||||
def total_user_scrobbles(self, value):
|
||||
db.update_tag(username=self.username, tag_id=self.tag_id, updates={'total_user_scrobbles': value})
|
||||
self._total_user_scrobbles = value
|
||||
|
||||
@property
|
||||
def last_updated(self):
|
||||
return self._last_updated
|
||||
|
||||
@last_updated.setter
|
||||
def last_updated(self, value):
|
||||
db.update_tag(username=self.username, tag_id=self.tag_id, updates={'last_updated': value})
|
||||
self._last_updated = value
|
72
music/tasks/update_tag.py
Normal file
72
music/tasks/update_tag.py
Normal file
@ -0,0 +1,72 @@
|
||||
import logging
|
||||
from datetime import datetime
|
||||
|
||||
import music.db.database as database
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def update_tag(username, tag_id):
|
||||
logger.info(f'updating {username} / {tag_id}')
|
||||
|
||||
tag = database.get_tag(username=username, tag_id=tag_id)
|
||||
|
||||
if tag is None:
|
||||
logger.error(f'{tag_id} for {username} not found')
|
||||
return
|
||||
|
||||
user = database.get_user(username)
|
||||
|
||||
if user.lastfm_username is None or len(user.lastfm_username) == 0:
|
||||
logger.error(f'{username} has no last.fm username')
|
||||
return
|
||||
|
||||
net = database.get_authed_lastfm_network(username=username)
|
||||
|
||||
tag_count = 0
|
||||
user_scrobbles = net.get_user_scrobble_count()
|
||||
|
||||
artists = []
|
||||
for artist in tag.artists:
|
||||
net_artist = net.get_artist(name=artist['name'])
|
||||
|
||||
if net_artist is not None:
|
||||
artist['count'] = net_artist.user_scrobbles
|
||||
tag_count += net_artist.user_scrobbles
|
||||
|
||||
artists.append(artist)
|
||||
|
||||
albums = []
|
||||
for album in tag.albums:
|
||||
net_album = net.get_album(name=album['name'], artist=album['artist'])
|
||||
|
||||
if net_album is not None:
|
||||
album['count'] = net_album.user_scrobbles
|
||||
|
||||
if album['artist'].lower() not in [i.lower() for i in [j['name'] for j in artists]]:
|
||||
tag_count += net_album.user_scrobbles
|
||||
|
||||
albums.append(album)
|
||||
|
||||
tracks = []
|
||||
for track in tag.tracks:
|
||||
net_track = net.get_track(name=track['name'], artist=track['artist'])
|
||||
|
||||
if net_track is not None:
|
||||
track['count'] = net_track.user_scrobbles
|
||||
|
||||
if track['artist'].lower() not in [i.lower() for i in [j['name'] for j in artists]]:
|
||||
tag_count += net_track.user_scrobbles
|
||||
|
||||
tracks.append(track)
|
||||
|
||||
tag.update_database({
|
||||
'tracks': tracks,
|
||||
'albums': albums,
|
||||
'artists': artists,
|
||||
|
||||
'total_user_scrobbles': user_scrobbles,
|
||||
'count': tag_count,
|
||||
'proportion': (tag_count / user_scrobbles) * 100,
|
||||
'last_updated': datetime.utcnow()
|
||||
})
|
Loading…
Reference in New Issue
Block a user