mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-08-28 22:47:20 +02:00
Task: Added a code path allowing parseJSON to be handed a JSON tree
This commit is contained in:
parent
965b7cfd3d
commit
5995320164
2 changed files with 102 additions and 98 deletions
198
src/Task.cpp
198
src/Task.cpp
|
@ -41,7 +41,6 @@
|
||||||
#include <Date.h>
|
#include <Date.h>
|
||||||
#include <Duration.h>
|
#include <Duration.h>
|
||||||
#include <Task.h>
|
#include <Task.h>
|
||||||
#include <JSON.h>
|
|
||||||
#ifdef PRODUCT_TASKWARRIOR
|
#ifdef PRODUCT_TASKWARRIOR
|
||||||
#include <RX.h>
|
#include <RX.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -624,115 +623,118 @@ void Task::parseJSON (const std::string& line)
|
||||||
{
|
{
|
||||||
// Parse the whole thing.
|
// Parse the whole thing.
|
||||||
json::value* root = json::parse (line);
|
json::value* root = json::parse (line);
|
||||||
if (root->type () == json::j_object)
|
if (root &&
|
||||||
|
root->type () == json::j_object)
|
||||||
|
parseJSON ((json::object*) root);
|
||||||
|
|
||||||
|
delete root;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
void Task::parseJSON (const json::object* root_obj)
|
||||||
|
{
|
||||||
|
// For each object element...
|
||||||
|
for (auto& i : root_obj->_data)
|
||||||
{
|
{
|
||||||
json::object* root_obj = (json::object*)root;
|
// If the attribute is a recognized column.
|
||||||
|
std::string type = Task::attributes[i.first];
|
||||||
// For each object element...
|
if (type != "")
|
||||||
for (auto& i : root_obj->_data)
|
|
||||||
{
|
{
|
||||||
// If the attribute is a recognized column.
|
// Any specified id is ignored.
|
||||||
std::string type = Task::attributes[i.first];
|
if (i.first == "id")
|
||||||
if (type != "")
|
;
|
||||||
|
|
||||||
|
// Urgency, if present, is ignored.
|
||||||
|
else if (i.first == "urgency")
|
||||||
|
;
|
||||||
|
|
||||||
|
// TW-1274 Standardization.
|
||||||
|
else if (i.first == "modification")
|
||||||
{
|
{
|
||||||
// Any specified id is ignored.
|
Date d (unquoteText (i.second->dump ()));
|
||||||
if (i.first == "id")
|
set ("modified", d.toEpochString ());
|
||||||
;
|
|
||||||
|
|
||||||
// Urgency, if present, is ignored.
|
|
||||||
else if (i.first == "urgency")
|
|
||||||
;
|
|
||||||
|
|
||||||
// TW-1274 Standardization.
|
|
||||||
else if (i.first == "modification")
|
|
||||||
{
|
|
||||||
Date d (unquoteText (i.second->dump ()));
|
|
||||||
set ("modified", d.toEpochString ());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dates are converted from ISO to epoch.
|
|
||||||
else if (type == "date")
|
|
||||||
{
|
|
||||||
std::string text = unquoteText (i.second->dump ());
|
|
||||||
Date d (text);
|
|
||||||
set (i.first, text == "" ? "" : d.toEpochString ());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tags are an array of JSON strings.
|
|
||||||
else if (i.first == "tags" && i.second->type() == json::j_array)
|
|
||||||
{
|
|
||||||
json::array* tags = (json::array*)i.second;
|
|
||||||
for (auto& t : tags->_data)
|
|
||||||
{
|
|
||||||
json::string* tag = (json::string*)t;
|
|
||||||
addTag (tag->_data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// This is a temporary measure to allow Mirakel sync, and will be removed
|
|
||||||
// in a future release.
|
|
||||||
else if (i.first == "tags" && i.second->type() == json::j_string)
|
|
||||||
{
|
|
||||||
json::string* tag = (json::string*)i.second;
|
|
||||||
addTag (tag->_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Strings are decoded.
|
|
||||||
else if (type == "string")
|
|
||||||
set (i.first, json::decode (unquoteText (i.second->dump ())));
|
|
||||||
|
|
||||||
// Other types are simply added.
|
|
||||||
else
|
|
||||||
set (i.first, unquoteText (i.second->dump ()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// UDA orphans and annotations do not have columns.
|
// Dates are converted from ISO to epoch.
|
||||||
|
else if (type == "date")
|
||||||
|
{
|
||||||
|
std::string text = unquoteText (i.second->dump ());
|
||||||
|
Date d (text);
|
||||||
|
set (i.first, text == "" ? "" : d.toEpochString ());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tags are an array of JSON strings.
|
||||||
|
else if (i.first == "tags" && i.second->type() == json::j_array)
|
||||||
|
{
|
||||||
|
json::array* tags = (json::array*)i.second;
|
||||||
|
for (auto& t : tags->_data)
|
||||||
|
{
|
||||||
|
json::string* tag = (json::string*)t;
|
||||||
|
addTag (tag->_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// This is a temporary measure to allow Mirakel sync, and will be removed
|
||||||
|
// in a future release.
|
||||||
|
else if (i.first == "tags" && i.second->type() == json::j_string)
|
||||||
|
{
|
||||||
|
json::string* tag = (json::string*)i.second;
|
||||||
|
addTag (tag->_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Strings are decoded.
|
||||||
|
else if (type == "string")
|
||||||
|
set (i.first, json::decode (unquoteText (i.second->dump ())));
|
||||||
|
|
||||||
|
// Other types are simply added.
|
||||||
|
else
|
||||||
|
set (i.first, unquoteText (i.second->dump ()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// UDA orphans and annotations do not have columns.
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Annotations are an array of JSON objects with 'entry' and
|
||||||
|
// 'description' values and must be converted.
|
||||||
|
if (i.first == "annotations")
|
||||||
|
{
|
||||||
|
std::map <std::string, std::string> annos;
|
||||||
|
|
||||||
|
json::array* atts = (json::array*)i.second;
|
||||||
|
for (auto& annotations : atts->_data)
|
||||||
|
{
|
||||||
|
json::object* annotation = (json::object*)annotations;
|
||||||
|
json::string* when = (json::string*)annotation->_data["entry"];
|
||||||
|
json::string* what = (json::string*)annotation->_data["description"];
|
||||||
|
|
||||||
|
if (! when)
|
||||||
|
throw format (STRING_TASK_NO_ENTRY, root_obj->dump ());
|
||||||
|
|
||||||
|
if (! what)
|
||||||
|
throw format (STRING_TASK_NO_DESC, root_obj->dump ());
|
||||||
|
|
||||||
|
std::string name = "annotation_" + Date (when->_data).toEpochString ();
|
||||||
|
annos.insert (std::make_pair (name, json::decode (what->_data)));
|
||||||
|
}
|
||||||
|
|
||||||
|
setAnnotations (annos);
|
||||||
|
}
|
||||||
|
|
||||||
|
// UDA Orphan - must be preserved.
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Annotations are an array of JSON objects with 'entry' and
|
|
||||||
// 'description' values and must be converted.
|
|
||||||
if (i.first == "annotations")
|
|
||||||
{
|
|
||||||
std::map <std::string, std::string> annos;
|
|
||||||
|
|
||||||
json::array* atts = (json::array*)i.second;
|
|
||||||
for (auto& annotations : atts->_data)
|
|
||||||
{
|
|
||||||
json::object* annotation = (json::object*)annotations;
|
|
||||||
json::string* when = (json::string*)annotation->_data["entry"];
|
|
||||||
json::string* what = (json::string*)annotation->_data["description"];
|
|
||||||
|
|
||||||
if (! when)
|
|
||||||
throw format (STRING_TASK_NO_ENTRY, line);
|
|
||||||
|
|
||||||
if (! what)
|
|
||||||
throw format (STRING_TASK_NO_DESC, line);
|
|
||||||
|
|
||||||
std::string name = "annotation_" + Date (when->_data).toEpochString ();
|
|
||||||
annos.insert (std::make_pair (name, json::decode (what->_data)));
|
|
||||||
}
|
|
||||||
|
|
||||||
setAnnotations (annos);
|
|
||||||
}
|
|
||||||
|
|
||||||
// UDA Orphan - must be preserved.
|
|
||||||
else
|
|
||||||
{
|
|
||||||
#ifdef PRODUCT_TASKWARRIOR
|
#ifdef PRODUCT_TASKWARRIOR
|
||||||
std::stringstream message;
|
std::stringstream message;
|
||||||
message << "Task::parseJSON found orphan '"
|
message << "Task::parseJSON found orphan '"
|
||||||
<< i.first
|
<< i.first
|
||||||
<< "' with value '"
|
<< "' with value '"
|
||||||
<< i.second
|
<< i.second
|
||||||
<< "' --> preserved\n";
|
<< "' --> preserved\n";
|
||||||
context.debug (message.str ());
|
context.debug (message.str ());
|
||||||
#endif
|
#endif
|
||||||
set (i.first, json::decode (unquoteText (i.second->dump ())));
|
set (i.first, json::decode (unquoteText (i.second->dump ())));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
delete root;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include <JSON.h>
|
||||||
|
|
||||||
class Task : public std::map <std::string, std::string>
|
class Task : public std::map <std::string, std::string>
|
||||||
{
|
{
|
||||||
|
@ -157,6 +158,7 @@ public:
|
||||||
private:
|
private:
|
||||||
int determineVersion (const std::string&);
|
int determineVersion (const std::string&);
|
||||||
void parseJSON (const std::string&);
|
void parseJSON (const std::string&);
|
||||||
|
void parseJSON (const json::object*);
|
||||||
void parseLegacy (const std::string&);
|
void parseLegacy (const std::string&);
|
||||||
void validate_before (const std::string&, const std::string&);
|
void validate_before (const std::string&, const std::string&);
|
||||||
const std::string encode (const std::string&) const;
|
const std::string encode (const std::string&) const;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue