コード例 #1
0
class ReflectionIdevice(Idevice):
    """
    A Reflection Idevice presents question/s for the student to think about
    before they look at the answer/s
    """
    persistenceVersion = 8
    
    def __init__(self, activity = "", answer = ""):
        """
        Initialize 
        """
        Idevice.__init__(self, 
                         x_(u"Reflection"),
                         x_(u"University of Auckland"), 
                         x_(u"""Reflection is a teaching method often used to 
connect theory to practice. Reflection tasks often provide learners with an 
opportunity to observe and reflect on their observations before presenting 
these as a piece of academic work. Journals, diaries, profiles and portfolios 
are useful tools for collecting observation data. Rubrics and guides can be 
effective feedback tools."""), u"", u"reflection")
        self.emphasis         = Idevice.SomeEmphasis
        self.group            = Idevice.Content
        self._activityInstruc = x_(u"""Enter a question for learners 
to reflect upon.""")
        self._answerInstruc   = x_(u"""Describe how learners will assess how 
they have done in the exercise. (Rubrics are useful devices for providing 
reflective feedback.)""")
        self.systemResources += ["common.js"]
        
        self.activityTextArea = TextAreaField(x_(u'Reflective question:'), 
                                    self._activityInstruc, activity)
        self.activityTextArea.idevice = self

        self.answerTextArea = TextAreaField(x_(u'Feedback:'), 
                                   self._answerInstruc, answer)
        self.answerTextArea.idevice = self

    # Properties
    activityInstruc = lateTranslate('activityInstruc')
    answerInstruc   = lateTranslate('answerInstruc')


    def getResourcesField(self, this_resource):
        """
        implement the specific resource finding mechanism for this iDevice:
        """ 
        # be warned that before upgrading, this iDevice field could not exist:
        if hasattr(self, 'activityTextArea')\
        and hasattr(self.activityTextArea, 'images'):
            for this_image in self.activityTextArea.images: 
                if hasattr(this_image, '_imageResource') \
                    and this_resource == this_image._imageResource: 
                        return self.activityTextArea

        # be warned that before upgrading, this iDevice field could not exist:
        if hasattr(self, 'answerTextArea')\
        and hasattr(self.answerTextArea, 'images'):
            for this_image in self.answerTextArea.images: 
                if hasattr(this_image, '_imageResource') \
                    and this_resource == this_image._imageResource: 
                        return self.answerTextArea

        return None

    def getRichTextFields(self):
        """
        Like getResourcesField(), a general helper to allow nodes to search 
        through all of their fields without having to know the specifics of each
        iDevice type.  
        """
        fields_list = []
        if hasattr(self, 'activityTextArea'):
            fields_list.append(self.activityTextArea)
        if hasattr(self, 'answerTextArea'):
            fields_list.append(self.answerTextArea)

        return fields_list

    def burstHTML(self, i):
        """
        takes a BeautifulSoup fragment (i) and bursts its contents to 
        import this idevice from a CommonCartridge export
        """
        # Reflection Idevice:
        title = i.find(name='span', attrs={'class' : 'iDeviceTitle' })
        self.title = title.renderContents().decode('utf-8')

        reflections = i.findAll(name='div', attrs={'id' : re.compile('^ta') })
        # should be exactly two of these:
        # 1st = field[0] == Activity
        if len(reflections) >= 1:
            self.activityTextArea.content_wo_resourcePaths = \
                    reflections[0].renderContents().decode('utf-8')
            # and add the LOCAL resource paths back in:
            self.activityTextArea.content_w_resourcePaths = \
                    self.activityTextArea.MassageResourceDirsIntoContent( \
                        self.activityTextArea.content_wo_resourcePaths)
            self.activityTextArea.content = \
                    self.activityTextArea.content_w_resourcePaths
        # 2nd = field[1] == Answer
        if len(reflections) >= 2:
            self.answerTextArea.content_wo_resourcePaths = \
                    reflections[1].renderContents().decode('utf-8')
            # and add the LOCAL resource paths back in:
            self.answerTextArea.content_w_resourcePaths = \
                    self.answerTextArea.MassageResourceDirsIntoContent( \
                        self.answerTextArea.content_wo_resourcePaths)
            self.answerTextArea.content = \
                    self.answerTextArea.content_w_resourcePaths

    def upgradeToVersion1(self):
        """
        Upgrades the node from version 0 to 1.
        """
        log.debug(u"Upgrading iDevice")
        self.icon       = u"reflection"


    def upgradeToVersion2(self):
        """
        Upgrades the node from 1 (v0.5) to 2 (v0.6).
        Old packages will loose their icons, but they will load.
        """
        log.debug(u"Upgrading iDevice")
        self.emphasis = Idevice.SomeEmphasis

        
    def upgradeToVersion3(self):
        """
        Upgrades v0.6 to v0.7.
        """
        self.lastIdevice = False


    def upgradeToVersion4(self):
        """
        Upgrades to exe v0.10
        """
        self._upgradeIdeviceToVersion1()
        self._activityInstruc = self.__dict__['activityInstruc']
        self._answerInstruc   = self.__dict__['answerInstruc']
   

    def upgradeToVersion5(self):
        """
        Upgrades to exe v0.10
        """
        self._upgradeIdeviceToVersion1()


    def upgradeToVersion6(self):
        """
        Upgrades to v0.12
        """
        self._upgradeIdeviceToVersion2()
        self.systemResources += ["common.js"]


    def upgradeToVersion7(self):
        """ 
        Upgrades to somewhere before version 0.25 (post-v0.24) 
        Taking the old unicode string fields, and converting them 
        into image-enabled TextAreaFields:
        """
        self.activityTextArea = TextAreaField(x_(u'Reflective question:'), 
                                    self._activityInstruc, self.activity)
        self.activityTextArea.idevice = self
        self.answerTextArea = TextAreaField(x_(u'Feedback:'), 
                                  self._answerInstruc, self.answer)
        self.answerTextArea.idevice = self


    def upgradeToVersion9(self):
        """
        Adds group to idevice
        """
        self.group = Idevice.Content
コード例 #2
0
ファイル: clozefpdidevice.py プロジェクト: sthagen/iteexe
class ClozefpdIdevice(Idevice):
    """
    Holds a paragraph with words missing that the student must fill in
    """
    
    persistenceVersion = 7

    def __init__(self, parentNode=None):
        """
        Sets up the idevice title and instructions etc
        """
        Idevice.__init__(self, x_(u"FPD - Cloze Activity"),
                         x_(u"University of Auckland"), 
                         x_(u"<p>Cloze exercises are texts or "
                             "sentences where students must fill in "
                             "missing words. They are often used for the "
                             "following purposes:</p>"
                             "<ol>"
                             "<li>To check knowledge of core course "
                             "concepts (this could be a pre-check, "
                             "formative exercise, or summative check).</li>"
                             "<li>To check reading comprehension.</li>"
                             "<li>To check vocabulary knowledge.</li>"
                             "<li>To check word formation and/or grammatical "
                             "competence. </li></ol>"),
                         x_(u"<dl>"
                             "  <dt>If your goal is to test understanding "
                             "of core concepts or reading comprehension"
                             "  </dt>"
                             "  <dd>"
                             "    <p>"
                             "  Write a summary of the concept or reading long "
                             " enough to adequately test the target's "
                             "knowledge, but short enough not to "
                             "induce fatigue. Less than one typed page is "
                             "probably adequate, but probably "
                             "considerably less for young students or "
                             "beginners."
                             "    </p>"
                             "    <p>"
                             "Select words in the text that"
                             "are key to understanding the concepts. These"
                             "will probably be verbs, nouns, and key adverbs."
                             "Choose alternatives with one clear answer."
                             "    </p>"
                             "  </dd>"
                             "  <dt>"
                             "If your goal is to test vocabulary knowledge"
                             "  </dt>"
                             "  <dd>"
                             "<p>Write a text using the target vocabulary. This "
                             "text should be coherent and cohesive, and be of "
                             "an appropriate length. Highlight the target "
                             "words in the text. Choose alternatives with one "
                             "clear answer.</p>"
                             "  </dd>"
                             "  <dt>"
                             "If your goal is to test word "
                             "formation/grammar:"
                             "  </dt>"
                             "  <dd>"
                             "  <p>"
                             "Write a text using the "
                             "target forms. This text should be coherent and "
                             "cohesive, and be of an appropriate length. "
                             "Remember that the goal is not vocabulary "
                             "knowledge, so the core meanings of the stem "
                             "words should be well known to the students."
                             "  </p>"
                             "  <p>"
                             "Highlight the target words in the text. Provide "
                             "alternatives with the same word stem, but "
                             "different affixes. It is a good idea to get a "
                             "colleague to test the test/exercise to make "
                             "sure there are no surprises!"
                             "  </p>"
                             "  </dd>"
                             "</dl>"),
                            u"autoevaluacionfpd",
                             parentNode)
        self.instructionsForLearners = TextAreaField(
            x_(u'Instructions'),
            x_(u"""Provide instruction on how the cloze activity should be 
completed. Default text will be entered if there are no changes to this field.
"""), "")
#            x_(u'Read the paragraph below and fill in the missing words.'))
        self.instructionsForLearners.idevice = self
        self._content = ClozeField(x_(u'Cloze'), 
            x_(u"""<p>Enter the text for the cloze activity in to the cloze field 
by either pasting text from another source or by typing text directly into the 
field.</p><p> To select words to hide, double click on the word to select it and 
click on the Hide/Show Word button below.</p><p>More than one possible answer can be defined enclosing them with pipes (|). I.e.: |dog|cat|bird|</p>"""))
        self._content.idevice = self
        self.feedback = TextAreaField(x_(u'Feedback'),
            x_(u'Enter any feedback you wish to provide the learner '
                'with-in the feedback field. This field can be left blank.'))
        self.feedback.idevice = self
