#!/usr/bin/env python # -*- coding: iso-8859-1 -*- from google.appengine.ext import webapp from google.appengine.api.labs.taskqueue import Task from google.appengine.ext.webapp.util import run_wsgi_app from google.appengine.ext import db from api import AnyClipAPI from backoffice import AnyClipBackoffice from django.utils.simplejson import load, dumps from random import randint from math import log10 import re import logging #global API object api = AnyClipAPI("CAD58B9E-F045-492F-81B9-22CFE6B00604") class Title(db.Model): title = db.StringProperty(required=True) code = db.StringProperty(required=True) imdbID = db.IntegerProperty(required=True) momentCount = db.IntegerProperty() shouldDisplay = db.BooleanProperty(default=False) quoteMomentCount = db.IntegerProperty(default=0) hasQuoteMoments = db.BooleanProperty(default=False) skill = db.IntegerProperty(default=0) class Moment(db.Model): title = db.ReferenceProperty(Title, required=True) quoteID = db.StringProperty(required=True) quote = db.TextProperty(required=True) momentName = db.StringProperty(required=True) submittedToAPI = db.BooleanProperty(default=False) class Request(webapp.RequestHandler): def __init__(self): self.splitPoint = None self.queryKeys = None self.lastLevel = None def getRandomUrl(self, level): if level > 3 or level < 1: return None if self.lastLevel != level: if level == 1: query = Title.all(keys_only=True).filter('shouldDisplay =', True).filter('skill =', 0) else: if self.splitPoint == None: topSkill = Title.all().filter('shouldDisplay =', True).order('-skill').get() if topSkill == None: return None self.splitPoint = (int)(topSkill.skill * (2.0/3.0)) if self.splitPoint == 0: self.splitPoint = 1 if level == 2: query = Title.all(keys_only=True).filter('shouldDisplay =', True).filter('skill <=', self.splitPoint).filter('skill >', 0) elif level == 3: query = Title.all(keys_only=True).filter('shouldDisplay =', True).filter('skill >', self.splitPoint) self.queryKeys = query.fetch(0x7FFFFFFF) self.lastLevel = level length = len(self.queryKeys) if length == 0: return None title = Title.get(self.queryKeys[randint(0, length - 1)]) preZero = "" for i in range(6 - int(log10(title.imdbID))): preZero += "0" return "http://www.imdb.com/title/tt%s%s/quotes" % (preZero, title.imdbID) def getUrls(self, request): urllist = [] if "count" not in request.keys(): request["count"] = 0 if "level" not in request.keys(): request["level"] = 1 if "doNotSend" not in request.keys(): request["doNotSend"] = [] for x in range(0, request["count"]): url = self.getRandomUrl(request["level"]) if url == None: break counter = 0 while (url in urllist or url in request["doNotSend"]) and counter < 100: url = self.getRandomUrl(request["level"]) counter += 1 if counter == 100: break urllist.append(url) self.response.out.write(dumps(urllist)) def submitMoment(self, request, title): Moment(title=title, quoteID=request["quoteID"], quote=request["quote"], momentName=request["momentName"]).put() title.momentCount += 1 title.quoteMomentCount += 1 title.hasQuoteMoments = True title.shouldDisplay = title.momentCount < 3 #if title.skill > 0: # title.skill -= 1 title.put() self.response.out.write("success") def unknownMovie(self, title): title.skill += 1 title.put() def getAlreadySubmitted(self, title): query = Moment.all().filter('title =', title) self.response.out.write(dumps([moment.quoteID for moment in query])) def post(self): self.response.headers['Content-Type'] = 'application/json' try: request = load(self.request.body_file) except: return if request["action"] == "getUrls": self.getUrls(request) else: if "url" in request.keys(): imdbID = re.search("http://.*imdb\.com/title/tt([0-9]{7})/quotes", request["url"]) try: imdbID = int(imdbID.group(1)) except: return title = Title.all().filter('imdbID =', imdbID).get() if title == None: return if request["action"] == "submitMoment": self.submitMoment(request, title) elif request["action"] == "unknownMovie": self.unknownMovie(title) elif request["action"] == "getAlreadySubmitted": self.getAlreadySubmitted(title) class LoadNewTitles(webapp.RequestHandler): def get(self): total = api.request("titles", (0, 1, "filter", 0))["TotalItemCount"] step = 20 for index in range(0, total, step): Task(url='/loadnewtitles', params={'index': index, 'step': step}).add(queue_name="titleloader") self.response.out.write("Requested update of titles and momentCounts.") def post(self): index = self.request.get("index") step = self.request.get("step") titles = api.request("titles", (index, step, "filter", 0))["Items"] for title in titles: if Title.all().filter('code = ', title["Code"]).count() == 0: Title(title=title["Name"], code=title["Code"], imdbID=title["ImdbID"]).put() Task(url='/updatemomentcount', params={'code': title["Code"]}).add(queue_name='momentcounter') class UpdateMomentCount(webapp.RequestHandler): def post(self): code = self.request.get("code") entry = Title.all().filter('code = ', code).get() if entry == None: return entry.momentCount = api.request("title", (code, "scenes", "0", "1"))["TotalItemCount"] + Moment.all().filter('title =', entry).filter('submittedToAPI =', False).count() entry.shouldDisplay = entry.momentCount < 3 #required because gql can't do mulpt inequality comparisons entry.put() class Debugger(webapp.RequestHandler): def get(self): titles = set() unsubmittedMoments = Moment.all().filter('submittedToAPI = ', False) for moment in unsubmittedMoments: self.response.out.write("

