commit
						7233034920
					
				| 
						 | 
				
			
			@ -1,3 +1,3 @@
 | 
			
		|||
client_secrets.json
 | 
			
		||||
client_secret.json
 | 
			
		||||
token.json
 | 
			
		||||
__pycache__/
 | 
			
		||||
__pycache__/
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,102 +0,0 @@
 | 
			
		|||
# 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/")
 | 
			
		||||
 | 
			
		||||
from scriptforge import ScriptForge, CreateScriptService
 | 
			
		||||
from unohelper import fileUrlToSystemPath
 | 
			
		||||
 | 
			
		||||
#[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)
 | 
			
		||||
else:
 | 
			
		||||
    importlib.reload(gquiz)
 | 
			
		||||
    importlib.reload(moodleQuiz)
 | 
			
		||||
 | 
			
		||||
#[end]
 | 
			
		||||
#[start] uncomemnt for run separatly from soffice
 | 
			
		||||
#sys.path.insert(0, '{}/{}'.format(os.getcwd(),'Library'))
 | 
			
		||||
#ScriptForge(hostname='localhost', port=2002)
 | 
			
		||||
#[end]
 | 
			
		||||
 | 
			
		||||
from gquiz import gquiz
 | 
			
		||||
from moodleQuiz import moodleQuiz
 | 
			
		||||
 | 
			
		||||
ui = CreateScriptService("UI")
 | 
			
		||||
doc = CreateScriptService("Calc")
 | 
			
		||||
bas = CreateScriptService("Basic")
 | 
			
		||||
 | 
			
		||||
def MakeTemplate():
 | 
			
		||||
    doc.SetArray(doc.CurrentSelection, \
 | 
			
		||||
            (("<Text question>","<IMG question image>", \
 | 
			
		||||
            "<isAnswerA>", "<IMG option1>", "<Text Option1>",  \
 | 
			
		||||
            "<isAnswerB>", "<IMG option2>", "<Text Option2>",  \
 | 
			
		||||
            "<isAnswerC>", "<IMG option3>", "<Text Option3>",  \
 | 
			
		||||
            "<isAnswerD>", "<IMG option4>", "<Text Option4>",  \
 | 
			
		||||
            "<isAnswerE>", "<IMG option5>", "<Text Option5>", ),))
 | 
			
		||||
 | 
			
		||||
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)
 | 
			
		||||
| 
						 | 
				
			
			@ -1,33 +0,0 @@
 | 
			
		|||
# 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)
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,143 @@
 | 
			
		|||
# coding: utf-8
 | 
			
		||||
from __future__ import unicode_literals
 | 
			
		||||
 | 
			
		||||
import os.path, time
 | 
			
		||||
from google.auth.transport.requests import Request
 | 
			
		||||
from google.oauth2.credentials import Credentials
 | 
			
		||||
from google_auth_oauthlib.flow import InstalledAppFlow
 | 
			
		||||
from googleapiclient.discovery import build
 | 
			
		||||
from googleapiclient.errors import HttpError
 | 
			
		||||
from pprint import pprint
 | 
			
		||||
import requests
 | 
			
		||||
from urllib.parse import urlparse
 | 
			
		||||
 | 
			
		||||
