From 315e0d22acce2c59604aec35ba6b636ce8fd1ea6 Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Sat, 13 May 2017 15:56:49 +0200 Subject: [PATCH 01/15] fix(tstamp): report `subject_prefix` when it has non-ASCII --- co2mpas/sampling/tstamp.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/co2mpas/sampling/tstamp.py b/co2mpas/sampling/tstamp.py index 478cf2f01..b6d51b802 100644 --- a/co2mpas/sampling/tstamp.py +++ b/co2mpas/sampling/tstamp.py @@ -181,8 +181,8 @@ def _is_all_latin(self, proposal): value = proposal.value if any(ord(c) >= 128 for c in value): myname = type(self).__name__ - raise trt.TraitError('%s.%s must not contain non-ASCII chars!' - % (myname, proposal.trait.name)) + raise trt.TraitError('%s.%s must not contain non-ASCII chars: %s' + % (myname, proposal.trait.name, value)) return value @property From 73aff2498bce88be4a69b7ac160f3b87ee88af08 Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Sat, 13 May 2017 20:16:13 +0200 Subject: [PATCH 02/15] fix(tstamp): rname wait_cretiria-->criteriO to designate is not a list --- co2mpas/sampling/tstamp.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/co2mpas/sampling/tstamp.py b/co2mpas/sampling/tstamp.py index b6d51b802..66ce9fc9f 100644 --- a/co2mpas/sampling/tstamp.py +++ b/co2mpas/sampling/tstamp.py @@ -500,7 +500,7 @@ class TstampReceiver(TstampSpec): are both compulsory; - see https://tools.ietf.org/html/rfc3501#page-49 for more. - More criteria are appended on runtime, ie `TstampSpec.subject_prefix`, - `wait_criteria` if --wait, and any args to `recv` command as ORed + `wait_criterio` if --wait, and any args to `recv` command as ORed and searched as subject terms (i.e. the (projects-ids"). - If you want to fetch tstamps sent to `tstamp_recipients`, either leave this empty, or set it to email-address of the sender: @@ -509,7 +509,7 @@ class TstampReceiver(TstampSpec): """ ).tag(config=True) - wait_criteria = trt.Unicode( + wait_criterio = trt.Unicode( 'NEW', allow_none=True, help="""The RFC3501 IMAP search criteria for when IDLE-waiting, usually RECENT+UNSEEN messages.""" ).tag(config=True) @@ -783,7 +783,7 @@ def _prepare_search_criteria(self, is_wait, projects): if self.subject_prefix: criteria.append('Subject "%s"' % self.subject_prefix) if is_wait: - criteria.append(self.wait_criteria) + criteria.append(self.wait_criterio) before, after = [self.before_date, self.after_date] if before or after: From 3d030f520960aecf87752e14639071383858177a Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Sat, 13 May 2017 20:56:59 +0200 Subject: [PATCH 03/15] fix(tstamp): strip all criteria and skip empties, with TCs --- co2mpas/sampling/tstamp.py | 32 +++++++++++++++++++++++--------- tests/sampling/test_tstamp.py | 17 +++++++++++++++++ 2 files changed, 40 insertions(+), 9 deletions(-) diff --git a/co2mpas/sampling/tstamp.py b/co2mpas/sampling/tstamp.py index 66ce9fc9f..58d1d2276 100644 --- a/co2mpas/sampling/tstamp.py +++ b/co2mpas/sampling/tstamp.py @@ -561,6 +561,11 @@ class TstampReceiver(TstampSpec): """ ).tag(config=True) + @trt.validate('subject_prefix', 'wait_criterio', 'before_date', 'after_date') + def _strip_trait(self, p): + v = p.value + return v and v.strip() + def _capture_stamper_msg_and_id(self, ts_msg: Text, ts_heads: Text) -> int: stamper_id = msg = None m = _stamper_id_regex.search(ts_heads) @@ -779,32 +784,41 @@ def list_mailbox(self, directory='""', pattern='*'): return ["Found %i mailboxes:" % len(res)] + res def _prepare_search_criteria(self, is_wait, projects): - criteria = list(self.email_criteria) - if self.subject_prefix: - criteria.append('Subject "%s"' % self.subject_prefix) - if is_wait: - criteria.append(self.wait_criterio) - + subj = self.subject_prefix before, after = [self.before_date, self.after_date] + waitcrt = self.wait_criterio + + criteria = [c and c.strip() for c in self.email_criteria] + criteria = [c for c in criteria if c] + + if subj: + criteria.append('Subject "%s"' % subj) + + if is_wait and waitcrt: + criteria.append(waitcrt) + if before or after: import parsedatetime as pdt c = self.dates_locale and pdt.Constants(self.dates_locale) cal = pdt.Calendar(c) - if before: + if before and before.strip(): criteria.append('SENTBEFORE "%s"' % parse_as_RFC3501_date(cal, before)) - if after: + if after and after.strip(): criteria.append('SINCE "%s"' % parse_as_RFC3501_date(cal, after)) + projects = [c and c.strip() for c in projects] + projects = [c for c in projects if c] if projects: criteria.append(pairwise_ORed(projects, lambda i: '(SUBJECT "%s")' % i)) criteria = [c.strip() for c in criteria] - criteria = [c if c.startswith('(') else '(%s)' % c for c in criteria] + criteria = [c if c.startswith('(') else '(%s)' % c + for c in criteria] criteria = ' '.join(criteria) return criteria diff --git a/tests/sampling/test_tstamp.py b/tests/sampling/test_tstamp.py index 855ce43c0..ccf34ec85 100644 --- a/tests/sampling/test_tstamp.py +++ b/tests/sampling/test_tstamp.py @@ -615,6 +615,23 @@ def test_parse_timestamps(self, case): rcv.force = True self.check_timestamp(rcv, *verdicts) + @ddt.data( + (None, []), + ('', []), + (' ', []), + + (None, ['', ' ']), + ('', ['', ' ']), + (' ', ['', ' ']), + ) + def test_criteria_stripping(self, case): + one, many = case + rcv = tstamp.TstampReceiver(email_criteria=many, + wait_criterio=one, + subject_prefix=one) + crt = rcv._prepare_search_criteria(True, many) + self.assertEqual(crt, '') + @ddt.ddt class TstampShell(unittest.TestCase): From ebadfb6a0bc8c7ff9ed425d4faa096ac75649816 Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Sat, 13 May 2017 21:14:37 +0200 Subject: [PATCH 04/15] feat(tstamp): allow None in search-criteria, TCs --- co2mpas/sampling/tstamp.py | 9 ++++++--- tests/sampling/test_tstamp.py | 22 +++++++++++++--------- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/co2mpas/sampling/tstamp.py b/co2mpas/sampling/tstamp.py index 58d1d2276..d0cbc5d99 100644 --- a/co2mpas/sampling/tstamp.py +++ b/co2mpas/sampling/tstamp.py @@ -478,7 +478,7 @@ class TstampReceiver(TstampSpec): ).tag(config=True) email_criteria = trt.List( - trt.Unicode(), + trt.Unicode(), allow_none=True, default_value=[ 'From "mailer@stamper.itconsult.co.uk"', 'Subject "Proof of Posting Certificate"', @@ -788,8 +788,11 @@ def _prepare_search_criteria(self, is_wait, projects): before, after = [self.before_date, self.after_date] waitcrt = self.wait_criterio - criteria = [c and c.strip() for c in self.email_criteria] - criteria = [c for c in criteria if c] + if not self.email_criteria: + criteria = [] + else: + criteria = [c and c.strip() for c in self.email_criteria] + criteria = [c for c in criteria if c] if subj: criteria.append('Subject "%s"' % subj) diff --git a/tests/sampling/test_tstamp.py b/tests/sampling/test_tstamp.py index ccf34ec85..fefb2696d 100644 --- a/tests/sampling/test_tstamp.py +++ b/tests/sampling/test_tstamp.py @@ -616,20 +616,24 @@ def test_parse_timestamps(self, case): self.check_timestamp(rcv, *verdicts) @ddt.data( - (None, []), - ('', []), - (' ', []), + (None, None, []), + (None, '', []), + (None, ' ', []), - (None, ['', ' ']), - ('', ['', ' ']), - (' ', ['', ' ']), + ([], None, []), + ([], '', []), + ([], ' ', []), + + (['', ' '], None, ['', ' ']), + (['', ' '], '', ['', ' ']), + (['', ' '], ' ', ['', ' ']), ) def test_criteria_stripping(self, case): - one, many = case - rcv = tstamp.TstampReceiver(email_criteria=many, + ecrts, one, projects = case + rcv = tstamp.TstampReceiver(email_criteria=ecrts, wait_criterio=one, subject_prefix=one) - crt = rcv._prepare_search_criteria(True, many) + crt = rcv._prepare_search_criteria(True, projects) self.assertEqual(crt, '') From 513e7b1d90f16094b947360434335cc0ee868311 Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Sat, 13 May 2017 21:16:07 +0200 Subject: [PATCH 05/15] feat(tstamp): eliminate dupes in project seearch ORed-terms, TCs --- co2mpas/sampling/tstamp.py | 2 +- tests/sampling/test_tstamp.py | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/co2mpas/sampling/tstamp.py b/co2mpas/sampling/tstamp.py index d0cbc5d99..015c3b6e9 100644 --- a/co2mpas/sampling/tstamp.py +++ b/co2mpas/sampling/tstamp.py @@ -814,7 +814,7 @@ def _prepare_search_criteria(self, is_wait, projects): parse_as_RFC3501_date(cal, after)) projects = [c and c.strip() for c in projects] - projects = [c for c in projects if c] + projects = list(set(c for c in projects if c)) if projects: criteria.append(pairwise_ORed(projects, lambda i: '(SUBJECT "%s")' % i)) diff --git a/tests/sampling/test_tstamp.py b/tests/sampling/test_tstamp.py index fefb2696d..72cec2e29 100644 --- a/tests/sampling/test_tstamp.py +++ b/tests/sampling/test_tstamp.py @@ -636,6 +636,18 @@ def test_criteria_stripping(self, case): crt = rcv._prepare_search_criteria(True, projects) self.assertEqual(crt, '') + def test_criteria_dupe_projects(self): + rcv = tstamp.TstampReceiver(email_criteria=[], + subject_prefix='') + crt = rcv._prepare_search_criteria(False, []) # sanity + self.assertEqual(crt, '') + + crt = rcv._prepare_search_criteria(False, ['ab', 'ab']) + self.assertNotIn('OR', crt) + + crt = rcv._prepare_search_criteria(False, ['ab', 'foo', 'ab']) + self.assertEqual(crt.count('OR'), 1) + @ddt.ddt class TstampShell(unittest.TestCase): From c5d1b39814677c158a35743ab735ab0f00024ae4 Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Sat, 13 May 2017 21:25:56 +0200 Subject: [PATCH 06/15] fix(tstamp): YAHOO screams with uncapitalied SBJECT IMAP keyword --- co2mpas/sampling/tstamp.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/co2mpas/sampling/tstamp.py b/co2mpas/sampling/tstamp.py index 015c3b6e9..defd71f75 100644 --- a/co2mpas/sampling/tstamp.py +++ b/co2mpas/sampling/tstamp.py @@ -795,7 +795,7 @@ def _prepare_search_criteria(self, is_wait, projects): criteria = [c for c in criteria if c] if subj: - criteria.append('Subject "%s"' % subj) + criteria.append('SUBJECT "%s"' % subj) if is_wait and waitcrt: criteria.append(waitcrt) From acc65a8e34146b7449d999df0505c47b87f4e0e1 Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Sat, 13 May 2017 23:30:41 +0200 Subject: [PATCH 07/15] refact(cfgcmd): extract match functions from `desc` to use with `show` --- co2mpas/sampling/cfgcmd.py | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/co2mpas/sampling/cfgcmd.py b/co2mpas/sampling/cfgcmd.py index 94cc254a1..654eb750d 100644 --- a/co2mpas/sampling/cfgcmd.py +++ b/co2mpas/sampling/cfgcmd.py @@ -14,6 +14,23 @@ from .._vendor import traitlets as trt +def prepare_matcher(terms, is_regex): + import re + + def matcher(r): + if is_regex: + return re.compile(r, re.I).search + else: + return lambda w: r.lower() in w.lower() + + matchers = [matcher(t) for t in terms] + + def match(word): + return any(m(word) for m in matchers) + + return match + + class ConfigCmd(baseapp.Cmd): """ Commands to manage configuration-options loaded from filesystem. @@ -272,20 +289,8 @@ def __init__(self, **kwds): ) def run(self, *args): - import re from toolz import dicttoolz as dtz - def matcher(r): - if self.regex: - return re.compile(r, re.I).search - else: - return lambda w: r.lower() in w.lower() - - matchers = [matcher(t) for t in args] - - def is_matching(word): - return any(m(word) for m in matchers) - ## Prefer to modify `class_names` after `initialize()`, or else, # the cmd options would be irrelevant and fatty :-) self.classes = self.all_app_configurables() @@ -307,7 +312,8 @@ def printer(name, v): cls, attr = v return cls.class_get_trait_help(attr) - res_map = dtz.keyfilter(is_matching, search_map) + match = prepare_matcher(args, self.regex) + res_map = dtz.keyfilter(match, search_map) for name, v in sorted(res_map.items()): if self.list: From 44de56e02e72c1a697d020ee85d98e8ce60c6168 Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Sat, 13 May 2017 23:50:44 +0200 Subject: [PATCH 08/15] fix(cfgcmd): desc-cmd was missing default flags/alias due to ctor + Was missing --verbose but not --vlevel... - NEED more investigation how they work:-) --- co2mpas/sampling/cfgcmd.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/co2mpas/sampling/cfgcmd.py b/co2mpas/sampling/cfgcmd.py index 654eb750d..240c09f8f 100644 --- a/co2mpas/sampling/cfgcmd.py +++ b/co2mpas/sampling/cfgcmd.py @@ -33,7 +33,7 @@ def match(word): class ConfigCmd(baseapp.Cmd): """ - Commands to manage configuration-options loaded from filesystem. + Commands to manage configuration-options loaded from filesystem, cmd-line or defaults. Read also the help message for `--config-paths` generic option. """ @@ -271,8 +271,8 @@ class DescCmd(baseapp.Cmd): def __init__(self, **kwds): import pandalone.utils as pndlu - super().__init__( - cmd_flags={ + kwds.setdefault( + 'cmd_flags', { ('l', 'list'): ( {type(self).__name__: {'list': True}}, pndlu.first_line(type(self).list.help) @@ -287,6 +287,7 @@ def __init__(self, **kwds): ), } ) + super().__init__(**kwds) def run(self, *args): from toolz import dicttoolz as dtz From 8296b3a7a0a5d16705aa718bedfd3609f19dc678 Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Sat, 13 May 2017 23:52:26 +0200 Subject: [PATCH 09/15] feat(cfgcmd): desc-cmd prints params in subclasses only when --verbose --- co2mpas/sampling/cfgcmd.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/co2mpas/sampling/cfgcmd.py b/co2mpas/sampling/cfgcmd.py index 240c09f8f..2dfe58d02 100644 --- a/co2mpas/sampling/cfgcmd.py +++ b/co2mpas/sampling/cfgcmd.py @@ -305,9 +305,13 @@ def printer(ne, cls): return cls.class_get_help() else: - search_map = {'%s.%s' % (cls.__name__, attr): (cls, trait) - for cls in all_classes - for attr, trait in cls.class_traits(config=True).items()} + search_map = { + '%s.%s' % (cls.__name__, attr): (cls, trait) + for cls in all_classes + for attr, trait in + (cls.class_traits + if self.verbose + else cls.class_own_traits)(config=True).items()} def printer(name, v): cls, attr = v From a9bffa141a83013a669528f4bb65d7cfe1e3b2a9 Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Sat, 13 May 2017 23:56:04 +0200 Subject: [PATCH 10/15] style(cfgcmd): del empty-lines --- co2mpas/sampling/cfgcmd.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/co2mpas/sampling/cfgcmd.py b/co2mpas/sampling/cfgcmd.py index 2dfe58d02..3b671b9e8 100644 --- a/co2mpas/sampling/cfgcmd.py +++ b/co2mpas/sampling/cfgcmd.py @@ -22,7 +22,7 @@ def matcher(r): return re.compile(r, re.I).search else: return lambda w: r.lower() in w.lower() - + matchers = [matcher(t) for t in terms] def match(word): @@ -240,6 +240,8 @@ class DescCmd(baseapp.Cmd): SYNTAX %(cmd_chain)s [OPTIONS] [] ... + + - Use --verbose to view config-params on all intermediate classes. """ examples = trt.Unicode(""" @@ -247,15 +249,14 @@ class DescCmd(baseapp.Cmd): %(cmd_chain)s --list 'criteria' %(cmd_chain)s -l --cls 'config' %(cmd_chain)s -l --regex '^t.+cmd' - To view help on specific parameters: %(cmd_chain)s wait %(cmd_chain)s -e 'rec.+wait' - + To view help on full classes: %(cmd_chain)s -ecl 'rec.+wait' """) - + list = trt.Bool( help="Just list any matches." ).tag(config=True) @@ -312,11 +313,11 @@ def printer(ne, cls): (cls.class_traits if self.verbose else cls.class_own_traits)(config=True).items()} - + def printer(name, v): cls, attr = v return cls.class_get_trait_help(attr) - + match = prepare_matcher(args, self.regex) res_map = dtz.keyfilter(match, search_map) From 48867e12964f79af7146552416e004e43a3dfcf1 Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Sun, 14 May 2017 15:30:18 +0200 Subject: [PATCH 11/15] feat(cfgcmd): desc-cmd disallow no-args to help user --- co2mpas/sampling/cfgcmd.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/co2mpas/sampling/cfgcmd.py b/co2mpas/sampling/cfgcmd.py index 3b671b9e8..f76187da0 100644 --- a/co2mpas/sampling/cfgcmd.py +++ b/co2mpas/sampling/cfgcmd.py @@ -239,8 +239,8 @@ class DescCmd(baseapp.Cmd): Describe config-params with their name '.' containing search-strings (case-insensitive). SYNTAX - %(cmd_chain)s [OPTIONS] [] ... - + %(cmd_chain)s [OPTIONS] [ ...] + - Use --verbose to view config-params on all intermediate classes. """ @@ -293,6 +293,10 @@ def __init__(self, **kwds): def run(self, *args): from toolz import dicttoolz as dtz + if len(args) == 0: + raise CmdException('Cmd %r takes at least one !' + % self.name) + ## Prefer to modify `class_names` after `initialize()`, or else, # the cmd options would be irrelevant and fatty :-) self.classes = self.all_app_configurables() From 5740a6151b8607d2b8d349f038bce767d439fb85 Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Sun, 14 May 2017 15:32:03 +0200 Subject: [PATCH 12/15] fix(proj): proj-cmds logged useless intent even when invalid args raised --- co2mpas/sampling/project.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/co2mpas/sampling/project.py b/co2mpas/sampling/project.py index a6d6ba2ff..6aa3865e7 100644 --- a/co2mpas/sampling/project.py +++ b/co2mpas/sampling/project.py @@ -1570,11 +1570,11 @@ class OpenCmd(_SubCmd): %(cmd_chain)s [OPTIONS] """ def run(self, *args): - self.log.info('Opening project %r...', args) if len(args) != 1: raise CmdException( "Cmd %r takes exactly one argument as the project-name, received %r!" % (self.name, args)) + self.log.info('Opening project %r...', args) projDB = self.projects_db proj = projDB.proj_open(args[0]) @@ -1947,6 +1947,7 @@ def __init__(self, **kwds): def run(self, *args): from . import tstamp + self.log.info("Receiving emails for projects(s) %s: ...", args) default_flow_style = None if self.verbose else False warn = self.log.warning rcver = tstamp.TstampReceiver(config=self.config) @@ -2154,10 +2155,11 @@ class BackupCmd(_SubCmd): ).tag(config=True) def run(self, *args): - self.log.info('Archiving repo into %r...', args) if len(args) > 1: raise CmdException('Cmd %r takes one optional filepath, received %d: %r!' % (self.name, len(args), args)) + self.log.info('Archiving repo into %r...', args) + archive_fpath = args and args[0] or None kwds = {} if archive_fpath: From af80c9afe59e4810395365893542cf655d68e32b Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Sun, 14 May 2017 19:15:42 +0200 Subject: [PATCH 13/15] refact(proj): `trecv` emit verdict before attempting to store it --- co2mpas/sampling/project.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/co2mpas/sampling/project.py b/co2mpas/sampling/project.py index 6aa3865e7..91b01ec16 100644 --- a/co2mpas/sampling/project.py +++ b/co2mpas/sampling/project.py @@ -1986,8 +1986,9 @@ def run(self, *args): mid, ex) ## Respect verbose flag for print-outs. - infos2 = rcver._get_recved_email_infos(mail, verdict) - yield _mydump({mid: infos2}, default_flow_style=default_flow_style) + if not self.verbose: + infos = rcver._get_recved_email_infos(mail, verdict) + yield _mydump({mid: infos}, default_flow_style=default_flow_style) class ExportCmd(_SubCmd): From 8157b6d1e354c090e94c523df4cc53bf4dd8293c Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Sun, 14 May 2017 20:08:06 +0200 Subject: [PATCH 14/15] feat(proj)); RENAME CMD `project tstamp-->tsend --- CHANGES.rst | 7 +++++++ co2mpas/sampling/project.py | 24 +++++++++++++++++------- co2mpas/sampling/tstamp.py | 3 ++- 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index ef607344c..3b7c9cb40 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -21,6 +21,13 @@ The Dice: timestamping_addresses --> tstamper_address ## Not a list anymore! TstampReceiver.subject --> TstampSpec.subject_prefix ## Also used by `recv` cmd. +- feat: renamed command: ``project tstamp -- > project tsend``. + Now there is symmetricity between ``co2dice tstamp`` and ``co2dice project`` + cmds:: + + tstamp send <--> project tsend + tstamp recv <--> project recv + - feat: new commands: - ``tstamp recv``: Fetch tstamps from IMAP server and derive *decisions* diff --git a/co2mpas/sampling/project.py b/co2mpas/sampling/project.py index 91b01ec16..47f99fd9a 100644 --- a/co2mpas/sampling/project.py +++ b/co2mpas/sampling/project.py @@ -1738,7 +1738,9 @@ class ReportCmd(_SubCmd): - Eventually the *Dice Report* parameters will be time-stamped and disseminated to TA authorities & oversight bodies with an email, to receive back the sampling decision. - - To get report ready for sending it MANUALLY, use tstamp` sub-command. + - To send the report to the stamper, use `tsend` sub-command. + - To get report ready for sending it MANUALLY, use `tsend --dry-run` + instead. """ @@ -1773,6 +1775,13 @@ def run(self, *args): class TstampCmd(_SubCmd): + """Deprecated: renamed as `tsend`!""" + def run(self, *args): + raise CmdException("Cmd %r has been renamed to %r!" + % (self.name, 'tsend')) + + +class TsendCmd(_SubCmd): """ IRREVOCABLY send report to the time-stamp service, or print it for sending it manually (--dry-run). @@ -1978,6 +1987,10 @@ def run(self, *args): mid, pname) continue + ## Respect verbose flag for print-outs. + infos = rcver._get_recved_email_infos(mail, verdict) + yield _mydump({mid: infos}, default_flow_style=default_flow_style) + try: proj.do_storedice(verdict=verdict) #report = proj.result # Not needed, we already have verdict. @@ -1985,11 +1998,6 @@ def run(self, *args): self.log.error('Failed storing %s email, due to: %s', mid, ex) - ## Respect verbose flag for print-outs. - if not self.verbose: - infos = rcver._get_recved_email_infos(mail, verdict) - yield _mydump({mid: infos}, default_flow_style=default_flow_style) - class ExportCmd(_SubCmd): """ @@ -2181,6 +2189,8 @@ def run(self, *args): all_subcmds = (LsCmd, InitCmd, OpenCmd, AppendCmd, ReportCmd, - TstampCmd, TrecvCmd, TparseCmd, + TstampCmd, ## TODO: delete deprecated `projext tsend` cmd + TsendCmd, + TrecvCmd, TparseCmd, StatusCmd, ExportCmd, ImportCmd, BackupCmd) diff --git a/co2mpas/sampling/tstamp.py b/co2mpas/sampling/tstamp.py index defd71f75..9f6096623 100644 --- a/co2mpas/sampling/tstamp.py +++ b/co2mpas/sampling/tstamp.py @@ -1122,7 +1122,8 @@ class SendCmd(baseapp.Cmd): SYNTAX %(cmd_chain)s [OPTIONS] [ ...] - - Do not use this command directly (unless experimenting) - prefer the `project tstamp` sub-command. + - Do not use this command directly (unless experimenting) - prefer + the `project tsend` sub-command. - If '-' is given or no files at all, it reads from STDIN. - Many options related to sending & receiving the email are expected to be stored in the config-file. - Use --verbose to print the timestamped email. From e32645aea10926609a7b982cfac67fa85c4e72a8 Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Sun, 14 May 2017 20:11:48 +0200 Subject: [PATCH 15/15] chore(ver): bump v1.6.0.b2-->v1.6.0.b3 --- README.rst | 12 ++++++------ co2mpas/_version.py | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/README.rst b/README.rst index e9b4b099d..71121be98 100644 --- a/README.rst +++ b/README.rst @@ -7,8 +7,8 @@ |co2mpas|: Vehicle simulator predicting NEDC |CO2| emissions from WLTP ###################################################################### -:release: 1.6.0.b2 -:date: 2017-05-13 00:45:12 +:release: 1.6.0.b3 +:date: 2017-05-14 08:10:10 :home: http://co2mpas.io/ :repository: https://github.com/JRCSTU/CO2MPAS-TA :pypi-repo: https://pypi.org/project/co2mpas/ @@ -346,7 +346,7 @@ Alternatively, open the CONSOLE and type the following command: ## Check co2mpas version. $ co2mpas -V - co2mpas-1.6.0.b2 + co2mpas-1.6.0.b3 |co2mpas| command syntax @@ -1348,7 +1348,7 @@ Install |co2mpas| package Downloading http://pypi.co2mpas.io/packages/co2mpas-... ... Installing collected packages: co2mpas - Successfully installed co2mpas-1.6.0.b2 + Successfully installed co2mpas-1.6.0.b3 .. Warning:: **Installation failures:** @@ -1368,8 +1368,8 @@ Install |co2mpas| package .. code-block:: console > co2mpas -vV - co2mpas_version: 1.6.0.b2 - co2mpas_rel_date: 2017-05-12 01:54:22 + co2mpas_version: 1.6.0.b3 + co2mpas_rel_date: 2017-05-14 08:10:10 co2mpas_path: d:\co2mpas_ALLINONE-64bit-v1.4.1\Apps\WinPython\python-3.4.3\lib\site-packages\co2mpas python_path: D:\co2mpas_ALLINONE-64bit-v1.4.1\WinPython\python-3.4.3 python_version: 3.4.3 (v3.4.3:9b73f1c3e601, Feb 24 2015, 22:44:40) [MSC v.1600 XXX] diff --git a/co2mpas/_version.py b/co2mpas/_version.py index fbba906dd..c01a015f8 100755 --- a/co2mpas/_version.py +++ b/co2mpas/_version.py @@ -9,7 +9,7 @@ #: Authoritative project's PEP 440 version. -__version__ = version = "1.6.0.b2" # Also update README.rst, CHANGES.rst, +__version__ = version = "1.6.0.b3" # Also update README.rst, CHANGES.rst, #: Input/Output file's version. __file_version__ = "2.2.6" @@ -21,4 +21,4 @@ # Please UPDATE TIMESTAMP WHEN BUMPING VERSIONS AND BEFORE RELEASE. #: Release date. -__updated__ = "2017-05-13 00:45:12" +__updated__ = "2017-05-14 08:10:10"