Deprecating php's regRename, migrating to python
This commit is contained in:
		@@ -1,225 +0,0 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace astropenguin\botanical;
 | 
			
		||||
use DirectoryIterator;
 | 
			
		||||
 | 
			
		||||
class RegRename
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
	//Define globals
 | 
			
		||||
	private $test = false;
 | 
			
		||||
	private $recursive = false;
 | 
			
		||||
	private $searchDirs = array();
 | 
			
		||||
	private $patterns = array();
 | 
			
		||||
	private $replaceStrs = array();
 | 
			
		||||
	private $excludes = array();
 | 
			
		||||
 | 
			
		||||
	private $logfile = NULL;
 | 
			
		||||
 | 
			
		||||
	public function begin()
 | 
			
		||||
	{
 | 
			
		||||
		$this->validateOptions();
 | 
			
		||||
 | 
			
		||||
		//------- Begin Operations -------
 | 
			
		||||
		foreach ( $this->searchDirs as $dir )
 | 
			
		||||
		{
 | 
			
		||||
			$this->elog("Directory: $dir\nBuilding file list ...");
 | 
			
		||||
			if ( $this->recursive )
 | 
			
		||||
			{
 | 
			
		||||
				$fileList = $this->getWholeFileList($dir);
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				$fileList = $this->getFileList($dir);
 | 
			
		||||
			}
 | 
			
		||||
			$this->elog("Searching ...");
 | 
			
		||||
			foreach ( $fileList as $file )
 | 
			
		||||
			{
 | 
			
		||||
				//
 | 
			
		||||
				// Get the file name
 | 
			
		||||
				// RegExplained:
 | 
			
		||||
				// Example: /foo/bar/foobar.bar
 | 
			
		||||
				//   $matches[0][0] is the whole string "/foo/bar/foobar.bar"
 | 
			
		||||
				//
 | 
			
		||||
				//   ^(.+?)
 | 
			
		||||
				//   This gets the file path "/foo/bar/" for $matches[1][0]
 | 
			
		||||
				//
 | 
			
		||||
				//   ([^\/\\\\]+)$
 | 
			
		||||
				//   This gets the file name "foobar.bar" for $matches[2][0]
 | 
			
		||||
				//
 | 
			
		||||
				preg_match_all('/^(.+?)([^\/\\\\]+)$/', $file, $matches );
 | 
			
		||||
				$newName = $matches[2][0];
 | 
			
		||||
				foreach ( $this->patterns as $key => $pattern )
 | 
			
		||||
				{
 | 
			
		||||
					//Rename over the patterns
 | 
			
		||||
					$newName = preg_replace( $pattern, $this->replaceStrs[$key], $newName );
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				if( $matches[2][0] != $newName )
 | 
			
		||||
				{
 | 
			
		||||
 | 
			
		||||
					// Excluede any matches
 | 
			
		||||
					foreach ( $this->excludes as $key => $pattern )
 | 
			
		||||
					{
 | 
			
		||||
						if(preg_match_all($pattern, $file))
 | 
			
		||||
						{
 | 
			
		||||
							$this->elog("S File \"{$matches[2][0]}\" excluded on $pattern");
 | 
			
		||||
							continue 2;
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					if( $this->test )
 | 
			
		||||
					{
 | 
			
		||||
						$this->elog("R File \"{$matches[2][0]}\" will be renamed to \"$newName\"");
 | 
			
		||||
					}
 | 
			
		||||
					else
 | 
			
		||||
					{
 | 
			
		||||
						rename ( $file, "{$matches[1][0]}$newName" );
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					if( $this->logfile )
 | 
			
		||||
					{
 | 
			
		||||
						file_put_contents( $this->logfile, $this->log );
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				/*
 | 
			
		||||
				else
 | 
			
		||||
				{
 | 
			
		||||
					echo "File \"{$matches[0][0]}\" will not be renamed\n";
 | 
			
		||||
				}
 | 
			
		||||
				//*/
 | 
			
		||||
			}
 | 
			
		||||
			$this->elog();
 | 
			
		||||
		}
 | 
			
		||||
		if ( $this->test ) $this->elog("*** Test enabled ***\n");
 | 
			
		||||
		//------- End Operations -------*/
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public function setOption( $item, $value = NULL )
 | 
			
		||||
	{
 | 
			
		||||
		switch($item)
 | 
			
		||||
		{
 | 
			
		||||
			case "-d":
 | 
			
		||||
				if($value)
 | 
			
		||||
				$this->searchDirs[] = $value;
 | 
			
		||||
				break;
 | 
			
		||||
			case "-p":
 | 
			
		||||
				if($value)
 | 
			
		||||
				$this->patterns[] = $value;
 | 
			
		||||
				break;
 | 
			
		||||
			case "-r":
 | 
			
		||||
				$this->recursive = true;
 | 
			
		||||
				break;
 | 
			
		||||
			case "-s":
 | 
			
		||||
				if($value)
 | 
			
		||||
				$this->replaceStrs[] = $value;
 | 
			
		||||
				break;
 | 
			
		||||
			case "-t":
 | 
			
		||||
				$this->test = true;
 | 
			
		||||
				break;
 | 
			
		||||
			case "-e":
 | 
			
		||||
				$this->excludes[] = $value;
 | 
			
		||||
				break;
 | 
			
		||||
			case "-l":
 | 
			
		||||
				$this->logfile = $value;
 | 
			
		||||
				break;
 | 
			
		||||
			default:
 | 
			
		||||
				//Do nothing
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	//------- Main Functions --------
 | 
			
		||||
 | 
			
		||||
	function elog( $line = "" )
 | 
			
		||||
	{
 | 
			
		||||
		$this->log .= $line;
 | 
			
		||||
		$this->log .= "\n";
 | 
			
		||||
		echo "$line\n";
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	private function getDirName ( $dir )
 | 
			
		||||
	{
 | 
			
		||||
		return is_dir ( $dir ) ? $dir : dirname ( $dir ) ;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private function getFileList ( $dir )
 | 
			
		||||
	{
 | 
			
		||||
		$fileList = array();
 | 
			
		||||
		$iterator = new DirectoryIterator ( $this->getDirName ( $dir )  ) ;
 | 
			
		||||
		foreach ( $iterator as $fileinfo )
 | 
			
		||||
		{
 | 
			
		||||
			if ( $fileinfo->isFile() )
 | 
			
		||||
			{
 | 
			
		||||
				$fileList[] = $dir."/".$fileinfo->getFilename();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return $fileList;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private function getDirList ( $dir )
 | 
			
		||||
	{
 | 
			
		||||
		$dirList = array();
 | 
			
		||||
		$iterator = new DirectoryIterator ( $this->getDirName ( $dir ) );
 | 
			
		||||
		foreach ( $iterator as $fileinfo )
 | 
			
		||||
		{
 | 
			
		||||
			if ( $fileinfo->isDir() && !$fileinfo->isDot())
 | 
			
		||||
			{
 | 
			
		||||
				$dirList[] = $fileinfo->getFilename();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return $dirList;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private function getWholeDirList ( $dir )
 | 
			
		||||
	{
 | 
			
		||||
		$wholeDirList = array();
 | 
			
		||||
		//getWholeDirList will stop untill getDirList return an empty array.
 | 
			
		||||
		foreach ( $this->getDirList ( $dir ) as $file )
 | 
			
		||||
		{
 | 
			
		||||
				//Store found path
 | 
			
		||||
				$wholeDirList[] = "$dir/$file";
 | 
			
		||||
				//Method getWholeDirList will self-iterate if sub-directories exist.
 | 
			
		||||
				$wholeDirList = array_merge ( $wholeDirList, $this->getWholeDirList ( "$dir/$file" )  ) ;
 | 
			
		||||
		}
 | 
			
		||||
		return $wholeDirList;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private function getWholeFileList ( $dir )
 | 
			
		||||
	{
 | 
			
		||||
		//Get the first level list.
 | 
			
		||||
		$wholeFileList = $this->getFileList( $dir );
 | 
			
		||||
		//getWholeDirList and search its files.
 | 
			
		||||
		foreach ( $this->getWholeDirList ( $dir ) as $dir )
 | 
			
		||||
		{
 | 
			
		||||
			$wholeFileList = array_merge ( $wholeFileList, $this->getFileList ( $dir )  ) ;
 | 
			
		||||
		}
 | 
			
		||||
		return $wholeFileList;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private function validateOptions (  )
 | 
			
		||||
	{
 | 
			
		||||
		try
 | 
			
		||||
		{
 | 
			
		||||
			if(count($this->searchDirs) == 0)
 | 
			
		||||
			throw new \Exception("Search directory is missing");
 | 
			
		||||
 | 
			
		||||
			else if(count($this->patterns) == 0)
 | 
			
		||||
			throw new \Exception("Search pattern is missing");
 | 
			
		||||
 | 
			
		||||
			else if(count($this->replaceStrs) == 0)
 | 
			
		||||
			throw new \Exception("Replacement string is missing");
 | 
			
		||||
 | 
			
		||||
			else if(count($this->replaceStrs) != count($this->patterns))
 | 
			
		||||
			throw new \Exception("Replacement string and pattern count not match");
 | 
			
		||||
		}
 | 
			
		||||
		catch( \Exception $e )
 | 
			
		||||
		{
 | 
			
		||||
			var_dump( $GLOBALS );
 | 
			
		||||
			die("Error: $e.\n");
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	//------- End Main Functions --------
 | 
			
		||||
}
 | 
			
		||||
@@ -1,47 +0,0 @@
 | 
			
		||||
#!/usr/bin/env php
 | 
			
		||||
<?php
 | 
			
		||||
error_reporting ( E_ALL^E_NOTICE ) ;
 | 
			
		||||
require_once dirname( __FILE__ ) . '/astropenguin/package.php';
 | 
			
		||||
 | 
			
		||||
use astropenguin\botanical\RegRename;
 | 
			
		||||
use astropenguin\botanical\Args;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//----------- Usage -----------
 | 
			
		||||
 | 
			
		||||
if ( !$argv[1] ) 
 | 
			
		||||
	die (<<<__USAGE__
 | 
			
		||||
Usage: php {$argv[0]} [options] [-d directory] [-p patterns] [-s "first match" "second" ...] [...args]
 | 
			
		||||
 | 
			
		||||
  -d <paths>	Directories to look over
 | 
			
		||||
  -p <patterns>	Define RegEx patterns
 | 
			
		||||
  -r		Rename file recursively
 | 
			
		||||
  -s <str ...>	Strings that will replace the matches
 | 
			
		||||
 | 
			
		||||
  Optional:
 | 
			
		||||
	-e <patterns>	Exclude defined pattern
 | 
			
		||||
	-l <File>	Output log file
 | 
			
		||||
	-t		Test without modifying anything
 | 
			
		||||
 | 
			
		||||
  Example:
 | 
			
		||||
    php regRename.php -d ~/ -p "/(.+)_.+/" -s "\\1"
 | 
			
		||||
 | 
			
		||||
    Result:
 | 
			
		||||
      R File ".mysql_history" will be renamed to ".mysql"
 | 
			
		||||
      R File ".db_pass" will be renamed to ".db"
 | 
			
		||||
      R File ".bash_logout" will be renamed to ".bash"
 | 
			
		||||
      R File ".mysql_pass" will be renamed to ".mysql"
 | 
			
		||||
      R File ".bash_history" will be renamed to ".bash"
 | 
			
		||||
 | 
			
		||||
    php regRename.php -d ~/ -p "/(.+)_.+/" -s "\\1"
 | 
			
		||||
 | 
			
		||||
__USAGE__
 | 
			
		||||
) ;
 | 
			
		||||
 | 
			
		||||
//------- End Usage -----------
 | 
			
		||||
 | 
			
		||||
$rrgr = new RegRename();
 | 
			
		||||
Args::PARSE ( $argv, array($rrgr, 'setOption') );
 | 
			
		||||
$rrgr->begin();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										168
									
								
								python/reg-rename.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										168
									
								
								python/reg-rename.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,168 @@
 | 
			
		||||
#!/bin/env python3
 | 
			
		||||
 | 
			
		||||
import argparse, os, re, sys
 | 
			
		||||
 | 
			
		||||
# {{{ Argument Parsing
 | 
			
		||||
parser = argparse.ArgumentParser(
 | 
			
		||||
	description = "Tools for renaming files using regular expressions"
 | 
			
		||||
	, formatter_class = argparse.RawDescriptionHelpFormatter
 | 
			
		||||
	, epilog = """
 | 
			
		||||
  Example:
 | 
			
		||||
    %(prog)s -d ~/ -p "/(.+)_.+/" -s "\\1"
 | 
			
		||||
 | 
			
		||||
  Result:
 | 
			
		||||
    R ".mysql_history" will be renamed to ".mysql"
 | 
			
		||||
    R ".db_pass" will be renamed to ".db"
 | 
			
		||||
    R ".bash_logout" will be renamed to ".bash"
 | 
			
		||||
    R ".mysql_pass" will be renamed to ".mysql"
 | 
			
		||||
    R ".bash_history" will be renamed to ".bash"
 | 
			
		||||
"""
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
parser.add_argument( "-r", action = "store_true", help = "Rename files recursively" )
 | 
			
		||||
parser.add_argument( "-d", required = True, metavar = "dirs", nargs = "+", help = "Directories to look over" )
 | 
			
		||||
parser.add_argument( "-p", required = True, metavar = "patterns", nargs = "+" , help = "Include patterns")
 | 
			
		||||
parser.add_argument( "-s", required = True, metavar = "substitudes", nargs = "+", help = "Strings that will replace the matches" )
 | 
			
		||||
parser.add_argument( "-e", metavar = "patterns", nargs = "+", help = "Exclude patterns" )
 | 
			
		||||
parser.add_argument( "-t", action = "store_true", help = "Test without modifying anything" )
 | 
			
		||||
# End Argement Parsing }}}
 | 
			
		||||
 | 
			
		||||
args = parser.parse_args()
 | 
			
		||||
 | 
			
		||||
class ArgumentRequired( Exception ): pass
 | 
			
		||||
class InvalidArgument( Exception ): pass
 | 
			
		||||
 | 
			
		||||
class LevelLogger:
 | 
			
		||||
	lv = 0
 | 
			
		||||
 | 
			
		||||
	def __init__( self, level ):
 | 
			
		||||
		self.lv = level
 | 
			
		||||
		self.pad = "    " * level
 | 
			
		||||
 | 
			
		||||
	def log( self, mesg ):
 | 
			
		||||
		print( self.pad + mesg )
 | 
			
		||||
 | 
			
		||||
	def log_all( self, mesgs ):
 | 
			
		||||
		for mesg in mesgs:
 | 
			
		||||
			self.log( mesg )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class LoggerSpawner:
 | 
			
		||||
 | 
			
		||||
	lv = 0
 | 
			
		||||
 | 
			
		||||
	def __enter__( self ):
 | 
			
		||||
		self.lv = self.lv + 1
 | 
			
		||||
		return LevelLogger( self.lv )
 | 
			
		||||
 | 
			
		||||
	def __exit__( self, *args ):
 | 
			
		||||
		self.lv = self.lv - 1
 | 
			
		||||
 | 
			
		||||
class RAction:
 | 
			
		||||
 | 
			
		||||
	def __init__( self, root, _from, _to, exclude ):
 | 
			
		||||
		self.root = root
 | 
			
		||||
		self._from = _from
 | 
			
		||||
		self._to = _to
 | 
			
		||||
		self.exc = exclude
 | 
			
		||||
 | 
			
		||||
	def run( self, test ):
 | 
			
		||||
		root, _from, _to = self.root, self._from, self._to
 | 
			
		||||
 | 
			
		||||
		if self.exc:
 | 
			
		||||
			return "= Excluding \"%s\"" % _from
 | 
			
		||||
 | 
			
		||||
		if test:
 | 
			
		||||
			return "R \"%s\" will be renamed to \"%s\"" % ( _from, _to )
 | 
			
		||||
		else:
 | 
			
		||||
			os.rename( os.path.join( root, _from ), os.path.join( root, _to ) )
 | 
			
		||||
			return "R \"%s\" -> \"%s\"" % ( _from, _to )
 | 
			
		||||
 | 
			
		||||
class RegReplace:
 | 
			
		||||
 | 
			
		||||
	def __init__( self, includes, replacements, excludes, recursive ):
 | 
			
		||||
		self.logger = LoggerSpawner()
 | 
			
		||||
		self.recursive = recursive
 | 
			
		||||
		self.includes = includes
 | 
			
		||||
		self.excludes = excludes
 | 
			
		||||
		self.subs = replacements
 | 
			
		||||
		self.test = False
 | 
			
		||||
 | 
			
		||||
	def _exclude( self, k ):
 | 
			
		||||
		for ex in self.excludes:
 | 
			
		||||
			if ex.match( k ):
 | 
			
		||||
				return True
 | 
			
		||||
		return False
 | 
			
		||||
 | 
			
		||||
	def _compile_actions( self, root, files ):
 | 
			
		||||
		rlist = []
 | 
			
		||||
		for file_name in files:
 | 
			
		||||
			for i, p in enumerate( self.includes ):
 | 
			
		||||
				if p.match( file_name ):
 | 
			
		||||
					if self._exclude( file_name ):
 | 
			
		||||
						rlist.append( RAction( root, file_name, file_name, True ) )
 | 
			
		||||
					else:
 | 
			
		||||
						sub = self.subs[ i ]
 | 
			
		||||
						k = p.sub( sub, file_name )
 | 
			
		||||
						rlist.append( RAction( root, file_name, k, False ) )
 | 
			
		||||
 | 
			
		||||
		return rlist
 | 
			
		||||
 | 
			
		||||
	def searchDirs( self, path ):
 | 
			
		||||
		bb = "-\\|/"
 | 
			
		||||
		bb_i = 0
 | 
			
		||||
		for root, dirs, files in os.walk( path ):
 | 
			
		||||
			actions = self._compile_actions( root, files )
 | 
			
		||||
 | 
			
		||||
			sys.stdout.write( bb[ bb_i ] )
 | 
			
		||||
			sys.stdout.flush()
 | 
			
		||||
			sys.stdout.write( "\b" )
 | 
			
		||||
			bb_i = bb_i + 1
 | 
			
		||||
			if 3 < bb_i:
 | 
			
		||||
				bb_i = 0
 | 
			
		||||
 | 
			
		||||
			if actions:
 | 
			
		||||
				with self.logger as DirLogger:
 | 
			
		||||
					DirLogger.log( "In directory: \"%s\"" % root )
 | 
			
		||||
 | 
			
		||||
					with self.logger as ActionLogger:
 | 
			
		||||
						for action in actions:
 | 
			
		||||
							mesg = action.run( self.test )
 | 
			
		||||
							ActionLogger.log( mesg )
 | 
			
		||||
 | 
			
		||||
			if not self.recursive:
 | 
			
		||||
				break
 | 
			
		||||
		sys.stdout.write( " " )
 | 
			
		||||
		sys.stdout.flush()
 | 
			
		||||
 | 
			
		||||
def _compile_re( patterns ):
 | 
			
		||||
	_list = []
 | 
			
		||||
 | 
			
		||||
	if patterns:
 | 
			
		||||
		for p in patterns:
 | 
			
		||||
 | 
			
		||||
			if not ( p[0] == p[-1] == "/" ):
 | 
			
		||||
				raise InvalidArgument( p )
 | 
			
		||||
 | 
			
		||||
			_list.append( re.compile( p[ 1:-1 ] ) )
 | 
			
		||||
 | 
			
		||||
	return _list
 | 
			
		||||
 | 
			
		||||
try:
 | 
			
		||||
	includes = _compile_re( args.p )
 | 
			
		||||
	excludes = _compile_re( args.e )
 | 
			
		||||
 | 
			
		||||
	if not args.d:
 | 
			
		||||
		raise ArgumentRequired( "-d" )
 | 
			
		||||
 | 
			
		||||
	if args.t:
 | 
			
		||||
		print( "** Test Mode" )
 | 
			
		||||
 | 
			
		||||
	reg_replace = RegReplace( includes, args.s, excludes, args.r )
 | 
			
		||||
	reg_replace.test = args.t
 | 
			
		||||
	for _dir in args.d:
 | 
			
		||||
		reg_replace.searchDirs( _dir )
 | 
			
		||||
 | 
			
		||||
except InvalidArgument as ex:
 | 
			
		||||
	print( "Invalid argument: %s" % ex )
 | 
			
		||||
	sys.exit( 1 )
 | 
			
		||||
		Reference in New Issue
	
	Block a user