Changeset 63:76140cb24ebd in stamper


Ignore:
Timestamp:
Jun 29, 2017, 8:28:12 AM (7 years ago)
Author:
Borja Lopez <borja@…>
Branch:
default
Phase:
public
Message:

Refactored date-based filters to their own module.

Added a new date-based filter to look for stamps N days/weeks/months/years
*after* a given date, for example:

"2017-06-29+4d" == "four days after the 29th june 2017"
"2017-06-29+1m" == "1 month after the 29th june 2017"

and so on.

Location:
stamper
Files:
1 added
1 edited

Legend:

Unmodified
Added
Removed
  • stamper/stamper.py

    r61 r63  
    11
    22import json
    3 import re
    43import os.path
    5 from datetime import datetime, date, timedelta
     4from datetime import datetime, timedelta
    65from os import symlink, remove, makedirs
    76from collections import OrderedDict
     
    1110from .http import HTTPClient
    1211from .config import Config
     12from .filters import DateFilter
    1313
    1414
     
    2929        self.ensure_charts_dir()
    3030        self.stamps = []
     31        self.date_filter = DateFilter(self.date_format)
    3132
    3233    def __json_load(self, filename):
     
    9394                    datetime.strptime(start, self.datetime_format))
    9495        return worktime.seconds
    95 
    96     def validate_filter(self, stamp_filter):
    97         """
    98         Validate a given filter. Filters can have the following notation:
    99 
    100         - %Y-%m-%d: Times recorded at a given date
    101 
    102         - %Y-%m-%d--%Y-%m-%d: Times recorded between two dates
    103 
    104         - *%Y-%m-%d: Times recorded up to a  given date
    105 
    106         - %Y-%m-%d*: Times recorded from a given date
    107 
    108         - N...N[d|w|m|y]: Times recorded N...N days/weeks/months/years ago
    109 
    110         Important: all date comparisons are made on datetime objects, using
    111         00:00 as the time (first second of the given day). This means that
    112         for range filters, the first day is included, but the second day is not
    113         """
    114         filter_from = None
    115         filter_to = None
    116 
    117         if stamp_filter is None:
    118             return filter_from, filter_to
    119 
    120         if '--' in stamp_filter:
    121             filter_from, filter_to = stamp_filter.split('--')
    122             filter_from = datetime.strptime(filter_from, self.date_format)
    123             filter_to = datetime.strptime(filter_to, self.date_format)
    124 
    125         elif stamp_filter.startswith('*'):
    126             filter_to = datetime.strptime(stamp_filter, '*'+self.date_format)
    127             filter_to = filter_to.replace(hour=0, minute=0, second=0)
    128 
    129         elif stamp_filter.endswith('*'):
    130             filter_from = datetime.strptime(stamp_filter, self.date_format+'*')
    131             filter_from = filter_from.replace(hour=0, minute=0, second=0)
    132 
    133         elif re.search(r'(\d+[dD]{1})', stamp_filter):
    134             number = int(stamp_filter.lower().replace('d', ''))
    135             delta = timedelta(days=number)
    136             filter_from = datetime.today() - delta
    137             filter_from = filter_from.replace(hour=0, minute=0, second=0)
    138 
    139         elif re.search(r'(\d+[wW]{1})', stamp_filter):
    140             number = int(stamp_filter.lower().replace('w', '')) * 7
    141             delta = timedelta(days=number)
    142             filter_from = datetime.today() - delta
    143             filter_from = filter_from.replace(hour=0, minute=0, second=0)
    144 
    145         elif re.search(r'(\d+[mM]{1})', stamp_filter):
    146             number = int(stamp_filter.lower().replace('m', ''))
    147             past = date.today()
    148             # start travelling in time, back to N months ago
    149             for n in range(number):
    150                 past = past.replace(day=1) - timedelta(days=1)
    151             # Now use the year/month from the past + the current day to set
    152             # the proper date
    153             filter_from = datetime(past.year, past.month, date.today().day)
    154 
    155         elif re.search(r'(\d+[yY]{1})', stamp_filter):
    156             number = int(stamp_filter.lower().replace('y', ''))
    157             today = date.today()
    158             filter_from = datetime(today.year - number, today.month, today.day)
    159 
    160         else:
    161             # maybe they are giving us a fixed date
    162             try:
    163                 filter_from = datetime.strptime(stamp_filter, self.date_format)
    164             except:
    165                 # nothing to be used as a filter, go on, printing a warning
    166                 print('[warning] invalid date filter: ' + stamp_filter)
    167             else:
    168                 filter_from = filter_from.replace(hour=0, minute=0, second=0)
    169                 filter_to = filter_from + timedelta(days=1)
    170 
    171         return filter_from, filter_to
    17296
    17397    @property
     
    252176
    253177    def timeline(self, customer=None, stamp_filter=None, filter_descr=None):
    254         filter_from, filter_to = self.validate_filter(stamp_filter)
     178        filter_from, filter_to = self.date_filter.validate(stamp_filter)
    255179        for stamp in self.stamps:
    256180            start = datetime.strptime(stamp['start'], self.datetime_format)
     
    283207        Generate charts with information from the stamps
    284208        """
    285         filter_from, filter_to = self.validate_filter(stamp_filter)
     209        filter_from, filter_to = self.date_filter.validate(stamp_filter)
    286210        chart = pygal.Bar(title='Work hours per day',
    287211                          range=(0, self.hours_day),
     
    333257    def show_stamps(self, customer=None, stamp_filter=None, verbose=False,
    334258        sum=False, filter_descr=None):
    335         filter_from, filter_to = self.validate_filter(stamp_filter)
     259        filter_from, filter_to = self.date_filter.validate(stamp_filter)
    336260
    337261        # If the user asks for verbose information, show it before the
     
    441365
    442366    def push_stamps(self, customer=None, stamp_filter=None, filter_descr=None):
    443         filter_from, filter_to = self.validate_filter(stamp_filter)
     367        filter_from, filter_to = self.date_filter.validate(stamp_filter)
    444368
    445369        stamps = []
Note: See TracChangeset for help on using the changeset viewer.