Esempio n. 1
0
    def add_path(self, path, album=False, session=None):
        self.log.info("add_path: %s, album=%s" % (path, album))
        assert session
        eid = None
        record = None
        record_a = None
        if not isinstance(path, unicode):
            path_u = to_unicode(path)
        else:
            path_u = path

        if os.path.isdir(path):
            eid = MediaManager.uuid(path)
            if album:
                record = self.Album(path)
            else:
                record = self.Artist(path)
            self.log.info("adding directory: %s, %s " % (eid, path_u))
        elif MediaManager.is_allowed_extension(path_u):
            try:
                record = self.Media(path)
                # Create a virtual album using a mock album id
                #   every song with the same virtual album (artist,album)
                #   is tied to it.
                if record.album != basename(path) and record.artist and record.album:
                    vpath = join("/", record.artist, record.album)
                    record_a = self.Album(vpath)
                    record.albumId = MediaManager.uuid(vpath)
                eid = record.id
                self.log.info("adding file: %s, %s " % (
                    eid, path_u))
            except UnsupportedMediaError, e:
                raise IposonicException(e)
Esempio n. 2
0
 def get_info(self, path_u):
     return {
         'id': MediaManager.uuid(path_u),
         'name': basename(path_u),
         'path': path_u,
         'isDir': 'true'
     }
Esempio n. 3
0
 def get_info(self, path_u):
     return {
         'id': MediaManager.uuid(path_u),
         'name': basename(path_u),
         'path': path_u,
         'isDir': 'true'
     }
Esempio n. 4
0
def get_now_playing_view():
    """TODO: save timestamp and song duration of every stream.view request

        xml response:
            <nowPlaying>
                <entry username="******"
                    minutesAgo="12"
                    playerId="2"
                    ... # all media properties />

                <entry username="******"
                    minutesAgo="1"
                    playerId="4"
                    playerName="Kitchen"
                    ... # all media properties
                />
            </nowPlaying>
        """
    (u, p, v, c, f, callback) = map(
        request.args.get, ['u', 'p', 'v', 'c', 'f', 'callback'])
    user = app.iposonic.get_users(eid=MediaManager.uuid(u))
    assert user.get('nowPlaying'), "Nothing playing now..."

    song = app.iposonic.get_songs(eid=user.get('nowPlaying'))
    song.update({'username': u})

    return request.formatter({'nowPlaying': {'entry': song}})
Esempio n. 5
0
def scrobble_view():
    """Add song to last.fm

        id	Yes		A string which uniquely identifies the file to scrobble.
        time	No		(Since 1.8.0) The time (in milliseconds since 1 Jan 1970) at which the song was listened to.
        submission	No	True	Whether this is a "submission" or a "now playing" notification.


    """
    from mediamanager.scrobble import q
    (u, p, v, c, f, callback) = map(
        request.args.get, ['u', 'p', 'v', 'c', 'f', 'callback'])
    (eid, ts, submission) = map(
        request.args.get, ['id', 'time', 'submission'])
    assert eid, "Missing song id"

    log.info("Retrieving scrobbling credentials")
    lastfm_user = app.iposonic.get_users(MediaManager.uuid(u))
    log.info("Scobbling credentials: %s" % lastfm_user)
    # get song info and append timestamp
    info = app.iposonic.get_entry_by_id(eid)
    info.update({'timestamp': int(time.time())})
    q.put(({
        'username': lastfm_user.get('scrobbleUser'),
        'password': lastfm_user.get('scrobblePassword')}, info))

    return request.formatter({})
