X-Git-Url: https://git.mdrn.pl/wolnelektury.git/blobdiff_plain/d52c76021eaf1621b4e55a6eba1df1c0404bd7dd..38d1b1c2437dae93c0a981a26579908b26ef969b:/apps/catalogue/views.py diff --git a/apps/catalogue/views.py b/apps/catalogue/views.py index 3a3283229..7ead47115 100644 --- a/apps/catalogue/views.py +++ b/apps/catalogue/views.py @@ -4,31 +4,26 @@ # import re import itertools -from datetime import datetime from django.conf import settings from django.template import RequestContext from django.shortcuts import render_to_response, get_object_or_404 from django.http import HttpResponse, HttpResponseRedirect, Http404, HttpResponsePermanentRedirect from django.core.urlresolvers import reverse -from django.db.models import Count, Sum, Q +from django.db.models import Q from django.contrib.auth.decorators import login_required, user_passes_test from django.utils.datastructures import SortedDict -from django.views.decorators.http import require_POST -from django.contrib import auth -from django.contrib.auth.forms import UserCreationForm, AuthenticationForm from django.utils.http import urlquote_plus -from django.views.decorators import cache from django.utils import translation -from django.utils.translation import ugettext as _ -from django.views.generic.list_detail import object_list +from django.utils.translation import ugettext as _, ugettext_lazy +from django.views.decorators.cache import never_cache + +from ajaxable.utils import JSONResponse, AjaxableFormView -from ajaxable.utils import LazyEncoder, JSONResponse from catalogue import models from catalogue import forms from catalogue.utils import (split_tags, AttachmentHttpResponse, async_build_pdf, MultiQuerySet) -from catalogue.tasks import touch_tag from pdcounter import models as pdcounter_models from pdcounter import views as pdcounter_views from suggest.forms import PublishingSuggestForm @@ -52,7 +47,8 @@ def catalogue(request): context_instance=RequestContext(request)) -def book_list(request, filter=None, template_name='catalogue/book_list.html'): +def book_list(request, filter=None, template_name='catalogue/book_list.html', + context=None): """ generates a listing of all books, optionally filtered with a test function """ books_by_author, orphans, books_by_parent = models.Book.book_list(filter) @@ -75,6 +71,17 @@ def daisy_list(request): template_name='catalogue/daisy_list.html') +def collection(request, slug): + coll = get_object_or_404(models.Collection, slug=slug) + slugs = coll.book_slugs.split() + # allow URIs + slugs = [slug.rstrip('/').rsplit('/', 1)[-1] if '/' in slug else slug + for slug in slugs] + return book_list(request, Q(slug__in=slugs), + template_name='catalogue/collection.html', + context={'collection': coll}) + + def differentiate_tags(request, tags, ambiguous_slugs): beginning = '/'.join(tag.url_chunk for tag in tags) unparsed = '/'.join(ambiguous_slugs[1:]) @@ -89,8 +96,8 @@ def differentiate_tags(request, tags, ambiguous_slugs): context_instance=RequestContext(request)) +@never_cache def tagged_object_list(request, tags=''): - # import pdb; pdb.set_trace() try: tags = models.Tag.get_tag_list(tags) except models.Tag.DoesNotExist: @@ -181,6 +188,7 @@ def tagged_object_list(request, tags=''): 'only_my_shelf': only_my_shelf, 'formats_form': forms.DownloadFormatsForm(), 'tags': tags, + 'theme_is_set': theme_is_set, }, context_instance=RequestContext(request)) @@ -196,33 +204,14 @@ def book_fragments(request, slug, theme_slug): context_instance=RequestContext(request)) +@never_cache def book_detail(request, slug): try: book = models.Book.objects.get(slug=slug) except models.Book.DoesNotExist: - return pdcounter_views.book_stub_detail(request, kwargs['slug']) - - book_tag = book.book_tag() - tags = list(book.tags.filter(~Q(category='set'))) - categories = split_tags(tags) - book_children = book.children.all().order_by('parent_number', 'sort_key') - - _book = book - parents = [] - while _book.parent: - parents.append(_book.parent) - _book = _book.parent - parents = reversed(parents) - - theme_counter = book.theme_counter - book_themes = models.Tag.objects.filter(pk__in=theme_counter.keys()) - for tag in book_themes: - tag.count = theme_counter[tag.pk] - - extra_info = book.get_extra_info_value() - hide_about = extra_info.get('about', '').startswith('http://wiki.wolnepodreczniki.pl') + return pdcounter_views.book_stub_detail(request, slug) - custom_pdf_form = forms.CustomPDFForm() + book_children = book.children.all().order_by('parent_number', 'sort_key') return render_to_response('catalogue/book_detail.html', locals(), context_instance=RequestContext(request)) @@ -257,10 +246,11 @@ def player(request, slug): else: have_oggs = False audiobooks.append(media) - print audiobooks projects = sorted(projects) + extra_info = book.get_extra_info_value() + return render_to_response('catalogue/player.html', locals(), context_instance=RequestContext(request)) @@ -454,7 +444,7 @@ def search(request): context_instance=RequestContext(request)) else: form = PublishingSuggestForm(initial={"books": prefix + ", "}) - return render_to_response('catalogue/search_no_hits.html', + return render_to_response('catalogue/search_no_hits.html', {'tags':tag_list, 'prefix':prefix, "pubsuggest_form": form}, context_instance=RequestContext(request)) @@ -465,7 +455,7 @@ def tags_starting_with(request): if len(prefix) < 2: return HttpResponse('') tags_list = [] - result = "" + result = "" for tag in _tags_starting_with(prefix, request.user): if not tag.name in tags_list: result += "\n" + tag.name @@ -489,169 +479,6 @@ def json_tags_starting_with(request, callback=None): result = {"matches": tags_list} return JSONResponse(result, callback) -# ==================== -# = Shelf management = -# ==================== -@login_required -@cache.never_cache -def user_shelves(request): - shelves = models.Tag.objects.filter(category='set', user=request.user) - new_set_form = forms.NewSetForm() - return render_to_response('catalogue/user_shelves.html', locals(), - context_instance=RequestContext(request)) - -@cache.never_cache -def book_sets(request, slug): - if not request.user.is_authenticated(): - return HttpResponse(_('

