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.
Files changed (47) hide show
  1. {io4it-1.0.1 → io4it-1.0.1.1}/PKG-INFO +3 -1
  2. {io4it-1.0.1 → io4it-1.0.1.1}/io4it.egg-info/PKG-INFO +3 -1
  3. {io4it-1.0.1 → io4it-1.0.1.1}/io4it.egg-info/SOURCES.txt +8 -0
  4. {io4it-1.0.1 → io4it-1.0.1.1}/io4it.egg-info/requires.txt +2 -0
  5. io4it-1.0.1.1/orangecontrib/IO4IT/widgets/OWExportMarkdown.py +150 -0
  6. {io4it-1.0.1 → io4it-1.0.1.1}/orangecontrib/IO4IT/widgets/OWS3Uploader.py +1 -1
  7. {io4it-1.0.1 → io4it-1.0.1.1}/orangecontrib/IO4IT/widgets/OWS3downloader.py +1 -1
  8. {io4it-1.0.1 → io4it-1.0.1.1}/orangecontrib/IO4IT/widgets/OWS3list.py +1 -1
  9. {io4it-1.0.1 → io4it-1.0.1.1}/orangecontrib/IO4IT/widgets/OWSpeechToText.py +3 -1
  10. io4it-1.0.1.1/orangecontrib/IO4IT/widgets/OWmailLoader.py +207 -0
  11. io4it-1.0.1.1/orangecontrib/IO4IT/widgets/OWmailSender.py +150 -0
  12. io4it-1.0.1.1/orangecontrib/IO4IT/widgets/designer/owexportmarkdown.ui +59 -0
  13. {io4it-1.0.1 → io4it-1.0.1.1}/orangecontrib/IO4IT/widgets/designer/owmailloader.ui +1 -1
  14. io4it-1.0.1.1/orangecontrib/IO4IT/widgets/designer/owmailsender.ui +32 -0
  15. io4it-1.0.1.1/orangecontrib/IO4IT/widgets/icons/export_md.png +0 -0
  16. io4it-1.0.1.1/orangecontrib/IO4IT/widgets/icons/mail_loader.png +0 -0
  17. io4it-1.0.1.1/orangecontrib/IO4IT/widgets/icons/mail_writer.png +0 -0
  18. {io4it-1.0.1 → io4it-1.0.1.1}/setup.py +3 -1
  19. {io4it-1.0.1 → io4it-1.0.1.1}/io4it.egg-info/dependency_links.txt +0 -0
  20. {io4it-1.0.1 → io4it-1.0.1.1}/io4it.egg-info/entry_points.txt +0 -0
  21. {io4it-1.0.1 → io4it-1.0.1.1}/io4it.egg-info/namespace_packages.txt +0 -0
  22. {io4it-1.0.1 → io4it-1.0.1.1}/io4it.egg-info/top_level.txt +0 -0
  23. {io4it-1.0.1 → io4it-1.0.1.1}/orangecontrib/IO4IT/__init__.py +0 -0
  24. {io4it-1.0.1 → io4it-1.0.1.1}/orangecontrib/IO4IT/ocr_function/__init__.py +0 -0
  25. {io4it-1.0.1 → io4it-1.0.1.1}/orangecontrib/IO4IT/ocr_function/word_converter.py +0 -0
  26. {io4it-1.0.1 → io4it-1.0.1.1}/orangecontrib/IO4IT/widgets/OWMarkdownizer.py +0 -0
  27. {io4it-1.0.1 → io4it-1.0.1.1}/orangecontrib/IO4IT/widgets/OWwordpdf2docx.py +0 -0
  28. {io4it-1.0.1 → io4it-1.0.1.1}/orangecontrib/IO4IT/widgets/__init__.py +0 -0
  29. {io4it-1.0.1 → io4it-1.0.1.1}/orangecontrib/IO4IT/widgets/designer/__init__.py +0 -0
  30. {io4it-1.0.1 → io4it-1.0.1.1}/orangecontrib/IO4IT/widgets/designer/chart.html +0 -0
  31. {io4it-1.0.1 → io4it-1.0.1.1}/orangecontrib/IO4IT/widgets/designer/nogui.ui +0 -0
  32. {io4it-1.0.1 → io4it-1.0.1.1}/orangecontrib/IO4IT/widgets/designer/ow_file_ext_selector.ui +0 -0
  33. {io4it-1.0.1 → io4it-1.0.1.1}/orangecontrib/IO4IT/widgets/designer/owspeechtotext.ui +0 -0
  34. {io4it-1.0.1 → io4it-1.0.1.1}/orangecontrib/IO4IT/widgets/designer/owvisualizationer.ui +0 -0
  35. {io4it-1.0.1 → io4it-1.0.1.1}/orangecontrib/IO4IT/widgets/designer/wordpdf2docx.ui +0 -0
  36. {io4it-1.0.1 → io4it-1.0.1.1}/orangecontrib/IO4IT/widgets/icons/__init__.py +0 -0
  37. {io4it-1.0.1 → io4it-1.0.1.1}/orangecontrib/IO4IT/widgets/icons/download.png +0 -0
  38. {io4it-1.0.1 → io4it-1.0.1.1}/orangecontrib/IO4IT/widgets/icons/file_extensor.png +0 -0
  39. {io4it-1.0.1 → io4it-1.0.1.1}/orangecontrib/IO4IT/widgets/icons/list_aws.png +0 -0
  40. {io4it-1.0.1 → io4it-1.0.1.1}/orangecontrib/IO4IT/widgets/icons/md.png +0 -0
  41. {io4it-1.0.1 → io4it-1.0.1.1}/orangecontrib/IO4IT/widgets/icons/speech_to_text.png +0 -0
  42. {io4it-1.0.1 → io4it-1.0.1.1}/orangecontrib/IO4IT/widgets/icons/upload.png +0 -0
  43. {io4it-1.0.1 → io4it-1.0.1.1}/orangecontrib/IO4IT/widgets/icons/visualizationer.png +0 -0
  44. {io4it-1.0.1 → io4it-1.0.1.1}/orangecontrib/IO4IT/widgets/icons/wordpdf2docx.png +0 -0
  45. {io4it-1.0.1 → io4it-1.0.1.1}/orangecontrib/IO4IT/widgets/icons_dev/__init__.py +0 -0
  46. {io4it-1.0.1 → io4it-1.0.1.1}/orangecontrib/__init__.py +0 -0
  47. {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
@@ -8,3 +8,5 @@ pyannote.audio
8
8
  pyannote-core
9
9
  wave
10
10
  scikit-learn
11
+ pylatexenc
12
+ docopt
@@ -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,QApplication
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,QApplication
6
+ from AnyQt.QtWidgets import QLineEdit, QFileDialog
7
7
  from Orange.data import Table
8
8
 
9
9
  class OWS3FileDownloader(OWWidget):
@@ -1,5 +1,5 @@
1
1
  import boto3
2
- from Orange.widgets.widget import OWWidget, Input, Output
2
+ from Orange.widgets.widget import OWWidget, Output
3
3
  from Orange.widgets.settings import Setting
4
4
  from Orange.widgets import gui
5
5
  from AnyQt.QtWidgets import QLineEdit, QApplication
@@ -357,4 +357,6 @@ if __name__ == "__main__":
357
357
  app = QApplication(sys.argv)
358
358
  window = OWSpeech_To_Text()
359
359
  window.show()
360
- sys.exit(app.exec_())
360
+
361
+ sys.exit(app.exec_())
362
+
@@ -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>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;justify&quot;&gt;This widget save the markdown from the column &amp;quot;content&amp;quot; in one of the mentionned extension (pdf, docx, pptx).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</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>
@@ -23,7 +23,7 @@
23
23
  </rect>
24
24
  </property>
25
25
  <property name="text">
26
- <string>Read input_dir column</string>
26
+ <string>Read "input_dir" column</string>
27
27
  </property>
28
28
  </widget>
29
29
  </widget>
@@ -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>
@@ -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