Replaced spaces with dashes in resource_id generation

Fixed track preview and download signed urls
Removed cloud_storage_deleter.py file
Changed cloud_storage settings in airtime.conf
This commit is contained in:
drigato 2014-10-17 17:16:53 -04:00
parent a10e287368
commit 544d20ebc2
7 changed files with 47 additions and 75 deletions

View file

@ -48,7 +48,6 @@ class AudiopreviewController extends Zend_Controller_Action
if ($type == "audioclip") { if ($type == "audioclip") {
$media = Application_Model_StoredFile::RecallById($audioFileID); $media = Application_Model_StoredFile::RecallById($audioFileID);
$uri = $baseUrl."api/get-media/file/".$audioFileID; $uri = $baseUrl."api/get-media/file/".$audioFileID;
//$uri = $media->getPropelOrm()->downloadFile();
$mime = $media->getPropelOrm()->getDbMime(); $mime = $media->getPropelOrm()->getDbMime();
} elseif ($type == "stream") { } elseif ($type == "stream") {
$webstream = CcWebstreamQuery::create()->findPk($audioFileID); $webstream = CcWebstreamQuery::create()->findPk($audioFileID);

View file

@ -368,8 +368,6 @@ SQL;
*/ */
public function delete() public function delete()
{ {
$filepath = $this->getFilePath();
// Check if the file is scheduled to be played in the future // Check if the file is scheduled to be played in the future
if (Application_Model_Schedule::IsFileScheduledInTheFuture($this->getId())) { if (Application_Model_Schedule::IsFileScheduledInTheFuture($this->getId())) {
throw new DeleteScheduledFileException(); throw new DeleteScheduledFileException();
@ -387,6 +385,8 @@ SQL;
//try { //try {
//Delete the physical file from either the local stor directory //Delete the physical file from either the local stor directory
//or from the cloud //or from the cloud
// TODO: don't have deletePhysicalFile return the filesize.
// Instead, fetch that value before deleting the file.
$filesize = $this->_file->deletePhysicalFile(); $filesize = $this->_file->deletePhysicalFile();
//Update the user's disk usage //Update the user's disk usage

View file

@ -28,21 +28,22 @@ class CloudFile extends BaseCloudFile
{ {
//should be longer than track length //should be longer than track length
$expires = 120; $expires = 120;
$resource = $this->getResourceId(); $resource_id = $this->getResourceId();
$expires = time()+$expires; $expires = time()+$expires;
$string_to_sign = "GET\n\n\n{$expires}\n/{$bucket}/{$resource}"; $string_to_sign = utf8_encode("GET\n\n\n$expires\n/$bucket/$resource_id");
$signature = base64_encode((hash_hmac("sha1", utf8_encode($string_to_sign), $s3_key_secret, TRUE))); // We need to urlencode the entire signature in case the hashed signature
// has spaces. (NOTE: utf8_encode() does not work here because it turns
// spaces into non-breaking spaces)
$signature = urlencode(base64_encode((hash_hmac("sha1", $string_to_sign, $s3_key_secret, true))));
$authentication_params = "AWSAccessKeyId={$s3_key}&Expires={$expires}&Signature={$signature}"; $authentication_params = "AWSAccessKeyId=$s3_key&Expires=$expires&Signature=$signature";
$s3 = new Zend_Service_Amazon_S3($s3_key, $s3_key_secret); $s3 = new Zend_Service_Amazon_S3($s3_key, $s3_key_secret);
$endpoint = $s3->getEndpoint(); $endpoint = $s3->getEndpoint();
$scheme = $endpoint->getScheme(); $scheme = $endpoint->getScheme();
$host = $endpoint->getHost(); $host = $endpoint->getHost();
$url = "$scheme://$host/$bucket/".utf8_encode($resource_id)."?$authentication_params";
$url = "{$scheme}://{$host}/{$bucket}/".urlencode($resource)."?{$authentication_params}";
Logging::info($url);
return $url; return $url;
} }
@ -78,8 +79,7 @@ class CloudFile extends BaseCloudFile
/** /**
* *
* Deletes the file from cloud storage by executing a python script * Deletes the file from Amazon S3
* that uses Apache Libcloud to connect with the cloud storage service
* *
* If the file was successfully deleted the filesize of that file is returned * If the file was successfully deleted the filesize of that file is returned
*/ */
@ -87,26 +87,29 @@ class CloudFile extends BaseCloudFile
{ {
$CC_CONFIG = Config::getConfig(); $CC_CONFIG = Config::getConfig();
$provider = escapeshellarg($CC_CONFIG["cloud_storage"]["provider"]); $s3 = new Zend_Service_Amazon_S3(
$bucket = escapeshellarg($CC_CONFIG["cloud_storage"]["bucket"]); $CC_CONFIG['cloud_storage']['api_key'],
$apiKey = escapeshellarg($CC_CONFIG["cloud_storage"]["api_key"]); $CC_CONFIG['cloud_storage']['api_key_secret']);
$apiSecret = escapeshellarg($CC_CONFIG["cloud_storage"]["api_key_secret"]);
$objName = escapeshellarg($this->getResourceId());
$command = "/usr/lib/airtime/pypo/bin/cloud_storage_deleter.py $provider $bucket $apiKey $apiSecret $objName 2>&1 echo $?"; $bucket = $CC_CONFIG['cloud_storage']['bucket'];
$resource_id = $this->getResourceId();
$amz_resource = utf8_encode("$bucket/$resource_id");
$output = shell_exec($command); if ($s3->isObjectAvailable($amz_resource)) {
if ($output != "") { $obj_info = $s3->getInfo($amz_resource);
if (stripos($output, 'filesize') === false) { $filesize = $obj_info["size"];
Logging::info($output);
throw new Exception("Could not delete file from cloud storage"); // removeObject() returns true even if the object was not deleted (bug?)
// so that is not a good way to do error handling. isObjectAvailable()
// does however return the correct value; We have to assume that if the
// object is available the removeObject() function will work.
$s3->removeObject($amz_resource);
return $filesize;
} else {
throw new Exception("ERROR: Could not locate object on Amazon S3");
} }
} }
$outputArr = json_decode($output, true);
return $outputArr["filesize"];
}
/** /**
* *
* Deletes the cloud_file's 'parent' object before itself * Deletes the cloud_file's 'parent' object before itself
@ -116,16 +119,4 @@ class CloudFile extends BaseCloudFile
CcFilesQuery::create()->findPk($this->getCcFileId())->delete(); CcFilesQuery::create()->findPk($this->getCcFileId())->delete();
parent::delete(); parent::delete();
} }
public function downloadFile()
{
$CC_CONFIG = Config::getConfig();
$s3 = new Zend_Service_Amazon_S3($CC_CONFIG['cloud_storage']['api_key'], $CC_CONFIG['cloud_storage']['api_key_secret']);
//$fileObj = $s3->getObject($CC_CONFIG['cloud_storage']['bucket']."/".$this->getResourceId());
$response_stream = $s3->getObjectStream($CC_CONFIG['cloud_storage']['bucket']."/".$this->getResourceId());
copy($response_stream->getStreamName(), "/tmp/".$this->getResourceId());
Logging::info($response_stream);
}
} }

View file

@ -230,6 +230,12 @@ class Rest_MediaController extends Zend_Rest_Controller
$file->setDbFilepath($requestData["filename"]); $file->setDbFilepath($requestData["filename"]);
$fileSizeBytes = $requestData["filesize"]; $fileSizeBytes = $requestData["filesize"];
if ($fileSizeBytes === false)
{
$file->setDbImportStatus(2)->save();
$this->fileNotFoundResponse();
return;
}
$cloudFile = new CloudFile(); $cloudFile = new CloudFile();
$cloudFile->setResourceId($requestData["resource_id"]); $cloudFile->setResourceId($requestData["resource_id"]);
$cloudFile->setCcFiles($file); $cloudFile->setCcFiles($file);

View file

@ -31,9 +31,7 @@ monit_password = airtime
connection_retries = 3 connection_retries = 3
time_between_retries = 60 time_between_retries = 60
[cloud_storage] [amazon]
provider =
endpoint =
bucket = bucket =
api_key = access_key =
api_key_secret = secret_key =

View file

@ -15,6 +15,13 @@ class CloudStorageUploader:
def upload_obj(self, audio_file_path, metadata): def upload_obj(self, audio_file_path, metadata):
file_base_name = os.path.basename(audio_file_path) file_base_name = os.path.basename(audio_file_path)
file_name, extension = os.path.splitext(file_base_name) file_name, extension = os.path.splitext(file_base_name)
'''
With Amazon S3 you cannot create a signed url if there are spaces
in the object name. URL encoding the object name doesn't solve the
problem. As a solution we will replace spaces with dashes.
'''
file_name = file_name.replace(" ", "-")
object_name = "%s_%s%s" % (file_name, str(uuid.uuid4()), extension) object_name = "%s_%s%s" % (file_name, str(uuid.uuid4()), extension)
cls = get_driver(getattr(Provider, self._provider)) cls = get_driver(getattr(Provider, self._provider))
@ -25,8 +32,7 @@ class CloudStorageUploader:
except ContainerDoesNotExistError: except ContainerDoesNotExistError:
container = driver.create_container(self._bucket) container = driver.create_container(self._bucket)
extra = {'meta_data': {'filename': file_base_name}, extra = {'meta_data': {'filename': file_base_name}}
'acl': 'public-read-write'}
obj = driver.upload_object(file_path=audio_file_path, obj = driver.upload_object(file_path=audio_file_path,
container=container, container=container,

View file

@ -1,28 +0,0 @@
#!/usr/bin/python
import sys
import simplejson
from libcloud.storage.providers import get_driver
from libcloud.storage.types import Provider, ObjectDoesNotExistError
provider = str(sys.argv[1])
bucket = str(sys.argv[2])
api_key = str(sys.argv[3])
api_key_secret = str(sys.argv[4])
obj_name = str(sys.argv[5])
cls = get_driver(getattr(Provider, provider))
driver = cls(api_key, api_key_secret)
try:
cloud_obj = driver.get_object(container_name=bucket,
object_name=obj_name)
filesize = getattr(cloud_obj, 'size')
driver.delete_object(obj=cloud_obj)
data = simplejson.dumps({"filesize": filesize})
print data
except ObjectDoesNotExistError:
raise Exception("Could not find object on %s in bucket: %s and object: %s" % (provider, bucket, obj_name))