Files
clip-vault/notif_vault/cli.py
T

79 lines
2.3 KiB
Python

import argparse
import time
from notif_vault import storage
def formatTimestamp(epochSeconds):
return time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(epochSeconds))
def truncate(text, length):
text = (text or "").replace("\n", " ").strip()
return text if len(text) <= length else text[: length - 3] + "..."
def printRows(rows):
if not rows:
print("(no notifications match)")
return
for notificationId, appName, summary, body, urgency, createdAt in rows:
print(f"[{formatTimestamp(createdAt)}] {appName}: {truncate(summary, 60)} - {truncate(body, 80)}")
def cmdList(args):
rows = storage.queryNotifications(
appName=args.app, search=args.search, sinceSeconds=parseSince(args.since), limit=args.limit
)
printRows(rows)
def cmdTail(args):
seenIds = set()
print("watching for new notifications, ctrl-c to stop")
while True:
rows = storage.queryNotifications(limit=20)
for row in reversed(rows):
if row[0] not in seenIds:
seenIds.add(row[0])
printRows([row])
time.sleep(1)
def parseSince(sinceText):
if not sinceText:
return None
unit = sinceText[-1]
amount = float(sinceText[:-1])
multiplier = {"m": 60, "h": 3600, "d": 86400}.get(unit)
if multiplier is None:
raise ValueError("since must look like 30m, 2h or 1d")
return amount * multiplier
def buildParser():
parser = argparse.ArgumentParser(prog="notif-vault", description="searchable desktop notification history")
subparsers = parser.add_subparsers(dest="command", required=True)
listParser = subparsers.add_parser("list", help="list recent notifications")
listParser.add_argument("--app", help="filter by app name substring")
listParser.add_argument("--search", help="filter by text in summary/body")
listParser.add_argument("--since", help="only show notifications newer than this, e.g. 30m, 2h, 1d")
listParser.add_argument("--limit", type=int, default=50)
listParser.set_defaults(func=cmdList)
tailParser = subparsers.add_parser("tail", help="live-follow new notifications")
tailParser.set_defaults(func=cmdTail)
return parser
def main():
parser = buildParser()
args = parser.parse_args()
args.func(args)
if __name__ == "__main__":
main()