fvde commited on
Commit
4660a39
·
1 Parent(s): 3c92970

Upload folder using huggingface_hub

Browse files
src/__pycache__/gradio_app.cpython-311.pyc CHANGED
Binary files a/src/__pycache__/gradio_app.cpython-311.pyc and b/src/__pycache__/gradio_app.cpython-311.pyc differ
 
src/__pycache__/llm_utils.cpython-311.pyc CHANGED
Binary files a/src/__pycache__/llm_utils.cpython-311.pyc and b/src/__pycache__/llm_utils.cpython-311.pyc differ
 
src/__pycache__/mailing.cpython-311.pyc CHANGED
Binary files a/src/__pycache__/mailing.cpython-311.pyc and b/src/__pycache__/mailing.cpython-311.pyc differ
 
src/__pycache__/prompts.cpython-311.pyc CHANGED
Binary files a/src/__pycache__/prompts.cpython-311.pyc and b/src/__pycache__/prompts.cpython-311.pyc differ
 
src/__pycache__/send_email.cpython-311.pyc ADDED
Binary file (16.2 kB). View file
 
src/__pycache__/summarization.cpython-311.pyc CHANGED
Binary files a/src/__pycache__/summarization.cpython-311.pyc and b/src/__pycache__/summarization.cpython-311.pyc differ
 
src/gradio_app.py CHANGED
@@ -10,6 +10,7 @@ from src.summarization import (
10
  )
11
  from src.legal_implications import parallel_legal_implications
12
  from src.mailing import send_email
 
13
 
14
 
15
  def _file_render_helper(file):
@@ -118,7 +119,7 @@ def load_summary_section(llm: ChatOpenAI):
118
  subject_email_summary = gr.Textbox(
119
  label="Subject", placeholder="Enter Subject"
120
  )
121
- send_email_button = gr.Button("TEST: Open Email", interactive=False)
122
  with gr.Column(scale=3):
