Helpviewer/AdBlock/AdBlockSubscription.py

branch
Py2 comp.
changeset 3057
10516539f238
parent 2525
8b507a9a2d40
parent 3000
971d84f7a6d6
child 3058
0a02c433f52d
equal deleted inserted replaced
3056:9986ec0e559a 3057:10516539f238
12 import os 12 import os
13 import re 13 import re
14 import hashlib 14 import hashlib
15 import base64 15 import base64
16 16
17 from PyQt4.QtCore import pyqtSignal, Qt, QObject, QByteArray, QDateTime, QUrl, \ 17 from PyQt4.QtCore import pyqtSignal, Qt, QObject, QByteArray, QDateTime, \
18 QCryptographicHash, QFile, QIODevice, QTextStream, QDate, QTime 18 QUrl, QCryptographicHash, QFile, QIODevice, QTextStream, QDate, QTime
19 from PyQt4.QtNetwork import QNetworkReply 19 from PyQt4.QtNetwork import QNetworkReply
20 20
21 from E5Gui import E5MessageBox 21 from E5Gui import E5MessageBox
22 22
23 import Utilities 23 import Utilities
69 self.__domainRestrictedCssRules = [] 69 self.__domainRestrictedCssRules = []
70 self.__elementHidingRules = "" 70 self.__elementHidingRules = ""
71 self.__documentRules = [] 71 self.__documentRules = []
72 self.__elemhideRules = [] 72 self.__elemhideRules = []
73 73
74 self.__checksumRe = re.compile(r"""^\s*!\s*checksum[\s\-:]+([\w\+\/=]+).*\n""", 74 self.__checksumRe = re.compile(
75 r"""^\s*!\s*checksum[\s\-:]+([\w\+\/=]+).*\n""",
75 re.IGNORECASE | re.MULTILINE) 76 re.IGNORECASE | re.MULTILINE)
76 self.__expiresRe = re.compile( 77 self.__expiresRe = re.compile(
77 r"""(?:expires:|expires after)\s*(\d+)\s*(hour|h)?""", 78 r"""(?:expires:|expires after)\s*(\d+)\s*(hour|h)?""",
78 re.IGNORECASE) 79 re.IGNORECASE)
79 self.__remoteModifiedRe = re.compile( 80 self.__remoteModifiedRe = re.compile(
111 if url.path() != "subscribe": 112 if url.path() != "subscribe":
112 return 113 return
113 114
114 self.__title = \ 115 self.__title = \
115 QUrl.fromPercentEncoding(url.encodedQueryItemValue("title")) 116 QUrl.fromPercentEncoding(url.encodedQueryItemValue("title"))
116 self.__enabled = \ 117 self.__enabled = QUrl.fromPercentEncoding(
117 QUrl.fromPercentEncoding(url.encodedQueryItemValue("enabled")) != "false" 118 url.encodedQueryItemValue("enabled")) != "false"
118 self.__location = \ 119 self.__location = QByteArray(QUrl.fromPercentEncoding(
119 QByteArray(QUrl.fromPercentEncoding(url.encodedQueryItemValue("location"))) 120 url.encodedQueryItemValue("location")))
120 121
121 # Check for required subscription 122 # Check for required subscription
122 self.__requiresLocation = \ 123 self.__requiresLocation = QUrl.fromPercentEncoding(
123 QUrl.fromPercentEncoding(url.encodedQueryItemValue("requiresLocation")) 124 url.encodedQueryItemValue("requiresLocation"))
124 self.__requiresTitle = \ 125 self.__requiresTitle = QUrl.fromPercentEncoding(
125 QUrl.fromPercentEncoding(url.encodedQueryItemValue("requiresTitle")) 126 url.encodedQueryItemValue("requiresTitle"))
126 if self.__requiresLocation and self.__requiresTitle: 127 if self.__requiresLocation and self.__requiresTitle:
127 import Helpviewer.HelpWindow 128 import Helpviewer.HelpWindow
128 Helpviewer.HelpWindow.HelpWindow.adBlockManager().loadRequiredSubscription( 129 Helpviewer.HelpWindow.HelpWindow.adBlockManager()\
129 self.__requiresLocation, self.__requiresTitle) 130 .loadRequiredSubscription(self.__requiresLocation,
131 self.__requiresTitle)
130 132
131 lastUpdateByteArray = url.encodedQueryItemValue("lastUpdate") 133 lastUpdateByteArray = url.encodedQueryItemValue("lastUpdate")
132 lastUpdateString = QUrl.fromPercentEncoding(lastUpdateByteArray) 134 lastUpdateString = QUrl.fromPercentEncoding(lastUpdateByteArray)
133 self.__lastUpdate = QDateTime.fromString(lastUpdateString, Qt.ISODate) 135 self.__lastUpdate = QDateTime.fromString(lastUpdateString, Qt.ISODate)
134 136
245 return self.location().toLocalFile() 247 return self.location().toLocalFile()
246 248
247 if self.__location.isEmpty(): 249 if self.__location.isEmpty():
248 return "" 250 return ""
249 251
250 sha1 = bytes( 252 sha1 = bytes(QCryptographicHash.hash(
251 QCryptographicHash.hash(self.__location, QCryptographicHash.Sha1).toHex())\ 253 self.__location, QCryptographicHash.Sha1).toHex()).decode()
252 .decode() 254 dataDir = os.path.join(
253 dataDir = os.path.join(Utilities.getConfigDir(), "browser", "subscriptions") 255 Utilities.getConfigDir(), "browser", "subscriptions")
254 if not os.path.exists(dataDir): 256 if not os.path.exists(dataDir):
255 os.makedirs(dataDir) 257 os.makedirs(dataDir)
256 fileName = os.path.join(dataDir, "adblock_subscription_{0}".format(sha1)) 258 fileName = os.path.join(
259 dataDir, "adblock_subscription_{0}".format(sha1))
257 return fileName 260 return fileName
258 261
259 def __loadRules(self): 262 def __loadRules(self):
260 """ 263 """
261 Private method to load the rules of the subscription. 264 Private method to load the rules of the subscription.
264 f = QFile(fileName) 267 f = QFile(fileName)
265 if f.exists(): 268 if f.exists():
266 if not f.open(QIODevice.ReadOnly): 269 if not f.open(QIODevice.ReadOnly):
267 E5MessageBox.warning(None, 270 E5MessageBox.warning(None,
268 self.trUtf8("Load subscription rules"), 271 self.trUtf8("Load subscription rules"),
269 self.trUtf8("""Unable to open adblock file '{0}' for reading.""")\ 272 self.trUtf8(
273 """Unable to open adblock file '{0}' for reading.""")\
270 .format(fileName)) 274 .format(fileName))
271 else: 275 else:
272 textStream = QTextStream(f) 276 textStream = QTextStream(f)
273 header = textStream.readLine(1024) 277 header = textStream.readLine(1024)
274 if not header.startswith("[Adblock"): 278 if not header.startswith("[Adblock"):
299 else: 303 else:
300 # days 304 # days
301 self.__updatePeriod = int(period) * 24 305 self.__updatePeriod = int(period) * 24
302 remoteModified = self.__remoteModifiedRe.search(line) 306 remoteModified = self.__remoteModifiedRe.search(line)
303 if remoteModified: 307 if remoteModified:
304 day, month, year, time, hour, minute = remoteModified.groups() 308 day, month, year, time, hour, minute = \
309 remoteModified.groups()
305 self.__remoteModified.setDate( 310 self.__remoteModified.setDate(
306 QDate(int(year), self.__monthNameToNumber[month], 311 QDate(int(year),
307 int(day))) 312 self.__monthNameToNumber[month],
313 int(day))
314 )
308 if time: 315 if time:
309 self.__remoteModified.setTime( 316 self.__remoteModified.setTime(
310 QTime(int(hour), int(minute))) 317 QTime(int(hour), int(minute)))
311 self.__populateCache() 318 self.__populateCache()
312 self.changed.emit() 319 self.changed.emit()
365 if reply.error() != QNetworkReply.NoError: 372 if reply.error() != QNetworkReply.NoError:
366 if not self.__defaultSubscription: 373 if not self.__defaultSubscription:
367 # don't show error if we try to load the default 374 # don't show error if we try to load the default
368 E5MessageBox.warning(None, 375 E5MessageBox.warning(None,
369 self.trUtf8("Downloading subscription rules"), 376 self.trUtf8("Downloading subscription rules"),
370 self.trUtf8("""<p>Subscription rules could not be downloaded.</p>""" 377 self.trUtf8(
371 """<p>Error: {0}</p>""").format(reply.errorString())) 378 """<p>Subscription rules could not be"""
379 """ downloaded.</p><p>Error: {0}</p>""")
380 .format(reply.errorString()))
372 else: 381 else:
373 # reset after first download attempt 382 # reset after first download attempt
374 self.__defaultSubscription = False 383 self.__defaultSubscription = False
375 return 384 return
376 385
384 QFile.remove(fileName) 393 QFile.remove(fileName)
385 f = QFile(fileName) 394 f = QFile(fileName)
386 if not f.open(QIODevice.ReadWrite): 395 if not f.open(QIODevice.ReadWrite):
387 E5MessageBox.warning(None, 396 E5MessageBox.warning(None,
388 self.trUtf8("Downloading subscription rules"), 397 self.trUtf8("Downloading subscription rules"),
389 self.trUtf8("""Unable to open adblock file '{0}' for writing.""")\ 398 self.trUtf8(
399 """Unable to open adblock file '{0}' for writing.""")\
390 .file(fileName)) 400 .file(fileName))
391 return 401 return
392 f.write(response) 402 f.write(response)
393 f.close() 403 f.close()
394 self.__lastUpdate = QDateTime.currentDateTime() 404 self.__lastUpdate = QDateTime.currentDateTime()
427 data = re.sub(self.__checksumRe, "", data) # remove checksum line 437 data = re.sub(self.__checksumRe, "", data) # remove checksum line
428 438
429 # calculate checksum 439 # calculate checksum
430 md5 = hashlib.md5() 440 md5 = hashlib.md5()
431 md5.update(data.encode("utf-8")) 441 md5.update(data.encode("utf-8"))
432 calculatedChecksum = base64.b64encode(md5.digest()).decode().rstrip("=") 442 calculatedChecksum = base64.b64encode(md5.digest()).decode()\
443 .rstrip("=")
433 if calculatedChecksum == expectedChecksum: 444 if calculatedChecksum == expectedChecksum:
434 return True 445 return True
435 else: 446 else:
436 res = E5MessageBox.yesNo(None, 447 res = E5MessageBox.yesNo(None,
437 self.trUtf8("Downloading subscription rules"), 448 self.trUtf8("Downloading subscription rules"),
438 self.trUtf8("""<p>AdBlock subscription <b>{0}</b> has a wrong""" 449 self.trUtf8(
439 """ checksum.<br/>""" 450 """<p>AdBlock subscription <b>{0}</b> has a wrong"""
440 """Found: {1}<br/>""" 451 """ checksum.<br/>"""
441 """Calculated: {2}<br/>""" 452 """Found: {1}<br/>"""
442 """Use it anyway?</p>""")\ 453 """Calculated: {2}<br/>"""
443 .format(self.__title, expectedChecksum, calculatedChecksum)) 454 """Use it anyway?</p>""")\
455 .format(self.__title, expectedChecksum,
456 calculatedChecksum))
444 return res 457 return res
445 458
446 def saveRules(self): 459 def saveRules(self):
447 """ 460 """
448 Public method to save the subscription rules. 461 Public method to save the subscription rules.
453 466
454 f = QFile(fileName) 467 f = QFile(fileName)
455 if not f.open(QIODevice.ReadWrite | QIODevice.Truncate): 468 if not f.open(QIODevice.ReadWrite | QIODevice.Truncate):
456 E5MessageBox.warning(None, 469 E5MessageBox.warning(None,
457 self.trUtf8("Saving subscription rules"), 470 self.trUtf8("Saving subscription rules"),
458 self.trUtf8("""Unable to open adblock file '{0}' for writing.""")\ 471 self.trUtf8(
472 """Unable to open adblock file '{0}' for writing.""")\
459 .format(fileName)) 473 .format(fileName))
460 return 474 return
461 475
462 textStream = QTextStream(f) 476 textStream = QTextStream(f)
463 if not self.__rules or not self.__rules[0].isHeader(): 477 if not self.__rules or not self.__rules[0].isHeader():
497 511
498 return False 512 return False
499 513
500 def elemHideDisabledForUrl(self, url): 514 def elemHideDisabledForUrl(self, url):
501 """ 515 """
502 Public method to check, if element hiding is disabled for the given URL. 516 Public method to check, if element hiding is disabled for the given
517 URL.
503 518
504 @param url URL to check (QUrl) 519 @param url URL to check (QUrl)
505 @return flag indicating disabled state (boolean) 520 @return flag indicating disabled state (boolean)
506 """ 521 """
507 if self.adBlockDisabledForUrl(url): 522 if self.adBlockDisabledForUrl(url):
658 rule = self.__rules[offset] 673 rule = self.__rules[offset]
659 rule.setEnabled(enabled) 674 rule.setEnabled(enabled)
660 if rule.isCSSRule(): 675 if rule.isCSSRule():
661 import Helpviewer.HelpWindow 676 import Helpviewer.HelpWindow
662 self.__populateCache() 677 self.__populateCache()
663 Helpviewer.HelpWindow.HelpWindow.mainWindow().reloadUserStyleSheet() 678 Helpviewer.HelpWindow.HelpWindow.mainWindow()\
679 .reloadUserStyleSheet()
664 680
665 return rule 681 return rule

eric ide

mercurial