''' the good stuff! the books! ''' import dateutil.parser from dateutil.parser import ParserError from django.contrib.auth.decorators import login_required from django.http import HttpResponseBadRequest, HttpResponseNotFound from django.shortcuts import get_object_or_404, redirect from django.utils import timezone from django.views.decorators.http import require_POST from bookwyrm import models from .helpers import get_edition, handle_reading_status from .shelf import handle_unshelve # pylint: disable= no-self-use @login_required @require_POST def start_reading(request, book_id): ''' begin reading a book ''' book = get_edition(book_id) shelf = models.Shelf.objects.filter( identifier='reading', user=request.user ).first() # create a readthrough readthrough = update_readthrough(request, book=book) if readthrough: readthrough.save() # create a progress update if we have a page readthrough.create_update() # shelve the book if request.POST.get('reshelve', True): try: current_shelf = models.Shelf.objects.get( user=request.user, edition=book ) handle_unshelve(request.user, book, current_shelf) except models.Shelf.DoesNotExist: # this just means it isn't currently on the user's shelves pass models.ShelfBook.objects.create( book=book, shelf=shelf, user=request.user) # post about it (if you want) if request.POST.get('post-status'): privacy = request.POST.get('privacy') handle_reading_status(request.user, shelf, book, privacy) return redirect(request.headers.get('Referer', '/')) @login_required @require_POST def finish_reading(request, book_id): ''' a user completed a book, yay ''' book = get_edition(book_id) shelf = models.Shelf.objects.filter( identifier='read', user=request.user ).first() # update or create a readthrough readthrough = update_readthrough(request, book=book) if readthrough: readthrough.save() # shelve the book if request.POST.get('reshelve', True): try: current_shelf = models.Shelf.objects.get( user=request.user, edition=book ) handle_unshelve(request.user, book, current_shelf) except models.Shelf.DoesNotExist: # this just means it isn't currently on the user's shelves pass models.ShelfBook.objects.create( book=book, shelf=shelf, user=request.user) # post about it (if you want) if request.POST.get('post-status'): privacy = request.POST.get('privacy') handle_reading_status(request.user, shelf, book, privacy) return redirect(request.headers.get('Referer', '/')) @login_required @require_POST def edit_readthrough(request): ''' can't use the form because the dates are too finnicky ''' readthrough = update_readthrough(request, create=False) if not readthrough: return HttpResponseNotFound() # don't let people edit other people's data if request.user != readthrough.user: return HttpResponseBadRequest() readthrough.save() # record the progress update individually # use default now for date field readthrough.create_update() return redirect(request.headers.get('Referer', '/')) @login_required @require_POST def delete_readthrough(request): ''' remove a readthrough ''' readthrough = get_object_or_404( models.ReadThrough, id=request.POST.get('id')) # don't let people edit other people's data if request.user != readthrough.user: return HttpResponseBadRequest() readthrough.delete() return redirect(request.headers.get('Referer', '/')) @login_required @require_POST def create_readthrough(request): ''' can't use the form because the dates are too finnicky ''' book = get_object_or_404(models.Edition, id=request.POST.get('book')) readthrough = update_readthrough(request, create=True, book=book) if not readthrough: return redirect(book.local_path) readthrough.save() return redirect(request.headers.get('Referer', '/')) def update_readthrough(request, book=None, create=True): ''' updates but does not save dates on a readthrough ''' try: read_id = request.POST.get('id') if not read_id: raise models.ReadThrough.DoesNotExist readthrough = models.ReadThrough.objects.get(id=read_id) except models.ReadThrough.DoesNotExist: if not create or not book: return None readthrough = models.ReadThrough( user=request.user, book=book, ) start_date = request.POST.get('start_date') if start_date: try: start_date = timezone.make_aware(dateutil.parser.parse(start_date)) readthrough.start_date = start_date except ParserError: pass finish_date = request.POST.get('finish_date') if finish_date: try: finish_date = timezone.make_aware( dateutil.parser.parse(finish_date)) readthrough.finish_date = finish_date except ParserError: pass progress = request.POST.get('progress') if progress: try: progress = int(progress) readthrough.progress = progress except ValueError: pass progress_mode = request.POST.get('progress_mode') if progress_mode: try: progress_mode = models.ProgressMode(progress_mode) readthrough.progress_mode = progress_mode except ValueError: pass if not readthrough.start_date and not readthrough.finish_date: return None return readthrough @login_required @require_POST def delete_progressupdate(request): ''' remove a progress update ''' update = get_object_or_404(models.ProgressUpdate, id=request.POST.get('id')) # don't let people edit other people's data if request.user != update.user: return HttpResponseBadRequest() update.delete() return redirect(request.headers.get('Referer', '/'))