From 11d18ad8e87978769389ba7b19f74dac40e1038e Mon Sep 17 00:00:00 2001 From: Naomi Aro Date: Wed, 8 Jun 2011 18:24:17 +0200 Subject: [PATCH] CC-1799 Put Airtime Storage into a Human Readable File Naming Convention can drag a bunch of songs into stor, and they are organized and imported to airtime. Need to fix length property. --- .../application/controllers/ApiController.php | 65 ++++++++++++------- .../controllers/PluploadController.php | 8 ++- airtime_mvc/application/models/StoredFile.php | 40 +++--------- python_apps/media-monitor/MediaMonitor.py | 42 +++++++++--- python_apps/media-monitor/media-monitor.cfg | 3 + 5 files changed, 92 insertions(+), 66 deletions(-) diff --git a/airtime_mvc/application/controllers/ApiController.php b/airtime_mvc/application/controllers/ApiController.php index 1f8b5d5ee..a545aaa20 100644 --- a/airtime_mvc/application/controllers/ApiController.php +++ b/airtime_mvc/application/controllers/ApiController.php @@ -10,6 +10,7 @@ class ApiController extends Zend_Controller_Action $context->addActionContext('version', 'json') ->addActionContext('recorded-shows', 'json') ->addActionContext('upload-recorded', 'json') + ->addActionContext('media-item-status', 'json') ->addActionContext('reload-metadata', 'json') ->initContext(); } @@ -293,17 +294,17 @@ class ApiController extends Zend_Controller_Action print 'You are not allowed to access this resource.'; exit; } - + $showCanceled = false; $show_instance = $this->_getParam('show_instance'); - + $upload_dir = ini_get("upload_tmp_dir"); $file = StoredFile::uploadFile($upload_dir); - + $show_name = ""; try { $show_inst = new ShowInstance($show_instance); - + $show_inst->setRecordedFile($file->getId()); $show_name = $show_inst->getName(); $show_genre = $show_inst->getGenre(); @@ -317,12 +318,12 @@ class ApiController extends Zend_Controller_Action //the library), now lets just return. $showCanceled = true; } - + $tmpTitle = !(empty($show_name))?$show_name."-":""; $tmpTitle .= $file->getName(); - + $file->setMetadataValue(UI_MDATA_KEY_TITLE, $tmpTitle); - + if (!$showCanceled && Application_Model_Preference::GetDoSoundCloudUpload()) { for ($i=0; $i<$CC_CONFIG['soundcloud-connection-retries']; $i++) { @@ -353,8 +354,35 @@ class ApiController extends Zend_Controller_Action $this->view->id = $file->getId(); } - public function reloadMetadataAction() { + public function mediaItemStatusAction() { + global $CC_CONFIG; + // disable the view and the layout + $this->view->layout()->disableLayout(); + $this->_helper->viewRenderer->setNoRender(true); + + $api_key = $this->_getParam('api_key'); + if (!in_array($api_key, $CC_CONFIG["apiKey"])) + { + header('HTTP/1.0 401 Unauthorized'); + print 'You are not allowed to access this resource.'; + exit; + } + + $md5 = $this->_getParam('md5'); + $file = StoredFile::RecallByMd5($md5); + + //New file added to Airtime + if (is_null($file)) { + $this->view->airtime_status = 0; + } + else { + $this->view->airtime_status = 1; + } + + } + + public function reloadMetadataAction() { global $CC_CONFIG; $api_key = $this->_getParam('api_key'); @@ -366,29 +394,20 @@ class ApiController extends Zend_Controller_Action } $md = $this->_getParam('md'); - $filepath = $md['filepath']; + $filepath = $md['MDATA_KEY_FILEPATH']; $filepath = str_replace("\\", "", $filepath); - $file = StoredFile::Recall(null, null, null, $filepath); - if (PEAR::isError($file)) { - $this->view->response = "Problem recalling file in Airtime"; - return; - } + $file = StoredFile::RecallByFilepath($filepath); //New file added to Airtime if (is_null($file)) { - + $file = new StoredFile($md); } //Updating a metadata change. else { - $res = $file->replaceDbMetadata($md); - - if (PEAR::isError($res)) { - $this->view->response = "Metadata Change Failed"; - } - else { - $this->view->response = "Success!"; - } + $file->setMetadata($md); } + + $this->view->id = $file->getId(); } } diff --git a/airtime_mvc/application/controllers/PluploadController.php b/airtime_mvc/application/controllers/PluploadController.php index 56c07bc23..d8fc10c08 100644 --- a/airtime_mvc/application/controllers/PluploadController.php +++ b/airtime_mvc/application/controllers/PluploadController.php @@ -25,9 +25,13 @@ class PluploadController extends Zend_Controller_Action public function uploadAction() { $upload_dir = ini_get("upload_tmp_dir") . DIRECTORY_SEPARATOR . "plupload"; - $file = StoredFile::uploadFile($upload_dir); + $res = StoredFile::uploadFile($upload_dir); - die('{"jsonrpc" : "2.0", "id" : '.$file->getId().' }'); + if (isset($res)) { + die('{"jsonrpc" : "2.0", "id" : '.$file->getMessage().' }'); + } + + die('{"jsonrpc" : "2.0"}'); } } diff --git a/airtime_mvc/application/models/StoredFile.php b/airtime_mvc/application/models/StoredFile.php index c55e67f34..1c8dcef42 100644 --- a/airtime_mvc/application/models/StoredFile.php +++ b/airtime_mvc/application/models/StoredFile.php @@ -402,13 +402,19 @@ class StoredFile { $storedFile = CcFilesQuery::create()->findPK(intval($p_id)); } else if (isset($p_gunid)) { - $storedFile = CcFilesQuery::create()->findByDbGunid($p_gunid); + $storedFile = CcFilesQuery::create() + ->filterByDbGunid($p_gunid) + ->findOne(); } else if (isset($p_md5sum)) { - $storedFile = CcFilesQuery::create()->findByDbMd5($p_md5sum); + $storedFile = CcFilesQuery::create() + ->filterByDbMd5($p_md5sum) + ->findOne(); } else if (isset($p_filepath)) { - $storedFile = CcFilesQuery::create()->findByDbFilepath($p_filepath); + $storedFile = CcFilesQuery::create() + ->filterByDbFilepath($p_filepath) + ->findOne(); } else { return null; @@ -697,34 +703,6 @@ class StoredFile { } } - $metadata = Metadata::LoadFromFile($audio_file); - - if (PEAR::isError($metadata)) { - die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": ' + $metadata->getMessage() + '}}'); - } - - // no id3 title tag -> use the original filename for title - if (empty($metadata[UI_MDATA_KEY_TITLE])) { - $metadata[UI_MDATA_KEY_TITLE] = basename($audio_file); - $metadata[UI_MDATA_KEY_FILENAME] = basename($audio_file); - } - - $values = array( - "filename" => basename($audio_file), - "filepath" => $audio_file, - "filetype" => "audioclip", - "mime" => $metadata[UI_MDATA_KEY_FORMAT], - "md5" => $md5 - ); - $storedFile = StoredFile::Insert($values); - - if (PEAR::isError($storedFile)) { - die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": ' + $storedFile->getMessage() + '}}'); - } - - $storedFile->setMetadataBatch($metadata); - - return $storedFile; } } diff --git a/python_apps/media-monitor/MediaMonitor.py b/python_apps/media-monitor/MediaMonitor.py index dcb4793d2..05704e724 100644 --- a/python_apps/media-monitor/MediaMonitor.py +++ b/python_apps/media-monitor/MediaMonitor.py @@ -9,6 +9,7 @@ import sys import hashlib import json import shutil +import math from subprocess import Popen, PIPE, STDOUT @@ -143,9 +144,20 @@ class MediaMonitor(ProcessEvent): return md5 ## mutagen_length is in seconds with the format (d+).dd - ## return format hh:mm:ss. + ## return format hh:mm:ss.uuu def format_length(self, mutagen_length): - time = mutagen_length.split(".") + t = float(mutagen_length) + h = int(math.floor(t/3600)) + + t = t % 3600 + m = int(math.floor(t/60)) + + # will be ss.uuu + s = t % 60 + + length = "%s:%s:%s" % (h, m, s) + + return length def ensure_dir(self, filepath): @@ -210,16 +222,19 @@ class MediaMonitor(ProcessEvent): filepath = self.create_unique_filename(base) self.ensure_dir(filepath) - shutil.move(imported_filepath, filepath) - def update_airtime(self, event): + return filepath + + + def update_airtime(self, filepath): self.logger.info("Updating Change to Airtime") + md = {} try: - md5 = self.get_md5(event.pathname) - md['MDATA_KEY_FILEPATH'] = event.pathname + md5 = self.get_md5(filepath) + md['MDATA_KEY_FILEPATH'] = filepath md['MDATA_KEY_MD5'] = md5 - file_info = mutagen.File(event.pathname, easy=True) + file_info = mutagen.File(filepath, easy=True) attrs = self.mutagen2airtime for key in file_info.keys() : if key in attrs : @@ -227,7 +242,7 @@ class MediaMonitor(ProcessEvent): md['MDATA_KEY_MIME'] = file_info.mime[0] md['MDATA_KEY_BITRATE'] = file_info.info.bitrate - md['MDATA_KEY_SAMPLERATE'] = file_info.info.sample_rated + md['MDATA_KEY_SAMPLERATE'] = file_info.info.sample_rate md['MDATA_KEY_DURATION'] = self.format_length(file_info.info.length) data = {'md': md} @@ -268,14 +283,21 @@ class MediaMonitor(ProcessEvent): #This is a newly imported file. else : if not self.is_renamed_file(event.pathname): - self.create_file_path(event.pathname) + md5 = self.get_md5(event.pathname) + response = self.api_client.check_media_status(md5) + + #this file is new, md5 does not exist in Airtime. + if(response['airtime_status'] == 0): + filepath = self.create_file_path(event.pathname) + shutil.move(event.pathname, filepath) + self.update_airtime(filepath) self.logger.info("%s: %s", event.maskname, event.pathname) def process_IN_MODIFY(self, event): if not event.dir : if self.is_audio_file(event.name) : - self.update_airtime(event) + self.update_airtime(event.pathname) self.logger.info("%s: %s", event.maskname, event.pathname) diff --git a/python_apps/media-monitor/media-monitor.cfg b/python_apps/media-monitor/media-monitor.cfg index 38b44cea7..a590f7c21 100644 --- a/python_apps/media-monitor/media-monitor.cfg +++ b/python_apps/media-monitor/media-monitor.cfg @@ -19,6 +19,9 @@ api_base = 'api' # URL to get the version number of the server API version_url = 'version/api_key/%%api_key%%' +# URL to check Airtime's status of a file +media_status_url = 'media-item-status/format/json/api_key/%%api_key%%/md5/%%md5%%' + # URL to tell Airtime to update file's meta data update_media_url = 'reload-metadata/format/json/api_key/%%api_key%%'