LINUX.ORG.RU

История изменений

Исправление neumond, (текущая версия) :

Я себе похожее наговнякал, запускаю примерно так:

timer 5m ; alarm blabla

alarm тоже скрипт, там notify-send и mpv звук звонка. По сути красивый sleep, показывающий сколько там осталось.

import argparse
import re
import sys
from time import monotonic_ns, sleep


T_RE = re.compile(r'^(\d+)([wdhms])')
KMAP = {
    'w': 604800,
    'd': 86400,
    'h': 3600,
    'm': 60,
    's': 1,
}


def create_parser():
    p = argparse.ArgumentParser()
    p.add_argument('timespec', nargs='+', help=(
        'Example: 1d 5h 45m; '
        's: seconds; '
        'm: minutes; '
        'h: hours; '
        'd: days; '
        'w: weeks'
    ))
    return p


def error(msg, exitcode=1):
    print(msg, file=sys.stderr)
    exit(exitcode)


def parse_timespec(tsp):
    seconds = 0
    for part in tsp:
        part = part.lower().strip()
        while part:
            if (m := T_RE.match(part)) is None:
                error(f'Unrecognized part: {part}')
            n, unit = m.group(1), m.group(2)
            seconds += int(n) * KMAP[unit]
            part = part[m.end():].lstrip()
    return seconds


def _mod(ts, d):
    return ts % d, ts // d


def time_string(t, total):
    percent = 1000 - t * 1000 // total
    percent = f'{percent // 10:>02}.{percent % 10:>01}%'
    s, t = _mod(t, 60)
    m, t = _mod(t, 60)
    h, d = _mod(t, 24)
    r = ''
    if d == 1:
        r = '1 day '
    elif d > 1:
        r = f'{d} days '
    return r + f'{h:>02}:{m:>02}:{s:>02} {percent} '


def print_same_line(text):
    print('\x1B[2K\x0D' + text, end='')


def main(args):
    seconds = parse_timespec(args.timespec)
    try:
        until = monotonic_ns() + seconds * 1_000_000_000
        while (t := monotonic_ns()) <= until:
            print_same_line(time_string(
                (until - t) // 1_000_000_000,
                seconds))
            sleep(1)
        print_same_line('Timer went off')
        print()
    except KeyboardInterrupt:
        print_same_line('')
        error('Timer has been cancelled')


if __name__ == '__main__':
    main(create_parser().parse_args())

Исходная версия neumond, :

Я себе похожее наговнякал, запускаю примерно так:

timer 5m ; alarm blabla

alarm тоже скрипт, там notify-send и mpv звук звонка. По сути красивый sleep, показывающий сколько там осталось.

import argparse
import re
import sys
from time import monotonic_ns, sleep


T_RE = re.compile(r'^(\d+)([wdhms])')
KMAP = {
    'w': 604800,
    'd': 86400,
    'h': 3600,
    'm': 60,
    's': 1,
}


def non_empty_str(v):
    if not v.strip():
        raise ValueError
    return v


def create_parser():
    p = argparse.ArgumentParser()
    p.add_argument('timespec', nargs='+', help=(
        'Example: 1d 5h 45m; '
        's: seconds; '
        'm: minutes; '
        'h: hours; '
        'd: days; '
        'w: weeks'
    ))
    return p


def error(msg, exitcode=1):
    print(msg, file=sys.stderr)
    exit(exitcode)


def parse_timespec(tsp):
    seconds = 0
    for part in tsp:
        part = part.lower().strip()
        while part:
            if (m := T_RE.match(part)) is None:
                error(f'Unrecognized part: {part}')
            n, unit = m.group(1), m.group(2)
            seconds += int(n) * KMAP[unit]
            part = part[m.end():].lstrip()
    return seconds


def _mod(ts, d):
    return ts % d, ts // d


def time_string(t, total):
    percent = 1000 - t * 1000 // total
    percent = f'{percent // 10:>02}.{percent % 10:>01}%'
    s, t = _mod(t, 60)
    m, t = _mod(t, 60)
    h, d = _mod(t, 24)
    r = ''
    if d == 1:
        r = '1 day '
    elif d > 1:
        r = f'{d} days '
    return r + f'{h:>02}:{m:>02}:{s:>02} {percent} '


def print_same_line(text):
    print('\x1B[2K\x0D' + text, end='')


def main(args):
    seconds = parse_timespec(args.timespec)
    try:
        until = monotonic_ns() + seconds * 1_000_000_000
        while (t := monotonic_ns()) <= until:
            print_same_line(time_string(
                (until - t) // 1_000_000_000,
                seconds))
            sleep(1)
        print_same_line('Timer went off')
        print()
    except KeyboardInterrupt:
        print_same_line('')
        error('Timer has been cancelled')


if __name__ == '__main__':
    main(create_parser().parse_args())