From 544b836dab71d36290d3da5131afaef77c88ccd8 Mon Sep 17 00:00:00 2001 From: mike Date: Fri, 17 Apr 2009 04:28:34 +0000 Subject: LP 341760 Core : Draft architecture for XML loading --- (limited to 'src/sugar/tutorius/bundler.py') diff --git a/src/sugar/tutorius/bundler.py b/src/sugar/tutorius/bundler.py index 6f61779..00ab3b6 100644 --- a/src/sugar/tutorius/bundler.py +++ b/src/sugar/tutorius/bundler.py @@ -189,7 +189,7 @@ class XMLSerializer(Serializer): def save_fsm(self, fsm, xml_filename, path): """ Save fsm to disk, in the xml file specified by "xml_filename", in the - "path" folder. If the specified file dont exist, it will be created. + "path" folder. If the specified file doesn't exist, it will be created. """ doc = xml.dom.minidom.Document() fsm_element = doc.createElement("FSM") @@ -204,13 +204,143 @@ class XMLSerializer(Serializer): file_object.close() + def _find_tutorial_dir_with_guid(self, guid): + """ + Finds the tutorial with the associated GUID. If it is found, return + the path to the tutorial's directory. If it doesn't exist, raise an + IOError. + + A note : if there are two tutorials with this GUID in the folders, + they will both be inspected and the one with the highest version + number will be returned. If they have the same version number, the one + from the global store will be returned. + + @param guid The GUID of the tutorial that is to be loaded. + """ + # Attempt to find the tutorial's directory in the global directory + global_dir = os.path.join(__get_store_root(), guid) + # Then in the activty's bundle path + activity_dir = os.path.join(__get_bundle_root(), guid) + + # If they both exist + if os.path.isdir(global_filename) and os.path.isdir(activity_dir): + # Inspect both metadata files + global_meta = os.path.join(global_dir, "meta.ini") + activity_meta = os.path.join(activity_dir, "meta.ini") + + # Open both config files + global_parser = SafeConfigParser() + global_parser.read(global_meta) + + activity_parser = SafeConfigParser() + activity_parser.read(activity_meta) + + # Get the version number for each tutorial + global_version = global_parser.get(INI_METADATA_SECTION, "version") + activity_version = activity_parser.get(INI_METADATA_SECTION, "version") + + # If the global version is higher or equal, we'll take it + if global_version >= activity_version: + return global_dir + else: + return activity_dir + + # Do we just have the global directory? + if os.path.isdir(global_dir): + return global_dir + + # Or just the activity's bundle directory? + if os.path.isdir(activity_dir): + return activity_dir + + # Error : none of these directories contain the tutorial + raise IOError(2, "Neither the global nor the bundle directory contained the tutorial with GUID"%guid) + + def _load_xml_properties(self, properties_elem): + """ + Changes a list of properties into fully instanciated properties. + + @param properties_elem An XML element reprensenting a list of + properties + """ + return [] + + def _load_xml_event_filters(self, filters_elem): + """ + Loads up a list of Event Filters. + + @param filters_elem An XML Element representing a list of event filters + """ + return [] + + def _load_xml_actions(self, actions_elem): + """ + Transforms an Actions element into a list of instanciated Action. + + @param actions_elem An XML Element representing a list of Actions + """ + return [] + + def _load_xml_states(self, states_elem): + """ + Takes in a States element and fleshes out a complete list of State + objects. + + @param states_elem An XML Element that represents a list of States + """ + return [] + + def _load_xml_fsm(self, fsm_elem): + """ + Takes in an XML element representing an FSM and returns the fully + crafted FSM. + + @param fsm_elem The XML element that describes a FSM + """ + # Load the FSM's name and start state's name + fsm_name = fsm_elem.getAttribute("fsm:Name") + + fsm_start_state_name = None + try: + fsm_start_state_name = fsm_elem.getAttribute("fsm:StartStateName") + except: + pass + + fsm = FiniteStateMachine(fsm_name, start_state_name=fsm_start_state_name) + + # Load the states + states = self._load_xml_states(fsm_elem.getElementsByName("States")) + for state in states: + fsm.add_state(state) + + # Load the actions on this FSM + actions = self._load_xml_actions(fsm_elem.getElementsByName("Actions")) + for action in actions: + fsm.add_action(action) + + # Load the event filters + events = self._load_xml_event_filters(fsm_elem.getElementsByName("EventFiltersList")) + for event in events: + fsm.add_event_filter(event) + + def load_fsm(self, guid): """ - Load fsm from xml file who .ini file guid match argument guid. + Load fsm from xml file whose .ini file guid match argument guid. """ + # Fetch the directory (if any) + tutorial_dir = self._find_tutorial_dir_with_guid(guid) + + # Open the XML file + tutorial_file = os.path.join(tutorial_dir, "fsm.xml") + xml_dom = xml.dom.minidom.parse(tutorial_file) + fsm_elem = xml_dom.getElementsByTagName("fsm")[0] + return self._load_xml_fsm(fsm_elem) + + class TutorialBundler: """ This class provide the various data handling methods useable by the tutorial -- cgit v0.9.1