Exemplo n.º 1
0
    def _do_lookup(self):
        """
            Searches for and displays one or more log entries.

            Arguments:  none.

            Returns:  True if successful; False if the user aborted.
           -------------------------------------------------------------
        """
        try:
            # Clear the screen.
            wl_resource.print_header(self)
            # If there are no entries in the log, tell the user and then
            #  return.
            if len(self.entries) == 0:
                io_utils.print_status(
                    "Error",
                    "There are no tasks in the log to search!",
                    line_length=self.line_length)
                return False
            # end if
            # Main menu.
            option_list = [
                "By Date/Time", "By Duration", "By Text Search",
                "By RE Pattern"
            ]
            prompt = "Please select a method by which to find entries:"
            search_opt = io_utils.menu(option_list,
                                       keystroke_list="#",
                                       prompt=prompt,
                                       line_length=self.line_length)
            # If the user quits, just return.
            if search_opt == 0:
                return False
            # end if
            # Otherwise call the appropriate lookup function.
            if search_opt == 1:
                results = wl_search.search_by_date(self)
            elif search_opt == 2:
                results = wl_search.search_by_duration(self)
            elif search_opt == 3:
                results = wl_search.search_by_text(self)
            else:  # search_opt == 4
                results = wl_search.search_by_re(self)
            # end if
            # If the search was unsuccessful, just return.
            if not results:
                return True
            # end if
            # Call the appropriate browse function, which will call other
            #  functions if needed.
            if type(results[0]) == datetime.date:
                wl_search.select_date(self, results)
                return True
            else:
                wl_search.select_entry(self, results)
                return True
            # end if
        except Exception as err:
            _z_exc("worklog.py/WorkLog/_do_lookup", err)
Exemplo n.º 2
0
    def _do_settings(self, flag):
        """
            Allows the user to change a setting.

            The date format, time format, or width of the screen can be
             changed.

            Arguments:  none.

            Returns:  nothing.
           -------------------------------------------------------------
        """
        try:
            # Loop until the user is done.
            while True:
                # Clear screen and print header.
                wl_resource.print_header(self)
                # Print instructions.
                self.help.print_help(self.show_help,
                                     "Settings",
                                     "_xh_settings",
                                     line_length=self.line_length)
                # Show menu and get a response.
                response = io_utils.menu(
                    ["Set Date Format", "Set Time Format", "Set Screen Width"],
                    keystroke_list="#",
                    help_toggle=True,
                    line_length=self.line_length)
                # If the user chose to toggle help, do that and then
                #  loop back.
                if str(response).lower() == "-h":
                    self.show_help = not self.show_help
                    continue
                # end if
                # If the user chose to go back, just return.
                if response == QUIT:
                    self.total_entries = flag
                    return
                # Otherwise, to change a setting, call the appropriate
                #  function.
                elif response == DATE_F:
                    wl_datetime.set_endian(self)
                elif response == TIME_F:
                    wl_datetime.set_time_format(self)
                else:  # response == 3
                    wl_resource.set_screen_width(self)
                # end if
            # end while
        except Exception as err:
            _z_exc("worklog.py/WorkLog/_do_settings", err)
