Esempio n. 1
0
class Entry(dict):
    '''The worklog entry class contains all properties and methods
    CRUD operations, pertaining to log entries.'''
    def __init__(self):
        super().__init__()
        self.utils = Utilities()
        self.validation = Validation()

    def _display_keep_current_value(self, value):
        '''Small internal helper method for display a message
        when no results are found during a search of the log.'''

        self.utils.clear_screen()
        print('Press enter to keep current value: {}'.format(value))
        print('-----------------')

    def _get_entry_data(self, editing=False, log_to_edit=None):
        '''This is an internal method of the Entry class

        The purpose of this method is to house the logic for asking a user
        for input regarding the creation or updating of a record in the log.'''

        if not editing:
            self['id'] = ''.join(
                random.choice('ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890')
                for _ in range(20))
        else:
            self['id'] = log_to_edit['id']

        current_title = " ({})".format(log_to_edit['title']) if editing else ''
        current_date = " ({})".format(log_to_edit['date']) if editing else ''
        current_time_spent = " ({})".format(
            log_to_edit['time_spent']) if editing else ''
        current_notes = " ({})".format(log_to_edit['notes']) if editing else ''

        self['title'] = input("\nPlease choose a title for this entry{}: ".
                              format(current_title)) or log_to_edit['title']

        while True:
            self['date'] = (input("\nPlease enter a date (ex. MM/DD/YYYY){}: ".
                                  format(current_date)) or log_to_edit['date'])

            if not self.validation.is_valid_date(self['date']):
                self.utils.clear_screen()
                continue

            break

        while True:
            self['time_spent'] = (input(
                "\nPlease enter the time spent on this entry in hours{}: ".
                format(current_time_spent)) or log_to_edit['time_spent'])

            if not self.validation.is_valid_number(self['time_spent']):
                self.utils.clear_screen()
                continue

            break

        self['notes'] = (input(
            "\nEnter any notes about this entry (optional){}: ".format(
                current_notes)) or log_to_edit['notes'])

    def create_new_entry(self):
        '''Method to create a new work entry.

        This method walks the user through a series of questions
        allowing them to create a single entry consisting of
        a date entered, a title, the time spent working and some
        optional notes if desired'''

        self._get_entry_data()

        with open(constants.FILENAME, 'a') as file:
            writer = csv.DictWriter(file, fieldnames=constants.FIELDNAMES)
            writer.writerow(self)

        self.utils.clear_screen()

        input("\nEntry has been added, "
              "press enter to return to the main menu")

    def update_current_entry(self, entry_id, edit_mode):
        '''Method for updating records of the worklog.

        This method takes the id of the entry to update and
        the type of update to make via the edit_mode argument.'''

        worklog = self.utils.read_file()
        status = 'updated' if edit_mode == 'edit' else 'deleted'

        for index, entry in enumerate(worklog):
            if entry['id'] == entry_id:
                if edit_mode == 'edit':
                    self._get_entry_data(editing=True, log_to_edit=entry)
                    worklog[index] = self

                if edit_mode == 'delete':
                    del worklog[index]

            with open('worklog.csv', 'w') as log:
                writer = csv.DictWriter(log, constants.FIELDNAMES)
                writer.writeheader()

                for row in worklog:
                    writer.writerow(row)

        self.utils.clear_screen()
        input("\nEntry has been {}! Press enter to continue.".format(status))
