| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523 |
- <?php
- Lib::loadClass('RouteBase');
- Lib::loadClass('UI');
- Lib::loadClass('DBG');
- Lib::loadClass('Request');
- Lib::loadClass('Response');
- Lib::loadClass('Crypt');
- Lib::loadClass('Route_Ant');
- class Route_UrlAction_Ant extends Route_Ant {// @doc @see Route_Ant
- public function handleAuth() {
- if (!User::logged()) {
- User::authByRequest();
- }
- session_write_close();
- }
- public function defaultAction() {
- UI::gora();
- UI::menu();
- UI::startContainer();
-
- echo UI::h('div', [ 'class' => "pull-right" ], [
- UI::h('a', [
- 'href' => $this->getLink('listLastJobs'),
- 'class' => "btn btn-link",
- ], "Ostatnio uruchione"),
- UI::hButtonPost("Odśwież", [
- 'class' => "btn btn-link",
- // 'form.class' => "pull-right",
- 'title' => "Wczytaj ponownie listę dostępnych funkcji",
- 'data' => [
- 'forceUpdate' => '1',
- ]
- ]),
- ]);
- echo UI::h('h1', [], 'Druki');
- UI::tryCatchView([ $this, 'listAntView' ]);
- UI::endContainer();
- UI::dol();
- }
- function listAntView() {
- $taskList = $this->getAntUrlActionList();
- // $featureID = V::get('featureID', '', $_GET);
- $primaryKey = V::get('primaryKey', '', $_GET, 'word');
- $typeName = V::get('typeName', '', $_GET, 'word');
- if (empty($typeName)) throw new Exception("Missing typeName");
- if (empty($primaryKey)) throw new Exception("Missing primaryKey");
- $parsedInfo = Core_AclHelper::parseTypeName($typeName);
- DBG::log($parsedInfo, '', "Ant parseTypeName({$typeName})");
- $acl = ACL::getAclByNamespace("{$parsedInfo['url']}/{$parsedInfo['name']}");
- $pkField = $acl->getPrimaryKeyField();
- echo UI::h('p', [ 'class' => "text-muted" ], [
- "Druki dla rekordu '{$primaryKey}' w tabeli ",
- UI::h('a', [
- 'href' => Router::getRoute('ViewTableAjax')->getLink('', [ 'namespace' => $acl->getNamespace() ])
- ], $acl->getRawLabel()),
- ]);
- UI::inlineJS( __FILE__ . '.async.js', [ // p5UI_runAntAsyncJob
- 'RUN_ANT_JOB_URL' => $this->getLink('startAntJobAjax'),
- 'RUN_TEST_ANT_JOB_URL' => $this->getLink('startTestAntJobAjax'),
- ]);
- // echo UI::h('div', [ 'style' => "padding-bottom:8px; border-bottom:1px solid #eee;" ], [
- // UI::h('select', [ 'class' => "form-control" ], array_map(function ($label, $path) {
- // return UI::h('option', [ 'value' => $path ], $label);
- // }, $taskList, array_keys($taskList))),
- // ]);
- UI::startTag('ul');
- foreach ($taskList as $path => $label) {
- echo UI::h('li', [], [
- UI::h('a', [
- 'class' => 'btn btn-md btn-link',
- 'href' => $this->getLink('ant', [
- 'path' => $path,
- 'typeName' => $typeName,
- 'primaryKey' => $primaryKey,
- 'primaryKeyField' => $pkField
- ])
- ], "Uruchom '{$label}'")
- ]);
- $tmpls = $this->getAntUrlActionTemplates($path);
- if (!empty($tmpls)) {
- foreach ($tmpls as $tmpl => $labelTmpl) {
- echo UI::h('div', [ 'style' => "padding-left: 50px" ], [
- UI::h('a', [
- 'href' => $this->getLink('ant', [
- 'path' => $path,
- 'template' => $tmpl,
- 'typeName' => $typeName,
- 'primaryKey' => $primaryKey,
- 'primaryKeyField' => $pkField
- ]),
- 'class' => 'btn btn-sm btn-link',
- ], '<i class="glyphicon glyphicon-arrow-right"></i> ' . $labelTmpl),
- " ",
- UI::h('a', [
- 'href' => $this->getLink('ant', [
- 'path' => $path,
- 'template' => $tmpl,
- 'typeName' => $typeName,
- 'primaryKey' => $primaryKey,
- 'primaryKeyField' => $pkField
- ]),
- 'onclick' => 'return p5UI_runAntAsyncJob(event, this)',
- 'data-namespace' => $acl->getNamespace(),
- 'data-primaryKey' => $primaryKey,
- 'data-ant_path' => $path,
- 'data-ant_template' => $tmpl,
- 'class' => 'btn btn-xs btn-default',
- 'title' => "Uruchom asynchronicznie",
- ], "uruchom"),
- " ",
- // UI::h('a', [
- // 'href' => $this->getLink('ant', [
- // 'path' => $path,
- // 'template' => $tmpl,
- // 'typeName' => $typeName,
- // 'primaryKey' => $primaryKey,
- // 'primaryKeyField' => $pkField
- // ]),
- // 'onclick' => 'return p5UI_runAntAsyncJob(event, this, { TEST: 1 })',
- // 'data-namespace' => $acl->getNamespace(),
- // 'data-primaryKey' => $primaryKey,
- // 'data-ant_path' => $path,
- // 'data-ant_template' => $tmpl,
- // 'class' => 'btn btn-xs btn-link',
- // 'title' => "TEST Uruchom asynchronicznie",
- // ], "test"),
- ]);
- }
- }
- }
- UI::endTag('ul');
- }
- function listLastJobsAction() { UI::layout([ get_called_class(), 'listLastJobsView' ]); }
- static function listLastJobsView() {
- echo UI::h('ol', [ 'class' => "breadcrumb" ], [
- UI::h('li', [], [
- UI::h('a', [ 'href' => self::link() ], [
- UI::h('i', [ 'class' => "glyphicon glyphicon-home", 'style' => "margin-right:6px" ]), // TODO: mv to h('p5:icon', [ 'type' => "home" ])
- " ",
- "Druki",
- ]),
- ]),
- UI::h('li', [], [
- "Ostatnio uruchomione zadania",
- ]),
- ]);
- echo UI::h('h1', [], "Ostatnio uruchomione zadania");
- $postTask = V::get('postTask', '', $_POST);
- if ('asyncJobStart' === $postTask) UI::tryCatchView([ get_called_class(), 'asyncJobStartPostTask' ], [ 'args' => $_POST ]);
- UI::table([
- 'disable_lp' => true,
- 'rows' => array_map(function ($item) {
- return array_merge(
- [
- '#' => '',
- 'Nr' => '',
- 'Status' => '',
- ],
- $item,
- [
- '#' => self::jobListItem_Akcje($item),
- 'Nr' => $item['ID'],
- 'Status' => self::jobListItem_Status($item['A_STATUS'], $item),
- ]
- );
- }, self::fetchUserLastAsyncJobs()),
- ]);
- throw new Exception("TODO: list last jobs");
- }
- static function fetchUserLastAsyncJobs() {
- return DB::getPDO()->fetchAll("
- select j.*
- from CRM_ASYNC_JOB_LOG j
- where j.USER = :user
- order by ID DESC
- ", [
- ':user' => User::getLogin(),
- ]);
- }
- static function jobListItem_Akcje($item) {
- return UI::h('div', [ 'class' => "btn-group" ], [
- UI::h('button', [
- // 'type' => "button",
- 'class' => "btn btn-xs btn-default dropdown-toggle",
- 'data-toggle' => "dropdown",
- ], [
- // UI::h('i', [ 'class' => "glyphicon glyphicon-hamburder" ])
- 'Akcje ',
- UI::h('span', [ 'class' => "caret" ]),
- ]),
- UI::h('ul', [ 'class' => "dropdown-menu" ], [
- UI::h('li', [], [
- UI::h('a', [
- 'href' => self::link('asyncJobDebug', [ 'id' => $item['ID'] ]),
- ], "Debug Info '{$item['ID']}'"),
- ]),
- UI::h('li', [], [
- UI::hButtonPost("Uruchom zadanie '{$item['ID']}'", [
- 'class' => "p5-hover",
- 'style' => "padding:3px 20px",
- // 'form.class' => "pull-right",
- // 'title' => "",
- 'data' => [
- 'postTask' => 'asyncJobStart',
- 'id' => $item['ID'],
- ]
- ]),
- ]),
- // <li role="separator" class="divider"></li>
- ]),
- ]);
- }
- static function jobListItem_Status($status, $item) {
- switch ($status) {
- case 'WAITING': return UI::h(null, null, [
- "Oczekujący",
- ]);
- case 'NORMAL': return UI::h(null, null, [
- "Uruchomiony",
- ]);
- case 'OFF_HARD': return UI::h(null, null, [
- "Zakończony",
- ]);
- default: return UI::h(null, null, $status);
- }
- }
- static function asyncJobStartPostTask($args) {
- DBG::nicePrint($args, 'DBG: $args');
- $idJob = V::get('id', 0, $args, 'int');
- if ($idJob <= 0) throw new Exception("Missing id");
- Lib::loadClass('Core_AsyncJobs');
- Core_AsyncJobs::startAsyncJob($idJob);
- throw new Exception("TODO: asyncJobStartPostTask");
- }
- function asyncJobDebugAction() { UI::layout([ $this, 'asyncJobDebugView' ]); }
- function asyncJobDebugView() {
- echo UI::h('ul', [ 'class' => "breadcrumb" ], [
- UI::h('li', [], [
- UI::h('a', [ 'href' => $this->getLink('listLastJobs') ], "Ostatnio uruchomione zadania"),
- ]),
- UI::h('li', [ 'class' => "active" ], [
- "Zadanie - Debug",
- ]),
- ]);
- $idJob = V::get('id', 0, $_GET, 'int');
- if ($idJob <= 0) throw new Exception("Missing job ID");
- $item = DB::getPDO()->fetchFirst("
- select j.ID
- -- , j.ID_FUNCTION
- -- , j.ID_SOURCE_JOB
- -- , j.P_ID
- , j.DATE -- 2020-02-26
- -- , j.VERSION
- , j.JOB_NAME -- Ant|default_db/IN7_DZIENNIK_KORESP|default_db.in7_dziennik_koresp/test-async|test-loop
- , j.LOCK_VALUE -- 66263
- -- , j.USER
- , j.A_STATUS
- , j.A_RECORD_CREATE_DATE
- , j.A_RECORD_CREATE_AUTHOR
- , j.A_RECORD_UPDATE_DATE
- , j.A_RECORD_UPDATE_AUTHOR
- from CRM_ASYNC_JOB_LOG j
- where j.USER = :user
- and j.ID = :id
- ", [
- ':id' => $idJob,
- ':user' => User::getLogin(),
- ]);
- if (!$item) throw new Exception("Zadanie nie istnieje");
- DBG::nicePrint($item, "Zadanie '{$idJob}'");
- // TODO: files list in task folder
- Lib::loadClass('Core_AsyncJobsFiles');
- $basePath = Core_AsyncJobsFiles::basePath($item['ID'], $item['DATE']);
- $propertyFile = Core_AsyncJobsFiles::propertyFile($item['ID'], $item['DATE']);
- $startScript = Core_AsyncJobsFiles::startScript($item['ID'], $item['DATE']);
- $outLog = Core_AsyncJobsFiles::outLog($item['ID'], $item['DATE']);
- $errorLog = Core_AsyncJobsFiles::errorLog($item['ID'], $item['DATE']);
- DBG::nicePrint([
- 'basePath' => $basePath,
- 'propertyFile' => $propertyFile,
- 'startScript' => $startScript,
- 'outLog' => $outLog,
- 'errorLog' => $errorLog,
- ], "DBG:job files");
- DBG::nicePrint(shell_exec("ls -l '{$basePath}'"), 'DBG: basePath');
- DBG::nicePrint(shell_exec("cat '{$propertyFile}'"), 'DBG: propertyFile');
- DBG::nicePrint(shell_exec("cat '{$startScript}'"), 'DBG: startScript');
- DBG::nicePrint(shell_exec("cat '{$outLog}'"), 'DBG: outLog');
- DBG::nicePrint(shell_exec("cat '{$errorLog}'"), 'DBG: errorLog');
- throw new Exception("TODO: asyncJobDebug");
- }
- public function outputAction() {// index.php?_route=UrlAction_Ant&_task=output & path={$path} & file={$file}";
- $path = V::get('path', '', $_GET);
- if (!$path) throw new Exception("Missing Ant path!");
- $file = V::get('file', '', $_GET);
- if (!$file) throw new Exception("Missing Ant file!");
- // TODO: allow auth by token?
- throw new Exception("TODO: return output file '$file' from ant task '{$path}'");
- }
- function startTestAntJobAjaxAction() { Response::sendTryCatchJson([ $this, 'startTestAntJobAjax' ], $args = 'JSON_FROM_REQUEST_BODY'); }
- function startTestAntJobAjax($args) {
- sleep(2);
- $ret = rand(0, 1);
- switch ($ret) {
- case 1: return [
- 'type' => "success",
- 'msg' => "Dodano zadanie",
- 'body' => [
- 'id_job' => 123,
- ],
- ];
- // default: throw new Exception("TODO:startAntJobAjax");
- default: return [
- 'type' => "error",
- 'msg' => "Wystąpił błąd podczas dodawania zadania",
- ];
- }
- }
- function startAntJobAjaxAction() { Response::sendTryCatchJson([ $this, 'startAntJobAjax' ], $args = 'JSON_FROM_REQUEST_BODY'); }
- function startAntJobAjax($args) {
- // $args = body: JSON.stringify({
- // namespace: "default_db/IN7_DZIENNIK_KORESP"
- // primaryKey: "66263"
- // ant_path: "default_db.in7_dziennik_koresp/test-bash"
- // ant_template: "test-loop"
- // })
- $namespace = V::get('namespace', '', $args);
- $primaryKey = V::get('primaryKey', '', $args);
- $ant_path = V::get('ant_path', '', $args);
- $ant_template = V::get('ant_template', '', $args);
- if (empty($namespace)) throw new Exception("Missing namespace");
- if (empty($primaryKey)) throw new Exception("Missing primaryKey");
- if (empty($ant_path)) throw new Exception("Missing ant_path");
- if (empty($ant_template)) throw new Exception("Missing ant_template");
- // TODO: convert antAction to async mode
- // - register async job or get jobID
- // - if exists: show last call info (result, when, etc.) + run again btn
- // - if not exists: create new folder with base files, create exec script, run this script in pm2 start
- // - parse result into AsyncJob/output and AsyncJob/output_type
- Lib::loadClass('Core_AsyncJobs');
- $idJob = Core_AsyncJobs::registerNewAntTask([
- 'namespace' => $namespace,
- 'primaryKey' => $primaryKey,
- 'ant_path' => $ant_path,
- 'ant_template' => $ant_template,
- ]);
- if (!$idJob) throw new Exception("Wystąpił błąd podczas dodawania zadania");
- return [
- 'type' => "success",
- 'msg' => "Dodano zadanie",
- '__DBG__args' => $args,
- ];
- }
- public function antAction() {
- UI::gora();
- UI::startContainer();
- try {
- $path = V::get('path', '', $_GET);
- if (!$path) throw new Exception("Missing Ant path!");
- $typeName = V::get('typeName', '', $_GET);
- if (!$typeName) throw new Exception("Missing typeName");
- $primaryKey = V::get('primaryKey', '', $_GET);
- if (!$primaryKey) throw new Exception("Missing primaryKey");
- $pkField = V::get('primaryKeyField', '', $_GET);
- if (!$pkField) throw new Exception("Missing primaryKeyField");
- // list($nsPrefix, $objectName) = explode(':', $typeName);// TODO: get wfs prefix from typeName
- $parsedInfo = Core_AclHelper::parseTypeName($typeName);
- DBG::log($parsedInfo, '', "Ant parseTypeName({$typeName})");
- $nsPrefix = $parsedInfo['prefix'];
- $objectName = $parsedInfo['name'];
- $template = V::get('template', '', $_GET);
- $confirmAntfile = V::get('confirmAntfile', '', $_GET);
- $confirmAntfileTarget = V::get('confirmAntfileTarget', '', $_GET);
- // TODO: validate missing ...
- DBG::log($_GET, 'array', '$_GET');
- DBG::log([ 'msg'=>'$path', '$path'=>$path]);
- DBG::log([ 'msg'=>'$primaryKey', '$primaryKey'=>$primaryKey]);
- DBG::log([ 'msg'=>'$typeName', '$typeName'=>$typeName]);
- $taskList = $this->getAntUrlActionList();
- if (!array_key_exists($path, $taskList)) throw new Exception("Ant path not exists! '{$path}'");
- echo UI::h('h3', [], [
- "Druk",
- '<br>',
- UI::h('small', [], $taskList[$path])
- ]);
- echo UI::h('hr');
- $webRootUrl = Request::getPathUri() . "schema/ant-url_action/{$path}";// TODO: security - only for test
- $outputFunctionUrl = $this->getLink('output') . "&path={$path}&file=";
- $antFunctionUrl = $this->getLink('ant') . "&path={$path}&file={$file}&template={$template}&typeName={$typeName}&primaryKey={$primaryKey}&primaryKeyField={$pkField}"; // &confirmAntfile={$confirmAntfile}&confirmAntfileTarget={$confirmAntfileTarget} sdo confirmacji potrzebne - wzglednie przetwarzac z tresci output URL_TASK - ale potrzebne parametry analogiczne aby chodzily
- DBG::log([ 'msg'=>'$webRootUrl', '$webRootUrl'=>$webRootUrl]);
- DBG::log([ 'msg'=>'$outputFunctionUrl', '$outputFunctionUrl'=>$outputFunctionUrl]);
- $testUrl = Request::getPathUri() . "wfs-data.php/default_db/?SERVICE=WFS&VERSION=1.0.0&TYPENAME={$typeName}&SRSNAME=EPSG:3003&featureID={$objectName}.{$primaryKey}";// &REQUEST=GetFeature
- // $testUrl = Request::getPathUri() . "wfs-data.php" ;// &REQUEST=GetFeature
- $cryptedPass = base64_encode(User::getLogin() . ":" . Crypt::decrypt($_SESSION['ADM_PASS_HASH']));
- $uniqID = date("Y-m-d-H_i_s") . substr(md5(time()), 0, 6);// TODO: uniq id for every request
- // $cmd = "{$this->pathUrlActions}/{$path}/do_build.sh";
- $cmd = "cd {$this->pathUrlActions}/{$path} && ant -S";
- // ant -silent, -S print nothing but task outputs and build failures
- // ant -D<property>=<value> use value for given property
- // ant -propertyfile <name> load all properties from file with -D properties taking precedence
- // TODO: mv to build.properties file @see https://dzone.com/tutorials/java/ant/ant-properties-file.html
- // ant -propertyfile build.properties
- $cmd .= " -DoutputFunctionUrl='{$outputFunctionUrl}'";
- $cmd .= " -DantFunctionUrl='{$antFunctionUrl}'";
- if( strlen($confirmAntfile) > 0 ) $cmd .= " -DconfirmAntfile={$confirmAntfile}";
- if( strlen($confirmAntfileTarget) > 0 ) $cmd .= " -DconfirmAntfileTarget={$confirmAntfileTarget}";
- $cmd .= " -DwebRootUrl='{$webRootUrl}'";
- // $cmd .= " -Durl='{$testUrl}'"; nie mozna tego uzywac, bo nadpisuje property w funkcji build_get_wfs.xml
- $cmd .= " -DpasswordBase64Basic=\"{$cryptedPass}\"";
- $cmd .= " -Duuid=\"{$uniqID}\"";
- $cmd .= " -Dphp_session_id=\"" . session_id() . "\"";
- $cmd .= " -Dxpath={$pkField}";
- $cmd .= " -Dxpath_value={$primaryKey}";
- $cmd .= " -Dtemplate={$template}";
- $cmd .= " -Dapi_url=".Request::getPathUri()."wfs-data.php"; //potrzebuje ten parametr do dzialania w AMS itp
- $cmd .= " -DtypeName=\"{$typeName}\"";
- if ($template) $cmd .= " {$template} ";
- $cmd .= " 2>&1";
- $pathCmd = [];
- $pathCmd[] = '/opt/local/bin/ant';
- $pathCmd[] = '/bin';
- $pathCmd[] = '/usr/bin';
- $pathCmd[] = '/usr/local/bin';
- $pathCmd[] = '/opt/local/bin';
- $pathCmd[] = '/sbin';
- $pathCmd[] = '/usr/sbin';
- $pathCmd[] = '/opt/local/sbin/skrypty';
- $pathCmd[] = '/opt/local/var/macports/software';
- $pathCmd[] = '/Applications/Server.app/Contents/ServerRoot/usr/bin';
- $pathCmd[] = '/Applications/Server.app/Contents/ServerRoot/usr/sbin';
- $cmd = 'export PATH=' . implode(':', $pathCmd) . "\n" .
- 'JAVA_HOME="/usr/bin/java"' . "\n" .
- 'MAVEN_OPTS="-Xms256m -Xmx512m"' . "\n" .
- $cmd;
- $useShellExec = true;
- if (User::isAdmin()) {
- echo UI::h('details', [], [
- UI::h('summary', [ 'style' => "padding:3px 8px;border:1px solid #ccc;background-color:#282c34;color:#de6b74;font-size:small" ], "DBG: command"),
- UI::h('div', [ 'style' => "padding:12px; background:#282c34;" ], [
- UI::h('pre', [], $cmd),
- ]),
- ]);
- }
- if ($useShellExec) $out = shell_exec($cmd);
- else V::exec($cmd, $out, $ret);
- DBG::log([ 'msg'=>"cmd and returns({$ret})", 'output'=>$out, 'cmd'=>str_replace(APP_PATH_ROOT, 'SE', $cmd) ]);
- if (empty($out)) throw new Exception("Empty output");
- if ($useShellExec) $out = explode("\n", $out);
- $outputType = 'HTML';
- $html = []; $startRead = false;
- foreach ($out as $line) {
- if (!$startRead) {
- if ('OUTPUT__TYPE__XML' == $line) $outputType = 'XML';
- if ('OUTPUT__TYPE__HTML' == $line) $outputType = 'HTML';
- if ('OUTPUT__START' == $line) {
- $startRead = true;
- continue;
- }
- } else {
- if ('<!DOCTYPE' == substr($line, 0, strlen('<!DOCTYPE'))) continue;
- if ('OUTPUT__END' == $line) {
- break;
- }
- $html[]= $line;
- }
- }
- if (empty($html)) UI::alert('danger', "Empty output!");
- else {
- if ('XML' == $outputType) {
- echo UI::h('pre', [], htmlspecialchars(implode("\n", $html)));
- } else if ('HTML' == $outputType) {
- echo UI::h('div', ['class'=>"container", 'style'=>"padding:12px; border:1px solid #ddd"], $html);
- }
- }
- } catch (Exception $e) {
- UI::alert('danger', $e->getMessage());
- DBG::log($e);
- }
- UI::endContainer();
- UI::dol();
- }
- }
|