Stefan Pranger
4 years ago
commit
f6e133c2c6
14 changed files with 602 additions and 0 deletions
-
19CMakeLists.txt
-
108calendar-daemon.cpp
-
44ical/Alarm.cpp
-
32ical/Alarm.h
-
38ical/Event.cpp
-
23ical/Event.h
-
15ical/IcalObject.h
-
7io/debug.cpp
-
30io/debug.h
-
244util/calendar_parsing.cpp
-
28util/calendar_parsing.h
-
BINutil/calendar_parsing.o
-
2util/calendar_parsing.o.d
-
12util/notifications.h
@ -0,0 +1,19 @@ |
|||
cmake_minimum_required(VERSION 2.8 FATAL_ERROR) |
|||
project(notification-daemon CXX) |
|||
# get all *.cpp files recursively |
|||
#file(GLOB_RECURSE SRC_FILES ${PROJECT_SOURCE_DIR}/*.cpp) |
|||
#file(GLOB_RECURSE HEADER_FILES ${PROJECT_SOURCE_DIR}/*.h) |
|||
include_directories(${PROJECT_SOURCE_DIR}) |
|||
#add_executable(notification-daemon ${SRC_FILES} ${HEADER_FILES}) |
|||
add_executable(notification-daemon |
|||
calendar-daemon |
|||
util/calendar_parsing.cpp |
|||
util/notifications.h |
|||
ical/Alarm.cpp |
|||
ical/Event.cpp |
|||
ical/IcalObject.h |
|||
io/debug.cpp |
|||
) |
|||
add_definitions(-DLOG_DEBUG) |
|||
target_link_libraries(notification-daemon ical boost_system boost_filesystem) |
|||
target_compile_options(notification-daemon PRIVATE -g) |
@ -0,0 +1,108 @@ |
|||
#include <dirent.h>
|
|||
#include <iterator>
|
|||
#include <cstdlib>
|
|||
#include <cstring>
|
|||
#include <sstream>
|
|||
#include <iostream>
|
|||
#include <stdlib.h>
|
|||
#include <string>
|
|||
#include <sys/stat.h>
|
|||
#include <syslog.h>
|
|||
#include <unistd.h>
|
|||
#include <vector>
|
|||
|
|||
#include <sqlite3.h>
|
|||
#include <util/notifications.h>
|
|||
#include <util/calendar_parsing.h>
|
|||
|
|||
#include <io/debug.h>
|
|||
const int MINUTE = 1000000; |
|||
|
|||
void update_database() { |
|||
std::vector<ical::ical_object*> objects = util::parse_cal_dir(); |
|||
} |
|||
|
|||
void do_heartbeat() |
|||
{ |
|||
util::notify("Testing", ""); |
|||
update_database(); |
|||
} |
|||
|
|||
// For security purposes, we don't allow any arguments to be passed into the daemon
|
|||
int main(void) |
|||
{ |
|||
// Define variables
|
|||
//pid_t pid, sid;
|
|||
|
|||
//// Fork the current process
|
|||
//pid = fork();
|
|||
//// The parent process continues with a process ID greater than 0
|
|||
//if(pid > 0)
|
|||
//{
|
|||
// exit(EXIT_SUCCESS);
|
|||
//}
|
|||
//// A process ID lower than 0 indicates a failure in either process
|
|||
//else if(pid < 0)
|
|||
//{
|
|||
// exit(EXIT_FAILURE);
|
|||
//}
|
|||
//// The parent process has now terminated, and the forked child process will continue
|
|||
//// (the pid of the child process was 0)
|
|||
|
|||
//// Since the child process is a daemon, the umask needs to be set so files and logs can be written
|
|||
//umask(0);
|
|||
|
|||
//// Open system logs for the child process
|
|||
//openlog("daemon-named", LOG_NOWAIT | LOG_PID, LOG_USER);
|
|||
//syslog(LOG_NOTICE, "Successfully started daemon-name");
|
|||
|
|||
//// Generate a session ID for the child process
|
|||
//sid = setsid();
|
|||
//// Ensure a valid SID for the child process
|
|||
//if(sid < 0)
|
|||
//{
|
|||
// // Log failure and exit
|
|||
// syslog(LOG_ERR, "Could not generate session ID for child process");
|
|||
|
|||
// // If a new session ID could not be generated, we must terminate the child process
|
|||
// // or it will be orphaned
|
|||
// exit(EXIT_FAILURE);
|
|||
//}
|
|||
|
|||
//// Change the current working directory to a directory guaranteed to exist
|
|||
//if((chdir("/")) < 0)
|
|||
//{
|
|||
// // Log failure and exit
|
|||
// syslog(LOG_ERR, "Could not change working directory to /");
|
|||
|
|||
// // If our guaranteed directory does not exist, terminate the child process to ensure
|
|||
// // the daemon has not been hijacked
|
|||
// exit(EXIT_FAILURE);
|
|||
//}
|
|||
|
|||
//// A daemon cannot use the terminal, so close standard file descriptors for security reasons
|
|||
//close(STDIN_FILENO);
|
|||
//close(STDOUT_FILENO);
|
|||
//close(STDERR_FILENO);
|
|||
|
|||
// Daemon-specific intialization should go here
|
|||
const int SLEEP_INTERVAL = 5 * MINUTE; |
|||
|
|||
// Enter daemon loop
|
|||
while(1) |
|||
{ |
|||
// Execute daemon heartbeat, where your recurring activity occurs
|
|||
do_heartbeat(); |
|||
exit(0); |
|||
|
|||
// Sleep for a period of time
|
|||
sleep(SLEEP_INTERVAL); |
|||
} |
|||
|
|||
// Close system logs for the child process
|
|||
//syslog(LOG_NOTICE, "Stopping daemon-name");
|
|||
//closelog();
|
|||
|
|||
// Terminate the child process when the daemon completes
|
|||
exit(EXIT_SUCCESS); |
|||
} |
@ -0,0 +1,44 @@ |
|||
#include <ical/Alarm.h>
|
|||
#include <libical/icalproperty_cxx.h>
|
|||
|
|||
namespace ical { |
|||
Alarm::Alarm(icalcomponent* alarm_component) { |
|||
parse(alarm_component); |
|||
} |
|||
|
|||
void Alarm::parse(icalcomponent* alarm_component) { |
|||
parse_action(alarm_component); |
|||
parse_description(alarm_component); |
|||
parse_trigger(alarm_component); |
|||
DEBUG << "\n" << print(); |
|||
} |
|||
|
|||
void Alarm::parse_action(icalcomponent* alarm_component) { |
|||
DEBUG << icalproperty_get_value_as_string(icalcomponent_get_first_property(alarm_component, ICAL_ACTION_PROPERTY)); |
|||
} |
|||
|
|||
void Alarm::parse_description(icalcomponent* alarm_component) { |
|||
// TODO Error Handling
|
|||
description = icalproperty_get_value_as_string(icalcomponent_get_first_property(alarm_component, ICAL_DESCRIPTION_PROPERTY)); |
|||
} |
|||
|
|||
void Alarm::parse_trigger(icalcomponent* alarm_component) { |
|||
icalproperty* trigger_property = icalcomponent_get_first_property(alarm_component, ICAL_TRIGGER_PROPERTY); |
|||
struct icaltriggertype tr; |
|||
if(trigger_property != 0) { |
|||
tr = icalproperty_get_trigger(trigger_property); |
|||
if (!icaltime_is_null_time(tr.time)) { |
|||
trigger = ical::trigger_type::ABSOLUTE; |
|||
} else { |
|||
trigger = ical::trigger_type::RELATIVE; |
|||
} |
|||
} |
|||
} |
|||
|
|||
std::string Alarm::print() { |
|||
std::string s = ""; |
|||
s += "DESCRIPTION: " + description + "\n"; |
|||
s += trigger == ical::trigger_type::ABSOLUTE ? "ABSOLUTE: " : "RELATIVE: "; |
|||
return s; |
|||
} |
|||
} |
@ -0,0 +1,32 @@ |
|||
#pragma once |
|||
|
|||
#include <string> |
|||
#include <memory> |
|||
#include <ical/IcalObject.h> |
|||
|
|||
namespace ical { |
|||
enum class action { |
|||
DISPLAY, AUDIO, EMAIL, PROC |
|||
}; |
|||
|
|||
enum class trigger_type { |
|||
ABSOLUTE, RELATIVE |
|||
}; |
|||
|
|||
class Alarm { |
|||
public: |
|||
Alarm(icalcomponent* alarm_component); |
|||
|
|||
void parse(icalcomponent* alarm_component); |
|||
void parse_action(icalcomponent* alarm_component); |
|||
void parse_description(icalcomponent* alarm_component); |
|||
void parse_trigger(icalcomponent* alarm_component); |
|||
|
|||
std::string print(); |
|||
private: |
|||
action a; |
|||
trigger_type trigger; |
|||
|
|||
std::string description; |
|||
}; |
|||
} |
@ -0,0 +1,38 @@ |
|||
#include <ical/Event.h>
|
|||
#include <ical/Alarm.h>
|
|||
|
|||
namespace ical { |
|||
Event::Event(ical::ical_object* object, icalcomponent* event_component) { |
|||
parse(object, event_component); |
|||
} |
|||
|
|||
void Event::parse(ical::ical_object* object, icalcomponent* event_component) { |
|||
dtstart = icalcomponent_get_dtstart(event_component); |
|||
dtend = icalcomponent_get_dtstart(event_component); |
|||
summary = std::string(icalcomponent_get_summary(event_component)); |
|||
parse_alarms(event_component); |
|||
DEBUG << "\n" << print(); |
|||
for(auto& a : alarms) { |
|||
DEBUG << "\n" << a.print(); |
|||
} |
|||
object->events.push_back(this); |
|||
} |
|||
|
|||
void Event::parse_alarms(icalcomponent* event_component) { |
|||
icalcomponent* c; |
|||
for(c = icalcomponent_get_first_component(event_component, ICAL_VALARM_COMPONENT); |
|||
c != 0; |
|||
c = icalcomponent_get_next_component(event_component, ICAL_VALARM_COMPONENT)) |
|||
{ |
|||
alarms.push_back(Alarm(c)); |
|||
} |
|||
} |
|||
|
|||
std::string Event::print() { |
|||
std::string s = ""; |
|||
s += "DTSTART: " + std::string(icaltime_as_ical_string(dtstart)) + "\n"; |
|||
s += "DTEND: " + std::string(icaltime_as_ical_string(dtend)) + "\n"; |
|||
s += "SUMMARY: " + summary + "\n"; |
|||
return s; |
|||
} |
|||
} |
@ -0,0 +1,23 @@ |
|||
#pragma once |
|||
|
|||
#include <string> |
|||
#include <vector> |
|||
#include <memory> |
|||
#include <ical/IcalObject.h> |
|||
|
|||
namespace ical { |
|||
class Event { |
|||
public: |
|||
Event(ical::ical_object* object, icalcomponent* event_component); |
|||
|
|||
void parse(ical::ical_object* object, icalcomponent* event); |
|||
void parse_alarms(icalcomponent* event_component); |
|||
|
|||
std::string print(); |
|||
private: |
|||
std::string summary; |
|||
icaltimetype dtstart; |
|||
icaltimetype dtend; |
|||
std::vector<Alarm> alarms; |
|||
}; |
|||
} |
@ -0,0 +1,15 @@ |
|||
#pragma once |
|||
|
|||
#include <libical/ical.h> |
|||
#include <vector> |
|||
|
|||
#include <io/debug.h> |
|||
|
|||
namespace ical { |
|||
class Alarm; |
|||
class Event; |
|||
|
|||
struct ical_object { |
|||
std::vector<ical::Event*> events; |
|||
}; |
|||
} |
@ -0,0 +1,7 @@ |
|||
#include <io/debug.h>
|
|||
|
|||
namespace io { |
|||
void debug(std::string msg) { |
|||
std::cout << "DEBUG: " << msg << std::endl;; |
|||
} |
|||
} |
@ -0,0 +1,30 @@ |
|||
#pragma once |
|||
|
|||
#include <iostream> |
|||
#include <string> |
|||
|
|||
struct X { |
|||
#ifdef LOG_DEBUG |
|||
X() { if(false) std::cout.setstate(std::ios_base::failbit); } |
|||
~X() { if(false) { std::cout.clear(); } else { std::cout << std::endl << std::flush; } } |
|||
#else |
|||
X() { std::cout.setstate(std::ios_base::failbit); } |
|||
~X() { std::cout.clear(); } |
|||
#endif |
|||
}; |
|||
|
|||
#define DEBUG (X(), std::cout << "DEBUG[" << __FILE__ << ":" << __LINE__ << " in " << __func__ << "()]: ") |
|||
#define WARN (X(), std::cout << "WARN [" << __FILE__ << ":" << __LINE__ << " in " << __func__ << "()]: ") |
|||
|
|||
#ifdef LOG_DEBUG |
|||
#define STEP \ |
|||
do { DEBUG << "Stepping through, Hit Enter..."; \ |
|||
std::cin.get(); \ |
|||
} while (0) |
|||
#else |
|||
#define STEP (void)(0) |
|||
#endif |
|||
|
|||
namespace io { |
|||
void debug(std::string msg); |
|||
} |
@ -0,0 +1,244 @@ |
|||
#include <util/calendar_parsing.h>
|
|||
|
|||
#include <memory>
|
|||
|
|||
namespace util { |
|||
std::vector<ical::ical_object*> parse_cal_dir() { |
|||
std::vector<ical::ical_object*> objects; |
|||
std::vector<icalcomponent*> components; |
|||
for (boost::filesystem::directory_entry& entry : boost::filesystem::directory_iterator(cal_dir)) { |
|||
DEBUG << "Parsing: " + entry.path().generic_string(); |
|||
ical::ical_object* object = new ical::ical_object(); |
|||
parse_main_component(object, parse_ics_file(entry.path().generic_string())); |
|||
} |
|||
return objects; |
|||
} |
|||
|
|||
icalcomponent* parse_main_component(ical::ical_object* object, icalcomponent* component) { |
|||
icalcomponent* c = icalcomponent_get_first_component(component, ICAL_ANY_COMPONENT); |
|||
while(c != 0) { |
|||
if(c != 0) { |
|||
parse_component(object, c); |
|||
} |
|||
c = parse_main_component(object, c); |
|||
if(c == 0) { |
|||
c = icalcomponent_get_next_component(component, ICAL_ANY_COMPONENT); |
|||
} |
|||
} |
|||
return c; |
|||
} |
|||
|
|||
void parse_component(ical::ical_object* object, icalcomponent* component) { |
|||
switch(icalcomponent_isa(component)) { |
|||
case ICAL_VALARM_COMPONENT: break; |
|||
case ICAL_NO_COMPONENT: |
|||
{ |
|||
DEBUG << "parsed component: ICAL_NO_COMPONENT"; |
|||
DEBUG << "\n" << icalcomponent_as_ical_string_r(component); |
|||
break; |
|||
} |
|||
case ICAL_ANY_COMPONENT: |
|||
{ |
|||
DEBUG << "parsed component: ICAL_ANY_COMPONENT"; |
|||
DEBUG << "\n" << icalcomponent_as_ical_string_r(component); |
|||
break; |
|||
} |
|||
case ICAL_XROOT_COMPONENT: |
|||
{ |
|||
DEBUG << "parsed component: ICAL_XROOT_COMPONENT"; |
|||
DEBUG << "\n" << icalcomponent_as_ical_string_r(component); |
|||
break; |
|||
} |
|||
case ICAL_XATTACH_COMPONENT: |
|||
{ |
|||
DEBUG << "parsed component: ICAL_XATTACH_COMPONENT"; |
|||
DEBUG << "\n" << icalcomponent_as_ical_string_r(component); |
|||
break; |
|||
} |
|||
case ICAL_VEVENT_COMPONENT: |
|||
{ |
|||
DEBUG << "parsed component: ICAL_VEVENT_COMPONENT"; |
|||
//DEBUG << "\n" << icalcomponent_as_ical_string_r(component);
|
|||
ical::Event(object, component); |
|||
break; |
|||
} |
|||
case ICAL_VTODO_COMPONENT: |
|||
{ |
|||
DEBUG << "parsed component: ICAL_VTODO_COMPONENT"; |
|||
DEBUG << "\n" << icalcomponent_as_ical_string_r(component); |
|||
break; |
|||
} |
|||
case ICAL_VJOURNAL_COMPONENT: |
|||
{ |
|||
DEBUG << "parsed component: ICAL_VJOURNAL_COMPONENT"; |
|||
DEBUG << "\n" << icalcomponent_as_ical_string_r(component); |
|||
break; |
|||
} |
|||
case ICAL_VCALENDAR_COMPONENT: |
|||
{ |
|||
DEBUG << "parsed component: ICAL_VCALENDAR_COMPONENT"; |
|||
DEBUG << "\n" << icalcomponent_as_ical_string_r(component); |
|||
break; |
|||
} |
|||
case ICAL_VAGENDA_COMPONENT: |
|||
{ |
|||
DEBUG << "parsed component: ICAL_VAGENDA_COMPONENT"; |
|||
DEBUG << "\n" << icalcomponent_as_ical_string_r(component); |
|||
break; |
|||
} |
|||
case ICAL_VFREEBUSY_COMPONENT: |
|||
{ |
|||
DEBUG << "parsed component: ICAL_VFREEBUSY_COMPONENT"; |
|||
DEBUG << "\n" << icalcomponent_as_ical_string_r(component); |
|||
break; |
|||
} |
|||
case ICAL_XAUDIOALARM_COMPONENT: |
|||
{ |
|||
DEBUG << "parsed component: ICAL_XAUDIOALARM_COMPONENT"; |
|||
DEBUG << "\n" << icalcomponent_as_ical_string_r(component); |
|||
break; |
|||
} |
|||
case ICAL_XDISPLAYALARM_COMPONENT: |
|||
{ |
|||
DEBUG << "parsed component: ICAL_XDISPLAYALARM_COMPONENT"; |
|||
DEBUG << "\n" << icalcomponent_as_ical_string_r(component); |
|||
break; |
|||
} |
|||
case ICAL_XEMAILALARM_COMPONENT: |
|||
{ |
|||
DEBUG << "parsed component: ICAL_XEMAILALARM_COMPONENT"; |
|||
DEBUG << "\n" << icalcomponent_as_ical_string_r(component); |
|||
break; |
|||
} |
|||
case ICAL_XPROCEDUREALARM_COMPONENT: |
|||
{ |
|||
DEBUG << "parsed component: ICAL_XPROCEDUREALARM_COMPONENT"; |
|||
DEBUG << "\n" << icalcomponent_as_ical_string_r(component); |
|||
break; |
|||
} |
|||
case ICAL_VTIMEZONE_COMPONENT: |
|||
{ |
|||
DEBUG << "parsed component: ICAL_VTIMEZONE_COMPONENT"; |
|||
break; |
|||
} |
|||
case ICAL_XSTANDARD_COMPONENT: |
|||
{ |
|||
DEBUG << "parsed component: ICAL_XSTANDARD_COMPONENT"; |
|||
break; |
|||
} |
|||
case ICAL_XDAYLIGHT_COMPONENT: |
|||
{ |
|||
DEBUG << "parsed component: ICAL_XDAYLIGHT_COMPONENT"; |
|||
break; |
|||
} |
|||
case ICAL_X_COMPONENT: |
|||
{ |
|||
DEBUG << "parsed component: ICAL_X_COMPONENT"; |
|||
DEBUG << "\n" << icalcomponent_as_ical_string_r(component); |
|||
break; |
|||
} |
|||
case ICAL_VSCHEDULE_COMPONENT: |
|||
{ |
|||
DEBUG << "parsed component: ICAL_VSCHEDULE_COMPONENT"; |
|||
DEBUG << "\n" << icalcomponent_as_ical_string_r(component); |
|||
break; |
|||
} |
|||
case ICAL_VQUERY_COMPONENT: |
|||
{ |
|||
DEBUG << "parsed component: ICAL_VQUERY_COMPONENT"; |
|||
DEBUG << "\n" << icalcomponent_as_ical_string_r(component); |
|||
break; |
|||
} |
|||
case ICAL_VREPLY_COMPONENT: |
|||
{ |
|||
DEBUG << "parsed component: ICAL_VREPLY_COMPONENT"; |
|||
DEBUG << "\n" << icalcomponent_as_ical_string_r(component); |
|||
break; |
|||
} |
|||
case ICAL_VCAR_COMPONENT: |
|||
{ |
|||
DEBUG << "parsed component: ICAL_VCAR_COMPONENT"; |
|||
DEBUG << "\n" << icalcomponent_as_ical_string_r(component); |
|||
break; |
|||
} |
|||
case ICAL_VCOMMAND_COMPONENT: |
|||
{ |
|||
DEBUG << "parsed component: ICAL_VCOMMAND_COMPONENT"; |
|||
DEBUG << "\n" << icalcomponent_as_ical_string_r(component); |
|||
break; |
|||
} |
|||
case ICAL_XLICINVALID_COMPONENT: |
|||
{ |
|||
DEBUG << "parsed component: ICAL_XLICINVALID_COMPONENT"; |
|||
DEBUG << "\n" << icalcomponent_as_ical_string_r(component); |
|||
break; |
|||
} |
|||
case ICAL_XLICMIMEPART_COMPONENT: |
|||
{ |
|||
DEBUG << "parsed component: ICAL_XLICMIMEPART_COMPONENT"; |
|||
DEBUG << "\n" << icalcomponent_as_ical_string_r(component); |
|||
break; |
|||
} |
|||
case ICAL_VAVAILABILITY_COMPONENT: |
|||
{ |
|||
DEBUG << "parsed component: ICAL_VAVAILABILITY_COMPONENT"; |
|||
DEBUG << "\n" << icalcomponent_as_ical_string_r(component); |
|||
break; |
|||
} |
|||
case ICAL_XAVAILABLE_COMPONENT: |
|||
{ |
|||
DEBUG << "parsed component: ICAL_XAVAILABLE_COMPONENT"; |
|||
DEBUG << "\n" << icalcomponent_as_ical_string_r(component); |
|||
break; |
|||
} |
|||
case ICAL_VPOLL_COMPONENT: |
|||
{ |
|||
DEBUG << "parsed component: ICAL_VPOLL_COMPONENT"; |
|||
DEBUG << "\n" << icalcomponent_as_ical_string_r(component); |
|||
break; |
|||
} |
|||
case ICAL_VVOTER_COMPONENT: |
|||
{ |
|||
DEBUG << "parsed component: ICAL_VVOTER_COMPONENT"; |
|||
DEBUG << "\n" << icalcomponent_as_ical_string_r(component); |
|||
break; |
|||
} |
|||
case ICAL_XVOTE_COMPONENT: |
|||
{ |
|||
DEBUG << "parsed component: ICAL_XVOTE_COMPONENT"; |
|||
DEBUG << "\n" << icalcomponent_as_ical_string_r(component); |
|||
break; |
|||
} |
|||
case ICAL_VPATCH_COMPONENT: |
|||
{ |
|||
DEBUG << "parsed component: ICAL_VPATCH_COMPONENT"; |
|||
DEBUG << "\n" << icalcomponent_as_ical_string_r(component); |
|||
break; |
|||
} |
|||
case ICAL_XPATCH_COMPONENT: |
|||
{ |
|||
DEBUG << "parsed component: ICAL_XPATCH_COMPONENT"; |
|||
DEBUG << "\n" << icalcomponent_as_ical_string_r(component); |
|||
break; |
|||
} |
|||
default: |
|||
DEBUG << "parse_component: something else found"; |
|||
break; |
|||
} |
|||
} |
|||
|
|||
std::string slurp(std::ifstream& in) { |
|||
std::ostringstream sstr; |
|||
sstr << in.rdbuf(); |
|||
return sstr.str(); |
|||
} |
|||
|
|||
icalcomponent* parse_ics_file(std::string filename) { |
|||
std::ifstream ifs (filename, std::ifstream::in); |
|||
return icalparser_parse_string(slurp(ifs).c_str()); |
|||
} |
|||
|
|||
void debug(icalcomponent* component) { |
|||
DEBUG << "\n" << icalcomponent_as_ical_string_r(component); |
|||
} |
|||
} |
@ -0,0 +1,28 @@ |
|||
#pragma once |
|||
|
|||
#include <fstream> |
|||
#include <sstream> |
|||
#include <iostream> |
|||
|
|||
#include <libical/ical.h> |
|||
#include <ical/IcalObject.h> |
|||
#include <ical/Alarm.h> |
|||
#include <ical/Event.h> |
|||
|
|||
#include <boost/filesystem.hpp> |
|||
|
|||
#include <io/debug.h> |
|||
|
|||
const std::string cal_dir = "/home/stefan/.local/share/khal/calendars/dummy/"; |
|||
|
|||
namespace util { |
|||
std::vector<ical::ical_object*> parse_cal_dir(); |
|||
icalcomponent* parse_main_component(ical::ical_object* object, icalcomponent* component); |
|||
void parse_component(ical::ical_object* object, icalcomponent* component); |
|||
|
|||
std::string slurp(std::ifstream& in); |
|||
icalcomponent* parse_ics_file(std::string filename); |
|||
|
|||
|
|||
void debug(icalcomponent* component); |
|||
} |
@ -0,0 +1,2 @@ |
|||
util/calendar_parsing.o: util/calendar_parsing.cpp \ |
|||
util/calendar_parsing.h io/debug.h |
@ -0,0 +1,12 @@ |
|||
#pragma once |
|||
|
|||
//#include <libnotify/notify.h> |
|||
#include <string> |
|||
|
|||
const std::string exec = "notify-send"; |
|||
namespace util { |
|||
uint notify(std::string summary, std::string body /* */) { |
|||
std::string cmd = exec + " " + summary + " " + body; |
|||
return system(cmd.c_str()); |
|||
} |
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue