Blog

Come gestire file in Genropy: le attachmentTable

Come gestire file in Genropy: le attachmentTable

In un software si ha molto spesso a che fare con la gestione di file su disco, di tipologie anche molto diverse a seconda del tipo di applicativo: cataloghi, brochure, curriculum, schede tecniche, bolle di trasporto, contratti, ecc.

Ciò che li accomuna è il collegamento con una tabella principale, quella dei prodotti, dei candidati, degli ordini, anche questa ovviamente molto diversa a seconda delle funzioni dell’applicativo. Come quindi gestire facilmente file così diversi in ambiti totalmente differenti?

Genropy mette a disposizione un’intera gestione dei file intesi come attachments: a una tabella principale si affiancherà una tabella di attachment, che si occuperà di creare dei record “allegato” da mettere in relazione alla tabella principale, mostrando all’interno dell’applicativo stesso i file collegati, e permettendone il caricamento di nuovi tramite interfaccia.

Come definire una tabella di Attachment

La definizione della tabella di attachment, come descritta nell’apposita documentazione, è molto semplice. È sufficiente creare un file tabellaprincipale_atc.py contenente queste tre righe di codice:

from gnr.app.gnrdbo import AttachmentTable
class Table(AttachmentTable):
    pass

È quindi sufficiente indicare la tabellaprincipale, ovvero quella a cui si riferiscono i file (prodotto, candidato, ecc). Genropy si occuperà poi autonomamente di tutti gli automatismi necessari sia a livello di filesystem che a livello di model.

Come visualizzare i file nell’applicativo

Esistono poi diversi modi di visualizzare i file collegati all’interno dell’applicativo. Il più utilizzato è l’attachmentMultiButtonFrame, ma esistono delle alternative Gallery o la più classica Grid. Ma è possibile personalizzare anche queste modalità di visualizzazione?

La risposta è ovviamente sì: indicando una viewResource come parametro della attachmentGrid, è possibile specificare quale risorsa utilizzare. Sarà quindi sufficiente creare la vista o la Form relativa come fosse una qualunque risorsa di un TableHandler.

Come personalizzare il model della tabella di attachment

Ma in che termini è personalizzabile la tabella di attachment? Supponiamo a questo punto di voler specificare per esempio la categoria del file allegato, indicando se l’allegato è di tipo catalogo, brochure, scheda tecnica.

Tutta la definizione della tabella di attachment è stata automatica, noi non siamo infatti intervenuti indicando le colonne da utilizzare. Non abbiamo neanche il classico metodo config_db presenti nelle tradizionali Table di Genropy. Come possiamo quindi modificare la struttura stessa della tabella di attachment, aggiungendo questa colonna non prevista ma per noi importante?

Genropy ci mette a disposizione un hook method onTableConfig, che ci dà la possibilità di aggiungere alla table altre colonne, in relazione o più semplicemente:

def onTableConfig(self, tbl): 
    tbl.column('category', name_long='Category')

A questo punto sarà sufficiente nella risorsa th mostrare una filteringSelect con una tendina delle opzioni a disposizione:

r.cell('category', name='Cat.', edit=True, values='CAT,SCT,BRO', width='4em')

Procedure automatiche: il metodo addAttachment

A questo punto possiamo già visualizzare tranquillamente gli allegati già inseriti o inserirne di nuovi, sfruttando tutti gli automatismi che le tabelle di attachment ci mettono a disposizione. Molte volte però ci troviamo a dover importare degli allegati già presenti su disco, per esempio durante la migrazione da un precedente applicativo, oppure per generiche importazioni in blocco. Trascinando molti allegati collegati a uno stesso record già possiamo evitare di caricarli uno a uno, ma abbiamo in questo caso delle alternative a effettuare il caricamento manuale record per record?

Anche in questo caso la risposta è ovviamente sì: la tabella di attachment mette a disposizione l’hook method addAttachment, che permette di aggiungere nel modo più corretto e semplice un record della table di attachment, senza dover ricorrere alla insert. Possiamo così aggiungere un allegato specificandone lorigin_filepath, ovvero il percorso di partenza, e il maintable_id, ovvero l’id del record della tabella principale a cui collegarsi.

Ipotizzando quindi di avere in una cartella cataloghi tutti i cataloghi dei nostri prodotti, già rinominati utilizzando il codice del prodotto, è possibile creare un batch di importazione che si occuperà di rintracciare il record collegato e agganciargli il file:

from gnr.web.batch.btcaction import BaseResourceAction
import os

caption='Importa cataloghi'
class Main(BaseResourceAction): 
    batch_prefix = 'IMP' batch_title = 'Importazione cataloghi'

    def do(self): 
        cataloghi_dir = self.page.site.site_path + '/cataloghi' 
        cataloghi = [f for f in os.listdir(cataloghi_dir) if f.endswith('.pdf')] 
        for catalogo in cataloghi: 
            codice = catalogo[:6] 
            prodotto_id = self.db.table('fatt.prodotto').readColumns(where='$codice=:cod', cod=codice, columns='$id') 
            filepath = cataloghi_dir + '/' + catalogo
            self.db.table('fatt.prodotto_atc').addAttachment(maintable_id=prodotto_id, origin_filepath=filepath, category='CAT', moveFile=True) 
        self.db.commit()

Con gli attributi copyFile e moveFile è possibile stabilire se copiare o spostare il file di origine, oppure con is_foreign_document evitare sia la copia che lo spostamento del file. In questo caso stiamo richiedendo di spostare il file, in modo da ripulire la directory di importazione.

Il metodo addAttachment riceve i seguenti parametri:

ParametroDescrizioneTipo
maintable_idL’id del record della tabella principale collegataT
origin_filepathIl path del fileT
external_urlAlternativa al path, permette di caricare un allegato da un’url esternaT
destFolderLa cartella di destinazioneT
descriptionIl friendly-name del file allegatoT
mimetypeIl tipo di file (rilevato automaticamente se omesso)T
copyFilePermette di indicare se copiare o meno il file partendo dall’origin_filepath indicatoB
moveFilePermette di indicare se spostare il file partendo dall’origin_filepath indicatoB
is_foreign_documentPermette di indicare se il file è esterno, in quel caso non verrà né copiato né spostatoB
filenameIl nome del fileT

Abbiamo quindi visto come sfruttare al massimo le tabelle di attachment, uno strumento che include automatismi in grado di semplificare notevolmente la vita dello sviluppatore. In poche righe è possibile impostare tutto un sistema di archiviazione e gestione dei file, personalizzabile ad alto livello. È poi possibile impostare delle procedure per il popolamento delle stesse tabelle in modo estremamente semplice, rendendo lo strumento ancora più flessibile e facilmente manutenibile. Usi già gli attachment e ti interessa darci il tuo feedback? Scrivici nei commenti o su AskGenropy.

Vuoi saperne di più? Consulta la sezione dedicata della Documentazione:


Ti stai avvicinando al mondo Genropy e desideri saperne di più? Seguici sui social per tenerti in contatto con le ultime novità che Genropy ha da offrire:

Genropy Seguici su Facebook
Pagina Facebook

 

Genropy Seguici Gruppo Facebook
Gruppo Facebook

 

Genropy Gruppo Telegram
Gruppo Telegram