From: Fredrik Tolf Date: Sun, 12 May 2013 03:17:12 +0000 (+0200) Subject: Removed the old automanga.py. ;_; X-Git-Url: http://git.dolda2000.com/gitweb/?a=commitdiff_plain;h=cf6e78d7cc9d25b630710d8f1982667a5844bd35;p=automanga.git Removed the old automanga.py. ;_; --- diff --git a/automanga.py b/automanga.py deleted file mode 100755 index 7b6aacf..0000000 --- a/automanga.py +++ /dev/null @@ -1,548 +0,0 @@ -#!/usr/bin/python -#encoding: utf8 -# -# automanga -# by Kaka - -import os, sys, optparse -from user import home -try: - import gtk - import pygtk; pygtk.require("2.0") -except AssertionError, e: - error("You need to install the package 'python-gtk2'") - -DIR_BASE = os.path.join(home, ".automanga") -DIR_PROFILES = os.path.join(DIR_BASE, "profiles") -FILE_SETTINGS = os.path.join(DIR_BASE, "settings") - -def init(): - global settings, profile, opts, args, cwd - - if not os.path.exists(DIR_PROFILES): - os.makedirs(DIR_PROFILES) - settings = Settings() - - usage = "Usage: %prog [options]" - parser = optparse.OptionParser(usage) # one delete option to use in combination with profile and directory? - parser.add_option("-p", "--profile", help="load or create a profile", metavar="profile") - parser.add_option("-r", "--remove-profile", help="remove profile", metavar="profile") - parser.add_option("-a", "--add", help="add a directory", metavar="dir") - parser.add_option("-d", "--delete", help="delete a directory", metavar="dir") - parser.add_option("-s", "--silent", help="no output", default=False, action="store_true") - parser.add_option("-v", "--verbose", help="show output", default=False, action="store_true") - opts, args = parser.parse_args() - - cwd = os.getcwd() - -def load_profile(name): - global profile - profile = Profile(name) - settings.last_profile(profile.name) - -def output(msg): - if not settings.silent(): - print msg - -def error(msg): - print >>sys.stderr, msg - sys.exit(1) - -def abs_path(path): - """Returns the absolute path""" - if not os.path.isabs(path): ret = os.path.join(cwd, path) - else: ret = path - return os.path.abspath(ret) - -def manga_dir(path): - """Checks if path is a manga directory""" - for node in os.listdir(path): - if node.rsplit(".", 1)[-1] in ("jpg", "png", "gif", "bmp"): - return True - return False - -def natsorted(strings): - """Sorts a list of strings naturally""" -# import re -# return sorted(strings, key=lambda s: [int(t) if t.isdigit() else t for t in re.split(r'(\d+)', s)]) - return sorted(strings, key=lambda s: [int(t) if t.isdigit() else t for t in s.rsplit(".")[0].split("-")]) - -class Reader(object): - """GUI""" - def __init__(self): - self.window = gtk.Window(gtk.WINDOW_TOPLEVEL) - self.window.connect("delete_event", lambda widget, event, data = None: False) - self.window.connect("destroy", lambda widget, data = None: self.quit()) - self.window.connect("key_press_event", self.keypress) -# self.window.set_border_width(10) - self.window.set_position(gtk.WIN_POS_CENTER) # save position in settings? -# self.window.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("#222")) # seems to do nothing - - self.set_title() - self.fullscreen = False - self.cursor = None - - self.container = gtk.VBox() - self.menu_bar = self.build_menu() - self.page_bar = gtk.HBox() - self.key = gtk.Label() -# self.key.set_padding(10, 10) - self.page_num = gtk.Label() - self.page = gtk.Image() - self.sep = gtk.HSeparator() - self.sbar = gtk.Statusbar(); self.sbar.show(); self.sbar.set_has_resize_grip(False) - - self.combo = gtk.combo_box_new_text() - self.combo.set_wrap_width(2) - for i in range(50): - self.combo.append_text('item - %d' % i) - self.combo.set_active(0) - - self.page_bar.pack_start(self.key, expand=False) - vsep = gtk.VSeparator(); vsep.show(); self.page_bar.pack_start(vsep, expand=False) -# self.page_bar.pack_start(self.combo, expand=False); self.combo.show() - self.page_bar.pack_start(self.page_num, expand=False) -# self.container.pack_start(self.menu_bar, expand=False) - self.container.pack_start(self.page_bar, expand=False) - self.container.pack_start(self.sep, expand=False) - self.container.pack_start(self.page) - self.container.pack_start(self.sbar, expand=False) - self.window.add(self.container) - - self.key.show() - self.page_num.show() - self.sep.show() - self.page.show() - self.page_bar.show() - self.container.show() - self.window.show() - - def build_menu(self): - menus = (("_File", ( - ("_New profile", gtk.STOCK_NEW, lambda widget, data: None), - ("_Load profile", gtk.STOCK_OPEN, lambda widget, data: None), - ("_Delete profile", gtk.STOCK_DELETE, lambda widget, data: None), - (), - ("_Quit", gtk.STOCK_QUIT, lambda widget, data: self.quit()), - )), - ("_Edit", ( - ("_Profile", gtk.STOCK_EDIT, lambda widget, data: None), - (), - ("_Settings", gtk.STOCK_PREFERENCES, lambda widget, data: None), - )), - ) - menu_bar = gtk.MenuBar() - menu_bar.show() - for submenu in menus: - lbl, items = submenu - menu = gtk.Menu() - menu.show() - mi = gtk.MenuItem(lbl, True) - mi.show() - mi.set_submenu(menu) - menu_bar.add(mi) - for item in items: - if not item: - mi = gtk.SeparatorMenuItem() - mi.show() - menu.add(mi) - else: - lbl, icon, func = item - img = gtk.Image() - img.set_from_stock(icon, gtk.ICON_SIZE_MENU) - mi = gtk.ImageMenuItem(lbl, True) - mi.show() - mi.set_image(img) - mi.connect("activate", func, None) - menu.add(mi) - return menu_bar - - def start(self): - gtk.main() - - def quit(self): - gtk.main_quit() - - def set_title(self, title = None): - self.window.set_title("Automanga" + (" - " + title if title else "")) - - def set_manga(self, manga): - self.manga = manga - self.set_title(manga.title()) - self.cursor = manga.mark - self.update_page() - - def update_page(self): - self.page.set_from_file(self.cursor.path) - self.page_num.set_label("Mark's at %s (%s/%s)\t\tYou're at %s (%s/%s)" % (self.manga.mark.name, self.manga.index_of(self.manga.mark) + 1, self.manga.num_pages(), self.cursor.name, self.manga.index_of(self.cursor) + 1, self.manga.num_pages())) - self.window.resize(*self.container.size_request()) - - self.sbar.pop(self.sbar.get_context_id("stat")) - self.sbar.push(self.sbar.get_context_id("stat"), "Mark's at %s (%s/%s)\t\tYou're at %s (%s/%s)" % (self.manga.mark.name, self.manga.index_of(self.manga.mark) + 1, self.manga.num_pages(), self.cursor.name, self.manga.index_of(self.cursor) + 1, self.manga.num_pages())) - - def keypress(self, widget, event, data = None): - if event.keyval in [32]: self.read_page(1) # space - elif event.keyval in [65288]: self.read_page(-1) # backspace - elif event.keyval in [65362, 65363]: self.browse_page(1) # up, right - elif event.keyval in [65361, 65364]: self.browse_page(-1) # left, down - elif event.keyval in [70, 102]: self.toggle_fullscreen() # f, F - elif event.keyval in [81, 113, 65307]: self.quit() # q, Q, esc - elif event.keyval in [65360]: self.browse_start() # home - elif event.keyval in [65367]: self.browse_end() # end - else: self.key.set_text(str(event.keyval)) - - def browse_page(self, step): - self.cursor = self.cursor.previous() if step < 0 else self.cursor.next() - self.update_page() - - def read_page(self, step): - if self.cursor == self.manga.mark: - if step < 0: self.manga.set_mark(self.cursor.previous()) - else: self.cursor = self.cursor.next() - if step < 0: self.cursor = self.manga.mark - else: self.manga.set_mark(self.cursor) - self.update_page() - - def browse_start(self): - self.cursor = self.manga.first_page() - self.update_page() - - def browse_end(self): - self.cursor = self.manga.last_page() - self.update_page() - - def toggle_fullscreen(self): - self.fullscreen = not self.fullscreen -# if self.fullscreen: self.window.fullscreen() -# else: self.window.unfullscreen() - if self.fullscreen: - self.window.set_decorated(False) - self.window.set_position(gtk.WIN_POS_CENTER_ALWAYS) - self.menu_bar.hide() - else: - self.window.set_decorated(True) - self.window.set_position(gtk.WIN_POS_NONE) - self.menu_bar.show() - -class File(object): - """A class for accessing the parsed content of a file as - attributes on an object.""" - - def __init__(self, path, create = False): ## add autosync - save everytime an attribute is set - does not work well with list attributes - self.path = path - self.attributes = [] ## make this a dict which stores the attributes, instead of adding them as attributes to the File object - if os.path.exists(path): - file = open(path) - self.parse(file) - file.close() - elif create: - self.save() - - def __setattr__(self, name, val): - if name not in ("path", "attributes") and name not in self.attributes: - self.attributes.append(name) - object.__setattr__(self, name, val) - - def __getattr__(self, name): - try: return object.__getattribute__(self, name) - except: return None - - def __delattr__(self, name): - self.attributes.remove(name) - object.__delattr__(self, name) - - def parse(self, file): - def add_attr(type, name, val): - if type and name and val: - if type == "str": val = val[0] - elif type == "int": val = int(val[0]) - elif type == "bool": val = (val[0].lower() == "true") - setattr(self, name, val) - type, attr, val = None, "", [] - for line in file.xreadlines(): - line = line.strip() - if line.startswith("["): - add_attr(type, attr, val) - (type, attr), val = line[1:-1].split(":"), [] - elif line: - val.append(line) - add_attr(type, attr, val) - - def exists(self): - return os.path.exists(self.path) - - def delete(self): - self.attributes = [] - os.remove(self.path) - - def save(self): - dir = self.path.rsplit("/", 1)[0] - if not os.path.exists(dir): - os.makedirs(dir) - file = open(self.path, "w") - for attr in self.attributes: - val = getattr(self, attr) - file.write("[%s:%s]\n" % (str(type(val))[7:-2], attr)) - if type(val) in (list, tuple): - for i in val: - file.write(i + "\n") - else: - file.write(str(val) + "\n") - file.write("\n") - file.close() - - def save_all(self): - self.save() - -class Directory(object): - """A class for accessing files, or directories, in a directory as - attributes on an object.""" - - def __init__(self, path): - self._path = path - self._nodes = [f for f in os.listdir(path) if "." not in f] if os.path.exists(path) else [] - self._opened_nodes = {} - - def __iter__(self): - return self._opened_nodes.itervalues() - - def __contains__(self, name): - return name in self._nodes - - def __getitem__(self, name): - if name in self._nodes: - return getattr(self, name) - raise KeyError(name) - - def __getattr__(self, name): - if name in self._nodes: - if name not in self._opened_nodes: - if os.path.isdir(self.path(name)): self._opened_nodes[name] = Directory(self.path(name)) - else: self._opened_nodes[name] = File(self.path(name)) - return self._opened_nodes[name] - return object.__getattribute__(self, name) - - def __delattr__(self, name): - if name in self._nodes: - self._nodes.remove(name) - if name in self._opened_nodes: - self._opened_nodes.pop(name).delete() - else: - object.__delattr__(self, name) - - def delete(self): - for n in self._nodes: - getattr(self, n).delete() - self._opened_nodes = {} - self._nodes = [] - os.rmdir(self.path()) - - def save(self): - if not self.exists(): - os.makedirs(self.path()) - - def save_all(self): - self.save() - for name, node in self._opened_nodes.items(): - node.save_all() - - def exists(self): - return os.path.exists(self.path()) - - def move(self, new_path): - if not self.exists() or os.path.exists(new_path): - return False - os.rename(self.path(), new_path) - self._path = new_path - return True - - def path(self, *name): - return os.path.join(self._path, *name) - - def add_dir(self, name): - if not os.path.exists(self.path(name)): - self._nodes.append(name) - self._opened_nodes[name] = Directory(self.path(name)) - return getattr(self, name) - - def add_file(self, name): - if not os.path.exists(self.path(name)): - self._nodes.append(name) - self._opened_nodes[name] = File(self.path(name)) - return getattr(self, name) - -class Settings(object): - def __init__(self): - self.file = File(FILE_SETTINGS, True) - if self.file.dirs is None: - self.file.dirs = [] - - def save(self): - self.file.save() - - def add_dir(self, path): - if not os.path.exists(path): - output("Failed to add directory - '%s' does not exist!" % path) - return - if path not in self.file.dirs: - self.file.dirs.append(path) - self.save() - output("Added '%s'!" % path) - - def delete_dir(self, dir): - if path not in self.file.dirs: - output("Failed to remove directory - '%s' not in list!" % path) - return - self.file.dirs.remove(dir) - self.save() - output("Removed '%s'!" % path) - - def silent(self, state = None): - if state is None: return self.file.silent - else: self.file.silent = state - - def last_profile(self, val = None): - if val is None: return self.file.last_profile - else: self.file.last_profile = val - - def load_last_profile(self): - if not self.file.last_profile: - return False - load_profile(self.file.last_profile) - if not profile.exists(): - del self.file.last_profile - self.save() - return False - return True - - def list_manga(self): - ret = [] - for dir in self.file.dirs: - if os.path.exists(dir): - ret += os.listdir(dir) - return ret - -class Profile(object): - def __init__(self, name): - self.name = name - self.dir = Directory(os.path.join(DIR_PROFILES, name)) - self.mangas = self.dir.add_dir("manga") - self.settings = self.dir.add_file("settings") - - def exists(self): - return self.dir.exists() - - def delete(self): - self.dir.delete() - - def rename(self, new_name): - if not self.dir.move(os.path.join(DIR_PROFILES, new_name)): - return False - self.name = new_name - return True - - def save(self): - self.dir.save_all() - - def save_page(self, manga): - if manga.title() not in self.mangas: - self.mangas.add_file(manga.title()) - file = self.mangas[manga.title()] - file.page = manga.mark.name - file.save() - - def load_manga(self, path): - self.settings.last_read = path - manga = path.rsplit("/", 1)[-1] - if manga in self.mangas: - return Manga(self, path, self.mangas[manga].page) - return Manga(self, path) - -class Manga(object): - def __init__(self, reader_profile, path, page = None): - self.reader = reader_profile - self.path = path - self.pages = self.load_pages() - self.mark = Page(self, page) if page else self.first_page() - - def load_pages(self): - files = [f for f in os.listdir(self.path) if f.rsplit(".", 1)[-1] in ("jpg", "png", "gif", "bmp")] - return natsorted(files) # check if there's an order file / only load image files - - def first_page(self): - return Page(self, self.pages[0]) - - def last_page(self): - return Page(self, self.pages[-1]) - - def num_pages(self): - return len(self.pages) - - def index_of(self, page): - return self.pages.index(page.name) - - def set_mark(self, page): - self.mark = page - self.reader.save_page(self) - - def previous(self, page, step = 1): - return Page(self, self.pages[max(0, self.pages.index(page) - step)]) - - def next(self, page, step = 1): - return Page(self, self.pages[min(len(self.pages) - 1, self.pages.index(page) + step)]) - - def title(self): - return self.path.rsplit("/", 1)[-1] - -class Page(object): - def __init__(self, manga, name): - self.manga = manga - self.name = name - self.path = os.path.join(manga.path, name) - - def previous(self, step = 1): - return self.manga.previous(self.name, step) - - def next(self, step = 1): - return self.manga.next(self.name, step) - -if __name__ == "__main__": - init() - - if opts.add: - path = abs_path(opts.add) - settings.add_dir(path) - - if opts.delete: - path = abs_path(opts.delete) - settings.delete_dir(path) - - if opts.silent: - settings.silent(True) - if opts.verbose: - settings.silent(False) - - if opts.profile: - load_profile(opts.profile) - if profile.exists(): - output("Loaded profile '%s'" % profile.name) - else: - profile.save() - output("Created profile '%s'" % profile.name) - else: - if settings.load_last_profile(): - output("No profile specified - loading '%s'" % profile.name) - else: - user = home.split("/")[-1] - output("No profile exists - creating one for '%s'" % user) - load_profile(user) - profile.save() - - reader = Reader() - manga_path = abs_path(args[0]) if args else cwd - if manga_dir(manga_path): - reader.set_manga(profile.load_manga(manga_path)) - reader.start() - - profile.save() - settings.save()