File size: 3,082 Bytes
8070315 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
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")
|