From 5491c551a2f88dbda852bc0e9d0c5406019e2be8 Mon Sep 17 00:00:00 2001 From: mike Date: Fri, 06 Nov 2009 05:13:59 +0000 Subject: LP 448319 : Add a resource translation layer for tutorial execution --- diff --git a/tests/translatortests.py b/tests/translatortests.py index 0f053b9..e71b795 100644 --- a/tests/translatortests.py +++ b/tests/translatortests.py @@ -16,9 +16,12 @@ import unittest import os +import uuid from sugar.tutorius.translator import * from sugar.tutorius.properties import * +from sugar.tutorius.tutorial import * +from sugar.tutorius import addon ############################################################################## ## Helper classes @@ -46,30 +49,65 @@ class ListResources(TPropContainer): ############################################################################## class ResourceTranslatorTests(unittest.TestCase): - temp_path = "/tmp/tutorius" - file_name = "temp.txt" + temp_path = "/tmp/" + file_name = "file.txt" def setUp(self): + # Generate a tutorial ID + self.tutorial_id = unicode(uuid.uuid1()) + + # Create a dummy fsm + self.fsm = Tutorial("TestTutorial1") + # Add a few states + act1 = addon.create('BubbleMessage', message="Hi", position=[300, 450]) + ev1 = addon.create('GtkWidgetEventFilter', "0.12.31.2.2", "clicked") + act2 = addon.create('BubbleMessage', message="Second message", position=[250, 150], tail_pos=[1,2]) + self.fsm.add_action("INIT", act1) + st2 = self.fsm.add_state((act2,)) + self.fsm.add_transition("INIT",(ev1, st2)) + + # Create a dummy metadata dictionnary + self.test_metadata_dict = {} + self.test_metadata_dict['name'] = 'TestTutorial1' + self.test_metadata_dict['guid'] = unicode(self.tutorial_id) + self.test_metadata_dict['version'] = '1' + self.test_metadata_dict['description'] = 'This is a test tutorial 1' + self.test_metadata_dict['rating'] = '3.5' + self.test_metadata_dict['category'] = 'Test' + self.test_metadata_dict['publish_state'] = 'false' + activities_dict = {} + activities_dict['org.laptop.tutoriusactivity'] = '1' + activities_dict['org.laptop,writus'] = '1' + self.test_metadata_dict['activities'] = activities_dict + + Vault.saveTutorial(self.fsm, self.test_metadata_dict) + try: os.mkdir(self.temp_path) except: pass - new_file = file(os.path.join(self.temp_path, self.file_name), "w") + abs_file_path = os.path.join(self.temp_path, self.file_name) + new_file = file(abs_file_path, "w") + + # Add the resource in the Vault + self.res_name = Vault.add_resource(self.tutorial_id, abs_file_path) # Use a dummy prob manager - we shouldn't be using it self.prob_man = object() - self.translator = ResourceTranslator(self.prob_man, '0101010101', testing=True) + self.translator = ResourceTranslator(self.prob_man, self.tutorial_id) pass def tearDown(self): + Vault.deleteTutorial(self.tutorial_id) + os.unlink(os.path.join(self.temp_path, self.file_name)) - pass def test_translate(self): # Create an action with a resource property res_action = ResourceAction() + res_action.resource = self.res_name self.translator.translate(res_action) diff --git a/tests/vaulttests.py b/tests/vaulttests.py index 48869a7..ca61225 100644 --- a/tests/vaulttests.py +++ b/tests/vaulttests.py @@ -270,20 +270,19 @@ class VaultInterfaceTest(unittest.TestCase): assert os.path.isfile(image_path), 'cannot find the test image file' # Create and save a tutorial - tutorial = Tutorial('test', self.fsm) - Vault.saveTutorial(tutorial, self.test_metadata_dict) + Vault.saveTutorial(self.fsm, self.test_metadata_dict) bundler = TutorialBundler(self.save_test_guid) tuto_path = bundler.get_tutorial_path(self.save_test_guid) # add the ressource to the tutorial - ressource_id = Vault.add_ressource(self.save_test_guid, image_path) + ressource_id = Vault.add_resource(self.save_test_guid, image_path) # Check that the image file is now in the vault assert os.path.isfile(os.path.join(tuto_path, 'ressources', ressource_id)), 'image file not found in vault' # Check if get_ressource_path Vault interface function is working - vault_path = Vault.get_ressource_path(self.save_test_guid, ressource_id) + vault_path = Vault.get_resource_path(self.save_test_guid, ressource_id) assert os.path.isfile(vault_path), 'path returned is not a file' basename, extension = os.path.splitext(vault_path) @@ -291,14 +290,10 @@ class VaultInterfaceTest(unittest.TestCase): # Delete the ressource - Vault.delete_ressource(self.save_test_guid, ressource_id) + Vault.delete_resource(self.save_test_guid, ressource_id) # Check that the ressource is not in the vault anymore assert os.path.isfile(os.path.join(tuto_path, 'ressources', ressource_id)) == False, 'image file found in vault when it should have been deleted.' - - - - def tearDown(self): folder = os.path.join(os.getenv("HOME"),".sugar", 'default', 'tutorius', 'data'); diff --git a/tutorius/properties.py b/tutorius/properties.py index ba3c211..c7af821 100644 --- a/tutorius/properties.py +++ b/tutorius/properties.py @@ -90,6 +90,21 @@ class TPropContainer(object): except AttributeError: return object.__setattr__(self, name, value) + def replace_property(self, prop_name, new_prop): + """ + Changes the content of a property. This is done in order to support + the insertion of executable properties in the place of a portable + property. The typical exemple is that a resource property needs to + be changed into a file property with the correct file name, since the + installation location will be different on every platform. + + @param prop_name The name of the property to be changed + @param new_prop The new property to insert + @raise AttributeError of the mentionned property doesn't exist + """ + props = object.__getattribute__(self, "_props") + props.__setitem__(prop_name, new_prop) + def get_properties(self): """ Return the list of property names. diff --git a/tutorius/translator.py b/tutorius/translator.py index 9925346..4e3e88d 100644 --- a/tutorius/translator.py +++ b/tutorius/translator.py @@ -20,9 +20,9 @@ import copy logger = logging.getLogger("ResourceTranslator") -from sugar.tutorius.properties import * +from .properties import * # TODO : Uncomment this line upon integration with the Vault -##from sugar.tutorius.vault import * +from .vault import Vault class ResourceTranslator(object): """ @@ -38,7 +38,7 @@ class ResourceTranslator(object): replace it. """ - def __init__(self, probe_manager, tutorial_id, testing=False): + def __init__(self, probe_manager, tutorial_id): """ Creates a new ResourceTranslator for the given tutorial. This translator is tasked with replacing resource properties of the @@ -49,15 +49,11 @@ class ResourceTranslator(object): @param probe_manager The probe manager to decorate @param tutorial_id The ID of the current tutorial - - @param testing Triggers the usage of a fake vault for testing purposes """ self._probe_manager = probe_manager self._tutorial_id = tutorial_id - self._testing = testing - - def translate_resource(self, res_prop): + def translate_resource(self, res_value): """ Replace the TResourceProperty in the container by their runtime-defined file equivalent. Since the resources are stored @@ -66,18 +62,13 @@ class ResourceTranslator(object): to transform the resource identifier into the absolute path for the process to be able to use it properly. - @param res_prop The resource property to be translated + @param res_prop The resource property's value to be translated @return The TFileProperty corresponding to this resource, containing an absolute path to the resource """ # We need to replace the resource by a file representation - filepath = "" - # TODO : Refactor when the Vault will be available - if not self._testing: - filepath = Vault.get_resource_path(self._tutorial_id, \ - prop_object.value) - else: - filepath = "/tmp/tutorius/temp.txt" + filepath = Vault.get_resource_path(self._tutorial_id, res_value) + # Create the new file representation file_prop = TFileProperty(filepath) @@ -114,7 +105,7 @@ class ResourceTranslator(object): # Apply the translation file_prop = self.translate_resource(prop_value) # Set the property with the new value - setattr(prop_container, propname, file_prop) + prop_container.replace_property(propname, file_prop) # If the property is an addon, then its value IS a # container too - we need to translate it @@ -139,7 +130,7 @@ class ResourceTranslator(object): prop_value.append(container) # Change the list contained in the addonlist property, since # we got a copy of the list when requesting it - setattr(prop_container, propname, prop_value) + prop_container.replace_property(propname, prop_value) ### ProbeManager interface for decorator ### diff --git a/tutorius/vault.py b/tutorius/vault.py index 22fa940..9576de9 100644 --- a/tutorius/vault.py +++ b/tutorius/vault.py @@ -324,14 +324,14 @@ class Vault(object): @staticmethod - def deleteTutorial(Tutorial): + def deleteTutorial(tutorial_id): """ Removes the tutorial from the Vault. It will unpublish the tutorial if need be, and it will also wipe it from the persistent storage. @returns true is the tutorial was deleted from the Vault """ - bundle = TutorialBundler(Guid) - bundle_path = bundle.get_tutorial_path(Guid) + bundle = TutorialBundler(tutorial_id) + bundle_path = bundle.get_tutorial_path(tutorial_id) # TODO : Need also to unpublish tutorial, need to interact with webservice module @@ -980,9 +980,3 @@ class TutorialBundler(object): xml_filename = config.get(INI_METADATA_SECTION, INI_XML_FSM_PROPERTY) serializer.save_tutorial(fsm, xml_filename, self.Path) - @staticmethod - def add_resources(typename, file): - """ - Add ressources to metadata. - """ - raise NotImplementedError("add_resources not implemented") -- cgit v0.9.1