Exemple #1
0
    def getArtist(self, **kwargs):
        rest = SubsonicREST(kwargs)
        success, response = rest.check_login()
        if not success:
            return response

        artistId = kwargs.get('id')
        if artistId:
            artist = request.env['oomusic.artist'].browse([int(artistId)])
            if not artist.exists():
                return rest.make_error(code='70', message='Artist not found')
        else:
            return rest.make_error(
                code='10',
                message='Required int parameter "id" is not present')

        root = etree.Element('subsonic-response',
                             status='ok',
                             version=rest.version_server)
        xml_artist = rest.make_ArtistID3(artist)
        root.append(xml_artist)

        for album in artist.album_ids:
            xml_album = rest.make_AlbumID3(album)
            xml_artist.append(xml_album)

        return rest.make_response(root)
Exemple #2
0
    def getSimilarSongs2(self, **kwargs):
        rest = SubsonicREST(kwargs)
        success, response = rest.check_login()
        if not success:
            return response

        songId = kwargs.get('id')
        if songId:
            track = request.env['oomusic.track'].browse([int(songId)])
            if not track.exists():
                return rest.make_error(code='70', message='Song not found')
        else:
            return rest.make_error(
                code='10',
                message='Required int parameter "id" is not present')

        count = int(kwargs.get('count', 50))
        tag_name = kwargs.get('tag_name', 'similarSongs2')

        root = etree.Element('subsonic-response',
                             status='ok',
                             version=rest.version_server)
        xml_song_info = rest.make_SimilarSongs2(track,
                                                count=count,
                                                tag_name=tag_name)
        root.append(xml_song_info)

        return rest.make_response(root)
    def getCoverArt(self, **kwargs):
        rest = SubsonicREST(kwargs)
        success, response = rest.check_login()
        if not success:
            return response

        folderId = kwargs.get('id')
        if folderId:
            try:
                if 'al-' in folderId:
                    folder = request.env['oomusic.album'].browse(
                        [int(folderId.split('-')[-1])])
                else:
                    folder = request.env['oomusic.folder'].browse(
                        [int(folderId.split('-')[-1])])
                if not folder.exists():
                    return rest.make_error(code='70',
                                           message='Folder not found')
            except:
                folder = request.env['oomusic.folder']
        else:
            return rest.make_error(
                code='10',
                message='Required int parameter "id" is not present')

        image = folder.image_medium or 'R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs='
        image_stream = StringIO.StringIO(image.decode('base64'))
        image_ext = '.' + (imghdr.what(image_stream) or 'png')
        return http.send_file(image_stream, filename=folderId + image_ext)
Exemple #4
0
    def getArtists(self, **kwargs):
        rest = SubsonicREST(kwargs)
        success, response = rest.check_login()
        if not success:
            return response

        root = etree.Element('subsonic-response',
                             status='ok',
                             version=rest.version_server)
        xml_artists = rest.make_ArtistsID3()
        root.append(xml_artists)

        musicFolderId = kwargs.get('musicFolderId')
        if musicFolderId:
            artists = request.env['oomusic.track'].search([
                ('folder_id', 'child_of', int(musicFolderId))
            ]).mapped('artist_id')
        else:
            artists = request.env['oomusic.artist'].search([])

        # Build indexes
        indexes_dict = rest.build_dict_indexes_artists(artists)

        # List of artists
        for k, v in sorted(indexes_dict.iteritems()):
            xml_index = rest.make_IndexID3(k)
            xml_artists.append(xml_index)
            for artist in v:
                xml_artist = rest.make_ArtistID3(artist)
                xml_index.append(xml_artist)

        return rest.make_response(root)
