dvd-collection / collection / views.py

from django.views.generic.list import ListView
from collection.models import Movie, Genre, Watchlist, Director
from django.shortcuts import get_object_or_404, render, redirect
import random
from django.views.generic.edit import CreateView, UpdateView
from collection.forms import MovieForm, UserForm
from django.views.generic.detail import DetailView
import urllib
import json
import datetime
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.core.mail import mail_admins
import sys
from django.http.response import HttpResponseRedirect, Http404
from django.contrib.auth.models import User
from django.contrib.auth import authenticate, login

LENGTH_STAMP = datetime.datetime(1983, 05, 10)  # This is used to determine the length of a movie title. Trivia, what date is this from?

# Placing global flash messages here to keep everything consistent.
IMDB_SUCCESS = "This movie information has just been updated from IMDb.  Hopefully I found the right movie."
IMDB_FAIL = "This movie title was not found on IMDb...  Perhaps try renaming the movie title."

class OnlyNickMixin(object):
    def dispatch(self, request, *args, **kwargs):
        if not request.user.is_staff:
            messages.error(request, "Only Nick has the powers to use this feature!")
            try:
                return HttpResponseRedirect(request.META['HTTP_REFERER'])
            except KeyError:
                return redirect('/')
        return super(OnlyNickMixin, self).dispatch(request, *args, **kwargs)

class BrowseCollection(ListView):
    model = Movie
    paginate_by = 100
    def get_queryset(self):
        self.query = ''
        qs = super(BrowseCollection, self).get_queryset().select_related()
        if 'ordering' in self.request.GET:
            self.query = '&ordering=%s' % self.request.GET.get('ordering')
            return qs.order_by(self.request.GET.get('ordering'))
        if 'startswith' in self.request.GET:
            self.query = '&startswith=%s' % self.request.GET.get('startswith')
            return qs.filter(title__startswith=self.request.GET.get('startswith'))
        return qs
    def get_context_data(self, **kwargs):
        kwargs.update({'extra_query':self.query})
        return super(BrowseCollection, self).get_context_data(**kwargs)

class BrowseGenre(ListView):
    model = Movie
    paginate_by = 100
    template_name = 'collection/genre_detail.html'
    def get_queryset(self):
        self.query = ''
        self.genre = get_object_or_404(Genre, slug=self.kwargs['slug'])
        qs = super(BrowseGenre, self).get_queryset().select_related().filter(genre=self.genre)
        if 'ordering' in self.request.GET:
            self.query = '&ordering=%s' % self.request.GET.get('ordering')
            return qs.order_by(self.request.GET.get('ordering'))
        if 'startswith' in self.request.GET:
            self.query = '&startswith=%s' % self.request.GET.get('startswith')
            return qs.filter(title__startswith=self.request.GET.get('startswith'))
        return qs
    def get_context_data(self, **kwargs):
        kwargs.update({'genre': self.genre, 'extra_query':self.query})
        return super(BrowseGenre, self).get_context_data(**kwargs)

class GenreList(ListView):
    model = Genre

class BrowseFormat(ListView):
    model = Movie
    paginate_by = 100
    template_name = 'collection/format_detail.html'
    def get_queryset(self):
        self.query = ''
        self.format = int(self.kwargs['format_id'])
        qs = super(BrowseFormat, self).get_queryset().select_related().filter(format=self.format)
        if 'ordering' in self.request.GET:
            self.query = '&ordering=%s' % self.request.GET.get('ordering')
            return qs.order_by(self.request.GET.get('ordering'))
        if 'startswith' in self.request.GET:
            self.query = '&startswith=%s' % self.request.GET.get('startswith')
            return qs.filter(title__startswith=self.request.GET.get('startswith'))
        return qs
    def get_context_data(self, **kwargs):
        kwargs.update({'format': self.format, 'extra_query':self.query})
        return super(BrowseFormat, self).get_context_data(**kwargs)

class AddMovie(OnlyNickMixin, CreateView):
    model = Movie
    form_class = MovieForm

class MovieDetail(DetailView):
    model = Movie
    def get_object(self):
        qs = self.get_queryset()
        slug = self.kwargs.get(self.slug_url_kwarg, None)
        qs=qs.filter(slug=slug)
        try:
            movie = qs.get()
        except Movie.DoesNotExist:
            raise Http404
        except Movie.MultipleObjectsReturned:
            messages.info(self.request, "Nick appears to have duplicates of this movie in his collection.")
            movie = qs[0]
        return movie
    def get_context_data(self, **kwargs):
        if self.object.imdb == None or self.object.imdb == '':
            movie_title = self.object.title
            movie_title=movie_title.replace(', The', '').replace('007: ', '').replace(' (Full Screen)', '').replace(' (Director\'s Cut)', '')
            movie_title=movie_title.replace(' (Special Edition)', '').replace(':', ' -').replace(' (2012)', '').replace(' (1966)', '')
            movie_title=movie_title.replace('Part 2', 'Part II').replace('Part 3', 'Part III').replace(', A', '')
            try:
                if self.object.year:
                    omdb = urllib.urlopen('http://www.omdbapi.com/?t=%s&y=%s' % (movie_title, self.object.year)).read()
                else:
                    omdb = urllib.urlopen('http://www.omdbapi.com/?t=%s' % movie_title).read()
            except:
                omdb = '{"Response":"False"}'
                value = sys.exc_info()[1]
                mail_admins('IMDb exception thrown: %s' % self.object.get_absolute_url(), value.__repr__())
            if self.object.import_imdb(json.loads(omdb)):
                messages.success(self.request, IMDB_SUCCESS)
            else:
                messages.error(self.request, IMDB_FAIL)
        kwargs.update({'length_stamp':LENGTH_STAMP})
        return super(MovieDetail, self).get_context_data(**kwargs)