#        self.emphasis   = Idevice.SomeEmphasis
        self.emphasis   = "_autoevaluacionfpd"
        self.systemResources += ["common.js"]
        self.isCloze = True


    # Properties
    content = property(lambda self: self._content, 
                       doc="Read only, use 'self.content.encodedContent = x' "
                           "instead")

    def getResourcesField(self, this_resource): 
        """ 
        implement the specific resource finding mechanism for this iDevice: 
        """ 
        # be warned that before upgrading, this iDevice field could not exist:
        if hasattr(self, '_content') and hasattr(self._content, 'images'):
            for this_image in self._content.images: 
                if hasattr(this_image, '_imageResource') \
                and this_resource == this_image._imageResource: 
                    return self._content

        # be warned that before upgrading, this iDevice field could not exist:
        if hasattr(self, 'instructionsForLearners')\
        and hasattr(self.instructionsForLearners, 'images'):
            for this_image in self.instructionsForLearners.images: 
                if hasattr(this_image, '_imageResource') \
                and this_resource == this_image._imageResource: 
                    return self.instructionsForLearners

        # be warned that before upgrading, this iDevice field could not exist:
        if hasattr(self, 'feedback') and hasattr(self.feedback, 'images'):
            for this_image in self.feedback.images: 
                if hasattr(this_image, '_imageResource') \
                and this_resource == this_image._imageResource: 
                    return self.feedback
        
        return None

      
    def getRichTextFields(self):
        """
        Like getResourcesField(), a general helper to allow nodes to search 
        through all of their fields without having to know the specifics of each
        iDevice type.  
        """
        fields_list = []
        if hasattr(self, '_content'):
            fields_list.append(self._content)
        if hasattr(self, 'instructionsForLearners'):
            fields_list.append(self.instructionsForLearners)
        if hasattr(self, 'feedback'):
            fields_list.append(self.feedback)
        return fields_list
        
    def burstHTML(self, i):
        """
        takes a BeautifulSoup fragment (i) and bursts its contents to 
        import this idevice from a CommonCartridge export
        """
        # Cloze Idevice:
        title = i.find(name='span', attrs={'class' : 'iDeviceTitle' })
        self.title = title.renderContents().decode('utf-8')

        inner = i.find(name='div', attrs={'class' : 'iDevice_inner' })

        instruct = inner.find(name='div', 
                attrs={'class' : 'block' , 'style' : 'display:block' })
        self.instructionsForLearners.content_wo_resourcePaths = \
                instruct.renderContents().decode('utf-8')
        # and add the LOCAL resource paths back in:
        self.instructionsForLearners.content_w_resourcePaths = \
                self.instructionsForLearners.MassageResourceDirsIntoContent( \
                    self.instructionsForLearners.content_wo_resourcePaths)
        self.instructionsForLearners.content = \
                self.instructionsForLearners.content_w_resourcePaths

        content = inner.find(name='div', attrs={'id' : re.compile('^cloze') })
        rebuilt_contents = ""
        for this_content in content.contents:
            if not this_content.__str__().startswith('<input'):
                if this_content.__str__().startswith('<span'):
                    # Now, decode the answer
                    # with code reverse-engineered from:
                    # a) Cloze's $exe.cloze.getAnswer() in common.js
                    # b) ClozeElement's renderView() + encrypt()
                    answer = ""
                    code_key = 'X'
                    code = this_content.renderContents()
                    code = code.decode('base64')
                    # now in the form %uABCD%uEFGH%uIJKL....
                    char_pos = 0
                    while char_pos < len(code):
                        # first 2 chars = %u, replace with 0x to get int
                        # next 4 = the encoded unichr
                        this_code_char = "0x" + code[char_pos+2 : char_pos+6]
                        this_code_ord = int(this_code_char, 16)
                        letter = chr(ord(code_key)^this_code_ord)
                        answer += letter
                        # key SHOULD be ^'d by letter, but seems to be:
                        code_key = letter
                        char_pos += 6
                    rebuilt_contents += "<U>" + answer + "</U>"
                elif not this_content.__str__().startswith('<div'):
                    # this should be the un-clozed text:
                    rebuilt_contents +=  this_content.__str__()
        self._content.content_wo_resourcePaths = rebuilt_contents
        # and add the LOCAL resource paths back in:
        self._content.content_w_resourcePaths = \
                self._content.MassageResourceDirsIntoContent( \
                    self._content.content_wo_resourcePaths)
        self._content.content = self._content.content_w_resourcePaths

        feedback = inner.find(name='div', attrs={'class' : 'feedback' })
        self.feedback.content_wo_resourcePaths = \
                feedback.renderContents().decode('utf-8')
        # and add the LOCAL resource paths back in:
        self.feedback.content_w_resourcePaths = \
                self.feedback.MassageResourceDirsIntoContent( \
                    self.feedback.content_wo_resourcePaths)
        self.feedback.content = self.feedback.content_w_resourcePaths

        # and each cloze flag field (strict, case, instant):
        flag_strict = inner.find(name='input', 
                attrs={'id' : re.compile('^clozeFlag.*strictMarking$') })
        if flag_strict.attrMap['value']=="true":
            self._content.strictMarking = True
        flag_caps = inner.find(name='input', 
                attrs={'id' : re.compile('^clozeFlag.*checkCaps$') })
        if flag_caps.attrMap['value']=="true":
            self._content.checkCaps = True
        flag_instant = inner.find(name='input', 
                attrs={'id' : re.compile('^clozeFlag.*instantMarking$') })
        if flag_instant.attrMap['value']=="true":
            self._content.instantMarking = True

    def upgradeToVersion1(self):
        """
        Upgrades exe to v0.10
        """
        self._upgradeIdeviceToVersion1()
        self.instructionsForLearners = TextAreaField(
            x_(u'Instructions For Learners'),
            x_(u'Put instructions for learners here'),
            x_(u'Read the paragraph below and fill in the missing words'))
        self.instructionsForLearners.idevice = self
        self.feedback = TextAreaField(x_(u'Feedback'))
        self.feedback.idevice = self


    def upgradeToVersion2(self):
        """
        Upgrades exe to v0.11
        """
        self.content.autoCompletion = True
        self.content.autoCompletionInstruc =  _(u"Allow auto completion when "
                                                u"user filling the gaps.")

    def upgradeToVersion3(self):
        """
        Upgrades to v0.12
        """
        self._upgradeIdeviceToVersion2()
        self.systemResources += ["common.js"]
        
    def upgradeToVersion4(self):
        """
        Upgrades to v0.20.3
        """
        self.isCloze = True

    def upgradeToVersion5(self):
        self._content._instruc = x_(u"""<p>Enter the text for the cloze activity in to the cloze field 
by either pasting text from another source or by typing text directly into the 
field.</p><p> To select words to hide, double click on the word to select it and 
click on the Hide/Show Word button below.</p><p>More than one possible answer can be defined enclosing them with pipes (|). I.e.: |dog|cat|bird|</p>""")

    def upgradeToVersion6(self):
        """
        Delete icon from system resources
        """
        self._upgradeIdeviceToVersion3()

    def upgradeToVersion7(self):
        if self._title == u"FPD - Actividad de Espacios en Blanco":
            self._title = u"FPD - Cloze Activity"
        if self._title == u"Actividad de Espacios en Blanco":
            self._title = u"Cloze Activity"
