#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <gemtext.h>
#include "gemlog.h"
static int
find_latest_year(struct gemlog_entry **feed)
{
int i;
int ret;
ret = 0;
for (i = 0; feed[i] != NULL; i++) {
if (feed[i]->date.tm_year > ret)
ret = feed[i]->date.tm_year;
}
return ret;
}
static int
find_latest_month(struct gemlog_entry **feed, int year)
{
int i;
int ret;
ret = 0;
for (i = 0; feed[i] != NULL; i++) {
if (feed[i]->date.tm_year == year) {
if (feed[i]->date.tm_mon > ret)
ret = feed[i]->date.tm_mon;
}
}
return ret;
}
static int
find_latest_day(struct gemlog_entry **feed, int year, int month)
{
int i;
int ret;
ret = 0;
for (i = 0; feed[i] != NULL; i++) {
if (feed[i]->date.tm_year == year && feed[i]->date.tm_mon == month) {
if (feed[i]->date.tm_mday > ret)
ret = feed[i]->date.tm_mday;
}
}
return ret;
}
static int
find_latest_hour(struct gemlog_entry **feed, int year, int month, int day)
{
int i;
int ret;
ret = 0;
for (i = 0; feed[i] != NULL; i++) {
if (feed[i]->date.tm_year == year && feed[i]->date.tm_mon == month && feed[i]->date.tm_mday == day) {
if (feed[i]->date.tm_hour > ret)
ret = feed[i]->date.tm_hour;
}
}
return ret;
}
static int
gemlog_write_index_hour(struct gemlog_entry **feed, int fd, int year, int month, int day, int hour)
{
int i;
char entrybuf[PATH_MAX+1];
char pathbuf[PATH_MAX+1];
char timestamp[11]; /* 1990-01-01\0 */
for (i = 0; feed[i] != NULL; i++) {
if (feed[i]->date.tm_year == year
&& feed[i]->date.tm_mon == month
&& feed[i]->date.tm_mday == day
&& feed[i]->date.tm_hour == hour) {
strftime(timestamp, sizeof(timestamp), "%F", &(feed[i]->date));
snprintf(pathbuf, sizeof(pathbuf), "%d/%d/%d/%d/%s", year+1900, month+1, day, hour, GEMLOG_CONTENT_HTML_FILENAME);
snprintf(entrybuf, sizeof(entrybuf), "<li><a href=\"%s\">%s: %s</a></li>\n", pathbuf, timestamp, feed[i]->title);
if (write(fd, entrybuf, strlen(entrybuf)) == -1)
return -1;
}
}
return 0;
}
static int
gemlog_write_index_day(struct gemlog_entry **feed, int fd, int year, int month, int day)
{
int hour;
for (hour = find_latest_hour(feed, year, month, day); hour != 0; hour--) {
if (gemlog_write_index_hour(feed, fd, year, month, day, hour) == -1)
return -1;
}
return 0;
}
static int
gemlog_write_index_month(struct gemlog_entry **feed, int fd, int year, int month)
{
int day;
for (day = find_latest_day(feed, year, month); day != 0; day--) {
if (gemlog_write_index_day(feed, fd, year, month, day) == -1)
return -1;
}
return 0;
}
static int
gemlog_write_index_year(struct gemlog_entry **feed, int fd, int year)
{
int month;
for (month = find_latest_month(feed, year); month != 0; month--) {
if (gemlog_write_index_month(feed, fd, year, month) == -1)
return -1;
}
return 0;
}
int
gemlog_write_html_index(struct gemlog_entry **feed, const char *path)
{
int year;
int fd;
fd = open(path, O_WRONLY|O_CREAT|O_TRUNC);
if (fd == -1)
return -1;
if (chmod(path, 0644) == -1) {
close(fd);
return -1;
}
if (write(fd, "<ul>\n", strlen("<ul>\n")) == -1) {
close(fd);
return -1;
}
for (year = find_latest_year(feed); year != 0; year--) {
if (gemlog_write_index_year(feed, fd, year) == -1) {
close(fd);
return -1;
}
}
if (write(fd, "</ul>\n", strlen("</ul>\n")) == -1) {
close(fd);
return -1;
}
close(fd);
return 0;
}