aboutsummaryrefslogtreecommitdiff
path: root/synchronise.py
diff options
context:
space:
mode:
Diffstat (limited to 'synchronise.py')
-rw-r--r--synchronise.py473
1 files changed, 238 insertions, 235 deletions
diff --git a/synchronise.py b/synchronise.py
index 66d6ad581..8951f1e85 100644
--- a/synchronise.py
+++ b/synchronise.py
@@ -1,235 +1,238 @@
-import os,sys,shutil,re,stat
-
-from optparse import OptionParser
-
-usage = "usage: %prog [options] <SrcDir> <DestDir>"
-parser = OptionParser(usage=usage)
-parser.add_option("-n", "--donothing", action='store_true', dest="DoNothing", default=False, help="Do not copy the files.")
-parser.add_option("", "--extension", action='store', dest="Extension", default=None, help="Copy only files with this extension.")
-parser.add_option("-y", "--ask", action='store_true', dest="Ask", default=False, help="Ask confirmation to copy.")
-parser.add_option("-a", "--ask-file", action='append', dest="FilesToConfirm", default=[], help="Ask confirmation to copy for this speicific file (only useful if -y is not used).")
-parser.add_option("-d", "--delete-file_re", dest="FilesToDeleteRe", default="", help="Regular expression of files to delete.")
-parser.add_option("-s", "--no-skip-svn", dest="NoSkipSvn", action='store_true', default=False, help="Do not Skip .svn directories.")
-parser.add_option("-g", "--no-skip-git", dest="NoSkipGit", action='store_true', default=False, help="Do not Skip .git directories.")
-parser.add_option("-e", "--del-exist-only-dest", dest="DelExistOnlyDest", action='store_true', default=False, help="Delete files that exist only in the destination directory.")
-parser.add_option( "" , "--skip-dir", dest="SkipDirs", action='append', default=[], help="Adds a directory name to skip.")
-parser.add_option( "" , "--skip-file", dest="SkipFiles", action='append', default=[], help="Adds a file name to skip.")
-
-(g_Options, g_Args) = parser.parse_args()
-
-if g_Options.FilesToDeleteRe:
- try:
- g_FilesToDelete=re.compile(g_Options.FilesToDeleteRe,re.I)
- except:
- print 'Wrong regular expression:',g_Options.FilesToDeleteRe
- sys.exit(1)
-else:
- g_FilesToDelete=None
-
-if len(g_Args)!=2:
- parser.error("Wrong number of arguments: "+repr(g_Args))
- sys.exit(1)
-
-g_FilesToConfirm={}
-for File in g_Options.FilesToConfirm:
- g_FilesToConfirm[File]=1
-
-g_DirsToSkip={}
-for Dir in g_Options.SkipDirs:
- g_DirsToSkip[Dir]=1
-
-g_FilesToSkip={}
-for File in g_Options.SkipFiles:
- g_FilesToSkip[File]=1
-
-g_Ask=g_Options.Ask
-g_DoNothing=g_Options.DoNothing
-g_NoSkipSvn=g_Options.NoSkipSvn
-g_NoSkipGit=g_Options.NoSkipGit
-
-g_WriteMask=stat.S_IWUSR|stat.S_IWGRP|stat.S_IWOTH
-
-g_SrcDir=os.path.realpath(g_Args[0])
-g_DestDir=os.path.realpath(g_Args[1])
-
-if g_Options.Extension:
- g_Extre=re.compile('.*\.%s$'%g_Options.Extension,re.I)
-else:
- g_Extre=None
-
-###############################################################################
-g_LenSrcDir=len(g_SrcDir)
-if g_SrcDir[-1]!=os.path.sep:
- g_LenSrcDir+=1
-
-def SkipDir(SrcDir,File):
- Ret = g_DirsToSkip.has_key(File)
- SrcDir=SrcDir[g_LenSrcDir:]
-
- while not Ret and SrcDir:
- SrcDir,Part=os.path.split(SrcDir)
- File=os.path.join(Part,File)
- Ret = g_DirsToSkip.has_key(File)
- return Ret
-
-###############################################################################
-def DeleteFiles(SrcFile,DestFile):
- print 'Deleting %s'%(SrcFile)
- os.remove(SrcFile)
- print 'Deleting %s'%(DestFile)
- try:
- os.remove(DestFile)
- except:
- print DestFile,'does not exist'
-
-###############################################################################
-#characters=['|','/','-','\\']
-#chariter=iter(characters)
-#def PrintBusy():
-# global characters
-# global chariter
-#
-# try:
-# char=chariter.next()
-# except StopIteration:
-# chariter=iter(characters)
-# char=chariter.next()
-#
-# sys.stdout.write(char)
-# sys.stdout.write(chr(8))
-count=0
-def PrintBusy():
- global count
- count+=1
- item=str(count)
- sys.stdout.write(item)
- sys.stdout.write(chr(8)*len(item))
-###############################################################################
-
-if not os.path.isdir(g_DestDir):
- print g_DestDir,"is not a directory"
- sys.exit(1)
-
-def FileDiff(SrcFile,DestFile):
- try:
- Src=open(SrcFile,'rb')
- Dest=open(DestFile,'rb')
- while 1:
- SrcLine=Src.read(4096)
- DestLine=Dest.read(4096)
- if SrcLine!=DestLine:
- return 1
- if not SrcLine:
- return 0
- except Exception,Object:
- #print "Exception occured"
- #print Object
- return 1
-
-g_Dot=0
-def SynchroniseDir(SrcDir,DestDir):
- global g_Dot
- SrcFiles=os.listdir(SrcDir)
- if g_Options.DelExistOnlyDest:
- DstFiles=os.listdir(DestDir)
- for File in DstFiles:
- DestFile=os.path.join(DestDir,File)
- try:
- Index=SrcFiles.index(File)
- except ValueError:
- if os.path.isdir(DestFile):
- if not g_NoSkipSvn and File=='.svn':
- continue # Skip svn administration dirs
- if not g_NoSkipGit and File=='.git':
- continue # Skip svn administration dirs
- if SkipDir(SrcDir,File):
- continue
- print 'Deleting directory',DestFile
- shutil.rmtree(DestFile)
- else:
- if g_FilesToSkip.has_key(File):
- continue
- print 'Deleting file',DestFile
- os.remove(DestFile)
-
- for File in SrcFiles:
- SrcFile=os.path.join(SrcDir,File)
- DestFile=os.path.join(DestDir,File)
- if os.path.isdir(SrcFile):
- if not g_NoSkipSvn and File=='.svn':
- continue # Skip svn administration dirs
- if not g_NoSkipGit and File=='.git':
- continue # Skip svn administration dirs
- if SkipDir(SrcDir,File):
- continue
- if not os.path.isdir(DestFile):
- if g_Dot:
- sys.stdout.write('\n')
- g_Dot=0
- if not g_DoNothing:
- if g_Ask:
- sys.stdout.write("Create directory %s? (y/n)"%DestFile)
- if sys.stdin.read(1)=='y':
- print "Creating dir",DestFile
- os.mkdir(DestFile)
- sys.stdin.read(1)
- else:
- print "Creating dir",DestFile
- os.mkdir(DestFile)
- else:
- print "Creating dir",DestFile
- SynchroniseDir(SrcFile,DestFile)
- else:
- if g_Extre and not g_Extre.search(File):
- continue
- if g_FilesToSkip.has_key(File):
- continue
- if g_FilesToDelete:
- if g_FilesToDelete.search(File):
- if g_Dot:
- sys.stdout.write('\n')
- g_Dot=0
- DeleteFiles(SrcFile,DestFile)
- continue
- if FileDiff(SrcFile,DestFile):
- #if os.system('fc /b "%s" "%s" >& nul'%(SrcFile,DestFile)):
- if g_Dot:
- sys.stdout.write('\n')
- g_Dot=0
- if not g_DoNothing:
- if g_Ask or g_FilesToConfirm.has_key(File):
- sys.stdout.write("Copy/Merge %s to %s? (y/n/m/d)"%(SrcFile,DestFile))
- R=sys.stdin.read(1)
- if R=='y':
- print '%s -> %s'%(SrcFile,DestFile)
- shutil.copyfile(SrcFile,DestFile)
- elif R=='m':
- print '%s -> %s'%(SrcFile,DestFile)
- os.system('fcg "%s" "%s"'%(SrcFile,DestFile))
- elif R=='d':
- DeleteFiles(SrcFile,DestFile)
- sys.stdin.read(1)
- else:
- print '%s -> %s'%(SrcFile,DestFile)
- # check if the file is read-only
- try:
- Mode=os.stat(DestFile).st_mode
- except OSError:
- Mode=g_WriteMask
- if not g_WriteMask&Mode:
- ReadOnly=True
- os.chmod(DestFile,Mode|g_WriteMask)
- else:
- ReadOnly=False
- shutil.copyfile(SrcFile,DestFile)
- if ReadOnly:
- os.chmod(DestFile,Mode & (~g_WriteMask) )
-
- else:
- print '%s -> %s'%(SrcFile,DestFile)
- else:
- PrintBusy()
- g_Dot=1
-
-SynchroniseDir(g_SrcDir,g_DestDir)
-sys.stdout.write("\n")
+#!/usr/bin/python
+import os,sys,shutil,re,stat
+
+from optparse import OptionParser
+
+sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
+
+usage = "usage: %prog [options] <SrcDir> <DestDir>"
+parser = OptionParser(usage=usage)
+parser.add_option("-n", "--donothing", action='store_true', dest="DoNothing", default=False, help="Do not copy the files.")
+parser.add_option("", "--extension", action='store', dest="Extension", default=None, help="Copy only files with this extension.")
+parser.add_option("-y", "--ask", action='store_true', dest="Ask", default=False, help="Ask confirmation to copy.")
+parser.add_option("-a", "--ask-file", action='append', dest="FilesToConfirm", default=[], help="Ask confirmation to copy for this speicific file (only useful if -y is not used).")
+parser.add_option("-d", "--delete-file_re", dest="FilesToDeleteRe", default="", help="Regular expression of files to delete.")
+parser.add_option("-s", "--no-skip-svn", dest="NoSkipSvn", action='store_true', default=False, help="Do not Skip .svn directories.")
+parser.add_option("-g", "--no-skip-git", dest="NoSkipGit", action='store_true', default=False, help="Do not Skip .git directories.")
+parser.add_option("-e", "--del-exist-only-dest", dest="DelExistOnlyDest", action='store_true', default=False, help="Delete files that exist only in the destination directory.")
+parser.add_option( "" , "--skip-dir", dest="SkipDirs", action='append', default=[], help="Adds a directory name to skip.")
+parser.add_option( "" , "--skip-file", dest="SkipFiles", action='append', default=[], help="Adds a file name to skip.")
+
+(g_Options, g_Args) = parser.parse_args()
+
+if g_Options.FilesToDeleteRe:
+ try:
+ g_FilesToDelete=re.compile(g_Options.FilesToDeleteRe,re.I)
+ except:
+ print 'Wrong regular expression:',g_Options.FilesToDeleteRe
+ sys.exit(1)
+else:
+ g_FilesToDelete=None
+
+if len(g_Args)!=2:
+ parser.error("Wrong number of arguments: "+repr(g_Args))
+ sys.exit(1)
+
+g_FilesToConfirm={}
+for File in g_Options.FilesToConfirm:
+ g_FilesToConfirm[File]=1
+
+g_DirsToSkip={}
+for Dir in g_Options.SkipDirs:
+ g_DirsToSkip[Dir]=1
+
+g_FilesToSkip={}
+for File in g_Options.SkipFiles:
+ g_FilesToSkip[File]=1
+
+g_Ask=g_Options.Ask
+g_DoNothing=g_Options.DoNothing
+g_NoSkipSvn=g_Options.NoSkipSvn
+g_NoSkipGit=g_Options.NoSkipGit
+
+g_WriteMask=stat.S_IWUSR|stat.S_IWGRP|stat.S_IWOTH
+
+g_SrcDir=os.path.realpath(g_Args[0])
+g_DestDir=os.path.realpath(g_Args[1])
+
+if g_Options.Extension:
+ g_Extre=re.compile('.*\.%s$'%g_Options.Extension,re.I)
+else:
+ g_Extre=None
+
+###############################################################################
+g_LenSrcDir=len(g_SrcDir)
+if g_SrcDir[-1]!=os.path.sep:
+ g_LenSrcDir+=1
+
+def SkipDir(SrcDir,File):
+ Ret = g_DirsToSkip.has_key(File)
+ SrcDir=SrcDir[g_LenSrcDir:]
+
+ while not Ret and SrcDir:
+ SrcDir,Part=os.path.split(SrcDir)
+ File=os.path.join(Part,File)
+ Ret = g_DirsToSkip.has_key(File)
+ return Ret
+
+###############################################################################
+def DeleteFiles(SrcFile,DestFile):
+ print 'Deleting %s'%(SrcFile)
+ os.remove(SrcFile)
+ print 'Deleting %s'%(DestFile)
+ try:
+ os.remove(DestFile)
+ except:
+ print DestFile,'does not exist'
+
+###############################################################################
+#characters=['|','/','-','\\']
+#chariter=iter(characters)
+#def PrintBusy():
+# global characters
+# global chariter
+#
+# try:
+# char=chariter.next()
+# except StopIteration:
+# chariter=iter(characters)
+# char=chariter.next()
+#
+# sys.stdout.write(char)
+# sys.stdout.write(chr(8))
+count=0
+def PrintBusy():
+ global count
+ count+=1
+ item=str(count)
+ sys.stdout.write(item)
+ sys.stdout.write(chr(8)*len(item))
+###############################################################################
+
+if not os.path.isdir(g_DestDir):
+ print g_DestDir,"is not a directory"
+ sys.exit(1)
+
+def FileDiff(SrcFile,DestFile):
+ try:
+ Src=open(SrcFile,'rb')
+ Dest=open(DestFile,'rb')
+ while 1:
+ SrcLine=Src.read(4096)
+ DestLine=Dest.read(4096)
+ if SrcLine!=DestLine:
+ return 1
+ if not SrcLine:
+ return 0
+ except Exception,Object:
+ #print "Exception occured"
+ #print Object
+ return 1
+
+g_Dot=0
+def SynchroniseDir(SrcDir,DestDir):
+ global g_Dot
+ SrcFiles=os.listdir(SrcDir)
+ if g_Options.DelExistOnlyDest:
+ DstFiles=os.listdir(DestDir)
+ for File in DstFiles:
+ DestFile=os.path.join(DestDir,File)
+ try:
+ Index=SrcFiles.index(File)
+ except ValueError:
+ if os.path.isdir(DestFile):
+ if not g_NoSkipSvn and File=='.svn':
+ continue # Skip svn administration dirs
+ if not g_NoSkipGit and File=='.git':
+ continue # Skip svn administration dirs
+ if SkipDir(SrcDir,File):
+ continue
+ print 'Deleting directory',DestFile
+ shutil.rmtree(DestFile)
+ else:
+ if g_FilesToSkip.has_key(File):
+ continue
+ print 'Deleting file',DestFile
+ os.remove(DestFile)
+
+ for File in SrcFiles:
+ SrcFile=os.path.join(SrcDir,File)
+ DestFile=os.path.join(DestDir,File)
+ if os.path.isdir(SrcFile):
+ if not g_NoSkipSvn and File=='.svn':
+ continue # Skip svn administration dirs
+ if not g_NoSkipGit and File=='.git':
+ continue # Skip svn administration dirs
+ if SkipDir(SrcDir,File):
+ continue
+ if not os.path.isdir(DestFile):
+ if g_Dot:
+ sys.stdout.write('\n')
+ g_Dot=0
+ if not g_DoNothing:
+ if g_Ask:
+ sys.stdout.write("Create directory %s? (y/n)"%DestFile)
+ if sys.stdin.read(1)=='y':
+ print "Creating dir",DestFile
+ os.mkdir(DestFile)
+ sys.stdin.read(1)
+ else:
+ print "Creating dir",DestFile
+ os.mkdir(DestFile)
+ else:
+ print "Creating dir",DestFile
+ SynchroniseDir(SrcFile,DestFile)
+ else:
+ if g_Extre and not g_Extre.search(File):
+ continue
+ if g_FilesToSkip.has_key(File):
+ continue
+ if g_FilesToDelete:
+ if g_FilesToDelete.search(File):
+ if g_Dot:
+ sys.stdout.write('\n')
+ g_Dot=0
+ DeleteFiles(SrcFile,DestFile)
+ continue
+ if FileDiff(SrcFile,DestFile):
+ #if os.system('fc /b "%s" "%s" >& nul'%(SrcFile,DestFile)):
+ if g_Dot:
+ sys.stdout.write('\n')
+ g_Dot=0
+ if not g_DoNothing:
+ if g_Ask or g_FilesToConfirm.has_key(File):
+ sys.stdout.write("Copy/Merge %s to %s? (y/n/m/d)"%(SrcFile,DestFile))
+ R=sys.stdin.read(1)
+ if R=='y':
+ print '%s -> %s'%(SrcFile,DestFile)
+ shutil.copyfile(SrcFile,DestFile)
+ elif R=='m':
+ print '%s -> %s'%(SrcFile,DestFile)
+ os.system('fcg "%s" "%s"'%(SrcFile,DestFile))
+ elif R=='d':
+ DeleteFiles(SrcFile,DestFile)
+ sys.stdin.read(1)
+ else:
+ print '%s -> %s'%(SrcFile,DestFile)
+ # check if the file is read-only
+ try:
+ Mode=os.stat(DestFile).st_mode
+ except OSError:
+ Mode=g_WriteMask
+ if not g_WriteMask&Mode:
+ ReadOnly=True
+ os.chmod(DestFile,Mode|g_WriteMask)
+ else:
+ ReadOnly=False
+ shutil.copyfile(SrcFile,DestFile)
+ if ReadOnly:
+ os.chmod(DestFile,Mode & (~g_WriteMask) )
+
+ else:
+ print '%s -> %s'%(SrcFile,DestFile)
+ else:
+ PrintBusy()
+ g_Dot=1
+
+SynchroniseDir(g_SrcDir,g_DestDir)
+sys.stdout.write("\n")