Example #1
0
 def test_write_single_digit_date_with_alignment_should_not_raise(self):
     file_path = self._create_month_file("2015-02.txt", "")
     write_line(file_path, " 2. 8:00")
     with open(file_path, 'r') as month_file:
         nt.assert_equal(
             month_file.read(),
             "2. 8:00")
Example #2
0
    def test_write_line_to_new_file(self):
        file_path = os.path.join(self.tempdir.name, "2015-02.txt")

        nt.assert_false(os.path.exists(file_path))

        write_line(file_path, "2. 8:00")

        with open(file_path, 'r') as month_file:
            nt.assert_equal(
                month_file.read(),
                "2. 8:00")
Example #3
0
    def test_write_line_to_empty_file(self):
        file_path = self._create_month_file("2015-02.txt", "")

        with open(file_path, 'r') as month_file:
            nt.assert_equal(month_file.read(), "")

        write_line(file_path, "2. 8:00")

        with open(file_path, 'r') as month_file:
            nt.assert_equal(
                month_file.read(),
                "2. 8:00")
Example #4
0
    def test_append_line_to_file_that_ends_with_several_newlines(self):
        file_path = self._create_month_file("2015-02.txt",
                                            "2. 8:00 1:00 17:00\n\n\n\n")

        with open(file_path, 'r') as month_file:
            nt.assert_equal(month_file.read(), "2. 8:00 1:00 17:00\n\n\n\n")

        write_line(file_path, "3. Narrowing, narrowing, narrowing, narrowing")

        with open(file_path, 'r') as month_file:
            nt.assert_equal(
                month_file.read(),
                "2. 8:00 1:00 17:00\n"
                "3. Narrowing, narrowing, narrowing, narrowing")
Example #5
0
    def test_append_line_to_file_that_ends_with_newline(self):
        file_path = self._create_month_file("2015-02.txt",
                                            "2. 8:00 1:00 17:00\n")

        with open(file_path, 'r') as month_file:
            nt.assert_equal(month_file.read(), "2. 8:00 1:00 17:00\n")

        write_line(file_path, "3. General I/O stream")

        with open(file_path, 'r') as month_file:
            nt.assert_equal(
                month_file.read(),
                "2. 8:00 1:00 17:00\n"
                "3. General I/O stream")
Example #6
0
    def test_append_line_to_file_that_ends_without_newline(self):
        file_path = self._create_month_file("2015-02.txt",
                                            "2. 8:00 1:00 17:00")

        with open(file_path, 'r') as month_file:
            nt.assert_equal(month_file.read(), "2. 8:00 1:00 17:00")

        write_line(file_path, "3. Row, row, row in line")

        with open(file_path, 'r') as month_file:
            nt.assert_equal(
                month_file.read(),
                "2. 8:00 1:00 17:00\n"
                "3. Row, row, row in line")
Example #7
0
    def test_edit_line_in_file(self):
        file_path = self._create_month_file("2015-02.txt",
                                            "2. 8:00 1:00 17:00\n"
                                            "3. 8:15\n")

        with open(file_path, 'r') as month_file:
            nt.assert_equal(month_file.read(),
                            "2. 8:00 1:00 17:00\n"
                            "3. 8:15\n")

        write_line(file_path, "3. 8:15 0:45")

        with open(file_path, 'r') as month_file:
            nt.assert_equal(
                month_file.read(),
                "2. 8:00 1:00 17:00\n"
                "3. 8:15 0:45")
