From eabba9daeaf67a77bdeeddcca36c6d8af22fd630 Mon Sep 17 00:00:00 2001 From: Yves Fischer Date: Tue, 14 Oct 2014 21:49:26 +0200 Subject: fancy rename script --- imdb-lookup/imdblookup.py | 203 +++++++++++++++++++++++++++++----------------- 1 file changed, 130 insertions(+), 73 deletions(-) (limited to 'imdb-lookup/imdblookup.py') 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 `") + 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() -- cgit v1.2.1