hacking-jack's picture
Upload 1579 files
8070315 verified
from requests import post, delete
from json import loads
from models import Video
from os import stat
CHUNK_SIZE = 5 * 1024 * 1024
class UploadSession(object):
def __init__(self, panda, file_name, **kwargs):
self.panda = panda
self.file_name = file_name
self.file_size = stat(file_name).st_size
params = {
"file_size": self.file_size,
"file_name": file_name,
"profiles": "h264"
}
params.update(kwargs)
data = panda.post('/videos/upload.json', params)
self.location = loads(data)["location"]
self.status = "initialized"
self.video = None
self.error_message = None
def _read_chunks(self, file_object):
i = 0
while True:
data = file_object.read(CHUNK_SIZE)
if not data:
break
yield (data, i)
i = i+1
def start(self, pos=0):
if self.status == "initialized":
self.status = "uploading"
with open(self.file_name) as f:
f.seek(pos)
try:
for chunk, i in self._read_chunks(f):
index = i * CHUNK_SIZE
res = post(self.location, headers = {
'Content-Type': 'application/octet-stream',
'Cache-Control': 'no-cache',
'Content-Range': "bytes {0}-{1}/{2}".format(pos+index, pos+index+CHUNK_SIZE-1, self.file_size),
'Content-Length': str(CHUNK_SIZE)
}, data=chunk)
if res.status_code == 200:
self.status = "uploaded"
self.video = Video(self.panda, json_attr=res.json())
elif res.status_code != 204:
self.status = "error"
break
except Exception as e:
self.status = "error"
self.error_message = str(e)
raise e
except KeyboardInterrupt:
self.status = "error"
self.error_message = "interrupted"
else:
raise KeyError("Already started")
def resume(self):
if self.status != "uploaded":
res = post(self.location, headers = {
'Content-Type': 'application/octet-stream',
'Cache-Control': 'no-cache',
'Content-Range': "bytes */{0}".format(self.file_size),
'Content-Length': "0"
})
pos = int(res.headers["Range"].split("-")[1])
self.status = "initialized"
self.start(pos=pos)
else:
raise KeyError("Already succeed")
def abort(self):
if self.status != "success":
self.status = "aborted"
self.error_message = None
res = delete(self.location)
else:
raise KeyError("Already succeed")