From 1e99a3de416a8498d834ca64bbfb7062ae48c5e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Jastrz=C4=99bski?= Date: Tue, 21 Apr 2020 18:54:59 +0200 Subject: [PATCH] CloudFlare handling changes (close #51) --- CB/Core.py | 31 ++++++++++++++++++++++++++----- CB/CurseForge.py | 5 ++--- CB/WoWInterface.py | 8 +++----- CB/__init__.py | 2 +- 4 files changed, 32 insertions(+), 14 deletions(-) diff --git a/CB/Core.py b/CB/Core.py index b2b1402..e3c6735 100644 --- a/CB/Core.py +++ b/CB/Core.py @@ -35,7 +35,23 @@ def __init__(self): self.cfDirs = None self.cfCache = {} self.wowiCache = {} - self.scraper = cloudscraper.create_scraper() + self.scraper = cloudscraper.create_scraper( + browser={ + 'custom': 'Mozilla/5.0 (Linux; U; Android 6.0.1; zh-cn; OPPO R9s Plus Build/MMB29M) AppleWebKit/537.36 ' + '(KHTML, like Gecko) Version/4.0 Chrome/53.0.2785.134 Mobile Safari/537.36 OppoBrowser/4.4.9' + }, + cipherSuite=[ + 'ECDHE-ECDSA-AES128-GCM-SHA256', + 'ECDHE-RSA-AES128-GCM-SHA256', + 'ECDHE-RSA-AES128-SHA', + 'AES128-GCM-SHA256', + 'AES128-SHA', + 'ECDHE-RSA-AES256-SHA384', + 'AES256-SHA', + 'DES-CBC3-SHA', + 'ECDHE-RSA-AES256-GCM-SHA384' + ] + ) def init_config(self): if os.path.isfile('CurseBreaker.json'): @@ -47,6 +63,7 @@ def init_config(self): self.config = {'Addons': [], 'IgnoreClientVersion': {}, 'Backup': {'Enabled': True, 'Number': 7}, + 'CFCacheCloudFlare': {}, 'Version': __version__, 'WAUsername': '', 'WAAccountName': '', @@ -92,7 +109,8 @@ def update_config(self): ['2.2.0', 'WAAPIKey', ''], ['2.2.0', 'WACompanionVersion', 0], ['2.8.0', 'IgnoreClientVersion', {}], - ['3.0.1', 'CFCacheTimestamp', 0]]: + ['3.0.1', 'CFCacheTimestamp', 0], + ['3.1.10', 'CFCacheCloudFlare', {}]]: if add[1] not in self.config.keys(): self.config[add[1]] = add[2] for delete in [['1.3.0', 'URLCache'], @@ -126,7 +144,7 @@ def parse_url(self, url): if url.startswith('https://www.curseforge.com/wow/addons/'): return CurseForgeAddon(self.parse_cf_id(url), self.cfCache, 'wow' if url in self.config['IgnoreClientVersion'].keys() else self.clientType, - self.check_if_dev(url), self.scraper) + self.check_if_dev(url)) elif url.startswith('https://www.wowinterface.com/downloads/'): return WoWInterfaceAddon(url, self.wowiCache, self.scraper) elif url.startswith('https://www.tukui.org/addons.php?id='): @@ -335,8 +353,9 @@ def parse_cf_id(self, url): self.save_config() with open(self.cachePath, 'rb') as f: self.cfIDs = pickle.load(f) + self.cfIDs = {**self.config['CFCacheCloudFlare'], **self.cfIDs} except Exception: - self.cfIDs = [] + self.cfIDs = {} slug = url.split('/')[-1] if slug in self.cfIDs: project = self.cfIDs[slug] @@ -346,7 +365,9 @@ def parse_cf_id(self, url): raise RuntimeError(slug) xml = parseString(payload.text) project = xml.childNodes[0].getElementsByTagName('project')[0].getAttribute('id') - self.cfIDs[slug] = project + self.config['CFCacheCloudFlare'][slug] = project + self.cfIDs = {**self.config['CFCacheCloudFlare'], **self.cfIDs} + self.save_config() return project @retry(custom_error='Failed to parse the XML file.') diff --git a/CB/CurseForge.py b/CB/CurseForge.py index 0fc0c98..873bf30 100644 --- a/CB/CurseForge.py +++ b/CB/CurseForge.py @@ -8,7 +8,7 @@ class CurseForgeAddon: @retry() - def __init__(self, project, checkcache, clienttype, allowdev, scraper): + def __init__(self, project, checkcache, clienttype, allowdev): if project in checkcache: self.payload = checkcache[project] else: @@ -23,7 +23,6 @@ def __init__(self, project, checkcache, clienttype, allowdev, scraper): raise RuntimeError(f'{self.name}.\nThe project doesn\'t have any releases.') self.clientType = clienttype self.allowDev = allowdev - self.scraper = scraper self.downloadUrl = None self.currentVersion = None self.archive = None @@ -46,7 +45,7 @@ def get_current_version(self): @retry() def get_addon(self): - self.archive = zipfile.ZipFile(io.BytesIO(self.scraper.get(self.downloadUrl).content)) + self.archive = zipfile.ZipFile(io.BytesIO(requests.get(self.downloadUrl, headers=HEADERS).content)) for file in self.archive.namelist(): if '/' not in os.path.dirname(file): self.directories.append(os.path.dirname(file)) diff --git a/CB/WoWInterface.py b/CB/WoWInterface.py index f2ad6a3..e93ff43 100644 --- a/CB/WoWInterface.py +++ b/CB/WoWInterface.py @@ -2,19 +2,18 @@ import io import re import zipfile -import requests -from . import retry, HEADERS +from . import retry class WoWInterfaceAddon: @retry() def __init__(self, url, checkcache, scraper): project = re.findall(r'\d+', url)[0] + self.scraper = scraper if project in checkcache: self.payload = checkcache[project] else: - self.payload = requests.get(f'https://api.mmoui.com/v4/game/WOW/filedetails/{project}.json', - headers=HEADERS).json() + self.payload = self.scraper.get(f'https://api.mmoui.com/v4/game/WOW/filedetails/{project}.json').json() if 'ERROR' in self.payload: raise RuntimeError(url) else: @@ -24,7 +23,6 @@ def __init__(self, url, checkcache, scraper): self.currentVersion = self.payload['version'] self.archive = None self.directories = [] - self.scraper = scraper @retry() def get_addon(self): diff --git a/CB/__init__.py b/CB/__init__.py index 477ecf7..607a823 100644 --- a/CB/__init__.py +++ b/CB/__init__.py @@ -1,7 +1,7 @@ import string import random -__version__ = '3.1.9' +__version__ = '3.1.10' __license__ = 'GPLv3' __copyright__ = '2019-2020, Paweł Jastrzębski ' __docformat__ = 'restructuredtext en'