src/Controller/DatasourceController.php line 193

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use AdimeoDataSuite\Datasource\WebCrawler;
  4. use AdimeoDataSuite\Model\Datasource;
  5. use AdimeoDataSuite\Model\DummyOutputManager;
  6. use Symfony\Component\Filesystem\Filesystem;
  7. use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
  8. use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
  9. use Symfony\Component\Form\Extension\Core\Type\IntegerType;
  10. use Symfony\Component\Form\Extension\Core\Type\SubmitType;
  11. use Symfony\Component\Form\Extension\Core\Type\TextareaType;
  12. use Symfony\Component\Form\Extension\Core\Type\TextType;
  13. use Symfony\Component\HttpFoundation\Request;
  14. use Symfony\Component\HttpFoundation\Response;
  15. class DatasourceController extends AdimeoDataSuiteController
  16. {
  17.   public function listDatasourcesAction(Request $request) {
  18.     $datasourceTypes = [];
  19.     $ids $this->container->getParameter('adimeodatasuite.datasources');
  20.     foreach($ids as $id) {
  21.       /** @var Datasource $ds */
  22.       $ds $this->container->get($id);
  23.       $datasourceTypes[$ds->getDisplayName()] = get_class($ds);
  24.     }
  25.     $form $this->createFormBuilder(null)
  26.       ->add('dataSourceType'ChoiceType::class, array(
  27.         'choices' => array($this->get('translator')->trans('Select') . ' >' => '') + $datasourceTypes,
  28.         'required' => true,
  29.       ))
  30.       ->add('ok'SubmitType::class, array(
  31.         'label' => $this->get('translator')->trans('Add')
  32.       ))
  33.       ->getForm();
  34.     $form->handleRequest($request);
  35.     if ($form->isSubmitted() && $form->isValid()) {
  36.       $data $form->getData();
  37.       return $this->redirect($this->generateUrl('datasource-add', array('datasourceType' => $data['dataSourceType'])));
  38.     }
  39.     return $this->render('datasource.html.twig', array(
  40.       'title' => $this->get('translator')->trans('Data sources'),
  41.       'main_menu_item' => 'datasources',
  42.       'datasources' => $this->getIndexManager()->listObjects('datasource'$this->buildSecurityContext()),
  43.       'form_add_datasource' => $form->createView(),
  44.       'procs' => $this->getRunningDatasources()
  45.     ));
  46.   }
  47.   public function addOrEditDatasourceAction(Request $request) {
  48.     if ($request->get('datasourceType') != null) {
  49.       $datasourceType $request->get('datasourceType');
  50.       /** @var Datasource $datasource */
  51.       $datasource = new $datasourceType();
  52.       $edit false;
  53.     } elseif($request->get('id') != null) {
  54.       $datasource $this->getIndexManager()->findObject('datasource'$request->get('id'), $this->buildSecurityContext());
  55.       $edit true;
  56.     } else {
  57.       $this->addSessionMessage('error'$this->get('translator')->trans('No datasource type provided'));
  58.       return $this->redirect($this->generateUrl('datasources'));
  59.     }
  60.     $form $this->createFormBuilder($edit $datasource->getSettings() + array('hasBatchExecution' => $datasource->hasBatchExecution()) : NULL);
  61.     $form->add('name'TextType::class, array(
  62.       'label' => $this->get('translator')->trans('Name'),
  63.       'required' => true,
  64.     ));
  65.     $this->addControls($form$datasource->getSettingFields(), $datasource);
  66.     $form->add('hasBatchExecution'CheckboxType::class, array(
  67.       'label' => $this->get('translator')->trans('Has batch execution'),
  68.       'required' => false
  69.     ));
  70.     $form->add('submit'SubmitType::class, array(
  71.       'label' => $this->get('translator')->trans($edit 'Update datasource' 'Create datasource')
  72.     ));
  73.     $form $form->getForm();
  74.     $form->handleRequest($request);
  75.     if ($form->isSubmitted() && $form->isValid()) {
  76.       $settings $this->handleFileUpload($form$datasource->getSettingFields());;
  77.       $datasource->setHasBatchExecution($settings['hasBatchExecution']);
  78.       unset($settings['hasBatchExecution']);
  79.       $datasource->setSettings($settings);
  80.       if(!$edit) {
  81.         $datasource->setCreatedBy($this->container->get('security.token_storage')->getToken()->getUser()->getUid());
  82.       }
  83.       $this->getIndexManager()->persistObject($datasource);
  84.       $this->addSessionMessage('status'$this->get('translator')->trans('Datasource has been added'));
  85.       return $this->redirect($this->generateUrl('datasources'));
  86.     }
  87.     return $this->render('datasource.html.twig', array(
  88.       'title' => $this->get('translator')->trans($edit 'Edit datasource' 'New datasource'),
  89.       'main_menu_item' => 'datasources',
  90.       'form' => $form->createView()
  91.     ));
  92.   }
  93.   public function executeDatasourceAction(Request $request) {
  94.     if ($request->get('id') != null) {
  95.       /** @var Datasource $instance */
  96.       $instance $this->getIndexManager()->findObject('datasource'$request->get('id'));
  97.       $procs $this->getRunningDatasources();
  98.       if(isset($procs[$instance->getId()])){
  99.         return $this->render('datasource.html.twig', array(
  100.           'title' => $this->get('translator')->trans('Monitor "@ds_name"', array('@ds_name' => $instance->getName())),
  101.           'main_menu_item' => 'datasources',
  102.           'proc' => $procs[$instance->getId()],
  103.           'datasource' => $instance
  104.         ));
  105.       }
  106.       else {
  107.         $form $this->createFormBuilder();
  108.         $this->addControls($form$instance->getExecutionArgumentFields(), $instance);
  109.         $form->add('submit'SubmitType::class, array(
  110.           'label' => $this->get('translator')->trans('Execute')
  111.         ));
  112.         $form $form->getForm();
  113.         $form->handleRequest($request);
  114.         if ($form->isSubmitted() && $form->isValid()) {
  115.           $data $this->handleFileUpload($form$instance->getExecutionArgumentFields());
  116.           $this->launchProcess($data$instance->getId());
  117.           $this->addSessionMessage('status'$this->get('translator')->trans('Datasource has been launched'));
  118.           return $this->redirect($this->generateUrl('datasource-exec', array('id' => $instance->getId())));
  119.         }
  120.         return $this->render('datasource.html.twig', array(
  121.           'title' => $this->get('translator')->trans('Execute "@ds_name"', array('@ds_name' => $instance->getName())),
  122.           'main_menu_item' => 'datasources',
  123.           'form' => $form->createView()
  124.         ));
  125.       }
  126.     } else {
  127.       $this->addSessionMessage('error'$this->get('translator')->trans('No id provided'));
  128.       return $this->redirect($this->generateUrl('datasources'));
  129.     }
  130.   }
  131.   private function launchProcess($args$id){
  132.     $paramsQsR = [];
  133.     foreach($args as $k => $v){
  134.       $paramsQsR[] = '"' str_replace('"''\\"'$v) . '"';
  135.     }
  136.     $paramsQs implode(' '$paramsQsR);
  137.     $output $this->getOutputFile($id);
  138.     popen($this->getCommand($id) . ' ' $paramsQs ' > ' $output ' 2>&1 &''w');
  139.   }
  140.   private function getOutputFile($id){
  141.     $fs = new Filesystem();
  142.     if(!$fs->exists(__DIR__ '/../../var')){
  143.       $fs->mkdir(__DIR__ '/../../var');
  144.     }
  145.     if(!$fs->exists(__DIR__ '/../../var/outputs')){
  146.       $fs->mkdir(__DIR__ '/../../var/outputs');
  147.     }
  148.     return __DIR__ '/../../var/outputs/' $id;
  149.   }
  150.   private function getCommand($id){
  151.     $bin PHP_BINARY;
  152.     if(!is_executable($bin)){
  153.       $bin PHP_BINDIR '/php';
  154.     }
  155.     $console __DIR__ '/../../bin/console';
  156.     $cmd '"' $bin '" "' $console '" ads:exec ' $id;
  157.     return $cmd;
  158.   }
  159.   private function getOutputContent($id$offset 0){
  160.     if(file_exists($this->getOutputFile($id)))
  161.       $content file_get_contents($this->getOutputFile($id), nullnull$offset);
  162.     else
  163.       $content '';
  164.     return $content;
  165.   }
  166.   private function getRunningDatasources(){
  167.     $r = array();
  168.     $procs '';
  169.     exec('ps aux | grep -i "ads:exec" | grep -v "grep"'$procs);
  170.     exec('ps aux | grep -i "ads:oai" | grep -v "grep"'$procs);
  171.     foreach($procs as $proc){
  172.       $raw preg_split('/[ ]+/'$proc);
  173.       $info = array(
  174.         'pid' => $raw[1],
  175.         'owner' => $raw[0],
  176.         'cpu' => $raw[2],
  177.         'mem' => $raw[3],
  178.         'time' => $raw[9],
  179.       );
  180.       if(isset($raw[13])){
  181.         $info['id'] = $raw[13];
  182.         $r[$raw[13]] = $info;
  183.       }
  184.     }
  185.     return $r;
  186.   }
  187.   public function kill($id){
  188.     $procs $this->getRunningDatasources();
  189.     if(isset($procs[$id])){
  190.       $pid $procs[$id]['pid'];
  191.       exec('kill -9 ' $pid);
  192.     }
  193.   }
  194.   public function getDatasourceOutputAction(Request $request) {
  195.     $output $this->getOutputContent($request->get('id'), $request->get('from'));
  196.     return new Response($output200, array('Content-Type' => 'text/plain; charset=utf-8'));
  197.   }
  198.   public function killDatasourceAction(Request $request) {
  199.     if ($request->get('id') != null) {
  200.       $this->kill($request->get('id'));
  201.       $this->addSessionMessage('status'$this->get('translator')->trans('Datasource has been killed'));
  202.     } else {
  203.       $this->addSessionMessage('error'$this->get('translator')->trans('No id provided'));
  204.     }
  205.     return $this->redirect($this->generateUrl('datasources'));
  206.   }
  207.   public function deleteDatasourceAction(Request $request) {
  208.     if ($request->get('id') != null) {
  209.       $this->getIndexManager()->deleteObject($request->get('id'));
  210.       $this->addSessionMessage('status'$this->get('translator')->trans('Datasource has been deleted'));
  211.     } else {
  212.       $this->addSessionMessage('error'$this->get('translator')->trans('No id provided'));
  213.     }
  214.     return $this->redirect($this->generateUrl('datasources'));
  215.   }
  216.   public function ajaxListDatasourcesAction(Request $request) {
  217.     $datasources $this->getIndexManager()->listObjects('datasource'$this->buildSecurityContext());
  218.     $r = [];
  219.     foreach($datasources as $datasource){
  220.       /** @var Datasource $datasource */
  221.       $r[] = array(
  222.         'id' => $datasource->getId(),
  223.         'name' => $datasource->getName(),
  224.         'class' => get_class($datasource)
  225.       );
  226.     }
  227.     return new Response(json_encode($rJSON_PRETTY_PRINT), 200, array('Content-type' => 'application/json; charset=utf-8'));
  228.   }
  229.   public function webCrawlerResponseAction(Request $request) {
  230.     if($request->get('datasourceId') != null){
  231.       $datasource $this->getIndexManager()->findObject('datasource'$request->get('datasourceId'));
  232.       if($datasource instanceof WebCrawler) {
  233.         $datasource->initForExecution($this->getIndexManager(), new DummyOutputManager(), $this->container->get('adimeo_data_suite_pdo_pool'));
  234.         $datasource->handleDataFromCallback(array(
  235.           'title' => $request->get('title') != null $request->get('title') : '',
  236.           'html' => $request->get('html') != null $request->get('html') : '',
  237.           'url' => $request->get('url') != null $request->get('url') : '',
  238.         ));
  239.         return new Response(json_encode(array('Status' => 'OK')), 200, array('Content-type' => 'text/html; charset=utf-8'));
  240.       }
  241.     }
  242.     return new Response(json_encode(array('Error' => 'Provided datasource is incorrect')), 400, array('Content-type' => 'application/json'));
  243.   }
  244. }