Beispiel #1
0
def action_stop(colorizer, time):
    data = get_data_store().load()

    ensure_working(data)
    current_entry = data['work'][-1]

    ensure_end_after_start(current_entry, time)
    current_entry['end'] = time

    get_data_store().dump(data)

    print('You stopped working on ' + colorizer.red(current_entry['name']) + ' at ' +
          colorizer.yellow(formatted_str_for_isotime_str(time, '%H:%M')) + '.')
Beispiel #2
0
def action_note(colorizer, content):
    data = get_data_store().load()

    ensure_working(data)

    current = data['work'][-1]

    if 'notes' not in current:
        current['notes'] = [content]
    else:
        current['notes'].append(content)

    get_data_store().dump(data)

    print('Yep, noted to ' + colorizer.yellow(current['name']) + '.')
Beispiel #3
0
def action_edit():
    if "EDITOR" not in os.environ:
        raise NoEditor("Please set the 'EDITOR' environment variable")

    store = get_data_store()

    data = store.load()
    yml = yaml.safe_dump(data, default_flow_style=False, allow_unicode=True)

    cmd = os.getenv('EDITOR')
    fd, temp_path = tempfile.mkstemp(suffix='.yml', prefix='tt.')
    with open(temp_path, "r+") as f:
        f.write(yml.replace('\n- ', '\n\n- '))
        f.seek(0)
        subprocess.check_call(cmd + ' ' + temp_path, shell=True)
        yml = f.read()
        f.truncate()
        f.close

    os.close(fd)
    os.remove(temp_path)

    try:
        data = yaml.load(yml, Loader=yaml.SafeLoader)
    except yaml.YAMLError as exc:
        raise InvalidYAML("Oops, that YAML doesn't appear to be valid!")

    store.dump(data)
Beispiel #4
0
Datei: tag.py Projekt: nedimAT/tt
def action_tag(tags):
    data = get_data_store().load()

    ensure_working(data)

    current = data['work'][-1]

    current['tags'] = set(current.get('tags') or [])
    current['tags'].update(tags)
    current['tags'] = list(current['tags'])

    get_data_store().dump(data)

    tag_count = len(tags)
    print("Okay, tagged current work with %d tag%s."
          % (tag_count, "s" if tag_count > 1 else ""))
Beispiel #5
0
def action_start(colorizer, name, time):
    data = get_data_store().load()
    work = data['work']

    if work and 'end' not in work[-1]:
        raise AlreadyOn("You are already working on %s. Stop it or use a "
                        "different sheet." %
                        (colorizer.yellow(work[-1]['name']), ))

    entry = {
        'name': name,
        'start': time,
    }

    work.append(entry)
    get_data_store().dump(data)

    print('Started working on ' + colorizer.green(name) + ' at ' +
          colorizer.yellow(formatted_str_for_isotime_str(time, '%H:%M')) + '.')
Beispiel #6
0
def generate_day_based_report():
    data = get_data_store().load()
    work = data['work']
    report = dict()
    for item in work:
        if 'end' in item:
            day = reportingutils.extract_day(item['start'])
            duration = parse_isotime(item['end']) - parse_isotime(
                item['start'])
            try:
                report[day]
            except KeyError:
                report[day] = defaultdict(lambda: timedelta())
            report[day][item['name']] += duration
            #print ('report[', day,  "][", item['name'], "]=" ,  report[day][item['name']])
    return report
