def queue_open(self, ws_user): track = cache.get('queue.current_track_%d' % ws_user.id) progress = cache.get('queue.current_progress_%d' % ws_user.id) if track is not None: ws.emit('queue.current_track_%d' % ws_user.id, track, ws_user=ws_user) if progress is not None: ws.emit('queue.current_progress_%d' % ws_user.id, progress, ws_user=ws_user)
def player(self): user = cherrypy.request.user queues, queue_info = queue_dao.get_queues(user.id) queue_current_track = queue_dao.get_current_track(user.id) current_track = cache.get('queue.current_track_%d' % user.id) current_progress = cache.get('queue.current_progress_%d' % user.id) return { 'queues': queues, 'queue_info': queue_info, 'queue_current_track': queue_current_track, 'current_track': current_track, 'current_progress': current_progress }
def get_current_track(self, user_id): track = cache.get('queue.current_track_%d' % user_id) if track is not None: track = library_dao.get_track(track['id']) if track is None: return self._get_current_track(user_id) else: return track else: return None
def default(self): user = cherrypy.request.user auth_url = new_auth = None need_config = False cache_key = 'settings_lastfm_session_key_%d' % cherrypy.request.user.id if user.lastfm_session_key is None: session_key = cache.get(cache_key) if session_key is not None: auth_url = session_key.get_auth_url() key = session_key.get_session_key() if key is not None: cache.set(cache_key, None) user.lastfm_session_key = key user.lastfm_user = lastfm.get_authenticated_user_name(key) auth_url = None new_auth = True else: try: session_key = SessionKey() auth_url = session_key.get_auth_url() cache.set(cache_key, session_key) except LastfmError: need_config = True remotes.update_user(user) return { "user": user, 'need_config': need_config, 'auth_url': auth_url, 'new_auth': new_auth }
def add(self, archive_password=None, audio_file=None, session=None, artist_name_fallback=None): cache_key = LibraryUpload.CACHE_KEY % (cherrypy.request.user.id, session) all_tracks = None if not cache.has(cache_key): raise cherrypy.HTTPError(status=409) else: all_tracks = cache.get(cache_key) if audio_file is not None and len(audio_file) == 0: audio_file = None if archive_password is not None and len(archive_password) == 0: archive_password = None content_disposition = cherrypy.request.headers.get('content-disposition') filename = content_disposition[content_disposition.index('filename=') + 9:] if filename.startswith('"') and filename.endswith('"'): filename = filename[1:-1] filename = unquote(filename) ext = os.path.splitext(filename)[1].lower()[1:] basename = os.path.splitext(filename)[0] cache_path = os.path.join(cherrypy.config['opmuse'].get('cache.path'), 'upload') if not os.path.exists(cache_path): os.mkdir(cache_path) tempdir = tempfile.mkdtemp(dir=cache_path) path = os.path.join(tempdir, filename) paths = [] rarfile.PATH_SEP = '/' messages = [] with open(path, 'wb') as fileobj: fileobj.write(cherrypy.request.rfile.read()) # this file is a regular file that belongs to an audio_file if audio_file is not None: track = None tries = 0 # try and sleep until we get the track.. this will almost always # be needed because of the async upload. while track is None and tries < 10: track = library_dao.get_track_by_filename(audio_file.encode('utf8')) tries += 1 if track is None: time.sleep(3) if track is None: messages.append(('warning', ("<strong>%s</strong>: Skipping <strong>%s</strong>, timeout trying to " + "find its track.") % (audio_file, filename))) else: track_structure = TrackStructureParser(track) track_path = track_structure.get_path(absolute=True) relative_track_path = track_structure.get_path(absolute=False).decode('utf8', 'replace') new_path = os.path.join(track_path, filename.encode('utf8')) if os.path.exists(new_path): messages.append(('warning', ("<strong>%s</strong>: Skipping <strong>%s</strong>, already exists " + "in <strong>%s</strong>.") % (audio_file, filename, relative_track_path))) else: shutil.move(path.encode('utf8'), new_path) messages.append(('info', ("<strong>%s</strong>: Uploaded <strong>%s</strong> to " + "<strong>%s</strong>.") % (audio_file, filename, relative_track_path))) elif ext == "zip": # set artist name fallback to zip's name so if it's missing artist tags # it's easily distinguishable and editable so it can be fixed after upload. artist_name_fallback = basename try: zip = ZipFile(path) if archive_password is not None: zip.setpassword(archive_password.encode()) zip.extractall(tempdir) os.remove(path) for name in zip.namelist(): namepath = os.path.join(tempdir, name) # ignore hidden files, e.g. OSX archive weirdness and such if name.startswith(".") or os.path.split(name)[0] == "__MACOSX": shutil.rmtree(namepath) continue paths.append(namepath.encode('utf8')) except Exception as error: messages.append(('danger', "<strong>%s</strong>: %s" % (os.path.basename(path), error))) elif ext == "rar": # look at corresponding ext == zip comment... artist_name_fallback = basename try: rar = RarFile(path) if archive_password is None and rar.needs_password(): messages.append(('danger', "<strong>%s</strong>: Needs password but none provided." % os.path.basename(path))) else: if archive_password is not None: rar.setpassword(archive_password) rar.extractall(tempdir) os.remove(path) for name in rar.namelist(): namepath = os.path.join(tempdir, name) if name.startswith("."): shutil.rmtree(namepath) continue paths.append(namepath.encode('utf8')) except Exception as error: messages.append(('danger', "<strong>%s</strong>: %s" % (os.path.basename(path), error))) # this is a plain audio file else: paths.append(path.encode('utf8')) for path in paths: # update modified time to now, we don't want the time from the zip # archive or whatever os.utime(path, None) if len(paths) > 0: tracks, add_files_messages = library_dao.add_files(paths, move=True, remove_dirs=False, artist_name_fallback=artist_name_fallback, user=cherrypy.request.user) messages += add_files_messages else: tracks = [] shutil.rmtree(tempdir) for track in tracks: all_tracks.append(track.id) if track.album is not None: remotes.update_album(track.album) if track.artist is not None: remotes.update_artist(track.artist) remotes.update_track(track) hierarchy = Library._produce_track_hierarchy(library_dao.get_tracks_by_ids(all_tracks)) return {'hierarchy': hierarchy, 'messages': messages}
def default(self, query=None, type=None): artists = [] albums = [] tracks = [] track_ids = [] hierarchy = None album_track_ids = set() recent_searches = [] if query is not None: albums = None tracks = None # only search for artists if type == 'artist': artists = search.query_artist(query, exact=True) albums = [] tracks = [] else: artists = search.query_artist(query) if albums is None: albums = search.query_album(query) if tracks is None: tracks = search.query_track(query) for artist in artists: remotes.update_artist(artist) for album in albums: remotes.update_album(album) for track in tracks: track_ids.append(track.id) remotes.update_track(track) entities = artists + albums + tracks if len(entities) == 1: for artist in artists: raise HTTPRedirect('/%s' % artist.slug) for album in albums: raise HTTPRedirect('/%s/%s' % (album.artists[0].slug, album.slug)) for track in tracks: raise HTTPRedirect('/library/track/%s' % track.slug) if cache.has(Search.CACHE_RECENT_KEY): recent_searches = cache.get(Search.CACHE_RECENT_KEY) else: cache.set(Search.CACHE_RECENT_KEY, recent_searches) if type is None and len(entities) > 0: if len(recent_searches) == 0 or query != recent_searches[0][0]: recent_searches.insert(0, (query, datetime.datetime.now(), cherrypy.request.user.login)) if len(recent_searches) > Search.MAX_RECENT: recent_searches.pop() entities = sorted(entities, key=lambda entity: entity._SEARCH_SCORE, reverse=True) hierarchy = Library._produce_track_hierarchy(entities) for key, result_artist in hierarchy['artists'].items(): for key, result_album in result_artist['albums'].items(): for track_id in library_dao.get_track_ids_by_album_id(result_album['entity'].id): album_track_ids.add(track_id) return { 'query': query, 'hierarchy': hierarchy, 'tracks': tracks, 'albums': albums, 'artists': artists, 'track_ids': track_ids, 'album_track_ids': list(album_track_ids), 'recent_searches': recent_searches }
def get_tag(self, tag_name): key = Remotes.TAG_KEY_FORMAT % tag_name return cache.get(key)
def get_artist(self, artist): key = Remotes.ARTIST_KEY_FORMAT % artist.id return cache.get(key)
def get_album(self, album): key = Remotes.ALBUM_KEY_FORMAT % album.id return cache.get(key)
def get_track(self, track): key = Remotes.TRACK_KEY_FORMAT % track.id return cache.get(key)
def get_user(self, user): key = Remotes.USER_KEY_FORMAT % user.id return cache.get(key)