Commit c8bac7ef authored by Romain Bignon's avatar Romain Bignon

split files

parent a0a098d6
all:
gcc -o irssleep -Wall -Wextra -ggdb main.c `imlib2-config --cflags` `imlib2-config --libs`
OBJ=main.o \
file.o \
data.o \
image.o
%.o: %.c
gcc -ggdb -Wall -Wextra -Wno-unused-parameter `imlib2-config --cflags` -c $<
all: $(OBJ)
gcc -o irssleep $(OBJ) `imlib2-config --libs`
clean:
rm -rf *.o
distclean: clean
rm -rf irssleep
#include "data.h"
static struct period* insert_period(struct data* data, struct period* prev, struct period* next, time_t start, time_t end)
{
struct period* p = calloc(sizeof(struct period), 1);
p->start = start;
p->end = end;
p->prev = prev;
p->next = next;
if (next)
next->prev = p;
if (prev)
prev->next = p;
else
data->periods = p;
return p;
}
void process_data(struct data* data, time_t start, time_t end)
{
struct period* p;
if (!data->periods)
{
insert_period(data, NULL, NULL, start, end);
return;
}
for (p = data->periods; p; p = p->next)
{
if (start <= p->end + IDLE_TIME)
{
/* p->prev p p->next
* +---------+<> <>+-------------+<> <>+-------+
* |<=====================|
* start
*/
if (end < p->start - IDLE_TIME)
{
/* p->prev p
* +-------+<> <>+----------+
* |<====>|
* period
*/
insert_period(data, p->prev, p, start, end);
return;
}
/* p->prev p p->next
* +-------+<> <>+-----------+<> <>+-------+
* |<=============================---
* period
*/
if (start < p->start)
p->start = start;
if (end > p->end)
{
struct period* next;
p->end = end;
for(next = p->next;
next && end >= next->start - IDLE_TIME;
next = p->next)
{
/* p next
* +-----+<> <>+--------+<>
* --=====================>
*/
p->next = next->next;
if (p->next)
p->next->prev = p;
if (next->end > end)
p->end = next->end;
free(next);
}
}
return;
}
/* Last entry */
if (!p->next)
{
/* p
* +--------+<>
* |<=============---
* start
*/
insert_period(data, p, NULL, start, end);
return;
}
}
}
#ifndef _DATA_H
#define _DATA_H
#include <stdlib.h>
#define IDLE_TIME 60*60
struct period
{
time_t start;
time_t end;
struct period* prev;
struct period* next;
};
struct data
{
struct period* periods;
};
void process_data(struct data* data, time_t start, time_t end);
#endif /* _DATA_H */
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include "data.h"
static int is_in_list(const char *elem, const char **list)
{
for(; *list && strcasecmp(elem, *list); ++list)
;
return *list != NULL;
}
static int str2mon(const char *str)
{
switch(*str)
{
case 'J':
case 'j':
if (str[1] == 'a')
return 0;
else if (str[2] == 'n')
return 5;
else
return 6;
case 'F':
case 'f':
return 1;
case 'M':
case 'm':
if (str[2] == 'r')
return 2;
else
return 4;
case 'A':
case 'a':
if (strchr("pv", str[1]))
return 3;
else
return 7;
case 'S':
case 's':
return 8;
case 'O':
case 'o':
return 9;
case 'N':
case 'n':
return 10;
case 'D':
case 'd':
return 11;
}
fprintf(stderr, "Unknown month '%s'\n", str);
return 0;
}
static int write_ts(int fd, time_t start, time_t end)
{
static time_t ts[2];
ts[0] = start;
ts[1] = end;
return write(fd, &ts, sizeof(ts));
}
int parse_file(int fd, const char **nicknames, const char *filename)
{
char *line = NULL;
size_t len = 0;
ssize_t read;
FILE* fp = fopen(filename, "r");
time_t last = 0, current = 0, start = 0;
struct tm lt;
if (!fp)
{
fprintf(stderr, "Unable to open %s\n", filename);
return -1;
}
while ((read = getline(&line, &len, fp)) != -1)
{
if (line[0] == '-')
{
char *p = NULL, *tmp;
if (!strncmp(line, "--- Log ", 8))
{
/* --- Log opened DDD MMM dd hh:mm:ss yyyy
* --- Log closed DDD MMM dd hh:mm:ss yyyy
*/
p = strchr(line + 15, ' ') + 1; /* don't care about the day of the week */
}
else if (!strncmp(line, "--- Day changed ", 16))
{
/* --- Day changed DDD MMM dd yyyy */
p = strchr(line + 16, ' ') + 1;
}
else
continue;
localtime_r(&current, &lt);
tmp = strchr(p, ' ');
*tmp++ = '\0';
lt.tm_mon = str2mon(p);
p = tmp;
lt.tm_mday = atoi(p);
p = strchr(p, ' ') + 1;
if (strchr(p, ':'))
{ /* There is a time */
lt.tm_hour = atoi(p);
p = strchr(p, ':') + 1;
lt.tm_min = atoi(p);
p = strchr(p, ':') + 1;
lt.tm_sec = atoi(p);
p = strchr(p, ' ') + 1;
}
else
{
lt.tm_hour = 0;
lt.tm_min = 0;
lt.tm_sec = 0;
}
lt.tm_year = atoi(p) - 1900;
current = mktime(&lt);
if (!last)
start = last = current;
/*
char s[300];
strftime(s, sizeof(s), "%D %H-%M-%S", &lt);
printf("%s\n", s);
*/
}
else
{
/* Assume that the line is in form:
* hh:mm [@+<]nick[> ][message]
*/
char *p = strchr(line, ' ');
char *end;
time_t t;
int hh, mm;
if (!p)
continue;
/* Get the nickname. */
while (strchr(" %@+<", *p))
++p; /* skip chan status */
if (strchr(".:-", *p))
continue; /* probably a status line */
end = strchr(p, '>');
if (!end)
end = strchr(p, ' ');
if (!end)
continue;
*end = '\0';
/* Check it's me. */
if (*p != '\0' && !is_in_list(p, nicknames))
continue;
/* Get timestamp */
p = strchr(line, ':') + 1;
hh = atoi(line);
mm = atoi(p);
localtime_r(&current, &lt);
lt.tm_min = mm;
lt.tm_hour = hh;
t = mktime(&lt);
if (t - last > IDLE_TIME)
{
write_ts(fd, start, last);
start = t;
}
current = last = t;
}
}
if (line)
free(line);
if (last)
write_ts(fd, start, last);
fclose(fp);
return 0;
}
#ifndef _FILE_H
#define _FILE_H
int parse_file(int fd, const char **nicknames, const char *filename);
#endif /* _FILE_H */
#include <Imlib2.h>
#include <time.h>
#include <stdio.h>
#include <string.h>
#include "data.h"
static void print_date(const char *text, time_t t)
{
struct tm lt;
char s[300];
localtime_r(&t, &lt);
strftime(s, sizeof(s), "%D %H:%M:%S", &lt);
if (text)
printf("%s: %s\n", text, s);
else
printf("%s\n", s);
}
static time_t reset_day(time_t ts)
{
struct tm lt;
localtime_r(&ts, &lt);
lt.tm_sec = 0;
lt.tm_min = 0;
lt.tm_hour = 0;
return mktime(&lt);
}
int create_image(struct data* data, const char *filename, int quiet)
{
const char *ext;
struct period *p;
time_t first, last;
int days, i;
first = reset_day(data->periods->start);
for (p = data->periods; p; p = p->next)
last = p->end;
last = reset_day(last);
days = difftime(last, first)/(3600*24) + 1;
if (!quiet)
{
print_date("Last", last);
print_date("First", first);
}
const int xgraph = 50;
const int ygraph = 0;
const int hgraph = 24*6;
const int wgraph = days;
Imlib_Image image = imlib_create_image(xgraph + wgraph,
ygraph + hgraph + 50);
imlib_context_set_image(image);
imlib_add_path_to_font_path("/usr/share/fonts/dejavu");
Imlib_Font font = imlib_load_font("DejaVuSans/10");
imlib_context_set_font(font);
for (i = 0; i < 24; ++i)
{
if (!(i % 2))
{
char text[6];
snprintf(text, sizeof text, "%02d:00", i);
imlib_text_draw(5, ygraph + (i*6) - 3, text);
}
}
for (i = 0; i < days; ++i)
{
struct tm lt;
/* TODO Does not work two times in a year because of summer time. */
time_t day_ts = first + (i*24*3600);
localtime_r(&day_ts, &lt);
if (lt.tm_mday == 1 && (lt.tm_mon % 2))
{
char text[10];
strftime(text, sizeof text, "%b %g", &lt);
imlib_context_set_color(255, 255, 255, 255);
imlib_context_set_image(image);
imlib_text_draw(xgraph + i + 5, ygraph + hgraph, text);
imlib_image_fill_rectangle(xgraph + i, ygraph + hgraph, 1, 15);
}
if (lt.tm_wday == 0 || lt.tm_wday == 6)
{
imlib_context_set_color(50, 50, 50, 255);
imlib_context_set_image(image);
imlib_image_fill_rectangle(xgraph + i, 0, 1, hgraph);
}
}
imlib_free_font();
for (p = data->periods; p; p = p->next)
{
struct tm lt_start, lt_end;
int first_day, last_day;
int day;
localtime_r(&p->start, &lt_start);
localtime_r(&p->end, &lt_end);
first_day = difftime(reset_day(p->start), first)/(3600*24);
last_day = difftime(reset_day(p->end), first)/(3600*24);
for (day = first_day; day <= last_day; ++day)
{
int start_h = 0;
int end_h = 24*6-1;
if (day == first_day)
start_h = lt_start.tm_hour * 6 + lt_start.tm_min/10;
if (day == last_day)
end_h = lt_end.tm_hour * 6 + lt_end.tm_min/10;
imlib_context_set_color(255, 0, 130, 255);
imlib_context_set_image(image);
imlib_image_fill_rectangle(xgraph + day, ygraph + start_h, 1, end_h-start_h);
}
}
ext = strrchr(filename, '.');
if (ext)
imlib_image_set_format(ext + 1);
else
imlib_image_set_format("png");
if (!quiet)
printf("Saved in %s\n", filename);
ImlibLoadError err = IMLIB_LOAD_ERROR_UNKNOWN;
imlib_save_image_with_error_return(filename, &err);
imlib_free_image();
return err;
}
#ifndef _IMAGE_H
#define _IMAGE_H
struct data;
extern int create_image(struct data* data, const char *filename, int quiet);
#endif /* _IMAGE_H */
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment