From 97b111acee9f613289950ce6904c010e86aa3fb8 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Savard Date: Thu, 16 Apr 2009 20:29:54 +0000 Subject: Merge of jc and origin jc Merge branch 'jc' of ssh://bobthebuilder.mine.nu:8080/home/git into jc Conflicts: source/external/source/sugar-toolkit/src/sugar/activity/activity.py source/external/source/sugar-toolkit/src/sugar/tutorius/Makefile.am source/external/source/sugar-toolkit/src/sugar/tutorius/bundler.py source/external/source/sugar-toolkit/src/sugar/tutorius/tests/run-tests.py --- (limited to 'src/sugar/tutorius/bundler.py') diff --git a/src/sugar/tutorius/bundler.py b/src/sugar/tutorius/bundler.py index 6f61779..8712c86 100644 --- a/src/sugar/tutorius/bundler.py +++ b/src/sugar/tutorius/bundler.py @@ -22,26 +22,38 @@ This module contains all the data handling class of Tutorius import logging import os +import shutil import uuid import xml.dom.minidom -import xml.dom.ext from sugar.tutorius import gtkutils, overlayer from sugar.tutorius.core import Tutorial, State, FiniteStateMachine -import sugar.tutorius.actions -import sugar.tutorius.filters +from sugar.tutorius.actions import DialogMessage, OnceWrapper, BubbleMessage +from sugar.tutorius.filters import GtkWidgetEventFilter, TimerEvent from ConfigParser import SafeConfigParser -def __get_store_root(): - return os.path.join(os.getenv("SUGAR_PREFIX"),"share","tutorius","data") -def __get_bundle_root(): - return os.path.join(os.getenv("SUGAR_BUNDLE_PATH"),"data","tutorius","data") +def _get_store_root(): + path = os.path.join(os.getenv("SUGAR_PREFIX"),"share","tutorius","data") + if os.path.exists(path): + return path + else: + os.makedirs(path) + return path +def _get_bundle_root(): + path = os.path.join(os.getenv("SUGAR_BUNDLE_PATH"),"data","tutorius","data") + if os.path.exists(path): + return path + else: + os.makedirs(path) + return path INI_ACTIVITY_SECTION = "RELATED_ACTIVITIES" INI_METADATA_SECTION = "GENERAL_METADATA" INI_GUID_PROPERTY = "GUID" INI_NAME_PROPERTY = "NAME" INI_XML_FSM_PROPERTY = "FSM_FILENAME" +INI_FILENAME = "meta.ini" +TUTORIAL_FILENAME = "tutorial.xml" class TutorialStore: @@ -51,8 +63,8 @@ class TutorialStore: given activity. """ - store_root = __get_store_root() - bundle_root = __get_bundle_root() + store_root = _get_store_root() + bundle_root = _get_bundle_root() logging.debug("*********** Path of store_root : " + store_root) @@ -119,96 +131,57 @@ class XMLSerializer(Serializer): used in the tutorials to/from a .xml file. Inherit from Serializer """ - def create_state_dict_node(self, state_dict, doc): - """ - Create and return a xml Node from a State dictionnary. - """ - statesList = doc.createElement("States") - for state_name, state in state_dict.items(): - stateNode = statesList.appendChild("State") - stateNode.setAttribute("State:Name", state_name) - stateNode = stateNode.appendChild(create_action_list_node(state.action_list, doc)) - stateNode = stateNode.appendChild(create_event_filters_node(state.event_filters, doc)) - return statesList - def create_action_list_node(self, action_list, doc): - """ - Create and return a xml Node from a Action list. - """ - actionsList = doc.createElement("Actions") - for action in action_list: - actionNode = actionsList.appendChild("Action") - if type(action) is DialogMessage: - actionNode.setAttribute("Action:Class", type(action)) - actionNode.setAttribute("Action:Message", action.message) - actionNode.setAttribute("Action:Position", action.position) - elif type(action) is BubbleMessage: - actionNode.setAttribute("Action:Class", str(type(action))) - actionNode.setAttribute("Action:Message", action.message) - actionNode.setAttribute("Action:Position", action.position) - actionNode.setAttribute("Action:Tail_pos", action.tail_pos) - # TODO : elif for each type of action - elif type(action) is WidgetIdentifyAction: - actionNode.setAttribute("Action:Class", str(type(action))) - # TODO - elif type(action) is ChainAction: - # TODO - actionNode.setAttribute("Action:Class", str(type(action))) - elif type(action) is DisableWidgetAction: - # TODO - actionNode.setAttribute("Action:Class", str(type(action))) - elif type(action) is TypeTextAction: - # TODO - actionNode.setAttribute("Action:Class", str(type(action))) - elif type(action) is ClickAction: - # TODO - actionNode.setAttribute("Action:Class", str(type(action))) - - return actionsList - def create_event_filters_node(self, event_filters, doc): - """ - Create and return a xml Node from a event filters. - """ - eventFiltersList = doc.createElement("EventFiltersList") - for event_f in event_filters: - eventFilterNode = eventFiltersList.appendChild("EventFilter") - # TODO : elif for each type of event filters - if type(event_f) is TimerEvent: - # TODO - eventFilterNode.setAttribute("EventFilter:Class", str(type(event_f))) - elif type(event_f) is GtkWidgetEventFilter: - # TODO - eventFilterNode.setAttribute("EventFilter:Class", str(type(event_f))) - elif type(event_f) is GtkWidgetTypeFilter: - # TODO - eventFilterNode.setAttribute("EventFilter:Class", str(type(event_f))) - - return eventFiltersList - - def save_fsm(self, fsm, xml_filename, path): + 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. """ - doc = xml.dom.minidom.Document() - fsm_element = doc.createElement("FSM") - doc.appendChild(fsm_element) - fsm_element.setAttribute("fsm:Name", fsm.name) - fsm_element.setAttribute("fsm:StartStateName", fsm.start_state_name) - fsm_element = fsm_element.appendChild(create_state_dict_node(fsm.state_dict, doc)) - fsm_element = fsm_element.appendChild(create_action_list_node(fsm.action_list, doc)) + fsm_xml = xml.dom.minidom.Document() + fsm_element = doc.createElementNS("http://tutorius.org", "FSM") + fsm_xml.appendChild(fsm_element) + fsm_element.setAttributeNS("http://tutorius.org", "fsm:Name", fsm.name) + fsm_element.setAttributeNS("http://tutorius.org", "fsm:StartStateName", fsm.start_state_name) + #fsm_element = doc. + tutorial_element.appendChild(fsm_element) - file_object = open(path + "/" + xml_filename, "w") - xml.dom.ext.PrettyPrint(doc, file_object) - file_object.close() - + +## logging.debug("************ found .tml file : " + file_name) +## key_line = linecache.getline(path + file_name, 1) +## key_line = key_line.split("\n")[0] +## fileKey = key_line.split("--KEY::")[1] +## logging.debug("************ fileKey = " + fileKey) +## if key == fileKey: +## logging.debug("************ Key : " + key + \ +## " = fileKey : " + fileKey) +## tml = file(path + file_name, "r") +## str = tml.read() +## pick = str.split("--PICKLE::")[1] +## +## fsm = pickle.loads(pick) +## tuto = {key:Tutorial(key,fsm)} +## +## return tuto + def load_fsm(self, guid): """ Load fsm from xml file who .ini file guid match argument guid. """ - +## +## path = os.getenv("SUGAR_ACTIVITY_ROOT") + "/data/" +## # Create /data/ folder if no exists +## if not os.path.exists(path): +## os.mkdir(path) +## logging.debug("************* Creating data folder") +## +## # Save the dictionnary to .tml file +## tutoSave = file(path + filename + ".tml", 'w') +## str = "--KEY::" + key + "\n--NAME::" + name + "\n--PICKLE::" + \ +## pickle.dumps(fsm,0) +## tutoSave.write(str) +## tutoSave.close() class TutorialBundler: @@ -217,74 +190,81 @@ class TutorialBundler: editor. """ + + def __init__(self,generated_guid = None): """ - TODO. Tutorial_bundler constructor. If a GUID is given in the parameter, the Tutorial_bundler object will be associated with it. If no GUID is given, a new GUID will be generated, """ - self.Guid = generated_guid or uuid.uuid1() #Look for the file in the path if a uid is supplied if generated_guid: #General store - store_path = os.path.join(__get_store_root(), generated_guid, INI_FILENAME) + store_path = os.path.join(_get_store_root(), generated_guid, INI_FILENAME) if os.path.isfile(store_path): self.Path = os.path.dirname(store_path) else: #Bundle store - bundle_path = os.path.join(__get_bundle_root(), generated_guid, INI_FILENAME) + bundle_path = os.path.join(_get_bundle_root(), generated_guid, INI_FILENAME) if os.path.isfile(bundle_path): self.Path = os.path.dirname(bundle_path) else: raise IOError(2,"Unable to locate metadata file for guid '%s'" % generated_guid) else: - #Create the folder, any failure will go through to the caller for now - store_path = os.path.join(__get_store_root(), generated_guid) - os.mkdir(store_path) - self.Path = store_path - - - def __SetGuid(self, value): - self.__guid = value - - def __GetGuid(self): - return self.__guid - - def __DelGuid(self): - del self.__guid - - def __SetPath(self, value): - self.__path = value - - def __GetPath(self): - return self.__path - - def __DelPath(self): - del self.__path - - Guid = property(fget=__SetGuid, - fset=__GetGuid, - fdel=__DelGuid, - doc="The guid associated with the Tutoria_Bundler") - - Path = property(fget=__SetPath, - fset=__GetPath, - fdel=__DelPath, - doc="The path associated with the Tutoria_Bundler") - + #Create the folder, any failure will go through to the caller for now + store_path = os.path.join(_get_store_root(), generated_guid) + os.mkdir(store_path) + self.Path = store_path + + def __SetGuid(self, value): + self.__guid = value + + def __GetGuid(self): + return self.__guid + + def __DelGuid(self): + del self.__guid + + def __SetPath(self, value): + self.__path = value + + def __GetPath(self): + return self.__path + + def __DelPath(self): + del self.__path - def write_metadata_file(self, data): + Guid = property(fget=__SetGuid, + fset=__GetGuid, + fdel=__DelGuid, + doc="The guid associated with the Tutorial_Bundler") + + Path = property(fget=__SetPath, + fset=__GetPath, + fdel=__DelPath, + doc="The path associated with the Tutorial_Bundler") + + + def write_metadata_file(self, tutorial): """ - Write metadata to a property file. If a GUID is provided, TutorialBundler - will try to find and overwrite the existing property file who contain the - given GUID, and will raise an exception if it cannot find it. + Write metadata to the property file. + @param tutorial Tutorial for which to write metadata """ - NotImplementedError - + #Create the Config Object and populate it + cfg = SafeConfigParser() + cfg.add_section(INI_METADATA_SECTION) + cfg.set(INI_METADATA_SECTION, INI_GUID_PROPERTY, self.Guid) + cfg.set(INI_METADATA_SECTION, INI_NAME_PROPERTY, tutorial.name) + cfg.set(INI_METADATA_SECTION, INI_XML_FSM_PROPERTY, TUTORIAL_FILENAME) + + + #Write the ini file + cfg.write( file( os.path.join(self.Path, INI_FILENAME) ) ) + def get_tutorial_path(self): """ Return the path of the .ini file associated with the guiven guid set in @@ -292,8 +272,8 @@ class TutorialBundler: more than one path, the store_root is given priority. """ - store_root = __get_store_root() - bundle_root = __get_bundle_root() + store_root = _get_store_root() + bundle_root = _get_bundle_root() config = SafeConfigParser() path = None @@ -357,8 +337,30 @@ class TutorialBundler: save_fsm(fsm, xml_filename, store_root) - def add_resources(self, typename, file): + def add_ressource(self, file): """ - Add ressources to metadata. + Add ressource in tutorial directory + return True if success or if file is already in tutorial directory + return False if file is a directory """ - raise NotImplementedError("add_resources not implemented") + path = get_tutorial_path() + if os.path.isfile(file): + filename = os.split(file) + target = os.path.join(path,filename) + if os.path.samefile(file,target): + return True + else: + try: + shutil.copy(file,target) + return True + #This error is raised if the file already exists + except shutil.Error, err: + logger.debug(err) + return True + #General error for copying file + except IOError,err: + logger.debug(err) + return False + else: + logger.debug("file is a directory :"+file) + return False -- cgit v0.9.1