Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/tutorius/translator.py
blob: 884714ef5621bad4d93ab0de2a87eec1afdad0fc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# Copyright (C) 2009, Tutorius.org
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

import os
import logging
import copy

logger = logging.getLogger("ResourceTranslator")


from sugar.tutorius.properties import *
from sugar.tutorius.vault import * 

class ResourceTranslator(object):
    """
    Handles the conversion of resource properties into file
    properties before action execution. This class works as a decorator
    to the ProbeManager class, as it is meant to be a transparent layer
    before sending the action to execution.
    """

    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
        incoming action into actually usable file properties pointing
        to the correct resource file. This is done by querying the vault
        for all the resources and creating a new file property from the
        returned path.
        
        @param probe_manager The probe manager to decorate
        @param tutorial_id The ID of the current tutorial
        """
        self._probe_manager = probe_manager
        self._tutorial_id = tutorial_id

    def _replace_resources(self, prop_container):
        """
        Replace the TResourceProperty in the container by their
        runtime-defined file equivalent. Since the resources are stored
        in a relative manner in the vault and that only the Vault knows
        which is the current folder for the current tutorial, it needs
        to transform the resource identifier into the absolute path for
        the process to be able to use it properly.

        This function does not return anything, but its post-condition is
        that all the resources properties of container have been replaced
        by its corresponding file property on disk.

        @param prop_container The property container in which we want to
                        replace all the resources for file properties and
                        to recursively do so for addon and addonlist
                        properties.
        """
        for propname in action.get_properties():
            prop_object = getattr(action, propname)
            prop_type = prop_object.type

            if prop_type == "resource":
                # We need to replace the resource by a file representation
                filepath = vault.get_resource_path(self._tutorial_id, \
                                                     prop_object.value)
                # Create the new file representation
                file_prop = TFileProperty(filepath)
                # Replace the property 
                setattr(action, propname, file_prop)
            elif prob_type == "addon":
                self._replace_resources(prop_object.value)
            elif prob_type == "addonlist":
                for container in prop_object.value:
                    self._replace_resources(container.value)
                
        
    ### ProbeManager interface for decorator ###

    ## Unchanged functions ##
    def setCurrentActivity(self, activity_id):
        self._probe_manager.setCurrentActivity(activity_id)

    def getCurrentActivity(self):
        return self._probe_manager.getCurrentActivity()

    currentActivity = property(fget=getCurrentActivity, fset=setCurrentActivity)
    def attach(self, activity_id):
        self._probe_manager.attach(activity_id)

    def detach(self, activity_id):
        self._probe_manager.detach(activity_id)

    def subscribe(self, event, callback):
        return self._probe_manager.subscribe(event, callback)

    def unsubscribe(self, event, callback):
        return self._probe_manager.unsubscribe(event, callback)

    def unsubscribe_all(self):
        return self._probe_manager.unsubscribe_all()
    
    ## Decorated functions ##
    def install(self, action):
        # Make a new copy of the action that we want to install,
        # because _replace_resources changes the action and we
        # don't want to modify the caller's action representation
        new_action = copy.deepcopy(action)
        # Execute the replacement
        self._replace_resources(new_action)

        # Send the new action to the probe manager
        return self._probe_manager.install(new_action)

    def update(self, action):
        # Make a new copy of the action that we want to install,
        # because _replace_resources changes the action and we
        # don't want to modify the caller's action representation
        new_action = copy.deepcopy(action)
        # Execute the replacement
        self._replace_resources(new_action)

        # Send the new action to the probe manager
        return self._probe_manager.update(new_action)

    def uninstall(self, action):
        # Make a new copy of the action that we want to install,
        # because _replace_resources changes the action and we
        # don't want to modify the caller's action representation
        new_action = copy.deepcopy(action)
        # Execute the replacement
        self._replace_resources(new_action)

        # Send the new action to the probe manager
        return self._probe_manager.uninstall(new_action)

    def uninstall_all(self):
        return self._probe_manager.uninstall_all()