Commits

markolopa  committed 50cf3fb

names and titles added to all items, usage of item types cleaned

  • Participants
  • Parent commits b5dc427

Comments (0)

Files changed (10)

File items/global_item_type_dict.py

-# global dict loaded by the item types appearing in the plugins
-# see plugins/__init__.py
-# note: the dict may not be empty (if there are default item types, i.e. item 
-# types not coming from the plugins)
-
-ITEM_TYPE_TO_CLASS = {}

File items/global_item_type_list.py

+# global list loaded by the item types appearing in the plugins
+# see plugins/__init__.py
+
+ITEM_TYPES = []

File plugins/plantrisk_change.py

 
 from limma import PACKAGE_DIR
 from limma.items.item import AbstractItem, Resource
-from limma.items.global_item_type_dict import ITEM_TYPE_TO_CLASS
+from limma.items.global_item_type_list import ITEM_TYPES
 from limma.elements.elements import TextInput, PathBox, SubprocessBox
 from limma.persister.container import PersistentObject
 
 class PlantriskChange(AbstractItem):
     "Define a PlantRisk master workbook for a case"
+    name = 'plantrisk_change'
+    title = 'PlantRisk change workbook'
+
     def __init__(self, name, parent_container, create=False):
         provides = [Resource('plantrisk_workbook_path', 'result_path')]
         AbstractItem.__init__(self, name, parent_container,
     def execute(self):
         raise NotImplementedError()
 
-ITEM_TYPE_TO_CLASS['PlantRisk change'] = PlantriskChange
+# trick to register the class of the plugin
+ITEM_TYPES.append(PlantriskChange)

File plugins/plantrisk_master.py

 import os
 
 from limma.items.item import AbstractItem, Resource
-from limma.items.global_item_type_dict import ITEM_TYPE_TO_CLASS
+from limma.items.global_item_type_list import ITEM_TYPES
 from limma.elements.elements import TextInput, PathBox
 from limma.persister.container import PersistentObject
 
 class PlantriskMaster(AbstractItem):
     "Define a PlantRisk master workbook for a case"
+    name = 'plantrisk_master'
+    title = 'PlantRisk master workbook'
+
     def __init__(self, name, sheet_persister, create=False):
         provides = [Resource('plantrisk_workbook_path', '_path')]
         AbstractItem.__init__(self, name, sheet_persister,
         # not needed since this item has no element to be executed by the ui
         raise NotImplementedError()
 
-ITEM_TYPE_TO_CLASS['PlantRisk master'] = PlantriskMaster
+# trick to register the class of the plugin
+ITEM_TYPES.append(PlantriskMaster)

File plugins/shell_no_cancel.py

 import subprocess
 
 from limma.items.item import AbstractItem
-from limma.items.global_item_type_dict import ITEM_TYPE_TO_CLASS
+from limma.items.global_item_type_list import ITEM_TYPES
 from limma.elements.elements import TextInput, TextBox
 from limma.persister.container import PersistentObject
 
 class ShellNoCancelItem(AbstractItem):
     """Run a shell command"""
+    name = 'shell_no_cancel'
+    title = u'Shell no cancel'
+
     def __init__(self, name, sheet_persister, create=False):
         AbstractItem.__init__(self, name, sheet_persister, create=create)
 
         raise NotImplementedError()
 
 # trick to register the class of the plugin
-ITEM_TYPE_TO_CLASS['shell_no_cancel'] = ShellNoCancelItem
+ITEM_TYPES.append(ShellNoCancelItem)

File plugins/shell_with_cancel.py

 from limma.items.item import AbstractItem
-from limma.items.global_item_type_dict import ITEM_TYPE_TO_CLASS
+from limma.items.global_item_type_list import ITEM_TYPES
 from limma.elements.elements import TextInput, SubprocessBox
 from limma.persister.container import PersistentObject
 
 class ShellWithCancelItem(AbstractItem):
     """Run a shell command using the Subprocess element which allows cancel"""
+    name = 'shell_with_cancel'
+    title = 'Shell with cancel'
+
     def __init__(self, name, parent_container, create=False):
         AbstractItem.__init__(self, name, parent_container, create=create)
 
         self._subprocess_box.visible = (len(self._output) > 0)
 
 # trick to register the class of the plugin
-ITEM_TYPE_TO_CLASS['shell_with_cancel'] = ShellWithCancelItem
+ITEM_TYPES.append(ShellWithCancelItem)

File plugins/upper_case.py

 from limma.items.item import AbstractItem
-from limma.items.global_item_type_dict import ITEM_TYPE_TO_CLASS
+from limma.items.global_item_type_list import ITEM_TYPES
 from limma.elements.elements import TextBox
 from limma.persister.container import PersistentObject
 
 class UpperCaseTextItem(AbstractItem):
+    name = 'upper_case'
+    title = u'Upper case'
+
     def __init__(self, name, sheet_persister, create=False):
         # When this code was first written the objects didn't have to be
         # replicated like they are now. Before, the persistence was made 
         #   text
         # - This new design seems ugly for this item, but for more complex 
         #   items it will imply a cleared, more explicit code
+
         AbstractItem.__init__(self, name, sheet_persister, create=create)
         self._entered_text = PersistentObject()
         self._formatted_text = PersistentObject()
         raise NotImplementedError()
 
 # trick to register the class of the plugin
-ITEM_TYPE_TO_CLASS['upper_case'] = UpperCaseTextItem
+ITEM_TYPES.append(UpperCaseTextItem)

File structure/sheet.py

 from limma.config.logger import get_module_logger
 
 # trick to feed the global dict with classes from the plugins
-from limma.items.global_item_type_dict import ITEM_TYPE_TO_CLASS
+from limma.items.global_item_type_list import ITEM_TYPES
 import limma.plugins  # pylint: disable=W0611
 
 class Sheet(Container):
     def add_item(self, item_type, name=None, index=None):
 
         self.logger.info("Adding item of type %s on index %s" 
-                         % (item_type, index))
+                         % (item_type.name, index))
 
         names = set([e.name for e in self._item_struct.list])
         if not name:
-            name = compute_random_name(item_type, names)
+            name = compute_random_name(item_type.name, names)
         else:
             # make sure that the name does not exist
             names = set([e.name for e in self._item_struct.list])
             if name in names:
                 raise ValueError("item '%s' already exists")
         
-        item_class = ITEM_TYPE_TO_CLASS[item_type]
-        item = item_class(name, self._persister, create=True)
+        item = item_type(name, self._persister, create=True)
         self._item_struct.add(item, item_type, index=index)
         
         # cursor can't remain after an edited item
         self._update_cursor_after_execution(item)
 
     @staticmethod
-    def list_all_item_types():
-        return sorted(ITEM_TYPE_TO_CLASS.keys())
+    def all_item_types():
+        return ITEM_TYPES
 
     @staticmethod
-    def item_type_name(item):
-        for name, klass in ITEM_TYPE_TO_CLASS.items():
-            if isinstance(item, klass):
-                return name
+    def item_type_from_name(name):
+        for _type in ITEM_TYPES:
+            if _type.name == name:
+                return _type
         else:
-            raise TypeError("Unforeseen type for item: '%s'" % type(item))
+            raise TypeError("Type of name %s not found" % name)
 
     # --------------------------------------------------------------------------
     # private
             # incrementing the cursor)
             self._cursor += 1
 
-    # --------------------------------------------------------------------------
-    # aux
-
-    def _create_random_name(self, item_type):
-        "an ugly way to give names, to be used as directory names"
-        # - it is better to give random names instead of 001, 002, etc
-        #   because the order of the creation may not be the order in 
-        #   the sheet (and so the names would be give a misleading
-        #   suggestion of order)
-        # - this ugly code will cleaned when the file system will 
-        #   be replaced by a better data structure (database?) to store
-        #   the sheet items
-        names = [e.name for e in self._item_struct.list]
-        trials = 0
-        while True:
-            i = random.randint(0, 1000)
-            name = '%s%03d' % (item_type, i)
-            if not name in names:
-                break
-            trials += 1
-            if trials == 10000:
-                raise RuntimeError("infinite loop avoided")
-        return name
-
     def _compute_data(self):
         # each processed item adds/overides objects
         self.data = {}
         #   for instantiating the item
         self.list = []
         for name in self._names:
-            tname = self._name_to_type_name[name]
-            item_class = ITEM_TYPE_TO_CLASS[tname]
-            item = item_class(name, self._persister)
+            item_type_name = self._name_to_type_name[name]
+            for _type in ITEM_TYPES:
+                if item_type_name == _type.name:
+                    item_type = _type
+                    break
+            else:
+                raise TypeError("Can't find item type of name %s" 
+                                % item_type_name)
+            item = item_type(name, self._persister)
             self.list.append(item)
 
-    def add(self, item, type_name, index=None):
+    def add(self, item, item_type, index=None):
         if index is None:
             index = len(self.list)
         name = item.name
         if name in self._names:
             raise ValueError("Item with name %s already exists" % name)
         self.list.insert(index, item)
-        self._name_to_type_name[name] = type_name
+        self._name_to_type_name[name] = item_type.name
         self._names.insert(index, name)
 
     def delete(self, index):

File tests/test_sheet.py

         
         sheet = Sheet('test-sheet', persister, create=True, title=u'test sheet')
 
+        upper_case_type = Sheet.item_type_from_name('upper_case')
+
         # upper case is the item used for tests
-        self.assertTrue('upper_case' in sheet.list_all_item_types())
+        self.assertTrue(upper_case_type in sheet.all_item_types())
 
         # add 1 item
         self.assertEqual(len(sheet), 0)
         self.assertEqual(sheet.cursor, 0)
 
         # add and edit first item
-        sheet.add_item('upper_case')
+        sheet.add_item(upper_case_type)
         i_item = 0
         text_0 = 'text 0'
         sheet.edit_element(i_item, I_ELEMENT_ENTERED, text_0)
 
         # add and edit second item
-        sheet.add_item('upper_case')
+        sheet.add_item(upper_case_type)
         i_item = 1
         text_1 = 'text 1'
         sheet.edit_element(i_item, I_ELEMENT_ENTERED, text_1)
         self.assertEqual(sheet.cursor, 1)
 
         # check aux methods
-        self.assertTrue('upper_case' in sheet.list_all_item_types())
-        i_item = 0
-        item = sheet.items[i_item]
-        self.assertEqual('upper_case', sheet.item_type_name(item))
-        self.assertRaises(TypeError,  sheet.item_type_name, 'just a string')
+        self.assertTrue(upper_case_type in sheet.all_item_types())
+        self.assertEqual(upper_case_type, sheet.item_type_from_name('upper_case'))
+        self.assertRaises(TypeError,  sheet.item_type_from_name, 'spam')
         
         # delete second item: cursor does not change
         sheet.delete_item(1)

File ui/console/console_ui.py

         AbstractUI.__init__(self, conf)
         struct = Structure(conf)
         self._book_tree = struct.book_tree
-        self._sheet = None
+        self._sheet = None  # sheet shown at the moment
 
     def loop(self):
         self._main_menu()
 
     def _display_item(self, i_item, item):
         info = []
-        info.append(self._sheet.item_type_name(item))
+        _type = type(item)
+        info.append(_type.title)
         if item.failed:
             info.append('[failed]')
         if item.cancelled:
 
     def _choose_type_menu(self, index):
         options = []
-        for i, etype in enumerate(self._sheet.list_all_item_types()):
-            options.append(Option(str(i), etype, self._sheet.add_item, 
-                                  args=(etype,), kwargs={'index': index}))
+        for i, _type in enumerate(self._sheet.all_item_types()):
+            options.append(Option(str(i), _type.title, self._sheet.add_item, 
+                                  args=(_type,), kwargs={'index': index}))
         options.append(EXIT_OPTION)
         Menu("Choose type of item to add", options).run()