def key_results(request): """ This responds to keyword search request (typically from the entry box on the jumbotron but could be anywhere. If there is more than one page, this routine may be re-entered to process other pages. """ start_time = time.time() page = request.GET.get('page') if page is None: form = KeySearchForm(request.GET) if form.is_valid(): # Uses session cookies to track the query between pages. request.session['keywords'] = form.cleaned_data['keywords'] # If ther are no keywords here, the user entered nothing or the # form was not valid. keywords = request.session.get('keywords', '') try: query = SearchTerm.search(keywords) except ProgrammingError: context = { 'active': 'None', 'message': 'Unable to parse keywords search terms', 'keyform': KeySearchForm(), } return render(request, 'results.html', context) paginator = Paginator(query, 25) try: pieces = paginator.page(page) except PageNotAnInteger: # typically the first page of results pieces = paginator.page(1) except EmptyPage: pieces = paginator.page(paginator.num_pages) end_time = time.time() context = { 'active': 'None', 'pieces': pieces, 'keyform': KeySearchForm(), 'pager': pieces, 'keywords': keywords, 'search_time': '%2.4g' % (end_time - start_time), } return render(request, 'results.html', context)
def key_results(request): """ This responds to keyword search request (typically from the entry box on the jumbotron but could be anywhere. If there is more than one page, this routine may be re-entered to process other pages. """ start_time = time.time() page = request.GET.get('page') if page is None: form = KeySearchForm(request.GET) if form.is_valid(): # Uses session cookies to track the query between pages. request.session['keywords'] = form.cleaned_data['keywords'] # If ther are no keywords here, the user entered nothing or the # form was not valid. keywords = request.session.get('keywords', '') try: query = SearchTerm.search(keywords) except ProgrammingError: context = { 'active' : 'None', 'message': 'Unable to parse keywords search terms', 'keyform': KeySearchForm(), } return render(request, 'results.html', context) paginator = Paginator(query, 25) try: pieces = paginator.page(page) except PageNotAnInteger: # typically the first page of results pieces = paginator.page(1) except EmptyPage: pieces = paginator.page(paginator.num_pages) end_time = time.time() context = { 'active' : 'None', 'pieces': pieces, 'keyform': KeySearchForm(), 'pager': pieces, 'keywords': keywords, 'search_time': '%2.4g' % (end_time - start_time), } return render(request, 'results.html', context)
def homepage(request): """ The home page for the site. """ # The number of pieces referencing an instrument isn't provided in # Instrument so we annotate in an extra column using an aggregate, # then do a reverse sort to get the most frequent instrument at # the top of the list. instruments = Instrument.objects.filter(in_mutopia=True) instruments = instruments.annotate(count=Count('piece')).order_by('-count') # similar for composers and styles composers = Composer.objects.all() composers = composers.annotate(count=Count('piece')).order_by('-count') styles = Style.objects.filter(in_mutopia=True) styles = styles.annotate(count=Count('piece')).order_by('-count') context = { 'active': 'home', 'keyform': KeySearchForm(auto_id=False), 'latest_list': Piece.objects.order_by('-piece_id')[:10], 'instruments': instruments[:18], 'composers': composers[:18], 'styles': styles[:18], 'pieces': Piece.objects.count(), 'collections': Collection.objects.all()[:14], } return render(request, 'index.html', context)
def piece_info(request, piece_id): """Given a piece identifier, render a page with extended Piece information. :param Request request: The HTTP request object :param int piece_id: the identifier (primary key) for a specific Piece model instance. :return: An HTTP response containing a filled piece_info HTML page. """ piece = get_object_or_404(Piece, pk=piece_id) asset = AssetMap.objects.get(piece=piece_id) context = { 'keyform': KeySearchForm(auto_id=False), 'piece': piece, 'asset': asset, 'preview_image': '/'.join([ FTP_URL, asset.folder, asset.name + '-preview.png', ]), 'instruments': piece.instruments.all(), } collection = piece.collection_set.all() if collection.count() > 0: context['collection'] = collection[0] return render(request, 'piece_info.html', context)
def homepage(request): """The home page for the site""" instruments = [] for i in Instrument.objects.filter(in_mutopia=True): instruments.append( (i.instrument, Piece.objects.filter(instruments=i).count())) instruments = sorted(instruments, key=lambda x: x[1], reverse=True) composers = [] for c in Composer.objects.all(): composers.append((c, Piece.objects.filter(composer=c).count())) composers = sorted(composers, key=lambda x: x[1], reverse=True) styles = [] for s in Style.objects.all(): styles.append((s, Piece.objects.filter(style=s).count())) styles = sorted(styles, key=lambda x: x[1], reverse=True) context = { 'active': 'home', 'keyform': KeySearchForm(auto_id=False), 'latest_list': Piece.objects.order_by('-piece_id')[:10], 'instruments': instruments[:18], 'composers': composers[:18], 'styles': styles[:18], 'pieces': Piece.objects.count(), 'collections': Collection.objects.all()[:14], } return render(request, 'index.html', context)
def piece_by_style(request, slug): """Render one or more pages of pieces composed for the given style. Note that the `slug` of the piece is passed so that the *actual style* will be valid as an HTML reference. The one style that is of particular interest is `Popular / Dance` which gets slugged as `popular-dance`. :param Request request: The HTTP request object :param str slug: The slug for this style. :return: A paginated page of pieces in the given style. """ # Uses a slug so that "Popular / Dance" looks like a sane URL style = Style.objects.get(slug=slug) paginator = Paginator(Piece.objects.filter(style=style), 25) p = request.GET.get('page') try: page = paginator.page(p) except PageNotAnInteger: page = paginator.page(1) except EmptyPage: page = paginator.page(paginator.num_pages) context = { 'keyform': KeySearchForm(auto_id=False), 'page': page, 'style': style } return render(request, 'piece_style.html', context)
def piece_by_composer(request, composer): """Render one or more pages of pieces written by the given composer. :param Request request: The HTTP request object. :param str composer: The composer, formatted appropriately to associate with a Composer instance. :return: A paginated page of pieces by the given composer. """ comp = Composer.objects.get(pk=composer) paginator = Paginator(Piece.objects.filter(composer=comp), 25) p = request.GET.get('page') try: page = paginator.page(p) except PageNotAnInteger: page = paginator.page(1) except EmptyPage: page = paginator.page(paginator.num_pages) context = { 'keyform': KeySearchForm(auto_id=False), 'page': page, 'composer': comp.rawstr() } return render(request, 'piece_composer.html', context)
def piece_by_version(request, version): """Render one or more pages of pieces transcribed by the given LilyPond style. :param Request request: The HTTP request object. :param str version: The LilyPond version. :return: A paginated page of pieces transcribed by this version. """ v = LPVersion.objects.get(version=version) paginator = Paginator(Piece.objects.filter(version=v), 25) p = request.GET.get('page') try: page = paginator.page(p) except PageNotAnInteger: page = paginator.page(1) except EmptyPage: page = paginator.page(paginator.num_pages) context = { 'keyform': KeySearchForm(auto_id=False), 'page': page, 'version': version } return render(request, 'piece_version.html', context)
def contribute(request): context = { 'keyform': KeySearchForm(auto_id=False), 'active': 'contribute', 'composers': Composer.objects.all(), 'licenses': License.objects.filter(active=True).order_by('name'), 'styles': Style.objects.filter(in_mutopia=True) } return render(request, 'contribute.html', context)
def legal(request): """ The legal/license page is mostly HTML with a search form. """ context = { 'active': 'legal', 'keyform': KeySearchForm(auto_id=False), } return render(request, 'legal.html', context)
def contact(request): """ The contact page is HTML with a search form. """ context = { 'active': 'contact', 'keyform': KeySearchForm(auto_id=False), } return render(request, 'contact.html', context)
def collection_list(request, col_tag): col = Collection.objects.get(tag=col_tag) # Check out the cool reverse lookup for the list of pieces. context = { 'keyform': KeySearchForm(auto_id=False), 'title': col.title, 'col_pieces': Piece.objects.filter(collectionpiece__collection=col_tag) } return render(request, 'collection.html', context)
def log_info(request, piece_id): asset = AssetMap.objects.get(piece=piece_id) url = '/'.join([FTP_URL, asset.folder, asset.name+'.log',]) context = { 'keyform': KeySearchForm(auto_id=False), 'piece' : Piece.objects.get(pk=piece_id), 'logfile': requests.get(url), } return render(request, 'piece_log.html', context)
def key_results(request): start_time = time.time() # Uses a session cookies to track the query between pages. page = request.GET.get('page') if page is None: form = KeySearchForm(request.GET) if form.is_valid(): request.session['keywords'] = form.cleaned_data['keywords'] # If this is blank, the user entered nothing or the form was not valid keywords = request.session.get('keywords', '') try: q = fts_search(keywords) except ProgrammingError: context = { 'active': 'None', 'message': 'Unable to parse keywords search terms', 'keyform': KeySearchForm(), } return render(request, 'results.html', context) paginator = Paginator(q, 25) try: pieces = paginator.page(page) except PageNotAnInteger: # typically the first page of results pieces = paginator.page(1) except EmptyPage: pieces = paginator.page(paginator.num_pages) end_time = time.time() context = { 'active': 'None', 'pieces': pieces, 'keyform': KeySearchForm(), 'pager': pieces, 'keywords': keywords, 'search_time': '%2.4g' % (end_time - start_time), } return render(request, 'results.html', context)
def key_results(request): start_time = time.time() # Uses a session cookies to track the query between pages. page = request.GET.get('page') if page is None: form = KeySearchForm(request.GET) if form.is_valid(): request.session['keywords'] = form.cleaned_data['keywords'] # If this is blank, the user entered nothing or the form was not valid keywords = request.session.get('keywords', '') try: q = fts_search(keywords) except ProgrammingError: context = { 'active' : 'None', 'message': 'Unable to parse keywords search terms', 'keyform': KeySearchForm(), } return render(request, 'results.html', context) paginator = Paginator(q, 25) try: pieces = paginator.page(page) except PageNotAnInteger: # typically the first page of results pieces = paginator.page(1) except EmptyPage: pieces = paginator.page(paginator.num_pages) end_time = time.time() context = { 'active' : 'None', 'pieces': pieces, 'keyform': KeySearchForm(), 'pager': pieces, 'keywords': keywords, 'search_time': '%2.4g' % (end_time - start_time), } return render(request, 'results.html', context)
def browse(request): """ The browse page is a page of links to the following items, * Collections * Composers * Styles * Instruments """ # TODO: this is a hacky way to split the columns. It works but # requires lots of messing about if the lists are restructured. It # also requires some fore-knowledge on the part of the template # since the presentation width is specified there. # collection col = Collection.objects.all() csplit = round(col.count() / 2) # composers comp = Composer.objects.all() comps = round(comp.count() / 3) # styles style = Style.objects.all() styles = round(style.count() / 3) inst = Instrument.objects.filter(in_mutopia=True) insts = round(inst.count() / 3) context = { 'keyform': KeySearchForm(auto_id=False), 'active': 'browse', 'collections': ( col[:csplit], col[csplit:], ), 'composers': ( comp[:comps], comp[comps:(comps + comps)], comp[(comps + comps):], ), 'styles': ( style[:styles], style[styles:(styles + styles)], style[(styles + styles):], ), 'instruments': ( inst[:insts], inst[insts:(insts + insts)], inst[(insts + insts):], ), } return render(request, 'browse.html', context)
def piece_info(request, piece_id): piece = get_object_or_404(Piece, pk=piece_id) asset = AssetMap.objects.get(piece=piece_id) context = { 'keyform': KeySearchForm(auto_id=False), 'piece': piece, 'asset': asset, 'preview_image': '/'.join([FTP_URL, asset.folder, asset.name+'-preview.png',]), 'instruments': piece.instruments.all(), } collection = Collection.objects.filter(collectionpiece__piece=piece_id) if collection.count() > 0: context['collection'] = collection[0] return render(request, 'piece_info.html', context)
def contribute(request): """ The contribute page display tables to help potential contributors build a correct header in their submissions. """ context = { 'keyform': KeySearchForm(auto_id=False), 'active': 'contribute', 'composers': Composer.objects.all(), 'licenses': License.objects.filter(active=True).order_by('name'), 'styles': Style.objects.filter(in_mutopia=True) } return render(request, 'contribute.html', context)
def collection_list(request, col_tag): """Display the collection associated with the given tag. :param Request request: The HTTP request object :param str col_tag: The tag for looking up the Collection. """ col = Collection.objects.get(tag=col_tag) context = { 'keyform': KeySearchForm(auto_id=False), 'title': col.title, 'col_pieces': col.pieces.all() } return render(request, 'collection.html', context)
def piece_by_version(request, version): v = LPVersion.objects.get(version=version) paginator = Paginator(Piece.objects.filter(version=v), 25) p = request.GET.get('page') try: page = paginator.page(p) except PageNotAnInteger: page = paginator.page(1) except EmptyPage: page = paginator.page(paginator.num_pages) context = { 'keyform': KeySearchForm(auto_id=False), 'page': page, 'version': version } return render(request, 'piece_version.html', context)
def piece_by_instrument(request, instrument): pieces = Piece.objects.filter(instruments__pk=instrument) paginator = Paginator(pieces, 25) p = request.GET.get('page') try: page = paginator.page(p) except PageNotAnInteger: page = paginator.page(1) except EmptyPage: page = paginator.page(paginator.num_pages) context = { 'keyform': KeySearchForm(auto_id=False), 'page': page, 'instrument': instrument } return render(request, 'piece_instrument.html', context)
def piece_by_composer(request, composer): comp = Composer.objects.get(pk=composer) paginator = Paginator(Piece.objects.filter(composer=comp), 25) p = request.GET.get('page') try: page = paginator.page(p) except PageNotAnInteger: page = paginator.page(1) except EmptyPage: page = paginator.page(paginator.num_pages) context = { 'keyform': KeySearchForm(auto_id=False), 'page': page, 'composer': comp.rawstr() } return render(request, 'piece_composer.html', context)
def piece_by_style(request, slug): # Uses a slug so that "Popular / Dance" looks like a sane URL style = Style.objects.get(slug=slug) paginator = Paginator(Piece.objects.filter(style=style), 25) p = request.GET.get('page') try: page = paginator.page(p) except PageNotAnInteger: page = paginator.page(1) except EmptyPage: page = paginator.page(paginator.num_pages) context = { 'keyform': KeySearchForm(auto_id=False), 'page': page, 'style': style } return render(request, 'piece_style.html', context)
def log_info(request, piece_id): """Display the GIT change log for a particular piece. :param Request request: The HTTP request object :return: An HTML page containing the log information. """ asset = AssetMap.objects.get(piece=piece_id) url = '/'.join([ FTP_URL, asset.folder, asset.name + '.log', ]) context = { 'keyform': KeySearchForm(auto_id=False), 'piece': Piece.objects.get(pk=piece_id), 'logfile': requests.get(url), } return render(request, 'piece_log.html', context)
def browse(request): # collection c = Collection.objects.all() csplit = round(c.count() / 2) # composers comp = Composer.objects.all() comps = round(comp.count() / 3) # styles s = Style.objects.all() ss = round(s.count() / 3) inst = Instrument.objects.filter(in_mutopia=True) insts = round(inst.count() / 3) context = { 'keyform': KeySearchForm(auto_id=False), 'active': 'browse', 'collections': ( c[:csplit], c[csplit:], ), 'composers': ( comp[:comps], comp[comps:(comps + comps)], comp[(comps + comps):], ), 'styles': ( s[:ss], s[ss:(ss + ss)], s[(ss + ss):], ), 'instruments': ( inst[:insts], inst[insts:(insts + insts)], inst[(insts + insts):], ), } return render(request, 'browse.html', context)
def piece_by_instrument(request, instrument): """Render one or more pages of pieces composed for the given instrument. :param Request request: The HTTP request object :param str instrument: Instrument used to associate to a Piece. :return: A paginated page of pieces associated with the instrument. """ pieces = Piece.objects.filter(instruments__pk=instrument) paginator = Paginator(pieces, 25) p = request.GET.get('page') try: page = paginator.page(p) except PageNotAnInteger: page = paginator.page(1) except EmptyPage: page = paginator.page(paginator.num_pages) context = { 'keyform': KeySearchForm(auto_id=False), 'page': page, 'instrument': instrument } return render(request, 'piece_instrument.html', context)
def contact(request): context = { 'active': 'contact', 'keyform': KeySearchForm(auto_id=False), } return render(request, 'contact.html', context)
def legal(request): context = { 'active': 'legal', 'keyform': KeySearchForm(auto_id=False), } return render(request, 'legal.html', context)