class gdoc:
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        '''
 | 
			
		||||
        Args : 
 | 
			
		||||
            templateId : get the id from link GoogleForm
 | 
			
		||||
        '''
 | 
			
		||||
        self.image_temp_service_url = "https://tmpfiles.org/api/v1/upload"
 | 
			
		||||
        # self.image_temp_service_url = "https://uguu.se/upload.php"
 | 
			
		||||
        self.submition = {"requests":[]}
 | 
			
		||||
        self.docs_service = None
 | 
			
		||||
        self.main_docs = None
 | 
			
		||||
        self.infoPrint = self._defaultPrint
 | 
			
		||||
        self.progress = -1
 | 
			
		||||
        self.resultUri = ""
 | 
			
		||||
        self.savePath = './'
 | 
			
		||||
        self.questionKey = []
 | 
			
		||||
 | 
			
		||||
    def setProgress(self, i : int):
 | 
			
		||||
        self.progress = i
 | 
			
		||||
 | 
			
		||||
    def setSavePath(self, path):
 | 
			
		||||
        self.savePath = path
 | 
			
		||||
 | 
			
		||||
    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 
 | 
			
		||||
         link : https://developers.google.com/docs/api/quickstart/python
 | 
			
		||||
        '''
 | 
			
		||||
        SCOPES = ["https://www.googleapis.com/auth/documents",]
 | 
			
		||||
 | 
			
		||||
        creds = None
 | 
			
		||||
        # The file token.json stores the user's access and refresh tokens, and is
 | 
			
		||||
        # created automatically when the authorization flow completes for the first
 | 
			
		||||
        # 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(
 | 
			
		||||
                    self.savePath+'/secret/client_secret.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)
 | 
			
		||||
            self.docs_service = build('docs',   'v1', credentials=creds)
 | 
			
		||||
 | 
			
		||||
        except HttpError as err:
 | 
			
		||||
            print(err)
 | 
			
		||||
        ''' End Tokenizing
 | 
			
		||||
        '''
 | 
			
		||||
 | 
			
		||||
    def createDocs(self, name):
 | 
			
		||||
        try: 
 | 
			
		||||
            self.infoPrint("creating document",self.progress)
 | 
			
		||||
            self.main_docs = self.docs_service.documents().create(body={"title":name}).execute()
 | 
			
		||||
        except HttpError as error:
 | 
			
		||||
            print('An error occurred: %s' % error)			
 | 
			
		||||
 | 
			
		||||
    def createOption(self, value, image=None):
 | 
			
		||||
        self.infoPrint("creating option",self.progress)
 | 
			
		||||
        opttxt = "\t{}\r\n".format(value)
 | 
			
		||||
        opt = [{'insertText' : {
 | 
			
		||||
                'location':{ 'index': 1, },
 | 
			
		||||
                'text': opttxt }}]
 | 
			
		||||
        if(image != None):
 | 
			
		||||
            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()))
 | 
			
		||||
            time.sleep(3)
 | 
			
		||||
            self.infoPrint("uploading option image... ok",self.progress)
 | 
			
		||||
            u = urlparse(req.json()['data']['url'])
 | 
			
		||||
            opt.append( { 'insertInlineImage' : {
 | 
			
		||||
                    'uri' : u._replace(path="/dl"+u.path).geturl(),
 | 
			
		||||
	                'location' : { 'index' : len(opttxt)-1}}
 | 
			
		||||
            })
 | 
			
		||||
        return opt
 | 
			
		||||
 | 
			
		||||
    def createQuestion(self, title, description, options, indexAnswer, itemImage=None):
 | 
			
		||||
        self.infoPrint("create question...",self.progress)
 | 
			
		||||
        itemtxt = "{}\r\n".format(description)
 | 
			
		||||
        item = [{'insertText' : {
 | 
			
		||||
                'text': itemtxt, 
 | 
			
		||||
                'location':{'index': 1,}}}]
 | 
			
		||||
        if (itemImage != None):
 | 
			
		||||
            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()))
 | 
			
		||||
            time.sleep(3)
 | 
			
		||||
            self.infoPrint("uploading question image... ok",self.progress)
 | 
			
		||||
            u = urlparse(req.json()['data']['url'])
 | 
			
		||||
            item.append( { 'insertInlineImage' : {
 | 
			
		||||
                    'uri' : u._replace(path="/dl"+u.path).geturl(),
 | 
			
		||||
	                'location' : { 'index' : len(itemtxt)-1 }}
 | 
			
		||||
            })
 | 
			
		||||
        item = list(reversed(options)) + item
 | 
			
		||||
        self.questionKey.append(indexAnswer)
 | 
			
		||||
        return item
 | 
			
		||||
 | 
			
		||||
    def submitItem(self, index, item):
 | 
			
		||||
        self.infoPrint("submit question",self.progress)
 | 
			
		||||
        for _item in item :
 | 
			
		||||
            submition = {}
 | 
			
		||||
            submition["requests"] = _item
 | 
			
		||||
            print(submition)
 | 
			
		||||
            r = self.docs_service.documents().batchUpdate(documentId=self.main_docs["documentId"], body=submition).execute()
 | 
			
		||||
            print(r)
 | 
			
		||||
 | 
			
		||||
    def update(self):
 | 
			
		||||
        self.infoPrint("Updating Docs...",self.progress)
 | 
			
		||||
        # Prints the result to show the question has been added
 | 
			
		||||
        # get_result = self.docs_service.documents().get(documentId=self.main_docs["documentId"]).execute()
 | 
			
		||||
        self.resultUri = self.main_docs["documentId"]
 | 
			
		||||
        self.infoPrint("Updating Form... Done",self.progress)
 | 
			
		||||
| 
						 | 
				
			
			@ -21,11 +21,11 @@ class gquiz:
 | 
			
		|||
        # self.image_temp_service_url = "https://uguu.se/upload.php"
 | 
			
		||||
        self.submition = {"requests":[]}
 | 
			
		||||
        self.form_service = None
 | 
			
		||||
        self.drive_service = None 
 | 
			
		||||
        self.main_form = None
 | 
			
		||||
        self.infoPrint = self._defaultPrint
 | 
			
		||||
        self.progress = -1
 | 
			
		||||
        self.resultUri = ""
 | 
			
		||||
        self.savePath = './'
 | 
			
		||||
 | 
			
		||||
        self.submition["requests"].append({
 | 
			
		||||
            "updateSettings": {
 | 
			
		||||
| 
						 | 
				
			
			@ -40,6 +40,10 @@ class gquiz:
 | 
			
		|||
 | 
			
		||||
    def setProgress(self, i : int):
 | 
			
		||||
        self.progress = i
 | 
			
		||||
 | 
			
		||||
    def setSavePath(self, path):
 | 
			
		||||
        self.savePath = path
 | 
			
		||||
 | 
			
		||||
    def AttachProcessInfo(self, callback):
 | 
			
		||||
        self.infoPrint = callback
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -51,10 +55,7 @@ class gquiz:
 | 
			
		|||
         here is the way to get token 
 | 
			
		||||
         link : https://developers.google.com/docs/api/quickstart/python
 | 
			
		||||
        '''
 | 
			
		||||
        SCOPES = ["https://www.googleapis.com/auth/forms.body",
 | 
			
		||||
                  "https://www.googleapis.com/auth/drive",
 | 
			
		||||
                  "https://www.googleapis.com/auth/drive.file",
 | 
			
		||||
                  "https://www.googleapis.com/auth/drive.appdata"]
 | 
			
		||||
        SCOPES = ["https://www.googleapis.com/auth/forms.body",]
 | 
			
		||||
        DISCOVERY_DOC = "https://forms.googleapis.com/$discovery/rest?version=v1"
 | 
			
		||||
 | 
			
		||||
        creds = None
 | 
			
		||||
