io4it 1.0.0.1__tar.gz → 1.0.0.3__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.
- {io4it-1.0.0.1 → io4it-1.0.0.3}/PKG-INFO +1 -1
- {io4it-1.0.0.1 → io4it-1.0.0.3}/io4it.egg-info/PKG-INFO +1 -1
- {io4it-1.0.0.1 → io4it-1.0.0.3}/io4it.egg-info/SOURCES.txt +2 -3
- io4it-1.0.0.3/orangecontrib/IO4IT/ocr_function/word_converter.py +333 -0
- io4it-1.0.0.3/orangecontrib/IO4IT/widgets/icons_dev/__init__.py +0 -0
- {io4it-1.0.0.1 → io4it-1.0.0.3}/setup.py +1 -1
- io4it-1.0.0.1/orangecontrib/IO4IT/widgets/OWFileExtSelector.py +0 -279
- io4it-1.0.0.1/orangecontrib/IO4IT/widgets/OWVisualizationer.py +0 -73
- io4it-1.0.0.1/orangecontrib/IO4IT/widgets/OWmailLoader.py +0 -156
- {io4it-1.0.0.1 → io4it-1.0.0.3}/io4it.egg-info/dependency_links.txt +0 -0
- {io4it-1.0.0.1 → io4it-1.0.0.3}/io4it.egg-info/entry_points.txt +0 -0
- {io4it-1.0.0.1 → io4it-1.0.0.3}/io4it.egg-info/namespace_packages.txt +0 -0
- {io4it-1.0.0.1 → io4it-1.0.0.3}/io4it.egg-info/requires.txt +0 -0
- {io4it-1.0.0.1 → io4it-1.0.0.3}/io4it.egg-info/top_level.txt +0 -0
- {io4it-1.0.0.1 → io4it-1.0.0.3}/orangecontrib/IO4IT/__init__.py +0 -0
- {io4it-1.0.0.1/orangecontrib/IO4IT/widgets/designer → io4it-1.0.0.3/orangecontrib/IO4IT/ocr_function}/__init__.py +0 -0
- {io4it-1.0.0.1 → io4it-1.0.0.3}/orangecontrib/IO4IT/widgets/OWMarkdownizer.py +0 -0
- {io4it-1.0.0.1 → io4it-1.0.0.3}/orangecontrib/IO4IT/widgets/OWS3Uploader.py +0 -0
- {io4it-1.0.0.1 → io4it-1.0.0.3}/orangecontrib/IO4IT/widgets/OWS3downloader.py +0 -0
- {io4it-1.0.0.1 → io4it-1.0.0.3}/orangecontrib/IO4IT/widgets/OWS3list.py +0 -0
- {io4it-1.0.0.1 → io4it-1.0.0.3}/orangecontrib/IO4IT/widgets/OWSpeechToText.py +0 -0
- {io4it-1.0.0.1 → io4it-1.0.0.3}/orangecontrib/IO4IT/widgets/OWwordpdf2docx.py +0 -0
- {io4it-1.0.0.1 → io4it-1.0.0.3}/orangecontrib/IO4IT/widgets/__init__.py +0 -0
- {io4it-1.0.0.1/orangecontrib/IO4IT/widgets/icons → io4it-1.0.0.3/orangecontrib/IO4IT/widgets/designer}/__init__.py +0 -0
- {io4it-1.0.0.1 → io4it-1.0.0.3}/orangecontrib/IO4IT/widgets/designer/chart.html +0 -0
- {io4it-1.0.0.1 → io4it-1.0.0.3}/orangecontrib/IO4IT/widgets/designer/nogui.ui +0 -0
- {io4it-1.0.0.1 → io4it-1.0.0.3}/orangecontrib/IO4IT/widgets/designer/ow_file_ext_selector.ui +0 -0
- {io4it-1.0.0.1 → io4it-1.0.0.3}/orangecontrib/IO4IT/widgets/designer/owmailloader.ui +0 -0
- {io4it-1.0.0.1 → io4it-1.0.0.3}/orangecontrib/IO4IT/widgets/designer/owspeechtotext.ui +0 -0
- {io4it-1.0.0.1 → io4it-1.0.0.3}/orangecontrib/IO4IT/widgets/designer/owvisualizationer.ui +0 -0
- {io4it-1.0.0.1 → io4it-1.0.0.3}/orangecontrib/IO4IT/widgets/designer/wordpdf2docx.ui +0 -0
- {io4it-1.0.0.1/orangecontrib/IO4IT/widgets/icons_dev → io4it-1.0.0.3/orangecontrib/IO4IT/widgets/icons}/__init__.py +0 -0
- {io4it-1.0.0.1 → io4it-1.0.0.3}/orangecontrib/IO4IT/widgets/icons/download.png +0 -0
- {io4it-1.0.0.1 → io4it-1.0.0.3}/orangecontrib/IO4IT/widgets/icons/file_extensor.png +0 -0
- {io4it-1.0.0.1 → io4it-1.0.0.3}/orangecontrib/IO4IT/widgets/icons/list_aws.png +0 -0
- {io4it-1.0.0.1 → io4it-1.0.0.3}/orangecontrib/IO4IT/widgets/icons/md.png +0 -0
- {io4it-1.0.0.1 → io4it-1.0.0.3}/orangecontrib/IO4IT/widgets/icons/speech_to_text.png +0 -0
- {io4it-1.0.0.1 → io4it-1.0.0.3}/orangecontrib/IO4IT/widgets/icons/upload.png +0 -0
- {io4it-1.0.0.1 → io4it-1.0.0.3}/orangecontrib/IO4IT/widgets/icons/visualizationer.png +0 -0
- {io4it-1.0.0.1 → io4it-1.0.0.3}/orangecontrib/IO4IT/widgets/icons/wordpdf2docx.png +0 -0
- {io4it-1.0.0.1 → io4it-1.0.0.3}/orangecontrib/__init__.py +0 -0
- {io4it-1.0.0.1 → io4it-1.0.0.3}/setup.cfg +0 -0
|
@@ -9,14 +9,13 @@ io4it.egg-info/requires.txt
|
|
|
9
9
|
io4it.egg-info/top_level.txt
|
|
10
10
|
orangecontrib/__init__.py
|
|
11
11
|
orangecontrib/IO4IT/__init__.py
|
|
12
|
-
orangecontrib/IO4IT/
|
|
12
|
+
orangecontrib/IO4IT/ocr_function/__init__.py
|
|
13
|
+
orangecontrib/IO4IT/ocr_function/word_converter.py
|
|
13
14
|
orangecontrib/IO4IT/widgets/OWMarkdownizer.py
|
|
14
15
|
orangecontrib/IO4IT/widgets/OWS3Uploader.py
|
|
15
16
|
orangecontrib/IO4IT/widgets/OWS3downloader.py
|
|
16
17
|
orangecontrib/IO4IT/widgets/OWS3list.py
|
|
17
18
|
orangecontrib/IO4IT/widgets/OWSpeechToText.py
|
|
18
|
-
orangecontrib/IO4IT/widgets/OWVisualizationer.py
|
|
19
|
-
orangecontrib/IO4IT/widgets/OWmailLoader.py
|
|
20
19
|
orangecontrib/IO4IT/widgets/OWwordpdf2docx.py
|
|
21
20
|
orangecontrib/IO4IT/widgets/__init__.py
|
|
22
21
|
orangecontrib/IO4IT/widgets/designer/__init__.py
|
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import win32com.client
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
import pathlib
|
|
5
|
+
import shutil
|
|
6
|
+
import time
|
|
7
|
+
import pythoncom
|
|
8
|
+
import fitz
|
|
9
|
+
|
|
10
|
+
if "site-packages/Orange/widgets" in os.path.dirname(os.path.abspath(__file__)).replace("\\", "/"):
|
|
11
|
+
from Orange.widgets.orangecontrib.AAIT.utils.MetManagement import get_local_store_path,reset_folder
|
|
12
|
+
else:
|
|
13
|
+
from orangecontrib.AAIT.utils.MetManagement import get_local_store_path,reset_folder
|
|
14
|
+
|
|
15
|
+
def enable_long_path(path):
|
|
16
|
+
"""Simplifie la gestion des chemins longs sous Windows."""
|
|
17
|
+
return pathlib.Path(r"\\?\\" + str(path))
|
|
18
|
+
|
|
19
|
+
def convert_pdf_structure(input_dir: str, output_dir: str,ignore_exsting_out_put=False,progress_callback=None):
|
|
20
|
+
"""
|
|
21
|
+
return a string with log in case of error
|
|
22
|
+
Recursively lists all .pdf and .PDF files in the input directory,
|
|
23
|
+
replicates the folder structure in the output directory, and
|
|
24
|
+
creates empty .docx files with the same names.
|
|
25
|
+
|
|
26
|
+
Parameters:
|
|
27
|
+
input_dir (str): Path to the input directory containing PDF files.
|
|
28
|
+
output_dir (str): Path to the output directory where DOCX files will be created.
|
|
29
|
+
"""
|
|
30
|
+
error_log=""
|
|
31
|
+
if os.name != 'nt':
|
|
32
|
+
error_log="version developped for windows computer "
|
|
33
|
+
return error_log
|
|
34
|
+
|
|
35
|
+
nbre_file = 0
|
|
36
|
+
for i, data in enumerate(input_dir):
|
|
37
|
+
input_path = Path(str(input_dir[i]))
|
|
38
|
+
for pdf_file in input_path.rglob("*.pdf"):
|
|
39
|
+
nbre_file += 1
|
|
40
|
+
|
|
41
|
+
k = 1
|
|
42
|
+
for i, data in enumerate(input_dir):
|
|
43
|
+
input_path = Path(str(input_dir[i]))
|
|
44
|
+
output_path = Path(str(output_dir[i]))
|
|
45
|
+
|
|
46
|
+
if not input_path.exists() or not input_path.is_dir():
|
|
47
|
+
print(f"Error: The input directory '{input_dir}' does not exist or is not a directory.")
|
|
48
|
+
return f"Error: The input directory '{input_dir}' does not exist or is not a directory. "
|
|
49
|
+
|
|
50
|
+
for pdf_file in input_path.rglob("*.pdf"): # Recursively search for .pdf and .PDF files
|
|
51
|
+
print("traitement de ",str(pdf_file))
|
|
52
|
+
relative_path = pdf_file.relative_to(input_path) # Get relative path from input root
|
|
53
|
+
new_file_path = output_path / relative_path.with_suffix(".docx") # Change extension to .docx
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
if ignore_exsting_out_put:
|
|
58
|
+
if os.path.exists(enable_long_path(str(new_file_path))):
|
|
59
|
+
print("ignoring",enable_long_path(str(new_file_path)))
|
|
60
|
+
continue
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
if 0!= convert_pdf_with_temp(str(pdf_file),str(new_file_path)):#convert_pdf_with_temp #convert_pdf_to_docx
|
|
64
|
+
if error_log!="":
|
|
65
|
+
error_log+="\n"
|
|
66
|
+
error_log+="error -> "+str(pdf_file)
|
|
67
|
+
return error_log # a supprimer
|
|
68
|
+
if progress_callback is not None:
|
|
69
|
+
progress_value = float(100 * (k) / nbre_file)
|
|
70
|
+
k += 1
|
|
71
|
+
progress_callback(progress_value)
|
|
72
|
+
# purge temp dir if everithing is ok
|
|
73
|
+
if error_log=="":
|
|
74
|
+
reset_folder(get_local_store_path() + "temp_word_conversion/", attempts=10, delay=0.05, recreate=False)
|
|
75
|
+
return error_log
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def convert_pdf_to_docx(pdf_path, docx_path):
|
|
81
|
+
"""
|
|
82
|
+
Convertit un fichier PDF en DOCX en utilisant Microsoft Word.
|
|
83
|
+
|
|
84
|
+
Args:
|
|
85
|
+
pdf_path (str): Chemin du fichier PDF source.
|
|
86
|
+
docx_path (str): Chemin du fichier DOCX de destination.
|
|
87
|
+
|
|
88
|
+
Returns:
|
|
89
|
+
int: 0 si la conversion a réussi, 1 en cas d'échec.
|
|
90
|
+
"""
|
|
91
|
+
if not os.path.exists(pdf_path):
|
|
92
|
+
print(f"Erreur : Le fichier {pdf_path} n'existe pas.")
|
|
93
|
+
return 1
|
|
94
|
+
|
|
95
|
+
try:
|
|
96
|
+
# Initialiser COM
|
|
97
|
+
pythoncom.CoInitialize()
|
|
98
|
+
|
|
99
|
+
# Lancer Word
|
|
100
|
+
word = win32com.client.Dispatch("Word.Application")
|
|
101
|
+
word.DisplayAlerts = 0 # Désactiver les alertes
|
|
102
|
+
word.Visible = True # Mettre à True pour voir Word en action
|
|
103
|
+
print(f"Conversion de {pdf_path} en {docx_path}...")
|
|
104
|
+
|
|
105
|
+
# Ouvrir le PDF en lecture seule
|
|
106
|
+
doc = word.Documents.Open(pdf_path, ReadOnly=True, ConfirmConversions=False)
|
|
107
|
+
|
|
108
|
+
# Sauvegarder en DOCX
|
|
109
|
+
doc.SaveAs(docx_path, FileFormat=16) # 16 = wdFormatDocumentDefault
|
|
110
|
+
doc.Close(False)
|
|
111
|
+
|
|
112
|
+
print(f"Conversion réussie : {docx_path}")
|
|
113
|
+
return 0
|
|
114
|
+
|
|
115
|
+
except Exception as e:
|
|
116
|
+
print(f"Erreur lors de la conversion : {e}")
|
|
117
|
+
return 1
|
|
118
|
+
|
|
119
|
+
finally:
|
|
120
|
+
if 'word' in locals():
|
|
121
|
+
word.Quit()
|
|
122
|
+
|
|
123
|
+
# Libérer COM
|
|
124
|
+
pythoncom.CoUninitialize()
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def wait_for_file_access(file_path, timeout=10, interval=0.5):
|
|
128
|
+
"""
|
|
129
|
+
Attendre que le fichier soit accessible en lecture/écriture.
|
|
130
|
+
|
|
131
|
+
Args:
|
|
132
|
+
file_path (str): Chemin du fichier à vérifier.
|
|
133
|
+
timeout (int): Temps max en secondes avant d'abandonner.
|
|
134
|
+
interval (float): Temps d'attente entre chaque vérification.
|
|
135
|
+
|
|
136
|
+
Returns:
|
|
137
|
+
bool: True si le fichier est accessible, False sinon.
|
|
138
|
+
"""
|
|
139
|
+
start_time = time.time()
|
|
140
|
+
|
|
141
|
+
while time.time() - start_time < timeout:
|
|
142
|
+
if os.path.exists(file_path) and os.access(file_path, os.R_OK | os.W_OK):
|
|
143
|
+
try:
|
|
144
|
+
with open(file_path, "a"):
|
|
145
|
+
pass # Test d'ouverture en écriture
|
|
146
|
+
return True
|
|
147
|
+
except IOError:
|
|
148
|
+
pass
|
|
149
|
+
|
|
150
|
+
time.sleep(interval) # Attendre avant de réessayer
|
|
151
|
+
|
|
152
|
+
print(f"Erreur : Le fichier {file_path} est verrouillé ou inaccessible.")
|
|
153
|
+
return False
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
def is_pdf_a4(pdf_path: str) -> bool:
|
|
159
|
+
"""
|
|
160
|
+
Vérifie si toutes les pages du PDF sont au format A4.
|
|
161
|
+
Retourne True si toutes les pages sont en A4, False sinon.
|
|
162
|
+
"""
|
|
163
|
+
A4_WIDTH_PTS = 595 # Largeur A4 en points (approx. 210mm)
|
|
164
|
+
A4_HEIGHT_PTS = 842 # Hauteur A4 en points (approx. 297mm)
|
|
165
|
+
TOLERANCE = 5 # Marge de tolérance en points
|
|
166
|
+
|
|
167
|
+
try:
|
|
168
|
+
doc = fitz.open(pdf_path)
|
|
169
|
+
if len(doc) == 0:
|
|
170
|
+
return False
|
|
171
|
+
|
|
172
|
+
for page in doc:
|
|
173
|
+
width, height = page.rect.width, page.rect.height
|
|
174
|
+
if not (
|
|
175
|
+
(abs(width - A4_WIDTH_PTS) <= TOLERANCE and abs(height - A4_HEIGHT_PTS) <= TOLERANCE) or
|
|
176
|
+
(abs(width - A4_HEIGHT_PTS) <= TOLERANCE and abs(height - A4_WIDTH_PTS) <= TOLERANCE)
|
|
177
|
+
):
|
|
178
|
+
return False
|
|
179
|
+
except Exception as e:
|
|
180
|
+
print("is A4?",e)
|
|
181
|
+
return False
|
|
182
|
+
return True
|
|
183
|
+
|
|
184
|
+
def convert_pdf_to_a4(input_pdf, output_pdf):
|
|
185
|
+
try:
|
|
186
|
+
# Dimensions A4 en points
|
|
187
|
+
a4_width, a4_height = fitz.paper_size("a4")
|
|
188
|
+
a3_width, a3_height = fitz.paper_size("a3")
|
|
189
|
+
doc = fitz.open(input_pdf)
|
|
190
|
+
new_doc = fitz.open()
|
|
191
|
+
|
|
192
|
+
for page in doc:
|
|
193
|
+
page_w, page_h = page.rect.width, page.rect.height
|
|
194
|
+
|
|
195
|
+
# Si la page est déjà en A4 (tolérance de 1 point)
|
|
196
|
+
if abs(page_w - a4_width) < 1 and abs(page_h - a4_height) < 1:
|
|
197
|
+
new_doc.insert_pdf(doc, from_page=page.number, to_page=page.number)
|
|
198
|
+
continue
|
|
199
|
+
|
|
200
|
+
# Si la page est déjà en A3 (tolérance de 1 point)
|
|
201
|
+
if abs(page_w - a3_width) < 1 and abs(page_h - a3_height) < 1:
|
|
202
|
+
new_doc.insert_pdf(doc, from_page=page.number, to_page=page.number)
|
|
203
|
+
continue
|
|
204
|
+
|
|
205
|
+
# Définition de la transformation selon l'orientation de la page
|
|
206
|
+
if page_w > page_h: # Paysage
|
|
207
|
+
# Après rotation, les dimensions seront inversées (largeur <-> hauteur)
|
|
208
|
+
effective_scale = min(a4_width / page_h, a4_height / page_w)
|
|
209
|
+
matrix = fitz.Matrix(effective_scale, effective_scale)
|
|
210
|
+
# Rotation de 90° et translation pour repositionner le contenu
|
|
211
|
+
matrix = matrix.prerotate(90).pretranslate(page_h * effective_scale, 0)
|
|
212
|
+
else: # Portrait
|
|
213
|
+
effective_scale = min(a4_width / page_w, a4_height / page_h)
|
|
214
|
+
matrix = fitz.Matrix(effective_scale, effective_scale)
|
|
215
|
+
|
|
216
|
+
# Générer le pixmap à la résolution finale souhaitée
|
|
217
|
+
pix = page.get_pixmap(matrix=matrix)
|
|
218
|
+
|
|
219
|
+
# Calcul du centrage sur la page A4
|
|
220
|
+
new_img_w, new_img_h = pix.width, pix.height
|
|
221
|
+
x_offset = (a4_width - new_img_w) / 2
|
|
222
|
+
y_offset = (a4_height - new_img_h) / 2
|
|
223
|
+
|
|
224
|
+
# Créer la nouvelle page et y insérer l'image
|
|
225
|
+
new_page = new_doc.new_page(width=a4_width, height=a4_height)
|
|
226
|
+
new_page.insert_image(
|
|
227
|
+
fitz.Rect(x_offset, y_offset, x_offset + new_img_w, y_offset + new_img_h),
|
|
228
|
+
pixmap=pix
|
|
229
|
+
)
|
|
230
|
+
new_doc.save(output_pdf)
|
|
231
|
+
new_doc.close()
|
|
232
|
+
doc.close()
|
|
233
|
+
return 0
|
|
234
|
+
except:
|
|
235
|
+
return 1
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
def write_two_strings_to_file(file_path: str,string1: str, string2: str):
|
|
239
|
+
"""
|
|
240
|
+
Writes two strings to a file, one per line, handling errors gracefully.
|
|
241
|
+
|
|
242
|
+
:param string1: The first string to write.
|
|
243
|
+
:param string2: The second string to write.
|
|
244
|
+
:param file_path: The path where the file should be saved.
|
|
245
|
+
"""
|
|
246
|
+
try:
|
|
247
|
+
file = open(file_path, 'w', encoding='utf-8')
|
|
248
|
+
file.write(string1 + "\n")
|
|
249
|
+
file.write(string2 )
|
|
250
|
+
print(f"Successfully written to {file_path}")
|
|
251
|
+
except IOError as e:
|
|
252
|
+
print(f"Error writing to file: {e}")
|
|
253
|
+
return 1
|
|
254
|
+
except Exception as e:
|
|
255
|
+
print(f"An unexpected error occurred: {e}")
|
|
256
|
+
return 1
|
|
257
|
+
finally:
|
|
258
|
+
file.close()
|
|
259
|
+
return 0
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
def convert_pdf_with_temp(temp_pdf, output_path):
|
|
263
|
+
"""
|
|
264
|
+
Copie le PDF source dans un dossier temporaire, le convertit en DOCX,
|
|
265
|
+
puis copie le fichier résultant vers le chemin de sortie spécifié,
|
|
266
|
+
en gérant les chemins longs.
|
|
267
|
+
"""
|
|
268
|
+
pdf_path = enable_long_path(os.path.abspath(temp_pdf))
|
|
269
|
+
output_path = enable_long_path(os.path.abspath(output_path))
|
|
270
|
+
output_dir = output_path.parent
|
|
271
|
+
|
|
272
|
+
if not pdf_path.exists():
|
|
273
|
+
print(f"Le fichier {pdf_path} n'existe pas.")
|
|
274
|
+
return 1
|
|
275
|
+
|
|
276
|
+
# Créer le dossier de sortie s'il n'existe pas
|
|
277
|
+
if not output_dir.exists():
|
|
278
|
+
output_dir.mkdir(parents=True, exist_ok=True)
|
|
279
|
+
|
|
280
|
+
try:
|
|
281
|
+
dest_dir = get_local_store_path() + "temp_word_conversion/"
|
|
282
|
+
if 0 != reset_folder(dest_dir, attempts=10, delay=0.05):
|
|
283
|
+
print("impossible to reset " + dest_dir)
|
|
284
|
+
return 1
|
|
285
|
+
# Création du dossier temporaire
|
|
286
|
+
temp_pdf = os.path.join(dest_dir, "input_toto.pdf")
|
|
287
|
+
temp_docx = os.path.join(dest_dir, "input_toto.docx")
|
|
288
|
+
|
|
289
|
+
print(dest_dir+"conversion_en_cours.txt")
|
|
290
|
+
print("######################################")
|
|
291
|
+
if 0!=write_two_strings_to_file(dest_dir+"conversion_en_cours.txt",str(pdf_path),str(output_path)):
|
|
292
|
+
print("error writing ",dest_dir+"conversion_en_cours.txt")
|
|
293
|
+
return 1
|
|
294
|
+
# Copie du fichier source vers le dossier temporaire
|
|
295
|
+
shutil.copy2(pdf_path, temp_pdf)
|
|
296
|
+
wait_for_file_access(temp_pdf)
|
|
297
|
+
|
|
298
|
+
if is_pdf_a4(temp_pdf)==False:
|
|
299
|
+
temp_pdf2 = os.path.join(dest_dir, "input_totoA4.pdf")
|
|
300
|
+
if 0!=convert_pdf_to_a4(temp_pdf,temp_pdf2):
|
|
301
|
+
print("erreur au resize du pdf")
|
|
302
|
+
return 1
|
|
303
|
+
temp_pdf=temp_pdf2
|
|
304
|
+
wait_for_file_access(temp_pdf)
|
|
305
|
+
time.sleep(1)
|
|
306
|
+
result=0
|
|
307
|
+
# Conversion du PDF en DOCX
|
|
308
|
+
for _ in range(4):
|
|
309
|
+
time.sleep(1)
|
|
310
|
+
result = convert_pdf_to_docx(str(temp_pdf), str(temp_docx))
|
|
311
|
+
if result==0:
|
|
312
|
+
break
|
|
313
|
+
if result == 0:
|
|
314
|
+
# Copie du fichier converti vers la destination finale
|
|
315
|
+
shutil.copy2(temp_docx, output_path)
|
|
316
|
+
print(f"recopie réussie : {output_path}")
|
|
317
|
+
|
|
318
|
+
# Supprimer les fichiers temporaires après le déplacement
|
|
319
|
+
# if temp_docx.exists():
|
|
320
|
+
# temp_docx.unlink()
|
|
321
|
+
# if temp_pdf.exists():
|
|
322
|
+
# temp_pdf.unlink()
|
|
323
|
+
return 0
|
|
324
|
+
else:
|
|
325
|
+
print("Erreur lors de la conversion.")
|
|
326
|
+
return 1
|
|
327
|
+
|
|
328
|
+
except Exception as e:
|
|
329
|
+
print(f"Erreur : {e}")
|
|
330
|
+
return 1
|
|
331
|
+
|
|
332
|
+
|
|
333
|
+
|
|
File without changes
|
|
@@ -1,279 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
import subprocess
|
|
3
|
-
import tempfile
|
|
4
|
-
|
|
5
|
-
from PyQt5.QtWidgets import QPushButton, QListWidget, QListWidgetItem, QApplication, QLabel, QWidget, QVBoxLayout
|
|
6
|
-
from PyQt5.QtGui import QFont
|
|
7
|
-
from PyQt5.QtCore import Qt, QThread, pyqtSignal, QObject
|
|
8
|
-
from PyQt5 import uic
|
|
9
|
-
from Orange.widgets.widget import OWWidget, Output, Input
|
|
10
|
-
from Orange.data import Table, Domain, StringVariable
|
|
11
|
-
from Orange.widgets.settings import Setting
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
class FileDialogWorker(QObject):
|
|
15
|
-
finished = pyqtSignal(list)
|
|
16
|
-
|
|
17
|
-
def __init__(self, ps_filter):
|
|
18
|
-
super().__init__()
|
|
19
|
-
self.ps_filter = ps_filter
|
|
20
|
-
|
|
21
|
-
def run(self):
|
|
22
|
-
from PyQt5.QtWidgets import QApplication
|
|
23
|
-
screen = QApplication.primaryScreen().geometry()
|
|
24
|
-
x = screen.x() + (screen.width() // 2) - 400
|
|
25
|
-
y = screen.y() + (screen.height() // 2) - 200
|
|
26
|
-
|
|
27
|
-
ps_code = f"""
|
|
28
|
-
Add-Type -AssemblyName System.Windows.Forms
|
|
29
|
-
|
|
30
|
-
# Créer une nouvelle fenêtre parent invisible
|
|
31
|
-
$parentForm = New-Object System.Windows.Forms.Form -Property @{{
|
|
32
|
-
Size = New-Object System.Drawing.Size(0,0) # Taille minimale
|
|
33
|
-
StartPosition = 'CenterScreen'
|
|
34
|
-
TopMost = $true
|
|
35
|
-
ShowInTaskbar = $false
|
|
36
|
-
FormBorderStyle = 'None'
|
|
37
|
-
Opacity = 0 # Rendre la fenêtre totalement transparente
|
|
38
|
-
}}
|
|
39
|
-
|
|
40
|
-
# Créer la boîte de dialogue de sélection de fichiers
|
|
41
|
-
$openFileDialog = New-Object System.Windows.Forms.OpenFileDialog -Property @{{
|
|
42
|
-
Filter = "{self.ps_filter}"
|
|
43
|
-
Multiselect = $true
|
|
44
|
-
}}
|
|
45
|
-
|
|
46
|
-
# Afficher la boîte de dialogue en tant que fenêtre enfant de $parentForm
|
|
47
|
-
$result = $openFileDialog.ShowDialog($parentForm)
|
|
48
|
-
|
|
49
|
-
# Traiter les fichiers sélectionnés
|
|
50
|
-
if ($result -eq [System.Windows.Forms.DialogResult]::OK) {{
|
|
51
|
-
$selectedFiles = $openFileDialog.FileNames
|
|
52
|
-
foreach ($file in $selectedFiles) {{
|
|
53
|
-
Write-Output $file
|
|
54
|
-
}}
|
|
55
|
-
}}
|
|
56
|
-
|
|
57
|
-
# Fermer la fenêtre parent
|
|
58
|
-
$parentForm.Close()
|
|
59
|
-
"""
|
|
60
|
-
|
|
61
|
-
with tempfile.NamedTemporaryFile(delete=False, suffix=".ps1", mode="w", encoding="utf-8") as f:
|
|
62
|
-
f.write(ps_code)
|
|
63
|
-
ps_path = f.name
|
|
64
|
-
|
|
65
|
-
result = subprocess.run(
|
|
66
|
-
["powershell", "-ExecutionPolicy", "Bypass", "-File", ps_path],
|
|
67
|
-
capture_output=True, text=True
|
|
68
|
-
)
|
|
69
|
-
os.unlink(ps_path)
|
|
70
|
-
|
|
71
|
-
file_paths = [line.strip() for line in result.stdout.strip().splitlines() if line.strip()]
|
|
72
|
-
self.finished.emit(file_paths)
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
class OWFileExtSelector(OWWidget):
|
|
76
|
-
name = "File Extension Selector"
|
|
77
|
-
description = "Select multiple extensions and files"
|
|
78
|
-
icon = "icons/file_extensor.png"
|
|
79
|
-
if "site-packages/Orange/widgets" in os.path.dirname(os.path.abspath(__file__)).replace("\\", "/"):
|
|
80
|
-
icon = "icons_dev/file_extensor.png"
|
|
81
|
-
category = "AAIT - Input"
|
|
82
|
-
gui_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "designer/ow_file_ext_selector.ui")
|
|
83
|
-
priority = 10
|
|
84
|
-
|
|
85
|
-
selected_extensions = Setting(["*.txt"])
|
|
86
|
-
selected_paths = Setting([])
|
|
87
|
-
|
|
88
|
-
class Inputs:
|
|
89
|
-
in_data = Input("Data", Table)
|
|
90
|
-
|
|
91
|
-
class Outputs:
|
|
92
|
-
data = Output("Data", Table)
|
|
93
|
-
|
|
94
|
-
def __init__(self):
|
|
95
|
-
super().__init__()
|
|
96
|
-
self.in_data = None
|
|
97
|
-
self.overlay = None
|
|
98
|
-
|
|
99
|
-
uic.loadUi(self.gui_path, self)
|
|
100
|
-
|
|
101
|
-
self.extension_list = self.findChild(QListWidget, "listExtensions")
|
|
102
|
-
self.file_button = self.findChild(QPushButton, "fileButton")
|
|
103
|
-
|
|
104
|
-
self.extension_list.setSelectionMode(QListWidget.MultiSelection)
|
|
105
|
-
self.populate_extensions()
|
|
106
|
-
self.restore_selected_extensions()
|
|
107
|
-
|
|
108
|
-
self.file_button.clicked.connect(self.select_files)
|
|
109
|
-
self.extension_list.itemSelectionChanged.connect(self.update_settings)
|
|
110
|
-
|
|
111
|
-
def loadSettings(self):
|
|
112
|
-
super().loadSettings()
|
|
113
|
-
|
|
114
|
-
def update_settings(self):
|
|
115
|
-
self.selected_extensions = self.get_selected_extensions()
|
|
116
|
-
self.saveSettings()
|
|
117
|
-
|
|
118
|
-
def restore_selected_extensions(self):
|
|
119
|
-
for i in range(self.extension_list.count()):
|
|
120
|
-
item = self.extension_list.item(i)
|
|
121
|
-
if item.flags() != Qt.NoItemFlags:
|
|
122
|
-
ext = item.data(Qt.UserRole)
|
|
123
|
-
if ext in self.selected_extensions:
|
|
124
|
-
item.setSelected(True)
|
|
125
|
-
self.update_settings()
|
|
126
|
-
|
|
127
|
-
def restore_selected_paths(self):
|
|
128
|
-
if self.selected_paths:
|
|
129
|
-
self.commit_paths()
|
|
130
|
-
|
|
131
|
-
def populate_extensions(self):
|
|
132
|
-
def add_category(label):
|
|
133
|
-
item = QListWidgetItem(label)
|
|
134
|
-
item.setFlags(Qt.NoItemFlags)
|
|
135
|
-
font = QFont()
|
|
136
|
-
font.setBold(True)
|
|
137
|
-
item.setFont(font)
|
|
138
|
-
item.setForeground(Qt.gray)
|
|
139
|
-
self.extension_list.addItem(item)
|
|
140
|
-
|
|
141
|
-
def add_extension(label, ext):
|
|
142
|
-
item = QListWidgetItem(f" {label}")
|
|
143
|
-
item.setData(Qt.UserRole, ext)
|
|
144
|
-
self.extension_list.addItem(item)
|
|
145
|
-
|
|
146
|
-
extensions = {
|
|
147
|
-
"Documents": [
|
|
148
|
-
("Text files (*.txt)", "*.txt"),
|
|
149
|
-
("Word documents (*.docx)", "*.docx"),
|
|
150
|
-
("PDF files (*.pdf)", "*.pdf"),
|
|
151
|
-
("Markdown (*.md)", "*.md"),
|
|
152
|
-
],
|
|
153
|
-
"Tableurs": [
|
|
154
|
-
("Excel files (*.xlsx)", "*.xlsx"),
|
|
155
|
-
("CSV files (*.csv)", "*.csv"),
|
|
156
|
-
],
|
|
157
|
-
"Images": [
|
|
158
|
-
("JPEG images (*.jpg *.jpeg)", "*.jpg *.jpeg"),
|
|
159
|
-
("PNG images (*.png)", "*.png"),
|
|
160
|
-
("GIF images (*.gif)", "*.gif"),
|
|
161
|
-
("SVG images (*.svg)", "*.svg"),
|
|
162
|
-
],
|
|
163
|
-
"Audio": [
|
|
164
|
-
("MP3 (*.mp3)", "*.mp3"),
|
|
165
|
-
("WAV (*.wav)", "*.wav"),
|
|
166
|
-
],
|
|
167
|
-
"Vidéo": [
|
|
168
|
-
("MP4 (*.mp4)", "*.mp4"),
|
|
169
|
-
("MKV (*.mkv)", "*.mkv"),
|
|
170
|
-
],
|
|
171
|
-
"Archives": [
|
|
172
|
-
("ZIP (*.zip)", "*.zip"),
|
|
173
|
-
("RAR (*.rar)", "*.rar"),
|
|
174
|
-
("7-Zip (*.7z)", "*.7z"),
|
|
175
|
-
],
|
|
176
|
-
"Code": [
|
|
177
|
-
("Python (*.py)", "*.py"),
|
|
178
|
-
("JSON (*.json)", "*.json"),
|
|
179
|
-
("HTML (*.html)", "*.html"),
|
|
180
|
-
("XML (*.xml)", "*.xml"),
|
|
181
|
-
("OWS (*.ows)", "*.ows"),
|
|
182
|
-
],
|
|
183
|
-
"Autres": [
|
|
184
|
-
("All files (*.*)", "*.*")
|
|
185
|
-
]
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
for category, items in extensions.items():
|
|
189
|
-
add_category(category)
|
|
190
|
-
for label, ext in items:
|
|
191
|
-
add_extension(label, ext)
|
|
192
|
-
|
|
193
|
-
def get_selected_extensions(self):
|
|
194
|
-
selected = [
|
|
195
|
-
item.data(Qt.UserRole)
|
|
196
|
-
for item in self.extension_list.selectedItems()
|
|
197
|
-
if item.flags() != Qt.NoItemFlags
|
|
198
|
-
]
|
|
199
|
-
return selected
|
|
200
|
-
|
|
201
|
-
def show_overlay(self):
|
|
202
|
-
if not self.overlay:
|
|
203
|
-
self.overlay = QWidget()
|
|
204
|
-
self.overlay.setWindowFlags(
|
|
205
|
-
Qt.FramelessWindowHint |
|
|
206
|
-
Qt.Tool # ← PAS de WindowStaysOnTopHint
|
|
207
|
-
)
|
|
208
|
-
self.overlay.setAttribute(Qt.WA_TranslucentBackground)
|
|
209
|
-
self.overlay.setAttribute(Qt.WA_TransparentForMouseEvents)
|
|
210
|
-
self.overlay.setStyleSheet("background-color: rgba(0, 0, 0, 150);")
|
|
211
|
-
|
|
212
|
-
layout = QVBoxLayout(self.overlay)
|
|
213
|
-
message = QLabel("Veuillez sélectionner un fichier...")
|
|
214
|
-
message.setStyleSheet("color: white; font-size: 24px;")
|
|
215
|
-
message.setAlignment(Qt.AlignCenter)
|
|
216
|
-
layout.addWidget(message)
|
|
217
|
-
self.overlay.setLayout(layout)
|
|
218
|
-
|
|
219
|
-
screen_geometry = QApplication.primaryScreen().geometry()
|
|
220
|
-
self.overlay.setGeometry(screen_geometry)
|
|
221
|
-
self.overlay.show()
|
|
222
|
-
|
|
223
|
-
QApplication.processEvents()
|
|
224
|
-
|
|
225
|
-
def hide_overlay(self):
|
|
226
|
-
if self.overlay:
|
|
227
|
-
self.overlay.hide()
|
|
228
|
-
self.overlay = None
|
|
229
|
-
|
|
230
|
-
def select_files(self):
|
|
231
|
-
self.show_overlay()
|
|
232
|
-
|
|
233
|
-
selected_exts = self.get_selected_extensions()
|
|
234
|
-
if not selected_exts:
|
|
235
|
-
self.warning("Please select at least one extension.")
|
|
236
|
-
self.hide_overlay()
|
|
237
|
-
return
|
|
238
|
-
|
|
239
|
-
all_patterns = ";".join(selected_exts)
|
|
240
|
-
ps_filter = f"Supported files ({all_patterns})|{all_patterns}"
|
|
241
|
-
|
|
242
|
-
self.thread = QThread()
|
|
243
|
-
self.worker = FileDialogWorker(ps_filter)
|
|
244
|
-
self.worker.moveToThread(self.thread)
|
|
245
|
-
|
|
246
|
-
self.thread.started.connect(self.worker.run)
|
|
247
|
-
self.worker.finished.connect(self.on_files_selected)
|
|
248
|
-
self.worker.finished.connect(self.thread.quit)
|
|
249
|
-
self.worker.finished.connect(self.worker.deleteLater)
|
|
250
|
-
self.thread.finished.connect(self.thread.deleteLater)
|
|
251
|
-
|
|
252
|
-
self.thread.start()
|
|
253
|
-
|
|
254
|
-
def on_files_selected(self, file_paths):
|
|
255
|
-
self.hide_overlay()
|
|
256
|
-
if file_paths:
|
|
257
|
-
self.selected_paths = file_paths
|
|
258
|
-
self.commit_paths()
|
|
259
|
-
|
|
260
|
-
def commit_paths(self):
|
|
261
|
-
var = StringVariable("file_path")
|
|
262
|
-
domain = Domain([], metas=[var])
|
|
263
|
-
table = Table(domain, [[p] for p in self.selected_paths])
|
|
264
|
-
self.Outputs.data.send(table)
|
|
265
|
-
|
|
266
|
-
@Inputs.in_data
|
|
267
|
-
def set_input_data(self, data):
|
|
268
|
-
self.in_data = data
|
|
269
|
-
|
|
270
|
-
def handleNewSignals(self):
|
|
271
|
-
pass
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
if __name__ == "__main__":
|
|
275
|
-
import sys
|
|
276
|
-
app = QApplication(sys.argv)
|
|
277
|
-
ow = OWFileExtSelector()
|
|
278
|
-
ow.show()
|
|
279
|
-
sys.exit(app.exec_())
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
from PyQt5.QtWidgets import QPushButton, QListWidget, QListWidgetItem, QApplication, QWidget, QVBoxLayout, QSizePolicy
|
|
3
|
-
from PyQt5.QtGui import QFont
|
|
4
|
-
from PyQt5.QtCore import Qt
|
|
5
|
-
from PyQt5 import uic
|
|
6
|
-
from AnyQt.QtWidgets import QFileDialog
|
|
7
|
-
from Orange.widgets.widget import OWWidget, Output, Input
|
|
8
|
-
from Orange.data import Table, Domain, StringVariable
|
|
9
|
-
from Orange.widgets.settings import Setting
|
|
10
|
-
|
|
11
|
-
if "site-packages/Orange/widgets" in os.path.dirname(os.path.abspath(__file__)).replace("\\", "/"):
|
|
12
|
-
from orangecontrib.AAIT.utils.import_uic import uic
|
|
13
|
-
from orangecontrib.AAIT.utils import SimpleDialogQt
|
|
14
|
-
from orangecontrib.AAIT.utils.MetManagement import get_local_store_path, GetFromRemote
|
|
15
|
-
else:
|
|
16
|
-
from orangecontrib.AAIT.utils.import_uic import uic
|
|
17
|
-
from orangecontrib.AAIT.utils import SimpleDialogQt
|
|
18
|
-
from orangecontrib.AAIT.utils.MetManagement import get_local_store_path, GetFromRemote
|
|
19
|
-
|
|
20
|
-
from PyQt5.QtWebEngineWidgets import QWebEngineView
|
|
21
|
-
from PyQt5.QtCore import QUrl
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
class OWFileExtSelector(OWWidget):
|
|
25
|
-
name = "Javascript visualization"
|
|
26
|
-
description = "Select multiple extensions and files"
|
|
27
|
-
icon = "icons/visualizationer.png"
|
|
28
|
-
if "site-packages/Orange/widgets" in os.path.dirname(os.path.abspath(__file__)).replace("\\", "/"):
|
|
29
|
-
icon = "icons_dev/visualizationer.png"
|
|
30
|
-
category = "AAIT - Input"
|
|
31
|
-
gui_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "designer/owvisualizationer.ui")
|
|
32
|
-
priority = 10
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
class Inputs:
|
|
36
|
-
in_data = Input("Data", Table)
|
|
37
|
-
|
|
38
|
-
class Outputs:
|
|
39
|
-
data = Output("Data", Table)
|
|
40
|
-
|
|
41
|
-
def __init__(self):
|
|
42
|
-
super().__init__()
|
|
43
|
-
self.in_data = None
|
|
44
|
-
|
|
45
|
-
# Load UI
|
|
46
|
-
uic.loadUi(self.gui_path, self)
|
|
47
|
-
|
|
48
|
-
self.web_frame = self.findChild(QWidget, "webFrame") # Doit exister dans le .ui
|
|
49
|
-
self.web_view = QWebEngineView(self.web_frame)
|
|
50
|
-
self.web_view.setMinimumSize(400, 300)
|
|
51
|
-
self.web_view.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
|
|
52
|
-
|
|
53
|
-
# Crée un layout si nécessaire
|
|
54
|
-
layout = QVBoxLayout(self.web_frame)
|
|
55
|
-
layout.setContentsMargins(0, 0, 0, 0)
|
|
56
|
-
layout.addWidget(self.web_view)
|
|
57
|
-
|
|
58
|
-
# Charge ton fichier HTML local
|
|
59
|
-
html_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "designer/chart.html"))
|
|
60
|
-
self.web_view.load(QUrl.fromLocalFile(html_path))
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
@Inputs.in_data
|
|
64
|
-
def set_input_data(self, data):
|
|
65
|
-
self.in_data = data
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
if __name__ == "__main__":
|
|
69
|
-
import sys
|
|
70
|
-
app = QApplication(sys.argv)
|
|
71
|
-
ow = OWFileExtSelector()
|
|
72
|
-
ow.show()
|
|
73
|
-
sys.exit(app.exec_())
|
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
import sys
|
|
3
|
-
from Orange.data import Domain, StringVariable, Table
|
|
4
|
-
import Orange.data
|
|
5
|
-
from AnyQt.QtWidgets import QApplication
|
|
6
|
-
from Orange.widgets import widget
|
|
7
|
-
from Orange.widgets.utils.signals import Input, Output
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
if "site-packages/Orange/widgets" in os.path.dirname(os.path.abspath(__file__)).replace("\\", "/"):
|
|
11
|
-
from Orange.widgets.orangecontrib.AAIT.utils import thread_management
|
|
12
|
-
from Orange.widgets.orangecontrib.AAIT.utils.import_uic import uic
|
|
13
|
-
from Orange.widgets.orangecontrib.AAIT.utils.initialize_from_ini import apply_modification_from_python_file
|
|
14
|
-
else:
|
|
15
|
-
from orangecontrib.AAIT.utils import thread_management
|
|
16
|
-
from orangecontrib.AAIT.utils.import_uic import uic
|
|
17
|
-
from orangecontrib.AAIT.utils.initialize_from_ini import apply_modification_from_python_file
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
@apply_modification_from_python_file(filepath_original_widget=__file__)
|
|
21
|
-
class OWMailLoader(widget.OWWidget):
|
|
22
|
-
name = "OWMailLoader"
|
|
23
|
-
description = "Load a mail from AAIT format"
|
|
24
|
-
icon = ""
|
|
25
|
-
#if "site-packages/Orange/widgets" in os.path.dirname(os.path.abspath(__file__)).replace("\\", "/"):
|
|
26
|
-
# icon = "icons_dev/owqueryllm.svg"
|
|
27
|
-
gui = os.path.join(os.path.dirname(os.path.abspath(__file__)), "designer/owmailloader.ui")
|
|
28
|
-
want_control_area = True
|
|
29
|
-
priority = 9999
|
|
30
|
-
|
|
31
|
-
class Inputs:
|
|
32
|
-
data = Input("Data", Orange.data.Table)
|
|
33
|
-
|
|
34
|
-
class Outputs:
|
|
35
|
-
data_out_all_dir = Output("Data Out All Dir", Orange.data.Table)
|
|
36
|
-
data_out_nothing_to_do=Output("Data Out Nothing to Do", Orange.data.Table)
|
|
37
|
-
|
|
38
|
-
@Inputs.data
|
|
39
|
-
def set_data(self, in_data):
|
|
40
|
-
self.valid_folders=[]
|
|
41
|
-
input_dir_path=""
|
|
42
|
-
self.error("")
|
|
43
|
-
if in_data is None:
|
|
44
|
-
return
|
|
45
|
-
if not "input_dir" in in_data.domain:
|
|
46
|
-
self.error("need input_dir in input data domain" )
|
|
47
|
-
return
|
|
48
|
-
if len(in_data)!=1:
|
|
49
|
-
self.error("in data need to be exactly 1 line" )
|
|
50
|
-
return
|
|
51
|
-
input_dir_path=str(in_data[0]["input_dir"].value)
|
|
52
|
-
input_dir_path.replace ("\\","/")
|
|
53
|
-
|
|
54
|
-
self.valid_folders=self.get_valid_folders(input_dir_path)
|
|
55
|
-
if len(self.valid_folders)==0:
|
|
56
|
-
self.send_nothing_to_do()
|
|
57
|
-
return
|
|
58
|
-
print( self.valid_folders)
|
|
59
|
-
self.run()
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
def __init__(self):
|
|
63
|
-
super().__init__()
|
|
64
|
-
# Qt Management
|
|
65
|
-
self.valid_folders=[]
|
|
66
|
-
self.can_run = True
|
|
67
|
-
self.setFixedWidth(700)
|
|
68
|
-
self.setFixedHeight(500)
|
|
69
|
-
uic.loadUi(self.gui, self)
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
# # Data Management
|
|
75
|
-
self.thread = None
|
|
76
|
-
|
|
77
|
-
# Custom updates
|
|
78
|
-
self.post_initialized()
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
def get_valid_folders(self,input_dir_path):
|
|
83
|
-
in_dir = os.path.join(input_dir_path, "in")
|
|
84
|
-
|
|
85
|
-
# Étape 1 : Vérifier si le dossier existe
|
|
86
|
-
if not os.path.isdir(in_dir):
|
|
87
|
-
print(f"Dossier introuvable : {in_dir}")
|
|
88
|
-
return [] # ou `return` selon ton besoin
|
|
89
|
-
|
|
90
|
-
# Étape 2 : Parcourir les sous-dossiers
|
|
91
|
-
valid_folders = []
|
|
92
|
-
for name in os.listdir(in_dir):
|
|
93
|
-
full_path = os.path.join(in_dir, name)
|
|
94
|
-
if os.path.isdir(full_path):
|
|
95
|
-
mail_ok_path = os.path.join(full_path, "mail.ok")
|
|
96
|
-
if os.path.isfile(mail_ok_path):
|
|
97
|
-
valid_folders.append(full_path.replace("\\","/"))
|
|
98
|
-
|
|
99
|
-
return valid_folders
|
|
100
|
-
def send_nothing_to_do(self):
|
|
101
|
-
|
|
102
|
-
# Définir une variable texte comme méta-attribut
|
|
103
|
-
text_meta = StringVariable("nothing to do")
|
|
104
|
-
|
|
105
|
-
# Créer un domaine sans variables principales, avec une méta
|
|
106
|
-
domain = Domain([], metas=[text_meta])
|
|
107
|
-
|
|
108
|
-
# Créer la table avec Table.from_list
|
|
109
|
-
data_table = Table.from_list(domain, [["nothing"]])
|
|
110
|
-
self.Outputs.data_out_nothing_to_do.send(data_table)
|
|
111
|
-
|
|
112
|
-
def run(self):
|
|
113
|
-
# Définir les variables de texte
|
|
114
|
-
var_mail_txt = StringVariable("mail_path")
|
|
115
|
-
var_pj_list = StringVariable("pj_files")
|
|
116
|
-
|
|
117
|
-
# Définir le domaine avec deux colonnes texte
|
|
118
|
-
domain = Domain([], metas=[var_mail_txt, var_pj_list])
|
|
119
|
-
|
|
120
|
-
# Construire les lignes de données
|
|
121
|
-
rows = []
|
|
122
|
-
for folder in self.valid_folders:
|
|
123
|
-
# Chemin vers mail.txt
|
|
124
|
-
mail_path = os.path.join(folder, "mail.txt")
|
|
125
|
-
|
|
126
|
-
# Chemin vers le sous-dossier "pj"
|
|
127
|
-
pj_path = os.path.join(folder, "pj")
|
|
128
|
-
|
|
129
|
-
# Lister les fichiers dans pj (ou chaîne vide s'il n'existe pas)
|
|
130
|
-
if os.path.isdir(pj_path):
|
|
131
|
-
files = os.listdir(pj_path)
|
|
132
|
-
else:
|
|
133
|
-
files = []
|
|
134
|
-
|
|
135
|
-
# Convertir la liste de fichiers en chaîne (ex : "file1.pdf, file2.docx")
|
|
136
|
-
files_str = ", ".join(files)
|
|
137
|
-
files_str='['+files_str+']'
|
|
138
|
-
# Ajouter la ligne
|
|
139
|
-
rows.append([mail_path, files_str])
|
|
140
|
-
|
|
141
|
-
# Créer la table Orange
|
|
142
|
-
data_table = Table.from_list(domain, rows)
|
|
143
|
-
|
|
144
|
-
# Afficher la table
|
|
145
|
-
self.Outputs.data_out_all_dir.send(data_table)
|
|
146
|
-
|
|
147
|
-
def post_initialized(self):
|
|
148
|
-
pass
|
|
149
|
-
|
|
150
|
-
if __name__ == "__main__":
|
|
151
|
-
app = QApplication(sys.argv)
|
|
152
|
-
data = Orange.data.Table("C:/toto_ta_ta_titi/input.tab")
|
|
153
|
-
my_widget = OWMailLoader()
|
|
154
|
-
my_widget.show()
|
|
155
|
-
my_widget.set_data(data)
|
|
156
|
-
app.exec_()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{io4it-1.0.0.1 → io4it-1.0.0.3}/orangecontrib/IO4IT/widgets/designer/ow_file_ext_selector.ui
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|