Exemple #1
0
 def test_unicode_in_uri(self):
     if sys.platform == 'win32':
         result = path.uri_to_path('file:///C://%C3%A6%C3%B8%C3%A5')
         self.assertEqual(result, 'C:/æøå'.encode('utf-8'))
     else:
         result = path.uri_to_path('file:///tmp/%C3%A6%C3%B8%C3%A5')
         self.assertEqual(result, '/tmp/æøå'.encode('utf-8'))
Exemple #2
0
 def test_simple_uri(self):
     if sys.platform == "win32":
         result = uri_to_path("file:///C://WINDOWS/clock.avi")
         self.assertEqual(result, u"C:/WINDOWS/clock.avi")
     else:
         result = uri_to_path("file:///etc/fstab")
         self.assertEqual(result, u"/etc/fstab")
Exemple #3
0
 def test_unicode_in_uri(self):
     if sys.platform == 'win32':
         result = uri_to_path( 'file:///C://%C3%A6%C3%B8%C3%A5')
         self.assertEqual(result, u'C:/æøå')
     else:
         result = uri_to_path(u'file:///tmp/%C3%A6%C3%B8%C3%A5')
         self.assertEqual(result, u'/tmp/æøå')
Exemple #4
0
 def test_simple_uri(self):
     if sys.platform == 'win32':
         result = uri_to_path('file:///C://WINDOWS/clock.avi')
         self.assertEqual(result, u'C:/WINDOWS/clock.avi')
     else:
         result = uri_to_path('file:///etc/fstab')
         self.assertEqual(result, u'/etc/fstab')
Exemple #5
0
 def test_space_in_uri(self):
     if sys.platform == 'win32':
         result = path.uri_to_path('file:///C://test%20this')
         self.assertEqual(result, 'C:/test this'.encode('utf-8'))
     else:
         result = path.uri_to_path('file:///tmp/test%20this')
         self.assertEqual(result, '/tmp/test this'.encode('utf-8'))
Exemple #6
0
 def test_space_in_uri(self):
     if sys.platform == 'win32':
         result = uri_to_path('file:///C://test%20this')
         self.assertEqual(result, u'C:/test this')
     else:
         result = uri_to_path(u'file:///tmp/test%20this')
         self.assertEqual(result, u'/tmp/test this')
Exemple #7
0
 def test_latin1_in_uri(self):
     if sys.platform == 'win32':
         result = path.uri_to_path('file:///C://%E6%F8%E5')
         self.assertEqual(result, 'C:/æøå'.encode('latin-1'))
     else:
         result = path.uri_to_path('file:///tmp/%E6%F8%E5')
         self.assertEqual(result, '/tmp/æøå'.encode('latin-1'))
Exemple #8
0
 def test_simple_uri(self):
     if sys.platform == 'win32':
         result = path.uri_to_path('file:///C://WINDOWS/clock.avi')
         self.assertEqual(result, 'C:/WINDOWS/clock.avi'.encode('utf-8'))
     else:
         result = path.uri_to_path('file:///etc/fstab')
         self.assertEqual(result, '/etc/fstab'.encode('utf-8'))
Exemple #9
0
 def test_unicode_in_uri(self):
     if sys.platform == "win32":
         result = uri_to_path("file:///C://%C3%A6%C3%B8%C3%A5")
         self.assertEqual(result, u"C:/æøå")
     else:
         result = uri_to_path(u"file:///tmp/%C3%A6%C3%B8%C3%A5")
         self.assertEqual(result, u"/tmp/æøå")
Exemple #10
0
 def test_space_in_uri(self):
     if sys.platform == "win32":
         result = uri_to_path("file:///C://test%20this")
         self.assertEqual(result, u"C:/test this")
     else:
         result = uri_to_path(u"file:///tmp/test%20this")
         self.assertEqual(result, u"/tmp/test this")
