Setting up vanilla docker for testing; Beginning syntax upgrade
This commit is contained in:
57
Dockerfile
57
Dockerfile
@ -1,55 +1,24 @@
|
||||
FROM debian:buster-slim
|
||||
FROM debian:buster
|
||||
|
||||
RUN set -ex \
|
||||
# Official Mopidy install for Debian/Ubuntu along with some extensions
|
||||
# (see https://docs.mopidy.com/en/latest/installation/debian/ )
|
||||
&& apt-get update \
|
||||
&& DEBIAN_FRONTEND=noninteractive apt-get install -y \
|
||||
curl \
|
||||
dumb-init \
|
||||
gcc \
|
||||
gnupg \
|
||||
python3-pip \
|
||||
gstreamer1.0-alsa \
|
||||
gstreamer1.0-plugins-bad \
|
||||
python-crypto \
|
||||
python-pykka \
|
||||
python-tornado \
|
||||
python3-gst-1.0 \
|
||||
git \
|
||||
nano \
|
||||
sudo \
|
||||
&& curl -L https://apt.mopidy.com/mopidy.gpg | apt-key add - \
|
||||
&& curl -L https://apt.mopidy.com/mopidy.list -o /etc/apt/sources.list.d/mopidy.list \
|
||||
&& apt-get update \
|
||||
&& DEBIAN_FRONTEND=noninteractive apt-get install -y \
|
||||
mopidy \
|
||||
mopidy-soundcloud \
|
||||
mopidy-spotify \
|
||||
&& curl -L https://bootstrap.pypa.io/get-pip.py | python - \
|
||||
&& pip install -U six pyasn1 requests[security] cryptography \
|
||||
&& pip install \
|
||||
Mopidy-Local-Images \
|
||||
Mopidy-Local-SQLite \
|
||||
Mopidy-Spotify-Web \
|
||||
Mopidy-GMusic \
|
||||
Mopidy-Pandora \
|
||||
pyopenssl \
|
||||
&& apt-get -f install \
|
||||
# Clean-up
|
||||
&& apt-get purge --auto-remove -y \
|
||||
curl \
|
||||
gcc \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* ~/.cache \
|
||||
# Clone Iris from the repository and install in development mode.
|
||||
# This allows a binding at "/iris" to map to your local folder for development, rather than
|
||||
# installing using pip.
|
||||
&& python3 -m pip install --pre mopidy \
|
||||
&& git clone https://github.com/jaedb/Iris.git /iris \
|
||||
&& cd /iris \
|
||||
&& python setup.py develop \
|
||||
&& mkdir -p /var/lib/mopidy/.config \
|
||||
&& ln -s /config /var/lib/mopidy/.config/mopidy \
|
||||
# Allow mopidy user to run system commands (restart, local scan, etc)
|
||||
&& echo "mopidy ALL=NOPASSWD: /iris/mopidy_iris/system.sh" >> /etc/sudoers
|
||||
&& ln -s /config /var/lib/mopidy/.config/mopidy
|
||||
|
||||
# Start helper script.
|
||||
COPY docker/entrypoint.sh /entrypoint.sh
|
||||
@ -62,17 +31,9 @@ COPY docker/pulse-client.conf /etc/pulse/client.conf
|
||||
|
||||
# Allows any user to run mopidy, but runs by default as a randomly generated UID/GID.
|
||||
ENV HOME=/var/lib/mopidy
|
||||
RUN set -ex \
|
||||
&& usermod -G audio,sudo mopidy \
|
||||
&& chown mopidy:audio -R $HOME /entrypoint.sh /iris \
|
||||
&& chmod go+rwx -R $HOME /entrypoint.sh /iris
|
||||
|
||||
# Runs as mopidy user by default.
|
||||
USER mopidy:audio
|
||||
EXPOSE 6600 6680
|
||||
|
||||
VOLUME ["/var/lib/mopidy/local", "/var/lib/mopidy/local-images", "/iris"]
|
||||
|
||||
EXPOSE 6600 6680 1704 1705 5555/udp
|
||||
|
||||
ENTRYPOINT ["/usr/bin/dumb-init", "/entrypoint.sh"]
|
||||
CMD ["/usr/bin/mopidy"]
|
||||
CMD ["/bin/bash"]
|
||||
#ENTRYPOINT ["/usr/bin/dumb-init", "/entrypoint.sh"]
|
||||
#CMD ["mopidy"]
|
||||
|
||||
@ -1,15 +1,14 @@
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import logging, os, json
|
||||
import logging, os, json, pathlib
|
||||
import tornado.web
|
||||
import tornado.websocket
|
||||
import handlers
|
||||
|
||||
from mopidy import config, ext
|
||||
from frontend import IrisFrontend
|
||||
from handlers import WebsocketHandler, HttpHandler
|
||||
from core import IrisCore
|
||||
from .frontend import IrisFrontend
|
||||
from .handlers import WebsocketHandler, HttpHandler
|
||||
from .core import IrisCore
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
__version__ = '3.42.2'
|
||||
@ -63,6 +62,7 @@ class Extension( ext.Extension ):
|
||||
class ReactRouterHandler(tornado.web.StaticFileHandler):
|
||||
def initialize(self, path):
|
||||
self.path = path
|
||||
self.absolute_path = path
|
||||
self.dirname, self.filename = os.path.split(path)
|
||||
super(ReactRouterHandler, self).initialize(self.dirname)
|
||||
|
||||
@ -74,7 +74,7 @@ class ReactRouterHandler(tornado.web.StaticFileHandler):
|
||||
##
|
||||
def iris_factory(config, core):
|
||||
|
||||
path = os.path.join( os.path.dirname(__file__), 'static')
|
||||
path = pathlib.Path(__file__).parent / "static"
|
||||
|
||||
return [
|
||||
(
|
||||
@ -104,7 +104,7 @@ def iris_factory(config, core):
|
||||
r'/assets/(.*)',
|
||||
tornado.web.StaticFileHandler,
|
||||
{
|
||||
'path': path+'/assets'
|
||||
'path': str(path)+'/assets'
|
||||
}
|
||||
),
|
||||
(
|
||||
@ -117,7 +117,7 @@ def iris_factory(config, core):
|
||||
(
|
||||
r'/(.*)',
|
||||
ReactRouterHandler, {
|
||||
'path': path+'/index.html'
|
||||
'path': str(path)+'/index.html'
|
||||
}
|
||||
),
|
||||
]
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import random, string, logging, json, pykka, urllib, urllib2, os, sys, mopidy_iris, subprocess
|
||||
import random, string, logging, json, pykka, urllib, os, sys, mopidy_iris, subprocess
|
||||
import tornado.web
|
||||
import tornado.ioloop
|
||||
import tornado.httpclient
|
||||
@ -407,10 +407,10 @@ class IrisCore(pykka.ThreadingActor):
|
||||
def get_version(self, *args, **kwargs):
|
||||
callback = kwargs.get('callback', False)
|
||||
url = 'https://pypi.python.org/pypi/Mopidy-Iris/json'
|
||||
req = urllib2.Request(url)
|
||||
req = urllib.request(url)
|
||||
|
||||
try:
|
||||
response = urllib2.urlopen(req, timeout=30).read()
|
||||
response = urllib.urlopen(req, timeout=30).read()
|
||||
response = json.loads(response)
|
||||
latest_version = response['info']['version']
|
||||
|
||||
@ -418,7 +418,7 @@ class IrisCore(pykka.ThreadingActor):
|
||||
upgrade_available = cmp( parse_version( latest_version ), parse_version( self.version ) )
|
||||
upgrade_available = ( upgrade_available == 1 )
|
||||
|
||||
except (urllib2.HTTPError, urllib2.URLError) as e:
|
||||
except (urllib.HTTPError, urllib.URLError) as e:
|
||||
latest_version = '0.0.0'
|
||||
upgrade_available = False
|
||||
|
||||
@ -694,10 +694,10 @@ class IrisCore(pykka.ThreadingActor):
|
||||
url = url+'&seed_tracks='+(",".join(self.radio['seed_tracks'])).replace('spotify:track:','')
|
||||
url = url+'&limit=50'
|
||||
|
||||
req = urllib2.Request(url)
|
||||
req = urllib.request(url)
|
||||
req.add_header('Authorization', 'Bearer '+access_token)
|
||||
|
||||
response = urllib2.urlopen(req, timeout=30).read()
|
||||
response = urllib.urlopen(req, timeout=30).read()
|
||||
response_dict = json.loads(response)
|
||||
|
||||
uris = []
|
||||
@ -998,7 +998,7 @@ class IrisCore(pykka.ThreadingActor):
|
||||
else:
|
||||
return response
|
||||
|
||||
except (urllib2.HTTPError, urllib2.URLError) as e:
|
||||
except (urllib.HTTPError, urllib.URLError) as e:
|
||||
error = json.loads(e.read())
|
||||
error = {'message': 'Could not refresh token: '+error['error_description']}
|
||||
|
||||
@ -1035,7 +1035,7 @@ class IrisCore(pykka.ThreadingActor):
|
||||
try:
|
||||
path = request.get_argument('path')
|
||||
url = 'https://genius.com'+path
|
||||
except Exception, e:
|
||||
except Exception as e:
|
||||
logger.error(e)
|
||||
error = {
|
||||
'message': "Path not valid",
|
||||
@ -1051,7 +1051,7 @@ class IrisCore(pykka.ThreadingActor):
|
||||
'description': 'Connection '+connection_id+' not connected'
|
||||
}
|
||||
|
||||
except Exception, e:
|
||||
except Exception as e:
|
||||
logger.error(e)
|
||||
error = {
|
||||
'message': "Unauthorized request",
|
||||
|
||||
@ -2,9 +2,9 @@
|
||||
from __future__ import unicode_literals
|
||||
from mopidy.core import CoreListener
|
||||
|
||||
import mem
|
||||
import pykka
|
||||
import logging
|
||||
from .mem import mem
|
||||
|
||||
# import logger
|
||||
logger = logging.getLogger(__name__)
|
||||
@ -16,7 +16,7 @@ class IrisFrontend(pykka.ThreadingActor, CoreListener):
|
||||
mem.iris.core = core
|
||||
mem.iris.config = config
|
||||
|
||||
def on_start(self):
|
||||
def on_start(self):
|
||||
mem.iris.start()
|
||||
|
||||
def on_stop(self):
|
||||
@ -27,4 +27,3 @@ class IrisFrontend(pykka.ThreadingActor, CoreListener):
|
||||
|
||||
def tracklist_changed(self):
|
||||
mem.iris.clean_queue_metadata()
|
||||
|
||||
@ -3,16 +3,18 @@ from __future__ import unicode_literals
|
||||
from datetime import datetime
|
||||
from tornado.escape import json_encode, json_decode
|
||||
import tornado.ioloop, tornado.web, tornado.websocket, tornado.template
|
||||
import random, string, logging, uuid, subprocess, pykka, ast, logging, json, urllib, urllib2, mem, requests, time
|
||||
import random, string, logging, uuid, subprocess, pykka, ast, logging, json, urllib, requests, time
|
||||
|
||||
from .mem import mem
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class WebsocketHandler(tornado.websocket.WebSocketHandler):
|
||||
|
||||
|
||||
# initiate (not the actual object __init__, but run shortly after)
|
||||
def initialize(self, core, config):
|
||||
self.core = core
|
||||
self.config = config
|
||||
self.core = core
|
||||
self.config = config
|
||||
|
||||
def check_origin(self, origin):
|
||||
return True
|
||||
@ -31,14 +33,14 @@ class WebsocketHandler(tornado.websocket.WebSocketHandler):
|
||||
'created': datetime.strftime(datetime.now(), '%Y-%m-%d %H:%M:%S')
|
||||
}
|
||||
|
||||
self.connection_id = client['connection_id']
|
||||
self.connection_id = client['connection_id']
|
||||
|
||||
mem.iris.add_connection(connection=self, client=client)
|
||||
|
||||
|
||||
|
||||
def on_message(self, message):
|
||||
logger.debug("Iris websocket message received: "+message)
|
||||
|
||||
|
||||
message = json_decode(message)
|
||||
|
||||
if 'id' in message:
|
||||
@ -48,7 +50,7 @@ class WebsocketHandler(tornado.websocket.WebSocketHandler):
|
||||
|
||||
if 'jsonrpc' not in message:
|
||||
self.handle_result(id=id, error={'id': id, 'code': 32602, 'message': 'Invalid JSON-RPC request (missing property "jsonrpc")'})
|
||||
|
||||
|
||||
if 'params' in message:
|
||||
params = message['params']
|
||||
|
||||
@ -66,7 +68,7 @@ class WebsocketHandler(tornado.websocket.WebSocketHandler):
|
||||
if hasattr(mem.iris, message['method']):
|
||||
try:
|
||||
getattr(mem.iris, message['method'])(data=params, callback=lambda response, error=False: self.handle_result(id=id, method=message['method'], response=response, error=error))
|
||||
except Exception, e:
|
||||
except Exception as e:
|
||||
logger.error(str(e))
|
||||
|
||||
else:
|
||||
@ -108,7 +110,7 @@ class WebsocketHandler(tornado.websocket.WebSocketHandler):
|
||||
# Just a regular json object, so not an external request
|
||||
else:
|
||||
request_response['result'] = response
|
||||
|
||||
|
||||
# Respond to the original request
|
||||
data = request_response
|
||||
data['recipient'] = self.connection_id
|
||||
@ -118,12 +120,12 @@ class WebsocketHandler(tornado.websocket.WebSocketHandler):
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class HttpHandler(tornado.web.RequestHandler):
|
||||
|
||||
def set_default_headers(self):
|
||||
self.set_header("Access-Control-Allow-Origin", "*")
|
||||
self.set_header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization, Client-Security-Token, Accept-Encoding")
|
||||
self.set_header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization, Client-Security-Token, Accept-Encoding")
|
||||
|
||||
def initialize(self, core, config):
|
||||
self.core = core
|
||||
@ -134,8 +136,7 @@ class HttpHandler(tornado.web.RequestHandler):
|
||||
def options(self, slug=None):
|
||||
self.set_status(204)
|
||||
self.finish()
|
||||
|
||||
@tornado.web.asynchronous
|
||||
|
||||
def get(self, slug=None):
|
||||
|
||||
id = int(time.time())
|
||||
@ -144,21 +145,20 @@ class HttpHandler(tornado.web.RequestHandler):
|
||||
if hasattr(mem.iris, slug):
|
||||
try:
|
||||
getattr(mem.iris, slug)(request=self, callback=lambda response, error=False: self.handle_result(id=id, method=slug, response=response, error=error))
|
||||
except Exception, e:
|
||||
except Exception as e:
|
||||
logger.error(str(e))
|
||||
|
||||
|
||||
else:
|
||||
self.handle_result(id=id, error={'code': 32601, 'message': "Method "+slug+" does not exist"})
|
||||
return
|
||||
|
||||
@tornado.web.asynchronous
|
||||
def post(self, slug=None):
|
||||
|
||||
id = int(time.time())
|
||||
|
||||
try:
|
||||
params = json.loads(self.request.body.decode('utf-8'))
|
||||
except:
|
||||
except:
|
||||
self.handle_result(id=id, error={'code': 32700, 'message': "Missing or invalid payload"})
|
||||
return
|
||||
|
||||
@ -167,7 +167,7 @@ class HttpHandler(tornado.web.RequestHandler):
|
||||
try:
|
||||
getattr(mem.iris, slug)(data=params, request=self.request, callback=lambda response=False, error=False: self.handle_result(id=id, method=slug, response=response, error=error))
|
||||
|
||||
except urllib2.HTTPError as e:
|
||||
except HTTPError as e:
|
||||
self.handle_result(id=id, error={'code': 32601, 'message': "Invalid JSON payload"})
|
||||
return
|
||||
|
||||
@ -222,4 +222,4 @@ class HttpHandler(tornado.web.RequestHandler):
|
||||
self.finish()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -20,7 +20,7 @@ class IrisSystemThread(Thread):
|
||||
|
||||
try:
|
||||
self.can_run()
|
||||
except Exception, e:
|
||||
except Exception as e:
|
||||
logger.error(e)
|
||||
|
||||
error = {
|
||||
|
||||
Reference in New Issue
Block a user