Exemplo n.º 3
0
    def action_get(self):
        """
            Gets an action from the user.

            If the log object is unitialized, asks the user to open or
             create a file.

            Arguments:  none.

            Returns:  False if the user chooses to exit the program,
             else True.
           -------------------------------------------------------------
        """
        try:
            print()
            # If the total_entries attribute is -1, the object is not
            #  initialized.  Ask the user to open or create a log file.
            if self.total_entries == -1:
                keystroke_list = ["O", "N", "X", "M"]
                action = io_utils.menu([
                    "Open Log File", "New Log File", "Change Settings",
                    "Read User Manual"
                ],
                                       option_type="actions",
                                       keystroke=True,
                                       keystroke_list=keystroke_list,
                                       lines=True,
                                       top_level=True,
                                       line_length=self.line_length)
                # If the user chooses to quit here...
                if action == 0:
                    # Set the action attribute so _action_take knows to
                    #  do nothing.
                    self.action = None
                    # return False to main() so it knows to exit the
                    #  program.
                    return False
                else:
                    # Set the action attribute, skip the other menu code and
                    #  immediately return.
                    self.action = keystroke_list[action - 1]
                    return True
                # end if
            # end if
            # If the object has been initialized, skip the above code,
            #  print the header and ask the user what they want to do.
            wl_resource.print_header(self)
            keystroke_list = ["A", "F", "S", "C", "X"]
            action = io_utils.menu([
                "Add Entries", "Find/Edit/Delete Entries", "Save Log File",
                "Close Log File", "Change Settings"
            ],
                                   option_type="actions",
                                   lines=True,
                                   keystroke=True,
                                   keystroke_list=keystroke_list,
                                   top_level=True,
                                   line_length=self.line_length)
            # If the user chose to quit...
            if action == QUIT:
                # Set the action attribute to None, which will be a flag
                #  for the action_take method.
                self.action = None
                # If the log object has changed, prompt to save.
                if self.changed is True:
                    save = io_utils.yes_no(
                        "The log file has changed.  Do you want to save it?",
                        line_length=self.line_length)
                    # If yes, just save the file now (bypass action_take
                    #  so that it will still exit).
                    if save:
                        self._do_save()
                    # end if
                # end if
                # Return the flag to end the object loop.
                return False
            else:
                # Set the action attribute.
                self.action = keystroke_list[action - 1]
            # end if
            # Always return True unless the user chose to quit.
            return True
        except Exception as err:
            _z_exc("worklog.py/WorkLog/action_get", err)
Exemplo n.º 4
0
def browse_entries(wl_obj, entry_list, ndx=0):
    """
        Allows the user to browse entries.

        Arguments:
        - wl_obj -- the work log object.
        - entry_list -- the list of entries to browse.

        Keyword Arguments:
        - ndx -- the index of the entry to initially display.

        Returns:  the entry list as modified.
       -----------------------------------------------------------------
    """
    try:
        # Loop.
        while True:
            # If the list is empty, automatically return.
            if len(entry_list) == 0:
                return entry_list
            # end if
            # Clear the screen.
            wl_resource.print_header(wl_obj)
            # Print status message.
            msg = f"Displaying task {(ndx + 1)} of {len(entry_list)}"
            io_utils.print_status("Status",
                                  msg,
                                  go=True,
                                  line_length=wl_obj.line_length)
            # Display the current entry.
            display_entry(wl_obj, entry_list[ndx])
            # Beneath the entry, display a menu.
            options = ["Edit", "Delete"]
            key_list = ["E", "D"]
            if ndx > 0:
                options.append("Previous")
                key_list.append("P")
            # end if
            if ndx < (len(entry_list) - 1):
                options.append("Next")
                key_list.append("N")
            # end if
            options.append("Back")
            key_list.append("B")
            response = io_utils.menu(options,
                                     keystroke=True,
                                     keystroke_list=key_list,
                                     lines=False,
                                     quit_=False,
                                     prompt=" ",
                                     line_length=wl_obj.line_length)
            # Convert the integer response back into the correct option.
            response = key_list[response - 1]
            # Take the appropriate action.
            if response == "B":
                # If the user wants to go back, return the entry list
                #  (as it may have been modified).
                return entry_list
            elif response == "P":
                # If the user wants to back up one entry, decrement the
                #  index and loop.
                ndx -= 1
                continue
            elif response == "N":
                # If the user wants to go to the next entry, increment
                #  the index and loop.
                ndx += 1
                continue
            elif response == "E":
                # If the user wants to edit the current entry, call the
                #  edit function and then loop.
                _edit_entry(wl_obj, entry_list[ndx], ndx, len(entry_list))
                continue
            else:
                # If the user wants to delete the entry, confirm, and if
                #  confirmed, call the delete function. and then loop.
                if io_utils.confirm("delete this entry"):
                    _delete_entry(wl_obj, entry_list, ndx)
                    # Delete the entry from the entry list.
                    # If there are no more entries, return the empty
                    #  list.
                    if len(entry_list) == 0:
                        return entry_list
                    # end if
                    # If the index is past the end of the list, reset
                    #  it.
                    if ndx <= len(entry_list):
                        ndx = len(entry_list) - 1
                    # end if
                # end if
                continue
            # end if
        # end while
    except Exception as err:
        _z_exc("wl_viewedit.py/browse_entries", err)
