eric7/WebBrowser/AdBlock/AdBlockSubscription.py

branch
eric7
changeset 9162
8b75b1668583
parent 8881
54e42bc2437a
child 9165
17617e5d5473
equal deleted inserted replaced
9161:90939b08da20 9162:8b75b1668583
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
387 Private slot to deal with the downloaded rules. 392 Private slot to deal with the downloaded rules.
388 393
389 @param reply reference to the network reply 394 @param reply reference to the network reply
390 @type QNetworkReply 395 @type QNetworkReply
391 """ 396 """
392 response = reply.readAll() 397 response = bytes(reply.readAll())
393 reply.close() 398 reply.close()
394 self.__downloading = None 399 self.__downloading = None
395 400
396 if reply.error() != QNetworkReply.NetworkError.NoError: 401 if reply.error() != QNetworkReply.NetworkError.NoError:
397 if not self.__defaultSubscription: 402 if not self.__defaultSubscription:
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

eric ide

mercurial