diff --git a/persoconf/main.py b/persoconf/main.py index 6227082..700ab3b 100755 --- a/persoconf/main.py +++ b/persoconf/main.py @@ -2,10 +2,11 @@ import argparse import logging -import json import os, os.path import shutil +from metafile import Metafile, MalformedMetafileError, NoPathDefinedError + # FUNCTIONS ######################################## def yes_no_question(question="Yes or no?", default=False): @@ -153,28 +154,29 @@ if args.command == "add": confpath = appdir + "/" + confname # Load app META file - metafile = appdir + "/" + args.metafile - try: - appmeta = json.load( open(metafile) ) + appmeta = Metafile(json_path = appdir + "/" + args.metafile) + except FileNotFoundError: log.info("Metafile %s does not exist for app %s" % (args.metafile, args.app)) - appmeta = { "name" : args.app, "depends": {}, "files": {} } + appmeta = Metafile( name=args.app ) + + except MalformedMetafileError: + log.error("Malformed metafile %s in app %s" % (args.metafile, args.app) ) + exit(1) # Check that the file is really new absconf = contractuser( os.path.abspath(os.path.expanduser(args.conf)) ) try: - destslist = {} + dstdic = appmeta.get_files_dst2src() - for (fname,finfo) in appmeta["files"].items(): - destslist[finfo["dest"]] = fname - except KeyError: + except MalformedMetafileError: log.error("Malformed metafile %s in app %s" % (args.metafile, args.app) ) exit(1) - - if absconf in destslist: - log.error("File %s already exists as %s in app %s" % (absconf, destslist[absconf], args.app)) + + if absconf in dstdic: + log.error("File %s already exists as %s in app %s" % (absconf, dstdic[absconf], args.app)) exit(1) # Copy the conf dir @@ -207,7 +209,6 @@ if args.command == "add": try: log.info("Copying conf file") shutil.copyfile(args.conf, confpath) - log.info("New conf file '%s' associated with app '%s'" % (confname, args.app)) except PermissionError: @@ -217,12 +218,16 @@ if args.command == "add": # Add the file to META # Update META data log.debug("adding meta data for %s in %s" % (confname, args.app)) - appmeta["files"][confname] = { "dest": absconf } + appmeta.add_file( confname, dest=absconf ) # Write to the metafile - log.debug("Wrinting to metafile") - json.dump(appmeta, open(metafile, 'w')) + try: + log.debug("Writing to metafile") + appmeta.save() + except NoPathDefinedError: + log.error("Unable to save json Metafile for app %s : no path defined" % appmeta.name) + exit(1) ######################################## diff --git a/persoconf/metafile.py b/persoconf/metafile.py new file mode 100644 index 0000000..268e9f7 --- /dev/null +++ b/persoconf/metafile.py @@ -0,0 +1,78 @@ +#!/usr/bin/env python3 + +import json + +class Metafile(): + """Representation of a metafile (default name META), containing (as its + name implies) metadata.""" + + + def __init__(self, json_path=None, name=None): + + self.name = name + + # json_path given => we load it ; otherwise fill with default + if json_path is not None: + self.load_json(json_path) # raise FileNotFoundError + else: + self.load_default() + + def load_default(self): + self.json_path = None + self.depends = {} + self.files = {} + # (Note that name is already written in __init__) + + def load_json(self, json_path): + self.json_path = json_path + + tmp = json.load( open(self.json_path) ) # Can raise a FileNotFoundError + + try: + self.name = tmp["name"] + self.depends = tmp["depends"] + self.files = tmp["files"] + except KeyError: + raise MalformedMetafileError("Missing attribute (name, depends or files)") + + def save(self): + if self.json_path is None: + raise NoPathDefinedError("json_path is not defined") + + json.dump( { "name": self.name, "depends": self.depends, "files": self.files }, open(self.json_path, 'w') ) + + + def get_files_dst2src(self): + dstdic = {} + + try: + for (fname, finfo) in self.files.items(): + dstdic[ finfo["dest"] ] = fname + except KeyError: + raise MalformedMetafileError("Missing 'dest' attribute in files infos") + + return dstdic + + def add_file(self, name, dest): + self.files[name] = { "dest": dest } + + + +# Exceptions +######################################## +class MalformedMetafileError(Exception): + """A custom exception to alert that the metafile is malformed""" + + def __init__(self, message): + Exception.__init__(self, message) + + +class NoPathDefinedError(Exception): + """A custom exception to alert that the json_path properties of the + Metafile is not defined, therefore we cannot write the data.""" + + def __init__(self, message): + Exception.__init__(self, message) + + +