Exemple #5
0
    def deletePlaylist(self, **kwargs):
        rest = SubsonicREST(kwargs)
        success, response = rest.check_login()
        if not success:
            return response

        PlaylistObj = request.env['oomusic.playlist']

        playlistId = kwargs.get('id')
        if playlistId:
            playlist = PlaylistObj.browse([int(playlistId)])
            if not playlist.exists():
                return rest.make_error(code='70', message='Playlist not found')
        else:
            return rest.make_error(
                code='10',
                message='Required int parameter "id" is not present')

        playlist.unlink()

        root = etree.Element('subsonic-response',
                             status='ok',
                             version=rest.version_server)

        return rest.make_response(root)
    def unstar(self, **kwargs):
        rest = SubsonicREST(kwargs)
        success, response = rest.check_login()
        if not success:
            return response

        trackId = kwargs.get('id')
        if trackId:
            track = request.env['oomusic.track'].browse([int(trackId)])
            if track.exists():
                track.write({'star': '0'})
            else:
                folder = request.env['oomusic.folder'].browse([int(trackId)])
                if folder.exists():
                    folder.write({'star': '1'})

        albumId = kwargs.get('albumId')
        if albumId:
            album = request.env['oomusic.album'].browse([int(albumId)])
            if album.exists():
                album.write({'star': '0'})

        artistId = kwargs.get('artistId')
        if artistId:
            artist = request.env['oomusic.artist'].browse([int(artistId)])
            if artist.exists():
                artist.write({'star': '0'})

        root = etree.Element('subsonic-response', status='ok', version=rest.version_server)

        return rest.make_response(root)
Exemple #7
0
    def getMusicDirectory(self, **kwargs):
        rest = SubsonicREST(kwargs)
        success, response = rest.check_login()
        if not success:
            return response

        folderId = kwargs.get('id')
        if folderId:
            folder = request.env['oomusic.folder'].browse([int(folderId)])
            if not folder.exists():
                return rest.make_error(code='70', message='Folder not found')
        else:
            return rest.make_error(
                code='10',
                message='Required int parameter "id" is not present')

        root = etree.Element('subsonic-response',
                             status='ok',
                             version=rest.version_server)
        xml_directory = rest.make_Directory(folder)
        root.append(xml_directory)

        # List of folders
        for child in folder.child_ids:
            xml_data = rest.make_Child_folder(child)
            xml_directory.append(xml_data)

        # List of tracks
        for track in folder.track_ids:
            xml_data = rest.make_Child_track(track)
            xml_directory.append(xml_data)

        return rest.make_response(root)
Exemple #8
0
    def getPlaylist(self, **kwargs):
        rest = SubsonicREST(kwargs)
        success, response = rest.check_login()
        if not success:
            return response

        playlistId = kwargs.get('id')
        if playlistId:
            playlist = request.env['oomusic.playlist'].browse(
                [int(playlistId)])
            if not playlist.exists():
                return rest.make_error(code='70', message='Playlist not found')
        else:
            return rest.make_error(
                code='10',
                message='Required int parameter "id" is not present')

        root = etree.Element('subsonic-response',
                             status='ok',
                             version=rest.version_server)
        xml_playlist = rest.make_Playlist(playlist)
        root.append(xml_playlist)

        for playlist_line in playlist.playlist_line_ids:
            xml_playlist_line = rest.make_Child_track(playlist_line.track_id,
                                                      tag_name='entry')
            xml_playlist.append(xml_playlist_line)

        return rest.make_response(root)
Exemple #9
0
    def getArtistInfo2(self, **kwargs):
        rest = SubsonicREST(kwargs)
        success, response = rest.check_login()
        if not success:
            return response

        artistId = kwargs.get('id')
        if artistId:
            artist = request.env['oomusic.artist'].browse([int(artistId)])
            if not artist.exists():
                return rest.make_error(code='70', message='Artist not found')
        else:
            return rest.make_error(
                code='10',
                message='Required int parameter "id" is not present')

        count = int(kwargs.get('count', 20))
        if kwargs.get('includeNotPresent'):
            includeNotPresent = True if kwargs.get(
                'includeNotPresent') == 'true' else False
        else:
            includeNotPresent = False

        root = etree.Element('subsonic-response',
                             status='ok',
                             version=rest.version_server)
        xml_artist_info = rest.make_ArtistInfo2(
            artist, count=count, includeNotPresent=includeNotPresent)
        root.append(xml_artist_info)

        return rest.make_response(root)
Exemple #10
0
    def getAlbum(self, **kwargs):
        rest = SubsonicREST(kwargs)
        success, response = rest.check_login()
        if not success:
            return response

        albumId = kwargs.get('id')
        if albumId:
            album = request.env['oomusic.album'].browse([int(albumId)])
            if not album.exists():
                return rest.make_error(code='70', message='Album not found')
        else:
            return rest.make_error(
                code='10',
                message='Required int parameter "id" is not present')

        root = etree.Element('subsonic-response',
                             status='ok',
                             version=rest.version_server)
        xml_album = rest.make_AlbumID3(album)
        root.append(xml_album)

        for track in album.track_ids:
            xml_song = rest.make_Child_track(track, tag_name='song')
            xml_album.append(xml_song)

        return rest.make_response(root)
