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.
This commit is contained in:
parent
f066135380
commit
11d18ad8e8
5 changed files with 92 additions and 66 deletions
|
@ -10,6 +10,7 @@ class ApiController extends Zend_Controller_Action
|
||||||
$context->addActionContext('version', 'json')
|
$context->addActionContext('version', 'json')
|
||||||
->addActionContext('recorded-shows', 'json')
|
->addActionContext('recorded-shows', 'json')
|
||||||
->addActionContext('upload-recorded', 'json')
|
->addActionContext('upload-recorded', 'json')
|
||||||
|
->addActionContext('media-item-status', 'json')
|
||||||
->addActionContext('reload-metadata', 'json')
|
->addActionContext('reload-metadata', 'json')
|
||||||
->initContext();
|
->initContext();
|
||||||
}
|
}
|
||||||
|
@ -353,8 +354,35 @@ class ApiController extends Zend_Controller_Action
|
||||||
$this->view->id = $file->getId();
|
$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;
|
global $CC_CONFIG;
|
||||||
|
|
||||||
$api_key = $this->_getParam('api_key');
|
$api_key = $this->_getParam('api_key');
|
||||||
|
@ -366,29 +394,20 @@ class ApiController extends Zend_Controller_Action
|
||||||
}
|
}
|
||||||
|
|
||||||
$md = $this->_getParam('md');
|
$md = $this->_getParam('md');
|
||||||
$filepath = $md['filepath'];
|
$filepath = $md['MDATA_KEY_FILEPATH'];
|
||||||
$filepath = str_replace("\\", "", $filepath);
|
$filepath = str_replace("\\", "", $filepath);
|
||||||
$file = StoredFile::Recall(null, null, null, $filepath);
|
$file = StoredFile::RecallByFilepath($filepath);
|
||||||
if (PEAR::isError($file)) {
|
|
||||||
$this->view->response = "Problem recalling file in Airtime";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//New file added to Airtime
|
//New file added to Airtime
|
||||||
if (is_null($file)) {
|
if (is_null($file)) {
|
||||||
|
$file = new StoredFile($md);
|
||||||
}
|
}
|
||||||
//Updating a metadata change.
|
//Updating a metadata change.
|
||||||
else {
|
else {
|
||||||
$res = $file->replaceDbMetadata($md);
|
$file->setMetadata($md);
|
||||||
|
}
|
||||||
|
|
||||||
if (PEAR::isError($res)) {
|
$this->view->id = $file->getId();
|
||||||
$this->view->response = "Metadata Change Failed";
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$this->view->response = "Success!";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,9 +25,13 @@ class PluploadController extends Zend_Controller_Action
|
||||||
public function uploadAction()
|
public function uploadAction()
|
||||||
{
|
{
|
||||||
$upload_dir = ini_get("upload_tmp_dir") . DIRECTORY_SEPARATOR . "plupload";
|
$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"}');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -402,13 +402,19 @@ class StoredFile {
|
||||||
$storedFile = CcFilesQuery::create()->findPK(intval($p_id));
|
$storedFile = CcFilesQuery::create()->findPK(intval($p_id));
|
||||||
}
|
}
|
||||||
else if (isset($p_gunid)) {
|
else if (isset($p_gunid)) {
|
||||||
$storedFile = CcFilesQuery::create()->findByDbGunid($p_gunid);
|
$storedFile = CcFilesQuery::create()
|
||||||
|
->filterByDbGunid($p_gunid)
|
||||||
|
->findOne();
|
||||||
}
|
}
|
||||||
else if (isset($p_md5sum)) {
|
else if (isset($p_md5sum)) {
|
||||||
$storedFile = CcFilesQuery::create()->findByDbMd5($p_md5sum);
|
$storedFile = CcFilesQuery::create()
|
||||||
|
->filterByDbMd5($p_md5sum)
|
||||||
|
->findOne();
|
||||||
}
|
}
|
||||||
else if (isset($p_filepath)) {
|
else if (isset($p_filepath)) {
|
||||||
$storedFile = CcFilesQuery::create()->findByDbFilepath($p_filepath);
|
$storedFile = CcFilesQuery::create()
|
||||||
|
->filterByDbFilepath($p_filepath)
|
||||||
|
->findOne();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return null;
|
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ import sys
|
||||||
import hashlib
|
import hashlib
|
||||||
import json
|
import json
|
||||||
import shutil
|
import shutil
|
||||||
|
import math
|
||||||
|
|
||||||
from subprocess import Popen, PIPE, STDOUT
|
from subprocess import Popen, PIPE, STDOUT
|
||||||
|
|
||||||
|
@ -143,9 +144,20 @@ class MediaMonitor(ProcessEvent):
|
||||||
return md5
|
return md5
|
||||||
|
|
||||||
## mutagen_length is in seconds with the format (d+).dd
|
## 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):
|
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):
|
def ensure_dir(self, filepath):
|
||||||
|
|
||||||
|
@ -210,16 +222,19 @@ class MediaMonitor(ProcessEvent):
|
||||||
|
|
||||||
filepath = self.create_unique_filename(base)
|
filepath = self.create_unique_filename(base)
|
||||||
self.ensure_dir(filepath)
|
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")
|
self.logger.info("Updating Change to Airtime")
|
||||||
|
md = {}
|
||||||
try:
|
try:
|
||||||
md5 = self.get_md5(event.pathname)
|
md5 = self.get_md5(filepath)
|
||||||
md['MDATA_KEY_FILEPATH'] = event.pathname
|
md['MDATA_KEY_FILEPATH'] = filepath
|
||||||
md['MDATA_KEY_MD5'] = md5
|
md['MDATA_KEY_MD5'] = md5
|
||||||
|
|
||||||
file_info = mutagen.File(event.pathname, easy=True)
|
file_info = mutagen.File(filepath, easy=True)
|
||||||
attrs = self.mutagen2airtime
|
attrs = self.mutagen2airtime
|
||||||
for key in file_info.keys() :
|
for key in file_info.keys() :
|
||||||
if key in attrs :
|
if key in attrs :
|
||||||
|
@ -227,7 +242,7 @@ class MediaMonitor(ProcessEvent):
|
||||||
|
|
||||||
md['MDATA_KEY_MIME'] = file_info.mime[0]
|
md['MDATA_KEY_MIME'] = file_info.mime[0]
|
||||||
md['MDATA_KEY_BITRATE'] = file_info.info.bitrate
|
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)
|
md['MDATA_KEY_DURATION'] = self.format_length(file_info.info.length)
|
||||||
|
|
||||||
data = {'md': md}
|
data = {'md': md}
|
||||||
|
@ -268,14 +283,21 @@ class MediaMonitor(ProcessEvent):
|
||||||
#This is a newly imported file.
|
#This is a newly imported file.
|
||||||
else :
|
else :
|
||||||
if not self.is_renamed_file(event.pathname):
|
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)
|
self.logger.info("%s: %s", event.maskname, event.pathname)
|
||||||
|
|
||||||
def process_IN_MODIFY(self, event):
|
def process_IN_MODIFY(self, event):
|
||||||
if not event.dir :
|
if not event.dir :
|
||||||
if self.is_audio_file(event.name) :
|
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)
|
self.logger.info("%s: %s", event.maskname, event.pathname)
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,9 @@ api_base = 'api'
|
||||||
# URL to get the version number of the server API
|
# URL to get the version number of the server API
|
||||||
version_url = 'version/api_key/%%api_key%%'
|
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
|
# URL to tell Airtime to update file's meta data
|
||||||
update_media_url = 'reload-metadata/format/json/api_key/%%api_key%%'
|
update_media_url = 'reload-metadata/format/json/api_key/%%api_key%%'
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue