#include #include #include #include #include #include #include #include #include #include static const char *version = "0.0"; using namespace std; static string wncmd_now() { time_t t = time(NULL); struct tm *tt = localtime (&t); char tmp[20]; snprintf (tmp,sizeof(tmp),"%04d/%02d/%02d-%02d:%02d:%02d" ,tt->tm_year+1900,tt->tm_mon+1,tt->tm_mday ,tt->tm_hour,tt->tm_min,tt->tm_sec); return tmp; } static string wncmd_today() { time_t t = time(NULL); struct tm *tt = localtime (&t); char tmp[20]; snprintf (tmp,sizeof(tmp),"%04d/%02d/%02d" ,tt->tm_year+1900,tt->tm_mon+1,tt->tm_mday); return tmp; } static string wncmd_tomorrow() { time_t t = time(NULL) + 24*60*60; struct tm *tt = localtime (&t); char tmp[20]; snprintf (tmp,sizeof(tmp),"%04d/%02d/%02d" ,tt->tm_year+1900,tt->tm_mon+1,tt->tm_mday); return tmp; } #if 0 static string wncmd_cnvdate (const char *s) { string ret; if (strlen(s)==10){ int year = atoi(s); int month = atoi(s+5); int day = atoi(s+8); } return ret; } #endif struct STATITEM{ string name; // File name or task string date; // Date assigned to owner string owner; // Person who will deal with that STATITEM (const char *_name, const char *_date, const char *_owner){ name = _name; date = _date; owner = _owner; } STATITEM (const char *_name, const string &_date, const char *_owner){ name = _name; date = _date; owner = _owner; } bool operator < (const STATITEM &n) const { return date < n.date; } }; static bool statitem_sortdate (const STATITEM &s1, const STATITEM &s2) { // We sort so older dates appear last. return s2.date < s1.date; } static bool statitem_sortname (const STATITEM &s1, const STATITEM &s2) { return s1.name < s2.name; } static bool statitem_sortrdate (const STATITEM &s1, const STATITEM &s2) { return s1.date < s2.date; } static bool statitem_sortrname (const STATITEM &s1, const STATITEM &s2) { return s2.name < s1.name; } struct STATUS{ string fname; // file name of the status file string description; string target_date; vector items; void load(const char *path); STATUS (); STATUS (const char *path); STATUS (const string &path); int write (); void assign (const char *file, const char *user); void assign (const string &file, const char *user); }; void STATUS::assign (const char *file, const char *user) { bool found = false; string now = wncmd_now(); for (unsigned i=0; i void STATUS::load(const char *path) { fname = path; glocal STATUS *o = this; (path,true); if (strncmp(line,"description:",12)==0){ glocal.o->description = str_skip(line+12); }else if (strncmp(line,"target_date:",12)==0){ glocal.o->target_date = str_skip(line+12); }else if (strncmp(line,"assign:",7)==0){ SSTRINGS words; int n = str_splitline (line+7,' ',words); if (n != 3){ tlmp_error ("Invalid line %d in file %s, ignored: %s\n" ,noline,info.filename,line); }else{ glocal.o->items.push_back(STATITEM(words.getitem(0)->c_str() ,words.getitem(1)->c_str(),words.getitem(2)->c_str())); } }else{ const char *pt = str_skip(line); if (*pt != '\0'){ tlmp_error ("Invalid line %d in file %s, ignored: %s\n" ,noline,info.filename,line); } } return 0; // File is optional } STATUS::STATUS() { load ("status"); } STATUS::STATUS(const char *path) { load (path); } STATUS::STATUS(const string &path) { load (path.c_str()); } int STATUS::write() { glocal STATUS *o = this; int ret = (fname.c_str(),false); fprintf (fout,"description: %s\n",glocal.o->description.c_str()); fprintf (fout,"target_date: %s\n",glocal.o->target_date.c_str()); for (unsigned i=0; iitems.size(); i++){ STATITEM &it = glocal.o->items[i]; fprintf (fout,"assign: %s %s %s\n",it.name.c_str(),it.date.c_str(),it.owner.c_str()); } return 0; return ret; } /* Analyse the path of a file and find the corresponding directory. From them return the path of the status file and the basename of the file */ static int wncmd_context (const char *file, string &basename, string &statusfile) { int ret = -1; const char *pt = strrchr(file,'/'); if (pt == NULL){ statusfile = "status"; basename = file; ret = 0; }else{ pt++; basename = pt; statusfile = string(file,pt-file); statusfile += "status"; ret = 0; } return ret; } static void wncmd_splitpath (const char *path, string &dir, string &name) { const char *pt = strrchr(path,'/'); if (pt == NULL){ // Relative file name name = path; dir = "."; }else{ dir = string(path,pt-path); name = pt+1; } } int main (int argc, char *argv[]) { glocal int ret = -1; glocal bool sort_by_name = false; glocal bool sort_reverse = false; glocal const char *user = NULL; glocal.ret = (argc,argv); setproginfo ("wncmd",version ,"Manage projects information\n" "\n" "Commands are:\n" "\tdone file1 [ file2 ...]\n" "\tgive user file1 [ files2 ...]\n" "\torphan\n" "\ttake file1 [ file2 ...]\n" "\ttarget date|days|today|tomorrow\n" "\ttodo\n" "\tdescription some text ...\n" ); setarg ('s',"sortbyname","Sort todo by names instead of dates",glocal.sort_by_name,false); setarg ('r',"sortreverse","Sort in reverse order",glocal.sort_reverse,false); setarg ('u',"user","Work as this user",glocal.user,false); int ret = -1; glocal string user_buf; if (glocal.user == NULL){ glocal.user = getenv("USER"); string wncmd_id = string(getenv("HOME")) + "/.wncmd"; (wncmd_id.c_str(),true); if (line[0] != '\0'){ glocal.user_buf = line; glocal.user = glocal.user_buf.c_str(); } return 0; } const char *cmd = argv[0]; if (strcmp(cmd,"take")==0){ for (int i=1; i myitems; ("."); if (strcmp(basename,"status")==0){ string dir,name; wncmd_splitpath(relpath,dir,name); STATUS st(path); for (unsigned i=0; i if (glocal.sort_reverse){ sort (glocal.myitems.begin(),glocal.myitems.end(),glocal.sort_by_name ? statitem_sortrname : statitem_sortrdate); }else{ sort (glocal.myitems.begin(),glocal.myitems.end(),glocal.sort_by_name ? statitem_sortname : statitem_sortdate); } for (unsigned i=0; i binfiles; if (binfiles.size()==0){ binfiles.insert (".csv"); binfiles.insert (".doc"); binfiles.insert (".docx"); binfiles.insert (".xls"); } const char *pt = strrchr(name,'.'); if (pt == NULL || binfiles.count(pt)==0){ printf ("\n"); (name,true); printf ("\t%s\n",line); return 0; printf ("\n"); } } }else if (strcmp(cmd,"orphan")==0){ // Walk all the projects to find stuff not assigned to anyone if (argc != 1){ tlmp_error ("No argument needed for the orphan command\n"); }else{ ("."); if (strcmp(basename,"status")!=0){ bool found = false; string dir,name; wncmd_splitpath(path,dir,name); string status = dir + "/status"; STATUS st(status.c_str()); for (unsigned i=0; i } }else{ tlmp_error ("Invalid command %s\n",cmd); usage(); } return ret; return glocal.ret; }