File Import

- Added format identifier code for task 1.4.3, task 1.5.0, todo.sh
  2.0 and CSV.
- Implemented import for type text.
- Implemented util.cpp:slurp function.
- Gathered sample input files for import testing, and later, unit
  tests.
This commit is contained in:
Paul Beckingham 2009-03-26 00:41:15 -04:00
parent db7b2dd9fe
commit 99dc72f26f
8 changed files with 239 additions and 24 deletions

View file

@ -28,24 +28,6 @@
#include <sstream> #include <sstream>
#include "task.h" #include "task.h"
////////////////////////////////////////////////////////////////////////////////
std::string handleImport (TDB& tdb, T& task, Config& conf)
{
std::stringstream out;
// Use the description as a file name.
std::string file = trim (task.getDescription ());
if (file.length () > 0)
{
out << "Not yet implemented." << std::endl;
}
else
throw std::string ("You must specify a file to import.");
return out.str ();
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// todo.sh v2.x // todo.sh v2.x
// file format: (A) Walk the dog +project @context // file format: (A) Walk the dog +project @context
@ -69,29 +51,221 @@ std::string handleImport (TDB& tdb, T& task, Config& conf)
// file format: project,priority,description // file format: project,priority,description
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void determineFileType () enum fileType
{ {
not_a_clue,
task_1_4_3,
task_1_5_0,
todo_sh_2_0,
csv,
text
};
static fileType determineFileType (const std::vector <std::string>& lines)
{
// '7f7a4191-c2f2-487f-8855-7a1eb378c267',' ...
// ....:....|....:....|....:....|....:....|
// 1 10 20 30 40
if (lines.size () > 1 &&
lines[1][0] == '\'' &&
lines[1][9] == '-' &&
lines[1][14] == '-' &&
lines[1][19] == '-' &&
lines[1][24] == '-' &&
lines[1][37] == '\'' &&
lines[1][38] == ',' &&
lines[1][39] == '\'')
{
if (lines[0] == "'id','uuid','status','tags','entry','start','due','recur',"
"'end','project','priority','fg','bg','description'")
return task_1_5_0;
if (lines[0] == "'id','status','tags','entry','start','due','end','project',"
"'priority','fg','bg','description'")
return task_1_4_3;
}
// x 2009-03-25 Walk the dog +project @context
// This is a test +project @context
for (unsigned int i = 0; i < lines.size (); ++i)
{
// All done tasks begin with "x YYYY-MM-DD".
if (lines[i].length () > 12)
{
if ( lines[i][0] == 'x' &&
lines[i][1] == ' ' &&
::isdigit (lines[i][2]) &&
::isdigit (lines[i][3]) &&
::isdigit (lines[i][4]) &&
::isdigit (lines[i][5]) &&
lines[i][6] == '-' &&
::isdigit (lines[i][7]) &&
::isdigit (lines[i][8]) &&
lines[i][9] == '-' &&
::isdigit (lines[i][10]) &&
::isdigit (lines[i][11]))
return todo_sh_2_0;
}
std::vector <std::string> words;
split (words, lines[i], ' ');
for (unsigned int w = 0; w < words.size (); ++w)
{
// +project
if (words[w].length () > 1 &&
words[w][0] == '+' &&
::isalnum (words[w][1]))
return todo_sh_2_0;
// @context
if (words[w].length () > 1 &&
words[w][0] == '@' &&
::isalnum (words[w][1]))
return todo_sh_2_0;
}
}
// CSV - commas on every line.
bool commas_on_every_line = true;
for (unsigned int i = 0; i < lines.size (); ++i)
{
if (lines[i].length () > 10 &&
lines[i][0] != '#' &&
lines[i].find (",") == std::string::npos)
{
commas_on_every_line = false;
break;
}
}
if (commas_on_every_line)
return csv;
// TODO text, possibly with commas.
for (unsigned int i = 0; i < lines.size (); ++i)
{
// TODO priority:{H,M,L}
// TODO priorit:{H,M,L}
// TODO priori:{H,M,L}
// TODO prior:{H,M,L}
// TODO prio:{H,M,L}
// TODO pri:{H,M,L}
// TODO project:.+
// TODO projec:.+
// TODO proje:.+
// TODO proj:.+
// TODO pro:.+
}
return not_a_clue;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void importTask_1_5 () static std::string importTask_1_4_3 (
TDB& tdb,
Config& conf,
const std::vector <std::string>& lines)
{ {
return "task 1.4.3\n";
} }
void importTask_1_6 () ////////////////////////////////////////////////////////////////////////////////
static std::string importTask_1_5_0 (
TDB& tdb,
Config& conf,
const std::vector <std::string>& lines)
{ {
return "task 1.5.0\n";
} }
void importTodoSh_2_0 () ////////////////////////////////////////////////////////////////////////////////
static std::string importTodoSh_2_0 (
TDB& tdb,
Config& conf,
const std::vector <std::string>& lines)
{ {
return "todo.sh 2.0\n";
} }
void importSingleLine () ////////////////////////////////////////////////////////////////////////////////
static std::string importText (
TDB& tdb,
Config& conf,
const std::vector <std::string>& lines)
{ {
std::vector <std::string> failed;
for (unsigned int i = 0; i < lines.size (); ++i)
{
std::string line = lines[i];
// Strip comments
std::string::size_type pound = line.find ("#");
if (pound != std::string::npos)
line = line.substr (0, pound);
// Skip blank lines
if (line.length () > 0)
{
T task;
task.parse (std::string ("\"") + lines[i] + "\"");
if (! tdb.addT (task))
failed.push_back (lines[i]);
}
}
std::stringstream out;
out << "Imported "
<< (lines.size () - failed.size ())
<< " tasks successfully, with "
<< failed.size ()
<< " errors."
<< std::endl;
std::string bad;
join (bad, "\n", failed);
return out.str () + "\n" + bad;
} }
void importCSV () ////////////////////////////////////////////////////////////////////////////////
static std::string importCSV (
TDB& tdb,
Config& conf,
const std::vector <std::string>& lines)
{ {
return "CSV\n";
}
////////////////////////////////////////////////////////////////////////////////
std::string handleImport (TDB& tdb, T& task, Config& conf)
{
std::stringstream out;
// Use the description as a file name.
std::string file = trim (task.getDescription ());
if (file.length () > 0)
{
// Load the file.
std::vector <std::string> lines;
slurp (file, lines, true);
// Determine which type it might be, then attempt an import.
switch (determineFileType (lines))
{
case task_1_4_3: out << importTask_1_4_3 (tdb, conf, lines); break;
case task_1_5_0: out << importTask_1_5_0 (tdb, conf, lines); break;
case todo_sh_2_0: out << importTodoSh_2_0 (tdb, conf, lines); break;
case csv: out << importCSV (tdb, conf, lines); break;
case text: out << importText (tdb, conf, lines); break;
case not_a_clue:
out << "?";
break;
}
}
else
throw std::string ("You must specify a file to import.");
return out.str ();
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

4
src/import/freeform.csv Normal file
View file

@ -0,0 +1,4 @@
'id','priority','description'
1,H,'this is a test'
2,,'another task'
1 'id' 'priority' 'description'
2 1 H 'this is a test'
3 2 'another task'

3
src/import/line.txt Normal file
View file

@ -0,0 +1,3 @@
This is a test priority:H project:A
Another task

View file

@ -0,0 +1,2 @@
'id','status','tags','entry','start','due','end','project','priority','fg','bg','description'
'545629d2-24a3-4a32-8894-57e708b98354','pending','',1238037900,,,,'A','M',,,'foo bar '
1 'id' 'status' 'tags' 'entry' 'start' 'due' 'end' 'project' 'priority' 'fg' 'bg' 'description'
2 '545629d2-24a3-4a32-8894-57e708b98354' 'pending' '' 1238037900 'A' 'M' 'foo bar '

View file

@ -0,0 +1,2 @@
'id','uuid','status','tags','entry','start','due','recur','end','project','priority','fg','bg','description'
'7f7a4191-c2f2-487f-8855-7a1eb378c267','pending','',1238037947,,,,,'A','M',,,'foo bar'
1 'id','uuid','status','tags','entry','start','due','recur','end','project','priority','fg','bg','description'
2 '7f7a4191-c2f2-487f-8855-7a1eb378c267','pending','',1238037947,,,,,'A','M',,,'foo bar'

2
src/import/todo.txt Normal file
View file

@ -0,0 +1,2 @@
x 2009-03-25 Walk the dog +project @context
This is a test +project @context

View file

@ -139,6 +139,8 @@ std::string expandPath (const std::string&);
int flock (int, int); int flock (int, int);
#endif #endif
bool slurp (const std::string&, std::vector <std::string>&, bool trimLines = false);
// rules.cpp // rules.cpp
void initializeColorRules (Config&); void initializeColorRules (Config&);
void autoColorize (T&, Text::color&, Text::color&, Config&); void autoColorize (T&, Text::color&, Text::color&, Config&);

View file

@ -25,6 +25,7 @@
// //
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#include <iostream> #include <iostream>
#include <fstream>
#include <vector> #include <vector>
#include <string> #include <string>
#include <sys/types.h> #include <sys/types.h>
@ -404,3 +405,28 @@ int flock (int fd, int operation)
#endif #endif
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
bool slurp (
const std::string& file,
std::vector <std::string>& contents,
bool trimLines /* = false */)
{
contents.clear ();
std::ifstream in (file.c_str ());
if (in.good ())
{
std::string line;
while (getline (in, line))
{
if (trimLines) line = trim (line);
contents.push_back (line);
}
in.close ();
return true;
}
return false;
}
////////////////////////////////////////////////////////////////////////////////