summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--imdb-lookup/imdblookup.py203
1 files changed, 130 insertions, 73 deletions
diff --git a/imdb-lookup/imdblookup.py b/imdb-lookup/imdblookup.py
index c4d7508..ce88183 100644
--- a/imdb-lookup/imdblookup.py
+++ b/imdb-lookup/imdblookup.py
@@ -1,71 +1,97 @@
#!/usr/bin/env python
+# coding: utf-8
import os
import sys
-import urwid
-import tmdbsimple as tmdb
-from pprint import pprint
-def run_async(func):
- from threading import Thread
- from functools import wraps
+import re
+import shutil
+from threading import Thread
+from functools import wraps
+try:
+ import urwid
+ import tmdbsimple as tmdb
+except ImportError as e:
+ print(u"Missing dependency: {0}".format(str(e)))
+ print(u"Install using system package manager or `pip install --user <module>`")
+ sys.exit(1)
+def run_async(func):
@wraps(func)
def async_func(*args, **kwargs):
- func_hl = Thread(target = func, args = args, kwargs = kwargs)
+ func_hl = Thread(target=func, args=args, kwargs=kwargs)
func_hl.start()
return func_hl
-
return async_func
def read_key():
- if "TMDB_KEY" in os.environ.keys():
- return os.environ["TMDB_KEY"]
- if "XDG_CONFIG_HOME" in os.environ.keys():
- cfg_home = os.environ["XDG_CONFIG_HOME"]
+ if u"TMDB_KEY" in os.environ.keys():
+ return os.environ[u"TMDB_KEY"]
+ if u"XDG_CONFIG_HOME" in os.environ.keys():
+ cfg_home = os.environ[u"XDG_CONFIG_HOME"]
+ else:
+ cfg_home = os.path.join(os.path.expanduser(u"~"), ".config")
+ if os.path.exists(os.path.join(cfg_home, u"tmdbkey")):
+ return open(os.path.join(cfg_home, u"tmdbkey"), "r").read().strip()
+ if os.path.exists(os.path.join(os.path.expanduser(u"~"), ".tmdbkey")):
+ return open(os.path.exists(os.path.join(os.path.expanduser(u"~"), ".tmdbkey"))).read().strip()
+ raise Exception(u"No TheMovieDB Key defined. Set Env. var. TMDB_KEY or .tmpdbkey file")
+
+def read_filename(filename):
+ stopwords = [
+ "dvd", "ac3", "r5", "unrated", "ts", "720p", "md",
+ "ts", "ld", "bdrip", "tvrip", "dvdrip", "dvdscr", "uncut",
+ "german", "english", "telesync", "20[0-1][0-9]|19[0-9][0-9]",
+ "x264", "hdtv", "ws"
+ ]
+ def findword(word):
+ return re.findall(u"(.*?)\.?" + word + u"[\.\- ]", filename, re.IGNORECASE)
+ matches = [i for i in map(findword, stopwords) if i!=[]]
+ matches.sort()
+ if len(matches) > 0:
+ name = matches[0][0]
else:
- cfg_home = os.path.join(os.path.expanduser("~"), ".config")
- if os.path.exists(os.path.join(cfg_home, "tmdbkey")):
- return open(os.path.join(cfg_home, "tmdbkey"), "r").read().strip()
- if os.path.exists(os.path.join(os.path.expanduser("~"), ".tmdbkey")):
- return open(os.path.exists(os.path.join(os.path.expanduser("~"), ".tmdbkey"))).read().strip()
- raise Exception("No TheMovieDB Key defined. Set Env. var. TMDB_KEY or write config key")
+ name = filename
+ return name.replace(u".", u" ")
+def write_filename(filename):
+ return re.sub(u"[^a-zA-Z123 ]", u"_", filename)
class FocusableFrame(urwid.Frame):
- def keypress(self,size,key):
- x=('header', 'footer', 'body')
+ def keypress(self, size, key):
+ parts = ("header", "footer", "body")
if key == "tab":
- i = x.index(self.focus_position)
- self.set_focus(x[(i+1)%3])
+ i = parts.index(self.focus_position)
+ self.set_focus(parts[(i+1)%3])
else:
- self.__super.keypress(size,key)
+ self.__super.keypress(size, key)
class SearchField(urwid.Edit):
signals = ["activate"]
- def keypress(self,size,key):
+ def keypress(self, size, key):
if key == "enter":
self._emit("activate")
else:
- self.__super.keypress(size,key)
+ self.__super.keypress(size, key)
class UI(urwid.WidgetWrap):
- def __init__(self, term, search_service, loop=None):
- self.edit_search = SearchField(("bold", u"Search for: "), term)
- header = urwid.Pile([self.edit_search, urwid.Divider(), urwid.Text(("bold", u"Results:"))])
+ def __init__(self, filename, search_service, loop=None):
+ self.filename = filename
+ self.search_service = search_service
+ self.loop = loop
+
+ self.term = read_filename(filename)
+ self.edit_search = SearchField(("bold", u"Search for: "), self.term)
+ header = urwid.Pile([self.edit_search, urwid.Divider(u"-"), urwid.Text((u"bold", u"Results:"))])
self.model = urwid.SimpleFocusListWalker([])
self.listbox = urwid.ListBox(self.model)
btn_quit = urwid.Button(("button", u"Exit"))
self.btn_apply = urwid.Button(("button", u"Apply"))
- self.description = urwid.Text(u"", align='center')
+ self.description = urwid.Text(u"")
self.btns = urwid.Columns([btn_quit, self.btn_apply])
- footer = urwid.Pile([self.description, self.btns])
- self.view = FocusableFrame(self.listbox, header=header, footer=footer, focus_part='header')
+ footer = urwid.Pile([urwid.Divider(u"="), self.description, urwid.Divider(u"-"), self.btns])
+ self.view = FocusableFrame(self.listbox, header=header, footer=footer, focus_part="header")
super(UI, self).__init__(self.view)
-
- self.search_service = search_service
- self.loop = loop
-
- urwid.connect_signal(btn_quit, 'click', lambda *a: sys.exit(0))
- urwid.connect_signal(self.edit_search, 'activate', self.search)
+ urwid.connect_signal(btn_quit, "click", lambda *a: sys.exit(0))
+ urwid.connect_signal(self.edit_search, "activate", self.search)
def search(self, *_):
@run_async
@@ -73,70 +99,101 @@ class UI(urwid.WidgetWrap):
results = self.search_service.search(self.edit_search.edit_text)
self.fill_results(self.loop, results)
self.view.set_focus("body")
- while len(self.model) > 0: self.model.pop()
+ while len(self.model) > 0:
+ self.model.pop()
self.description.set_text(u"Searching for {}".format(self.edit_search.edit_text))
query()
def fill_results(self, loop, data):
- for result in data:
- btn = urwid.Button(u"{release_date} - {title}".format(**result))
- urwid.connect_signal(btn, 'click', self.select_movie, result["id"])
- self.model.append(btn)
+ self.description.set_text(u"Found {} matches".format(len(data)))
+ if len(data) == 0:
+ self.view.set_focus("header")
+ else:
+ for result in data:
+ if not result["release_date"]:
+ continue
+ result["year"] = result["release_date"].split("-")[0]
+ btn = urwid.Button(u"{title} ({year})".format(**result))
+ urwid.connect_signal(btn, "click", self.select_movie, result["id"])
+ self.model.append(btn)
loop.draw_screen()
- def select_movie(self, src, movie_id):
+ def select_movie(self, _, movie_id):
@run_async
def query(pos):
try:
- info = self.search_service.info(movie_id)
+ info = self.search_service.info(movie_id)
+ alt_titles = self.search_service.alternative_titles(movie_id)["titles"]
info["year"] = info["release_date"].split("-")[0]
info["filename"] = u"{title} ({year}) #{imdb_id}".format(**info)
- self.model.remove( self.model[pos] )
- btn = urwid.Button(u"{title} ({year}) #{imdb_id}".format(**info))
- urwid.connect_signal(btn, 'click', self.rename, info)
- self.model.insert(pos, btn)
-
- self.description.set_text(('description',info["overview"]))
- except:
- self.description.set_text(('error', "Request failed"))
+ btn = urwid.Button(("fetched", u"{title} ({year}) #{imdb_id}".format(**info)))
+ urwid.connect_signal(btn, "click", self.rename, info)
+ self.model.insert(pos+1, btn)
+ self.model.remove(self.model[pos])
+
+ self.description.set_text([
+ ("desc", u"Original Title: "), info["original_title"], u" ",
+ ("desc", u"Release date: "), info["release_date"], u" ",
+ ("desc", u"Genres: "), u", ".join(map(lambda e:e["name"],info["genres"])), " ",
+ ("desc", u"Length: "), u"{runtime}min".format(**info), " ",
+ "\n",
+ ("desc", u"Titles: "), u", ".join(map(lambda e:u"{title} ({iso_3166_1})".format(**e),alt_titles)),
+ "\n",
+ ("desc", u"Overview: "), info["overview"],
+ ])
+ except Exception as e:
+ self.description.set_text((u"error", u"Request failed: {0}".format(e)))
finally:
self.loop.draw_screen()
pos = self.listbox.focus_position
query(pos)
- def rename(self, src, info):
+ def rename(self, _, info):
def rename(*_):
- print info["filename"]
- sys.exit(1)
+ urwid.disconnect_signal(self.btn_apply, u"click", rename)
+ try:
+ shutil.move(self.filename, info["filename"])
+ raise urwid.ExitMainLoop()
+ except Exception as e:
+ self.view.set_focus("header")
+ self.description.set_text((u"error", u"Rename failed: {0}".format(e)))
+
self.description.set_text([
- ("bold", u"Rename "),
- ("underline", u"foo"),
- " to ",
- ("underline", info["filename"]),
- " ?"])
- self.view.set_focus("footer")
+ (u"bold", "Move "),
+ (u"underline", self.filename), "\n"
+ u" under new folder ",
+ (u"underline", info["filename"]),
+ u" ? (Click Apply or Exit)"])
+ self.view.set_focus(u"footer")
self.btns.set_focus(self.btn_apply)
- urwid.connect_signal(self.btn_apply, 'click', rename)
+ urwid.connect_signal(self.btn_apply, u"click", rename)
class Search(object):
def __init__(self):
self.tmdb_search = tmdb.Search()
def search(self, term):
- return self.tmdb_search.movie(query=term)["results"]
- def info(self, id):
- return tmdb.Movies(id).info()
+ return self.tmdb_search.movie(query=term)[u"results"]
+ def info(self, movie_id):
+ return tmdb.Movies(movie_id).info()
+ def alternative_titles(self, movie_id):
+ return tmdb.Movies(movie_id).alternative_titles()
-if __name__ == "__main__":
+def main():
tmdb.API_KEY = read_key()
palette = [
- ('bold', 'default,bold', 'default', 'bold'),
- ('button', 'default,bold', 'default', 'bold', '', 'dark blue'),
- ('underline', 'default,underline', 'default', 'underline'),
- ('description', '', '', '', 'light gray', '')]
+ ("bold", "default,bold", "default", "bold"),
+ ("fetched", "", "", "", "light green", ""),
+ ("button", "default,bold", "default", "bold", "", "dark blue"),
+ ("underline", "default,underline", "default", "underline"),
+ ("desc", "", "", "light gray", "bold", ""),
+ ("error", "", "", "light red", "bold", ""),
+ ]
args = sys.argv[1:]
- ui = UI(len(args) > 0 and " ".join(args) or "", Search())
- loop = urwid.MainLoop(ui, palette)
+ tmdb_ui = UI(len(args) > 0 and u" ".join(args) or "", Search())
+ loop = urwid.MainLoop(tmdb_ui, palette)
loop.screen.set_terminal_properties(colors=256)
- ui.loop = loop
+ tmdb_ui.loop = loop
loop.run()
+if __name__ == u"__main__":
+ main()