Skip to content

Commit

Permalink
Merge tag '0.37.0'
Browse files Browse the repository at this point in the history
"release 0.37.0"
  • Loading branch information
devsnd committed Jul 9, 2016
2 parents 7ec737c + 8bea0a2 commit 3c1ebb8
Show file tree
Hide file tree
Showing 43 changed files with 1,177 additions and 371 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,7 @@ doc/sphinx/_build

res/ngclient/node_modules/
res/ngclient/app/components/
/venv
/venv2

node_modules
4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ language: python
python:
- "2.6"
- "2.7"
- "3.2"
- "3.3"
- "3.4"
- "3.5"
- "pypy"
- "pypy3"

Expand Down Expand Up @@ -43,7 +43,7 @@ matrix:

# command to install dependencies
install:
- "pip install cherrypy${CHERRYPY_VERSION} --no-use-wheel --use-mirrors"
- "pip install cherrypy${CHERRYPY_VERSION} --no-use-wheel"
- "pip install coveralls pyyaml"
- "if [[ $TRAVIS_PYTHON_VERSION = 2.6 ]]; then pip install unittest2 --use-mirrors; fi"

Expand Down
23 changes: 23 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
@@ -1,6 +1,29 @@
Changelog
---------

0.37.0 (2016-07-09)
- FEATURE: support for reading MP4 tags
- FIXED: unicode crash when using cherrypy > 5.4
- FIXED: running the server directly on port 80
- FIXED: transcoding of OGG files with other samplerates than 44khz
- IMPROVEMENT: documented --deleteuser and --changepassword switches
- IMPROVEMENT: don't show remaining time in shuffle mode

0.36.0 (2015-11-21)
- FIXED: *Security* CVE-2015-8309 Download of arbitrary files by logged in users (thanks
feedersec)
- FIXED: *Security* CVE-2015-8310 XSS attack by logged-in users (thanks feedersec)
- FIXED: OGA files are now correctly recognized as ogg-audio files
- FIXED: Sorting tracks by track number correctly
- FIXED: Cannot load playlists containing single quotes
- FEATURE: allow reverse-sorting of playlists (thanks pando85)
- FEATURE: Enabled support of ffmpeg to decode ALAC files
- FEATURE: Added optional support for Pillow as Image Library
- IMPROVEMENT: disabled confirm-to-quit message for playlist downloads
- IMPROVEMENT: Updated TinyTag to version 0.10.1 (much faster ID3 parsing)
- IMPROVEMENT: Predictable selection of album-art images (thanks lzh9102)
- FIXED: Removed restrictions for passwords created in CLI

0.35.2 (2015-04-20)
- FIXED: server not starting on windows

