excel2moodle 0.3.2__py3-none-any.whl → 0.3.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
excel2moodle/ui/appUi.py CHANGED
@@ -4,51 +4,51 @@ It needs to be seperated from ``windowMain.py`` because that file will be change
4
4
  which generates the python code from the ``.ui`` file
5
5
  """
6
6
 
7
- from PySide6 import QtCore
8
- from PySide6.QtCore import Qt
9
- from PySide6 import QtWidgets
7
+ import logging as logging
10
8
  from pathlib import Path
11
- from excel2moodle.ui.windowMain import Ui_MoodleTestGenerator
12
- from .windowEquationChecker import Ui_EquationChecker
13
- from excel2moodle.ui import windowEquationChecker, dialogs
9
+
10
+ from PySide6 import QtCore, QtWidgets
11
+ from PySide6.QtCore import Qt
12
+
13
+ from excel2moodle import e2mMetadata, qSignalLogger
14
14
  from excel2moodle.core.dataStructure import QuestionDB
15
- from excel2moodle.ui.treewidget import QuestionItem, CategoryItem
16
15
  from excel2moodle.extra import equationVerification as eqVerif
17
- from excel2moodle import qSignalLogger
16
+ from excel2moodle.ui import dialogs, windowEquationChecker
18
17
  from excel2moodle.ui.settings import Settings
19
- from excel2moodle.ui.windowDoc import DocumentationWindow
20
- import logging as logging
21
-
22
- from excel2moodle import dirDocumentation
18
+ from excel2moodle.ui.treewidget import CategoryItem, QuestionItem
19
+ from excel2moodle.ui.windowMain import Ui_MoodleTestGenerator
23
20
 
21
+ from .windowEquationChecker import Ui_EquationChecker
24
22
 
25
23
  logger = logging.getLogger(__name__)
26
24
 
27
25
 
28
-
29
26
  class MainWindow(QtWidgets.QMainWindow):
30
- def __init__(self, settings:Settings, testDB:QuestionDB)->None:
27
+ def __init__(self, settings: Settings, testDB: QuestionDB) -> None:
31
28
  super().__init__()
32
- # self.questionGenerator = questionGenerator
33
- # self.readSettings()
34
29
  self.settings = settings
35
- self.excelPath: Path|None = None
36
- if self.excelPath is not None:
37
- self.ui.buttonSpreadSheet.setText(self.excelPath.name)
38
- self.mainPath = (self.excelPath.parent if self.excelPath is not None else None)
30
+ self.excelPath: Path | None = None
31
+ self.mainPath = self.excelPath.parent if self.excelPath is not None else None
39
32
  self.exportFile = Path()
40
33
  self.testDB = testDB
41
34
  self.ui = Ui_MoodleTestGenerator()
42
35
  self.ui.setupUi(self)
43
36
 
44
- # self.ui.buttonRefresh.clicked.connect(lambda: self.refreshList(self.test))
45
37
  self.ui.treeWidget.setSelectionMode(QtWidgets.QAbstractItemView.MultiSelection)
46
- self.ui.treeWidget.header().setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents)
38
+ self.ui.treeWidget.header().setSectionResizeMode(
39
+ QtWidgets.QHeaderView.ResizeToContents
40
+ )
41
+ self.ui.checkBoxIncludeCategories.setChecked(
42
+ self.settings.value("testGen/includeCats", type=bool)
43
+ )
47
44
 
48
45
  self.ui.retranslateUi(self)
49
46
  logger.info(f"Settings are stored under: {self.settings.fileName()}")
50
47
  self.ui.pointCounter.setReadOnly(True)
51
- self.setStatus("Wählen Sie bitte eine Excel Tabelle und einen Export Ordner für die Fragen aus")
48
+ self.ui.questionCounter.setReadOnly(True)
49
+ self.setStatus(
50
+ "Wählen Sie bitte eine Excel Tabelle und einen Export Ordner für die Fragen aus"
51
+ )
52
52
  try:
53
53
  self.resize(self.settings.value("windowSize"))
54
54
  self.move(self.settings.value("windowPosition"))
@@ -56,42 +56,72 @@ class MainWindow(QtWidgets.QMainWindow):
56
56
  pass
57
57
  self.connectEvents()
58
58
 
59
- def connectEvents(self)->None:
59
+ def connectEvents(self) -> None:
60
60
  self.ui.treeWidget.itemClicked.connect(self.onSelectionChanged)
61
- self.ui.checkBoxQuestionListSelectAll.checkStateChanged.connect(self.toggleQuestionSelectionState)
61
+ self.ui.checkBoxQuestionListSelectAll.checkStateChanged.connect(
62
+ self.toggleQuestionSelectionState
63
+ )
62
64
  qSignalLogger.emitter.signal.connect(self.updateLog)
63
65
  self.ui.actionEquationChecker.triggered.connect(self.onButOpenEqChecker)
64
- self.ui.checkBoxIncludeCategories.checkStateChanged.connect(self.setIncludeCategoriesSetting)
66
+ self.ui.checkBoxIncludeCategories.checkStateChanged.connect(
67
+ self.setIncludeCategoriesSetting
68
+ )
65
69
  # self.ui.buttonRefresh.clicked.connect(self.refreshList)
66
- self.ui.actionParseAll.triggered.connect(self.onParseAll )
70
+ self.ui.actionParseAll.triggered.connect(self.onParseAll)
67
71
  self.testDB.dataChanged.signal.connect(self.onParseAll)
68
72
  self.ui.buttonSpreadSheet.clicked.connect(self.onButSpreadsheet)
69
73
  self.ui.buttonTestGen.clicked.connect(self.onButGenTest)
70
74
  self.ui.actionPreviewQ.triggered.connect(self.previewQ)
71
- self.ui.actionDocumentation.triggered.connect(self.onOpenDocumentation)
75
+ self.ui.actionAbout.triggered.connect(self.onAbout)
72
76
  self.settings.shPathChanged.connect(self.onSheetPathChanged)
73
77
 
74
-
75
78
  @QtCore.Slot(Path)
76
- def onSheetPathChanged(self, sheet:Path)->None:
79
+ def onSheetPathChanged(self, sheet: Path) -> None:
77
80
  logger.debug("Slot, new Spreadsheet triggered")
78
81
  self.spreadSheetPath = sheet
79
82
  self.mainPath = sheet.parent
83
+ self.ui.buttonSpreadSheet.setText(str(sheet.name))
80
84
 
81
- def updateLog(self,log)->None:
85
+ def updateLog(self, log) -> None:
82
86
  self.ui.loggerWindow.append(log)
83
87
 
84
88
  def setIncludeCategoriesSetting(self):
85
89
  if self.ui.checkBoxIncludeCategories.isChecked():
86
- self.settings.set("testGen/includeCats", True)
90
+ self.settings.testgenSet("includeCats", True)
91
+ logger.debug("set includeCats to True")
87
92
  else:
88
- self.settings.set("testGen/includeCats", False)
93
+ self.settings.testgenSet("includeCats", False)
94
+ logger.debug("set includeCats to False")
89
95
 
90
96
  @QtCore.Slot()
91
- def onOpenDocumentation(self):
92
- documentationWindow = DocumentationWindow(dirDocumentation, self)
93
- documentationWindow.show()
94
-
97
+ def onAbout(self):
98
+ aboutMessage: str = f"""
99
+ <h1> About {e2mMetadata['name']}</h1><br>
100
+ <p style="text-align:center">
101
+
102
+ <b><a href="{e2mMetadata['homepage']}">{e2mMetadata['name']}</a> - {e2mMetadata['description']}</b>
103
+ </p>
104
+ <p style="text-align:center">
105
+ The documentation can be found under <b>
106
+ <a href="{e2mMetadata['documentation']}">{e2mMetadata['documentation']}</a></b>
107
+ </br>
108
+ </p>
109
+ <p style="text-align:center">
110
+ This project is maintained by {e2mMetadata['author']}.
111
+ <br>
112
+ Development takes place at <a href="{e2mMetadata['homepage']}"> GitLab: {e2mMetadata['homepage']}</a>
113
+ contributions are very welcome
114
+ </br>
115
+ If you encounter any issues please report them under the repositories issues page.
116
+ </br>
117
+ </p>
118
+ <p style="text-align:center">
119
+ <i>This project is published under {e2mMetadata['license']}, you are welcome, to share, modify and reuse the code.</i>
120
+ </p>
121
+ """
122
+ QtWidgets.QMessageBox.information(
123
+ self, f"About {e2mMetadata['name']}", aboutMessage
124
+ )
95
125
 
96
126
  def closeEvent(self, event):
97
127
  self.settings.setValue("windowSize", self.size())
@@ -108,7 +138,7 @@ class MainWindow(QtWidgets.QMainWindow):
108
138
  questions += 1
109
139
  count += q.getQuestion().points
110
140
 
111
- logger.info(f'{questions} questions are selected with {count} points')
141
+ logger.info(f"{questions} questions are selected with {count} points")
112
142
  self.ui.pointCounter.setValue(count)
113
143
  self.ui.questionCounter.setValue(questions)
114
144
  return None
@@ -117,7 +147,8 @@ class MainWindow(QtWidgets.QMainWindow):
117
147
  def toggleQuestionSelectionState(self, state):
118
148
  if state == Qt.Checked:
119
149
  setter = True
120
- else: setter = False
150
+ else:
151
+ setter = False
121
152
  root = self.ui.treeWidget.invisibleRootItem()
122
153
  childN = root.childCount()
123
154
  for i in range(childN):
@@ -126,34 +157,37 @@ class MainWindow(QtWidgets.QMainWindow):
126
157
  root.child(i).child(q).setSelected(setter)
127
158
 
128
159
  @QtCore.Slot()
129
- def onButGenTest(self)->None:
130
- path = QtWidgets.QFileDialog.getSaveFileName(self, "Select Output File",
131
- dir=f"{self.mainPath/"Testfile.xml"}",
132
- filter="xml Files (*.xml)")
160
+ def onButGenTest(self) -> None:
161
+ path = QtWidgets.QFileDialog.getSaveFileName(
162
+ self,
163
+ "Select Output File",
164
+ dir=f"{
165
+ self.mainPath/"Testfile.xml"}",
166
+ filter="xml Files (*.xml)",
167
+ )
133
168
  self.exportFile = Path(path[0])
134
169
  logger.info(f"New Export File is set{self.exportFile=}")
135
- selection:list[QuestionItem] = self.ui.treeWidget.selectedItems()
170
+ selection: list[QuestionItem] = self.ui.treeWidget.selectedItems()
136
171
  self.testDB.appendQuestions(selection, self.exportFile)
137
172
  return None
138
173
 
139
174
  @QtCore.Slot()
140
175
  def onButSpreadsheet(self):
141
- file = QtWidgets.QFileDialog.getOpenFileName(self,
142
- self.tr("Open Spreadsheet"),
143
- dir = str(self.mainPath),
144
- filter=self.tr("Spreadsheet(*.xlsx *.ods)"),
145
- selectedFilter=("*.ods"))
176
+ file = QtWidgets.QFileDialog.getOpenFileName(
177
+ self,
178
+ self.tr("Open Spreadsheet"),
179
+ dir=str(self.mainPath),
180
+ filter=self.tr("Spreadsheet(*.xlsx *.ods)"),
181
+ selectedFilter=("*.ods"),
182
+ )
146
183
  self.excelPath = Path(file[0]).resolve()
147
184
  self.settings.setSpreadsheet(self.excelPath)
148
- self.mainPath = self.excelPath.parent
149
- self.ui.buttonSpreadSheet.setText(self.excelPath.name)
150
- logger.debug(f'Saved Spreadsheet Path: {self.excelPath}\n')
185
+ logger.debug(f"Saved Spreadsheet Path: {self.excelPath}\n")
151
186
  self.setStatus("[OK] Excel Tabelle wurde eingelesen")
152
187
  return None
153
188
 
154
-
155
189
  @QtCore.Slot()
156
- def onParseAll (self)->None:
190
+ def onParseAll(self) -> None:
157
191
  """Event triggered by the *Tools/Parse all Questions* Event
