FF4/JSON Interop

- Removed the \n characters from Task::composeFF4 and Task::ComposeJSON.
- Tasks in backlog.data file are now written as JSON.
- Tasks are recognized in FF4 or JSON format.
This commit is contained in:
Paul Beckingham 2013-06-02 20:38:58 -04:00
parent 29e9dbcea6
commit 4133d29cca
5 changed files with 59 additions and 59 deletions

View file

@ -223,7 +223,7 @@ void TF2::commit ()
task != _added_tasks.end (); task != _added_tasks.end ();
++task) ++task)
{ {
_file.append (task->composeF4 ()); _file.append (task->composeF4 () + "\n");
} }
_added_tasks.clear (); _added_tasks.clear ();
@ -255,7 +255,7 @@ void TF2::commit ()
task != _tasks.end (); task != _tasks.end ();
++task) ++task)
{ {
_file.append (task->composeF4 ()); _file.append (task->composeF4 () + "\n");
} }
// Write out all the added lines. // Write out all the added lines.
@ -565,12 +565,12 @@ void TDB2::add (Task& task, bool add_to_backlog /* = true */)
// new <task> // new <task>
// --- // ---
undo.add_line ("time " + Date ().toEpochString () + "\n"); undo.add_line ("time " + Date ().toEpochString () + "\n");
undo.add_line ("new " + task.composeF4 ()); undo.add_line ("new " + task.composeF4 () + "\n");
undo.add_line ("---\n"); undo.add_line ("---\n");
// Add task to backlog. // Add task to backlog.
if (add_to_backlog) if (add_to_backlog)
backlog.add_task (task); backlog.add_line (task.composeJSON () + "\n");
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -597,13 +597,13 @@ void TDB2::modify (Task& task, bool add_to_backlog /* = true */)
// new <task> // new <task>
// --- // ---
undo.add_line ("time " + Date ().toEpochString () + "\n"); undo.add_line ("time " + Date ().toEpochString () + "\n");
undo.add_line ("old " + original.composeF4 ()); undo.add_line ("old " + original.composeF4 () + "\n");
undo.add_line ("new " + task.composeF4 ()); undo.add_line ("new " + task.composeF4 () + "\n");
undo.add_line ("---\n"); undo.add_line ("---\n");
// Add modified task to backlog. // Add modified task to backlog.
if (add_to_backlog) if (add_to_backlog)
backlog.add_task (task); backlog.add_line (task.composeJSON () + "\n");
} }
} }
@ -1112,9 +1112,7 @@ void TDB2::merge (const std::string& mergeFile)
<< "\n"; << "\n";
*/ */
// remove the \n from composeF4() string
std::string newline = tmod.getAfter ().composeF4 (); std::string newline = tmod.getAfter ().composeF4 ();
newline = newline.substr (0, newline.length ()-1);
// does the tasks move to pending data? // does the tasks move to pending data?
// this taskmod will not arise from // this taskmod will not arise from
@ -1154,10 +1152,7 @@ void TDB2::merge (const std::string& mergeFile)
cutOff (tmod.getBefore ().get ("description"), 10)) cutOff (tmod.getBefore ().get ("description"), 10))
<< "\n"; << "\n";
// remove the \n from composeF4() string
// which will replace the current line
std::string newline = tmod.getAfter ().composeF4 (); std::string newline = tmod.getAfter ().composeF4 ();
newline = newline.substr (0, newline.length ()-1);
// does the tasks move to completed data // does the tasks move to completed data
if ( (statusAfter == Task::completed) if ( (statusAfter == Task::completed)
@ -1215,10 +1210,7 @@ void TDB2::merge (const std::string& mergeFile)
cutOff (tmod.getAfter ().get ("description"), 10)) cutOff (tmod.getAfter ().get ("description"), 10))
<< "\n"; << "\n";
// remove the \n from composeF4() string pending_lines.push_back (tmod.getAfter ().composeF4 ());
std::string newline = tmod.getAfter ().composeF4 ();
newline = newline.substr (0, newline.length ()-1);
pending_lines.push_back (newline);
} }
else else
{ {

View file

@ -399,49 +399,53 @@ void Task::parse (const std::string& input)
try try
{ {
// File format version 4, from 2009-5-16 - now, v1.7.1+ // File format version 4, from 2009-5-16 - now, v1.7.1+
// This is the parse format tried first, because it is most used.
clear (); clear ();
Nibbler n (copy); if (copy[0] == '[')
std::string line;
if (n.skip ('[') &&
n.getUntil (']', line) &&
n.skip (']') &&
n.depleted ())
{ {
if (line.length () == 0) Nibbler n (copy);
throw std::string (STRING_RECORD_EMPTY); std::string line;
if (n.skip ('[') &&
Nibbler nl (line); n.getUntil (']', line) &&
std::string name; n.skip (']') &&
std::string value; n.depleted ())
while (!nl.depleted ())
{ {
if (nl.getUntil (':', name) && if (line.length () == 0)
nl.skip (':') && throw std::string (STRING_RECORD_EMPTY);
nl.getQuoted ('"', value))
Nibbler nl (line);
std::string name;
std::string value;
while (!nl.depleted ())
{ {
// Experimental legacy value translation of 'recur:m' --> 'recur:mo'. if (nl.getUntil (':', name) &&
if (name == "recur" && nl.skip (':') &&
digitsOnly (value.substr (0, value.length () - 1)) && nl.getQuoted ('"', value))
value[value.length () - 1] == 'm') {
value += 'o'; // Experimental legacy value translation of 'recur:m' --> 'recur:mo'.
if (name == "recur" &&
digitsOnly (value.substr (0, value.length () - 1)) &&
value[value.length () - 1] == 'm')
value += 'o';
if (name.substr (0, 11) == "annotation_") if (name.substr (0, 11) == "annotation_")
++annotation_count; ++annotation_count;
(*this)[name] = decode (json::decode (value)); (*this)[name] = decode (json::decode (value));
}
nl.skip (' ');
} }
nl.skip (' '); std::string remainder;
nl.getUntilEOS (remainder);
if (remainder.length ())
throw std::string (STRING_RECORD_JUNK_AT_EOL);
} }
std::string remainder;
nl.getUntilEOS (remainder);
if (remainder.length ())
throw std::string (STRING_RECORD_JUNK_AT_EOL);
} }
else if (input[0] == '{') else if (copy[0] == '{')
parseJSON (input); parseJSON (copy);
else else
throw std::string (STRING_RECORD_NOT_FF4); throw std::string (STRING_RECORD_NOT_FF4);
} }
@ -686,7 +690,7 @@ void Task::parseLegacy (const std::string& line)
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// The format is: // The format is:
// //
// [ <name>:<value> ... ] \n // [ <name>:<value> ... ]
// //
std::string Task::composeF4 () const std::string Task::composeF4 () const
{ {
@ -705,7 +709,7 @@ std::string Task::composeF4 () const
} }
} }
ff4 += "]\n"; ff4 += "]";
return ff4; return ff4;
} }
@ -728,6 +732,10 @@ std::string Task::composeJSON (bool decorate /*= false*/) const
if (attributes_written) if (attributes_written)
out << ","; out << ",";
// Annotations are not written out here.
if (i->first.substr (0, 11) == "annotation_")
continue;
std::string type = Task::attributes[i->first]; std::string type = Task::attributes[i->first];
if (type == "") if (type == "")
type = "string"; type = "string";