To maintain your shelves you need to be logged in.

')) - - book = get_object_or_404(models.Book, slug=slug) - - user_sets = models.Tag.objects.filter(category='set', user=request.user) - book_sets = book.tags.filter(category='set', user=request.user) - - if request.method == 'POST': - form = forms.ObjectSetsForm(book, request.user, request.POST) - if form.is_valid(): - old_shelves = list(book.tags.filter(category='set')) - new_shelves = [models.Tag.objects.get(pk=id) for id in form.cleaned_data['set_ids']] - - for shelf in [shelf for shelf in old_shelves if shelf not in new_shelves]: - touch_tag(shelf) - - for shelf in [shelf for shelf in new_shelves if shelf not in old_shelves]: - touch_tag(shelf) - - book.tags = new_shelves + list(book.tags.filter(~Q(category='set') | ~Q(user=request.user))) - if request.is_ajax(): - return JSONResponse('{"msg":"'+_("

Shelves were sucessfully saved.

")+'", "after":"close"}') - else: - return HttpResponseRedirect('/') - else: - form = forms.ObjectSetsForm(book, request.user) - new_set_form = forms.NewSetForm() - - return render_to_response('catalogue/book_sets.html', locals(), - context_instance=RequestContext(request)) - - -@login_required -@require_POST -@cache.never_cache -def remove_from_shelf(request, shelf, slug): - book = get_object_or_404(models.Book, slug=slug) - - shelf = get_object_or_404(models.Tag, slug=shelf, category='set', user=request.user) - - if shelf in book.tags: - models.Tag.objects.remove_tag(book, shelf) - touch_tag(shelf) - - return HttpResponse(_('Book was successfully removed from the shelf')) - else: - return HttpResponse(_('This book is not on the shelf')) - - -def collect_books(books): - """ - Returns all real books in collection. - """ - result = [] - for book in books: - if len(book.children.all()) == 0: - result.append(book) - else: - result += collect_books(book.children.all()) - return result - - -@cache.never_cache -def download_shelf(request, slug): - """" - Create a ZIP archive on disk and transmit it in chunks of 8KB, - without loading the whole file into memory. A similar approach can - be used for large dynamic PDF files. - """ - from slughifi import slughifi - import tempfile - import zipfile - - shelf = get_object_or_404(models.Tag, slug=slug, category='set') - - formats = [] - form = forms.DownloadFormatsForm(request.GET) - if form.is_valid(): - formats = form.cleaned_data['formats'] - if len(formats) == 0: - formats = models.Book.ebook_formats - - # Create a ZIP archive - temp = tempfile.TemporaryFile() - archive = zipfile.ZipFile(temp, 'w') - - for book in collect_books(models.Book.tagged.with_all(shelf)): - for ebook_format in models.Book.ebook_formats: - if ebook_format in formats and book.has_media(ebook_format): - filename = book.get_media(ebook_format).path - archive.write(filename, str('%s.%s' % (book.slug, ebook_format))) - archive.close() - - response = HttpResponse(content_type='application/zip', mimetype='application/x-zip-compressed') - response['Content-Disposition'] = 'attachment; filename=%s.zip' % slughifi(shelf.name) - response['Content-Length'] = temp.tell() - - temp.seek(0) - response.write(temp.read()) - return response - - -@cache.never_cache -def shelf_book_formats(request, shelf): - """" - Returns a list of formats of books in shelf. - """ - shelf = get_object_or_404(models.Tag, slug=shelf, category='set') - - formats = {} - for ebook_format in models.Book.ebook_formats: - formats[ebook_format] = False - - for book in collect_books(models.Book.tagged.with_all(shelf)): - for ebook_format in models.Book.ebook_formats: - if book.has_media(ebook_format): - formats[ebook_format] = True - - return HttpResponse(LazyEncoder().encode(formats)) - - -@login_required -@require_POST -@cache.never_cache -def new_set(request): - new_set_form = forms.NewSetForm(request.POST) - if new_set_form.is_valid(): - new_set = new_set_form.save(request.user) - - if request.is_ajax(): - return JSONResponse('{"id":"%d", "name":"%s", "msg":"

Shelf %s was successfully created

"}' % (new_set.id, new_set.name, new_set)) - else: - return HttpResponseRedirect('/') - - return HttpResponseRedirect('/') - - -@login_required -@require_POST -@cache.never_cache -def delete_shelf(request, slug): - user_set = get_object_or_404(models.Tag, slug=slug, category='set', user=request.user) - user_set.delete() - - if request.is_ajax(): - return HttpResponse(_('

Shelf %s was successfully removed

') % user_set.name) - else: - return HttpResponseRedirect('/') - # ========= # = Admin = @@ -704,15 +531,15 @@ def download_zip(request, format, slug=None): return HttpResponseRedirect(urlquote_plus(settings.MEDIA_URL + url, safe='/?=')) -def download_custom_pdf(request, slug): +def download_custom_pdf(request, slug, method='GET'): book = get_object_or_404(models.Book, slug=slug) - if request.method == 'GET': - form = forms.CustomPDFForm(request.GET) + if request.method == method: + form = forms.CustomPDFForm(method == 'GET' and request.GET or request.POST) if form.is_valid(): cust = form.customizations pdf_file = models.get_customized_pdf_path(book, cust) - + if not path.exists(pdf_file): result = async_build_pdf.delay(book.id, cust, pdf_file) result.wait() @@ -721,3 +548,26 @@ def download_custom_pdf(request, slug): raise Http404(_('Incorrect customization options for PDF')) else: raise Http404(_('Bad method')) + + +class CustomPDFFormView(AjaxableFormView): + form_class = forms.CustomPDFForm + title = ugettext_lazy('Download custom PDF') + submit = ugettext_lazy('Download') + + def __call__(self, request): + from copy import copy + if request.method == 'POST': + request.GET = copy(request.GET) + request.GET['next'] = "%s?%s" % (reverse('catalogue.views.download_custom_pdf', args=[request.GET.get('slug')]), + request.POST.urlencode()) + return super(CustomPDFFormView, self).__call__(request) + + def get_object(self, request): + return get_object_or_404(models.Book, slug=request.GET.get('slug')) + + def context_description(self, request, obj): + return obj.pretty_title() + + def success(self, *args): + pass