158
192
 
159
193
  It parses all the Questions found in the spreadsheet and then refreshes the list of questions.
@@ -164,23 +198,24 @@ class MainWindow(QtWidgets.QMainWindow):
164
198
  self.setStatus("[OK] Alle Fragen wurden erfolgreich in XML-Dateien umgewandelt")
165
199
  # below is former refres method
166
200
  logger.info("starting List refresh")
167
- cats = self.testDB.categories
201
+ cats = self.testDB.categories
168
202
  self.ui.treeWidget.clear()
169
203
  for cat in cats.values():
170
- catItem = CategoryItem(self.ui.treeWidget,cat)
204
+ catItem = CategoryItem(self.ui.treeWidget, cat)
171
205
  catItem.setFlags(catItem.flags() & ~Qt.ItemIsSelectable)
172
206
  for q in cat.questions.values():
173
- QuestionItem(catItem,q)
207
+ QuestionItem(catItem, q)
174
208
  self.setStatus("[OK] Fragen Liste wurde aktualisiert")
175
209
  return None
176
210
 
177
211
  @QtCore.Slot()
178
- def previewQ(self)->None:
212
+ def previewQ(self) -> None:
179
213
  item = self.ui.treeWidget.currentItem()
180
214
  if isinstance(item, QuestionItem):
181
215
  dialog = dialogs.QuestinoPreviewDialog(self, item.getQuestion())
182
216
  dialog.show()
183
- else: logger.info(f"current Item is not a Question, can't preview")
217
+ else:
218
+ logger.info(f"current Item is not a Question, can't preview")
184
219
 
185
220
  def setStatus(self, status):
186
221
  self.ui.statusbar.clearMessage()
@@ -200,26 +235,35 @@ class EqCheckerWindow(QtWidgets.QWidget):
200
235
  self.excelFile = Path()
201
236
  self.ui = Ui_EquationChecker()
202
237
  self.ui.setupUi(self)
203
- self.ui.buttonRunCheck.clicked.connect(lambda: self.onButRunCheck(self.ui.catNumber.value(), self.ui.qNumber.value()))
238
+ self.ui.buttonRunCheck.clicked.connect(
239
+ lambda: self.onButRunCheck(
240
+ self.ui.catNumber.value(), self.ui.qNumber.value()
241
+ )
242
+ )
204
243
 
205
- def onButRunCheck(self, catN:int, qN:int)->None:
244
+ def onButRunCheck(self, catN: int, qN: int) -> None:
206
245
  """
207
246
  Is Triggered by the ``Run Check now`` Button and runs the Equation Check
208
247
  """
209
-
248
+
210
249
  self.ui.textResultsOutput.clear()
211
- bullets, results, firstResult = eqVerif.equationChecker(f'KAT_{catN}',qN, self.excelFile)
250
+ bullets, results, firstResult = eqVerif.equationChecker(
251
+ f"KAT_{catN}", qN, self.excelFile
252
+ )
212
253
  check = False
213
- self.ui.lineFirstResult.setText(f'{firstResult}')
254
+ self.ui.lineFirstResult.setText(f"{firstResult}")
214
255
  for i, calculation in enumerate(results):
215
- if i == 0 and firstResult !=0:
256
+ if i == 0 and firstResult != 0:
216
257
  check = eqVerif.checkResult(firstResult, calculation)
217
- self.ui.lineCalculatedRes.setText(f'{calculation}')
218
- self.ui.textResultsOutput.append(f"Ergebnis {i+1}: \t{calculation}\n\tMit den Werten: \n{bullets[i]}\n")
258
+ self.ui.lineCalculatedRes.setText(f"{calculation}")
259
+ self.ui.textResultsOutput.append(
260
+ f"Ergebnis {i+1}: \t{calculation}\n\tMit den Werten: \n{bullets[i]}\n"
261
+ )
219
262
 
220
263
  if check == True:
221
264
  self.ui.lineCheckResult.setText("[OK]")
222
- logger.info(f"Das erste berechnete Ergebnis stimmt mit dem Wert in 'firstResult' überein\n")
265
+ logger.info(
266
+ f"Das erste berechnete Ergebnis stimmt mit dem Wert in 'firstResult' überein\n"
267
+ )
223
268
  else:
224
269
  self.ui.lineCheckResult.setText("[ERROR]")
225
-
@@ -1,16 +1,17 @@
1
- """This Module hosts the various Dialog Classes, that can be shown from main Window
2
- """
3
- from PySide6 import QtWidgets, QtGui
1
+ """This Module hosts the various Dialog Classes, that can be shown from main Window"""
2
+
4
3
  import lxml.etree as ET
4
+ from PySide6 import QtGui, QtWidgets
5
5
  from PySide6.QtSvgWidgets import QGraphicsSvgItem
6
6
 
7
+ from excel2moodle.core.globals import XMLTags
7
8
  from excel2moodle.core.question import Question
8
- from excel2moodle.ui.variantDialog import Ui_Dialog
9
9
  from excel2moodle.ui.questionPreviewDialog import Ui_QuestionPrevDialog
10
+ from excel2moodle.ui.variantDialog import Ui_Dialog
10
11
 
11
12
 
12
13
  class QuestionVariantDialog(QtWidgets.QDialog):
13
- def __init__(self, parent, question:Question):
14
+ def __init__(self, parent, question: Question):
14
15
  super().__init__(parent)
15
16
  self.setWindowTitle("Question Variant Dialog")
16
17
  self.maxVal = question.variants
@@ -31,7 +32,7 @@ class QuestionVariantDialog(QtWidgets.QDialog):
31
32
 
32
33
 
33
34
  class QuestinoPreviewDialog(QtWidgets.QDialog):
34
- def __init__(self, parent: QtWidgets.QWidget, question:Question) -> None:
35
+ def __init__(self, parent: QtWidgets.QWidget, question: Question) -> None:
35
36
  super().__init__(parent)
36
37
  self.question = question
37
38
  self.ui = Ui_QuestionPrevDialog()
@@ -39,42 +40,58 @@ class QuestinoPreviewDialog(QtWidgets.QDialog):
39
40
  self.setWindowTitle(f"Question - {question.id} - Preview")
40
41
  self.setupQuestion()
41
42
 
42
- def setupQuestion(self)->None:
43
+ def setupQuestion(self) -> None:
43
44
  self.ui.qNameLine.setText(self.question.name)
44
45
  self.ui.qTypeLine.setText(self.question.qtype)
45
46
  self.setText()
46
47
  self.setAnswers()
