#include #include #include #include "gd.h" #include "gdfontl.h" enum { CAL_BORDER = 2, CELL_BORDER = 5 }; char* month_names[] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; char* week_days[] = { "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa" }; char* color_names[] = { "red", "green", "blue", "yellow" }; char* user; char* map_url; void generate_calendar (char* file_name, int month, int year, int personal_colors[], int group_colors[]); void parse_appointments (int month, int year, FILE* fd, int personal_colors[], int group_colors[]); int main (int argc, char* argv[]) { int month; int year; int personal_colors[31]; int group_colors[31]; int i; char file_name[50]; sprintf (file_name, "/tmp/gif-cal%d", getpid ()); for (i = 0; i < 31; i++) { personal_colors[i] = -1; group_colors[i] = -1; } user = argv[1]; map_url = argv[2]; month = atoi (argv[3]); year = atoi (argv[4]); parse_appointments (month, year, stdin, personal_colors, group_colors); generate_calendar (file_name, month, year, personal_colors, group_colors); printf ("%s\n", file_name); return 0; } int find_color (char* color) { int i; int ncolors = sizeof (color_names) / sizeof (char*); for (i = 0; i < ncolors; i++) if (strcasecmp (color, color_names[i]) == 0) return i; return 0; } void parse_appointments (int month, int year, FILE* fd, int personal_colors[], int group_colors[]) { char line[100]; int len; int app_day; int app_month; int app_year; char app_type[50]; char app_color[50]; while (fgets (line, sizeof (line), fd) != NULL) { if ((len = strlen (line)) > 0) line[len - 1] = '\0'; if (sscanf (line, "%d/%d/%d %50s %50s", &app_month, &app_day, &app_year, app_type, app_color) == 5 && app_month == month && app_year == year) if (strcasecmp (app_type, "group") == 0) group_colors[app_day - 1] = find_color (app_color); else personal_colors[app_day - 1] = find_color (app_color); } } void generate_calendar (char* file_name, int month, int year, int personal_colors[], int group_colors[]) { gdImagePtr image; gdFontPtr font = gdFontLarge; int width; int height; struct tm date; int ndays; int wday; int day; int xpos; int ypos; int background; int foreground; int dark_gray; int first_color; FILE* fd; char buffer[20]; char gif_name[50]; char map_name[50]; sprintf (gif_name, "%s.gif", file_name); sprintf (map_name, "%s.map", file_name); width = 7 * 2 * font->w + 2 * CAL_BORDER + 6 * CELL_BORDER; height = 8 * font->h + 2 * CAL_BORDER + 7 * CELL_BORDER; image = gdImageCreate (width, height); background = gdImageColorAllocate (image, 0xCC, 0xCC, 0xCC); /* gray */ gdImageColorTransparent (image, background); foreground = gdImageColorAllocate (image, 0x00, 0x00, 0x00); /* black */ dark_gray = gdImageColorAllocate (image, 0x66, 0x66, 0x66); /* dark gray */ first_color = gdImageColorAllocate (image, 0xFF, 0x66, 0x66); /* red */ gdImageColorAllocate (image, 0x66, 0xFF, 0x66); /* green */ gdImageColorAllocate (image, 0x66, 0x66, 0xFF); /* blue */ gdImageColorAllocate (image, 0xFF, 0xFF, 0x66); /* yellow */ sprintf (buffer, "%s %d", month_names[month - 1], year); gdImageString (image, font, (width - strlen (buffer) * font->w) / 2, CAL_BORDER, buffer, foreground); for (wday = 0; wday < 7; wday++) gdImageString (image, font, CAL_BORDER + wday * (2 * font->w + CELL_BORDER), CAL_BORDER + font->h + CELL_BORDER, week_days[wday], wday == 0 || wday == 6 ? dark_gray : foreground); memset (&date, 0, sizeof (date)); date.tm_year = year - 1900; date.tm_mon = month - 1; date.tm_mday = 1; mktime (&date); wday = date.tm_wday; if ((month % 2 == 0) == (month >= 8)) ndays = 31; else if (month != 2) ndays = 30; else if (year % 4 == 0) ndays = 29; else ndays = 28; if ((fd = fopen (map_name, "w")) != NULL) fprintf (fd, "\n", year, month); ypos = CAL_BORDER + 2 * (font->h + CELL_BORDER); for (day = 1; day <= ndays; day++, wday++) { if (wday == 7) { wday = 0; ypos += font->h + CELL_BORDER; } xpos = CAL_BORDER + wday * (2 * font->w + CELL_BORDER); if (fd != NULL) fprintf (fd, "\n", xpos, ypos, xpos + 2 * font->w, ypos + font->h, map_url, year, month, day, user); if (personal_colors[day - 1] >= 0) gdImageFilledRectangle (image, xpos, ypos, xpos + font->w, ypos + font->h, personal_colors[day - 1] + first_color); if (group_colors[day - 1] >= 0) gdImageFilledRectangle (image, xpos + font->w, ypos, xpos + 2 * font->w, ypos + font->h, group_colors[day - 1] + first_color); sprintf (buffer, "%2d", day); gdImageString (image, font, xpos, ypos, buffer, wday == 0 || wday == 6 ? dark_gray : foreground); } if (fd != NULL) { fprintf (fd, "\n"); fclose (fd); } if ((fd = fopen (gif_name, "wb")) != NULL) { gdImageGif (image, fd); fclose (fd); } gdImageDestroy (image); }