Skip to content

Commit

Permalink
allow multiple values in --older-than and --newer-than
Browse files Browse the repository at this point in the history
  • Loading branch information
oxij committed Nov 22, 2023
1 parent f7669b0 commit 92755a3
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 29 deletions.
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -409,17 +409,17 @@ Logins to a specified server, performs specified actions on all messages matchin

- message search filters:
- `--older-than DAYS`
: operate on messages older than this many days, **the date will be rounded down to the start of the day; actual matching happens on the server, so all times are server time**; e.g. `--older-than 0` means older than the start of today by server time, `--older-than 1` means older than the start of yesterday, etc
: operate on messages older than this many days, **the date will be rounded down to the start of the day; actual matching happens on the server, so all times are server time**; e.g. `--older-than 0` means older than the start of today by server time, `--older-than 1` means older than the start of yesterday, etc; can be specified multiple times, in which case the earliest (the most old) date on the list will be chosen
- `--newer-than DAYS`
: operate on messages newer than this many days, a negation of`--older-than`, so **everything from `--older-than` applies**; e.g., `--newer-than -1` will match files dated into the future, `--newer-than 0` will match files delivered from the beginning of today, etc
: operate on messages newer than this many days, a negation of`--older-than`, so **everything from `--older-than` applies**; e.g., `--newer-than -1` will match files dated into the future, `--newer-than 0` will match files delivered from the beginning of today, etc; can be specified multiple times, in which case the latest (the least old) date on the list will be chosen
- `--older-than-timestamp-in PATH`
: operate on messages older than the timestamp (in seconds since UNIX Epoch) recorded on the first line of this PATH, rounded as above (can be specified multiple times)
: operate on messages older than the timestamp (in seconds since UNIX Epoch) recorded on the first line of this PATH, rounded as described above; can be specified multiple times, in which case it will processed as described above
- `--newer-than-timestamp-in PATH`
: operate on messages newer than the timestamp (in seconds since UNIX Epoch) recorded on the first line of this PATH, rounded as above (can be specified multiple times)
: operate on messages newer than the timestamp (in seconds since UNIX Epoch) recorded on the first line of this PATH, rounded as described above; can be specified multiple times, in which case it will processed as described above
- `--older-than-mtime-of PATH`
: operate on messages older than `mtime` of this PATH, rounded as above (can be specified multiple times)
: operate on messages older than `mtime` of this PATH, rounded as described above; can be specified multiple times, in which case it will processed as described above
- `--newer-than-mtime-of PATH`
: operate on messages newer than `mtime` of this PATH, rounded as above (can be specified multiple times)
: operate on messages newer than `mtime` of this PATH, rounded as described above; can be specified multiple times, in which case it will processed as described above
- `--from ADDRESS`
: operate on messages that have this string as substring of their header's FROM field; can be specified multiple times
- `--not-from ADDRESS`
Expand Down
39 changes: 16 additions & 23 deletions imaparms/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,9 +177,8 @@ def imap_quote(arg : str) -> str:
def imap_date(date : time.struct_time) -> str:
return f"{str(date.tm_mday)}-{imap_months[date.tm_mon-1]}-{str(date.tm_year)}"

def make_search_filter(cfg : Namespace) -> _t.Tuple[str, bool]:
def make_search_filter(cfg : Namespace) -> str:
filters = []
dynamic = False

if cfg.seen is not None:
if cfg.seen:
Expand Down Expand Up @@ -211,43 +210,37 @@ def read_timestamp(path : str) -> int:
now = time.time_ns()

older_than = []
if cfg.older_than is not None:
older_than.append(now - cfg.older_than * 86400 * 10**9)
dynamic = True
for dt in cfg.older_than:
older_than.append(now - dt * 86400 * 10**9)

for path in cfg.older_than_timestamp_in:
older_than.append(read_timestamp(os.path.expanduser(path)))
dynamic = True

for path in cfg.older_than_mtime_of:
older_than.append(os.stat(os.path.expanduser(path)).st_mtime_ns)
dynamic = True

if len(older_than) > 0:
date = time.gmtime(min(older_than) / 10**9)
filters.append(f"BEFORE {imap_date(date)}")

newer_than = []
if cfg.newer_than is not None:
newer_than.append(now - cfg.newer_than * 86400 * 10**9)
dynamic = True
for dt in cfg.newer_than:
newer_than.append(now - dt * 86400 * 10**9)

for path in cfg.newer_than_timestamp_in:
newer_than.append(read_timestamp(os.path.expanduser(path)))
dynamic = True

for path in cfg.newer_than_mtime_of:
newer_than.append(os.stat(os.path.expanduser(path)).st_mtime_ns)
dynamic = True

if len(newer_than) > 0:
date = time.gmtime(max(newer_than) / 10**9)
filters.append(f"NOT BEFORE {imap_date(date)}")

if len(filters) == 0:
return "(ALL)", dynamic
return "(ALL)"
else:
return "(" + " ".join(filters) + ")", dynamic
return "(" + " ".join(filters) + ")"