123
  email_instructions_summary = gr.Textbox(
124
  label="Email Instructions",
@@ -171,12 +172,11 @@ def load_summary_section(llm: ChatOpenAI):
171
 
172
  # Email button click opens the default email client and fills in the email instructions
173
  send_email_button.click(
174
- fn=send_email,
175
  inputs=[
176
- summary_output,
177
  recipiant_email_summary,
178
  subject_email_summary,
179
- email_instructions_summary,
180
  ],
181
  outputs=[],
182
  # queue=False,
 
10
  )
11
  from src.legal_implications import parallel_legal_implications
12
  from src.mailing import send_email
13
+ from src.send_email import wrap_mailto
14
 
15
 
16
  def _file_render_helper(file):
 
119
  subject_email_summary = gr.Textbox(
120
  label="Subject", placeholder="Enter Subject"
121
  )
122
+ send_email_button = gr.Button("Open Email", interactive=False)
123
  with gr.Column(scale=3):
124
  email_instructions_summary = gr.Textbox(
125
  label="Email Instructions",
 
172
 
173
  # Email button click opens the default email client and fills in the email instructions
174
  send_email_button.click(
175
+ fn=wrap_mailto,
176
  inputs=[
 
177
  recipiant_email_summary,
178
  subject_email_summary,
179
+ summary_output,
180
  ],
181
  outputs=[],
182
  # queue=False,
src/send_email.py ADDED
@@ -0,0 +1,407 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+
3
+ """Utilities for opening files or URLs in the registered default application
4
+ and for sending e-mail using the user's preferred composer.
5
+
6
+ https://stackoverflow.com/a/19779373/3211506
7
+
8
+ """
9
+
10
+ __version__ = "1.1"
11
+ __all__ = ["open", "mailto"]
12
+
13
+ import os
14
+ import sys
15
+ import webbrowser
16
+ import subprocess
17
+
18
+ from email.utils import encode_rfc2231
19
+
20
+ _controllers = {}
21
+ _open = None
22
+
23
+ fileopen = open
24
+
25
+
26
+ class BaseController(object):
27
+ """Base class for open program controllers."""
28
+
29
+ def __init__(self, name):
30
+ self.name = name
31
+
32
+ def open(self, filename):
33
+ raise NotImplementedError
34
+
35
+
36
+ class Controller(BaseController):
37
+ """Controller for a generic open program."""
38
+
39
+ def __init__(self, *args):
40
+ super(Controller, self).__init__(os.path.basename(args[0]))
41
+ self.args = list(args)
42
+
43
+ def _invoke(self, cmdline):
44
+ if sys.platform[:3] == "win":
45
+ closefds = False
46
+ startupinfo = subprocess.STARTUPINFO()
47
+ startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
48
+ else:
49
+ closefds = True
50
+ startupinfo = None
51
+
52
+ if (
53
+ os.environ.get("DISPLAY")
54
+ or sys.platform[:3] == "win"
55
+ or sys.platform == "darwin"
56
+ ):
57
+ inout = fileopen(os.devnull, "r+")
58
+ else:
59
+ # for TTY programs, we need stdin/out
60
+ inout = None
61
+
62
+ # if possible, put the child precess in separate process group,
63
+ # so keyboard interrupts don't affect child precess as well as
64
+ # Python
65
+ setsid = getattr(os, "setsid", None)
66
+ if not setsid:
67
+ setsid = getattr(os, "setpgrp", None)
68
+
69
+ pipe = subprocess.Popen(
70
+ cmdline,
71
+ stdin=inout,
72
+ stdout=inout,
73
+ stderr=inout,
74
+ close_fds=closefds,
75
+ preexec_fn=setsid,
76
+ startupinfo=startupinfo,
77
+ )
78
+
79
+ # It is assumed that this kind of tools (gnome-open, kfmclient,
80
+ # exo-open, xdg-open and open for OSX) immediately exit after lauching
81
+ # the specific application
82
+ returncode = pipe.wait()
83
+ if hasattr(self, "fixreturncode"):
84
+ returncode = self.fixreturncode(returncode)
85
+ return not returncode
86
+
87
+ def open(self, filename):
88
+ if isinstance(filename, str):
89
+ cmdline = self.args + [filename]
90
+ else:
91
+ # assume it is a sequence
92
+ cmdline = self.args + filename
93
+ try:
94
+ return self._invoke(cmdline)
95
+ except OSError:
96
+ return False
97
+
98
+
99
+ # Platform support for Windows
100
+ if sys.platform[:3] == "win":
101
+
102
+ class Start(BaseController):
103
+ """Controller for the win32 start progam through os.startfile."""
104
+
105
+ def open(self, filename):
106
+ try:
107
+ os.startfile(filename)
108
+ except WindowsError:
109
+ # [Error 22] No application is associated with the specified
110
+ # file for this operation: '<URL>'
111
+ return False
112
+ else:
113
+ return True
114
+
115
+ _controllers["windows-default"] = Start("start")
116
+ _open = _controllers["windows-default"].open
117
+
118
+
119
+ # Platform support for MacOS
120
+ elif sys.platform == "darwin":
121
+ _controllers["open"] = Controller("open")
122
+ _open = _controllers["open"].open
123
+
124
+
125
+ # Platform support for Unix
126
+ else:
127
+ import subprocess, stat
128
+
129
+ # @WARNING: use the private API of the webbrowser module
130
+ # from webbrowser import _iscommand
131
+
132
+ def _isexecutable(cmd):
133
+ if os.path.isfile(cmd):
134
+ mode = os.stat(cmd)[stat.ST_MODE]
135
+ if mode & stat.S_IXUSR or mode & stat.S_IXGRP or mode & stat.S_IXOTH:
136
+ return True
137
+ return False
138
+
139
+ def _iscommand(cmd):
140
+ """Return True if cmd is executable or can be found on the executable
141
+ search path."""
142
+ if _isexecutable(cmd):
143
+ return True
144
+
145
+ path = os.environ.get("PATH")
146
+ if not path:
147
+ return False
148
+ for d in path.split(os.pathsep):
149
+ exe = os.path.join(d, cmd)
150
+ if _isexecutable(exe):
151
+ return True
152
+ return False
153
+
154
+ class KfmClient(Controller):
155
+ """Controller for the KDE kfmclient program."""
156
+
157
+ def __init__(self, kfmclient="kfmclient"):
158
+ super(KfmClient, self).__init__(kfmclient, "exec")
159
+ self.kde_version = self.detect_kde_version()
160
+
161
+ def detect_kde_version(self):
162
+ kde_version = None
163
+ try:
164
+ info = subprocess.getoutput("kde-config --version")
165
+
166
+ for line in info.splitlines():
167
+ if line.startswith("KDE"):
168
+ kde_version = line.split(":")[-1].strip()
169
+ break
170
+ except (OSError, RuntimeError):
171
+ pass
172
+
173
+ return kde_version
174
+
175
+ def fixreturncode(self, returncode):
176
+ if returncode is not None and self.kde_version > "3.5.4":
177
+ return returncode
178
+ else:
179
+ return os.EX_OK
180
+
181
+ def detect_desktop_environment():
182
+ """Checks for known desktop environments
183
+
184
+ Return the desktop environments name, lowercase (kde, gnome, xfce)
185
+ or "generic"
186
+
187
+ """
188
+
189
+ desktop_environment = "generic"
190
+
191
+ if os.environ.get("KDE_FULL_SESSION") == "true":
192
+ desktop_environment = "kde"
193
+ elif os.environ.get("GNOME_DESKTOP_SESSION_ID"):
194
+ desktop_environment = "gnome"
195
+ else:
196
+ try:
197
+ info = subprocess.getoutput("xprop -root _DT_SAVE_MODE")
198
+ if ' = "xfce4"' in info:
199
+ desktop_environment = "xfce"
200
+ except (OSError, RuntimeError):
201
+ pass
202
+
203
+ return desktop_environment
204
+
205
+ def register_X_controllers():
206
+ if _iscommand("kfmclient"):
207
+ _controllers["kde-open"] = KfmClient()
208
+
209
+ for command in ("gnome-open", "exo-open", "xdg-open"):
210
+ if _iscommand(command):
211
+ _controllers[command] = Controller(command)
212
+
213
+ def get():
214
+ controllers_map = {
215
+ "gnome": "gnome-open",
216
+ "kde": "kde-open",
217
+ "xfce": "exo-open",
218
+ }
219
+
220
+ desktop_environment = detect_desktop_environment()
221
+
222
+ try:
223
+ controller_name = controllers_map[desktop_environment]
224
+ return _controllers[controller_name].open
225
+
226
+ except KeyError:
227
+ if "xdg-open" in _controllers:
228
+ return _controllers["xdg-open"].open
229
+ else:
230
+ return webbrowser.open
231
+
232
+ if os.environ.get("DISPLAY"):
233
+ register_X_controllers()
234
+ _open = get()
235
+
236
+
237
+ def open(filename):
238
+ """Open a file or an URL in the registered default application."""
239
+
240
+ return _open(filename)
241
+
242
+
243
+ def _fix_addersses(**kwargs):
244
+ for headername in ("address", "to", "cc", "bcc"):
245
+ try:
246
+ headervalue = kwargs[headername]
247
+ if not headervalue:
248
+ del kwargs[headername]
249
+ continue
250
+ elif not isinstance(headervalue, str):
251
+ # assume it is a sequence
252
+ headervalue = ",".join(headervalue)
253
+
254
+ except KeyError:
255
+ pass
256
+ except TypeError:
257
+ raise TypeError(
258
+ 'string or sequence expected for "%s", '
259
+ "%s found" % (headername, type(headervalue).__name__)
260
+ )
261
+ else:
262
+ translation_map = {"%": "%25", "&": "%26", "?": "%3F"}
263
+ for char, replacement in list(translation_map.items()):
264
+ headervalue = headervalue.replace(char, replacement)
265
+ kwargs[headername] = headervalue
266
+
267
+ return kwargs
268
+
269
+
270
+ def mailto_format(**kwargs):
271
+ # @TODO: implement utf8 option
272
+
273
+ kwargs = _fix_addersses(**kwargs)
274
+ parts = []
275
+ for headername in ("to", "cc", "bcc", "subject", "body"):
276
+ if headername in kwargs:
277
+ headervalue = kwargs[headername]
278
+ if not headervalue:
279
+ continue
280
+ if headername in ("address", "to", "cc", "bcc"):
281
+ parts.append("%s=%s" % (headername, headervalue))
282
+ else:
283
+ headervalue = encode_rfc2231(headervalue, charset="utf-8")[
284
+ 7:
285
+ ] # @TODO: check
286
+ parts.append("%s=%s" % (headername, headervalue))
287
+
288
+ mailto_string = "mailto:%s" % kwargs.get("address", "")
289
+ if parts:
290
+ mailto_string = "%s?%s" % (mailto_string, "&".join(parts))
291
+
292
+ return mailto_string
293
+
294
+
295
+ def wrap_mailto(recipiant_email_summary, subject_email_summary, summary_output):
296
+ return mailto(
297
+ address=recipiant_email_summary,
298
+ subject=subject_email_summary,
299
+ body=summary_output,
300
+ )
301
+
302
+
303
+ def mailto(address, to=None, cc=None, bcc=None, subject=None, body=None, attach=None):
304
+ """Send an e-mail using the user's preferred composer.
305
+
306
+ Open the user's preferred e-mail composer in order to send a mail to
307
+ address(es) that must follow the syntax of RFC822. Multiple addresses
308
+ may be provided (for address, cc and bcc parameters) as separate
309
+ arguments.
310
+
311
+ All parameters provided are used to prefill corresponding fields in
312
+ the user's e-mail composer. The user will have the opportunity to
313
+ change any of this information before actually sending the e-mail.
314
+
315
+ address - specify the destination recipient
316
+ cc - specify a recipient to be copied on the e-mail
317
+ bcc - specify a recipient to be blindly copied on the e-mail
318
+ subject - specify a subject for the e-mail
319
+ body - specify a body for the e-mail. Since the user will be able
320
+ to make changes before actually sending the e-mail, this
321
+ can be used to provide the user with a template for the
322
+ e-mail text may contain linebreaks
323
+ attach - specify an attachment for the e-mail. file must point to
324
+ an existing file (UNSUPPORTED)
325
+
326
+ """
327
+
328
+ mailto_string = mailto_format(**locals())
329
+ return open(mailto_string)
330
+
331
+
332
+ if __name__ == "__main__":
333
+ from optparse import OptionParser
334
+
335
+ version = "%%prog %s" % __version__
336
+ usage = (
337
+ "\n\n%prog FILENAME [FILENAME(s)] -- for opening files"
338
+ "\n\n%prog -m [OPTIONS] ADDRESS [ADDRESS(es)] -- for sending e-mails"
339
+ )
340
+
341
+ parser = OptionParser(usage=usage, version=version, description=__doc__)
342
+ parser.add_option(
343
+ "-m",
344
+ "--mailto",
345
+ dest="mailto_mode",
346
+ default=False,
347
+ action="store_true",
348
+ help="set mailto mode. " "If not set any other option is ignored",
349
+ )
350
+ parser.add_option(
351
+ "--cc", dest="cc", help="specify a recipient to be " "copied on the e-mail"
352
+ )
353
+ parser.add_option(
354
+ "--bcc",
355
+ dest="bcc",
356
+ help="specify a recipient to be " "blindly copied on the e-mail",
357
+ )
358
+ parser.add_option(
359
+ "--subject", dest="subject", help="specify a subject for the e-mail"
360
+ )
361
+ parser.add_option(
362
+ "--body",
363
+ dest="body",
364
+ help="specify a body for the "
365
+ "e-mail. Since the user will be able to make changes "
366
+ "before actually sending the e-mail, this can be used "
367
+ "to provide the user with a template for the e-mail "
368
+ "text may contain linebreaks",
369
+ )
370
+ parser.add_option(
371
+ "--attach",
372
+ dest="attach",
373
+ help="specify an attachment "
374
+ "for the e-mail. file must point to an existing file",
375
+ )
376
+ # breakpoint()
377
+ (options, args) = parser.parse_args()
378
+
379
+ if not args:
380
+ parser.print_usage()
381
+ parser.exit(1)
382
+
383
+ if options.mailto_mode:
384
+ if not mailto(
385
+ args,
386
+ None,
387
+ options.cc,
388
+ options.bcc,
389
+ options.subject,
390
+ options.body,
391
+ options.attach,
392
+ ):
393
+ sys.exit("Unable to open the e-mail client")
394
+ else:
395
+ for name in ("cc", "bcc", "subject", "body", "attach"):
396
+ if getattr(options, name):
397
+ parser.error(
398
+ 'The "cc", "bcc", "subject", "body" and "attach" '
399
+ "options are only accepten in mailto mode"
400
+ )
401
+ success = False
402
+ for arg in args:
403
+ if not open(arg):
404
+ print('Unable to open "%s"' % arg)
405
+ else:
406
+ success = True
407
+ sys.exit(success)