View file

@ -182,10 +182,10 @@ std::string Taskmod::toString ()
if (_bBeforeSet) if (_bBeforeSet)
{ {
stream << STRING_TASKMOD_OLD << _before.composeF4(); stream << STRING_TASKMOD_OLD << _before.composeF4() << "\n";
} }
stream << STRING_TASKMOD_NEW << _after.composeF4(); stream << STRING_TASKMOD_NEW << _after.composeF4() << "\n";
stream << "---\n"; stream << "---\n";
return stream.str (); return stream.str ();

View file

@ -77,7 +77,7 @@ int main (int argc, char** argv)
// Task::set // Task::set
task.clear (); task.clear ();
task.set ("name", "value"); task.set ("name", "value");
t.is (task.composeF4 (), "[name:\"value\"]\n", "Task::set"); t.is (task.composeF4 (), "[name:\"value\"]", "Task::set");
// Task::has // Task::has
t.ok (task.has ("name"), "Task::has"); t.ok (task.has ("name"), "Task::has");
@ -85,18 +85,18 @@ int main (int argc, char** argv)
// Task::get_int // Task::get_int
task.set ("one", 1); task.set ("one", 1);
t.is (task.composeF4 (), "[name:\"value\" one:\"1\"]\n", "Task::set"); t.is (task.composeF4 (), "[name:\"value\" one:\"1\"]", "Task::set");
t.is (task.get_int ("one"), 1, "Task::get_int"); t.is (task.get_int ("one"), 1, "Task::get_int");
// Task::get_ulong // Task::get_ulong
task.set ("two", "4294967295"); task.set ("two", "4294967295");
t.is (task.composeF4 (), "[name:\"value\" one:\"1\" two:\"4294967295\"]\n", "Task::set"); t.is (task.composeF4 (), "[name:\"value\" one:\"1\" two:\"4294967295\"]", "Task::set");
t.is ((size_t)task.get_ulong ("two"), (size_t)4294967295UL, "Task::get_ulong"); t.is ((size_t)task.get_ulong ("two"), (size_t)4294967295UL, "Task::get_ulong");
// Task::remove // Task::remove
task.remove ("one"); task.remove ("one");
task.remove ("two"); task.remove ("two");
t.is (task.composeF4 (), "[name:\"value\"]\n", "Task::remove"); t.is (task.composeF4 (), "[name:\"value\"]", "Task::remove");
// Task::all // Task::all
t.is (task.size (), (size_t)1, "Task::all size"); t.is (task.size (), (size_t)1, "Task::all size");

