2016-06-22 05:49:20 +00:00
< ? php
namespace App\Console\Commands ;
use Log ;
use Illuminate\Console\Command ;
use App\Model\Person ;
use App\Model\PhotoPerson ;
use App\Model\Photo ;
use App\Model\PhotoTag ;
use App\Model\Tag ;
class Import extends Command
{
/**
* The name and signature of the console command .
*
* @ var string
*/
protected $signature = ' photo : import
{ -- dir = : Directory to Parse }
{ -- file = : File to import }
{ -- ignoredupe : Ignore duplicate files }
{ -- deletedupe : Delete duplicate files }
{ -- people = : People to reference in photo }
{ -- tags = : Add tag to photo } ' ;
/**
* The console command description .
*
* @ var string
*/
protected $description = 'Import photos into the database' ;
/**
* Create a new command instance .
*
* @ return void
*/
public function __construct ()
{
parent :: __construct ();
}
/**
* Execute the console command .
*
* @ return mixed
*/
public function handle ()
{
// Make sure we got a directory or a file to import
if ( is_null ( $this -> option ( 'file' )) AND is_null ( $this -> option ( 'dir' )))
abort ( 500 , 'Missing filename, please use --file= OR --dir=' );
Log :: info ( 'Processing: ' . ( $this -> option ( 'file' ) ? $this -> option ( 'file' ) : $this -> option ( 'dir' )));
$files = [];
if ( $this -> option ( 'dir' ))
{
// Remove our trailing slash from the directory.
$dir = preg_replace ( '/\/$/' , '' , $this -> option ( 'dir' ));
// Exclude . & .. from the path.
$files = array_diff ( scandir ( $dir ), array ( '.' , '..' ));
// Determine if our dir is releative to where we store data
$dir = preg_replace ( '/^\//' , '' , str_replace ( config ( 'photo.dir' ), '' , $dir ));
// Add our path
if ( $dir )
array_walk ( $files , function ( & $value , $key , $path = '' ) {
if ( $path ) {
$value = sprintf ( '%s/%s' , $path , $value );
}
}, $dir );
}
elseif ( $this -> option ( 'file' ))
{
$files = array ( $this -> option ( 'file' ));
}
// Show a progress bar
$bar = $this -> output -> createProgressBar ( count ( $files ));
$bar -> setFormat ( " %current%/%max% [%bar%] %percent:3s%% (%memory%) (%remaining%) " );
$tags = NULL ;
$t = $p = array ();
// Tags
if ( $this -> option ( 'tags' ))
{
$tags = explode ( ',' , $this -> option ( 'tags' ));
$t = Tag :: whereIn ( 'tag' , $tags ) -> get ();
}
// People
if ( $this -> option ( 'people' ))
{
$tags = explode ( ',' , $this -> option ( 'people' ));
$p = Person :: whereIn ( 'tag' , $tags ) -> get ();
}
$c = 0 ;
foreach ( $files as $file )
{
$bar -> advance ();
if ( preg_match ( '/@__thumb/' , $file ) OR preg_match ( '/\/._/' , $file ))
{
$this -> warn ( sprintf ( 'Ignoring file [%s]' , $file ));
continue ;
}
if ( ! in_array ( strtolower ( pathinfo ( $file , PATHINFO_EXTENSION )), config ( 'photo.import.accepted' )))
{
$this -> warn ( sprintf ( 'Ignoring [%s]' , $file ));
continue ;
}
if ( $this -> option ( 'verbose' ))
$this -> info ( sprintf ( 'Processing file [%s]' , $file ));
$c ++ ;
$po = Photo :: where ( 'filename' , $file ) -> first ();
if ( is_null ( $po ))
{
$po = new Photo ;
$po -> filename = $file ;
}
$po -> date_taken = strtotime ( $po -> io ( 'exif:DateTime' ));
$po -> subsectime = $po -> io ( 'exif:SubSecTimeOriginal' );
$po -> signature = $po -> io () -> getImageSignature ();
$po -> make = $po -> io ( 'exif:Make' );
$po -> model = $po -> io ( 'exif:Model' );
$po -> height = $po -> io () -> getImageheight ();
$po -> width = $po -> io () -> getImageWidth ();
$po -> orientation = $po -> io () -> getImageOrientation ();
2016-06-22 06:51:31 +00:00
$po -> gps_lat = $po -> latlon ( preg_split ( '/,\s?/' , $po -> io () -> getImageProperty ( 'exif:GPSLatitude' )), $po -> io () -> getImageProperty ( 'exif:GPSLatitudeRef' ));
$po -> gps_lon = $po -> latlon ( preg_split ( '/,\s?/' , $po -> io () -> getImageProperty ( 'exif:GPSLongitude' )), $po -> io () -> getImageProperty ( 'exif:GPSLongitudeRef' ));
2016-06-22 05:49:20 +00:00
try {
$po -> thumbnail = exif_thumbnail ( $po -> file_path ());
} catch ( Exception $e ) {
// @todo Couldnt get the thumbnail, so we should create one.
}
// If this is a duplicate
$x = $po -> list_duplicate () -> get ();
if ( count ( $x )) {
$skip = FALSE ;
foreach ( $x as $o ) {
// We'll only ignore based on the same signature.
if ( $po -> signature != $o -> signature AND ! $po -> exists )
continue ;
if ( $this -> option ( 'ignoredupe' ))
{
$skip = TRUE ;
$this -> warn ( sprintf ( " Ignoring file [%s], it's the same as [%s] with id %s " , $po -> file_path (), $o -> filename , $o -> id ));
break ;
}
elseif ( $this -> option ( 'deletedupe' ) AND ( $po -> filename != $o -> filename ))
{
$skip = TRUE ;
$this -> error ( sprintf ( " Deleting file [%s], it's the same as [%s] with id %s and signature [%s] \n " , $po -> file_path (), $o -> filename , $o -> id , $po -> signature ));
unlink ( $po -> file_path ());
}
}
if ( $skip )
continue ;
$po -> duplicate = '1' ;
$this -> warn ( sprintf ( 'Image [%s] marked as a duplicate' , $file ));
}
if ( $po -> exists )
$this -> warn ( sprintf ( 'Image [%s] already in DB: %s' , $file , $po -> id ));
$po -> save ();
if ( $po -> wasRecentlyCreated )
$this -> info ( sprintf ( 'Image [%s] stored in DB: %s' , $file , $po -> id ));
// Record our tags
foreach ( $t as $o )
if ( ! ( new PhotoTag ) -> where ( 'tag_id' , '=' , $o -> id ) -> where ( 'photo_id' , '=' , $po -> id ) -> count ())
{
$x = new PhotoTag ;
$x -> tag_id = $o -> id ;
$x -> photo_id = $po -> id ;
$x -> save ();
}
// Record our people
foreach ( $p as $o )
if ( ! ( new PhotoPerson ) -> where ( 'people_id' , '=' , $o -> id ) -> where ( 'photo_id' , '=' , $po -> id ) -> count ())
{
$x = new PhotoPerson ;
$x -> people_id = $o -> id ;
$x -> photo_id = $po -> id ;
$x -> save ();
}
}
$bar -> finish ();
return $this -> info ( sprintf ( 'Images processed: %s' , $c ));
}
}