123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361 |
- <?php
- $api = new Api("skanman", "Api de scanner");
- //Envoi d'un scan
- $api->route('commit',"Validation d'un envois de scan (json)",'POST',function($request,&$response){
- global $conf,$myUser,$_;
- $_ = json_decode($request['body'],true);
- if(empty($conf->get('skanman_api_user'))) throw new Exception("Api user is missing in erp configuration, please call an administator",501);
- if(empty($_['category'])) throw new Exception("Category missing",501);
- if(!isset($_['stack'])) throw new Exception("Stack is not defined");
- require_once(__DIR__.SLASH.'Scanfile.class.php');
- require_once(__DIR__.SLASH.'ScanCategory.class.php');
- $category = ScanCategory::load(array('slug'=>$_['category']) );
- Plugin::need('document/Element,document/ElementRight');
- Plugin::need('client/Client');
- $myUser = User::byLogin($conf->get('skanman_api_user'));
- $_SESSION['currentUser'] = serialize($myUser);
- $targetUser = new User();
- $targetUser->login = 'anonymous';
- if(!empty($_['user']) && !empty($_['user']['login'])) $targetUser = User::byLogin($_['user']['login']);
- $owner = $myUser;
- if($category->slug=='mine'){
- $category->path = $targetUser->fullName();
- $owner = $targetUser;
- }
- //Récuperation du dossier de construction de l'id commité
- $constructionDirectory = File::dir().'skanman'.SLASH.'tmp'.SLASH.$_['id'];
- if(!file_exists($constructionDirectory)) throw new Exception("Le dossier de construction '".$_['id']."' n'existe pas");
- //si la catégorie est dossier perso, on modifie le nom du dossier
- if($category->slug=='mine'){
- $category->path = $targetUser->fullName();
- $owner = $targetUser;
- }
- //Dossier de catégorie d'envois
- $path = Element::root().$category->path.SLASH;
- //Si le dossier de catégorie n'existe pas, on le créé
- if(!file_exists($path)){
- //Si la catégorie est dossier perso, on donne les droits uniquement au user concerné
- if($category->slug=='mine'){
- Element::addFolder($path,true,false, $owner->login);
- //Sinon on donne les droits au rang de tous les utilisateurs skanman
- }else{
- $element = Element::addFolder($path,true,false);
- $right = new ElementRight();
- $right->element = $element->id;
- $right->entity = 'rank';
- $right->uid = $conf->get('skanman_users_rank');
- $right->read = true;
- $right->edit = true;
- $right->recursive = true;
- $right->save();
- }
- }
- //Racine du fichier dans la ged
- $fileRoot = $path.$_['id'];
- //Liste des fichiers temporaires du dossier de consturction
- $files = glob($constructionDirectory.SLASH.'*.jpeg');
- $filesPathes = array();
- switch($_['stack']){
- case 'one-file':
- //Convertion en pdf
- if(!empty($conf->get('skanman_image_to_pdf'))){
- $filePath=$fileRoot.'.pdf';
- Image::toPdf($files,$filePath);
- //Convertion en image concatenée
- }else{
- $filePath=$fileRoot.'.jpeg';
- $response[] = $files;
- //print_r($filePath);
- Image::concatenate($files,$filePath);
- }
- $filesPathes[] = $filePath;
- break;
- case 'multiple-files':
- foreach($files as $i=>$file){
- //Convertion en pdf
- if(!empty($conf->get('skanman_image_to_pdf'))){
- $filePath=$fileRoot.'-'.$i.'.pdf';
- Image::toPdf(array($file),$filePath);
- //déplacement simple
- }else{
- $filePath=$fileRoot.'-'.$i.'.jpeg';
- rename($file,$filePath);
- }
- $filesPathes[] = $filePath;
- }
- break;
- }
-
- //Envoi par mail si l'option est sélectionnée
- if($category->slug == 'mail'){
- $mail = new Mail();
- $mail->recipients['to'][] = $targetUser->mail;
- $mail->title = 'Fichier envoyé depuis le scanner';
- $mail->message = $conf->get('skanman_mail_body');
-
- if(empty($mail->message)) $mail->message = 'Bonjour,<br/> le fichier çi-attaché vous a été envoyé depuis le scanner';
- foreach($filesPathes as $filePath){
- $mail->attachments[] = array(
- 'name' => basename($filePath),
- 'type' => File::mime($filePath),
- 'stream'=>file_get_contents($filePath)
- );
- }
- $mail->send();
- }
- //Pour chaque fichier définitif
- foreach($filesPathes as $filePath){
- //Sauvegarde de l'élément depuis le chemin du fichier physique
- $file = Element::fromPath($filePath);
- if($category->slug== 'mine') $file->creator = $targetUser->login;
- $file->save();
- //Création des metas infos de l'élément représenté par
- $scanFile = new Scanfile();
- $scanFile->label = $file->label;
- $tags = array();
- $tags[] = slugify($category->label);
- //Mini detection OCR, nécessite l'installation du paquet ocrmypdf et des paquet dictionnaires de langue
- if($conf->get('skanman_ocr_enable')){
- $command = array('export LC_ALL=C.UTF-8 && export LANG=C.UTF-8 &&','ocrmypdf');
- $command[] = '-l fra'; # it supports multiple languages
- $command[] = '--rotate-pages'; # it can fix pages that are misrotated
- $command[] = '--deskew'; # it can deskew crooked PDFs!
- $command[] = '--jobs 4'; # it uses multiple cores by default
- $command[] = '"'.$filePath.'"'; # takes PDF input (or images)
- $command[] = 'output_pdf'; # it produces PDF/A by default
- $command[] = '--sidecar -'; //__DIR__.SLASH.'output_searchable.pdf'; # produces validated PDF output
- $command = implode(' ',$command);
- $stream = mb_strtolower(shell_exec($command));
-
- $regexes = array(
- array(
- 'regex'=>'/[\s\n\t](prestation)[\s\n\t]/is',
- 'tag' => 'prestation'
- ),
- array(
- 'regex'=>'/[\s\n\t](m[eé]moire)[\s\n\t]/is',
- 'tag' => 'mémoire'
- ),
- array(
- 'regex'=>'/[\s\n\t](cahier des charges?)[\s\n\t]/is',
- 'tag' => 'cdc'
- ),
- array(
- 'regex'=>'/[\s\n\t](factur(es?|ations?))[\s\n\t]/is',
- 'tag' => 'facture'
- ),
- array(
- 'regex'=>'/[\s\n\t](statistiques?)[\s\n\t]/is',
- 'tag' => 'statistiques'
- ),
- array(
- 'regex'=>'/[\s\n\t](r[ée]gl[eé]e?|acquitt[ée]e?|pay[ée]e?)[\s\n\t]/is',
- 'tag' => 'acquitté'
- ),
- array(
- 'regex'=>'/[\s\n\t](frais?)[\s\n\t]/is',
- 'tag' => 'frais'
- ),
- array(
- 'regex'=>'/[\s\n\t](documentations?)[\s\n\t]/is',
- 'tag' => 'documentation'
- ),
- array(
- 'regex'=>'/[\s\n\t](restaurations?|restaurants?)[\s\n\t]/is',
- 'tag' => 'restauration'
- ),
- //emails
- array(
- 'regex'=>'/([a-z0-9\.\_\-]+@[a-z0-9]+\.(fr|com|net|org|edu|gouv))/is',
- 'tag' => '$1'
- ),
- //dates
- array(
- 'regex'=>'/[\s\n\t]([0-9]{2}[\-\/][0-9]{2}[\-\/][0-9]{2,4})[\s\n\t]/is',
- 'tag' => '$1'
- )
- );
- //Détection des noms de clients en base
- foreach(Client::loadAll() as $client){
- $regexes[] = array(
- 'regex'=>'|[\s\n\t]('.preg_quote($client->label).')[\s\n\t]|is',
- 'tag' => '$1'
- );
- }
- foreach($regexes as $regex){
- preg_match_all($regex['regex'],$stream,$out);
- if(count($out)==0 || count($out[0])==0) continue;
-
- if(preg_match('/\$([0-9]*)/is',$regex['tag'],$match)){
- if(!isset($out[$match[1]][0])) continue;
- $regex['tag'] = $out[$match[1]][0];
- }
- $tags[] = $regex['tag'];
- }
- }
- $scanFile->tag = implode(',',$tags);
- $scanFile->creator = $owner->login;
- $scanFile->element = $file->id;
- $scanFile->size = $file->size;
- $scanFile->save();
- }
- $myUser->getFirms();
- $firms = array_values($myUser->firms);
- //Save en historique
- $history = new History();
- $history->scope = 'skanman';
- $history->comment = 'Envois d\'un document';
- $history->comment .= ' utilisateur cible '.$targetUser->login;
- $history->comment .= ' catégorie cible '.$category->label;
- $history->save();
- //Trigger pour utilisation sur le workflow
- if(count($firms)>0 && $firms[0]->has_plugin('fr.core.workflow')){
- Plugin::need('workflow/WorkflowEvent');
- WorkflowEvent::trigger('skanman-scanfile-send',array('old'=>$scanFile, 'current'=>$scanFile));
- }
- });
- //Envoi d'un scan
- $api->route('send',"Envois d'un fichier scanné (binaire) et de ses catégories (json)",'POST',function($request,&$response){
- global $conf,$myUser,$_;
- $_ = json_decode($request['body'],true);
- preg_match('/boundary=([0-9a-z]*)/is',$request['headers']['content-type'],$match);
- $boundary = $match[1];
- $request['body'] = str_replace("\n\n".'--'.$boundary.'-','',$request['body']);
- $parts = explode('--'.$boundary."\n",$request['body']);
- $parts = array_filter($parts);
- $stream = '';
- foreach($parts as $i=>$part){
- $part = explode("\n\n",$part,2);
- preg_match('/Content-Type\s*:\s*([^;\n]*)/is',$part[0],$match);
- $mime = $match[1];
- switch($mime){
- case 'application/json':
- $_ = json_decode($part[1],true);
- break;
- default:
- $part[1] = str_replace('--'.$boundary.'-','',$part[1]);
- preg_match('/Content-Disposition\s*:.*filename\s*=\s*"([^;\n]*)"/is',$part[0],$match);
- $filename = isset($match[1]) ? $match[1] : 'file.jpeg';
- preg_match('/Content-Disposition\s*:.*;\s*name\s*=\s*"([^;\n]*)"/is',$part[0],$match);
- $name = isset($match[1]) ? $match[1] : 'file';
- $stream = $part[1];
- break;
- }
- }
- if(empty($conf->get('skanman_api_user'))) throw new Exception("Api user is missing in erp configuration, please call an administator",501);
- if(empty($_['category'])) throw new Exception("Category missing",501);
- $workspace = File::dir().'skanman';
- if(!file_exists($workspace)) mkdir($workspace,0755,true);
- $constructionDirectory = $workspace.SLASH.'tmp'.SLASH.$_['id'];
- //On ajoute le @ car le send multiple cause parfois un cas rare : le dossier est créé par un autre process send entre le moment du test de l'existence du dossier
- //et sa création effective ce qui cause une erreur
- if(!file_exists($constructionDirectory)) @mkdir($constructionDirectory,0755,true);
- $filePath = $constructionDirectory.SLASH.$_['number'];
- file_put_contents($filePath,$stream);
- if(!empty($conf->get('skanman_image_rotate'))) Image::rotate($filePath,$filePath,180);
- $response['id'] = $_['id'];
- $response['number'] = $_['number'];
- $response['success'] = true;
- });
- //Ping + récuperation des confs erp sur le scanner
- $api->route('ping',"Récuperation des configurations erp pour le scanner",'POST',function($request,&$response){
- global $conf,$myUser,$_;
- $_ = json_decode($request['body'],true);
- if(!$myUser || !$myUser->connected()) throw new Exception("Credentials are missing",401);
- if(empty($_['synchronizationVersion'])) throw new Exception("synchronization version is missing",401);
- if(empty($conf->get('skanman_api_user'))) throw new Exception("Api user is missing in erp configuration, please call an administator",501);
- if($conf->get('skanman_synchronization_version')==$_['synchronizationVersion']) return;
- require_once(__DIR__.SLASH.'Scanfile.class.php');
- require_once(__DIR__.SLASH.'ScanCategory.class.php');
-
- //On force le reload pour eviter le cache
- $conf->getAll(true);
- $users = array();
- $avatars = array();
- if(!empty($conf->get('skanman_users_rank'))){
- foreach (User::getAll() as $user) {
- if(!$user->hasRank($conf->get('skanman_users_rank'))) continue;
- $users[] = array(
- 'login'=>$user->login,
- 'fullName'=>$user->fullName(),
- 'mail'=>$user->mail,
- 'phone'=>$user->phone,
- 'mobile'=>$user->mobile
- );
- $avatars[$user->login] = array(
- 'stream'=>base64_encode(file_get_contents($user->getAvatar(true)) ),
- 'extension' => getExt($user->getAvatar(true))
- );
- }
- }
- $categories = array();
- foreach (ScanCategory::loadAll() as $category)
- $categories[$category->slug] = $category->toArray();
- $response['configuration'] = array(
- 'format' => $conf->get('skanman_scan_format'),
- 'color' => $conf->get('skanman_scan_color'),
- 'face' => $conf->get('skanman_scan_face'),
- 'stack' => $conf->get('skanman_scan_stack'),
- 'contrast' => $conf->get('skanman_scan_contrast' ),
- 'light' => $conf->get('skanman_scan_light'),
- 'resolution' => $conf->get('skanman_scan_resolution' ),
- 'categories' => $categories,
- 'pageHeight' => $conf->get('skanman_scan_page_height'),
- 'synchronizationVersion' => $conf->get('skanman_synchronization_version'),
- 'extraCss' => $conf->get('skanman_scan_css'),
- 'users' => $users,
- 'avatars' => $avatars,
- );
- $imageDirectory = File::dir().'skanman'.SLASH.'tosend';
- if(file_exists($imageDirectory)){
- $imagesToSend = glob($imageDirectory.SLASH.'*.{png,jpeg,jpg,bmp}',GLOB_BRACE);
- if(count($imagesToSend)>0){
- $response['configuration']['images'] = array();
- foreach($imagesToSend as $image){
- $response['configuration']['images'][] = array(
- 'stream'=>base64_encode(file_get_contents($image) ),
- 'label' => basename($image)
- );
- unlink($image);
- }
- }
- }
- });
- $api->register();
|