mel 3
This commit is contained in:
parent
47cdc830a0
commit
f910bd6add
|
@ -15,7 +15,7 @@
|
||||||
hide_duplicate_count = false
|
hide_duplicate_count = false
|
||||||
history_length = 20
|
history_length = 20
|
||||||
horizontal_padding = 8
|
horizontal_padding = 8
|
||||||
icon_path = /usr/share/icons/gnome/256x256/status/:/usr/share/icons/gnome/256x256/devices/
|
icon_path = /usr/share/icons/gnome/256x256/actions/:/usr/share/icons/gnome/256x256/status/:/usr/share/icons/gnome/256x256/devices/
|
||||||
icon_position = left
|
icon_position = left
|
||||||
idle_threshold = 120
|
idle_threshold = 120
|
||||||
ignore_newline = no
|
ignore_newline = no
|
||||||
|
|
292
scripts/mel
292
scripts/mel
|
@ -2,10 +2,35 @@
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Meh mail client
|
Meh mail client
|
||||||
|
A dumb Python scripts that leverages notmuch, mbsync, and msmtp
|
||||||
|
to become a fully-functional extremly-opinonated mail client.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# TODO Features
|
# TODO Features
|
||||||
|
# TODO Lockfiles for write operations on mail files (mbsync, tags→maildir operations)
|
||||||
|
# TODO OPTI Lockfile per account and process everything in parallel (if implemented, this
|
||||||
|
# should be optional since while it may speed up the mail fetching process, its multi-threading
|
||||||
|
# nature would cause a lot of cache flushes and be not very efficient on battery)
|
||||||
|
# TODO Handle true character width
|
||||||
|
# TODO IMAP IDLE watches?
|
||||||
# TODO (only then) Refactor
|
# TODO (only then) Refactor
|
||||||
|
# TODO OOP-based
|
||||||
|
# TODO Merge file with melConf
|
||||||
|
|
||||||
|
# DEBUG Small perf profiler
|
||||||
|
import time
|
||||||
|
perf_dict = dict()
|
||||||
|
perf_last = time.perf_counter()
|
||||||
|
def perfstep(name):
|
||||||
|
t = time.perf_counter()
|
||||||
|
global perf_last
|
||||||
|
global perf_dict
|
||||||
|
diff = t - perf_last
|
||||||
|
if name not in perf_dict:
|
||||||
|
perf_dict[name] = 0
|
||||||
|
perf_dict[name] += diff
|
||||||
|
perf_last = time.perf_counter()
|
||||||
|
|
||||||
|
|
||||||
import notmuch
|
import notmuch
|
||||||
import logging
|
import logging
|
||||||
|
@ -14,7 +39,6 @@ import colorama
|
||||||
import datetime
|
import datetime
|
||||||
import os
|
import os
|
||||||
import progressbar
|
import progressbar
|
||||||
import time
|
|
||||||
import argparse
|
import argparse
|
||||||
import configparser
|
import configparser
|
||||||
import base64
|
import base64
|
||||||
|
@ -23,9 +47,27 @@ import argparse
|
||||||
import xdg.BaseDirectory
|
import xdg.BaseDirectory
|
||||||
import sys
|
import sys
|
||||||
import subprocess
|
import subprocess
|
||||||
|
import html
|
||||||
|
import re
|
||||||
|
|
||||||
|
perfstep("import")
|
||||||
|
|
||||||
ACCOUNTS = dict()
|
ACCOUNTS = dict()
|
||||||
ALIASES = set()
|
ALIASES = set()
|
||||||
|
db = None
|
||||||
|
config = None
|
||||||
|
|
||||||
|
|
||||||
|
def open_database(write=False):
|
||||||
|
global db
|
||||||
|
mode = notmuch.Database.MODE.READ_WRITE if write else notmuch.Database.MODE.READ_ONLY
|
||||||
|
dbPath = os.path.realpath(os.path.expanduser(config["GENERAL"]["storage"]))
|
||||||
|
db = notmuch.Database(mode=mode, path=dbPath)
|
||||||
|
|
||||||
|
def close_database():
|
||||||
|
global db
|
||||||
|
db.close()
|
||||||
|
db = None
|
||||||
|
|
||||||
def generate_aliases():
|
def generate_aliases():
|
||||||
for name in config.sections():
|
for name in config.sections():
|
||||||
|
@ -73,26 +115,25 @@ def format_date(date):
|
||||||
else:
|
else:
|
||||||
return date.strftime('%d/%m/%y')
|
return date.strftime('%d/%m/%y')
|
||||||
|
|
||||||
def threadIdToB64(tid):
|
WIDTH_FIXED = 31
|
||||||
assert len(tid) == 16
|
|
||||||
tidInt = int(tid, 16)
|
|
||||||
tidBytes = tidInt.to_bytes(8, 'big')
|
|
||||||
tidB64 = base64.b64encode(tidBytes)
|
|
||||||
assert len(tidB64) == 12
|
|
||||||
return tidB64.decode()
|
|
||||||
|
|
||||||
WIDTH_FIXED = 30
|
|
||||||
WIDTH_RATIO_DEST_SUBJECT = 0.3
|
WIDTH_RATIO_DEST_SUBJECT = 0.3
|
||||||
|
ISATTY = sys.stdout.isatty()
|
||||||
destWidth = None
|
destWidth = None
|
||||||
subjectWidth = None
|
subjectWidth = None
|
||||||
def compute_line_format():
|
def compute_line_format():
|
||||||
|
if ISATTY:
|
||||||
columns, rows = shutil.get_terminal_size((80, 20))
|
columns, rows = shutil.get_terminal_size((80, 20))
|
||||||
remain = columns - WIDTH_FIXED - 1
|
remain = columns - WIDTH_FIXED - 1
|
||||||
global destWidth, subjectWidth
|
global destWidth, subjectWidth
|
||||||
destWidth = int(remain * WIDTH_RATIO_DEST_SUBJECT)
|
destWidth = int(remain * WIDTH_RATIO_DEST_SUBJECT)
|
||||||
subjectWidth = remain - destWidth
|
subjectWidth = remain - destWidth
|
||||||
|
else:
|
||||||
|
destWidth = None
|
||||||
|
subjectWidth = None
|
||||||
|
|
||||||
def clip_text(size, text):
|
def clip_text(size, text):
|
||||||
|
if size is None:
|
||||||
|
return text
|
||||||
l = len(text)
|
l = len(text)
|
||||||
if l == size:
|
if l == size:
|
||||||
return text
|
return text
|
||||||
|
@ -106,22 +147,28 @@ def print_msg(msg):
|
||||||
if not destWidth:
|
if not destWidth:
|
||||||
compute_line_format()
|
compute_line_format()
|
||||||
|
|
||||||
|
sep = " " if ISATTY else "\t"
|
||||||
line = ""
|
line = ""
|
||||||
tags = set(msg.get_tags())
|
tags = set(msg.get_tags())
|
||||||
mailbox, folder, state = get_location(msg)
|
mailbox, folder, state = get_location(msg)
|
||||||
|
if ISATTY:
|
||||||
line += get_mailbox_color(mailbox)
|
line += get_mailbox_color(mailbox)
|
||||||
|
|
||||||
# ID
|
# UID
|
||||||
line += threadIdToB64(msg.get_thread_id())
|
uid = None
|
||||||
# line += str(int(msg.get_thread_id(), 16))
|
for tag in tags:
|
||||||
|
if tag.startswith('tuid'):
|
||||||
|
uid = tag[4:]
|
||||||
|
assert isUID(uid), uid
|
||||||
|
line += uid
|
||||||
|
|
||||||
# Date
|
# Date
|
||||||
line += " "
|
line += sep
|
||||||
date = datetime.datetime.fromtimestamp(msg.get_date())
|
date = datetime.datetime.fromtimestamp(msg.get_date())
|
||||||
line += format_date(date)
|
line += format_date(date)
|
||||||
|
|
||||||
# Icons
|
# Icons
|
||||||
line += " "
|
line += sep
|
||||||
def tags2col1(tag1, tag2, both, first, second, none):
|
def tags2col1(tag1, tag2, both, first, second, none):
|
||||||
nonlocal line
|
nonlocal line
|
||||||
if tag1 in tags:
|
if tag1 in tags:
|
||||||
|
@ -144,20 +191,20 @@ def print_msg(msg):
|
||||||
dest = msg.get_header("to")
|
dest = msg.get_header("to")
|
||||||
else:
|
else:
|
||||||
dest = msg.get_header("from")
|
dest = msg.get_header("from")
|
||||||
line += " "
|
line += sep
|
||||||
line += clip_text(destWidth, dest)
|
line += clip_text(destWidth, dest)
|
||||||
|
|
||||||
# Subject
|
# Subject
|
||||||
line += " "
|
line += sep
|
||||||
subject = msg.get_header("subject")
|
subject = msg.get_header("subject")
|
||||||
line += clip_text(subjectWidth, subject)
|
line += clip_text(subjectWidth, subject)
|
||||||
|
|
||||||
|
if ISATTY:
|
||||||
line += colorama.Style.RESET_ALL
|
line += colorama.Style.RESET_ALL
|
||||||
print(line)
|
print(line)
|
||||||
|
|
||||||
|
|
||||||
def retag_msg(msg):
|
def retag_msg(msg):
|
||||||
msg.freeze()
|
|
||||||
mailbox, folder, state = get_location(msg)
|
mailbox, folder, state = get_location(msg)
|
||||||
|
|
||||||
# Search-friendly folder name
|
# Search-friendly folder name
|
||||||
|
@ -181,11 +228,18 @@ def retag_msg(msg):
|
||||||
tag_if('deleted', slugFolder[0] == 'TRASH')
|
tag_if('deleted', slugFolder[0] == 'TRASH')
|
||||||
tag_if('draft', slugFolder[0] == 'DRAFTS')
|
tag_if('draft', slugFolder[0] == 'DRAFTS')
|
||||||
tag_if('sent', expeditor in ALIASES)
|
tag_if('sent', expeditor in ALIASES)
|
||||||
# TODO remove unprocessed
|
tag_if('unprocessed', False)
|
||||||
|
|
||||||
|
# UID
|
||||||
|
uid = msg.get_header("X-TUID")
|
||||||
|
assert isUID(uid)
|
||||||
|
uidtag = 'tuid{}'.format(uid)
|
||||||
|
# Remove eventual others UID
|
||||||
|
for tag in tags:
|
||||||
|
if tag.startswith('tuid') and tag != uidtag:
|
||||||
|
msg.remove_tag(tag)
|
||||||
|
msg.add_tag(uidtag)
|
||||||
|
|
||||||
# Save
|
|
||||||
msg.thaw()
|
|
||||||
msg.tags_to_maildir_flags()
|
|
||||||
|
|
||||||
|
|
||||||
def extract_email(field):
|
def extract_email(field):
|
||||||
|
@ -196,23 +250,37 @@ def extract_email(field):
|
||||||
except ValueError:
|
except ValueError:
|
||||||
return field
|
return field
|
||||||
|
|
||||||
def applyMsgs(queryStr, action, *args, showProgress=False, **kwargs):
|
msg = None
|
||||||
|
def applyMsgs(queryStr, action, *args, showProgress=False, write=False, closeDb=True, **kwargs):
|
||||||
|
if db is None:
|
||||||
|
open_database(write=write)
|
||||||
|
|
||||||
log.info("Querying {}".format(queryStr))
|
log.info("Querying {}".format(queryStr))
|
||||||
query = notmuch.Query(db, queryStr)
|
query = notmuch.Query(db, queryStr)
|
||||||
query.set_sort(notmuch.Query.SORT.OLDEST_FIRST)
|
query.set_sort(notmuch.Query.SORT.OLDEST_FIRST)
|
||||||
|
|
||||||
elements = query.search_messages()
|
elements = query.search_messages()
|
||||||
|
|
||||||
if showProgress:
|
|
||||||
nbMsgs = query.count_messages()
|
nbMsgs = query.count_messages()
|
||||||
iterator = progressbar.progressbar(elements, max_value=nbMsgs)
|
|
||||||
else:
|
iterator = progressbar.progressbar(elements, max_value=nbMsgs) if showProgress else elements
|
||||||
iterator = elements
|
|
||||||
|
|
||||||
log.info("Executing {}".format(action))
|
log.info("Executing {}".format(action))
|
||||||
|
global msg
|
||||||
for msg in iterator:
|
for msg in iterator:
|
||||||
|
if write:
|
||||||
|
msg.freeze()
|
||||||
|
|
||||||
action(msg, *args, **kwargs)
|
action(msg, *args, **kwargs)
|
||||||
|
|
||||||
|
if write:
|
||||||
|
msg.thaw()
|
||||||
|
msg.tags_to_maildir_flags()
|
||||||
|
|
||||||
|
if closeDb:
|
||||||
|
close_database()
|
||||||
|
|
||||||
|
return nbMsgs
|
||||||
|
|
||||||
# applyMsgs('*', print_msg)
|
# applyMsgs('*', print_msg)
|
||||||
# applyMsgs('tag:inbox', print_msg)
|
# applyMsgs('tag:inbox', print_msg)
|
||||||
# applyMsgs('tag:spam', print_msg)
|
# applyMsgs('tag:spam', print_msg)
|
||||||
|
@ -223,6 +291,92 @@ def applyMsgs(queryStr, action, *args, showProgress=False, **kwargs):
|
||||||
# applyMsgs('tag:unprocessed', retag_msg, useProgressbar=True)
|
# applyMsgs('tag:unprocessed', retag_msg, useProgressbar=True)
|
||||||
# applyMsgs('*', retag_msg, useProgressbar=True)
|
# applyMsgs('*', retag_msg, useProgressbar=True)
|
||||||
|
|
||||||
|
# def update_polybar_status():
|
||||||
|
def update_polybar_status(*args, **kwargs):
|
||||||
|
log.info("Updating polybar status")
|
||||||
|
accountsList = sorted(ACCOUNTS.keys())
|
||||||
|
print(accountsList)
|
||||||
|
open_database()
|
||||||
|
statusArr = []
|
||||||
|
for account in accountsList:
|
||||||
|
queryStr = 'folder:/{}/ and tag:unread'.format(account)
|
||||||
|
query = notmuch.Query(db, queryStr)
|
||||||
|
nbMsgs = query.count_messages()
|
||||||
|
if nbMsgs < 1:
|
||||||
|
continue
|
||||||
|
color = config[account]['color']
|
||||||
|
statusAccStr = '%{F' + color + '}' + str(nbMsgs) + '%{F-}'
|
||||||
|
statusArr.append(statusAccStr)
|
||||||
|
close_database()
|
||||||
|
statusStr = ('_' + ' '.join(statusArr)) if len(statusArr) else '\n'
|
||||||
|
statusPath = os.path.expanduser("~/.cache/mutt/status") # TODO Better
|
||||||
|
with open(statusPath, 'w') as f:
|
||||||
|
f.write(statusStr)
|
||||||
|
# statusPath = os.path.expanduser("~/.cache/mel/polybarstatus") # TODO Better
|
||||||
|
|
||||||
|
def notify_msg(msg):
|
||||||
|
log.info("Sending notification for {}".format(msg))
|
||||||
|
subject = msg.get_header("subject")
|
||||||
|
expd = msg.get_header("from")
|
||||||
|
account, _, _ = get_location(msg)
|
||||||
|
|
||||||
|
summary = '{} (<i>{}</i>)'.format(html.escape(expd), account)
|
||||||
|
body = html.escape(subject)
|
||||||
|
cmd = ["notify-send", "-u", "low", "-i", "mail-message-new", summary, body]
|
||||||
|
print(' '.join(cmd))
|
||||||
|
subprocess.run(cmd)
|
||||||
|
|
||||||
|
|
||||||
|
def notify_all(*args, **kwargs):
|
||||||
|
open_database()
|
||||||
|
nbMsgs = applyMsgs('tag:unread and tag:unprocessed', notify_msg)
|
||||||
|
if nbMsgs > 0:
|
||||||
|
log.info("Playing notification sound ({} new message(s))".format(nbMsgs))
|
||||||
|
cmd = ["play", "-n", "synth", "sine", "E4", "sine", "A5", "remix", "1-2", "fade", "0.5", "1.2", "0.5", "2"]
|
||||||
|
subprocess.run(cmd)
|
||||||
|
close_database()
|
||||||
|
|
||||||
|
def isUID(uid):
|
||||||
|
return isinstance(uid, str) and len(uid) == 12 and re.match('^[a-zA-Z0-9+/]{12}$', uid)
|
||||||
|
|
||||||
|
# From https://stackoverflow.com/a/312464
|
||||||
|
def chunks(l, n):
|
||||||
|
"""Yield successive n-sized chunks from l."""
|
||||||
|
for i in range(0, len(l), n):
|
||||||
|
yield l[i:i + n]
|
||||||
|
|
||||||
|
def apply_msgs_input(argmessages, action, write=False):
|
||||||
|
if not len(argmessages):
|
||||||
|
fromStdin = not sys.stdin.isatty()
|
||||||
|
else:
|
||||||
|
fromStdin = len(argmessages) == 1 and argmessages == '-'
|
||||||
|
|
||||||
|
messages = list()
|
||||||
|
if fromStdin:
|
||||||
|
for line in sys.stdin:
|
||||||
|
uid = line[:12]
|
||||||
|
if not isUID(uid):
|
||||||
|
log.error("Not an UID: {}".format(uid))
|
||||||
|
continue
|
||||||
|
messages.append(uid)
|
||||||
|
else:
|
||||||
|
for uids in argmessages:
|
||||||
|
if len(uids) > 12:
|
||||||
|
log.warn("Might have forgotten some spaces between the UIDs. Don't worry, I'll split them for you")
|
||||||
|
for uid in chunks(uids, 12):
|
||||||
|
if not isUID(uid):
|
||||||
|
log.error("Not an UID: {}".format(uid))
|
||||||
|
continue
|
||||||
|
messages.append(uid)
|
||||||
|
|
||||||
|
for message in messages:
|
||||||
|
queryStr = 'tag:tuid{}'.format(message)
|
||||||
|
nbMsgs = applyMsgs(queryStr, action, write=write)
|
||||||
|
if nbMsgs < 1:
|
||||||
|
log.error("Couldn't execute function for message {}".format(message))
|
||||||
|
|
||||||
|
perfstep("definitions")
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
# Main arguments
|
# Main arguments
|
||||||
parser = argparse.ArgumentParser(description="Meh mail client")
|
parser = argparse.ArgumentParser(description="Meh mail client")
|
||||||
|
@ -232,18 +386,13 @@ if __name__ == "__main__":
|
||||||
defaultConfigFile = os.path.join(xdg.BaseDirectory.xdg_config_home, 'mel', 'accounts.conf')
|
defaultConfigFile = os.path.join(xdg.BaseDirectory.xdg_config_home, 'mel', 'accounts.conf')
|
||||||
parser.add_argument('-c', '--config', default=defaultConfigFile, help="Accounts config file")
|
parser.add_argument('-c', '--config', default=defaultConfigFile, help="Accounts config file")
|
||||||
|
|
||||||
parser.set_defaults(dbmode=notmuch.Database.MODE.READ_ONLY)
|
subparsers = parser.add_subparsers(help="Action to execute")
|
||||||
parser.set_defaults(showProgress=False)
|
|
||||||
parser.set_defaults(useThreads=False)
|
|
||||||
parser.set_defaults(actionBefore=None)
|
|
||||||
parser.set_defaults(actionAfter=None)
|
|
||||||
parser.set_defaults(action=None)
|
|
||||||
|
|
||||||
subparsers = parser.add_subparsers(help="Action to execute", required=True)
|
|
||||||
|
|
||||||
|
|
||||||
## List messages
|
## List messages
|
||||||
|
|
||||||
|
def func_default(args):
|
||||||
|
applyMsgs('tag:inbox', print_msg)
|
||||||
|
parser.set_defaults(func=func_default)
|
||||||
|
|
||||||
# inbox (default)
|
# inbox (default)
|
||||||
def func_inbox(args):
|
def func_inbox(args):
|
||||||
|
@ -258,10 +407,30 @@ if __name__ == "__main__":
|
||||||
|
|
||||||
# list folder [--recurse]
|
# list folder [--recurse]
|
||||||
## List actions
|
## List actions
|
||||||
|
|
||||||
|
|
||||||
|
# flag msg...
|
||||||
|
def func_flag(args):
|
||||||
|
def flag_msg(msg):
|
||||||
|
msg.add_tag('flagged')
|
||||||
|
apply_msgs_input(args.message, action=flag_msg, write=True)
|
||||||
|
parserFlag = subparsers.add_parser("flag", help="Mark messages as flagged")
|
||||||
|
parserFlag.add_argument('message', nargs='*', help="Messages")
|
||||||
|
parserFlag.set_defaults(func=func_flag)
|
||||||
|
|
||||||
|
|
||||||
|
# unflag msg...
|
||||||
|
def func_unflag(args):
|
||||||
|
def unflag_msg(msg):
|
||||||
|
msg.remove_tag('flagged')
|
||||||
|
apply_msgs_input(args.message, action=unflag_msg, write=True)
|
||||||
|
parserUnflag = subparsers.add_parser("unflag", help="Mark messages as not-flagged")
|
||||||
|
parserUnflag.add_argument('message', nargs='*', help="Messages")
|
||||||
|
parserUnflag.set_defaults(func=func_unflag)
|
||||||
|
|
||||||
|
|
||||||
# delete msg...
|
# delete msg...
|
||||||
# spam msg...
|
# spam msg...
|
||||||
# flag msg...
|
|
||||||
# ↑un* equivalents
|
|
||||||
# move dest msg...
|
# move dest msg...
|
||||||
## Read message
|
## Read message
|
||||||
# read msg [--html] [--plain] [--browser]
|
# read msg [--html] [--plain] [--browser]
|
||||||
|
@ -270,6 +439,7 @@ if __name__ == "__main__":
|
||||||
# new account
|
# new account
|
||||||
# reply msg [--all]
|
# reply msg [--all]
|
||||||
## Folder management
|
## Folder management
|
||||||
|
# tree [folder]
|
||||||
# mkdir folder
|
# mkdir folder
|
||||||
# rmdir folder (prevent if folder isn't empty (mail/subfolder))
|
# rmdir folder (prevent if folder isn't empty (mail/subfolder))
|
||||||
# (yeah that should do)
|
# (yeah that should do)
|
||||||
|
@ -293,25 +463,40 @@ if __name__ == "__main__":
|
||||||
log.debug(" ".join(cmd))
|
log.debug(" ".join(cmd))
|
||||||
subprocess.run(cmd)
|
subprocess.run(cmd)
|
||||||
|
|
||||||
# Tag new mails
|
|
||||||
applyMsgs('tag:unprocessed', retag_msg, showProgress=True)
|
|
||||||
|
|
||||||
# Notify
|
# Notify
|
||||||
log.info("Notifying new mails")
|
notify_all()
|
||||||
# TODO Maybe before retag, notify unprocessed && unread
|
update_polybar_status()
|
||||||
|
|
||||||
|
# Tag new mails
|
||||||
|
applyMsgs('tag:unprocessed', retag_msg, showProgress=True, write=True)
|
||||||
|
|
||||||
parserFetch = subparsers.add_parser("fetch", help="Fetch mail, tag them, and run notifications")
|
parserFetch = subparsers.add_parser("fetch", help="Fetch mail, tag them, and run notifications")
|
||||||
parserFetch.set_defaults(dbmode=notmuch.Database.MODE.READ_WRITE)
|
|
||||||
parserFetch.set_defaults(func=func_fetch)
|
parserFetch.set_defaults(func=func_fetch)
|
||||||
|
|
||||||
|
|
||||||
## Debug
|
## Debug
|
||||||
# process (all or unprocessed)
|
# debug (various)
|
||||||
|
parserRetag = subparsers.add_parser("debug", help="Who know what this holds...")
|
||||||
|
parserRetag.set_defaults(verbosity='DEBUG')
|
||||||
|
parserRetag.set_defaults(func=notify_all)
|
||||||
|
|
||||||
|
# retag (all or unprocessed)
|
||||||
|
def func_retag(args):
|
||||||
|
applyMsgs('*', retag_msg, showProgress=True, write=True)
|
||||||
|
parserRetag = subparsers.add_parser("retag", help="Retag all mails (when you changed configuration)")
|
||||||
|
parserRetag.set_defaults(func=func_retag)
|
||||||
|
|
||||||
|
# all
|
||||||
|
def func_all(args):
|
||||||
|
applyMsgs('*', print_msg)
|
||||||
|
|
||||||
|
parserAll = subparsers.add_parser("all", help="Show ALL messages")
|
||||||
|
parserAll.set_defaults(func=func_all)
|
||||||
|
|
||||||
|
# Init
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
print(args)
|
perfstep("parse_args")
|
||||||
|
|
||||||
# Installing logs
|
|
||||||
colorama.init()
|
colorama.init()
|
||||||
coloredlogs.install(level=args.verbosity, fmt='%(levelname)s %(message)s')
|
coloredlogs.install(level=args.verbosity, fmt='%(levelname)s %(message)s')
|
||||||
log = logging.getLogger()
|
log = logging.getLogger()
|
||||||
|
@ -325,13 +510,14 @@ if __name__ == "__main__":
|
||||||
config.read(args.config)
|
config.read(args.config)
|
||||||
|
|
||||||
generate_aliases()
|
generate_aliases()
|
||||||
|
perfstep("config")
|
||||||
if args.dbmode is not None:
|
|
||||||
log.info("Loading database")
|
|
||||||
dbPath = os.path.realpath(os.path.expanduser(config["GENERAL"]["storage"]))
|
|
||||||
db = notmuch.Database(mode=args.dbmode, path=dbPath)
|
|
||||||
|
|
||||||
if args.func:
|
if args.func:
|
||||||
log.info("Executing function {}".format(args.func))
|
log.info("Executing function {}".format(args.func))
|
||||||
args.func(args)
|
args.func(args)
|
||||||
|
|
||||||
|
perfstep("exec")
|
||||||
|
|
||||||
|
# DEBUG
|
||||||
|
for kv in sorted(perf_dict.items(), key=lambda p: p[1]):
|
||||||
|
log.debug("{1:.6f} {0}".format(*kv))
|
||||||
|
|
|
@ -203,7 +203,7 @@ primary_email={main[from]}
|
||||||
other_email={other_email}
|
other_email={other_email}
|
||||||
|
|
||||||
[new]
|
[new]
|
||||||
tags=unprocessed;
|
tags=unprocessed;unread;
|
||||||
ignore=
|
ignore=
|
||||||
|
|
||||||
[search]
|
[search]
|
||||||
|
|
Loading…
Reference in a new issue