예제 #1
0
    def __check_datestamp_correctness(self, datestamp):
        """
        Checks a datestamp 'YYYY.MM.DD' if its components are a valid date.
        """

        if len(datestamp) != 10:
            return False
        try:
            year = int(datestamp[:4])
            month = int(datestamp[5:7])
            day = int(datestamp[8:10])
        except ValueError:
            logging.debug(
                '__check_datestamp_correctness(' + str(datestamp) +
                ') does not follow YYYY-MM-DD with integers as components for year, month, day.'
            )
            return False

        if year < 1900 or \
           year > 2100 or \
           month < 1 or \
           month > 12 or \
           day < 1 or \
           day > 31:
            logging.debug('__check_datestamp_correctness(' + str(datestamp) +
                          ') NEGATIVE')
            return False
        else:
            try:
                orgdate = OrgFormat.strdate(datestamp)
            except ValueError:
                return False
            return True
예제 #2
0
    def test_strdate(self):
        self.assertEqual(OrgFormat.strdate('2011-11-03'), '<2011-11-03 Thu>')
        self.assertEqual(OrgFormat.strdate('2011-11-3'), '<2011-11-03 Thu>')
        self.assertEqual(OrgFormat.strdate('2011-1-3'), '<2011-01-03 Mon>')
        with self.assertRaises(TimestampParseException):
            OrgFormat.strdate('11-1-3')
        self.assertEqual(OrgFormat.strdate('2011-11-03', show_time=True), '<2011-11-03 Thu 00:00>')
        self.assertEqual(OrgFormat.strdate('2011-11-03', inactive=True), '[2011-11-03 Thu]')
        self.assertEqual(OrgFormat.strdate('2011-11-03', inactive=True, show_time=True), '[2011-11-03 Thu 00:00]')

        self.assertEqual(OrgFormat.strdate('2011-11-03 23:59'), '<2011-11-03 Thu>')
        self.assertEqual(OrgFormat.strdate('2011-11-03 23:59:00'), '<2011-11-03 Thu>')
        self.assertEqual(OrgFormat.strdate('2011-11-03 23:59', show_time=True), '<2011-11-03 Thu 23:59>')
        self.assertEqual(OrgFormat.strdate('2011-11-03 23:59:00', show_time=True), '<2011-11-03 Thu 23:59>')
        self.assertEqual(OrgFormat.strdate('2011-1-2 3:4:5', show_time=True), '<2011-01-02 Sun 03:04>')
        self.assertEqual(OrgFormat.strdate('2011-11-03 23:59', show_time=False), '<2011-11-03 Thu>')
        self.assertEqual(OrgFormat.strdate('2011-11-03 23:59', inactive=True, show_time=True), '[2011-11-03 Thu 23:59]')

        self.assertEqual(OrgFormat.strdate('2011-11-03T23:59'), '<2011-11-03 Thu>')
        self.assertEqual(OrgFormat.strdate('2011-11-03T23:59:58'), '<2011-11-03 Thu>')
        self.assertEqual(OrgFormat.strdate('2011-11-03T23.59'), '<2011-11-03 Thu>')
        self.assertEqual(OrgFormat.strdate('2011-11-03T23.59:58'), '<2011-11-03 Thu>')

        with self.assertRaises(TimestampParseException):
            OrgFormat.strdate('foo')
        with self.assertRaises(TimestampParseException):
            OrgFormat.strdate('2019-04-31 23:59')

        self.assertEqual(OrgFormat.strdate('2011-11-30T21.06', show_time=True),
                         '<2011-11-30 Wed 21:06>')
        self.assertEqual(OrgFormat.strdate('2011-11-30T21.06.00', show_time=True),
                         '<2011-11-30 Wed 21:06>')
        self.assertEqual(OrgFormat.strdate('2011-11-30T21.06.02', show_time=True),
                         '<2011-11-30 Wed 21:06>')
        self.assertEqual(OrgFormat.strdate('1899-12-30T21.06.02', show_time=True),
                         '<1899-12-30 Sat 21:06>')
        self.assertEqual(OrgFormat.strdate('2011-11-30 21.06', show_time=True),
                         '<2011-11-30 Wed 21:06>')
        self.assertEqual(OrgFormat.strdate('2011-11-30 21.06.02', show_time=True),
                         '<2011-11-30 Wed 21:06>')
        self.assertEqual(OrgFormat.strdate('2011-11-30 21:06:02', show_time=True),
                         '<2011-11-30 Wed 21:06>')
        self.assertEqual(OrgFormat.strdate('2011-11-30 21:06', show_time=True),
                         '<2011-11-30 Wed 21:06>')
