myl 0.8.13__py3-none-any.whl → 0.9.0__py3-none-any.whl
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.
- {myl-0.8.13.dist-info → myl-0.9.0.dist-info}/METADATA +1 -1
- myl-0.9.0.dist-info/RECORD +7 -0
- myl.py +329 -158
- myl-0.8.13.dist-info/RECORD +0 -7
- {myl-0.8.13.dist-info → myl-0.9.0.dist-info}/LICENSE +0 -0
- {myl-0.8.13.dist-info → myl-0.9.0.dist-info}/WHEEL +0 -0
- {myl-0.8.13.dist-info → myl-0.9.0.dist-info}/entry_points.txt +0 -0
- {myl-0.8.13.dist-info → myl-0.9.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,7 @@
|
|
1
|
+
myl.py,sha256=EthLDnMEB9lqE0T0em1DaUE9oOPHMm43Ng2AyBTCDTc,13680
|
2
|
+
myl-0.9.0.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
3
|
+
myl-0.9.0.dist-info/METADATA,sha256=ghRv6c27QA4-RCYNTqeG5Yrg3-0rSVltMQBmPbJuadY,43317
|
4
|
+
myl-0.9.0.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
|
5
|
+
myl-0.9.0.dist-info/entry_points.txt,sha256=q6nr0Kzim7JzreXQE3BTU4asLh2sx5-D0w1yLBOcHxc,33
|
6
|
+
myl-0.9.0.dist-info/top_level.txt,sha256=Wn88OJVVWyYSsKVoqzlHXxfFxh5IbrJ_Yw-ldNLe7Po,4
|
7
|
+
myl-0.9.0.dist-info/RECORD,,
|
myl.py
CHANGED
@@ -2,13 +2,20 @@
|
|
2
2
|
# coding: utf-8
|
3
3
|
|
4
4
|
import argparse
|
5
|
-
import html2text
|
6
|
-
import json
|
7
5
|
import logging
|
8
6
|
import ssl
|
9
7
|
import sys
|
8
|
+
from json import dumps as json_dumps
|
10
9
|
|
11
|
-
import
|
10
|
+
import html2text
|
11
|
+
from imap_tools.consts import MailMessageFlags
|
12
|
+
from imap_tools.mailbox import (
|
13
|
+
BaseMailBox,
|
14
|
+
MailBox,
|
15
|
+
MailBoxTls,
|
16
|
+
MailBoxUnencrypted,
|
17
|
+
)
|
18
|
+
from imap_tools.query import AND
|
12
19
|
from myldiscovery import autodiscover
|
13
20
|
from rich import print, print_json
|
14
21
|
from rich.console import Console
|
@@ -23,13 +30,88 @@ GMAIL_SENT_FOLDER = "[Gmail]/Sent Mail"
|
|
23
30
|
# GMAIL_ALL_FOLDER = "[Gmail]/All Mail"
|
24
31
|
|
25
32
|
|
33
|
+
class MissingServerException(Exception):
|
34
|
+
pass
|
35
|
+
|
36
|
+
|
26
37
|
def error_msg(msg):
|
27
38
|
print(f"[red]{msg}[/red]", file=sys.stderr)
|
28
39
|
|
29
40
|
|
41
|
+
def mail_to_dict(msg, date_format="%Y-%m-%d %H:%M:%S"):
|
42
|
+
return {
|
43
|
+
"uid": msg.uid,
|
44
|
+
"subject": msg.subject,
|
45
|
+
"from": msg.from_,
|
46
|
+
"to": msg.to,
|
47
|
+
"date": msg.date.strftime(date_format),
|
48
|
+
"timestamp": str(int(msg.date.timestamp())),
|
49
|
+
"unread": mail_is_unread(msg),
|
50
|
+
"flags": msg.flags,
|
51
|
+
"content": {
|
52
|
+
"raw": msg.obj.as_string(),
|
53
|
+
"html": msg.html,
|
54
|
+
"text": msg.text,
|
55
|
+
},
|
56
|
+
"attachments": msg.attachments,
|
57
|
+
}
|
58
|
+
|
59
|
+
|
60
|
+
def mail_to_json(msg, date_format="%Y-%m-%d %H:%M:%S"):
|
61
|
+
return json_dumps(mail_to_dict(msg, date_format))
|
62
|
+
|
63
|
+
|
64
|
+
def mail_is_unread(msg):
|
65
|
+
return MailMessageFlags.SEEN not in msg.flags
|
66
|
+
|
67
|
+
|
30
68
|
def parse_args():
|
31
69
|
parser = argparse.ArgumentParser()
|
32
|
-
parser.
|
70
|
+
subparsers = parser.add_subparsers(
|
71
|
+
dest="command", help="Available commands"
|
72
|
+
)
|
73
|
+
|
74
|
+
# Default command: list all emails
|
75
|
+
subparsers.add_parser("list", help="List all emails")
|
76
|
+
|
77
|
+
# Get/show email command
|
78
|
+
get_parser = subparsers.add_parser(
|
79
|
+
"get", help="Retrieve a specific email or attachment"
|
80
|
+
)
|
81
|
+
get_parser.add_argument("MAILID", help="Mail ID to fetch", type=int)
|
82
|
+
get_parser.add_argument(
|
83
|
+
"ATTACHMENT",
|
84
|
+
help="Name of the attachment to fetch",
|
85
|
+
nargs="?",
|
86
|
+
default=None,
|
87
|
+
)
|
88
|
+
|
89
|
+
# Delete email command
|
90
|
+
delete_parser = subparsers.add_parser("delete", help="Delete an email")
|
91
|
+
delete_parser.add_argument(
|
92
|
+
"MAILIDS", help="Mail ID(s) to delete", type=int, nargs="+"
|
93
|
+
)
|
94
|
+
|
95
|
+
# Mark email as read/unread
|
96
|
+
mark_read_parser = subparsers.add_parser(
|
97
|
+
"read", help="mark an email as read"
|
98
|
+
)
|
99
|
+
mark_read_parser.add_argument(
|
100
|
+
"MAILIDS", help="Mail ID(s) to mark as read", type=int, nargs="+"
|
101
|
+
)
|
102
|
+
mark_unread_parser = subparsers.add_parser(
|
103
|
+
"unread", help="mark an email as unread"
|
104
|
+
)
|
105
|
+
mark_unread_parser.add_argument(
|
106
|
+
"MAILIDS", help="Mail ID(s) to mark as unread", type=int, nargs="+"
|
107
|
+
)
|
108
|
+
|
109
|
+
# Optional arguments
|
110
|
+
parser.add_argument(
|
111
|
+
"-d", "--debug", help="Enable debug mode", action="store_true"
|
112
|
+
)
|
113
|
+
|
114
|
+
# IMAP connection settings
|
33
115
|
parser.add_argument(
|
34
116
|
"-s", "--server", help="IMAP server address", required=False
|
35
117
|
)
|
@@ -45,7 +127,7 @@ def parse_args():
|
|
45
127
|
"--auto",
|
46
128
|
help="Autodiscovery of the required server and port",
|
47
129
|
action="store_true",
|
48
|
-
default=
|
130
|
+
default=True,
|
49
131
|
)
|
50
132
|
parser.add_argument(
|
51
133
|
"-P", "--port", help="IMAP server port", default=IMAP_PORT
|
@@ -60,16 +142,8 @@ def parse_args():
|
|
60
142
|
action="store_true",
|
61
143
|
default=False,
|
62
144
|
)
|
63
|
-
|
64
|
-
|
65
|
-
"--count",
|
66
|
-
help="Number of messages to fetch",
|
67
|
-
default=10,
|
68
|
-
type=int,
|
69
|
-
)
|
70
|
-
parser.add_argument(
|
71
|
-
"-m", "--mark-seen", help="Mark seen", action="store_true"
|
72
|
-
)
|
145
|
+
|
146
|
+
# Credentials
|
73
147
|
parser.add_argument(
|
74
148
|
"-u", "--username", help="IMAP username", required=True
|
75
149
|
)
|
@@ -80,9 +154,32 @@ def parse_args():
|
|
80
154
|
help="IMAP password (file path)",
|
81
155
|
type=argparse.FileType("r"),
|
82
156
|
)
|
157
|
+
|
158
|
+
# Display preferences
|
159
|
+
parser.add_argument(
|
160
|
+
"-c",
|
161
|
+
"--count",
|
162
|
+
help="Number of messages to fetch",
|
163
|
+
default=10,
|
164
|
+
type=int,
|
165
|
+
)
|
83
166
|
parser.add_argument(
|
84
167
|
"-t", "--no-title", help="Do not show title", action="store_true"
|
85
168
|
)
|
169
|
+
parser.add_argument(
|
170
|
+
"--date-format", help="Date format", default="%H:%M %d/%m/%Y"
|
171
|
+
)
|
172
|
+
|
173
|
+
# IMAP actions
|
174
|
+
parser.add_argument(
|
175
|
+
"-m",
|
176
|
+
"--mark-seen",
|
177
|
+
help="Mark seen",
|
178
|
+
action="store_true",
|
179
|
+
default=False,
|
180
|
+
)
|
181
|
+
|
182
|
+
# Email filtering
|
86
183
|
parser.add_argument("-f", "--folder", help="IMAP folder", default="INBOX")
|
87
184
|
parser.add_argument(
|
88
185
|
"--sent",
|
@@ -90,7 +187,21 @@ def parse_args():
|
|
90
187
|
action="store_true",
|
91
188
|
)
|
92
189
|
parser.add_argument("-S", "--search", help="Search string", default="ALL")
|
93
|
-
parser.add_argument(
|
190
|
+
parser.add_argument(
|
191
|
+
"--unread",
|
192
|
+
help="Limit to unread emails",
|
193
|
+
action="store_true",
|
194
|
+
default=False,
|
195
|
+
)
|
196
|
+
|
197
|
+
# Output preferences
|
198
|
+
parser.add_argument(
|
199
|
+
"-H",
|
200
|
+
"--html",
|
201
|
+
help="Show HTML email",
|
202
|
+
action="store_true",
|
203
|
+
default=False,
|
204
|
+
)
|
94
205
|
parser.add_argument(
|
95
206
|
"-j",
|
96
207
|
"--json",
|
@@ -105,24 +216,11 @@ def parse_args():
|
|
105
216
|
action="store_true",
|
106
217
|
default=False,
|
107
218
|
)
|
108
|
-
parser.add_argument("MAILID", help="Mail ID to fetch", nargs="?")
|
109
|
-
parser.add_argument(
|
110
|
-
"ATTACHMENT", help="Name of the attachment to fetch", nargs="?"
|
111
|
-
)
|
112
219
|
|
113
220
|
return parser.parse_args()
|
114
221
|
|
115
222
|
|
116
|
-
def
|
117
|
-
console = Console()
|
118
|
-
args = parse_args()
|
119
|
-
logging.basicConfig(
|
120
|
-
format="%(message)s",
|
121
|
-
handlers=[RichHandler(console=console)],
|
122
|
-
level=logging.DEBUG if args.debug else logging.INFO,
|
123
|
-
)
|
124
|
-
LOGGER.debug(args)
|
125
|
-
|
223
|
+
def mb_connect(console, args) -> BaseMailBox:
|
126
224
|
imap_password = args.password or (
|
127
225
|
args.password_file and args.password_file.read()
|
128
226
|
)
|
@@ -143,12 +241,13 @@ def main():
|
|
143
241
|
args.username,
|
144
242
|
password=imap_password,
|
145
243
|
insecure=args.insecure,
|
146
|
-
).get("imap")
|
244
|
+
).get("imap", {})
|
147
245
|
except Exception:
|
148
246
|
error_msg("Failed to autodiscover IMAP settings")
|
149
247
|
if args.debug:
|
150
248
|
console.print_exception(show_locals=True)
|
151
|
-
|
249
|
+
raise
|
250
|
+
|
152
251
|
LOGGER.debug(f"Discovered settings: {settings})")
|
153
252
|
args.server = settings.get("server")
|
154
253
|
args.port = settings.get("port", IMAP_PORT)
|
@@ -166,11 +265,87 @@ def main():
|
|
166
265
|
"- set --google if you are using a Gmail account\n"
|
167
266
|
"- use --auto to attempt autodiscovery"
|
168
267
|
)
|
169
|
-
|
268
|
+
raise MissingServerException()
|
269
|
+
|
270
|
+
ssl_context = ssl.create_default_context()
|
271
|
+
if args.insecure:
|
272
|
+
ssl_context.check_hostname = False
|
273
|
+
ssl_context.verify_mode = ssl.CERT_NONE
|
274
|
+
|
275
|
+
mb_kwargs = {"host": args.server, "port": args.port}
|
276
|
+
if args.ssl:
|
277
|
+
mb = MailBox
|
278
|
+
mb_kwargs["ssl_context"] = ssl_context
|
279
|
+
elif args.starttls:
|
280
|
+
mb = MailBoxTls
|
281
|
+
mb_kwargs["ssl_context"] = ssl_context
|
282
|
+
else:
|
283
|
+
mb = MailBoxUnencrypted
|
284
|
+
|
285
|
+
mailbox = mb(**mb_kwargs)
|
286
|
+
mailbox.login(args.username, imap_password, args.folder)
|
287
|
+
return mailbox
|
288
|
+
|
289
|
+
|
290
|
+
def display_single_mail(
|
291
|
+
mailbox: BaseMailBox,
|
292
|
+
mail_id: int,
|
293
|
+
attachment: str | None = None,
|
294
|
+
mark_seen: bool = False,
|
295
|
+
raw: bool = False,
|
296
|
+
html: bool = False,
|
297
|
+
json: bool = False,
|
298
|
+
):
|
299
|
+
LOGGER.debug("Fetch mail %s", mail_id)
|
300
|
+
msg = next(mailbox.fetch(f"UID {mail_id}", mark_seen=mark_seen))
|
301
|
+
LOGGER.debug("Fetched mail %s", msg)
|
302
|
+
|
303
|
+
if attachment:
|
304
|
+
for att in msg.attachments:
|
305
|
+
if att.filename == attachment:
|
306
|
+
sys.stdout.buffer.write(att.payload)
|
307
|
+
return 0
|
308
|
+
print(
|
309
|
+
f"attachment {attachment} not found",
|
310
|
+
file=sys.stderr,
|
311
|
+
)
|
312
|
+
return 1
|
313
|
+
|
314
|
+
if html:
|
315
|
+
output = msg.text
|
316
|
+
if raw:
|
317
|
+
output = msg.html
|
318
|
+
else:
|
319
|
+
output = html2text.html2text(msg.html)
|
320
|
+
print(output)
|
321
|
+
elif raw:
|
322
|
+
print(msg.obj.as_string())
|
323
|
+
return 0
|
324
|
+
elif json:
|
325
|
+
print_json(mail_to_json(msg))
|
326
|
+
return 0
|
327
|
+
else:
|
328
|
+
print(msg.text)
|
170
329
|
|
330
|
+
for att in msg.attachments:
|
331
|
+
print(f"📎 Attachment: {att.filename}", file=sys.stderr)
|
332
|
+
return 0
|
333
|
+
|
334
|
+
|
335
|
+
def display_emails(
|
336
|
+
mailbox,
|
337
|
+
console,
|
338
|
+
no_title=False,
|
339
|
+
search="ALL",
|
340
|
+
unread_only=False,
|
341
|
+
count=10,
|
342
|
+
mark_seen=False,
|
343
|
+
json=False,
|
344
|
+
date_format="%H:%M %d/%m/%Y",
|
345
|
+
):
|
171
346
|
json_data = []
|
172
347
|
table = Table(
|
173
|
-
show_header=not
|
348
|
+
show_header=not no_title,
|
174
349
|
header_style="bold",
|
175
350
|
expand=True,
|
176
351
|
show_lines=False,
|
@@ -184,138 +359,134 @@ def main():
|
|
184
359
|
table.add_column("From", style="blue", no_wrap=True, ratio=2)
|
185
360
|
table.add_column("Date", style="cyan", no_wrap=True)
|
186
361
|
|
187
|
-
|
188
|
-
|
189
|
-
ssl_context.check_hostname = False
|
190
|
-
ssl_context.verify_mode = ssl.CERT_NONE
|
362
|
+
if unread_only:
|
363
|
+
search = AND(seen=False)
|
191
364
|
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
365
|
+
for msg in mailbox.fetch(
|
366
|
+
criteria=search,
|
367
|
+
reverse=True,
|
368
|
+
bulk=True,
|
369
|
+
limit=count,
|
370
|
+
mark_seen=mark_seen,
|
371
|
+
headers_only=False, # required for attachments
|
372
|
+
):
|
373
|
+
subj_prefix = "🆕 " if mail_is_unread(msg) else ""
|
374
|
+
subj_prefix += "📎 " if len(msg.attachments) > 0 else ""
|
375
|
+
subject = (
|
376
|
+
msg.subject.replace("\n", "") if msg.subject else "<no-subject>"
|
377
|
+
)
|
378
|
+
if json:
|
379
|
+
json_data.append(mail_to_dict(msg))
|
380
|
+
else:
|
381
|
+
table.add_row(
|
382
|
+
msg.uid if msg.uid else "???",
|
383
|
+
f"{subj_prefix}{subject}",
|
384
|
+
msg.from_,
|
385
|
+
(msg.date.strftime(date_format) if msg.date else "???"),
|
386
|
+
)
|
387
|
+
if table.row_count >= count:
|
388
|
+
break
|
389
|
+
|
390
|
+
if json:
|
391
|
+
print_json(json_dumps(json_data))
|
199
392
|
else:
|
200
|
-
|
393
|
+
console.print(table)
|
394
|
+
if table.row_count == 0:
|
395
|
+
print(
|
396
|
+
"[yellow italic]No messages[/yellow italic]",
|
397
|
+
file=sys.stderr,
|
398
|
+
)
|
399
|
+
return 0
|
400
|
+
|
401
|
+
|
402
|
+
def delete_emails(mailbox: BaseMailBox, mail_ids: list):
|
403
|
+
LOGGER.warning("Deleting mails %s", mail_ids)
|
404
|
+
mailbox.delete([str(x) for x in mail_ids])
|
405
|
+
return 0
|
406
|
+
|
407
|
+
|
408
|
+
def set_seen(mailbox: BaseMailBox, mail_ids: list, value=True):
|
409
|
+
LOGGER.info(
|
410
|
+
"Marking mails as %s: %s", "read" if value else "unread", mail_ids
|
411
|
+
)
|
412
|
+
mailbox.flag(
|
413
|
+
[str(x) for x in mail_ids],
|
414
|
+
flag_set=(MailMessageFlags.SEEN),
|
415
|
+
value=value,
|
416
|
+
)
|
417
|
+
return 0
|
418
|
+
|
419
|
+
|
420
|
+
def mark_read(mailbox: BaseMailBox, mail_ids: list):
|
421
|
+
return set_seen(mailbox, mail_ids, value=True)
|
422
|
+
|
423
|
+
|
424
|
+
def mark_unread(mailbox: BaseMailBox, mail_ids: list):
|
425
|
+
return set_seen(mailbox, mail_ids, value=False)
|
426
|
+
|
427
|
+
|
428
|
+
def main() -> int:
|
429
|
+
console = Console()
|
430
|
+
args = parse_args()
|
431
|
+
logging.basicConfig(
|
432
|
+
format="%(message)s",
|
433
|
+
handlers=[RichHandler(console=console)],
|
434
|
+
level=logging.DEBUG if args.debug else logging.INFO,
|
435
|
+
)
|
436
|
+
LOGGER.debug(args)
|
201
437
|
|
202
438
|
try:
|
203
|
-
with
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
439
|
+
with mb_connect(console, args) as mailbox:
|
440
|
+
# inbox display
|
441
|
+
if args.command in ["list", None]:
|
442
|
+
return display_emails(
|
443
|
+
mailbox=mailbox,
|
444
|
+
console=console,
|
445
|
+
no_title=args.no_title,
|
446
|
+
search=args.search,
|
447
|
+
unread_only=args.unread,
|
448
|
+
count=args.count,
|
449
|
+
mark_seen=args.mark_seen,
|
450
|
+
json=args.json,
|
451
|
+
date_format=args.date_format,
|
211
452
|
)
|
212
|
-
if args.ATTACHMENT:
|
213
|
-
for att in msg.attachments:
|
214
|
-
if att.filename == args.ATTACHMENT:
|
215
|
-
sys.stdout.buffer.write(att.payload)
|
216
|
-
return 0
|
217
|
-
print(
|
218
|
-
f"Attachment {args.ATTACHMENT} not found",
|
219
|
-
file=sys.stderr,
|
220
|
-
)
|
221
|
-
return 1
|
222
|
-
else:
|
223
|
-
if args.raw:
|
224
|
-
print(msg.obj.as_string())
|
225
|
-
return 0
|
226
|
-
elif args.json:
|
227
|
-
print_json(
|
228
|
-
json.dumps(
|
229
|
-
{
|
230
|
-
"uid": msg.uid,
|
231
|
-
"subject": msg.subject,
|
232
|
-
"from": msg.from_,
|
233
|
-
"to": msg.to,
|
234
|
-
"date": msg.date.strftime(
|
235
|
-
"%Y-%m-%d %H:%M:%S"
|
236
|
-
),
|
237
|
-
"timestamp": str(
|
238
|
-
int(msg.date.timestamp())
|
239
|
-
),
|
240
|
-
"content": {
|
241
|
-
"raw": msg.obj.as_string(),
|
242
|
-
"html": msg.html,
|
243
|
-
"text": msg.text,
|
244
|
-
},
|
245
|
-
"attachments": msg.attachments,
|
246
|
-
}
|
247
|
-
)
|
248
|
-
)
|
249
|
-
return 0
|
250
|
-
|
251
|
-
output = msg.text
|
252
|
-
if args.html:
|
253
|
-
if args.raw:
|
254
|
-
output = msg.html
|
255
|
-
else:
|
256
|
-
output = html2text.html2text(msg.html)
|
257
|
-
print(output)
|
258
|
-
for att in msg.attachments:
|
259
|
-
print(
|
260
|
-
f"📎 Attachment: {att.filename}", file=sys.stderr
|
261
|
-
)
|
262
|
-
return 0
|
263
453
|
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
if msg.subject
|
276
|
-
else "<no-subject>"
|
454
|
+
# single email
|
455
|
+
# FIXME $ myl 219 raises an argparse error
|
456
|
+
elif args.command in ["get", "show", "display"]:
|
457
|
+
return display_single_mail(
|
458
|
+
mailbox=mailbox,
|
459
|
+
mail_id=args.MAILID,
|
460
|
+
attachment=args.ATTACHMENT,
|
461
|
+
mark_seen=args.mark_seen,
|
462
|
+
raw=args.raw,
|
463
|
+
html=args.html,
|
464
|
+
json=args.json,
|
277
465
|
)
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
"to": msg.to,
|
285
|
-
"date": msg.date.strftime("%Y-%m-%d %H:%M:%S"),
|
286
|
-
"timestamp": str(int(msg.date.timestamp())),
|
287
|
-
"content": {
|
288
|
-
"raw": msg.obj.as_string(),
|
289
|
-
"html": msg.html,
|
290
|
-
"text": msg.text,
|
291
|
-
},
|
292
|
-
"attachments": msg.attachments,
|
293
|
-
}
|
294
|
-
)
|
295
|
-
else:
|
296
|
-
table.add_row(
|
297
|
-
msg.uid if msg.uid else "???",
|
298
|
-
f"{subj_prefix}{subject}",
|
299
|
-
msg.from_,
|
300
|
-
(
|
301
|
-
msg.date.strftime("%H:%M %d/%m/%Y")
|
302
|
-
if msg.date
|
303
|
-
else "???"
|
304
|
-
),
|
305
|
-
)
|
306
|
-
if table.row_count >= args.count:
|
307
|
-
break
|
308
|
-
|
309
|
-
if args.json:
|
310
|
-
print_json(json.dumps(json_data))
|
311
|
-
else:
|
312
|
-
console.print(table)
|
313
|
-
if table.row_count == 0:
|
314
|
-
print(
|
315
|
-
"[yellow italic]No messages[/yellow italic]",
|
316
|
-
file=sys.stderr,
|
466
|
+
|
467
|
+
# mark emails as read
|
468
|
+
elif args.command in ["read"]:
|
469
|
+
return mark_read(
|
470
|
+
mailbox=mailbox,
|
471
|
+
mail_ids=args.MAILIDS,
|
317
472
|
)
|
318
|
-
|
473
|
+
|
474
|
+
elif args.command in ["unread"]:
|
475
|
+
return mark_unread(
|
476
|
+
mailbox=mailbox,
|
477
|
+
mail_ids=args.MAILIDS,
|
478
|
+
)
|
479
|
+
|
480
|
+
# delete email
|
481
|
+
elif args.command in ["delete", "remove"]:
|
482
|
+
return delete_emails(
|
483
|
+
mailbox=mailbox,
|
484
|
+
mail_ids=args.MAILIDS,
|
485
|
+
)
|
486
|
+
else:
|
487
|
+
error_msg(f"Unknown command: {args.command}")
|
488
|
+
return 1
|
489
|
+
|
319
490
|
except Exception:
|
320
491
|
console.print_exception(show_locals=True)
|
321
492
|
return 1
|
myl-0.8.13.dist-info/RECORD
DELETED
@@ -1,7 +0,0 @@
|
|
1
|
-
myl.py,sha256=LWpXsRzp4TJDlZo9FmvU05MapAOymm5zbDoTIM2r0JM,10715
|
2
|
-
myl-0.8.13.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
3
|
-
myl-0.8.13.dist-info/METADATA,sha256=DWSnwsMfGtJlBJxGCGXcxC6czJFQjOHCoGBGHo3qFwM,43318
|
4
|
-
myl-0.8.13.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
|
5
|
-
myl-0.8.13.dist-info/entry_points.txt,sha256=q6nr0Kzim7JzreXQE3BTU4asLh2sx5-D0w1yLBOcHxc,33
|
6
|
-
myl-0.8.13.dist-info/top_level.txt,sha256=Wn88OJVVWyYSsKVoqzlHXxfFxh5IbrJ_Yw-ldNLe7Po,4
|
7
|
-
myl-0.8.13.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|