commit 8a828cdf345dcd2ce7bd57a127ccd8f00c4f143e
| author | 斟酌 鵬兄 <tgckpg@gmail.com> |
| date | 2017-12-01T05:15:37Z |
| subject | Deprecating php's regRename, migrating to python |
commit 8a828cdf345dcd2ce7bd57a127ccd8f00c4f143e
Author: 斟酌 鵬兄 <tgckpg@gmail.com>
Date: 2017-12-01T05:15:37Z
Deprecating php's regRename, migrating to python
---
php/astropenguin/botanical/RegRename.php | 225 -------------------------------
php/regRename.php | 47 -------
python/reg-rename.py | 168 +++++++++++++++++++++++
3 files changed, 168 insertions(+), 272 deletions(-)
diff --git a/php/astropenguin/botanical/RegRename.php b/php/astropenguin/botanical/RegRename.php
deleted file mode 100644
index fbac369..0000000
--- a/php/astropenguin/botanical/RegRename.php
+++ /dev/null
@@ -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 --------
-}
diff --git a/php/regRename.php b/php/regRename.php
deleted file mode 100644
index b402b78..0000000
--- a/php/regRename.php
+++ /dev/null
@@ -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();
-
-
diff --git a/python/reg-rename.py b/python/reg-rename.py
new file mode 100644
index 0000000..033db0c
--- /dev/null
+++ b/python/reg-rename.py
@@ -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 )