mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-08-29 07:57:20 +02:00
Enhancement - file import
- Added support for configuration variables that override field mapping. - Updated documentation.
This commit is contained in:
parent
120593887b
commit
b8187e24ae
5 changed files with 107 additions and 22 deletions
|
@ -337,6 +337,28 @@ ID Project Pri Description
|
|||
</p>
|
||||
</dd>
|
||||
|
||||
<dt>import.synonym.id</dt>
|
||||
<dt>import.synonym.uuid</dt>
|
||||
<dt>import.synonym.status</dt>
|
||||
<dt>import.synonym.tags</dt>
|
||||
<dt>import.synonym.entry</dt>
|
||||
<dt>import.synonym.start</dt>
|
||||
<dt>import.synonym.due</dt>
|
||||
<dt>import.synonym.recur</dt>
|
||||
<dt>import.synonym.end</dt>
|
||||
<dt>import.synonym.project</dt>
|
||||
<dt>import.synonym.priority</dt>
|
||||
<dt>import.synonym.fg</dt>
|
||||
<dt>import.synonym.bg</dt>
|
||||
<dt>import.synonym.description</dt>
|
||||
<dd>
|
||||
If any of these configuration variables are found, they influence
|
||||
data import by specifying a single additional field name synonym.
|
||||
If a data import is failing because certain column names are not
|
||||
being recognized, then this is how the field mapping can be
|
||||
controlled.
|
||||
</dd>
|
||||
|
||||
<p>
|
||||
Note that the command:
|
||||
</p>
|
||||
|
@ -347,6 +369,8 @@ ID Project Pri Description
|
|||
will display the configuration variables found in the .taskrc file,
|
||||
and will warn you of any variables that are not recognized.
|
||||
</p>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<br />
|
||||
|
|
|
@ -50,13 +50,56 @@
|
|||
<li>Plain text files, with one task listed per line.
|
||||
<li>Task command line format.
|
||||
</ul>
|
||||
|
||||
Task makes a good effort to determine which of these formats a
|
||||
file is, and then imports accordingly.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
It would be wise to backup your task data files before an import.
|
||||
Task makes a good effort to determine which of these formats a
|
||||
file is. It does this by reading the file, and looking for
|
||||
familiar patterns. For example, the easiest files to recognize
|
||||
are those exported from task itself, because they all have a
|
||||
header line that comes in only three variations. Other formats
|
||||
are a little harder to identify, but they all have their own
|
||||
identifying characteristics.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The most complex import is when a CSV file is recognized.
|
||||
Task needs a field header line in order to map columns to task
|
||||
data items. For example, the if the following file is
|
||||
imported:
|
||||
</p>
|
||||
|
||||
<pre><code>number,status,task
|
||||
1,pending,task one
|
||||
2,pending,task two</code></pre>
|
||||
|
||||
<p>
|
||||
Task will map the "number" field to task's "id" field, etc,
|
||||
based on name. Task has a list of synonyms that it uses to
|
||||
map fields, but you can specify your own override with any of
|
||||
the following configuration variables:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>import.synonym.id
|
||||
<li>import.synonym.uuid
|
||||
<li>import.synonym.status
|
||||
<li>import.synonym.tags
|
||||
<li>import.synonym.entry
|
||||
<li>import.synonym.start
|
||||
<li>import.synonym.due
|
||||
<li>import.synonym.recur
|
||||
<li>import.synonym.end
|
||||
<li>import.synonym.project
|
||||
<li>import.synonym.priority
|
||||
<li>import.synonym.fg
|
||||
<li>import.synonym.bg
|
||||
<li>import.synonym.description
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
Please note that it is wise to backup your task data files
|
||||
before an import.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -372,7 +372,12 @@ std::string handleVersion (Config& conf)
|
|||
"color.pri.L color.pri.M color.pri.none color.recurring color.tagged "
|
||||
"confirmation curses data.location dateformat default.command "
|
||||
"default.priority defaultwidth due echo.command locking monthsperline nag "
|
||||
"next project shadow.command shadow.file shadow.notify";
|
||||
"next project shadow.command shadow.file shadow.notify "
|
||||
"import.synonym.id import.synonym.uuid import.synonym.status "
|
||||
"import.synonym.tags import.synonym.entry import.synonym.start "
|
||||
"import.synonym.due import.synonym.recur import.synonym.end "
|
||||
"import.synonym.project import.synonym.priority import.synonym.fg "
|
||||
"import.synonym.bg import.synonym.description";
|
||||
|
||||
// This configuration variable is supported, but not documented. It exists
|
||||
// so that unit tests can force color to be on even when the output from task
|
||||
|
|
|
@ -917,7 +917,8 @@ static std::string importCSV (
|
|||
std::string name = lowerCase (trim (unquoteText (trim (headings[h]))));
|
||||
|
||||
// If there is a mapping for the field, use the value.
|
||||
if (name == "id" ||
|
||||
if (name == conf.get ("import.synonym.id") ||
|
||||
name == "id" ||
|
||||
name == "#" ||
|
||||
name == "sequence" ||
|
||||
name.find ("num") != std::string::npos)
|
||||
|
@ -925,28 +926,32 @@ static std::string importCSV (
|
|||
mapping["id"] = (int)h;
|
||||
}
|
||||
|
||||
else if (name == "uuid" ||
|
||||
else if (name == conf.get ("import.synonym.uuid") ||
|
||||
name == "uuid" ||
|
||||
name == "guid" ||
|
||||
name.find ("unique") != std::string::npos)
|
||||
{
|
||||
mapping["uuid"] = (int)h;
|
||||
}
|
||||
|
||||
else if (name == "status" ||
|
||||
else if (name == conf.get ("import.synonym.status") ||
|
||||
name == "status" ||
|
||||
name == "condition" ||
|
||||
name == "state")
|
||||
{
|
||||
mapping["status"] = (int)h;
|
||||
}
|
||||
|
||||
else if (name == "tags" ||
|
||||
else if (name == conf.get ("import.synonym.tags") ||
|
||||
name == "tags" ||
|
||||
name.find ("categor") != std::string::npos ||
|
||||
name.find ("tag") != std::string::npos)
|
||||
{
|
||||
mapping["tags"] = (int)h;
|
||||
}
|
||||
|
||||
else if (name == "entry" ||
|
||||
else if (name == conf.get ("import.synonym.entry") ||
|
||||
name == "entry" ||
|
||||
name.find ("added") != std::string::npos ||
|
||||
name.find ("created") != std::string::npos ||
|
||||
name.find ("entered") != std::string::npos)
|
||||
|
@ -954,62 +959,71 @@ static std::string importCSV (
|
|||
mapping["entry"] = (int)h;
|
||||
}
|
||||
|
||||
else if (name == "start" ||
|
||||
else if (name == conf.get ("import.synonym.start") ||
|
||||
name == "start" ||
|
||||
name.find ("began") != std::string::npos ||
|
||||
name.find ("begun") != std::string::npos ||
|
||||
name.find ("started") != std::string::npos ||
|
||||
name == "")
|
||||
name.find ("started") != std::string::npos)
|
||||
{
|
||||
mapping["start"] = (int)h;
|
||||
}
|
||||
|
||||
else if (name == "due" ||
|
||||
else if (name == conf.get ("import.synonym.due") ||
|
||||
name == "due" ||
|
||||
name.find ("expected") != std::string::npos)
|
||||
{
|
||||
mapping["due"] = (int)h;
|
||||
}
|
||||
|
||||
else if (name == "recur" ||
|
||||
else if (name == conf.get ("import.synonym.recur") ||
|
||||
name == "recur" ||
|
||||
name == "frequency")
|
||||
{
|
||||
mapping["recur"] = (int)h;
|
||||
}
|
||||
|
||||
else if (name == "end" ||
|
||||
else if (name == conf.get ("import.synonym.end") ||
|
||||
name == "end" ||
|
||||
name == "done" ||
|
||||
name.find ("complete") != std::string::npos)
|
||||
{
|
||||
mapping["end"] = (int)h;
|
||||
}
|
||||
|
||||
else if (name == "project" ||
|
||||
else if (name == conf.get ("import.synonym.project") ||
|
||||
name == "project" ||
|
||||
name.find ("proj") != std::string::npos)
|
||||
{
|
||||
mapping["project"] = (int)h;
|
||||
}
|
||||
|
||||
else if (name == "priority" ||
|
||||
else if (name == conf.get ("import.synonym.priority") ||
|
||||
name == "priority" ||
|
||||
name == "pri" ||
|
||||
name.find ("importan") != std::string::npos)
|
||||
{
|
||||
mapping["priority"] = (int)h;
|
||||
}
|
||||
|
||||
else if (name.find ("fg") != std::string::npos ||
|
||||
else if (name == conf.get ("import.synonym.fg") ||
|
||||
name.find ("fg") != std::string::npos ||
|
||||
name.find ("foreground") != std::string::npos ||
|
||||
name.find ("color") != std::string::npos)
|
||||
{
|
||||
mapping["fg"] = (int)h;
|
||||
}
|
||||
|
||||
else if (name == "bg" ||
|
||||
else if (name == conf.get ("import.synonym.bg") ||
|
||||
name == "bg" ||
|
||||
name.find ("background") != std::string::npos)
|
||||
{
|
||||
mapping["bg"] = (int)h;
|
||||
}
|
||||
|
||||
else if (name.find ("desc") != std::string::npos ||
|
||||
else if (name == conf.get ("import.synonym.description") ||
|
||||
name.find ("desc") != std::string::npos ||
|
||||
name.find ("detail") != std::string::npos ||
|
||||
name.find ("task") != std::string::npos ||
|
||||
name.find ("what") != std::string::npos)
|
||||
{
|
||||
mapping["description"] = (int)h;
|
||||
|
|
|
@ -864,7 +864,6 @@ std::string runTaskCommand (
|
|||
else if (command == "import") { cmdMod = true; out = handleImport (tdb, task, conf); }
|
||||
|
||||
// Command that display IDs and therefore need TDB::gc first.
|
||||
|
||||
else if (command == "completed") { if (gc) gcMod = tdb.gc (); out = handleCompleted (tdb, task, conf); }
|
||||
else if (command == "next") { if (gc) gcMod = tdb.gc (); out = handleReportNext (tdb, task, conf); }
|
||||
else if (command == "active") { if (gc) gcMod = tdb.gc (); out = handleReportActive (tdb, task, conf); }
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue