#include #include #include typedef struct { int id; char title[256]; char og_title[256]; char directors[1024]; char actors[1024]; char prod_year[32]; char release_date[32]; char duration[32]; char main_genres[256]; char nationality[256]; char pitch[2048]; char poster[256]; char week_times[4096]; char times[4096]; } Movie; Movie movies[64] = {0}; CURL *curl = NULL; static void print_style(int boring_css) { puts(""); puts(""); puts(""); puts(""); if (boring_css) puts(""); else puts(""); /* doq's style */ puts(""); } static void print_times(Movie *movie) { printf("
    \n"); for (const char *tok = strtok(movie->times, ";"); tok != NULL; tok = strtok(NULL, ";")) printf("
  • %s
  • \n", tok); printf("
\n"); } static void print_movie(Movie *movie, int hide_fr) { if (hide_fr && strcmp(movie->nationality, "France") == 0) return; if (movie->og_title[0] != '\0') printf("

%s

\n", movie->og_title); else printf("

%s

\n", movie->title); printf("\"affiche\"\n", movie->poster, movie->poster); printf("
    \n"); printf("
  • réalisateurs : %s
  • \n", movie->directors); printf("
  • acteurs : %s
  • \n", movie->actors); printf("
  • année de production : %s
  • \n", movie->prod_year); printf("
  • date de sortie : %s
  • \n", movie->release_date); printf("
  • durée : %s
  • \n", movie->duration); printf("
  • genres : %s
  • \n", movie->main_genres); printf("
  • nationalité : %s
  • \n", movie->nationality); //printf("synopsis : %s\n", movie->pitch); printf("
  • horaires :
  • \n"); print_times(movie); printf("
\n"); printf("\n"); } static void download_poster(Movie *movie, int skip) { char out_path[512]; char *last_slash = movie->poster; while (strchr(last_slash, '/') != NULL) last_slash = strchr(last_slash, '/') + 1; if (skip) { strcpy(movie->poster, last_slash); return; } strcpy(out_path, "cite/"); strcat(out_path, last_slash); FILE *const fp = fopen(out_path, "wb"); if (fp == NULL) return; curl_easy_setopt(curl, CURLOPT_URL, movie->poster); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, NULL); curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); fprintf(stderr, "getting %s", out_path); fprintf(stderr, "\rgot %s \n", out_path); const CURLcode res = curl_easy_perform(curl); if (res == CURLE_OK) strcpy(movie->poster, last_slash); } static void xfree(const void *ptr) { if (ptr != NULL) xmlFree((void *)ptr); } static int get_id(const xmlNode *node) { const xmlChar *id = xmlGetProp(node, "id"); if (id == NULL) return 0; const int v = atoi(id); xfree(id); return v; } static const xmlNode *get_movie_node(const xmlNode *node) { while (node != NULL && strcmp((const char *)node->name, "film") != 0) node = node->children; return node; } static Movie *get_movie(int id) { Movie *movie = movies; while (movie->id != id && movie->id != 0) movie += 1; return movie; } static int set_movie_base_fields(Movie *movie, const xmlNode *node) { const xmlNode *times_node = node->children; if (times_node == NULL || times_node->next == NULL) return 1; int err = 0; const xmlChar *title = xmlGetProp(node, "titre"); const xmlChar *og_title = xmlGetProp(node, "titreoriginal"); const xmlChar *directors = xmlGetProp(node, "realisateurs"); const xmlChar *actors = xmlGetProp(node, "acteurs"); const xmlChar *prod_year = xmlGetProp(node, "anneeproduction"); const xmlChar *release_date = xmlGetProp(node, "datesortie"); const xmlChar *duration = xmlGetProp(node, "duree"); const xmlChar *main_genres = xmlGetProp(node, "genreprincipal"); const xmlChar *nationality = xmlGetProp(node, "nationalite"); const xmlChar *pitch = xmlGetProp(node, "synopsis"); const xmlChar *poster = xmlGetProp(node, "affichette"); const xmlChar *week_times = xmlNodeGetContent(times_node); const xmlChar *times = xmlNodeGetContent(times_node->next); if (title == NULL || og_title == NULL || directors == NULL || actors == NULL || prod_year == NULL || release_date == NULL || duration == NULL || main_genres == NULL || nationality == NULL || pitch == NULL || poster == NULL || week_times == NULL || times == NULL) { err = 1; goto set_fields_panic; } strncpy(movie->title, title, sizeof(movie->title) - 1); strncpy(movie->og_title, og_title, sizeof(movie->title) - 1); strncpy(movie->directors, directors, sizeof(movie->directors) - 1); strncpy(movie->actors, actors, sizeof(movie->actors) - 1); strncpy(movie->prod_year, prod_year, sizeof(movie->prod_year) - 1); strncpy(movie->release_date, release_date, sizeof(movie->release_date) - 1); strncpy(movie->duration, duration, sizeof(movie->duration) - 1); strncpy(movie->main_genres, main_genres, sizeof(movie->main_genres) - 1); strncpy(movie->nationality, nationality, sizeof(movie->nationality) - 1); strncpy(movie->pitch, pitch, sizeof(movie->pitch) - 1); strncpy(movie->poster, poster, sizeof(movie->poster) - 1); strncpy(movie->week_times, week_times, sizeof(movie->week_times) - 1); strcpy(movie->times, ""); strncat(movie->times, times, sizeof(movie->times) - 1); strncat(movie->times, "", sizeof(movie->times) - 1); set_fields_panic: xfree(title); xfree(og_title); xfree(directors); xfree(actors); xfree(prod_year); xfree(release_date); xfree(duration); xfree(main_genres); xfree(nationality); xfree(pitch); xfree(poster); xfree(week_times); xfree(times); return err; } static int append_movie_times(Movie *movie, const xmlNode *node) { const xmlNode *times_node = node->children; if (times_node == NULL || times_node->next == NULL) return 1; const xmlChar *week_times = xmlNodeGetContent(times_node); const xmlChar *times = xmlNodeGetContent(times_node->next); if (week_times == NULL || times == NULL) { xfree(week_times); xfree(times); return 1; } strncat(movie->week_times, "\n", sizeof(movie->week_times) - 1); strncat(movie->week_times, week_times, sizeof(movie->week_times) - 1); strncat(movie->times, ";", sizeof(movie->times) - 1); strncat(movie->times, times, sizeof(movie->times) - 1); xfree(week_times); xfree(times); return 0; } int main(int argc, char **argv) { if (argc != 5) return 1; xmlDoc *const document = xmlReadFile(argv[1], NULL, 0); if (document == NULL) { xmlCleanupParser(); return 1; } xmlNode *const root = xmlDocGetRootElement(document); if (root == NULL) { xmlCleanupParser(); xmlFreeDoc(document); return 1; } curl = curl_easy_init(); if (curl == NULL) { xmlCleanupParser(); xmlFreeDoc(document); return 1; } for (const xmlNode *week = root->children; week != NULL; week = week->next) { for (const xmlNode *mov = get_movie_node(week); mov != NULL; mov = mov->next) { const int id = get_id(mov); if (id == 0) continue; Movie *movie = get_movie(id); if (movie->id == 0) { movie->id = id; set_movie_base_fields(movie, mov); } else append_movie_times(movie, mov); } } print_style(atoi(argv[3])); puts(""); puts("

cinéma de la cité

"); for (Movie *movie = movies; movie->id != 0; movie++) { download_poster(movie, atoi(argv[4])); print_movie(movie, atoi(argv[2])); } puts(""); puts(""); curl_easy_cleanup(curl); xmlFreeDoc(document); xmlCleanupParser(); return 0; }