mirror of
https://github.com/GothenburgBitFactory/timewarrior.git
synced 2025-07-07 20:06:39 +02:00
Add configurable default range for reports
Query rule 'reports.<name>.range' for the specific default range of the report. Use rule 'reports.range' to configure an overall default range for all reports. Make internal reports 'summary', 'month', 'week', 'day', and 'gaps' use this feature. Closes #477 Signed-off-by: Thomas Lauf <thomas.lauf@tngtech.com>
This commit is contained in:
parent
d056719a36
commit
5265b26e86
8 changed files with 84 additions and 11 deletions
1
AUTHORS
1
AUTHORS
|
@ -104,3 +104,4 @@ Thanks to the following, who submitted detailed bug reports and excellent sugges
|
|||
eq0cdk
|
||||
squirrellyDave
|
||||
Edd Salkield
|
||||
Oivvio Polite
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
- #470 Do not leak filter in IntervalFilterFirstOf
|
||||
(thanks to Shaun Ruffel)
|
||||
- #474 Make display of ids and annotations in summary report configurable
|
||||
- #477 Add configurable default range for reports
|
||||
(thanks to Oivvio Polite)
|
||||
- #478 Add support for XDG Base Directory specification on Unixes
|
||||
(Thanks to Stanisław Wysocki)
|
||||
- #491 Tracking an interval in the future while actively tracking time results in a database inconsistency
|
||||
|
|
|
@ -14,6 +14,7 @@ A chart summarizes the tracked and untracked time with colored blocks drawn on a
|
|||
It accepts date ranges and tags for filtering.
|
||||
There are three types: *day*, *week*, and *month* with their respective commands.
|
||||
The **reports.**__<type>__**.range** configuration setting overrides the default date range.
|
||||
One can override the global default date range with the **reports.range** configuration.
|
||||
For more details, and precise times, use the 'summary' report.
|
||||
|
||||
*month*::
|
||||
|
|
|
@ -18,3 +18,14 @@ This does however assume there is a 'foo' extension installed.
|
|||
|
||||
The return code is the return code of the extension.
|
||||
If the extension produces no output and a non-zero rc, then 255 is returned.
|
||||
|
||||
== CONFIGURATION
|
||||
|
||||
**reports.range**::
|
||||
Sets the default date range for all reports.
|
||||
The value has to be a range hint, see timew-hints(7).
|
||||
Defaults to `:all`
|
||||
|
||||
**reports.**__<name>__**.range**::
|
||||
Set the date range for report _name_, where _name_ is the name of the report executable without its extension (i.e. a report executable 'foo.py' is referred to by 'foo').
|
||||
The value has to be a range hint, see timew-hints(7).
|
||||
|
|
|
@ -37,6 +37,11 @@ Determines whether the id column is shown in the summary.
|
|||
Can be overridden by the ':ids' and ':no-ids' hint, respectively.
|
||||
Default value is 'no'
|
||||
|
||||
**reports.summary.range**::
|
||||
Set the date range for the summary report.
|
||||
The value has to be a range hint, see timew-hints(7).
|
||||
Default value is ':day'
|
||||
|
||||
**tags.**__<tag>__**.color**::
|
||||
Assigns a specific foreground and background color to a tag.
|
||||
Examples of valid colors include 'white', 'gray8', 'black on yellow', and 'rgb345'.
|
||||
|
|
|
@ -48,8 +48,11 @@ int CmdChartDay (
|
|||
Rules& rules,
|
||||
Database& database)
|
||||
{
|
||||
auto default_hint = rules.get ("reports.range", ":day");
|
||||
auto report_hint = rules.get ("reports.day.range", default_hint);
|
||||
|
||||
Range default_range = {};
|
||||
expandIntervalHint (rules.get ("reports.day.range", ":day"), default_range);
|
||||
expandIntervalHint (report_hint, default_range);
|
||||
|
||||
// Create a filter, and if empty, choose the current day.
|
||||
auto filter = cli.getFilter (default_range);
|
||||
|
@ -63,8 +66,11 @@ int CmdChartWeek (
|
|||
Rules& rules,
|
||||
Database& database)
|
||||
{
|
||||
auto default_hint = rules.get ("reports.range", ":week");
|
||||
auto report_hint = rules.get ("reports.week.range", default_hint);
|
||||
|
||||
Range default_range = {};
|
||||
expandIntervalHint (rules.get ("reports.week.range", ":week"), default_range);
|
||||
expandIntervalHint (report_hint, default_range);
|
||||
|
||||
// Create a filter, and if empty, choose the current week.
|
||||
auto filter = cli.getFilter (default_range);
|
||||
|
@ -78,8 +84,11 @@ int CmdChartMonth (
|
|||
Rules& rules,
|
||||
Database& database)
|
||||
{
|
||||
auto default_hint = rules.get ("reports.range", ":month");
|
||||
auto report_hint = rules.get ("reports.month.range", default_hint);
|
||||
|
||||
Range default_range = {};
|
||||
expandIntervalHint (rules.get ("reports.month.range", ":month"), default_range);
|
||||
expandIntervalHint (report_hint, default_range);
|
||||
|
||||
// Create a filter, and if empty, choose the current month.
|
||||
auto filter = cli.getFilter (default_range);
|
||||
|
|
|
@ -77,6 +77,35 @@ static std::string findExtension (
|
|||
return "";
|
||||
}
|
||||
|
||||
std::string basename (const std::string &script_path)
|
||||
{
|
||||
const auto lastSlash = script_path.find_last_of ('/');
|
||||
|
||||
if (lastSlash != std::string::npos)
|
||||
{
|
||||
return script_path.substr (lastSlash + 1);
|
||||
}
|
||||
|
||||
return script_path;
|
||||
}
|
||||
|
||||
std::string dropExtension (const std::string& basename)
|
||||
{
|
||||
const auto lastDot = basename.find_last_of ('.');
|
||||
|
||||
if (lastDot != std::string::npos)
|
||||
{
|
||||
return basename.substr (0, lastDot);
|
||||
}
|
||||
|
||||
return basename;
|
||||
}
|
||||
|
||||
std::string getScriptName (const std::string& script_path)
|
||||
{
|
||||
return dropExtension (basename (script_path));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int CmdReport (
|
||||
const CLI& cli,
|
||||
|
@ -84,22 +113,30 @@ int CmdReport (
|
|||
Database& database,
|
||||
const Extensions& extensions)
|
||||
{
|
||||
std::string script;
|
||||
std::string script_path;
|
||||
for (auto& arg : cli._args)
|
||||
{
|
||||
if (arg.hasTag ("EXT"))
|
||||
{
|
||||
script = findExtension (extensions, arg.attribute ("canonical"));
|
||||
script_path = findExtension (extensions, arg.attribute ("canonical"));
|
||||
}
|
||||
}
|
||||
|
||||
if (script.empty ())
|
||||
if (script_path.empty ())
|
||||
{
|
||||
throw std::string ("Specify which report to run.");
|
||||
}
|
||||
|
||||
// Compose Header info.
|
||||
auto filter = cli.getFilter ();
|
||||
auto script_name = getScriptName (script_path);
|
||||
auto default_hint = rules.get ("reports.range", ":all");
|
||||
auto report_hint = rules.get (format ("reports.{1}.range", script_name), default_hint);
|
||||
|
||||
Range default_range = {};
|
||||
expandIntervalHint (report_hint, default_range);
|
||||
|
||||
// Create a filter, and if empty, choose the current week.
|
||||
auto filter = cli.getFilter (default_range);
|
||||
|
||||
IntervalFilterAndGroup filtering ({
|
||||
std::make_shared <IntervalFilterAllInRange> ( Range { filter.start, filter.end }),
|
||||
std::make_shared <IntervalFilterAllWithTags> (filter.tags ())
|
||||
|
@ -107,6 +144,7 @@ int CmdReport (
|
|||
|
||||
auto tracked = getTracked (database, rules, filtering);
|
||||
|
||||
// Compose Header info.
|
||||
rules.set ("temp.report.start", filter.is_started () ? filter.start.toISO () : "");
|
||||
rules.set ("temp.report.end", filter.is_ended () ? filter.end.toISO () : "");
|
||||
rules.set ("temp.report.tags", joinQuotedIfNeeded (",", filter.tags ()));
|
||||
|
@ -123,10 +161,10 @@ int CmdReport (
|
|||
|
||||
// Run the extensions.
|
||||
std::vector <std::string> output;
|
||||
int rc = extensions.callExtension (script, split (input, '\n'), output);
|
||||
int rc = extensions.callExtension (script_path, split (input, '\n'), output);
|
||||
if (rc != 0 && output.size () == 0)
|
||||
{
|
||||
throw format ("'{1}' returned {2} without producing output.", script, rc);
|
||||
throw format ("'{1}' returned {2} without producing output.", script_path, rc);
|
||||
}
|
||||
|
||||
// Display the output.
|
||||
|
|
|
@ -48,7 +48,13 @@ int CmdSummary (
|
|||
const bool verbose = rules.getBoolean ("verbose");
|
||||
|
||||
// Create a filter, and if empty, choose 'today'.
|
||||
auto filter = cli.getFilter (Range { Datetime ("today"), Datetime ("tomorrow") });
|
||||
auto default_hint = rules.get ("reports.range", ":day");
|
||||
auto report_hint = rules.get ("reports.summary.range", default_hint);
|
||||
|
||||
Range default_range = {};
|
||||
expandIntervalHint (report_hint, default_range);
|
||||
|
||||
auto filter = cli.getFilter (default_range);
|
||||
|
||||
// Load the data.
|
||||
IntervalFilterAndGroup filtering ({
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue