Viewing: trunk/collection/views.py

Revision: 8

View as text-only | View History
Index: views.py
===================================================================
--- views.py	(revision 8)
+++ views.py	(revision 61)
@@ -1,46 +1,52 @@
 from django.views.generic.list import ListView
-from collection.models import Movie, Genre, Director
+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
+from collection.forms import MovieForm, UserForm
 from django.views.generic.detail import DetailView
-import urllib2
-import json
-import datetime
 from django.contrib import messages
 from django.contrib.auth.decorators import login_required
-from django.core.files.uploadedfile import SimpleUploadedFile
+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)
+LENGTH_STAMP = datetime.datetime(1983, 05, 10)  # This is used to determine the length of a movie title. Trivia, what date is this from?
 
-def get_length(value):
-    tokens = value.split(' ')
-    if tokens[1] == 'h':
-        hours = int(tokens[0])
-        mins = int(tokens[2])
-        return datetime.datetime(1983, 05, 10, hours, mins)
-    else:
-        hours = 0
-        mins = int(tokens[0])
-        return datetime.datetime(1983, 05, 10, hours, mins)
+# 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."
 
-def get_poster(url, referer):
-    req = urllib2.Request(url)
-    req.add_header('Referer', 'http://www.imdb.com/title/%s/' % referer)
-    req.add_header('User-agent', 'Mozilla/5.0 (X11; Linux x86_64; rv:20.0) Gecko/20100101 Firefox/20.0')
-    return urllib2.urlopen(req).read()
+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
@@ -47,15 +53,18 @@
     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})
+        kwargs.update({'genre': self.genre, 'extra_query':self.query})
         return super(BrowseGenre, self).get_context_data(**kwargs)
 
 class GenreList(ListView):
@@ -66,23 +75,44 @@
     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})
+        kwargs.update({'format': self.format, 'extra_query':self.query})
         return super(BrowseFormat, self).get_context_data(**kwargs)
 
-class AddMovie(CreateView):
+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)
+        return redirect(self.object)
 
 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
@@ -89,35 +119,74 @@
             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', '')
-            if self.object.year:
-                omdb = urllib2.urlopen('http://www.omdbapi.com/?t=%s&y=%s' % (movie_title, self.object.year)).read()
+            try:
+                if self.object.year:
+                    omdb = urllib.urlopen('http://www.omdbapi.com/?t=%s&y=%s&apikey=%s' % (movie_title, self.object.year, settings.OMDB_APIKEY)).read()
+                else:
+                    omdb = urllib.urlopen('http://www.omdbapi.com/?t=%s&apikey=%s' % (movie_title, settings.OMDB_APIKEY)).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:
-                omdb = urllib2.urlopen('http://www.omdbapi.com/?t=%s' % movie_title).read()
-            omdb = json.loads(omdb)
-            if omdb['Response'] == 'True':
-                self.object.imdb = omdb['imdbID']
-                self.object.poster = omdb['Poster']
-                self.object.year = int(omdb['Year'])
-                self.object.released = datetime.datetime.strptime(omdb['Released'], "%d %b %Y")
-                if omdb['Runtime'] != 'N/A':
-                    self.object.length = get_length(omdb['Runtime'])
-                self.object.plot = omdb['Plot']
-                self.object.imdb_rating = int(round(float(omdb['imdbRating'])))
-                director, created = Director.objects.get_or_create(name=omdb['Director'])
-                self.object.director = director
-                self.object.save()
-                poster = get_poster(self.object.poster, self.object.imdb)
-                self.object.poster_img.save("%s.jpg" % self.object.slug, SimpleUploadedFile("%s.jpg" % self.object.slug, poster, 'image/jpeg'))
-                self.object.close()
-            else:
-                messages.success(self.request, "This movie title was not found on IMDb...  Perhaps try renaming the movie title.")
+                messages.error(self.request, IMDB_FAIL)
         kwargs.update({'length_stamp':LENGTH_STAMP})
         return super(MovieDetail, self).get_context_data(**kwargs)
 
-class EditMovie(UpdateView):
+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:
@@ -131,42 +200,82 @@
     except:
         genre = fmt = 0
     qs = Movie.objects.select_related().all()
-    if genre:
-        if genre > 0:
-            g = get_object_or_404(Genre, pk=genre)
-            qs=qs.filter(genre=g)
-    if fmt:
-        if fmt > 0:
-            qs=qs.filter(format=fmt)
+    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 = []
-    for i in range(10):
-        movie_list.append(random.choice(qs))
-    return render(req, 'collection/random_list.html', {'movie_list':movie_list, 'genre':genre, 'format':fmt})
+    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)
-    omdb = urllib2.urlopen('http://www.omdbapi.com/?i=%s' % movie.imdb).read()
-    omdb = json.loads(omdb)
-    if omdb['Response'] == 'True':
-        movie.poster = omdb['Poster']
-        movie.year = int(omdb['Year'])
-        movie.released = datetime.datetime.strptime(omdb['Released'], "%d %b %Y")
-        if omdb['Runtime'] != 'N/A':
-            movie.length = get_length(omdb['Runtime'])
-        movie.plot = omdb['Plot']
-        movie.imdb_rating = int(round(float(omdb['imdbRating'])))
-        director, created = Director.objects.get_or_create(name=omdb['Director'])
-        movie.director = director
-        movie.save()
-        poster = get_poster(movie.poster, movie.imdb)
-        movie.poster_img.save("%s.jpg" % movie.slug, SimpleUploadedFile("%s.jpg" % movie.slug, poster, 'image/jpeg'))
+    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&apikey=%s' % (movie.imdb, settings.OMDB_APIKEY)).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)