Example #8
0
def main():
    locale.setlocale(locale.LC_ALL, '')
    arguments = docopt(__doc__)
    if arguments['--verbose']:
        print(arguments)
    config_path = os.path.expanduser("~/.chrono")
    config = get_config(config_path)
    reconfigured = False
    if 'Data' not in config['Paths']:
        print("Chrono requires a data folder. Specify data folder with the "
              "--set-data-folder option.")

        sys.exit(1)
    elif arguments["--set-data-folder"]:
        data_folder = os.path.abspath(
            os.path.expanduser(arguments["--set-data-folder"]))

        if os.path.isdir(data_folder):
            config['Paths']['Data'] = data_folder
            reconfigured = True
        else:
            raise ValueError("Couln't find folder '{}'.".format(data_folder))
    else:
        data_folder = os.path.expanduser(config['Paths']['Data'])
        parser = Parser()
        parser.parse_user_file(os.path.join(data_folder, "user.cfg"))
        year_files = [
            f[:4] for f in os.listdir(data_folder)
            if f.endswith(".cfg") and len(os.path.basename(f)) == 8
        ]

        month_files = sorted(
            glob(
                os.path.join(data_folder,
                             "[1-2][0-9][0-9][0-9]-[0-1][0-9].txt")))

        for month_file in month_files:
            year = os.path.basename(month_file)[:4]
            if year in year_files:
                parser.parse_year_file(
                    os.path.join(data_folder, "{}.cfg".format(year)))

                year_files.remove(year)
            parser.parse_month_file(month_file)

        # Handling CLI commands
        if arguments['today'] or arguments['day']:
            if not arguments['<date>']:
                selected_day = parser.user.today()
            else:
                date = arguments['<date>'].split("-")
                if len(date) == 1:
                    day = int(date[0])
                    selected_day = [
                        d for d in parser.user.current_month().days
                        if d.date.day == day
                    ][0]

                elif len(date) == 2:
                    month, day = date
                    month = int(month)
                    day = int(day)
                    selected_month = [
                        m for m in parser.user.current_year().months
                        if m.month == month
                    ][0]

                    selected_day = [
                        d for d in selected_month.days if d.date.day == day
                    ][0]

                elif len(date) == 3:
                    year, month, day = date
                    year = int(year)
                    month = int(month)
                    day = int(day)
                    selected_year = [
                        y for y in parser.user.years if y.year == year
                    ][0]

                    selected_month = [
                        m for m in selected_year.months if m.month == month
                    ][0]

                    selected_day = [
                        d for d in selected_month.days if d.date.day == day
                    ][0]
                else:
                    raise errors.BadDateError(
                        "Date string must have between 1 and 3 elements.")

            print(selected_day)
        elif arguments['week']:
            selected_week = parser.user.current_week()
            print(selected_week)
            print("Total flextime: {}".format(
                pretty_timedelta(parser.user.calculate_flextime(),
                                 signed=True)))

        elif arguments['month']:
            if arguments['<date>']:
                if "-" in arguments['<date>']:
                    year, month = arguments['<date>'].split("-")
                    year = int(year)
                    month = int(month)
                else:
                    year = parser.user.current_year().year
                    month = int(arguments['<date>'])
                selected_year = [
                    y for y in parser.user.years if y.year == year
                ][0]

                selected_month = [
                    m for m in selected_year.months if m.month == month
                ][0]
            else:
                selected_month = parser.user.years[-1].months[-1]
            print(selected_month)
            print("Total flextime: {}".format(
                pretty_timedelta(parser.user.calculate_flextime(),
                                 signed=True)))

        elif arguments['year']:
            if arguments['<date>']:
                selected_year = [
                    year for year in parser.user.years
                    if str(year.year) == arguments['<date>']
                ][0]
            else:
                selected_year = parser.user.years[-1]
            for month in selected_year.months:
                print(month)
        elif arguments['report']:
            if arguments['start']:
                start_time = (arguments['<time>']
                              or datetime.datetime.now().strftime("%H:%M"))

                parser.user.add_day(
                    parser.user.next_workday()).report_start_time(start_time)

            elif arguments['end']:
                end_time = (arguments['<time>']
                            or datetime.datetime.now().strftime("%H:%M"))
                parser.user.today().report_end_time(end_time)
            elif arguments['lunch']:
                parser.user.today().report_lunch_duration(arguments['<time>'])
            elif arguments["deviation"]:
                parser.user.today().report_deviation(arguments['<time>'])
            today = parser.user.today()
            month_file = os.path.join(
                data_folder, "{}.txt".format(today.date.strftime("%Y-%m")))

            writer.write_line(month_file, today.export())
        elif arguments['user']:
            print()
            print(parser.user)
            print()
        elif arguments['stats']:
            if arguments['-w']:
                selected_period = parser.user.current_week().days
            elif arguments['-m']:
                selected_period = parser.user.current_month().days
            elif arguments['-y']:
                selected_period = parser.user.current_year().days
            else:
                selected_period = parser.user.all_days()
            if arguments['start']:
                print_start_statistics(selected_period,
                                       histogram=arguments['--hist'],
                                       bin_width=int(arguments['--bin-width']),
                                       height=int(arguments['--height']))

            if arguments['end']:
                print_end_statistics(selected_period,
                                     histogram=arguments['--hist'],
                                     bin_width=int(arguments['--bin-width']),
                                     height=int(arguments['--height']))

        elif arguments['vacation']:
            print("Vacation left: {} / {}".format(parser.user.vacation_left(),
                                                  parser.user.payed_vacation))
        elif arguments['edit']:
            if 'Editor' in config['Paths']:
                if arguments['<month>']:
                    month_string = arguments['<month>']
                else:
                    month_string = parser.user.today().date.strftime("%Y-%m")
                month_file = os.path.join(data_folder,
                                          "{}.txt".format(month_string))

                if not os.path.exists(month_file):
                    raise errors.BadDateError(
                        "Couldn't find month file '{}'".format(month_file))

                command = [config['Paths']['Editor'], month_file]
                subprocess.call(command)
            else:
                print("Add an editor to your .chrono configuration file.")

    if reconfigured:
        write_config(config, config_path)
