excel2moodle 0.3.3__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,46 +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 import e2mMetadata
12
- from excel2moodle.ui.windowMain import Ui_MoodleTestGenerator
13
- from .windowEquationChecker import Ui_EquationChecker
14
- 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
15
14
  from excel2moodle.core.dataStructure import QuestionDB
16
- from excel2moodle.ui.treewidget import QuestionItem, CategoryItem
17
15
  from excel2moodle.extra import equationVerification as eqVerif
18
- from excel2moodle import qSignalLogger
16
+ from excel2moodle.ui import dialogs, windowEquationChecker
19
17
  from excel2moodle.ui.settings import Settings
20
- import logging as logging
18
+ from excel2moodle.ui.treewidget import CategoryItem, QuestionItem
19
+ from excel2moodle.ui.windowMain import Ui_MoodleTestGenerator
21
20
 
21
+ from .windowEquationChecker import Ui_EquationChecker
22
22
 
23
23
  logger = logging.getLogger(__name__)
24
24
 
25
25
 
26
-
27
26
  class MainWindow(QtWidgets.QMainWindow):
28
- def __init__(self, settings:Settings, testDB:QuestionDB)->None:
27
+ def __init__(self, settings: Settings, testDB: QuestionDB) -> None:
29
28
  super().__init__()
30
29
  self.settings = settings
31
- self.excelPath: Path|None = None
32
- 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
33
32
  self.exportFile = Path()
34
33
  self.testDB = testDB
35
34
  self.ui = Ui_MoodleTestGenerator()
36
35
  self.ui.setupUi(self)
37
36
 
38
37
  self.ui.treeWidget.setSelectionMode(QtWidgets.QAbstractItemView.MultiSelection)
39
- self.ui.treeWidget.header().setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents)
40
- self.ui.checkBoxIncludeCategories.setChecked(self.settings.value("testGen/includeCats", type=bool))
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
+ )
41
44
 
42
45
  self.ui.retranslateUi(self)
43
46
  logger.info(f"Settings are stored under: {self.settings.fileName()}")
44
47
  self.ui.pointCounter.setReadOnly(True)
45
48
  self.ui.questionCounter.setReadOnly(True)
46
- self.setStatus("Wählen Sie bitte eine Excel Tabelle und einen Export Ordner für die Fragen aus")
49
+ self.setStatus(
50
+ "Wählen Sie bitte eine Excel Tabelle und einen Export Ordner für die Fragen aus"
51
+ )
47
52
  try:
48
53
  self.resize(self.settings.value("windowSize"))
49
54
  self.move(self.settings.value("windowPosition"))
@@ -51,14 +56,18 @@ class MainWindow(QtWidgets.QMainWindow):
51
56
  pass
52
57
  self.connectEvents()
53
58
 
54
- def connectEvents(self)->None:
59
+ def connectEvents(self) -> None:
55
60
  self.ui.treeWidget.itemClicked.connect(self.onSelectionChanged)
56
- self.ui.checkBoxQuestionListSelectAll.checkStateChanged.connect(self.toggleQuestionSelectionState)
61
+ self.ui.checkBoxQuestionListSelectAll.checkStateChanged.connect(
62
+ self.toggleQuestionSelectionState
63
+ )
57
64
  qSignalLogger.emitter.signal.connect(self.updateLog)
58
65
  self.ui.actionEquationChecker.triggered.connect(self.onButOpenEqChecker)
59
- self.ui.checkBoxIncludeCategories.checkStateChanged.connect(self.setIncludeCategoriesSetting)
66
+ self.ui.checkBoxIncludeCategories.checkStateChanged.connect(
67
+ self.setIncludeCategoriesSetting
68
+ )
60
69
  # self.ui.buttonRefresh.clicked.connect(self.refreshList)
61
- self.ui.actionParseAll.triggered.connect(self.onParseAll )
70
+ self.ui.actionParseAll.triggered.connect(self.onParseAll)
62
71
  self.testDB.dataChanged.signal.connect(self.onParseAll)
63
72
  self.ui.buttonSpreadSheet.clicked.connect(self.onButSpreadsheet)
64
73
  self.ui.buttonTestGen.clicked.connect(self.onButGenTest)
@@ -66,26 +75,24 @@ class MainWindow(QtWidgets.QMainWindow):
66
75
  self.ui.actionAbout.triggered.connect(self.onAbout)
