Example #1
0
def write_line(file_path: str, date_string: str):
    file_match = re.match("^[1-2][0-9]{3}-[0-2][0-9]\.txt",
                          os.path.basename(file_path))
    if not file_match:
        raise errors.ReportError(
            "File name is not a month file: \"{}\"".format(file_path))

    date_match = re.match("^\s*(\d+)\.\s+.*$", date_string)
    if not date_match:
        raise errors.ReportError(
            "Bad report string: \"{}\"".format(date_string))

    date = date_match.group(1)
    date_string = date_string.strip()

    if os.path.exists(file_path):
        with open(file_path, 'r') as text_file:
            lines = text_file.readlines()
        lines = [l.rstrip("\n") for l in lines if l.rstrip()]
    else:
        lines = []

    if lines and lines[-1].startswith(date + "."):
        lines[-1] = date_string
    else:
        lines.append(date_string)

    lines = "\n".join(lines)
    with open(file_path, 'w') as text_file:
        text_file.write(lines)
Example #2
0
    def add_day(self, date_string: str) -> Day:
        new_day = Day(date_string)
        if new_day.date.year != self.year or new_day.date.month != self.month:
            raise errors.ReportError("New date string didn't match month. "
                                     "{}-{:02d} doesn't include {}.".format(
                                         self.year, self.month, date_string))

        for old_day in self.days:
            if new_day.date == old_day.date:
                raise errors.ReportError(
                    "Date 2014-09-02 already added to month.")
            if not old_day.complete():
                raise errors.ReportError("New days can't be added while the "
                                         "report for a previous day is "
                                         "incomplete.")

        next_workday = datetime.strptime(self.next_workday(),
                                         "%Y-%m-%d").date()

        if new_day.date > next_workday:
            raise errors.ReportError(
                "New work days must be added consecutively. Expected {}, got "
                "{}.".format(self.next_workday(), date_string))

        if date_string in self.holidays:
            new_day.day_type = DayType.holiday
            new_day.info = self.holidays[date_string]
        self.days.append(new_day)
        return new_day
Example #3
0
 def report_deviation(self, deviation: str):
     match = re.match("^(\d{1,2})(?::(\d{2}))?$", deviation)
     if match:
         self.deviation = timedelta(
             hours=int(match.group(1)), minutes=int(match.group(2) or 0))
     else:
         raise errors.ReportError("Bad deviation for date {}: '{}'".format(
             self.date, deviation))
Example #4
0
    def report_lunch_duration(self, lunch_duration: str):
        if self.start_time is None:
            raise errors.ReportError(
                "Date {} must have a start time before a lunch duration can "
                "be reported.".format(self.date.isoformat()))

        if self.lunch_duration is not None:
            raise errors.ReportError("Date {} allready has a lunch duration."
                                     .format(self.date.isoformat()))

        match = re.match("^(\d{1,2})(?::(\d{2}))?$", lunch_duration)
        if match:
            self.lunch_duration = timedelta(
                hours=int(match.group(1)), minutes=int(match.group(2) or 0))
        else:
            raise errors.ReportError(
                "Bad lunch duration for date {}: '{}'".format(self.date,
                                                              lunch_duration))
Example #5
0
    def archive_month(self, month: month.Month):
        for old_month in self.months:
            if old_month.year == month.year and old_month.month == month.month:
                raise errors.ReportError(
                    "Month {}-{} is allready archived.".format(
                        month.year, month.month))

        date_string = "{}-{:02d}".format(month.year, month.month)
        if self.next_month() != "" and date_string != self.next_month():
            raise errors.ReportError(
                "Months must be archived sequentially. Expected {}, got "
                "{}-{:02d}.".format(self.next_month(), month.year,
                                    month.month))

        if not month.complete():
            raise errors.ReportError("Month still has unreported workdays and "
                                     "can't be archived.")
        self.months.append(month)
Example #6
0
    def report_end_time(self, end_time: str):
        if self.start_time is None:
            raise errors.ReportError(
                "Date {} must have a start time before an end time can be "
                "reported.".format(self.date.isoformat()))

        if self.lunch_duration is None:
            raise errors.ReportError(
                "Date {} must have a lunch duration before an end time can be "
                "reported.".format(self.date.isoformat()))

        try:
            end_time = datetime.strptime(
                end_time, "%H:%M").time()

        except TypeError:
            raise TypeError("Given end time must be a string.")
        except ValueError:
            raise errors.BadTimeError("Bad end time: \"{}\"".format(end_time))
        self.end_time = datetime.combine(self.date, end_time)
Example #7
0
    def report_start_time(self, start_time: str):
        if self.start_time is not None:
            raise errors.ReportError("Date {} allready has a start time."
                                     .format(self.date.isoformat()))

        try:
            start_time = datetime.strptime(
                start_time, "%H:%M").time()
        except ValueError:
            raise errors.BadTimeError(
                "Bad start time: \"{}\".".format(start_time))

        self.start_time = datetime.combine(self.date, start_time)
Example #8
0
    def add_day(self, date_string: str) -> day.Day:
        new_day = day.Day(date_string)
        if new_day.date.year != self.year:
            raise errors.ReportError(
                "New date string didn't match year. {} doesn't include {}.".
                format(self.year, date_string))

        if self.next_workday()[:7] == self.next_month():
            new_month = month.Month(self.next_month())
            for date, name in self.holidays[self.next_month()].items():
                new_month.add_holiday(date, name)
            self.months.append(new_month)
        day_1 = self.months[-1].add_day(date_string)
        return day_1