コード例 #3
0
class ParasabermasfpdIdevice(Idevice):
    """
    El iDevice Para saber permite al alumnado ampliar conocimientos voluntarios para su aprendizaje
    """
    persistenceVersion = 9

    def __init__(self, activity="", answer=""):
        """
        Initialize 
        """
        Idevice.__init__(
            self, x_(u"FPD - A Step Ahead"), x_(u"Jose Ramon Jimenez Reyes"),
            x_(u"""A Step Ahead is an iDevice that permits students widen their knowledge with further contents."""
               ), u"", u"parasabermasfpd")
        #        self.emphasis         = Idevice.SomeEmphasis
        self.emphasis = "_parasabermasfpd"
        self._activityInstruc = x_(
            u"""Enter the text that will appear on this iDevice""")
        #        self.systemResources += ["common.js"]

        self.activityTextArea = TextAreaField(x_(u'A Step Ahead Text'),
                                              self._activityInstruc, activity)
        self.activityTextArea.idevice = self

    # Properties
    activityInstruc = lateTranslate('activityInstruc')

    def getResourcesField(self, this_resource):
        """
        implement the specific resource finding mechanism for this iDevice:
        """
        # be warned that before upgrading, this iDevice field could not exist:
        if hasattr(self, 'activityTextArea')\
        and hasattr(self.activityTextArea, 'images'):
            for this_image in self.activityTextArea.images:
                if hasattr(this_image, '_imageResource') \
                    and this_resource == this_image._imageResource:
                    return self.activityTextArea

        return None

    def getRichTextFields(self):
        fields_list = []
        if hasattr(self, 'activityTextArea'):
            fields_list.append(self.activityTextArea)

        return fields_list

    def burstHTML(self, i):
        # Parasabermasfpd Idevice:
        title = i.find(name='span', attrs={'class': 'iDeviceTitle'})
        self.title = title.renderContents().decode('utf-8')

        reflections = i.findAll(name='div', attrs={'id': re.compile('^ta')})
        # should be exactly two of these:
        # 1st = field[0] == Activity
        if len(reflections) >= 1:
            self.activityTextArea.content_wo_resourcePaths = \
                    reflections[0].renderContents().decode('utf-8')
            # and add the LOCAL resource paths back in:
            self.activityTextArea.content_w_resourcePaths = \
                    self.activityTextArea.MassageResourceDirsIntoContent( \
                        self.activityTextArea.content_wo_resourcePaths)
            self.activityTextArea.content = \
                    self.activityTextArea.content_w_resourcePaths

    def upgradeToVersion1(self):
        """
        Upgrades the node from version 0 to 1.
        """
        log.debug(u"Upgrading iDevice")
        self.icon = u"activity"

    def upgradeToVersion2(self):
        """
        Upgrades the node from 1 (v0.5) to 2 (v0.6).
        Old packages will loose their icons, but they will load.
        """
        log.debug(u"Upgrading iDevice")
        #        self.emphasis         = Idevice.SomeEmphasis
        self.emphasis = "_parasabermasfpd"

    def upgradeToVersion3(self):
        """
        Upgrades v0.6 to v0.7.
        """
        self.lastIdevice = False

    def upgradeToVersion4(self):
        """
        Upgrades to exe v0.10
        """
        self._upgradeIdeviceToVersion1()
        self._activityInstruc = self.__dict__['activityInstruc']

    def upgradeToVersion5(self):
        """
        Upgrades to exe v0.10
        """
        self._upgradeIdeviceToVersion1()

    def upgradeToVersion6(self):
        """
        Upgrades to v0.12
        """
        self._upgradeIdeviceToVersion2()
#        self.systemResources += ["common.js"]

    def upgradeToVersion7(self):
        """ 
        Upgrades to somewhere before version 0.25 (post-v0.24) 
        Taking the old unicode string fields, and converting them 
        into image-enabled TextAreaFields:
        """
        self.activityTextArea = TextAreaField(x_(u'A Step Ahead Text'),
                                              self._activityInstruc,
                                              self.activity)
        self.activityTextArea.idevice = self

    def upgradeToVersion8(self):
        """
        Delete icon from system resources
        """
        self._upgradeIdeviceToVersion3()

    def upgradeToVersion9(self):
        if self._title == u"FPD - Para Saber Mas":
            self._title = u"FPD - A Step Ahead"
        if self._purpose == u"""Para saber m&aacute;s es un iDevice que permite al alumnado ampliar conocimientos, siendo estos voluntarios para su aprendizaje.""":
            self._purpose = u"""A Step Ahead is an iDevice that permits students widen their knowledge with further contents."""
        if self._activityInstruc == u"""Introduce el texto que aparecer&aacute; en este iDevice""":
            self._activityInstruc = u"""Enter the text that will appear on this iDevice"""
        if self.activityTextArea._name == u'Texto Para saber m&aacute;s':
            self.activityTextArea._name = u'A Step Ahead Text'
