def update_queues(self, queues): for id, args in queues: get_database().query(Queue).filter_by(id=id).update(args) get_database().commit() ws.emit('queue.update')
def add_submit(self, login=None, mail=None, roles=None, password1=None, password2=None): AdminUsers._validate_user_params(login, mail, roles, password1, password2) if roles is None: roles = [] if isinstance(roles, str): roles = [roles] salt = ''.join(random.choice(string.ascii_letters + string.digits) for i in range(64)) password = hash_password(password1, salt) user = User(login, password, mail, salt) get_database().add(user) for role in get_database().query(Role).filter(Role.id.in_(roles)): role.users.append(user) get_database().commit() messages_service.success('User was added.') raise HTTPRedirect('/admin/users')
def refresh(self, type, slug): if type not in ["album", "artist"]: raise ValueError("Invalid type %s supplied" % type) entity = None if type == "album": entity = library_dao.get_album_by_slug(slug) elif type == "artist": entity = library_dao.get_artist_by_slug(slug) if entity is not None: if entity.cover_path is not None and os.path.exists(entity.cover_path): os.remove(entity.cover_path) entity.cover_path = None entity.cover_hash = None entity.cover = None entity.cover_large = None get_database().commit() if type == "album": ws.emit_all("covers.album.update", entity.id) elif type == "artist": ws.emit_all("covers.artist.update", entity.id)
def edit_submit(self, user_id, login=None, mail=None, roles=None, password1=None, password2=None): try: user = (get_database().query(User) .filter_by(id=user_id).one()) except NoResultFound: raise cherrypy.NotFound() AdminUsers._validate_user_params(login, mail, roles, password1, password2) if roles is None: roles = [] if isinstance(roles, str): roles = [roles] password = hash_password(password1, user.salt) user.login = login user.mail = mail user.password = password user.roles[:] = [] for role in get_database().query(Role).filter(Role.id.in_(roles)): role.users.append(user) get_database().commit() messages_service.success('User was edited.') raise HTTPRedirect('/admin/users')
def move(self, ids, where=None): filenames = [] ids = ids.split(',') for id in ids: if id == "": continue track_paths = get_database().query(TrackPath).filter_by(track_id=id).all() for track_path in track_paths: filenames.append(track_path.path) get_database().delete(track_path.track) get_database().commit() if where == "va": artist_name = 'Various Artists' else: artist_name = None tracks, messages = library_dao.add_files( filenames, move=True, remove_dirs=True, artist_name_override=artist_name ) tracks = LibraryEdit._sort_tracks(tracks) hierarchy = Library._produce_track_hierarchy(tracks) return {'hierarchy': hierarchy, 'messages': messages}
def shuffle(self): user_id = cherrypy.request.user.id current_index = (get_database().query(Queue.index) .filter(Queue.user_id == user_id, Queue.current) .scalar()) query = get_database().query(Queue).filter(Queue.user_id == user_id) if current_index is None: current_index = 0 else: query = query.filter(Queue.index > current_index) queue_count = query.count() indexes = list(range(queue_count)) random.shuffle(indexes) for index, queue in enumerate(query.all()): queue.index = current_index + 1 + indexes[index] get_database().commit() ws.emit('queue.update')
def add_tracks(self, track_ids): user_id = cherrypy.request.user.id queues = [] for track_id in track_ids: if track_id == "": continue index = self.get_new_pos(user_id) queue = Queue(index) queue.track_id = track_id queue.user_id = user_id get_database().add(queue) queues.append(queue) get_database().commit() for queue in queues: # always update seen, True means now if queue.track.album is not None: queue.track.album.seen = True ws.emit('queue.update')
def update_import_status(self, status, torrent_id=None): query = get_database().query(Torrent) if torrent_id is not None: query = query.filter(Torrent.torrent_id == torrent_id) query.update({'import_status': status[0:128]}) get_database().commit()
def clear(self): user_id = cherrypy.request.user.id get_database().query(Queue).filter(Queue.user_id == user_id).delete(synchronize_session='fetch') get_database().commit() self._reset_current() ws.emit('queue.update')
def _save(self, expiration_time): data = pickle.dumps(self._data, self.pickle_protocol) if self._exists(): (get_database().query(Session).filter(Session.sess_id == self.id) .update({'data': data, 'expiration_time': expiration_time})) else: params = {'sess_id': self.id, 'data': data, 'expiration_time': expiration_time} get_database().execute(Session.__table__.insert(), params) get_database().commit()
def default(self): roles = (get_database().query(Role).order_by(Role.name).all()) users = (get_database().query(User).order_by(User.login).all()) for user in users: remotes.update_user(user) return { 'users': users, 'roles': roles }
def reset_current(self): user_id = cherrypy.request.user.id (get_database().query(Queue) .filter(and_(Queue.user_id == user_id, Queue.current)) .update({'current': False, 'current_seconds': None}, synchronize_session='fetch')) get_database().commit() self._reset_current() ws.emit('queue.update')
def edit(self, login): try: user = (get_database().query(User) .filter_by(login=login) .order_by(User.login).one()) except NoResultFound: raise cherrypy.NotFound() roles = (get_database().query(Role).order_by(Role.name).all()) return { 'user': user, 'roles': roles }
def default(self, filter="importable"): config = cherrypy.tree.apps[""].config["opmuse"] if "deluge.host" not in config: raise cherrypy.NotFound() query = get_database().query(Torrent).order_by(Torrent.added.desc()) if filter == "importable": query = query.filter(Torrent.importable) else: filter = "nothing" torrents = query.all() deluge_host = config["deluge.host"] deluge_port = config["deluge.port"] deluge_updated = cache.storage.get_updated(DelugeBackgroundTaskCron.UPDATE_TORRENTS_KEY_DONE) return { "deluge_host": deluge_host, "deluge_port": deluge_port, "filter": filter, "deluge_updated": deluge_updated, "torrents": torrents, }
def dashboard(self): library_path = cherrypy.request.app.config.get('opmuse').get('library.path') stat = os.statvfs(os.path.realpath(library_path)) disk = { 'path': library_path, 'free': stat.f_frsize * stat.f_bavail, 'total': stat.f_frsize * stat.f_blocks } formats = (get_database().query(Track.format, func.sum(Track.duration), func.sum(Track.size), func.count(Track.format)).group_by(Track.format).all()) stats = { 'tracks': library_dao.get_track_count(), 'invalid': library_dao.get_invalid_track_count(), 'albums': library_dao.get_album_count(), 'artists': library_dao.get_artist_count(), 'track_paths': library_dao.get_track_path_count(), 'duration': library_dao.get_track_duration(), 'size': library_dao.get_track_size(), 'scanning': cherrypy.request.library.scanning, 'processed': cherrypy.request.library.processed, 'files_found': cherrypy.request.library.files_found } return { 'cache_size': cache.storage.size(), 'disk': disk, 'stats': stats, 'formats': formats }
def remove(self, ids): user_id = cherrypy.request.user.id query = get_database().query(Queue).filter(and_(Queue.user_id == user_id, Queue.id.in_(ids))) try: query.filter("current").one() self._reset_current() except NoResultFound: pass query.delete(synchronize_session='fetch') get_database().commit() ws.emit('queue.update')
def get_new_pos(self, user_id): index = get_database().query(func.max(Queue.index)).filter_by(user_id=user_id).scalar() if index is None: index = 0 else: index += 1 return index
def _load(self): try: session = get_database().query(Session).filter(Session.sess_id == self.id).one() except NoResultFound: return None data = pickle.loads(session.data) return data, session.expiration_time
def check_credentials(login, password): try: user = get_database().query(User).filter_by(login=login).one() user.active = datetime.datetime.now() hashed = hash_password(password, user.salt) if hashed == user.password: return True except NoResultFound: return False
def default(self, *args): if len(args) == 1: raise cherrypy.InternalRedirect('/users/_user/%s' % args[0]) users = (get_database().query(User).order_by(User.active.desc()).all()) for user in users: remotes.update_user(user) return { 'users': users, }
def _get_current_track(self, user_id): try: return (get_database() .query(Track) .join(Queue, Track.id == Queue.track_id) .join(User, Queue.user_id == User.id) .filter(and_(User.id == user_id, Queue.current)) .group_by(Track.id) .limit(1) .one()) except NoResultFound: return None
def get_queues(self, user_id): queues = [] album = None artist = None track = None info = current_queues = None query = get_database().query(Queue).filter_by(user_id=user_id).order_by(Queue.index) for index, queue in enumerate(query.all()): if (index == 0 or queue.track.album is not None and album is not None and album.id != queue.track.album.id or queue.track.album is None and album is not None or queue.track.artist is None and artist is not None or track is not None and track.disc != queue.track.disc): if info is not None and current_queues is not None: queues.append((info, current_queues)) info = { 'duration': 0, 'artists': set(), 'album': queue.track.album, 'disc': queue.track.disc, } current_queues = [] info['duration'] += queue.track.duration if queue.track.duration is not None else 0 info['artists'].add(queue.track.artist) current_queues.append(queue) album = queue.track.album artist = queue.track.artist track = queue.track if current_queues is not None and len(current_queues) > 0: queues.append((info, current_queues)) full_info = { 'duration': 0 } for info, queue in queues: full_info['duration'] += info['duration'] info['artists'] = list(info['artists']) return queues, full_info
def update_torrents(self): torrents = self.client.call('core.get_torrents_status', {}, ['name', 'files', 'save_path', 'time_added', 'total_size', 'paused', 'is_finished', 'progress']) all_torrents = set() for torrent_id, in get_database().query(Torrent.torrent_id).all(): all_torrents.add(torrent_id) for torrent_id, data in torrents.items(): torrent_id = torrent_id.decode('utf-8') if torrent_id in all_torrents: all_torrents.remove(torrent_id) torrent = get_database().query(Torrent).filter(Torrent.torrent_id == torrent_id).one() else: torrent = Torrent() for file in data[b'files']: if Library.is_supported(file[b'path']): has_supported_files = True break else: has_supported_files = False torrent.torrent_id = torrent_id torrent.name = data[b'name'].decode('utf-8') torrent.has_supported_files = has_supported_files torrent.added = datetime.datetime.fromtimestamp(data[b'time_added']) torrent.size = data[b'total_size'] torrent.paused = data[b'paused'] torrent.finished = data[b'is_finished'] torrent.progress = data[b'progress'] get_database().add(torrent) get_database().commit() if len(all_torrents) > 0: (get_database().query(Torrent).filter(Torrent.torrent_id.in_(all_torrents)) .delete(synchronize_session='fetch')) get_database().commit()
def tracks(self, sort=None, filter=None, page=None): if sort is None: sort = "created" if filter is None: filter = "none" if page is None: page = 1 page = int(page) page_size = 70 offset = page_size * (page - 1) query = get_database().query(Track).filter(Track.scanned).group_by(Track.id) if sort == "created": query = query.order_by(Track.created.desc()) elif sort == "updated": query = query.order_by(Track.updated.desc()) elif sort == "random": query = query.order_by(func.rand()) page = None if filter == "woartist": query = query.filter("artist_id is null") elif filter == "woalbum": query = query.filter("album_id is null") elif filter == "invalid": query = query.filter("invalid is not null") elif filter == "duplicates": query = (query.join(TrackPath, Track.id == TrackPath.track_id) .having(func.count(distinct(TrackPath.id)) > 1)) total = query.count() pages = math.ceil(total / page_size) tracks = query.limit(page_size).offset(offset).all() return { 'tracks': tracks, 'page': page, 'page_size': page_size, 'total': total, 'pages': pages, 'sort': sort, 'filter': filter }
def start(self, needs_auth=False, roles=[]): if re.match('^/static', cherrypy.request.path_info): return login = cherrypy.session.get('_login') cherrypy.response.headers['X-Opmuse-Authenticated'] = 'true' if login else 'false' if login: cherrypy.request.user = get_database().query(User).filter_by(login=login).one() if not is_granted(roles): raise cherrypy.HTTPError(401) elif needs_auth: raise HTTPRedirect("/login?came_from=%s" % do_urlencode(cherrypy.url())) else: cherrypy.request.user = None
def get_next(self, user_id): database = get_database() current_queue = next_queue = None try: current_queue = (database.query(Queue) .filter_by(user_id=user_id, current=True) .order_by(Queue.index).one()) if current_queue.current_seconds is not None: next_queue = current_queue current_queue = None except NoResultFound: pass if next_queue is None: if current_queue is not None: next_queue = (database.query(Queue) .filter_by(user_id=user_id) .filter(Queue.index > current_queue.index) .order_by(Queue.index).first()) else: database.query(Queue).filter_by(user_id=user_id).update({'played': None}) next_queue = (database.query(Queue) .filter_by(user_id=user_id) .order_by(Queue.index).first()) if current_queue is not None: current_queue.current = False if next_queue is not None: next_queue.current = True database.commit() if next_queue is not None: cherrypy.request.queue_current_id = next_queue.id cherrypy.engine.publish('queue.next', next=next_queue) return next_queue
def _fetch_track(self, id): key = Remotes.TRACK_KEY_FORMAT % id try: track_entity = get_database().query(Track).filter(Track.id == id).one() except NoResultFound: # track was probably removed, edited and therefor recreated. either # way we just ignore it return album_name = track_entity.album.name if track_entity.album is not None else None artist_name = track_entity.artist.name if track_entity.artist is not None else None track = { 'wikipedia': wikipedia.get_track(artist_name, album_name, track_entity.name), 'lastfm': lastfm.get_track(artist_name, track_entity.name) } cache.set(key, track) ws.emit_all('remotes.track.fetched', id)
def _fetch_artist(self, id): key = Remotes.ARTIST_KEY_FORMAT % id try: artist_entity = get_database().query(Artist).filter(Artist.id == id).one() except NoResultFound: # artist removed, just ignore return artist = { 'wikipedia': wikipedia.get_artist(artist_entity.name), 'lastfm': lastfm.get_artist(artist_entity.name), 'google': google.get_artist_search(artist_entity), 'musicbrainz': musicbrainz.get_artist(artist_entity) } cache.set(key, artist) ws.emit_all('remotes.artist.fetched', id, [album.id for album in artist_entity.albums], [track.id for track in artist_entity.tracks])
def _user(self, login): try: user = (get_database().query(User) .filter_by(login=login) .order_by(User.login).one()) except NoResultFound: raise cherrypy.NotFound() remotes.update_user(user) remotes_user = remotes.get_user(user) Dashboard.update_recent_tracks() recently_listeneds = Dashboard.get_recently_listeneds(user) now = datetime.now() def get_year(year): return ('%s' % year, self._get_top_artists(user.id, datetime(year, 1, 1), datetime(year, 12, 31))) top_artists_categories = [ ('Overall', self._get_top_artists(user.id, None, None)), get_year(now.year - 1), get_year(now.year - 2), get_year(now.year - 3), get_year(now.year - 4), get_year(now.year - 5), ('This Month', self._get_top_artists(user.id, datetime(now.year, now.month, 1), None)), ] uploaded_albums = library_dao.get_albums_by_created_user(user.id) return { 'user': user, 'uploaded_albums': uploaded_albums, 'top_artists_categories': top_artists_categories, 'recently_listeneds': recently_listeneds, 'remotes_user': remotes_user }
def _fetch_album(self, id): key = Remotes.ALBUM_KEY_FORMAT % id try: album_entity = get_database().query(Album).filter(Album.id == id).one() except NoResultFound: # album removed, just ignore return if len(album_entity.artists) > 0: artist_name = album_entity.artists[0].name else: artist_name = None album = { 'wikipedia': wikipedia.get_album(artist_name, album_entity.name), 'lastfm': lastfm.get_album(artist_name, album_entity.name), 'musicbrainz': musicbrainz.get_album(album_entity) } cache.set(key, album) ws.emit_all('remotes.album.fetched', id, [track.id for track in album_entity.tracks])