Exemple #11
0
    def jukeboxControl(self, **kwargs):
        rest = SubsonicREST(kwargs)
        success, response = rest.check_login()
        if not success:
            return response

        return rest.make_error(code='30',
                               message='Feature not supported by server.')
Exemple #12
0
    def getVideoInfo(self, **kwargs):
        # TODO: support video infos
        rest = SubsonicREST(kwargs)
        success, response = rest.check_login()
        if not success:
            return response

        return request.make_error(code='30',
                                  message='Videos are not supported yet')
    def scrobble(self, **kwargs):
        rest = SubsonicREST(kwargs)
        success, response = rest.check_login()
        if not success:
            return response

        # TODO support lastfm scrobble

        return rest.make_error(code='30', message='Feature not supported by server.')
Exemple #14
0
    def addChatMessage(self, **kwargs):
        rest = SubsonicREST(kwargs)
        success, response = rest.check_login()
        if not success:
            return response

        root = etree.Element('subsonic-response', status='ok', version=rest.version_server)

        return rest.make_response(root)
Exemple #15
0
    def getChatMessages(self, **kwargs):
        rest = SubsonicREST(kwargs)
        success, response = rest.check_login()
        if not success:
            return response

        root = etree.Element('subsonic-response', status='ok', version=rest.version_server)
        xml_messages = rest.make_ChatMessages()
        root.append(xml_messages)

        return rest.make_response(root)
    def actionUsers(self, **kwargs):
        rest = SubsonicREST(kwargs)
        success, response = rest.check_login()
        if not success:
            return response

        # Do not support these actions on purpose, for security reason

        root = etree.Element('subsonic-response',
                             status='ok',
                             version=rest.version_server)

        return rest.make_response(root)
Exemple #17
0
    def getInternetRadioStations(self, **kwargs):
        rest = SubsonicREST(kwargs)
        success, response = rest.check_login()
        if not success:
            return response

        root = etree.Element('subsonic-response',
                             status='ok',
                             version=rest.version_server)
        xml_radios = rest.make_InternetRadioStations()
        root.append(xml_radios)

        return rest.make_response(root)
Exemple #18
0
    def getNewestPodcasts(self, **kwargs):
        rest = SubsonicREST(kwargs)
        success, response = rest.check_login()
        if not success:
            return response

        root = etree.Element('subsonic-response',
                             status='ok',
                             version=rest.version_server)
        xml_podcasts = rest.make_Podcasts(tag_name='newestPodcasts')
        root.append(xml_podcasts)

        return rest.make_response(root)
    def stream(self, **kwargs):
        rest = SubsonicREST(kwargs)
        success, response = rest.check_login()
        if not success:
            return response

        trackId = kwargs.get('id')
        if trackId:
            track = request.env['oomusic.track'].browse([int(trackId)])
            if not track.exists():
                return rest.make_error(code='70', message='Song not found')
        else:
            return rest.make_error(
                code='10',
                message='Required int parameter "id" is not present')

        maxBitRate = int(kwargs.get('maxBitRate', 0))
        output_format = kwargs.get('format', 'mp3')
        estimateContentLength = kwargs.get('estimateContentLength', False)

        # Only for video
        # timeOffset = kwargs.get('timeOffset')
        # size = kwargs.get('size')
        # converted = kwargs.get('size', False)

        fn_ext = os.path.splitext(track.path)[1]

        # As specified in Subsonic API: if maxBitRate is set to zero, no limit is imposed. We also
        # avoid any upsampling.
        if fn_ext[1:] == output_format and (not maxBitRate
                                            or maxBitRate >= track.bitrate):
            return http.send_file(track.path)

        Transcoder = request.env['oomusic.transcoder'].search(
            [('input_formats.name', '=', fn_ext[1:]),
             ('output_format.name', '=', output_format)],
            limit=1,
        )
        if Transcoder:
            generator = Transcoder.transcode(int(trackId),
                                             bitrate=maxBitRate).stdout
            mimetype = Transcoder.output_format.mimetype
        else:
            _logger.warning('Could not find converter from "%s" to "%s"',
                            fn_ext[1:], output_format)
            return http.send_file(track.path)

        data = wrap_file(request.httprequest.environ,
                         generator,
                         buffer_size=Transcoder.buffer_size * 1024)
        return Response(data, mimetype=mimetype, direct_passthrough=True)
