class ReadingActivityIdevice(GenericIdevice): group = Idevice.CONTENT name = _("Reading Activity") title = models.CharField(max_length=100, default=name) author = _("University of Auckland") purpose = _("""<p>The Reading Activity will primarily be used to check a learner's comprehension of a given text. This can be done by asking the learner to reflect on the reading and respond to questions about the reading, or by having them complete some other possibly more physical task based on the reading.</p>""") icon = "icon_reading.gif" emphasis = Idevice.SOMEEMPHASIS to_read = fields.RichTextField(blank=True, default="", help_text=_("""Enter the details of the reading including reference details. The referencing style used will depend on the preference of your faculty or department.""")) activity = fields.RichTextField(blank=True, default="", help_text= _("""Describe the tasks related to the reading learners should undertake. This helps demonstrate relevance for learners.""")) feedback = fields.FeedbackField(blank=True, default="", help_text= _("""Use feedback to provide a summary of the points covered in the reading, or as a starting point for further analysis of the reading by posing a question or providing a statement to begin a debate.""")) class Meta: app_label = "exeapp"
class GlossaryTerm(models.Model): title = fields.RichTextField(max_length=100, blank=True, default="", help_text="Enter term you want to describe") definition = fields.RichTextField(blank=True, default="", help_text="Enter defintion of the term") idevice = models.ForeignKey("GlossaryIdevice", related_name="terms") class Meta: app_label = "exeapp"
class ProtectedFreeTextVersion(models.Model): idevice = models.ForeignKey("ProtectedFreeTextIdevice", related_name="versions") content = fields.RichTextField(blank=True, default="") date_created = models.DateTimeField(default=datetime.now) class Meta: app_label = "exeapp"
class CaseActivity(models.Model): activity = fields.RichTextField( blank=True, default="", help_text=_("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. ")) feedback = fields.FeedbackField( blank=True, default="", help_text=_("Provide relevant feedback on the situation")) idevice = models.ForeignKey("CaseStudyIdevice", related_name="terms") def to_dict(self): d = self.__dict__ d = { k: v for k, v in d.items() if k != 'idevice_id' and k != 'id' and not k.startswith('_') } return d class Meta: app_label = "exeapp"
class ReflectionIdevice(GenericIdevice): name = _("Reflection") title = models.CharField(max_length=100, default=name) author = _("University of Auckland") purpose = _("""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.""") emphasis = Idevice.SOMEEMPHASIS group = Idevice.TEST activity = fields.RichTextField( blank=True, default="", help_text=_("""Enter a question for learners to reflect upon.""")) answer = fields.FeedbackField( blank=True, default="", help_text=_("""Describe how learners will assess how they have done in the exercise. (Rubrics are useful devices for providing reflective feedback.)""")) class Meta: app_label = "exeapp"
class RSSIdevice(GenericIdevice): name = _("RSS") title = models.CharField(max_length=100, default=name) author = _("Auckland University of Technology") purpose = _("""The RSS iDevice is used to provide new content to an individual users machine. Using this iDevice you can provide links from a feed you select for learners to view.""") emphasis = Idevice.NOEMPHASIS group = Idevice.COMMUNICATION icon = "icon_inter.gif" rss_url = fields.URLField(max_length=200, blank=True, default="", help_text=_("""Enter an RSS URL for the RSS feed you want to attach to your content. Feeds are often identified by a small graphic icon (often like this <img src="/static/images/feed-icon.png" />) or the text "RSS". Clicking on the icon or text label will display an RSS feed right in your browser. You can copy and paste the URL into this field. Alternately, right clicking on the link or graphic will open a menu box; click on COPY LINK LOCATION or Copy Shortcut. Back in eXe open the RSS bookmark iDevice and Paste the URL into the RSS URL field and click the LOAD button. This will extract the titles from your feed and display them as links in your content. From here you can edit the bookmarks and add instructions or additional learning information.""")) content = fields.RichTextField(blank=True, default="") def load_rss(self, url): """ Load the rss """ self.rss_url = url content = "" try: rssDic = feedparser.parse(url) length = len(rssDic['entries']) if length > 0: for i in range(0, length): content += '<p><A href="%s">%s</A></P>' % ( rssDic['entries'][i].link, rssDic['entries'][i].title) except IOError as error: content += _( "Unable to load RSS feed from %s <br/>Please check the " "spelling and connection and try again.") % url if content == "": content += _( "Unable to load RSS feed from %s <br/>Please check the " "spelling and connection and try again.") % url self.content = content class Meta: app_label = "exeapp"
class GlossaryTerm(models.Model): title = fields.RichTextField( max_length=100, blank=True, default="", help_text=_("Enter term you want to describe")) definition = fields.RichTextField( blank=True, default="", help_text=_("Enter definition of the term")) idevice = models.ForeignKey("GlossaryIdevice", related_name="terms") def to_dict(self): d = self.__dict__ d = { k: v for k, v in d.items() if k != 'idevice_id' and k != 'id' and not k.startswith('_') } return d class Meta: app_label = "exeapp"
class TOCIdevice(GenericIdevice): name = _("Table Of Content") title = name emphasis = Idevice.SOMEEMPHASIS group = Idevice.CONTENT content = fields.RichTextField(blank=True, default="") author = _("Technical University Munich") icon = "icon_inter.gif" edit_message = _("The content of this iDevice is automatically generated" "should not be edited directly.") class Meta: app_label = "exeapp"
class CommentIdevice(GenericIdevice): name = "Remark" title = models.CharField(max_length=100, default=name) author = "TU Munich" purpose = "Leave a commentary for others who work on this package." emphasis = Idevice.SOMEEMPHASIS icon = "icon_summary.gif" group = Idevice.DIDACTICS content = fields.RichTextField(blank=True, default="", help_text="""Use this field to leave a comment for people who works on this package with you. This iDevice won't be exported""") class Meta: app_label = "exeapp"
class FreeTextIdevice(GenericIdevice): """ FreeTextIdevice: just has a block of text """ group = Idevice.CONTENT name = "Free Text" title = "Free Text" author = "University of Auckland" purpose = """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.""" emphasis = Idevice.NOEMPHASIS content = fields.RichTextField(blank=True, default="") class Meta: app_label = "exeapp"
class ObjectivesIdevice(GenericIdevice): name = _("Objectives") title = models.CharField(max_length=100, default=name) author = _("University of Auckland") purpose = _("""Objectives describe the expected outcomes of the learning " "and should define what the learners will be able to do when they have " "completed the learning tasks.""") emphasis = Idevice.SOMEEMPHASIS content = fields.RichTextField( blank=True, default="", help_text=_("Type the learning objectives for this resource.")) group = Idevice.DIDACTICS class Meta: app_label = "exeapp"
class ClozeIdevice(GenericIdevice): group = Idevice.TEST name = _("Cloze") title = models.CharField(max_length=100, default=name) author = _("University of Auckland") purpose = _("""<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>""") emphasis = Idevice.SOMEEMPHASIS icon = "icon_question.gif" description = fields.RichTextField( blank=True, default="", help_text=_("""Provide instruction on how the cloze activity should be completed. Default text will be entered if there are no changes to this field. """)) cloze_text = fields.ClozeTextField( blank=True, default="", help_text=_( """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.To select words to hide, double click on the word to select it and click on the underscore button in the toolbar.""")) feedback = fields.FeedbackField( blank=True, default="", help_text=_("""Enter any feedback you wish to provide the learner with-in the feedback field. This field can be left blank.""")) drag_n_drop = models.BooleanField(default=False) class Meta: app_label = "exeapp"
class ActivityIdevice(GenericIdevice): group = Idevice.CONTENT name = "Activity" title = models.CharField(max_length=100, default=name) author = "University of Auckland" purpose = """An activity can be defined as a task or set of tasks a learner must complete. Provide a clear statement of the task and consider any conditions that may help or hinder the learner in the performance of the task.""" icon = "icon_activity.gif" emphasis = Idevice.SOMEEMPHASIS content = fields.RichTextField( blank=True, default="", help_text="Describe the tasks the learners should complete.") class Meta: app_label = "exeapp"
class PreknowledgeIdevice(GenericIdevice): name = "Preknowledge" title = models.CharField(max_length=100, default=name) purpose = """Prerequisite knowledge refers to the knowledge learners should already have in order to be able to effectively complete the learning. Examples of pre-nowledge can be: <ul> <li>Learners must have level 4 English </li> <li>Learners must be able to assemble standard power tools </li></ul> """ group = Idevice.DIDACTICS emphasis = Idevice.SOMEEMPHASIS content = fields.RichTextField( blank=True, default="", help_text="""Describe the prerequisite knowledge learners should have to effectively complete this learning.""") icon = "icon_preknowledge.gif" class Meta: app_label = "exeapp"
class MultiChoiceOptionIdevice(models.Model): option = fields.MultiChoiceOptionField( blank=True, default="", help_text=_("An answer option for the multiple choice question. Check" " the 'right answer' checkmark to mark the right option") ) feedback = fields.RichTextField("Feedback", "feedback", blank=True, null=True, help_text="Feedback text for the answer") right_answer = models.BooleanField(default=False) idevice = models.ForeignKey("MultiChoiceIdevice", related_name="options") def to_dict(self): d = self.__dict__ d = {k: v for k, v in d.items() if k != 'idevice_id' and k != 'id' and not k.startswith('_') } return d class Meta: app_label = "exeapp"
class TOCIdevice(GenericIdevice): name = "Table Of Content" title = name emphasis = Idevice.SOMEEMPHASIS group = Idevice.CONTENT content = fields.RichTextField(blank=True, default="") author = "TU Munich" icon = u"icon_inter.gif" def save(self, *args, **kwargs): self.content = self.populate_toc() super(TOCIdevice, self).save(*args, **kwargs) def populate_toc(self): package = self.parent_node.package toc_list = [self._generate_item(package.root)] if package.root.children.exists(): toc_list.append(self._generate_toc_tree(package.root)) return '<ul class="toc">%s</ul>' % unordered_list(toc_list) def _generate_toc_tree(self, node): list = [] for child in node.children.all(): list.append(self._generate_item(child)) if child.children.exists(): list.append(self._generate_toc_tree(child)) return list def _generate_item(self, node): return '<a href="%s.html">%s</a>' %\ (node.unique_name(), node.title) class Meta: app_label = "exeapp"
class CaseStudyIdevice(Idevice): name = _("Case Study") title = models.CharField(max_length=100, default=name) author = _("Technical University Munich") purpose = _("""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>""") emphasis = Idevice.SOMEEMPHASIS group = Idevice.TEST icon = "icon_casestudy.gif" story = fields.RichTextField( blank=True, default="", help_text=_("""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.""")) objects = CaseStudyIdeviceManager() def add_child(self): CaseActivity.objects.create(idevice=self) def to_dict(self): d = self.__dict__ d = { k: v for k, v in d.items() if k != 'id' and k != 'idevice_ptr_id' and k != 'parent_node_id' and not k.startswith('_') } d['child_type'] = self.get_klass() d['terms'] = [] for term in self.terms.all(): d['terms'].append(term.to_dict()) return d def from_dict(self, dic): print(dic) self.title = dic['title'] self.edit = dic['edit'] self.story = dic['story'] #clear blank answer created by default for this question in the manager CaseActivity.objects.filter(idevice=self).delete() for term in dic['terms']: CaseActivity.objects.create(idevice=self, activity=term['activity'], feedback=term['feedback']) self.save() return self class Meta: app_label = "exeapp"
class FreeTextIdevice(GenericIdevice): """ FreeTextIdevice: just has a block of text """ group = Idevice.CONTENT name = _("Free Text") title = _("Free Text") author = _("University of Auckland") purpose = _("""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.""") emphasis = Idevice.NOEMPHASIS content = fields.RichTextField(blank=True, default="") date_created = models.DateTimeField(blank=True, null=True, editable=False) class Meta: app_label = "exeapp" def to_dict(self): d = self.__dict__ d = { k: v for k, v in d.items() if k != 'id' and k != 'idevice_ptr_id' and k != 'parent_node_id' and k != 'date_created' and not k.startswith('_') } d['child_type'] = self.get_klass() soup = BeautifulSoup(d['content']) images = soup.findAll("img") for img in images: img['src'] = Path(img['src']).basename() d['content'] = soup.prettify() return d def from_dict(self, dic): print(dic) self.edit = dic['edit'] soup = BeautifulSoup(dic['content']) images = soup.findAll("img") for img in images: img['src'] = Path.joinpath( self.parent_node.package.user.profile.media_url, img['src']) self.content = soup.prettify() self.date_created = datetime.now() self.save() FreeTextVersion.objects.create(idevice=self, content=self.content, date_created=self.date_created) return self def has_previous_version(self, date=None): if date is None: date = self.date_created if date is None: return False if FreeTextVersion.objects.filter(idevice_id=self.id, date_created__lt=date).count(): return True else: return False def has_later_version(self, date=None): if date is None: date = self.date_created if date is None: return False if FreeTextVersion.objects.filter(idevice_id=self.id, date_created__gt=date).count(): return True else: return False def get_previous_version(self, date=None): if date is None: date = self.date_created if date is None: return None f1 = FreeTextVersion.objects.filter( idevice_id=self.id, date_created__lt=date).order_by('-date_created') if f1.count() > 0: return f1[0] else: return None def get_later_version(self, date=None): if date is None: date = self.date_created if date is None: return None f = FreeTextVersion.objects.filter( idevice_id=self.id, date_created__gt=date).order_by('date_created') if f.count() > 0: return f[0] else: return None def get_current_version(self): f = FreeTextVersion.objects.filter(idevice_id=self.id, date_created=self.date_created) if f.count() > 0: return f[0] else: return None def delete_unnecessary_version(self): FreeTextVersion.objects.filter( idevice_id=self.id, date_created__gt=self.date_created).delete() def apply_changes(self, formdata, formsetdata=None): #check for first time. it is none at first if self.date_created: self.delete_unnecessary_version() #check for same old version saving again. avoid duplication during creating versions v = self.get_current_version() if v is None: self.date_created = datetime.now() FreeTextVersion.objects.create(idevice=self, content=formdata['content'], date_created=self.date_created) elif self.content != v.content: self.date_created = datetime.now() FreeTextVersion.objects.create(idevice=self, content=formdata['content'], date_created=self.date_created) self.edit = False
class MultiChoiceIdevice(Idevice): name = _("Multiple Choice") title = models.CharField(max_length=100, default=name) author = _("Technische Univesität München") purpose = _("""Create a multiple choice questionary to review the learned material""") emphasis = Idevice.SOMEEMPHASIS group = Idevice.TEST icon = "icon_question.gif" question = fields.RichTextField( blank=True, default="", help_text=_("""Create a multiple choice questionary to review the learned material. Click "Add option" to add more answer options""") ) objects = MultiChoiceIdeviceManager() def add_child(self): MultiChoiceOptionIdevice.objects.create(idevice=self) class Meta: app_label = "exeapp" def submit_answers(self, data): chosen_option = MultiChoiceOptionIdevice.objects.get(pk=data['option']) assert chosen_option.idevice == self return chosen_option.right_answer def is_multioptional(self): """ Returns true, if the question has more than one correct option """ return self.options.filter(right_answer=True).count() > 1 def to_dict(self): d = self.__dict__ d = {k: v for k, v in d.items() if k != 'id' and k != 'idevice_ptr_id' and k != 'parent_node_id' and not k.startswith('_') } d['child_type'] = self.get_klass() d['answers'] = [] for answer in self.options.all(): d['answers'].append(answer.to_dict()) return d def from_dict(self, dic): self.question = dic['question'] self.edit = dic['edit'] #clear blank answer created by default for this question in the manager MultiChoiceOptionIdevice.objects.filter(idevice=self).delete() for answer in dic['answers']: MultiChoiceOptionIdevice.objects.create(idevice=self, option=answer['option'], right_answer=answer['right_answer'], feedback=answer.get('feedback', None) ) self.save() return self
class ProtectedFreeTextIdevice(GenericIdevice): group = Idevice.CONTENT name = _("Protected Free Text") title = _("Protected Free Text") purpose = _("""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.""") emphasis = Idevice.NOEMPHASIS content = fields.RichTextField(blank=True, default="") password = models.CharField(max_length=20, blank=True, default="", help_text=_("Input password to encrypt content")) date_created = models.DateTimeField(blank=True, null=True, editable=False) class Meta: app_label = "exeapp" def to_dict(self): d = self.__dict__ d = {k: v for k, v in d.items() if k != 'id' and k != 'idevice_ptr_id' and k != 'parent_node_id' and k != 'date_created' and not k.startswith('_') } d['child_type'] = self.get_klass() return d def from_dict(self, dic): print(dic) self.edit = dic['edit'] self.content = dic['content'] self.password = dic['password'] self.date_created = datetime.now() self.save() ProtectedFreeTextVersion.objects.create(idevice=self, content=self.content, date_created=self.date_created) return self def has_previous_version(self, date=None): if date is None: date = self.date_created if date is None: return False if ProtectedFreeTextVersion.objects.filter(idevice_id=self.id, date_created__lt=date).count(): return True else: return False def has_later_version(self, date=None): if date is None: date = self.date_created if date is None: return False if ProtectedFreeTextVersion.objects.filter(idevice_id=self.id, date_created__gt=date).count(): return True else: return False def get_previous_version(self, date=None): if date is None: date = self.date_created if date is None: return None f1 = ProtectedFreeTextVersion.objects.filter(idevice_id=self.id, date_created__lt=date).order_by('-date_created') if f1.count() > 0: return f1[0] else: return None def get_later_version(self, date=None): if date is None: date = self.date_created if date is None: return None f = ProtectedFreeTextVersion.objects.filter(idevice_id=self.id, date_created__gt=date).order_by('date_created') if f.count() > 0: return f[0] else: return None def get_current_version(self): f = ProtectedFreeTextVersion.objects.filter(idevice_id=self.id, date_created=self.date_created) if f.count() > 0: return f[0] else: return None def delete_unnecessary_version(self): ProtectedFreeTextVersion.objects.filter(idevice_id=self.id, date_created__gt=self.date_created).delete() def apply_changes(self, formdata, formsetdata=None): #check for first time. it is none at first if self.date_created: self.delete_unnecessary_version() #check for same old version saving again. avoid duplication during creating versions v = self.get_current_version() if v is None: self.date_created = datetime.now() ProtectedFreeTextVersion.objects.create(idevice=self, content=formdata['content'], date_created=self.date_created) elif self.content != v.content: self.date_created = datetime.now() ProtectedFreeTextVersion.objects.create(idevice=self, content=formdata['content'], date_created=self.date_created) self.edit = False