コード例 #4
0
class OpinionIdevice(Idevice):
    """
    A TrueFalse Idevice is one built up from question and options
    """
    persistenceVersion = 9

    def __init__(self):
        """
        Initialize 
        """
        Idevice.__init__(
            self, x_(u"Opinion Question"), x_(u"University of Auckland"),
            x_(u"""Opinion questions present a statement where 
the learner must decide if he agrees or disagrees."""), u"", u"question")
        self.emphasis = Idevice.SomeEmphasis
        self._hintInstruc = x_(u"""A hint may be provided to assist the 
learner in answering the question.""")
        self.questions = []
        self._questionInstruc = x_(u"""Type the question stem. The question 
should be clear and unambiguous. Avoid negative premises as these can tend to 
be ambiguous.""")
        self._keyInstruc = ""
        self._feedbackInstruc = x_(u"""Enter any feedback you wish to provide 
to the learner. This field may be left blank. if this field is left blank 
default feedback will be provided.""")
        self.questions.append(OpinionQuestion(self))
        self.systemResources += [
            "common.js", "libot_drag.js", "panel-amusements.png",
            "stock-stop.png"
        ]
        self.instructionsForLearners = TextAreaField(
            x_(u'Instructions'),
            x_(u"""Provide instruction on how the Opinion Question should be 
completed."""), u'')

        self.instructionsForLearners.idevice = self
        self.icon = u"activity"

    # Properties
    hintInstruc = lateTranslate('hintInstruc')
    questionInstruc = lateTranslate('questionInstruc')
    keyInstruc = lateTranslate('keyInstruc')
    feedbackInstruc = lateTranslate('feedbackInstruc')

    def addQuestion(self):
        """
        Add a new question to this iDevice. 
        """
        self.questions.append(OpinionQuestion(self))

    def getResourcesField(self, this_resource):
        """
        implement the specific resource finding mechanism for this iDevice:
        """
        # be warned that before upgrading, this iDevice field could not exist:
        if hasattr(self, 'instructionsForLearners')\
        and hasattr(self.instructionsForLearners, 'images'):
            for this_image in self.instructionsForLearners.images:
                if hasattr(this_image, '_imageResource') \
                    and this_resource == this_image._imageResource:
                    return self.instructionsForLearners

        for this_question in self.questions:
            this_field = this_question.getResourcesField(this_resource)
            if this_field is not None:
                return this_field

        return None

    def getRichTextFields(self):
        """
        Like getResourcesField(), a general helper to allow nodes to search 
        through all of their fields without having to know the specifics of each
        iDevice type.  
        """
        fields_list = []
        if hasattr(self, 'instructionsForLearners'):
            fields_list.append(self.instructionsForLearners)

        for this_question in self.questions:
            fields_list.extend(this_question.getRichTextFields())

        return fields_list

    def burstHTML(self, i):
        """
        takes a BeautifulSoup fragment (i) and bursts its contents to 
        import this idevice from a CommonCartridge export
        """
        # True-False Idevice:
        title = i.find(name='h2', attrs={'class': 'iDeviceTitle'})
        self.title = title.renderContents().decode('utf-8')

        inner = i.find(name='div', attrs={'class': 'iDevice_inner'})

        instruct = inner.find(name='div',
                              attrs={
                                  'class': 'block',
                                  'style': 'display:block'
                              })
        self.instructionsForLearners.content_wo_resourcePaths = \
                instruct.renderContents().decode('utf-8')
        # and add the LOCAL resource paths back in:
        self.instructionsForLearners.content_w_resourcePaths = \
                self.instructionsForLearners.MassageResourceDirsIntoContent( \
                    self.instructionsForLearners.content_wo_resourcePaths)
        self.instructionsForLearners.content = \
                self.instructionsForLearners.content_w_resourcePaths

        # copied and modified from Multi-Select, and others :-) :

        tf_questions = inner.findAll(name='div', attrs={'class': 'question'})
        if len(tf_questions) < 1:
            # need to remove the default 1st question
            del self.questions[0]

        for question_num in range(len(tf_questions)):
            if question_num > 0:
                # only created with the first question, add others:
                self.addQuestion()

            question = tf_questions[question_num]

            questions = question.findAll(name='div',
                                         attrs={
                                             'class': 'block',
                                             'id': re.compile('^taquestion')
                                         })
            if len(questions) == 1:
                # ELSE: should warn of unexpected result!
                inner_question = questions[0]
                self.questions[question_num].questionTextArea.content_wo_resourcePaths \
                        = inner_question.renderContents().decode('utf-8')
                # and add the LOCAL resource paths back in:
                self.questions[question_num].questionTextArea.content_w_resourcePaths \
                        = self.questions[question_num].questionTextArea.MassageResourceDirsIntoContent( \
                            self.questions[question_num].questionTextArea.content_wo_resourcePaths)
                self.questions[question_num].questionTextArea.content = \
                        self.questions[question_num].questionTextArea.content_w_resourcePaths

            answer_true = question.find(name='div',
                                        attrs={'id': re.compile('^s0b')})
            answer_false = question.find(name='div',
                                         attrs={'id': re.compile('^s1b')})
            # true-false only has 1 feedback per question:
            feedbacks = question.findAll(name='div',
                                         attrs={'id': re.compile('^sfb')})
            # true-false only has 1 hint per question:
            hints = question.findAll(name='div',
                                     attrs={'id': re.compile('^tahint')})

            # and finally, see if this is a correct answer:
            even_score = int(answer_true.attrMap['even_steven'])
            if not (even_score % 2):
                # i.e., if it IS even, then this is correct:
                self.questions[question_num].isCorrect = True

            if len(hints) >= 1:
                inner_hint = hints[0]
                self.questions[question_num].hintTextArea.content_wo_resourcePaths \
                        = inner_hint.renderContents().decode('utf-8')
                # and add the LOCAL resource paths back in:
                self.questions[question_num].hintTextArea.content_w_resourcePaths \
                        = self.questions[question_num].hintTextArea.MassageResourceDirsIntoContent( \
                            self.questions[question_num].hintTextArea.content_wo_resourcePaths)
                self.questions[question_num].hintTextArea.content = \
                        self.questions[question_num].hintTextArea.content_w_resourcePaths
            else:
                # no user-defined feedback, just using the default:
                self.questions[question_num].hintTextArea.content = ""
                self.questions[question_num].hintTextArea.content_w_resourcePaths \
                        = ""
                self.questions[question_num].hintTextArea.content_wo_resourcePaths \
                        = ""

            if len(feedbacks) >= 1:
                inner_feedback = feedbacks[0]
                self.questions[question_num].feedbackTextArea.content_wo_resourcePaths \
                        = inner_feedback.renderContents().decode('utf-8')
                # and add the LOCAL resource paths back in:
                self.questions[question_num].feedbackTextArea.content_w_resourcePaths \
                        = self.questions[question_num].feedbackTextArea.MassageResourceDirsIntoContent( \
                            self.questions[question_num].feedbackTextArea.content_wo_resourcePaths)
                self.questions[question_num].feedbackTextArea.content = \
                        self.questions[question_num].feedbackTextArea.content_w_resourcePaths
            else:
                # no user-defined feedback, just using the default:
                self.questions[question_num].feedbackTextArea.content = ""
                self.questions[question_num].feedbackTextArea.content_w_resourcePaths \
                        = ""
                self.questions[question_num].feedbackTextArea.content_wo_resourcePaths \
                        = ""

    def upgradeToVersion1(self):
        """
        Upgrades the node from version 0 to 1.
        Old packages will loose their icons, but they will load.
        """
        log.debug(u"Upgrading iDevice")
        self.icon = u"multichoice"

    def upgradeToVersion2(self):
        """
        Upgrades the node from 1 (v0.5) to 2 (v0.6).
        Old packages will loose their icons, but they will load.
        """
        log.debug(u"Upgrading iDevice")
        self.emphasis = Idevice.SomeEmphasis

    def upgradeToVersion3(self):
        """
        Upgrades the node from 1 (v0.6) to 2 (v0.7).
        Change icon from 'multichoice' to 'question'
        """
        log.debug(u"Upgrading iDevice icon")
        self.icon = "question"

    def upgradeToVersion4(self):
        """
        Upgrades v0.6 to v0.7.
        """
        self.lastIdevice = False

    def upgradeToVersion5(self):
        """
        Upgrades exe to v0.10
        """
        self._upgradeIdeviceToVersion1()
        self._hintInstruc = self.__dict__['hintInstruc']
        self._questionInstruc = self.__dict__['questionInstruc']
        self._keyInstruc = self.__dict__['keyInstruc']

    def upgradeToVersion6(self):
        """
        Upgrades exe to v0.11
        """
        self._feedbackInstruc = x_(u"""Type in the feedback that you want the 
student to see when selecting the particular question. If you don't complete
this box, eXe will automatically provide default feedback as follows: 
"Correct answer" as indicated by the selection for the correct answer; or 
"Wrong answer" for the other alternatives.""")

    def upgradeToVersion7(self):
        """
        Upgrades to v0.12
        """
        self._upgradeIdeviceToVersion2()
        self.systemResources += [
            "common.js", "libot_drag.js", "panel-amusements.png",
            "stock-stop.png"
        ]

    def upgradeToVersion8(self):
        """
        Upgrades to v0.15
        """
        self.instructionsForLearners = TextAreaField(
            x_(u'Instructions'),
            x_(u"""Provide instruction on how the True/False Question should be 
completed."""),
            x_(u'Read the paragraph below and '
               'fill in the missing words.'))
        self.instructionsForLearners.idevice = self

    def upgradeToVersion9(self):
        """ 
        Upgrades to somewhere before version 0.25 (post-v0.24) 
        Taking the TrueFalseQuestions' old unicode string fields, 
        and converting them into a image-enabled TextAreaFields:
        """
        for question in self.questions:
            question.upgrade_setIdevice(self)