67
76
  self.settings.shPathChanged.connect(self.onSheetPathChanged)
68
77
 
69
-
70
78
  @QtCore.Slot(Path)
71
- def onSheetPathChanged(self, sheet:Path)->None:
79
+ def onSheetPathChanged(self, sheet: Path) -> None:
72
80
  logger.debug("Slot, new Spreadsheet triggered")
73
81
  self.spreadSheetPath = sheet
74
82
  self.mainPath = sheet.parent
75
83
  self.ui.buttonSpreadSheet.setText(str(sheet.name))
76
84
 
77
- def updateLog(self,log)->None:
85
+ def updateLog(self, log) -> None:
78
86
  self.ui.loggerWindow.append(log)
79
87
 
80
88
  def setIncludeCategoriesSetting(self):
81
89
  if self.ui.checkBoxIncludeCategories.isChecked():
82
- self.settings.set("testGen/includeCats", True)
90
+ self.settings.testgenSet("includeCats", True)
83
91
  logger.debug("set includeCats to True")
84
92
  else:
85
- self.settings.set("testGen/includeCats", False)
93
+ self.settings.testgenSet("includeCats", False)
86
94
  logger.debug("set includeCats to False")
87
95
 
88
-
89
96
  @QtCore.Slot()
90
97
  def onAbout(self):
91
98
  aboutMessage: str = f"""
@@ -94,27 +101,27 @@ class MainWindow(QtWidgets.QMainWindow):
94
101
 
95
102
  <b><a href="{e2mMetadata['homepage']}">{e2mMetadata['name']}</a> - {e2mMetadata['description']}</b>
96
103
  </p>
97
- <p style="text-align:center">
98
- The documentation can be found under <b><a href="{e2mMetadata['documentation']}">{e2mMetadata['documentation']}</a></b>
99
- </br>
100
- </br>
101
- If you encounter any issues please report them under the <a href="{e2mMetadata['issues']}"> repositories issues page</a>
104
+ <p style="text-align:center">
105
+ The documentation can be found under <b>
106
+ <a href="{e2mMetadata['documentation']}">{e2mMetadata['documentation']}</a></b>
102
107
  </br>
103
108
  </p>
104
109
  <p style="text-align:center">
105
110
  This project is maintained by {e2mMetadata['author']}.
106
111
  <br>
107
- Development takes place at <a href="{e2mMetadata['homepage']}">{e2mMetadata['homepage']}</a>
108
- Contributions are very welcome
109
- <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>
110
117
  </p>
111
118
  <p style="text-align:center">
112
119
  <i>This project is published under {e2mMetadata['license']}, you are welcome, to share, modify and reuse the code.</i>
113
120
  </p>
114
121
  """
115
- QtWidgets.QMessageBox.information(self,
116
- f"About {e2mMetadata['name']}",
117
- aboutMessage)
122
+ QtWidgets.QMessageBox.information(
123
+ self, f"About {e2mMetadata['name']}", aboutMessage
124
+ )
118
125
 
119
126
  def closeEvent(self, event):
120
127
  self.settings.setValue("windowSize", self.size())
@@ -131,7 +138,7 @@ class MainWindow(QtWidgets.QMainWindow):
131
138
  questions += 1
132
139
  count += q.getQuestion().points
133
140
 
134
- logger.info(f'{questions} questions are selected with {count} points')
141
+ logger.info(f"{questions} questions are selected with {count} points")
135
142
  self.ui.pointCounter.setValue(count)
136
143
  self.ui.questionCounter.setValue(questions)
137
144
  return None
@@ -140,7 +147,8 @@ class MainWindow(QtWidgets.QMainWindow):
140
147
  def toggleQuestionSelectionState(self, state):
141
148
  if state == Qt.Checked:
142
149
  setter = True
143
- else: setter = False
150
+ else:
151
+ setter = False
144
152
  root = self.ui.treeWidget.invisibleRootItem()
145
153
  childN = root.childCount()
146
154
  for i in range(childN):
@@ -149,32 +157,37 @@ class MainWindow(QtWidgets.QMainWindow):
149
157
  root.child(i).child(q).setSelected(setter)
150
158
 
151
159
  @QtCore.Slot()