Exemplo n.º 5
0
def _edit_entry(wl_obj, edit_entry, ndx, total):
    """
        Allows the user to edit a log entry.

        Arguments:
        - wl_obj -- the work log object.
        - edit_entry -- the entry to edit.
        - ndx -- the number of the entry being edited.
        - total -- the total number of entries being displayed.

        Returns:  nothing.
       -----------------------------------------------------------------
    """
    try:
        # This function mainly piggybacks on the add functions to alter
        #  the attributes of the log entry object.  All values are
        #  preserved via the info attribute of a working copy until
        #  saved by the user.
        changed = False
        # Create a working copy of the entry to be edited.
        new_entry = _copy_entry(edit_entry)
        # Store the original values in the info attribute.
        new_entry.info["title"] = new_entry.title
        new_entry.info["date"] = new_entry.date
        new_entry.info["time"] = new_entry.time
        new_entry.info["duration"] = new_entry.duration
        new_entry.info["notes"] = new_entry.notes
        new_entry.info["ndx"] = f"task {ndx + 1} of {total}"
        resort = False
        # Loop.
        while True:
            # Clear the screen and display program header.
            wl_resource.print_header(wl_obj)
            # Print status message.
            io_utils.print_status("Status",
                                  f"Editing {new_entry.info['ndx']}…",
                                  go=True,
                                  line_length=wl_obj.line_length)
            # Display the entry.
            display_entry(wl_obj, new_entry, edit=True)
            # Print instructions.
            wl_obj.help.print_help(wl_obj.show_help,
                                   "Editing",
                                   "_eh_edit",
                                   line_length=wl_obj.line_length)
            options = ["Title", "Date", "Time", "Duration", "Notes"]
            # User selects the field to edit.
            response = io_utils.menu(
                options,
                keystroke_list="#",
                prompt="Please select a field to edit.  When you are finished,"
                + " go back to save or discard your changes:",
                line_length=wl_obj.line_length,
                help_toggle=True)
            # If the user chose to toggle help, do that and loop back.
            if str(response).lower() == "-h":
                wl_obj.show_help = not wl_obj.show_help
                continue
            # end if
            # If the user chose to quit...
            if response == QUIT:
                # If the entry has been edited, prompt to save changes.
                if (changed and io_utils.yes_no(
                        "Do you want to save your changes?",
                        line_length=wl_obj.line_length)):
                    # Recalculate the datetime attribute, in case either
                    #  the date or time changed.
                    new_entry.datetime = wl_add.add_datetime(new_entry)
                    # Save the changed values to the original log entry
                    #  object.
                    _update_entry(wl_obj, new_entry, resort)
                    # Set the flag that the log object has changed.
                    wl_obj.changed = True
                # end if
                return
            # Edit title.
            elif response == TITLE:
                ch = wl_add.add_title(wl_obj, new_entry, edit=True)
                # If the title was edited, turn on the resort flag.
                if ch:
                    resort = True
                # end if
            # Edit date.
            elif response == DATE:
                ch = wl_add.add_date(wl_obj, new_entry, edit=True)
                # If the date was edited, turn on the resort flag.
                if ch:
                    resort = True
                # end if
            # Edit time.
            elif response == TIME:
                ch = wl_add.add_time(wl_obj, new_entry, edit=True)
                # If the time was edited, turn on the resort flag.
                if ch:
                    resort = True
                # end if
            # Edit duration.
            elif response == DURATION:
                ch = wl_add.add_duration(wl_obj, new_entry, edit=True)
            # Edit notes.
            else:
                ch = wl_add.add_note(wl_obj, new_entry, edit=True)
            # end if
            # If something was edited, turn on the changed flag.
            if ch:
                changed = True
            # end if
        # end while
    except Exception as err:
        _z_exc("wl_viewedit.py/_edit_entry", err)
