def test_close(self): fridge = Fridge(file=self.buf) fridge['a'] = 'a' fridge.close() self.assertTrue(fridge.closed) self.assertFalse(self.buf.closed) self.assertEqual(self.buf.getvalue(), '{"a": "a"}') with self.assertRaises(ValueError): fridge.load() with self.assertRaises(ValueError): fridge.save()
class Blast: DEFAULT_DB_PATH = path.expanduser(path.join("~", ".blast_db.json")) def __init__(self, path=None): if path is None: self.db_path = self.DEFAULT_DB_PATH else: self.db_path = path self.entries = Fridge(self.db_path) self.closed = False def validating_key(func): @wraps(func) def wrapper(self, args): if args.key is not None: self.validate_key(args.key) try: func(self, args) except KeyError: print("Error: Key not found!") return wrapper @staticmethod def is_valid_key(key): reg = r"[\w]+(\.[\w]+)?$" return re.match(reg, key) def clear(self, key=None): if key is not None: new_entries = {k: v for k, v in self.entries.items() if not k.startswith(key + ".")} else: new_entries = {} self.entries.clear() self.entries.update(new_entries) def get_list(self, key=None): if key is not None: keys = [name for name in self if name.startswith(key + ".")] else: keys = list(self) return sorted(keys) @classmethod def validate_key(cls, key): if not cls.is_valid_key(key): print( "Error: Invalid key: `{0}`\n".format(key) + "Expected format: `<word1>[.<word2>]` " + "where words consist of letters, numbers and underscores" ) sys.exit(1) ### Commands ### @validating_key def cmd_get(self, args): key = args.key val = self[key] print(val) @validating_key def cmd_set(self, args): key = args.key value = args.value if value is None: value = sys.stdin.read() self[key] = value @validating_key def cmd_delete(self, args): key = args.key del self[key] @validating_key def cmd_clear(self, args): key = args.key self.clear(key) @validating_key def cmd_list(self, args): key = args.key entries = self.get_list(key) if not entries: print("There are no entries!") return print("\n".join(entries)) @validating_key def cmd_open(self, args): key = args.key val = self[key] Platform.open(val) @validating_key def cmd_copy(self, args): key = args.key val = self[key] Platform.copy_to_clipboard(val) print(val) def cmd_move(self, args): key = args.key dest = args.dest self.validate_key(key) self.validate_key(dest) self[dest] = self[key] del self[key] ###^ Commands ^### ### Container interface ### def __getitem__(self, key): return self.entries[key] def __setitem__(self, key, value): self.entries[key] = value def __delitem__(self, key): del self.entries[key] def __iter__(self): return iter(self.entries) def __len__(self): return len(self.entries) def __contains__(self, item): return item in self.entries ###^ Container interface ^### ### Resource management ### def close(self): self.entries.close() self.closed = False def __enter__(self): return self def __exit__(self, *_): self.close() return False def __del__(self): self.close()