Esempio n. 6
0
def get_now_playing_view():
    """TODO: save timestamp and song duration of every stream.view request

        xml response:
            <nowPlaying>
                <entry username="******"
                    minutesAgo="12"
                    playerId="2"
                    ... # all media properties />

                <entry username="******"
                    minutesAgo="1"
                    playerId="4"
                    playerName="Kitchen"
                    ... # all media properties
                />
            </nowPlaying>
        """
    (u, p, v, c, f, callback) = map(request.args.get,
                                    ['u', 'p', 'v', 'c', 'f', 'callback'])
    user = app.iposonic.get_users(eid=MediaManager.uuid(u))
    assert user.get('nowPlaying'), "Nothing playing now..."

    song = app.iposonic.get_songs(eid=user.get('nowPlaying'))
    song.update({'username': u})

    return request.formatter({'nowPlaying': {'entry': song}})
Esempio n. 7
0
    def walk_music_directory_old(self):
        """Find all artists (top-level directories) and create indexes.

          TODO: create a cache for this.
        """
        #raise NotImplementedError("This method should not be used")
        log.info("walking: ", self.get_music_folders())

        # reset database
        self.reset()

        # find all artists
        for music_folder in self.get_music_folders():
            artists_local = [
                x for x in os.listdir(music_folder)
                if os.path.isdir(join("/", music_folder, x))
            ]

            #index all artists
            for a in artists_local:
                if a:
                    path = join("/", music_folder, a)
                    try:
                        self.add_path(path)
                        self.artists[MediaManager.uuid(
                            path)] = IposonicDB.Artist(path)
                        artist_j = {
                            'artist': {
                                'id': MediaManager.uuid(path),
                                'name': a
                            }
                        }

                        #
                        # indexes = { 'A' : {'artist': {'id': .., 'name': ...}}}
                        #
                        first = a[0:1].upper()
                        self.indexes.setdefault(first, [])
                        self.indexes[first].append(artist_j)
                        log.info("Adding to index converted entry: %s" %
                                 artist_j)
                    except IposonicException as e:
                        log.error(e)
                log.info("artists: %s" % self.artists)

        return self.get_indexes()
Esempio n. 8
0
 def get_info(self, path):
     """TODO use path_u directly."""
     eid = MediaManager.uuid(path)
     path_u = stringutils.to_unicode(path)
     parent = dirname(path)
     dirname_u = MediaManager.get_album_name(path_u)
     return {
         'id': eid,
         'name': dirname_u,
         'isDir': 'true',
         'path': path_u,
         'title': dirname_u,
         'parent': MediaManager.uuid(parent),
         'album': dirname_u,
         'artist': basename(parent),
         'coverArt': eid
     }
Esempio n. 9
0
 def get_info(self, path):
     """TODO use path_u directly."""
     eid = MediaManager.uuid(path)
     path_u = stringutils.to_unicode(path)
     parent = dirname(path)
     dirname_u = MediaManager.get_album_name(path_u)
     return {
         'id': eid,
         'name': dirname_u,
         'isDir': 'true',
         'path': path_u,
         'title': dirname_u,
         'parent': MediaManager.uuid(parent),
         'album': dirname_u,
         'artist': basename(parent),
         'coverArt': eid
     }
Esempio n. 10
0
def stream_view():
    """@params
        - id=1409097050
        - maxBitRate=0 TODO

    """
    (u, p, v, c, f, callback) = map(
        request.args.get, ['u', 'p', 'v', 'c', 'f', 'callback'])

    (eid, maxBitRate) = map(request.args.get, ['id', 'maxBitRate'])

    print("request.headers: %s" % request.headers)
    if not eid:
        raise SubsonicProtocolException(
            "Missing required parameter: 'id' in stream.view")
    info = app.iposonic.get_entry_by_id(eid)
    path = info.get('path', None)
    assert path, "missing path in song: %s" % info

    def is_transcode(maxBitRate, info):
        try:
            maxBitRate = int(maxBitRate)
            if maxBitRate:
                return maxBitRate < info.get('bitRate')
        except:
            print("sending unchanged")
            return False

    log.info("actual - bitRate: %s" % info.get('bitRate'))
    assert os.path.isfile(path), "Missing file: %s" % path

    # update now playing
    try:
        log.info("Update nowPlaying: %s for user: %s -> %s" % (eid,
                 u, MediaManager.uuid(u)))
        user = app.iposonic.update_user(
            MediaManager.uuid(u), {'nowPlaying': eid})
    except:
        log.exception("Can't update nowPlaying for user: %s" % u)

    if is_transcode(maxBitRate, info):
        return Response(_transcode(path, maxBitRate), direct_passthrough=True)
    log.info("sending static file: %s" % path)
    return send_file(path)
