from django.shortcuts import render from django.http import HttpResponse,HttpResponseRedirect,FileResponse from django.urls import reverse from django.db import IntegrityError from .models import * from config.views import * from att.views import * from django.conf import settings from django.conf.urls.static import static from django.contrib.auth import authenticate import mimetypes from random import randint import csv import time import datetime import zipfile #pip install python-codicefiscale from codicefiscale import codicefiscale import os # come sono gestiti i file nella configurazione: # MEDIA_ROOT=os.path.join(settings.BASE_DIR,'static/upload') # che diventa = os.path.join(settings.BASE_DIR,getConfig('DocPath')) # inoltre devo aver fatto qualche casino oggi 9.8.24 con i copia e incolla. ho dovuto rivedere tutto il file # il terrore si impossessa di me. sta storia del cvs non e' esattamente chiara # questo blocco rimuove fisicamente il file prima della sua rimozione logica nel db def delete_file(documento): file_path = os.path.join(settings.BASE_DIR,getConfig('DocPath'),documento.utente.azienda.partitaiva,documento.utente.codicefiscale,documento.storage) print('Path completa:',file_path) if os.path.isfile(file_path): print('rimozione fisica file:',file_path) try: os.remove(file_path) except OSError as ose: print('errore nella rimozione del file:',ose) # impacchetta il file e procede a fornire il file via web def download_file(request,uid): utente = Utenti.objects.get(pk=uid) file_path = os.path.join(settings.BASE_DIR,getConfig('DocPath'),documento.utente.azienda.partitaiva,documento.utente.codicefiscale,utente.storage) print('Path completa da Basedir:',file_path) if utente.storage and os.path.isfile(file_path): try: fl = open(file_path, 'rb') except Exception as er: print('errore',er) data=dict() data['errore']="File non esistente o non ancora disponibile" data['utente'] = utente return render(request,'documento.error.html',data) else: print('il file non esiste',file_path) data=dict() data['errore']='File non esistente o non ancora disponibile' data['utente'] = utente return render(request,'documento.error.html',data) mime_type, _ = mimetypes.guess_type(file_path) print('file',file_path,mime_type) response = FileResponse(open(file_path,'rb'),content_type='application/pdf',as_attachment=False) #response['Content-Disposition'] = "attachment; filename=%s" % u.documento return response # upload file # procedura singolo file per singolo utente def upload_file(uploaded_file,utente,originale=False): stored_file = ''.join((str(time.time()),'.saved')) fl_path = os.path.join(settings.BASE_DIR,getConfig('DocPath')) print('nome file',uploaded_file.name,stored_file) #modifico il file per dire alla funzione superiore se il file e' stato caricato o meno nomefile=None if originale: nomefile = uploaded_file.name else: nomefile = stored_file # vediamo se caricare o meno. # in questo caso, se il documento esiste gia', non lo carica. # come facciamo a stabilire se il documento esiste gia'? # fl_path = corrisponde a media.ROOT (che mi domando se non e' il caso di spostarlo nella configurazione) # azienda.partitaiva # utente.codicefiscale (prima era "record" e mi sono deciso a cambiarlo) try: print('posizione partitaiva',os.path.join(fl_path,utente.azienda.partitaiva)) os.mkdir(os.path.join(fl_path,utente.azienda.partitaiva)) except FileExistsError as fee: print('posizione partitaiva',os.path.join(fl_path,utente.azienda.partitaiva),"esistente") try: print("posizione partitaiva codicefiscale",os.path.join(fl_path,utente.azienda.partitaiva,utente.codicefiscale)) os.mkdir(os.path.join(fl_path,utente.azienda.partitaiva,utente.codicefiscale)) except FileExistsError as fee: print("posizione partitaiva codicefiscale",os.path.join(fl_path,utente.azienda.partitaiva,utente.codicefiscale),"esistente") with open(os.path.join(fl_path,utente.azienda.partitaiva,utente.codicefiscale,nomefile),'wb+') as d: for chunk in uploaded_file.chunks(): d.write(chunk) if originale: # viene richiesto il file originale piuttosto cheil file codificato con il timing print("viene restituito il file originale",os.path.join(fl_path,utente.azienda.partitaiva,utente.codicefiscale,nomefile)) return os.path.join(fl_path,utente.azienda.partitaiva,utente.codicefiscale,nomefile) print("viene restituito il file rinominato",os.path.join(fl_path,utente.azienda.partitaiva,utente.codicefiscale,nomefile)) return stored_file # caricamento file indice (gestito in modo diverso) def upload_file_indice(uploaded_file): stored_file = ''.join((str(time.time()),'.saved')) fl_path = os.path.join(settings.BASE_DIR,getConfig('DocPath'),getConfig('DocPathIndex')) print('nome file',uploaded_file.name,stored_file) # verifica l'esistenza della directory try: os.mkdir(fl_path) except FileExistsError as fee: print(fl_path,"esistente") print('file_memorizzato',os.path.join(fl_path,stored_file)) with open(os.path.join(fl_path,stored_file),'wb+') as d: for chunk in uploaded_file.chunks(): d.write(chunk) return stored_file # il file caricato viene associato a un utente specifico def associafile_a_utente(singolodocumento,request,utente,azienda=None,sede=None,descrizione=None,amministratore=None,pertutti=False): risultato = upload_file(singolodocumento,utente) documento = Documento() documento.dataupload = datetime.datetime.now() documento.utente = utente listaok = None listanotok = None associato = False if pertutti: documento.documento = "".join((utente.codicefiscale.strip(),"_",singolodocumento.name)) else: documento.documento = singolodocumento.name print('documento.documento',documento.documento) documento.storage = risultato documento.descrizione = descrizione try: documento.save() setLog(8,azienda=azienda,sede=sede,utente=utente,documento=documento,amministratore=amministratore) listaok = documento associato = True except IntegrityError as ie: print("problema di integrita', il file esiste",ie) listanotok = documento if not associato: print('documento da rimuovere di nuovo',associato) return(listaok,listanotok) ################################################################################## # carica file multipli. Utilizzato prevalentemente dalla gestione documenti. def save_and_load_file_multiple(listadocumenti,request,utente,azienda=None,sede=None,descrizione=None,amministratore=None,pertutti=False,ignoraAzienda=False,ignoraSede=False): listaok = list() listanotok = list() if azienda: print('Caricamento Multiplo,azienda',azienda.nome) if sede: print('Caricamento Multiplo,sede',sede.nome) print("Ignora le aziende",ignoraAzienda) print("Ignora le sedi",ignoraSede) print("Per tutti",pertutti) for singolodocumento in listadocumenti: print('singolodocumento:',singolodocumento) for ut in utente: print('utente:',ut.nome) lok = None nok = None # si deve individuare il codice fiscale dell'utente if not pertutti: if ut.codicefiscale.strip() in singolodocumento.name: print('associa documento CON riferimento a codice fiscale') if ignoraAzienda: print("Effettua ricerca in tutte le aziende") lok,nok = associafile_a_utente(singolodocumento,request,ut,ut.azienda,sede,descrizione,amministratore) elif ignoraSede: print("Effettua ricerca in tutte le Sedi dell'azienda") lok,nok = associafile_a_utente(singolodocumento,request,ut,ut.azienda,sede,descrizione,amministratore) else: print("Caricamento solo per l'azienda corrente") lok,nok = associafile_a_utente(singolodocumento,request,ut,azienda,sede,descrizione,amministratore) else: print('il codice fiscale',ut.codicefiscale.strip()," non si trova in ",singolodocumento.name) else: print('associo documento SENZA riferimento a codice fiscale') lok,nok = associafile_a_utente(singolodocumento,request,ut,azienda,sede,descrizione,amministratore,pertutti) if lok: listaok.append(lok) if nok: listanotok.append(nok) print('lista',listaok,listanotok) return (listaok,listanotok) #carica un singolofile - utilizzato prevalentemente nella pagina utente def save_and_load_file_single(listadocumenti,request,utente,azienda=None,sede=None,descrizione=None,amministratore=None): """ listadocumenti da caricare request: i documenti vengono caricati via web utente: utente a cui associare il documento azienda: (perche? se l'utente deve essere gia' associato a un'azienda?) sede: (lo stesso, perche' passare la sede, se l'utente stesso dovrebbe avere gia' l'indicazione della sede) e comunque questi parametri servono solo per i log, che insomma, posso aggirarli con semplicita' descrizione: descrizione assegnata al documento amministratore: caricamente a mezzo di un amministratore """ listaok = list() listanotok = list() associato=False for singolodocumento in listadocumenti: print('singolodocumento',singolodocumento,descrizione) #risultato = upload_file(singolodocumento,utente) documento = Documento() documento.dataupload = datetime.datetime.now() documento.utente = utente documento.documento = singolodocumento.name #documento.storage = risultato documento.descrizione = descrizione try: documento.save() setLog(8,azienda=azienda,sede=sede,utente=utente,documento=documento,amministratore=amministratore) #listaok.append(documento) print('record generato:',documento.id) associato=True except IntegrityError as ie: print("problema di integrita', il file esiste",ie) listanotok.append(documento) if associato: # se il record e' stato correttamente salvato, procede al caricamento del file. risultato=upload_file(singolodocumento,utente) documento.storage = risultato documento.save() listaok.append(documento) return (listaok,listanotok) #file_indice: contiene l'elenco dei nominativi da gestire. def save_and_load_file_indice(request,fileindice,azienda=None,sede=None): """ qui, oltre alla request, viene chiesto il nome del file indice il nome dell'azienda a cui si fa riferimento e la sua sede """ print('nome indice caricato',fileindice.name) if azienda: print('azienda',azienda.nome) if sede: print('sede',sede.nome) file_memorizzato = upload_file_indice(request.FILES['indice']) fl_path = os.path.join(getConfig('DocPath'),getConfig('DocPathIndex')) risultato = None listaOk=list() listaNotOk=list() with open(os.path.join(fl_path,file_memorizzato),'rb') as ind: risultato = ind.read() risultato = risultato.decode('utf-8',errors='replace') if isinstance(risultato,str): risultato = risultato.encode('utf8') with open(os.path.join(fl_path,''.join((file_memorizzato,'.cvtd'))),'wb') as ind: ind.write(risultato) print('una volta convertito, passiamo oltre') with open(os.path.join(fl_path,''.join((file_memorizzato,'.cvtd'))),'rt') as ind: spamreader = csv.reader(ind,delimiter=';') count = 0 for sr in spamreader: salvare = False count +=1 if count==1: continue print(count,'sr',sr,len(sr)) if len(sr) >= 1: # la lunghezza del record segnala qualcosa print('lunghezza ok',sr[0]) utente = None codicefiscale = sr[1].strip() print('codice fiscale',sr[1].strip().upper()) try: utente = Utente.objects.get(codicefiscale=sr[1].strip().upper()) listaNotOk.append({"nome":utente.nome,"codicefiscale":utente.codicefiscale,"errore":"giĆ  presente"}) except Utente.DoesNotExist as dne: print('Utente non trovato') utente = Utente() if azienda: utente.azienda = azienda if sede: utente.sede = sede utente.nome = sr[0].strip().title() utente.codicefiscale=sr[1].strip().upper() for fmt in ('%d/%m/%y','%d/%m/%Y','%d-%m-%y','%d-%m-%Y'): try: data_convertita = datetime.datetime.strptime(sr[2],fmt) print('data convertita',data_convertita) utente.datanascita = data_convertita except ValueError as ve: print('errore con la data di nascita',ve) utente.luogonascita = sr[3].title() utente.mail = sr[4].strip().lower() # ricerca sede: se il codice estratto nella colonna corrisponde... tmp_sede = sr[5] lista_sede = azienda.sede_set.all() for ls in lista_sede: if tmp_sede == ls.identificativo: utente.sede = ls utente.cabiopassword = ls.cambiopassword utente.forzanuovapassword = ls.forzanuovapassword utente.otppassword = ls.otppassword else: utente.cabiopassword = azienda.cambiopassword utente.forzanuovapassword = azienda.forzanuovapassword utente.otppassword = azienda.otppassword utente.inserimento = datetime.datetime.today().strftime("%Y-%m-%d") utente.pin = str(randint(100000,999999)) if len(utente.codicefiscale) == 16: utente.save() listaOk.append({"nome":utente.nome,"codicefiscale":utente.codicefiscale}) else: print("Codice Fiscale NON valido o mancante") listaNotOk.append({"nome":utente.nome,"codicefiscale":utente.codicefiscale,"errore":"Codice Fiscale"}) return (listaOk,listaNotOk) def PrepareZipFile(listafile=[]): zip_path = os.path.join(settings.BASE_DIR,getConfig('DocZipFile')) print("zip_path:",zip_path) # verifica l'esistenza della directory try: os.mkdir(zip_path) except FileExistsError as fee: print(zip_path,"esistente") filename = ''.join((str(time.time()),'.zip')) with zipfile.ZipFile(os.path.join(zip_path,filename),'w') as zip: for lf in listafile: d = Documento.objects.get(pk=lf) file2zip = os.path.join(settings.BASE_DIR,getConfig('DocPath'),d.utente.azienda.partitaiva,d.utente.codicefiscale,d.storage) zip.write(file2zip,arcname=d.documento) print('path completa',file2zip) print('file completo',os.path.join(zip_path,filename)) return (zip_path,filename)