ChkNames

From RdiffBackupWiki

Jump to: navigation, search
# coding: latin-1

import os, sys, time

#################################################################################################
# This script checks if any file or directory name has characters in the range 0x80 trough 0x9f #
# in it.                                                                                        #
# Files with name containing these characters cannot be opened in a Linux mounting, so they     #
# cannot be backuped by rdiff-backup.                                                           #
# IMPORTANT: It must be run on the Windows machine                                              #
#                                                                                               #
# A error log is generated in a file named like this: 2007-28-07_10-51-18_errors.txt            #
# Inside the error log file there are the filenames with wrong characters.                      #
# If the name is of a directory it is terminated by a os directory separator ("\" on Windows).  #
#                                                                                               #
# I've wrote this script in portuguese (my native language) and translated the variables and    #
# coments to english, so it could be (more) buggy (than the original version).                  #
# This script worked fine to me on a Windows 2000 Server.                                       #
# Maybe it'll work for you too.                                                                 #
#                                                                                               #
#                                                                                               #
# Author: Armando M. Baratti                                                                    #
#         ambaratti  <at>   larc  (dot) com   (dot) br                                          #                            
#         2007-07-31                                                                            #
#################################################################################################


class ConsCl:
	""" Console class to deal with encoding, menus and the like. (Somewhat striped down version).
	
	"""
	def __init__(self):
		import os
		self.Os = os.name
		self.OutEnc = sys.stdout.encoding
		self.InEnc = sys.stdin.encoding

	def Clean(self):
		if self.Os == 'posix':
			os.system('clear')
		else:
			os.system('cls')

	def Print(self, Str):
		print Str.decode('latin-1')

	def PrintInLine(self, obj, ConsSize=80):
		""" Prints without line termination.
		
			ConsSize is the size of the console (default 80) in columns.
		"""
		ValStr = str(obj)
		sys.stdout.write(ValStr + (ConsSize - 2 - len(ValStr)) * ' ' + '\r')
		sys.stdout.flush()

	def OptMenu(self, Prompt, OptLst, Clean=True):
		""" Shows a menu with Prompt and a list of options (OptLst) and get the choosen option.
		
			Returns the index of the choosen item.
			Discards non numeric or out of the range characters.
			Clean set to True makes the screen to be blanked before showing the Menu.
		"""
		MenuLst = [Prompt]
		for Idx,Opt in enumerate(OptLst):
			if len(OptLst) < 10:
				MenuLst.append('%d - %s' % (Idx + 1, Opt))
			else:
				MenuLst.append('%02d - %s' % (Idx + 1, Opt))
		Menu = '\n'.join(MenuLst)
		OptIdx = -1
		while OptIdx not in range(len(OptLst)):
			if Clean:
				self.Clean()
			self.Print(Menu)
			try:
				OptIdx = int(raw_input()) - 1
			except ValueError:
				OptIdx = -1
		return OptIdx

	def Raw_input(self, Msg, Enc='latin-1'):
		""" Get accented characters correctly on a Windows console.
		
		"""
		UMsg = unicode(Msg)
		return raw_input(UMsg.encode(self.OutEnc)).decode(self.OutEnc).encode(Enc)



if __name__ == '__main__':
	# List of offending characters
	CharErrorLst = [chr(c) for c in range(0x80, 0xa0)]
	Cons = ConsCl()
	MenuLst = ['Verify filenames after a point on a directory tree',
				'Quit']
	while True:
		Msg = ''
		MenuOpt = Cons.OptMenu('Choose an option:', MenuLst)
		if MenuOpt == MenuLst.index('Verify filenames after a point on a directory tree'):
			while True:
				# Check if the path corresponds to a valid directory
				IniDir = Cons.Raw_input('Enter the path from where to start: ')
				if (os.path.isdir(IniDir)):
					break
				else:
					Cons.Print('.. invalid path ..\n')
			OutFileName = '%04d-%02d-%02d_%02d-%02d-%02d_errors.txt' % time.localtime()[:6]
			FOut = open(OutFileName, 'w')
			try:
				for Dir, Subdirs, Files in os.walk(IniDir):
					if [Char for Char in Dir if Char in CharErrorLst]:
						# Found any invalid char in the directory name
						FOut.write('%s%s\n' % (Dir, os.sep))
					for File in Files:
						# Found any invalid char in the file name
						if [Char for Char in File if Char in CharErrorLst]:
							FOut.write('%s\n' % os.path.join(Dir,File))
			finally:
				FOut.close()
			Msg = 'Filenames verified.\nSee %s file.' % OutFileName
		elif MenuOpt == MenuLst.index('Quit'):
			break
		Cons.Raw_input(Msg)

Personal tools