View file

@ -57,7 +57,7 @@ int main (int argc, char** argv)
std::vector <Task> pending = context.tdb2.pending.get_tasks (); std::vector <Task> pending = context.tdb2.pending.get_tasks ();
std::vector <Task> completed = context.tdb2.completed.get_tasks (); std::vector <Task> completed = context.tdb2.completed.get_tasks ();
std::vector <std::string> undo = context.tdb2.undo.get_lines (); std::vector <std::string> undo = context.tdb2.undo.get_lines ();
std::vector <Task> backlog = context.tdb2.backlog.get_tasks (); std::vector <std::string> backlog = context.tdb2.backlog.get_lines ();
t.is ((int) pending.size (), 0, "TDB2 Read empty pending"); t.is ((int) pending.size (), 0, "TDB2 Read empty pending");
t.is ((int) completed.size (), 0, "TDB2 Read empty completed"); t.is ((int) completed.size (), 0, "TDB2 Read empty completed");
@ -71,7 +71,7 @@ int main (int argc, char** argv)
pending = context.tdb2.pending.get_tasks (); pending = context.tdb2.pending.get_tasks ();
completed = context.tdb2.completed.get_tasks (); completed = context.tdb2.completed.get_tasks ();
undo = context.tdb2.undo.get_lines (); undo = context.tdb2.undo.get_lines ();
backlog = context.tdb2.backlog.get_tasks (); backlog = context.tdb2.backlog.get_lines ();
t.is ((int) pending.size (), 1, "TDB2 after add, 1 pending task"); t.is ((int) pending.size (), 1, "TDB2 after add, 1 pending task");
t.is ((int) completed.size (), 0, "TDB2 after add, 0 completed tasks"); t.is ((int) completed.size (), 0, "TDB2 after add, 0 completed tasks");
@ -84,7 +84,7 @@ int main (int argc, char** argv)
pending = context.tdb2.pending.get_tasks (); pending = context.tdb2.pending.get_tasks ();
completed = context.tdb2.completed.get_tasks (); completed = context.tdb2.completed.get_tasks ();
undo = context.tdb2.undo.get_lines (); undo = context.tdb2.undo.get_lines ();
backlog = context.tdb2.backlog.get_tasks (); backlog = context.tdb2.backlog.get_lines ();
t.is ((int) pending.size (), 1, "TDB2 after add, 1 pending task"); t.is ((int) pending.size (), 1, "TDB2 after add, 1 pending task");
t.is ((int) completed.size (), 0, "TDB2 after add, 0 completed tasks"); t.is ((int) completed.size (), 0, "TDB2 after add, 0 completed tasks");