def show_history(args): """Displays events filtered by given query or given date. Concerning format: the `Python string formatting` rules apply. For the list of available fields see the :class:`orgtool.ext.events.schema.Event` document. Also available is keyword "delta". .. _Python string formatting: http://docs.python.org/library/string.html """ fix_unicode(args, 'query', 'format') # TODO this lists *all* events, whether related to time tracking or not. # here we only need a subset of them: the *user's* activities! # FIXME import warnings warnings.warn('FIXME: for some reason "ls|wc -l" and "ls --count" ' 'return slightly different results') db = default_storage() events = Event.objects(db).order_by('date_time') if args.query: events = events.where(summary__matches_caseless=args.query) if args.count: yield events.count() else: for event in events: template = args.format or u'{date_time} {summary}' delta = '' if 'delta' in template: if event.date_time_end: delta = event.date_time_end - event.date_time yield template.format(delta=delta, **event)
def list_contacts(args): "Lists contacts for matching actors." fix_unicode(args, 'actor', 'type') for actor in find_actors(args.actor): contacts = actor.contacts.order_by(['kind', 'scope']) if args.type: contacts = contacts.where(kind__in=args.type) if not contacts: continue yield(Style.BRIGHT + Fore.YELLOW + u'{0}:'.format(actor) + Fore.RESET + Style.NORMAL) yield('') for contact in contacts: summary = '' if contact.summary == actor.name else contact.summary scope = '' if contact.scope == 'primary' else contact.scope value = contact.value if contact.kind == 'text': value = contact.value.replace('\n', '\n ') template = u'\n {style}{scope}{summary}{endstyle}\n {value}\n' else: template = u' {value} {style}{scope}{summary}{endstyle}' scope = u'({0}) '.format(scope) if scope else '' style = Style.DIM endstyle = Style.NORMAL yield(template.format(**locals())) yield('')
def move_contact(args): "Moves matching contacts to given actor" fix_unicode(args, 'from_actor', 'query', 'type', 'new_actor') new_actor = None try: new_actor = get_single(find_actors, args.new_actor) except MultipleMatches as e: raise CommandError(e) except NotFound as e: raise CommandError(u'No actor matches "{0}".'.format(args.actor)) assert args.from_actor or args.query, 'specify actor or auery' db = default_storage() contacts = Contact.objects(db).where_not(actor=new_actor.pk) if args.type: contacts = contacts.where(type__in=args.type) if args.query: contacts = contacts.where(value__matches_caseless=args.query) if args.from_actor: try: from_actor = get_single(find_actors, args.from_actor) except MultipleMatches as e: raise CommandError(e) except NotFound(e): raise CommandError('Bad --from-actor: no match for "{0}"'.format( args.from_actor)) contacts = contacts.where(actor=from_actor.pk) if not len(contacts): raise CommandError('No suitable contacts were found.') yield('About to move these contacts:\n') for c in contacts: yield(u'- {actor}: {kind} {v}'.format(v=bright(c.value), **c)) yield('') msg = u'Move these contacts to {0}'.format(bright(new_actor)) if confirm(msg, default=True): for c in contacts: c.actor = new_actor c.save(db) else: yield('\nCancelled.')
def add_contact(args): "Adds a contact to given actor" fix_unicode(args, 'actor', 'value', 'type') actor = None try: actor = get_single(find_actors, args.actor) except MultipleMatches as e: raise CommandError(e) except NotFound as e: raise CommandError(u'No actor matches "{0}".'.format(args.actor)) db = default_storage() qs = Contact.objects(db) dupes = qs.where(actor=actor, kind=args.type, value=args.value) if dupes.count(): raise CommandError('Such contact already exists.') # FIXME Docu doesn't properly assign values from Contact(foo=bar) contact = Contact() contact.actor = actor contact.kind = args.type contact.value = args.value contact.save(db)