inpython-package 1.0.8__tar.gz → 1.1.6__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {inpython_package-1.0.8/inpython_package.egg-info → inpython_package-1.1.6}/PKG-INFO +15 -2
- inpython_package-1.1.6/inpython/inqrcode/__init__.py +6 -0
- inpython_package-1.1.6/inpython/inqrcode/inqrcode.py +59 -0
- inpython_package-1.1.6/inpython/inqrcode/paymentqrcode.py +129 -0
- inpython_package-1.1.6/inpython/inrest/__init__.py +6 -0
- inpython_package-1.1.6/inpython/inrest/in_jwt.py +131 -0
- {inpython_package-1.0.8 → inpython_package-1.1.6}/inpython/intools/Servalux-devis.py +58 -58
- {inpython_package-1.0.8 → inpython_package-1.1.6}/inpython/intools/__init__.py +6 -6
- {inpython_package-1.0.8 → inpython_package-1.1.6}/inpython/intools/in_docx.py +61 -61
- {inpython_package-1.0.8 → inpython_package-1.1.6}/inpython/intools/in_projet.py +55 -55
- {inpython_package-1.0.8 → inpython_package-1.1.6}/inpython/intools/in_test.py +3 -3
- {inpython_package-1.0.8 → inpython_package-1.1.6}/inpython/intools/xls_to_csv.py +45 -45
- {inpython_package-1.0.8 → inpython_package-1.1.6/inpython_package.egg-info}/PKG-INFO +15 -2
- {inpython_package-1.0.8 → inpython_package-1.1.6}/inpython_package.egg-info/SOURCES.txt +5 -0
- inpython_package-1.1.6/inpython_package.egg-info/requires.txt +5 -0
- {inpython_package-1.0.8 → inpython_package-1.1.6}/setup.py +5 -2
- inpython_package-1.0.8/inpython_package.egg-info/requires.txt +0 -2
- {inpython_package-1.0.8 → inpython_package-1.1.6}/LICENSE.txt +0 -0
- {inpython_package-1.0.8 → inpython_package-1.1.6}/README.md +0 -0
- {inpython_package-1.0.8 → inpython_package-1.1.6}/inpython/__init__.py +0 -0
- {inpython_package-1.0.8 → inpython_package-1.1.6}/inpython/__main__.py +0 -0
- {inpython_package-1.0.8 → inpython_package-1.1.6}/inpython/aotools/__init__.py +0 -0
- {inpython_package-1.0.8 → inpython_package-1.1.6}/inpython/aotools/aogeo.py +0 -0
- {inpython_package-1.0.8 → inpython_package-1.1.6}/inpython/ingraph/__init__.py +0 -0
- {inpython_package-1.0.8 → inpython_package-1.1.6}/inpython/ingraph/ingraph.py +0 -0
- {inpython_package-1.0.8 → inpython_package-1.1.6}/inpython_package.egg-info/dependency_links.txt +0 -0
- {inpython_package-1.0.8 → inpython_package-1.1.6}/inpython_package.egg-info/top_level.txt +0 -0
- {inpython_package-1.0.8 → inpython_package-1.1.6}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: inpython-package
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.1.6
|
|
4
4
|
Summary: # Infodata's IN-Tools U2Python Package
|
|
5
5
|
Home-page: https://bitbucket.org/infodata-dev/inpython
|
|
6
6
|
Author: infodata
|
|
@@ -11,6 +11,19 @@ Description-Content-Type: text/markdown
|
|
|
11
11
|
License-File: LICENSE.txt
|
|
12
12
|
Requires-Dist: msal>=1.22
|
|
13
13
|
Requires-Dist: qrcode
|
|
14
|
+
Requires-Dist: requests
|
|
15
|
+
Requires-Dist: qrcode[pil]
|
|
16
|
+
Requires-Dist: dotenv
|
|
17
|
+
Dynamic: author
|
|
18
|
+
Dynamic: author-email
|
|
19
|
+
Dynamic: description
|
|
20
|
+
Dynamic: description-content-type
|
|
21
|
+
Dynamic: home-page
|
|
22
|
+
Dynamic: license
|
|
23
|
+
Dynamic: license-file
|
|
24
|
+
Dynamic: requires-dist
|
|
25
|
+
Dynamic: requires-python
|
|
26
|
+
Dynamic: summary
|
|
14
27
|
|
|
15
28
|
# README
|
|
16
29
|
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"""
|
|
2
|
+
script/fonction encode(ErrorCorrection: str = "Q", Valeur: str ) -> str:
|
|
3
|
+
qui execute python qrcode https://pypi.org/project/qrcode/ pour encoder la valeur
|
|
4
|
+
et retourner un tableau de 1010110
|
|
5
|
+
|
|
6
|
+
Usage :
|
|
7
|
+
- Python ...\inqrcode.py codeErr "Valeur"
|
|
8
|
+
Dans ce cas, la fonction sort sur un 'print(result)'
|
|
9
|
+
- from inpython.inqrcode import inqrcode.py
|
|
10
|
+
qrc = inqrcode.encode(codeErr, valeur)
|
|
11
|
+
|
|
12
|
+
"""
|
|
13
|
+
import qrcode
|
|
14
|
+
import sys
|
|
15
|
+
|
|
16
|
+
error_correction = {
|
|
17
|
+
'L': qrcode.ERROR_CORRECT_L,
|
|
18
|
+
'M': qrcode.ERROR_CORRECT_M,
|
|
19
|
+
'Q': qrcode.ERROR_CORRECT_Q,
|
|
20
|
+
'H': qrcode.ERROR_CORRECT_H,
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
def encode(codeErr: str = "M", data: str = "") -> str:
|
|
24
|
+
"""fonction qui encode la valeur pour en faire un qrcode avec le module POST
|
|
25
|
+
|
|
26
|
+
Args:
|
|
27
|
+
codeErr (str, optional): Error Correcton level. Defaults to "M".
|
|
28
|
+
The error_correction parameter controls the error correction used for the QR Code. The following four constants are made available on the qrcode package:
|
|
29
|
+
ERROR_CORRECT_L : About 7% or less errors can be corrected.
|
|
30
|
+
ERROR_CORRECT_M (default) : About 15% or less errors can be corrected.
|
|
31
|
+
ERROR_CORRECT_Q : About 25% or less errors can be corrected.
|
|
32
|
+
ERROR_CORRECT_H. : About 30% or less errors can be corrected
|
|
33
|
+
data (str, optional): _description_. Defaults to "".
|
|
34
|
+
|
|
35
|
+
Returns:
|
|
36
|
+
str: sequence de 01010101 emballé sous le format : qrcode<data>\\n-----\\n01010...\\n-----\\n. Separator 'lineFeed' (char(10))
|
|
37
|
+
Exemple :
|
|
38
|
+
qrcode<content_of_arg'data'>
|
|
39
|
+
-----
|
|
40
|
+
111111101111101111111
|
|
41
|
+
100000100011101000001
|
|
42
|
+
-----
|
|
43
|
+
|
|
44
|
+
"""
|
|
45
|
+
qr = qrcode.QRCode(error_correction=error_correction[codeErr])
|
|
46
|
+
qr.add_data(data)
|
|
47
|
+
qr.border = 0
|
|
48
|
+
qrbool = qr.get_matrix()
|
|
49
|
+
out = sys.stdout
|
|
50
|
+
result = 'qrcode<' + data + '>\n' + '-----\n'
|
|
51
|
+
for l in qrbool:
|
|
52
|
+
s = ''.join(['1' if x else '0' for x in l])
|
|
53
|
+
result += s + '\n'
|
|
54
|
+
result += '-----\n'
|
|
55
|
+
return result
|
|
56
|
+
|
|
57
|
+
if __name__ == "__main__":
|
|
58
|
+
print(encode(sys.argv[1],sys.argv[2]))
|
|
59
|
+
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import requests
|
|
2
|
+
import qrcode
|
|
3
|
+
from dotenv import load_dotenv
|
|
4
|
+
import os
|
|
5
|
+
from PIL import Image
|
|
6
|
+
|
|
7
|
+
load_dotenv()
|
|
8
|
+
|
|
9
|
+
ADYEN_API_KEY = os.getenv("ADYEN_API_KEY")
|
|
10
|
+
MERCHANT_ACCOUNT = os.getenv("MERCHANT_ACCOUNT")
|
|
11
|
+
URL = os.getenv("ADYEN_API_URL")
|
|
12
|
+
|
|
13
|
+
HEADERS = {
|
|
14
|
+
"X-API-Key": ADYEN_API_KEY,
|
|
15
|
+
"Content-Type": "application/json"
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
def create_payment_link_adyen(amount_cents: int, currency: str, reference: str, mode: str = 1, logo_path: str = None, env_path: str = None, qrcode_path: str = None ) -> str:
|
|
19
|
+
"""Crée un lien de paiement via l'API Adyen. Si mode=2, génère aussi un QR code (avec logo si fourni). Si env_path est fourni, charge les variables d'environnement depuis ce fichier."""
|
|
20
|
+
if env_path and os.path.exists(env_path):
|
|
21
|
+
from dotenv import dotenv_values
|
|
22
|
+
env_vars = dotenv_values(env_path)
|
|
23
|
+
adyen_api_key = env_vars.get("ADYEN_API_KEY")
|
|
24
|
+
merchant_account = env_vars.get("MERCHANT_ACCOUNT")
|
|
25
|
+
url = env_vars.get("ADYEN_API_URL")
|
|
26
|
+
else:
|
|
27
|
+
adyen_api_key = ADYEN_API_KEY
|
|
28
|
+
merchant_account = MERCHANT_ACCOUNT
|
|
29
|
+
url = URL
|
|
30
|
+
headers = {
|
|
31
|
+
"X-API-Key": adyen_api_key,
|
|
32
|
+
"Content-Type": "application/json"
|
|
33
|
+
}
|
|
34
|
+
payload = {
|
|
35
|
+
"amount": {
|
|
36
|
+
"value": amount_cents,
|
|
37
|
+
"currency": currency
|
|
38
|
+
},
|
|
39
|
+
"reference": reference,
|
|
40
|
+
"merchantAccount": merchant_account
|
|
41
|
+
}
|
|
42
|
+
response = requests.post(url, headers=headers, json=payload)
|
|
43
|
+
if response.status_code != 200:
|
|
44
|
+
response.raise_for_status()
|
|
45
|
+
data = response.json()
|
|
46
|
+
payment_url = data["url"]
|
|
47
|
+
if mode == 2:
|
|
48
|
+
qr_path = generate_qr_code(payment_url, reference, logo_path,qrcode_path)
|
|
49
|
+
return qr_path
|
|
50
|
+
return payment_url
|
|
51
|
+
|
|
52
|
+
def generate_qr_code(url: str, reference: str, logo_path: str = None, qrcode_path: str = None) -> None:
|
|
53
|
+
"""Génère un QR code dans le dossier ./qrcode/ (au même niveau que paymentqrcode.py), avec logo si fourni. Crée/écrase un fichier qrcode_logs.txt pour le diagnostic."""
|
|
54
|
+
import traceback
|
|
55
|
+
base_dir = os.path.dirname(os.path.abspath(__file__))
|
|
56
|
+
output_dir = os.path.join(base_dir, "qrcode")
|
|
57
|
+
|
|
58
|
+
os.makedirs(output_dir, exist_ok=True)
|
|
59
|
+
print("qrcode_path : ",qrcode_path)
|
|
60
|
+
if qrcode_path:
|
|
61
|
+
filename = os.path.join(qrcode_path, f"{reference}.jpg")
|
|
62
|
+
log_file = os.path.join(qrcode_path, "qrcode_debug.log")
|
|
63
|
+
else:
|
|
64
|
+
filename = os.path.join(output_dir, f"{reference}.jpg")
|
|
65
|
+
log_file = os.path.join(output_dir, "qrcode_debug.log")
|
|
66
|
+
|
|
67
|
+
# Supprime le fichier s’il existe
|
|
68
|
+
if os.path.exists(log_file):
|
|
69
|
+
os.remove(log_file)
|
|
70
|
+
|
|
71
|
+
log_lines = []
|
|
72
|
+
try:
|
|
73
|
+
qr = qrcode.QRCode(
|
|
74
|
+
version=1,
|
|
75
|
+
error_correction=qrcode.constants.ERROR_CORRECT_H,
|
|
76
|
+
box_size=10,
|
|
77
|
+
border=4,
|
|
78
|
+
)
|
|
79
|
+
qr.add_data(url)
|
|
80
|
+
qr.make(fit=True)
|
|
81
|
+
img_qr = qr.make_image(fill_color="black", back_color="white").convert('RGB')
|
|
82
|
+
log_lines.append(f"QR code généré pour l'URL: {url}\n")
|
|
83
|
+
if logo_path:
|
|
84
|
+
log_lines.append(f"Chemin du logo fourni: {logo_path}\n")
|
|
85
|
+
if os.path.exists(logo_path):
|
|
86
|
+
try:
|
|
87
|
+
logo = Image.open(logo_path)
|
|
88
|
+
log_lines.append(f"Logo ouvert avec succès. Mode: {logo.mode}, Taille: {logo.size}\n")
|
|
89
|
+
qr_width, qr_height = img_qr.size
|
|
90
|
+
logo_size = int(qr_width * 0.2)
|
|
91
|
+
logo = logo.resize((logo_size, logo_size), Image.LANCZOS)
|
|
92
|
+
log_lines.append(f"Logo redimensionné à: {logo.size}\n")
|
|
93
|
+
pos = ((qr_width - logo_size) // 2, (qr_height - logo_size) // 2)
|
|
94
|
+
img_qr.paste(logo, pos, mask=logo if logo.mode == 'RGBA' else None)
|
|
95
|
+
log_lines.append(f"Logo collé au centre du QR code.\n")
|
|
96
|
+
except Exception as e:
|
|
97
|
+
log_lines.append(f"Erreur lors de l'ouverture ou du collage du logo: {e}\n{traceback.format_exc()}\n")
|
|
98
|
+
else:
|
|
99
|
+
log_lines.append(f"Logo non trouvé : {logo_path}, QR code généré sans logo.\n")
|
|
100
|
+
else:
|
|
101
|
+
log_lines.append("Aucun chemin de logo fourni, QR code généré sans logo.\n")
|
|
102
|
+
img_qr.save(filename, format="JPEG")
|
|
103
|
+
log_lines.append(f"QR code enregistré : {filename}\n")
|
|
104
|
+
except Exception as e:
|
|
105
|
+
log_lines.append(f"Erreur générale lors de la génération du QR code: {e}\n{traceback.format_exc()}\n")
|
|
106
|
+
# Toujours écrire le log, même si une exception a eu lieu
|
|
107
|
+
with open(log_file, 'w') as f:
|
|
108
|
+
f.writelines(log_lines)
|
|
109
|
+
return filename
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def clean(s):
|
|
113
|
+
return s.strip('"').strip("'")
|
|
114
|
+
|
|
115
|
+
if __name__ == "__main__":
|
|
116
|
+
import sys
|
|
117
|
+
try:
|
|
118
|
+
# Utilisation : python paymentqrcode.py <mode> <montant> <devise> <reference> [chemin_logo] [chemin_env]
|
|
119
|
+
mode = int(clean(sys.argv[1]))
|
|
120
|
+
amount = int(clean(sys.argv[2]))
|
|
121
|
+
currency = sys.argv[3]
|
|
122
|
+
reference = sys.argv[4]
|
|
123
|
+
logo_path = sys.argv[5] if len(sys.argv) > 5 else ''
|
|
124
|
+
env_path = sys.argv[6] if len(sys.argv) > 6 else ''
|
|
125
|
+
qrcode_path = sys.argv[7] if len(sys.argv) > 7 else ''
|
|
126
|
+
result = create_payment_link_adyen(amount, currency, reference, mode, logo_path, env_path,qrcode_path)
|
|
127
|
+
print(result)
|
|
128
|
+
except Exception as e:
|
|
129
|
+
print("Erreur :", e)
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
#--------------------------------------------------------
|
|
2
|
+
# Manipulates a Json web token
|
|
3
|
+
#
|
|
4
|
+
#--------------------------------------------------------
|
|
5
|
+
# 22/08/2024 (JCD) : Creation fonction generateJwtClientAssertion
|
|
6
|
+
#--------------------------------------------------------
|
|
7
|
+
from cryptography.hazmat.primitives.serialization import pkcs12
|
|
8
|
+
from cryptography.hazmat.primitives import serialization
|
|
9
|
+
from cryptography.hazmat.backends import default_backend
|
|
10
|
+
import jwt
|
|
11
|
+
import datetime
|
|
12
|
+
import sys
|
|
13
|
+
import getopt
|
|
14
|
+
|
|
15
|
+
# Generates a jwt client assertion from a private key
|
|
16
|
+
def generateJwtClientAssertion(mode,path_certificate,private_key,client_id,audience,expirationTime=10):
|
|
17
|
+
""" Return jwt token assertion
|
|
18
|
+
|
|
19
|
+
Parameters
|
|
20
|
+
------------
|
|
21
|
+
mode:int
|
|
22
|
+
= 1 : Private key
|
|
23
|
+
= 2 : Private password
|
|
24
|
+
path_certificate: string
|
|
25
|
+
Path crt/cer file if mode = 1
|
|
26
|
+
Path pfx file if mode = 2
|
|
27
|
+
private_key: byte
|
|
28
|
+
Path key file file if mode = 1
|
|
29
|
+
Private password if mode = 2
|
|
30
|
+
client_id: string
|
|
31
|
+
audience: string
|
|
32
|
+
expirationTime: string, Optional
|
|
33
|
+
in minutes. Default to 10 minutes
|
|
34
|
+
"""
|
|
35
|
+
try:
|
|
36
|
+
if mode != "1" and mode != "2" :
|
|
37
|
+
raise Exception("Unmanaged mode")
|
|
38
|
+
|
|
39
|
+
if not expirationTime:
|
|
40
|
+
expirationTime = 10
|
|
41
|
+
else:
|
|
42
|
+
expirationTime = int(expirationTime)
|
|
43
|
+
|
|
44
|
+
# Load the public certificate
|
|
45
|
+
with open(path_certificate, "rb") as cert_file:
|
|
46
|
+
certificate_data = cert_file.read()
|
|
47
|
+
|
|
48
|
+
# Load the private key
|
|
49
|
+
if mode == "1":
|
|
50
|
+
with open(private_key, "rb") as key_file:
|
|
51
|
+
private_key = serialization.load_pem_private_key(
|
|
52
|
+
key_file.read(),
|
|
53
|
+
password=None,
|
|
54
|
+
backend=default_backend()
|
|
55
|
+
)
|
|
56
|
+
else:
|
|
57
|
+
private_key, certificate, additional_certs = pkcs12.load_key_and_certificates(
|
|
58
|
+
certificate_data, private_key.encode(), backend=default_backend()
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
now = datetime.datetime.now(datetime.timezone.utc)
|
|
62
|
+
# Define the JWT claims
|
|
63
|
+
claims = {
|
|
64
|
+
"iss": client_id, # The issuer, typically your client ID
|
|
65
|
+
"sub": client_id, # The subject, typically your client ID
|
|
66
|
+
"aud": audience, # The audience, typically the token endpoint URL
|
|
67
|
+
"exp": now + datetime.timedelta(expirationTime), # Expiration time
|
|
68
|
+
"jti": "unique-identifier", # JWT ID, a unique identifier for the JWT
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
# Create the JWT (client assertion)
|
|
72
|
+
if mode == 1:
|
|
73
|
+
client_assertion = jwt.encode(
|
|
74
|
+
claims,
|
|
75
|
+
private_key,
|
|
76
|
+
algorithm="RS256",
|
|
77
|
+
headers={"x5c": [certificate_data.decode("utf-8").replace("\n", "")]}
|
|
78
|
+
)
|
|
79
|
+
else:
|
|
80
|
+
client_assertion = jwt.encode(
|
|
81
|
+
claims, private_key, algorithm="RS256", headers={"alg": "RS256","typ": "JWT"}
|
|
82
|
+
)
|
|
83
|
+
return client_assertion
|
|
84
|
+
except:
|
|
85
|
+
raise # so that the caller receives the exception
|
|
86
|
+
|
|
87
|
+
def main(argv):
|
|
88
|
+
#mode = "1"
|
|
89
|
+
#private_key = "C:\\TRF\\cleanup\\Cleanup1_private.key"
|
|
90
|
+
#path_certificate = "C:\\TRF\\cleanup\\Cleanup1_request.crt"
|
|
91
|
+
#client_id = "self_service_chaman_109660_shr5ppy83v"
|
|
92
|
+
|
|
93
|
+
#mode = "2"
|
|
94
|
+
#path_certificate = "/tmp/jcd/CermiaRest.pfx"
|
|
95
|
+
#private_key = "2024infodd1648!" # Use b'' for an empty password
|
|
96
|
+
#client_id = "self_service_chaman_108306_safnfiag3h"
|
|
97
|
+
#audience = "https://services.socialsecurity.be/REST/oauth/v5/token"
|
|
98
|
+
mode = ''
|
|
99
|
+
private_key = ''
|
|
100
|
+
path_certificate = ''
|
|
101
|
+
client_id = ''
|
|
102
|
+
audience = ''
|
|
103
|
+
expirationTime = None
|
|
104
|
+
try:
|
|
105
|
+
opts, args = getopt.getopt(argv, "m:k:x:c:a:e:", ["mode=", "private_key=", "path_certificate=", "client_id=", "audience=", "expirationTime="])
|
|
106
|
+
except getopt.GetoptError:
|
|
107
|
+
print('script.py -i <inputfile> -o <outputfile>')
|
|
108
|
+
sys.exit(2)
|
|
109
|
+
|
|
110
|
+
for opt, arg in opts:
|
|
111
|
+
if opt in ("-m", "--mode"):
|
|
112
|
+
mode = arg
|
|
113
|
+
elif opt in ("-k", "--private_key"):
|
|
114
|
+
private_key = arg
|
|
115
|
+
elif opt in ("-x", "--path_certificate"):
|
|
116
|
+
path_certificate = arg
|
|
117
|
+
elif opt in ("-c", "--client_id"):
|
|
118
|
+
client_id = arg
|
|
119
|
+
elif opt in ("-a", "--audience"):
|
|
120
|
+
audience = arg
|
|
121
|
+
elif opt in ("-e", "--expirationTime"):
|
|
122
|
+
if arg != "":
|
|
123
|
+
expirationTime = arg
|
|
124
|
+
|
|
125
|
+
result = generateJwtClientAssertion(mode,path_certificate,private_key,client_id,audience,expirationTime)
|
|
126
|
+
print(result)
|
|
127
|
+
|
|
128
|
+
if __name__ == "__main__":
|
|
129
|
+
main(sys.argv[1:])
|
|
130
|
+
|
|
131
|
+
|
|
@@ -1,58 +1,58 @@
|
|
|
1
|
-
from docx import Document
|
|
2
|
-
|
|
3
|
-
def chk_br(par):
|
|
4
|
-
for run in par.r_lst:
|
|
5
|
-
if len(run.br_lst) > 0:
|
|
6
|
-
return(True)
|
|
7
|
-
return(False)
|
|
8
|
-
|
|
9
|
-
def build_word_file(doc_directory,fab_filename,skipped_pg_br,keeped_pg_br):
|
|
10
|
-
tmp_file = doc_directory + "/schemas.docx"
|
|
11
|
-
|
|
12
|
-
print(fab_filename)
|
|
13
|
-
doc_fab = Document(fab_filename)
|
|
14
|
-
doc_fab.save(tmp_file)
|
|
15
|
-
doc_tmp = Document(tmp_file)
|
|
16
|
-
|
|
17
|
-
# extraction des pages du docuemnt fabriquant
|
|
18
|
-
num_page_breaks = 0
|
|
19
|
-
|
|
20
|
-
state = 0
|
|
21
|
-
|
|
22
|
-
for elt_idx, elt in enumerate(doc_tmp.element.body):
|
|
23
|
-
print(elt.tag)
|
|
24
|
-
if state == 0:
|
|
25
|
-
if elt.tag == "{http://schemas.openxmlformats.org/wordprocessingml/2006/main}p":
|
|
26
|
-
if chk_br(elt):
|
|
27
|
-
num_page_breaks += 1
|
|
28
|
-
if num_page_breaks == 2:
|
|
29
|
-
doc_tmp.save(tmp_file)
|
|
30
|
-
state = 1
|
|
31
|
-
doc_tmp.element.body.remove(elt)
|
|
32
|
-
elif state == 1:
|
|
33
|
-
if elt.tag == "{http://schemas.openxmlformats.org/wordprocessingml/2006/main}p":
|
|
34
|
-
if chk_br(elt):
|
|
35
|
-
num_page_breaks += 1
|
|
36
|
-
if num_page_breaks == 3:
|
|
37
|
-
state = 2
|
|
38
|
-
doc_tmp.element.body.remove(elt)
|
|
39
|
-
#doc_tmp.add_paragraph()
|
|
40
|
-
#elif elt.tag == "{http://schemas.openxmlformats.org/wordprocessingml/2006/main}tbl":
|
|
41
|
-
#table_copy(elt, doc_fab, doc_tmp)
|
|
42
|
-
elif state == 2:
|
|
43
|
-
if elt.tag != "{http://schemas.openxmlformats.org/wordprocessingml/2006/main}sectPr":
|
|
44
|
-
doc_tmp.element.body.remove(elt)
|
|
45
|
-
|
|
46
|
-
print("save " + tmp_file)
|
|
47
|
-
doc_tmp.save(tmp_file)
|
|
48
|
-
|
|
49
|
-
return(tmp_file)
|
|
50
|
-
|
|
51
|
-
def build_devis(doc_directory,fab_filename,startdoc,end_doc):
|
|
52
|
-
tmp_doc = build_word_file(doc_directory,fab_filename,2,1)
|
|
53
|
-
print(tmp_doc)
|
|
54
|
-
|
|
55
|
-
doc_dir = "Q:/is/chantier/1000/"
|
|
56
|
-
fab_fn = "Q:/is/chantier/1000/FABRIQUANT/1000.docx"
|
|
57
|
-
|
|
58
|
-
build_devis(doc_dir,fab_fn,"","")
|
|
1
|
+
from docx import Document
|
|
2
|
+
|
|
3
|
+
def chk_br(par):
|
|
4
|
+
for run in par.r_lst:
|
|
5
|
+
if len(run.br_lst) > 0:
|
|
6
|
+
return(True)
|
|
7
|
+
return(False)
|
|
8
|
+
|
|
9
|
+
def build_word_file(doc_directory,fab_filename,skipped_pg_br,keeped_pg_br):
|
|
10
|
+
tmp_file = doc_directory + "/schemas.docx"
|
|
11
|
+
|
|
12
|
+
print(fab_filename)
|
|
13
|
+
doc_fab = Document(fab_filename)
|
|
14
|
+
doc_fab.save(tmp_file)
|
|
15
|
+
doc_tmp = Document(tmp_file)
|
|
16
|
+
|
|
17
|
+
# extraction des pages du docuemnt fabriquant
|
|
18
|
+
num_page_breaks = 0
|
|
19
|
+
|
|
20
|
+
state = 0
|
|
21
|
+
|
|
22
|
+
for elt_idx, elt in enumerate(doc_tmp.element.body):
|
|
23
|
+
print(elt.tag)
|
|
24
|
+
if state == 0:
|
|
25
|
+
if elt.tag == "{http://schemas.openxmlformats.org/wordprocessingml/2006/main}p":
|
|
26
|
+
if chk_br(elt):
|
|
27
|
+
num_page_breaks += 1
|
|
28
|
+
if num_page_breaks == 2:
|
|
29
|
+
doc_tmp.save(tmp_file)
|
|
30
|
+
state = 1
|
|
31
|
+
doc_tmp.element.body.remove(elt)
|
|
32
|
+
elif state == 1:
|
|
33
|
+
if elt.tag == "{http://schemas.openxmlformats.org/wordprocessingml/2006/main}p":
|
|
34
|
+
if chk_br(elt):
|
|
35
|
+
num_page_breaks += 1
|
|
36
|
+
if num_page_breaks == 3:
|
|
37
|
+
state = 2
|
|
38
|
+
doc_tmp.element.body.remove(elt)
|
|
39
|
+
#doc_tmp.add_paragraph()
|
|
40
|
+
#elif elt.tag == "{http://schemas.openxmlformats.org/wordprocessingml/2006/main}tbl":
|
|
41
|
+
#table_copy(elt, doc_fab, doc_tmp)
|
|
42
|
+
elif state == 2:
|
|
43
|
+
if elt.tag != "{http://schemas.openxmlformats.org/wordprocessingml/2006/main}sectPr":
|
|
44
|
+
doc_tmp.element.body.remove(elt)
|
|
45
|
+
|
|
46
|
+
print("save " + tmp_file)
|
|
47
|
+
doc_tmp.save(tmp_file)
|
|
48
|
+
|
|
49
|
+
return(tmp_file)
|
|
50
|
+
|
|
51
|
+
def build_devis(doc_directory,fab_filename,startdoc,end_doc):
|
|
52
|
+
tmp_doc = build_word_file(doc_directory,fab_filename,2,1)
|
|
53
|
+
print(tmp_doc)
|
|
54
|
+
|
|
55
|
+
doc_dir = "Q:/is/chantier/1000/"
|
|
56
|
+
fab_fn = "Q:/is/chantier/1000/FABRIQUANT/1000.docx"
|
|
57
|
+
|
|
58
|
+
build_devis(doc_dir,fab_fn,"","")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# inpython.ingraph init file
|
|
2
|
-
# executed when 'from inpython.ingraph import *'
|
|
3
|
-
|
|
4
|
-
# !! update the list when new modules are added !!
|
|
5
|
-
|
|
6
|
-
__all__ = ["xls_to_csv", "in_projet", "in_docx","in_test"]
|
|
1
|
+
# inpython.ingraph init file
|
|
2
|
+
# executed when 'from inpython.ingraph import *'
|
|
3
|
+
|
|
4
|
+
# !! update the list when new modules are added !!
|
|
5
|
+
|
|
6
|
+
__all__ = ["xls_to_csv", "in_projet", "in_docx","in_test"]
|
|
@@ -1,61 +1,61 @@
|
|
|
1
|
-
from docx import Document
|
|
2
|
-
from docxcompose.composer import Composer
|
|
3
|
-
|
|
4
|
-
def chk_br(par):
|
|
5
|
-
for run in par.r_lst:
|
|
6
|
-
if len(run.br_lst) > 0:
|
|
7
|
-
return(True)
|
|
8
|
-
return(False)
|
|
9
|
-
|
|
10
|
-
def doc_extract(doc_directory,fab_filename,skipped_pg_br,keeped_pg_br):
|
|
11
|
-
tmp_file = doc_directory + "/schemas.docx"
|
|
12
|
-
|
|
13
|
-
doc_fab = Document(fab_filename)
|
|
14
|
-
doc_fab.save(tmp_file)
|
|
15
|
-
doc_tmp = Document(tmp_file)
|
|
16
|
-
|
|
17
|
-
# extraction des pages du docuemnt fabriquant
|
|
18
|
-
num_page_breaks = 0
|
|
19
|
-
|
|
20
|
-
state = 0
|
|
21
|
-
|
|
22
|
-
for elt_idx, elt in enumerate(doc_tmp.element.body):
|
|
23
|
-
if state == 0:
|
|
24
|
-
if elt.tag == "{http://schemas.openxmlformats.org/wordprocessingml/2006/main}p":
|
|
25
|
-
if chk_br(elt):
|
|
26
|
-
num_page_breaks += 1
|
|
27
|
-
if num_page_breaks == 2:
|
|
28
|
-
doc_tmp.save(tmp_file)
|
|
29
|
-
state = 1
|
|
30
|
-
doc_tmp.element.body.remove(elt)
|
|
31
|
-
elif state == 1:
|
|
32
|
-
if elt.tag == "{http://schemas.openxmlformats.org/wordprocessingml/2006/main}p":
|
|
33
|
-
if chk_br(elt):
|
|
34
|
-
num_page_breaks += 1
|
|
35
|
-
if num_page_breaks == 3:
|
|
36
|
-
state = 2
|
|
37
|
-
doc_tmp.element.body.remove(elt)
|
|
38
|
-
#doc_tmp.add_paragraph()
|
|
39
|
-
#elif elt.tag == "{http://schemas.openxmlformats.org/wordprocessingml/2006/main}tbl":
|
|
40
|
-
#table_copy(elt, doc_fab, doc_tmp)
|
|
41
|
-
elif state == 2:
|
|
42
|
-
if elt.tag != "{http://schemas.openxmlformats.org/wordprocessingml/2006/main}sectPr":
|
|
43
|
-
doc_tmp.element.body.remove(elt)
|
|
44
|
-
|
|
45
|
-
doc_tmp.save(tmp_file)
|
|
46
|
-
|
|
47
|
-
return(tmp_file)
|
|
48
|
-
|
|
49
|
-
def compose_doc(base_file,files_list,final_doc):
|
|
50
|
-
files_list = files_list.split(";")
|
|
51
|
-
master = Document(base_file)
|
|
52
|
-
composer = Composer(master)
|
|
53
|
-
for filename in files_list:
|
|
54
|
-
doc_temp = Document(filename)
|
|
55
|
-
composer.append(doc_temp)
|
|
56
|
-
composer.save(final_doc)
|
|
57
|
-
return
|
|
58
|
-
|
|
59
|
-
if __name__ == '__main__':
|
|
60
|
-
flist = ['//winprod/commun/is/chantier/1000/schemas.docx', '//winprod/commun/is/chantier/1000/1000_DETAIL.docx', '//winprod/commun/is/chantier/_doc_base/Formulaire_ALU_cgv.docx']
|
|
61
|
-
compose_doc('//winprod/commun/is/chantier/_doc_base/Formulaire_ALU_1-3.docx',flist,'//winprod/commun/is/chantier/1000/Devis.docx')
|
|
1
|
+
from docx import Document
|
|
2
|
+
from docxcompose.composer import Composer
|
|
3
|
+
|
|
4
|
+
def chk_br(par):
|
|
5
|
+
for run in par.r_lst:
|
|
6
|
+
if len(run.br_lst) > 0:
|
|
7
|
+
return(True)
|
|
8
|
+
return(False)
|
|
9
|
+
|
|
10
|
+
def doc_extract(doc_directory,fab_filename,skipped_pg_br,keeped_pg_br):
|
|
11
|
+
tmp_file = doc_directory + "/schemas.docx"
|
|
12
|
+
|
|
13
|
+
doc_fab = Document(fab_filename)
|
|
14
|
+
doc_fab.save(tmp_file)
|
|
15
|
+
doc_tmp = Document(tmp_file)
|
|
16
|
+
|
|
17
|
+
# extraction des pages du docuemnt fabriquant
|
|
18
|
+
num_page_breaks = 0
|
|
19
|
+
|
|
20
|
+
state = 0
|
|
21
|
+
|
|
22
|
+
for elt_idx, elt in enumerate(doc_tmp.element.body):
|
|
23
|
+
if state == 0:
|
|
24
|
+
if elt.tag == "{http://schemas.openxmlformats.org/wordprocessingml/2006/main}p":
|
|
25
|
+
if chk_br(elt):
|
|
26
|
+
num_page_breaks += 1
|
|
27
|
+
if num_page_breaks == 2:
|
|
28
|
+
doc_tmp.save(tmp_file)
|
|
29
|
+
state = 1
|
|
30
|
+
doc_tmp.element.body.remove(elt)
|
|
31
|
+
elif state == 1:
|
|
32
|
+
if elt.tag == "{http://schemas.openxmlformats.org/wordprocessingml/2006/main}p":
|
|
33
|
+
if chk_br(elt):
|
|
34
|
+
num_page_breaks += 1
|
|
35
|
+
if num_page_breaks == 3:
|
|
36
|
+
state = 2
|
|
37
|
+
doc_tmp.element.body.remove(elt)
|
|
38
|
+
#doc_tmp.add_paragraph()
|
|
39
|
+
#elif elt.tag == "{http://schemas.openxmlformats.org/wordprocessingml/2006/main}tbl":
|
|
40
|
+
#table_copy(elt, doc_fab, doc_tmp)
|
|
41
|
+
elif state == 2:
|
|
42
|
+
if elt.tag != "{http://schemas.openxmlformats.org/wordprocessingml/2006/main}sectPr":
|
|
43
|
+
doc_tmp.element.body.remove(elt)
|
|
44
|
+
|
|
45
|
+
doc_tmp.save(tmp_file)
|
|
46
|
+
|
|
47
|
+
return(tmp_file)
|
|
48
|
+
|
|
49
|
+
def compose_doc(base_file,files_list,final_doc):
|
|
50
|
+
files_list = files_list.split(";")
|
|
51
|
+
master = Document(base_file)
|
|
52
|
+
composer = Composer(master)
|
|
53
|
+
for filename in files_list:
|
|
54
|
+
doc_temp = Document(filename)
|
|
55
|
+
composer.append(doc_temp)
|
|
56
|
+
composer.save(final_doc)
|
|
57
|
+
return
|
|
58
|
+
|
|
59
|
+
if __name__ == '__main__':
|
|
60
|
+
flist = ['//winprod/commun/is/chantier/1000/schemas.docx', '//winprod/commun/is/chantier/1000/1000_DETAIL.docx', '//winprod/commun/is/chantier/_doc_base/Formulaire_ALU_cgv.docx']
|
|
61
|
+
compose_doc('//winprod/commun/is/chantier/_doc_base/Formulaire_ALU_1-3.docx',flist,'//winprod/commun/is/chantier/1000/Devis.docx')
|
|
@@ -1,55 +1,55 @@
|
|
|
1
|
-
from docx import Document
|
|
2
|
-
from docx.shared import Pt
|
|
3
|
-
import csv
|
|
4
|
-
|
|
5
|
-
def hello_world():
|
|
6
|
-
print('Hello world fron in_projet')
|
|
7
|
-
|
|
8
|
-
def build_projet(txt_filename,tpl_filename,doc_filename):
|
|
9
|
-
doc_prj = Document(tpl_filename)
|
|
10
|
-
font_size = Pt(8)
|
|
11
|
-
|
|
12
|
-
ret = False
|
|
13
|
-
table = doc_prj.tables[0]
|
|
14
|
-
|
|
15
|
-
data = []
|
|
16
|
-
# Ouvrir le fichier en mode lecture
|
|
17
|
-
with open(txt_filename, 'r', encoding="utf-8") as file:
|
|
18
|
-
# Créer un lecteur CSV
|
|
19
|
-
reader = csv.reader(file, delimiter=';') # Spécifiez le délimiteur approprié si nécessaire
|
|
20
|
-
for rowidx, row in enumerate(reader):
|
|
21
|
-
if rowidx >= 11:
|
|
22
|
-
if len(row) > 0:
|
|
23
|
-
data.append(row)
|
|
24
|
-
|
|
25
|
-
current_pos = ''
|
|
26
|
-
for posidx, pos in enumerate(data[0]):
|
|
27
|
-
if pos != "X":
|
|
28
|
-
current_pos = data[1][posidx]
|
|
29
|
-
cells = table.add_row().cells
|
|
30
|
-
cells[0].text = data[1][posidx]
|
|
31
|
-
cells[0].paragraphs[0].runs[0].font.bold = True
|
|
32
|
-
text = str(data[4][posidx])
|
|
33
|
-
cells[1].text = text.replace("|","\r")
|
|
34
|
-
cells[2].text = data[3][posidx]
|
|
35
|
-
cells[3].text = data[13][posidx]
|
|
36
|
-
cells[4].text = data[5][posidx]
|
|
37
|
-
cells[5].text = data[11][posidx]
|
|
38
|
-
cells[6].text = data[12][posidx]
|
|
39
|
-
|
|
40
|
-
#else:
|
|
41
|
-
# print("desigantion = ",data[4][posidx])
|
|
42
|
-
|
|
43
|
-
for cell in table._cells:
|
|
44
|
-
for paragraph in cell.paragraphs:
|
|
45
|
-
for run in paragraph.runs:
|
|
46
|
-
run.font.size = font_size
|
|
47
|
-
run.font.name = 'Calibri'
|
|
48
|
-
|
|
49
|
-
doc_prj.save(doc_filename)
|
|
50
|
-
ret = True
|
|
51
|
-
return(ret)
|
|
52
|
-
|
|
53
|
-
if __name__ == '__main__':
|
|
54
|
-
arguments = sys.argv
|
|
55
|
-
|
|
1
|
+
from docx import Document
|
|
2
|
+
from docx.shared import Pt
|
|
3
|
+
import csv
|
|
4
|
+
|
|
5
|
+
def hello_world():
|
|
6
|
+
print('Hello world fron in_projet')
|
|
7
|
+
|
|
8
|
+
def build_projet(txt_filename,tpl_filename,doc_filename):
|
|
9
|
+
doc_prj = Document(tpl_filename)
|
|
10
|
+
font_size = Pt(8)
|
|
11
|
+
|
|
12
|
+
ret = False
|
|
13
|
+
table = doc_prj.tables[0]
|
|
14
|
+
|
|
15
|
+
data = []
|
|
16
|
+
# Ouvrir le fichier en mode lecture
|
|
17
|
+
with open(txt_filename, 'r', encoding="utf-8") as file:
|
|
18
|
+
# Créer un lecteur CSV
|
|
19
|
+
reader = csv.reader(file, delimiter=';') # Spécifiez le délimiteur approprié si nécessaire
|
|
20
|
+
for rowidx, row in enumerate(reader):
|
|
21
|
+
if rowidx >= 11:
|
|
22
|
+
if len(row) > 0:
|
|
23
|
+
data.append(row)
|
|
24
|
+
|
|
25
|
+
current_pos = ''
|
|
26
|
+
for posidx, pos in enumerate(data[0]):
|
|
27
|
+
if pos != "X":
|
|
28
|
+
current_pos = data[1][posidx]
|
|
29
|
+
cells = table.add_row().cells
|
|
30
|
+
cells[0].text = data[1][posidx]
|
|
31
|
+
cells[0].paragraphs[0].runs[0].font.bold = True
|
|
32
|
+
text = str(data[4][posidx])
|
|
33
|
+
cells[1].text = text.replace("|","\r")
|
|
34
|
+
cells[2].text = data[3][posidx]
|
|
35
|
+
cells[3].text = data[13][posidx]
|
|
36
|
+
cells[4].text = data[5][posidx]
|
|
37
|
+
cells[5].text = data[11][posidx]
|
|
38
|
+
cells[6].text = data[12][posidx]
|
|
39
|
+
|
|
40
|
+
#else:
|
|
41
|
+
# print("desigantion = ",data[4][posidx])
|
|
42
|
+
|
|
43
|
+
for cell in table._cells:
|
|
44
|
+
for paragraph in cell.paragraphs:
|
|
45
|
+
for run in paragraph.runs:
|
|
46
|
+
run.font.size = font_size
|
|
47
|
+
run.font.name = 'Calibri'
|
|
48
|
+
|
|
49
|
+
doc_prj.save(doc_filename)
|
|
50
|
+
ret = True
|
|
51
|
+
return(ret)
|
|
52
|
+
|
|
53
|
+
if __name__ == '__main__':
|
|
54
|
+
arguments = sys.argv
|
|
55
|
+
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
def hello_world:
|
|
3
|
-
print("salut les aminches")
|
|
1
|
+
|
|
2
|
+
def hello_world:
|
|
3
|
+
print("salut les aminches")
|
|
4
4
|
return("ça roule ma poule!")
|
|
@@ -1,45 +1,45 @@
|
|
|
1
|
-
import pandas as pd
|
|
2
|
-
import sys
|
|
3
|
-
import csv
|
|
4
|
-
|
|
5
|
-
def hello_world():
|
|
6
|
-
print('Hello world fron xls_to_csv')
|
|
7
|
-
|
|
8
|
-
def parse_csv(csv_file):
|
|
9
|
-
# Ouvrir le fichier CSV en mode lecture
|
|
10
|
-
with open(csv_file, newline='') as csvfile:
|
|
11
|
-
# Créer un lecteur CSV
|
|
12
|
-
lecteur_csv = csv.reader(csvfile, delimiter=';')
|
|
13
|
-
donnees = list(lecteur_csv)
|
|
14
|
-
# Parcourir chaque ligne du fichier CSV
|
|
15
|
-
for lindex, ligne in enumerate(donnees):
|
|
16
|
-
# Parcourir chaque cellule de la ligne
|
|
17
|
-
for cindex, cellule in enumerate(ligne):
|
|
18
|
-
if len(cellule) > 0:
|
|
19
|
-
donnees[lindex][cindex] = cellule.replace('\n','|')
|
|
20
|
-
|
|
21
|
-
with open(csv_file, 'w', newline='') as fichier_sortie:
|
|
22
|
-
writer_csv = csv.writer(fichier_sortie, delimiter=';')
|
|
23
|
-
# Écrire les données modifiées dans le nouveau fichier CSV
|
|
24
|
-
writer_csv.writerows(donnees)
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
def convert_to_csv(xls_file,csv_file):
|
|
28
|
-
df = pd.read_excel(xls_file)
|
|
29
|
-
df.to_csv(csv_file, index=False, sep=';')
|
|
30
|
-
parse_csv(csv_file)
|
|
31
|
-
return
|
|
32
|
-
|
|
33
|
-
if __name__ == '__main__':
|
|
34
|
-
arguments = sys.argv
|
|
35
|
-
|
|
36
|
-
if len(arguments) == 3:
|
|
37
|
-
xl_filename = arguments[1].replace('\\','/') # Premier argument
|
|
38
|
-
csv_filename = arguments[2].replace('\\','/') # Deuxième argument
|
|
39
|
-
convert_to_csv(xl_filename, csv_filename)
|
|
40
|
-
else:
|
|
41
|
-
xl_filename = "Q:/is/chantier/1000/1000_DETAIL.xlsx" # Premier argument
|
|
42
|
-
csv_filename = "Q:/is/chantier/1000/1000_DETAIL.csv" # Deuxième argument
|
|
43
|
-
convert_to_csv(xl_filename, csv_filename)
|
|
44
|
-
print("Veuillez spécifier des arguments.")
|
|
45
|
-
|
|
1
|
+
import pandas as pd
|
|
2
|
+
import sys
|
|
3
|
+
import csv
|
|
4
|
+
|
|
5
|
+
def hello_world():
|
|
6
|
+
print('Hello world fron xls_to_csv')
|
|
7
|
+
|
|
8
|
+
def parse_csv(csv_file):
|
|
9
|
+
# Ouvrir le fichier CSV en mode lecture
|
|
10
|
+
with open(csv_file, newline='') as csvfile:
|
|
11
|
+
# Créer un lecteur CSV
|
|
12
|
+
lecteur_csv = csv.reader(csvfile, delimiter=';')
|
|
13
|
+
donnees = list(lecteur_csv)
|
|
14
|
+
# Parcourir chaque ligne du fichier CSV
|
|
15
|
+
for lindex, ligne in enumerate(donnees):
|
|
16
|
+
# Parcourir chaque cellule de la ligne
|
|
17
|
+
for cindex, cellule in enumerate(ligne):
|
|
18
|
+
if len(cellule) > 0:
|
|
19
|
+
donnees[lindex][cindex] = cellule.replace('\n','|')
|
|
20
|
+
|
|
21
|
+
with open(csv_file, 'w', newline='') as fichier_sortie:
|
|
22
|
+
writer_csv = csv.writer(fichier_sortie, delimiter=';')
|
|
23
|
+
# Écrire les données modifiées dans le nouveau fichier CSV
|
|
24
|
+
writer_csv.writerows(donnees)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def convert_to_csv(xls_file,csv_file):
|
|
28
|
+
df = pd.read_excel(xls_file)
|
|
29
|
+
df.to_csv(csv_file, index=False, sep=';')
|
|
30
|
+
parse_csv(csv_file)
|
|
31
|
+
return
|
|
32
|
+
|
|
33
|
+
if __name__ == '__main__':
|
|
34
|
+
arguments = sys.argv
|
|
35
|
+
|
|
36
|
+
if len(arguments) == 3:
|
|
37
|
+
xl_filename = arguments[1].replace('\\','/') # Premier argument
|
|
38
|
+
csv_filename = arguments[2].replace('\\','/') # Deuxième argument
|
|
39
|
+
convert_to_csv(xl_filename, csv_filename)
|
|
40
|
+
else:
|
|
41
|
+
xl_filename = "Q:/is/chantier/1000/1000_DETAIL.xlsx" # Premier argument
|
|
42
|
+
csv_filename = "Q:/is/chantier/1000/1000_DETAIL.csv" # Deuxième argument
|
|
43
|
+
convert_to_csv(xl_filename, csv_filename)
|
|
44
|
+
print("Veuillez spécifier des arguments.")
|
|
45
|
+
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: inpython-package
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.1.6
|
|
4
4
|
Summary: # Infodata's IN-Tools U2Python Package
|
|
5
5
|
Home-page: https://bitbucket.org/infodata-dev/inpython
|
|
6
6
|
Author: infodata
|
|
@@ -11,6 +11,19 @@ Description-Content-Type: text/markdown
|
|
|
11
11
|
License-File: LICENSE.txt
|
|
12
12
|
Requires-Dist: msal>=1.22
|
|
13
13
|
Requires-Dist: qrcode
|
|
14
|
+
Requires-Dist: requests
|
|
15
|
+
Requires-Dist: qrcode[pil]
|
|
16
|
+
Requires-Dist: dotenv
|
|
17
|
+
Dynamic: author
|
|
18
|
+
Dynamic: author-email
|
|
19
|
+
Dynamic: description
|
|
20
|
+
Dynamic: description-content-type
|
|
21
|
+
Dynamic: home-page
|
|
22
|
+
Dynamic: license
|
|
23
|
+
Dynamic: license-file
|
|
24
|
+
Dynamic: requires-dist
|
|
25
|
+
Dynamic: requires-python
|
|
26
|
+
Dynamic: summary
|
|
14
27
|
|
|
15
28
|
# README
|
|
16
29
|
|
|
@@ -7,6 +7,11 @@ inpython/aotools/__init__.py
|
|
|
7
7
|
inpython/aotools/aogeo.py
|
|
8
8
|
inpython/ingraph/__init__.py
|
|
9
9
|
inpython/ingraph/ingraph.py
|
|
10
|
+
inpython/inqrcode/__init__.py
|
|
11
|
+
inpython/inqrcode/inqrcode.py
|
|
12
|
+
inpython/inqrcode/paymentqrcode.py
|
|
13
|
+
inpython/inrest/__init__.py
|
|
14
|
+
inpython/inrest/in_jwt.py
|
|
10
15
|
inpython/intools/Servalux-devis.py
|
|
11
16
|
inpython/intools/__init__.py
|
|
12
17
|
inpython/intools/in_docx.py
|
|
@@ -9,7 +9,7 @@ with open("README.md", "r") as fh:
|
|
|
9
9
|
|
|
10
10
|
setup(
|
|
11
11
|
name="inpython-package",
|
|
12
|
-
version="1.
|
|
12
|
+
version="1.1.6",
|
|
13
13
|
author="infodata",
|
|
14
14
|
author_email="efv@infodata.lu",
|
|
15
15
|
packages=find_packages(),
|
|
@@ -21,6 +21,9 @@ setup(
|
|
|
21
21
|
python_requires='>=3.4',
|
|
22
22
|
install_requires=[
|
|
23
23
|
'msal >= 1.22',
|
|
24
|
-
'qrcode'
|
|
24
|
+
'qrcode',
|
|
25
|
+
'requests',
|
|
26
|
+
'qrcode[pil]',
|
|
27
|
+
'dotenv'
|
|
25
28
|
]
|
|
26
29
|
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{inpython_package-1.0.8 → inpython_package-1.1.6}/inpython_package.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|