From bf261762436130089108a1c4919fa76b9bf0fb4a Mon Sep 17 00:00:00 2001 From: Scott Mcdermott Date: Fri, 28 Oct 2022 12:00:41 -0700 Subject: [PATCH] Allow specification of intervals to the export command This patch checks if intervals are given on cli to 'timew export', and if so will filter only those numbered IDs out from the db. This lets the user that already knows the interval(s) they want to know about, to ask for only those, without parsing the whole thing (similar to how we can do this for taskwarrior IDs). If both intervals and other filters -- time range or tags -- are given, this is considered an error. There would seem to be little use to AND or OR tags/ranges with IDs because anyone that knew IDs to request would already know those IDs met their requirement. Fixes #510 Code additions from @lauft PR notes (thanks!): - factor out 'filtering' so we can do only one call to getTracked() - simplify (tag || range) to .empty(), which already checks both - error message phrasing Signed-off-by: Scott Mcdermott --- doc/man1/timew-export.1.adoc | 6 +++--- src/commands/CmdExport.cpp | 29 +++++++++++++++++++++++------ test/export.t | 11 +++++++++++ 3 files changed, 37 insertions(+), 9 deletions(-) diff --git a/doc/man1/timew-export.1.adoc b/doc/man1/timew-export.1.adoc index fe38ec3a..a34771f7 100644 --- a/doc/man1/timew-export.1.adoc +++ b/doc/man1/timew-export.1.adoc @@ -5,13 +5,13 @@ timew-export - export tracked time in JSON == SYNOPSIS [verse] -*timew export* [__] [__**...**] +*timew export* [__**...**] | [[__] [__**...**]] == DESCRIPTION -Exports all the tracked time in JSON format. -Supports filtering. +Exports all the tracked time in JSON format. Supply either a list of interval IDs (e.g. `@1 @2`), or optional filters (see **timew-ranges(7)** and/or **timew-tags(1)**) == EXAMPLES For example: $ timew export from 2016-01-01 for 3wks tag1 + $ timew export @1 @3 @7 diff --git a/src/commands/CmdExport.cpp b/src/commands/CmdExport.cpp index 27e8ee5b..b92c39d9 100644 --- a/src/commands/CmdExport.cpp +++ b/src/commands/CmdExport.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -38,14 +39,30 @@ int CmdExport ( Database& database) { auto filter = cli.getFilter (); + std::set ids = cli.getIds (); + std::shared_ptr filtering; - IntervalFilterAndGroup filtering ({ - std::make_shared ( Range { filter.start, filter.end }), - std::make_shared (filter.tags()) - }); - - auto intervals = getTracked (database, rules, filtering); + if (!ids.empty ()) + { + if (!filter.empty ()) + { + throw std::string ("You cannot specify both id and tags/range to export intervals."); + } + filtering = std::make_shared (ids); + } + else + { + filtering = std::make_shared ( + std::vector > ( + { + std::make_shared (Range{filter.start, filter.end}), + std::make_shared (filter.tags ()), + } + ) + ); + } + auto intervals = getTracked (database, rules, *filtering); std::cout << jsonFromIntervals (intervals); return 0; diff --git a/test/export.t b/test/export.t index c6726e62..f38d4251 100755 --- a/test/export.t +++ b/test/export.t @@ -48,6 +48,17 @@ class TestExport(TestCase): code, out, err = self.t("export") self.assertIn("[\n]\n", out) + def test_fixed_id_export(self): + """Give specific IDs on CLI""" + self.t("track 2022-12-10T00:00:00Z - 2022-12-10T01:00:00Z") + self.t("track 2022-12-10T01:00:00Z - 2022-12-10T02:00:00Z") + self.t("track 2022-12-10T02:00:00Z - 2022-12-10T03:00:00Z") + self.t("track 2022-12-10T04:00:00Z - 2022-12-10T05:00:00Z") + j = self.t.export("@1 @4") + self.assertEqual(len(j), 2) + self.assertClosedInterval(j[0], expectedStart="20221210T000000Z", expectedId=4) + self.assertClosedInterval(j[1], expectedStart="20221210T040000Z", expectedId=1) + def test_single_unobstructed_interval(self): """Single unobstructed interval""" now_utc = datetime.now().utcnow()