152
- def onButGenTest(self)->None:
153
- path = QtWidgets.QFileDialog.getSaveFileName(self, "Select Output File",
154
- dir=f"{self.mainPath/"Testfile.xml"}",
155
- 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
+ )
156
168
  self.exportFile = Path(path[0])
157
169
  logger.info(f"New Export File is set{self.exportFile=}")
158
- selection:list[QuestionItem] = self.ui.treeWidget.selectedItems()
170
+ selection: list[QuestionItem] = self.ui.treeWidget.selectedItems()
159
171
  self.testDB.appendQuestions(selection, self.exportFile)
160
172
  return None
161
173
 
162
174
  @QtCore.Slot()
163
175
  def onButSpreadsheet(self):
164
- file = QtWidgets.QFileDialog.getOpenFileName(self,
165
- self.tr("Open Spreadsheet"),
166
- dir = str(self.mainPath),
167
- filter=self.tr("Spreadsheet(*.xlsx *.ods)"),
168
- 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
+ )
169
183
  self.excelPath = Path(file[0]).resolve()
170
184
  self.settings.setSpreadsheet(self.excelPath)
171
- logger.debug(f'Saved Spreadsheet Path: {self.excelPath}\n')
185
+ logger.debug(f"Saved Spreadsheet Path: {self.excelPath}\n")
172
186
  self.setStatus("[OK] Excel Tabelle wurde eingelesen")
173
187
  return None
174
188
 
175
-
176
189
  @QtCore.Slot()
177
- def onParseAll (self)->None:
190
+ def onParseAll(self) -> None:
178
191
  """Event triggered by the *Tools/Parse all Questions* Event
179
192
 
180
193
  It parses all the Questions found in the spreadsheet and then refreshes the list of questions.
@@ -185,23 +198,24 @@ class MainWindow(QtWidgets.QMainWindow):
185
198
  self.setStatus("[OK] Alle Fragen wurden erfolgreich in XML-Dateien umgewandelt")
186
199
  # below is former refres method
187
200
  logger.info("starting List refresh")
188
- cats = self.testDB.categories
201
+ cats = self.testDB.categories
189
202
  self.ui.treeWidget.clear()
190
203
  for cat in cats.values():
191
- catItem = CategoryItem(self.ui.treeWidget,cat)
204
+ catItem = CategoryItem(self.ui.treeWidget, cat)
192
205
  catItem.setFlags(catItem.flags() & ~Qt.ItemIsSelectable)
193
206
  for q in cat.questions.values():
194
- QuestionItem(catItem,q)
207
+ QuestionItem(catItem, q)
195
208
  self.setStatus("[OK] Fragen Liste wurde aktualisiert")
196
209
  return None
197
210
 
198
211
  @QtCore.Slot()
199
- def previewQ(self)->None:
212
+ def previewQ(self) -> None:
200
213
  item = self.ui.treeWidget.currentItem()
201
214
  if isinstance(item, QuestionItem):
202
215
  dialog = dialogs.QuestinoPreviewDialog(self, item.getQuestion())
203
216
  dialog.show()
204
- 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")
205
219
 
206
220
  def setStatus(self, status):
207
221
  self.ui.statusbar.clearMessage()
@@ -221,26 +235,35 @@ class EqCheckerWindow(QtWidgets.QWidget):
221
235
  self.excelFile = Path()
222
236
  self.ui = Ui_EquationChecker()
223
237
  self.ui.setupUi(self)
224
- 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
+ )
225
243
 
226
- def onButRunCheck(self, catN:int, qN:int)->None:
244
+ def onButRunCheck(self, catN: int, qN: int) -> None:
227
245
  """
228
246
  Is Triggered by the ``Run Check now`` Button and runs the Equation Check
