IO4IT 4.0.6__tar.gz → 4.0.8__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.8/PKG-INFO +28 -0
- io4it-4.0.8/io4it.egg-info/PKG-INFO +28 -0
- {io4it-4.0.6 → io4it-4.0.8}/io4it.egg-info/SOURCES.txt +4 -0
- io4it-4.0.8/orangecontrib/IO4IT/utils/environment_collector.py +71 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/utils/mail.py +15 -5
- io4it-4.0.8/orangecontrib/IO4IT/utils/pptx2jpg.py +102 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/OWPPTX2JPG.py +1 -1
- io4it-4.0.8/orangecontrib/IO4IT/widgets/OWPipAuditor.py +240 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/OWXLSX_insert.py +21 -4
- io4it-4.0.8/orangecontrib/IO4IT/widgets/designer/owpipauditor.ui +101 -0
- io4it-4.0.8/orangecontrib/IO4IT/widgets/icons/pip_auditor.png +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/setup.py +1 -1
- io4it-4.0.6/PKG-INFO +0 -12
- io4it-4.0.6/io4it.egg-info/PKG-INFO +0 -12
- io4it-4.0.6/orangecontrib/IO4IT/utils/pptx2jpg.py +0 -64
- {io4it-4.0.6 → io4it-4.0.8}/io4it.egg-info/dependency_links.txt +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/io4it.egg-info/entry_points.txt +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/io4it.egg-info/namespace_packages.txt +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/io4it.egg-info/requires.txt +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/io4it.egg-info/top_level.txt +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/__init__.py +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/ocr_function/__init__.py +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/ocr_function/word_converter.py +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/toolViews/designer/key_manager_ui.ui +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/toolViews/designer/link_workflow_manager_ui.ui +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/toolViews/key_manager_ui.py +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/toolViews/linkHTLMWorkflow_manager_ui.py +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/utils/__init__.py +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/utils/keys_manager.py +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/utils/pool_exec_utils.py +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/utils/secret_manager.py +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/utils/utils_md.py +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/OWChatGpt.py +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/OWDeep_Search.py +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/OWDoclingToMarkdown.py +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/OWExportMarkdown.py +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/OWExtractTablesDocxToXlsx.py +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/OWInboxMailMonitoring.py +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/OWJsonToDataTable.py +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/OWMD2HTML.py +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/OWMarkdownLoader.py +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/OWMarkdownizer.py +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/OWOfficeNormalizer.py +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/OWParserHTML.py +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/OWPdfType.py +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/OWProcessPoolExecutor.py +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/OWS3Uploader.py +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/OWS3downloader.py +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/OWS3list.py +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/OWWebSearch.py +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/OWmailLoader.py +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/OWmailSender.py +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/OWwordpdf2docx.py +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/__init__.py +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/designer/__init__.py +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/designer/nogui.ui +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/designer/ow_extract_tables_docx_to_xlsx.ui +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/designer/ow_file_ext_selector.ui +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/designer/ow_json_to_data_table.ui +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/designer/owchatgpt.ui +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/designer/owdeepsearch.ui +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/designer/owdoclingasr.ui +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/designer/owdoclingtomarkdown.ui +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/designer/owexportmarkdown.ui +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/designer/owinboxmailmonitoring.ui +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/designer/owinsertdatatoexcel.ui +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/designer/owmailloader.ui +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/designer/owmailsender.ui +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/designer/owmarkdownizer.ui +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/designer/owmarkdownloader.ui +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/designer/owmd2html.ui +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/designer/owofficenormalizer.ui +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/designer/owparserhtml.ui +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/designer/owpdftype.ui +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/designer/owpptx2jpg.ui +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/designer/owprocesspoolexecutor.ui +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/designer/owspeechtotext.ui +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/designer/owvisualizationer.ui +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/designer/owwebsearch.ui +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/designer/wordpdf2docx.ui +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/icons/__init__.py +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/icons/chatgpt.png +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/icons/check_pdf.png +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/icons/deepsearch.svg +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/icons/dep_md_old.png +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/icons/download.png +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/icons/export_md.png +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/icons/extract_table.png +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/icons/file_extensor.png +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/icons/html.png +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/icons/json-file.png +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/icons/list_aws.png +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/icons/load_md.png +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/icons/mail_loader.png +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/icons/mail_writer.png +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/icons/md.png +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/icons/monitor-email.svg +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/icons/office_normalizer.png +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/icons/owmd2html.svg +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/icons/pptx2jpg.png +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/icons/process_pool_executor.png +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/icons/speech_to_text.png +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/icons/upload.png +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/icons/visualizationer.png +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/icons/websearch.png +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/icons/wordpdf2docx.png +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/icons/xlsx_insert.png +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/IO4IT/widgets/icons_dev/__init__.py +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/orangecontrib/__init__.py +0 -0
- {io4it-4.0.6 → io4it-4.0.8}/setup.cfg +0 -0
io4it-4.0.8/PKG-INFO
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: io4it
|
|
3
|
+
Version: 4.0.8
|
|
4
|
+
Home-page:
|
|
5
|
+
Author:
|
|
6
|
+
Author-email:
|
|
7
|
+
Keywords: orange3 add-on
|
|
8
|
+
Requires-Dist: torchvision
|
|
9
|
+
Requires-Dist: torch
|
|
10
|
+
Requires-Dist: pylatexenc
|
|
11
|
+
Requires-Dist: docopt
|
|
12
|
+
Requires-Dist: boto3
|
|
13
|
+
Requires-Dist: opencv-python-headless
|
|
14
|
+
Requires-Dist: docling
|
|
15
|
+
Requires-Dist: docling-core
|
|
16
|
+
Requires-Dist: whisper
|
|
17
|
+
Requires-Dist: whisper-openai
|
|
18
|
+
Requires-Dist: pypandoc
|
|
19
|
+
Requires-Dist: pypandoc-binary
|
|
20
|
+
Requires-Dist: scikit-learn
|
|
21
|
+
Requires-Dist: openai
|
|
22
|
+
Requires-Dist: pip-system-certs
|
|
23
|
+
Requires-Dist: docx2pdf
|
|
24
|
+
Requires-Dist: msal
|
|
25
|
+
Requires-Dist: exchangelib
|
|
26
|
+
Requires-Dist: html2text
|
|
27
|
+
Requires-Dist: ddgs
|
|
28
|
+
Requires-Dist: CATEGORIT
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: io4it
|
|
3
|
+
Version: 4.0.8
|
|
4
|
+
Home-page:
|
|
5
|
+
Author:
|
|
6
|
+
Author-email:
|
|
7
|
+
Keywords: orange3 add-on
|
|
8
|
+
Requires-Dist: torchvision
|
|
9
|
+
Requires-Dist: torch
|
|
10
|
+
Requires-Dist: pylatexenc
|
|
11
|
+
Requires-Dist: docopt
|
|
12
|
+
Requires-Dist: boto3
|
|
13
|
+
Requires-Dist: opencv-python-headless
|
|
14
|
+
Requires-Dist: docling
|
|
15
|
+
Requires-Dist: docling-core
|
|
16
|
+
Requires-Dist: whisper
|
|
17
|
+
Requires-Dist: whisper-openai
|
|
18
|
+
Requires-Dist: pypandoc
|
|
19
|
+
Requires-Dist: pypandoc-binary
|
|
20
|
+
Requires-Dist: scikit-learn
|
|
21
|
+
Requires-Dist: openai
|
|
22
|
+
Requires-Dist: pip-system-certs
|
|
23
|
+
Requires-Dist: docx2pdf
|
|
24
|
+
Requires-Dist: msal
|
|
25
|
+
Requires-Dist: exchangelib
|
|
26
|
+
Requires-Dist: html2text
|
|
27
|
+
Requires-Dist: ddgs
|
|
28
|
+
Requires-Dist: CATEGORIT
|
|
@@ -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)
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
import time
|
|
3
|
+
import subprocess
|
|
4
|
+
import shutil
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
def get_conversion_method():
|
|
8
|
+
"""Determines the best available conversion method."""
|
|
9
|
+
# 1. Check for MS Office
|
|
10
|
+
if sys.platform.startswith("win"):
|
|
11
|
+
try:
|
|
12
|
+
import win32com.client
|
|
13
|
+
# Try to see if the COM object is registered
|
|
14
|
+
win32com.client.GetActiveObject("PowerPoint.Application")
|
|
15
|
+
return "office"
|
|
16
|
+
except:
|
|
17
|
+
try:
|
|
18
|
+
# If not running, try to see if it's dispatchable
|
|
19
|
+
win32com.client.Dispatch("PowerPoint.Application")
|
|
20
|
+
return "office"
|
|
21
|
+
except: pass
|
|
22
|
+
elif sys.platform == "darwin":
|
|
23
|
+
# Check if PowerPoint app exists on Mac
|
|
24
|
+
if Path("/Applications/Microsoft PowerPoint.app").exists():
|
|
25
|
+
return "office"
|
|
26
|
+
|
|
27
|
+
# 2. Check for LibreOffice (soffice)
|
|
28
|
+
if shutil.which("soffice"):
|
|
29
|
+
return "libreoffice"
|
|
30
|
+
|
|
31
|
+
# 3. Fallback to Aspose
|
|
32
|
+
return "aspose"
|
|
33
|
+
|
|
34
|
+
def convert_via_office(src: Path, pdf_path: Path):
|
|
35
|
+
if sys.platform.startswith("win"):
|
|
36
|
+
import win32com.client
|
|
37
|
+
powerpoint = win32com.client.Dispatch("PowerPoint.Application")
|
|
38
|
+
try:
|
|
39
|
+
presentation = powerpoint.Presentations.Open(str(src), WithWindow=False)
|
|
40
|
+
presentation.SaveAs(str(pdf_path), 32) # 32 = ppSaveAsPDF
|
|
41
|
+
presentation.Close()
|
|
42
|
+
finally:
|
|
43
|
+
# Note: We don't quit() powerpoint here to avoid killing other open docs
|
|
44
|
+
pass
|
|
45
|
+
elif sys.platform == "darwin":
|
|
46
|
+
script = f'tell application "Microsoft PowerPoint" to save (open POSIX file "{src}") in POSIX file "{pdf_path}" as PDF'
|
|
47
|
+
subprocess.run(["osascript", "-e", script], check=True)
|
|
48
|
+
|
|
49
|
+
def convert_via_libreoffice(src: Path, out_dir: Path):
|
|
50
|
+
subprocess.run([
|
|
51
|
+
"soffice", "--headless", "--convert-to", "pdf",
|
|
52
|
+
"--outdir", str(out_dir), str(src)
|
|
53
|
+
], check=True, capture_output=True)
|
|
54
|
+
return src.with_suffix(".pdf")
|
|
55
|
+
|
|
56
|
+
def process_one_pptx(file_path_str: str, unique_folder: bool = True):
|
|
57
|
+
try:
|
|
58
|
+
import fitz # PyMuPDF
|
|
59
|
+
except ImportError:
|
|
60
|
+
return [file_path_str, "", "nok", "0.0", "Erreur: PyMuPDF non installé"]
|
|
61
|
+
|
|
62
|
+
t0 = time.time()
|
|
63
|
+
src = Path(file_path_str).resolve()
|
|
64
|
+
out_dir = src.parent / (f"images_{src.stem}" if unique_folder else "images")
|
|
65
|
+
out_dir.mkdir(parents=True, exist_ok=True)
|
|
66
|
+
|
|
67
|
+
method = get_conversion_method()
|
|
68
|
+
img_list = []
|
|
69
|
+
|
|
70
|
+
try:
|
|
71
|
+
# --- PHASE 1: GENERATE IMAGES ---
|
|
72
|
+
if method == "aspose":
|
|
73
|
+
# import aspose.slides as slides
|
|
74
|
+
# with slides.Presentation(str(src)) as pres:
|
|
75
|
+
# for i, slide in enumerate(pres.slides, start=1):
|
|
76
|
+
# img_path = out_dir / f"{src.stem}_slide_{i:03d}.jpg"
|
|
77
|
+
# slide.get_thumbnail(1.5, 1.5).save(str(img_path), slides.export.ImageFormat.JPEG)
|
|
78
|
+
# img_list.append(str(img_path))
|
|
79
|
+
print("converting slides without having libre office or office isn't possible for the moment")
|
|
80
|
+
else:
|
|
81
|
+
# Office or LibreOffice both generate a PDF first
|
|
82
|
+
pdf_path = out_dir / f"{src.stem}.pdf"
|
|
83
|
+
if method == "office":
|
|
84
|
+
convert_via_office(src, pdf_path)
|
|
85
|
+
else: # libreoffice
|
|
86
|
+
convert_via_libreoffice(src, out_dir)
|
|
87
|
+
|
|
88
|
+
# Convert PDF pages to JPG using PyMuPDF
|
|
89
|
+
doc = fitz.open(str(pdf_path))
|
|
90
|
+
for i, page in enumerate(doc, start=1):
|
|
91
|
+
pix = page.get_pixmap(dpi=150)
|
|
92
|
+
img_path = out_dir / f"{src.stem}_slide_{i:03d}.jpg"
|
|
93
|
+
pix.save(str(img_path))
|
|
94
|
+
img_list.append(str(img_path))
|
|
95
|
+
doc.close()
|
|
96
|
+
if pdf_path.exists(): pdf_path.unlink()
|
|
97
|
+
|
|
98
|
+
duration = time.time() - t0
|
|
99
|
+
return [str(src), "|".join(img_list), "ok", f"{duration:.2f}", f"{len(img_list)} slides ({method})"]
|
|
100
|
+
|
|
101
|
+
except Exception as e:
|
|
102
|
+
return [str(src), "", "nok", f"{time.time()-t0:.2f}", f"Method {method} failed: {str(e)}"]
|
|
@@ -1,7 +1,7 @@
|
|
|
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
|
|
@@ -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
|
io4it-4.0.6/PKG-INFO
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import sys
|
|
2
|
-
import time
|
|
3
|
-
import subprocess
|
|
4
|
-
from pathlib import Path
|
|
5
|
-
|
|
6
|
-
def pptx_to_pdf(pptx_path: Path) -> Path:
|
|
7
|
-
pdf_path = pptx_path.with_suffix(".pdf")
|
|
8
|
-
if sys.platform.startswith("win"):
|
|
9
|
-
import win32com.client
|
|
10
|
-
powerpoint = win32com.client.Dispatch("PowerPoint.Application")
|
|
11
|
-
try:
|
|
12
|
-
presentation = powerpoint.Presentations.Open(str(pptx_path), WithWindow=False)
|
|
13
|
-
presentation.SaveAs(str(pdf_path), 32)
|
|
14
|
-
presentation.Close()
|
|
15
|
-
except Exception as e:
|
|
16
|
-
raise RuntimeError(f"Erreur PowerPoint : {e}")
|
|
17
|
-
elif sys.platform == "darwin":
|
|
18
|
-
script = f'tell application "Microsoft PowerPoint" to save (open POSIX file "{pptx_path}") in POSIX file "{pdf_path}" as PDF'
|
|
19
|
-
subprocess.run(["osascript", "-e", script], check=True)
|
|
20
|
-
else:
|
|
21
|
-
raise RuntimeError("Système d'exploitation non supporté.")
|
|
22
|
-
return pdf_path
|
|
23
|
-
|
|
24
|
-
def process_one_pptx(file_path_str: str, unique_folder: bool = True):
|
|
25
|
-
try:
|
|
26
|
-
import fitz
|
|
27
|
-
except ImportError:
|
|
28
|
-
return [file_path_str, "", "nok", "0.0", "Erreur: PyMuPDF (fitz) non installé"]
|
|
29
|
-
|
|
30
|
-
t0 = time.time()
|
|
31
|
-
src = Path(file_path_str).resolve()
|
|
32
|
-
|
|
33
|
-
# ✅ unique_folder=True → un dossier par pptx : images_monFichier/
|
|
34
|
-
# ✅ unique_folder=False → tout dans un dossier commun : images/ (à côté des pptx)
|
|
35
|
-
if unique_folder:
|
|
36
|
-
out_dir = src.parent / f"images_{src.stem}"
|
|
37
|
-
else:
|
|
38
|
-
out_dir = src.parent / "images"
|
|
39
|
-
|
|
40
|
-
try:
|
|
41
|
-
out_dir.mkdir(parents=True, exist_ok=True)
|
|
42
|
-
|
|
43
|
-
pdf_path = pptx_to_pdf(src)
|
|
44
|
-
|
|
45
|
-
doc = fitz.open(str(pdf_path))
|
|
46
|
-
img_list = []
|
|
47
|
-
for i, page in enumerate(doc, start=1):
|
|
48
|
-
pix = page.get_pixmap(dpi=150)
|
|
49
|
-
# ✅ Préfixe avec le nom du pptx pour éviter les collisions en mode commun
|
|
50
|
-
img_path = out_dir / f"{src.stem}_slide_{i:03d}.jpg"
|
|
51
|
-
pix.save(str(img_path))
|
|
52
|
-
img_list.append(str(img_path))
|
|
53
|
-
doc.close()
|
|
54
|
-
|
|
55
|
-
if pdf_path.exists():
|
|
56
|
-
pdf_path.unlink()
|
|
57
|
-
|
|
58
|
-
duration = time.time() - t0
|
|
59
|
-
return [str(src), "|".join(img_list), "ok", f"{duration:.2f}", f"{len(img_list)} slides"]
|
|
60
|
-
|
|
61
|
-
except Exception as e:
|
|
62
|
-
duration = time.time() - t0
|
|
63
|
-
import traceback
|
|
64
|
-
return [str(src), "", "nok", f"{duration:.2f}", f"{str(e)}\n{traceback.format_exc()}"]
|
|
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.6 → io4it-4.0.8}/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
|
{io4it-4.0.6 → io4it-4.0.8}/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
|