CC-5709: Airtime Analyzer
* Overhauled Add Media screen, now shows state of recent uploads * Dropped old unused "state" column, added new file_import column to cc_files * New PluploadController methods * Save the filename as the track title for unprocessed uploads * Hide pending files from the library until they've been processed. * Don't overwrite files with duplicate names, we rename them instead.
This commit is contained in:
parent
2b696dbee5
commit
878dd11ccc
|
@ -2,12 +2,11 @@
|
|||
|
||||
class PluploadController extends Zend_Controller_Action
|
||||
{
|
||||
|
||||
public function init()
|
||||
{
|
||||
$ajaxContext = $this->_helper->getHelper('AjaxContext');
|
||||
$ajaxContext->addActionContext('upload', 'json')
|
||||
->addActionContext('uploadFinished', 'json')
|
||||
->addActionContext('recent-uploads', 'json')
|
||||
->initContext();
|
||||
}
|
||||
|
||||
|
@ -18,12 +17,14 @@ class PluploadController extends Zend_Controller_Action
|
|||
$baseUrl = Application_Common_OsPath::getBaseDir();
|
||||
$locale = Application_Model_Preference::GetLocale();
|
||||
|
||||
$this->view->headScript()->appendFile($baseUrl.'js/datatables/js/jquery.dataTables.js?'.$CC_CONFIG['airtime_version'], 'text/javascript');
|
||||
$this->view->headScript()->appendFile($baseUrl.'js/plupload/plupload.full.min.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
$this->view->headScript()->appendFile($baseUrl.'js/plupload/jquery.plupload.queue.min.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
$this->view->headScript()->appendFile($baseUrl.'js/airtime/library/plupload.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
$this->view->headScript()->appendFile($baseUrl.'js/plupload/i18n/'.$locale.'.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
|
||||
$this->view->headLink()->appendStylesheet($baseUrl.'css/plupload.queue.css?'.$CC_CONFIG['airtime_version']);
|
||||
$this->view->headLink()->appendStylesheet($baseUrl.'css/addmedia.css?'.$CC_CONFIG['airtime_version']);
|
||||
}
|
||||
|
||||
public function uploadAction()
|
||||
|
@ -34,31 +35,43 @@ class PluploadController extends Zend_Controller_Action
|
|||
|
||||
$this->_helper->json->sendJson(array("jsonrpc" => "2.0", "tempfilepath" => $tempFileName));
|
||||
}
|
||||
|
||||
public function uploadFinishedAction()
|
||||
|
||||
public function recentUploadsAction()
|
||||
{
|
||||
$upload_dir = ini_get("upload_tmp_dir") . DIRECTORY_SEPARATOR . "plupload";
|
||||
$filename = $this->_getParam('name');
|
||||
$tempname = $this->_getParam('tempname');
|
||||
$result = Application_Model_StoredFile::importUploadedFile($upload_dir, $filename, $tempname);
|
||||
if (!is_null($result))
|
||||
$this->_helper->json->sendJson(array("jsonrpc" => "2.0", "error" => $result));
|
||||
//$this->dis
|
||||
//( $_GET['iDisplayStart'] ) && $_GET['iDisplayLength'] != '-1' )
|
||||
$limit = isset($_GET['iDisplayLength']) ? $_GET['iDisplayLength'] : 10;
|
||||
$rowStart = isset($_GET['iDisplayStart']) ? $_GET['iDisplayStart'] : 0;
|
||||
|
||||
$this->_helper->json->sendJson(array("jsonrpc" => "2.0"));
|
||||
$recentUploads = CcFilesQuery::create()->filterByDbUtime(array('min' => time() - 30 * 24 * 60 * 60))
|
||||
->orderByDbUtime(Criteria::DESC)
|
||||
->offset($rowStart)
|
||||
->limit($limit)
|
||||
->find();
|
||||
|
||||
$numRecentUploads = $limit;
|
||||
|
||||
$numTotalRecentUploads = CcFilesQuery::create()->filterByDbUtime(array('min' => time() - 30 * 24 * 60 * 60))
|
||||
->count();
|
||||
|
||||
//$this->_helper->json->sendJson(array("jsonrpc" => "2.0", "tempfilepath" => $tempFileName));
|
||||
|
||||
$uploadsArray = array();
|
||||
|
||||
foreach ($recentUploads as $upload)
|
||||
{
|
||||
$upload->toArray(BasePeer::TYPE_FIELDNAME);
|
||||
//array_push($uploadsArray, $upload); //TODO: $this->sanitizeResponse($upload));
|
||||
|
||||
//$this->_helper->json->sendJson($upload->asJson());
|
||||
array_push($uploadsArray, $upload->toArray(BasePeer::TYPE_FIELDNAME));
|
||||
}
|
||||
|
||||
|
||||
$this->view->sEcho = intval($this->getRequest()->getParam('sEcho'));
|
||||
$this->view->iTotalDisplayRecords = $numTotalRecentUploads;
|
||||
//$this->view->iTotalDisplayRecords = $numRecentUploads; //$r["iTotalDisplayRecords"];
|
||||
$this->view->iTotalRecords = $numTotalRecentUploads; //$r["iTotalRecords"];
|
||||
$this->view->files = $uploadsArray; //$r["aaData"];
|
||||
}
|
||||
/* FIXME: I renamed this guy to uploadFinishedAction and am just starting to rewrite it to use the new File API.
|
||||
* -- Albert March 10, 2014
|
||||
public function copyfileAction()
|
||||
{
|
||||
$upload_dir = ini_get("upload_tmp_dir") . DIRECTORY_SEPARATOR . "plupload";
|
||||
$filename = $this->_getParam('name');
|
||||
$tempname = $this->_getParam('tempname');
|
||||
$result = Application_Model_StoredFile::copyFileToStor($upload_dir,
|
||||
$filename, $tempname);
|
||||
if (!is_null($result))
|
||||
$this->_helper->json->sendJson(array("jsonrpc" => "2.0", "error" => $result));
|
||||
|
||||
$this->_helper->json->sendJson(array("jsonrpc" => "2.0"));
|
||||
}*/
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ class Rest_MediaController extends Zend_Rest_Controller
|
|||
|
||||
$this->getResponse()
|
||||
->setHttpResponseCode(200)
|
||||
->appendBody(json_encode($files_array));
|
||||
->appendBody(json_encode($files_array));
|
||||
|
||||
/** TODO: Use this simpler code instead after we upgrade to Propel 1.7 (Airtime 2.6.x branch):
|
||||
$this->getResponse()
|
||||
|
@ -121,8 +121,10 @@ class Rest_MediaController extends Zend_Rest_Controller
|
|||
$file->fromArray($this->validateRequestData($this->getRequest()->getPost()));
|
||||
$file->setDbOwnerId($this->getOwnerId());
|
||||
$now = new DateTime("now", new DateTimeZone("UTC"));
|
||||
$file->setDbTrackTitle($_FILES["file"]["name"]);
|
||||
$file->setDbUtime($now);
|
||||
$file->setDbMtime($now);
|
||||
$file->setDbHidden(true);
|
||||
$file->save();
|
||||
|
||||
$callbackUrl = $this->getRequest()->getScheme() . '://' . $this->getRequest()->getHttpHost() . $this->getRequest()->getRequestUri() . "/" . $file->getPrimaryKey();
|
||||
|
@ -170,7 +172,7 @@ class Rest_MediaController extends Zend_Rest_Controller
|
|||
$file->setDbDirectory(1); //1 corresponds to the default stor/imported directory.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$now = new DateTime("now", new DateTimeZone("UTC"));
|
||||
$file->setDbMtime($now);
|
||||
$file->save();
|
||||
|
|
|
@ -9,3 +9,19 @@
|
|||
<div id="plupload_error">
|
||||
<table></table>
|
||||
</div>
|
||||
|
||||
<div id="recent_uploads_wrapper" class="lib-content ui-widget ui-widget-content block-shadow alpha-block">
|
||||
<div id="recent_uploads" class="padded">
|
||||
|
||||
<div id="recent_uploads_filter">
|
||||
<form>
|
||||
<input type="radio" name="upload_status" id="upload_status_all" checked></input><label for="upload_status_all">All</label>
|
||||
<input type="radio" name="upload_status" id="upload_status_failed"></input><label for="upload_status_failed">Failed</label>
|
||||
<input type="radio" name="upload_status" id="upload_status_pending"></input><label for="upload_status_pending">Pending</label>
|
||||
</form>
|
||||
</div>
|
||||
<H2>Recent Uploads</H2>
|
||||
<table id="recent_uploads_table" class="lib-content ui-widget ui-widget-content block-shadow alpha-block "></table>
|
||||
</div>
|
||||
<div style="clear: both;"></div>
|
||||
</div>
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
<column name="ftype" phpName="DbFtype" type="VARCHAR" size="128" required="true" defaultValue=""/>
|
||||
<column name="directory" phpName="DbDirectory" type="INTEGER" required="false"/>
|
||||
<column name="filepath" phpName="DbFilepath" type="LONGVARCHAR" required="false" defaultValue=""/>
|
||||
<column name="state" phpName="DbState" type="VARCHAR" size="128" required="true" defaultValue="empty"/>
|
||||
<column name="import_status" phpName="DbImportStatus" type="INTEGER" required="true" defaultValue="0"/>
|
||||
<column name="currentlyaccessing" phpName="DbCurrentlyaccessing" type="INTEGER" required="true" defaultValue="0"/>
|
||||
<column name="editedby" phpName="DbEditedby" type="INTEGER" required="false"/>
|
||||
<column name="mtime" phpName="DbMtime" type="TIMESTAMP" size="6" required="false"/>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
$(document).ready(function() {
|
||||
|
||||
var uploader;
|
||||
var self = this;
|
||||
|
||||
$("#plupload_files").pluploadQueue({
|
||||
// General settings
|
||||
|
@ -19,6 +20,13 @@ $(document).ready(function() {
|
|||
|
||||
uploader.bind('FileUploaded', function(up, file, json) {
|
||||
|
||||
var j = jQuery.parseJSON(json.response);
|
||||
console.log(j);
|
||||
console.log(file.name);
|
||||
|
||||
self.recentUploadsTable.fnDraw(); //Only works because we're using bServerSide
|
||||
//In DataTables 1.10 and greater, we can use .fnAjaxReload()
|
||||
|
||||
/*
|
||||
var j = jQuery.parseJSON(json.response);
|
||||
|
||||
|
@ -52,7 +60,7 @@ $(document).ready(function() {
|
|||
var uploadProgress = false;
|
||||
|
||||
uploader.bind('QueueChanged', function(){
|
||||
uploadProgress = (uploader.files.length > 0)
|
||||
uploadProgress = (uploader.files.length > 0);
|
||||
});
|
||||
|
||||
uploader.bind('UploadComplete', function(){
|
||||
|
@ -65,5 +73,32 @@ $(document).ready(function() {
|
|||
"\n", "\n");
|
||||
}
|
||||
});
|
||||
|
||||
self.setupRecentUploadsTable = function() {
|
||||
return recentUploadsTable = $("#recent_uploads_table").dataTable({
|
||||
"bJQueryUI": true,
|
||||
"bProcessing": false,
|
||||
"bServerSide": true,
|
||||
"sAjaxSource": '/Plupload/recent-uploads/format/json',
|
||||
"sAjaxDataProp": 'files',
|
||||
"bSearchable": false,
|
||||
"bInfo": true,
|
||||
"sScrollY": "200px",
|
||||
"bFilter": false,
|
||||
"bSort": false,
|
||||
"sDom": '<"H"l>frtip',
|
||||
"bPaginate" : true,
|
||||
"sPaginationType": "full_numbers",
|
||||
"aoColumns": [
|
||||
{ "mData" : "artist_name", "sTitle" : $.i18n._("Creator") },
|
||||
{ "mData" : "track_title", "sTitle" : $.i18n._("Title") },
|
||||
{ "mData" : "state", "sTitle" : $.i18n._("Import Status")},
|
||||
{ "mData" : "utime", "sTitle" : $.i18n._("Uploaded") }
|
||||
]
|
||||
});
|
||||
};
|
||||
self.recentUploadsTable = self.setupRecentUploadsTable();
|
||||
|
||||
$("#recent_uploads_table.div.fg-toolbar").prepend('<b>Custom tool bar! Text/images etc.</b>');
|
||||
|
||||
});
|
||||
|
|
|
@ -2,6 +2,8 @@ import logging
|
|||
import multiprocessing
|
||||
import shutil
|
||||
import os, errno
|
||||
import time
|
||||
import uuid
|
||||
from metadata_analyzer import MetadataAnalyzer
|
||||
|
||||
class AnalyzerPipeline:
|
||||
|
@ -33,6 +35,9 @@ class AnalyzerPipeline:
|
|||
# back to the main process.
|
||||
|
||||
#Import the file over to it's final location.
|
||||
#TODO: Move all this file moving stuff to its own Analyzer class.
|
||||
# Also, handle the case where the move fails and write some code
|
||||
# to possibly move the file to problem_files.
|
||||
|
||||
final_file_path = import_directory
|
||||
if results.has_key("artist_name"):
|
||||
|
@ -44,16 +49,28 @@ class AnalyzerPipeline:
|
|||
#Ensure any redundant slashes are stripped
|
||||
final_file_path = os.path.normpath(final_file_path)
|
||||
|
||||
#final_audio_file_path = final_directory + os.sep + os.path.basename(audio_file_path)
|
||||
#If a file with the same name already exists in the "import" directory, then
|
||||
#we add a unique string to the end of this one. We never overwrite a file on import
|
||||
#because if we did that, it would mean Airtime's database would have
|
||||
#the wrong information for the file we just overwrote (eg. the song length would be wrong!)
|
||||
if os.path.exists(final_file_path) and not os.path.samefile(audio_file_path, final_file_path):
|
||||
raise Exception("File exists and will not be overwritten.") # by design
|
||||
#Overwriting a file would mean Airtime's database has the wrong information...
|
||||
#If the final file path is the same as the file we've been told to import (which
|
||||
#you often do when you're debugging), then don't move the file at all.
|
||||
|
||||
base_file_path, file_extension = os.path.splitext(final_file_path)
|
||||
final_file_path = "%s_%s%s" % (base_file_path, time.strftime("%m-%d-%Y-%H-%M-%S", time.localtime()), file_extension)
|
||||
|
||||
#If THAT path exists, append a UUID instead:
|
||||
while os.path.exists(final_file_path):
|
||||
base_file_path, file_extension = os.path.splitext(final_file_path)
|
||||
final_file_path = "%s_%s%s" % (base_file_path, str(uuid.uuid4()), file_extension)
|
||||
|
||||
#Ensure the full path to the file exists
|
||||
mkdir_p(os.path.dirname(final_file_path))
|
||||
|
||||
#Move the file into its final destination directory
|
||||
shutil.move(audio_file_path, final_file_path)
|
||||
|
||||
#Ensure the full path to the file exists
|
||||
mkdir_p(os.path.dirname(final_file_path))
|
||||
|
||||
#Move the file into its final destination directory
|
||||
shutil.move(audio_file_path, final_file_path)
|
||||
|
||||
#Pass the full path back to Airtime
|
||||
results["full_path"] = final_file_path
|
||||
|
|
|
@ -100,7 +100,9 @@ class MetadataAnalyzer(Analyzer):
|
|||
|
||||
#Airtime <= 2.5.x nonsense:
|
||||
metadata["ftype"] = "audioclip"
|
||||
#Other fields we'll want to set for Airtime:
|
||||
metadata["cueout"] = metadata["length"]
|
||||
metadata["hidden"] = False
|
||||
|
||||
return metadata
|
||||
|
||||
|
|
Loading…
Reference in New Issue