def renderMenu(self, main_nav, sub_nav=''): children = [] main_menu = [] sub_menu = [] menu_items = self.main_nav for item in menu_items: css_class = '' if main_nav == item['name']: # We found the menu item that is currently active - set the correct # CSS class so that it is rendered properly, plus grab any children that we # need to handle css_class = 'active' children = item['children'] # Skip this item if they don't have permission to access if item.has_key('perm') and not identity.has_permission(item['perm']): continue children = [] for child in item['children']: if child.has_key('perm') and not identity.has_permission(child['perm']): continue children.append(child) main_menu.append({'name': item['label'], 'link': item['link'], 'link_class': item.get('link_class', ''), 'css_class': css_class, 'children': children}) return (main_menu, sub_menu)
def dashboard(self): q_score = None current = None age = None feed_entries = None usage = dict() now = datetime.now() curso = self.get_curso_actual() instancias = list() correcciones = list() respuestas_pendientes = list() if curso and identity.has_permission(Permiso.entregar_tp): for ej in curso.ejercicios: for inst in ej.instancias_a_entregar: instancias.append(inst) alumno = identity.current.user alumno_inscripto = alumno.get_inscripcion(curso) correcciones = alumno.get_correcciones(curso) correcciones.sort(lambda x,y: cmp(x.instancia, y.instancia)) if identity.has_permission(Permiso.examen.respuesta.revisar): respuestas_pendientes = Respuesta.get_pendientes_de_revision() feed_url = config.get('sercom.welcome.rssfeed.url') if identity.has_permission(Permiso.admin): # A los admins les muestro info del server q_score = Entrega.selectBy(inicio=None).count() current = None try: current = Entrega.select(AND(Entrega.q.inicio!=None, Entrega.q.fin==None)).orderBy(Entrega.q.fecha).reversed()[0] age = current.fecha except: pass usage = sercom.serverinfo.getinfo() elif feed_url: # Al resto el feed de noticias, hasta cuatro count = 0 feed = feedparser.parse(feed_url) if feed is not None: feed_entries = list() for e in feed.entries: if e.category == 'Noticias' and count < 4: # No logré que el parser deje de escapear el HTML y lo necesito e.html_content = e.summary.replace('>', '>') e.html_content = e.html_content.replace('<', '<') e.presented_date = time.strftime('%d/%m/%Y %H:%M', e.updated_parsed) feed_entries.append(e) count = count + 1 return dict(curso=curso, now=now, instancias_activas = instancias, correcciones = correcciones, respuestas_pendientes = respuestas_pendientes, q_score = q_score, usage=usage, age=age, q_current=current, feed_entries = feed_entries)
def statistics(self, **kw): """Crea el formulario de estadisticas sobre entregas""" curso = self.get_curso_actual() cant_por_instancia = [] cant_por_dias_anticip = {} for e in curso.ejercicios: for i in e.instancias: cant_por_instancia += [(i.shortrepr(), len(i.entregas))] for entrega in i.entregas: anticip = (i.fin - entrega.fecha) dias_anticipacion = anticip.days if dias_anticipacion in cant_por_dias_anticip: cant_por_dias_anticip[dias_anticipacion] += 1 else: cant_por_dias_anticip[dias_anticipacion] = 1 items = cant_por_dias_anticip.items() items.sort() items.reverse() # Entregas colgadas, sólo admins q_data = None if identity.has_permission(Permiso.admin): q_data = Entrega.selectBy(inicio=None, fin=None).orderBy('fecha') for e in q_data: e.edad = (datetime.now() - e.fecha) e.suficientemente_viejo = e.edad > timedelta(minutes=5) return dict(cant_por_instancia=cant_por_instancia, q_data = q_data, cant_por_dias_anticip = [('%s dias' % dias, cant) for dias, cant in items])
def get_curso_actual(self): try: contexto = SessionHelper().get_contexto_usuario() return contexto.get_curso() except SinCursosDisponibles as e: if identity.has_permission(Permiso.admin): raise redirect(url('/curso/new')) else: raise redirect(url('/error/%s' % e))
def filter_members(location, text_filter, type, active_only, start, end, override_user=None): if type == "member_search": text_filter = "%" + " ".join(text_filter.split()).replace("'","\\'") + "%" if override_user: user_locs = Location.select() else: user_locs = user_locations(identity.current.user, ['member', 'host']) if user_locs: if location: relevant_groups = location.groups relevant_user_ids = tuple((ug.userID for ug in UserGroup.select(IN(UserGroup.q.group, tuple(relevant_groups))))) display_name_clause = iLIKE(User.q.display_name, text_filter) user_id_clause = IN(User.q.id, relevant_user_ids) # so that we select all members even those with homehub as this hub if active_only: user_active_clause = (User.q.active == 1) users = User.select(AND(display_name_clause, user_id_clause, user_active_clause)) else: users = User.select(AND(display_name_clause, user_id_clause)) else: display_name_clause = iLIKE(User.q.display_name, text_filter) if active_only: user_active_clause = (User.q.active == 1) users = User.select(AND(display_name_clause, user_active_clause)) else: users = User.select(display_name_clause) users = users.orderBy('display_name') else: users = [] elif type == 'rfid_member_search': users = User.select(AND(User.q.rfid == text_filter)) elif type == 'fulltext_member_search': users = hubspace.search.do_search(text_filter) if location: user_ids = tuple(user.id for user in users) if not user_ids: users = [] else: users = User.select(AND(IN(User.q.id, user_ids), User.q.homeplaceID==location.id)) if start != None and end != None: users = users[start:end] try: webapi = User.selectBy(first_name="web", last_name="api")[0] if webapi in users and not identity.has_permission("superuser"): users.remove(webapi) except: pass return users
def locations(permission="manage_resources"): """get all the locations in which the current user has a specific permission """ if identity.has_permission('superuser'): locations = list(Location.select()) else: locations = [] for group in identity.current.user.groups: location = get_place(group) if location: if permission_or_owner(location, location, permission) and location not in locations: locations.append(location) locations.sort(loc_alpha) return locations
class IdentityRoot(RootController): [expose()] def index(self): pass [expose()] def identity_failed(self, **kw): cherrypy.response.status = 401 return 'identity_failed_answer' [expose()] [identity.require(not_anonymous())] def logged_in_only(self): return 'logged_in_only' [expose()] [identity.require(in_group('peon'))] def in_peon_group(self): return 'in_peon_group' [expose()] def test_exposed_require(self): if not hasattr(self.in_peon_group, '_require'): return 'no _require attr' if not isinstance(self.in_peon_group._require, in_group): return 'not correct class' if 'peon' != self.in_peon_group._require.group_name: return 'not correct group name' return '_require is exposed' [expose()] [identity.require(in_group('admin'))] def in_admin_group(self): return 'in_admin_group' [expose()] [identity.require(has_permission('chops_wood'))] def has_chopper_permission(self): return 'has_chopper_permission' [expose()] [identity.require(has_permission('bosses_people'))] def has_boss_permission(self): return "has_boss_permission" [expose()] def logout(self): identity.current.logout() return "logged out" [expose()] [identity.require(not_anonymous())] def user_email(self): return identity.current.user.email_address peon_area = RestrictedArea() [expose()] def new_user_setup(self, user_name, password): return '%s %s' % (user_name, password) _test_encoded_params = ('b=krümel&d.a=klöße1') [expose()] [identity.require(not_anonymous())] def test_params(self, **kwargs): params = self._test_encoded_params # formencode's variable_decode create a datastructure # but does not "decode" anything to_datastruct = formencode.variabledecode.variable_decode expected_params = to_datastruct( dict([p.split('=') for p in params.split('&')])) params_ok = True if not expected_params['b'].decode( 'utf8') == cherrypy.request.params['b']: params_ok = False if not expected_params['d']['a'].decode( 'utf8') == cherrypy.request.params['d']['a']: params_ok = False if params_ok: return 'params ok' else: return 'wrong params: %s\nexpected unicode objects' \ ' for all strings' % cherrypy.request.params
def UserMenu(self, **kw): ''' Return a list of menu items available to the current user ''' #log.debug('UserMenu') results = [] #Display top menu based on permissions of user. results.append(dict(link='/',name='Main Menu',sub_menu=[])) if identity.has_permission("reg_view"): results.append(dict(link='/registration',name='Registration',sub_menu=[])) if identity.has_permission("bill_view"): results.append(dict(link='/billing',name='Billing',sub_menu=[])) Locations = model.InvLocation.select() LocationStoreGroups = {} LocationDispGroups = {} for location in Locations: name_store = '%s_store' % location.Name.lower().replace(' ','_') name_disp = '%s_disp' % location.Name.lower().replace(' ','_') # Create the store link if getattr(self,name_store,None) != None and identity.has_permission('%s_view' % name_store): for group in location.Groups: if LocationStoreGroups.has_key(group.Name): LocationStoreGroups[group.Name].append(dict(link='/%s' % name_store, name='%s Inventory' % location.Name,sub_menu=[])) else: LocationStoreGroups[group.Name] = [dict(link='/%s' % name_store, name='%s Inventory' % location.Name,sub_menu=[])] if len(location.Groups) == 0: if LocationStoreGroups.has_key('Other'): LocationStoreGroups['Other'].append(dict(link='/%s' % name_store, name='%s Inventory' % location.Name,sub_menu=[])) else: LocationStoreGroups['Other'] = [dict(link='/%s' % name_store, name='%s Inventory' % location.Name,sub_menu=[])] # Create the dispensing location if location.CanSell: if getattr(self,name_disp,None) != None and identity.has_permission('%s_view' % name_disp): for group in location.Groups: if LocationDispGroups.has_key(group.Name): LocationDispGroups[group.Name].append(dict(link='/%s' % name_disp, name='%s Dispensing' % location.Name,sub_menu=[])) else: LocationDispGroups[group.Name] = [dict(link='/%s' % name_disp, name='%s Dispensing' % location.Name,sub_menu=[])] if len(location.Groups) == 0: if LocationDispGroups.has_key('Other'): LocationDispGroups['Other'].append(dict(link='/%s' % name_disp, name='%s Dispensing' % location.Name,sub_menu=[])) else: LocationDispGroups['Other'] = [dict(link='/%s' % name_disp, name='%s Dispensing' % location.Name,sub_menu=[])] if len(LocationStoreGroups) > 0: SubMenu = [] keys = LocationStoreGroups.keys() keys.sort() for key in keys: SubMenu.append(dict(link='',name=key, sub_menu=LocationStoreGroups[key])) results.append(dict(link='', name='Inventory', sub_menu=SubMenu)) if len(LocationDispGroups) > 0: SubMenu = [] keys = LocationDispGroups.keys() keys.sort() for key in keys: SubMenu.append(dict(link='',name=key, sub_menu=LocationDispGroups[key])) results.append(dict(link='', name='Dispensing', sub_menu=SubMenu)) if identity.has_permission("admin_controllers_inventory"): results.append(dict(link='/inventory',name='Admin Inventory',sub_menu=[])) if identity.has_permission("admin_users"): results.append(dict(link='/user_manager',name='User admin',sub_menu=[])) if identity.has_permission("admin_controllers_configuration"): results.append(dict(link='/configuration',name='Configuration Admin',sub_menu=[])) if identity.not_anonymous(): results.append(dict(link='/user_reports',name='User Reports',sub_menu=[])) return results
class Root(controllers.RootController): @expose(template="dejagears.templates.page") def index(self, pagename="FrontPage" ): box = hub.getConnection() player_fields = { Player : [ ('Name', 'name'), ('Birth Date', 'birthdate'), #('Team', 'team'), ('Points', 'points'), ], Team : [ ('City', 'city'), ('NickName', 'nickname'), ], } team_fields = [ ('City', 'city'), ('NickName', 'nickname'), ] page = box.Page(pagename=pagename) if page == None: raise turbogears.redirect("notfound", pagename = pagename) content = publish_parts(page.data, writer_name="html")['html_body'] root = str(turbogears.url('/')) content = wikiwords.sub(r'<a href="%s\1">\1</a>' % root, content) return dict( data=content, page=page, players=box.recall(Team + Player), teams=box.recall(Team), players_widget=DataGrid(fields=player_fields), teams_widget=DataGrid(fields=team_fields), ) @expose(template="dejagears.templates.edit") def edit(self,pagename): box = hub.getConnection() page = box.Page(pagename=pagename) return dict(page=page) @expose() @identity.require(identity.Any(identity.in_group("admin"),identity.has_permission("ls"))) def save(self, pagename, data, submit): box = hub.getConnection() #.begin( isolation = turbogears.database.SERIALIZABLE ) self.increment_counter() page = box.Page(pagename=pagename) if page == None: page = Page(pagename=pagename,data=data) box.memorize(page) page.data = data turbogears.flash("Changes saved!") raise turbogears.redirect("/", pagename=pagename) @expose() def default_values(self): "Set some default values in the database" # Add some information box = hub.getConnection() t1 = Team(city='Pittsburgh', nickname='Ferrous Metals') box.memorize(t1) t2 = Team(city='Seattle', nickname='Seagulls') box.memorize(t2) p1 = Player(name='Bob Waffleburger', birthdate=datetime.date(1982,3,2), points=21) box.memorize(p1) p2 = Player(name='Mike Handleback', birthdate=datetime.date(1975,9,25), points=10) box.memorize(p2) p1.team = t1.ID p2.team = t2.ID # Add a default Page page = Page( pagename="FrontPage", data="This is the main page, please edit it." ) box.memorize( page ) # Setup identity data jrodrigo = TG_User( user_name = "jrodrigo" ) box.memorize( jrodrigo ) jrodrigo.password = "******" root = TG_User( user_name = "root" ) box.memorize( root ) root.password = "******" user = TG_Group( group_name = "user" ) box.memorize( user ) admin = TG_Group( group_name = "admin" ) box.memorize( admin ) format = TG_Permission( permission_name = "format" ) box.memorize( format ) ls = TG_Permission( permission_name = "ls" ) box.memorize( ls ) cat = TG_Permission( permission_name = "cat" ) box.memorize( cat ) o = TG_UserGroup( user_id = root.user_id, group_id = user.group_id ) box.memorize( o ) o = TG_UserGroup( user_id = root.user_id, group_id = admin.group_id ) box.memorize( o ) o = TG_UserGroup( user_id = jrodrigo.user_id, group_id = user.group_id ) box.memorize( o ) o = TG_GroupPermission( group_id = admin.group_id, permission_id = format.permission_id ) box.memorize( o ) o = TG_GroupPermission( group_id = user.group_id, permission_id = ls.permission_id ) box.memorize( o ) o = TG_GroupPermission( group_id = user.group_id, permission_id = cat.permission_id ) box.memorize( o ) return "done" @expose() def default(self, pagename): return self.index(pagename) @expose("dejagears.templates.edit") def notfound(self, pagename): page = Page(pagename=pagename, data="") return dict(page=page) @expose("dejagears.templates.pagelist") @expose("json") def pagelist(self): box = hub.getConnection() self.increment_counter() pages = box.recall(Page) pages.sort(dejavu.sort('pagename')) pages = [page.pagename for page in pages] return dict(pages=pages) def increment_counter(self): # We call acquire_lock at the beginning # of the method cherrypy.session.acquire_lock() c = cherrypy.session.get('counter', 0) + 1 cherrypy.session['counter'] = c return str(c) increment_counter.exposed = True def read_counter(self): # No need to call acquire_lock # because we're only reading # the session data c = cherrypy.session.get('counter', 0) + 1 return str(c) read_counter.exposed = True @expose() def logout(self): identity.current.logout() raise redirect("/") @expose("json") def lookup( self ): user = identity.current.user print user.userId print user.emailAddress print user.displayName group = user.groups.pop() print group.groupId print group.displayName permission = user.permissions.pop() print permission.permissionId print permission.groups print group.permissions print group.users print user.groups print user.permissions return [ jsonify.encode( identity.current.user ), jsonify.encode( identity.current.user.groups.pop() ), jsonify.encode( identity.current.user.permissions.pop() ), ] @expose("dejagears.templates.login") def login(self, forward_url=None, previous_url=None, *args, **kw): if not identity.current.anonymous \ and identity.was_login_attempted() \ and not identity.get_identity_errors(): raise redirect(forward_url) forward_url=None previous_url= request.path if identity.was_login_attempted(): msg=_("The credentials you supplied were not correct or " "did not grant access to this resource.") elif identity.get_identity_errors(): msg=_("You must provide your credentials before accessing " "this resource.") else: msg=_("Please log in.") forward_url= request.headers.get("Referer", "/") response.status=403 return dict(message=msg, previous_url=previous_url, logging_in=True, original_parameters=request.params, forward_url=forward_url) @expose() @identity.require(identity.has_permission("format")) def format_only(self): return "format_only" @expose() @identity.require(identity.in_group("admin")) def root_only(self): return "root_only" @expose() @identity.require(identity.Any(identity.has_permission("ls"),identity.has_permission("format"))) def both(self): return "both" @expose() @identity.require(identity.All(identity.has_permission("format"),identity.in_group("user"))) def all(self): return "all"
def test_has_permission(self): """Test predicate for checking particular permissions.""" assert self.met(has_permission('read')) assert not self.met(has_permission('delete'))
def renderMenu(self, main_nav, sub_nav=''): children = [] main_menu = [] sub_menu = [] user = identity.current.user customer = identity.current.user.customer brand = customer.brand # See if we have a cached copy available to use last_config_change = masterdb.Customer._connection.queryOne("select last_config_change from Customer where id=%s" % customer.id)[0] if not last_config_change: last_config_change = datetime.now() customer.last_config_change = last_config_change if 'menu-user' in session and 'menu-content' in session and session['menu-user'] == user and \ session.get('menu-timestamp', datetime(2014,1,1)) > last_config_change: return (session['menu-content'], []) # If we get a customer that hasn't picked a package, set it to the Brand's highlight_package if customer.brand and not customer.package: customer.package = customer.brand.highlight_package menu_items = self.main_nav extra_items = [] excluded_items = [] #if customer.package.isFreeTrial(): #excluded_items.append('menu.billing') # Exclude some items that aren't included in some brands if brand: if not brand.show_billing and not user.isSuperuser(): excluded_items.append('menu.billing') if not brand.show_support and not user.isSuperuser(): excluded_items.append('menu.support') if not brand.show_public_reports: excluded_items.append('menu.reports.public') if not brand.show_email_templates: excluded_items.append('menu.settings.email_templates') if not customer.hasSnmpPolling(): excluded_items.append('menu.settings.snmp_credential') #print "="*80 + user.server_group_access + "*"*80 if brand.isWhiteLabel() and brand.textkey != 'panopta': excluded_items.append('menu.downloads') # Special template for FireHost doesn't need Dashboard menu if brand.textkey == 'partner.firehost': excluded_items.append('menu.dashboard') if not customer.public_reports_v1: excluded_items.append('menu.reports.public') if user.server_group_access == 'selected': excluded_items.append('menu.settings.apikey') # Exclude the user/contacts menu if the user only has a partial view of the account if user.server_group_access == 'selected': excluded_items.append('menu.contacts') if not customer.canAddServer(): excluded_items.append('menu.server.add_server') # Show the global menu for install-level and brand-level admins if not user.hasModeratePermission(): excluded_items.append('menu.global') if not user.isRelatedToAdmin() and not user.customer.brand.hasHeatmap(): excluded_items.append('menu.global.unified_heatmap') if not user.isRelatedToAdmin(): # Hide the global items that only apply to install-level admins excluded_items.append('menu.global.outage_history') excluded_items.append('menu.global.account_history') if not user.isRelatedToSuperuser(): excluded_items.append('menu.reports.reseller_summary') if not user.isRelatedToAdmin(): excluded_items.append('menu.settings.dashboard') if user.isDashboardOnlyAccess(): excluded_items.append('menu.outages') excluded_items.append('menu.config') excluded_items.append('menu.reports') excluded_items.append('menu.billing') excluded_items.append('menu.downloads') excluded_items.append('menu.global') for item in menu_items: if item["id"] == "menu.settings": item.update({ 'id': 'menu.settings.my_account', 'label': 'My Account', 'name': _('My Account'), 'data-toggle': 'modal', 'link': '/userconfig/EditUser?user_id=-1', 'children': [] }) # # Show billing if not restricted by branding # if not brand or (brand and brand.show_billing): # extra_items.append({'name': 'billing', # 'label': _('Billing'), # 'link': '/billing', # 'children': [], # 'perm': 'perm.billing', # }) # if not brand or (brand and brand.show_support): # extra_items.append({'name': 'support', # 'label': _('Support'), # 'link': '/support', # 'children': [] # }) for item in menu_items: css_class = '' if main_nav == item['name']: # We found the menu item that is currently active - set the correct # CSS class so that it is rendered properly, plus grab any children that we # need to handle css_class = 'active' children = item['children'] # Skip this item if they don't have permission to access or it should be shielded for the brand if item['id'] in excluded_items: continue if item.has_key('perm') and not identity.has_permission(item['perm']): continue children = [] for child in item['children']: if child['id'] in excluded_items: continue if child.has_key('perm') and not identity.has_permission(child['perm']): continue children.append(child) link = item['link'] if len(children) == 1: link = children[0]['link'] children = [] main_menu.append({'name': item['label'], 'link': link, 'link_class': item.get('link_class', ''), 'css_class': css_class, 'target': item.get('target', '_self'), 'data-toggle': item.get('data-toggle', ''), 'children': children}) # Add custom dashboard links main_menu[0]['children'].append({'id': 'menu.dashboard.panopta', 'name': '%s Home' % brand.name, 'label': '%s Home' % brand.name, 'link': '/dashboard', 'children': []}) dashboards = masterdb.Dashboard.selectBy(customer=customer, deleted=False).orderBy("rank") dashboard_list = [] for d in dashboards: if d.created_by != user: if d.access_level == 'only_for_me': continue elif d.access_level == 'limited_by_tag' and not any([t in user.tags for t in d.tags]): continue dashboard_list.append({ 'name': d.name, 'rank': d.rank, 'id': d.id, 'link': '/dashboard/render_dashboard?dashboard_id=%s' % d.id }) customer_heatmap = customer.getAttribute("heatmap_config") try: config = json.loads(customer_heatmap) d = config['dashboard'] dashboard_list.append({ 'name': d['name'], 'rank': d['rank'], 'id': 'heatmap', 'link': '/dashboard/Heatmap' }) except: pass dashboard_list.sort(key=lambda d: d['rank']) for d in dashboard_list: main_menu[0]['children'].append({'id': 'menu.dashboard.%s' % d['id'], 'name': d['name'], 'label': d['name'], 'link': d['link'], 'children': [], }) if user.inGroup("customer.config") or user.inGroup('brand.superuser') or user.inGroup('customer.admin') or user.inGroup('admin'): main_menu[0]['children'].append({'id': 'menu.dashboard.add_dashboard', 'name': 'Add Dashboard', 'label': 'Add Dashboard', 'data-toggle': 'modal', 'data-divider': 'true', 'link': '/dashboard/EditDashboard', 'children': []}) # Store the rendered menu in the session so it can be reused on the next pageload session['menu-user'] = user session['menu-content'] = main_menu session['menu-timestamp'] = datetime.now() return (main_menu, sub_menu)
class Root(controllers.RootController): """The root controller of the application.""" @expose(template="gordonweb.templates.index") # @identity.require(identity.in_group("admin")) def index(self): """Show the welcome page.""" # log.debug("Happy TurboGears Controller Responding For Duty") #flash(_(u"Your application is now running")) return dict(now=datetime.datetime.now()) @expose(template='gordonweb.templates.admin') @identity.require(identity.has_permission("edit")) def admin(self, task=''): if task == 'resolve_all_albums': #closest_mb_albums_to_db' : mbrainz_resolver = gordon.db.mbrainz_resolver.GordonResolver() flash("Running mbrainz_resolver.resolve_all_albums()") mbrainz_resolver.resolve_all_albums() return dict() @expose("json") @identity.require(identity.has_permission("listen")) def audio(self, fn_or_track_id): #this should be flexible enough to do either a filename or track_id fn_or_track_id = str(fn_or_track_id) (path, fn) = os.path.split(fn_or_track_id) vals = fn.split('.') stub = vals[0] if stub.startswith('T'): stub = stub[1:] try: track_id = int(stub) except: return "Cannot find audio file %s" % str(fn_or_track_id) #we are hardcoding a path here to get around NFS issues outfn = gordon_db.get_full_audiofilename(track_id) print 'Serving', outfn return cherrypy.lib.cptools.serveFile(path=outfn, disposition='attachment', name=os.path.basename(outfn)) @expose("json") @identity.require(identity.has_permission("listen")) def mp3(self, fn_or_track_id): #this should be flexible enough to do either a filename or track_id fn_or_track_id = str(fn_or_track_id) (path, fn) = os.path.split(fn_or_track_id) vals = fn.split('.') stub = vals[0] if stub.startswith('T'): stub = stub[1:] try: track_id = int(stub) except: return "Cannot find audio file %s" % str(fn_or_track_id) #we are hardcoding a path here to get around NFS issues audiofn = gordon_db.get_full_audiofilename(track_id) if not audiofn.endswith('.mp3'): audiofn = widgets.transcode_audio_to_mp3(audiofn) print 'Serving', audiofn return cherrypy.lib.cptools.serveFile(path=audiofn, disposition='attachment', name=os.path.basename(audiofn)) @expose("json") @identity.require(identity.has_permission("listen")) def feature(self, fn_or_track_id): #this should be flexible enough to do either a filename or track_id fn_or_track_id = str(fn_or_track_id) (path, fn) = os.path.split(fn_or_track_id) vals = fn.split('.') stub = vals[0] if stub.startswith('T'): stub = stub[1:] try: track_id = int(stub) except: return "Cannot find feature %s" % str(fn_or_track_id) track = gordon_model.Track.query.get(track_id) outfn = track.fn_feature print 'Serving', outfn return cherrypy.lib.cptools.serveFile(path=outfn, disposition='attachment', name=os.path.basename(outfn)) #return serve_file(fn) @expose("json") @identity.require(identity.has_permission("listen")) def cover(self, fn_or_album_id): #this should be flexible enough to do either a filename or album_id #serves a cover if it is found. Otherwise serves an empty album graphic fn_or_album_id = str(fn_or_album_id) (path, fn) = os.path.split(fn_or_album_id) vals = fn.split('.') stub = vals[0] if stub.startswith('A'): stub = stub[1:] try: album_id = int(stub) except: return "Cannot find cover %s" % str(fn_or_album_id) fn = '' try: album = gordon_db.Album.query.get(album_id) fn = album.fn_albumcover except: pass if fn == '' or not os.path.exists(fn): fn = '/static/images/emptyalbum.jpg' # return serve_file(fn) return cherrypy.lib.cptools.serveFile(path=fn) @expose(template="gordonweb.templates.login") def login(self, forward_url=None, *args, **kw): """Show the login form or forward user to previously requested page.""" if forward_url: if isinstance(forward_url, list): forward_url = forward_url.pop(0) else: del request.params['forward_url'] new_visit = visit.current() if new_visit: new_visit = new_visit.is_new if (not new_visit and not identity.current.anonymous and identity.was_login_attempted() and not identity.get_identity_errors()): redirect(forward_url or '/', kw) if identity.was_login_attempted(): if new_visit: msg = _(u"Cannot log in because your browser " "does not support session cookies.") else: msg = _(u"The credentials you supplied were not correct or " "did not grant access to this resource.") elif identity.get_identity_errors(): msg = _(u"You must provide your credentials before accessing " "this resource.") else: msg = _(u"Please log in.") if not forward_url: forward_url = request.headers.get("Referer", "/") # we do not set the response status here anymore since it # is now handled in the identity exception. return dict(logging_in=True, message=msg, forward_url=forward_url, previous_url=request.path_info, original_parameters=request.params) @expose() def logout(self): """Log out the current identity and redirect to start page.""" identity.current.logout() redirect("/") @expose(template="gordonweb.templates.stats") @identity.require(identity.has_permission("listen")) def stats(self): track_total = gordon_model.Track.query.count() artist_total = gordon_model.Artist.query.count() album_total = gordon_model.Album.query.count() sec_total = gordon_model.session.query( func.sum(gordon_model.Track.secs)).first()[0] #string s = sec_total temp = float(s) / (60 * 60 * 24) d = int(temp) temp = (temp - d) * 24 h = int(temp) temp = (temp - h) * 60 m = int(temp) temp = (temp - m) * 60 sec = temp time_total = '%s days %s hours %s minutes %i seconds' % (d, h, m, int(sec)) track_labeled = track_total - gordon_model.Track.query.filter_by( mb_id='').count() artist_labeled = artist_total - gordon_model.Artist.query.filter_by( mb_id='').count() album_labeled = album_total - gordon_model.Album.query.filter_by( mb_id='').count() x = 100.0 * track_labeled / track_total track_pct = '%2.2f%%' % (100.0 * track_labeled / track_total) artist_pct = '%2.2f%%' % (100.0 * artist_labeled / artist_total) album_pct = '%2.2f%%' % (100.0 * album_labeled / album_total) return dict(track_total=track_total, artist_total=artist_total, album_total=album_total, track_labeled=track_labeled, artist_labeled=artist_labeled, album_labeled=album_labeled, track_pct=track_pct, artist_pct=artist_pct, album_pct=album_pct, time_total=time_total, sec_total=sec_total) #track------------------------------------------- @expose(template="gordonweb.templates.track") @identity.require(identity.has_permission("listen")) @paginate('artists', default_order='name', limit=20) @paginate('albums', default_order='name', limit=20) def track(self, id=1, action='view'): if len(id) == 36: #mbid track = gordon_model.Track.query.filter_by(mb_id=id) if track.count() > 0: track = track.first() id = track.id else: track = None else: track = gordon_model.Track.query.get(id) if track == None: flash('gordon_model.Track %s not found' % str(id)) redirect('/') track = gordon_model.Track.query.get(id) referer = cherrypy.request.headerMap.get("Referer", "/") track.referer = referer yahoo_url = get_yahoo_player_audio_url(track) #widget_data is for the widget to render while track is the actual record. #allows us to render for viewing using DataGrid track_time = widgets.get_track_time(track) #feat_pathlist = widgets.get_featurelist(track.id) feat_urllist = list() #for p in feat_pathlist : # elem =ET.Element('a',href='/%s' % p) # (pth,feat)=os.path.split(p)## #set a short name to display in url # shortfeat=feat.split('.') # shortfeat=string.join(shortfeat[2:],'.') # elem.text=shortfeat # feat_urllist.append(elem) if action == 'edit': track_widget = track_edit_widget track_widget_data = track alternate_action = list() sub1 = ET.Element('a', href='/track/%s/view' % str(id)) sub1.text = 'View' alternate_action.append(sub1) print alternate_action #alternate_action=ET.Element('a',href='/track/%s/view' % str(id)) #alternate_action.text='View' afeat_graph = '' else: #view track_widget = null_widget track_widget_data = list() #rotate_record(track) alternate_action = list() sub1 = ET.Element('a', href='/track/%s/edit' % str(id)) sub1.text = 'Edit' alternate_action.append(sub1) grstr = '/dynimage?track=%s' % str(id) afeat_graph = ET.Element('a', href=grstr) afeat_img = ET.SubElement(afeat_graph, 'img', align='right', src=grstr, width='750') #suppress alternate action if we are not an editor if not ("edit" in identity.current.permissions): alternate_action = '' if track.mb_id <> None and len(track.mb_id) > 5: track_mb_id_link = ET.Element( 'a', href='http://www.musicbrainz.org/track/%s.html' % track.mb_id) #,target='_blank') track_mb_id_link.text = "MusicBrainz" else: track_mb_id_link = '' try: htk_annotation_datatables = ( widgets.generate_htk_annotation_datatables_for_track(track)) except: htk_annotation_datatables = [] return dict(track_widget=track_widget, track_widget_data=track_widget_data, track=track, afeat_graph=afeat_graph, alternate_action=alternate_action, artist_widget=artist_datagrid, artists=track.artists, track_time=track_time, album_widget=album_datagrid, albums=track.albums, collection_widget=collection_datagrid, collections=track.collections, yahoo_url=yahoo_url, feat_urllist=feat_urllist, track_mb_id_link=track_mb_id_link, htk_annotation_datatables=htk_annotation_datatables) @expose(template='gordonweb.templates.tracks') @identity.require(identity.has_permission("listen")) @paginate('tracks', default_order='id', limit=20) def tracks(self, track=''): print 'gordon_model.Track is', track if track <> '': tracks = gordon_model.Track.query.filter( "(lower(track.title) ~ ('%s'))" % track.lower()) if tracks.count() == 1: #we only have one track, redirect to the album page redirect("/track/%s/view" % tracks[0].id) print 'gordon_model.Tracks', tracks.count() else: tracks = gordon_model.Track.query().order_by('title') print 'gordon_model.Tracks', tracks.count(), type(tracks) return dict(tracks=tracks, tracklist=track_datagrid) @expose() @validate(form=track_edit_widget) @error_handler(track) @identity.require(identity.has_permission("edit")) def track_modify(self, **kw): operation = kw.pop('operation') id = kw.pop('id') referer = kw.pop('referer') track = gordon_model.Track.query.get(id) modfields = list() if operation == 'edit': for field in kw.keys(): #if track._SO_getValue(field)<> kw[field] : if track.__getattribute__(field) <> kw[field]: modfields.append(field) track.__setattr__(field, kw[field]) #not sure how to set a value using field name so we use eval #exec('track.%s=%s' % (field,repr(kw[field]))) if len(modfields) > 0: st = 'Saved track %s with field(s) %s' % ( str(id), string.join(modfields, ',')) else: st = 'Nothing to save in track %s' % str(id) flash(st) if referer.count('resolve') > 0: raise (redirect(referer)) else: raise redirect('/track/%s/edit' % id) elif operation == 'delete': #decrement track count for related album #I wish this could happen in the gordon_model.Track class but can't figure out how to get things to work. gordon_db.delete_track(track) #albums = track.albums; #session.delete(track) flash('Deleted track %s' % str(id)) for album in albums: if album.trackcount > 0: print 'Decrementing track count of album', album album.trackcount -= 1 print 'gordon_model.Album track count is now', album.trackcount redirect(referer) @expose("json") @identity.require(identity.has_permission("listen")) def dynimage(self, track=1, name=None, **kwargs): track = gordon_model.Track.query.get(track) h = widgets.plot_track_features(track, name, **kwargs) cherrypy.response.headers['Content-Type'] = "image/png" page = h.getvalue() return page #artists----------------------------------------- @expose(template="gordonweb.templates.artist") @paginate('albums', default_order='name', limit=25) @paginate('artist_top_sims', default_order='value', limit=20) @paginate('artist_bottom_sims', default_order='value', limit=20) #@paginate('tracks', default_order='title',limit=10) @identity.require(identity.has_permission("listen")) def artist(self, id=1, action='view', shuffle=''): if len(id) == 36: #mbid artist = gordon_model.Artist.query.filter_by(mb_id=id) if artist.count() > 0: artist = artist.first() id = artist.id else: artist = None else: artist = gordon_model.Artist.query.get(id) if artist == None: flash('gordon_model.Artist %s not found' % str(id)) redirect('/') referer = cherrypy.request.headerMap.get("Referer", "/") artist.referer = referer if artist.mb_id <> None and len(artist.mb_id) > 5: artist_mb_id_link = ET.Element( 'a', href='http://www.musicbrainz.org/artist/%s.html' % artist.mb_id) #,target='_top') artist_mb_id_link.text = "MusicBrainz" else: artist_mb_id_link = '' #widget_data is for the widget to render while track is the actual record. #allows us to render for viewing using DataGrid if action == 'edit': artist_widget = artist_edit_widget artist_widget_data = artist alternate_action = ET.Element('a', href='/artist/%s/view' % str(id)) alternate_action.text = 'View' else: artist_widget = null_widget artist_widget_data = list() #rotate_record(artist) alternate_action = ET.Element('a', href='/artist/%s/edit' % str(id)) alternate_action.text = 'Edit' artist_sims = list() artist_top_sims = list() artist_bottom_sims = list() #artist_sims=gordon_model.ArtistSim.query.filter_by(artist_id=id) #if artist_sims.count()==0 : # artist_top_sims=list() # artist_bottom_sims=list() #else : # artist_sims=artist_sims[artist_sims.count()-1] # artist_top_sims=artist_sims.top_sims # artist_bottom_sims=artist_sims.bottom_sims #build list of audio files #for t in artist.tracks : tracks = artist.tracks random.shuffle(tracks) audiourls = list() for (ctr, t) in enumerate(tracks): link = widgets.get_yahoo_player_audio_url(t, arrow=False) audiourls.append(link) if ctr == 100: break if shuffle == '': shuffle_state = 0 else: shuffle_state = 1 return dict(artist_widget=artist_widget, artist_widget_data=artist_widget_data, artist=artist, alternate_action=alternate_action, album_widget=album_datagrid, albums=artist.albums, artist_mb_id_link=artist_mb_id_link, shuffle_state=shuffle_state, action=action, artist_top_sims=artist_top_sims, artist_bottom_sims=artist_bottom_sims, artist_top_sim_datagrid=artist_top_sim_datagrid, artist_bottom_sim_datagrid=artist_bottom_sim_datagrid, audiourls=audiourls) @expose(template='gordonweb.templates.artists') @identity.require(identity.has_permission("listen")) @paginate('artists', default_order='name', limit=20) def artists(self, artist='', album=''): if artist <> '': artists = gordon_model.Artist.query.filter( "(lower(artist.name) ~ ('%s'))" % artist.lower()) if artists.count() == 1: redirect("/artist/%s/view" % artists[0].id) else: artists = gordon_model.Artist.query() return dict(artists=artists, artistlist=artist_datagrid) @expose(template="gordonweb.templates.artists") @identity.require(identity.has_permission("listen")) @paginate('artists', default_order='name', limit=10000000) def artists_all(self): artists = gordon_model.Artist.query() return dict(artists=artists, artistlist=artist_datagrid) @expose() @validate(form=artist_edit_widget) @identity.require(identity.has_permission("edit")) @error_handler(artist) def artist_modify(self, **kw): operation = kw.pop('operation') id = kw.pop('id') mergeid = kw.pop('mergeid') referer = kw.pop('referer') artist = gordon_model.Artist.query.get(id) modfields = list() if operation == 'edit': for field in kw.keys(): #if artist._SO_getValue(field)<> kw[field] : if artist.__getattribute__(field) <> kw[field]: modfields.append(field) artist.__setattr__(field, kw[field]) if len(modfields) > 0: st = 'Saved artist %s with field(s) %s' % ( str(id), string.join(modfields, ',')) else: st = 'Nothing to save in artist %s' % str(id) flash(st) if referer.count('resolve') > 0: raise (redirect(referer)) else: raise redirect('/artist/%s/edit' % id) elif operation == 'delete': #session.delete(artist) flash('Would have deleted artist %s' % str(id)) redirect(referer) elif operation == 'merge': #str = 'Would have merged artist %s with artist %s' % (str(id),str(mergeid)) flash('Would have merged artist %s with artist %s' % (str(id), str(mergeid))) tracks = gordon_model.Artist.query.get(int(id)) for t in tracks: print redirect(referer) #queries ----------------------- @expose("json") @identity.require(identity.has_permission("listen")) def query(self, album='', artist='', track='', collection=''): if album <> '': redirect("/albums", dict(album=album)) elif artist <> '': redirect("/artists", dict(artist=artist)) elif collection <> '': redirect("/collections", dict(collection=collection)) elif track <> '': redirect("/tracks", dict(track=track)) else: referrer = request.headers.get("Referer", "/") if referrer.endswith('query'): #break feedback loop redirect('/') else: redirect(referrer) #albums----------------------------------------- @expose(template="gordonweb.templates.album") @identity.require(identity.has_permission("listen")) @paginate('tracks', default_order='tracknum', limit=1000000) @paginate('artists', default_order='name', limit=50) def album(self, id=1, action='view', shuffle=''): if len(id) == 36: #mbid album = gordon_model.Album.query.filter_by(mb_id=id) if album.count() > 0: album = album.first() id = album.id else: album = None else: album = gordon_model.Album.query.get(id) if album == None: flash('gordon_model.Album %s not found' % str(id)) redirect('/') referer = cherrypy.request.headerMap.get("Referer", "/") album.referer = referer albumcover = widgets.get_albumcover(album) artiststring = widgets.get_album_artiststring(album) if album.mb_id <> None and len(album.mb_id) > 5: album_mb_id_link = ET.Element( 'a', href='http://www.musicbrainz.org/release/%s.html' % album.mb_id) #target='_blank') album_mb_id_link.text = "MusicBrainz" else: album_mb_id_link = '' #widget_data is for the widget to render while track is the actual record. #allows us to render for viewing using DataGrid if action == 'edit': album_widget = album_edit_widget album_widget_data = album alternate_action = ET.Element('a', href='/album/%s/view' % str(id)) alternate_action.text = 'View' track_widget = track_edit_datagrid deleteform_header = ET.Element('form', action='/album_modify/deletetracks', method="post") deleteform_button = ET.Element( 'input', type='submit', value='Delete Selected gordon_model.Tracks') deleteform_footer = ET.Element('/form') else: album_widget = null_widget album_widget_data = list() #rotate_record(artist) alternate_action = ET.Element('a', href='/album/%s/edit' % str(id)) alternate_action.text = 'Edit' track_widget = track_datagrid_no_album deleteform_header = '' deleteform_button = '' deleteform_footer = '' album_sims = list() album_top_sims = list() album_bottom_sims = list() # album_sims=gordon_model.AlbumSim.query.filter_by(album_id=id) # if album_sims.count()==0 : # album_top_sims=list() # album_bottom_sims=list() # else : # album_sims=album_sims[album_sims.count()-1] # album_top_sims=album_sims.top_sims # album_bottom_sims=album_sims.bottom_sims top_albumcovers = list() top_albumtitles = list() top_albumartists = list() albumtitles = set() albumartists = set() albumids = set() #albums already used ctr = 0 idx = 0 #build our grid for similar albums doall = False do_albumgrid = False while do_albumgrid and len(album_top_sims) > 0: if idx == len(album_top_sims): #oops we ran out of data. Loop again and take whatever we can get idx = 1 doall = True if ctr == 9: break other = album_top_sims[idx].other if not other: break album_id = other.id atitle = other.name if len(album_top_sims[idx].other.artists) > 1: aartist = "Various gordon_model.Artists" elif len(album_top_sims[idx].other.artists) == 0: aartist = "Unknown" else: aartist = album_top_sims[idx].other.artists[0].name albumcvr = widgets.get_albumcover(album_top_sims[idx].other, clickable=False, sz=90) albumtitle = ET.Element('a', href='/album/%s' % album_id) if len(atitle) > 20: atitle = '%s...' % atitle[0:19] albumtitle.text = atitle albumartist = ET.Element('a', href='/album/%s' % album_id) albumartist.text = aartist idx += 1 if not doall: #we try to skip some undesirable albums if atitle == "": #skip blank albums continue if atitle.lower() == gordon_model.Album.query.get( id).name.lower and aartist.lower( ) == gordon_model.Album.query.get(id).artists[0].name: continue if aartist.lower() == 'various artists': continue if aartist.lower() in albumartists: continue albumartists.add(aartist.lower()) albumtitles.add(atitle.lower()) top_albumcovers.append(albumcvr) top_albumtitles.append(albumtitle) top_albumartists.append(albumartist) ctr += 1 do_albumgrid = len(top_albumcovers) > 8 #should we show an album grid? tracks = album.tracks if shuffle <> '': random.shuffle(tracks) return dict(album_widget=album_widget, album_widget_data=album_widget_data, album=album, alternate_action=alternate_action, artiststring=artiststring, album_mb_id_url=get_album_mb_id_url(album.mb_id), albumcover=albumcover, tracks=album.tracks, track_widget=track_widget, artist_widget=artist_datagrid, artists=album.artists, deleteform_header=deleteform_header, deleteform_button=deleteform_button, deleteform_footer=deleteform_footer, album_mb_id_link=album_mb_id_link, action=action, album_top_sims=album_top_sims, album_bottom_sims=album_bottom_sims, album_top_sim_datagrid=album_top_sim_datagrid, album_bottom_sim_datagrid=album_bottom_sim_datagrid, top_albumcovers=top_albumcovers, top_albumtitles=top_albumtitles, top_albumartists=top_albumartists, do_albumgrid=do_albumgrid) @expose() @validate(form=album_edit_widget) @identity.require(identity.has_permission("edit")) @error_handler(album) def album_modify(self, **kw): operation = kw.pop('operation') id = kw.pop('id') referer = kw.pop('referer') album = gordon_model.Album.query.get(id) modfields = list() if operation == 'edit': for field in kw.keys(): if album.__getattribute__(field) <> kw[field]: modfields.append(field) album.__setattr__(field, kw[field]) #not sure how to set a value using field name so we use eval exec('album.%s=%s' % (field, repr(kw[field]))) if len(modfields) > 0: st = 'Saved album %s with field(s) %s' % ( str(id), string.join(modfields, ',')) else: st = 'Nothing to save in album %s' % str(id) flash(st) if referer.count('resolve') > 0: raise (redirect(referer)) else: raise redirect('/album/%s/edit' % id) elif operation == 'delete': gordon_db.delete_album(album) flash('Deleted album %s' % str(id)) redirect(referer) elif operation == 'deletetracks': for field in kw.keys(): #delete checked tracks if kw[field] == 'on': try: id = int(field) track = gordon_model.Track.query.get(id) print 'Deleting', track gordon_db.delete_track(track) except: print 'Could not delete track', field redirect(referer) #123979 @expose(template='gordonweb.templates.albums') @paginate('albums', default_order='name', limit=20) @identity.require(identity.has_permission("listen")) def albums(self, album=''): if album <> '': print 'Searching for', album albums = gordon_model.Album.query.filter( "(lower(album.name) ~ ('%s'))" % album.lower()) if albums.count() == 1: #we only have one album, redirect to the album page redirect("/album/%s/view" % albums[0].id) else: albums = gordon_model.Album.query() return dict(albums=albums, albumlist=album_datagrid) @expose(template="gordonweb.templates.albums") @paginate('albums', default_order='name', limit=1000000) @identity.require(identity.has_permission("listen")) def albums_all(self): albums = gordon_model.Album.query() return dict(albums=albums, albumlist=album_datagrid) #resolver--------------------------------------------- @expose("json") @identity.require(identity.has_permission("edit")) def resolve_submitalbum(self, id=0, mb_id=''): mbrainz_resolver = gordon.db.mbrainz_resolver.GordonResolver() if mb_id == '': st = 'Recieved no mb_id' elif id == 0: st = 'Recieved invalid id' else: mbrainz_resolver.update_album(id=id, mb_id=mb_id, use_recommended_track_order=True, doit=True) st = 'Resolved musicbrainz album id %s against internal album id %s' % ( mb_id, id) flash(st) #now go back to our review page redirect("/resolve_viewalbums") #referrer=request.headers.get("Referer", "/") #redirect(referrer) @expose() @identity.require(identity.has_permission("edit")) def resolve_submitalbums(self, **kw): mbrainz_resolver = gordon.db.mbrainz_resolver.GordonResolver() st = '' for k in kw: (id, mb_id) = k.split('SEP') mb_id = mb_id.replace('H', '-') mbrainz_resolver.update_album(id=id, mb_id=mb_id, use_recommended_track_order=True, doit=True) st = "%s\nUpdated %s" % (st, id) flash(st) redirect("/resolve_viewalbums") @expose() @identity.require(identity.has_permission("edit")) def resolve_recommendalbum(self, id=1): mbrainz_resolver = gordon.db.mbrainz_resolver.GordonResolver() mbrainz_resolver.resolve_album(id=id) redirect(request.headers.get("Referer", "/")) @expose() @identity.require(identity.has_permission("edit")) def resolve_setalbumstatus(self, id, status="weird", sort_order='conf'): #set the status of an album. id = int(id) album = gordon_model.Album.query.get(id) if gordon_model.AlbumStatus.query.filter_by( album=album, status=status).count() == 0: gordon_model.AlbumStatus(album=album, status=status) #TODO: this next line will not ever return recommendations for albums marked with *any* AlbumStatus #it should probably be to only ignore those which are from a fixed list of AlbumStatus codewords. Anyway this warrants #discussion. . . #here we pull up the next album in the list. Is that what we want to do? mbrecommend = gordon_model.Mbalbum_recommend.query.filter( gordon_model.Mbalbum_recommend.album.has( gordon_model.Album.mb_id == '')).filter( gordon_model.Mbalbum_recommend.album.has( ~gordon_model.Album.status.any())).order_by('%s DESC' % sort_order) print 'Redirecting to', str(mbrecommend[0].album_id) redirect("/resolve_viewalbum/%s" % str(mbrecommend[0].album_id)) @expose(template="gordonweb.templates.resolve_viewalbum") @paginate('tracks', limit=100000000) @identity.require(identity.has_permission("edit")) def resolve_viewalbum(self, id=1): album = gordon_model.Album.query.get(id) tracks = album.tracks albumcover = widgets.get_albumcover(album) artiststring = widgets.get_album_artiststring(album) res = gordon_model.Mbalbum_recommend.query.filter_by(album_id=id) if res.count() <> 1: flash( 'No recommendation or multiple recommendations for album %s' % id) redirect("/resolve_viewalbums") else: mbrecommend = res[0] if mbrecommend.trackorder <> None: trackorder = eval(mbrecommend.trackorder) if len(trackorder) == len(tracks): trks = [0] * len(tracks) for t in tracks: idx = trackorder[t.id] trks[idx] = t tracks = trks mbrainz_resolver = gordon.db.mbrainz_resolver.GordonResolver() #get the recommended album name for display (recommend_tracks, status) = mbrainz_resolver.add_mbalbumdata_to_trackdict( mbrecommend.mb_id, tracks) #adds mb tracks to tracks structure if status == False: #try redoing the recommmendation print 'Trying to get closest album' mbrainz_resolver.resolve_album(id) (recommend_tracks, status) = mbrainz_resolver.add_mbalbumdata_to_trackdict( mbrecommend.mb_id, tracks) #adds mb tracks to tracks structure if status == False: flash('Unable to merge tracks for album %s' % id) redirect('/resolve_viewalbums') mbrecommend_mb_id_url = widgets.get_album_mb_id_url(mbrecommend.mb_id) mb_album = mbrecommend.mb_album submit_form = TableForm( fields=[ TextField(name='mb_id', default=mbrecommend.mb_id, label='Recommended MB_ID', attrs=dict(size='38')) ], action="../resolve_submitalbum/%s" % str(id), submit_text="Accept and Update(!)", ) return dict(album=album, artiststring=artiststring, albumcover=albumcover, tracks=recommend_tracks, mb_album=mb_album, tracklist=mbrecommend_track_datagrid, mbrecommend=mbrecommend, submit_form=submit_form, mbrecommend_mb_id_url=mbrecommend_mb_id_url) @expose(template="gordonweb.templates.resolve_viewalbums") @paginate('mbrecommend', default_order='-conf', limit=20) def resolve_viewalbums(self): #get recommendations for un-mbrid albums with no status messages #here we assume that any status is a bad one. But this could be softened by changing the any part of the query mbrecommend = gordon_model.Mbalbum_recommend.query.filter( gordon_model.Mbalbum_recommend.album.has( or_(gordon_model.Album.mb_id == '', gordon_model.Album.mb_id == None))).filter( gordon_model.Mbalbum_recommend.album.has( ~gordon_model.Album.status.any())) return dict(mbrecommend=mbrecommend, mbrecommend_list=mbrecommend_datagrid) #download --------------------------------------- #@expose("json") @expose() #@identity.require(identity.has_permission("listen")) def download(self, params=''): pdict = { 'track_id': '', 'artist_id': '', 'album_id': '', 'collection_id': '', 'randomize': '0' } pairs = params.split('!') for p in pairs: (key, val) = p.split(':') pdict[key] = val tracks = '' album = '' if pdict['album_id'] <> '': tracks = gordon_model.Album.query.get(int( pdict['album_id'])).tracks elif pdict['collection_id'] <> '': tracks = gordon_model.Collection.query.get( int(pdict['collection_id'])).tracks elif pdict['artist_id'] <> '': tracks = gordon_model.Artist.query.get(int( pdict['artist_id'])).tracks elif pdict['track_id'] <> '': tracks = [gordon_model.Track.query.get(int(pdict['track_id']))] return widgets.download(tracks=tracks, album=album, randomize=int(pdict['randomize'])) #playlist --------------------------------------- # @expose("json", format="xml") @expose("gordonweb.templates.playlist_album", format="XML") #@identity.require(identity.has_permission("listen")) def playlist(self, params=''): if params.endswith('.xml'): params = params[0:len(params) - 4] print params pdict = { 'track_id': '', 'artist_id': '', 'album_id': '', 'randomize': '0' } pairs = params.split('!') for p in pairs: (key, val) = p.split(':') pdict[key] = val tracks = '' album = '' if pdict['album_id'] <> '': album = gordon_model.Album.query.get(int(pdict['album_id'])) tracks = album.tracks elif pdict['artist_id'] <> '': tracks = gordon_model.Artist.query.get(int( pdict['artist_id'])).tracks elif pdict['track_id'] <> '': tracks = [gordon_model.Track.query.get(int(pdict['track_id']))] return widgets.playlist(tracks=tracks, album=album, randomize=int(pdict['randomize'])) #collections----------------------------------------- @expose(template="gordonweb.templates.collection") @identity.require(identity.has_permission("listen")) @paginate('tracks', default_order='album', limit=1000000) def collection(self, id=1, action='view', shuffle=''): collection = gordon_model.Collection.query.get(id) if collection == None: flash('gordon_model.Collection %s not found' % str(id)) redirect('/') tracks = collection.tracks if shuffle <> '': random.shuffle(tracks) return dict(action=action, collection=collection, collection_datagrid=collection_datagrid, tracks=tracks, track_datagrid=track_datagrid) @expose(template='gordonweb.templates.collections') @paginate('collections', default_order='name', limit=20) @identity.require(identity.has_permission("listen")) def collections(self, collection=''): if collection <> '': print 'Searching for', collection collections = gordon_model.Collection.query.filter( "(lower(collection.name) ~ ('%s'))" % collection.lower()) if collections.count() == 1: #we only have one collection, redirect to the collection page redirect("/collection/%s/view" % collections[0].id) else: collections = gordon_model.Collection.query() return dict(collections=collections, collectionlist=collection_datagrid) @expose(template="gordonweb.templates.collections") @paginate('collections', default_order='name', limit=1000000) @identity.require(identity.has_permission("listen")) def collections_all(self): collections = gordon_model.Collection.query() return dict(collections=collections, collectionlist=collection_datagrid) #feature extractors----------------------------------------- @expose(template="gordonweb.templates.feature_extractor") @identity.require(identity.has_permission("listen")) #@paginate('tracks', default_order='tracknum',limit=1000000) def feature_extractor(self, id=1, action='view'): fe = gordon_model.FeatureExtractor.query.get(id) if fe == None: flash('gordon_model.FeatureExtractor %s not found' % str(id)) redirect('/') source_code = get_feature_extractor_source_code(fe) return dict(action=action, feature_extractor=fe, source_code=source_code) @expose(template='gordonweb.templates.feature_extractors') @paginate('feature_extractors', default_order='name', limit=20) def feature_extractors(self, feature_extractor=''): if feature_extractor <> '': print 'Searching for', feature_extractor fes_extractors = gordon_model.FeatureExtractor.query.filter( "(lower(feature_extractor.name) ~ ('%s'))" % feature_extractor.lower()) if fes.count() == 1: #we only have one feature_extractor, redirect to the feature_extractor page redirect("/feature_extractor/%s/view" % fes[0].id) else: fes = gordon_model.FeatureExtractor.query() return dict(feature_extractors=fes, feature_extractorlist=feature_extractor_datagrid)