00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifdef HAVE_CONFIG_H
00020 #include "config.h"
00021 #endif
00022
00023 #if TIME_WITH_SYS_TIME
00024 # include <sys/time.h>
00025 # include <time.h>
00026 #else
00027 # if HAVE_SYS_TIME_H
00028 # include <sys/time.h>
00029 # else
00030 # include <time.h>
00031 # endif
00032 #endif
00033
00034 #include <kcmdlineargs.h>
00035 #include <kaboutdata.h>
00036 #include <klocale.h>
00037 #include <kglobal.h>
00038 #include <kconfig.h>
00039 #include <kstandarddirs.h>
00040 #include <kdebug.h>
00041
00042 #include <libkcal/calformat.h>
00043 #include <libkcal/calendarresources.h>
00044 #include <libkcal/resourcelocal.h>
00045
00046 #include <qdatetime.h>
00047 #include <qfile.h>
00048
00049 #include <stdlib.h>
00050 #include <iostream>
00051
00052 #include "konsolekalendar.h"
00053 #include "konsolekalendarepoch.h"
00054
00055 #include "konsolekalendarvariables.h"
00056
00057 using namespace KCal;
00058 using namespace std;
00059
00060 static const char progName[] = "konsolekalendar";
00061 static const char progDisplay[] = "KonsoleKalendar";
00062 static const char progVersion[] = "1.0.0";
00063 static const char description[] = I18N_NOOP("A command line interface to KDE calendars");
00064
00065 static KCmdLineOptions options[] =
00066 {
00067 { "help", I18N_NOOP("Print this help and exit"), 0 },
00068 { "verbose", I18N_NOOP("Print helpful runtime messages"), 0 },
00069 { "dry-run", I18N_NOOP("Print what would have been done, but do not execute"), 0 },
00070 { "file <calendar-file>", I18N_NOOP("Specify which calendar you want to use"), 0 },
00071
00072
00073 { ":", I18N_NOOP(" Major operation modes:"), 0 },
00074 { "view", I18N_NOOP(" Print calendar events in specified export format"), 0 },
00075 { "add", I18N_NOOP(" Insert an event into the calendar"), 0 },
00076 { "change", I18N_NOOP(" Modify an existing calendar event"), 0 },
00077 { "delete", I18N_NOOP(" Remove an existing calendar event"), 0 },
00078 { "create", I18N_NOOP(" Create new calendar file if one does not exist"), 0 },
00079 { "import <import-file>", I18N_NOOP(" Import this calendar to main calendar"), 0 },
00080
00081 { ":", I18N_NOOP(" Operation modifiers:"), 0 },
00082 { "next", I18N_NOOP(" View next activity in calendar"), 0 },
00083 { "all", I18N_NOOP(" View all calendar entries"), 0 },
00084 { "uid <uid>", I18N_NOOP(" Event Unique-string identifier"), 0 },
00085 { "show-next <show-next>", I18N_NOOP(" From this day show next # days activities"), 0 },
00086 { "date <start-date>", I18N_NOOP(" Start from this day [YYYY-MM-DD]"), 0 },
00087 { "time <start-time>", I18N_NOOP(" Start from this time [HH:MM:SS]"), 0 },
00088 { "end-date <end-date>", I18N_NOOP(" End at this day [YYYY-MM-DD]"), 0 },
00089 { "end-time <end-time>", I18N_NOOP(" End at this time [HH:MM:SS]"), 0 },
00090 { "epoch-start <epoch-time>", I18N_NOOP(" Start from this time [secs since epoch]"), 0 },
00091 { "epoch-end <epoch-time>", I18N_NOOP(" End at this time [secs since epoch]"), 0 },
00092 { "summary <summary>", I18N_NOOP(" Add summary to event (for add/change modes)"), 0 },
00093 { "description <description>", I18N_NOOP("Add description to event (for add/change modes)"), 0 },
00094
00095 { ":", I18N_NOOP(" Export options:"), 0 },
00096 { "export-type <export-type>", I18N_NOOP("Export file type (Default: text)"), 0 },
00097 { "export-file <export-file>", I18N_NOOP("Export to file (Default: stdout)"), 0 },
00098 { "export-list", I18N_NOOP(" Print list of export types supported and exit"), 0 },
00099
00100 { "", I18N_NOOP("Examples:\n konsolekalendar --view\n konsolekalendar --add --date 2003-06-04 --time 10:00 --end-time 12:00 \\\n --summary \"Doctor Visit\" --description \"Get My Head Examined\"\n konsolekalendar --delete --uid KOrganizer-1740380426.803"), 0 },
00101
00102 KCmdLineLastOption
00103 };
00104
00105 int main(int argc, char *argv[])
00106 {
00107
00108 KAboutData aboutData(
00109 progName,
00110 I18N_NOOP( progDisplay ),
00111 progVersion,
00112 description,
00113 KAboutData::License_GPL,
00114 "(c) 2002-2003, Tuukka Pasanen and Allen Winter",
00115 0,
00116 "http://pim.kde.org",
00117 "bugs.kde.org"
00118 );
00119
00120 aboutData.addAuthor(
00121 "Tuukka Pasanen",
00122 I18N_NOOP("Primary Author"),
00123 "illuusio@mailcity.com",
00124 0
00125 );
00126 aboutData.addAuthor(
00127 "Allen Winter",
00128 I18N_NOOP("Author"),
00129 "awinterz@users.sourceforge.net",
00130 0
00131 );
00132
00133
00134
00135
00136
00137 KCmdLineArgs::init( argc, argv, &aboutData, true );
00138 KCmdLineArgs::addCmdLineOptions( options );
00139
00140 KInstance ins(progName);
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150 KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
00151
00152 QString KalendarFile;
00153
00154
00155 QDate startdate = QDate::currentDate();
00156 QTime starttime(7,0);
00157
00158
00159 QDate enddate = QDate::currentDate();
00160 QTime endtime(17,0);
00161
00162
00163 bool view = true;
00164 bool add = false;
00165 bool change = false;
00166 bool del = false;
00167 bool create = false;
00168 bool calendarFile = false;
00169 bool importFile = false;
00170
00171 QString option;
00172
00173 KonsoleKalendarVariables variables;
00174 KonsoleKalendarEpoch epochs;
00175
00176
00177 variables.setExportType( NONE );
00178
00179 if ( args->isSet("verbose") ) {
00180 variables.setVerbose(true);
00181 }
00182
00183 if ( args->isSet("dry-run") ) {
00184 variables.setDryRun(true);
00185 }
00186
00187
00188
00189
00190
00191 if ( args->isSet("export-list") ) {
00192 cout << i18n("\nKonsoleKalendar supports these export formats:\n Text [Default]\n HTML\n CSV (Comma-Separated Values)").local8Bit() << endl;
00193 return(0);
00194 }
00195
00196
00197
00198
00199
00200 if ( args->isSet("export-type") ) {
00201 option = args->getOption("export-type");
00202
00203 if ( option.upper() == "HTML" ) {
00204 kdDebug() << "main | export-type | Export to HTML" << endl;
00205 variables.setExportType( HTML );
00206 } else if( option.upper() == "CSV" ) {
00207 kdDebug() << "main | export-type | Export to CSV" << endl;
00208 variables.setExportType( CSV );
00209 } else if( option.upper() == "TEXT" ) {
00210 kdDebug() << "main | exporttype | Export to TXT" << endl;
00211 variables.setExportType( TEXT_KONSOLEKALENDAR );
00212 } else {
00213 kdError() << i18n("Invalid Export Type Specified: ").local8Bit() << option << endl;
00214 return(1);
00215 }
00216 }
00217
00218
00219
00220
00221
00222 if ( args->isSet("export-file") ) {
00223 option = args->getOption("export-file");
00224
00225 kdDebug() << "main | parse options | Export File: (" << option << ")" << endl;
00226
00227 variables.setExportFile(option);
00228 }
00229
00230
00231
00232
00233
00234 if ( args->isSet("view") ) {
00235 view=true;
00236
00237 kdDebug() << "main | parse options | Mode: (Print events)" << endl;
00238 }
00239
00240
00241
00242
00243
00244 if ( args->isSet("add") ) {
00245 view=false;
00246 add=true;
00247
00248 kdDebug() << "main | parse options | Mode: (Add event)" << endl;
00249 }
00250
00251
00252
00253
00254
00255 if ( args->isSet("change") ) {
00256 view=false;
00257 change=true;
00258
00259 kdDebug() << "main | parse options | Mode: (Change event)" << endl;
00260 }
00261
00262
00263
00264
00265
00266 if ( args->isSet("delete") ) {
00267 view=false;
00268 del=true;
00269
00270 kdDebug() << "main | parse options | Mode: (Delete event)" << endl;
00271 }
00272
00273
00274
00275
00276
00277 if ( args->isSet("create") ) {
00278 view=false;
00279 create=true;
00280
00281 kdDebug() << "main | parse options | Calendar File: (Create)" << endl;
00282
00283 }
00284
00285
00286
00287
00288
00289
00290 if ( args->isSet("summary") ) {
00291 option = args->getOption("summary");
00292
00293 kdDebug() << "main | parse options | Summary: (" << option << ")" << endl;
00294
00295 variables.setSummary(option);
00296 }
00297
00298
00299
00300
00301
00302 if ( args->isSet("description") ) {
00303 option = args->getOption("description");
00304
00305 kdDebug() << "main | parse options | Description: (" << option << ")" << endl;
00306
00307 variables.setDescription(option);
00308 }
00309
00310
00311
00312
00313
00314 if ( args->isSet("next") )
00315 {
00316 kdDebug() << "main | parse options | Show next event only" << endl;
00317
00318 variables.setNext(true);
00319 }
00320
00321
00322
00323
00324
00325
00326 if (args->isSet("uid") ) {
00327 option = args->getOption("uid");
00328
00329 kdDebug() << "main | parse options | Event UID: (" << option << ")" << endl;
00330
00331 variables.setUID( option );
00332 }
00333
00334
00335
00336
00337
00338 if ( args->isSet("date") ) {
00339 option = args->getOption("date");
00340
00341 kdDebug() << "main | parse options | Start date before conversion: (" << option << ")" << endl;
00342
00343 startdate = QDate::fromString( option, Qt::ISODate );
00344 if( ! startdate.isValid() ) {
00345 kdError() << i18n("Invalid Start Date Specified: ").local8Bit() << option << endl;
00346 return(1);
00347 }
00348 kdDebug() << "main | parse options | Start date after conversion: (" << startdate.toString() << ")" << endl;
00349 }
00350
00351
00352
00353
00354
00355
00356 if ( args->isSet("time") ) {
00357 option = args->getOption("time");
00358
00359 kdDebug() << "main | parse options | Start time before conversion : (" << option << ")" << endl;
00360
00361 starttime = QTime::fromString( option, Qt::ISODate );
00362 if( ! starttime.isValid() ) {
00363 kdError() << i18n("Invalid Start Time Specified: ").local8Bit() << option << endl;
00364 return(1);
00365 }
00366 kdDebug() << "main | parse options | Start time after conversion: (" << starttime.toString() << ")" << endl;
00367 }
00368
00369
00370
00371
00372
00373
00374 if ( args->isSet("end-date") ) {
00375 QString option = args->getOption("end-date");
00376
00377 kdDebug() << "main | parse options | End date before conversion: (" << option << ")" << endl;
00378
00379 enddate = QDate::fromString( option, Qt::ISODate );
00380 if( ! enddate.isValid() ) {
00381 kdError() << i18n("Invalid End Date Specified: ").local8Bit() << option << endl;
00382 return(1);
00383 }
00384 kdDebug() << "main | parse options | End date after converstion: (" << enddate.toString() << ")" << endl;
00385 }
00386
00387
00388
00389
00390
00391
00392 if ( args->isSet("show-next") )
00393 {
00394
00395 bool ok;
00396
00397 option = args->getOption("show-next");
00398 kdDebug() << "main | parse options | Show " << option << " days ahead" << endl;
00399 variables.setDaysCount( option.toInt( &ok, 10 ) );
00400
00401 if( !ok ){
00402 kdError() << i18n("Invalid Date Count Specified: ").local8Bit() << option << endl;
00403 return(1);
00404 }
00405
00406 enddate = startdate;
00407 enddate = enddate.addDays( variables.getDaysCount() );
00408 kdDebug() << "main | parse options | End date after converstion: (" << enddate.toString() << ")" << endl;
00409
00410 }
00411
00412
00413
00414
00415
00416 if ( args->isSet("end-time") ) {
00417 option = args->getOption("end-time");
00418
00419 kdDebug() << "main | parse options | End time before conversion: (" << option << ")" << endl;
00420
00421 endtime = QTime::fromString( option, Qt::ISODate );
00422 if( ! endtime.isValid() ) {
00423 kdError() << i18n("Invalid End Time Specified: ").local8Bit() << option << endl;
00424 return(1);
00425 }
00426
00427 kdDebug() << "main | parse options | End time after conversion: (" << endtime.toString() << ")" << endl;
00428 }
00429
00430
00431
00432
00433
00434 time_t epochstart=0;
00435 if ( args->isSet("epoch-start") ) {
00436 option = args->getOption("epoch-start");
00437
00438 kdDebug() << "main | parse options | Epoch start: (" << option << ")" << endl;
00439
00440 epochstart = (time_t) option.toULong(0,10);
00441 }
00442
00443
00444
00445
00446
00447 time_t epochend=0;
00448 if ( args->isSet("epoch-end") ) {
00449 option = args->getOption("epoch-end");
00450
00451 kdDebug() << "main | parse options | Epoch end: (" << option << ")" << endl;
00452
00453 epochend = (time_t) option.toULong(0,10);
00454 }
00455
00456 if( args->isSet("all") ) {
00457 variables.setAll( true );
00458 } else {
00459 variables.setAll( false );
00460 }
00461
00462 if ( args->isSet("import") ) {
00463 importFile = true;
00464 option = args->getOption("import");
00465 variables.setImportFile( option );
00466
00467 kdDebug() << "main | parse options | importing file from: (" << option << ")" << endl;
00468 }
00469
00470 KonsoleKalendar *konsolekalendar = new KonsoleKalendar( &variables );
00471
00472 if ( args->isSet("file") ) {
00473 calendarFile = true;
00474 option = args->getOption("file");
00475 variables.setCalendarFile( option );
00476
00477
00478
00479
00480
00481
00482 QFile fileExists( variables.getCalendarFile() );
00483 bool exists = fileExists.exists();
00484 fileExists.close();
00485
00486 if ( create ) {
00487
00488 kdDebug() << "main | createcalendar | check if calendar file already exists" << endl;
00489
00490 if( exists ) {
00491 kdError() << i18n("Calendar ").local8Bit() << variables.getCalendarFile() << i18n(" already exists").local8Bit() << endl;
00492 return(1);
00493 }
00494 if( konsolekalendar->createCalendar() ) {
00495 cout << i18n("Calendar ").local8Bit() << variables.getCalendarFile().local8Bit() << i18n(" successfully created.").local8Bit() << endl;
00496 return(0);
00497 } else {
00498 kdError() << i18n("Unable to create calendar: ").local8Bit() << variables.getCalendarFile() << endl;
00499 return(1);
00500 }
00501 }
00502
00503 if ( !exists ){
00504 cout << i18n("Calendar file not found").local8Bit() << option.local8Bit() << endl;
00505 cout << i18n("Try --create to create new calendar file").local8Bit() << endl;
00506 return(1);
00507 }
00508 }
00509
00510 CalendarResources *calendarResource = NULL;
00511 CalendarLocal *localCalendar = NULL;
00512
00513
00514
00515
00516
00517 if( args->isSet("file") ) {
00518 localCalendar = new CalendarLocal();
00519 localCalendar->load( variables.getCalendarFile() );
00520 variables.setCalendar( localCalendar );
00521 } else {
00522 calendarResource = new CalendarResources();
00523 variables.setCalendarResources( calendarResource );
00524 }
00525
00526
00527
00528
00529 QDateTime startdatetime, enddatetime;
00530
00531
00532 if( !args->isSet("end-date") && args->isSet("date") ) {
00533 enddate = startdate;
00534 kdDebug() << "main | datetimestamp | setting enddate to startdate" << endl;
00535 } else if( args->isSet("end-date") && !args->isSet("date") ) {
00536 startdate = enddate;
00537 kdDebug() << "main | datetimestamp | setting startdate to enddate" << endl;
00538 }
00539
00540
00541
00542
00543
00544 if( !args->isSet("end-time") && !args->isSet("epoch-end") ) {
00545 if( args->isSet("time") ) {
00546 endtime = starttime.addSecs(60*60);
00547 kdDebug() << "main | datetimestamp | setting endtime 1 hour after starttime" << endl;
00548 } else if( args->isSet("epoch-start") ) {
00549 startdatetime = epochs.epoch2QDateTime(epochstart);
00550 enddatetime = startdatetime.addSecs(60*60);
00551 kdDebug() << "main | datetimestamp | setting endtime 1 hour after epochstart" << endl;
00552 }
00553 }
00554
00555
00556
00557 if( !args->isSet("time") && !args->isSet("epoch-start") ) {
00558 if( args->isSet("end-time") ) {
00559 starttime = endtime.addSecs(-60*60);
00560 kdDebug() << "main | datetimestamp | setting starttime 1 hour before endtime" << endl;
00561 } else if( args->isSet("epoch-end") ) {
00562 enddatetime = epochs.epoch2QDateTime(epochend);
00563 startdatetime = enddatetime.addSecs(-60*60);
00564 kdDebug() << "main | datetimestamp | setting starttime 1 before after epochend" << endl;
00565 }
00566 }
00567
00568
00569 if( !args->isSet("time") && !args->isSet("epoch-start") &&
00570 !args->isSet("end-time") && !args->isSet("epoch-end") ) {
00571
00572 startdatetime = QDateTime::QDateTime(startdate, starttime);
00573 kdDebug() << "main | datetimestamp | setting startdatetime from default startdate (today) and starttime" << endl;
00574
00575 enddatetime = QDateTime::QDateTime(enddate, endtime);
00576 kdDebug() << "main | datetimestamp | setting enddatetime from default enddate (today) and endtime" << endl;
00577 }
00578
00579
00580 if( startdatetime.isNull() ) {
00581 startdatetime = QDateTime::QDateTime(startdate, starttime);
00582 kdDebug() << "main | datetimestamp | setting startdatetime from startdate and starttime" << endl;
00583 }
00584 if( enddatetime.isNull() ) {
00585 enddatetime = QDateTime::QDateTime(enddate, endtime);
00586 kdDebug() << "main | datetimestamp | setting enddatetime from enddate and endtime" << endl;
00587 }
00588
00589
00590 variables.setStartDateTime( startdatetime );
00591 variables.setEndDateTime( enddatetime );
00592
00593
00594 kdDebug() << "main | datetimestamp | StartDate=" << startdatetime.toString(Qt::TextDate) << endl;
00595 kdDebug() << "main | datetimestamp | EndDate=" << enddatetime.toString(Qt::TextDate) << endl;
00596
00597
00598
00599
00600
00601
00602 if( create + view + add + change + del > 1 ) {
00603 kdError() << i18n("Only 1 operation mode (view, add, change, delete,create) permitted at a time").local8Bit() << endl;
00604 return(1);
00605 }
00606
00607
00608 if( startdatetime > enddatetime ) {
00609 kdError() << i18n("Ending Date/Time occurs before the Starting Date/Time").local8Bit() << endl;
00610 return(1);
00611 }
00612
00613
00614
00615
00616
00617
00618 if( add ) {
00619
00620
00621 if( args->isSet("time") || args->isSet("end-time") ||
00622 args->isSet("epoch-start") || args->isSet("epoch-end") ) {
00623 variables.setFloating(false);
00624 kdDebug() << "main | floatingcheck | turn-off floating event" << endl;
00625 }
00626 }
00627
00628 args->clear();
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640 QString prodId = "-//K Desktop Environment//NONSGML %1 %2//EN";
00641 CalFormat::setApplication( progDisplay, prodId.arg( progDisplay).arg( progVersion ) );
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651 if( importFile ) {
00652 konsolekalendar->importCalendar();
00653 }
00654
00655 if( add ) {
00656 if( !konsolekalendar->isEvent( startdatetime, enddatetime, variables.getSummary() ) ) {
00657 kdDebug() << "main | modework | calling addEvent()" << endl;
00658 konsolekalendar->addEvent();
00659 } else {
00660 kdError() << i18n("Attempting to insert an event that already exists").local8Bit() << endl;
00661 return(1);
00662 }
00663 }
00664
00665 if( change ) {
00666 kdDebug() << "main | modework | calling changeEvent()" << endl;
00667 if( !variables.isUID() ) {
00668 kdError() << i18n("Must specify a UID with --uid to change event").local8Bit() << endl;
00669 return(1);
00670 }
00671 if( konsolekalendar->changeEvent() != true ) {
00672 kdError() << i18n("Attempting to change a non-existent event").local8Bit() << endl;
00673 return(1);
00674 }
00675 kdDebug() << "main | modework | succesful changeEvent()" << endl;
00676 }
00677
00678 if( del ) {
00679 kdDebug() << "main | modework | calling deleteEvent()" << endl;
00680 if( !variables.isUID() ) {
00681 kdError() << i18n("Must specify a UID with --uid to delete event").local8Bit() << endl;
00682 return(1);
00683 }
00684 if( konsolekalendar->deleteEvent() != true ) {
00685 kdError() << i18n("Attempting to delete a non-existent event").local8Bit() << endl;
00686 return(1);
00687 }
00688 kdDebug() << "main | modework | succesful deleteEvent()" << endl;
00689 }
00690
00691 if( view ) {
00692 kdDebug() << "main | modework | calling showInstance() to view events" << endl;
00693 if( !konsolekalendar->showInstance() ) {
00694 kdError() << i18n("Cannot open specified export file: ").local8Bit() << variables.getExportFile() << endl;
00695 return(1);
00696 }
00697 }
00698
00699 delete konsolekalendar;
00700
00701 if( calendarFile ){
00702 localCalendar->close();
00703 delete localCalendar;
00704 } else {
00705 calendarResource->close();
00706 delete calendarResource;
00707 }
00708
00709 kdDebug() << "main | exiting" << endl;
00710
00711 return 0;
00712 }