diff --git a/Scripts/Python/Library/gquiz.py b/Scripts/Python/Library/gquiz.py
index b96822d..cde4489 100644
--- a/Scripts/Python/Library/gquiz.py
+++ b/Scripts/Python/Library/gquiz.py
@@ -23,6 +23,9 @@ class gquiz:
self.form_service = None
self.drive_service = None
self.main_form = None
+ self.infoPrint = self._defaultPrint
+ self.progress = -1
+ self.resultUri = ""
self.submition["requests"].append({
"updateSettings": {
@@ -35,6 +38,14 @@ class gquiz:
}
})
+ def setProgress(self, i : int):
+ self.progress = i
+ def AttachProcessInfo(self, callback):
+ self.infoPrint = callback
+
+ def _defaultPrint(self, text : str, progress: int):
+ print("{}% {}".format(progress, text))
+
def generateService(self):
''' Start Tokenizing
here is the way to get token
@@ -52,19 +63,23 @@ class gquiz:
# time.
if os.path.exists('token.json'):
creds = Credentials.from_authorized_user_file('token.json', SCOPES)
+ self.infoPrint("token already exist",self.progress)
# If there are no (valid) credentials available, let the user log in.
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
+ self.infoPrint("refresh token",self.progress)
else:
flow = InstalledAppFlow.from_client_secrets_file(
'./secret/client_secrets.json', SCOPES)
creds = flow.run_local_server(port=0)
+ self.infoPrint("generate token",self.progress)
# Save the credentials for the next run
with open('token.json', 'w') as token:
token.write(creds.to_json())
try:
+ self.infoPrint("creating service",self.progress)
service = build('docs', 'v1', credentials=creds)
self.form_service, self.drive_service = \
build('forms', 'v1', credentials=creds, discoveryServiceUrl=DISCOVERY_DOC, static_discovery=False),\
@@ -81,6 +96,7 @@ class gquiz:
name : name form
"""
try:
+ self.infoPrint("creating form",self.progress)
self.main_form = self.form_service.forms().create(body={"info":{"title":name}}).execute()
except HttpError as error:
print('An error occurred: %s' % error)
@@ -120,13 +136,15 @@ class gquiz:
}
}}
'''
+ self.infoPrint("creating option",self.progress)
opt = {"value" : "{}".format(value)}
if(image != None):
- print("print with image, uploading... ")
+ self.infoPrint("uploading option image... ",self.progress)
req = requests.post(self.image_temp_service_url,files={"file": open(image,'rb')})
if(req.json()['status'] == 'error'):
raise Exception("upload failed : {}".format(req.json()))
- print("success")
+ time.sleep(3)
+ self.infoPrint("uploading option image... ok",self.progress)
u = urlparse(req.json()['data']['url'])
opt.update({"image" : {
"sourceUri": u._replace(path="/dl"+u.path).geturl(),
@@ -168,12 +186,14 @@ class gquiz:
}
}
}
+ self.infoPrint("create question...",self.progress)
if (itemImage != None):
- print("uploading image for quesiton : ")
+ self.infoPrint("uploading question image...",self.progress)
req = requests.post(self.image_temp_service_url,files={"file": open(itemImage,'rb')})
if(req.json()['status'] == 'error'):
raise Exception("upload failed : {}".format(req.json()))
- print("succes")
+ time.sleep(3)
+ self.infoPrint("uploading question image... ok",self.progress)
u = urlparse(req.json()['data']['url'])
item['questionItem'].update(\
{"image": {
@@ -183,7 +203,6 @@ class gquiz:
}
}
})
- time.sleep(3)
return item
def submitQuestion(self, index, item):
@@ -198,14 +217,18 @@ class gquiz:
"item": item
}
})
+ self.infoPrint("submit question",self.progress)
print(self.submition)
def update(self):
+ self.infoPrint("Updating Form...",self.progress)
# Adds the question to the form
question_setting = self.form_service.forms().batchUpdate(formId=self.main_form["formId"], body=self.submition).execute()
print(question_setting)
# Prints the result to show the question has been added
get_result = self.form_service.forms().get(formId=self.main_form["formId"]).execute()
+ self.resultUri = get_result['responderUri']
print(get_result)
+ self.infoPrint("Updating Form... Done",self.progress)
diff --git a/Scripts/Python/Library/moodleQuiz.py b/Scripts/Python/Library/moodleQuiz.py
new file mode 100644
index 0000000..850821c
--- /dev/null
+++ b/Scripts/Python/Library/moodleQuiz.py
@@ -0,0 +1,87 @@
+# coding: utf-8
+from __future__ import unicode_literals
+import base64
+import xml.etree.ElementTree as ET
+
+class moodleQuiz:
+ def __init__(self):
+ self.infoPrint = self._defaultPrint
+ self.progress = -1
+ self.resultUri = ""
+ self.data = ET.Element('quiz')
+
+ def setProgress(self, i : int):
+ self.progress = i
+ self.infoPrint("generating...", self.progress)
+
+ def AttachProcessInfo(self, callback):
+ self.infoPrint = callback
+
+ def _defaultPrint(self, text : str, progress: int):
+ print("{}% {}".format(progress, text))
+
+ def _subElementFile(self, parent, file):
+ Efile = ET.SubElement(parent, "file")
+ Efile.set('name',file.name.split("/").pop())
+ Efile.set('path','/')
+ Efile.set('encoding','base64')
+ Efile.text = base64.b64encode(file.read()).decode('utf-8')
+
+ def createOption(self, value, image=None):
+ ans = ET.Element('answer')
+ ans.set('fraction', '0')
+ ans.set('format', 'html')
+ if(image == None):
+ ET.SubElement(ans, 'text').text = "
{}
".format(value)
+ else :
+ f = open(image,"rb")
+ ET.SubElement(ans, 'text').text = "" + \
+ "
"\
+ .format(f.name.split("/").pop(), f.name.split("/").pop().split(".")[0])
+ self._subElementFile(ans, f)
+ ET.SubElement(ET.SubElement(ans,'feedback'), 'text').text = "Ooopss!"
+ return ans
+
+
+ def createQuestion(self, title, description, options, indexAnswer, itemImage=None):
+ question = ET.Element('question')
+ question.set('type','multichoice')
+
+ ET.SubElement(ET.SubElement(question, 'name'), 'text')\
+ .text = title
+
+ descQuestion = ET.SubElement(question, 'questiontext')
+ descQuestion.set('format', 'html')
+ descText = ET.SubElement(descQuestion, 'text')
+ descText.text = "{}
".format(description)
+
+ if (itemImage != None):
+ f = open(itemImage,"rb")
+ descText.text = descText.text + "" + \
+ "
"\
+ .format(f.name.split("/").pop(), f.name.split("/").pop().split(".")[0])
+ self._subElementFile(descQuestion, f)
+
+ for i in range(0, len(options)):
+ ans = options[i]
+ if i == (indexAnswer-1) :
+ ans.set('fraction', '100')
+ ans.find('feedback').find('text').text = "YES!"
+ question.append(ET.fromstring(ET.tostring(ans)))
+
+ ET.SubElement(question, 'shuffleanswers').text = '0'
+ ET.SubElement(question, 'answernumbering').text = 'abc'
+ return question
+
+ def submitQuestion(self, index, item):
+ self.data.append(ET.fromstring(ET.tostring(item)))
+
+ def copyFile(self,origin_file_id, copy_title):
+ print("noting to copy, it for moodle")
+
+ def update(self):
+ ET.indent(self.data)
+ print(ET.tostring(self.data))
+ ET.ElementTree(self.data).write("./moodleXMLMultichoiceQuestion.xml")
+
+
diff --git a/Scripts/Python/quiz_generator.py b/Scripts/Python/quiz_generator.py
index ecf51e8..99ae0d2 100644
--- a/Scripts/Python/quiz_generator.py
+++ b/Scripts/Python/quiz_generator.py
@@ -1,70 +1,102 @@
# coding: utf-8
from __future__ import unicode_literals
import sys, os
+import requests
+import importlib
+
+# to run separatly from soffice
+# $ soffice --calc --accept="socket,host=localhost,port=2002;urp;StarOffice.ServiceManager"
# uncomemnt for run separatly from soffice
-#sys.path.append("/lib64/libreoffice/program/")
+# sys.path.append("/lib64/libreoffice/program/")
+
from scriptforge import ScriptForge, CreateScriptService
from unohelper import fileUrlToSystemPath
-# uncomemnt for run separatly from soffice
-#ScriptForge(hostname='localhost', port=2021)
-def generateTemplate():
- doc = CreateScriptService("Calc")
- basic = CreateScriptService("Basic")
- doc.SetArray(doc.CurrentSelection, \
- (("","
", \
- "", "
", "", \
- "", "
", "", \
- "", "
", "", \
- "", "
", "", \
- "", "
", "", ),))
-
-def updateQuestion():
-# strat comment for run separatly from soffice
- if not 'gquiz' in sys.modules:
+#[start] comment for run separatly from soffice
+if (not 'gquiz' in sys.modules) or (not 'moodleQuiz' in sys.modules):
doc = XSCRIPTCONTEXT.getDocument()
url = fileUrlToSystemPath('{}/{}'.format(doc.URL,'Scripts/python/Library'))
sys.path.insert(0, url)
-# end
- from gquiz import gquiz
- import requests
-
- doc = CreateScriptService("Calc")
- selctedCell = doc.CurrentSelection
-
- q = gquiz()
- q.generateService()
- q.createForm("Demo Soal")
- cwd = os.getcwd()
- for nrow in range(0, doc.LastRow(selctedCell)+1-doc.FirstRow(selctedCell)):
- item = doc.getValue(doc.Offset(doc.FirstCell(selctedCell),nrow,0,1,17))
- opt = []
- theAnswer = -1
- c = 1
-
- for o in range(2,17,3):
- if (item[o] == 1):
- theAnswer = c
- if (item[o+1] != ""):
- opt.append(q.createOption("{}. {}".format(chr(64+c),item[o+2]),cwd+item[o+1]))
- else:
- opt.append(q.createOption("{}. {}".format(chr(64+c),item[o+2])))
- c = c+1
-
- if (theAnswer == -1):
- raise Exception("Chose the correct answer")
+else:
+ importlib.reload(gquiz)
+ importlib.reload(moodleQuiz)
- if( item[1] != ""):
- img = cwd+item[1]
- else:
- img = None
-
- qq = q.createQuestion(title = "Soal No {}".format(nrow+1),\
- description = item[0],\
- indexAnswer = theAnswer, \
- options = opt, itemImage=img)
- q.submitQuestion(nrow,qq)
- q.update()
-
-g_exportedScripts = (generateTemplate, updateQuestion, )
+#[end]
+#[start] uncomemnt for run separatly from soffice
+#sys.path.insert(0, '{}/{}'.format(os.getcwd(),'Library'))
+#[end]
+
+from gquiz import gquiz
+from moodleQuiz import moodleQuiz
+
+ScriptForge(hostname='localhost', port=2002)
+ui = CreateScriptService("UI")
+doc = CreateScriptService("Calc")
+bas = CreateScriptService("Basic")
+
+def MakeTemplate():
+ doc.SetArray(doc.CurrentSelection, \
+ (("","
", \
+ "", "
", "", \
+ "", "
", "", \
+ "", "
", "", \
+ "", "
", "", \
+ "", "
", "", ),))
+
+def _statusBarInfoUpdate(text : str, progress : int):
+ ui.SetStatusbar("{}% {}".format(progress,text), progress)
+
+def _updateQuestion(q):
+ selctedCell = doc.CurrentSelection
+ cwd = os.getcwd()
+ maxRow = doc.LastRow(selctedCell)+1-doc.FirstRow(selctedCell)
+ for nrow in range(0, maxRow):
+ q.setProgress(int(((nrow+1)/maxRow)*100))
+ item = doc.getValue(doc.Offset(doc.FirstCell(selctedCell),nrow,0,1,17))
+ opt = []
+ theAnswer = -1
+ c = 1
+ for o in range(2,17,3):
+ if (item[o] == 1):
+ theAnswer = c
+ if (item[o+1] != ""):
+ opt.append(q.createOption("{}. {}".format(chr(64+c),item[o+2]),cwd+item[o+1]))
+ else:
+ opt.append(q.createOption("{}. {}".format(chr(64+c),item[o+2])))
+ c = c+1
+
+ if (theAnswer == -1):
+ raise Exception("Chose the correct answer")
+
+ if( item[1] != ""):
+ img = cwd+item[1]
+ else:
+ img = None
+
+ qq = q.createQuestion(title = "Soal No {}".format(nrow+1),\
+ description = item[0],\
+ indexAnswer = theAnswer, \
+ options = opt, itemImage=img)
+ q.submitQuestion(nrow,qq)
+ q.update()
+
+def GoogleQuiz():
+ q = gquiz()
+ q.AttachProcessInfo(_statusBarInfoUpdate)
+ q.setProgress(0)
+ q.generateService()
+ q.createForm("Demo Soal")
+ _updateQuestion(q)
+ ui.SetStatusbar("creating google form quiz done!")
+ bas.InputBox("Open link to edit your form:","Your Google Form Quiz, done!", "{}".format(q.resultUri))
+
+def MoodleQuiz():
+ q = moodleQuiz()
+ q.AttachProcessInfo(_statusBarInfoUpdate)
+ q.setProgress(0)
+ _updateQuestion(q)
+ ui.SetStatusbar("Done!")
+ bas.MsgBox("Check *.xml file in curent folder!")
+
+g_exportedScripts = (MakeTemplate, GoogleQuiz, MoodleQuiz)
diff --git a/Scripts/Python/test_gquiz.py b/Scripts/Python/test_gquiz.py
deleted file mode 100644
index c36fdc9..0000000
--- a/Scripts/Python/test_gquiz.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# coding: utf-8
-from __future__ import unicode_literals
-
-import sys, requests
-from unohelper import fileUrlToSystemPath
-
-def gquiz_test():
- if not 'gquiz' in sys.modules:
- doc = XSCRIPTCONTEXT.getDocument()
- url = fileUrlToSystemPath('{}/{}'.format(doc.URL,'Scripts/python/Library'))
- sys.path.insert(0, url)
- from gquiz import gquiz
-
- q = gquiz()
-
- q.generateService()
-
- q.copyFile("16-rh3W-NwYzdKVBZJmi574sTWe_rMIdE-FQSw_33qXI", "Soal Masuk Penjara")
- opt = [ q.createOption("A.","./asset/option1.png"),
- q.createOption("B.","./asset/option2.png"),
- q.createOption("C.","./asset/option3.png"),
- q.createOption("D.","./asset/option4.png"),
- q.createOption("E.","./asset/option5.png") ]
-
- qq = q.createQuestion(title = "Soal No 1",\
- description = "Dari gambar dibawah ini, ada bagian gambar yang hilang. Dari pilihan dibawah, manakah gambar yang benar?",\
- indexAnswer = 4, options = opt, itemImage='./asset/test_image.png')
- q.submitQuestion(0,qq)
- q.update()
diff --git a/Scripts/Python/test_quiz.py b/Scripts/Python/test_quiz.py
new file mode 100644
index 0000000..6db6933
--- /dev/null
+++ b/Scripts/Python/test_quiz.py
@@ -0,0 +1,33 @@
+# coding: utf-8
+from __future__ import unicode_literals
+
+import sys, requests, os
+from unohelper import fileUrlToSystemPath
+
+sys.path.insert(0, "{}/{}".format(os.getcwd(),"Library"))
+from gquiz import gquiz
+from moodleQuiz import moodleQuiz
+
+def test(q):
+ opt = [ q.createOption("A.","./asset/option1.png"),
+ q.createOption("B.","./asset/option2.png"),
+ q.createOption("C.","./asset/option3.png"),
+ q.createOption("D.","./asset/option4.png"),
+ q.createOption("E.","./asset/option5.png") ]
+ qq = q.createQuestion(title = "Soal No 1",\
+ description = "Dari gambar dibawah ini, ada bagian gambar yang hilang. Dari pilihan dibawah, manakah gambar yang benar?",\
+ indexAnswer = 4, options = opt, itemImage='./asset/test_image.png')
+ q.submitQuestion(0,qq)
+ q.update()
+
+os.system("mkdir asset && mkdir secret")
+os.system("cp ../../asset/* ./asset")
+os.system("cp ../../secret/client_secrets.json ./secret")
+
+q = moodleQuiz()
+test(q)
+
+q = gquiz()
+q.generateService()
+q.createForm("test")
+test(q)
diff --git a/myedu.ods b/myedu.ods
index 34919bf..eea9789 100644
Binary files a/myedu.ods and b/myedu.ods differ