Esempio n. 11
0
    def get_info_test_mp3_3(self):
        file_name = "./test/data/edith_piaf/letoile_de_la_chanson/16_bal_dans_ma_rue.mp3"
        parent = dirname(file_name)

        expected = {
            'title': 'bal dans ma rue',
            'artist': 'Edith Piaf',
            'parent': MediaManager.uuid(join("/", os.getcwd(), parent))
        }
        self.get_info_harn(file_name, expected)
Esempio n. 12
0
    def get_info_test_mp3_3(self):
        file_name = "./test/data/edith_piaf/letoile_de_la_chanson/16_bal_dans_ma_rue.mp3"
        parent = dirname(file_name)

        expected = {
            'title': 'bal dans ma rue',
            'artist': 'Edith Piaf',
            'parent': MediaManager.uuid(join("/", os.getcwd(), parent))
        }
        self.get_info_harn(file_name, expected)
Esempio n. 13
0
    def get_info_test_ogg(self):
        file_name = "./test/data/mock_artist/mock_album/sample.ogg"
        parent = dirname(file_name)

        expected = {
            'title': 'mock_title',
            'artist': 'mock_artist',
            'year': 'mock_year',
            'parent': MediaManager.uuid(join("/", os.getcwd(), parent))
        }
        self.get_info_harn(file_name, expected)
Esempio n. 14
0
    def get_info_test_mp3_2(self):
        file_name = "./test/data/Aretha Franklin/20 Greatest hits/Angel.mp3"
        parent = dirname(file_name)

        expected = {
            'title': 'Angel',
            'artist': 'Aretha Franklin',
            'bitRate': 128,
            'parent': MediaManager.uuid(join("/", os.getcwd(), parent))
        }
        self.get_info_harn(file_name, expected)
Esempio n. 15
0
    def get_info_test_mp3(self):
        file_name = "./test/data/lara.mp3"
        parent = dirname(file_name)

        expected = {
            'title': 'BWV 1041 : I. Allegro (PREVIEW: buy it at www.magnatune.com)',
            'artist': 'Lara St John (PREVIEW: buy it at www.magnatune.com)',
            'bitRate': 128,
            'parent': MediaManager.uuid(join("/", os.getcwd(), parent))
        }
        self.get_info_harn(file_name, expected)
Esempio n. 16
0
    def get_info_test_ogg(self):
        file_name = "./test/data/mock_artist/mock_album/sample.ogg"
        parent = dirname(file_name)

        expected = {
            'title': 'mock_title',
            'artist': 'mock_artist',
            'year': 'mock_year',
            'parent': MediaManager.uuid(join("/", os.getcwd(), parent))
        }
        self.get_info_harn(file_name, expected)
Esempio n. 17
0
    def get_info_test_mp3_2(self):
        file_name = "./test/data/Aretha Franklin/20 Greatest hits/Angel.mp3"
        parent = dirname(file_name)

        expected = {
            'title': 'Angel',
            'artist': 'Aretha Franklin',
            'bitRate': 128,
            'parent': MediaManager.uuid(join("/", os.getcwd(), parent))
        }
        self.get_info_harn(file_name, expected)
Esempio n. 18
0
    def get_info_test_mp3(self):
        file_name = "./test/data/lara.mp3"
        parent = dirname(file_name)

        expected = {
            'title':
            'BWV 1041 : I. Allegro (PREVIEW: buy it at www.magnatune.com)',
            'artist': 'Lara St John (PREVIEW: buy it at www.magnatune.com)',
            'bitRate': 128,
            'parent': MediaManager.uuid(join("/", os.getcwd(), parent))
        }
        self.get_info_harn(file_name, expected)