229
247
  """
230
-
248
+
231
249
  self.ui.textResultsOutput.clear()
232
- 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
+ )
233
253
  check = False
234
- self.ui.lineFirstResult.setText(f'{firstResult}')
254
+ self.ui.lineFirstResult.setText(f"{firstResult}")
235
255
  for i, calculation in enumerate(results):
236
- if i == 0 and firstResult !=0:
256
+ if i == 0 and firstResult != 0:
237
257
  check = eqVerif.checkResult(firstResult, calculation)
238
- self.ui.lineCalculatedRes.setText(f'{calculation}')
239
- 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
+ )
240
262
 
241
263
  if check == True:
242
264
  self.ui.lineCheckResult.setText("[OK]")
243
- 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
+ )
244
268
  else:
245
269
  self.ui.lineCheckResult.setText("[ERROR]")
246
-
@@ -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
73
  for text in self.question.qtextParagraphs:
69
- t.append(ET.tostring(text, encoding='unicode'))
70
- t.append(ET.tostring(self.question.bulletList, encoding='unicode'))
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,8 +1,11 @@
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
11
  if self.contains("core/spreadsheet"):
@@ -10,26 +13,60 @@ class Settings(QSettings):
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()
20
+
21
+ def ensureSettings(self) -> None:
22
+ """Makes sure all necessary settings are made
16
23
 
17
- def _emitSpreadsheetChanged(self)->None:
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
39
  return self.value(value, default)
24
40
 
25
-
26
41
  def set(self, setting, value):
27
42
  self.setValue(setting, value)
28
43
 
29
- 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:
30
68
  if isinstance(sheet, Path):
31
69
  self.sheet = sheet.resolve(strict=True)
32
70
  self.setValue("core/spreadsheet", self.sheet)
33
71
  self.shPathChanged.emit(sheet)
34
72
  return None
35
-
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: excel2moodle
3
- Version: 0.3.3
3
+ Version: 0.3.4
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
@@ -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 (79.0.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=dsK3KrorPt06FUp18_dw2m4p9P8E7rFf9I0BR-4I28k,4263
2
- excel2moodle/__main__.py,sha256=SsulFcOSlRBF2tLTUIdFgB0EJdSLGBIQ_HO53S4Sih8,541
3
- excel2moodle/core/__init__.py,sha256=E7smxf7ESHlucvho4Gb5oaTHA7IsOv9J-UDIsoKwp84,399
4
- excel2moodle/core/category.py,sha256=rZsQW5-Ud182xCrS4R8B0vrPMrI-azwtfzlTdy89SR4,2982
5
- excel2moodle/core/dataStructure.py,sha256=h82r4wO2PhhHA4EqROjfkqWGUpg6UKQhkyrdjdisLxg,6343
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=0bLP_bkTFu3URw08sn1zJCvA3YCKxDAC4a6I14koHho,13408
11
- excel2moodle/core/question.py,sha256=zzdL_7BdWs0wUVl8-06gLkKu0Is3n0zU-2ZkaYhU504,5913
12
- excel2moodle/core/questionValidator.py,sha256=taOrrR6pd5mN7SGpET9eLOvb1v5NWvg_VgMj8opQlZ4,4791
13
- excel2moodle/core/questionWriter.py,sha256=kyUTrnjWrLEWdez5_7FPNJ0Cs_fF5d16oOQiVvHv3zA,10242
14
- excel2moodle/core/stringHelpers.py,sha256=9BqR7yx2bL8WknVMPuNlmWz05bgi4qWjFYHsgaftpZw,3141
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=TEqslEDExDOyYwCh7czg3YZggPdZewFiImbpzACLYLU,10533
19
- excel2moodle/ui/dialogs.py,sha256=5dnzRN9cwaxjJsxA7I9v1imH4k6XVzzievYi3PR32XI,3038
20
- excel2moodle/ui/questionPreviewDialog.py,sha256=_rJvz1GM90aNnj3P6SugEezK7JW6m74ZALgkChohWLM,4980
21
- excel2moodle/ui/settings.py,sha256=PB0uBMCd8DIRSFfvUAPs5hK4UEcb0y7dG9ZJ--kOvuQ,1115
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.3.dist-info/licenses/LICENSE,sha256=ywQqe6Sitymkf2lV2NRcx_aGsaC-KbSl_EfEsRXmNRw,35135
28
- excel2moodle-0.3.3.dist-info/METADATA,sha256=i7lC9k3j8ErKfWNnPAngdrnDAWIqC5V6egSB5uWivW8,2904
29
- excel2moodle-0.3.3.dist-info/WHEEL,sha256=pxyMxgL8-pra_rKaQ4drOZAegBVuX-G_4nRHjjgWbmo,91
30
- excel2moodle-0.3.3.dist-info/top_level.txt,sha256=5V1xRUQ9o7UmOCmNoWCZPAuy5nXp3Qbzyqch8fUGT_c,13
31
- excel2moodle-0.3.3.dist-info/RECORD,,