#! /usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright 2011-2012, 2014, Marten de Vries
# Copyright 2011, Milan Boers
#
# This file is part of OpenTeacher.
#
# OpenTeacher is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# OpenTeacher is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with OpenTeacher. If not, see <http://www.gnu.org/licenses/>.
import copy
import datetime
class Teach2000SaverModule:
def __init__(self, moduleManager, *args, **kwargs):
super().__init__(*args, **kwargs)
self._mm = moduleManager
self.type = "save"
self.priorities = {
"default": 448,
}
self.uses = (
self._mm.mods(type="translator"),
)
self.filesWithTranslations = ("t2k.py",)
def _retranslate(self):
try:
translator = self._modules.default("active", type="translator")
except IndexError:
_, ngettext = str, lambda a, b, n: a if n == 1 else b
else:
_, ngettext = translator.gettextFunctions(
self._mm.resourcePath("translations")
)
self.saves = {"words": {
#TRANSLATORS: This is the name of an application. For more info
#TRANSLATORS: about Teach2000: http://www.teach2000.org/
"t2k": _("Teach2000"),
}}
def enable(self):
global pyratemp
try:
import pyratemp
except ImportError:
return #remain inactive
self._modules = set(self._mm.mods(type="modules")).pop()
try:
translator = self._modules.default("active", type="translator")
except IndexError:
pass
else:
translator.languageChanged.handle(self._retranslate)
self._retranslate()
self.active = True
def disable(self):
self.active = False
del self._modules
del self.saves
def save(self, type, lesson, path):
#copy, we're going to modify it
wordList = copy.deepcopy(lesson.list)
self._storeRightWrongCountInWords(wordList)
for test in wordList.get("tests", []):
test["note"] = self._calculateNote(test)
test["start"] = self._startTime(test)
test["duration"] = self._duration(test)
test["answerscorrect"] = self._answersCorrect(test)
test["wrongonce"] = self._wrongOnce(test)
test["wrongtwice"] = self._wrongTwice(test)
test["wrongmorethantwice"] = self._wrongMoreThanTwice(test)
templatePath = self._mm.resourcePath("template.xml")
with open(templatePath, encoding='UTF-8') as f:
t = pyratemp.Template(f.read())
data = {
"wordList": wordList,
}
content = t(**data)
with open(path, "w", encoding='UTF-8') as f:
f.write(content)
lesson.path = None
def _storeRightWrongCountInWords(self, wordList):
for word in wordList.get("items", []):
word["wrongCount"] = 0
word["rightCount"] = 0
for test in wordList.get("tests", []):
for result in test["results"]:
if result["itemId"] == word["id"]:
if result["result"] == "right":
word["rightCount"] += 1
else:
word["wrongCount"] += 1
def _calculateNote(self, test):
#dutch note, but with full float representation.
right = 0
wrong = 0
for result in test["results"]:
if result["result"] == "right":
right += 1
else:
wrong += 1
return str(right / float(right + wrong) * 9 + 1)
def _startTime(self, test):
try:
t = test["results"][0]["active"][0]["start"]
except (KeyError, IndexError):
t = datetime.datetime.now()
return self._composeDateTime(t)
def _composeDateTime(self, dt):
#chop off the last three millisecond decimals, because Teach2000
#can't handle that kind of precision. That's bad.
return dt.strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3]
def _duration(self, test):
try:
start = test["results"][0]["active"]["start"]
end = test["results"][-1]["active"]["end"]
except (KeyError, IndexError):
t = datetime.datetime.fromtimestamp(0)
else:
t = datetime.datetime.fromtimestamp(0) + (end - start)
#Teach2000 is written in Pascal... Blegh :P.
#use its epoch. (So not the unix one)
#strftime doesn't allow dates < 1900, so that's why the weird
#string formatting. See _composeDateTime for info on the [:-3].
return "1899-12-30T%s" % t.strftime("%H:%M:%S.%f")[:-3]
def _answersCorrect(self, test):
correct = 0
for result in test["results"]:
if result["result"] == "right":
correct += 1
return correct
def _stats(self, test):
stats = {}
for result in test["results"]:
if result["result"] == "wrong":
try:
stats[result["itemId"]] += 1
except KeyError:
stats[result["itemId"]] = 1
return stats
def _wrongOnce(self, test):
return list(self._stats(test).values()).count(1)
def _wrongTwice(self, test):
return list(self._stats(test).values()).count(2)
def _wrongMoreThanTwice(self, test):
count = 0
for val in self._stats(test).values():
if val > 2:
count += 1
return count
def init(moduleManager):
return Teach2000SaverModule(moduleManager)