2010-04-27 14:42:21 +00:00
|
|
|
/* -*- mode: c++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
|
|
|
|
* vim: ts=4 sw=4 noet ai cindent syntax=cpp
|
|
|
|
*
|
|
|
|
* Conky, a system monitor, based on torsmo
|
|
|
|
*
|
|
|
|
* Please see COPYING for details
|
|
|
|
*
|
|
|
|
* Copyright (c) 2005-2010 Brenden Matthews, Philip Kovacs, et. al.
|
|
|
|
* (see AUTHORS)
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <libical/ical.h>
|
|
|
|
#include "logging.h"
|
|
|
|
|
|
|
|
struct ical_event {
|
|
|
|
icaltimetype start;
|
|
|
|
icalcomponent *event;
|
|
|
|
ical_event *next, *prev;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct obj_ical {
|
|
|
|
struct ical_event *list;
|
|
|
|
icalcomponent *comps;
|
|
|
|
icalparser *parser;
|
|
|
|
unsigned int num;
|
|
|
|
};
|
|
|
|
|
|
|
|
char* read_stream(char *s, size_t size, void *d) {
|
|
|
|
return fgets(s, size, (FILE*) d);
|
|
|
|
}
|
|
|
|
|
|
|
|
struct ical_event *add_event(struct ical_event *listend, icalcomponent *new_ev) {
|
|
|
|
struct ical_event *ev_new, *ev_cur;
|
|
|
|
icaltimetype start;
|
|
|
|
|
|
|
|
start = icalcomponent_get_dtstart(new_ev);
|
|
|
|
if(icaltime_compare(start, icaltime_from_timet(time(NULL), 0)) <= 0) return NULL;
|
|
|
|
ev_new = (struct ical_event *) malloc(sizeof(struct ical_event));
|
|
|
|
memset(ev_new, 0, sizeof(struct ical_event));
|
|
|
|
ev_new->event = new_ev;
|
|
|
|
ev_new->start = start;
|
|
|
|
if(listend) { //list already contains events
|
|
|
|
ev_cur = listend;
|
|
|
|
while(icaltime_compare(ev_new->start, ev_cur->start) <= 0) {
|
|
|
|
if( ! ev_cur->prev) { //ev_new starts first
|
|
|
|
ev_new->next = ev_cur;
|
|
|
|
ev_cur->prev = ev_new;
|
|
|
|
return listend;
|
|
|
|
}
|
|
|
|
ev_cur = ev_cur->prev;
|
|
|
|
}
|
|
|
|
if(ev_cur == listend) { //ev_new starts last
|
|
|
|
ev_cur->next = ev_new;
|
|
|
|
ev_new->prev = ev_cur;
|
|
|
|
return ev_new;
|
|
|
|
}
|
|
|
|
//ev_new somewhere in the middle
|
|
|
|
ev_new->prev = ev_cur;
|
|
|
|
ev_new->next = ev_cur->next;
|
|
|
|
ev_cur->next->prev = ev_new;
|
|
|
|
ev_cur->next = ev_new;
|
|
|
|
return listend;
|
|
|
|
}
|
|
|
|
return ev_new;
|
|
|
|
}
|
|
|
|
|
|
|
|
void parse_ical_args(struct text_object *obj, const char* arg, void *free_at_crash, void *free_at_crash2) {
|
|
|
|
char *filename = strdup(arg);
|
|
|
|
FILE *file;
|
|
|
|
icalparser *parser;
|
|
|
|
icalcomponent *allc, *curc;
|
2010-04-28 10:18:15 +00:00
|
|
|
struct ical_event *ll_start, *ll_end, *ll_new;
|
2010-04-27 14:42:21 +00:00
|
|
|
struct obj_ical *opaque;
|
|
|
|
unsigned int num;
|
|
|
|
|
|
|
|
if(sscanf(arg , "%d %s", &num, filename) != 2) {
|
|
|
|
free(filename);
|
|
|
|
free(obj);
|
|
|
|
CRIT_ERR(free_at_crash, free_at_crash2, "wrong number of arguments for $ical");
|
|
|
|
}
|
|
|
|
file = fopen(filename, "r");
|
|
|
|
if( ! file) {
|
|
|
|
free(obj);
|
|
|
|
free(free_at_crash);
|
|
|
|
CRIT_ERR(filename, free_at_crash2, "Can't read file %s", filename);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
free(filename);
|
|
|
|
parser = icalparser_new();
|
|
|
|
icalparser_set_gen_data(parser, file);
|
|
|
|
allc = icalparser_parse(parser, read_stream);
|
|
|
|
fclose(file);
|
|
|
|
curc = icalcomponent_get_first_component(allc, ICAL_VEVENT_COMPONENT);
|
|
|
|
if(!curc) {
|
|
|
|
icalparser_free(parser);
|
|
|
|
NORM_ERR("No ical events available");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
ll_start = add_event(NULL, curc);
|
2010-04-28 10:18:15 +00:00
|
|
|
ll_end = ll_start;
|
2010-04-27 14:42:21 +00:00
|
|
|
while(1) {
|
|
|
|
curc = icalcomponent_get_next_component(allc, ICAL_VEVENT_COMPONENT);
|
|
|
|
if(!curc) break;
|
2010-04-28 10:18:15 +00:00
|
|
|
ll_new = add_event(ll_end, curc);
|
2010-04-27 14:42:21 +00:00
|
|
|
if( ! ll_start) { //first component was not added
|
2010-04-28 10:18:15 +00:00
|
|
|
ll_start = ll_new;
|
|
|
|
ll_end = ll_new;
|
2010-04-27 14:42:21 +00:00
|
|
|
}else if( ll_start->prev ) {
|
|
|
|
ll_start = ll_start->prev;
|
2010-04-28 10:18:15 +00:00
|
|
|
}else if( ll_end->next ) {
|
|
|
|
ll_end = ll_end->next;
|
2010-04-27 14:42:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
opaque = (struct obj_ical *) malloc(sizeof(struct obj_ical));
|
|
|
|
opaque->list = ll_start;
|
|
|
|
opaque->parser = parser;
|
|
|
|
opaque->comps = allc;
|
|
|
|
opaque->num = num;
|
|
|
|
obj->data.opaque = opaque;
|
|
|
|
}
|
|
|
|
|
|
|
|
void print_ical(struct text_object *obj, char *p, int p_max_size) {
|
|
|
|
struct obj_ical *ical_obj = (struct obj_ical *) obj->data.opaque;
|
|
|
|
struct ical_event *ll_current = ical_obj->list;
|
|
|
|
|
|
|
|
unsigned int i=1;
|
|
|
|
while(1) {
|
|
|
|
if( ! ll_current) return;
|
|
|
|
if(i > ical_obj->num) return;
|
|
|
|
if(i == ical_obj->num) break;
|
|
|
|
if(i < ical_obj->num) {
|
|
|
|
ll_current = ll_current->next;
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
snprintf(p, p_max_size, "%s", icalproperty_get_summary(icalcomponent_get_first_property(ll_current->event, ICAL_SUMMARY_PROPERTY)));
|
|
|
|
}
|
|
|
|
|
|
|
|
void free_ical(struct text_object *obj) {
|
|
|
|
struct obj_ical *ical_free_me = (struct obj_ical *) obj->data.opaque;
|
|
|
|
icalcomponent_free(ical_free_me->comps);
|
|
|
|
icalparser_free(ical_free_me->parser);
|
|
|
|
while(ical_free_me->list) {
|
|
|
|
if(ical_free_me->list->next) {
|
|
|
|
ical_free_me->list = ical_free_me->list->next;
|
|
|
|
free_and_zero(ical_free_me->list->prev);
|
|
|
|
} else free_and_zero(ical_free_me->list);
|
|
|
|
}
|
|
|
|
free(obj->data.opaque);
|
|
|
|
}
|