local: Remove local-json as a split out extension.
Will be re-added using the new library interface. This commit does break tests.
This commit is contained in:
parent
4c0b54317b
commit
7e063774b3
@ -95,34 +95,7 @@ Pluggable library support
|
||||
-------------------------
|
||||
|
||||
Local libraries are fully pluggable. What this means is that users may opt to
|
||||
disable the current default library ``local-json``, replacing it with a third
|
||||
disable the current default library ``json``, replacing it with a third
|
||||
party one. When running :command:`mopidy local scan` mopidy will populate
|
||||
whatever the current active library is with data. Only one library may be
|
||||
active at a time.
|
||||
|
||||
|
||||
*****************
|
||||
Mopidy-Local-JSON
|
||||
*****************
|
||||
|
||||
Extension for storing local music library in a JSON file, default built in
|
||||
library for local files.
|
||||
|
||||
|
||||
Default configuration
|
||||
=====================
|
||||
|
||||
.. literalinclude:: ../../mopidy/backends/local/json/ext.conf
|
||||
:language: ini
|
||||
|
||||
|
||||
Configuration values
|
||||
====================
|
||||
|
||||
.. confval:: local-json/enabled
|
||||
|
||||
If the local-json extension should be enabled or not.
|
||||
|
||||
.. confval:: local-json/json_file
|
||||
|
||||
Path to a file to store the gzipped JSON data in.
|
||||
|
||||
@ -1,30 +0,0 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import os
|
||||
|
||||
import mopidy
|
||||
from mopidy import config, ext
|
||||
|
||||
|
||||
class Extension(ext.Extension):
|
||||
|
||||
dist_name = 'Mopidy-Local-JSON'
|
||||
ext_name = 'local-json'
|
||||
version = mopidy.__version__
|
||||
|
||||
def get_default_config(self):
|
||||
conf_file = os.path.join(os.path.dirname(__file__), 'ext.conf')
|
||||
return config.read(conf_file)
|
||||
|
||||
def get_config_schema(self):
|
||||
schema = super(Extension, self).get_config_schema()
|
||||
schema['json_file'] = config.Path()
|
||||
return schema
|
||||
|
||||
def get_backend_classes(self):
|
||||
from .actor import LocalJsonBackend
|
||||
return [LocalJsonBackend]
|
||||
|
||||
def get_library_updaters(self):
|
||||
from .library import LocalJsonLibraryUpdateProvider
|
||||
return [LocalJsonLibraryUpdateProvider]
|
||||
@ -1,30 +0,0 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import logging
|
||||
import os
|
||||
|
||||
import pykka
|
||||
|
||||
from mopidy.backends import base
|
||||
from mopidy.utils import encoding
|
||||
|
||||
from . import library
|
||||
|
||||
logger = logging.getLogger('mopidy.backends.local.json')
|
||||
|
||||
|
||||
class LocalJsonBackend(pykka.ThreadingActor, base.Backend):
|
||||
def __init__(self, config, audio):
|
||||
super(LocalJsonBackend, self).__init__()
|
||||
|
||||
self.config = config
|
||||
self.library = library.LocalJsonLibraryProvider(backend=self)
|
||||
self.uri_schemes = ['local']
|
||||
|
||||
if not os.path.exists(config['local-json']['json_file']):
|
||||
try:
|
||||
library.write_library(config['local-json']['json_file'], {})
|
||||
logger.info('Created empty local JSON library.')
|
||||
except EnvironmentError as error:
|
||||
error = encoding.locale_decode(error)
|
||||
logger.warning('Could not create local library: %s', error)
|
||||
@ -1,3 +0,0 @@
|
||||
[local-json]
|
||||
enabled = true
|
||||
json_file = $XDG_DATA_DIR/mopidy/local/library.json.gz
|
||||
@ -1,108 +0,0 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import gzip
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import tempfile
|
||||
|
||||
import mopidy
|
||||
from mopidy import models
|
||||
from mopidy.backends import base
|
||||
from mopidy.backends.local import search
|
||||
|
||||
logger = logging.getLogger('mopidy.backends.local.json')
|
||||
|
||||
|
||||
def load_library(json_file):
|
||||
try:
|
||||
with gzip.open(json_file, 'rb') as fp:
|
||||
return json.load(fp, object_hook=models.model_json_decoder)
|
||||
except (IOError, ValueError) as e:
|
||||
logger.warning('Loading JSON local library failed: %s', e)
|
||||
return {}
|
||||
|
||||
|
||||
def write_library(json_file, data):
|
||||
data['version'] = mopidy.__version__
|
||||
directory, basename = os.path.split(json_file)
|
||||
|
||||
# TODO: cleanup directory/basename.* files.
|
||||
tmp = tempfile.NamedTemporaryFile(
|
||||
prefix=basename + '.', dir=directory, delete=False)
|
||||
|
||||
try:
|
||||
with gzip.GzipFile(fileobj=tmp, mode='wb') as fp:
|
||||
json.dump(data, fp, cls=models.ModelJSONEncoder,
|
||||
indent=2, separators=(',', ': '))
|
||||
os.rename(tmp.name, json_file)
|
||||
finally:
|
||||
if os.path.exists(tmp.name):
|
||||
os.remove(tmp.name)
|
||||
|
||||
|
||||
class LocalJsonLibraryProvider(base.BaseLibraryProvider):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(LocalJsonLibraryProvider, self).__init__(*args, **kwargs)
|
||||
self._uri_mapping = {}
|
||||
self._media_dir = self.backend.config['local']['media_dir']
|
||||
self._json_file = self.backend.config['local-json']['json_file']
|
||||
self.refresh()
|
||||
|
||||
def refresh(self, uri=None):
|
||||
logger.debug(
|
||||
'Loading local tracks from %s using %s',
|
||||
self._media_dir, self._json_file)
|
||||
|
||||
tracks = load_library(self._json_file).get('tracks', [])
|
||||
uris_to_remove = set(self._uri_mapping)
|
||||
|
||||
for track in tracks:
|
||||
self._uri_mapping[track.uri] = track
|
||||
uris_to_remove.discard(track.uri)
|
||||
|
||||
for uri in uris_to_remove:
|
||||
del self._uri_mapping[uri]
|
||||
|
||||
logger.info(
|
||||
'Loaded %d local tracks from %s using %s',
|
||||
len(tracks), self._media_dir, self._json_file)
|
||||
|
||||
def lookup(self, uri):
|
||||
try:
|
||||
return [self._uri_mapping[uri]]
|
||||
except KeyError:
|
||||
logger.debug('Failed to lookup %r', uri)
|
||||
return []
|
||||
|
||||
def find_exact(self, query=None, uris=None):
|
||||
tracks = self._uri_mapping.values()
|
||||
return search.find_exact(tracks, query=query, uris=uris)
|
||||
|
||||
def search(self, query=None, uris=None):
|
||||
tracks = self._uri_mapping.values()
|
||||
return search.search(tracks, query=query, uris=uris)
|
||||
|
||||
|
||||
class LocalJsonLibraryUpdateProvider(base.BaseLibraryProvider):
|
||||
uri_schemes = ['local']
|
||||
|
||||
def __init__(self, config):
|
||||
self._tracks = {}
|
||||
self._media_dir = config['local']['media_dir']
|
||||
self._json_file = config['local-json']['json_file']
|
||||
|
||||
def load(self):
|
||||
for track in load_library(self._json_file).get('tracks', []):
|
||||
self._tracks[track.uri] = track
|
||||
return self._tracks.values()
|
||||
|
||||
def add(self, track):
|
||||
self._tracks[track.uri] = track
|
||||
|
||||
def remove(self, uri):
|
||||
if uri in self._tracks:
|
||||
del self._tracks[uri]
|
||||
|
||||
def commit(self):
|
||||
write_library(self._json_file, {'tracks': self._tracks.values()})
|
||||
Loading…
Reference in New Issue
Block a user