Esempio n. 19
0
def get_music_folders_view():
    """Return all music folders."""
    (u, p, v, c, f, callback) = map(request.args.get,
                                    ['u', 'p', 'v', 'c', 'f', 'callback'])
    return request.formatter({
        'musicFolders': {
            'musicFolder': [{
                'id': MediaManager.uuid(d),
                'name': d
            } for d in app.iposonic.get_music_folders() if isdir(d)]
        }
    })
Esempio n. 20
0
    def walk_music_directory_old(self):
        """Find all artists (top-level directories) and create indexes.

          TODO: create a cache for this.
        """
        #raise NotImplementedError("This method should not be used")
        log.info("walking: ", self.get_music_folders())

        # reset database
        self.reset()

        # find all artists
        for music_folder in self.get_music_folders():
            artists_local = [x for x in os.listdir(
                music_folder) if os.path.isdir(join("/", music_folder, x))]

            #index all artists
            for a in artists_local:
                if a:
                    path = join("/", music_folder, a)
                    try:
                        self.add_path(path)
                        self.artists[MediaManager.uuid(
                            path)] = IposonicDB.Artist(path)
                        artist_j = {'artist': {
                            'id': MediaManager.uuid(path), 'name': a}}

                        #
                        # indexes = { 'A' : {'artist': {'id': .., 'name': ...}}}
                        #
                        first = a[0:1].upper()
                        self.indexes.setdefault(first, [])
                        self.indexes[first].append(artist_j)
                        log.info(
                            "Adding to index converted entry: %s" % artist_j)
                    except IposonicException as e:
                        log.error(e)
                log.info("artists: %s" % self.artists)

        return self.get_indexes()
Esempio n. 21
0
def get_music_folders_view():
    """Return all music folders."""
    (u, p, v, c, f, callback) = map(
        request.args.get, ['u', 'p', 'v', 'c', 'f', 'callback'])
    return request.formatter(
        {'musicFolders': {'musicFolder':
                          [
                          {
                          'id': MediaManager.uuid(d),
                          'name': d
                          } for d in app.iposonic.get_music_folders() if isdir(d)
                          ]
                          }}
    )
Esempio n. 22
0
def create_playlist_view():
    """TODO move to app.iposonic

        request body:
            name=2012-09-08&
            songId=-2072958145&
            songId=-2021195453&
            songId=-1785884780

    """
    (u, p, v, c, f, callback) = map(
        request.args.get, ['u', 'p', 'v', 'c', 'f', 'callback'])

    (name, playlistId) = map(request.values.get, ['name', 'playlistId'])
    songId_l = request.values.getlist('songId')
    print("songId: %s" % songId_l)
    if not (name or playlistId):
        print("request: %s" % request.data)
        raise SubsonicMissingParameterException(
            'id or playlistId', 'create_playlist_view')

    # create a new playlist
    if not playlistId:
        eid = MediaManager.uuid(name)
        try:
            playlist = app.iposonic.get_playlists(eid=eid)
            raise IposonicException("Playlist esistente")
        except:
            pass
        # TODO DAO should not be exposed
        playlist = app.iposonic.db.Playlist(name)
        playlist.update({'entry': ",".join(songId_l)})
        app.iposonic.create_entry(playlist)

    # update
    else:
        playlist = app.iposonic.get_playlists(eid=playlistId)
        assert playlist
        songs = playlist.get('entry')
        songs += ",".join(songId_l)
        app.iposonic.update_entry(eid=playlistId, new={'entry': songs})
    return request.formatter({'status': 'ok'})