Exemplo n.º 6
0
def browse_list(wl_obj, browse_list, start=0):
    """
        Presents a list to the user and asks him/her to select one.

        Arguments:
        - wl_obj -- the work log object.
        - browse_list -- the list to present.
        - start -- the first item to display (default 0).

        Returns:  an integer representing an item to display, 0 if the
         user quits, or a string representing a navigational command.
       -----------------------------------------------------------------
    """
    try:
        # If the list is empty, automatically return as if the user had
        #  quit.
        if len(browse_list) == 0:
            return 0
        # end if
        # Clear the screen and print the matches to be listed.
        wl_resource.print_header(wl_obj)
        if len(browse_list) == 1:
            msg = "Showing match 1 of 1"
        else:
            msg = f"Showing matches {start + 1}-"
            if start + 9 <= len(browse_list):
                msg += f"{start + 9} of {len(browse_list)}"
            else:
                msg += f"{len(browse_list)} of {len(browse_list)}"
            # end if
        # end if
        io_utils.print_status("Status",
                              msg,
                              go=True,
                              line_length=wl_obj.line_length)
        # Build the options list.
        options = []
        # For dates, just append the date (as a string).
        if type(browse_list[0]) == datetime.date:
            for ndx in range(start, start + 9):
                # Stop if at the end of the list.
                if ndx == len(browse_list):
                    break
                # end if
                options.append(str(browse_list[ndx]))
            # end for
        # For entries, append the title, date and time (as strings).
        else:
            for ndx in range(start, start + 9):
                # Stop if at the end of the list.
                if ndx == len(browse_list):
                    break
                # end if
                # Gather the fields.
                title = browse_list[ndx].title
                date = wl_resource.format_string(wl_obj,
                                                 browse_list[ndx].date,
                                                 short=True)
                time = wl_resource.format_string(wl_obj, browse_list[ndx].time)
                # If the time had a leading zero stripped, replace it
                #  with a space.
                if time[1] == ":":
                    time = f" {time}"
                # end if
                max_title_len = wl_obj.line_length - 23
                # If the title is too long to fit in the column,
                #  truncate it.
                if len(title) > max_title_len:
                    title = title[:max_title_len - 1] + "… "
                else:
                    title += " "
                # end if
                rj = wl_obj.line_length - len(title) - 4
                option = title + f" {date} {time}".rjust(rj, ".")
                # Append the assembled string.
                options.append(option)
            # end for
        # end if
        if start > 0:
            prev = True
        else:
            prev = False
        # end if
        if start + 9 < len(browse_list):
            nxt = True
        else:
            nxt = False
        # end if
        # Now display the menu and return the user's choice.
        return io_utils.menu(options,
                             prompt="Select an entry to view:",
                             keystroke_list="#",
                             nav=True,
                             prev=prev,
                             nxt=nxt,
                             line_length=wl_obj.line_length)
    except Exception as err:
        _z_exc("wl_viewedit.py/browse_list", err)