\"" + moment.momentName + "\" from " + moment.title.title + "

" + moment.quote + "

") for moment in unsubmittedMoments: titles.add(moment.title.title) for title in titles: self.response.out.write("%s
" % title) return me = Request() self.response.out.write("Url: %s
lastLevel: %s
splitPoint: %s

" % (me.getRandomUrl(1), me.lastLevel, me.splitPoint)) self.response.out.write("Url: %s
lastLevel: %s
splitPoint: %s

" % (me.getRandomUrl(2), me.lastLevel, me.splitPoint)) self.response.out.write("Url: %s
lastLevel: %s
splitPoint: %s

" % (me.getRandomUrl(3), me.lastLevel, me.splitPoint)) #for title in Title.all(): # Task(url='/debugger', params={'code': title.code, 'action': 'zeroIt'}).add(queue_name='debugger') #for moment in Moment.all(): # Task(url='/debugger', params={'code': moment.title.code, 'action': 'increaseIt'}).add(queue_name='debugger') """ titles = {} for moment in Moment.all(): id = moment.title.key().id() if id in titles: titles[id] += 1 else: titles[id] = 1 for id,count in titles.items(): Task(url='/debugger', params={'id': id, 'action': 'setIt', 'count': count}).add(queue_name='debugger') """ count = 0 for title in Title.all().filter('hasQuoteMoments =', True): count += title.quoteMomentCount self.response.out.write(str(count)) def post(self): if self.request.get("action") == "zeroIt": code = self.request.get("code") entry = Title.all().filter('code = ', code).get() if entry == None: return entry.quoteMomentCount = 0 entry.put() elif self.request.get("action") == "increaseIt": code = self.request.get("code") entry = Title.all().filter('code = ', code).get() if entry == None: return entry.quoteMomentCount += 1 entry.hasQuoteMoments = True entry.put() elif self.request.get("action") == "setIt": title = Title.get_by_id(int(self.request.get('id'))) title.quoteMomentCount = int(self.request.get('count')) title.hasQuoteMoments = True title.put() class ResetSkills(webapp.RequestHandler): def get(self): for title in Title.all(): if title.skill != 0: title.skill = 0 title.put() self.response.out.write("Set %s to normal skill
" % title.title) class AdminRequest(webapp.RequestHandler): def get(self): self.response.headers['Content-Type'] = 'application/json' if self.request.get('action') == 'titles': titles = [] count = 0 for title in Title.all().filter('hasQuoteMoments =', True).order('title'): titles.append({ 'id': title.key().id(), 'title': title.title, 'count': title.quoteMomentCount }) count += title.quoteMomentCount self.response.out.write(dumps({ 'total': count, 'titles': titles })) elif self.request.get('action') == 'moments': moments = [] for moment in Moment.all().filter('title =', Title.get_by_id(int(self.request.get('id')))): moments.append({ 'quote': moment.quote, 'name': moment.momentName, 'submittedToAPI': moment.submittedToAPI, 'id': str(moment.key().id()) }) self.response.out.write(dumps(moments)) elif self.request.get('action') == 'changeName': moment = Moment.get_by_id(int(self.request.get('id'))) if moment == None: self.response.out.write("failure") return moment.momentName = self.request.get('name') moment.put() self.response.out.write("success") elif self.request.get('action') == 'deleteMoment': moment = Moment.get_by_id(int(self.request.get('id'))) if moment == None: self.response.out.write("failure") return moment.title.momentCount -= 1 moment.title.quoteMomentCount -= 1 if moment.title.quoteMomentCount == 0: moment.title.hasQuoteMoments = False moment.title.shouldDisplay = moment.title.momentCount < 3 moment.title.put() moment.delete() self.response.out.write("success") elif self.request.get('action') == 'submitMoment': moment = Moment.get_by_id(int(self.request.get('id'))) if moment == None or moment.submittedToAPI: self.response.out.write("failure") return backoffice = AnyClipBackoffice("3A0E5351-2E01-4B13-87C8-63E09B26374F") response = backoffice.request("title", moment.title.code, "scenes", "new", "raw", imdbQuoteID=moment.quoteID, name=moment.momentName) if response != None: self.response.out.write("success") moment.submittedToAPI = True moment.put() else: self.response.out.write("failure") elif self.request.get('action') == 'submitAllMoments': for moment in Moment.all(keys_only=True).filter('submittedToAPI =', False): Task(url='/adminrequest', params={'action': 'submitMoment', 'id': moment.id()}, method="GET").add(queue_name='momentsubmitter') self.response.out.write("Queued up all non-submitted moments to be submitted.") def main(): logging.getLogger().setLevel(logging.DEBUG) application = webapp.WSGIApplication ([ ('/request', Request), ('/loadnewtitles', LoadNewTitles), ('/updatemomentcount', UpdateMomentCount), ('/resetskills', ResetSkills), ('/debugger', Debugger), ('/adminrequest', AdminRequest) ], debug=True) run_wsgi_app(application) if __name__ == "__main__": main()