コード例 #5
0
ファイル: casestudyidevice.py プロジェクト: luisgg/iteexe
class CasestudyIdevice(Idevice):
    """
    A multichoice Idevice is one built up from question and options
    """
    persistenceVersion = 8

    def __init__(self, story="", defaultImage=None):
        """
        Initialize 
        """
        Idevice.__init__(self,
                         x_(u"Case Study"),
                         x_(u"University of Auckland"), 
                         x_(u"""A case study is a device that provides learners 
with a simulation that has an educational basis. It takes a situation, generally 
based in reality, and asks learners to demonstrate or describe what action they 
would take to complete a task or resolve a situation. The case study allows 
learners apply their own knowledge and experience to completing the tasks 
assigned. when designing a case study consider the following:<ul> 
<li>	What educational points are conveyed in the story</li>
<li>	What preparation will the learners need to do prior to working on the 
case study</li>
<li>	Where the case study fits into the rest of the course</li>
<li>	How the learners will interact with the materials and each other e.g.
if run in a classroom situation can teams be setup to work on different aspects
of the case and if so how are ideas feed back to the class</li></ul>"""), 
                         "",
                         u"casestudy")
        self.emphasis     = Idevice.SomeEmphasis
        
        self._storyInstruc = x_(u"""Create the case story. A good case is one 
that describes a controversy or sets the scene by describing the characters 
involved and the situation. It should also allow for some action to be taken 
in order to gain resolution of the situation.""")
        self.storyTextArea = TextAreaField(x_(u'Story:'), self._storyInstruc, story)
        self.storyTextArea.idevice = self


        self.questions    = []
        self._questionInstruc = x_(u"""Describe the activity tasks relevant 
to the case story provided. These could be in the form of questions or 
instructions for activity which may lead the learner to resolving a dilemma 
presented. """)
        self._feedbackInstruc = x_(u"""Provide relevant feedback on the 
situation.""")
        if defaultImage is None:
            defaultImage = G.application.config.webDir/'images'/DEFAULT_IMAGE
        self.defaultImage = toUnicode(defaultImage)
        self.addQuestion()

    # Properties
    storyInstruc    = lateTranslate('storyInstruc')
    questionInstruc = lateTranslate('questionInstruc')
    feedbackInstruc = lateTranslate('feedbackInstruc')
    storyInstruc    = lateTranslate('storyInstruc')
    questionInstruc = lateTranslate('questionInstruc')
    feedbackInstruc = lateTranslate('feedbackInstruc')
 
    def addQuestion(self):
        """
        Add a new question to this iDevice. 
        """
        self.questions.append(Question(self))

    def getResourcesField(self, this_resource):
        """
        implement the specific resource finding mechanism for this iDevice:
        """
        # be warned that before upgrading, this iDevice field could not exist:
        if hasattr(self, 'storyTextArea')\
        and hasattr(self.storyTextArea, 'images'):
            for this_image in self.storyTextArea.images:
                if hasattr(this_image, '_imageResource') \
                and this_resource == this_image._imageResource:
                    return self.storyTextArea

        for this_question in self.questions:
            this_field = this_question.getResourcesField(this_resource)
            if this_field is not None:
                return this_field

        return None

      
    def getRichTextFields(self):
        """
        Like getResourcesField(), a general helper to allow nodes to search 
        through all of their fields without having to know the specifics of each
        iDevice type.  
        """
        fields_list = []
        if hasattr(self, 'storyTextArea'):
            fields_list.append(self.storyTextArea)

        for this_question in self.questions:
            fields_list.extend(this_question.getRichTextFields())

        return fields_list
        
    def burstHTML(self, i):
        """
        takes a BeautifulSoup fragment (i) and bursts its contents to 
        import this idevice from a CommonCartridge export
        """
        # CaseStudy Idevice:
        title = i.find(name='h2', attrs={'class' : 'iDeviceTitle' })
        self.title = title.renderContents().decode('utf-8')

        inner = i.find(name='div', attrs={'class' : 'iDevice_inner' })

        story = inner.find(name='div', 
                attrs={'class' : 'block' , 'id' : re.compile('^ta') })
        self.storyTextArea.content_wo_resourcePaths = \
                story.renderContents().decode('utf-8')
        # and add the LOCAL resource paths back in:
        self.storyTextArea.content_w_resourcePaths = \
                self.storyTextArea.MassageResourceDirsIntoContent( \
                    self.storyTextArea.content_wo_resourcePaths)
        self.storyTextArea.content = self.storyTextArea.content_w_resourcePaths

        case_questions = inner.findAll(name='div', attrs={'class' : 'question'})
        for question_num in range(len(case_questions)):
            if question_num > 0:
                # only created with the first question, add others:
                self.addQuestion()

            question = case_questions[question_num]

            case_stories = question.findAll(name='div', 
                    attrs={'class' : 'block' , 
                        'id' : re.compile('^taquesQuestion') })
            if len(case_stories) == 1:
                # ELSE: should warn of unexpected result!
                inner_question = case_stories[0]
                self.questions[question_num].questionTextArea.content = \
                        inner_question.renderContents().decode('utf-8')
                self.questions[question_num].questionTextArea.content_w_resourcePaths \
                        = inner_question.renderContents().decode('utf-8')
                self.questions[question_num].questionTextArea.content_wo_resourcePaths \
                        = inner_question.renderContents().decode('utf-8')
                # and add the LOCAL resource paths back in:
                self.questions[question_num].questionTextArea.content_w_resourcePaths \
                        = self.questions[question_num].questionTextArea.MassageResourceDirsIntoContent( \
                            self.questions[question_num].questionTextArea.content_wo_resourcePaths)
                self.questions[question_num].questionTextArea.content = \
                        self.questions[question_num].questionTextArea.content_w_resourcePaths

            case_feedbacks = question.findAll(name='div', 
                    attrs={'class' : 'feedback' , 'id' : re.compile('^sq') })
            if len(case_feedbacks) == 1:
                # no warning otherwise, since feedback is optional
                inner_feedback = case_feedbacks[0]
                self.questions[question_num].feedbackTextArea.content_wo_resourcePaths \
                        = inner_feedback.renderContents().decode('utf-8')
                # and add the LOCAL resource paths back in:
                self.questions[question_num].feedbackTextArea.content_w_resourcePaths \
                        = self.questions[question_num].feedbackTextArea.MassageResourceDirsIntoContent( \
                            self.questions[question_num].feedbackTextArea.content_wo_resourcePaths)
                self.questions[question_num].feedbackTextArea.content = \
                        self.questions[question_num].feedbackTextArea.content_w_resourcePaths
            else:
                self.questions[question_num].feedbackTextArea.content = ""
                self.questions[question_num].feedbackTextArea.content_w_resourcePaths \
                        = ""
                self.questions[question_num].feedbackTextArea.content_wo_resourcePaths \
                        = ""


    def upgradeToVersion1(self):
        """
        Upgrades the node from version 0 to 1.
        Old packages will loose their icons, but they will load.
        """
        log.debug(u"Upgrading iDevice")
        self.icon = "casestudy"
   

    def upgradeToVersion2(self):
        """
        Upgrades the node from 1 (v0.5) to 2 (v0.6).
        Old packages will loose their icons, but they will load.
        """
        log.debug(u"Upgrading iDevice")
        self.emphasis = Idevice.SomeEmphasis
        
    def upgradeToVersion3(self):
        """
        Upgrades v0.6 to v0.7.
        """
        self.lastIdevice = False
    
    def upgradeToVersion4(self):
        """
        Upgrades to exe v0.10
        """
        self._upgradeIdeviceToVersion1()
        self._storyInstruc    = self.__dict__['storyInstruc']
        self._questionInstruc = self.__dict__['questionInstruc']
        self._feedbackInstruc = self.__dict__['feedbackInstruc']

    def upgradeToVersion5(self):
        """
        Upgrades to v0.12
        """
        self._upgradeIdeviceToVersion2()
        
    def upgradeToVersion6(self):
        """
        Upgrades for v0.18
        """
        self.defaultImage = toUnicode(G.application.config.webDir/'images'/DEFAULT_IMAGE)
        for question in self.questions:
            question.setupImage(self)

    def upgradeToVersion7(self):
        """
        Upgrades to somewhere before version 0.25 (post-v0.24)
        Taking the old unicode string fields, 
        and converting them into a image-enabled TextAreaFields:
        """
        self.storyTextArea = TextAreaField(x_(u'Story:'), 
                                 self._storyInstruc, self.story)
        self.storyTextArea.idevice = self
        for question in self.questions:
            question.questionTextArea = TextAreaField(u'', 
                                            u'', question.question)
            question.questionTextArea.idevice = self
            question.feedbackTextArea = TextAreaField(u'', 
                                            u'', question.feedback)
            question.feedbackTextArea.idevice = self

    def upgradeToVersion8(self):
        """
        Converting CaseStudyIdevice's image -> embedded image in its feedback
        field, a TextField than can now hold embedded images.

        BUT - due to the inconsistent loading of the objects via unpickling,
        since the resources aren't necessarily properly loaded and upgraded,
        NOR is the package necessarily, as it might not even have a list of
        resources yet, all of this conversion code must be done in an
        afterUpgradeHandler  
        (as perhaps should have been done for the previous upgradeToVersion7)
        """
        G.application.afterUpgradeHandlers.append(self.embedImagesInFeedback)

    def embedImagesInFeedback(self):
        """
        Loop through each question, to call their conversion:
              CaseStudyIdevice's image -> embedded in its feedback field,
        now that its TextField can hold embeddded images.
        """
        for question in self.questions:
            question.embedImageInFeedback()
