Update kwik.py

master
Arjix 2021-08-20 18:58:51 +03:00 committed by GitHub
parent 69de7f3e1b
commit ff38e125ca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 108 additions and 51 deletions

View File

@ -1,65 +1,122 @@
import logging
from platform import node
import re
import subprocess
from base64 import b64decode
import requests
import tempfile
import logging
import re
from anime_downloader.extractors.base_extractor import BaseExtractor
from anime_downloader.sites.helpers.request import temp_dir
from anime_downloader.sites import helpers
from anime_downloader import util
from anime_downloader.util import eval_in_node
from subprocess import CalledProcessError
from anime_downloader import util
logger = logging.getLogger(__name__)
class Kwik(BaseExtractor):
'''Extracts video url from kwik pages, Kwik has some `security`
which allows to access kwik pages when only referred by something
and the kwik video stream when referred through the corresponding
kwik video page.
'''
YTSM = re.compile(r"ysmm = '([^']+)")
KWIK_PARAMS_RE = re.compile(r'\("(\w+)",\d+,"(\w+)",(\d+),(\d+),\d+\)')
KWIK_D_URL = re.compile(r'action="([^"]+)"')
KWIK_D_TOKEN = re.compile(r'value="([^"]+)"')
CHARACTER_MAP = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/"
def get_string(self, content: str, s1: int, s2: int) -> str:
slice_2 = self.CHARACTER_MAP[0:s2]
acc = 0
for n, i in enumerate(content[::-1]):
acc += int(i if i.isdigit() else 0) * s1**n
k = ''
while acc > 0:
k = slice_2[int(acc % s2)] + k
acc = (acc - (acc % s2)) / s2
return k or '0'
def decrypt(self, full_string: str, key: str, v1: int, v2: int) -> str:
v1, v2 = int(v1), int(v2)
r, i = "", 0
while i < len(full_string):
s = ""
while (full_string[i] != key[v2]):
s += full_string[i]
i += 1
j = 0
while j < len(key):
s = s.replace(key[j], str(j))
j += 1
r += chr(int(self.get_string(s, v2, 10)) - v1)
i += 1
return r
def decode_adfly(self, coded_key: str) -> str:
r, j = '', ''
for n, l in enumerate(coded_key):
if not n % 2:
r += l
else:
j = l + j
encoded_uri = list(r + j)
numbers = ((i, n) for i, n in enumerate(encoded_uri) if str.isdigit(n))
for first, second in zip(numbers, numbers):
xor = int(first[1]) ^ int(second[1])
if xor < 10:
encoded_uri[first[0]] = str(xor)
return b64decode(("".join(encoded_uri)).encode("utf-8")
)[16:-16].decode('utf-8', errors='ignore')
def bypass_adfly(self, adfly_url):
session = requests.session()
response_code = 302
while response_code != 200:
adfly_content = session.get(
session.get(
adfly_url,
allow_redirects=False).headers.get('location'),
allow_redirects=False)
response_code = adfly_content.status_code
return self.decode_adfly(self.YTSM.search(adfly_content.text).group(1))
def get_stream_url_from_kwik(self, adfly_url):
session = requests.session()
f_content = requests.get(
self.bypass_adfly(adfly_url),
headers={
'referer': 'https://kwik.cx/'
}
)
decrypted = self.decrypt(
*
self.KWIK_PARAMS_RE.search(
f_content.text
).group(
1, 2,
3, 4
)
)
code = 419
while code != 302:
content = session.post(
self.KWIK_D_URL.search(decrypted).group(1),
allow_redirects=False,
data={
'_token': self.KWIK_D_TOKEN.search(decrypted).group(1)},
headers={
'referer': str(f_content.url),
'cookie': f_content.headers.get('set-cookie')})
code = content.status_code
return content.headers.get('location')
def _get_data(self):
ld = logger.debug
# Kwik servers don't have direct link access you need to be referred
# from somewhere, I will just use the url itself. We then
# have to rebuild the url. Hopefully kwik doesn't block this too
# Necessary
headers = {"Referer": "https://kwik.cx/"}
res = requests.get(self.url, headers=headers)
evalText = helpers.soupify(res.text)
scripts = evalText.select("script")
for i in scripts:
rexd = re.compile("<script>eval[\s\S]*<\/script>").match(str(i))
if not rexd == None:
rexd = rexd.group()
rexd = rexd.replace("<script>", "")
rexd = rexd.replace("</script>", "")
break
tf = tempfile.mktemp(dir=temp_dir)
with open(tf, 'w', encoding="utf-8") as f:
f.write(rexd)
nodeRes = str(subprocess.getoutput(f"node {tf}"))
ld(nodeRes)
stream_url = re.search(
r"source='([^;]*)';", nodeRes).group().replace("source='", "").replace("';", "")
ld(stream_url)
return {
'stream_url': stream_url,
'referer': "https://kwik.cx/"
'stream_url': self.get_stream_url_from_kwik(self.url),
'referer': None
}