From 67bd9619b6a1fa21cf332e60bbc0de51d131c31d Mon Sep 17 00:00:00 2001 From: Etienne Loupias Date: Thu, 8 Mar 2018 11:50:35 +0100 Subject: [PATCH] Version d'initialisation --- CartADS.egg-info/PKG-INFO | 10 + CartADS.egg-info/SOURCES.txt | 8 + CartADS.egg-info/dependency_links.txt | 1 + CartADS.egg-info/top_level.txt | 1 + README | 0 cartads/__init__.py | 0 cartads/__init__.pyc | Bin 0 -> 155 bytes cartads/formdata.py | 81 +++++ cartads/formdata.pyc | Bin 0 -> 3859 bytes cartads/migrations/0001_initial.py | 28 ++ cartads/migrations/0001_initial.pyc | Bin 0 -> 1660 bytes cartads/migrations/0002_auto_20180129_1403.py | 43 +++ .../migrations/0002_auto_20180129_1403.pyc | Bin 0 -> 1417 bytes cartads/migrations/0003_auto_20180129_1405.py | 18 ++ .../migrations/0003_auto_20180129_1405.pyc | Bin 0 -> 826 bytes .../0004_remove_cartads_application.py | 18 ++ .../0004_remove_cartads_application.pyc | Bin 0 -> 807 bytes cartads/migrations/__init__.py | 0 cartads/migrations/__init__.pyc | Bin 0 -> 166 bytes cartads/models.py | 299 ++++++++++++++++++ cartads/models.pyc | Bin 0 -> 10047 bytes setup.py | 11 + 22 files changed, 518 insertions(+) create mode 100644 CartADS.egg-info/PKG-INFO create mode 100644 CartADS.egg-info/SOURCES.txt create mode 100644 CartADS.egg-info/dependency_links.txt create mode 100644 CartADS.egg-info/top_level.txt create mode 100644 README create mode 100644 cartads/__init__.py create mode 100644 cartads/__init__.pyc create mode 100644 cartads/formdata.py create mode 100644 cartads/formdata.pyc create mode 100644 cartads/migrations/0001_initial.py create mode 100644 cartads/migrations/0001_initial.pyc create mode 100644 cartads/migrations/0002_auto_20180129_1403.py create mode 100644 cartads/migrations/0002_auto_20180129_1403.pyc create mode 100644 cartads/migrations/0003_auto_20180129_1405.py create mode 100644 cartads/migrations/0003_auto_20180129_1405.pyc create mode 100644 cartads/migrations/0004_remove_cartads_application.py create mode 100644 cartads/migrations/0004_remove_cartads_application.pyc create mode 100644 cartads/migrations/__init__.py create mode 100644 cartads/migrations/__init__.pyc create mode 100644 cartads/models.py create mode 100644 cartads/models.pyc create mode 100644 setup.py diff --git a/CartADS.egg-info/PKG-INFO b/CartADS.egg-info/PKG-INFO new file mode 100644 index 0000000..30f8845 --- /dev/null +++ b/CartADS.egg-info/PKG-INFO @@ -0,0 +1,10 @@ +Metadata-Version: 1.0 +Name: CartADS +Version: 0.0.0 +Summary: UNKNOWN +Home-page: http://example.net/ +Author: Grand Lyon +Author-email: toto@example.net +License: UNKNOWN +Description: UNKNOWN +Platform: UNKNOWN diff --git a/CartADS.egg-info/SOURCES.txt b/CartADS.egg-info/SOURCES.txt new file mode 100644 index 0000000..da32e77 --- /dev/null +++ b/CartADS.egg-info/SOURCES.txt @@ -0,0 +1,8 @@ +README +setup.py +CartADS.egg-info/PKG-INFO +CartADS.egg-info/SOURCES.txt +CartADS.egg-info/dependency_links.txt +CartADS.egg-info/top_level.txt +cartads/__init__.py +cartads/models.py \ No newline at end of file diff --git a/CartADS.egg-info/dependency_links.txt b/CartADS.egg-info/dependency_links.txt new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/CartADS.egg-info/dependency_links.txt @@ -0,0 +1 @@ + diff --git a/CartADS.egg-info/top_level.txt b/CartADS.egg-info/top_level.txt new file mode 100644 index 0000000..de78169 --- /dev/null +++ b/CartADS.egg-info/top_level.txt @@ -0,0 +1 @@ +cartads diff --git a/README b/README new file mode 100644 index 0000000..e69de29 diff --git a/cartads/__init__.py b/cartads/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/cartads/__init__.pyc b/cartads/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..db16a043cabb3f3725af5695979919b7ff99cf3d GIT binary patch literal 155 zcmZSn%*)04EiWpW0SXv_v;z?d0031AB%J^N literal 0 HcmV?d00001 diff --git a/cartads/formdata.py b/cartads/formdata.py new file mode 100644 index 0000000..5b22d4f --- /dev/null +++ b/cartads/formdata.py @@ -0,0 +1,81 @@ +# Copyright (C) 2016 Entr'ouvert +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +from datetime import datetime + + +def is_required(value): + if not value: + raise ValueError('is required') + return value + +def to_datetime(value): + if not value: + return + return datetime.strptime(value[:19], '%Y-%m-%dT%H:%M:%S') + +def default_to_now(value): + if not value: + return datetime.now() + return value + + +CREATION_SCHEMA = ( +) + +def list_schema_fields(schema): + for fieldname in schema: + yield fieldname[0] if isinstance(fieldname, tuple) else fieldname + +class FormData(object): + + def __init__(self, formdata, schema): + if not isinstance(formdata, dict): + raise ValueError('formdata must be a dict') + + if 'fields' in formdata and isinstance(formdata['fields'], dict): + values = formdata['fields'] + if 'extra' in formdata: + values.update(formdata['extra']) + else: + values = formdata + + # extract/create/validate fields according to schema + self.fields = {} + for fieldname in schema: + if isinstance(fieldname, tuple): + value = values.get(fieldname[0]) + for modifier in fieldname[1:]: + try: + value = modifier(value) + except ValueError as e: + raise ValueError('%s: %s' % (fieldname[0], e.message)) + fieldname = fieldname[0] + else: + value = values.get(fieldname) + if value is not None: + self.fields[fieldname] = value + + # extract attachments + self.attachments = [] + attachments = { + key: value + for key, value in values.items() + if isinstance(value, dict) and ('filename' in value and + 'content_type' in value and + 'content' in value) + } + for key in sorted(attachments.keys()): + self.attachments.append(attachments[key]) diff --git a/cartads/formdata.pyc b/cartads/formdata.pyc new file mode 100644 index 0000000000000000000000000000000000000000..20cb50d651b3904093c12eb0250ff0b8a6f7fc65 GIT binary patch literal 3859 zcmcIm-A@}w5T898g9!xk9YPb_G)_qyAW1(Jp{OmSN*+QblZFHZosQczoVgEkyQU!7 zQdIf}RO+A7mp=A?>QmK+_BVUB;SB0iu)XWqnYrEl&CJbA;ji)0ucwoBpSquW`2Pk& z|BXrFCnzL}h}MaObm$jQf@HxG4#}b=3M7X}395rr>Jh^|VuX}Ksz7z9m5A>D zb0o(|j*~o3a)RU}$qOVelDtInGRZ3>uadk*@;b>Wk~c_Bll*|>O_H}r&XBB-{E*~r zk{^-0L$XTpF3FEc&XT-G@)MGulDtoHj_UVleTd||y>p4=0;yrD1I`2H91^`*A0hdW zR%agpeef?nvjUVEVPkkknIKX=b9guyOBi|zQyc$R$XJ6N3i?@4Y?-UGthS=hVGeX9 zRlBVqRWjRl6wFs%*iui^G)Xhw5O{mcn*~93(#xP0wv$LLY^7c-!-FJV(5b)B^t4u~ z3PUy57tHxyYCNeIdjIt#jc|8wzIkA>Te!VjT*AJ(#OH{Tm=Jwr1#m2~TOb(OD2Ku- z&@}|F5fl}~!l468vF=J>ce((w`ev>g%~j>g>a)ky7muqM{u(5i6}3s5Y()#U#t zoF;L5F1wCn`Z$Y6IN6I9=VcI#bCNv>jE6vr^{Tz)igjTIfzigvPiK4k^EgDRy4MPg z3luo-COCZnqr#N24y05OqCr`&N~QfYfN7K1O!D(d>lv!|W>YRY@ zp_T8&h@zQ6;j!!VbZ(!fb9Aeo8i%Su!qgGo0o6+Lp_-HQLN&)c7OFY^QK;tF$3iv7 z&xdMG#G%S&$}y4B_X0nwGn^oc7(Ryn4AcI7PE^Yqcc>#cS+y}EUpbWCWg3}zDlRbf zO6(5P8mH~70tI-OENQsx1UiTjg0Zg*R~*wqxMot$1lr#QNSkKrfeK~pA!CF8zUvWZ z0Ys{CvjbgwnC4Wg88wMfVQdEb;mrLVhUS-9WjzVmvhGkVOWQu@YKA(D zv4o+2#Z$*krf-o!!vgd53O0%wOt({_w9(ZBXR2%9hBYwO9rQ8Q#;n++c7Ymp3FZ{G z61z=`ORNkvFdi?shIwH-L_59$={-k681}Zu7_x5dE+^C zN^~$uZRp?;D_`6For<{q&M2k-kmwAPU@ZMz+QZa9Z{yI_3>?&7W2|)#!5!iWdvp6l zwkI}6yzG=Iea8pk-i;#PVsZB!;kUMxVJVXwW>fR6N4Zok^W!75KTjw{?Gb8>F&E6` zjT_V{+l|W97-w0#+_h0GvfvznXI3;P&|afbiCWrJHdV!|$iUA^Qx+IDRMkG-78}h0 zM}aMiRsFb9)jqEa7#z{7EaOPZJh1VM-a7owbR27a%-L&$HV{x?Nca*o`kOwDVCc~x z;LqP2+AVc^9vhc+)Fys6Y|ZphdXey5TW&e%x{R!ScnF5!pk_?AYl6Rs<{uco@s2t; zt7Ztz8_^=4%0=nP9#)!-UKV9BEylzww;MISUTu*lHll3@T1{>bYF{z)5i|LsTS%ph zEmB&0STLd$F2mefdIqoPHdj4uU4^b7(snPMr06uPHlSuauh~?woaO6TfmUHXvud|v zt#QJ$kK2Y=*FMMEn#rm~i3|`IDIAF$P+MZ*6HI53sMuhx8^nQe-PfQs8-&m^PdGDT z6jr?ElnP~}s|j&QTo45@392f_oe9V;7s^gaOb$(n%yOPO3C#pnOSPxpzI^_}io3e> z?CFbdYhSPimkI7JePg#ht2!X2i5i)pe@9>RB+W4H_pk6|u|f`jpY-;?qI JPPtGn{s&~=rau4x literal 0 HcmV?d00001 diff --git a/cartads/migrations/0001_initial.py b/cartads/migrations/0001_initial.py new file mode 100644 index 0000000..404619e --- /dev/null +++ b/cartads/migrations/0001_initial.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('base', '0007_auto_20180129_1355'), + ] + + operations = [ + migrations.CreateModel( + name='CartADS', + fields=[ + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), + ('title', models.CharField(max_length=50, verbose_name='Title')), + ('description', models.TextField(verbose_name='Description')), + ('slug', models.SlugField(unique=True)), + ('log_level', models.CharField(default=b'INFO', max_length=10, verbose_name='Log Level', choices=[(b'NOTSET', b'NOTSET'), (b'DEBUG', b'DEBUG'), (b'INFO', b'INFO'), (b'WARNING', b'WARNING'), (b'ERROR', b'ERROR'), (b'CRITICAL', b'CRITICAL'), (b'FATAL', b'FATAL')])), + ('users', models.ManyToManyField(to='base.ApiUser', blank=True)), + ], + options={ + 'verbose_name': 'Webservice CartADS', + }, + ), + ] diff --git a/cartads/migrations/0001_initial.pyc b/cartads/migrations/0001_initial.pyc new file mode 100644 index 0000000000000000000000000000000000000000..10d03ff7c5a065126ff57e126941a752d42154e8 GIT binary patch literal 1660 zcmcIk-EZ4Q45utRiIb+yx;0&~ho$SbdhHTBDY_4!80I=jVIXk;*+ntG2(pe=E|n!u zcNf%s&Hk(XS$iF@kyQNgxR=QW#jm5tA9?iu+TQ&0Q9g{}_VMZcD^$RAh*9+SAO)Cs zF!aD#i^^`1*R;@+sF;QCapr0yTWwP;dmDWSQ_K>3sgKAY)&W}`pHpb!LQlE( zA|J2FoV7_^BAL?g{O-{4Or&{25w9_|T#mwVe!&hljMY~dGQ<~qi5 zzi{{qQ@t%-@cJR@7h7H+j}G0lOVVV>;~C8L3hyYw9iC++8(seqyk5H7%Kyu zJI0NBaL}IWw`36CQ5t3MC2%g~8F!!D-rpr+i8aOZHQPBv=yDC$V{%Pq0ZFEK}($&zh!) zo72cppD|5we__~<>E=bsH0ST-+H2CyJq&fGEnTvM=`7%V%pEYhMArOzweGD|o_b$+ z59s&GdtC9op6u9L;Kt6nf`ALi9i(D)6=g|&phg0nKqXO^$qV;?RUqAcRrd22?vsq# IPG#5s7k|rjrT_o{ literal 0 HcmV?d00001 diff --git a/cartads/migrations/0002_auto_20180129_1403.py b/cartads/migrations/0002_auto_20180129_1403.py new file mode 100644 index 0000000..eadf8e3 --- /dev/null +++ b/cartads/migrations/0002_auto_20180129_1403.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('cartads', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='cartads', + name='application', + field=models.CharField(default='CartADS', max_length=200, verbose_name='Application identifier'), + preserve_default=False, + ), + migrations.AddField( + model_name='cartads', + name='token_authorization', + field=models.CharField(default='', max_length=128, verbose_name='Token Authorization'), + preserve_default=False, + ), + migrations.AddField( + model_name='cartads', + name='token_url', + field=models.URLField(default='', max_length=256, verbose_name='Token URL'), + preserve_default=False, + ), + migrations.AddField( + model_name='cartads', + name='verify_cert', + field=models.BooleanField(default=True, verbose_name='Check HTTPS Certificate validity'), + ), + migrations.AddField( + model_name='cartads', + name='wsdl_url', + field=models.CharField(default='', max_length=256, verbose_name='WSDL URL'), + preserve_default=False, + ), + ] diff --git a/cartads/migrations/0002_auto_20180129_1403.pyc b/cartads/migrations/0002_auto_20180129_1403.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2528961bdc9a77635f07ea02c53c168fac104d97 GIT binary patch literal 1417 zcmcgs&2G~`5FXn}+Vlrn3Z)1M<(NyGA2@)75NWE4LqRAhLgawudN;|o8#}Uh3*m$W z55XhxK0E+?vu>Iei5^L;_3Z4-H{blMgJ0__KOUxom@a++-Y?0gybD3#@kkR*JQ{f9 z@!lux(?(w4I@Kz69WrI?he~Q;7*5DxWVLb7T|jpZ`UO(- zIn**4nX&o_GsEG|WpNfBD2S+u)xv9Rf)O9X~VSv!pA`D&0!Vq(B zwZxVUgq+F*MTwQnd+rXgM@NW5E`HD59nPaWjxwimojJt4k`5bG3N?f6r>T}vQYg5! z$C;HbYC6STbXTtqH7%C>BesokI*|=r&P3>0nl$n(ZcL*bt&v*G-OGdBi?M3V--{dF zz?8MQX=&JQww^Xy?Pp=@N%QgEbk^gq4o^|u#!?BYrK(rK|B+Ym|1IrYp1pBjnTz5L wt+5%3*8>!}Z-+RIl2N)RPF(q1#azTij!yayiMob7FWUQpJC}10HvH}253(ge)ju%hvNcqVV&jQIP0YyR1kH9QN1#TqNXJyC`9~*>NORjHeAm=Qq127Tq0%;uIkH8f zZB|3&8q-x?Gjf(s5A*5lNKW_jxl1V4RV_MBFnz%2cSt{>T_~MafB_!I%CjFy`J;2^o^54Ae+TY+cF)DCW#^M`JNbCeb+hy>606F6EVXexSYzvLFmw-BjJm?5Snw etl;$sbvDR@_6qRB9KNlY|IRopFT!^GQTzvCNW(1v literal 0 HcmV?d00001 diff --git a/cartads/migrations/0004_remove_cartads_application.py b/cartads/migrations/0004_remove_cartads_application.py new file mode 100644 index 0000000..59a2b16 --- /dev/null +++ b/cartads/migrations/0004_remove_cartads_application.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('cartads', '0003_auto_20180129_1405'), + ] + + operations = [ + migrations.RemoveField( + model_name='cartads', + name='application', + ), + ] diff --git a/cartads/migrations/0004_remove_cartads_application.pyc b/cartads/migrations/0004_remove_cartads_application.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1420122b54a054dac612d45b119551f8a03ed66c GIT binary patch literal 807 zcmcgqJx}B?5S_%y9t(#=#WnW>wg8glLjnmQbSGU0MW{$)nRs>ya^fg&%75So zz>IfcucX3??B|R<^WGba*X_-h-?pq^H3Y4f5QFcC00lgxFpEGZ@C@(-a9gIJQ@ELoC{O)HV-gYaJ2VY#U0IFN)E;|f+$846CQVH} z@0G7@>pb6U=#+7OOz`R>^2s!%zkitN9svXY&Eu3jjjmham@l7`-uN)G&)?e9eEfmn@|+ilbg{t zySEKyWNNF;!nT>~tE^MbVUNb({%2r+WkvR}t~-&DGsm(IW#uX?|5JX@Eed`$Y^Y;R zBQZ|K(I~oJ%H+OEIUD@Yld^(#5IU+KR6Dl^`YvcI_zi?SYXt#)qm0mz^JNb%n2+Ob I@5H;}9pn(jLI3~& literal 0 HcmV?d00001 diff --git a/cartads/migrations/__init__.py b/cartads/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/cartads/migrations/__init__.pyc b/cartads/migrations/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..21f8f8efa59fd03d869684966b00e47da092b8df GIT binary patch literal 166 zcmZSn%*(Y~GCwMr0SXv_v;zsh#3GVM=0(9 literal 0 HcmV?d00001 diff --git a/cartads/models.py b/cartads/models.py new file mode 100644 index 0000000..0976749 --- /dev/null +++ b/cartads/models.py @@ -0,0 +1,299 @@ +# Copyright (C) 2016 Entr'ouvert +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +import base64 +import json +import datetime +import uuid + +from email import encoders +from email.mime.audio import MIMEAudio +from email.mime.base import MIMEBase +from email.mime.image import MIMEImage +from email.mime.multipart import MIMEMultipart +from email.mime.text import MIMEText + +from suds.client import Client +from suds.transport import Reply +from suds.transport.http import HttpAuthenticated +import suds.sudsobject + +from django.db import models +from django.utils.translation import ugettext_lazy as _ +from django.core.cache import cache + +from passerelle.base.models import BaseResource +from passerelle.utils.api import endpoint + +from .formdata import FormData, CREATION_SCHEMA, list_schema_fields + + +class ParameterTypeError(Exception): + http_status = 400 + log_error = False + + +def fill_sudsobject_with_dict(sudsobject, fields, prefix=None): + for key, value in sudsobject: + if prefix: + attr = '%s_%s' % (prefix, key) + else: + attr = key + if isinstance(value, suds.sudsobject.Object): + fill_sudsobject_with_dict(value, fields, attr) + else: + if attr in fields: + # sudsobject.foo.bar <- fields['foo_bar'] + setattr(sudsobject, key, fields[attr]) + +def sudsobject_to_dict(sudsobject): + out = {} + for key, value in suds.sudsobject.asdict(sudsobject).iteritems(): + if hasattr(value, '__keylist__'): + out[key] = sudsobject_to_dict(value) + elif isinstance(value, list): + out[key] = [] + for item in value: + if hasattr(item, '__keylist__'): + out[key].append(sudsobject_to_dict(item)) + else: + out[key].append(item) + else: + out[key] = value + return out + + +class CartADS(BaseResource): + token_url = models.URLField(_('Token URL'), max_length=256) + token_authorization = models.CharField(_('Token Authorization'), max_length=128) + wsdl_url = models.CharField(_('WSDL URL'), max_length=256) # not URLField, it can be file:// + 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\\' + + category = _('Business Process Connectors') + + class Meta: + verbose_name = _('CartADS Webservices') + + def get_token(self, renew=False): + cache_key = 'cartads-%s-token' % self.id + if not renew: + token = cache.get(cache_key) + if token: + return token + headers = {'Authorization': 'Basic %s' % self.token_authorization} + resp = self.requests.post(self.token_url, headers=headers, + data={'grant_type': 'client_credentials'}, + verify=self.verify_cert).json() + token = '%s %s' % (resp.get('token_type'), resp.get('access_token')) + timeout = int(resp.get('expires_in')) + cache.set(cache_key, token, timeout) + self.logger.debug('new token: %s (timeout %ss)', token, timeout) + return token + + def get_client(self, attachments=[]): + class Transport(HttpAuthenticated): + def __init__(self, instance, attachments): + self.instance = instance + self.attachments = attachments + HttpAuthenticated.__init__(self) + + 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() + resp = self.instance.requests.post(request.url, data=request.message, + headers=request.headers, + verify=self.instance.verify_cert) + if resp.status_code == 401: + # ask for a new token, and retry + request.headers['Authorization'] = self.instance.get_token(renew=True) + resp = self.instance.requests.post(request.url, data=request.message, + headers=request.headers, + verify=self.instance.verify_cert) + + return Reply(resp.status_code, resp.headers, resp.content) + + return Client(url=self.wsdl_url, transport=Transport(self, attachments)) + + + @endpoint(perm='can_access', methods=['get','post']) + def create(self, request): + + # get creation fields from payload + try: + formdata = FormData(json.loads(request.body), CREATION_SCHEMA) + except ValueError as e: + raise ParameterTypeError(e.message) + + 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): + 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(), "b64_fileContent: ", b64_fileContent + + + # Pour l'instant pour test, on envoie le dernier fichier du formulaires + # TODO : construire le zip de tous les fichiers du form + + + # Nom du fichier zip a envoyer + fileName = str(uuid.uuid4()) + ".zip"; + + # test base64 + #b64_fileContent = "UEsDBBQAAAAAAMqEQUzI2HQpGgAAABoAAAAKAAAAdGVzdDAxLnR4dHRlc3QgYmFzZTY0IG1pbmkgdG90byB0YXRhUEsBAhQAFAAAAAAAyoRBTMjYdCkaAAAAGgAAAAoAAAAAAAAAAQAgAAAAAAAAAHRlc3QwMS50eHRQSwUGAAAAAAEAAQA4AAAAQgAAAAAA" + + # size_max doit etre un multiple de 4 pour avoir un nb de caracteres valide en base 64 (car 3 octets y sont encodes sur 4 caracteres) + # size_max choisi pour eviter erreur OpenSSL.SSL.WantWriteError due au openssl socket send buffer size (https://pyopenssl.org/en/stable/api/ssl.html) + # TODO: demander a EO si on peut l'augmenter, car en curl on peut envoyer plus de 7 Mo d'un coup d'apres nos tests + size_max = 65536 # 64 ko, d'apres test semble etre la limite par defaut du openssl socket send buffer size + + # 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, + '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)} + + + @classmethod + def creation_fields(cls): + '''used in cartads_detail.html template''' + return list_schema_fields(CREATION_SCHEMA) + + def get_token_cartads(self): + #TODO : a encoder d'apres les exemples php et c# fournispar GFI + return 'ieTluf0q6vwjitxope55YZ2ud0CEtuO9BBHr2hQaxySeDrz66mntHl83Wqj7oadMSyZqwSkzVdZJrQ92Zg2p3bwkAuv5yUzwmpBfdtAYYLE=' + + def get_type_compte_utilisateur(self): + #TODO : a encoder d'apres les exemples php et c# fournispar GFI + return 'ContactService' + + @endpoint(perm='can_access') + def get_communes(self, request): + resp = self.get_client().service.GetCommunes(self.get_token_cartads(), + self.get_type_compte_utilisateur() + ) + ''' + #TODO: Ca serait mieux mais ca marche pas... + resp = self.get_client().service.GetCommunes({ + 'token': self.get_token_cartads(), + 'typeCompteUtilisateur': self.get_type_compte_utilisateur(), + })''' + return {'data': sudsobject_to_dict(resp)} + + @endpoint(perm='can_access') + def get_objets_demande(self, request, type_dossier): + resp = self.get_client().service.GetObjetsDemande(self.get_token_cartads(), type_dossier) + + # 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 + out = {} + for key, value in suds.sudsobject.asdict(resp).iteritems(): + out[key] = [] + for item in value: + if hasattr(item, '__keylist__'): + out_item = {} + for key_item, value_item in suds.sudsobject.asdict(item).iteritems(): + out_item['id'] = item.Key + out_item['text'] = item.Value + out[key].append(out_item) + else: + item.id = item.Key + item.text = item.Value + out[key].append(item) + return {'data': out['KeyValueOfintstring']} + + @endpoint(perm='can_access') + def get_liste_pdf(self, request, type_dossier): + resp = self.get_client().service.GetListePdf(self.get_token_cartads(), + type_dossier, + self.get_type_compte_utilisateur() + ) + return {'data': sudsobject_to_dict(resp)} + + @endpoint(perm='can_access') + def get_pieces(self, request, type_dossier, objet_demande): + resp = self.get_client().service.GetPieces(self.get_token_cartads(), + type_dossier, + objet_demande + ) + return {'data': sudsobject_to_dict(resp)} diff --git a/cartads/models.pyc b/cartads/models.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7d6d88c104a5cfcfed8acb08e830d87188e7cf3c GIT binary patch literal 10047 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 h?N>ZENR4?P1#CFd+1-C-y@at