Exemple #11
0
 def _save_m3u(self, playlist):
     file_path = path.uri_to_path(playlist.uri)
     path.check_file_path_is_inside_base_dir(file_path, self._path)
     with open(file_path, 'w') as file_handle:
         for track in playlist.tracks:
             if track.uri.startswith('file://'):
                 uri = path.uri_to_path(track.uri)
             else:
                 uri = track.uri
             file_handle.write(uri + '\n')
Exemple #12
0
 def translate(self, track):
     base_path = self.media_dir.encode("utf-8")
     result = dict(translator.track_to_mpd_format(track))
     result["file"] = uri_to_path(result["file"])[len(base_path) + 1 :]
     result["key"] = os.path.basename(result["file"])
     result["mtime"] = mtime("")
     return translator.order_mpd_track_info(result.items())
Exemple #13
0
 def change_track(self, track):
     media_dir = self.backend.config['local']['media_dir']
     # TODO: check that type is correct.
     file_path = path.uri_to_path(track.uri).split(b':', 1)[1]
     file_path = os.path.join(media_dir, file_path)
     track = track.copy(uri=path.path_to_uri(file_path))
     return super(LocalPlaybackProvider, self).change_track(track)
Exemple #14
0
 def translate(self, track):
     base_path = self.media_dir.encode('utf-8')
     result = dict(translator.track_to_mpd_format(track))
     result['file'] = uri_to_path(result['file'])[len(base_path) + 1:]
     result['key'] = os.path.basename(result['file'])
     result['mtime'] = mtime('')
     return translator.order_mpd_track_info(result.items())
Exemple #15
0
 def translate(self, track):
     folder = settings.LOCAL_MUSIC_PATH
     result = dict(translator.track_to_mpd_format(track))
     result['file'] = uri_to_path(result['file'])
     result['file'] = result['file'][len(folder)+1:]
     result['key'] = os.path.basename(result['file'])
     result['mtime'] = mtime('')
     return translator.order_mpd_track_info(result.items())
Exemple #16
0
    def _rename_m3u(self, playlist):
        src_file_path = path.uri_to_path(playlist.uri)
        path.check_file_path_is_inside_base_dir(src_file_path, self._path)

        dst_file_path = self._get_m3u_path(playlist.name)
        path.check_file_path_is_inside_base_dir(dst_file_path, self._path)

        shutil.move(src_file_path, dst_file_path)

        return playlist.copy(uri=path.path_to_uri(dst_file_path))
Exemple #17
0
def tracks_to_directory_tree(tracks):
    directories = ({}, [])

    for track in tracks:
        path = b""
        current = directories

        absolute_track_dir_path = os.path.dirname(uri_to_path(track.uri))
        relative_track_dir_path = re.sub("^" + re.escape(settings.LOCAL_MUSIC_PATH), b"", absolute_track_dir_path)

        for part in split_path(relative_track_dir_path):
            path = os.path.join(path, part)
            if path not in current[0]:
                current[0][path] = ({}, [])
            current = current[0][path]
        current[1].append(track)
    return directories
Exemple #18
0
    def process_application(self, bus, message):
        if message.src != self.fakesink:
            return

        if message.structure.get_name() != 'handoff':
            return

        uri = unicode(self.uribin.get_property('uri'))
        self.data['uri'] = uri
        self.data['mtime'] = os.path.getmtime(path.uri_to_path(uri))
        self.data[gst.TAG_DURATION] = self.get_duration()

        try:
            self.data_callback(self.data)
            self.next_uri()
        except KeyboardInterrupt:
            self.stop()
Exemple #19
0
def tracks_to_directory_tree(tracks):
    directories = ({}, [])
    for track in tracks:
        path = u''
        current = directories

        local_folder = settings.LOCAL_MUSIC_PATH
        track_path = uri_to_path(track.uri)
        track_path = re.sub('^' + re.escape(local_folder), '', track_path)
        track_dir = os.path.dirname(track_path)

        for part in split_path(track_dir):
            path = os.path.join(path, part)
            if path not in current[0]:
                current[0][path] = ({}, [])
            current = current[0][path]
        current[1].append(track)
    return directories
