IO4IT 4.0.22__tar.gz → 4.0.23__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.23/PKG-INFO +28 -0
- io4it-4.0.23/io4it.egg-info/PKG-INFO +28 -0
- {io4it-4.0.22 → io4it-4.0.23}/io4it.egg-info/SOURCES.txt +7 -3
- io4it-4.0.23/orangecontrib/IO4IT/utils/custom_api.py +132 -0
- io4it-4.0.23/orangecontrib/IO4IT/utils/file2images.py +211 -0
- io4it-4.0.23/orangecontrib/IO4IT/widgets/OWCustomLLMApi.py +260 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/OWJsonToDataTable.py +166 -166
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/OWPPTX2JPG.py +102 -40
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/OWXLSX_insert.py +62 -1
- io4it-4.0.23/orangecontrib/IO4IT/widgets/designer/owcustomllmapi.ui +364 -0
- io4it-4.0.23/orangecontrib/IO4IT/widgets/designer/owfile2images.ui +229 -0
- io4it-4.0.23/orangecontrib/IO4IT/widgets/icons/file2images.png +0 -0
- io4it-4.0.23/orangecontrib/IO4IT/widgets/icons/owcustomllmapi.svg +9 -0
- {io4it-4.0.22 → io4it-4.0.23}/setup.py +1 -1
- io4it-4.0.22/PKG-INFO +0 -7
- io4it-4.0.22/io4it.egg-info/PKG-INFO +0 -7
- io4it-4.0.22/orangecontrib/IO4IT/utils/pptx2jpg.py +0 -102
- io4it-4.0.22/orangecontrib/IO4IT/widgets/designer/owpptx2jpg.ui +0 -132
- io4it-4.0.22/orangecontrib/IO4IT/widgets/icons/pptx2jpg.png +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/io4it.egg-info/dependency_links.txt +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/io4it.egg-info/entry_points.txt +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/io4it.egg-info/namespace_packages.txt +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/io4it.egg-info/requires.txt +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/io4it.egg-info/top_level.txt +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/__init__.py +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/ocr_function/__init__.py +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/ocr_function/word_converter.py +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/toolViews/designer/key_manager_ui.ui +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/toolViews/designer/link_workflow_manager_ui.ui +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/toolViews/key_manager_ui.py +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/toolViews/linkHTLMWorkflow_manager_ui.py +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/utils/__init__.py +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/utils/environment_collector.py +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/utils/keys_manager.py +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/utils/mail.py +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/utils/pool_exec_utils.py +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/utils/pst_extractor/TigerODMPST.dll +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/utils/pst_extractor/__init__.py +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/utils/pst_extractor/export_pst.py +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/utils/pst_extractor/libpff.dll +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/utils/pst_extractor/z.dll +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/utils/secret_manager.py +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/utils/utils_md.py +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/OWChatGpt.py +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/OWDeep_Search.py +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/OWDoclingToMarkdown.py +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/OWExportMarkdown.py +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/OWExtractTablesDocxToXlsx.py +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/OWInboxMailMonitoring.py +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/OWMD2HTML.py +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/OWMarkdownLoader.py +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/OWMarkdownizer.py +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/OWOfficeNormalizer.py +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/OWParserHTML.py +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/OWPdfType.py +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/OWPipAuditor.py +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/OWProcessPoolExecutor.py +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/OWS3Uploader.py +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/OWS3downloader.py +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/OWS3list.py +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/OWWebSearch.py +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/OWmailLoader.py +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/OWmailSender.py +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/OWwordpdf2docx.py +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/__init__.py +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/designer/__init__.py +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/designer/nogui.ui +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/designer/ow_extract_tables_docx_to_xlsx.ui +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/designer/ow_file_ext_selector.ui +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/designer/ow_json_to_data_table.ui +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/designer/owchatgpt.ui +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/designer/owdeepsearch.ui +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/designer/owdoclingtomarkdown.ui +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/designer/owexportmarkdown.ui +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/designer/owinboxmailmonitoring.ui +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/designer/owinsertdatatoexcel.ui +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/designer/owmailloader.ui +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/designer/owmailsender.ui +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/designer/owmarkdownizer.ui +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/designer/owmarkdownloader.ui +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/designer/owmd2html.ui +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/designer/owofficenormalizer.ui +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/designer/owparserhtml.ui +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/designer/owpdftype.ui +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/designer/owpipauditor.ui +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/designer/owprocesspoolexecutor.ui +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/designer/owspeechtotext.ui +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/designer/owvisualizationer.ui +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/designer/owwebsearch.ui +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/designer/wordpdf2docx.ui +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/icons/__init__.py +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/icons/chatgpt.png +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/icons/check_pdf.png +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/icons/deepsearch.svg +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/icons/dep_md_old.png +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/icons/download.png +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/icons/export_md.png +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/icons/extract_table.png +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/icons/file_extensor.png +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/icons/html.png +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/icons/json-file.png +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/icons/list_aws.png +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/icons/load_md.png +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/icons/mail_loader.png +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/icons/mail_writer.png +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/icons/md.png +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/icons/monitor-email.svg +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/icons/office_normalizer.png +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/icons/owmd2html.svg +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/icons/pip_auditor.png +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/icons/process_pool_executor.png +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/icons/speech_to_text.png +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/icons/upload.png +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/icons/visualizationer.png +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/icons/websearch.png +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/icons/wordpdf2docx.png +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/icons/xlsx_insert.png +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/IO4IT/widgets/icons_dev/__init__.py +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/orangecontrib/__init__.py +0 -0
- {io4it-4.0.22 → io4it-4.0.23}/setup.cfg +0 -0
io4it-4.0.23/PKG-INFO
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: io4it
|
|
3
|
+
Version: 4.0.23
|
|
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: pypandoc
|
|
17
|
+
Requires-Dist: pypandoc-binary
|
|
18
|
+
Requires-Dist: scikit-learn
|
|
19
|
+
Requires-Dist: openai
|
|
20
|
+
Requires-Dist: pip-system-certs
|
|
21
|
+
Requires-Dist: docx2pdf
|
|
22
|
+
Requires-Dist: msal
|
|
23
|
+
Requires-Dist: exchangelib
|
|
24
|
+
Requires-Dist: html2text
|
|
25
|
+
Requires-Dist: ddgs
|
|
26
|
+
Requires-Dist: CATEGORIT
|
|
27
|
+
Dynamic: keywords
|
|
28
|
+
Dynamic: requires-dist
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: io4it
|
|
3
|
+
Version: 4.0.23
|
|
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: pypandoc
|
|
17
|
+
Requires-Dist: pypandoc-binary
|
|
18
|
+
Requires-Dist: scikit-learn
|
|
19
|
+
Requires-Dist: openai
|
|
20
|
+
Requires-Dist: pip-system-certs
|
|
21
|
+
Requires-Dist: docx2pdf
|
|
22
|
+
Requires-Dist: msal
|
|
23
|
+
Requires-Dist: exchangelib
|
|
24
|
+
Requires-Dist: html2text
|
|
25
|
+
Requires-Dist: ddgs
|
|
26
|
+
Requires-Dist: CATEGORIT
|
|
27
|
+
Dynamic: keywords
|
|
28
|
+
Dynamic: requires-dist
|
|
@@ -11,11 +11,12 @@ 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/custom_api.py
|
|
14
15
|
orangecontrib/IO4IT/utils/environment_collector.py
|
|
16
|
+
orangecontrib/IO4IT/utils/file2images.py
|
|
15
17
|
orangecontrib/IO4IT/utils/keys_manager.py
|
|
16
18
|
orangecontrib/IO4IT/utils/mail.py
|
|
17
19
|
orangecontrib/IO4IT/utils/pool_exec_utils.py
|
|
18
|
-
orangecontrib/IO4IT/utils/pptx2jpg.py
|
|
19
20
|
orangecontrib/IO4IT/utils/secret_manager.py
|
|
20
21
|
orangecontrib/IO4IT/utils/utils_md.py
|
|
21
22
|
orangecontrib/IO4IT/utils/pst_extractor/TigerODMPST.dll
|
|
@@ -24,6 +25,7 @@ orangecontrib/IO4IT/utils/pst_extractor/export_pst.py
|
|
|
24
25
|
orangecontrib/IO4IT/utils/pst_extractor/libpff.dll
|
|
25
26
|
orangecontrib/IO4IT/utils/pst_extractor/z.dll
|
|
26
27
|
orangecontrib/IO4IT/widgets/OWChatGpt.py
|
|
28
|
+
orangecontrib/IO4IT/widgets/OWCustomLLMApi.py
|
|
27
29
|
orangecontrib/IO4IT/widgets/OWDeep_Search.py
|
|
28
30
|
orangecontrib/IO4IT/widgets/OWDoclingToMarkdown.py
|
|
29
31
|
orangecontrib/IO4IT/widgets/OWExportMarkdown.py
|
|
@@ -58,9 +60,11 @@ orangecontrib/IO4IT/widgets/designer/ow_extract_tables_docx_to_xlsx.ui
|
|
|
58
60
|
orangecontrib/IO4IT/widgets/designer/ow_file_ext_selector.ui
|
|
59
61
|
orangecontrib/IO4IT/widgets/designer/ow_json_to_data_table.ui
|
|
60
62
|
orangecontrib/IO4IT/widgets/designer/owchatgpt.ui
|
|
63
|
+
orangecontrib/IO4IT/widgets/designer/owcustomllmapi.ui
|
|
61
64
|
orangecontrib/IO4IT/widgets/designer/owdeepsearch.ui
|
|
62
65
|
orangecontrib/IO4IT/widgets/designer/owdoclingtomarkdown.ui
|
|
63
66
|
orangecontrib/IO4IT/widgets/designer/owexportmarkdown.ui
|
|
67
|
+
orangecontrib/IO4IT/widgets/designer/owfile2images.ui
|
|
64
68
|
orangecontrib/IO4IT/widgets/designer/owinboxmailmonitoring.ui
|
|
65
69
|
orangecontrib/IO4IT/widgets/designer/owinsertdatatoexcel.ui
|
|
66
70
|
orangecontrib/IO4IT/widgets/designer/owmailloader.ui
|
|
@@ -72,7 +76,6 @@ orangecontrib/IO4IT/widgets/designer/owofficenormalizer.ui
|
|
|
72
76
|
orangecontrib/IO4IT/widgets/designer/owparserhtml.ui
|
|
73
77
|
orangecontrib/IO4IT/widgets/designer/owpdftype.ui
|
|
74
78
|
orangecontrib/IO4IT/widgets/designer/owpipauditor.ui
|
|
75
|
-
orangecontrib/IO4IT/widgets/designer/owpptx2jpg.ui
|
|
76
79
|
orangecontrib/IO4IT/widgets/designer/owprocesspoolexecutor.ui
|
|
77
80
|
orangecontrib/IO4IT/widgets/designer/owspeechtotext.ui
|
|
78
81
|
orangecontrib/IO4IT/widgets/designer/owvisualizationer.ui
|
|
@@ -86,6 +89,7 @@ orangecontrib/IO4IT/widgets/icons/dep_md_old.png
|
|
|
86
89
|
orangecontrib/IO4IT/widgets/icons/download.png
|
|
87
90
|
orangecontrib/IO4IT/widgets/icons/export_md.png
|
|
88
91
|
orangecontrib/IO4IT/widgets/icons/extract_table.png
|
|
92
|
+
orangecontrib/IO4IT/widgets/icons/file2images.png
|
|
89
93
|
orangecontrib/IO4IT/widgets/icons/file_extensor.png
|
|
90
94
|
orangecontrib/IO4IT/widgets/icons/html.png
|
|
91
95
|
orangecontrib/IO4IT/widgets/icons/json-file.png
|
|
@@ -96,9 +100,9 @@ orangecontrib/IO4IT/widgets/icons/mail_writer.png
|
|
|
96
100
|
orangecontrib/IO4IT/widgets/icons/md.png
|
|
97
101
|
orangecontrib/IO4IT/widgets/icons/monitor-email.svg
|
|
98
102
|
orangecontrib/IO4IT/widgets/icons/office_normalizer.png
|
|
103
|
+
orangecontrib/IO4IT/widgets/icons/owcustomllmapi.svg
|
|
99
104
|
orangecontrib/IO4IT/widgets/icons/owmd2html.svg
|
|
100
105
|
orangecontrib/IO4IT/widgets/icons/pip_auditor.png
|
|
101
|
-
orangecontrib/IO4IT/widgets/icons/pptx2jpg.png
|
|
102
106
|
orangecontrib/IO4IT/widgets/icons/process_pool_executor.png
|
|
103
107
|
orangecontrib/IO4IT/widgets/icons/speech_to_text.png
|
|
104
108
|
orangecontrib/IO4IT/widgets/icons/upload.png
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import base64
|
|
2
|
+
import mimetypes
|
|
3
|
+
import os
|
|
4
|
+
|
|
5
|
+
import requests
|
|
6
|
+
|
|
7
|
+
import Orange.data
|
|
8
|
+
from Orange.data import StringVariable
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def build_headers(header_name, auth_scheme, api_key):
|
|
12
|
+
header_name = (header_name or "Authorization").strip()
|
|
13
|
+
auth_scheme = (auth_scheme or "").strip()
|
|
14
|
+
value = f"{auth_scheme} {api_key}".strip() if auth_scheme else str(api_key)
|
|
15
|
+
return {"Content-Type": "application/json", header_name: value}
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def image_to_data_uri(file_path):
|
|
19
|
+
"""Encode a local image file as a base64 data URI."""
|
|
20
|
+
mime_type, _ = mimetypes.guess_type(file_path)
|
|
21
|
+
mime_type = mime_type or "application/octet-stream"
|
|
22
|
+
with open(file_path, "rb") as f:
|
|
23
|
+
encoded = base64.b64encode(f.read()).decode("utf-8")
|
|
24
|
+
return f"data:{mime_type};base64,{encoded}"
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def build_user_content(prompt, image_paths):
|
|
28
|
+
"""Build the 'content' field of a user message, attaching images when provided."""
|
|
29
|
+
if not image_paths:
|
|
30
|
+
return str(prompt)
|
|
31
|
+
|
|
32
|
+
content = []
|
|
33
|
+
for image_path in image_paths:
|
|
34
|
+
image_path = image_path.strip().strip("'").strip('"')
|
|
35
|
+
if not image_path:
|
|
36
|
+
continue
|
|
37
|
+
if not os.path.exists(image_path):
|
|
38
|
+
content.append({"type": "text", "text": f"[ERROR] Image not found: {image_path}"})
|
|
39
|
+
continue
|
|
40
|
+
try:
|
|
41
|
+
content.append({"type": "image_url", "image_url": {"url": image_to_data_uri(image_path)}})
|
|
42
|
+
except Exception as e:
|
|
43
|
+
content.append({"type": "text", "text": f"[ERROR] Unable to read image {image_path}: {e}"})
|
|
44
|
+
content.append({"type": "text", "text": str(prompt)})
|
|
45
|
+
return content
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def call_chat_completion(prompt, system_prompt, config, image_paths=None):
|
|
49
|
+
"""
|
|
50
|
+
Call a /chat/completions endpoint using the widely adopted chat-completions
|
|
51
|
+
message format. Vision-capable models can be reached by passing image_paths,
|
|
52
|
+
which are embedded in the user message as base64 data URIs.
|
|
53
|
+
|
|
54
|
+
config keys: base_url, route, header_name, auth_scheme, api_key,
|
|
55
|
+
model, max_tokens, temperature, cert_path, cert_is_ca,
|
|
56
|
+
proxy_url
|
|
57
|
+
"""
|
|
58
|
+
url = config["base_url"].rstrip("/") + config["route"]
|
|
59
|
+
headers = build_headers(config["header_name"], config["auth_scheme"], config["api_key"])
|
|
60
|
+
|
|
61
|
+
messages = []
|
|
62
|
+
if system_prompt:
|
|
63
|
+
messages.append({"role": "system", "content": str(system_prompt)})
|
|
64
|
+
messages.append({"role": "user", "content": build_user_content(prompt, image_paths)})
|
|
65
|
+
|
|
66
|
+
payload = {
|
|
67
|
+
"model": config["model"],
|
|
68
|
+
"messages": messages,
|
|
69
|
+
"temperature": config["temperature"],
|
|
70
|
+
"max_tokens": config["max_tokens"],
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
kwargs = {"timeout": 600}
|
|
74
|
+
cert_path = config.get("cert_path")
|
|
75
|
+
if cert_path:
|
|
76
|
+
if config.get("cert_is_ca"):
|
|
77
|
+
kwargs["verify"] = cert_path
|
|
78
|
+
else:
|
|
79
|
+
kwargs["cert"] = cert_path
|
|
80
|
+
|
|
81
|
+
if config.get("use_proxy"):
|
|
82
|
+
# Explicitly set, even when empty: an empty value forces a direct
|
|
83
|
+
# connection and bypasses any http_proxy/https_proxy environment
|
|
84
|
+
# variable (e.g. the one Orange itself sets from its preferences),
|
|
85
|
+
# instead of silently inheriting it.
|
|
86
|
+
proxy_url = config.get("proxy_url") or ""
|
|
87
|
+
kwargs["proxies"] = {"http": proxy_url, "https": proxy_url}
|
|
88
|
+
|
|
89
|
+
response = requests.post(url, headers=headers, json=payload, **kwargs)
|
|
90
|
+
response.raise_for_status()
|
|
91
|
+
data = response.json()
|
|
92
|
+
return data["choices"][0]["message"]["content"]
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def generate_answers(data, config, progress_callback=None):
|
|
96
|
+
"""
|
|
97
|
+
Runs call_chat_completion for every row of `data` (needs a 'prompt' column,
|
|
98
|
+
optionally a 'system_prompt' column and an 'image paths' column for
|
|
99
|
+
vision-capable models) and returns a new Table with an added 'Answer'
|
|
100
|
+
string column.
|
|
101
|
+
|
|
102
|
+
The 'image paths' column, when present, holds one or more image file
|
|
103
|
+
paths separated by ';' for that row.
|
|
104
|
+
"""
|
|
105
|
+
domain = data.domain
|
|
106
|
+
has_system_prompt = "system_prompt" in domain
|
|
107
|
+
has_images = "image paths" in domain
|
|
108
|
+
|
|
109
|
+
prompts = data.get_column("prompt")
|
|
110
|
+
system_prompts = data.get_column("system_prompt") if has_system_prompt else None
|
|
111
|
+
image_paths_column = data.get_column("image paths") if has_images else None
|
|
112
|
+
|
|
113
|
+
answers = []
|
|
114
|
+
n_rows = len(data)
|
|
115
|
+
for i in range(n_rows):
|
|
116
|
+
prompt = prompts[i]
|
|
117
|
+
system_prompt = system_prompts[i] if system_prompts is not None else None
|
|
118
|
+
image_paths = image_paths_column[i].split(";") if image_paths_column is not None else None
|
|
119
|
+
try:
|
|
120
|
+
answer = call_chat_completion(prompt, system_prompt, config, image_paths)
|
|
121
|
+
except requests.HTTPError as e:
|
|
122
|
+
body = e.response.text if e.response is not None else str(e)
|
|
123
|
+
answer = f"[ERROR] HTTP {e.response.status_code if e.response is not None else '?'}: {body}"
|
|
124
|
+
except Exception as e:
|
|
125
|
+
answer = f"[ERROR] {e}"
|
|
126
|
+
|
|
127
|
+
answers.append(answer)
|
|
128
|
+
if progress_callback is not None:
|
|
129
|
+
progress_callback((int(100 * (i + 1) / max(n_rows, 1)), f"Row {i + 1}/{n_rows} done\n"))
|
|
130
|
+
|
|
131
|
+
answer_var = StringVariable("Answer")
|
|
132
|
+
return data.add_column(answer_var, answers)
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
import time
|
|
3
|
+
import subprocess
|
|
4
|
+
import shutil
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def get_conversion_method():
|
|
9
|
+
"""Determines the best available conversion method."""
|
|
10
|
+
# 1. Check for MS Office
|
|
11
|
+
if sys.platform.startswith("win"):
|
|
12
|
+
try:
|
|
13
|
+
import win32com.client
|
|
14
|
+
# Try to see if the COM object is registered
|
|
15
|
+
win32com.client.GetActiveObject("PowerPoint.Application")
|
|
16
|
+
return "office"
|
|
17
|
+
except:
|
|
18
|
+
try:
|
|
19
|
+
# If not running, try to see if it's dispatchable
|
|
20
|
+
win32com.client.Dispatch("PowerPoint.Application")
|
|
21
|
+
return "office"
|
|
22
|
+
except:
|
|
23
|
+
pass
|
|
24
|
+
elif sys.platform == "darwin":
|
|
25
|
+
# Check if PowerPoint app exists on Mac
|
|
26
|
+
if Path("/Applications/Microsoft PowerPoint.app").exists():
|
|
27
|
+
return "office"
|
|
28
|
+
|
|
29
|
+
# 2. Check for LibreOffice (soffice)
|
|
30
|
+
if shutil.which("soffice"):
|
|
31
|
+
return "libreoffice"
|
|
32
|
+
|
|
33
|
+
# 3. Fallback to Aspose
|
|
34
|
+
return "aspose"
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def convert_via_office(src: Path, pdf_path: Path):
|
|
38
|
+
if sys.platform.startswith("win"):
|
|
39
|
+
import win32com.client
|
|
40
|
+
powerpoint = win32com.client.Dispatch("PowerPoint.Application")
|
|
41
|
+
try:
|
|
42
|
+
presentation = powerpoint.Presentations.Open(str(src), WithWindow=False)
|
|
43
|
+
presentation.SaveAs(str(pdf_path), 32) # 32 = ppSaveAsPDF
|
|
44
|
+
presentation.Close()
|
|
45
|
+
finally:
|
|
46
|
+
# Note: We don't quit() powerpoint here to avoid killing other open docs
|
|
47
|
+
pass
|
|
48
|
+
elif sys.platform == "darwin":
|
|
49
|
+
script = f'tell application "Microsoft PowerPoint" to save (open POSIX file "{src}") in POSIX file "{pdf_path}" as PDF'
|
|
50
|
+
subprocess.run(["osascript", "-e", script], check=True)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def convert_via_libreoffice(src: Path, out_dir: Path):
|
|
54
|
+
subprocess.run([
|
|
55
|
+
"soffice", "--headless", "--convert-to", "pdf",
|
|
56
|
+
"--outdir", str(out_dir), str(src)
|
|
57
|
+
], check=True, capture_output=True)
|
|
58
|
+
return out_dir / f"{src.stem}.pdf"
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def parse_pages(spec, total):
|
|
62
|
+
"""Convertit une spécification de pages en liste d'indices 1-based, triés et dédupliqués.
|
|
63
|
+
|
|
64
|
+
Exemples (total = nombre de pages du document) :
|
|
65
|
+
None / "" / "all" / "*" -> toutes les pages
|
|
66
|
+
"1" -> [1]
|
|
67
|
+
"1,3,5" -> [1, 3, 5]
|
|
68
|
+
"1-3" -> [1, 2, 3]
|
|
69
|
+
"2-4,6" -> [2, 3, 4, 6]
|
|
70
|
+
Les pages hors intervalle [1, total] sont ignorées silencieusement.
|
|
71
|
+
"""
|
|
72
|
+
if spec is None:
|
|
73
|
+
return list(range(1, total + 1))
|
|
74
|
+
|
|
75
|
+
spec = str(spec).strip().lower()
|
|
76
|
+
if spec in ("", "all", "toutes", "tout", "*"):
|
|
77
|
+
return list(range(1, total + 1))
|
|
78
|
+
|
|
79
|
+
pages = set()
|
|
80
|
+
for part in spec.split(","):
|
|
81
|
+
part = part.strip()
|
|
82
|
+
if not part:
|
|
83
|
+
continue
|
|
84
|
+
try:
|
|
85
|
+
if "-" in part:
|
|
86
|
+
a, b = part.split("-", 1)
|
|
87
|
+
a, b = int(a), int(b)
|
|
88
|
+
for p in range(min(a, b), max(a, b) + 1):
|
|
89
|
+
pages.add(p)
|
|
90
|
+
else:
|
|
91
|
+
pages.add(int(part))
|
|
92
|
+
except ValueError:
|
|
93
|
+
# Fragment invalide (ex. "abc") -> on l'ignore
|
|
94
|
+
continue
|
|
95
|
+
|
|
96
|
+
return sorted(p for p in pages if 1 <= p <= total)
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
# Formats gérés nativement par Pixmap.save() de PyMuPDF.
|
|
100
|
+
# Les autres (tif/tiff, webp, bmp...) passent par Pillow via pix.pil_save().
|
|
101
|
+
_NATIVE_FORMATS = {"jpg", "jpeg", "png", "pnm", "pgm", "ppm", "pbm", "pam", "tga", "ps", "psd"}
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def normalize_ext(out_ext):
|
|
105
|
+
"""Nettoie l'extension demandée : minuscule, sans point initial, jpg par défaut."""
|
|
106
|
+
ext = str(out_ext or "jpg").strip().lower().lstrip(".")
|
|
107
|
+
if ext == "jpeg":
|
|
108
|
+
ext = "jpg"
|
|
109
|
+
return ext or "jpg"
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def normalize_dpi(dpi, default=150):
|
|
113
|
+
"""Convertit le DPI en entier valide (> 0), sinon retombe sur `default`."""
|
|
114
|
+
try:
|
|
115
|
+
dpi = int(dpi)
|
|
116
|
+
except (TypeError, ValueError):
|
|
117
|
+
return default
|
|
118
|
+
return dpi if dpi > 0 else default
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def _save_pixmap(pix, img_path: Path, ext: str):
|
|
122
|
+
"""Sauvegarde le pixmap au bon format selon l'extension."""
|
|
123
|
+
if ext in _NATIVE_FORMATS:
|
|
124
|
+
pix.save(str(img_path))
|
|
125
|
+
else:
|
|
126
|
+
# tif/tiff et autres formats -> nécessite Pillow
|
|
127
|
+
pix.pil_save(str(img_path))
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def process_one_file(file_path_str: str, out_dir_str: str = None,
|
|
131
|
+
pages: str = "all", out_ext: str = "jpg",
|
|
132
|
+
dpi: int = 150, unique_folder: bool = True):
|
|
133
|
+
"""Convertit un PPTX (ou PDF) en images.
|
|
134
|
+
|
|
135
|
+
Args:
|
|
136
|
+
file_path_str : chemin du fichier source (.pptx ou .pdf).
|
|
137
|
+
out_dir_str : dossier de sortie. Si None/vide, on retombe sur le
|
|
138
|
+
comportement historique (images_<nom> ou images/).
|
|
139
|
+
pages : pages/slides à extraire ("all", "1", "1,3", "1-3"...).
|
|
140
|
+
out_ext : format d'image de sortie ("jpg", "png", "tif"...).
|
|
141
|
+
dpi : résolution de rendu en points par pouce (défaut 150).
|
|
142
|
+
unique_folder : utilisé seulement quand out_dir_str n'est pas fourni.
|
|
143
|
+
|
|
144
|
+
Retour : [src, "img1|img2|...", "ok"/"nok", durée, message]
|
|
145
|
+
"""
|
|
146
|
+
try:
|
|
147
|
+
import fitz # PyMuPDF
|
|
148
|
+
except ImportError:
|
|
149
|
+
return [file_path_str, "", "nok", "0.0", "Erreur: PyMuPDF non installé"]
|
|
150
|
+
|
|
151
|
+
t0 = time.time()
|
|
152
|
+
src = Path(file_path_str).resolve()
|
|
153
|
+
ext_out = normalize_ext(out_ext)
|
|
154
|
+
dpi_out = normalize_dpi(dpi)
|
|
155
|
+
|
|
156
|
+
# --- Dossier de sortie : colonne prioritaire, sinon fallback historique ---
|
|
157
|
+
if out_dir_str and str(out_dir_str).strip():
|
|
158
|
+
out_dir = Path(str(out_dir_str).strip())
|
|
159
|
+
else:
|
|
160
|
+
out_dir = src.parent / (f"images_{src.stem}" if unique_folder else "images")
|
|
161
|
+
out_dir.mkdir(parents=True, exist_ok=True)
|
|
162
|
+
|
|
163
|
+
img_list = []
|
|
164
|
+
ext = src.suffix.lower()
|
|
165
|
+
method = "pdf" # méthode par défaut si l'entrée est déjà un PDF
|
|
166
|
+
temp_pdf = False # True si on a généré un PDF intermédiaire à supprimer
|
|
167
|
+
|
|
168
|
+
try:
|
|
169
|
+
# --- PHASE 1 : obtenir un PDF ---
|
|
170
|
+
if ext == ".pdf":
|
|
171
|
+
pdf_path = src
|
|
172
|
+
else:
|
|
173
|
+
method = get_conversion_method()
|
|
174
|
+
if method == "aspose":
|
|
175
|
+
# import aspose.slides as slides # (fallback désactivé)
|
|
176
|
+
return [str(src), "", "nok", f"{time.time()-t0:.2f}",
|
|
177
|
+
"Conversion impossible sans LibreOffice ou MS Office"]
|
|
178
|
+
|
|
179
|
+
pdf_path = out_dir / f"{src.stem}.pdf"
|
|
180
|
+
temp_pdf = True
|
|
181
|
+
if method == "office":
|
|
182
|
+
convert_via_office(src, pdf_path)
|
|
183
|
+
else: # libreoffice
|
|
184
|
+
convert_via_libreoffice(src, out_dir)
|
|
185
|
+
|
|
186
|
+
# --- PHASE 2 : rasteriser uniquement les pages demandées ---
|
|
187
|
+
doc = fitz.open(str(pdf_path))
|
|
188
|
+
wanted = parse_pages(pages, doc.page_count)
|
|
189
|
+
|
|
190
|
+
for i in wanted:
|
|
191
|
+
page = doc.load_page(i - 1) # fitz est 0-based
|
|
192
|
+
pix = page.get_pixmap(dpi=dpi_out)
|
|
193
|
+
img_path = out_dir / f"{src.stem}_slide_{i:03d}.{ext_out}"
|
|
194
|
+
_save_pixmap(pix, img_path, ext_out)
|
|
195
|
+
img_list.append(str(img_path))
|
|
196
|
+
doc.close()
|
|
197
|
+
|
|
198
|
+
if temp_pdf and pdf_path.exists():
|
|
199
|
+
pdf_path.unlink()
|
|
200
|
+
|
|
201
|
+
duration = time.time() - t0
|
|
202
|
+
if not img_list:
|
|
203
|
+
return [str(src), "", "nok", f"{duration:.2f}",
|
|
204
|
+
f"Aucune page valide pour la spec '{pages}' ({method})"]
|
|
205
|
+
|
|
206
|
+
return [str(src), "|".join(img_list), "ok", f"{duration:.2f}",
|
|
207
|
+
f"{len(img_list)} image(s) .{ext_out} @ {dpi_out} DPI ({method})"]
|
|
208
|
+
|
|
209
|
+
except Exception as e:
|
|
210
|
+
return [str(src), "", "nok", f"{time.time()-t0:.2f}",
|
|
211
|
+
f"Method {method} failed: {str(e)}"]
|