IO4IT 4.0.5__tar.gz → 4.0.7__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-4.0.5 → io4it-4.0.7}/PKG-INFO +1 -1
- {io4it-4.0.5 → io4it-4.0.7}/io4it.egg-info/PKG-INFO +1 -1
- {io4it-4.0.5 → io4it-4.0.7}/io4it.egg-info/SOURCES.txt +4 -0
- io4it-4.0.7/orangecontrib/IO4IT/utils/environment_collector.py +71 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/utils/mail.py +15 -5
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/OWPPTX2JPG.py +8 -23
- io4it-4.0.7/orangecontrib/IO4IT/widgets/OWPipAuditor.py +240 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/OWXLSX_insert.py +21 -4
- io4it-4.0.7/orangecontrib/IO4IT/widgets/designer/owpipauditor.ui +101 -0
- io4it-4.0.7/orangecontrib/IO4IT/widgets/icons/pip_auditor.png +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/setup.py +1 -1
- {io4it-4.0.5 → io4it-4.0.7}/io4it.egg-info/dependency_links.txt +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/io4it.egg-info/entry_points.txt +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/io4it.egg-info/namespace_packages.txt +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/io4it.egg-info/requires.txt +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/io4it.egg-info/top_level.txt +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/__init__.py +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/ocr_function/__init__.py +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/ocr_function/word_converter.py +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/toolViews/designer/key_manager_ui.ui +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/toolViews/designer/link_workflow_manager_ui.ui +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/toolViews/key_manager_ui.py +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/toolViews/linkHTLMWorkflow_manager_ui.py +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/utils/__init__.py +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/utils/keys_manager.py +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/utils/pool_exec_utils.py +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/utils/pptx2jpg.py +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/utils/secret_manager.py +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/utils/utils_md.py +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/OWChatGpt.py +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/OWDeep_Search.py +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/OWDoclingToMarkdown.py +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/OWExportMarkdown.py +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/OWExtractTablesDocxToXlsx.py +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/OWInboxMailMonitoring.py +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/OWJsonToDataTable.py +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/OWMD2HTML.py +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/OWMarkdownLoader.py +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/OWMarkdownizer.py +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/OWOfficeNormalizer.py +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/OWParserHTML.py +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/OWPdfType.py +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/OWProcessPoolExecutor.py +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/OWS3Uploader.py +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/OWS3downloader.py +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/OWS3list.py +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/OWWebSearch.py +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/OWmailLoader.py +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/OWmailSender.py +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/OWwordpdf2docx.py +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/__init__.py +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/designer/__init__.py +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/designer/nogui.ui +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/designer/ow_extract_tables_docx_to_xlsx.ui +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/designer/ow_file_ext_selector.ui +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/designer/ow_json_to_data_table.ui +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/designer/owchatgpt.ui +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/designer/owdeepsearch.ui +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/designer/owdoclingasr.ui +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/designer/owdoclingtomarkdown.ui +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/designer/owexportmarkdown.ui +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/designer/owinboxmailmonitoring.ui +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/designer/owinsertdatatoexcel.ui +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/designer/owmailloader.ui +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/designer/owmailsender.ui +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/designer/owmarkdownizer.ui +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/designer/owmarkdownloader.ui +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/designer/owmd2html.ui +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/designer/owofficenormalizer.ui +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/designer/owparserhtml.ui +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/designer/owpdftype.ui +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/designer/owpptx2jpg.ui +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/designer/owprocesspoolexecutor.ui +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/designer/owspeechtotext.ui +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/designer/owvisualizationer.ui +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/designer/owwebsearch.ui +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/designer/wordpdf2docx.ui +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/icons/__init__.py +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/icons/chatgpt.png +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/icons/check_pdf.png +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/icons/deepsearch.svg +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/icons/dep_md_old.png +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/icons/download.png +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/icons/export_md.png +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/icons/extract_table.png +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/icons/file_extensor.png +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/icons/html.png +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/icons/json-file.png +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/icons/list_aws.png +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/icons/load_md.png +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/icons/mail_loader.png +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/icons/mail_writer.png +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/icons/md.png +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/icons/monitor-email.svg +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/icons/office_normalizer.png +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/icons/owmd2html.svg +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/icons/pptx2jpg.png +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/icons/process_pool_executor.png +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/icons/speech_to_text.png +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/icons/upload.png +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/icons/visualizationer.png +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/icons/websearch.png +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/icons/wordpdf2docx.png +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/icons/xlsx_insert.png +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/icons_dev/__init__.py +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/orangecontrib/__init__.py +0 -0
- {io4it-4.0.5 → io4it-4.0.7}/setup.cfg +0 -0
|
@@ -11,6 +11,7 @@ orangecontrib/IO4IT/__init__.py
|
|
|
11
11
|
orangecontrib/IO4IT/ocr_function/__init__.py
|
|
12
12
|
orangecontrib/IO4IT/ocr_function/word_converter.py
|
|
13
13
|
orangecontrib/IO4IT/utils/__init__.py
|
|
14
|
+
orangecontrib/IO4IT/utils/environment_collector.py
|
|
14
15
|
orangecontrib/IO4IT/utils/keys_manager.py
|
|
15
16
|
orangecontrib/IO4IT/utils/mail.py
|
|
16
17
|
orangecontrib/IO4IT/utils/pool_exec_utils.py
|
|
@@ -31,6 +32,7 @@ orangecontrib/IO4IT/widgets/OWOfficeNormalizer.py
|
|
|
31
32
|
orangecontrib/IO4IT/widgets/OWPPTX2JPG.py
|
|
32
33
|
orangecontrib/IO4IT/widgets/OWParserHTML.py
|
|
33
34
|
orangecontrib/IO4IT/widgets/OWPdfType.py
|
|
35
|
+
orangecontrib/IO4IT/widgets/OWPipAuditor.py
|
|
34
36
|
orangecontrib/IO4IT/widgets/OWProcessPoolExecutor.py
|
|
35
37
|
orangecontrib/IO4IT/widgets/OWS3Uploader.py
|
|
36
38
|
orangecontrib/IO4IT/widgets/OWS3downloader.py
|
|
@@ -65,6 +67,7 @@ orangecontrib/IO4IT/widgets/designer/owmd2html.ui
|
|
|
65
67
|
orangecontrib/IO4IT/widgets/designer/owofficenormalizer.ui
|
|
66
68
|
orangecontrib/IO4IT/widgets/designer/owparserhtml.ui
|
|
67
69
|
orangecontrib/IO4IT/widgets/designer/owpdftype.ui
|
|
70
|
+
orangecontrib/IO4IT/widgets/designer/owpipauditor.ui
|
|
68
71
|
orangecontrib/IO4IT/widgets/designer/owpptx2jpg.ui
|
|
69
72
|
orangecontrib/IO4IT/widgets/designer/owprocesspoolexecutor.ui
|
|
70
73
|
orangecontrib/IO4IT/widgets/designer/owspeechtotext.ui
|
|
@@ -90,6 +93,7 @@ orangecontrib/IO4IT/widgets/icons/md.png
|
|
|
90
93
|
orangecontrib/IO4IT/widgets/icons/monitor-email.svg
|
|
91
94
|
orangecontrib/IO4IT/widgets/icons/office_normalizer.png
|
|
92
95
|
orangecontrib/IO4IT/widgets/icons/owmd2html.svg
|
|
96
|
+
orangecontrib/IO4IT/widgets/icons/pip_auditor.png
|
|
93
97
|
orangecontrib/IO4IT/widgets/icons/pptx2jpg.png
|
|
94
98
|
orangecontrib/IO4IT/widgets/icons/process_pool_executor.png
|
|
95
99
|
orangecontrib/IO4IT/widgets/icons/speech_to_text.png
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
import platform
|
|
3
|
+
import datetime
|
|
4
|
+
|
|
5
|
+
try:
|
|
6
|
+
import importlib.metadata as importlib_metadata
|
|
7
|
+
except ImportError:
|
|
8
|
+
import importlib_metadata # fallback for Python < 3.8
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class EnvironmentCollector:
|
|
12
|
+
"""
|
|
13
|
+
Utilitaire pour collecter les informations d'environnement système
|
|
14
|
+
(OS, Python, dépendances pip) sans recourir à subprocess.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
@staticmethod
|
|
18
|
+
def _dependencies_freeze_space() -> str:
|
|
19
|
+
"""
|
|
20
|
+
Retourne l'équivalent d'un `pip freeze` (Package==Version ...)
|
|
21
|
+
séparé par des retours à la ligne.
|
|
22
|
+
Utilise importlib.metadata (pas de subprocess).
|
|
23
|
+
"""
|
|
24
|
+
try:
|
|
25
|
+
dists = sorted(
|
|
26
|
+
importlib_metadata.distributions(),
|
|
27
|
+
key=lambda d: (d.metadata.get("Name", "") or "").lower()
|
|
28
|
+
)
|
|
29
|
+
parts = []
|
|
30
|
+
for dist in dists:
|
|
31
|
+
name = (dist.metadata.get("Name") or "").strip()
|
|
32
|
+
version = getattr(dist, "version", None)
|
|
33
|
+
if name and version:
|
|
34
|
+
parts.append(f"{name}=={version}")
|
|
35
|
+
return "\n\r".join(parts)
|
|
36
|
+
except Exception as e:
|
|
37
|
+
return f"Error collecting dependencies: {e}"
|
|
38
|
+
|
|
39
|
+
def _collect(self):
|
|
40
|
+
"""
|
|
41
|
+
Collecte les informations clés de l'environnement courant.
|
|
42
|
+
|
|
43
|
+
Returns:
|
|
44
|
+
tuple: (keys: list[str], vals: list[str|None])
|
|
45
|
+
- keys : noms des colonnes
|
|
46
|
+
- vals : valeurs correspondantes
|
|
47
|
+
(None pour "Row number", géré en aval avec np.arange)
|
|
48
|
+
"""
|
|
49
|
+
keys = [
|
|
50
|
+
"Row number",
|
|
51
|
+
"Current Time",
|
|
52
|
+
"OS",
|
|
53
|
+
"Machine",
|
|
54
|
+
"Processor",
|
|
55
|
+
"Python Version",
|
|
56
|
+
"Python Executable",
|
|
57
|
+
"Dependencies",
|
|
58
|
+
]
|
|
59
|
+
|
|
60
|
+
vals = [
|
|
61
|
+
None, # Row number (géré dans _apply avec np.arange)
|
|
62
|
+
datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
|
|
63
|
+
platform.platform(),
|
|
64
|
+
platform.machine(),
|
|
65
|
+
platform.processor() or platform.machine(),
|
|
66
|
+
sys.version.replace("\n", " "),
|
|
67
|
+
sys.executable,
|
|
68
|
+
self._dependencies_freeze_space(),
|
|
69
|
+
]
|
|
70
|
+
|
|
71
|
+
return keys, vals
|
|
@@ -677,9 +677,18 @@ def extraire_emails(champ):
|
|
|
677
677
|
"""
|
|
678
678
|
if not champ:
|
|
679
679
|
return []
|
|
680
|
+
# Nettoie les guillemets littéraux et valeurs placeholder
|
|
681
|
+
champ = champ.strip().strip('"').strip("'")
|
|
682
|
+
|
|
683
|
+
if champ in ("", "?", "-", "none", "null"):
|
|
684
|
+
return []
|
|
680
685
|
|
|
681
686
|
emails = champ.replace(";", ",").split(",")
|
|
682
|
-
return [
|
|
687
|
+
return [
|
|
688
|
+
email.strip().strip('"').strip("'")
|
|
689
|
+
for email in emails
|
|
690
|
+
if email.strip().strip('"').strip("'") and "@" in email
|
|
691
|
+
]
|
|
683
692
|
|
|
684
693
|
def to_graph_recipients(champ):
|
|
685
694
|
"""
|
|
@@ -722,7 +731,7 @@ def check_send_new_emails(offusc_conf_agent, type_co):
|
|
|
722
731
|
destinataires,
|
|
723
732
|
infos["tit"],
|
|
724
733
|
infos["txt"],
|
|
725
|
-
cc=copies,
|
|
734
|
+
#cc=copies,
|
|
726
735
|
piece_jointe_paths=chemin_dossier_out + "/" + contenu + "/pj"
|
|
727
736
|
)
|
|
728
737
|
MetManagement.reset_folder(chemin_dossier_in + contenu, recreate=False)
|
|
@@ -906,7 +915,7 @@ def check_send_new_emails(offusc_conf_agent, type_co):
|
|
|
906
915
|
client_id, client_secret, tenant_id, user_email = keys_manager.lire_config_oauth2(
|
|
907
916
|
offusc_conf_agent, type_co
|
|
908
917
|
)
|
|
909
|
-
|
|
918
|
+
print(client_id, client_secret, tenant_id, user_email)
|
|
910
919
|
agent = user_email
|
|
911
920
|
chemin_dossier_in, chemin_dossier_out = mail_in_folder(agent, "out")
|
|
912
921
|
authority = f"https://login.microsoftonline.com/{tenant_id}"
|
|
@@ -993,6 +1002,7 @@ def check_send_new_emails(offusc_conf_agent, type_co):
|
|
|
993
1002
|
response = requests.post(send_url, headers=headers, json=message_data)
|
|
994
1003
|
response.raise_for_status()
|
|
995
1004
|
except requests.exceptions.HTTPError as e:
|
|
1005
|
+
print(f"Graph error body: {response.json()}") # ← ajoute cette ligne
|
|
996
1006
|
if response.status_code == 403:
|
|
997
1007
|
raise Exception("❌ Permission Mail.Send manquante.")
|
|
998
1008
|
else:
|
|
@@ -1035,7 +1045,7 @@ if __name__ == "__main__":
|
|
|
1035
1045
|
while True:
|
|
1036
1046
|
for offusc_conf_agent in offusc_conf_agents:
|
|
1037
1047
|
print("offusc conf agent : ", offusc_conf_agent)
|
|
1038
|
-
check_new_emails(offusc_conf_agent,type_co, list_agent_email)
|
|
1039
|
-
time.sleep(1)
|
|
1048
|
+
#check_new_emails(offusc_conf_agent,type_co, list_agent_email)
|
|
1049
|
+
#time.sleep(1)
|
|
1040
1050
|
check_send_new_emails(offusc_conf_agent,type_co)
|
|
1041
1051
|
time.sleep(1)
|
|
@@ -1,19 +1,17 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import sys
|
|
3
3
|
from AnyQt.QtWidgets import QApplication
|
|
4
|
-
from AnyQt.QtCore import pyqtSignal
|
|
4
|
+
from AnyQt.QtCore import pyqtSignal
|
|
5
5
|
from Orange.widgets.utils.signals import Input, Output
|
|
6
6
|
from Orange.data import Domain, StringVariable, Table, DiscreteVariable
|
|
7
7
|
from Orange.widgets.settings import Setting
|
|
8
8
|
|
|
9
9
|
if "site-packages/Orange/widgets" in os.path.dirname(os.path.abspath(__file__)).replace("\\", "/"):
|
|
10
10
|
from Orange.widgets.orangecontrib.IO4IT.utils import pptx2jpg
|
|
11
|
-
from Orange.widgets.orangecontrib.AAIT.utils.import_uic import uic
|
|
12
11
|
from Orange.widgets.orangecontrib.AAIT.utils.thread_management import Thread
|
|
13
12
|
from Orange.widgets.orangecontrib.AAIT.utils import base_widget
|
|
14
13
|
else:
|
|
15
14
|
from orangecontrib.IO4IT.utils import pptx2jpg
|
|
16
|
-
from orangecontrib.AAIT.utils.import_uic import uic
|
|
17
15
|
from orangecontrib.AAIT.utils.thread_management import Thread
|
|
18
16
|
from orangecontrib.AAIT.utils import base_widget
|
|
19
17
|
|
|
@@ -47,7 +45,7 @@ class OWPPTX2JPG(base_widget.BaseListWidget):
|
|
|
47
45
|
if self.data:
|
|
48
46
|
self.var_selector.add_variables(self.data.domain)
|
|
49
47
|
self.var_selector.select_variable_by_name(self.selected_column_name)
|
|
50
|
-
if self.
|
|
48
|
+
if self.auto_send:
|
|
51
49
|
self.run()
|
|
52
50
|
|
|
53
51
|
def __init__(self):
|
|
@@ -113,22 +111,10 @@ class OWPPTX2JPG(base_widget.BaseListWidget):
|
|
|
113
111
|
|
|
114
112
|
self.thread = Thread(self._convert_and_build_table, pptx_files, unique_folder)
|
|
115
113
|
|
|
116
|
-
self.thread.
|
|
114
|
+
self.thread.progress.connect(self.handle_progress)
|
|
117
115
|
self.thread.result.connect(self.handle_result)
|
|
118
116
|
self.thread.finish.connect(self.handle_finish)
|
|
119
117
|
self.thread.start()
|
|
120
|
-
|
|
121
|
-
def handleNewSignals(self):
|
|
122
|
-
if self.data:
|
|
123
|
-
has_path = any(v.name == self.selected_column_name for v in self.data.domain.variables + self.data.domain.metas)
|
|
124
|
-
if hasattr(self, "pushButton_send"):
|
|
125
|
-
self.pushButton_send.setEnabled(has_path)
|
|
126
|
-
|
|
127
|
-
if has_path and self.auto_send:
|
|
128
|
-
QTimer.singleShot(100, self.run)
|
|
129
|
-
else:
|
|
130
|
-
if hasattr(self, "pushButton_send"):
|
|
131
|
-
self.pushButton_send.setEnabled(False)
|
|
132
118
|
|
|
133
119
|
def handle_status_update(self, info):
|
|
134
120
|
path_str, status, message = info
|
|
@@ -137,14 +123,12 @@ class OWPPTX2JPG(base_widget.BaseListWidget):
|
|
|
137
123
|
|
|
138
124
|
def handle_progress(self, value: float) -> None:
|
|
139
125
|
"""Met à jour la barre de progression (reçu via progress_callback)"""
|
|
140
|
-
self.progressBarSet(value)
|
|
126
|
+
self.progressBarSet(int(value))
|
|
141
127
|
|
|
142
128
|
def handle_result(self, result_table):
|
|
143
|
-
"""Gère la table de données finale reçue du thread"""
|
|
144
129
|
try:
|
|
145
130
|
self.Outputs.data.send(result_table)
|
|
146
131
|
|
|
147
|
-
# Envoie la status table
|
|
148
132
|
final_statuses = {
|
|
149
133
|
path: d for path, d in self.processed_statuses.items()
|
|
150
134
|
if d["status"] != "in_progress"
|
|
@@ -157,12 +141,13 @@ class OWPPTX2JPG(base_widget.BaseListWidget):
|
|
|
157
141
|
])
|
|
158
142
|
|
|
159
143
|
rows = [[path, d["status"], d["message"]] for path, d in final_statuses.items()]
|
|
160
|
-
if rows
|
|
161
|
-
|
|
162
|
-
|
|
144
|
+
status_table = Table.from_list(status_domain, rows) if rows else None
|
|
145
|
+
self.Outputs.status_data.send(status_table) # ← always sent
|
|
146
|
+
|
|
163
147
|
except Exception as e:
|
|
164
148
|
print("An error occurred when sending out_data:", e)
|
|
165
149
|
self.Outputs.data.send(None)
|
|
150
|
+
self.Outputs.status_data.send(None) # ← always sent on error too
|
|
166
151
|
|
|
167
152
|
def handle_finish(self):
|
|
168
153
|
"""Nettoyage final une fois le thread terminé"""
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import sys
|
|
3
|
+
import Orange.data
|
|
4
|
+
from Orange.widgets import widget
|
|
5
|
+
from Orange.data import Domain, StringVariable, Table
|
|
6
|
+
from AnyQt.QtWidgets import QApplication
|
|
7
|
+
from Orange.widgets.settings import Setting
|
|
8
|
+
from Orange.widgets.utils.signals import Output
|
|
9
|
+
from AnyQt.QtCore import QTimer
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
# Importations conditionnelles selon l'architecture du projet
|
|
13
|
+
if "site-packages/Orange/widgets" in os.path.dirname(os.path.abspath(__file__)).replace("\\", "/"):
|
|
14
|
+
from Orange.widgets.orangecontrib.AAIT.utils import thread_management, help_management
|
|
15
|
+
from Orange.widgets.orangecontrib.AAIT.utils.initialize_from_ini import apply_modification_from_python_file
|
|
16
|
+
from Orange.widgets.orangecontrib.IO4IT.utils.environment_collector import EnvironmentCollector
|
|
17
|
+
from Orange.widgets.orangecontrib.AAIT.utils.import_uic import uic
|
|
18
|
+
else:
|
|
19
|
+
from orangecontrib.AAIT.utils import thread_management, help_management
|
|
20
|
+
from orangecontrib.AAIT.utils.initialize_from_ini import apply_modification_from_python_file
|
|
21
|
+
from orangecontrib.IO4IT.utils.environment_collector import EnvironmentCollector
|
|
22
|
+
from orangecontrib.AAIT.utils.import_uic import uic
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
# ---------------------------------------------------------------------------
|
|
26
|
+
# Helpers (module-level, utilisables hors widget et dans les threads)
|
|
27
|
+
# ---------------------------------------------------------------------------
|
|
28
|
+
|
|
29
|
+
def get_pip_freeze_dict() -> dict:
|
|
30
|
+
"""
|
|
31
|
+
Retourne un dict {package_name_lower: version} via importlib.metadata.
|
|
32
|
+
N'utilise pas de subprocess.
|
|
33
|
+
"""
|
|
34
|
+
collector = EnvironmentCollector()
|
|
35
|
+
freeze_str = collector._dependencies_freeze_space()
|
|
36
|
+
packages = {}
|
|
37
|
+
for line in freeze_str.splitlines():
|
|
38
|
+
line = line.strip().strip("\r")
|
|
39
|
+
if "==" in line:
|
|
40
|
+
name, version = line.split("==", 1)
|
|
41
|
+
packages[name.lower()] = version
|
|
42
|
+
return packages
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def _make_table(rows: list, columns: list) -> Table:
|
|
46
|
+
"""Construit une Orange Table avec les colonnes (StringVariable) spécifiées."""
|
|
47
|
+
metas = [StringVariable(col) for col in columns]
|
|
48
|
+
domain = Domain([], metas=metas)
|
|
49
|
+
return Table.from_list(domain, rows)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def run_audit(saved_packages: dict) -> tuple:
|
|
53
|
+
current_packages = get_pip_freeze_dict()
|
|
54
|
+
all_keys = set(saved_packages.keys()) | set(current_packages.keys())
|
|
55
|
+
|
|
56
|
+
diff_rows = []
|
|
57
|
+
current_rows = []
|
|
58
|
+
previous_rows = []
|
|
59
|
+
|
|
60
|
+
for pkg in sorted(all_keys):
|
|
61
|
+
saved_v = saved_packages.get(pkg, "(Absent)")
|
|
62
|
+
current_v = current_packages.get(pkg, "(Nouveau)")
|
|
63
|
+
|
|
64
|
+
if saved_v == "(Absent)":
|
|
65
|
+
status = "➕ Nouveau"
|
|
66
|
+
elif current_v == "(Nouveau)":
|
|
67
|
+
status = "❌ Manquant"
|
|
68
|
+
elif saved_v != current_v:
|
|
69
|
+
status = "⚠️ Différent"
|
|
70
|
+
else:
|
|
71
|
+
status = "✅ OK"
|
|
72
|
+
|
|
73
|
+
# Table différences : 4 colonnes complètes
|
|
74
|
+
#if status != "✅ OK":
|
|
75
|
+
diff_rows.append([pkg, saved_v, current_v, status])
|
|
76
|
+
|
|
77
|
+
# Table courante : uniquement Package + Version courante
|
|
78
|
+
if current_v != "(Nouveau)":
|
|
79
|
+
current_rows.append([pkg, current_v])
|
|
80
|
+
|
|
81
|
+
# Table précédente : uniquement Package + Version sauvegardée
|
|
82
|
+
if saved_v != "(Absent)":
|
|
83
|
+
previous_rows.append([pkg, saved_v])
|
|
84
|
+
|
|
85
|
+
diff_cols = ["Package", "Saved Version", "Current Version", "Status"]
|
|
86
|
+
current_cols = ["Package", "Current Version"]
|
|
87
|
+
previous_cols = ["Package", "Saved Version"]
|
|
88
|
+
|
|
89
|
+
diff_table = _make_table(diff_rows, diff_cols) if diff_rows else None
|
|
90
|
+
current_table = _make_table(current_rows, current_cols) if current_rows else None
|
|
91
|
+
previous_table = _make_table(previous_rows, previous_cols) if previous_rows else None
|
|
92
|
+
|
|
93
|
+
return diff_table, current_table, previous_table
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
# ---------------------------------------------------------------------------
|
|
97
|
+
# Widget
|
|
98
|
+
# ---------------------------------------------------------------------------
|
|
99
|
+
|
|
100
|
+
@apply_modification_from_python_file(filepath_original_widget=__file__)
|
|
101
|
+
class OWPipAuditor(widget.OWWidget):
|
|
102
|
+
name = "Pip Auditor"
|
|
103
|
+
description = "Snapshot and compare pip freeze environment"
|
|
104
|
+
category = "AAIT - TOOLBOX"
|
|
105
|
+
icon = "icons/pip_auditor.png"
|
|
106
|
+
if "site-packages/Orange/widgets" in os.path.dirname(os.path.abspath(__file__)).replace("\\", "/"):
|
|
107
|
+
icon = "icons_dev/pip_auditor.png"
|
|
108
|
+
|
|
109
|
+
gui = os.path.join(os.path.dirname(os.path.abspath(__file__)), "designer/owpipauditor.ui")
|
|
110
|
+
|
|
111
|
+
want_control_area = False
|
|
112
|
+
priority = 1100
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
# ------------------------------------------------------------------
|
|
116
|
+
# Settings persistants
|
|
117
|
+
# ------------------------------------------------------------------
|
|
118
|
+
saved_freeze: dict = Setting({}) # Snapshot sauvegardé (dict pkg→version)
|
|
119
|
+
autorun: bool = Setting(False) # Checkbox "Lancer automatiquement au démarrage"
|
|
120
|
+
|
|
121
|
+
# ------------------------------------------------------------------
|
|
122
|
+
# Sorties
|
|
123
|
+
# ------------------------------------------------------------------
|
|
124
|
+
class Outputs:
|
|
125
|
+
diff_table = Output("Différences", Orange.data.Table) # Packages avec écart
|
|
126
|
+
current_table = Output("Actuels", Orange.data.Table) # Snapshot courant
|
|
127
|
+
previous_table = Output("Précédents", Orange.data.Table) # Snapshot sauvegardé
|
|
128
|
+
|
|
129
|
+
# ------------------------------------------------------------------
|
|
130
|
+
# Initialisation
|
|
131
|
+
# ------------------------------------------------------------------
|
|
132
|
+
def __init__(self):
|
|
133
|
+
super().__init__()
|
|
134
|
+
self.setFixedWidth(470)
|
|
135
|
+
self.setFixedHeight(351)
|
|
136
|
+
uic.loadUi(self.gui, self)
|
|
137
|
+
|
|
138
|
+
self.thread = None
|
|
139
|
+
self._last_results = (None, None, None) # (diff, current, previous)
|
|
140
|
+
|
|
141
|
+
# Connexion des boutons définis dans le .ui
|
|
142
|
+
self.pushButton_snapshot.clicked.connect(self.take_snapshot)
|
|
143
|
+
self.pushButton_run.clicked.connect(self.run)
|
|
144
|
+
|
|
145
|
+
# Checkbox autorun (doit être définie dans owpipauditor.ui avec le nom checkBox_autorun)
|
|
146
|
+
self.checkBox_autorun.setChecked(self.autorun)
|
|
147
|
+
self.checkBox_autorun.stateChanged.connect(self._on_autorun_changed)
|
|
148
|
+
|
|
149
|
+
self.post_initialized()
|
|
150
|
+
QTimer.singleShot(0, lambda: help_management.override_help_action(self))
|
|
151
|
+
|
|
152
|
+
# Démarrage automatique si l'option est activée et qu'un snapshot existe
|
|
153
|
+
if self.autorun and self.saved_freeze:
|
|
154
|
+
QTimer.singleShot(100, self.run)
|
|
155
|
+
|
|
156
|
+
# ------------------------------------------------------------------
|
|
157
|
+
# Slots
|
|
158
|
+
# ------------------------------------------------------------------
|
|
159
|
+
def _on_autorun_changed(self, state: int):
|
|
160
|
+
"""Persistance de la checkbox autorun."""
|
|
161
|
+
self.autorun = bool(state)
|
|
162
|
+
|
|
163
|
+
def take_snapshot(self):
|
|
164
|
+
"""Sauvegarde l'état pip courant dans le Setting."""
|
|
165
|
+
try:
|
|
166
|
+
self.saved_freeze = get_pip_freeze_dict()
|
|
167
|
+
self.information(
|
|
168
|
+
f"Snapshot réussi : {len(self.saved_freeze)} packages sauvegardés."
|
|
169
|
+
)
|
|
170
|
+
except Exception as e:
|
|
171
|
+
self.error(f"Erreur Snapshot: {str(e)}")
|
|
172
|
+
|
|
173
|
+
def run(self):
|
|
174
|
+
"""Compare le snapshot sauvegardé avec l'environnement courant et émet les 3 sorties."""
|
|
175
|
+
self.error("")
|
|
176
|
+
self.warning("")
|
|
177
|
+
|
|
178
|
+
if not self.saved_freeze:
|
|
179
|
+
self.error("Aucun snapshot sauvegardé. Cliquez d'abord sur Snapshot.")
|
|
180
|
+
return
|
|
181
|
+
|
|
182
|
+
if self.thread is not None:
|
|
183
|
+
self.thread.safe_quit()
|
|
184
|
+
|
|
185
|
+
self.progressBarInit()
|
|
186
|
+
|
|
187
|
+
self.thread = thread_management.Thread(run_audit, self.saved_freeze)
|
|
188
|
+
self.thread.progress.connect(self.handle_progress)
|
|
189
|
+
self.thread.result.connect(self.handle_result)
|
|
190
|
+
self.thread.finish.connect(self.handle_finish)
|
|
191
|
+
self.thread.start()
|
|
192
|
+
|
|
193
|
+
# ------------------------------------------------------------------
|
|
194
|
+
# Handlers thread
|
|
195
|
+
# ------------------------------------------------------------------
|
|
196
|
+
def handle_progress(self, value: float):
|
|
197
|
+
self.progressBarSet(value)
|
|
198
|
+
|
|
199
|
+
def handle_result(self, result):
|
|
200
|
+
"""
|
|
201
|
+
result est un tuple (diff_table, current_table, previous_table).
|
|
202
|
+
"""
|
|
203
|
+
try:
|
|
204
|
+
diff_table, current_table, previous_table = result
|
|
205
|
+
self._last_results = result
|
|
206
|
+
|
|
207
|
+
self.Outputs.diff_table.send(diff_table)
|
|
208
|
+
self.Outputs.current_table.send(current_table)
|
|
209
|
+
self.Outputs.previous_table.send(previous_table)
|
|
210
|
+
|
|
211
|
+
n_diff = sum(1 for row in diff_table if str(row["Status"]) != "✅ OK")
|
|
212
|
+
self.information(f"Audit terminé : {n_diff} différence(s) détectée(s) sur {len(diff_table)} package(s).")
|
|
213
|
+
except Exception as e:
|
|
214
|
+
self.error(f"Erreur lors de l'envoi des tables: {e}")
|
|
215
|
+
self.Outputs.diff_table.send(None)
|
|
216
|
+
self.Outputs.current_table.send(None)
|
|
217
|
+
self.Outputs.previous_table.send(None)
|
|
218
|
+
|
|
219
|
+
def handle_finish(self):
|
|
220
|
+
self.progressBarFinished()
|
|
221
|
+
|
|
222
|
+
# ------------------------------------------------------------------
|
|
223
|
+
# Hook post-init (override si besoin dans une sous-classe)
|
|
224
|
+
# ------------------------------------------------------------------
|
|
225
|
+
def post_initialized(self):
|
|
226
|
+
pass
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
# ---------------------------------------------------------------------------
|
|
230
|
+
# Lancement standalone
|
|
231
|
+
# ---------------------------------------------------------------------------
|
|
232
|
+
if __name__ == "__main__":
|
|
233
|
+
app = QApplication(sys.argv)
|
|
234
|
+
my_widget = OWPipAuditor()
|
|
235
|
+
my_widget.show()
|
|
236
|
+
if hasattr(app, "exec"):
|
|
237
|
+
app.exec()
|
|
238
|
+
else:
|
|
239
|
+
app.exec_()
|
|
240
|
+
|
|
@@ -207,12 +207,29 @@ class OWInsertDataToExcel(base_widget.BaseListWidget):
|
|
|
207
207
|
self.Outputs.status_data.send(Table.from_list(domain, [[status, details]]))
|
|
208
208
|
|
|
209
209
|
def _orange_table_to_dataframe(self, table: Table) -> pd.DataFrame:
|
|
210
|
-
|
|
210
|
+
# Preserve original column order: attributes first, then metas, then class
|
|
211
|
+
# but respect the domain's actual declaration order
|
|
212
|
+
all_vars = list(table.domain.attributes) + list(table.domain.metas)
|
|
211
213
|
if table.domain.class_var:
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
data = {
|
|
214
|
+
all_vars.append(table.domain.class_var)
|
|
215
|
+
|
|
216
|
+
data = {}
|
|
217
|
+
for var in all_vars:
|
|
218
|
+
raw = list(table.get_column(var.name))
|
|
219
|
+
if isinstance(var, DiscreteVariable):
|
|
220
|
+
data[var.name] = [
|
|
221
|
+
var.values[int(v)] if not (isinstance(v, float) and pd.isna(v)) and int(v) >= 0 else ""
|
|
222
|
+
for v in raw
|
|
223
|
+
]
|
|
224
|
+
else:
|
|
225
|
+
data[var.name] = raw
|
|
226
|
+
|
|
215
227
|
df = pd.DataFrame(data).astype(str).replace("nan", "")
|
|
228
|
+
|
|
229
|
+
# Re-order columns to match the original Table column order
|
|
230
|
+
original_order = [var.name for var in table.domain.variables + table.domain.metas]
|
|
231
|
+
df = df[[col for col in original_order if col in df.columns]]
|
|
232
|
+
|
|
216
233
|
return df
|
|
217
234
|
|
|
218
235
|
if __name__ == "__main__":
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<ui version="4.0">
|
|
3
|
+
<class>Form</class>
|
|
4
|
+
<widget class="QWidget" name="Form">
|
|
5
|
+
<property name="geometry">
|
|
6
|
+
<rect>
|
|
7
|
+
<x>0</x>
|
|
8
|
+
<y>0</y>
|
|
9
|
+
<width>470</width>
|
|
10
|
+
<height>351</height>
|
|
11
|
+
</rect>
|
|
12
|
+
</property>
|
|
13
|
+
<property name="windowTitle">
|
|
14
|
+
<string>Pip Auditor</string>
|
|
15
|
+
</property>
|
|
16
|
+
<widget class="QGroupBox" name="groupBox">
|
|
17
|
+
<property name="geometry">
|
|
18
|
+
<rect>
|
|
19
|
+
<x>20</x>
|
|
20
|
+
<y>20</y>
|
|
21
|
+
<width>431</width>
|
|
22
|
+
<height>100</height>
|
|
23
|
+
</rect>
|
|
24
|
+
</property>
|
|
25
|
+
<property name="title">
|
|
26
|
+
<string>1. Environment Reference</string>
|
|
27
|
+
</property>
|
|
28
|
+
<widget class="QPushButton" name="pushButton_snapshot">
|
|
29
|
+
<property name="geometry">
|
|
30
|
+
<rect>
|
|
31
|
+
<x>10</x>
|
|
32
|
+
<y>40</y>
|
|
33
|
+
<width>411</width>
|
|
34
|
+
<height>41</height>
|
|
35
|
+
</rect>
|
|
36
|
+
</property>
|
|
37
|
+
<property name="text">
|
|
38
|
+
<string>Take Snapshot (pip freeze)</string>
|
|
39
|
+
</property>
|
|
40
|
+
</widget>
|
|
41
|
+
</widget>
|
|
42
|
+
<widget class="QGroupBox" name="groupBox_2">
|
|
43
|
+
<property name="geometry">
|
|
44
|
+
<rect>
|
|
45
|
+
<x>20</x>
|
|
46
|
+
<y>140</y>
|
|
47
|
+
<width>431</width>
|
|
48
|
+
<height>171</height>
|
|
49
|
+
</rect>
|
|
50
|
+
</property>
|
|
51
|
+
<property name="title">
|
|
52
|
+
<string>2. Audit & Comparison</string>
|
|
53
|
+
</property>
|
|
54
|
+
<widget class="QLabel" name="label">
|
|
55
|
+
<property name="geometry">
|
|
56
|
+
<rect>
|
|
57
|
+
<x>10</x>
|
|
58
|
+
<y>30</y>
|
|
59
|
+
<width>411</width>
|
|
60
|
+
<height>41</height>
|
|
61
|
+
</rect>
|
|
62
|
+
</property>
|
|
63
|
+
<property name="text">
|
|
64
|
+
<string>Compare the current environment with the snapshot.
|
|
65
|
+
This will output a table of differences (mismatches, missing or new packages).</string>
|
|
66
|
+
</property>
|
|
67
|
+
<property name="wordWrap">
|
|
68
|
+
<bool>true</bool>
|
|
69
|
+
</property>
|
|
70
|
+
</widget>
|
|
71
|
+
<widget class="QCheckBox" name="checkBox_autorun">
|
|
72
|
+
<property name="geometry">
|
|
73
|
+
<rect>
|
|
74
|
+
<x>10</x>
|
|
75
|
+
<y>80</y>
|
|
76
|
+
<width>411</width>
|
|
77
|
+
<height>21</height>
|
|
78
|
+
</rect>
|
|
79
|
+
</property>
|
|
80
|
+
<property name="text">
|
|
81
|
+
<string>Auto-run comparison on startup</string>
|
|
82
|
+
</property>
|
|
83
|
+
</widget>
|
|
84
|
+
<widget class="QPushButton" name="pushButton_run">
|
|
85
|
+
<property name="geometry">
|
|
86
|
+
<rect>
|
|
87
|
+
<x>10</x>
|
|
88
|
+
<y>111</y>
|
|
89
|
+
<width>411</width>
|
|
90
|
+
<height>41</height>
|
|
91
|
+
</rect>
|
|
92
|
+
</property>
|
|
93
|
+
<property name="text">
|
|
94
|
+
<string>Run Comparison</string>
|
|
95
|
+
</property>
|
|
96
|
+
</widget>
|
|
97
|
+
</widget>
|
|
98
|
+
</widget>
|
|
99
|
+
<resources/>
|
|
100
|
+
<connections/>
|
|
101
|
+
</ui>
|
|
Binary file
|
|
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-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/toolViews/designer/link_workflow_manager_ui.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
|
|
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-4.0.5 → io4it-4.0.7}/orangecontrib/IO4IT/widgets/designer/ow_extract_tables_docx_to_xlsx.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
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|