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