From c22d66b350db2e213cc916fae4f6207440a9be4f Mon Sep 17 00:00:00 2001 From: Elena ``of Valhalla'' Grandi Date: Mon, 19 Dec 2016 22:12:58 +0100 Subject: Create new empty entry, also from the command line --- lesana/collection.py | 60 ++++++++++++++++++++++++++++++++--------- lesana/command.py | 18 +++++++++++++ scripts/lesana | 15 +++++++++++ tests/data/simple/settings.yaml | 3 +++ tests/test_collection.py | 37 +++++++++++++++++++++++-- 5 files changed, 118 insertions(+), 15 deletions(-) create mode 100644 lesana/command.py create mode 100755 scripts/lesana diff --git a/lesana/collection.py b/lesana/collection.py index b3c994f..305fed3 100644 --- a/lesana/collection.py +++ b/lesana/collection.py @@ -9,8 +9,15 @@ import xapian class Entry(object): def __init__(self, collection, data={}, fname=None): self.collection = collection - self.data = data + self.data = data or self.empty_data() self.fname = fname + self.uid = self.data.get('uid', None) + if not self.uid: + if self.fname: + self.uid, ext = os.path.splitext(os.path.basename(self.fname)) + else: + self.uid = uuid.uuid4().hex + self.fname = self.uid + '.yaml' @property def indexed_fields(self): @@ -26,19 +33,26 @@ class Entry(object): return fields + def empty_data(self): + data = {} + for field in self.collection.settings['fields']: + t = field['type'] + if t in ['string', 'text']: + data[field['name']] = '' + elif t == 'integer': + data[field['name']] = 0 + else: + data[field['name']] = None + return data + + @property def yaml_data(self): return ruamel.yaml.dump(self.data, Dumper=ruamel.yaml.RoundTripDumper) @property def idterm(self): - uid = self.data.get('uid', None) - if not uid: - if self.fname: - uid, ext = os.path.splitext(os.path.basename(self.fname)) - else: - uid = uuid.uuid4().hex - return "Q"+uid + return "Q"+self.uid class Collection(object): @@ -47,6 +61,7 @@ class Collection(object): def __init__(self, directory=None): self.basedir = directory or os.getcwd() + self.cache = None try: with open(os.path.join(self.basedir, 'settings.yaml')) as fp: self.settings = ruamel.yaml.load( @@ -81,17 +96,24 @@ class Collection(object): doc = xapian.Document() self.indexer.set_document(doc) - # FIXME: this is obviously wrong, actually index the right - # things # Fields with prefix, for field search for field in entry.indexed_fields: - self.indexer.index_text(field['value'], 1, field['prefix']) + try: + self.indexer.index_text(field['value'], 1, field['prefix']) + except ValueError as e: + logging.info("Not indexing empty? value {}: {}".format( + field['value'], + str(e))) # unprefixed fields, for full text search for field in entry.indexed_fields: if field.get('free_search', False): - self.indexer.index_text(field['value']) - self.indexer.increase_termpos() + try: + self.indexer.index_text(field['value']) + self.indexer.increase_termpos() + except ValueError as e: + # probably already logged earlier + pass doc.set_data(entry.yaml_data) doc.add_boolean_term(entry.idterm) @@ -131,3 +153,15 @@ class Collection(object): else: updated += 1 return updated + + def save_entries(self, entries=None): + if not entries: + raise NotImplementedYet + for e in entries: + complete_name = os.path.join( + self.basedir, + 'items', + e.fname + ) + with open(complete_name, 'w') as fp: + fp.write(e.yaml_data) diff --git a/lesana/command.py b/lesana/command.py new file mode 100644 index 0000000..bd6ecab --- /dev/null +++ b/lesana/command.py @@ -0,0 +1,18 @@ +import gadona +#from .collection import Collection, Entry +from . import Collection, Entry + + +class New(gadona.Command): + name = 'new' + arguments = [ + (['--collection', '-c'], dict( + help='The collection to work on (default .)' + )), + ] + + def main(self): + collection = Collection() + new_entry = Entry(collection) + collection.save_entries(new_entry) + print(new_entry.fname) diff --git a/scripts/lesana b/scripts/lesana new file mode 100755 index 0000000..64cbc17 --- /dev/null +++ b/scripts/lesana @@ -0,0 +1,15 @@ +#!/usr/bin/env python3 + +import gadona +from lesana.command import New + +if __name__ == '__main__': + app = gadona.App() + app.description = "Manage collections" + app.commands = [ + New(), + ] + app.main() + + + diff --git a/tests/data/simple/settings.yaml b/tests/data/simple/settings.yaml index 177aa92..36c4e3e 100644 --- a/tests/data/simple/settings.yaml +++ b/tests/data/simple/settings.yaml @@ -10,3 +10,6 @@ fields: - name: position type: string index: facet + - name: quantity + type: integer + index: no diff --git a/tests/test_collection.py b/tests/test_collection.py index c54dc32..1bacfd6 100644 --- a/tests/test_collection.py +++ b/tests/test_collection.py @@ -24,7 +24,7 @@ class testCollectionLoading(unittest.TestCase): self.collection = lesana.Collection('tests/data/simple') self.assertIsNotNone(self.collection.settings) self.assertEqual(self.collection.settings['name'], "Simple lesana collection") - self.assertEqual(len(self.collection.settings['fields']), 3) + self.assertEqual(len(self.collection.settings['fields']), 4) self.collection.update_cache() self.assertIsNotNone(self.collection.cache) @@ -59,7 +59,7 @@ class testEntries(unittest.TestCase): data = ruamel.yaml.load(fp) entry = lesana.Entry(self.collection, data=data, fname=fname) self.assertEqual(entry.idterm, 'Q'+data['uid']) - self.assertEqual(len(entry.indexed_fields), 3) + self.assertEqual(len(entry.indexed_fields), 4) fname = '11189ee47ddf4796b718a483b379f976.yaml' uid = '11189ee47ddf4796b718a483b379f976' with open(os.path.join(self.basepath, fname)) as fp: @@ -67,3 +67,36 @@ class testEntries(unittest.TestCase): entry = lesana.Entry(self.collection, data=data, fname=fname) self.assertEqual(entry.idterm, 'Q'+uid) self.assertEqual(len(entry.indexed_fields), 3) + + def test_write_new(self): + new_entry = lesana.Entry(self.collection) + self.collection.save_entries(entries=[new_entry]) + entry_fname = 'tests/data/simple/items/' + new_entry.fname + with open(entry_fname) as fp: + written = ruamel.yaml.load(fp) + self.assertIsInstance(written['quantity'], int) + self.assertIsInstance(written['name'], str) + os.remove(entry_fname) + + +class testComplexCollection(unittest.TestCase): + @classmethod + def setUpClass(self): + self.collection = lesana.Collection('tests/data/complex') + + @classmethod + def tearDownClass(self): + shutil.rmtree(os.path.join(self.collection.basedir, '.lesana')) + + def test_init(self): + self.assertIsNotNone(self.collection.settings) + self.assertEqual( + self.collection.settings['name'], + "Fully featured lesana collection" + ) + self.assertEqual(len(self.collection.settings['fields']), 3) + self.assertIsNotNone(self.collection.stemmer) + + def test_index(self): + self.collection.update_cache() + self.assertIsNotNone(self.collection.cache) -- cgit v1.2.3