Exemple #20
0
    def getNowPlaying(self, **kwargs):
        rest = SubsonicREST(kwargs)
        success, response = rest.check_login()
        if not success:
            return response

        root = etree.Element('subsonic-response',
                             status='ok',
                             version=rest.version_server)
        xml_song_list = rest.make_listSongs('nowPlaying')
        root.append(xml_song_list)

        # TODO support NowPlayingEntry

        return rest.make_response(root)
Exemple #21
0
    def getLicense(self, **kwargs):
        rest = SubsonicREST(kwargs)
        success, response = rest.check_login()
        if not success:
            return response

        root = etree.Element('subsonic-response',
                             status='ok',
                             version=rest.version_server)
        etree.SubElement(root,
                         'license',
                         valid='true',
                         email='*****@*****.**',
                         licenseExpires='2099-12-31T23:59:59')
        return rest.make_response(root)
Exemple #22
0
    def getShares(self, **kwargs):
        rest = SubsonicREST(kwargs)
        success, response = rest.check_login()
        if not success:
            return response

        root = etree.Element('subsonic-response',
                             status='ok',
                             version=rest.version_server)
        xml_shares = rest.make_Shares()
        root.append(xml_shares)

        # TODO support shares

        return rest.make_response(root)
Exemple #23
0
    def getIndexes(self, **kwargs):
        rest = SubsonicREST(kwargs)
        success, response = rest.check_login()
        if not success:
            return response

        ifModifiedSince = kwargs.get('ifModifiedSince')
        if ifModifiedSince:
            try:
                ifModifiedSince = int(ifModifiedSince) / 1000
            except:
                return rest.make_error(code='0', message='Invalid timestamp')

        musicFolderId = kwargs.get('musicFolderId')
        if musicFolderId is None:
            folder = request.env['oomusic.folder'].search(
                [('root', '=', True)], limit=1)
        else:
            folder = request.env['oomusic.folder'].browse([int(musicFolderId)])
            if not folder.exists():
                return rest.make_error(code='70', message='Folder not found')

        root = etree.Element('subsonic-response',
                             status='ok',
                             version=rest.version_server)
        xml_indexes = rest.make_Indexes(folder)
        root.append(xml_indexes)

        if ifModifiedSince is not None and folder.last_modification < ifModifiedSince:
            return rest.make_response(root)

        # Build indexes
        indexes_dict = rest.build_dict_indexes_folder(folder)

        # List of folders
        for k, v in sorted(indexes_dict.iteritems()):
            xml_index = rest.make_Index(k)
            xml_indexes.append(xml_index)
            for child in v:
                xml_data = rest.make_Artist(child)
                xml_index.append(xml_data)

        # List of tracks
        for track in folder.track_ids:
            xml_data = rest.make_Child_track(track)
            xml_indexes.append(xml_data)

        return rest.make_response(root)
    def getLyrics(self, **kwargs):
        rest = SubsonicREST(kwargs)
        success, response = rest.check_login()
        if not success:
            return response

        artist = kwargs.get('artist')
        title = kwargs.get('title')

        root = etree.Element('subsonic-response',
                             status='ok',
                             version=rest.version_server)
        xml_lyrics = rest.make_Lyrics(artist, title)
        root.append(xml_lyrics)

        return rest.make_response(root)
    def download(self, **kwargs):
        rest = SubsonicREST(kwargs)
        success, response = rest.check_login()
        if not success:
            return response

        trackId = kwargs.get('id')
        if trackId:
            track = request.env['oomusic.track'].browse([int(trackId)])
            if not track.exists():
                return rest.make_error(code='70', message='Song not found')
        else:
            return rest.make_error(
                code='10',
                message='Required int parameter "id" is not present')

        return http.send_file(track.path, as_attachment=True)