コード例 #6
0
class DestacadofpdIdevice(Idevice):
    """
    El iDevice Destacado permite resaltar texto para llamar la atención del alumnado
    """
    persistenceVersion = 7

    def __init__(self, activity="", answer=""):
        """
        Initialize 
        """
        Idevice.__init__(
            self, x_(u"FPD - Destacado"), x_(u"Jose Ramon Jimenez Reyes"),
            x_(u"""Destacado es un iDevice que permite resaltar texto para llamar la atención del alumnado."""
               ), u"", u"destacadofpd")
        self.emphasis = Idevice.NoEmphasis
        self._activityInstruc = x_(
            u"""Introduce el texto que aparecer&aacute; en este iDevice""")
        self.systemResources += ["common.js"]

        self.activityTextArea = TextAreaField(x_(u'Texto Destacado:'),
                                              self._activityInstruc, activity)
        self.activityTextArea.idevice = self

    # Properties
    activityInstruc = lateTranslate('activityInstruc')

    def getResourcesField(self, this_resource):
        """
        implement the specific resource finding mechanism for this iDevice:
        """
        # be warned that before upgrading, this iDevice field could not exist:
        if hasattr(self, 'activityTextArea')\
        and hasattr(self.activityTextArea, 'images'):
            for this_image in self.activityTextArea.images:
                if hasattr(this_image, '_imageResource') \
                    and this_resource == this_image._imageResource:
                    return self.activityTextArea

        return None

    def getRichTextFields(self):
        fields_list = []
        if hasattr(self, 'activityTextArea'):
            fields_list.append(self.activityTextArea)

        return fields_list

    def burstHTML(self, i):
        # Destacadofpd Idevice:
        title = i.find(name='span', attrs={'class': 'iDeviceTitle'})
        self.title = title.renderContents().decode('utf-8')

        reflections = i.findAll(name='div', attrs={'id': re.compile('^ta')})
        # should be exactly two of these:
        # 1st = field[0] == Activity
        if len(reflections) >= 1:
            self.activityTextArea.content_wo_resourcePaths = \
                    reflections[0].renderContents().decode('utf-8')
            # and add the LOCAL resource paths back in:
            self.activityTextArea.content_w_resourcePaths = \
                    self.activityTextArea.MassageResourceDirsIntoContent( \
                        self.activityTextArea.content_wo_resourcePaths)
            self.activityTextArea.content = \
                    self.activityTextArea.content_w_resourcePaths

    def upgradeToVersion1(self):
        """
        Upgrades the node from version 0 to 1.
        """
        log.debug(u"Upgrading iDevice")
        self.icon = u"destacadofpd"

    def upgradeToVersion2(self):
        """
        Upgrades the node from 1 (v0.5) to 2 (v0.6).
        Old packages will loose their icons, but they will load.
        """
        log.debug(u"Upgrading iDevice")
        self.emphasis = Idevice.NoEmphasis

    def upgradeToVersion3(self):
        """
        Upgrades v0.6 to v0.7.
        """
        self.lastIdevice = False

    def upgradeToVersion4(self):
        """
        Upgrades to exe v0.10
        """
        self._upgradeIdeviceToVersion1()
        self._activityInstruc = self.__dict__['activityInstruc']

    def upgradeToVersion5(self):
        """
        Upgrades to exe v0.10
        """
        self._upgradeIdeviceToVersion1()

    def upgradeToVersion6(self):
        """
        Upgrades to v0.12
        """
        self._upgradeIdeviceToVersion2()
#        self.systemResources += ["common.js"]

    def upgradeToVersion7(self):
        """ 
        Upgrades to somewhere before version 0.25 (post-v0.24) 
        Taking the old unicode string fields, and converting them 
        into image-enabled TextAreaFields:
        """
        self.activityTextArea = TextAreaField(x_(u'Texto Destacado:'),
                                              self._activityInstruc,
                                              self.activity)
        self.activityTextArea.idevice = self
コード例 #7
0
class HintIdevice(Idevice):
    """
    HintIdevice: just has a block of text don't exporting
    """
    persistenceVersion = 9

    def __init__(self, content=""):
        Idevice.__init__(
            self, x_(u"Remark"), x_(u"University of Auckland"),
            x_(u"""Leave a commentary for
others who work on this package."""), "", "")
        self.emphasis = Idevice.SomeEmphasis
        self.icon = u"summary"
        self.group = Idevice.Didactics
        self.content = TextAreaField(
            x_(u"Hint"),
            x_(u"""Use this field to leave a
comment for people who works on this package with you. 
This iDevice won't be exported"""), content)
        self.content.idevice = self
        if content:
            self.edit = False
        # determines if the element is exported to presentation
        self.presentable = 'False'

    def getResourcesField(self, this_resource):
        """
        implement the specific resource finding mechanism for this iDevice:
        """
        # be warned that before upgrading, this iDevice field could not exist:
        if hasattr(self, 'content') and hasattr(self.content, 'images'):
            for this_image in self.content.images:
                if hasattr(this_image, '_imageResource') \
                and this_resource == this_image._imageResource:
                    return self.content

        return None

    def getRichTextFields(self):
        """
        Like getResourcesField(), a general helper to allow nodes to search 
        through all of their fields without having to know the specifics of each
        iDevice type.  
        """
        fields_list = []
        if hasattr(self, 'content'):
            fields_list.append(self.content)
        return fields_list

    def burstHTML(self, i):
        """
        takes a BeautifulSoup fragment (i) and bursts its contents to 
        import this idevice from a CommonCartridge export
        """
        # Free Text Idevice:
        #title = i.find(name='span', attrs={'class' : 'iDeviceTitle' })
        #idevice.title = title.renderContents().decode('utf-8')
        # no title for this iDevice.

        # FreeText is also a catch-all idevice for any other which
        # is unable to be burst on its own.
        if i.attrMap['class'] == "FreeTextIdevice":
            # For a REAL FreeText, just read the inner div with class:
            inner = i.find(name='div',
                           attrs={
                               'class': 'block',
                               'style': 'display:block'
                           })
        else:
            # But for all others, read the whole thing:
            inner = i

        self.content.content_wo_resourcePaths = \
                inner.renderContents().decode('utf-8')
        # and add the LOCAL resource paths back in:
        self.content.content_w_resourcePaths = \
                self.content.MassageResourceDirsIntoContent( \
                    self.content.content_wo_resourcePaths)
        self.content.content = self.content.content_w_resourcePaths

    def upgradeToVersion1(self):
        """
        Upgrades the node from version 0 (eXe version 0.4) to 1.
        Adds icon
        """
        self.icon = ""

    def upgradeToVersion2(self):
        """
        Upgrades the node from version 1 (not released) to 2
        Use new Field classes
        """
        self.content = TextAreaField(
            "content",
            x_(u"This is a free text field general learning content can be entered."
               ), self.content)

    def upgradeToVersion3(self):
        """
        Upgrades the node from 2 (v0.5) to 3 (v0.6).
        Old packages will loose their icons, but they will load.
        """
        log.debug(u"Upgrading iDevice")
        self.emphasis = Idevice.NoEmphasis

    def upgradeToVersion4(self):
        """
        Upgrades v0.6 to v0.7.
        """
        self.lastIdevice = False

    def upgradeToVersion5(self):
        """
        Upgrades v0.6 to v0.7.
        """
        self._upgradeIdeviceToVersion1()

    def upgradeToVersion6(self):
        """
        Upgrades to v0.12
        """
        self._upgradeIdeviceToVersion2()

    def upgradeToVersion7(self):
        """
        Attach the idevice to the TextAreaField for tinyMCE image embedding:
        """
        self.content.idevice = self

    def upgradeToVersion8(self):
        """
        Attach presentable to idevice
        Tum changes
        """
        self.presentable = 'False'

    def upgradeToVersion9(self):
        """
        Adds group to idevice
        """
        self.group = Idevice.Content
