Skip to content
Snippets Groups Projects
serializers.py 6.54 KiB
Newer Older
  • Learn to ignore specific revisions
  • import collections
    
    from django.db.models import functions, Count
    
    from rest_framework import serializers
    
    
    from funkwhale_api.music import models as music_models
    
    
    def get_artist_data(artist_values):
        return {
            'id': artist_values['id'],
            'name': artist_values['name'],
            'albumCount': artist_values['_albums_count']
        }
    
    
    
    class GetArtistsSerializer(serializers.Serializer):
        def to_representation(self, queryset):
            payload = {
                'ignoredArticles': '',
                'index': []
            }
    
            queryset = queryset.with_albums_count()
    
            queryset = queryset.order_by(functions.Lower('name'))
            values = queryset.values('id', '_albums_count', 'name')
    
            first_letter_mapping = collections.defaultdict(list)
            for artist in values:
                first_letter_mapping[artist['name'][0].upper()].append(artist)
    
            for letter, artists in sorted(first_letter_mapping.items()):
                letter_data = {
                    'name': letter,
                    'artist': [
    
                        for v in artists
                    ]
                }
                payload['index'].append(letter_data)
            return payload
    
    
    class GetArtistSerializer(serializers.Serializer):
        def to_representation(self, artist):
            albums = artist.albums.prefetch_related('tracks__files')
            payload = {
                'id': artist.pk,
                'name': artist.name,
                'albumCount': len(albums),
                'album': [],
            }
            for album in albums:
                album_data = {
                    'id': album.id,
                    'artistId': artist.id,
                    'name': album.title,
                    'artist': artist.name,
                    'created': album.creation_date,
    
                    'songCount': len(album.tracks.all()),
    
                if album.cover:
                    album_data['coverArt'] = 'al-{}'.format(album.id)
    
                if album.release_date:
                    album_data['year'] = album.release_date.year
                payload['album'].append(album_data)
            return payload
    
    
    
    def get_track_data(album, track, tf):
        data = {
            'id': track.pk,
            'isDir': 'false',
            'title': track.title,
            'album': album.title,
            'artist': album.artist.name,
    
            'track': track.position or 1,
    
            'contentType': tf.mimetype,
            'suffix': tf.extension or '',
            'duration': tf.duration or 0,
            'created': track.creation_date,
            'albumId': album.pk,
            'artistId': album.artist.pk,
            'type': 'music',
        }
    
        if track.album.cover:
            data['coverArt'] = 'al-{}'.format(track.album.id)
    
        if tf.bitrate:
            data['bitrate'] = int(tf.bitrate/1000)
        if tf.size:
            data['size'] = tf.size
    
        if album.release_date:
            data['year'] = album.release_date.year
        return data
    
    
    def get_album2_data(album):
        payload = {
            'id': album.id,
            'artistId': album.artist.id,
            'name': album.title,
            'artist': album.artist.name,
            'created': album.creation_date,
        }
    
        if album.cover:
            payload['coverArt'] = 'al-{}'.format(album.id)
    
    
        try:
            payload['songCount'] = album._tracks_count
        except AttributeError:
            payload['songCount'] = len(album.tracks.prefetch_related('files'))
        return payload
    
    
    def get_song_list_data(tracks):
        songs = []
        for track in tracks:
            try:
                tf = [tf for tf in track.files.all()][0]
            except IndexError:
                continue
            track_data = get_track_data(track.album, track, tf)
            songs.append(track_data)
        return songs
    
    
    
    class GetAlbumSerializer(serializers.Serializer):
        def to_representation(self, album):
    
            tracks = album.tracks.prefetch_related('files').select_related('album')
            payload = get_album2_data(album)
    
            if album.release_date:
                payload['year'] = album.release_date.year
    
    
            payload['song'] = get_song_list_data(tracks)
    
    
    
    def get_starred_tracks_data(favorites):
        by_track_id = {
            f.track_id: f
            for f in favorites
        }
        tracks = music_models.Track.objects.filter(
            pk__in=by_track_id.keys()
        ).select_related('album__artist').prefetch_related('files')
        tracks = tracks.order_by('-creation_date')
        data = []
        for t in tracks:
            try:
                tf = [tf for tf in t.files.all()][0]
            except IndexError:
                continue
            td = get_track_data(t.album, t, tf)
            td['starred'] = by_track_id[t.pk].creation_date
            data.append(td)
        return data
    
    
    def get_album_list2_data(albums):
        return [
            get_album2_data(a)
            for a in albums
        ]
    
    
    
    def get_playlist_data(playlist):
        return {
            'id': playlist.pk,
            'name': playlist.name,
            'owner': playlist.user.username,
            'public': 'false',
            'songCount': playlist._tracks_count,
            'duration': 0,
            'created': playlist.creation_date,
        }
    
    
    def get_playlist_detail_data(playlist):
        data = get_playlist_data(playlist)
        qs = playlist.playlist_tracks.select_related(
            'track__album__artist'
        ).prefetch_related('track__files').order_by('index')
        data['entry'] = []
        for plt in qs:
            try:
                tf = [tf for tf in plt.track.files.all()][0]
            except IndexError:
                continue
            td = get_track_data(plt.track.album, plt.track, tf)
            data['entry'].append(td)
        return data
    
    
    
    def get_music_directory_data(artist):
        tracks = artist.tracks.select_related('album').prefetch_related('files')
        data = {
            'id': artist.pk,
            'parent': 1,
            'name': artist.name,
            'child': []
        }
        for track in tracks:
            try:
                tf = [tf for tf in track.files.all()][0]
            except IndexError:
                continue
            album = track.album
            td = {
                'id': track.pk,
                'isDir': 'false',
                'title': track.title,
                'album': album.title,
                'artist': artist.name,
                'track': track.position or 1,
                'year': track.album.release_date.year if track.album.release_date else 0,
                'contentType': tf.mimetype,
                'suffix': tf.extension or '',
                'duration': tf.duration or 0,
                'created': track.creation_date,
                'albumId': album.pk,
                'artistId': artist.pk,
                'parent': artist.id,
                'type': 'music',
            }
    
            if tf.bitrate:
                td['bitrate'] = int(tf.bitrate/1000)
            if tf.size:
                td['size'] = tf.size
    
            data['child'].append(td)
        return data