def die(desc : str, code : int = 1) -> None:
sys.stderr.write(gettext("error") + ": " + desc + "\n")
Expand Down Expand Up @@ -529,8 +522,8 @@ def prepare_cmd(cfg : Namespace) -> None:
if cfg.not_folders:
place += " " + gettext("excluding %s") % (", ".join(map(repr, cfg.not_folders)),)

search_filter, dynamic = make_search_filter(cfg)
if dynamic:
search_filter = make_search_filter(cfg)
if cfg.every is not None:
search_filter += " " + gettext("{dynamic}")

if "mark" in cfg:
Expand Down Expand Up @@ -583,7 +576,7 @@ def for_each_folder(cfg : Namespace, state : State, account : Account, srv : IMA

def do_folder_action(cfg : Namespace, state : State, account : Account, srv : IMAP4,
folder : str, command : str) -> None:
search_filter, _ = make_search_filter(cfg)
search_filter = make_search_filter(cfg)

typ, data = srv.uid("SEARCH", search_filter)
if typ != "OK":
Expand Down Expand Up @@ -1146,14 +1139,14 @@ def add_folders_sub(cmd : _t.Any) -> _t.Any:

def add_common_filters(cmd : _t.Any) -> _t.Any:
agrp = cmd.add_argument_group(_("message search filters"))
agrp.add_argument("--older-than", metavar = "DAYS", type=int, help=_("operate on messages older than this many days, **the date will be rounded down to the start of the day; actual matching happens on the server, so all times are server time**; e.g. `--older-than 0` means older than the start of today by server time, `--older-than 1` means older than the start of yesterday, etc"))
agrp.add_argument("--newer-than", metavar = "DAYS", type=int, help=_("operate on messages newer than this many days, a negation of`--older-than`, so **everything from `--older-than` applies**; e.g., `--newer-than -1` will match files dated into the future, `--newer-than 0` will match files delivered from the beginning of today, etc"))
agrp.add_argument("--older-than", metavar = "DAYS", action="append", default=[], type=int, help=_("operate on messages older than this many days, **the date will be rounded down to the start of the day; actual matching happens on the server, so all times are server time**; e.g. `--older-than 0` means older than the start of today by server time, `--older-than 1` means older than the start of yesterday, etc; can be specified multiple times, in which case the earliest (the most old) date on the list will be chosen"))
agrp.add_argument("--newer-than", metavar = "DAYS", action="append", default=[], type=int, help=_("operate on messages newer than this many days, a negation of`--older-than`, so **everything from `--older-than` applies**; e.g., `--newer-than -1` will match files dated into the future, `--newer-than 0` will match files delivered from the beginning of today, etc; can be specified multiple times, in which case the latest (the least old) date on the list will be chosen"))

agrp.add_argument("--older-than-timestamp-in", metavar = "PATH", action="append", default=[], type=str, help=_("operate on messages older than the timestamp (in seconds since UNIX Epoch) recorded on the first line of this PATH, rounded as above (can be specified multiple times)"))
agrp.add_argument("--newer-than-timestamp-in", metavar = "PATH", action="append", default=[], type=str, help=_("operate on messages newer than the timestamp (in seconds since UNIX Epoch) recorded on the first line of this PATH, rounded as above (can be specified multiple times)"))
agrp.add_argument("--older-than-timestamp-in", metavar = "PATH", action="append", default=[], type=str, help=_("operate on messages older than the timestamp (in seconds since UNIX Epoch) recorded on the first line of this PATH, rounded as described above; can be specified multiple times, in which case it will processed as described above"))
agrp.add_argument("--newer-than-timestamp-in", metavar = "PATH", action="append", default=[], type=str, help=_("operate on messages newer than the timestamp (in seconds since UNIX Epoch) recorded on the first line of this PATH, rounded as described above; can be specified multiple times, in which case it will processed as described above"))

agrp.add_argument("--older-than-mtime-of", metavar = "PATH", action="append", default=[], type=str, help=_("operate on messages older than `mtime` of this PATH, rounded as above (can be specified multiple times)"))
agrp.add_argument("--newer-than-mtime-of", metavar = "PATH", action="append", default=[], type=str, help=_("operate on messages newer than `mtime` of this PATH, rounded as above (can be specified multiple times)"))
agrp.add_argument("--older-than-mtime-of", metavar = "PATH", action="append", default=[], type=str, help=_("operate on messages older than `mtime` of this PATH, rounded as described above; can be specified multiple times, in which case it will processed as described above"))
agrp.add_argument("--newer-than-mtime-of", metavar = "PATH", action="append", default=[], type=str, help=_("operate on messages newer than `mtime` of this PATH, rounded as described above; can be specified multiple times, in which case it will processed as described above"))

agrp.add_argument("--from", dest="hfrom", metavar = "ADDRESS", action = "append", type=str, default = [], help=_("operate on messages that have this string as substring of their header's FROM field; can be specified multiple times"))
agrp.add_argument("--not-from", dest="hnotfrom", metavar = "ADDRESS", action = "append", type=str, default = [], help=_("operate on messages that don't have this string as substring of their header's FROM field; can be specified multiple times"))
Expand Down

0 comments on commit 92755a3

Please sign in to comment.