12 import hashlib |
12 import hashlib |
13 import base64 |
13 import base64 |
14 |
14 |
15 from PyQt6.QtCore import ( |
15 from PyQt6.QtCore import ( |
16 pyqtSignal, Qt, QObject, QByteArray, QDateTime, QUrl, QUrlQuery, |
16 pyqtSignal, Qt, QObject, QByteArray, QDateTime, QUrl, QUrlQuery, |
17 QCryptographicHash, QFile, QIODevice, QTextStream, QDate, QTime |
17 QCryptographicHash, QDate, QTime |
18 ) |
18 ) |
19 from PyQt6.QtNetwork import QNetworkReply, QNetworkRequest |
19 from PyQt6.QtNetwork import QNetworkReply, QNetworkRequest |
20 |
20 |
21 from EricWidgets import EricMessageBox |
21 from EricWidgets import EricMessageBox |
22 |
22 |
276 def __loadRules(self): |
276 def __loadRules(self): |
277 """ |
277 """ |
278 Private method to load the rules of the subscription. |
278 Private method to load the rules of the subscription. |
279 """ |
279 """ |
280 fileName = self.rulesFileName() |
280 fileName = self.rulesFileName() |
281 f = QFile(fileName) |
281 if os.path.exists(fileName): |
282 if f.exists(): |
282 try: |
283 if not f.open(QIODevice.OpenModeFlag.ReadOnly): |
283 with open(fileName, "r", encoding="utf-8") as f: |
|
284 header = f.readline().strip() |
|
285 if not header.startswith("[Adblock"): |
|
286 EricMessageBox.warning( |
|
287 None, |
|
288 self.tr("Load subscription rules"), |
|
289 self.tr("""AdBlock file '{0}' does not start""" |
|
290 """ with [Adblock.""") |
|
291 .format(fileName)) |
|
292 f.close() |
|
293 os.unlink(fileName) |
|
294 self.__lastUpdate = QDateTime() |
|
295 else: |
|
296 from .AdBlockRule import AdBlockRule |
|
297 |
|
298 self.__updatePeriod = 0 |
|
299 self.__remoteModified = QDateTime() |
|
300 self.__rules = [] |
|
301 self.__rules.append(AdBlockRule(header, self)) |
|
302 for line in f.readlines(): |
|
303 line = line.strip() |
|
304 if not line: |
|
305 continue |
|
306 self.__rules.append(AdBlockRule(line, self)) |
|
307 expires = self.__expiresRe.search(line) |
|
308 if expires: |
|
309 period, kind = expires.groups() |
|
310 if kind: |
|
311 # hours |
|
312 self.__updatePeriod = int(period) |
|
313 else: |
|
314 # days |
|
315 self.__updatePeriod = int(period) * 24 |
|
316 remoteModified = self.__remoteModifiedRe.search( |
|
317 line) |
|
318 if remoteModified: |
|
319 day, month, year, time, hour, minute = ( |
|
320 remoteModified.groups() |
|
321 ) |
|
322 self.__remoteModified.setDate( |
|
323 QDate(int(year), |
|
324 self.__monthNameToNumber[month], |
|
325 int(day)) |
|
326 ) |
|
327 if time: |
|
328 self.__remoteModified.setTime( |
|
329 QTime(int(hour), int(minute))) |
|
330 else: |
|
331 # no time given, set it to 23:59 |
|
332 self.__remoteModified.setTime( |
|
333 QTime(23, 59)) |
|
334 self.changed.emit() |
|
335 except OSError as err: |
284 EricMessageBox.warning( |
336 EricMessageBox.warning( |
285 None, |
337 None, |
286 self.tr("Load subscription rules"), |
338 self.tr("Load subscription rules"), |
287 self.tr( |
339 self.tr( |
288 """Unable to open AdBlock file '{0}' for reading.""") |
340 """Unable to read AdBlock file '{0}'\nReason: {1}.""") |
289 .format(fileName)) |
341 .format(fileName, str(err)) |
290 else: |
342 ) |
291 textStream = QTextStream(f) |
343 |
292 header = textStream.readLine(1024) |
|
293 if not header.startswith("[Adblock"): |
|
294 EricMessageBox.warning( |
|
295 None, |
|
296 self.tr("Load subscription rules"), |
|
297 self.tr("""AdBlock file '{0}' does not start""" |
|
298 """ with [Adblock.""") |
|
299 .format(fileName)) |
|
300 f.close() |
|
301 f.remove() |
|
302 self.__lastUpdate = QDateTime() |
|
303 else: |
|
304 from .AdBlockRule import AdBlockRule |
|
305 |
|
306 self.__updatePeriod = 0 |
|
307 self.__remoteModified = QDateTime() |
|
308 self.__rules = [] |
|
309 self.__rules.append(AdBlockRule(header, self)) |
|
310 while not textStream.atEnd(): |
|
311 line = textStream.readLine() |
|
312 self.__rules.append(AdBlockRule(line, self)) |
|
313 expires = self.__expiresRe.search(line) |
|
314 if expires: |
|
315 period, kind = expires.groups() |
|
316 if kind: |
|
317 # hours |
|
318 self.__updatePeriod = int(period) |
|
319 else: |
|
320 # days |
|
321 self.__updatePeriod = int(period) * 24 |
|
322 remoteModified = self.__remoteModifiedRe.search(line) |
|
323 if remoteModified: |
|
324 day, month, year, time, hour, minute = ( |
|
325 remoteModified.groups() |
|
326 ) |
|
327 self.__remoteModified.setDate( |
|
328 QDate(int(year), |
|
329 self.__monthNameToNumber[month], |
|
330 int(day)) |
|
331 ) |
|
332 if time: |
|
333 self.__remoteModified.setTime( |
|
334 QTime(int(hour), int(minute))) |
|
335 else: |
|
336 # no time given, set it to 23:59 |
|
337 self.__remoteModified.setTime(QTime(23, 59)) |
|
338 self.changed.emit() |
|
339 elif not fileName.endswith("_custom"): |
344 elif not fileName.endswith("_custom"): |
340 self.__lastUpdate = QDateTime() |
345 self.__lastUpdate = QDateTime() |
341 |
346 |
342 self.checkForUpdate() |
347 self.checkForUpdate() |
343 |
348 |
406 else: |
411 else: |
407 # reset after first download attempt |
412 # reset after first download attempt |
408 self.__defaultSubscription = False |
413 self.__defaultSubscription = False |
409 return |
414 return |
410 |
415 |
411 if response.isEmpty(): |
416 if not response: |
412 EricMessageBox.warning( |
417 EricMessageBox.warning( |
413 None, |
418 None, |
414 self.tr("Downloading subscription rules"), |
419 self.tr("Downloading subscription rules"), |
415 self.tr("""Got empty subscription rules.""")) |
420 self.tr("""Got empty subscription rules.""")) |
416 return |
421 return |
417 |
422 |
418 fileName = self.rulesFileName() |
423 fileName = self.rulesFileName() |
419 QFile.remove(fileName) |
424 try: |
420 f = QFile(fileName) |
425 with open(fileName, "wb") as f: |
421 if not f.open(QIODevice.OpenModeFlag.ReadWrite): |
426 from WebBrowser.WebBrowserWindow import WebBrowserWindow |
|
427 if ( |
|
428 WebBrowserWindow.adBlockManager().useLimitedEasyList() and |
|
429 self.url().toString().startswith( |
|
430 WebBrowserWindow.adBlockManager() |
|
431 .getDefaultSubscriptionUrl()) |
|
432 ): |
|
433 limited = True |
|
434 # ignore Third-party advertisers rules for performance |
|
435 # whitelist rules at the end will be used |
|
436 index = response.find( |
|
437 b"!---------------------------" |
|
438 b"Third-party advertisers" |
|
439 b"---------------------------!") |
|
440 part1 = response[:index] |
|
441 index = response.find( |
|
442 b"!-----------------------" |
|
443 b"Whitelists to fix broken sites" |
|
444 b"------------------------!") |
|
445 part2 = response[index:] |
|
446 f.write(part1) |
|
447 f.write(part2) |
|
448 else: |
|
449 limited = False |
|
450 f.write(response) |
|
451 f.close() |
|
452 self.__lastUpdate = QDateTime.currentDateTime() |
|
453 |
|
454 if limited or self.__validateCheckSum(fileName): |
|
455 self.__loadRules() |
|
456 else: |
|
457 os.unlink(fileName) |
|
458 except OSError: |
422 EricMessageBox.warning( |
459 EricMessageBox.warning( |
423 None, |
460 None, |
424 self.tr("Downloading subscription rules"), |
461 self.tr("Downloading subscription rules"), |
425 self.tr( |
462 self.tr("""Unable to write to AdBlock file '{0}'.""") |
426 """Unable to open AdBlock file '{0}' for writing.""") |
|
427 .file(fileName)) |
463 .file(fileName)) |
428 return |
|
429 |
|
430 from WebBrowser.WebBrowserWindow import WebBrowserWindow |
|
431 if ( |
|
432 WebBrowserWindow.adBlockManager().useLimitedEasyList() and |
|
433 self.url().toString().startswith( |
|
434 WebBrowserWindow.adBlockManager().getDefaultSubscriptionUrl()) |
|
435 ): |
|
436 limited = True |
|
437 # ignore Third-party advertisers rules for performance |
|
438 # whitelist rules at the end will be used |
|
439 index = response.indexOf( |
|
440 b"!---------------------------" |
|
441 b"Third-party advertisers" |
|
442 b"---------------------------!") |
|
443 part1 = response.left(index) |
|
444 index = response.indexOf( |
|
445 b"!-----------------------" |
|
446 b"Whitelists to fix broken sites" |
|
447 b"------------------------!") |
|
448 part2 = response.mid(index) |
|
449 f.write(part1) |
|
450 f.write(part2) |
|
451 else: |
|
452 limited = False |
|
453 f.write(response) |
|
454 f.close() |
|
455 self.__lastUpdate = QDateTime.currentDateTime() |
|
456 if limited or self.__validateCheckSum(fileName): |
|
457 self.__loadRules() |
|
458 else: |
|
459 QFile.remove(fileName) |
|
460 self.__downloading = None |
464 self.__downloading = None |
461 reply.deleteLater() |
465 reply.deleteLater() |
462 |
466 |
463 def __validateCheckSum(self, fileName): |
467 def __validateCheckSum(self, fileName): |
464 """ |
468 """ |
518 """ |
522 """ |
519 fileName = self.rulesFileName() |
523 fileName = self.rulesFileName() |
520 if not fileName: |
524 if not fileName: |
521 return |
525 return |
522 |
526 |
523 f = QFile(fileName) |
527 try: |
524 if not f.open(QIODevice.OpenModeFlag.ReadWrite | |
528 with open(fileName, "w", encoding="utf-8") as f: |
525 QIODevice.OpenModeFlag.Truncate): |
529 if not self.__rules or not self.__rules[0].isHeader(): |
|
530 f.write("[Adblock Plus 2.0]\n") |
|
531 for rule in self.__rules: |
|
532 f.write(rule.filter() + "\n") |
|
533 except OSError: |
526 EricMessageBox.warning( |
534 EricMessageBox.warning( |
527 None, |
535 None, |
528 self.tr("Saving subscription rules"), |
536 self.tr("Saving subscription rules"), |
529 self.tr( |
537 self.tr("""Unable to write to AdBlock file '{0}'.""") |
530 """Unable to open AdBlock file '{0}' for writing.""") |
|
531 .format(fileName)) |
538 .format(fileName)) |
532 return |
|
533 |
|
534 textStream = QTextStream(f) |
|
535 if not self.__rules or not self.__rules[0].isHeader(): |
|
536 textStream << "[Adblock Plus 1.1.1]\n" |
|
537 for rule in self.__rules: |
|
538 textStream << rule.filter() << "\n" |
|
539 |
539 |
540 def rule(self, offset): |
540 def rule(self, offset): |
541 """ |
541 """ |
542 Public method to get a specific rule. |
542 Public method to get a specific rule. |
543 |
543 |