コード例 #8
0
class ScormDropDownIdevice(Idevice):
    """
    Holds a paragraph with words missing that the student must fill in
    """
    
    persistenceVersion = 4

    def __init__(self, parentNode=None):
        """
        Sets up the idevice title and instructions etc
        """
        Idevice.__init__(self, x_(u"SCORM Test Dropdown"),
                         x_(u"University of Auckland"), 
                         x_(u"<p>Cloze exercises are texts or "
                             "sentences where students must fill in "
                             "missing words. They are often used for the "
                             "following purposes:</p>"
                             "<ol>"
                             "<li>To check knowledge of core course "
                             "concepts (this could be a pre-check, "
                             "formative exercise, or summative check).</li>"
                             "<li>To check reading comprehension.</li>"
                             "<li>To check vocabulary knowledge.</li>"
                             "<li>To check word formation and/or grammatical "
                             "competence. </li></ol>"),
                         x_(u"<dl>"
                             "  <dt>If your goal is to test understanding "
                             "of core concepts or reading comprehension"
                             "  </dt>"
                             "  <dd>"
                             "    <p>"
                             "  Write a summary of the concept or reading long "
                             " enough to adequately test the target's "
                             "knowledge, but short enough not to "
                             "induce fatigue. Less than one typed page is "
                             "probably adequate, but probably "
                             "considerably less for young students or "
                             "beginners."
                             "    </p>"
                             "    <p>"
                             "Select words in the text that"
                             "are key to understanding the concepts. These"
                             "will probably be verbs, nouns, and key adverbs."
                             "Choose alternatives with one clear answer."
                             "    </p>"
                             "  </dd>"
                             "  <dt>"
                             "If your goal is to test vocabulary knowledge"
                             "  </dt>"
                             "  <dd>"
                             "<p>Write a text using the target vocabulary. This "
                             "text should be coherent and cohesive, and be of "
                             "an appropriate length. Highlight the target "
                             "words in the text. Choose alternatives with one "
                             "clear answer.</p>"
                             "  </dd>"
                             "  <dt>"
                             "If your goal is to test word "
                             "formation/grammar:"
                             "  </dt>"
                             "  <dd>"
                             "  <p>"
                             "Write a text using the "
                             "target forms. This text should be coherent and "
                             "cohesive, and be of an appropriate length. "
                             "Remember that the goal is not vocabulary "
                             "knowledge, so the core meanings of the stem "
                             "words should be well known to the students."
                             "  </p>"
                             "  <p>"
                             "Highlight the target words in the text. Provide "
                             "alternatives with the same word stem, but "
                             "different affixes. It is a good idea to get a "
                             "colleague to test the test/exercise to make "
                             "sure there are no surprises!"
                             "  </p>"
                             "  </dd>"
                             "</dl>"),
                            u"question",
                             parentNode)
        self.instructionsForLearners = TextAreaField(
            x_(u'Instructions'),
#translated
#            x_(u"""Hier k&ouml;nnen Sie eine Aufgabenstellung eingeben oder die Standardanweisung &uuml;bernehmen."""),
            x_(u"""Provide instruction how to complete the exercise or take the default text."""),
#            x_(u"""W&auml;hle im folgenden Abschnitt die richtigen Antworten aus!"""))
			x_(u'Choose the correct answers in the paragraph below.'))
        self.instructionsForLearners.idevice = self
        self._content = ClozeField(x_(u'Cloze'), 
            x_(u"""<p>To create a gap with answer options, write the correct answer and then separated by
                '|' the wrong answers:
                true|false|false|false ...
                Mark all answer options and click on the 'Hide/Show Word' button below.
                Hint: answers may contain spaces.</p>"""))
#            x_(u"""<p>Um eine L&uuml;cke mit Antwortm&ouml;glichkeiten zu erzeugen,
#                schreiben sie zuerst die richtige Antwort und dann getrennt
#                mit '|' die falschen Antworten, also folgenderma&szlig;en:
#                richtig|falsch|falsch|falsch...
#                Markieren Sie die gesamten Antworten und klicken sie
#                auf den Button 'Wort verbergen/anzeigen'.
#                Hinweise:<br>In Antworten k&ouml;nnen Leerzeichen enthalten
#                sein<br>Das Zeichen '|' erhalten Sie, indem Sie die 
#                'Alt Gr'-Taste gedr&uuml;ckt halten und dann auf die Taste
#                mit dem Zeichen '|' tippen (auf deutschen Tastaturen meist
#                neben dem 'Y').
#                </p>"""))
        self._content.idevice = self
        self.feedback = TextAreaField(x_(u'Feedback'),
            x_(u'Enter any feedback you wish to provide the learner '
                'with-in the feedback field. This field can be left blank.'))
        self.feedback.idevice = self
        self.emphasis = Idevice.SomeEmphasis
        self.systemResources += ["common.js"]
        self.isCloze = True


    # Properties
    content = property(lambda self: self._content, 
                       doc="Read only, use 'self.content.encodedContent = x' "
                           "instead")

    def getResourcesField(self, this_resource): 
        """ 
        implement the specific resource finding mechanism for this iDevice: 
        """ 
        # be warned that before upgrading, this iDevice field could not exist:
        if hasattr(self, '_content') and hasattr(self._content, 'images'):
            for this_image in self._content.images: 
                if hasattr(this_image, '_imageResource') \
                and this_resource == this_image._imageResource: 
                    return self._content

        # be warned that before upgrading, this iDevice field could not exist:
        if hasattr(self, 'instructionsForLearners')\
        and hasattr(self.instructionsForLearners, 'images'):
            for this_image in self.instructionsForLearners.images: 
                if hasattr(this_image, '_imageResource') \
                and this_resource == this_image._imageResource: 
                    return self.instructionsForLearners

        # be warned that before upgrading, this iDevice field could not exist:
        if hasattr(self, 'feedback') and hasattr(self.feedback, 'images'):
            for this_image in self.feedback.images: 
                if hasattr(this_image, '_imageResource') \
                and this_resource == this_image._imageResource: 
                    return self.feedback
        
        return None

      
    def getRichTextFields(self):
        """
        Like getResourcesField(), a general helper to allow nodes to search 
        through all of their fields without having to know the specifics of each
        iDevice type.  
        """
        fields_list = []
        if hasattr(self, '_content'):
            fields_list.append(self._content)
        if hasattr(self, 'instructionsForLearners'):
            fields_list.append(self.instructionsForLearners)
        if hasattr(self, 'feedback'):
            fields_list.append(self.feedback)
        return fields_list
        
    def burstHTML(self, i):
        """
        takes a BeautifulSoup fragment (i) and bursts its contents to 
        import this idevice from a CommonCartridge export
        """
        # Cloze Idevice:
        title = i.find(name='span', attrs={'class' : 'iDeviceTitle' })
        self.title = title.renderContents().decode('utf-8')

        inner = i.find(name='div', attrs={'class' : 'iDevice_inner' })

        instruct = inner.find(name='div', 
                attrs={'class' : 'block' , 'style' : 'display:block' })
        self.instructionsForLearners.content_wo_resourcePaths = \
                instruct.renderContents().decode('utf-8')
        # and add the LOCAL resource paths back in:
        self.instructionsForLearners.content_w_resourcePaths = \
                self.instructionsForLearners.MassageResourceDirsIntoContent( \
                    self.instructionsForLearners.content_wo_resourcePaths)
        self.instructionsForLearners.content = \
                self.instructionsForLearners.content_w_resourcePaths

        content = inner.find(name='div', attrs={'id' : re.compile('^cloze') })
        rebuilt_contents = ""
        for this_content in content.contents:
            if not this_content.__str__().startswith('<input'):
                if this_content.__str__().startswith('<span'):
                    # Now, decode the answer
                    # with code reverse-engineered from:
                    # a) Cloze's getClozeAnswer() in common.js
                    # b) ClozeElement's renderView() + encrypt()
                    answer = ""
                    code_key = 'X'
                    code = this_content.renderContents()
                    code = code.decode('base64')
                    # now in the form %uABCD%uEFGH%uIJKL....
                    char_pos = 0
                    while char_pos < len(code):
                        # first 2 chars = %u, replace with 0x to get int
                        # next 4 = the encoded unichr
                        this_code_char = "0x" + code[char_pos+2 : char_pos+6]
                        this_code_ord = int(this_code_char, 16)
                        letter = chr(ord(code_key)^this_code_ord)
                        answer += letter
                        # key SHOULD be ^'d by letter, but seems to be:
                        code_key = letter
                        char_pos += 6
                    rebuilt_contents += "<U>" + answer + "</U>"
                elif not this_content.__str__().startswith('<div'):
                    # this should be the un-clozed text:
                    rebuilt_contents +=  this_content.__str__()
        self._content.content_wo_resourcePaths = rebuilt_contents
        # and add the LOCAL resource paths back in:
        self._content.content_w_resourcePaths = \
                self._content.MassageResourceDirsIntoContent( \
                    self._content.content_wo_resourcePaths)
        self._content.content = self._content.content_w_resourcePaths

        feedback = inner.find(name='div', attrs={'class' : 'feedback' })
        self.feedback.content_wo_resourcePaths = \
                feedback.renderContents().decode('utf-8')
        # and add the LOCAL resource paths back in:
        self.feedback.content_w_resourcePaths = \
                self.feedback.MassageResourceDirsIntoContent( \
                    self.feedback.content_wo_resourcePaths)
        self.feedback.content = self.feedback.content_w_resourcePaths

        # and each cloze flag field (strict, case, instant):
        flag_strict = inner.find(name='input', 
                attrs={'id' : re.compile('^clozeFlag.*strictMarking$') })
        if flag_strict.attrMap['value']=="true":
            self._content.strictMarking = True
        flag_caps = inner.find(name='input', 
                attrs={'id' : re.compile('^clozeFlag.*checkCaps$') })
        if flag_caps.attrMap['value']=="true":
            self._content.checkCaps = True
        flag_instant = inner.find(name='input', 
                attrs={'id' : re.compile('^clozeFlag.*instantMarking$') })
        if flag_instant.attrMap['value']=="true":
            self._content.instantMarking = True

    def upgradeToVersion1(self):
        """
        Upgrades exe to v0.10
        """
        self._upgradeIdeviceToVersion1()
        self.instructionsForLearners = TextAreaField(
            x_(u'Instructions For Learners'),
            x_(u'Put instructions for learners here'),
            x_(u'Read the paragraph below and '
                'fill in the missing words'))
        self.instructionsForLearners.idevice = self
        self.feedback = TextAreaField(x_(u'Feedback'))
        self.feedback.idevice = self


    def upgradeToVersion2(self):
        """
        Upgrades exe to v0.11
        """
        self.content.autoCompletion = True
        self.content.autoCompletionInstruc =  _(u"Allow auto completion when "
                                                u"user filling the gaps.")

    def upgradeToVersion3(self):
        """
        Upgrades to v0.12
        """
        self._upgradeIdeviceToVersion2()
        self.systemResources += ["common.js"]
        
    def upgradeToVersion4(self):
        """
        Upgrades to v0.20.3
        """
        self.isCloze = True
