io4it 1.0.1__tar.gz → 1.0.1.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {io4it-1.0.1 → io4it-1.0.1.1}/PKG-INFO +3 -1
- {io4it-1.0.1 → io4it-1.0.1.1}/io4it.egg-info/PKG-INFO +3 -1
- {io4it-1.0.1 → io4it-1.0.1.1}/io4it.egg-info/SOURCES.txt +8 -0
- {io4it-1.0.1 → io4it-1.0.1.1}/io4it.egg-info/requires.txt +2 -0
- io4it-1.0.1.1/orangecontrib/IO4IT/widgets/OWExportMarkdown.py +150 -0
- {io4it-1.0.1 → io4it-1.0.1.1}/orangecontrib/IO4IT/widgets/OWS3Uploader.py +1 -1
- {io4it-1.0.1 → io4it-1.0.1.1}/orangecontrib/IO4IT/widgets/OWS3downloader.py +1 -1
- {io4it-1.0.1 → io4it-1.0.1.1}/orangecontrib/IO4IT/widgets/OWS3list.py +1 -1
- {io4it-1.0.1 → io4it-1.0.1.1}/orangecontrib/IO4IT/widgets/OWSpeechToText.py +3 -1
- io4it-1.0.1.1/orangecontrib/IO4IT/widgets/OWmailLoader.py +207 -0
- io4it-1.0.1.1/orangecontrib/IO4IT/widgets/OWmailSender.py +150 -0
- io4it-1.0.1.1/orangecontrib/IO4IT/widgets/designer/owexportmarkdown.ui +59 -0
- {io4it-1.0.1 → io4it-1.0.1.1}/orangecontrib/IO4IT/widgets/designer/owmailloader.ui +1 -1
- io4it-1.0.1.1/orangecontrib/IO4IT/widgets/designer/owmailsender.ui +32 -0
- io4it-1.0.1.1/orangecontrib/IO4IT/widgets/icons/export_md.png +0 -0
- io4it-1.0.1.1/orangecontrib/IO4IT/widgets/icons/mail_loader.png +0 -0
- io4it-1.0.1.1/orangecontrib/IO4IT/widgets/icons/mail_writer.png +0 -0
- {io4it-1.0.1 → io4it-1.0.1.1}/setup.py +3 -1
- {io4it-1.0.1 → io4it-1.0.1.1}/io4it.egg-info/dependency_links.txt +0 -0
- {io4it-1.0.1 → io4it-1.0.1.1}/io4it.egg-info/entry_points.txt +0 -0
- {io4it-1.0.1 → io4it-1.0.1.1}/io4it.egg-info/namespace_packages.txt +0 -0
- {io4it-1.0.1 → io4it-1.0.1.1}/io4it.egg-info/top_level.txt +0 -0
- {io4it-1.0.1 → io4it-1.0.1.1}/orangecontrib/IO4IT/__init__.py +0 -0
- {io4it-1.0.1 → io4it-1.0.1.1}/orangecontrib/IO4IT/ocr_function/__init__.py +0 -0
- {io4it-1.0.1 → io4it-1.0.1.1}/orangecontrib/IO4IT/ocr_function/word_converter.py +0 -0
- {io4it-1.0.1 → io4it-1.0.1.1}/orangecontrib/IO4IT/widgets/OWMarkdownizer.py +0 -0
- {io4it-1.0.1 → io4it-1.0.1.1}/orangecontrib/IO4IT/widgets/OWwordpdf2docx.py +0 -0
- {io4it-1.0.1 → io4it-1.0.1.1}/orangecontrib/IO4IT/widgets/__init__.py +0 -0
- {io4it-1.0.1 → io4it-1.0.1.1}/orangecontrib/IO4IT/widgets/designer/__init__.py +0 -0
- {io4it-1.0.1 → io4it-1.0.1.1}/orangecontrib/IO4IT/widgets/designer/chart.html +0 -0
- {io4it-1.0.1 → io4it-1.0.1.1}/orangecontrib/IO4IT/widgets/designer/nogui.ui +0 -0
- {io4it-1.0.1 → io4it-1.0.1.1}/orangecontrib/IO4IT/widgets/designer/ow_file_ext_selector.ui +0 -0
- {io4it-1.0.1 → io4it-1.0.1.1}/orangecontrib/IO4IT/widgets/designer/owspeechtotext.ui +0 -0
- {io4it-1.0.1 → io4it-1.0.1.1}/orangecontrib/IO4IT/widgets/designer/owvisualizationer.ui +0 -0
- {io4it-1.0.1 → io4it-1.0.1.1}/orangecontrib/IO4IT/widgets/designer/wordpdf2docx.ui +0 -0
- {io4it-1.0.1 → io4it-1.0.1.1}/orangecontrib/IO4IT/widgets/icons/__init__.py +0 -0
- {io4it-1.0.1 → io4it-1.0.1.1}/orangecontrib/IO4IT/widgets/icons/download.png +0 -0
- {io4it-1.0.1 → io4it-1.0.1.1}/orangecontrib/IO4IT/widgets/icons/file_extensor.png +0 -0
- {io4it-1.0.1 → io4it-1.0.1.1}/orangecontrib/IO4IT/widgets/icons/list_aws.png +0 -0
- {io4it-1.0.1 → io4it-1.0.1.1}/orangecontrib/IO4IT/widgets/icons/md.png +0 -0
- {io4it-1.0.1 → io4it-1.0.1.1}/orangecontrib/IO4IT/widgets/icons/speech_to_text.png +0 -0
- {io4it-1.0.1 → io4it-1.0.1.1}/orangecontrib/IO4IT/widgets/icons/upload.png +0 -0
- {io4it-1.0.1 → io4it-1.0.1.1}/orangecontrib/IO4IT/widgets/icons/visualizationer.png +0 -0
- {io4it-1.0.1 → io4it-1.0.1.1}/orangecontrib/IO4IT/widgets/icons/wordpdf2docx.png +0 -0
- {io4it-1.0.1 → io4it-1.0.1.1}/orangecontrib/IO4IT/widgets/icons_dev/__init__.py +0 -0
- {io4it-1.0.1 → io4it-1.0.1.1}/orangecontrib/__init__.py +0 -0
- {io4it-1.0.1 → io4it-1.0.1.1}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: io4it
|
|
3
|
-
Version: 1.0.1
|
|
3
|
+
Version: 1.0.1.1
|
|
4
4
|
Home-page:
|
|
5
5
|
Author:
|
|
6
6
|
Author-email:
|
|
@@ -15,5 +15,7 @@ Requires-Dist: pyannote.audio
|
|
|
15
15
|
Requires-Dist: pyannote-core
|
|
16
16
|
Requires-Dist: wave
|
|
17
17
|
Requires-Dist: scikit-learn
|
|
18
|
+
Requires-Dist: pylatexenc
|
|
19
|
+
Requires-Dist: docopt
|
|
18
20
|
Dynamic: keywords
|
|
19
21
|
Dynamic: requires-dist
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: io4it
|
|
3
|
-
Version: 1.0.1
|
|
3
|
+
Version: 1.0.1.1
|
|
4
4
|
Home-page:
|
|
5
5
|
Author:
|
|
6
6
|
Author-email:
|
|
@@ -15,5 +15,7 @@ Requires-Dist: pyannote.audio
|
|
|
15
15
|
Requires-Dist: pyannote-core
|
|
16
16
|
Requires-Dist: wave
|
|
17
17
|
Requires-Dist: scikit-learn
|
|
18
|
+
Requires-Dist: pylatexenc
|
|
19
|
+
Requires-Dist: docopt
|
|
18
20
|
Dynamic: keywords
|
|
19
21
|
Dynamic: requires-dist
|
|
@@ -11,25 +11,33 @@ orangecontrib/__init__.py
|
|
|
11
11
|
orangecontrib/IO4IT/__init__.py
|
|
12
12
|
orangecontrib/IO4IT/ocr_function/__init__.py
|
|
13
13
|
orangecontrib/IO4IT/ocr_function/word_converter.py
|
|
14
|
+
orangecontrib/IO4IT/widgets/OWExportMarkdown.py
|
|
14
15
|
orangecontrib/IO4IT/widgets/OWMarkdownizer.py
|
|
15
16
|
orangecontrib/IO4IT/widgets/OWS3Uploader.py
|
|
16
17
|
orangecontrib/IO4IT/widgets/OWS3downloader.py
|
|
17
18
|
orangecontrib/IO4IT/widgets/OWS3list.py
|
|
18
19
|
orangecontrib/IO4IT/widgets/OWSpeechToText.py
|
|
20
|
+
orangecontrib/IO4IT/widgets/OWmailLoader.py
|
|
21
|
+
orangecontrib/IO4IT/widgets/OWmailSender.py
|
|
19
22
|
orangecontrib/IO4IT/widgets/OWwordpdf2docx.py
|
|
20
23
|
orangecontrib/IO4IT/widgets/__init__.py
|
|
21
24
|
orangecontrib/IO4IT/widgets/designer/__init__.py
|
|
22
25
|
orangecontrib/IO4IT/widgets/designer/chart.html
|
|
23
26
|
orangecontrib/IO4IT/widgets/designer/nogui.ui
|
|
24
27
|
orangecontrib/IO4IT/widgets/designer/ow_file_ext_selector.ui
|
|
28
|
+
orangecontrib/IO4IT/widgets/designer/owexportmarkdown.ui
|
|
25
29
|
orangecontrib/IO4IT/widgets/designer/owmailloader.ui
|
|
30
|
+
orangecontrib/IO4IT/widgets/designer/owmailsender.ui
|
|
26
31
|
orangecontrib/IO4IT/widgets/designer/owspeechtotext.ui
|
|
27
32
|
orangecontrib/IO4IT/widgets/designer/owvisualizationer.ui
|
|
28
33
|
orangecontrib/IO4IT/widgets/designer/wordpdf2docx.ui
|
|
29
34
|
orangecontrib/IO4IT/widgets/icons/__init__.py
|
|
30
35
|
orangecontrib/IO4IT/widgets/icons/download.png
|
|
36
|
+
orangecontrib/IO4IT/widgets/icons/export_md.png
|
|
31
37
|
orangecontrib/IO4IT/widgets/icons/file_extensor.png
|
|
32
38
|
orangecontrib/IO4IT/widgets/icons/list_aws.png
|
|
39
|
+
orangecontrib/IO4IT/widgets/icons/mail_loader.png
|
|
40
|
+
orangecontrib/IO4IT/widgets/icons/mail_writer.png
|
|
33
41
|
orangecontrib/IO4IT/widgets/icons/md.png
|
|
34
42
|
orangecontrib/IO4IT/widgets/icons/speech_to_text.png
|
|
35
43
|
orangecontrib/IO4IT/widgets/icons/upload.png
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import sys
|
|
3
|
+
|
|
4
|
+
from Orange.widgets import widget
|
|
5
|
+
from Orange.widgets.widget import Input
|
|
6
|
+
from AnyQt.QtWidgets import QFileDialog, QMessageBox, QApplication
|
|
7
|
+
|
|
8
|
+
from orangecontrib.text.corpus import Corpus
|
|
9
|
+
from docx import Document
|
|
10
|
+
from docx.shared import Pt
|
|
11
|
+
from pptx import Presentation
|
|
12
|
+
from pptx.util import Inches, Pt
|
|
13
|
+
|
|
14
|
+
if "site-packages/Orange/widgets" in os.path.dirname(os.path.abspath(__file__)).replace("\\", "/"):
|
|
15
|
+
from Orange.widgets.orangecontrib.AAIT.utils.import_uic import uic
|
|
16
|
+
else:
|
|
17
|
+
from orangecontrib.AAIT.utils.import_uic import uic
|
|
18
|
+
|
|
19
|
+
import pypandoc
|
|
20
|
+
import tempfile
|
|
21
|
+
|
|
22
|
+
# pip install pypandoc
|
|
23
|
+
# pip install pypandoc_binary
|
|
24
|
+
|
|
25
|
+
class OWExportMarkdown(widget.OWWidget):
|
|
26
|
+
name = "OWExportMarkdown"
|
|
27
|
+
description = "Export results from a markdown as pdf, docx, pptx"
|
|
28
|
+
icon = "icons/export_md.png"
|
|
29
|
+
if "site-packages/Orange/widgets" in os.path.dirname(os.path.abspath(__file__)).replace("\\", "/"):
|
|
30
|
+
icon = "icons_dev/export_md.png"
|
|
31
|
+
want_control_area = True
|
|
32
|
+
priority = 9999
|
|
33
|
+
|
|
34
|
+
class Inputs:
|
|
35
|
+
corpus = Input("Corpus", Corpus, replaces=["Data"])
|
|
36
|
+
|
|
37
|
+
def __init__(self):
|
|
38
|
+
super().__init__()
|
|
39
|
+
self.corpus = None
|
|
40
|
+
self.markdown_text = ""
|
|
41
|
+
|
|
42
|
+
# Load .ui file
|
|
43
|
+
ui_path = os.path.join(os.path.dirname(__file__), "designer", "owexportmarkdown.ui")
|
|
44
|
+
uic.loadUi(ui_path, baseinstance=self)
|
|
45
|
+
|
|
46
|
+
# Connect the Save button
|
|
47
|
+
self.saveButton.clicked.connect(self.save_markdown_as)
|
|
48
|
+
|
|
49
|
+
@Inputs.corpus
|
|
50
|
+
def set_corpus(self, corpus):
|
|
51
|
+
if corpus is not None:
|
|
52
|
+
self.corpus = corpus
|
|
53
|
+
self.markdown_text = "\n".join(str(d) for d in corpus.documents)
|
|
54
|
+
else:
|
|
55
|
+
self.corpus = None
|
|
56
|
+
self.markdown_text = ""
|
|
57
|
+
|
|
58
|
+
def ajouter_en_tete_pied_docx(self, file_path, header_text, footer_text):
|
|
59
|
+
doc = Document(file_path)
|
|
60
|
+
section = doc.sections[0]
|
|
61
|
+
|
|
62
|
+
# En-tête
|
|
63
|
+
header = section.header
|
|
64
|
+
if not header.paragraphs:
|
|
65
|
+
p = header.add_paragraph()
|
|
66
|
+
else:
|
|
67
|
+
p = header.paragraphs[0]
|
|
68
|
+
p.text = header_text
|
|
69
|
+
p.runs[0].font.size = Pt(10)
|
|
70
|
+
|
|
71
|
+
# Pied de page
|
|
72
|
+
footer = section.footer
|
|
73
|
+
if not footer.paragraphs:
|
|
74
|
+
p = footer.add_paragraph()
|
|
75
|
+
else:
|
|
76
|
+
p = footer.paragraphs[0]
|
|
77
|
+
p.text = footer_text
|
|
78
|
+
p.runs[0].font.size = Pt(10)
|
|
79
|
+
|
|
80
|
+
doc.save(file_path)
|
|
81
|
+
|
|
82
|
+
def ajouter_entete_pied_pptx(self, file_path, entete_text, pied_text):
|
|
83
|
+
prs = Presentation(file_path)
|
|
84
|
+
for slide in prs.slides:
|
|
85
|
+
# En-tête
|
|
86
|
+
entete = slide.shapes.add_textbox(Inches(0.3), Inches(0.2), Inches(8), Inches(0.5))
|
|
87
|
+
tf_entete = entete.text_frame
|
|
88
|
+
tf_entete.text = entete_text
|
|
89
|
+
tf_entete.paragraphs[0].font.size = Pt(12)
|
|
90
|
+
tf_entete.paragraphs[0].font.bold = True
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
pied = slide.shapes.add_textbox(Inches(0.3), Inches(6.3), Inches(8), Inches(0.5))
|
|
94
|
+
tf_pied = pied.text_frame
|
|
95
|
+
tf_pied.text = pied_text
|
|
96
|
+
tf_pied.paragraphs[0].font.size = Pt(10)
|
|
97
|
+
|
|
98
|
+
prs.save(file_path)
|
|
99
|
+
|
|
100
|
+
def save_markdown_as(self):
|
|
101
|
+
if not self.markdown_text.strip():
|
|
102
|
+
QMessageBox.warning(self, "Aucun contenu", "Aucun contenu markdown à exporter.")
|
|
103
|
+
return
|
|
104
|
+
|
|
105
|
+
filters = "PDF (*.pdf);;Word (*.docx);;PowerPoint (*.pptx)"
|
|
106
|
+
file_path, selected_filter = QFileDialog.getSaveFileName(self, "Enregistrer sous", "", filters)
|
|
107
|
+
|
|
108
|
+
if not file_path:
|
|
109
|
+
return
|
|
110
|
+
|
|
111
|
+
ext_map = {
|
|
112
|
+
"PDF (*.pdf)": "pdf",
|
|
113
|
+
"Word (*.docx)": "docx",
|
|
114
|
+
"PowerPoint (*.pptx)": "pptx"
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
extension = ext_map.get(selected_filter)
|
|
118
|
+
if not extension:
|
|
119
|
+
QMessageBox.critical(self, "Erreur", "Format de fichier non pris en charge.")
|
|
120
|
+
return
|
|
121
|
+
|
|
122
|
+
if not file_path.lower().endswith(f".{extension}"):
|
|
123
|
+
file_path += f".{extension}"
|
|
124
|
+
|
|
125
|
+
try:
|
|
126
|
+
with tempfile.NamedTemporaryFile(mode="w", suffix=".md", delete=False, encoding="utf-8") as tmp:
|
|
127
|
+
tmp.write(self.markdown_text)
|
|
128
|
+
tmp_path = tmp.name
|
|
129
|
+
|
|
130
|
+
pypandoc.convert_file(tmp_path, to=extension, outputfile=file_path)
|
|
131
|
+
|
|
132
|
+
if extension == "docx":
|
|
133
|
+
self.ajouter_en_tete_pied_docx(file_path, "Rapport - Orange AI",
|
|
134
|
+
"Page générée automatiquement - Ne pas diffuser")
|
|
135
|
+
|
|
136
|
+
if extension == "pptx":
|
|
137
|
+
self.ajouter_entete_pied_pptx(file_path, "Orange AI – Présentation", "Page générée automatiquement")
|
|
138
|
+
|
|
139
|
+
os.remove(tmp_path)
|
|
140
|
+
|
|
141
|
+
QMessageBox.information(self, "Succès", f"Fichier exporté :\n{file_path}")
|
|
142
|
+
except Exception as e:
|
|
143
|
+
QMessageBox.critical(self, "Erreur d'export", f"Erreur : {str(e)}")
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
if __name__ == "__main__":
|
|
147
|
+
app = QApplication(sys.argv)
|
|
148
|
+
my_widget = OWExportMarkdown()
|
|
149
|
+
my_widget.show()
|
|
150
|
+
app.exec_()
|
|
@@ -3,7 +3,7 @@ import boto3
|
|
|
3
3
|
from Orange.widgets.widget import OWWidget, Input
|
|
4
4
|
from Orange.widgets.settings import Setting
|
|
5
5
|
from Orange.widgets import gui
|
|
6
|
-
from AnyQt.QtWidgets import QLineEdit, QFileDialog
|
|
6
|
+
from AnyQt.QtWidgets import QLineEdit, QFileDialog
|
|
7
7
|
from Orange.data import Table
|
|
8
8
|
|
|
9
9
|
|
|
@@ -3,7 +3,7 @@ import boto3
|
|
|
3
3
|
from Orange.widgets.widget import OWWidget, Input
|
|
4
4
|
from Orange.widgets.settings import Setting
|
|
5
5
|
from Orange.widgets import gui
|
|
6
|
-
from AnyQt.QtWidgets import QLineEdit, QFileDialog
|
|
6
|
+
from AnyQt.QtWidgets import QLineEdit, QFileDialog
|
|
7
7
|
from Orange.data import Table
|
|
8
8
|
|
|
9
9
|
class OWS3FileDownloader(OWWidget):
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import sys
|
|
3
|
+
from Orange.data import Domain, StringVariable, Table
|
|
4
|
+
import Orange.data
|
|
5
|
+
from AnyQt.QtWidgets import QApplication
|
|
6
|
+
from Orange.widgets import widget
|
|
7
|
+
from Orange.widgets.utils.signals import Input, Output
|
|
8
|
+
import re
|
|
9
|
+
|
|
10
|
+
if "site-packages/Orange/widgets" in os.path.dirname(os.path.abspath(__file__)).replace("\\", "/"):
|
|
11
|
+
from Orange.widgets.orangecontrib.AAIT.utils.import_uic import uic
|
|
12
|
+
from Orange.widgets.orangecontrib.AAIT.utils.initialize_from_ini import apply_modification_from_python_file
|
|
13
|
+
else:
|
|
14
|
+
from orangecontrib.AAIT.utils.import_uic import uic
|
|
15
|
+
from orangecontrib.AAIT.utils.initialize_from_ini import apply_modification_from_python_file
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
equivalence = {
|
|
21
|
+
"who": "Mailbox",
|
|
22
|
+
"eme": "Sender",
|
|
23
|
+
"des": "Receiver",
|
|
24
|
+
"cop": "Copy",
|
|
25
|
+
"pri": "Priority",
|
|
26
|
+
"tit": "Title",
|
|
27
|
+
"txt": "content"
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@apply_modification_from_python_file(filepath_original_widget=__file__)
|
|
32
|
+
class OWMailLoader(widget.OWWidget):
|
|
33
|
+
name = "OWMailLoader"
|
|
34
|
+
description = "Load a mail from AAIT format"
|
|
35
|
+
icon = "icons/mail_loader.png"
|
|
36
|
+
if "site-packages/Orange/widgets" in os.path.dirname(os.path.abspath(__file__)).replace("\\", "/"):
|
|
37
|
+
icon = "icons_dev/mail_loader.png"
|
|
38
|
+
gui = os.path.join(os.path.dirname(os.path.abspath(__file__)), "designer/owmailloader.ui")
|
|
39
|
+
want_control_area = False
|
|
40
|
+
priority = 9999
|
|
41
|
+
|
|
42
|
+
class Inputs:
|
|
43
|
+
data = Input("Data", Orange.data.Table)
|
|
44
|
+
|
|
45
|
+
class Outputs:
|
|
46
|
+
data = Output("Data", Orange.data.Table)
|
|
47
|
+
data_out_nothing_to_do = Output("Data Out Nothing to Do", Orange.data.Table)
|
|
48
|
+
|
|
49
|
+
@Inputs.data
|
|
50
|
+
def set_data(self, in_data):
|
|
51
|
+
self.valid_folders=[]
|
|
52
|
+
input_dir_path=""
|
|
53
|
+
self.error("")
|
|
54
|
+
if in_data is None:
|
|
55
|
+
return
|
|
56
|
+
if not "input_dir" in in_data.domain:
|
|
57
|
+
self.error("need input_dir in input data domain" )
|
|
58
|
+
return
|
|
59
|
+
if len(in_data)!=1:
|
|
60
|
+
self.error("in data need to be exactly 1 line" )
|
|
61
|
+
return
|
|
62
|
+
input_dir_path=str(in_data[0]["input_dir"].value)
|
|
63
|
+
input_dir_path.replace ("\\","/")
|
|
64
|
+
|
|
65
|
+
self.valid_folders=self.get_valid_folders(input_dir_path)
|
|
66
|
+
if len(self.valid_folders)==0:
|
|
67
|
+
self.send_nothing_to_do()
|
|
68
|
+
return
|
|
69
|
+
print( self.valid_folders)
|
|
70
|
+
self.run()
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def __init__(self):
|
|
74
|
+
super().__init__()
|
|
75
|
+
# Qt Management
|
|
76
|
+
self.valid_folders=[]
|
|
77
|
+
self.can_run = True
|
|
78
|
+
self.setFixedWidth(700)
|
|
79
|
+
self.setFixedHeight(500)
|
|
80
|
+
uic.loadUi(self.gui, self)
|
|
81
|
+
|
|
82
|
+
# # Data Management
|
|
83
|
+
self.thread = None
|
|
84
|
+
|
|
85
|
+
# Custom updates
|
|
86
|
+
self.post_initialized()
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def get_valid_folders(self,input_dir_path):
|
|
90
|
+
in_dir = input_dir_path
|
|
91
|
+
|
|
92
|
+
# Étape 1 : Vérifier si le dossier existe
|
|
93
|
+
if not os.path.isdir(in_dir):
|
|
94
|
+
print(f"Dossier introuvable : {in_dir}")
|
|
95
|
+
return [] # ou `return` selon ton besoin
|
|
96
|
+
|
|
97
|
+
# Étape 2 : Parcourir les sous-dossiers
|
|
98
|
+
valid_folders = []
|
|
99
|
+
for name in os.listdir(in_dir):
|
|
100
|
+
full_path = os.path.join(in_dir, name)
|
|
101
|
+
if os.path.isdir(full_path):
|
|
102
|
+
mail_ok_path = os.path.join(full_path, "mail.ok")
|
|
103
|
+
if os.path.isfile(mail_ok_path):
|
|
104
|
+
valid_folders.append(full_path.replace("\\","/"))
|
|
105
|
+
|
|
106
|
+
return valid_folders
|
|
107
|
+
|
|
108
|
+
def send_nothing_to_do(self):
|
|
109
|
+
# Définir une variable texte comme méta-attribut
|
|
110
|
+
text_meta = StringVariable("nothing to do")
|
|
111
|
+
|
|
112
|
+
# Créer un domaine sans variables principales, avec une méta
|
|
113
|
+
domain = Domain([], metas=[text_meta])
|
|
114
|
+
|
|
115
|
+
# Créer la table avec Table.from_list
|
|
116
|
+
data_table = Table.from_list(domain, [["nothing"]])
|
|
117
|
+
self.Outputs.data_out_nothing_to_do.send(data_table)
|
|
118
|
+
|
|
119
|
+
def lire_fichier_txt_mail_and_parse(self,nom_du_fichier):
|
|
120
|
+
try:
|
|
121
|
+
# vba enregistre en ansi
|
|
122
|
+
with open(nom_du_fichier, 'r', encoding='cp1252') as fichier:
|
|
123
|
+
texte = fichier.read()
|
|
124
|
+
except FileNotFoundError:
|
|
125
|
+
print(f"Le fichier '{nom_du_fichier}' n'a pas été trouvé.")
|
|
126
|
+
return None
|
|
127
|
+
except Exception as e:
|
|
128
|
+
print(f"Une erreur s'est produite : {e}")
|
|
129
|
+
return None
|
|
130
|
+
|
|
131
|
+
# Utilisation d'une expression régulière pour trouver toutes les lignes commençant par '#$'
|
|
132
|
+
pattern = r'^\#\$(.+?) : (.*)$'
|
|
133
|
+
|
|
134
|
+
# Recherche de tous les matches dans le texte, en utilisant un flag MULTILINE
|
|
135
|
+
matches = re.findall(pattern, texte, re.MULTILINE)
|
|
136
|
+
|
|
137
|
+
# Création d'un dictionnaire pour stocker les résultats
|
|
138
|
+
resultats = {}
|
|
139
|
+
|
|
140
|
+
for cle, valeur in matches:
|
|
141
|
+
resultats[cle] = valeur
|
|
142
|
+
|
|
143
|
+
return resultats
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
# def run(self):
|
|
147
|
+
# rows = []
|
|
148
|
+
# for folder in self.valid_folders:
|
|
149
|
+
# mail_path = os.path.join(folder, "mail.txt")
|
|
150
|
+
# with open(mail_path, 'r', encoding='cp1252') as f:
|
|
151
|
+
# content = f.read()
|
|
152
|
+
# pj_folder = os.path.join(folder, "pj")
|
|
153
|
+
# rows.append([mail_path, content, pj_folder])
|
|
154
|
+
#
|
|
155
|
+
# var_folder = StringVariable("Mail - path")
|
|
156
|
+
# var_content = StringVariable("Mail - content")
|
|
157
|
+
# var_attachments = StringVariable("Attachments path")
|
|
158
|
+
# domain = Domain([], metas=[var_folder, var_content, var_attachments])
|
|
159
|
+
# out_data = Table.from_list(domain=domain, rows=rows)
|
|
160
|
+
#
|
|
161
|
+
# self.Outputs.data.send(out_data)
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
def run(self):
|
|
165
|
+
# Définir les variables de texte
|
|
166
|
+
var_mail_path = StringVariable("Mail path")
|
|
167
|
+
var_pj_path = StringVariable("Attachments")
|
|
168
|
+
|
|
169
|
+
# Définir le domaine avec deux colonnes texte
|
|
170
|
+
# domain = Domain([], metas=[var_mail_path, var_pj_path])
|
|
171
|
+
|
|
172
|
+
# Construire les lignes de données
|
|
173
|
+
rows = []
|
|
174
|
+
for idx,folder in enumerate(self.valid_folders):
|
|
175
|
+
# Chemin vers mail.txt
|
|
176
|
+
mail_path = os.path.join(folder, "mail.txt").replace("\\", "/")
|
|
177
|
+
pj_path = os.path.join(folder, "pj").replace("\\", "/")
|
|
178
|
+
|
|
179
|
+
# Lecture du contenu du mail
|
|
180
|
+
detail = self.lire_fichier_txt_mail_and_parse(mail_path)
|
|
181
|
+
renamed = {equivalence.get(k, k): v for k, v in detail.items()}
|
|
182
|
+
if detail is None:
|
|
183
|
+
self.error("error reading " + mail_path)
|
|
184
|
+
return
|
|
185
|
+
|
|
186
|
+
# Ajout des éléments à la row
|
|
187
|
+
row = [mail_path, pj_path] + list(renamed.values())
|
|
188
|
+
rows.append(row)
|
|
189
|
+
|
|
190
|
+
# On utilise detail du dernier mail analysé, qui devrait être le même pour tous mails
|
|
191
|
+
new_metas = [var_mail_path, var_pj_path] + [Orange.data.StringVariable(key) for key in list(renamed.keys())]
|
|
192
|
+
dom = Orange.data.Domain([], [], metas=new_metas)
|
|
193
|
+
out_data = Table.from_list(domain=dom, rows=rows)
|
|
194
|
+
|
|
195
|
+
self.Outputs.data.send(out_data)
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
def post_initialized(self):
|
|
199
|
+
pass
|
|
200
|
+
|
|
201
|
+
if __name__ == "__main__":
|
|
202
|
+
app = QApplication(sys.argv)
|
|
203
|
+
data = Orange.data.Table(r"C:\Users\lucas\Downloads\input.tab")
|
|
204
|
+
my_widget = OWMailLoader()
|
|
205
|
+
my_widget.show()
|
|
206
|
+
my_widget.set_data(data)
|
|
207
|
+
app.exec_()
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import sys
|
|
3
|
+
# from Orange.data import Domain, StringVariable, Table
|
|
4
|
+
import Orange.data
|
|
5
|
+
from AnyQt.QtWidgets import QApplication
|
|
6
|
+
from Orange.widgets import widget
|
|
7
|
+
from Orange.widgets.utils.signals import Input, Output
|
|
8
|
+
|
|
9
|
+
if "site-packages/Orange/widgets" in os.path.dirname(os.path.abspath(__file__)).replace("\\", "/"):
|
|
10
|
+
from Orange.widgets.orangecontrib.AAIT.utils.import_uic import uic
|
|
11
|
+
from Orange.widgets.orangecontrib.AAIT.utils.initialize_from_ini import apply_modification_from_python_file
|
|
12
|
+
else:
|
|
13
|
+
from orangecontrib.AAIT.utils.import_uic import uic
|
|
14
|
+
from orangecontrib.AAIT.utils.initialize_from_ini import apply_modification_from_python_file
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@apply_modification_from_python_file(filepath_original_widget=__file__)
|
|
18
|
+
class OWMailSender(widget.OWWidget):
|
|
19
|
+
name = "OWMailSender"
|
|
20
|
+
description = "Send a mail from AAIT format"
|
|
21
|
+
icon = ""
|
|
22
|
+
icon = "icons/mail_writer.png"
|
|
23
|
+
if "site-packages/Orange/widgets" in os.path.dirname(os.path.abspath(__file__)).replace("\\", "/"):
|
|
24
|
+
icon = "icons_dev/mail_writer.png"
|
|
25
|
+
gui = os.path.join(os.path.dirname(os.path.abspath(__file__)), "designer/owmailsender.ui")
|
|
26
|
+
want_control_area = False
|
|
27
|
+
priority = 9999
|
|
28
|
+
|
|
29
|
+
class Inputs:
|
|
30
|
+
data = Input("Data", Orange.data.Table)
|
|
31
|
+
|
|
32
|
+
class Outputs:
|
|
33
|
+
data = Output("Data", Orange.data.Table)
|
|
34
|
+
|
|
35
|
+
@Inputs.data
|
|
36
|
+
def set_data(self, in_data):
|
|
37
|
+
self.data = in_data
|
|
38
|
+
if self.autorun:
|
|
39
|
+
self.run()
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def __init__(self):
|
|
43
|
+
super().__init__()
|
|
44
|
+
# Qt Management
|
|
45
|
+
self.valid_folders=[]
|
|
46
|
+
self.can_run = True
|
|
47
|
+
self.setFixedWidth(700)
|
|
48
|
+
self.setFixedHeight(500)
|
|
49
|
+
uic.loadUi(self.gui, self)
|
|
50
|
+
|
|
51
|
+
# # Data Management
|
|
52
|
+
self.data = None
|
|
53
|
+
self.thread = None
|
|
54
|
+
self.autorun = True
|
|
55
|
+
|
|
56
|
+
# Custom updates
|
|
57
|
+
self.post_initialized()
|
|
58
|
+
|
|
59
|
+
def run(self):
|
|
60
|
+
self.error("")
|
|
61
|
+
if self.data is None:
|
|
62
|
+
return
|
|
63
|
+
|
|
64
|
+
# TODO : Rajouter le content du mail original ?
|
|
65
|
+
domain_requirements = ["Sender", "Receiver", "Copy", "Priority", "Title", "Answer"]
|
|
66
|
+
for name in domain_requirements:
|
|
67
|
+
if not name in self.data.domain:
|
|
68
|
+
self.error(f'You need a column "{name}" in your input data.')
|
|
69
|
+
return
|
|
70
|
+
|
|
71
|
+
for row in self.data:
|
|
72
|
+
mail_path = row["Mail path"].value
|
|
73
|
+
# TODO : que faire si out_dir_path existe déjà ? pour le moment ça le remplacera juste, est-ce qu'on veut un warning ?
|
|
74
|
+
out_dir_path = os.path.dirname(mail_path)
|
|
75
|
+
out_mail_path = os.path.join(out_dir_path, "mail.txt")
|
|
76
|
+
out_mail_path_ok = os.path.join(out_dir_path, "mail.ok")
|
|
77
|
+
os.makedirs(out_dir_path, exist_ok=True)
|
|
78
|
+
response_content = self.format_response(row)
|
|
79
|
+
with open(out_mail_path, "w", encoding="utf-8") as f:
|
|
80
|
+
f.write(response_content)
|
|
81
|
+
with open(out_mail_path_ok, "w", encoding="utf-8") as f:
|
|
82
|
+
f.write(response_content)
|
|
83
|
+
self.Outputs.data.send(self.data)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def format_response(self, row):
|
|
87
|
+
"""
|
|
88
|
+
Formats metadata from an Orange Data Table row into a structured text block.
|
|
89
|
+
|
|
90
|
+
Extracts specific fields (Receiver, Sender, Copy, Priority, Title, Answer) from the given row,
|
|
91
|
+
maps them to standardized tags (eme, des, cop, pri, tit, txt), and returns a string formatted
|
|
92
|
+
in the style of metadata headers (e.g., "#$eme : value").
|
|
93
|
+
|
|
94
|
+
Parameters:
|
|
95
|
+
row (Orange.data.Instance): A single row from an Orange Data Table.
|
|
96
|
+
|
|
97
|
+
Returns:
|
|
98
|
+
str: A formatted string representing the metadata of the row, ready to be saved or processed.
|
|
99
|
+
"""
|
|
100
|
+
# Gather the metadata from the row instance
|
|
101
|
+
sender = self.safe_get(row, "Sender")
|
|
102
|
+
receiver = self.safe_get(row, "Receiver")
|
|
103
|
+
copy = self.safe_get(row, "Copy")
|
|
104
|
+
priority = self.safe_get(row, "Priority")
|
|
105
|
+
title = self.safe_get(row, "Title")
|
|
106
|
+
answer = self.safe_get(row, "Answer")
|
|
107
|
+
|
|
108
|
+
# Format the metadata with proper prefixes
|
|
109
|
+
# TODO : ajouter la gestion du content original !
|
|
110
|
+
metadata = {
|
|
111
|
+
"eme": sender,
|
|
112
|
+
"des": receiver,
|
|
113
|
+
"cop": copy,
|
|
114
|
+
"pri": priority,
|
|
115
|
+
"tit": title,
|
|
116
|
+
"txt": answer
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
# Build the text content as a string
|
|
120
|
+
txt_content = ""
|
|
121
|
+
for key, value in metadata.items():
|
|
122
|
+
line = f"#${key} : {value if value is not None else ''}\n"
|
|
123
|
+
txt_content += line
|
|
124
|
+
return txt_content
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def safe_get(self, row, name):
|
|
128
|
+
"""
|
|
129
|
+
Safely retrieves the value of a given column from a row in an Orange Data Table.
|
|
130
|
+
|
|
131
|
+
Parameters:
|
|
132
|
+
row (Orange.data.Instance): A single row from an Orange Table.
|
|
133
|
+
name (str): The name of the column to retrieve.
|
|
134
|
+
|
|
135
|
+
Returns:
|
|
136
|
+
The value of the column if it exists in the table domain, otherwise "Empty".
|
|
137
|
+
"""
|
|
138
|
+
return row[name].value if name in self.data.domain else "Empty"
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def post_initialized(self):
|
|
142
|
+
pass
|
|
143
|
+
|
|
144
|
+
if __name__ == "__main__":
|
|
145
|
+
app = QApplication(sys.argv)
|
|
146
|
+
data = Orange.data.Table("C:/toto_ta_ta_titi/input.tab")
|
|
147
|
+
my_widget = OWMailSender()
|
|
148
|
+
my_widget.show()
|
|
149
|
+
my_widget.set_data(data)
|
|
150
|
+
app.exec_()
|
|
@@ -0,0 +1,59 @@
|
|
|
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>732</width>
|
|
10
|
+
<height>472</height>
|
|
11
|
+
</rect>
|
|
12
|
+
</property>
|
|
13
|
+
<property name="windowTitle">
|
|
14
|
+
<string>Export markdown</string>
|
|
15
|
+
</property>
|
|
16
|
+
<widget class="QLabel" name="Description">
|
|
17
|
+
<property name="geometry">
|
|
18
|
+
<rect>
|
|
19
|
+
<x>60</x>
|
|
20
|
+
<y>190</y>
|
|
21
|
+
<width>611</width>
|
|
22
|
+
<height>81</height>
|
|
23
|
+
</rect>
|
|
24
|
+
</property>
|
|
25
|
+
<property name="sizePolicy">
|
|
26
|
+
<sizepolicy hsizetype="Maximum" vsizetype="Expanding">
|
|
27
|
+
<horstretch>0</horstretch>
|
|
28
|
+
<verstretch>0</verstretch>
|
|
29
|
+
</sizepolicy>
|
|
30
|
+
</property>
|
|
31
|
+
<property name="font">
|
|
32
|
+
<font>
|
|
33
|
+
<pointsize>8</pointsize>
|
|
34
|
+
</font>
|
|
35
|
+
</property>
|
|
36
|
+
<property name="text">
|
|
37
|
+
<string><html><head/><body><p align="justify">This widget save the markdown from the column &quot;content&quot; in one of the mentionned extension (pdf, docx, pptx).</p></body></html></string>
|
|
38
|
+
</property>
|
|
39
|
+
<property name="wordWrap">
|
|
40
|
+
<bool>true</bool>
|
|
41
|
+
</property>
|
|
42
|
+
</widget>
|
|
43
|
+
<widget class="QPushButton" name="saveButton">
|
|
44
|
+
<property name="geometry">
|
|
45
|
+
<rect>
|
|
46
|
+
<x>400</x>
|
|
47
|
+
<y>380</y>
|
|
48
|
+
<width>291</width>
|
|
49
|
+
<height>51</height>
|
|
50
|
+
</rect>
|
|
51
|
+
</property>
|
|
52
|
+
<property name="text">
|
|
53
|
+
<string>Save markdown (pdf, docx, pptx)</string>
|
|
54
|
+
</property>
|
|
55
|
+
</widget>
|
|
56
|
+
</widget>
|
|
57
|
+
<resources/>
|
|
58
|
+
<connections/>
|
|
59
|
+
</ui>
|
|
@@ -0,0 +1,32 @@
|
|
|
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>732</width>
|
|
10
|
+
<height>472</height>
|
|
11
|
+
</rect>
|
|
12
|
+
</property>
|
|
13
|
+
<property name="windowTitle">
|
|
14
|
+
<string>Speech to Text</string>
|
|
15
|
+
</property>
|
|
16
|
+
<widget class="QLabel" name="label">
|
|
17
|
+
<property name="geometry">
|
|
18
|
+
<rect>
|
|
19
|
+
<x>200</x>
|
|
20
|
+
<y>130</y>
|
|
21
|
+
<width>261</width>
|
|
22
|
+
<height>41</height>
|
|
23
|
+
</rect>
|
|
24
|
+
</property>
|
|
25
|
+
<property name="text">
|
|
26
|
+
<string>Read "Mail path" column</string>
|
|
27
|
+
</property>
|
|
28
|
+
</widget>
|
|
29
|
+
</widget>
|
|
30
|
+
<resources/>
|
|
31
|
+
<connections/>
|
|
32
|
+
</ui>
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -36,7 +36,7 @@ class CustomInstall(install):
|
|
|
36
36
|
|
|
37
37
|
# Configuration
|
|
38
38
|
NAME = "io4it"
|
|
39
|
-
VERSION = "1.0.1"
|
|
39
|
+
VERSION = "1.0.1.1"
|
|
40
40
|
|
|
41
41
|
INSTALL_REQUIRES = [
|
|
42
42
|
"boto3",
|
|
@@ -49,6 +49,8 @@ INSTALL_REQUIRES = [
|
|
|
49
49
|
"pyannote-core",
|
|
50
50
|
"wave",
|
|
51
51
|
"scikit-learn",
|
|
52
|
+
"pylatexenc",
|
|
53
|
+
"docopt",
|
|
52
54
|
]
|
|
53
55
|
|
|
54
56
|
AUTHOR = ""
|
|
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
|