Exemple #26
0
    def createPlaylist(self, **kwargs):
        rest = SubsonicREST(kwargs)
        success, response = rest.check_login()
        if not success:
            return response

        PlaylistObj = request.env['oomusic.playlist']
        mode = 'create'

        playlistId = kwargs.get('id')
        if playlistId:
            playlist = PlaylistObj.browse([int(playlistId)])
            if playlist.exists():
                mode = 'update'

        name = kwargs.get('name')
        if mode == 'mode' and not name:
            return rest.make_error(
                code='10',
                message='Required str parameter "name" is not present')

        songId = kwargs.get('songId')
        if songId:
            track = request.env['oomusic.track'].browse([int(songId)])
            if not track.exists():
                return rest.make_error(code='70', message='Song not found')

        if mode == 'create':
            playlist = PlaylistObj.create({'name': name})

        if playlist:
            playlist._add_tracks(track)

        root = etree.Element('subsonic-response',
                             status='ok',
                             version=rest.version_server)
        if API_VERSION_LIST[rest.version_client] >= API_VERSION_LIST['1.14.0']:
            xml_playlist = rest.make_Playlist(playlist)
            root.append(xml_playlist)

            for playlist_line in playlist.playlist_line_ids:
                xml_playlist_line = rest.make_Child_track(
                    playlist_line.track_id, tag_name='entry')
                xml_playlist.append(xml_playlist_line)

        return rest.make_response(root)
Exemple #27
0
    def getRandomSongs(self, **kwargs):
        rest = SubsonicREST(kwargs)
        success, response = rest.check_login()
        if not success:
            return response

        TrackObj = request.env['oomusic.track']

        fromYear = kwargs.get('fromYear')
        toYear = kwargs.get('toYear')
        genre = kwargs.get('genre')

        folderId = kwargs.get('musicFolderId')
        if folderId:
            folder = request.env['oomusic.folder'].browse([int(folderId)])
            if not folder.exists():
                return rest.make_error(code='70', message='Folder not found')

        size = min(int(kwargs.get('size', 10)), 500)

        # Build domain
        domain = [('id', 'child_of', int(folderId))] if folderId else []
        if fromYear:
            domain += [('year', '>=', fromYear)]
        if toYear:
            domain += [('year', '<=', toYear)]
        if genre:
            domain += [('genre_id.name', 'ilike', genre)]

        track_ids = TrackObj.search(domain).ids
        if track_ids:
            track_ids = random.sample(track_ids, min(size, len(track_ids)))

        tracks = TrackObj.browse(track_ids)

        root = etree.Element('subsonic-response',
                             status='ok',
                             version=rest.version_server)
        xml_song_list = rest.make_listSongs('randomSongs')
        root.append(xml_song_list)

        for track in tracks:
            xml_song = rest.make_Child_track(track, tag_name='song')
            xml_song_list.append(xml_song)

        return rest.make_response(root)
Exemple #28
0
    def getPlaylists(self, **kwargs):
        rest = SubsonicREST(kwargs)
        success, response = rest.check_login()
        if not success:
            return response

        root = etree.Element('subsonic-response',
                             status='ok',
                             version=rest.version_server)
        xml_playlists = rest.make_Playlists()
        root.append(xml_playlists)

        for playlist in request.env['oomusic.playlist'].search([]):
            xml_playlist = rest.make_Playlist(playlist)
            xml_playlists.append(xml_playlist)

        return rest.make_response(root)
    def getUsers(self, **kwargs):
        rest = SubsonicREST(kwargs)
        success, response = rest.check_login()
        if not success:
            return response

        root = etree.Element('subsonic-response',
                             status='ok',
                             version=rest.version_server)
        xml_users = rest.make_Users()
        root.append(xml_users)

        users = request.env['res.users'].search([])
        for user in users:
            xml_user = rest.make_User(user)
            xml_users.append(xml_user)

        return rest.make_response(root)
Exemple #30
0
    def getMusicFolders(self, **kwargs):
        rest = SubsonicREST(kwargs)
        success, response = rest.check_login()
        if not success:
            return response

        root = etree.Element('subsonic-response',
                             status='ok',
                             version=rest.version_server)
        xml_music_folders = rest.make_MusicFolders()
        root.append(xml_music_folders)

        for folder in request.env['oomusic.folder'].search([('root', '=', True)
                                                            ]):
            xml_music_folder = rest.make_MusicFolder(folder)
            xml_music_folders.append(xml_music_folder)

        return rest.make_response(root)