import requests
from requests_toolbelt import MultipartEncoder
from os.path import basename, getsize, abspath
from argparse import ArgumentParser
from math import ceil
from json.decoder import JSONDecodeError
BASE_URL = 'https://s3.krakenfiles.com/_uploader/gallery/upload'
MAX_CHUNK_SIZE = 1024 * 1024 * 70
def uploader(file_path):
FILE_NAME = basename(file_path)
FILE_SIZE = getsize(file_path)
session = requests.Session()
session.options(BASE_URL)
session.headers.update({
'Content-Disposition': (
f'form-data; name="files[]"; filename="{ FILE_NAME }"'
)
})
CHUNK_COUNT = ceil(FILE_SIZE / MAX_CHUNK_SIZE)
with open(file_path, 'rb') as f:
for i in range(CHUNK_COUNT):
offset = MAX_CHUNK_SIZE * i
chunk_size = min(MAX_CHUNK_SIZE, FILE_SIZE - offset)
encoder = MultipartEncoder(
fields={'files[]': (FILE_NAME, f.read(chunk_size))}
)
session.headers.update({
'Content-Length': str(encoder.len),
'Content-Range': f'bytes { offset }-{ (offset + chunk_size) - 1 }/{ FILE_SIZE }',
'Content-Type': encoder.content_type
})
response = session.post(
BASE_URL,
data=encoder
)
try:
data = response.json()
if not data:
continue
except JSONDecodeError:
pass
files = data.get('files', [])
if not files:
return False
file = files[0]
error = file.get('error')
purl = file.get('url')
if error:
return error
return f'https://krakenfiles.com{ purl }'
return False
if __name__ == '__main__':
parser = ArgumentParser()
parser.add_argument(
'-p', '--path',
dest='file_path'
)
args = parser.parse_args()
file_path = args.file_path
if file_path:
print(uploader(abspath(file_path)))