コード例 #9
0
class FreeTextIdevice(Idevice):
    """
    FreeTextIdevice: just has a block of text
    """
    persistenceVersion = 7

    def __init__(self, content="", type=None, parent=None):
        Idevice.__init__(
            self, x_(u"Free Text"), x_(u"University of Auckland"),
            x_(u"""The majority of a learning resource will be 
establishing context, delivering instructions and providing general information.
This provides the framework within which the learning activities are built and 
delivered."""), "", "")
        self.emphasis = Idevice.NoEmphasis
        self.content = TextAreaField(
            x_(u"Free Text"),
            x_(u"""Use this field to enter text. This 
iDevice has no emphasis applied although limited formatting can be applied to 
text through the text editing buttons associated with the field."""), content)
        self.content.idevice = self
        if content:
            self.edit = False
        self.type = type
        self.parent = parent
        self.childs = []
        if parent:
            self.parent.childs.append(self)

    def setContent(self,
                   content_w_resourcePaths="",
                   content_wo_resourcePaths=""):
        self.content.content = content_w_resourcePaths
        self.content.content_w_resourcePaths = content_w_resourcePaths
        self.content.content_wo_resourcePaths = content_wo_resourcePaths

    def getResourcesField(self, this_resource):
        """
        implement the specific resource finding mechanism for this iDevice:
        """
        # be warned that before upgrading, this iDevice field could not exist:
        if hasattr(self, 'content') and hasattr(self.content, 'images'):
            for this_image in self.content.images:
                if hasattr(this_image, '_imageResource') \
                and this_resource == this_image._imageResource:
                    return self.content

        return None

    def getRichTextFields(self):
        """
        Like getResourcesField(), a general helper to allow nodes to search 
        through all of their fields without having to know the specifics of each
        iDevice type.  
        """
        fields_list = []
        if hasattr(self, 'content'):
            fields_list.append(self.content)
        return fields_list

    def burstHTML(self, i):
        """
        takes a BeautifulSoup fragment (i) and bursts its contents to 
        import this idevice from a CommonCartridge export
        """
        # Free Text Idevice:
        #title = i.find(name='span', attrs={'class' : 'iDeviceTitle' })
        #idevice.title = title.renderContents().decode('utf-8')
        # no title for this iDevice.

        # FreeText is also a catch-all idevice for any other which
        # is unable to be burst on its own.
        if i.attrMap['class'] == "FreeTextIdevice":
            # For a REAL FreeText, just read the inner div with class:
            inner = i.find(name='div',
                           attrs={
                               'class': 'block',
                               'style': 'display:block'
                           })
        else:
            # But for all others, read the whole thing:
            inner = i

        self.content.content_wo_resourcePaths = \
                inner.renderContents().decode('utf-8')
        # and add the LOCAL resource paths back in:
        self.content.content_w_resourcePaths = \
                self.content.MassageResourceDirsIntoContent( \
                    self.content.content_wo_resourcePaths)
        self.content.content = self.content.content_w_resourcePaths

    def upgradeToVersion1(self):
        """
        Upgrades the node from version 0 (eXe version 0.4) to 1.
        Adds icon
        """
        self.icon = ""

    def upgradeToVersion2(self):
        """
        Upgrades the node from version 1 (not released) to 2
        Use new Field classes
        """
        self.content = TextAreaField(
            "content",
            x_(u"This is a free text field general learning content can be entered."
               ), self.content)

    def upgradeToVersion3(self):
        """
        Upgrades the node from 2 (v0.5) to 3 (v0.6).
        Old packages will loose their icons, but they will load.
        """
        log.debug(u"Upgrading iDevice")
        self.emphasis = Idevice.NoEmphasis

    def upgradeToVersion4(self):
        """
        Upgrades v0.6 to v0.7.
        """
        self.lastIdevice = False

    def upgradeToVersion5(self):
        """
        Upgrades v0.6 to v0.7.
        """
        self._upgradeIdeviceToVersion1()

    def upgradeToVersion6(self):
        """
        Upgrades to v0.12
        """
        self._upgradeIdeviceToVersion2()

    def upgradeToVersion7(self):
        """
        Attach the idevice to the TextAreaField for tinyMCE image embedding:
        """
        self.content.idevice = self
コード例 #10
0
class TOCIdevice(Idevice):
    """
    Build a table of content
    """
    persistenceVersion = 9

    def __init__(self):
        Idevice.__init__(self, x_(u"TOC"), 
                         x_(u"TUM"), 
                         x_(u"""Insert a table of content"""), 
                         u"", u"")
        self.emphasis         = Idevice.NoEmphasis
        self.group            = Idevice.Content
        self.source           = u""
        self.article          = TextAreaField(x_(u"Article"))
        self.article.idevice  = self
        self.images           = {}
        self.icon             = u"inter"

    def generateTOC(self):
        '''Generates toc like as we were exporting'''

        
        root = self.parentNode.package.root
        pageNumbers = {}
        html = self.generateTOCEntry(root, pageNumbers)
        self.article.content_w_resourcePaths = html
        self.article.content_wo_resourcePaths = html


    def generateTOCEntry(self, page, pageNumbers):
        '''recursively generates a TOC entry for a page'''

        html  = u'<ul class="toc">\n'
        pageName = page.titleShort.lower().replace(" ", "_")
        pageName = re.sub(r"\W", "", pageName)
        if pageName in pageNumbers:
            pageNumbers[pageName] += 1
            pageName += str(pageNumbers[pageName])
        else:
            pageNumbers[pageName] = 0
        html += u'<a href="%s.html">%s</a>\n' % \
                (quote(pageName), escape(page.titleShort))
        if page.children:
            for child in page.children:
                html += u'<li>\n' + self.\
                        generateTOCEntry(child, pageNumbers) + '</li>\n'
        html += u'</ul>\n'

        return html


    def getRichTextFields(self):
        """
        Like getResourcesField(), a general helper to allow nodes to search 
        through all of their fields without having to know the specifics of each
        iDevice type.  
        """
        fields_list = []
        if hasattr(self, 'article'):
            fields_list.append(self.article)

        return fields_list


    def burstHTML(self, i):
        """
        takes a BeautifulSoup fragment (i) and bursts its contents to 
        import this idevice from a CommonCartridge export
        """
        # Wiki Article Idevice:
        # option title for Wikipedia, with mode emphasis:
        title = i.find(name='span', attrs={'class' : 'iDeviceTitle' })
        if title is not None: 
            self.title = title.renderContents().decode('utf-8')
            self.emphasis=Idevice.SomeEmphasis

        wiki = i.find(name='div', attrs={'id' : re.compile('^ta') })
        self.article.content_wo_resourcePaths = \
                wiki.renderContents().decode('utf-8')
        # and add the LOCAL resource paths back in:
        self.article.content_w_resourcePaths = \
                self.article.MassageResourceDirsIntoContent( \
                    self.article.content_wo_resourcePaths)
        self.article.content = self.article.content_w_resourcePaths

        site = i.find(name='div', attrs={'class' : 'wiki_site' })
        if site is not None: 
            self.site = site.attrMap['value'].decode('utf-8')

        name = i.find(name='div', attrs={'class' : 'article_name' })
        if name is not None: 
            # WARNING: the following crashes on accented characters, eg:
            #  'ascii' codec can't encode character u'\xe8' in 
            #  position 11: ordinal not in range(128)
            self.articleName = name.attrMap['value'].decode('utf-8')

        own_url = i.find(name='div', attrs={'class' : 'own_url' })
        if own_url is not None: 
            self.own_url = own_url.attrMap['value'].decode('utf-8')