47
48
  self.setPicture()
48
49
 
49
- def setPicture(self)->None:
50
+ def setPicture(self) -> None:
50
51
  if hasattr(self.question, "picture") and self.question.picture.ready:
51
52
  self.picScene = QtWidgets.QGraphicsScene(self)
52
53
  self.ui.graphicsView.setScene(self.picScene)
53
54
  path = self.question.picture.path
54
- if path.suffix =='.svg':
55
+ if path.suffix == ".svg":
55
56
  picItem = QGraphicsSvgItem(str(self.question.picture.path))
56
57
  else:
57
58
  pic = QtGui.QPixmap(self.question.picture.path)
58
59
  aspRat = pic.height() // pic.width()
59
60
  width = 400
60
61
  scaleHeight = aspRat * width
61
- picItem = QtWidgets.QGraphicsPixmapItem(pic.scaled(width, scaleHeight, QtGui.Qt.AspectRatioMode.KeepAspectRatio))
62
+ picItem = QtWidgets.QGraphicsPixmapItem(
63
+ pic.scaled(
64
+ width, scaleHeight, QtGui.Qt.AspectRatioMode.KeepAspectRatio
65
+ )
66
+ )
62
67
  self.picScene.addItem(picItem)
63
68
  else:
64
69
  self.ui.graphicsView.setFixedHeight(1)
65
70
 
66
- def setText(self)->None:
71
+ def setText(self) -> None:
67
72
  t = []
68
- for text in self.question.qtextElements:
69
- t.append(ET.tostring(text, encoding='unicode'))
70
-
73
+ for text in self.question.qtextParagraphs:
74
+ t.append(ET.tostring(text, encoding="unicode"))
75
+ if self.question.bulletList is not None:
76
+ t.append(ET.tostring(self.question.bulletList, encoding="unicode"))
71
77
  self.ui.questionText.setText("\n".join(t))
72
78
 
73
- def setAnswers(self)->None:
79
+ def setAnswers(self) -> None:
74
80
  if self.question.qtype == "NFM":
75
- for i,ans in enumerate(self.question.answerVariants):
76
- a = ans.find('text').text
77
- text = QtWidgets.QLineEdit(a, self )
78
- self.ui.answersFormLayout.addRow(f'Answer {i+1}', text)
81
+ for i, ans in enumerate(self.question.answerVariants):
82
+ a = ans.find("text").text
83
+ text = QtWidgets.QLineEdit(a, self)
84
+ self.ui.answersFormLayout.addRow(f"Answer {i+1}", text)
79
85
 
86
+ elif self.question.qtype == "NF":
87
+ ans = self.question.element.find(XMLTags.ANSWER)
88
+ a = ans.find("text").text
89
+ text = QtWidgets.QLineEdit(a, self)
90
+ self.ui.answersFormLayout.addRow(f"Result", text)
80
91
 
92
+ elif self.question.qtype == "MC":
93
+ for i, ans in enumerate(self.question.element.findall(XMLTags.ANSWER)):
94
+ a = ans.find("text").text
95
+ frac = ans.get("fraction")
96
+ text = QtWidgets.QLineEdit(a, self)
97
+ self.ui.answersFormLayout.addRow(f"Fraction: {frac}", text)
@@ -1,34 +1,72 @@
1
- from PySide6.QtCore import QSettings, QTimer, Signal
2
1
  from pathlib import Path
3
2
 
3
+ from PySide6.QtCore import QSettings, QTimer, Signal
4
+
5
+
4
6
  class Settings(QSettings):
5
7
  shPathChanged = Signal(Path)
8
+
6
9
  def __init__(self):
7
10
  super().__init__("jbosse3", "excel2moodle")
8
- if self.contains("spreadsheet"):
9
- self.sheet = self.value("spreadsheet")
11
+ if self.contains("core/spreadsheet"):
12
+ self.sheet = self.value("core/spreadsheet")
10
13
  try:
11
14
  self.sheet.resolve(strict=True)
12
15
  if self.sheet.is_file():
13
- QTimer.singleShot(0,self._emitSpreadsheetChanged)
16
+ QTimer.singleShot(0, self._emitSpreadsheetChanged)
14
17
  except Exception:
15
18
  return None
19
+ self.ensureSettings()
16
20
 
17
- def _emitSpreadsheetChanged(self)->None:
21
+ def ensureSettings(self) -> None:
22
+ """Makes sure all necessary settings are made
23
+
24
+ if not yet inside the settings file, they will be appended
25
+ """
26
+ print("setting necessary settings")
27
+
28
+ if not self.contains("parser/nf/tolerance"):
29
+ self.setValue("parser/nf/tolerance", 1)
30
+
31
+ if not self.contains("core/pictureSubFolder"):
32
+ self.set("core/pictureSubFolder", "Abbildungen_SVG")
33
+
34
+ def _emitSpreadsheetChanged(self) -> None:
18
35
  self.shPathChanged.emit(self.sheet)
19
36
  print("Emitting Spreadsheet Changed Event")
20
37
 
21
-
22
38
  def get(self, value, default=None):
23
- self.value(value, default)
39
+ return self.value(value, default)
24
40
 
25
41
  def set(self, setting, value):
26
42
  self.setValue(setting, value)
27
43
 
28
- def setSpreadsheet(self, sheet:Path)->None:
44
+ def parserSet(self, setting, value) -> None:
45
+ self.beginGroup("parser")
46
+ self.setValue(setting, value)
47
+ self.endGroup()
48
+
49
+ def nfParserSet(self, setting, value) -> None:
50
+ self.beginGroup("parser")
51
+ self.setValue(setting, value)
52
+ self.endGroup()
53
+
54
+ def parserGet(self, value, default=None, **kwargs):
55
+ self.beginGroup("parser")
56
+ return self.value(value, default, **kwargs)
57
+
58
+ def testgenSet(self, setting, value) -> None:
59
+ self.beginGroup("testGen")
60
+ self.setValue(setting, value)
61
+ self.endGroup()
62
+
63
+ def testgenGet(self, value, default=None):
64
+ self.beginGroup("testGen")
65
+ return self.value(value, default)
66
+
67
+ def setSpreadsheet(self, sheet: Path) -> None:
29
68
  if isinstance(sheet, Path):
30
69
  self.sheet = sheet.resolve(strict=True)
31
- self.setValue("spreadsheet", self.sheet)
70
+ self.setValue("core/spreadsheet", self.sheet)
32
71
  self.shPathChanged.emit(sheet)
33
72
  return None
34
-
@@ -1,11 +1,11 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: excel2moodle
3
- Version: 0.3.2
4
- Summary: A Package for Converting Questions input into a spreadsheet, to valid moodle-xml
3
+ Version: 0.3.4
4
+ Summary: A package for converting questions from a spreadsheet, to valid moodle-xml
5
5
  Author: Jakob Bosse
6
6
  License-Expression: GPL-3.0-or-later
7
- Project-URL: Homepage, https://gitlab.com/jbosse3/excel2moodle
8
- Project-URL: documentation, https://jbosse3.gitlab.io/excel2moodle
7
+ Project-URL: Repository, https://gitlab.com/jbosse3/excel2moodle.git
8
+ Project-URL: Documentation, https://jbosse3.gitlab.io/excel2moodle
9
9
  Keywords: moodle,XML,teaching,question,converter
10
10
  Classifier: Programming Language :: Python :: 3
11
11
  Classifier: Operating System :: OS Independent
@@ -15,8 +15,9 @@ License-File: LICENSE
15
15
  Requires-Dist: pyside6>=6.8.0
16
16
  Requires-Dist: pandas>=2.1.3
17
17
  Requires-Dist: openpyxl>=3.1.5
18
- Requires-Dist: asteval
19
- Requires-Dist: odfpy
18
+ Requires-Dist: lxml>=5.4.0
19
+ Requires-Dist: odfpy>=1.4.1
20
+ Requires-Dist: asteval>=1.0.6
20
21
  Dynamic: license-file
21
22
 
22
23
  # excel 2 Moodle
