Nelle ultime versioni di QualiWare, a partire dalla 2023.00.17, sono disponibili una serie di funzionalità per l’interfacciamento con Google Drive. Questo interfacciamento permette di importare una serie di documenti da Google Drive (disco o cartella condivisa) a QualiWare, e viceversa.
Importazione da Google Drive a QualiWare
Su QualiWare è disponibile un apposito form indipendente che permette di importare documenti da un servizio in cloud (tra cui Google Drive). Si rimanda all’apposita pagina della guida per approfondirne il funzionamento.
È bene specificare, comunque, che è possibile utilizzare le funzioni elencate nell’apposito paragrafo di questa pagina per modificare ulteriormente il form ed aggiungerci determinate funzionalità.
Esportazione da QualiWare a Google Drive
Per esportare un gruppo di documenti da QualiWare a Google Drive è necessario, da parte dell’amministratore del Drive:
- creare un account di servizio, e fornire le credenziali all’amministratore di QualiWare
- condividere, con l’account di servizio, l’intero Drive, oppure le cartelle di destinazione dei documenti da esportare
Entrambi i passaggi saranno spiegati nel dettaglio nei seguenti paragrafi.
Creazione dell’account di servizio
L’account di servizio si può creare e configurare all’interno della Google Cloud Platform (CGP). Per farlo, bisogna accedere alla console e, da qui, procede alla sezione “IAM”. Per aggiungerne uno, bisogna, come indicato nell’immagine, accedere alla sezione “Service accounts” e poi cliccare su “Create Service account”.
I dati essenziali da specificare per l’account di servizio sono un nome ed un ID.
Dopo avere creato l’account, è necessario creare una chiave di accesso per permetterne l’utilizzo tramite API. Si può fare premere sull’icona nella colonna “Actions” e poi su scegliere “Manage keys”.
Dalla schermata delle chiavi, sarà poi sufficiente cliccare su “Add Key” e poi su “Create new key”. Si aprirà una schermata che consentirà di scegliere il modo in cui generare la chiave. La modalità più semplice è quella di utilizzare il formato JSON, naturalmente con le dovute precauzioni. Il contenuto del JSON generato sarà ciò che bisognerà fornire all’amministratore di QualiWare per poter impostare i servizi di esportazione. In particolare, il JSON è ciò che dovrà essere passato alla funzione GDriveGetService per effettuare l’autenticazione tra QualiWare e il Drive (per i dettagli, si veda il paragrafo apposito).
L’ultimo passaggio da effettuare, per completare la configurazione dell’utente di servizio, è abilitare l’utilizzo delle API di Google Drive da parte dell’account in questione. Per farlo, andare nella sezione “APIs and services” della console, scegliere “Enabled APIs and services”, poi “Enable APIs and services”. Fatto ciò, basta proseguire scegliendo di attivare quelle relative a Google Drive.
Funzioni
Di seguito l’elenco delle funzioni che permettono la gestione dei file su Google Drive.
QWGoogle.DriveGetService(<Json>): restituisce l’oggetto servizio da passare nelle altre funzioni come parametroservice. Nel parametroJsonviene passato il contenuto del file JSON scaricato in fase di creazione della chiave dell’account di servizio.QWGoogle.GDriveGetFolderIDByName(<service>,<folderName>,<parentFolderId>): restituisce l’ID di una cartella a partire dal nome. Il parametroparentFolderIdcontiene l’Id dell’eventuale cartella all’interno della quale è contenuta la cartella di cui è stato specificato il nome. Questo parametro va lasciatoNothingnel caso si desideri cercare la cartella in tutto lo spazio di archiviazione condiviso. Se la cartella non esiste, la funzione ritornaNothing.
ATTENZIONE: se non viene specificato il parametroparentFolderId, la funzione cerca in tutto lo spazio di archiviazione condiviso. Si tenga quindi in considerazione che:- è di fondamentale importanza che i nomi delle cartelle di primo livello siano univoci nello spazio di archiviazione stesso
- la funzione può essere estremamente lenta (nell’ordine dei minuti) a ricavare l’ID della cartella, nel caso l’account Google utilizzato abbia un Drive corposo e/o dei Drive condivisi. Può quindi essere necessario specificare un
parentFolderIDper ottenere il risultato in una frazione di secondo,
QWGoogle.GDriveGetFolderNameByID(<service>,<folderId>): recupera il nome della cartella a partire dall’ID passato nel parametrofolderId. Se la cartella non esiste, la funzione ritornaNothing.QWGoogle.GDriveCreateFolder(<service>,<name>,<parentFolderId>,<errmsg>): crea una cartella con il nome specificato nel parametronameall’interno della cartella il cui ID è specificato nel parametroparentFolderId. Questa funzione ritorna l’ID della cartella se l’operazione è andata a buon fine,Nothingaltrimenti, e, in questo caso, nel parametroerrmsgè contenuta la descrizione dell’errore.
NOTA: se la cartella esiste già, ne viene restituito l’ID.QWGoogle.GDriveGetFiles(<service>,<folderId>,<optional recurse>,<optional filter>): restituisce un oggetto DBArray con informazioni relative ai file contenuti nella cartella il cui ID è specificato nel parametrofolderID. Ogni elemento dell’array corrisponde ad un file, e consiste a sua volta in un DBArray di 5 elementi. Il primo è il nome del file con relativa estensione, il secondo l’ID, il terzo la data di ultima modifica, il quarto la dimensione in byte, e il quinto il path senza nome del file (e la cui radice è la cartella specificata nel primo tab del form). Il parametro opzionalerecurse, seTrue, consente di recuperare i file anche dalle sotto cartelle. Il parametro opzionalefilterconsente di filtrare i file in base a parte del nome. E’ possibile anche usare il carattere*come wildcard. Seè Nothing, vengono restituiti i file contenuti nella root.<folderId>QWGoogle.GDriveGetFolders(<service>,<folderId>): restituisce un oggetto DBArray con informazioni relative alle sottocartelle contenute nella cartella il cui ID è specificato nel parametrofolderID. Gli elementi dell’array restituito sono a loro volta oggetti DBArray di due elementi. Il primo è il nome della sottocartella, il secondo il suo ID. Seè Nothing, vengono restituite le cartelle dipendenti dalla root.<folderId>QWGoogle.GDriveDeleteFileOrFolder(<service>,<name>,<folderId>,<errmsg>)*: cancella il file o la sottocartella il cui nome è contenuto nel parametronamee che si trova nella cartella il cui ID è specificato nel parametrofolderID. Questa funzione ritornaTruese l’operazione è andata a buon fine,Falsealtrimenti, e, in questo caso, nel parametroerrmsgè contenuta la descrizione dell’errore. N.B. è possibile cancellare solo file caricati tramite script. Seè Nothing, vengono cancellati il file o la cartella contenuti nella root.<folderId>QWGoogle.GDriveDeleteFileOrFolderByID(<service>,<ID>,<errmsg>)*: cancella il file o la sottocartella il cui ID è contenuto nel parametroID. Questa funzione ritornaTruese l’operazione è andata a buon fine,Falsealtrimenti, e, in questo caso, nel parametroerrmsgè contenuta la descrizione dell’errore. N.B. è possibile cancellare solo file caricati tramite script.QWGoogle.GDriveGetFile(<service>,<name>,<folderId>,<errmsg>): scarica il file il cui nome è contenuto nel parametronamee che si trova nella cartella il cui ID è specificato nel parametrofolderID. Ritorna il percorso del file scaricato, oppureNothingse l’operazione non è andata a buon fine e, in questo caso, nel parametroerrmsgè contenuta la descrizione dell’errore. Seè Nothing, viene restituito il file contenuto nella root.<folderId>QWGoogle.GDriveGetFileByID(<service>,<ID>,<errmsg>): scarica il file il cui ID è contenuto nel parametroID. Ritorna il percorso del file scaricato, oppureNothingse l’operazione non è andata a buon fine e, in questo caso, nel parametroerrmsgè contenuta la descrizione dell’errore.QWGoogle.GDriveUploadFile(<service>,<path>,<name>,<folderId>,<errmsg>): carica il file dal percorso specificato nel parametropathattribuendogli il nome contenuto nel parametronamee mettendolo nella cartella il cui ID è specificato nel parametrofolderID. Questa funzione ritornaTruese l’operazione è andata a buon fine,Falsealtrimenti, e, in questo caso, nel parametroerrmsgè contenuta la descrizione dell’errore. Da notare che la data di ultima modifica del file viene assegnata su Google Drive uguale a quella del file caricato, il che consente di verificare eventuali aggiornamenti intervenuti in locale o su GDrive. Si noti che questa funzione non aggiunge automaticamente l’estensione al nome del file.QWGoogle.GDriveRenameFileOrFolder(<service>,<oldname>,<newname>,<folderId>,<errmsg>): rinomina il file o la sottocartella il cui nome è contenuto nel parametrooldnamee che si trova nella cartella il cui ID è specificato nel parametrofolderID, assegnandogli il nome specificato nel parametro<newname>. Questa funzione ritornaTruese l’operazione è andata a buon fine,Falsealtrimenti, e, in questo caso, nel parametroerrmsgè contenuta la descrizione dell’errore.QWGoogle.GDriveRenameFileOrFolderByID(<service>,<ID>,<newname>,<errmsg>): rinomina il file o la sottocartella il cui ID è contenuto nel parametroID, assegnandogli il nome specificato nel parametro<newname>. Questa funzione ritornaTruese l’operazione è andata a buon fine,Falsealtrimenti, e, in questo caso, nel parametroerrmsgè contenuta la descrizione dell’errore.
* La cancellazione di un file è possibile solo se l’utente di servizio è proprietario (owner) del file stesso e, quindi, se l’ha creato lui. Diversamente, l’uso delle funzioni ritorna l’errore “forbidden”.
Esempio
Il codice riportato di seguito su Google Drive, in una cartella condivisa chiamata “ActiveDoc”, i file relativi ad una categoria documentale di QualiWare, mettendoli in una sottocartella il cui nome è uguale al nome della categoria, e attribuendo ai file un nome composto dal codice, dal titolo e dalla revisione.
' Assegnare alla variabile "json" il contenuto del json scaricato in fase di creazione della chiave
Dim json As String = "{
""type"": ""sxxxxx"",
""project_id"": ""sxxxxx"",
""private_key_id"": ""sxxxxx"",
""private_key"": ""-----BEGIN PRIVATE KEY-----
-----END PRIVATE KEY-----\n"",
""client_email"": ""sxxxxx"",
""client_id"": ""sxxxxx"",
""auth_uri"": ""https://accounts.google.com/o/oauth2/auth"",
""token_uri"": ""https://oauth2.googleapis.com/token"",
""auth_provider_x509_cert_url"": ""https://www.googleapis.com/oauth2/v1/certs"",
""client_x509_cert_url"": ""https://www.googleapis.com/robot/v1/metadata/x509/xxxxxxxxx"",
""universe_domain"": ""googleapis.com""
}"
' Create Drive API service.
Dim Service As Google.Apis.Drive.v3.DriveService=QWGoogle.GDriveGetService(json)
Dim tipo as string="DM7TEST" ' codice della categoria da esportare
Dim cartella as string="ActiveDoc" ' Nome della sottocartella in cui esportare i documenti
dim q as new QWTable()
q.database=form.GetDataBase()
q.sql="select NOME from TIPI_DOC where TIPO=:TIPO"
q.params("TIPO")=tipo
q.requestlive=false
q.active=true
dim nome_categoria as string=q.rowset.fields(1).value
q.active=false
Dim i as integer
dim errmsg as string
dim ok as boolean
dim id as string=QWGoogle.GDriveGetFolderIDByName(service,cartella,nothing) ' Recupera l'ID della cartella principale in cui inserire i file
dim nome_cartella_categoria as string=Sane_Filename(nome_categoria)
dim id_categoria as string=QWGoogle.GDriveCreateFolder(service,nome_cartella_categoria,id,errmsg)
if not id is nothing
q.sql="select TIPO,TIPO_CONT,NUMERO,IND_REV,TITOLO,_CODDOC from DOCUMENT where TIPO=:TIPO and PUBBLICATO=1"
q.params("TIPO")=tipo
q.requestlive=false
q.active=true
dim files as DBArray=QWGoogle.GDriveGetFiles(service,id_categoria)
ok=true
while not q.rowset.endofset and ok
dim path as string=form.GetSession().GetDocumentPath(q.rowset.fields("_CODDOC").value)
dim nomefile as string=q.rowset.fields("TIPO_CONT").value+"-"+q.rowset.fields("NUMERO").value+" "+Sane_FIlename(q.rowset.fields("TITOLO").value)+" rev. "+ltrim(str(q.rowset.fields("IND_REV").value))+System.IO.Path.GetExtension(path)
' Cerca nei file attuali se è presente
dim upload as boolean=true
for i=1 to files.size
if files(i)(1)=nomefile
dim dtqw as DateTime=files(i)(3)
dim dtG as DateTime=System.IO.File.GetLastWriteTime(path)
if dtQW.Year=dtG.Year and dtQW.Month=dtG.Month and dtQW.Day=dtG.Day and dtQW.Hour=dtG.Hour and dtQW.Minute=dtG.Minute and dtQW.Second=dtG.Second
upload=false
End If
files(i).add(true) ' per marcarlo come presente
Exit for
End If
next
if upload
ok=QWGoogle.GDriveUploadFile(Service,path,nomefile,id_categoria,errmsg,q.rowset.fields("TITOLO").value)
End If
q.rowset.next()
End while
q.active=false
if ok
' Cancella eventuali file in più presenti nella cartella di esportazione
for i=1 to files.size
if files(i).Size=3
QWGoogle.GDriveDeleteFileOrFolder(service,files(i)(1),id_categoria,errmsg)
End If
next
End If
End If



