src/eric7/WebBrowser/Bookmarks/XbelReader.py

branch
eric7
changeset 9221
bf71ee032bb4
parent 9209
b99e7fd55fd3
child 9473
3f23dbf37dbe
equal deleted inserted replaced
9220:e9e7eca7efee 9221:bf71ee032bb4
6 """ 6 """
7 Module implementing a class to read XBEL bookmark files. 7 Module implementing a class to read XBEL bookmark files.
8 """ 8 """
9 9
10 from PyQt6.QtCore import ( 10 from PyQt6.QtCore import (
11 QXmlStreamReader, QXmlStreamEntityResolver, QIODevice, QFile, 11 QXmlStreamReader,
12 QCoreApplication, QXmlStreamNamespaceDeclaration, QDateTime, Qt 12 QXmlStreamEntityResolver,
13 QIODevice,
14 QFile,
15 QCoreApplication,
16 QXmlStreamNamespaceDeclaration,
17 QDateTime,
18 Qt,
13 ) 19 )
14 20
15 from .BookmarkNode import BookmarkNode 21 from .BookmarkNode import BookmarkNode
16 22
17 23
18 class XmlEntityResolver(QXmlStreamEntityResolver): 24 class XmlEntityResolver(QXmlStreamEntityResolver):
19 """ 25 """
20 Class implementing an XML entity resolver for bookmark files. 26 Class implementing an XML entity resolver for bookmark files.
21 """ 27 """
28
22 def resolveUndeclaredEntity(self, entity): 29 def resolveUndeclaredEntity(self, entity):
23 """ 30 """
24 Public method to resolve undeclared entities. 31 Public method to resolve undeclared entities.
25 32
26 @param entity entity to be resolved (string) 33 @param entity entity to be resolved (string)
27 @return resolved entity (string) 34 @return resolved entity (string)
28 """ 35 """
29 if entity == "nbsp": 36 if entity == "nbsp":
30 return " " 37 return " "
33 40
34 class XbelReader(QXmlStreamReader): 41 class XbelReader(QXmlStreamReader):
35 """ 42 """
36 Class implementing a reader object for XBEL bookmark files. 43 Class implementing a reader object for XBEL bookmark files.
37 """ 44 """
45
38 def __init__(self): 46 def __init__(self):
39 """ 47 """
40 Constructor 48 Constructor
41 """ 49 """
42 super().__init__() 50 super().__init__()
43 51
44 self.__resolver = XmlEntityResolver() 52 self.__resolver = XmlEntityResolver()
45 self.setEntityResolver(self.__resolver) 53 self.setEntityResolver(self.__resolver)
46 54
47 def read(self, fileNameOrDevice): 55 def read(self, fileNameOrDevice):
48 """ 56 """
49 Public method to read an XBEL bookmark file. 57 Public method to read an XBEL bookmark file.
50 58
51 @param fileNameOrDevice name of the file to read (string) 59 @param fileNameOrDevice name of the file to read (string)
52 or reference to the device to read (QIODevice) 60 or reference to the device to read (QIODevice)
53 @return reference to the root node (BookmarkNode) 61 @return reference to the root node (BookmarkNode)
54 """ 62 """
55 if isinstance(fileNameOrDevice, QIODevice): 63 if isinstance(fileNameOrDevice, QIODevice):
58 f = QFile(fileNameOrDevice) 66 f = QFile(fileNameOrDevice)
59 if not f.exists(): 67 if not f.exists():
60 return BookmarkNode(BookmarkNode.Root) 68 return BookmarkNode(BookmarkNode.Root)
61 f.open(QIODevice.OpenModeFlag.ReadOnly) 69 f.open(QIODevice.OpenModeFlag.ReadOnly)
62 self.setDevice(f) 70 self.setDevice(f)
63 71
64 root = BookmarkNode(BookmarkNode.Root) 72 root = BookmarkNode(BookmarkNode.Root)
65 while not self.atEnd(): 73 while not self.atEnd():
66 self.readNext() 74 self.readNext()
67 if self.isStartElement(): 75 if self.isStartElement():
68 version = self.attributes().value("version") 76 version = self.attributes().value("version")
69 if ( 77 if self.name() == "xbel" and (not version or version == "1.0"):
70 self.name() == "xbel" and
71 (not version or version == "1.0")
72 ):
73 self.__readXBEL(root) 78 self.__readXBEL(root)
74 else: 79 else:
75 self.raiseError(QCoreApplication.translate( 80 self.raiseError(
76 "XbelReader", 81 QCoreApplication.translate(
77 "The file is not an XBEL version 1.0 file.")) 82 "XbelReader", "The file is not an XBEL version 1.0 file."
78 83 )
84 )
85
79 return root 86 return root
80 87
81 def __readXBEL(self, node): 88 def __readXBEL(self, node):
82 """ 89 """
83 Private method to read and parse the XBEL file. 90 Private method to read and parse the XBEL file.
84 91
85 @param node reference to the node to attach to (BookmarkNode) 92 @param node reference to the node to attach to (BookmarkNode)
86 """ 93 """
87 if not self.isStartElement() and self.name() != "xbel": 94 if not self.isStartElement() and self.name() != "xbel":
88 return 95 return
89 96
90 while not self.atEnd(): 97 while not self.atEnd():
91 self.readNext() 98 self.readNext()
92 if self.isEndElement(): 99 if self.isEndElement():
93 break 100 break
94 101
95 if self.isStartElement(): 102 if self.isStartElement():
96 if self.name() == "folder": 103 if self.name() == "folder":
97 self.__readFolder(node) 104 self.__readFolder(node)
98 elif self.name() == "bookmark": 105 elif self.name() == "bookmark":
99 self.__readBookmarkNode(node) 106 self.__readBookmarkNode(node)
100 elif self.name() == "separator": 107 elif self.name() == "separator":
101 self.__readSeparator(node) 108 self.__readSeparator(node)
102 else: 109 else:
103 self.__skipUnknownElement() 110 self.__skipUnknownElement()
104 111
105 def __readFolder(self, node): 112 def __readFolder(self, node):
106 """ 113 """
107 Private method to read and parse a folder subtree. 114 Private method to read and parse a folder subtree.
108 115
109 @param node reference to the node to attach to (BookmarkNode) 116 @param node reference to the node to attach to (BookmarkNode)
110 """ 117 """
111 if not self.isStartElement() and self.name() != "folder": 118 if not self.isStartElement() and self.name() != "folder":
112 return 119 return
113 120
114 folder = BookmarkNode(BookmarkNode.Folder, node) 121 folder = BookmarkNode(BookmarkNode.Folder, node)
115 folder.expanded = self.attributes().value("folded") == "no" 122 folder.expanded = self.attributes().value("folded") == "no"
116 folder.added = QDateTime.fromString( 123 folder.added = QDateTime.fromString(
117 self.attributes().value("added"), Qt.DateFormat.ISODate) 124 self.attributes().value("added"), Qt.DateFormat.ISODate
118 125 )
119 while not self.atEnd(): 126
120 self.readNext() 127 while not self.atEnd():
121 if self.isEndElement(): 128 self.readNext()
122 break 129 if self.isEndElement():
123 130 break
131
124 if self.isStartElement(): 132 if self.isStartElement():
125 if self.name() == "title": 133 if self.name() == "title":
126 self.__readTitle(folder) 134 self.__readTitle(folder)
127 elif self.name() == "desc": 135 elif self.name() == "desc":
128 self.__readDescription(folder) 136 self.__readDescription(folder)
134 self.__readSeparator(folder) 142 self.__readSeparator(folder)
135 elif self.name() == "info": 143 elif self.name() == "info":
136 self.__readInfo() 144 self.__readInfo()
137 else: 145 else:
138 self.__skipUnknownElement() 146 self.__skipUnknownElement()
139 147
140 def __readTitle(self, node): 148 def __readTitle(self, node):
141 """ 149 """
142 Private method to read the title element. 150 Private method to read the title element.
143 151
144 @param node reference to the bookmark node title belongs to 152 @param node reference to the bookmark node title belongs to
145 (BookmarkNode) 153 (BookmarkNode)
146 """ 154 """
147 if not self.isStartElement() and self.name() != "title": 155 if not self.isStartElement() and self.name() != "title":
148 return 156 return
149 157
150 node.title = self.readElementText() 158 node.title = self.readElementText()
151 159
152 def __readDescription(self, node): 160 def __readDescription(self, node):
153 """ 161 """
154 Private method to read the desc element. 162 Private method to read the desc element.
155 163
156 @param node reference to the bookmark node desc belongs to 164 @param node reference to the bookmark node desc belongs to
157 (BookmarkNode) 165 (BookmarkNode)
158 """ 166 """
159 if not self.isStartElement() and self.name() != "desc": 167 if not self.isStartElement() and self.name() != "desc":
160 return 168 return
161 169
162 node.desc = self.readElementText() 170 node.desc = self.readElementText()
163 171
164 def __readSeparator(self, node): 172 def __readSeparator(self, node):
165 """ 173 """
166 Private method to read a separator element. 174 Private method to read a separator element.
167 175
168 @param node reference to the bookmark node the separator belongs to 176 @param node reference to the bookmark node the separator belongs to
169 (BookmarkNode) 177 (BookmarkNode)
170 """ 178 """
171 sep = BookmarkNode(BookmarkNode.Separator, node) 179 sep = BookmarkNode(BookmarkNode.Separator, node)
172 sep.added = QDateTime.fromString( 180 sep.added = QDateTime.fromString(
173 self.attributes().value("added"), Qt.DateFormat.ISODate) 181 self.attributes().value("added"), Qt.DateFormat.ISODate
174 182 )
183
175 # empty elements have a start and end element 184 # empty elements have a start and end element
176 while not self.atEnd(): 185 while not self.atEnd():
177 self.readNext() 186 self.readNext()
178 if self.isEndElement(): 187 if self.isEndElement():
179 break 188 break
180 189
181 if self.isStartElement(): 190 if self.isStartElement():
182 if self.name() == "info": 191 if self.name() == "info":
183 self.__readInfo() 192 self.__readInfo()
184 else: 193 else:
185 self.__skipUnknownElement() 194 self.__skipUnknownElement()
186 195
187 def __readBookmarkNode(self, node): 196 def __readBookmarkNode(self, node):
188 """ 197 """
189 Private method to read and parse a bookmark subtree. 198 Private method to read and parse a bookmark subtree.
190 199
191 @param node reference to the node to attach to (BookmarkNode) 200 @param node reference to the node to attach to (BookmarkNode)
192 """ 201 """
193 if not self.isStartElement() and self.name() != "bookmark": 202 if not self.isStartElement() and self.name() != "bookmark":
194 return 203 return
195 204
196 bookmark = BookmarkNode(BookmarkNode.Bookmark, node) 205 bookmark = BookmarkNode(BookmarkNode.Bookmark, node)
197 bookmark.url = self.attributes().value("href") 206 bookmark.url = self.attributes().value("href")
198 bookmark.added = QDateTime.fromString( 207 bookmark.added = QDateTime.fromString(
199 self.attributes().value("added"), Qt.DateFormat.ISODate) 208 self.attributes().value("added"), Qt.DateFormat.ISODate
209 )
200 bookmark.modified = QDateTime.fromString( 210 bookmark.modified = QDateTime.fromString(
201 self.attributes().value("modified"), Qt.DateFormat.ISODate) 211 self.attributes().value("modified"), Qt.DateFormat.ISODate
212 )
202 bookmark.visited = QDateTime.fromString( 213 bookmark.visited = QDateTime.fromString(
203 self.attributes().value("visited"), Qt.DateFormat.ISODate) 214 self.attributes().value("visited"), Qt.DateFormat.ISODate
215 )
204 try: 216 try:
205 bookmark.visitCount = int(self.attributes().value("visitCount")) 217 bookmark.visitCount = int(self.attributes().value("visitCount"))
206 except ValueError: 218 except ValueError:
207 bookmark.visitCount = 0 219 bookmark.visitCount = 0
208 220
209 while not self.atEnd(): 221 while not self.atEnd():
210 self.readNext() 222 self.readNext()
211 if self.isEndElement(): 223 if self.isEndElement():
212 break 224 break
213 225
214 if self.isStartElement(): 226 if self.isStartElement():
215 if self.name() == "title": 227 if self.name() == "title":
216 self.__readTitle(bookmark) 228 self.__readTitle(bookmark)
217 elif self.name() == "desc": 229 elif self.name() == "desc":
218 self.__readDescription(bookmark) 230 self.__readDescription(bookmark)
219 elif self.name() == "info": 231 elif self.name() == "info":
220 self.__readInfo() 232 self.__readInfo()
221 else: 233 else:
222 self.__skipUnknownElement() 234 self.__skipUnknownElement()
223 235
224 if not bookmark.title: 236 if not bookmark.title:
225 bookmark.title = QCoreApplication.translate( 237 bookmark.title = QCoreApplication.translate("XbelReader", "Unknown title")
226 "XbelReader", "Unknown title") 238
227
228 def __readInfo(self): 239 def __readInfo(self):
229 """ 240 """
230 Private method to read and parse an info subtree. 241 Private method to read and parse an info subtree.
231 """ 242 """
232 self.addExtraNamespaceDeclaration(QXmlStreamNamespaceDeclaration( 243 self.addExtraNamespaceDeclaration(
233 "bookmark", "http://www.python.org")) 244 QXmlStreamNamespaceDeclaration("bookmark", "http://www.python.org")
245 )
234 self.skipCurrentElement() 246 self.skipCurrentElement()
235 247
236 def __skipUnknownElement(self): 248 def __skipUnknownElement(self):
237 """ 249 """
238 Private method to skip over all unknown elements. 250 Private method to skip over all unknown elements.
239 """ 251 """
240 self.skipCurrentElement() 252 self.skipCurrentElement()

eric ide

mercurial