Exemple #20
0
def tracks_to_directory_tree(tracks, media_dir):
    directories = ({}, [])

    for track in tracks:
        path = b''
        current = directories

        absolute_track_dir_path = os.path.dirname(uri_to_path(track.uri))
        relative_track_dir_path = re.sub(
            '^' + re.escape(media_dir), b'', absolute_track_dir_path)

        for part in split_path(relative_track_dir_path):
            path = os.path.join(path, part)
            if path not in current[0]:
                current[0][path] = ({}, [])
            current = current[0][path]
        current[1].append(track)
    return directories
 def scan(self, uri):
     logger.debug('Scanning %s for images', uri)
     data = self.scanner.scan(uri)
     images = []
     # Use image 'image' tag if available, or smaller, lower quality 'preview-image' otherwise
     for image in data['tags'].get('image', []) or data['tags'].get('preview-image', []):
         try:
             images.append(self.get_or_create_image_file(None, image.data))
         except Exception as e:
             logger.warn('Cannot extract images for %s: %s', uri, e)
     dirname = os.path.dirname(uri_to_path(uri))
     for pattern in self.patterns:
         for path in glob.glob(os.path.join(dirname, pattern)):
             try:
                 images.append(self.get_or_create_image(path))
             except Exception as e:
                 logger.warn('Cannot read album art from %s: %s', path, e)
     return images
Exemple #22
0
 def scan(self, uri):
     if not self._scanner:
         self._scanner = Scanner()
     data = self._scanner.scan(uri)
     logger.debug('Scanning for images: %r', data)
     images = []
     for image in data['tags'].get('image', []):
         try:
             images.append(self._get_or_create_image(None, image.data))
         except Exception as e:
             logger.warn('Cannot extract image from %s: %s', uri, e)
     dirname = os.path.dirname(uri_to_path(uri))
     for pattern in self._patterns:
         for path in glob.glob(os.path.join(dirname, pattern)):
             try:
                 images.append(self._get_or_create_image(path))
             except Exception as e:
                 logger.warn('Cannot read album art from %s: %s', path, e)
     return images
Exemple #23
0
def _add_to_tag_cache(result, dirs, files, media_dir):
    base_path = media_dir.encode('utf-8')

    for path, (entry_dirs, entry_files) in dirs.items():
        try:
            text_path = path.decode('utf-8')
        except UnicodeDecodeError:
            text_path = urllib.quote(path).decode('utf-8')
        name = os.path.split(text_path)[1]
        result.append(('directory', text_path))
        result.append(('mtime', get_mtime(os.path.join(base_path, path))))
        result.append(('begin', name))
        _add_to_tag_cache(result, entry_dirs, entry_files, media_dir)
        result.append(('end', name))

    result.append(('songList begin',))

    for track in files:
        track_result = dict(track_to_mpd_format(track))

        # XXX Don't save comments to the tag cache as they may span multiple
        # lines. We'll start saving track comments when we move from tag_cache
        # to a JSON file. See #579 for details.
        if 'Comment' in track_result:
            del track_result['Comment']

        path = uri_to_path(track_result['file'])
        try:
            text_path = path.decode('utf-8')
        except UnicodeDecodeError:
            text_path = urllib.quote(path).decode('utf-8')
        relative_path = os.path.relpath(path, base_path)
        relative_uri = urllib.quote(relative_path)

        # TODO: use track.last_modified
        track_result['file'] = relative_uri
        track_result['mtime'] = get_mtime(path)
        track_result['key'] = os.path.basename(text_path)
        track_result = order_mpd_track_info(track_result.items())

        result.extend(track_result)

    result.append(('songList end',))