class EditMovie(OnlyNickMixin, UpdateView):
    model = Movie
    form_class = MovieForm

class SignUp(CreateView):
    model = User
    form_class = UserForm
    template_name = 'registration/signup.html'
    def form_valid(self, form):
        self.object = form.save()
        self.object.set_password(self.object.password)
        self.object.save()
        user = authenticate(username=form.cleaned_data['username'], password=form.cleaned_data['password'])
        login(self.request, user)
        messages.success(self.request, "Your account has been created, and you have been logged in.")
        return redirect('browse_collection')

class WatchlistView(DetailView):
    model = Watchlist
    def get_object(self, queryset=None):
        username = self.kwargs.get('username', None)
        if username:
            try:
                user = User.objects.get(username=username)
            except User.DoesNotExist:
                raise Http404
            return self.get_queryset().get(owner=user)
        try:
            return self.get_queryset().get(owner=self.request.user)
        except Watchlist.DoesNotExist:
            return Watchlist.objects.create(owner=self.request.user)

class BrowseDirector(ListView):
    model = Movie
    paginate_by = 100
    template_name = 'collection/director_detail.html'
    def get_queryset(self):
        self.director = get_object_or_404(Director, slug=self.kwargs['slug'])
        qs = super(BrowseDirector, self).get_queryset().select_related().filter(director=self.director)
        if 'ordering' in self.request.GET:
            return qs.order_by(self.request.GET.get('ordering'))
        if 'startswith' in self.request.GET:
            return qs.filter(title__startswith=self.request.GET.get('startswith'))
        return qs
    def get_context_data(self, **kwargs):
        kwargs.update({'director': self.director})
        return super(BrowseDirector, self).get_context_data(**kwargs)

class DirectorList(ListView):
    model = Director
    paginate_by = 100

def format_list(req):
    formats = []
    for fmt in Movie.FORMAT_CHOICES:
        formats.append({'name':fmt[1], 'id':fmt[0], 'title_count': Movie.objects.filter(format=fmt[0]).count()})
    return render(req, 'collection/format_list.html', {'format_list':formats})

def random_list(req):
    try:
        genre = int(req.GET.get('genre', 0))
        fmt = int(req.GET.get('format', 0))
    except:
        genre = fmt = 0
    qs = Movie.objects.select_related().all()
    if genre > 0:
        g = get_object_or_404(Genre, pk=genre)
        qs=qs.filter(genre=g)
    if fmt > 0:
        qs=qs.filter(format=fmt)
    movie_list = []
    try:
        for i in range(10):
            movie_list.append(random.choice(qs))
    except IndexError:
        pass
    ctx = {'movie_list':movie_list, 'genre':genre, 'format':fmt}
    if 'thumbnails' in req.GET:
        ctx.update({'thumbnails':True})
    return render(req, 'collection/random_list.html', ctx)

@login_required
def update_from_imdb(req, slug):
    movie = get_object_or_404(Movie, slug=slug)
    if not req.user.is_staff:
        messages.error(req, "You do not have access to update the info from IMDb.")
        return redirect(movie)
    try:
        omdb = urllib.urlopen('http://www.omdbapi.com/?i=%s' % movie.imdb).read()
    except:
        omdb = '{"Response":"False"}'
        value = sys.exc_info()[1]
        mail_admins('IMDb exception thrown: %s' % movie.get_absolute_url(), value.__repr__())
    if movie.import_imdb(json.loads(omdb)):
        messages.success(req, IMDB_SUCCESS)
    else:
        messages.error(req, IMDB_FAIL)
    return redirect(movie)

@login_required
def just_watched(req, slug):
    movie = get_object_or_404(Movie, slug=slug)
    if not req.user.is_staff:
        messages.error(req, "Only Nick can say if he watched a movie or not.")
        return redirect(movie)
    movie.watched +=1
    movie.last_watched = datetime.date.today()
    movie.save()
    return redirect(movie)

@login_required
def add_to_watchlist(req, slug):
    movie = get_object_or_404(Movie, slug=slug)
    watchlist, created = Watchlist.objects.get_or_create(owner=req.user)
    watchlist.movies.add(movie)
    messages.success(req, "Movie has been added to your watchlist.")
    return redirect(movie)

@login_required
def add_to_genres(req, slug):
    genre = get_object_or_404(Genre, slug=slug)
    watchlist, created = Watchlist.objects.get_or_create(owner=req.user)
    watchlist.genres.add(genre)
    messages.success(req, "Genre has been added to your watchlist.")
    return redirect(genre)

@login_required
def remove_from_watchlist(req, slug):
    movie = get_object_or_404(Movie, slug=slug)
    watchlist, created = Watchlist.objects.get_or_create(owner=req.user)
    watchlist.movies.remove(movie)
    messages.success(req, "Movie has been removed from your watchlist.")
    return redirect('my_watchlist')

def search(req):
    ctx = {}
    query = req.GET.get('q', None)
    if query:
        ctx.update({'query':query})
        if len(query) > 3:
            ctx.update({'results':Movie.objects.filter(title__icontains=query)})
        else:
            messages.info(req, "Please enter in a Query larger than 3 characters.")
    return render(req, "search.html", ctx)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.