2014-10-27 16:29:04 -06:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
import pycurl
|
|
|
|
import sys
|
|
|
|
import threading
|
|
|
|
import time
|
|
|
|
import json
|
2015-01-18 17:19:39 -06:00
|
|
|
import logging
|
2016-05-06 03:24:01 -05:00
|
|
|
from utils import convert_bytes
|
2014-12-29 20:58:30 -06:00
|
|
|
from pubsub import pub
|
2014-10-27 16:29:04 -06:00
|
|
|
|
2015-01-18 17:19:39 -06:00
|
|
|
log = logging.getLogger("extra.AudioUploader.transfer")
|
2014-10-27 16:29:04 -06:00
|
|
|
class Transfer(object):
|
|
|
|
|
2016-04-30 06:16:16 -05:00
|
|
|
def __init__(self, obj=None, url=None, filename=None, follow_location=True, completed_callback=None, verbose=False, *args, **kwargs):
|
2014-10-27 16:29:04 -06:00
|
|
|
self.url = url
|
|
|
|
self.filename = filename
|
2015-01-18 17:19:39 -06:00
|
|
|
log.debug("Uploading audio to %s, filename %s" % (url, filename))
|
2014-10-27 16:29:04 -06:00
|
|
|
self.curl = pycurl.Curl()
|
|
|
|
self.start_time = None
|
|
|
|
self.completed_callback = completed_callback
|
|
|
|
self.background_thread = None
|
|
|
|
self.transfer_rate = 0
|
2016-05-06 03:24:01 -05:00
|
|
|
self.curl.setopt(self.curl.XFERINFOFUNCTION, self.progress_callback)
|
2014-10-27 16:29:04 -06:00
|
|
|
self.curl.setopt(self.curl.URL, url)
|
|
|
|
self.curl.setopt(self.curl.NOPROGRESS, 0)
|
|
|
|
self.curl.setopt(self.curl.HTTP_VERSION, self.curl.CURL_HTTP_VERSION_1_0)
|
|
|
|
self.curl.setopt(self.curl.FOLLOWLOCATION, int(follow_location))
|
|
|
|
self.curl.setopt(self.curl.VERBOSE, int(verbose))
|
|
|
|
super(Transfer, self).__init__(*args, **kwargs)
|
2016-04-30 06:16:16 -05:00
|
|
|
self.obj = obj
|
2014-10-27 16:29:04 -06:00
|
|
|
|
|
|
|
def elapsed_time(self):
|
|
|
|
if not self.start_time:
|
|
|
|
return 0
|
|
|
|
return time.time() - self.start_time
|
|
|
|
|
|
|
|
def progress_callback(self, down_total, down_current, up_total, up_current):
|
|
|
|
progress = {}
|
|
|
|
progress["total"] = up_total
|
|
|
|
progress["current"] = up_current
|
|
|
|
if progress["current"] == 0:
|
|
|
|
progress["percent"] = 0
|
|
|
|
self.transfer_rate = 0
|
|
|
|
else:
|
|
|
|
progress["percent"] = int((float(progress["current"]) / progress["total"]) * 100)
|
|
|
|
self.transfer_rate = progress["current"] / self.elapsed_time()
|
|
|
|
progress["speed"] = '%s/s' % convert_bytes(self.transfer_rate)
|
|
|
|
if self.transfer_rate:
|
|
|
|
progress["eta"] = (progress["total"] - progress["current"]) / self.transfer_rate
|
|
|
|
else:
|
|
|
|
progress["eta"] = 0
|
2014-12-29 20:58:30 -06:00
|
|
|
pub.sendMessage("uploading", data=progress)
|
2014-10-27 16:29:04 -06:00
|
|
|
|
|
|
|
def perform_transfer(self):
|
2015-01-18 17:19:39 -06:00
|
|
|
log.debug("starting upload...")
|
2014-10-27 16:29:04 -06:00
|
|
|
self.start_time = time.time()
|
|
|
|
self.curl.perform()
|
|
|
|
self.curl.close()
|
2015-01-18 17:19:39 -06:00
|
|
|
log.debug("Upload finished.")
|
2014-12-29 20:58:30 -06:00
|
|
|
self.complete_transfer()
|
2014-10-27 16:29:04 -06:00
|
|
|
|
2016-04-30 06:16:16 -05:00
|
|
|
def perform_threaded(self, *args, **kwargs):
|
2014-10-27 16:29:04 -06:00
|
|
|
self.background_thread = threading.Thread(target=self.perform_transfer)
|
|
|
|
self.background_thread.daemon = True
|
|
|
|
self.background_thread.start()
|
|
|
|
|
|
|
|
def complete_transfer(self):
|
|
|
|
if callable(self.completed_callback):
|
|
|
|
self.curl.close()
|
2016-04-30 06:16:16 -05:00
|
|
|
self.completed_callback(self.obj)
|
2014-10-27 16:29:04 -06:00
|
|
|
|
|
|
|
class Upload(Transfer):
|
|
|
|
|
|
|
|
def __init__(self, field=None, filename=None, *args, **kwargs):
|
|
|
|
super(Upload, self).__init__(filename=filename, *args, **kwargs)
|
|
|
|
self.response = dict()
|
|
|
|
self.curl.setopt(self.curl.POST, 1)
|
|
|
|
if isinstance(filename, unicode):
|
|
|
|
local_filename = filename.encode(sys.getfilesystemencoding())
|
|
|
|
else:
|
|
|
|
local_filename = filename
|
|
|
|
self.curl.setopt(self.curl.HTTPPOST, [(field, (self.curl.FORM_FILE, local_filename, self.curl.FORM_FILENAME, filename.encode("utf-8")))])
|
|
|
|
self.curl.setopt(self.curl.HEADERFUNCTION, self.header_callback)
|
|
|
|
self.curl.setopt(self.curl.WRITEFUNCTION, self.body_callback)
|
|
|
|
|
|
|
|
def header_callback(self, content):
|
|
|
|
self.response['header'] = content
|
|
|
|
|
|
|
|
def body_callback(self, content):
|
|
|
|
self.response['body'] = content
|
|
|
|
|
|
|
|
def get_url(self):
|
|
|
|
return json.loads(self.response['body'])['url']
|