Exemple #24
0
def _add_to_tag_cache(result, folders, files):
    music_folder = settings.LOCAL_MUSIC_PATH
    regexp = '^' + re.escape(music_folder).rstrip('/') + '/?'

    for path, entry in folders.items():
        name = os.path.split(path)[1]
        mtime = get_mtime(os.path.join(music_folder, path))
        result.append(('directory', path))
        result.append(('mtime', mtime))
        result.append(('begin', name))
        _add_to_tag_cache(result, *entry)
        result.append(('end', name))

    result.append(('songList begin',))
    for track in files:
        track_result = dict(track_to_mpd_format(track))
        path = uri_to_path(track_result['file'])
        track_result['mtime'] = get_mtime(path)
        track_result['file'] = re.sub(regexp, '', path)
        track_result['key'] = os.path.basename(track_result['file'])
        track_result = order_mpd_track_info(track_result.items())
        result.extend(track_result)
    result.append(('songList end',))
Exemple #25
0
def _add_to_tag_cache(result, folders, files):
    base_path = settings.LOCAL_MUSIC_PATH.encode("utf-8")

    for path, entry in folders.items():
        try:
            text_path = path.decode("utf-8")
        except UnicodeDecodeError:
            text_path = urllib.quote(path).decode("utf-8")
        name = os.path.split(text_path)[1]
        result.append(("directory", text_path))
        result.append(("mtime", get_mtime(os.path.join(base_path, path))))
        result.append(("begin", name))
        _add_to_tag_cache(result, *entry)
        result.append(("end", name))

    result.append(("songList begin",))

    for track in files:
        track_result = dict(track_to_mpd_format(track))

        path = uri_to_path(track_result["file"])
        try:
            text_path = path.decode("utf-8")
        except UnicodeDecodeError:
            text_path = urllib.quote(path).decode("utf-8")
        relative_path = os.path.relpath(path, base_path)
        relative_uri = urllib.quote(relative_path)

        track_result["file"] = relative_uri
        track_result["mtime"] = get_mtime(path)
        track_result["key"] = os.path.basename(text_path)
        track_result = order_mpd_track_info(track_result.items())

        result.extend(track_result)

    result.append(("songList end",))
Exemple #26
0
def _add_to_tag_cache(result, folders, files):
    base_path = settings.LOCAL_MUSIC_PATH.encode('utf-8')

    for path, entry in folders.items():
        try:
            text_path = path.decode('utf-8')
        except UnicodeDecodeError:
            text_path = urllib.quote(path).decode('utf-8')
        name = os.path.split(text_path)[1]
        result.append(('directory', text_path))
        result.append(('mtime', get_mtime(os.path.join(base_path, path))))
        result.append(('begin', name))
        _add_to_tag_cache(result, *entry)
        result.append(('end', name))

    result.append(('songList begin',))

    for track in files:
        track_result = dict(track_to_mpd_format(track))

        path = uri_to_path(track_result['file'])
        try:
            text_path = path.decode('utf-8')
        except UnicodeDecodeError:
            text_path = urllib.quote(path).decode('utf-8')
        relative_path = os.path.relpath(path, base_path)
        relative_uri = urllib.quote(relative_path)

        track_result['file'] = relative_uri
        track_result['mtime'] = get_mtime(path)
        track_result['key'] = os.path.basename(text_path)
        track_result = order_mpd_track_info(track_result.items())

        result.extend(track_result)

    result.append(('songList end',))
Exemple #27
0
def playlist_uri_to_path(uri, playlists_dir):
    if not uri.startswith('m3u:'):
        raise ValueError('Invalid URI %s' % uri)
    file_path = uri_to_path(uri)
    return os.path.join(playlists_dir, file_path)