@@ -0,0 +1,32 @@
1
+ excel2moodle/__init__.py,sha256=LAJas1vxu_JirKDM5b1Jp11SkA7BRei61dk-SrqJg8g,4249
2
+ excel2moodle/__main__.py,sha256=8o3KK_RDgyTNW05cRL_iiu7BBHbIqWX9H878eHvf9Ag,544
3
+ excel2moodle/core/__init__.py,sha256=E7smxf7ESHlucvho4Gb5oaTHA7IsOv9J-UDIsoKwp84,399
4
+ excel2moodle/core/category.py,sha256=p1Njl9QGBdc_5GPCZ7DJbHxNSP-eI0CH7oevkW69jXc,3005
5
+ excel2moodle/core/dataStructure.py,sha256=xz_tQcLCAXRHEl-8U4fjEQVNKlLyPiH4x_90QXgKLsM,6922
6
+ excel2moodle/core/etHelpers.py,sha256=3ZYrYomaPax5uXnG4i4aCTeyF9szMbkJVS5-RPabEZQ,2343
7
+ excel2moodle/core/exceptions.py,sha256=M1iItmJFF1UzCdOBgYseB_fze76UXKWocmxK9_YtDC4,740
8
+ excel2moodle/core/globals.py,sha256=w_KfucRD8uIffilx0nJCtQSokZEBnxorkge_RPjd3XI,3679
9
+ excel2moodle/core/numericMultiQ.py,sha256=nuNZugvH6FSU36eyWTqqKz7y6unE34FOGePpZ8K_Iz8,2721
10
+ excel2moodle/core/parser.py,sha256=oVUBWlRSYI27OtncE_dvTbbAKRUq8VrtKncgNmUMI1Y,14577
11
+ excel2moodle/core/question.py,sha256=yM8E2bhfkydwGSb6CTEd3lNtFo8ynIzKUGuq7BkMW2s,6306
12
+ excel2moodle/core/questionValidator.py,sha256=0LqA5VVdlm4OXb753kRD8ADtcVpP5Id4P9DAeelvfLY,4694
13
+ excel2moodle/core/questionWriter.py,sha256=kyUTrnjWrLEWdez5_7FPNJ0Cs_fF5d16oOQiVvHv3zA,10242
14
+ excel2moodle/core/stringHelpers.py,sha256=26pqaqtwE10MwKbrN7QcLEfGLJu71aCu0mi0YIigCxY,3251
15
+ excel2moodle/extra/__init__.py,sha256=PM-id60HD21A3IcGC_fCYFihS8osBGZMIJCcN-ZRsIM,293
16
+ excel2moodle/extra/equationVerification.py,sha256=pozULgIiTuHUB3fBkgugfJdoaZGMcy6WTrw_wL3sHO4,4398
17
+ excel2moodle/ui/__init__.py,sha256=4EdGtpzwH3rgw4xW9E5x9kdPQYwKbo9rehHRZTNxCrQ,44
18
+ excel2moodle/ui/appUi.py,sha256=AE_Kob-ddawVfIWDAJWoymT9dB8hN0kmb-9yGXWMrF8,10519
19
+ excel2moodle/ui/dialogs.py,sha256=ye17B_jJcLwUCxrgnUDsSekip2lvNFFUAmFWqqizJdM,3821
20
+ excel2moodle/ui/questionPreviewDialog.py,sha256=_rJvz1GM90aNnj3P6SugEezK7JW6m74ZALgkChohWLM,4980
21
+ excel2moodle/ui/settings.py,sha256=JOGtjUrM5dKpMjzGR4fCH90yTHgStiBHhrICRGQgssc,2305
22
+ excel2moodle/ui/treewidget.py,sha256=xiYWhJeJ9o9Iubtr44HcyJas9v4m8aBsHNdokQAHi80,2357
23
+ excel2moodle/ui/variantDialog.py,sha256=snVaF3_YAc7NWjMRg7NzbjL_PzNbOpt4eiqElkE46io,5414
24
+ excel2moodle/ui/windowDoc.py,sha256=IciZpwrLnGzIQV1aCdKQBg6km3oufHGs8havTFzNJyU,1055
25
+ excel2moodle/ui/windowEquationChecker.py,sha256=fLyal3sbJwpthWCAxLB5vbSFOX23JoivoYksNp3mZVY,7925
26
+ excel2moodle/ui/windowMain.py,sha256=sB1ahkAwxFxO3EYP3X_MuB6ohgXwK5NUQHWeFo4eqrI,21062
27
+ excel2moodle-0.3.4.dist-info/licenses/LICENSE,sha256=ywQqe6Sitymkf2lV2NRcx_aGsaC-KbSl_EfEsRXmNRw,35135
28
+ excel2moodle-0.3.4.dist-info/METADATA,sha256=BB871FJP7X3BAUgxKM-7Jk9afnpKb1rVp9b1BBaDEu8,2945
29
+ excel2moodle-0.3.4.dist-info/WHEEL,sha256=SmOxYU7pzNKBqASvQJ7DjX3XGUF92lrGhMb3R6_iiqI,91
30
+ excel2moodle-0.3.4.dist-info/entry_points.txt,sha256=myfMLDThuGgWHMJDPPfILiZqo_7D3fhmDdJGqWOAjPw,60
31
+ excel2moodle-0.3.4.dist-info/top_level.txt,sha256=5V1xRUQ9o7UmOCmNoWCZPAuy5nXp3Qbzyqch8fUGT_c,13
32
+ excel2moodle-0.3.4.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (78.1.0)
2
+ Generator: setuptools (79.0.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ excel2moodle = excel2moodle.__main__:main
@@ -1,31 +0,0 @@
1
- excel2moodle/__init__.py,sha256=nb37g9Zga4KqTA5r-GFei9_XCunoPESxww9BL8zzMBI,3841
2
- excel2moodle/__main__.py,sha256=yLls1C3w070wtrrRl3_HXs5TNaO8l0yRDGtIAcHmeDk,695
3
- excel2moodle/core/__init__.py,sha256=E7smxf7ESHlucvho4Gb5oaTHA7IsOv9J-UDIsoKwp84,399
4
- excel2moodle/core/category.py,sha256=6U10HgQQVi0BYO28XrsLbYFqr0GbxEN9U2-fPDTM1Ng,4149
5
- excel2moodle/core/dataStructure.py,sha256=8cLqGZLhHRscohrstvsYARWvKekGAfdoMV1zWuUpHCA,6200
6
- excel2moodle/core/etHelpers.py,sha256=_fd-fGMVNWt1l8FY7xcA2uXOBahxtq8ggYxRYm4SwdA,2354
7
- excel2moodle/core/exceptions.py,sha256=3OLVHMCBgETiOxSsirlsCPvlMN5UgEQcMkRDkCfrUs4,675
8
- excel2moodle/core/globals.py,sha256=9V9-KBSsHMdsRZWg2wGrvjAd6dc3XZG4pNPnun0AHGE,3595
9
- excel2moodle/core/numericMultiQ.py,sha256=InBrn-tsCCYwDb78sGR3FyFxVeN0GfIg63JGtr_tqg4,2751
10
- excel2moodle/core/parser.py,sha256=ruSFHKjwpXggaETrtsUBdZK1BENCe2wppmOLdpKrAAs,13455
11
- excel2moodle/core/question.py,sha256=4mbzy6ZodvdM5QfBZltR950BmMdXqSBe9V7HBLZMewM,4198
12
- excel2moodle/core/questionValidator.py,sha256=6leCAvMFOieiVJtQEYx4iihiaKuuSBlCpBkpqbzKa3M,4139
13
- excel2moodle/core/questionWriter.py,sha256=kyUTrnjWrLEWdez5_7FPNJ0Cs_fF5d16oOQiVvHv3zA,10242
14
- excel2moodle/core/stringHelpers.py,sha256=c92YYFluZ6-NIM7K1k0SzN_zB82hh3huNZMH0NnlDLg,3009
15
- excel2moodle/extra/__init__.py,sha256=e70OmuW3j7N4ErIIHlK4vkmCKcpRbitJCdJvzjego8c,339
16
- excel2moodle/extra/equationVerification.py,sha256=FOvVBQZ357fbA5nYkHjvvWWVP3pQpo4RK3H7vru9v3A,4278
17
- excel2moodle/ui/__init__.py,sha256=4EdGtpzwH3rgw4xW9E5x9kdPQYwKbo9rehHRZTNxCrQ,44
18
- excel2moodle/ui/appUi.py,sha256=gWLJ3vU-KcHAz0HQXrOk2hGi3LD_8SSC5aPVEpayMEA,9518
19
- excel2moodle/ui/dialogs.py,sha256=C58PzPLfkzglsRl-x8Y23TC08_JG03JgFCVFfEi_od8,2961
20
- excel2moodle/ui/questionPreviewDialog.py,sha256=_rJvz1GM90aNnj3P6SugEezK7JW6m74ZALgkChohWLM,4980
21
- excel2moodle/ui/settings.py,sha256=Zz4zxdGC55Ma6pB1HWdPdiAsN0fnqrPfgOFgSkVnKNA,1092
22
- excel2moodle/ui/treewidget.py,sha256=xiYWhJeJ9o9Iubtr44HcyJas9v4m8aBsHNdokQAHi80,2357
23
- excel2moodle/ui/variantDialog.py,sha256=snVaF3_YAc7NWjMRg7NzbjL_PzNbOpt4eiqElkE46io,5414
24
- excel2moodle/ui/windowDoc.py,sha256=IciZpwrLnGzIQV1aCdKQBg6km3oufHGs8havTFzNJyU,1055
25
- excel2moodle/ui/windowEquationChecker.py,sha256=fLyal3sbJwpthWCAxLB5vbSFOX23JoivoYksNp3mZVY,7925
26
- excel2moodle/ui/windowMain.py,sha256=sB1ahkAwxFxO3EYP3X_MuB6ohgXwK5NUQHWeFo4eqrI,21062
27
- excel2moodle-0.3.2.dist-info/licenses/LICENSE,sha256=ywQqe6Sitymkf2lV2NRcx_aGsaC-KbSl_EfEsRXmNRw,35135
28
- excel2moodle-0.3.2.dist-info/METADATA,sha256=f_TnbqQEmg8wy6WuvMuYOTd8u_-h5qw4aKADlcvtzsM,2904
29
- excel2moodle-0.3.2.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
30
- excel2moodle-0.3.2.dist-info/top_level.txt,sha256=5V1xRUQ9o7UmOCmNoWCZPAuy5nXp3Qbzyqch8fUGT_c,13
31
- excel2moodle-0.3.2.dist-info/RECORD,,