def get_optional_nonstop_zones():
return [('', '')] + get_nonstop_zones()
+def get_search_nonstop_zones():
+ return [('', 'All'), ('', '--------------')] + get_nonstop_zones() + [('', '--------------'), ('none', 'None')]
+
class UploadTracksForm(forms.Form):
tracks = forms.FileField(widget=forms.ClearableFileInput(
attrs={'multiple': True, 'accept': 'audio/*'}))
class TrackSearchForm(forms.Form):
- q = forms.CharField(label=_('Text'))
- zone = forms.ChoiceField(label=_('Nonstop Zone'), choices=get_optional_nonstop_zones)
+ q = forms.CharField(label=_('Text'), required=False)
+ zone = forms.ChoiceField(label=_('Nonstop Zone'),
+ choices=get_search_nonstop_zones, required=False)
order_by = forms.ChoiceField(label=_('Order'),
- choices=[('alpha', _('Alphabetically'))])
+ required=False,
+ choices=[('title', _('Alphabetically')),
+ ('-added_to_nonstop_timestamp', _('Newest first')),
+ ('added_to_nonstop_timestamp', _('Oldest first'))])
class CleanupForm(forms.Form):
</form>
<hr>
-{% if tracks.exists %}
-<ul>
+{% if tracks %}
+<table>
{% for track in tracks %}
- <li><a href="{% url 'track-view' pk=track.id %}">{{track.title}}</a> — {{track.artist.name}}</li>
+ <tr><td class="track"><a href="{% url 'track-view' pk=track.id %}">{{track.title}}</a></td>
+ <td class="artist">{{track.artist.name}}</td>
+ <td class="zone">{% for zone in track.nonstop_zones.all %}{{ zone.title }}{% if not forloop.last %}, {% endif %}{% endfor %}</td>
+ <td class="since">{% if track.added_to_nonstop_timestamp %}(since {{track.added_to_nonstop_timestamp|date:"SHORT_DATE_FORMAT" }}{% endif %}</td>
+ </tr>
{% endfor %}
-</ul>
+</table>
+
+<div class="pagination">
+ <span class="step-links">
+ {% if tracks.has_previous %}
+ <a href="?{{ qs }}&page={{ tracks.previous_page_number }}">←</a>
+ {% endif %}
+
+ <span class="current">
+ {{ tracks.number }} / {{ tracks.paginator.num_pages }}
+ </span>
+
+ {% if tracks.has_next %}
+ <a href="?{{ qs }}&page={{ tracks.next_page_number }}">→</a>
+ {% endif %}
+ </span>
+</div>
{% endif %}
+<style>
+table {
+ max-width: 100%;
+ min-width: 50em;
+}
+td {
+ padding: 0.4ex 1ex;
+}
+td.track {
+ min-width: 30em;
+}
+td.artist {
+ min-width: 20em;
+}
+td.zone {
+ min-width: 10em;
+}
+td.since {
+ min-width: 10em;
+}
+tr:nth-child(even) {
+ background: #f2f2f2;
+}
+
+.step-links a {
+ padding: 1ex;
+}
+
+div.pagination {
+ margin-top: 1em;
+}
+</style>
+
{% endblock %}
import mutagen
from django.core.files.storage import default_storage
+from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.core.urlresolvers import reverse
from django.contrib import messages
from django.db.models import Q
def get_context_data(self, **kwargs):
ctx = super(SearchView, self).get_context_data(**kwargs)
- ctx['form'] = TrackSearchForm()
+ ctx['form'] = TrackSearchForm(self.request.GET)
queryset = Track.objects.all()
q = self.request.GET.get('q')
zone = self.request.GET.get('zone')
if zone:
from emissions.models import Nonstop
- queryset = queryset.filter(nonstop_zones=zone)
-
- if q or zone:
- ctx['tracks'] = queryset.order_by('title').select_related()
+ if zone == 'none':
+ queryset = queryset.filter(nonstop_zones=None)
+ else:
+ queryset = queryset.filter(nonstop_zones=zone)
+
+ qs = self.request.GET.copy()
+ qs.pop('page', None)
+ ctx['qs'] = qs.urlencode()
+
+ order = self.request.GET.get('order_by') or 'title'
+ if order:
+ if 'added_to_nonstop_timestamp' in order:
+ queryset = queryset.filter(added_to_nonstop_timestamp__isnull=False)
+ queryset = queryset.order_by(order)
+
+ tracks = Paginator(queryset.select_related(), 20)
+
+ page = self.request.GET.get('page')
+ try:
+ ctx['tracks'] = tracks.page(page)
+ except PageNotAnInteger:
+ ctx['tracks'] = tracks.page(1)
+ except EmptyPage:
+ ctx['tracks'] = tracks.page(tracks.num_pages)
return ctx