Adding 'delete' command

master
Lertsenem 2015-09-16 18:51:44 +02:00
parent cedd6c3522
commit b473e698f1
2 changed files with 145 additions and 4 deletions

View File

@ -175,6 +175,43 @@ def copy_file_or_directory(logger, path_dst, path_src, overwrite=True):
# The End. # The End.
return True return True
# ======================================
def delete_file_or_dir(path, logger=None):
# Set logger to '/dev/null' if it's not set
if logger is None:
logger = logging.getLogger("/dev/null")
logger.addHandler(logging.NullHandler())
# Try it as a dir first
try:
logger.info("Removing directory %s" % path)
shutil.rmtree(path)
except FileNotFoundError:
logger.warning("File %s seems to be already deleted" % path)
return False
except PermissionError:
logger.warning("Cannot remove dir %s, you will have to do it manually"
% path)
return False
# If not, try it as a file
except NotADirectoryError:
try:
logger.info("Removing file %s" % path)
os.remove(path)
except PermissionError:
logger.warning( "Cannot remove file %s, you'll have to do it " \
"manually"
% path )
return False
return True
# ARGPARSE # ARGPARSE
@ -282,12 +319,17 @@ parser_del.add_argument( "app" ,
help="The app to delete, or the app to delete a " \ help="The app to delete, or the app to delete a " \
"conf file from" ) "conf file from" )
parser_del.add_argument( "conf" , parser_del.add_argument( "files" ,
nargs="?" , nargs="*" ,
type=str , type=str ,
help="The conf file or directory to delete from " \ help="The conf files or directories to delete from " \
"the app" ) "the app" )
parser_del.add_argument( "--force-yes", "-y" ,
action="store_true" ,
help="Don't ask silly questions" )
# Parse arguments # Parse arguments
args = parser.parse_args() args = parser.parse_args()
@ -361,6 +403,98 @@ if args.command == "list":
for app in persoconf.list_apps(logger=log): for app in persoconf.list_apps(logger=log):
print(app) print(app)
# DELETE COMMAND
########################################
if args.command == "delete":
# Does this app really exists ?
try:
appmeta = Metafile( json_path = persoconf.path
+"/"+ args.app
+"/"+ persoconf.metafile )
except FileNotFoundError:
log.error( "App %s does not seem to exist" % args.app )
exit(1)
except MalformedMetafileError:
log.error( "Failed to load metafile from app %s" % args.app )
exit(1)
# Does the user want to remove files or the entire app ?
if args.files == []:
# Delete the entire app
if ( args.force_yes
or yes_no_question("Really delete app '%s'?" % appmeta.name )
):
shutil.rmtree( persoconf.path +"/"+ appmeta.name )
log.warning("App %s was deleted" % appmeta.name)
else:
log.warning("Nothing was deleted")
exit(0)
else:
# Delete all required files (or directories)
if ( not args.force_yes
and not yes_no_question( "Delete all files from following list: " \
"%s from app %s?"
% (str(args.files),appmeta.name))
):
log.warning("Nothing was deleted")
exit(0)
# The filenames can be confnames or real files names. For each we'll
# assume first that it's a confname, then that it's a file name if that
# fails.
dstdic = appmeta.get_files_dst2src() # Get that here for optimization
for f in args.files:
# 1) It's probably a confname
if f in appmeta.files:
if delete_file_or_dir( logger = log ,
path = persoconf.path
+"/"+ appmeta.name
+"/"+ f ):
# File deleted, let's delete the entry in Metafile
appmeta.del_file(f)
appmeta.save()
else:
log.warning( "Something wrong occured while deleting " \
"file %s"
% f )
continue
# 2) If not, it must be a real filename
else:
absf = contractuser(os.path.abspath(os.path.expanduser(f)))
if absf in dstdic:
if delete_file_or_dir( logger = log ,
path = persoconf.path
+"/"+ appmeta.name
+"/"+ dstdir[absf] ):
# File deleted, let's delete the entry in Metafile
appmeta.del_file(dstdir[absf])
appmeta.save()
else:
log.warning( "Something wrong occured while " \
"deleting file %s"
% f )
continue
# 3) Otherwise, no idea what it is
else:
log.warning( "Cannot find file %s in app %s data; " \
"ignoring it"
% (f, appmeta.name) )
continue
# ADD COMMAND # ADD COMMAND
######################################## ########################################
if args.command == "add": if args.command == "add":
@ -475,7 +609,8 @@ if args.command == "update":
if args.files != []: if args.files != []:
dstdic = apps_to_update[app].get_files_dst2src() dstdic = apps_to_update[app].get_files_dst2src() # Get that here
# for optimization
# The filenames can be confnames or real files names. For each # The filenames can be confnames or real files names. For each
# we'll assume first that it's a confname, then that it's a file # we'll assume first that it's a confname, then that it's a file
@ -500,6 +635,7 @@ if args.command == "update":
"Failed to update %s from %s ; ignoring" "Failed to update %s from %s ; ignoring"
% ( f, apps_to_update[app].files[f]["dest"]) % ( f, apps_to_update[app].files[f]["dest"])
) )
continue
# 2) If not, it must be a real filename # 2) If not, it must be a real filename
else: else:
@ -521,12 +657,14 @@ if args.command == "update":
log.warning( "Failed to update %s from %s ; " \ log.warning( "Failed to update %s from %s ; " \
"ignoring" "ignoring"
% (dstdic[absf], absf) ) % (dstdic[absf], absf) )
continue
# 3) Otherwise, no idea what it is # 3) Otherwise, no idea what it is
else: else:
log.warning( "Cannot find file %s in app data; " \ log.warning( "Cannot find file %s in app data; " \
"ignoring it" "ignoring it"
% f ) % f )
continue
# If they were no 'file' args, it means we need to update all files in # If they were no 'file' args, it means we need to update all files in
# the app # the app

View File

@ -56,6 +56,9 @@ class Metafile():
def add_file(self, name, dest): def add_file(self, name, dest):
self.files[name] = { "dest": dest } self.files[name] = { "dest": dest }
def del_file(self, name):
del self.files[name]
# Exceptions # Exceptions