| 
						 | 
				
			
			@ -71,7 +72,7 @@ class gquiz:
 | 
			
		|||
                self.infoPrint("refresh token",self.progress)
 | 
			
		||||
            else:
 | 
			
		||||
                flow = InstalledAppFlow.from_client_secrets_file(
 | 
			
		||||
                    './secret/client_secrets.json', SCOPES)
 | 
			
		||||
                    self.savePath+'/secret/client_secret.json', SCOPES)
 | 
			
		||||
                creds = flow.run_local_server(port=0)
 | 
			
		||||
                self.infoPrint("generate token",self.progress)
 | 
			
		||||
            # Save the credentials for the next run
 | 
			
		||||
| 
						 | 
				
			
			@ -80,10 +81,7 @@ class gquiz:
 | 
			
		|||
 | 
			
		||||
        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),\
 | 
			
		||||
                    build('drive', 'v3', credentials=creds)
 | 
			
		||||
            self.form_service = build('forms', 'v1', credentials=creds, discoveryServiceUrl=DISCOVERY_DOC, static_discovery=False)
 | 
			
		||||
 | 
			
		||||
        except HttpError as err:
 | 
			
		||||
            print(err)
 | 
			
		||||
| 
						 | 
				
			
			@ -101,30 +99,6 @@ class gquiz:
 | 
			
		|||
        except HttpError as error:
 | 
			
		||||
            print('An error occurred: %s' % error)			
 | 
			
		||||
 | 
			
		||||
    def copyFile(self,origin_file_id, copy_title):
 | 
			
		||||
        """Copy an existing file.
 | 
			
		||||
        Args:
 | 
			
		||||
          service: Drive API service instance.
 | 
			
		||||
          origin_file_id: ID of the origin file to copy.
 | 
			
		||||
          copy_title: Title of the copy.
 | 
			
		||||
 | 
			
		||||
        Returns:
 | 
			
		||||
          The copied file if successful, None otherwise.
 | 
			
		||||
        """
 | 
			
		||||
 | 
			
		||||
        try:
 | 
			
		||||
            if((self.drive_service == None) or (self.form_service == None)):
 | 
			
		||||
                raise Exception('please generate service first')
 | 
			
		||||
 | 
			
		||||
            newFormId = self.drive_service.files().copy(\
 | 
			
		||||
                  fileId=origin_file_id, body={"name":copy_title})\
 | 
			
		||||
                  .execute()
 | 
			
		||||
            print(newFormId)
 | 
			
		||||
            self.main_form = self.form_service.forms().get(formId=newFormId["id"]).execute()
 | 
			
		||||
 | 
			
		||||
        except HttpError as error:
 | 
			
		||||
            print('An error occurred: %s' % error)
 | 
			
		||||
 | 
			
		||||
    def createOption(self, value, image=None):
 | 
			
		||||
        '''
 | 
			
		||||
        return {"value" : "A. option 1"}
 | 
			
		||||
| 
						 | 
				
			
			@ -205,7 +179,7 @@ class gquiz:
 | 
			
		|||
                     })
 | 
			
		||||
        return item
 | 
			
		||||
 | 
			
		||||
    def submitQuestion(self, index, item):
 | 
			
		||||
    def submitItem(self, index, item):
 | 
			
		||||
        """ Submit item to submition
 | 
			
		||||
        Args: 
 | 
			
		||||
            index : location item in form
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1 @@
 | 
			
		|||
# TODO jadikan satu semua code yang berhubungan dengan autentikasi dan generate service
 | 
			
		||||
| 
						 | 
				
			
			@ -9,6 +9,10 @@ class moodleQuiz:
 | 
			
		|||
        self.progress = -1
 | 
			
		||||
        self.resultUri = ""
 | 
			
		||||
        self.data = ET.Element('quiz')
 | 
			
		||||
        self.savePath = '.'
 | 
			
		||||
 | 
			
		||||
    def setSavePath(self, path):
 | 
			
		||||
        self.savePath = path
 | 
			
		||||
 | 
			
		||||
    def setProgress(self, i : int):
 | 
			
		||||
        self.progress = i
 | 
			
		||||
| 
						 | 
				
			
			@ -82,6 +86,6 @@ class moodleQuiz:
 | 
			
		|||
    def update(self):
 | 
			
		||||
        ET.indent(self.data)
 | 
			
		||||
        print(ET.tostring(self.data))
 | 
			
		||||
        ET.ElementTree(self.data).write("./moodleXMLMultichoiceQuestion.xml")
 | 
			
		||||
        ET.ElementTree(self.data).write("{}/{}".format(self.savePath, "moodleXMLMultichoiceQuestion.xml"))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,64 @@
 | 
			
		|||
# 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"
 | 
			
		||||
 | 
			
		||||
sys.path.append("/lib64/libreoffice/program/")
 | 
			
		||||
 | 
			
		||||
from scriptforge import ScriptForge, CreateScriptService
 | 
			
		||||
from unohelper import fileUrlToSystemPath
 | 
			
		||||
 | 
			
		||||
sys.path.insert(0, '{}/{}'.format(os.getcwd(),'Library'))
 | 
			
		||||
ScriptForge(hostname='localhost', port=2002)
 | 
			
		||||
 | 
			
		||||
from gquiz import gquiz
 | 
			
		||||
 | 
			
		||||
ui = CreateScriptService("UI")
 | 
			
		||||
doc = CreateScriptService("Calc")
 | 
			
		||||
bas = CreateScriptService("Basic")
 | 
			
		||||
 | 
			
		||||
q = gquiz()
 | 
			
		||||
q.generateService()
 | 
			
		||||
 | 
			
		||||
def get_file_id_from_link(link):
 | 
			
		||||
    # Find the starting index of the file ID
 | 
			
		||||
    start_index = -1
 | 
			
		||||
    if "/d/" in link:
 | 
			
		||||
        start_index = link.index("/d/") + 3
 | 
			
		||||
    elif "id=" in link:
 | 
			
		||||
        start_index = link.index("id=") + 3
 | 
			
		||||
    elif "rs/" in link:
 | 
			
		||||
        start_index = link.index("rs/") + 3
 | 
			
		||||
 | 
			
		||||
    if start_index != -1:
 | 
			
		||||
        # Find the ending index of the file ID
 | 
			
		||||
        end_index = link.index("/", start_index)
 | 
			
		||||
        if end_index == -1:
 | 
			
		||||
            # If there is no trailing "/", use the end of the string
 | 
			
		||||
            end_index = len(link)
 | 
			
		||||
 | 
			
		||||
        # Extract the file ID
 | 
			
		||||
        file_id = link[start_index:end_index]
 | 
			
		||||
        return file_id
 | 
			
		||||
    else:
 | 
			
		||||
        # Return None if no file ID is found
 | 
			
		||||
        return None
 | 
			
		||||
 | 
			
		||||
cells = doc.getValue("")
 | 
			
		||||
 | 
			
		||||
for col in range(0, len(cells)):
 | 
			
		||||
    for row in range(0, len(cells[0])):
 | 
			
		||||
        if(str(cells[col][row]).startswith("https://")):
 | 
			
		||||
           print("found the culprit!!")
 | 
			
		||||
           url = cells[col][row]
 | 
			
		||||
           print(url)
 | 
			
		||||
           Id=get_file_id_from_link(url)
 | 
			
		||||
           file = q.drive_service.files().get(fileId=Id).execute()
 | 
			
		||||
           newCell = "/asset/{newname}".format(newname=file["name"])
 | 
			
		||||
           print("{new} <- {old}".format(new=newCell, old=cells[col][row]))
 | 
			
		||||
           doc.setValue(doc.Offset("A1",col,row),newCell)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,135 @@
 | 
			
		|||
# 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/")
 | 
			
		||||
 | 
			
		||||
from scriptforge import ScriptForge, CreateScriptService
 | 
			
		||||
from unohelper import fileUrlToSystemPath
 | 
			
		||||
 | 
			
		||||
ui = CreateScriptService("UI")
 | 
			
		||||
doc = CreateScriptService("Calc")
 | 
			
		||||
bas = CreateScriptService("Basic")
 | 
			
		||||
url = fileUrlToSystemPath(XSCRIPTCONTEXT.getDocument().URL )
 | 
			
		||||
curpath = '/'.join([url.split('/')[x] for x in range(0,len(url.split('/'))-1)])
 | 
			
		||||
if not ui.Activate(url) : 
 | 
			
		||||
    bas.MsgBox("Error no window active",bas.MB_OK)
 | 
			
		||||
 | 
			
		||||
def _load_module():
 | 
			
		||||
    #[start] comment for run embeded module
 | 
			
		||||
    if (not 'gquiz' in sys.modules) or (not 'moodleQuiz' in sys.modules):
 | 
			
		||||
        doc = XSCRIPTCONTEXT.getDocument()
 | 
			
		||||
        urlem = '{}/{}'.format(url,'/Scripts/python/Library')
 | 
			
		||||
        sys.path.insert(0, urlem)
 | 
			
		||||
        _statusBarInfoUpdate("Load embedded modul link form {}".format(url),0)
 | 
			
		||||
    #[end]
 | 
			
		||||
    #[start] uncomemnt for run separatly from soffice
 | 
			
		||||
    #sys.path.insert(0, '{}/{}'.format(os.getcwd(),'Library'))
 | 
			
		||||
    #ScriptForge(hostname='localhost', port=2002)
 | 
			
		||||
    #[end]
 | 
			
		||||
 | 
			
		||||
def MakeTemplate():
 | 
			
		||||
    doc.SetArray(doc.CurrentSelection, \
 | 
			
		||||
            (("<Text question>","<IMG question image>", \
 | 
			
		||||
            "<isAnswerA>", "<IMG option1>", "<Text Option1>",  \
 | 
			
		||||
            "<isAnswerB>", "<IMG option2>", "<Text Option2>",  \
 | 
			
		||||
            "<isAnswerC>", "<IMG option3>", "<Text Option3>",  \
 | 
			
		||||
            "<isAnswerD>", "<IMG option4>", "<Text Option4>",  \
 | 
			
		||||
            "<isAnswerE>", "<IMG option5>", "<Text Option5>", ),))
 | 
			
		||||
 | 
			
		||||
def _statusBarInfoUpdate(text : str, progress : int):
 | 
			
		||||
    ui.ShowProgressBar("loading...", "{}% {}".format(progress,text), progress)
 | 
			
		||||
 | 
			
		||||
def _updateQuestion(q, isReverse = False):
 | 
			
		||||
    selctedCell = doc.CurrentSelection      #
 | 
			
		||||
    cwd = curpath
 | 
			
		||||
    maxRow = doc.LastRow(selctedCell)+1-doc.FirstRow(selctedCell)
 | 
			
		||||
    rnge = reversed(range(0, maxRow)) if isReverse else range(0, maxRow)
 | 
			
		||||
    for nrow in rnge:
 | 
			
		||||
        q.setProgress(int(((nrow+1)/maxRow)*100))
 | 
			
		||||
        item = doc.getValue(doc.Offset(doc.FirstCell(selctedCell),nrow,0,1,17))
 | 
			
		||||
        # item[0]	<Text question>	
 | 
			
		||||
        # item[1]	<IMG question image>
 | 
			
		||||
        # item[2]	<isAnswerA>
 | 
			
		||||
        # item[3]	<IMG option1>
 | 
			
		||||
        # item[4]	<Text Option1>
 | 
			
		||||
        # item[5]	<isAnswerB>
 | 
			
		||||
        # item[6]	<IMG option2>
 | 
			
		||||
        # item[7]	<Text Option2>
 | 
			
		||||
        # item[8]	<isAnswerC>
 | 
			
		||||
        # item[9]	<IMG option3>
 | 
			
		||||
        # item[10]	<Text Option3>
 | 
			
		||||
        # item[11]	<isAnswerD>
 | 
			
		||||
        # item[12]	<IMG option4>
 | 
			
		||||
        # item[13]	<Text Option4>
 | 
			
		||||
        # item[14]	<isAnswerE>
 | 
			
		||||
        # item[15]	<IMG option5>
 | 
			
		||||
        # item[16]	<Text Option5>
 | 
			
		||||
        opt, theAnswer, c = [], -1, 1
 | 
			
		||||
        for o in range(2, 17, 3): # mengambil kolim jawaban saja 
 | 
			
		||||
            if (item[o] == 1)
 | 
			
		||||
                theAnswer = c
 | 
			
		||||
            opt.append(\
 | 
			
		||||
                q.createOption(\
 | 
			
		||||
                    "{}. {}".format(chr(64+c),item[o+2]),\
 | 
			
		||||
                    cwd+item[o+1] if (item[o+1] != "") else None))
 | 
			
		||||
            c = c+1
 | 
			
		||||
    
 | 
			
		||||
        if (theAnswer == -1):
 | 
			
		||||
            raise Exception("Chose the correct answer")	
 | 
			
		||||
 | 
			
		||||
        img = cwd+item[1] if ( item[1] != "") else None
 | 
			
		||||
        qq = q.createQuestion(\
 | 
			
		||||
                title = "Soal No {}".format(nrow+1),\
 | 
			
		||||
                description = item[0],\
 | 
			
		||||
                indexAnswer = theAnswer, \
 | 
			
		||||
                options = opt, itemImage=img)
 | 
			
		||||
        q.submitItem(nrow,qq)
 | 
			
		||||
    q.update()	
 | 
			
		||||
 | 
			
		||||
def GoogleQuiz():
 | 
			
		||||
    _load_module()
 | 
			
		||||
    from gquiz import gquiz
 | 
			
		||||
    q = gquiz()
 | 
			
		||||
    q.setSavePath(curpath)
 | 
			
		||||
    q.AttachProcessInfo(_statusBarInfoUpdate)
 | 
			
		||||
    q.setProgress(0)
 | 
			
		||||
    q.generateService()
 | 
			
		||||
    q.createForm("Demo Soal") #TODO : put this mundane inside generateService()
 | 
			
		||||
    _updateQuestion(q)
 | 
			
		||||
    ui.SetStatusbar("creating google form quiz done!")
 | 
			
		||||
    _statusBarInfoUpdate("Finish!!",100)
 | 
			
		||||
    bas.InputBox("Open link to edit your form:","Your Google Form Quiz, done!", "{}".format(q.resultUri))
 | 
			
		||||
 | 
			
		||||
def GoogleDocs():
 | 
			
		||||
    _load_module()
 | 
			
		||||
    from gdoc import gdoc 
 | 
			
		||||
    q = gdoc()
 | 
			
		||||
    q.setSavePath(curpath)
 | 
			
		||||
    q.AttachProcessInfo(_statusBarInfoUpdate)
 | 
			
		||||
    q.setProgress(0)
 | 
			
		||||
    q.generateService()
 | 
			
		||||
    q.createDocs("Demo Soal") #TODO : put this mundane inside generateService()
 | 
			
		||||
    _updateQuestion(q, True)
 | 
			
		||||
    ui.SetStatusbar("creating google form quiz done!")
 | 
			
		||||
    _statusBarInfoUpdate("Finish!!",100)
 | 
			
		||||
    bas.InputBox("Open link to edit your form:","Your Google Form Quiz, done!", "{}".format(q.resultUri))
 | 
			
		||||
 | 
			
		||||
def MoodleQuiz():
 | 
			
		||||
    _load_module()
 | 
			
		||||
    from moodleQuiz import moodleQuiz
 | 
			
		||||
    q = moodleQuiz()
 | 
			
		||||
    q.setSavePath(curpath)
 | 
			
		||||
    q.AttachProcessInfo(_statusBarInfoUpdate)
 | 
			
		||||
    q.setProgress(0)
 | 
			
		||||
    _updateQuestion(q)
 | 
			
		||||
    ui.SetStatusbar("Done!")
 | 
			
		||||
    _statusBarInfoUpdate("Check *.xml file in curent folder!",100)
 | 
			
		||||
 | 
			
		||||
g_exportedScripts = (MakeTemplate, GoogleQuiz, GoogleDocs, MoodleQuiz)
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,75 @@
 | 
			
		|||
# coding: utf-8
 | 
			
		||||
# run it under boring_edu_doc folder
 | 
			
		||||
# $ python Scripts/python/test_gquiz.py
 | 
			
		||||
from __future__ import unicode_literals
 | 
			
		||||
import os, sys, requests
 | 
			
		||||
if (len(sys.argv) < 2):
 | 
			
		||||
    print("arg[1] : form, docs, moodle")
 | 
			
		||||
    quit()
 | 
			
		||||
 | 
			
		||||
def gquiz_form_test():
 | 
			
		||||
    '''
 | 
			
		||||
    arg[1] = form
 | 
			
		||||
    '''
 | 
			
		||||
    if not 'gquiz' in sys.modules:
 | 
			
		||||
        sys.path.insert(0, os.getcwd()+"/Scripts/python/Library/")
 | 
			
		||||
    from gquiz import gquiz
 | 
			
		||||
 | 
			
		||||
    q = gquiz()
 | 
			
		||||
    q.setSavePath(".")
 | 
			
		||||
    q.setProgress(0)
 | 
			
		||||
    q.generateService()
 | 
			
		||||
    q.setProgress(20)
 | 
			
		||||
    q.createForm("test quiz")
 | 
			
		||||
    q.setProgress(50)
 | 
			
		||||
    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") ]
 | 
			
		||||
    q.setProgress(80)
 | 
			
		||||
    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.setProgress(85)
 | 
			
		||||
    q.submitItem(0,qq)
 | 
			
		||||
    q.setProgress(90)
 | 
			
		||||
    q.update()
 | 
			
		||||
    q.setProgress(100)
 | 
			
		||||
    print("Open link : {}".format(q.resultUri))
 | 
			
		||||
 | 
			
		||||
def gquiz_docs_test():
 | 
			
		||||
    '''
 | 
			
		||||
    arg[1] = docs
 | 
			
		||||
    '''
 | 
			
		||||
    if not 'gdoc' in sys.modules:
 | 
			
		||||
        sys.path.insert(0, os.getcwd()+"/Scripts/python/Library/")
 | 
			
		||||
    from gdoc import gdoc
 | 
			
		||||
 | 
			
		||||
    q = gdoc()
 | 
			
		||||
    q.setSavePath(".")
 | 
			
		||||
    q.setProgress(0)
 | 
			
		||||
    q.generateService()
 | 
			
		||||
    q.setProgress(20)
 | 
			
		||||
    q.createDocs("test quiz")
 | 
			
		||||
    q.setProgress(50)
 | 
			
		||||
    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") ]
 | 
			
		||||
    q.setProgress(80)
 | 
			
		||||
    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.setProgress(85)
 | 
			
		||||
    q.submitItem(0,qq)
 | 
			
		||||
    q.setProgress(90)
 | 
			
		||||
    q.update()
 | 
			
		||||
    q.setProgress(100)
 | 
			
		||||
    print("Open link : {}".format(q.resultUri))
 | 
			
		||||
 | 
			
		||||
if (sys.argv[1] == 'form'):
 | 
			
		||||
    gquiz_form_test()
 | 
			
		||||
elif (sys.argv[1] == 'docs'):
 | 
			
		||||
    gquiz_docs_test()
 | 
			
		||||
| 
						 | 
				
			
			@ -1 +1,12 @@
 | 
			
		|||
ok
 | 
			
		||||
Authorize credentials for a desktop application
 | 
			
		||||
To authenticate as an end user and access user data in your app, you need to create one or more OAuth 2.0 Client IDs. A client ID is used to identify a single app to Google's OAuth servers. If your app runs on multiple platforms, you must create a separate client ID for each platform.
 | 
			
		||||
 | 
			
		||||
    In the Google Cloud console, go to Menu menu > APIs & Services > Credentials.
 | 
			
		||||
 | 
			
		||||
    Go to Credentials
 | 
			
		||||
    Click Create Credentials > OAuth client ID.
 | 
			
		||||
    Click Application type > Desktop app.
 | 
			
		||||
    In the Name field, type a name for the credential. This name is only shown in the Google Cloud console.
 | 
			
		||||
    Click Create. The OAuth client created screen appears, showing your new Client ID and Client secret.
 | 
			
		||||
    Click OK. The newly created credential appears under OAuth 2.0 Client IDs.
 | 
			
		||||
    Save the downloaded JSON file as credentials.json, and move the file to your working directory.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue