Source code for mishmash.web.views

import os
import random
from gettext import gettext as _

from pyramid.response import Response
from pyramid.view import view_config
from pyramid.httpexceptions import HTTPNotFound

from sqlalchemy import desc

from eyed3.utils import formatTime
from eyed3.core import (LP_TYPE, EP_TYPE, COMP_TYPE, VARIOUS_TYPE, LIVE_TYPE,
                        DEMO_TYPE, SINGLE_TYPE, ALBUM_TYPE_IDS)

from ..__about__ import __project_name__ as PROJECT_NAME
from ..__about__ import __version__ as VERSION

from .. import database
from .. import util
from ..orm import Artist, Album, Image, VARIOUS_ARTISTS_NAME, VARIOUS_ARTISTS_ID

_vars = {"project_name": PROJECT_NAME,
         "project_version": VERSION,
        }


[docs]class ResponseDict(dict): def __init__(self, *args, **kwargs): super(ResponseDict, self).__init__(*args, **kwargs) self.update(_vars)
# Not in eyeD3 ALL_TYPE = "All" TYPE_DISPLAY_NAMES = {ALL_TYPE: _(ALL_TYPE), LP_TYPE: _("LPs"), EP_TYPE: _("EPs"), COMP_TYPE: _("Compilations"), VARIOUS_TYPE: VARIOUS_ARTISTS_NAME, LIVE_TYPE: _("Live"), DEMO_TYPE: _("Demos"), SINGLE_TYPE: _("Singles"), } TYPE_DISPLAY_NAMES[ALL_TYPE] = _(ALL_TYPE)
[docs]@view_config(route_name="home", renderer="templates/home.pt", layout="main-layout") def home_view(request): return ResponseDict()
[docs]@view_config(route_name="all_artists", renderer="templates/artists.pt", layout="main-layout") def allArtistsView(request): NUM_COLS = 2 NUMBER = u"#" OTHER = u"Other" buckets = {} # buckets['A'] = count, etc. artist_dict = {} def _whichBucket(name): first_l = name[0].upper() if not first_l.isalpha(): first_l = NUMBER if first_l.isnumeric() else OTHER if first_l not in buckets: buckets[first_l] = 0 buckets[first_l] += 1 return first_l count = 0 active_types = _getActiveAlbumTypes(request.params) artist_types = {} session = request.DBSession for artist in session.query(Artist)\ .order_by(Artist.sort_name).all(): types = set([alb.type for alb in artist.albums]) for t in types: if t not in artist_types: artist_types[t] = { "active": t in active_types, "display_name": TYPE_DISPLAY_NAMES[t], } if not active_types.intersection(types): continue count += 1 bucket = _whichBucket(artist.sort_name) if bucket not in artist_dict: artist_dict[bucket] = [] if artist_dict[bucket]: # Adding show_origin member to the instance here. True for # dup artists, false otherwise. if artist_dict[bucket][-1].name == artist.name: artist_dict[bucket][-1].show_origin = True artist.show_origin = True else: artist.show_origin = False else: artist.show_origin = False artist_dict[bucket].append(artist) keys = list(buckets.keys()) keys.sort() if OTHER in keys: keys.remove(OTHER) keys.append(OTHER) # Build column based on keys and counts col_cnt, col_curr = 0, 0 key_cols = [] # key_cols[0] = [k1, k2, ...], key_cols[1] = [k10, ...] key_cols.append([]) num_per_col = round(count / NUM_COLS) for k in keys: col_cnt += buckets[k] if col_cnt >= num_per_col: key_cols.append([]) col_curr += 1 col_cnt = 0 key_cols[col_curr].append(k) return ResponseDict(artist_keys=keys, artist_dict=artist_dict, artist_types=artist_types, artist_count=count, key_columns=key_cols)
[docs]@view_config(route_name="artist", renderer="templates/artist.pt", layout="main-layout") def artistView(request): artist_id = int(request.matchdict["id"]) session = request.DBSession artist = session.query(Artist).filter_by(id=artist_id).first() if not artist: raise HTTPNotFound() def _filterByType(typ, artist, albums): if typ == SINGLE_TYPE: return artist.getTrackSingles() elif typ == ALL_TYPE: return albums else: return artist.getAlbumsByType(typ) albums = list(artist.albums) all_tabs = [ALL_TYPE] + ALBUM_TYPE_IDS active_albums = [] active_singles = [] active_tab = request.GET.get("album_tab", None) if not active_tab: # No album type was requested, try to pick a smart one. for active_tab in all_tabs: active_albums = _filterByType(active_tab, artist, albums) if active_albums: break else: active_albums = _filterByType(active_tab, artist, albums) if active_tab == SINGLE_TYPE: active_singles = active_albums active_albums = [] if active_albums: active_albums = util.sortByDate(active_albums, active_tab == LIVE_TYPE) else: # Unlike tags, the orm.Track does not have dates so not sorting :/ # XXX active_singles = util.sortByDate(active_singles) pass for a in active_albums: covers = [img for img in a.images if img.type == Image.FRONT_COVER_TYPE] a.cover = random.choice(covers) if covers else None tabs = {} if artist.id != VARIOUS_ARTISTS_ID: for name in all_tabs: t = dict(name=name, display_name=TYPE_DISPLAY_NAMES[name], active=active_tab == name, has_items=bool(len(_filterByType(name, artist, albums)))) if name in tabs: raise ValueError("Duplicate album type found: " + name) tabs[name] = t if len([t for t in tabs.values() if t["has_items"]]) == 2: # If all we have is "All" and another type, lose "All" tabs[ALL_TYPE]["has_items"] = False return ResponseDict(artist=artist, active_tab=active_tab, active_albums=active_albums, active_singles=active_singles, tabs=tabs, )
[docs]@view_config(route_name="images.covers") def covers(request): iid = request.matchdict["id"] if iid == "default": return Response(content_type="image/png", body=DEFAULT_COVER_DATA) else: session = request.DBSession image = session.query(Image).filter(Image.id == int(iid)).first() if not image: raise HTTPNotFound() return Response(content_type=image.mime_type, body=image.data)
with open(os.path.join(os.path.dirname(__file__), "static", "record150.png"), "rb") as _cover_fp: DEFAULT_COVER_DATA = _cover_fp.read() del _cover_fp
[docs]@view_config(route_name="new_music", renderer="templates/new_music.pt", layout="main-layout") def newMusicView(request): from math import ceil session = request.DBSession albums = session.query(Album).order_by(desc("date_added")).limit(25).all() # FIXME: handle new singles here, make sure this works for various return ResponseDict(albums=albums, ceil=ceil)
[docs]@view_config(route_name="album", renderer="templates/album.pt", layout="main-layout") def albumView(request): album_id = int(request.matchdict["id"]) session = request.DBSession album = session.query(Album).filter_by(id=album_id).first() if not album: raise HTTPNotFound() return ResponseDict(album=album, formatTime=formatTime, )
[docs]@view_config(route_name="search", renderer="templates/search_results.pt", layout="main-layout") def searchView(request): query = request.POST["q"] results = database.search(request.DBSession, query) return ResponseDict(**results)
[docs]@view_config(route_name="all_albums", renderer="templates/albums.pt", layout="main-layout") def allAlbumsView(request): album_dict = {} album_types = {} if ("filter-form" in request.params and request.params.get("filter-form") == "true" and not request.params.getall("type")): # Form submit with no filters checks, this is not the default /albums active_types = set() else: active_types = _getActiveAlbumTypes(request.params) session = request.DBSession for album in session.query(Album)\ .order_by(Album.original_release_date).all(): if album.type not in album_types: album_types[album.type] = { "active": album.type in active_types, "display_name": TYPE_DISPLAY_NAMES[album.type], } if not album_types[album.type]["active"]: continue d = album.getBestDate() bucket = d.year // 10 * 10 if d else 0 if bucket not in album_dict: album_dict[bucket] = [] album_dict[bucket].append(album) buckets = list(album_dict.keys()) buckets.sort() return ResponseDict(album_decades=buckets, album_dict=album_dict, album_types=album_types)
def _getActiveAlbumTypes(params): inc_types = set([p for p in params.getall("type") if p[0] != '!']) exc_types = set([p[1:] for p in params.getall("type") if p[0] == '!']) active_types = set(ALBUM_TYPE_IDS).difference(exc_types) if inc_types: active_types = active_types.intersection(inc_types) return active_types