From 2e724924459e88840dc59f38434688fa3ebb0965 Mon Sep 17 00:00:00 2001 From: Etienne Loupias Date: Thu, 29 Mar 2018 15:37:56 +0200 Subject: [PATCH] ajout depot de dossier --- cartads/formdata.py | 11 +- cartads/models.py | 289 +++++++++++++++++++++++++++++++++----------- 2 files changed, 228 insertions(+), 72 deletions(-) diff --git a/cartads/formdata.py b/cartads/formdata.py index 5b22d4f..fd852ef 100644 --- a/cartads/formdata.py +++ b/cartads/formdata.py @@ -68,8 +68,15 @@ class FormData(object): if value is not None: self.fields[fieldname] = value + # keep all form values + self.values = values + ''' + for key, value in values.items(): + print >> open('/home/grandlyon/log/cartads.debug', 'a+'), datetime.now(), key, ": ", value + ''' + # extract attachments - self.attachments = [] + self.attachments = {} attachments = { key: value for key, value in values.items() @@ -78,4 +85,4 @@ class FormData(object): 'content' in value) } for key in sorted(attachments.keys()): - self.attachments.append(attachments[key]) + self.attachments[key] = attachments[key] diff --git a/cartads/models.py b/cartads/models.py index b5d3c28..1ad092c 100644 --- a/cartads/models.py +++ b/cartads/models.py @@ -17,6 +17,9 @@ import base64 import json import datetime import uuid +import zipfile +import StringIO +import os # TODO: inutile si on genere le zip in-memory from email import encoders from email.mime.audio import MIMEAudio @@ -82,7 +85,8 @@ class CartADS(BaseResource): verify_cert = models.BooleanField(default=True, verbose_name=_('Check HTTPS Certificate validity')) # TODO : a mettre en param du connecteur - dirname = 'D:\LSM\Gfi\DepotDossierFTP\client1\\' + #dirname = 'D:\LSM\Gfi\DepotDossierFTP\client1\\' #dev cartads + dirname = 'E:\LSM\Gfi\DepotDossierFTP\client1\\' #recette cartads category = _('Business Process Connectors') @@ -114,65 +118,18 @@ class CartADS(BaseResource): def send(self, request): request.message = request.message.replace("contentType", "xm:contentType") - - # a priori attachement inutile pour cartads, a voir si on supprime - if self.attachments: - # SOAP Attachement format - message = MIMEMultipart('related', type="text/xml", - start="") - xml = MIMEText(None, _subtype='xml', _charset='utf-8') - xml.add_header('Content-ID', '') - # do not base64-encode the soap message - xml.replace_header('Content-Transfer-Encoding', '8bit') - xml_payload = request.message - - # hack payload to include attachment filenames in - # SOAP-ENV:Header. - soap_headers = [] - for num, attachment in enumerate(self.attachments): - filename = attachment.get('filename') or 'file%s.bin' % num - if isinstance(filename, unicode): - filename = filename.encode('utf-8', 'ignore') - soap_headers.append('%s' % (num, filename, num)) - xml_payload = xml_payload.replace('', - '%s' % ''.join(soap_headers)) - xml.set_payload(xml_payload) - message.attach(xml) - - for num, attachment in enumerate(self.attachments): - filename = attachment.get('filename') or 'file%s.bin' % num - content = base64.b64decode(attachment.get('content') or '') - content_type = attachment.get('content_type') or 'application/octet-stream' - maintype, subtype = content_type.split('/', 1) - if maintype == 'text': - part = MIMEText(content, _subtype=subtype) - else: - part = MIMEBase(maintype, subtype, name=filename) - part.set_payload(content) - part.add_header('Content-Transfer-Encoding', 'binary') - encoders.encode_noop(part) - part.add_header('Content-Disposition', 'attachment', name=filename, filename=filename) - part.add_header('Content-ID', '<%s>' % filename) - message.attach(part) - - message._write_headers = lambda x: None - msg_x = message.as_string(unixfrom=False) - # RFC 2045 defines MIME multipart boundaries: - # * boundary := 0*69 bcharsnospace - # * dash-boundary := "--" boundary - # * delimiter := CRLF dash-boundary - # but Python doesn't use CRLF, will only use LF (on Unix systems - # at least). This is http://bugs.python.org/issue1349106 and has - # been fixed in Python 3.2. - # - # Manually hack message to put \r\n so that the message is - # correctly read by Apache Axis strict parser. - boundary = message.get_boundary() - request.message = message.as_string(unixfrom=False - ).replace(boundary + '\n', boundary + '\r\n' - ).replace('\n--' + boundary, '\r\n--' + boundary) - request.headers.update(dict(message._headers)) request.headers['Authorization'] = self.instance.get_token() + + ''' inutile pour test avec traitement dans la minute toujours active en dev et rec + #print >> open('/home/grandlyon/log/cartads.debug', 'a+'), datetime.datetime.now(), "message: ", request.message + if "" in request.message: + # fait planter + #request.message = request.message.replace('xmlns:ns0="http://tempuri.org/"', + #'xmlns:ns0="http://tempuri.org/" xmlns:arr="http://schemas.microsoft.com/2003/10/Serialization/Arrays') + request.message = request.message.replace("", + "traitementImmediat1") + ''' + resp = self.instance.requests.post(request.url, data=request.message, headers=request.headers, verify=self.instance.verify_cert) @@ -191,28 +148,78 @@ class CartADS(BaseResource): @endpoint(perm='can_access', methods=['get','post']) def create(self, request): + # Create the in-memory file-like object for working w/imz (https://stackoverflow.com/questions/10908877/extracting-a-zipfile-to-memory) + self.in_memory_zip = StringIO.StringIO() + # Zip creation (https://pymotw.com/2/zipfile/) + # Get a handle to the in-memory zip in append mode + #zf = zipfile.ZipFile(self.in_memory_zip, "a", zipfile.ZIP_DEFLATED, False) + + # Nom du fichier zip a envoyer + zipFileName = str(uuid.uuid4()) + ".zip"; + #b64_fileContent = base64.b64encode(self.in_memory_zip.read()) + + # TODO : temp : on genere fichier physique parce que in_memory_zip genere un zip vide pour l'instant + localFileName = '/home/grandlyon/temp/'+zipFileName + + zf = zipfile.ZipFile(localFileName, + mode='w', + compression=zipfile.ZIP_DEFLATED, + ) + + # get creation fields from payload try: formdata = FormData(json.loads(request.body), CREATION_SCHEMA) except ValueError as e: raise ParameterTypeError(e.message) + #print >> open('/home/grandlyon/log/cartads.debug', 'a+'), datetime.datetime.now(), "commune_raw=", formdata.values['commune_raw'] + #return + + + if formdata.attachments: print >> open('/home/grandlyon/log/cartads.debug', 'a+'), datetime.datetime.now(), "nb attach: ", len(formdata.attachments) - for num, attachment in enumerate(formdata.attachments): + for key, attachment in formdata.attachments.items(): filename = attachment.get('filename') or 'file%s.bin' % num - print >> open('/home/grandlyon/log/cartads.debug', 'a+'), datetime.datetime.now(), "filename: ", filename - #content = base64.b64decode(attachment.get('content') or '') - b64_fileContent = attachment.get('content') + print >> open('/home/grandlyon/log/cartads.debug', 'a+'), datetime.datetime.now(), "key: ", key, " ; filename: ", filename + content = base64.b64decode(attachment.get('content') or '') + + + #b64_fileContent = attachment.get('content') #print >> open('/home/grandlyon/log/cartads.debug', 'a+'), datetime.datetime.now(), "b64_fileContent: ", b64_fileContent + try: + #zf.writestr("Pieces/"+filename, content) + # pour l'instant test en dur avec nom du cerfa pour le CU + if "cerfa" in key: + print >> open('/home/grandlyon/log/cartads.debug', 'a+'), datetime.datetime.now(), "cerfa_nom: ", formdata.values['cerfa_nom'] + filenameInZip = formdata.values['cerfa_nom'] + ".pdf" + else: + obj, idPiece, codePiece = key.split("_") + filenameInZip = "Pieces/"+ idPiece + "-" + codePiece + if "." in filename: + filenameInZip += filename[filename.find("."):] + print >> open('/home/grandlyon/log/cartads.debug', 'a+'), datetime.datetime.now(), "filenameInZip: ", filenameInZip + zf.writestr(filenameInZip, content) + + except ValueError as e: + raise ParameterTypeError(e.message) - # Pour l'instant pour test, on envoie le dernier fichier du formulaires - # TODO : construire le zip de tous les fichiers du form + zf.close() + + ''' + os.remove(localFileName) + return + ''' - # Nom du fichier zip a envoyer - fileName = str(uuid.uuid4()) + ".zip"; + + with open(localFileName, "rb") as image_file: + b64_fileContent = base64.b64encode(image_file.read()) + + + #print >> open('/home/grandlyon/log/cartads.debug', 'a+'), datetime.datetime.now(), "test apres:", b64_fileContent # test base64 #b64_fileContent = "UEsDBBQAAAAAAMqEQUzI2HQpGgAAABoAAAAKAAAAdGVzdDAxLnR4dHRlc3QgYmFzZTY0IG1pbmkgdG90byB0YXRhUEsBAhQAFAAAAAAAyoRBTMjYdCkaAAAAGgAAAAoAAAAAAAAAAQAgAAAAAAAAAHRlc3QwMS50eHRQSwUGAAAAAAEAAQA4AAAAQgAAAAAA" @@ -222,14 +229,32 @@ class CartADS(BaseResource): # TODO : mettre en parametre l'url du ws sendfile for x in range(0, len(b64_fileContent)/size_max + 1): - resp = self.requests.post('https://api-rec.grandlyon.com/ads-sendfile-dev/sendfile.aspx', - data={'fileName': self.dirname+fileName, + #respHttp = self.requests.post('https://api-rec.grandlyon.com/ads-sendfile-dev/sendfile.aspx', + respHttp = self.requests.post('https://api-rec.grandlyon.com/ads-sendfile-rec/sendfile.aspx', + data={'fileName': self.dirname+zipFileName, 'b64_fileContent': b64_fileContent[x*size_max:(x+1)*size_max], 'part': str(x), 'total': int(len(b64_fileContent)/size_max)} ) #.json() - return {'data': resp.content, 'length': len(b64_fileContent)} + os.remove(localFileName) + + infos = {"traitementImmediat" : 1} + #infos = dict(traitementImmediat='1') + + + #TODO : a voir si on met traitementImmediat a 1 + resp = self.get_client().service.NotifierDepotDossier(self.get_token_cartads(), + formdata.values['commune_raw'], + formdata.values['type_dossier'], + zipFileName, + formdata.values['email'], + self.get_type_compte_utilisateur(), + '' + ) + + #return {'data': sudsobject_to_dict(resp), 'respHttp': respHttp.content, 'length': len(b64_fileContent)} + return {'respHttp': respHttp.content, 'length': len(b64_fileContent)} @classmethod @@ -261,6 +286,17 @@ class CartADS(BaseResource): @endpoint(perm='can_access') def get_objets_demande(self, request, type_dossier): resp = self.get_client().service.GetObjetsDemande(self.get_token_cartads(), type_dossier) + dict_resp = sudsobject_to_dict(resp) + + out = [] + for objet in dict_resp['KeyValueOfintstring']: + out_item = {} + out_item['id'] = objet["Key"] + out_item['text'] = objet["Value"] + out.append(out_item) + + return {'data': out} + # TODO : parcourir la liste en json devrait etre plus simple qu'en suds, mais j'ai pas reussi pour l'instant # On parcourt la liste pour la mettre sous la forme id, text, pour l'utiliser comme source de donnees dans le formulaire @@ -295,3 +331,116 @@ class CartADS(BaseResource): objet_demande ) return {'data': sudsobject_to_dict(resp)} + + + @endpoint(perm='can_access') + def write_wcs_files(self, request, type_dossier): + output_string = "\n" + + dict_resp = self.get_objets_demande(request, type_dossier) + for objet in dict_resp['data']: + #print >> open('/home/grandlyon/log/cartads.debug', 'a+'), datetime.datetime.now(), "objet: ", objet + #return {'data': dict_resp} + + resp = self.get_pieces(request, type_dossier, objet["id"]) + dict_resp = resp["data"] + + #print >> open('/home/grandlyon/log/cartads.debug', 'a+'), datetime.datetime.now(), "dict_resp: ", dict_resp + + date_file = datetime.datetime.now() + #TODO: faire un id unique et invariant si on reimporte le form (si ajout de champs dans le BO cartads) + #(par exemple : 1000*objet["id"]+10*no du champ+no de la piece si elle est envoyee 6 fois) + id = 100*objet["id"] + + #TODO: mettre les accents dans "Pieces a joindre" + output_string += "\n" + output_string += " \n" + output_string += " page\n" + output_string += " \n" + output_string += " python\n" + output_string += ' form_var_objet_raw == "'+str(objet["id"])+'"\n' + output_string += " "+str(id)+"\n" + id += 1 + output_string += " \n" + output_string += ' \n" + output_string += " comment\n" + output_string += " imgCommune\n" + output_string += " "+str(id)+"\n" + id += 1 + output_string += " \n" + output_string += " \n" + output_string += " comment\n" + output_string += " "+str(id)+"\n" + id += 1 + output_string += " \n" + output_string += " \n" + output_string += " file\n" + output_string += " True\n" + output_string += " objet"+str(objet["id"])+"_cerfa\n" + output_string += " True\n" + output_string += " \n" + output_string += " none\n" + output_string += " 200M\n" + output_string += " True\n" + output_string += " "+str(id)+"\n" + id += 1 + output_string += " \n" + + + for piece in dict_resp['Piece']: + #print >> open('/home/grandlyon/log/cartads.debug', 'a+'), datetime.datetime.now(), "IdPiece: ", piece["IdPiece"] + #for key, value in piece.items(): + #print >> open('/home/grandlyon/log/'+type_dossier+'_'+date_file.strftime('%Y%m%d%H%M%S')+'.wcs', 'a+'), key,": ", value + #self.print_wcs_files(type_dossier, date_file, key+": "+str(value)) + output_string += "\n" + output_string += " \n" + output_string += " file\n" + output_string += " "+str(piece["Reglementaire"]).title()+"\n" + hint = "" + if piece["Descriptif"]: hint = piece["Descriptif"] + output_string += " "+hint+"\n" + output_string += " objet"+str(objet["id"])+"_"+str(piece["IdPiece"])+"_"+str(piece["CodePiece"])+"\n" + output_string += " False\n" + output_string += " \n" + output_string += " none\n" + output_string += " 50M\n" + output_string += " True\n" + output_string += " "+str(id)+"\n" + output_string += "\n" + id += 1 + + output_string += " \n" + + #TODO: a voir pb utf8 (pour l'instant tous les caracteres accentues sont supprimes par le ignore) + output_string = output_string.encode('ascii', 'ignore') + print >> open('/home/grandlyon/log/'+type_dossier+'_'+date_file.strftime('%Y%m%d%H%M%S')+'.wcs', 'a+'), output_string + + return {'data': output_string}