Beispiel #7
0
def action_log(period):
    data = get_data_store().load()
    work = data['work']
    log = defaultdict(lambda: {'delta': timedelta()})
    current = None

    for item in work:
        start_time = parse_isotime(item['start'])

        if 'end' in item:
            log[item['name']]['delta'] += (
                    parse_isotime(item['end']) - start_time)
        else:
            log[item['name']]['delta'] += datetime.utcnow() - start_time
            current = item['name']

    name_col_len = 0

    for name, item in log.items():
        name_col_len = max(name_col_len, len(strip_color(name)))

        secs = item['delta'].total_seconds()
        tmsg = []

        if secs > 3600:
            hours = int(secs // 3600)
            secs -= hours * 3600
            tmsg.append(str(hours) + ' hour' + ('s' if hours > 1 else ''))

        if secs > 60:
            mins = int(secs // 60)
            secs -= mins * 60
            tmsg.append(str(mins) + ' minute' + ('s' if mins > 1 else ''))

        if secs:
            tmsg.append(str(secs) + ' second' + ('s' if secs > 1 else ''))

        print(tmsg)
        log[name]['tmsg'] = ', '.join(tmsg)[::-1].replace(',', '& ', 1)[::-1]

    for name, item in sorted(log.items(), key=(lambda x: x[0]), reverse=True):
        print(ljust_with_color(name, name_col_len), ' :: ', item['tmsg'],
              end=' <- working\n' if current == name else '\n')
Beispiel #8
0
def action_csv():
    sep = '|'
    data = get_data_store().load()
    work = data['work']

    for item in work:
        if 'end' in item:
            notes = reportingutils.get_notes_from_workitem(item)
            duration = parse_isotime(item['end']) - parse_isotime(
                item['start'])
            duration_total = reportingutils.remove_seconds(duration)
            date = reportingutils.extract_day(item['start'])
            name = item['name']
            start = format_csv_time(item['start'])
            end = format_csv_time(item['end'])
            tags = ''
            if 'tags' in item:
                tags = item['tags']
            print_elements(date, name, start, end, duration_total, notes, tags,
                           sep)
Beispiel #9
0
def action_status(colorizer):
    data = get_data_store().load()

    ensure_working(data)

    current = data['work'][-1]

    start_time = parse_isotime(current['start'])
    diff = timegap(start_time, datetime.utcnow())

    isotime_local = isotime_utc_to_local(current['start'])
    start_h_m = isotime_local.strftime('%H:%M')
    now_time_str = datetime.now().strftime('%H:%M');

    print('You have been working on {0} for {1}, since {2}; It is now {3}.'
          .format(colorizer.green(current['name']), colorizer.yellow(diff),
                  colorizer.yellow(start_h_m), colorizer.yellow(now_time_str)))

    if 'notes' in current:
        for note in current['notes']:
            print('  * ', note)
Beispiel #10
0
def action_report(colorizer, activity):
    print('Displaying all entries for ',
          colorizer.yellow(activity),
          ' grouped by day:',
          sep='')
    print()
    sep = ' | '
    data = get_data_store().load()
    work = data['work']
    report = defaultdict(
        lambda: {
            'sum': timedelta(),
            'notes': '',
            'weekday': '',
            'start_time': None,
            'end_time': None
        })

    total_time = 0
    for item in work:
        if item['name'] == activity and 'end' in item:
            start_time = parse_isotime(item['start'])
            end_time = parse_isotime(item['end'])
            day = reportingutils.extract_day(item['start'])
            duration = parse_isotime(item['end']) - parse_isotime(
                item['start'])
            report[day]['sum'] += duration
            report[day]['notes'] += reportingutils.get_notes_from_workitem(
                item)
            report[day][
                'weekday'] = reportingutils.extract_day_custom_formatter(
                    item['start'], '%a')
            report[day]['start_time'] = get_min_date(report[day]['start_time'],
                                                     start_time)
            report[day]['end_time'] = get_max_date(report[day]['end_time'],
                                                   end_time)
            total_time += duration.seconds

    print('weekday', sep, 'date', sep, 'total duration', sep, 'start time',
          sep, 'end time', sep, 'break', sep, 'description', sep)

    for date, details in sorted(report.items()):
        start_time = utc_to_local(details['start_time']).strftime("%H:%M")
        end_time = utc_to_local(details['end_time']).strftime("%H:%M")
        break_duration = get_break_duration(details['start_time'],
                                            details['end_time'],
                                            details['sum'])
        print(details['weekday'],
              sep,
              date,
              sep,
              start_time,
              sep,
              end_time,
              sep,
              format_time(break_duration, colorizer),
              sep,
              format_time(details['sum'], colorizer),
              sep,
              details['notes'],
              sep="")

    should_hours = 8 * len(report.items())
    should_hours_str = str(should_hours) + ':00'
    print()
    print('Based on your current entries, you should have logged ',
          colorizer.green(should_hours_str),
          ' ; you instead logged ',
          format_time_seconds(total_time, colorizer),
          sep='')