Esempio n. 23
0
 def add_path(self, path, album=False):
     """Create an entry from path and add it to the DB."""
     if os.path.isdir(path):
         self.log.warn(
             "Adding %s: %s " %
             ("album" if album else "artist", stringutils.to_unicode(path)))
         eid = MediaManager.uuid(path)
         if album:
             self.albums[eid] = IposonicDB.Album(path)
         else:
             self.artists[eid] = IposonicDB.Artist(path)
         self.log.info(u"adding directory: %s, %s " %
                       (eid, stringutils.to_unicode(path)))
         return eid
     elif MediaManager.is_allowed_extension(path):
         try:
             info = MediaManager.get_info(path)
             info.update({'coverArt': MediaManager.cover_art_uuid(info)})
             self.songs[info['id']] = info
             self.log.info("adding file: %s, %s " % (info['id'], path))
             return info['id']
         except UnsupportedMediaError as e:
             raise IposonicException(e)
     raise IposonicException("Path not found or bad extension: %s " % path)
Esempio n. 24
0
 def add_path(self, path, album=False):
     """Create an entry from path and add it to the DB."""
     if os.path.isdir(path):
         self.log.warn(
             "Adding %s: %s " % ("album" if album else "artist", stringutils.to_unicode(path)))
         eid = MediaManager.uuid(path)
         if album:
             self.albums[eid] = IposonicDB.Album(path)
         else:
             self.artists[eid] = IposonicDB.Artist(path)
         self.log.info(u"adding directory: %s, %s " % (eid, stringutils.to_unicode(path)))
         return eid
     elif MediaManager.is_allowed_extension(path):
         try:
             info = MediaManager.get_info(path)
             info.update({
                 'coverArt': MediaManager.cover_art_uuid(info)
             })
             self.songs[info['id']] = info
             self.log.info("adding file: %s, %s " % (info['id'], path))
             return info['id']
         except UnsupportedMediaError as e:
             raise IposonicException(e)
     raise IposonicException("Path not found or bad extension: %s " % path)
Esempio n. 25
0
 def test_get_user(self):
     from mediamanager import MediaManager
     eid = MediaManager.uuid('mock_user')
     ret = self.db.get_users(eid)
     assert ret, "Can't find user %s" % eid
     assert ret.get('username') == 'mock_user', "No user: %s" % ret
Esempio n. 26
0
 def test_get_playlist(self):
     eid = MediaManager.uuid('mock_playlist')
     ret = self.db.get_playlists(eid=eid)
     assert ret, "Can't find playlist %s" % eid
     assert ret.get('name') == 'mock_playlist', "No playlists: %s" % ret
Esempio n. 27
0
 def get_info(self, name):
     return {'id': MediaManager.uuid(name), 'name': name}
Esempio n. 28
0
 def __init__(self, username):
     IposonicDBTables.BaseB.__init__(self)
     self.update({
         'id': MediaManager.uuid(username),
         'username': username
     })