Expand Down
40 changes: 28 additions & 12 deletions audiotranscode/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
MIMETYPES = {
'mp3': 'audio/mpeg',
'ogg': 'audio/ogg',
'oga': 'audio/ogg',
'flac': 'audio/flac',
'aac': 'audio/aac',
'm4a': 'audio/m4a',
Expand Down Expand Up @@ -69,6 +70,8 @@ def encode(self, decoder_process, bitrate):
cmd = [find_executable(self.command[0])] + self.command[1:]
if 'BITRATE' in cmd:
cmd[cmd.index('BITRATE')] = str(bitrate)
if 'KBITRATE' in cmd:
cmd[cmd.index('KBITRATE')] = str(bitrate) + 'k'
return subprocess.Popen(cmd,
stdin=decoder_process.stdout,
stdout=subprocess.PIPE,
Expand Down Expand Up @@ -160,11 +163,9 @@ class AudioTranscode:
or transcode_stream to get a generator of the encoded stream"""
READ_BUFFER = 1024
Encoders = [
#encoders take input from stdin and write output to stout
Encoder('ogg', ['oggenc', '-b', 'BITRATE', '-']),
#doesn't work yet
#Encoder('ogg', ['ffmpeg', '-i', '-', '-f', 'ogg',
# '-acodec', 'vorbis', '-']),
# encoders take input from stdin and write output to stout
# Encoder('ogg', ['ffmpeg', '-i', '-', '-f', 'ogg', '-c:a', 'libvorbis', '-b', 'KBITRATE', '-']),
Encoder('ogg', ['oggenc', '--resample', '44100', '-b', 'BITRATE', '-']),
Encoder('mp3', ['lame', '-b', 'BITRATE', '-', '-']),
Encoder('aac', ['faac', '-b', 'BITRATE', '-P', '-X', '-o', '-', '-']),
Encoder('m4a', ['faac', '-b', 'BITRATE', '-P', '-X', '-o', '-', '-']),
Expand All @@ -181,15 +182,30 @@ class AudioTranscode:
Decoder('mp3', ['ffmpeg', '-ss', 'STARTTIME',
'-i', 'INPUT', '-f', 'wav',
'-acodec', 'pcm_s16le', '-']),
Decoder('wma' , ['ffmpeg', '-ss', 'STARTTIME',
'-i', 'INPUT', '-f', 'wav',
'-acodec', 'pcm_s16le', '-']),
Decoder('ogg', ['oggdec', '-Q', '-b', '16', '-o', '-', 'INPUT']),
Decoder('ogg', ['ffmpeg', '-ss', 'STARTTIME',
'-i', 'INPUT', '-f', 'wav',
Decoder('wma', ['ffmpeg', '-ss', 'STARTTIME',
'-i', 'INPUT', '-f', 'wav',
'-acodec', 'pcm_s16le', '-']),
Decoder('ogg', ['oggdec', '-Q', '-b', '16', '-o', '-', 'INPUT']),
Decoder('ogg', ['ffmpeg',
'-ss', 'STARTTIME',
'-i', 'INPUT',
'-f', 'wav',
'-acodec', 'pcm_s16le',
'-']),
# duplicate ogg decoders for oga files
Decoder('oga', ['oggdec', '-Q', '-b', '16', '-o', '-', 'INPUT']),
Decoder('oga', ['ffmpeg',
'-ss', 'STARTTIME',
'-i', 'INPUT',
'-f', 'wav',
'-acodec', 'pcm_s16le',
'-']),
Decoder('flac', ['flac', '-F', '-d', '-c', 'INPUT']),
Decoder('aac', ['faad', '-w', 'INPUT']),
# prefer ffmpeg over faad for decoding to handle ALAC streams #584
Decoder('m4a', ['ffmpeg', '-ss', 'STARTTIME',
'-i', 'INPUT', '-f', 'wav',
'-acodec', 'pcm_s16le', '-']),
Decoder('m4a', ['faad', '-w', 'INPUT']),
Decoder('wav', ['cat', 'INPUT']),
Decoder('opus', ['opusdec', 'INPUT', '--force-wav', '--quiet', '-']),
Expand Down Expand Up @@ -282,6 +298,7 @@ def transcode_stream(self, filepath, newformat, bitrate=None,
time.sleep(0.1) # wait for new data...
break
yield data
yield encoder_process.stdout.read()
finally:
if decoder_process and decoder_process.poll() is None:
if decoder_process.stderr:
Expand All @@ -292,7 +309,6 @@ def transcode_stream(self, filepath, newformat, bitrate=None,
decoder_process.stdin.close()
decoder_process.terminate()
if encoder_process:
encoder_process.stdout.read()
encoder_process.stdout.close()
if encoder_process.stdin:
encoder_process.stdin.close()
Expand Down
15 changes: 14 additions & 1 deletion cherrymusic
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env python3
#
# CherryMusic - a standalone music server
# Copyright (c) 2012 - 2015 Tom Wallroth & Tilman Boerner
# Copyright (c) 2012 - 2016 Tom Wallroth & Tilman Boerner
#
# Project page:
# http://fomori.org/cherrymusic/
Expand Down Expand Up @@ -162,7 +162,10 @@ else:
parser.add_argument('--newconfig', dest='newconfig', action='store_true', help='Create a new config file next to your current one, e.g. ~/.config/cherrymusic/cherrymusic.conf.new.')
parser.add_argument('--dropfiledb', dest='dropfiledb', action='store_true', help='Clear the file database. This might be necessary after a version jump.')
parser.add_argument('--setup', dest='setup', action='store_true', help='Configure CherryMusic in your browser.')

parser.add_argument('--adduser', dest='adduser', nargs=2, metavar=('USERNAME', 'PASSWORD'), default=None, help='Create a new user with the given password.')
parser.add_argument('--deleteuser', dest='deleteuser', nargs=1, metavar=('USERNAME',), default=None, help='Delete a user')
parser.add_argument('--changepassword', dest='changepassword', nargs=2, metavar=('USERNAME', 'PASSWORD'), default=None, help='Change the password of a user')

ConfigOptions.addShortcutOption(parser, ('--port', '-p'), key='server.port', type=int, help='Set the port the server will listen to.')
ConfigOptions.addGeneralOption(parser, ('--conf', '-c'), help='Override configuration values.')
Expand Down Expand Up @@ -215,6 +218,16 @@ if __name__ == "__main__":
success = cherrymusicserver.create_user(username, password)
sys.exit(0 if success else 1)

if args.deleteuser:
username = args.deleteuser[0]
success = cherrymusicserver.delete_user(username)
sys.exit(0 if success else 1)

if args.changepassword:
username, password = args.changepassword
success = cherrymusicserver.change_password(username, password)
sys.exit(0 if success else 1)

if args.update is not None:
cherrymusicserver.update_filedb(args.update)
if not args.setup:
Expand Down
71 changes: 51 additions & 20 deletions cherrymusicserver/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# -*- coding: utf-8 -*-
#
# CherryMusic - a standalone music server
# Copyright (c) 2012 - 2015 Tom Wallroth & Tilman Boerner
# Copyright (c) 2012 - 2016 Tom Wallroth & Tilman Boerner
#
# Project page:
# http://fomori.org/cherrymusic/
Expand Down Expand Up @@ -32,7 +32,7 @@
#python 2.6+ backward compability
from __future__ import unicode_literals

VERSION = "0.35.2"
VERSION = "0.37.0"
__version__ = VERSION
DESCRIPTION = "an mp3 server for your browser"
LONG_DESCRIPTION = """CherryMusic is a music streaming
Expand Down Expand Up @@ -148,20 +148,40 @@ def fake_wait_for_occupied_port(host, port):
cherrypy.process.servers.wait_for_occupied_port = fake_wait_for_occupied_port
# end of port patch

# workaround for cherrypy not using unicode strings for URI, see:
# https://bitbucket.org/cherrypy/cherrypy/issue/1148/wrong-encoding-for-urls-containing-utf-8
cherrypy.lib.static.__serve_file = cherrypy.lib.static.serve_file

def serve_file_utf8_fix(path, content_type=None, disposition=None,
name=None, debug=False):
if sys.version_info >= (3,):
#python3+
# see also below: mirrored mangling of basedir for '/serve' static dir
path = codecs.decode(codecs.encode(path, 'latin-1'), 'utf-8')
return cherrypy.lib.static.__serve_file(path, content_type,
disposition, name, debug)
cherrypy.lib.static.serve_file = serve_file_utf8_fix
# end of unicode workaround
# trying to detect the version to determine if we need to monkeypatch cherrypy
if cherrypy.__version__ == 'unknown':
print(_(
'Could not determine cherrypy version. Please install cherrypy '
'using pip or your OS\'s package manager. Trying to detect version '
'automatically.'
))
try:
# this decorator was added between 5.4 and 5.5
# https://github.com/cherrypy/cherrypy/pull/1428
# commit: dff09e92fb2e83fb4248826c9bc14cd3b6281706
import cherrypy._cptools.register
needs_serve_file_utf8_fix = False
except ImportError:
needs_serve_file_utf8_fix = True
else:
cherrypy_version = tuple(int(v) for v in cherrypy.__version__.split('.'))
needs_serve_file_utf8_fix = cherrypy_version < (5, 5)

if needs_serve_file_utf8_fix:
# workaround for cherrypy < 5.5.0 not using unicode strings for URI, see:
# https://bitbucket.org/cherrypy/cherrypy/issue/1148/wrong-encoding-for-urls-containing-utf-8
cherrypy.lib.static.__serve_file = cherrypy.lib.static.serve_file

def serve_file_utf8_fix(path, content_type=None, disposition=None,
name=None, debug=False):
if sys.version_info >= (3,):
#python3+
# see also below: mirrored mangling of basedir for '/serve' static dir
path = codecs.decode(codecs.encode(path, 'latin-1'), 'utf-8')
return cherrypy.lib.static.__serve_file(path, content_type,
disposition, name, debug)
cherrypy.lib.static.serve_file = serve_file_utf8_fix
# end of unicode workaround

from cherrymusicserver import configuration as cfg
config = None
Expand Down Expand Up @@ -262,12 +282,23 @@ def start_server(cfg_override=None):
def create_user(username, password):
""" Creates a non-admin user with given username and password """
non_alnum = re.compile('[^a-z0-9]', re.IGNORECASE)
if non_alnum.findall(username) or non_alnum.findall(password):
log.e(_('username and password may only contain english letters'
' and digits'))
if non_alnum.findall(username):
log.e(_('usernames may only contain letters and digits'))
return False
return service.get('users').addUser(username, password, admin=False)

def delete_user(username):
userservice = service.get('users')
userid = userservice.getIdByName(username)
if userid is None:
log.e(_('user with the name "%s" does not exist!'), username)
return False
return userservice.deleteUser(userid)

def change_password(username, password):
userservice = service.get('users')
result = userservice.changePassword(username, password)
return result == 'success'

def update_filedb(paths):
""" Updates the file database in a separate thread,
Expand Down Expand Up @@ -337,7 +368,7 @@ def create_pid_file(cls):
os.getpgid(int(pidfile.read()))
sys.exit(_("""============================================
Process id file %s already exists.
I've you are sure that cherrymusic is not running, you can delete this file and restart cherrymusic.
If you are sure that cherrymusic is not running, you can delete this file and restart cherrymusic.
============================================""") % pathprovider.pidFile())
except OSError:
print('Stale process id file, removing.')
Expand Down
Loading

0 comments on commit 3c1ebb8

Please sign in to comment.