Viewing: trunk/collection/views.py

View as text-only | View History | View diff
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
from django.views.generic.edit import CreateView, UpdateView
from collection.forms import MovieForm, UserForm
from django.views.generic.detail import DetailView
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.core.mail import mail_admins
from django.http.response import HttpResponseRedirect, Http404
from django.contrib.auth.models import User
from django.contrib.auth import authenticate, login
from django.template.loader import get_template
from django.template.context import Context
import random, urllib, json, datetime, sys
from django.conf import settings

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
    def form_valid(self, form):
        self.object = form.save()
        #for watchlist in self.object.genre.watchlist_set.all():
        #    body = get_template("collection/notifications/new_movie.txt").render(Context({'user':watchlist.owner, 'movie':self.object}))
        #    watchlist.owner.email_user('Nick added a new %s movie' % self.object.genre, body)
        movie_url = 'http://www.cinema-nick.com%s' % self.object.get_absolute_url()
        urls = urllib.urlencode({'href':movie_url, 'redirect_uri':movie_url})
        return HttpResponseRedirect('https://www.facebook.com/dialog/share?app_id=%s&display=page&%s' % (settings.FACEBOOK_APP_ID, urls))

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)