#2566 cli: list-task --after/--before/--all
Merged a year ago by tkopecek. Opened 2 years ago by tkopecek.
tkopecek/koji issue2565  into  master

file modified
+21 -50
@@ -17,7 +17,6 @@ 

  from collections import OrderedDict, defaultdict

  from optparse import SUPPRESS_HELP, OptionParser

  

- import dateutil.parser

  import six

  import six.moves.xmlrpc_client

  from six.moves import filter, map, range, zip
@@ -25,6 +24,7 @@ 

  import koji

  from koji.util import base64encode, md5_constructor, to_list

  from koji_cli.lib import (

+     TimeOption,

      _,

      _list_tasks,

      _progress_callback,
@@ -3017,15 +3017,12 @@ 

  def anon_handle_list_builds(goptions, session, args):

      "[info] Print the build listing"

      usage = _("usage: %prog list-builds [options]")

-     parser = OptionParser(usage=get_usage_str(usage))

+     parser = OptionParser(usage=get_usage_str(usage), option_class=TimeOption)

      parser.add_option("--package", help=_("List builds for this package"))

      parser.add_option("--buildid", help=_("List specific build from ID or nvr"))

-     parser.add_option("--before",

-                       help=_("List builds built before this time, "

-                              "time is specified as timestamp or date/time in any "

-                              "format which can be parsed by dateutil.parser. e.g. "

-                              "\"2020-12-31 12:35\" or \"December 31st 12:35\""))

-     parser.add_option("--after",

+     parser.add_option("--before", type="time",

+                       help=_("List builds built before this time, ") + TimeOption.get_help())

+     parser.add_option("--after", type="time",

                        help=_("List builds built after this time (same format as for --before"))

      parser.add_option("--state", help=_("List builds in this state"))

      parser.add_option("--task", help=_("List builds for this task"))
@@ -3090,26 +3087,10 @@ 

                  opts['state'] = koji.BUILD_STATES[options.state]

              except KeyError:

                  parser.error(_("Invalid state"))

-     for opt in ('before', 'after'):

-         val = getattr(options, opt)

-         if not val:

-             continue

-         try:

-             ts = float(val)

-             setattr(options, opt, ts)

-             continue

-         except ValueError:

-             pass

-         try:

-             dt = dateutil.parser.parse(val)

-             ts = time.mktime(dt.timetuple())

-             setattr(options, opt, ts)

-         except Exception:

-             parser.error(_("Invalid time specification: %s") % val)

      if options.before:

-         opts['completeBefore'] = getattr(options, 'before')

+         opts['completeBefore'] = options.before

      if options.after:

-         opts['completeAfter'] = getattr(options, 'after')

+         opts['completeAfter'] = options.after

      if options.task:

          try:

              opts['taskID'] = int(options.task)
@@ -4475,7 +4456,7 @@ 

  def anon_handle_list_history(goptions, session, args):

      "[info] Display historical data"

      usage = _("usage: %prog list-history [options]")

-     parser = OptionParser(usage=get_usage_str(usage))

+     parser = OptionParser(usage=get_usage_str(usage), option_class=TimeOption)

      # Don't use local debug option, this one stays here for backward compatibility

      # https://pagure.io/koji/issue/2084

      parser.add_option("--debug", action="store_true", default=goptions.debug, help=SUPPRESS_HELP)
@@ -4495,12 +4476,9 @@ 

      parser.add_option("--group", help=_("Only show entries relating to a given group"))

      parser.add_option("--host", help=_("Only show entries related to given host"))

      parser.add_option("--channel", help=_("Only show entries related to given channel"))

-     parser.add_option("--before",

-                       help=_("Only show entries before this time, "

-                              "time is specified as timestamp or date/time in any "

-                              "format which can be parsed by dateutil.parser. e.g. "

-                              "\"2020-12-31 12:35\" or \"December 31st 12:35\""))

-     parser.add_option("--after",

+     parser.add_option("--before", type="time",

+                       help=_("Only show entries before this time, ") + TimeOption.get_help())

+     parser.add_option("--after", type="time",

                        help=_("Only show entries after timestamp (same format as for --before)"))

      parser.add_option("--before-event", metavar="EVENT_ID", type='int',

                        help=_("Only show entries before event"))
@@ -4522,22 +4500,6 @@ 

          parser.error(_("This command takes no arguments"))

      kwargs = {}

      limited = False

-     for opt in ('before', 'after'):

-         val = getattr(options, opt)

-         if not val:

-             continue

-         try:

-             ts = float(val)

-             setattr(options, opt, ts)

-             continue

-         except ValueError:

-             pass

-         try:

-             dt = dateutil.parser.parse(val)

-             ts = time.mktime(dt.timetuple())

-             setattr(options, opt, ts)

-         except Exception:

-             parser.error(_("Invalid time specification: %s") % val)

      for opt in ('package', 'tag', 'build', 'editor', 'user', 'permission',

                  'cg', 'external_repo', 'build_target', 'group', 'before',

                  'after', 'host', 'channel'):
@@ -6382,7 +6344,7 @@ 

  def handle_list_tasks(goptions, session, args):

      "[info] Print the list of tasks"

      usage = _("usage: %prog list-tasks [options]")

-     parser = OptionParser(usage=get_usage_str(usage))

+     parser = OptionParser(usage=get_usage_str(usage), option_class=TimeOption)

      parser.add_option("--mine", action="store_true", help=_("Just print your tasks"))

      parser.add_option("--user", help=_("Only tasks for this user"))

      parser.add_option("--arch", help=_("Only tasks for this architecture"))
@@ -6391,10 +6353,19 @@ 

      parser.add_option("--host", help=_("Only tasks for this host"))

      parser.add_option("--quiet", action="store_true", default=goptions.quiet,

                        help=_("Do not display the column headers"))

+     parser.add_option("--before", type="time",

+                       help=_("List tasks completed before this time, ") + TimeOption.get_help())

+     parser.add_option("--after", type="time",

+                       help=_("List tasks completed after this time (same format as for --before"))

+     parser.add_option("--all", action="store_true",

+                       help=_("List also finished tasks (valid only with --after)"))

      (options, args) = parser.parse_args(args)

      if len(args) != 0:

          parser.error(_("This command takes no arguments"))

  

+     if options.all and not options.after:

+         parser.error(_("--all must be used with --after"))

+ 

      activate_session(session, goptions)

      tasklist = _list_tasks(options, session)

      if not tasklist:

file modified
+40 -1
@@ -10,9 +10,11 @@ 

  import sys

  import time

  from contextlib import closing

+ from copy import copy

  

  import requests

  import six

+ import dateutil.parser

  from six.moves import range

  

  import koji
@@ -23,8 +25,39 @@ 

  

  # for compatibility with plugins based on older version of lib

  # Use optparse imports directly in new code.

+ # Nevertheless, TimeOption can be used from here.

  OptionParser = optparse.OptionParser

  

+ 

+ def _check_time_option(option, opt, value):

+     """Converts str timestamp or date/time to float timestamp"""

+     try:

+         ts = float(value)

+         return ts

+     except ValueError:

+         pass

+     try:

+         dt = dateutil.parser.parse(value)

+         ts = time.mktime(dt.timetuple())

+         return ts

+     except Exception:

+         raise optparse.OptionValueError(

+             _("option %s: invalid time specification: %r") % (opt, value))

+ 

+ 

+ class TimeOption(optparse.Option):

+     """OptionParser extension for timestamp/datetime values"""

+     TYPES = optparse.Option.TYPES + ("time",)

+     TYPE_CHECKER = copy(optparse.Option.TYPE_CHECKER)

+     TYPE_CHECKER['time'] = _check_time_option

+ 

+     @classmethod

+     def get_help(self):

+         return _("time is specified as timestamp or date/time in any "

+                  "format which can be parsed by dateutil.parser. e.g. "

+                  "\"2020-12-31 12:35\" or \"December 31st 12:35\"")

+ 

+ 

  greetings = ('hello', 'hi', 'yo', "what's up", "g'day", 'back to work',

               'bonjour',

               'hallo',
@@ -722,9 +755,15 @@ 

      "Retrieve a list of tasks"

  

      callopts = {

-         'state': [koji.TASK_STATES[s] for s in ('FREE', 'OPEN', 'ASSIGNED')],

          'decode': True,

      }

+     if not options.all:

+         callopts['state'] = [koji.TASK_STATES[s] for s in ('FREE', 'OPEN', 'ASSIGNED')]

+ 

+     if options.after:

+         callopts['startedAfter'] = options.after

+     if options.before:

+         callopts['startedBefore'] = options.before

  

      if getattr(options, 'mine', False):

          if getattr(options, 'user', None):

@@ -22,6 +22,9 @@ 

          options.method = None

          options.channel = None

          options.host = None

+         options.before = None

+         options.after = None

+         options.all = False

          session = mock.MagicMock(name='session')

          session.getLoggedInUser.return_value = {'id': 1, 'username': 'name'}

          session.listTasks.return_value = []
@@ -259,4 +262,11 @@ 

    --channel=CHANNEL  Only tasks in this channel

    --host=HOST        Only tasks for this host

    --quiet            Do not display the column headers

+   --before=BEFORE    List tasks completed before this time, time is specified

+                      as timestamp or date/time in any format which can be

+                      parsed by dateutil.parser. e.g. "2020-12-31 12:35" or

+                      "December 31st 12:35"

+   --after=AFTER      List tasks completed after this time (same format as for

+                      --before

+   --all              List also finished tasks (valid only with --after)

  """ % self.progname)

Metadata Update from @tkopecek:
- Pull-request tagged with: testing-ready

a year ago

When PR is related to list-tasks, I guess help message should be 'List tasks ....', or not? Same for option --after.

rebased onto da3ede794b90c056fee81167ec9f5e6165643b06

a year ago

1 new commit added

  • fix help message
a year ago

rebased onto 0256282

a year ago

2 new commits added

  • cli: create after/before OptionParser helper
  • cli: list-task --after/--before/--all
a year ago

Metadata Update from @jcupova:
- Pull-request tagged with: testing-done

a year ago

Commit 4542c11 fixes this pull-request

Pull-Request has been merged by tkopecek

a year ago