summaryrefslogtreecommitdiff
path: root/imdb-lookup
diff options
context:
space:
mode:
authorYves Fischer <yvesf-git@xapek.org>2014-12-21 22:47:26 +0100
committerYves Fischer <yvesf-git@xapek.org>2014-12-21 22:47:26 +0100
commit2d0e49183a5c49badb96a0168dab575f7db70b21 (patch)
tree521662aaeca0357aa19b39076f7383ccc8839221 /imdb-lookup
parent3008170f2bd120c43a876b1f1adba885db594618 (diff)
downloadscripts-2d0e49183a5c49badb96a0168dab575f7db70b21.tar.gz
scripts-2d0e49183a5c49badb96a0168dab575f7db70b21.zip
simpliefied caching
Diffstat (limited to 'imdb-lookup')
-rw-r--r--imdb-lookup/css/style.css4
-rwxr-xr-ximdb-lookup/imdbinfo.py193
-rw-r--r--imdb-lookup/index.jinja2.html18
-rw-r--r--imdb-lookup/js/app.js26
4 files changed, 115 insertions, 126 deletions
diff --git a/imdb-lookup/css/style.css b/imdb-lookup/css/style.css
index 2a0b6eb..5f04ced 100644
--- a/imdb-lookup/css/style.css
+++ b/imdb-lookup/css/style.css
@@ -6,10 +6,6 @@
clear: both;
position: relative;
}
-.filter, .sort {
- padding: 4px;
- display: inline-block;
-}
.error {
background-color: #EFAAAA;
height: 150px;
diff --git a/imdb-lookup/imdbinfo.py b/imdb-lookup/imdbinfo.py
index e1fe5be..7419103 100755
--- a/imdb-lookup/imdbinfo.py
+++ b/imdb-lookup/imdbinfo.py
@@ -5,7 +5,6 @@ import sys
assert sys.version.startswith("3."), "Requires python3"
import os
import re
-import dbm
import json
import time
import argparse
@@ -42,36 +41,62 @@ def read_key():
class TMDBCache(object):
- def __enter__(self):
+ def __init__(self):
logger_name = self.__class__.__module__ + "." + self.__class__.__name__
self.logger = logging.getLogger(logger_name)
- self.logger.info("Open db")
- self.db = dbm.open(self._get_db_filename("tmdbmovie.dbm"), "c")
- self.db_images = dbm.open(self._get_db_filename("tmdbposter.dbm"), "c")
- return self
- def __exit__(self, type, value, traceback):
- self.logger.info("Close db")
- self.db.close()
- self.db_images.close()
-
- def _get_db_filename(self, name):
+ def _get_cachedir(self, movie_id):
if "XDG_CACHE_HOME" in os.environ.keys():
cachedir = os.environ["XDG_CACHE_HOME"]
else:
cachedir = os.path.join(os.path.expanduser("~"), ".cache")
- return os.path.join(cachedir, name)
- def _cache(self, key, callable_func):
- if key not in self.db:
- self.db[key] = json.dumps(callable_func())
- d = self.db[key].decode('utf-8')
- return json.loads(d)
+ cachedir = os.path.join(cachedir, "movies")
+ cachedir = os.path.join(cachedir, movie_id)
+ if not os.path.exists(cachedir):
+ os.makedirs(cachedir)
+
+ return cachedir
+
+ def _cache(self, movie_id, key, callable_func):
+ cachedir = self._get_cachedir(movie_id)
+ cachefile = os.path.join(cachedir, key)
+ if os.path.exists(cachefile):
+ fh = open(cachefile, "rb")
+ data = fh.read()
+ fh.close()
+ return data
+ else:
+ fh = open(cachefile, 'wb')
+ data = callable_func()
+ fh.write(data)
+ fh.close()
+ return data
+
+ def _cache_json(self, movie_id, key, callable_func):
+ def json_wrapper():
+ return json.dumps(callable_func()).encode('utf-8')
+ return json.loads(self._cache(movie_id, key, json_wrapper).decode('utf-8'))
+
+ def prune(self, movie_id):
+ self.logger.debug("prune {}".format(movie_id))
+ keys = [
+ "tmdb_info.json",
+ "tmdb_alternative_title.json",
+
+ ]
+ for key in keys:
+ cachefile = os.path.join(self._get_cachedir(movie_id), key)
+ if os.path.exists(cachefile):
+ self.logger.warn("Remove {}".format(cachefile))
+ os.unlink(cachefile)
+ else:
+ self.logger.debug("Key in db {}".format(cachefile))
def infos(self, movie_id):
try:
self.logger.debug("movie %s", movie_id)
- return self._cache(movie_id + "movies.info",
+ return self._cache_json(movie_id, "tmdb_info.json",
tmdb.Movies(movie_id).info)
except Exception as e:
raise Exception("Failed to query movie-id {id}: {reason}".format(
@@ -80,9 +105,9 @@ class TMDBCache(object):
def alternative_title(self, movie_id, locale):
"""Returns the title in selected locale or original title otherwise"""
try:
- key = movie_id + "movies.alt_titles"
+ key = movie_id + "tmdb_alternative_title.json"
search = tmdb.Movies(movie_id).alternative_titles
- titles = self._cache(key, search)
+ titles = self._cache_json(movie_id, key, search)
alt_title = list(filter(lambda l: l["iso_3166_1"] == locale,
titles["titles"]))
if alt_title:
@@ -94,42 +119,28 @@ class TMDBCache(object):
raise Exception("Failed to query movie-id {id}: {reason}".format(
id=movie_id, reason=str(e)))
- def prune(self, movie_id):
- self.logger.debug("prune {}".format(movie_id))
- keys = [
- "imdb_maindetails_{}".format(movie_id),
- movie_id + "movies.info",
- movie_id + "movies.alt_titles",
- ]
- for key in keys:
- if key in self.db:
- self.logger.warn("Remove {}".format(key))
- del self.db[key]
- else:
- self.logger.debug("Key not in db {}".format(key))
+ def poster(self, movie_id, f="w154"):
+ poster_path = self.infos(movie_id)['poster_path']
+ assert poster_path, "No poster_path defined for {}".format(movie_id)
- def poster(self, poster_path, f="w154"):
- self.logger.debug("poster %s", poster_path)
- key = "poster_{}_{}".format(f, hashlib.md5(poster_path.encode('utf-8')).hexdigest()[0:10])
- keyContentType = "{}_ct".format(key)
url = "http://image.tmdb.org/t/p/{}/{}".format(f, poster_path)
- if key not in self.db_images or keyContentType not in self.db_images:
- r = requests.get(url)
- self.db_images[key] = r.content
- self.db_images[keyContentType] = r.headers['content-type']
+ self.logger.debug("poster %s", poster_path)
+ def download():
+ r = requests.get(url) # r.headers['content-type']
r.close()
- return (self.db_images[keyContentType], self.db_images[key])
+ return r.content
- def poster_low(self, poster_path, format="w154"):
- p = self.poster(poster_path, format)
- if not p:
+ return self._cache(movie_id, "tmdb_poster.jpg", download)
+
+ def poster_low(self, movie_id, format="w154"):
+ data = self.poster(movie_id, format)
+ if not data:
return None
- contentType, data = p
image = Image.open(BytesIO(data))
image = image.filter(ImageFilter.GaussianBlur(radius=1))
buf = BytesIO()
image.save(buf, "JPEG", quality=18, optimize=True)
- return ("image/jpeg", buf.getvalue())
+ return buf.getvalue()
def _imdb_request(self, path, query):
# see also https://github.com/richardasaurus/imdb-pie
@@ -163,8 +174,7 @@ class TMDBCache(object):
r.close()
assert data is not None and data['data'], "Data must not be empty"
return data
- key = "imdb_maindetails_{}".format(movie_id)
- return self._cache(key, do_request)
+ return self._cache_json(movie_id, "imdb_maindetails", do_request)
def omdb_movie(self, movie_id):
def do_request():
@@ -176,8 +186,7 @@ class TMDBCache(object):
r.close()
assert data is not None and data['Response'] == 'True', "Data must not be empty"
return data
- key = "omdb_{}".format(movie_id)
- return self._cache(key, do_request)
+ return self._cache_json(movie_id, "omdb.json", do_request)
def weight_rating(infos):
@@ -228,9 +237,9 @@ class Protector(object):
def do_aka(args, imdb_ids):
- with TMDBCache() as tmdbcache:
- for (filename, imdb_id) in imdb_ids:
- print(tmdbcache.alternative_title(imdb_id, locale=args.lang))
+ tmdbcache = TMDBCache()
+ for (filename, imdb_id) in imdb_ids:
+ print(tmdbcache.alternative_title(imdb_id, locale=args.lang))
def do_data(args, imdb_ids):
@@ -248,34 +257,34 @@ def do_data(args, imdb_ids):
elif type(data) in (bool, str, int, float):
io.write(str(data))
- with TMDBCache() as tmdbcache:
- for (filename, imdb_id) in imdb_ids:
- print_data({"TMDB": tmdbcache.infos(imdb_id),
- "IMDB": tmdbcache.imdb_movie(imdb_id),
- "OMDB": tmdbcache.omdb_movie(imdb_id)}, sys.stdout)
+ tmdbcache = TMDBCache()
+ for (filename, imdb_id) in imdb_ids:
+ print_data({"TMDB": tmdbcache.infos(imdb_id),
+ "IMDB": tmdbcache.imdb_movie(imdb_id),
+ "OMDB": tmdbcache.omdb_movie(imdb_id)}, sys.stdout)
def do_year(args, imdb_ids):
- with TMDBCache() as tmdbcache:
- for (filename, imdb_id) in imdb_ids:
- print(tmdbcache.infos(imdb_id)["release_date"].split("-")[0])
+ tmdbcache = TMDBCache()
+ for (filename, imdb_id) in imdb_ids:
+ print(tmdbcache.infos(imdb_id)["release_date"].split("-")[0])
def do_prune(args, imdb_ids):
- with TMDBCache() as tmdbcache:
- for (filename, imdb_id) in imdb_ids:
- tmdbcache.prune(imdb_id)
+ tmdbcache = TMDBCache()
+ for (filename, imdb_id) in imdb_ids:
+ tmdbcache.prune(imdb_id)
def do_rating(args, imdb_ids):
"""Calculates a rating based on vote_average and vote_count"""
- with TMDBCache() as tmdbcache:
- infos = filter(lambda i: "vote_average" in i and "vote_count" in i,
- map(lambda fid: tmdbcache.infos(fid[1]), imdb_ids))
- weight_rating(infos)
- for info in infos:
- print("{rating:.02f} {imdb_id} {title:30s} avg=" +
- "{vote_average:.1f} count={vote_count:.0f}".format(**info))
+ tmdbcache = TMDBCache()
+ infos = filter(lambda i: "vote_average" in i and "vote_count" in i,
+ map(lambda fid: tmdbcache.infos(fid[1]), imdb_ids))
+ weight_rating(infos)
+ for info in infos:
+ print("{rating:.02f} {imdb_id} {title:30s} avg=" +
+ "{vote_average:.1f} count={vote_count:.0f}".format(**info))
def do_index(args, imdb_ids):
@@ -298,14 +307,15 @@ def do_index(args, imdb_ids):
return out
def data(callbackName):
- db = Protector(tmdbcache)
- def poster(imdb_id, data):
+ db = TMDBCache() #Protector(tmdbcache)
+ def poster(imdb_id):
+ data = db.poster_low(imdb_id)
if data:
if not os.path.exists(".index.html/poster"):
os.makedirs(".index.html/poster")
out = os.path.join(".index.html/poster",imdb_id+".jpg")
- open(out, "wb").write(data[1])
+ open(out, "wb").write(data)
return out
else:
return None
@@ -323,7 +333,7 @@ def do_index(args, imdb_ids):
'id': imdb_id,
'title': tmdb['title'],
'path': path,
- 'poster': poster(imdb_id, db.poster_low(tmdb['poster_path'])),
+ 'poster': poster(imdb_id),
'tagline': 'tagline' in imdb and imdb['tagline'] or None,
'plot': 'plot' in imdb and imdb['plot']['outline'] or None,
'website': 'homepage' in imdb and imdb['homepage'] or omdb['Website'] != 'N/A' and omdb['Website'] or None,
@@ -336,7 +346,6 @@ def do_index(args, imdb_ids):
'omdbUserTomato': (omdb['tomatoUserMeter'] != 'N/A') and float(omdb['tomatoUserMeter']) or None,
'omdbTomatoRating': (omdb['tomatoRating'] != 'N/A') and float(omdb['tomatoRating']) or None,
'omdbTomatoUserRating': (omdb['tomatoUserRating'] != 'N/A') and float(omdb['tomatoUserRating']) or None,
- 'omdbTomatoFresh': (omdb['tomatoFresh'] != 'N/A') and int(omdb['tomatoFresh']) or None,
'tmdbId': tmdb['id'],
}
@@ -360,20 +369,20 @@ def do_index(args, imdb_ids):
template_file = os.path.join(os.path.dirname(__file__),
"index.jinja2.html")
template = Template(open(template_file, "r").read())
- with TMDBCache() as tmdbcache:
- mapping = {
- 'title': 'Movie overview',
- 'install': install,
- 'data': data,
- }
- assert not os.path.exists("index.html") and not os.path.exists(".index.html"), \
- "index.html or folder .index.html already exists"
- stream = template.generate(mapping)
- outfile = open("index.html", "wb")
- for output in stream:
- out = output.strip()
- out = re.sub(" {2,}", " ", out)
- outfile.write(out.encode('utf-8'))
+ tmdbcache = TMDBCache()
+ mapping = {
+ 'title': 'Movie overview',
+ 'install': install,
+ 'data': data,
+ }
+ assert not os.path.exists("index.html") and not os.path.exists(".index.html"), \
+ "index.html or folder .index.html already exists"
+ stream = template.generate(mapping)
+ outfile = open("index.html", "wb")
+ for output in stream:
+ out = output.strip()
+ out = re.sub(" {2,}", " ", out)
+ outfile.write(out.encode('utf-8'))
class HelpAction(argparse._HelpAction):
diff --git a/imdb-lookup/index.jinja2.html b/imdb-lookup/index.jinja2.html
index 4a140b4..58dd4bf 100644
--- a/imdb-lookup/index.jinja2.html
+++ b/imdb-lookup/index.jinja2.html
@@ -7,24 +7,23 @@
<link rel="stylesheet" href="{{ install("css/style.css") }}">
</head>
<body>
- {% raw %}
<script type="text/x-handlebars">
+ <h1>{{title}}</h1>
+ {% raw %}
{{outlet}}
</script>
<script type="text/x-handlebars" id="index">
<div class="box">
- <div class="filter">
- <h2>Filter</h2>
- {{input type='text' value=filter placeholder='Title'}}
- </div>
<div class="sort">
<h2>Sort</h2>
<button {{action 'sortBy' 'imdbRating'}}>IMDB Rating</button>
<button {{action 'sortBy' 'imdbVotes'}}>IMDB Votes</button>
<button {{action 'sortBy' 'release'}}>Release Year</button>
+ <button {{action 'sortBy' 'omdbTomato'}}>RT Meter %</button>
+ <button {{action 'sortBy' 'omdbTomatoRating'}}>RT Rating</button>
</div>
-</div>
- {{#each movie in filteredContent}}
+ </div>
+ {{#each movie in arrangedContent}}
<div class="box">
<table>
<tr>
@@ -60,6 +59,8 @@
&ensp;
➜ <a {{bind-attr href=movie.linkOfdb}} rel="noreferrer">ofdb.db</a>
&ensp;
+ ➜ <a {{bind-attr href=movie.linkRotten}} rel="noreferrer">rottentomatoes</a>
+ &ensp;
➜ <span class="imdbid">{{movie.id}}</span>
</td>
</tr>
@@ -74,9 +75,6 @@
<table>
<tr><td>IMDB</td><td>{{movie.imdbRating}}</td></tr>
<tr><td>IMDB votes</td><td>{{movie.imdbVotes}}</td></tr>
- {{#if movie.omdbTomatoFresh}}
- <tr><td>Fresh</td><td>{{movie.omdbTomatoFresh}}</td></tr>
- {{/if}}
{{#if movie.omdbTomatoRating}}
<tr><td>RT</td><td>{{movie.omdbTomatoRating}}</td></tr>
{{/if}}
diff --git a/imdb-lookup/js/app.js b/imdb-lookup/js/app.js
index 03819e6..8cd5e76 100644
--- a/imdb-lookup/js/app.js
+++ b/imdb-lookup/js/app.js
@@ -28,12 +28,9 @@ App.Movie = DS.Model.extend({
omdbUserTomato: DS.attr('int'),
omdbTomatoRating: DS.attr(),
omdbTomatoUserRating: DS.attr(),
- omdbTomatoFresh: DS.attr('int'),
- tmdbId: DS.attr('int')
-})
-
-App.MovieController = Ember.ObjectController.extend({
+ tmdbId: DS.attr('int'),
+
linkTmdb: function() {
return "http://www.themoviedb.org/movie/" + this.get('tmdbId');
}.property('tmdbId'),
@@ -45,24 +42,13 @@ App.MovieController = Ember.ObjectController.extend({
}.property('tmdbId'),
linkOfdb: function() {
return "http://www.ofdb.de/view.php?page=suchergebnis&Kat=IMDb&SText=" + this.get('id');
- }.property('id')
+ }.property('id'),
+ linkRotten: function() {
+ return "http://www.rottentomatoes.com/search/?search=" + encodeURIComponent(this.get('title'));
+ }.property('title')
});
App.IndexController = Ember.ArrayController.extend({
- itemController: 'movie',
- filter: '',
- filteredContent: function(){
- var filter = this.get('filter');
- var content = this.get('arrangedContent');
- if (filter.length > 2) {
- var rx = new RegExp(filter, 'gi');
- return content.filter(function(movie) {
- return movie && movie.get('title').match(rx);
- });
- } else {
- return content;
- }
- }.property('arrangedContent', 'filter'),
actions: {
sortBy: function(property) {
this.set('sortProperties', [property]);