Esempio n. 29
0
def get_playlist_view():
    """Return a playlist.

        response xml:
     <playlist id="15" name="kokos" comment="fan" owner="admin" public="true" songCount="6" duration="1391"
                     created="2012-04-17T19:53:44">
               <allowedUser>sindre</allowedUser>
               <allowedUser>john</allowedUser>
               <entry id="657" parent="655" title="Making Me Nervous" album="I Don&apos;t Know What I&apos;m Doing"
                      artist="Brad Sucks" isDir="false" coverArt="655" created="2008-04-10T07:10:32" duration="159"
                     bitRate="202" track="1" year="2003" size="4060113" suffix="mp3" contentType="audio/mpeg" isVideo="false"
                     path="Brad Sucks/I Don&apos;t Know What I&apos;m Doing/01 - Making Me Nervous.mp3" albumId="58"
                     artistId="45" type="music"/>
        response jsonp:
            {'playlist': {
                'id':,
                'name':,
                'songCount',
                'allowedUser': [ 'user1', 'user2' ],
                'entry': [ {
                    id:,
                    title:,
                    ...
                    },
                ]
                }}

        TODO move database objects to app.iposonicdb. They  shouldn't be
                exposed outside.
    """
    (u, p, v, c, f, callback) = map(
        request.args.get, ['u', 'p', 'v', 'c', 'f', 'callback'])
    eid = request.args.get('id')
    if not eid:
        raise SubsonicProtocolException(
            "Missing required parameter: 'id' in stream.view")

    entries = []
    # use default playlists
    if eid == MediaManager.uuid('starred'):
        j_playlist = app.iposonic.get_playlists_static(eid=eid)
        songs = app.iposonic.get_starred().get('title')
        entries = randomize2_list(songs, 5)
    elif eid in [x.get('id') for x in app.iposonic.get_playlists_static()]:
        j_playlist = app.iposonic.get_playlists_static(eid=eid)
        entries = randomize2_list(app.iposonic.get_songs())
    else:
        playlist = app.iposonic.get_playlists(eid=eid)
        assert playlist, "Playlists: %s" % app.iposonic.db.playlists
        print("found playlist: %s" % playlist)
        entry_ids = playlist.get('entry')
        if entry_ids:
            entries = [x for x in app.iposonic.get_song_list(
                entry_ids.split(","))]
        j_playlist = playlist
    # format output
    assert entries, "Missing entries: %s" % entries
    print("Entries retrieved: %s" % entries)
    j_playlist.update({
        'entry': entries,
        'songCount': len(entries),
        'duration': sum([x.get('duration', 0) for x in entries])
    })
    return request.formatter({'status': 'ok', 'playlist': j_playlist})
Esempio n. 30
0
def get_music_directory_view():
    """Return the content of a directory.

      params:
        - id=-493506601
        -

      xml response 1:
          <directory id="1" name="ABBA">
            <child id="11"
                parent="1"
                title="Arrival"
                artist="ABBA"
                isDir="true"
                coverArt="22"/>
            <child id="12"
                parent="1"
                title="Super Trouper"
                artist="ABBA"
                isDir="true"
                coverArt="23"/>
          </directory>

      xml response 2:
          <directory id="11" parent="1" name="Arrival">
            <child id="111"
                parent="11"
                title="Dancing Queen"
                isDir="false"
                album="Arrival"
                artist="ABBA"
                track="7"
                year="1978"
                genre="Pop"
                coverArt="24"
                size="8421341"
                contentType="audio/mpeg"
                suffix="mp3"
                duration="146"
                bitRate="128"
                path="ABBA/Arrival/Dancing Queen.mp3"/>

            <child id="112"
                parent="11"
                ... # se above
                contentType="audio/flac"
                suffix="flac"
                transcodedContentType="audio/mpeg"
                transcodedSuffix="mp3"
                duration="208"
                bitRate="128"
                />
          </directory>

        jsonp response
    """
    (u, p, v, c, f, callback,
     dir_id) = map(request.args.get,
                   ['u', 'p', 'v', 'c', 'f', 'callback', 'id'])

    if not dir_id:
        raise SubsonicProtocolException(
            "Missing required parameter: 'id' in getMusicDirectory.view")
    (path, dir_path) = app.iposonic.get_directory_path_by_id(dir_id)
    mf = app.iposonic.db.music_folders[0]
    dir_path = os.path.join("/", mf, dir_path)
    log.info("Getting entries in path: %s" % dir_path)
    children = []
    artist = app.iposonic.db.Artist(dir_path)
    #
    # if nothing changed before our last visit
    #    or is a virtual path (eg. uniexistent)
    #    don't rescan
    #
    try:
        last_modified = os.stat(dir_path).st_ctime
    except:
        last_modified = -1

    if last_modified == -1:
        print("Getting items from valbum.")
        children = app.iposonic.get_songs(query={'albumId': dir_id})
    elif fs_cache.get(dir_id, 0) == last_modified:
        print("Getting items from cache.")
        children = app.iposonic.get_songs(query={'parent': dir_id})
        children.extend(app.iposonic.get_albums(query={'parent': dir_id}))
    else:
        for child in os.listdir(unicode(dir_path)):
            # TODO find a way to support non-unicode directories and
            #    folders. The easiest way is to simply RENAME THEM!
            #    ................
            print("checking string type: ", type(child))
            #child = to_unicode(child)
            if child[0] in ['.', '_']:
                continue

            #
            # To manage non-utf8 filenames
            # the easiest thing is to rename
            # paths in utf.
            #
            # This may cause issues for collections
            # stored on windows or vfat filesystem.
            #
            # This is the KISS-siest approach
            # that avoids continuously encode
            # and decode of the filenames.
            #
            if not isinstance(child, unicode):
                if not app.config.get('rename_non_utf8'):
                    log.warn("skipping non unicode path: %s " %
                             to_unicode(child))
                    continue
                child_new = to_unicode(child)
                os.rename(
                    b'%s/%s' % (dir_path.encode('utf-8'), child), b'%s/%s' %
                    (dir_path.encode('utf-8'), child_new.encode('utf-8')))
                child = child_new

            path = join(dir_path, child)
            try:
                child_j = {}
                is_dir = isdir(path)
                # This is a Lazy Indexing. It should not be there
                #   unless a cache is set
                # XXX
                eid = MediaManager.uuid(path)
                try:
                    child_j = app.iposonic.get_entry_by_id(eid)
                except IposonicException:
                    app.iposonic.add_path(path, album=is_dir)
                    child_j = app.iposonic.get_entry_by_id(eid)

                children.append(child_j)
            except IposonicException as e:
                log.info(e)
        fs_cache.setdefault(dir_id, last_modified)

    def _track_or_die(x):
        try:
            return int(x['track'])
        except:
            return 0

    # Sort songs by track id, if possible
    children = sorted(children, key=_track_or_die)

    return request.formatter({
        'directory': {
            'id': dir_id,
            'name': artist.get('name'),
            'child': children
        }
    })
