From fcc3f76455f4d6dc6616bf1b6edc4527fd15a6bb Mon Sep 17 00:00:00 2001 From: Yves Fischer Date: Sat, 22 Nov 2014 16:20:09 +0100 Subject: generate shiny html stuff with pictures --- imdb-lookup/imdbinfo.py | 114 +++++++++++++++++++++++++++++++----------- imdb-lookup/index.jinja2.html | 37 ++++++++++++++ 2 files changed, 121 insertions(+), 30 deletions(-) create mode 100644 imdb-lookup/index.jinja2.html diff --git a/imdb-lookup/imdbinfo.py b/imdb-lookup/imdbinfo.py index 2835eb8..7d00a72 100755 --- a/imdb-lookup/imdbinfo.py +++ b/imdb-lookup/imdbinfo.py @@ -6,11 +6,13 @@ import sys import re import dbm import json +import base64 import argparse import math try: import tmdbsimple as tmdb + import requests except ImportError as e: print(u"Missing dependency: {0}".format(str(e))) print(u"Install using system package manager or `pip install --user `") @@ -31,18 +33,20 @@ def read_key(): class TMDBCache(object): def __enter__(self): - self.db = dbm.open(self._get_db_filename(),"c") + 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.db.close() + self.db_images.close() - def _get_db_filename(self): + def _get_db_filename(self, name): if u"XDG_CACHE_HOME" in os.environ.keys(): cachedir = os.environ["XDG_CACHE_HOME"] else: cachedir = os.path.join(os.path.expanduser(u"~"), ".cache") - return os.path.join(cachedir, "tmdbmovie.dbm") + return os.path.join(cachedir, name) def _cache(self, key, callable_func): if key not in self.db: @@ -75,15 +79,31 @@ class TMDBCache(object): if key in self.db: print("Remove {}".format(key)) del self.db[key] - + + def poster(self, poster_path, format="w185"): + key = "poster_{}_{}".format(format, poster_path) + keyContentType = "poster_{}_{}_content_type".format(format, poster_path) + url = "http://image.tmdb.org/t/p/{}/{}".format(format, poster_path) + if key not in self.db_images: + r = requests.get(url) + self.db_images[key] = r.content + self.db_images[keyContentType] = r.headers['content-type'] + return (self.db_images[keyContentType], self.db_images[key]) + + def poster_base64(self, poster_path, format="w185"): + contentType, data = self.poster(poster_path, format) + data64 = "".join(map(lambda c: isinstance(c,int) and chr(c) or c, + filter(lambda c: c!='\n', base64.encodestring(data)))) + return "data:{};base64,{}".format(contentType, data64) + def do_aka(args, imdb_ids): with TMDBCache() as tmdbcache: - for imdb_id in imdb_ids: + for (filename, imdb_id) in imdb_ids: print(tmdbcache.alternative_title(imdb_id, locale=args.lang)) def do_data(args, imdb_ids): with TMDBCache() as tmdbcache: - for imdb_id in imdb_ids: + for (filename, imdb_id) in imdb_ids: selected_properties = ["imdb_id", "revenue", "vote_average", "vote_count", "runtime", "budget", "vote_avarage", "release_date", "popularity", ] kv = map(lambda kv: u"{}={}".format(*kv), filter(lambda kv: kv[0] in selected_properties, @@ -92,19 +112,19 @@ def do_data(args, imdb_ids): def do_year(args, imdb_ids): with TMDBCache() as tmdbcache: - for imdb_id in imdb_ids: + 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 imdb_id in imdb_ids: + 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 = list(filter(lambda i: "vote_average" in i and "vote_count" in i, - map(lambda imdb_id: tmdbcache.infos(imdb_id), imdb_ids))) + map(lambda filename,imdb_id: tmdbcache.infos(imdb_id), imdb_ids))) maxvotes = max(map(lambda i: i["vote_count"], infos)) for info in infos: f = math.sin(math.pi * ( info["vote_average"]/10.0 ) ) @@ -113,29 +133,59 @@ def do_rating(args, imdb_ids): print("{rating:.02f} {imdb_id} {title:30s} avg={vote_average:.1f} count={vote_count:.0f}".format(**info)) +def do_index(args, imdb_ids): + """creates a index website""" + def asBase64(poster): + contentType, data = poster + data64 = filter(lambda c: c!='\n', base64.encodestring(data)) + return "data:{};base64,{}".format(contentType, data64) + try: + from jinja2 import Template + except ImportError: + print("Failed to import jinja2 library for html-templating") + sys.exit(1) + template_file = os.path.join(os.path.dirname(__file__), "index.jinja2.html") + template = Template(open(template_file).read()) + with TMDBCache() as tmdbcache: + #infos = list(map(tmdbcache.infos, imdb_ids)) + #posters = list(map(asBase64, map(tmdbcache.poster, map(lambda info: info['poster_path'], infos)))) + mapping = { + 'input' : imdb_ids, + 'tmdbcache' : tmdbcache, + 'title' : 'Movie overview', + } + assert not os.path.exists("index.html"), "index.html already exists" + open("index.html", "w").write(template.render(mapping)) class HelpAction(argparse._HelpAction): - def __call__(self, parser, namespace, values, option_string=None): - parser.print_help() - print("") - - # retrieve subparsers from parser + formatter = parser._get_formatter() + formatter.add_usage(parser.usage, parser._actions, parser._mutually_exclusive_groups) + formatter.add_text(parser.description) + + formatter.start_section(parser._optionals.title) + formatter.add_text(parser._optionals.description) + formatter.add_arguments(parser._optionals._group_actions) + formatter.end_section() + subparsers_actions = [ action for action in parser._actions if isinstance(action, argparse._SubParsersAction)] - # there will probably only be one subparser_action, - # but better save than sorry + for subparsers_action in subparsers_actions: # get all subparsers and print help - for choice, subparser in subparsers_action.choices.items(): - formatter = argparse.HelpFormatter(prog=choice) - print("subcommand {}:".format(choice)) - for action_group in subparser._action_groups: - formatter.add_arguments(action_group._group_actions) - print(formatter.format_help()) - - parser.exit() + subparsers = subparsers_action.choices + for subaction in subparsers_action._get_subactions(): + subparser = subparsers[subaction.dest] + formatter.start_section("{} {} {}".format(formatter._prog, subaction.dest, + formatter._format_actions_usage(subparser._actions, []))) + formatter.add_text(subaction.help) + formatter.add_arguments(subparser._positionals._group_actions) + formatter.add_arguments(subparser._optionals._group_actions) + formatter.end_section() + + print(formatter.format_help()) + parser.exit(0) if __name__ == u"__main__": tmdb.API_KEY = read_key() @@ -145,29 +195,33 @@ if __name__ == u"__main__": parser.add_argument("-h", action=argparse._HelpAction, help="Display short help") subparsers = parser.add_subparsers() - parser_aka = subparsers.add_parser("aka", add_help=False) + parser_aka = subparsers.add_parser("aka", add_help=False, help="Print alternative title in other languages") parser_aka.add_argument("--lang", help="Language code (default 'DE')") parser_aka.set_defaults(func=do_aka) parser_aka.add_argument("files", action="append", nargs="+", help="Files containing distinct movie-ids") - parser_data = subparsers.add_parser("data", add_help=False) + parser_data = subparsers.add_parser("data", add_help=False, help="Print all available data") parser_data.set_defaults(func=do_data) parser_data.add_argument("files", action="append", nargs="+", help="Files containing distinct movie-ids") - parser_year = subparsers.add_parser("year", add_help=False) + parser_year = subparsers.add_parser("year", add_help=False, help="Print only the release year") parser_year.set_defaults(func=do_year) parser_year.add_argument("files", action="append", nargs="+", help="Files containing distinct movie-ids") - parser_prune = subparsers.add_parser("prune", add_help=False) + parser_prune = subparsers.add_parser("prune", add_help=False, help="Delete cache entries") parser_prune.set_defaults(func=do_prune) parser_prune.add_argument("files", action="append", nargs="+", help="Files containing distinct movie-ids") - parser_rating = subparsers.add_parser("rating", add_help=False) + parser_rating = subparsers.add_parser("rating", add_help=False, help="Print movie ratings") parser_rating.set_defaults(func=do_rating) parser_rating.add_argument("files", action="append", nargs="+", help="Files containing distinct movie-ids") + parser_index = subparsers.add_parser("index", add_help=False, help="Generate index.html file") + parser_index.set_defaults(func=do_index) + parser_index.add_argument("files", action="append", nargs="+", help="Files containing distinct movie-ids") + args = parser.parse_args(sys.argv[1:]) - ids = map(lambda filename: (lambda x: x.groups()[0] if x else None)(re.match(".*#(tt[0-9]{7}).*", filename)), + ids = map(lambda filename: (lambda x: (filename, x.groups()[0]) if x else None)(re.match(".*#(tt[0-9]{7}).*", filename)), args.files[0]) args.func(args, filter(lambda i: i is not None, ids)) diff --git a/imdb-lookup/index.jinja2.html b/imdb-lookup/index.jinja2.html new file mode 100644 index 0000000..42eed34 --- /dev/null +++ b/imdb-lookup/index.jinja2.html @@ -0,0 +1,37 @@ + + + + + + {{title}} + + +

List of Movies

+ {% for (filename, imdb_id) in input %} + {% set info = tmdbcache.infos(imdb_id) %} + {% set posterBase64 = tmdbcache.poster_base64(info['poster_path']) %} +
+

{{ info.title }}

+
+ +
+
+
+ {{ info.overview }} +
+ + {% for (key, value) in info.items() %} + {% if key in ['runtime','adult','homepage','release_date','original_title'] %} + + + + + {% endif %} + {% endfor %} +
{{ key }}{{ value }}
+
+
+ {% endfor %} + + -- cgit v1.2.1