Source code for dob.facts.simple_prompts

# This file exists within 'dob':
#
#   https://github.com/hotoffthehamster/dob
#
# Copyright © 2018-2020 Landon Bouma,  2015-2016 Eric Goller.  All rights reserved.
#
# 'dob' is free software: you can redistribute it and/or modify it under the terms
# of the GNU General Public License  as  published by the Free Software Foundation,
# either version 3  of the License,  or  (at your option)  any   later    version.
#
# 'dob' is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
# without even the implied warranty of MERCHANTABILITY  or  FITNESS FOR A PARTICULAR
# PURPOSE.  See  the  GNU General Public License  for  more details.
#
# You can find the GNU General Public License reprinted in the file titled 'LICENSE',
# or visit <http://www.gnu.org/licenses/>.

import traceback

from gettext import gettext as _

import click_hotoffthehamster as click
from inflector import English, Inflector

from dob_bright.crud.fix_times import mend_fact_timey_wimey
from dob_bright.termio import (
    attr,
    click_echo,
    dob_in_user_exit,
    fg,
)

from .echo_fact import echo_fact

__all__ = (
    'mend_facts_confirm_and_save_maybe',
    # Private:
    #   'echo_ongoing_completed',
    #   'must_confirm_fact_edits',
    #   'save_facts_maybe',
)


# ***

[docs]def mend_facts_confirm_and_save_maybe( controller, fact, time_hint, other_edits, yes, dry, ): """""" def _mend_facts_confirm_and_save_maybe(): new_fact_or_two, conflicts = mend_fact_timey_wimey( controller, fact, time_hint, other_edits, ) saved_facts = confirm_conflicts_and_save_all(new_fact_or_two, conflicts) return saved_facts def confirm_conflicts_and_save_all(new_fact_or_two, conflicts): """""" # Ask user what to do about conflicts/edits. ignore_pks = other_edits.keys() must_confirm_fact_edits(controller, conflicts, yes, dry) saved_facts = save_facts_maybe( controller, new_fact_or_two, conflicts, ignore_pks, dry, ) return saved_facts return _mend_facts_confirm_and_save_maybe()
# *** def must_confirm_fact_edits(controller, conflicts, yes, dry): """""" def _must_confirm_fact_edits(conflicts, yes, dry): conflicts = cull_stopped_ongoing(conflicts) if not conflicts: return yes = yes or dry if not yes: echo_confirmation_banner(conflicts) n_conflict = 0 n_confirms = 0 for edited_fact, original in conflicts: n_conflict += 1 if not yes: confirmed = echo_confirmation_edited( n_conflict, edited_fact, original, ) n_confirms += 1 if confirmed else 0 else: controller.client_logger.debug( _('Editing fact: {}').format(edited_fact) ) if n_conflict != n_confirms: # (lb): This function is not used by the carousel -- only by # one-off CLI commands -- so blowing up here is perfectly fine. # (The carousel has its own error message display mechanism; # and more importantly the carousel should never die, # but should only ever be asked to die by the user.) dob_in_user_exit(_("Please try again.")) def cull_stopped_ongoing(conflicts): return [con for con in conflicts if 'stopped' not in con[0].dirty_reasons] def echo_confirmation_banner(conflicts): # FIXME: (lb): Replace hardcoded styles. Assign from styles.conf. #styling click.echo() click.echo(_( 'Found {}{}{} {}. ' '{}Please confirm the following changes:{}' .format( fg('magenta'), len(conflicts), attr('reset'), Inflector(English).conditional_plural(len(conflicts), 'conflict'), attr('underlined'), attr('reset'), ) )) def echo_confirmation_edited(n_conflict, edited_fact, original): click.echo() # MAYBE: # from dob_viewer.ptkui.re_confirm import confirm # confirmed = confirm() confirmed = click.confirm( text=_('Conflict #{}\n-----------\n{}\nReally edit fact?').format( n_conflict, original.friendly_diff(edited_fact), ), default=False, abort=False, # prompt_suffix=': ', # show_default=True, # err=False, ) return confirmed # *** _must_confirm_fact_edits(conflicts, yes, dry) # *** def save_facts_maybe(controller, new_facts, conflicts, ignore_pks, dry): """""" def _save_facts_maybe(controller, new_facts, conflicts, ignore_pks, dry): new_and_edited = [] if conflicts and dry: echo_dry_run() for edited_fact, original in conflicts: if not dry: new_and_edited += save_fact(controller, edited_fact, dry) if 'stopped' in edited_fact.dirty_reasons: # This'll happen on one-off dob-to/dob-at/etc., but it # will not happen on dob-import, e.g., if dob-import # closes ongoing fact, it'll be saved normally, and it # will not be passed herein as part of conflicts. echo_ongoing_completed(controller, edited_fact) else: click.echo(original.friendly_diff(edited_fact)) for fact in new_facts: new_and_edited += save_fact(controller, fact, dry, ignore_pks=ignore_pks) return new_and_edited def echo_dry_run(): click.echo() click.echo('{}Dry run! These facts will be edited{}:\n '.format( attr('underlined'), attr('reset'), )) def save_fact(controller, fact, dry, ignore_pks=[]): # (lb): SIMILAR: edits_manager.save_edited_fact, create.save_fact. if fact.pk and fact.pk < 0: fact.pk = None if fact.pk is None and fact.deleted: controller.client_logger.debug('{}: {}'.format(_('Dead fact'), fact.short)) return [] if not dry: controller.client_logger.debug('{}: {}'.format(_('Save fact'), fact.short)) try: new_fact = controller.facts.save(fact, ignore_pks=ignore_pks) except Exception as err: traceback.print_exc() dob_in_user_exit(str(err)) else: new_fact = fact echo_fact(fact) return [new_fact, ] # *** return _save_facts_maybe(controller, new_facts, conflicts, ignore_pks, dry) # *** def echo_ongoing_completed(controller, fact, cancelled=False): """""" def _echo_ongoing_completed(): colorful = controller.config['term.use_color'] leader = _('Completed: ') if not cancelled else _('Cancelled: ') cut_width = width_avail(len(leader)) completed_msg = echo_fact(leader, colorful, cut_width) controller.client_logger.debug(completed_msg) def width_avail(leader_len): term_width = click.get_terminal_size()[0] width_avail = term_width - leader_len return width_avail def echo_fact(leader, colorful, cut_width): completed_msg = ( leader + fact.friendly_str( shellify=False, description_sep=': ', # FIXME: (lb): Implement localize. # FIXME/2018-06-10: (lb): fact being saved as UTC localize=True, colorful=colorful, cut_width_complete=cut_width, show_elapsed=True, ) ) click_echo(completed_msg) return completed_msg _echo_ongoing_completed()