# !/usr/bin/env python3 import http.client import json import mimetypes import os import random import sys from string import digits, ascii_letters from urllib.parse import quote from uuid import uuid4 class ProgressBar: def __init__(self, title, count=0.0, run_status=None, fin_status=None, total=100.0, unit='KB', sep='/', chunk_size=1024): self.info = "[%s...] %s %.2f %s %s %.2f %s" self.title = title[:10] self.count = count self.total = total self.chunk_size = chunk_size self.status = run_status or "" self.fin_status = fin_status or " " * len(self.status) self.unit = unit self.sep = sep def __get_info(self): info = self.info % ( self.title, self.status, self.count / self.chunk_size, self.unit, self.sep, self.total / self.chunk_size, self.unit) return info def refresh(self, count=1, status=None): self.count += count self.status = status or self.status end_str = "\r" if self.count >= self.total: end_str = "\n" self.status = status or self.fin_status print(self.__get_info(), end=end_str) def read_in_chunks(file_path, chunk_size=1024): """ Lazy function (generator) to read a file piece by piece. Default chunk size: 1k. """ with open(file_path, "rb") as file_obj: for chunk in iter(lambda: file_obj.read(chunk_size), b""): yield chunk def body_iter(boundary, fields): for key, value in fields.items(): yield '--{}\r\n'.format(boundary).encode('ascii') if key == 'file': yield 'Content-Disposition: form-data; name={}; filename={}\r\n'.format(key, quote( os.path.basename(value))).encode('ascii') file_type = mimetypes.guess_type(value)[0] or 'application/octet-stream' yield 'Content-Type: {}\r\n'.format(file_type).encode('ascii') yield '\r\n'.encode('ascii') if not os.path.isfile(value): sys.exit('File not found: {}'.format(value)) progress = ProgressBar(os.path.basename(value), total=os.path.getsize(value), run_status="Uploading", fin_status="Upload completed") for chunk in read_in_chunks(value): progress.refresh(count=len(chunk)) yield chunk yield '\r\n'.encode('ascii') else: yield 'Content-Disposition: form-data; name={}\r\n'.format(key).encode('ascii') yield '\r\n'.encode('ascii') yield '{}\r\n'.format(value).encode('ascii') yield '--{}--\r\n'.format(boundary).encode('ascii') def upload_file(file_path): boundary = uuid4().hex headers = {'content-type': "multipart/form-data; boundary=%s" % boundary} conn = http.client.HTTPSConnection("connect.tmp.link") token = ''.join(random.choice(digits + ascii_letters) for i in range(10)) meta = {'action': 'upload', 'model': 0, 'token': token, 'file': file_path} conn.request("POST", "/api_v2/file", body_iter(boundary, meta), headers) res = conn.getresponse() if res.code == 200: data = json.loads(res.read().decode("utf-8")) if data.get('data', {}).get('url'): return 'Here is your temp link: ' + data['data'].get('url', '') return 'Something wrong with the tmp.link service' if __name__ == '__main__': if len(sys.argv) != 2: sys.exit('Usage: {} '.format(sys.argv[0])) print(upload_file(sys.argv[1]))