Example #9
0
def main():
    locale.setlocale(locale.LC_ALL, "")
    arguments = docopt(__doc__)
    if arguments["--verbose"]:
        print(arguments)
    config_path = os.path.expanduser("~/.chrono")
    config = get_config(config_path)
    reconfigured = False
    if "Data" not in config["Paths"]:
        print("Chrono requires a data folder. Specify data folder with the " "--set-data-folder option.")

        sys.exit(1)
    elif arguments["--set-data-folder"]:
        data_folder = os.path.abspath(os.path.expanduser(arguments["--set-data-folder"]))

        if os.path.isdir(data_folder):
            config["Paths"]["Data"] = data_folder
            reconfigured = True
        else:
            raise ValueError("Couln't find folder '{}'.".format(data_folder))
    else:
        data_folder = os.path.expanduser(config["Paths"]["Data"])
        parser = Parser()
        parser.parse_user_file(os.path.join(data_folder, "user.cfg"))
        year_files = [f[:4] for f in os.listdir(data_folder) if f.endswith(".cfg") and len(os.path.basename(f)) == 8]

        month_files = sorted(glob(os.path.join(data_folder, "[1-2][0-9][0-9][0-9]-[0-1][0-9].txt")))

        for month_file in month_files:
            year = os.path.basename(month_file)[:4]
            if year in year_files:
                parser.parse_year_file(os.path.join(data_folder, "{}.cfg".format(year)))

                year_files.remove(year)
            parser.parse_month_file(month_file)

        # Handling CLI commands
        if arguments["today"] or arguments["day"]:
            if not arguments["<date>"]:
                selected_day = parser.user.today()
            else:
                date = arguments["<date>"].split("-")
                if len(date) == 1:
                    day = int(date[0])
                    selected_day = [d for d in parser.user.current_month().days if d.date.day == day][0]

                elif len(date) == 2:
                    month, day = date
                    month = int(month)
                    day = int(day)
                    selected_month = [m for m in parser.user.current_year().months if m.month == month][0]

                    selected_day = [d for d in selected_month.days if d.date.day == day][0]

                elif len(date) == 3:
                    year, month, day = date
                    year = int(year)
                    month = int(month)
                    day = int(day)
                    selected_year = [y for y in parser.user.years if y.year == year][0]

                    selected_month = [m for m in selected_year.months if m.month == month][0]

                    selected_day = [d for d in selected_month.days if d.date.day == day][0]
                else:
                    raise errors.BadDateError("Date string must have between 1 and 3 elements.")

            print(selected_day)
        elif arguments["week"]:
            selected_week = parser.user.current_week()
            print(selected_week)
            print("Total flextime: {}".format(pretty_timedelta(parser.user.calculate_flextime(), signed=True)))

        elif arguments["month"]:
            if arguments["<date>"]:
                if "-" in arguments["<date>"]:
                    year, month = arguments["<date>"].split("-")
                    year = int(year)
                    month = int(month)
                else:
                    year = parser.user.current_year().year
                    month = int(arguments["<date>"])
                selected_year = [y for y in parser.user.years if y.year == year][0]

                selected_month = [m for m in selected_year.months if m.month == month][0]
            else:
                selected_month = parser.user.years[-1].months[-1]
            print(selected_month)
            print("Total flextime: {}".format(pretty_timedelta(parser.user.calculate_flextime(), signed=True)))

        elif arguments["year"]:
            if arguments["<date>"]:
                selected_year = [year for year in parser.user.years if str(year.year) == arguments["<date>"]][0]
            else:
                selected_year = parser.user.years[-1]
            for month in selected_year.months:
                print(month)
        elif arguments["report"]:
            if arguments["start"]:
                start_time = arguments["<time>"] or datetime.datetime.now().strftime("%H:%M")

                parser.user.add_day(parser.user.next_workday()).report_start_time(start_time)

            elif arguments["end"]:
                end_time = arguments["<time>"] or datetime.datetime.now().strftime("%H:%M")
                parser.user.today().report_end_time(end_time)
            elif arguments["lunch"]:
                parser.user.today().report_lunch_duration(arguments["<time>"])
            elif arguments["deviation"]:
                parser.user.today().report_deviation(arguments["<time>"])
            today = parser.user.today()
            month_file = os.path.join(data_folder, "{}.txt".format(today.date.strftime("%Y-%m")))

            writer.write_line(month_file, today.export())
        elif arguments["user"]:
            print()
            print(parser.user)
            print()
        elif arguments["stats"]:
            if arguments["-w"]:
                selected_period = parser.user.current_week().days
            elif arguments["-m"]:
                selected_period = parser.user.current_month().days
            elif arguments["-y"]:
                selected_period = parser.user.current_year().days
            else:
                selected_period = parser.user.all_days()
            if arguments["start"]:
                print_start_statistics(
                    selected_period,
                    histogram=arguments["--hist"],
                    bin_width=int(arguments["--bin-width"]),
                    height=int(arguments["--height"]),
                )

            if arguments["end"]:
                print_end_statistics(
                    selected_period,
                    histogram=arguments["--hist"],
                    bin_width=int(arguments["--bin-width"]),
                    height=int(arguments["--height"]),
                )

        elif arguments["vacation"]:
            print("Vacation left: {} / {}".format(parser.user.vacation_left(), parser.user.payed_vacation))
        elif arguments["edit"]:
            if "Editor" in config["Paths"]:
                if arguments["<month>"]:
                    month_string = arguments["<month>"]
                else:
                    month_string = parser.user.today().date.strftime("%Y-%m")
                month_file = os.path.join(data_folder, "{}.txt".format(month_string))

                if not os.path.exists(month_file):
                    raise errors.BadDateError("Couldn't find month file '{}'".format(month_file))

                command = [config["Paths"]["Editor"], month_file]
                subprocess.call(command)
            else:
                print("Add an editor to your .chrono configuration file.")

    if reconfigured:
        write_config(config, config_path)