Files
Phraseanet/lib/classes/task/batchupload.class.php
2011-02-16 16:09:48 +01:00

345 lines
11 KiB
PHP

<?php
class task_batchupload extends phraseatask
{
// ======================================================================================================
// ===== les interfaces de settings (task2.php) pour ce type de tache
// ======================================================================================================
// ====================================================================
// getName() : must return the name of this kind of task (utf8), MANDATORY
// ====================================================================
public function getName()
{
return(utf8_encode("Batch upload process (XML Service)"));
}
// ====================================================================
// graphic2xml : must return the xml (text) version of the form
// ====================================================================
/*
public function graphic2xml($oldxml)
{
return($oldxml);
}
*/
// ====================================================================
// xml2graphic : must fill the graphic form (using js) from xml
// ====================================================================
/*
public function xml2graphic($xml, $form)
{
return(true);
}
*/
// ====================================================================
// printInterfaceJS() : print the js part of the graphic view
// ====================================================================
/*
public function printInterfaceJS()
{
}
*/
// ====================================================================
// printInterfaceHTML(..) : print the html part of the graphic view
// ====================================================================
/*
public function printInterfaceHTML()
{
?>
<form name="graphicForm" onsubmit="return(false);">
</form>
<?php
}
*/
// ====================================================================
// getGraphicForm() : must return the name graphic form to submit
// if not implemented, assume 'graphicForm'
// ====================================================================
/*
public function getGraphicForm()
{
return('graphicForm');
}
*/
// ====================================================================
// $argt : command line args specifics to this task
// ====================================================================
/*
public $argt = array(
);
*/
// ======================================================================================================
// help() : text displayed if --help
// ======================================================================================================
public function help()
{
return(utf8_encode("Hello I'm the batch upload process."));
}
// ======================================================================================================
// run() : the real code executed by each task, MANDATORY
// ======================================================================================================
function run()
{
if( ($this->sxTaskSettings = simplexml_load_string($this->taskSettings)) )
{
}
else
{
// Settings illisibles
return(false);
}
return($this->run2());
}
function run2()
{
$conn = connection::getInstance();
$ret = '';
$this->running = true;
$taskStatus = '';
$loop = 0;
while($conn && $this->running)
{
$sql = "UPDATE task2 SET last_exec_time=NOW() WHERE task_id='" . $conn->escape_string($this->taskid)."'" ;
$conn->query($sql);
$sql = "SELECT status FROM task2 WHERE task_id='" . $conn->escape_string($this->taskid)."'" ;
if($rs = $conn->query($sql))
{
if($row = $conn->fetch_assoc($rs))
{
$taskStatus = $row['status'];
if($taskStatus == 'tostop')
{
$ret = 'stopped';
$this->running = false;
}
else
{
// flag bad batches (bad coll_number)
$sql = 'UPDATE uplfile AS f INNER JOIN uplbatch AS u USING(uplbatch_id) SET f.error="1", u.error="1"'
. ' WHERE u.error=0 AND u.base_id NOT IN(SELECT base_id FROM bas)';
$conn->query($sql);
// work on good batches
$sql = 'SELECT uplbatch_id, sbas_id, server_coll_id, usr_id FROM (uplbatch u INNER JOIN bas b USING(base_id)) WHERE complete="1" AND error="0" ORDER BY uplbatch_id';
if($rs2 = $conn->query($sql))
{
while($row = $conn->fetch_assoc($rs2))
{
$this->log(sprintf(('processing batch %s'), $row['uplbatch_id']));
if(($action = @unserialize($row['action'])) === false)
$action = '';
$batch = $this->processBatch($row['usr_id'], $row['uplbatch_id'], $row['sbas_id'], $row['server_coll_id'], $action);
$sql = 'UPDATE uplbatch SET complete="2", error="'.$batch['error'].'" WHERE uplbatch_id="'.$conn->escape_string($row['uplbatch_id']).'"';
$conn->query($sql);
$this->log(sprintf(('finishing batch %s'), $row['uplbatch_id']));
}
$conn->free_result($rs2);
}
}
}
$conn->free_result($rs);
}
$conn->close();
unset($conn);
sleep(10);
$conn = connection::getInstance();
if($loop > 5 || memory_get_usage()>>20 >= 15)
{
$ret = 'torestart';
$this->running = false;
}
$loop++;
}
return($ret);
}
function processBatch($usr_id, $batch_id, $sbas_id, $cid, $action)
{
$batch = array('error'=>'0', 'records'=>array());
$conn = connection::getInstance();
$session = session::getInstance();
$connbas = NULL;
$sxBasePrefs = NULL;
$path = NULL;
try
{
// check tmp dir
$path = GV_RootPath.'tmp/batches/'.$batch_id.'/';
if(!is_dir($path))
throw new Exception(sprintf(('Batch directory \'%s\' does not exist'), $path));
// check sbas
$connbas = connection::getInstance($sbas_id);
if(!$connbas || !$connbas->isok())
throw new Exception(sprintf(('sbas(id=%s) is unavailable'), $sbas_id));
// get struct
$sxBasePrefs = databox::get_sxml_structure($sbas_id);
if(!$sxBasePrefs)
throw new Exception(sprintf(('Can\'t get structure of sbas(id=%s)'), $sbas_id));
}
catch(Exception $e) // abort if something is wrong
{
$this->log($e->getMessage());
$sql = 'UPDATE uplfile AS f INNER JOIN uplbatch AS u USING(uplbatch_id) SET f.error="1", u.error="1"'
. ' WHERE u.uplbatch_id=\''.$conn->escape_string($batch_id).'\'';
$conn->query($sql);
$batch['error'] = '1';
return $batch;
}
//on cree une session artificielle quon va detruire
p4::authenticate($usr_id);
// do the job
$sql = 'SELECT * FROM uplfile WHERE uplbatch_id=\''.$conn->escape_string($batch_id).'\' ORDER BY idx';
if($rs = $conn->query($sql))
{
if( ($nfiles = $conn->num_rows($rs)) > 0)
{
$rid = $connbas->getId("RECORD", $nfiles);
while($row = $conn->fetch_assoc($rs))
{
$this->log(sprintf(('archiving file \'%s\''), $row['filename']));
$file = $row['idx'];
$mimeExt = giveMimeExt($path.'/'.$file);
$propfile = array(
'recordid' => $rid,
'extension' => $mimeExt['ext'],
'mime' => $mimeExt['mime'],
'size' => sprintf('%u', filesize($path.'/'.$file)),
'subpath' => '',
'parentdirectory' => '',
'hotfolderfile' => $path.'/'.$file,
'hotfoldercaptionfile' => NULL,
'pathhd' => '',
'file' => '',
'originalname' => $row['filename'],
'inbase' => 0,
'type' => giveMeDocType($mimeExt['mime'])
);
$meta = get_xml($sxBasePrefs, $propfile);
$stat0 = $stat1 = '0';
$file_uuid = new uuid($path.'/'.$file);
$uuid = $file_uuid->check_uuid();
// ... flag the record as 'to reindex' (status-bits 0 and 1 to 0) AND UNLOCK IT (status-bit 2 to 1)
// ... and flag it for subdef creation (jeton bit 0 to 1)
$fl = 'coll_id, record_id, parent_record_id, status, jeton, moddate, credate, xml, type, sha256, uuid';
$vl = $cid . ', ' .$rid . ', ' . '0' . ', (((' . $stat0 . ' | ' . $stat1 . ') & ~0x0F) | 0x0C), '.JETON_READ_META_DOC_MAKE_SUBDEF.', NOW(), NOW(), \'' . $connbas->escape_string($meta['xml']->saveXML()) . '\', \'' . $connbas->escape_string($propfile['type']) . '\', \''.hash_file('sha256',$propfile["hotfolderfile"]).'\', "'.$connbas->escape_string($uuid).'"';
$sql = 'INSERT INTO record ('.$fl.') VALUES ('.$vl.')';
if($connbas->query($sql))
{
$copyhd = (bool)($sxBasePrefs->copy_hd);
$documentisok = false;
if($copyhd)
{
// archiving with copy into base
$pathhd = trim((string)($sxBasePrefs->path));
$pathhd = p4::dispatch($pathhd);
$newname = $rid . "_document.".$propfile["extension"];
if(copy($propfile["hotfolderfile"], $pathhd . $newname))
{
$propfile['pathhd'] = $pathhd;
$propfile['file'] = $newname;
$propfile['inbase'] = 1;
$fl = 'record_id'; $vl = $rid;
$fl .= ', name'; $vl .= ", 'document'";
$fl .= ', path'; $vl .= ", '" . $connbas->escape_string($propfile['pathhd']) . "'";
$fl .= ', file'; $vl .= ", '" . $connbas->escape_string($propfile['file']) . "'";
$fl .= ', inbase'; $vl .= ", '" . $propfile['inbase'] . "'";
if(isset($propfile['width']))
{
$fl .= ', width'; $vl .= ", '" . $connbas->escape_string($propfile['width']) . "'";
}
if(isset($propfile['height']))
{
$fl .= ', height'; $vl .= ", '" . $connbas->escape_string($propfile['height']) . "'";
}
$fl .= ', mime'; $vl .= ", '" . $connbas->escape_string($propfile['mime']) . "'";
$fl .= ', size'; $vl .= ", '" . $connbas->escape_string($propfile['size']) . "'";
$fl .= ', dispatched'; $vl .= ", '1'";
$sql = "INSERT INTO subdef (".$fl.") VALUES (".$vl.")";
if($connbas->query($sql))
{
if(isset($session->logs[$sbas_id]))
{
$sql = 'INSERT INTO log_docs (id, log_id, date, record_id, action, final, comment) VALUES (null, "'.$connbas->escape_string($session->logs[$sbas_id]).'", now(), "'.$connbas->escape_string($rid).'", "add", "'.$connbas->escape_string($cid).'","")';
$connbas->query($sql);
}
}
}
@unlink($propfile["hotfolderfile"]);
}
else
{
// archiving 'in place'
}
$batch['records'][] = $rid;
}
$rid++;
}
}
$conn->free_result($rs);
}
@p4::logout();
rmdir($path);
return $batch;
}
}
?>