ajout depot de dossier

This commit is contained in:
Etienne Loupias 2018-03-29 15:37:56 +02:00
parent 8359e4ae19
commit 2e72492445
2 changed files with 228 additions and 72 deletions

View File

@ -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]

View File

@ -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="<rootpart@entrouvert.org>")
xml = MIMEText(None, _subtype='xml', _charset='utf-8')
xml.add_header('Content-ID', '<rootpart@entrouvert.org>')
# 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('<filename%s>%s</filename%s>' % (num, filename, num))
xml_payload = xml_payload.replace('<SOAP-ENV:Header/>',
'<SOAP-ENV:Header>%s</SOAP-ENV:Header>' % ''.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<bchars> 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 "<ns0:informationsComplementaires></ns0:informationsComplementaires>" 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("<ns0:informationsComplementaires></ns0:informationsComplementaires>",
"<ns0:informationsComplementaires><arr:KeyValueOfstringstring><arr:Key>traitementImmediat</arr:Key><arr:Value>1</arr:Value></arr:KeyValueOfstringstring></ns0:informationsComplementaires>")
'''
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 = "<!--#### A inserer apres field 'Un code de suivi de votre demande...' -->\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 += "<field>\n"
output_string += " <label>Pieces a joindre</label>\n"
output_string += " <type>page</type>\n"
output_string += " <condition>\n"
output_string += " <type>python</type>\n"
output_string += ' <value>form_var_objet_raw == "'+str(objet["id"])+'"</value>\n'
output_string += " </condition><id>"+str(id)+"</id>\n"
id += 1
output_string += " </field><field>\n"
output_string += ' <label>[is form_option_type_dossier "foo"] [end]'
output_string += "\n"
output_string += '&lt;span id="logo_commune"&gt;&lt;/span&gt;\n'
output_string += "\n"
output_string += "\n"
output_string += '&lt;script type="text/javascript"&gt;\n'
output_string += "function slugify(text)\n"
output_string += "{\n"
output_string += " return text.toString().toLowerCase()\n"
output_string += " .replace(/\s+/g, '-') // Replace spaces with -\n"
output_string += " .replace(/\'/g, '-') // Replace ' with -\n"
output_string += " .replace(/&#244;/g, 'o').replace(/&#233;/g, 'e').replace(/&#232;/g, 'e') // Remove accent\n"
output_string += " .replace(/[^\w\-]+/g, '') // Remove all non-word chars\n"
output_string += " .replace(/\-\-+/g, '-') // Replace multiple - with single -\n"
output_string += " .replace(/^-+/, '') // Trim - from start of text\n"
output_string += " .replace(/-+$/, ''); // Trim - from end of text\n"
output_string += "}\n"
output_string += "function setLogo()\n"
output_string += "{\n"
output_string += ' var selectedText ="[form_var_commune]";\n'
output_string += " var communeChanged = slugify(selectedText);\n"
output_string += " // Pour enlever arrondissement de Lyon\n"
output_string += ' if( selectedText.startsWith("Lyon") ) communeChanged = "lyon"\n'
output_string += ' $("#logo_commune").html(\'&lt;img src="[portal_url]static/grandlyon-gnm/producers/\'+communeChanged+\'.png" /&gt;\');\n'
output_string += "}\n"
output_string += "setLogo();\n"
output_string += "&lt;/script&gt;\n"
output_string += "\n"
output_string += "</label>\n"
output_string += " <type>comment</type>\n"
output_string += " <extra_css_class>imgCommune</extra_css_class>\n"
output_string += " <id>"+str(id)+"</id>\n"
id += 1
output_string += " </field><field>\n"
output_string += " <label>&lt;p&gt;&lt;strong&gt;2/ Votre dossier est pr&amp;ecirc;t &amp;agrave; &amp;ecirc;tre d&amp;eacute;pos&amp;eacute;.&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Merci de nous faire parvenir les pi&amp;egrave;ces ci-dessous.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;</label>\n"
output_string += " <type>comment</type>\n"
output_string += " <id>"+str(id)+"</id>\n"
id += 1
output_string += " </field><field>\n"
output_string += " <label>Cerfa rempli</label>\n"
output_string += " <type>file</type>\n"
output_string += " <required>True</required>\n"
output_string += " <varname>objet"+str(objet["id"])+"_cerfa</varname>\n"
output_string += " <in_listing>True</in_listing>\n"
output_string += " <prefill>\n"
output_string += " <type>none</type>\n"
output_string += " </prefill><max_file_size>200M</max_file_size>\n"
output_string += " <allow_portfolio_picking>True</allow_portfolio_picking>\n"
output_string += " <id>"+str(id)+"</id>\n"
id += 1
output_string += " </field>\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 += "<field>\n"
output_string += " <label>"+piece["Libelle"]+"</label>\n"
output_string += " <type>file</type>\n"
output_string += " <required>"+str(piece["Reglementaire"]).title()+"</required>\n"
hint = ""
if piece["Descriptif"]: hint = piece["Descriptif"]
output_string += " <hint>"+hint+"</hint>\n"
output_string += " <varname>objet"+str(objet["id"])+"_"+str(piece["IdPiece"])+"_"+str(piece["CodePiece"])+"</varname>\n"
output_string += " <in_listing>False</in_listing>\n"
output_string += " <prefill>\n"
output_string += " <type>none</type>\n"
output_string += " </prefill><max_file_size>50M</max_file_size>\n"
output_string += " <allow_portfolio_picking>True</allow_portfolio_picking>\n"
output_string += " <id>"+str(id)+"</id>\n"
output_string += "</field>\n"
id += 1
output_string += " </fields><options>\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}