예제 #3
0
    def test_generate_heading(self):

        ## minimal heading with all parameters provided:
        self.assertEqual(
            OrgFormat.generate_heading(level=2,
                                       keyword=None,
                                       priority=None,
                                       title=None,
                                       tags=None,
                                       scheduled_timestamp=None,
                                       deadline_timestamp=None,
                                       properties=None,
                                       section=None), '** \n')

        ## maximal heading with all parameters as named parameters:
        self.assertEqual(
            OrgFormat.generate_heading(
                level=1,
                keyword='TODO',
                priority='A',
                title='This is my title',
                tags=['foo', 'bar_baz'],
                scheduled_timestamp='<2019-12-29 Sun 11:35>',
                deadline_timestamp='<2019-12-30 Mon 23:59>',
                properties=[('CREATED',
                             OrgFormat.strdate('2011-11-03 23:59',
                                               inactive=True,
                                               show_time=True)),
                            ('myproperty', 'foo bar baz')],
                section=' With this being\nthe content of the heading section.'
            ), '''* TODO [#A] This is my title  :foo:bar_baz:
SCHEDULED: <2019-12-29 Sun 11:35> DEADLINE: <2019-12-30 Mon 23:59>
:PROPERTIES:
:CREATED: [2011-11-03 Thu 23:59]
:myproperty: foo bar baz
:END:

 With this being
the content of the heading section.
''')

        ## heading with title + one property with all named parameters:
        self.assertEqual(
            OrgFormat.generate_heading(level=3,
                                       keyword=None,
                                       priority=None,
                                       title='This is my title',
                                       tags=None,
                                       properties=[('CREATED',
                                                    OrgFormat.strdate(
                                                        '2011-11-03 23:59',
                                                        inactive=True,
                                                        show_time=True))],
                                       section=None), '''*** This is my title
:PROPERTIES:
:CREATED: [2011-11-03 Thu 23:59]
:END:
''')

        ## heading with title + one property with selected named parameters:
        self.assertEqual(
            OrgFormat.generate_heading(level=3,
                                       title='This is my title',
                                       properties=[('CREATED',
                                                    OrgFormat.strdate(
                                                        '2011-11-03 23:59',
                                                        inactive=True,
                                                        show_time=True))]),
            '''*** This is my title
:PROPERTIES:
:CREATED: [2011-11-03 Thu 23:59]
:END:
''')

        ## simple heading:
        self.assertEqual(
            OrgFormat.generate_heading(7, title='This is my title'),
            '''******* This is my title
''')

        ## simple heading with section:
        self.assertEqual(
            OrgFormat.generate_heading(7,
                                       title='This is my title',
                                       section='Let\'s test the format here.'),
            '''******* This is my title

Let's test the format here.
''')

        ## simple heading with section and DEADLINE:
        self.assertEqual(
            OrgFormat.generate_heading(7,
                                       deadline_timestamp='<2019-12-29 Sun>',
                                       title='This is my title',
                                       section='Let\'s test the format here.'),
            '''******* This is my title
DEADLINE: <2019-12-29 Sun>

Let's test the format here.
''')

        ## simple heading with section and SCHEDULED:
        self.assertEqual(
            OrgFormat.generate_heading(7,
                                       scheduled_timestamp='<2019-12-29 Sun>',
                                       title='This is my title',
                                       section='Let\'s test the format here.'),
            '''******* This is my title
SCHEDULED: <2019-12-29 Sun>

Let's test the format here.
''')
예제 #4
0
    def __handle_file(self, file, rootdir):
        """
        handles a file (except ending with a tilde)
        """
        # don't handle emacs tmp files (file~)
        if file[-1:] == '~':
            return

        link = os.path.join(rootdir, file)
        logging.debug('__handle_file: ' + '#' * 50)
        logging.debug('__handle_file: ' + link)

        orgdate = False  # set to default value

        if self._args.force_filedate_extraction:
            # in this case, skip any clever
            # extraction mechanism to extract
            # date/time from file name and use
            # the mtime instead:
            logging.debug(
                '__handle_file: force_filedate_extraction: using datetime from mtime of file'
            )
            file_datetime = time.localtime(os.path.getmtime(link))
            orgdate = OrgFormat.date(file_datetime, show_time=True)
            self.__write_file(file, link, orgdate)
            return

        # very basic checks for correctness (e.g., month=20, hour=70)
        # are part of these RegEx (and do not have to be checked
        # below)
        filename_timestamp_match = DATETIME_REGEX.match(file)
        logging.debug('__handle_file: filename_timestamp_match? ' +
                      str(filename_timestamp_match is True))

        if filename_timestamp_match:
            # day1/2 are like 'YYYY-MM-DD' time1/2 like 'HH:MM':
            has_1ymd, has_1ymdhm, has_2ymd, has_2ymdhm, \
                day1, time1, day2, time2 = self.__extract_days_and_times(filename_timestamp_match)

            # Note: following things are available for formatting:
            # self._args.inactive_timestamps -> Bool
            # OrgFormat.strdate('YYYY-MM-DD', inactive=False) -> <YYYY-MM-DD Sun>
            # OrgFormat.strdate('YYYY-MM-DD HH:MM', inactive=False, show_time=True) -> <YYYY-MM-DD Sun HH:MM>

            assert (has_1ymd)
            try:
                if has_1ymdhm:
                    if self.__check_datestamp_correctness(day1):
                        if self.__check_timestamp_correctness(time1):
                            orgdate = OrgFormat.strdate(
                                day1 + ' ' + time1,
                                inactive=self._args.inactive_timestamps,
                                show_time=True)
                        else:
                            logging.warning(
                                'File "' + file +
                                '" has an invalid timestamp (' + str(time1) +
                                '). Skipping this faulty time-stamp.')
                            orgdate = OrgFormat.strdate(
                                day1, inactive=self._args.inactive_timestamps)
                    else:
                        logging.warning('File "' + file +
                                        '" has an invalid datestamp (' +
                                        str(day1) + ').')
                        # omit optional second day if first has an issue:
                        has_2ymd = False
                        has_2ymdhm = False
                        orgdate = False
                elif has_1ymd:  # missing time-stamp for day1
                    if self.__check_datestamp_correctness(day1):
                        if not self._args.skip_filetime_extraction:
                            # we've got only a day but we're able to determine
                            # time from file mtime, if same as ISO day in file
                            # name:
                            logging.debug(
                                '__handle_file: try to get file time from mtime if days match between mtime and filename ISO ...'
                            )
                            file_datetime = time.localtime(
                                os.path.getmtime(link))
                            if self.__check_if_days_in_timestamps_are_same(
                                    file_datetime, day1):
                                orgdate = OrgFormat.date(
                                    file_datetime,
                                    inactive=self._args.inactive_timestamps,
                                    show_time=True)
                            else:
                                logging.debug(
                                    '__handle_file: day of mtime and filename ISO differs, using filename ISO day'
                                )
                                orgdate = OrgFormat.strdate(
                                    day1,
                                    inactive=self._args.inactive_timestamps)
                        else:
                            # we've got only a day and determining mtime
                            # is not planned, so use the day as date-stamp
                            orgdate = OrgFormat.strdate(
                                day1, inactive=self._args.inactive_timestamps)
                    else:
                        logging.warning('File "' + file +
                                        '" has an invalid datestamp (' +
                                        str(day1) + ').')
                        orgdate = False
                else:
                    logging.warning('File "' + file +
                                    '" has an invalid datestamp (' +
                                    str(day1) +
                                    '). Skipping this faulty date.')
                    # omit optional second day if first has an issue:
                    has_2ymd = False
                    has_2ymdhm = False

                # there is a time range:
                if has_2ymdhm:
                    assert (day2)
                    if self.__check_datestamp_correctness(day2):
                        if self.__check_timestamp_correctness(time2):
                            orgdate += '--' + OrgFormat.strdate(
                                day2 + ' ' + time2,
                                inactive=self._args.inactive_timestamps,
                                show_time=True)
                        else:
                            logging.warning(
                                'File "' + file +
                                '" has an invalid timestamp (' + str(time2) +
                                '). Skipping this faulty time-stamp.')
                            orgdate += '--' + OrgFormat.strdate(
                                day2, inactive=self._args.inactive_timestamps)
                    else:
                        logging.warning('File "' + file +
                                        '" has an invalid datestamp (' +
                                        str(day2) +
                                        '). Skipping this faulty date.')
                elif has_2ymd:
                    assert (day2)
                    if self.__check_datestamp_correctness(day2):
                        orgdate += '--' + OrgFormat.strdate(
                            day2, inactive=self._args.inactive_timestamps)
                    else:
                        logging.warning('File "' + file +
                                        '" has an invalid datestamp (' +
                                        str(day2) +
                                        '). Skipping this faulty date.')
            except TimestampParseException:
                logging.error(
                    'File "' + str(file) +
                    '" has in invalid date- or timestamp. OrgFormat of one of day1: "'
                    + str(day1) + '" time1: "' + str(time1) + '" day2: "' +
                    str(day2) + '" time2: "' + str(time2) + '" ' +
                    'failed with TimestampParseException. Skipping this faulty date.'
                )
                orgdate = False

        else:
            logging.debug('__handle_file: no date- nor timestamp')
            orgdate = False

        if not orgdate and self._args.skip_notimestamp_files:
            logging.debug(
                '__handle_file: file had no or wrong time-stamp and you decided to skip them.'
            )
            return

        self.__write_file(file, link, orgdate)
        logging.debug('__handle_file: using orgdate: ' + str(orgdate))
        return