Esempio n. 31
0
 def get_folder_by_id(self, folder_id):
     """It's ok just because self.db.get_music_folders() are few"""
     for folder in self.db.get_music_folders():
         if MediaManager.uuid(folder) == folder_id:
             return folder
     raise IposonicException("Missing music folder with id: %s" % folder_id)
Esempio n. 32
0
 def __init__(self, username):
     IposonicDBTables.BaseB.__init__(self)
     self.update({
         'id': MediaManager.uuid(username),
         'username': username}
     )
Esempio n. 33
0
 def get_info(self, name):
     return {
         'id': MediaManager.uuid(name),
         'name': name
     }
Esempio n. 34
0
def get_music_directory_view():
    """Return the content of a directory.

      params:
        - id=-493506601
        -

      xml response 1:
          <directory id="1" name="ABBA">
            <child id="11"
                parent="1"
                title="Arrival"
                artist="ABBA"
                isDir="true"
                coverArt="22"/>
            <child id="12"
                parent="1"
                title="Super Trouper"
                artist="ABBA"
                isDir="true"
                coverArt="23"/>
          </directory>

      xml response 2:
          <directory id="11" parent="1" name="Arrival">
            <child id="111"
                parent="11"
                title="Dancing Queen"
                isDir="false"
                album="Arrival"
                artist="ABBA"
                track="7"
                year="1978"
                genre="Pop"
                coverArt="24"
                size="8421341"
                contentType="audio/mpeg"
                suffix="mp3"
                duration="146"
                bitRate="128"
                path="ABBA/Arrival/Dancing Queen.mp3"/>

            <child id="112"
                parent="11"
                ... # se above
                contentType="audio/flac"
                suffix="flac"
                transcodedContentType="audio/mpeg"
                transcodedSuffix="mp3"
                duration="208"
                bitRate="128"
                />
          </directory>

        jsonp response
    """
    (u, p, v, c, f, callback, dir_id) = map(
        request.args.get, ['u', 'p', 'v', 'c', 'f', 'callback', 'id'])

    if not dir_id:
        raise SubsonicProtocolException(
            "Missing required parameter: 'id' in getMusicDirectory.view")
    (path, dir_path) = app.iposonic.get_directory_path_by_id(dir_id)
    mf = app.iposonic.db.music_folders[0]
    dir_path = os.path.join("/", mf, dir_path)
    log.info("Getting entries in path: %s" % dir_path)
    children = []
    artist = app.iposonic.db.Artist(dir_path)
    #
    # if nothing changed before our last visit
    #    or is a virtual path (eg. uniexistent)
    #    don't rescan
    #
    try:
        last_modified = os.stat(dir_path).st_ctime
    except:
        last_modified = -1

    if last_modified == -1:
        print("Getting items from valbum.")
        children = app.iposonic.get_songs(query={'albumId': dir_id})
    elif fs_cache.get(dir_id, 0) == last_modified:
        print("Getting items from cache.")
        children = app.iposonic.get_songs(query={'parent': dir_id})
        children.extend(app.iposonic.get_albums(query={'parent': dir_id}))
    else:
        for child in os.listdir(unicode(dir_path)):
            # TODO find a way to support non-unicode directories and
            #    folders. The easiest way is to simply RENAME THEM!
            #    ................
            print("checking string type: ", type(child))
            #child = to_unicode(child)
            if child[0] in ['.', '_']:
                continue

            #
            # To manage non-utf8 filenames
            # the easiest thing is to rename
            # paths in utf.
            #
            # This may cause issues for collections
            # stored on windows or vfat filesystem.
            #
            # This is the KISS-siest approach
            # that avoids continuously encode
            # and decode of the filenames.
            #
            if not isinstance(child, unicode):
                if not app.config.get('rename_non_utf8'):
                    log.warn(
                        "skipping non unicode path: %s " % to_unicode(child))
                    continue
                child_new = to_unicode(child)
                os.rename(
                    b'%s/%s' % (dir_path.encode('utf-8'), child),
                    b'%s/%s' % (
                        dir_path.encode('utf-8'), child_new.encode('utf-8'))
                )
                child = child_new

            path = join(dir_path, child)
            try:
                child_j = {}
                is_dir = isdir(path)
                # This is a Lazy Indexing. It should not be there
                #   unless a cache is set
                # XXX
                eid = MediaManager.uuid(path)
                try:
                    child_j = app.iposonic.get_entry_by_id(eid)
                except IposonicException:
                    app.iposonic.add_path(path, album=is_dir)
                    child_j = app.iposonic.get_entry_by_id(eid)

                children.append(child_j)
            except IposonicException as e:
                log.info(e)
        fs_cache.setdefault(dir_id, last_modified)

    def _track_or_die(x):
        try:
            return int(x['track'])
        except:
            return 0
    # Sort songs by track id, if possible
    children = sorted(children, key=_track_or_die)

    return request.formatter(
        {'directory': {
            'id': dir_id,
            'name': artist.get('name'),
            'child': children
        }
        })
Esempio n. 35
0
 def __init__(self, username):
     Base.__init__(self)
     self.update({
         'id': MediaManager.uuid(username),
         'username': username}
     )
Esempio n. 36
0
 def get_folder_by_id(self, folder_id):
     """It's ok just because self.db.get_music_folders() are few"""
     for folder in self.db.get_music_folders():
         if MediaManager.uuid(folder) == folder_id:
             return folder
     raise IposonicException("Missing music folder with id: %s" % folder_id)
Esempio n. 37
0
 def test_get_playlist(self):
     eid = MediaManager.uuid('mock_playlist')
     ret = self.db.get_playlists(eid=eid)
     assert ret, "Can't find playlist %s" % eid
     assert ret.get('name') == 'mock_playlist', "No playlists: %s" % ret
Esempio n. 38
0
 def test_get_user(self):
     from mediamanager import MediaManager
     eid = MediaManager.uuid('mock_user')
     ret = self.db.get_users(eid)
     assert ret, "Can't find user %s" % eid
     assert ret.get('username') == 'mock_user', "No user: %s" % ret