X-Git-Url: https://git.phdru.name/?p=bookmarks_db.git;a=blobdiff_plain;f=bkmk_objects.py;h=6897721da802123064222a0ebac2c81b65081b14;hp=344312ca0f91b9d22a7481612d0868fc23a389d0;hb=HEAD;hpb=7028dcb5fe31ccf6d348dca315154d719f3c481e diff --git a/bkmk_objects.py b/bkmk_objects.py index 344312c..bf5904b 100644 --- a/bkmk_objects.py +++ b/bkmk_objects.py @@ -1,168 +1,224 @@ -""" - Objects to represent bookmarks.html structure - - Written by Oleg BroytMann. Copyright (C) 2000-2007 PhiloSoft Design. -""" - - -class Folder(list): - isFolder = 1 - isBookmark = 0 - - def __init__(self, add_date=None, comment='', last_modified=None): - super(Folder, self).__init__() - self.comment = comment - self.add_date = add_date - self.last_modified = last_modified - - def walk_depth(self, walker, level=0): - if hasattr(self, "header"): # root folder - prune = 0 - walker.root_folder(self) - else: - prune = walker.prune_folder(self) - if not prune: - walker.start_folder(self, level) - - if not prune: - for object in self: - if object.isFolder: - object.walk_depth(walker, level+1) - elif object.isBookmark: - walker.bookmark(object, level) - else: - walker.ruler(object, level) +"""Objects to represent bookmarks.html structure - walker.end_folder(self, level) - - -class Bookmark: - isFolder = 0 - isBookmark = 1 - - def __init__(self, href, add_date, last_visit=None, last_modified=None, - keyword=None, comment='', icon=None, charset=None): - self.href = href - self.add_date = add_date - self.last_visit = last_visit - self.last_modified = last_modified - self.keyword = keyword - self.comment = comment - self.icon = icon - self.charset = charset - - -class Ruler: - isFolder = 0 - isBookmark = 0 +This file is a part of Bookmarks database and Internet robot. +""" -class Walker: - """ - Interface class. Any instance that will be passed to Folder.walk_depth - may be derived from this class. It is not mandatory - unlike Java - Python does not require interface classes; but it is convenient to have - some methods predefined to no-op, in case you do not want to - provide end_folder etc. - """ +__author__ = "Oleg Broytman " +__copyright__ = "Copyright (C) 2000-2024 PhiloSoft Design" +__license__ = "GNU GPL" - def root_folder(self, r): - pass +__all__ = ['Folder', 'Bookmark', 'Ruler', 'Walker', 'Writer', 'Robot', + 'InverseLinker', 'Linear', 'make_linear', 'make_tree', 'break_tree', + 'quote_title', 'unquote_title', 'parse_params', 'set_params', + ] - def start_folder(self, f, level): - pass - def end_folder(self, f, level): - pass +from urllib.parse import unquote +import os - def bookmark(self, b, level): - pass +BKMK_FORMAT = os.environ.get("BKMK_FORMAT", "MOZILLA") - def ruler(self, r, level): - pass - def prune_folder(self, folder): - return 0 +class Folder(list): + isFolder = 1 + isBookmark = 0 + + def __init__(self, add_date=None, comment='', last_modified=None): + super(Folder, self).__init__() + self.comment = comment + self.add_date = add_date + self.last_modified = last_modified + + def walk_depth(self, walker, level=0): + if hasattr(self, "header"): # root folder + prune = 0 + walker.root_folder(self) + else: + prune = walker.prune_folder(self) + if not prune: + walker.start_folder(self, level) + + if not prune: + for object in self: + if object.isFolder: + object.walk_depth(walker, level+1) + elif object.isBookmark: + walker.bookmark(object, level) + else: + walker.ruler(object, level) + + walker.end_folder(self, level) + + +class Bookmark(object): + isFolder = 0 + isBookmark = 1 + + def __init__(self, href, add_date, last_visit=None, last_modified=None, + keyword=None, comment='', icon_href=None, icon=None, + charset=None, parser_charset=None): + self.href = href + self.add_date = add_date + self.last_visit = last_visit + self.last_modified = last_modified + self.keyword = keyword + self.comment = comment + self.icon_href = icon_href + self.icon = icon + self.charset = charset + + +class Ruler(object): + isFolder = 0 + isBookmark = 0 + + +class Walker(object): + """ + Interface class. Any instance that will be passed to Folder.walk_depth + may be derived from this class. It is not mandatory - unlike Java + Python does not require interface classes; but it is convenient to have + some methods predefined to no-op, in case you do not want to + provide end_folder etc. + """ + + def root_folder(self, r): + pass + + def start_folder(self, f, level): + pass + + def end_folder(self, f, level): + pass + + def bookmark(self, b, level): + pass + + def ruler(self, r, level): + pass + + def prune_folder(self, folder): + return 0 class Writer(Walker): - def __init__(self, outfile, prune=None): - self.outfile = outfile - self.prune = prune + def __init__(self, outfile, prune=None): + self.outfile = outfile + self.prune = prune - def prune_folder(self, folder): - return self.prune == folder.name + def prune_folder(self, folder): + return self.prune == folder.name -class Robot: - def __init__(self, tempfname, log): - self.tempfname = tempfname - self.log = log +class Robot(object): + def __init__(self, log): + self.log = log - def stop(self): - pass # Nothing to do on cleanup + def stop(self): + pass # Nothing to do on cleanup # Helper class to make inverese links (nodes linked to their parent) class InverseLinker(Walker): - def root_folder(self, r): - self.parent_stack = [r] + def root_folder(self, r): + self.parent_stack = [r] - def start_folder(self, f, level): - f.parent = self.parent_stack[-1] - self.parent_stack.append(f) # Push the folder onto the stack of parents + def start_folder(self, f, level): + f.parent = self.parent_stack[-1] + # Push the folder onto the stack of parents + self.parent_stack.append(f) - def end_folder(self, f, level): - del self.parent_stack[-1] # Pop off the stack + def end_folder(self, f, level): + del self.parent_stack[-1] # Pop off the stack - def bookmark(self, b, level): - b.parent = self.parent_stack[-1] + def bookmark(self, b, level): + b.parent = self.parent_stack[-1] - def ruler(self, r, level): - r.parent = self.parent_stack[-1] + def ruler(self, r, level): + r.parent = self.parent_stack[-1] # Helper class to make linear represenatation of the tree class Linear(Walker): - def root_folder(self, r): - r.linear = [r] - self.linear = r.linear + def root_folder(self, r): + r.linear = [r] + self.linear = r.linear - def add_object(self, object): - self.linear.append(object) + def add_object(self, object): + self.linear.append(object) - def start_folder(self, f, level): - self.add_object(f) + def start_folder(self, f, level): + self.add_object(f) - def bookmark(self, b, level): - self.add_object(b) + def bookmark(self, b, level): + self.add_object(b) - def ruler(self, r, level): - self.add_object(r) + def ruler(self, r, level): + self.add_object(r) -# Helper - make linked linear represenatation of the tree, suitable to be stored in sequential storage +# Helper - make linked linear represenatation of the tree, +# suitable to be stored in sequential storage. def make_linear(root_folder): - linker = InverseLinker() - root_folder.walk_depth(linker) + linker = InverseLinker() + root_folder.walk_depth(linker) - linear = Linear() - root_folder.walk_depth(linear) + linear = Linear() + root_folder.walk_depth(linear) -# Helper, opposite of make_linear - make a tree from the linked linear representation +# Helper, opposite of make_linear - +# make a tree from the linked linear representation. def make_tree(linear): - root_folder = linear[0] - del linear[0] + root_folder = linear[0] + del linear[0] - for object in linear: - object.parent.append(object) + for object in linear: + object.parent.append(object) - return root_folder + return root_folder -def break_tree(linear): - root_folder = linear[0] - del linear[0] - for object in linear: - del object.parent +def break_tree(linear): + del linear[0] + + for object in linear: + del object.parent + + +def quote_title(title): + if BKMK_FORMAT == "MOZILLA": + title = title.replace("'", "'") + return title + + +def unquote_title(title): + if BKMK_FORMAT == "MOZILLA": + try: + from HTMLParser import HTMLParser + except ImportError: + from html import unescape + else: + unescape = HTMLParser().unescape + title = unescape( + title.replace("&", '&')) + title = title.replace("'", "'") + return title + + +def parse_params(param_str): + params = param_str.split(':') + main_param = params.pop(0) + param_list = {} + for param in params: + key, value = param.split('=', 1) + param_list[key] = unquote(value) + return main_param, param_list + + +def set_params(obj, params): + if hasattr(params, "items"): + params = params.items() + for key, value in params: + setattr(obj, key, value)