Esempio n. 2
0
class Search:
    '''This class contains all methods for searching the worklog
    and displaying the results'''
    def __init__(self):
        self.utils = Utilities()
        self.validation = Validation()
        self.entry = Entry()
        self.menu = Menu()

        self.results = list()

    def search(self, query_text, search_type=''):
        '''Method for searching the worklog

        This method takes the text to ask the user for input
        and the type of search to conduct.'''

        while True:
            self.utils.clear_screen()
            query = input(query_text).lower()

            worklog = self.utils.read_file()

            if search_type == 'date':
                if not self.validation.is_valid_date(query):
                    continue
            elif search_type == 'time_spent':
                if not self.validation.is_valid_number(query):
                    continue
            elif search_type == 'exact_match' or search_type == 'regex':
                if not self.validation.is_valid_input(query):
                    continue
            elif search_type == 'date_range':
                if not self.validation.is_valid_date_range(query.split(', ')):
                    continue

            search = re.compile(r'{}'.format(query), re.I)

            for line in worklog:

                if search_type == 'date' or search_type == 'time_spent':
                    if search.match(line[search_type]):
                        self.results.append(line)

                elif search_type == 'exact_match' or search_type == 'regex':
                    if search.findall(line['title']) \
                            or search.findall(line['notes']):
                        self.results.append(line)

                elif search_type == 'date_range':
                    real_date = datetime.strptime(line['date'], '%m/%d/%Y')
                    date_range = query.split(', ')

                    if (datetime.strptime(date_range[0], '%m/%d/%Y') <=
                            real_date and datetime.strptime(
                                date_range[1], '%m/%d/%Y') >= real_date):
                        self.results.append(line)

            if not self.results:
                print("-------------------------------\n")
                print('No results found...')
                input('Press Enter to try again.')
                continue
            else:
                self.display_search_results()
                break

    def display_search_results(self):
        '''This method displays the results of a user search
        if any are found.'''

        index = 0

        while True:
            num_results = len(self.results)
            entry = self.results[index]

            self.utils.clear_screen()

            print('\n{} Search Results Found'.format(num_results))
            print("-------------------------------\n")

            print('title: {}'.format(entry['title']))
            print('date: {}'.format(entry['date']))
            print('time spent: {}'.format(entry['time_spent']))
            print('notes: {}'.format(entry['notes']))

            print("-------------------------------")
            print('Result {}/{}'.format((index + 1), num_results))
            print("-------------------------------\n")

            choice = input("Choose an action: "
                           "[N]ext, "
                           "[P]revious, "
                           "[E]dit, "
                           "[D]elete, "
                           "[S]earch Menu: ").lower()

            if not self.validation.is_valid_input(choice, menu='npeds'):
                self.utils.clear_screen()
                continue

            if choice == 'n':
                if index != (len(self.results) - 1):
                    index += 1
                else:
                    index = 0

            elif choice == 'p':
                if index != 0:
                    index -= 1
                else:
                    index = (len(self.results) - 1)

            elif choice == 'e' or choice == 's' or choice == 'd':
                if choice == 'e':
                    self.entry.update_current_entry(entry['id'],
                                                    edit_mode='edit')
                if choice == 'd':
                    self.entry.update_current_entry(entry['id'],
                                                    edit_mode='delete')

                self.menu.display(constants.SEARCH_MENU)
                self.results = list()

                break
Esempio n. 3
0
    def access_log(self):
        '''Method containing the main loop to run the program.'''

        menu = Menu()
        entry = Entry()
        utils = Utilities()
        search = Search()
        validation = Validation()
        current_menu = constants.MAIN_MENU

        if not os.path.exists(constants.FILENAME):
            with open(constants.FILENAME, 'a') as file:
                writer = csv.DictWriter(file, fieldnames=constants.FIELDNAMES)
                writer.writeheader()

        while True:
            utils.clear_screen()
            menu.display(current_menu)
            choice = menu.get_user_choice()

            if current_menu == constants.MAIN_MENU:

                if not validation.is_valid_input(choice, menu='csq'):
                    continue

                if choice == 'c':
                    utils.clear_screen()
                    entry.create_new_entry()

                elif choice == 's':
                    current_menu = constants.SEARCH_MENU

                elif choice == 'q':
                    break

            elif current_menu == constants.SEARCH_MENU:

                if not validation.is_valid_input(choice, menu='edtprm'):
                    continue

                if choice == 'e':
                    search.search('Please enter a date to search: ', 'date')

                elif choice == 'd':
                    search.search(
                        'Please enter two comma separated dates to search'
                        '\n(ex. 01/15/1982, 12/11/2017): ', 'date_range')

                elif choice == 't':
                    search.search(
                        'Please enter a time to search: ', 'time_spent')

                elif choice == 'p':
                    search.search(
                        'Please enter a word or phrase to search: ',
                        'exact_match')

                elif choice == 'r':
                    search.search(
                        'Please enter a word or phrase to search: ', 'regex')

                elif choice == 'm':
                    current_menu = constants.MAIN_MENU