Exemple #28
0
def main():
    args = parse_args()
    # TODO: support config files and overrides (shared from main?)
    config_files = [b'/etc/mopidy/mopidy.conf',
                    b'$XDG_CONFIG_DIR/mopidy/mopidy.conf']
    config_overrides = []

    # TODO: decide if we want to avoid this boilerplate some how.
    # Initial config without extensions to bootstrap logging.
    logging_config, _ = config_lib.load(config_files, [], config_overrides)
    log.setup_root_logger()
    log.setup_console_logging(logging_config, args.verbosity_level)

    extensions = ext.load_extensions()
    config, errors = config_lib.load(
        config_files, extensions, config_overrides)
    log.setup_log_levels(config)

    if not config['local']['media_dir']:
        logging.warning('Config value local/media_dir is not set.')
        return

    if not config['local']['scan_timeout']:
        logging.warning('Config value local/scan_timeout is not set.')
        return

    # TODO: missing config error checking and other default setup code.

    updaters = {}
    for e in extensions:
        for updater_class in e.get_library_updaters():
            if updater_class and 'local' in updater_class.uri_schemes:
                updaters[e.ext_name] = updater_class

    if not updaters:
        logging.error('No usable library updaters found.')
        return
    elif len(updaters) > 1:
        logging.error('More than one library updater found. '
                      'Provided by: %s', ', '.join(updaters.keys()))
        return

    local_updater = updaters.values()[0](config)  # TODO: switch to actor?

    media_dir = config['local']['media_dir']

    uris_library = set()
    uris_update = set()
    uris_remove = set()

    logging.info('Checking tracks from library.')
    for track in local_updater.load():
        try:
            stat = os.stat(path.uri_to_path(track.uri))
            if int(stat.st_mtime) > track.last_modified:
                uris_update.add(track.uri)
            uris_library.add(track.uri)
        except OSError:
            uris_remove.add(track.uri)

    logging.info('Removing %d moved or deleted tracks.', len(uris_remove))
    for uri in uris_remove:
        local_updater.remove(uri)

    logging.info('Checking %s for new or modified tracks.', media_dir)
    for uri in path.find_uris(config['local']['media_dir']):
        if uri not in uris_library:
            uris_update.add(uri)

    logging.info('Found %d new or modified tracks.', len(uris_update))

    def store(data):
        track = translator(data)
        local_updater.add(track)
        logging.debug('Added %s', track.uri)

    def debug(uri, error, debug):
        logging.warning('Failed %s: %s', uri, error)
        logging.debug('Debug info for %s: %s', uri, debug)

    scan_timeout = config['local']['scan_timeout']

    logging.info('Scanning new and modified tracks.')
    # TODO: just pass the library in instead?
    scanner = Scanner(uris_update, store, debug, scan_timeout)
    try:
        scanner.start()
    except KeyboardInterrupt:
        scanner.stop()
        raise

    logging.info('Done scanning; commiting changes.')
    local_updater.commit()
Exemple #29
0
 def _query_mtime(self, uri):
     if not uri.startswith('file:'):
         return None
     return os.path.getmtime(path.uri_to_path(uri))
Exemple #30
0
 def test_latin1_in_uri(self):
     result = path.uri_to_path("file:///tmp/%E6%F8%E5")
     self.assertEqual(result, "/tmp/æøå".encode("latin-1"))
Exemple #31
0
 def test_unicode_in_uri(self):
     result = path.uri_to_path("file:///tmp/%C3%A6%C3%B8%C3%A5")
     self.assertEqual(result, "/tmp/æøå".encode("utf-8"))
Exemple #32
0
 def test_space_in_uri(self):
     result = path.uri_to_path("file:///tmp/test%20this")
     self.assertEqual(result, "/tmp/test this".encode("utf-8"))
Exemple #33
0
def local_track_uri_to_path(uri, media_dir):
    if not uri.startswith('local:track:'):
        raise ValueError('Invalid URI.')
    file_path = uri_to_path(uri).split(b':', 1)[1]
    return os.path.join(media_dir, file_path)
Exemple #34
0
 def _delete_m3u(self, uri):
     file_path = path.uri_to_path(uri)
     path.check_file_path_is_inside_base_dir(file_path, self._path)
     if os.path.exists(file_path):
         os.remove(file_path)