1# -*- coding: utf-8 -*- 2 3# Copyright (c) 2012 - 2021 Detlev Offenbach <detlev@die-offenbachs.de> 4# 5 6""" 7Module implementing a class to write Netscape HTML bookmark files. 8""" 9 10from PyQt5.QtCore import QObject, QIODevice, QFile 11 12from .BookmarkNode import BookmarkNode 13 14import Utilities 15 16 17class NsHtmlWriter(QObject): 18 """ 19 Class implementing a writer object to generate Netscape HTML bookmark 20 files. 21 """ 22 indentSize = 4 23 24 def __init__(self): 25 """ 26 Constructor 27 """ 28 super().__init__() 29 30 def write(self, fileNameOrDevice, root): 31 """ 32 Public method to write an Netscape HTML bookmark file. 33 34 @param fileNameOrDevice name of the file to write (string) 35 or device to write to (QIODevice) 36 @param root root node of the bookmark tree (BookmarkNode) 37 @return flag indicating success (boolean) 38 """ 39 if isinstance(fileNameOrDevice, QIODevice): 40 f = fileNameOrDevice 41 else: 42 f = QFile(fileNameOrDevice) 43 if root is None or not f.open(QFile.WriteOnly): 44 return False 45 46 self.__dev = f 47 return self.__write(root) 48 49 def __write(self, root): 50 """ 51 Private method to write an Netscape HTML bookmark file. 52 53 @param root root node of the bookmark tree (BookmarkNode) 54 @return flag indicating success (boolean) 55 """ 56 self.__dev.write( 57 "<!DOCTYPE NETSCAPE-Bookmark-file-1>\n" 58 "<!-- This is an automatically generated file.\n" 59 " It will be read and overwritten.\n" 60 " DO NOT EDIT! -->\n" 61 "<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html;" 62 " charset=UTF-8\">\n" 63 "<TITLE>Bookmarks</TITLE>\n" 64 "<H1>Bookmarks</H1>\n" 65 "\n" 66 "<DL><p>\n") 67 if root.type() == BookmarkNode.Root: 68 for child in root.children(): 69 self.__writeItem(child, self.indentSize) 70 else: 71 self.__writeItem(root, self.indentSize) 72 self.__dev.write("</DL><p>\n") 73 return True 74 75 def __writeItem(self, node, indent): 76 """ 77 Private method to write an entry for a node. 78 79 @param node reference to the node to be written (BookmarkNode) 80 @param indent size of the indentation (integer) 81 """ 82 if node.type() == BookmarkNode.Folder: 83 self.__writeFolder(node, indent) 84 elif node.type() == BookmarkNode.Bookmark: 85 self.__writeBookmark(node, indent) 86 elif node.type() == BookmarkNode.Separator: 87 self.__writeSeparator(indent) 88 89 def __writeSeparator(self, indent): 90 """ 91 Private method to write a separator. 92 93 @param indent size of the indentation (integer) 94 """ 95 self.__dev.write(" " * indent) 96 self.__dev.write("<HR>\n") 97 98 def __writeBookmark(self, node, indent): 99 """ 100 Private method to write a bookmark node. 101 102 @param node reference to the node to be written (BookmarkNode) 103 @param indent size of the indentation (integer) 104 """ 105 added = ( 106 " ADD_DATE=\"{0}\"".format(node.added.toTime_t()) 107 if node.added.isValid() else 108 "" 109 ) 110 modified = ( 111 " LAST_MODIFIED=\"{0}\"".format(node.modified.toTime_t()) 112 if node.modified.isValid() else 113 "" 114 ) 115 visited = ( 116 " LAST_VISIT=\"{0}\"".format(node.visited.toTime_t()) 117 if node.visited.isValid() else 118 "" 119 ) 120 121 self.__dev.write(" " * indent) 122 self.__dev.write("<DT><A HREF=\"{0}\"{1}{2}{3}>{4}</A>\n".format( 123 node.url, added, modified, visited, 124 Utilities.html_uencode(node.title) 125 )) 126 127 if node.desc: 128 self.__dev.write(" " * indent) 129 self.__dev.write("<DD>{0}\n".format( 130 Utilities.html_uencode("".join(node.desc.splitlines())))) 131 132 def __writeFolder(self, node, indent): 133 """ 134 Private method to write a bookmark node. 135 136 @param node reference to the node to be written (BookmarkNode) 137 @param indent size of the indentation (integer) 138 """ 139 folded = "" if node.expanded else " FOLDED" 140 141 added = ( 142 " ADD_DATE=\"{0}\"".format(node.added.toTime_t()) 143 if node.added.isValid() else 144 "" 145 ) 146 147 self.__dev.write(" " * indent) 148 self.__dev.write("<DT><H3{0}{1}>{2}</H3>\n".format( 149 folded, added, Utilities.html_uencode(node.title) 150 )) 151 152 if node.desc: 153 self.__dev.write(" " * indent) 154 self.__dev.write("<DD>{0}\n".format( 155 "".join(node.desc.splitlines()))) 156 157 self.__dev.write(" " * indent) 158 self.__dev.write("<DL><p>\n") 159 160 for child in node.children(): 161 self.__writeItem(child, indent + self.indentSize) 162 163 self.__dev.write(" " * indent) 164 self.__dev.write("</DL><p>\n") 165