Exemplo n.º 7
0
def select_entry(wl_obj, entry_list):
    """
        Allows the user to either browse a set of entries, or choose
         from a list.

        Arguments:
        - wl_obj -- the work log object.
        - entry_list -- the list of entries.

        Returns:  nothing.
       -----------------------------------------------------------------
    """
    try:
        # Clear the screen.
        wl_resource.print_header(wl_obj)
        # Print the number of dates found.
        if len(entry_list) == 1:
            msg = "Found 1 task."
        else:
            msg = f"Found {len(entry_list)} tasks."
        # end if
        io_utils.print_status("Status", msg, line_length=wl_obj.line_length)
        # Ask the user to browse or pick from list.
        response = io_utils.menu(
            [
                "Browse all matching tasks",
                "Choose from a list of matching tasks"
            ],
            keystroke_list="#",
            quit_=True,
            prompt="Please select how you want to see the matching tasks:",
            line_length=wl_obj.line_length)
        # If the user chooses to go back, just return.
        if response == QUIT:
            return
        # end if
        # If the user chooses to browse the matches, call the browse
        #  function, then return.
        if response == 1:
            entry_list = wl_viewedit.browse_entries(wl_obj, entry_list)
            return
        # If the user chooses to see a list, display it here.
        else:
            start = 0
            # Run in a loop until the user is done viewing/editing, then
            #  return.
            while True:
                # Call list browse.
                response = wl_viewedit.browse_list(wl_obj,
                                                   entry_list,
                                                   start=start)
                # If the response isn't an integer, it's a command to
                #  move forward or back.  Move the start position, but
                #  only if it doesn't go beyond the bounds of the list.
                if type(response) == str:
                    if (response.lower() == "p") and (start - 9 >= 0):
                        start -= 9
                    elif ((response.lower() == "n")
                          and (start + 9 < len(entry_list))):
                        start += 9
                    # end if
                    # Clear the screen before looping back.
                    wl_resource.print_header(wl_obj)
                    continue
                # end if
                # If the user quits, return.
                if response == QUIT:
                    return
                # end if
                # If it's a non-zero integer, the user chose an entry.
                #  Get the index number of the chosen entry in the list.
                ndx = start + response - 1
                # Browse entries, starting with the selected one.
                wl_viewedit.browse_entries(wl_obj, entry_list, ndx=ndx)
                # Clear the screen before looping back.
                wl_resource.print_header(wl_obj)
            # end while
        # end if
    except Exception as err:
        _z_exc("wl_search.py/select_entry", err)
Exemplo n.º 8
0
def select_date(wl_obj, date_list):
    """
        Show a list (or part of a list) of dates that contain log
         entries.

        Arguments:
        - wl_obj -- the work log object.
        - date_list -- the list of dates.

        Returns:  nothing.
       -----------------------------------------------------------------
    """
    try:
        start = 0
        # Clear the screen.
        wl_resource.print_header(wl_obj)
        # Print the number of dates found.
        if len(date_list) == 1:
            msg = "Found 1 date with entries."
        else:
            msg = f"Found {len(date_list)} dates with entries."
        # end if
        io_utils.print_status("Status", msg, line_length=wl_obj.line_length)
        # Run in a loop until the user is done viewing/editing, then
        #  return.
        while True:
            # Call list browse.
            response = wl_viewedit.browse_list(wl_obj, date_list, start=start)
            # If the response isn't an integer, it's a command to move
            #  forward or back.  Move the start position, but only if it
            #  doesn't go beyond the bounds of the list.
            if type(response) == str:
                if (response.upper() == "P") and (start - 9 >= 0):
                    start -= 9
                elif ((response.upper() == "N")
                      and (start + 9 < len(date_list))):
                    start += 9
                # end if
                # Clear the screen before looping back.
                wl_resource.print_header(wl_obj)
                continue
            # end if
            # If the user quits, return.
            if response == QUIT:
                return
            # end if
            # If it's a non-zero integer, the user chose a date.  Find
            #  all entries on that date.
            start_date = datetime.datetime.combine(
                date_list[start + response - 1], datetime.time())
            end_date = start_date.replace(hour=23, minute=59)
            entry_list = _find_entries_date(wl_obj, start_date, end_date)
            # Let the user browse/edit those entries. (If the user
            #  edited the list, it will come back changed.)
            entry_list = wl_viewedit.browse_entries(wl_obj, entry_list)
            # If the user deleted all of the entries for a date, then
            #  that date is no longer valid and must be removed.
            if len(entry_list) == 0:
                del date_list[start + response - 1]
            # end if
            # Clear the screen before looping back.
            wl_resource.print_header(wl_obj)
        # end while
    except Exception as err:
        _z_exc("wl_search.py/select_date", err)