def create_application(): global app if not config.check(): return None if not os.path.exists(config.get('base', 'cache_dir')): os.makedirs(config.get('base', 'cache_dir')) app = Flask(__name__) app.secret_key = '?9huDM\\H' app.teardown_appcontext(teardown_db) if config.get('base', 'log_file'): import logging from logging.handlers import TimedRotatingFileHandler handler = TimedRotatingFileHandler(config.get('base', 'log_file'), when = 'midnight') handler.setLevel(logging.WARNING) app.logger.addHandler(handler) from supysonic import frontend from supysonic import api return app
def cover_art(): status, res = get_entity(request, Folder) if not status: return res if not res.has_cover_art or not os.path.isfile(os.path.join(res.path, 'cover.jpg')): return request.error_formatter(70, 'Cover art not found') size = request.values.get('size') if size: try: size = int(size) except: return request.error_formatter(0, 'Invalid size value') else: return send_file(os.path.join(res.path, 'cover.jpg')) im = Image.open(os.path.join(res.path, 'cover.jpg')) if size > im.size[0] and size > im.size[1]: return send_file(os.path.join(res.path, 'cover.jpg')) size_path = os.path.join(config.get('webapp', 'cache_dir'), str(size)) path = os.path.join(size_path, str(res.id)) if os.path.exists(path): return send_file(path) if not os.path.exists(size_path): os.makedirs(size_path) im.thumbnail([size, size], Image.ANTIALIAS) im.save(path, 'JPEG') return send_file(path)
def cover_art(): status, res = get_entity(request, Folder) if not status: return res if not res.has_cover_art or not os.path.isfile(os.path.join(res.path, 'cover.jpg')): return request.error_formatter(70, 'Cover art not found') size = request.args.get('size') if size: try: size = int(size) except: return request.error_formatter(0, 'Invalid size value') else: return send_file(os.path.join(res.path, 'cover.jpg')) im = Image.open(os.path.join(res.path, 'cover.jpg')) if size > im.size[0] and size > im.size[1]: return send_file(os.path.join(res.path, 'cover.jpg')) size_path = os.path.join(config.get('webapp', 'cache_dir'), str(size)) path = os.path.join(size_path, str(res.id)) if os.path.exists(path): return send_file(path) if not os.path.exists(size_path): os.makedirs(size_path) im.thumbnail([size, size], Image.ANTIALIAS) im.save(path, 'JPEG') return send_file(path)
def __init__(self, store): self.__store = store self.__added_artists = 0 self.__added_albums = 0 self.__added_tracks = 0 self.__deleted_artists = 0 self.__deleted_albums = 0 self.__deleted_tracks = 0 extensions = config.get('base', 'scanner_extensions') self.__extensions = map(str.lower, extensions.split()) if extensions else None
def create_application(): global app if not config.check(): return None if not os.path.exists(config.get('webapp', 'cache_dir')): os.makedirs(config.get('webapp', 'cache_dir')) app = Flask(__name__) app.secret_key = '?9huDM\\H' app.teardown_appcontext(teardown_db) if config.get('webapp', 'log_file'): import logging from logging.handlers import TimedRotatingFileHandler handler = TimedRotatingFileHandler(config.get('webapp', 'log_file'), when = 'midnight') if config.get('webapp', 'log_level'): mapping = { 'DEBUG': logging.DEBUG, 'INFO': logging.INFO, 'WARNING': logging.WARNING, 'ERROR': logging.ERROR, 'CRTICAL': logging.CRITICAL } handler.setLevel(mapping.get(config.get('webapp', 'log_level').upper(), logging.NOTSET)) app.logger.addHandler(handler) from supysonic import frontend from supysonic import api return app
def __init__(self, store): self.__store = store self.__added_artists = 0 self.__added_albums = 0 self.__added_tracks = 0 self.__deleted_artists = 0 self.__deleted_albums = 0 self.__deleted_tracks = 0 extensions = config.get('base', 'scanner_extensions') self.__extensions = map(str.lower, extensions.split()) if extensions else None self.__folders_to_check = set() self.__artists_to_check = set() self.__albums_to_check = set()
def __init__(self, store, force = False): self.__store = store self.__force = force self.__added_artists = 0 self.__added_albums = 0 self.__added_tracks = 0 self.__deleted_artists = 0 self.__deleted_albums = 0 self.__deleted_tracks = 0 extensions = config.get('base', 'scanner_extensions') self.__extensions = map(str.lower, extensions.split()) if extensions else None self.__folders_to_check = set() self.__artists_to_check = set() self.__albums_to_check = set()
def create_application(): global app # Check config for mandatory fields config.check() # Test for the cache directory if not path.exists(config.get('webapp', 'cache_dir')): makedirs(config.get('webapp', 'cache_dir')) # Flask! app = Flask(__name__) # Set a secret key for sessions secret_key = config.get('base', 'secret_key') # If secret key is not defined in config, set develop key if secret_key is None: app.secret_key = 'd3v3l0p' else: app.secret_key = secret_key # Close database connection on teardown app.teardown_appcontext(close_db) # Set loglevel if config.get('webapp', 'log_file'): import logging from logging.handlers import TimedRotatingFileHandler handler = TimedRotatingFileHandler(config.get('webapp', 'log_file'), when = 'midnight') if config.get('webapp', 'log_level'): mapping = { 'DEBUG': logging.DEBUG, 'INFO': logging.INFO, 'WARNING': logging.WARNING, 'ERROR': logging.ERROR, 'CRTICAL': logging.CRITICAL } handler.setLevel(mapping.get(config.get('webapp', 'log_level').upper(), logging.NOTSET)) app.logger.addHandler(handler) # Import app sections from supysonic import frontend from supysonic import api return app
def get_db_store(): store = getattr(g, 'store', None) if store: return store g.store = get_store(config.get('base', 'database_uri')) return g.store
def get_mime(ext): return mimetypes.guess_type('dummy.' + ext, False)[0] or config.get( 'mimetypes', ext) or 'application/octet-stream'
def get_mime(ext): return mimetypes.guess_type('dummy.' + ext, False)[0] or config.get('mimetypes', ext) or 'application/octet-stream'
def stream_media(): status, res = get_entity(request, Track) if not status: return res maxBitRate, format, timeOffset, size, estimateContentLength, client = map(request.values.get, [ 'maxBitRate', 'format', 'timeOffset', 'size', 'estimateContentLength', 'c' ]) if format: format = format.lower() src_suffix = res.suffix() dst_suffix = res.suffix() dst_bitrate = res.bitrate dst_mimetype = res.content_type if client: prefs = store.get(ClientPrefs, (request.user.id, client)) if not prefs: prefs = ClientPrefs() prefs.user_id = request.user.id prefs.client_name = client store.add(prefs) if prefs.format: dst_suffix = prefs.format if prefs.bitrate and prefs.bitrate < dst_bitrate: dst_bitrate = prefs.bitrate if maxBitRate: try: maxBitRate = int(maxBitRate) except: return request.error_formatter(0, 'Invalid bitrate value') if dst_bitrate > maxBitRate and maxBitRate != 0: dst_bitrate = maxBitRate if format and format != 'raw' and format != src_suffix: dst_suffix = format dst_mimetype = scanner.get_mime(dst_suffix) if format != 'raw' and (dst_suffix != src_suffix or dst_bitrate != res.bitrate): transcoder = config.get('transcoding', 'transcoder_{}_{}'.format(src_suffix, dst_suffix)) decoder = config.get('transcoding', 'decoder_' + src_suffix) or config.get('transcoding', 'decoder') encoder = config.get('transcoding', 'encoder_' + dst_suffix) or config.get('transcoding', 'encoder') if not transcoder and (not decoder or not encoder): transcoder = config.get('transcoding', 'transcoder') if not transcoder: return request.error_formatter(0, 'No way to transcode from {} to {}'.format(src_suffix, dst_suffix)) transcoder, decoder, encoder = map(lambda x: prepare_transcoding_cmdline(x, res.path, src_suffix, dst_suffix, dst_bitrate), [ transcoder, decoder, encoder ]) try: if transcoder: dec_proc = None proc = subprocess.Popen(transcoder, stdout = subprocess.PIPE) else: dec_proc = subprocess.Popen(decoder, stdout = subprocess.PIPE) proc = subprocess.Popen(encoder, stdin = dec_proc.stdout, stdout = subprocess.PIPE) except: return request.error_formatter(0, 'Error while running the transcoding process') def transcode(): try: while True: data = proc.stdout.read(8192) if not data: break yield data except: if dec_proc != None: dec_proc.terminate() proc.terminate() if dec_proc != None: dec_proc.wait() proc.wait() app.logger.info('Transcoding track {0.id} for user {1.id}. Source: {2} at {0.bitrate}kbps. Dest: {3} at {4}kbps'.format(res, request.user, src_suffix, dst_suffix, dst_bitrate)) response = Response(transcode(), mimetype = dst_mimetype) else: response = send_file(res.path, mimetype = dst_mimetype) res.play_count = res.play_count + 1 res.last_play = now() request.user.last_play = res request.user.last_play_date = now() store.commit() return response
def __init__(self, user, logger): self.__user = user self.__api_key = config.get('lastfm', 'api_key') self.__api_secret = config.get('lastfm', 'secret') self.__enabled = self.__api_key is not None and self.__api_secret is not None self.__logger = logger
def user_profile(uid): if uid == 'me': prefs = store.find(ClientPrefs, ClientPrefs.user_id == uuid.UUID(session.get('userid'))) return render_template('profile.html', user = UserManager.get(store, session.get('userid'))[1], api_key = config.get('lastfm', 'api_key'), clients = prefs, admin = UserManager.get(store, session.get('userid'))[1].admin) else: if not UserManager.get(store, session.get('userid'))[1].admin or not UserManager.get(store, uid)[0] is UserManager.SUCCESS: return redirect(url_for('index')) prefs = store.find(ClientPrefs, ClientPrefs.user_id == uuid.UUID(uid)) return render_template('profile.html', user = UserManager.get(store, uid)[1], api_key = config.get('lastfm', 'api_key'), clients = prefs, admin = UserManager.get(store, session.get('userid'))[1].admin)
def user_profile(uid, user): prefs = store.find(ClientPrefs, ClientPrefs.user_id == user.id) return render_template('profile.html', user = user, has_lastfm = config.get('lastfm', 'api_key') != None, clients = prefs)
def get_db(): if not hasattr(g, 'database'): g.database = get_store(config.get('base', 'database_uri')) return g.database
def stream_media(): status, res = get_entity(request, Track) if not status: return res maxBitRate, format, timeOffset, size, estimateContentLength, client = map(request.args.get, [ 'maxBitRate', 'format', 'timeOffset', 'size', 'estimateContentLength', 'c' ]) if format: format = format.lower() src_suffix = res.suffix() dst_suffix = res.suffix() dst_bitrate = res.bitrate dst_mimetype = res.content_type if client: prefs = store.get(ClientPrefs, (request.user.id, client)) if not prefs: prefs = ClientPrefs() prefs.user_id = request.user.id prefs.client_name = client store.add(prefs) if prefs.format: dst_suffix = prefs.format if prefs.bitrate and prefs.bitrate < dst_bitrate: dst_bitrate = prefs.bitrate if maxBitRate: try: maxBitRate = int(maxBitRate) except: return request.error_formatter(0, 'Invalid bitrate value') if dst_bitrate > maxBitRate and maxBitRate != 0: dst_bitrate = maxBitRate if format and format != 'raw' and format != src_suffix: dst_suffix = format dst_mimetype = scanner.get_mime(dst_suffix) if format != 'raw' and (dst_suffix != src_suffix or dst_bitrate != res.bitrate): transcoder = config.get('transcoding', 'transcoder_{}_{}'.format(src_suffix, dst_suffix)) decoder = config.get('transcoding', 'decoder_' + src_suffix) or config.get('transcoding', 'decoder') encoder = config.get('transcoding', 'encoder_' + dst_suffix) or config.get('transcoding', 'encoder') if not transcoder and (not decoder or not encoder): transcoder = config.get('transcoding', 'transcoder') if not transcoder: return request.error_formatter(0, 'No way to transcode from {} to {}'.format(src_suffix, dst_suffix)) transcoder, decoder, encoder = map(lambda x: prepare_transcoding_cmdline(x, res.path, src_suffix, dst_suffix, dst_bitrate), [ transcoder, decoder, encoder ]) try: if transcoder: proc = subprocess.Popen(transcoder, stdout = subprocess.PIPE) else: dec_proc = subprocess.Popen(decoder, stdout = subprocess.PIPE) proc = subprocess.Popen(encoder, stdin = dec_proc.stdout, stdout = subprocess.PIPE) except: return request.error_formatter(0, 'Error while running the transcoding process') def transcode(): while True: data = proc.stdout.read(8192) if not data: break yield data proc.terminate() proc.wait() app.logger.info('Transcoding track {0.id} for user {1.id}. Source: {2} at {0.bitrate}kbps. Dest: {3} at {4}kbps'.format(res, request.user, src_suffix, dst_suffix, dst_bitrate)) response = Response(transcode(), mimetype = dst_mimetype) else: response = send_file(res.path, mimetype = dst_mimetype) res.play_count = res.play_count + 1 res.last_play = now() request.user.last_play = res request.user.last_play_date = now() store.commit() return response
def user_profile(): prefs = store.find(ClientPrefs, ClientPrefs.user_id == uuid.UUID(session.get('userid'))) return render_template('profile.html', user = UserManager.get(store, session.get('userid'))[1], api_key = config.get('lastfm', 'api_key'), clients = prefs)