Exemplo n.º 1
0
/**
 * rss_parser_load_from_file:
 * @self: a #RssParser
 * @filename: the path to the file to parse
 * @error: a location for a newly created #GError
 *
 * Parses the file found at @filename as an rss file. You can retrieve
 * the parsed document with rss_parser_get_document().
 *
 * Returns: TRUE if the parse was successful
 */
gboolean
rss_parser_load_from_file (RssParser  *self,
                           gchar      *filename,
                           GError    **error)
{
	mrss_t       *mrss;
	mrss_error_t  res;

	g_signal_emit (self, parser_signals[PARSE_START], 0);

	/* parse the buffer */
	res = mrss_parse_file (filename, &mrss);

	/* if there was an error parsing, set the error and return false */
	if (MRSS_OK != res) {
		if (error) {
			g_set_error (error, RSS_PARSER_ERROR,
			             RSS_PARSER_ERROR_INVALID_DATA,
			             "Could not parse file contents");
		}
		return FALSE;
	}

	/* keep a copy of our parsed document */
	self->priv->document = rss_parser_parse (self, mrss);

	/* free our mrss data */
	mrss_free (mrss);

	g_signal_emit (self, parser_signals[PARSE_END], 0);

	return TRUE;
}
Exemplo n.º 2
0
rss_t* load_rss(gchar* feed_url, GError** err){
    
    mrss_t *feed;
    mrss_error_t ret;
    mrss_item_t *item;
    CURLcode code;
    
    ret = mrss_parse_url_with_options_and_error(feed_url, &feed, NULL, &code);
    if(ret){
        if(ret == MRSS_ERR_DOWNLOAD){
            g_set_error(err, rss_quark(), RSS_ERR_CURL, "mrss_curl_strerror: %s\n",
                mrss_curl_strerror(code));
        }
        else{
            g_set_error(err, rss_quark(), RSS_ERR_MRSS, "mrss_strerror: %s\n",
                mrss_strerror(ret));
        }
        return NULL;
    }
    
    rss_t* rss = (rss_t*) malloc(sizeof(rss_t));
    if(rss == NULL){
        g_set_error(err, rss_quark(), RSS_ERR_MEMORY_ALLOC,
            "malloc: Failed to alloc memory for read the rss_t* structure.\n");
        return NULL;
    }
    
    rss->chapters = NULL;
    for(item = feed->item, rss->chap_len = 0; item != NULL; item = item->next, rss->chap_len++){
        rss->chapters = (chapter_t**) realloc(
            rss->chapters, (rss->chap_len + 1) * sizeof(chapter_t*)
        );
        if(rss->chapters == NULL){
            g_set_error(err, rss_quark(), RSS_ERR_MEMORY_ALLOC,
                "malloc: Failed to alloc memory for read the chapter_t** structure.\n");
            return NULL;
        }
        rss->chapters[rss->chap_len] = (chapter_t*) malloc(sizeof(chapter_t));
        if(rss->chapters[rss->chap_len] == NULL){
            g_set_error(err, rss_quark(), RSS_ERR_MEMORY_ALLOC,
                "malloc: Failed to alloc memory for read the chapter_t* structure.\n");
            return NULL;
        }
        
        rss->chapters[rss->chap_len]->title = g_strdup(item->title);
        rss->chapters[rss->chap_len]->url = g_strdup(item->enclosure_url);
        rss->chapters[rss->chap_len]->type = g_strdup(item->enclosure_type);
        rss->chapters[rss->chap_len]->size = item->enclosure_length;
    }
    
    mrss_free(feed);
    
    return rss;
}
Exemplo n.º 3
0
mrss_error_t mrss_parse_url_auth(char *url, mrss_t ** ret, char *userpass,
				 long int authtype)
{
    __mrss_download_t *download;
    nxml_t         *doc;
    mrss_error_t    err;

    if (!url || !ret) {
        return MRSS_ERR_DATA;
    }

    if (!(download = __mrss_download_file_auth(url, __mrss_timeout, userpass,
				               authtype))) {
        return MRSS_ERR_POSIX;
    }

    if (nxml_new(&doc) != NXML_OK) {
        return MRSS_ERR_POSIX;
    }

    if (nxml_parse_buffer(doc, download->mm, download->size) != NXML_OK) {
        free(download->mm);
        free(download);

        nxml_free(doc);

        return MRSS_ERR_PARSER;
    }

    if (!(err = __mrss_parser(doc, ret))) {
        if (!((*ret)->file = strdup(url))) {
            free(download->mm);
            free(download);

            mrss_free(*ret);
            nxml_free(doc);

            return MRSS_ERR_POSIX;
        }

        (*ret)->size = download->size;
    }

    free(download->mm);
    free(download);

    nxml_free(doc);

    return err;
}
Exemplo n.º 4
0
mrss_error_t
mrss_parse_file (char *file, mrss_t ** ret)
{
  nxml_t *doc;
  mrss_error_t err;
  struct stat st;

  if (!file || !ret)
    return MRSS_ERR_DATA;

  if (lstat (file, &st))
    return MRSS_ERR_POSIX;

  if (nxml_new (&doc) != NXML_OK)
    return MRSS_ERR_POSIX;

  if (nxml_parse_file (doc, file) != NXML_OK)
    {
      nxml_free (doc);
      return MRSS_ERR_PARSER;
    }

  if (!(err = __mrss_parser (doc, ret)))
    {
      if (!((*ret)->file = strdup (file)))
	{
	  nxml_free (doc);
	  mrss_free (*ret);

	  return MRSS_ERR_POSIX;
	}

      (*ret)->size = st.st_size;
    }

  nxml_free (doc);

  return err;
}
Exemplo n.º 5
0
int main(int argc, char *argv[])
{
	char **url = NULL;
	int n_url = 0, cur_url = 0;
	int check_interval = 15 * 60;
	mrss_t **data_prev = NULL;
	mrss_t **data_cur = NULL;
	int data_size;
	char *proxy = NULL, *proxy_auth = NULL;
	int sw;
	int verbose = 0;
	char show_timestamp = 0, show_link = 0, show_description = 0, show_pubdate = 0, show_author = 0, show_comments = 0;
	char strip_html = 0, no_error_exit = 0;
	char one_shot = 0;
	char no_heading = 0;
	int bytes_limit = 0;
	time_t last_changed = (time_t)0;
	char continue_on_error = 0, dummy;
	int show_n = -1;
	long int max_age = -1;
	char *heading = NULL;
	mrss_options_t mot;
	char *auth = NULL;
	char *current_encoding = NULL;
	char reverse = 0;
    iconv_t converter = 0;

	memset(&mot, 0x00, sizeof(mot));

	while((sw = getopt(argc, argv, "A:Z:1b:PHztldrpacu:Ni:n:x:y:vVh")) != -1)
	{
		switch(sw)
		{
			case 'A':
				auth = optarg;
				break;

			case 'Z':
				heading = optarg;
				break;

			case 'N':
				no_heading = 1;
				break;

			case '1':
				one_shot = 1;
				break;

			case 'b':
				bytes_limit = atoi(optarg);
				if (bytes_limit <= 0)
				{
					printf("-b requires a number > 0\n");
					return 1;
				}
				break;

			case 'P':
				no_error_exit = 1;
				break;

			case 'H':
				strip_html = 1;
				break;

			case 'n':
				show_n = atoi(optarg);
				if (show_n < 0)
				{
					printf("-n requires an positive value\n");
					return 1;
				}
				else if (show_n > 50)
					printf("Initially showing more then 50 items, must be one hell of an rss feed!\n");
				break;

#if 0
			case 'o':
				dummy = optarg[strlen(optarg) - 1];
				max_age = atoi(optarg);
				if (max_age < 0)
				{
					printf("-o requires an positive value\n");
					return 1;
				}
				if (dummy == 's')
					max_age *= 1;
				else if (dummy == 'M')
					max_age *= 60;
				else if (dummy == 'h')
					max_age *= 3600;
				else if (dummy == 'd')
					max_age *= 86400;
				else if (dummy == 'm')
					max_age *= 86400 * 31;
				else if (dummy == 'y')
					max_age *= 86400 * 365.25;
				else if (isalpha(dummy))
				{
					printf("'%c' is a not recognized multiplier\n", dummy);
					return 1;
				}
				break;
#endif

			case 'z':
				continue_on_error = 1;
				break;

			case 't':
				show_timestamp = 1;
				break;

			case 'l':
				show_link = 1;
				break;

			case 'd':
				show_description = 1;
				break;

			case 'r':
				reverse = 1;
				break;

			case 'p':
				show_pubdate = 1;
				break;

			case 'a':
				show_author = 1;
				break;

			case 'c':
				show_comments = 1;
				break;

			case 'u':
				url = (char **)realloc(url, sizeof(char *) * (n_url + 1));
				if (!url)
				{
					fprintf(stderr, "Cannot allocate memory\n");
					return 2;
				}
				url[n_url++] = optarg;
				break;

			case 'i':
				check_interval = atoi(optarg);
				break;

			case 'x':
				proxy = optarg;
				break;
			
			case 'y':
				proxy_auth = optarg;
				break;

			case 'v':
				verbose++;
				break;

			case 'V':
				version();
				return 1;

			case 'h':
			default:
				usage();
				return 1;
		}
	}

	mot.timeout = check_interval;
    	mot.proxy = proxy;
	mot.proxy_authentication = proxy_auth;
	mot.user_agent = "rsstail " VERSION ", (C) 2006-2013 by [email protected]";
	mot.authentication = auth;

	if (n_url == 0)
	{
		fprintf(stderr, "Please give the URL of the RSS feed to check with the '-u' parameter.\n");
		return 1;
	}

	data_size = sizeof(mrss_t *) * n_url;
	data_prev = (mrss_t **)malloc(data_size);
	data_cur  = (mrss_t **)malloc(data_size);
	if (!data_prev || !data_cur)
	{
		fprintf(stderr, "Cannot allocate memory\n");
		return 2;
	}

	memset(data_prev, 0x00, data_size);
	memset(data_cur , 0x00, data_size);

	setlocale(LC_ALL, "");
	current_encoding = nl_langinfo(CODESET);

	if (verbose)
	{
		int loop;
		printf("Monitoring RSS feeds:\n");
		for(loop=0; loop<n_url; loop++)
			printf("\t%s\n", url[loop]);
		printf("Check interval: %d\n", check_interval);
		printf("Output current_encoding: %s\n", current_encoding);
	}

	for(;;)
	{
		mrss_error_t err_read;
		mrss_item_t *item_cur = NULL;
		mrss_item_t *first_item[n_url];
		mrss_item_t *tmp_first_item;
		time_t cur_last_changed;
		int n_shown = 0;

		if (verbose)
			printf("Retrieving RSS feed '%s'...\n", url[cur_url]);

		if ((err_read = mrss_get_last_modified_with_options(url[cur_url], &cur_last_changed, &mot)) != MRSS_OK)
		{
			if (err_read == MRSS_ERR_POSIX)
			{
				if (errno == EINPROGRESS)
				{
					fprintf(stderr, "Time-out while connecting to RSS feed, continuing\n");
					goto goto_next_url;
				}
			}

			fprintf(stderr, "Error reading RSS feed: %s\n", mrss_strerror(err_read));

			if (no_error_exit)
				goto goto_next_url;
			else
				return 2;
		}

		if (cur_last_changed == last_changed && cur_last_changed != 0)
		{
			if (verbose)
				printf("Feed did not change since last check.\n");
			goto goto_next_url;
		}
		else if (verbose > 2)
		{
			printf("Feed change detected, %s", ctime(&cur_last_changed));
		}

		last_changed = cur_last_changed;

		if ((err_read = mrss_parse_url_with_options(url[cur_url], &data_cur[cur_url], &mot)) != MRSS_OK)
		{
			if (err_read == MRSS_ERR_POSIX)
			{
				if (errno == EINPROGRESS)
				{
					fprintf(stderr, "Time-out while connecting to RSS feed, continuing\n");
					goto goto_next_url;
				}
			}
			else if (err_read == MRSS_ERR_PARSER && continue_on_error)
			{
				fprintf(stderr, "Error reading RSS feed: %s\n", mrss_strerror(err_read));
				goto goto_next_url;
			}

			fprintf(stderr, "Error reading RSS feed: %s\n", mrss_strerror(err_read));
			if (no_error_exit)
				goto goto_next_url;
			else
				return 2;
		}

        if (verbose)
          printf("Creating converter %s -> %s\n", data_cur[cur_url] -> encoding, current_encoding);
        converter = iconv_open(current_encoding, data_cur[cur_url] -> encoding);
        if (converter == (iconv_t) -1) {
          fprintf(stderr, "Error creating converter: %s \n", strerror(errno));
          return 2;
        }

		item_cur = data_cur[cur_url] -> item;

		if (reverse) {
			if (verbose)
			       printf("Reversing...\n");
			mrss_item_t *rev_item_cur = NULL;
			mrss_item_t *rev_item_last = NULL;
			for (;;) {
			       rev_item_last = rev_item_cur;
			       rev_item_cur = item_cur;
			       if (item_cur -> next) {
				       item_cur = item_cur -> next;
				       rev_item_cur -> next = rev_item_last;
			       }
			       else {
				       rev_item_cur -> next = rev_item_last;
				       break;
			       }
			}
		}

		tmp_first_item = item_cur;

		while(item_cur)
		{
			if ((data_prev[cur_url] && is_new_record(first_item[cur_url], item_cur) != -1) ||
			    (!data_prev[cur_url]))
			{
#if 0
				if (/* pubdate */ < max_age && max_age != -1)
					continue;
#endif

				if ((!data_prev[cur_url]) && n_shown >= show_n && show_n != -1)
				{
					item_cur = item_cur -> next;
					continue;
				}
				n_shown++;

				if ((show_link + show_description + show_pubdate + show_author + show_comments ) > 1)
					printf("\n");

				if (show_timestamp)
				{
					time_t now = time(NULL);
					struct tm *now_tm = localtime(&now);

					printf("%04d/%02d/%02d %02d:%02d:%02d  ",
							now_tm -> tm_year + 1900,
							now_tm -> tm_mon + 1,
							now_tm -> tm_mday,
							now_tm -> tm_hour,
							now_tm -> tm_min,
							now_tm -> tm_sec);
				}

				if (heading)
				{
					printf(" %s", heading);
				}

				if (item_cur -> title != NULL) {
                    char *title = my_convert(converter, item_cur -> title);
                    if (title) {
                      printf("%s%s\n", no_heading?" ":"Title: ", title);
                      free(title);
                    }
                }

				if (show_link && item_cur -> link != NULL) {
                    char *link = my_convert(converter, item_cur -> link);
                    if(link) {
                      printf("%s%s\n", no_heading?" ":"Link: ", item_cur -> link);
                      free(link);
                    }
                }

				if (show_description && item_cur -> description != NULL)
				{
					if (strip_html)
					{
						char *stripped = remove_html_tags(item_cur -> description);

						if (bytes_limit != 0 && bytes_limit < strlen(stripped))
							stripped[bytes_limit] = 0x00;

                        char *description = my_convert(converter, stripped);
                        if (description) {
                          printf("%s%s\n", no_heading?" ":"Description: ", description);
                          free(description);
                        }

						free(stripped);
					}
					else
					{
						if (bytes_limit != 0 && bytes_limit < strlen(item_cur -> description))
							(item_cur -> description)[bytes_limit] = 0x00;

                        char *description = my_convert(converter, item_cur -> description);
                        if (description) {
                          printf("%s%s\n", no_heading?" ":"Description: ", description);
                          free(description);
                        }
					}
				}

				if (show_pubdate && item_cur -> pubDate != NULL)
					printf("%s%s\n", no_heading?" ":"Pub.date: ", item_cur -> pubDate);

				if (show_author && item_cur -> author != NULL){
                    char *author = my_convert(converter, item_cur -> author);
                    if (author) {
                      printf("%s%s\n", no_heading?" ":"Author: ", author);
                      free(author);
                    }
                }

				if (show_comments && item_cur -> comments != NULL)
				{
					if (bytes_limit != 0 && bytes_limit < strlen(item_cur -> comments))
						(item_cur -> comments)[bytes_limit] = 0x00;

                    char *comments = my_convert(converter, item_cur -> comments);
                    if (comments) {
                      printf("%s%s\n", no_heading?" ":"Comments: ", item_cur -> comments);
                      free(comments);
                    }
				}
			}

			item_cur = item_cur -> next;
		}

		if (data_prev[cur_url])
		{
			mrss_error_t err_free = mrss_free(data_prev[cur_url]);

			if (err_free != MRSS_OK)
			{
				fprintf(stderr, "Error freeing up memory: %s\n", mrss_strerror(err_read));
				if (no_error_exit)
					goto goto_next_url;
				else
					return 2;
			}
		}

		data_prev[cur_url] = data_cur[cur_url];
		data_cur[cur_url] = NULL;
		first_item[cur_url] = tmp_first_item;

goto_next_url:
        if (converter) {
          iconv_close (converter);
          converter = 0;
        }
		cur_url++;
		if (cur_url == n_url)
			cur_url = 0;

		fflush(stdout);

		if (one_shot)
			break;

		if (verbose > 2)
			printf("Sleeping...\n");
		sleep(check_interval / n_url);
	}

	return 0;
}
Exemplo n.º 6
0
static mrss_error_t
__mrss_parser_rss (mrss_version_t v, nxml_t * doc, nxml_data_t * cur,
		   mrss_t ** ret)
{
  mrss_t *data;
  char *c, *attr;

  if (!(data = (mrss_t *) malloc (sizeof (mrss_t))))
    return MRSS_ERR_POSIX;

  memset (data, 0, sizeof (mrss_t));
  data->element = MRSS_ELEMENT_CHANNEL;
  data->allocated = 1;
  data->version = v;

  if (doc->encoding && !(data->encoding = strdup (doc->encoding)))
    {
      mrss_free (data);
      return MRSS_ERR_POSIX;
    }

  if (data->version == MRSS_VERSION_1_0)
    {
      nxml_data_t *cur_channel = NULL;

      while (cur)
	{

	  if (!strcmp (cur->value, "channel"))
	    cur_channel = cur;

	  else if (!strcmp (cur->value, "image"))
	    __mrss_parser_rss_image (doc, cur, data);

	  else if (!strcmp (cur->value, "textinput"))
	    __mrss_parser_rss_textinput (doc, cur, data);

	  else if (!strcmp (cur->value, "item"))
	    __mrss_parser_rss_item (doc, cur, data);

	  cur = cur->next;
	}

      cur = cur_channel;
    }
  else
    {
      while (cur && strcmp (cur->value, "channel"))
	cur = cur->next;
    }

  if (!cur)
    {
      mrss_free (data);
      return MRSS_ERR_PARSER;
    }

  if (data->version == MRSS_VERSION_1_0)
    {
      if ((attr = nxmle_find_attribute (cur, "about", NULL)))
	data->about = attr;
    }

  for (cur = cur->children; cur; cur = cur->next)
    {
      if (cur->type == NXML_TYPE_ELEMENT)
	{
	  /* title */
	  if (!strcmp (cur->value, "title") && !data->title &&
	      (c = nxmle_get_string (cur, NULL)))
	    data->title = c;

	  /* description */
	  else if (!strcmp (cur->value, "description") && !data->description
		   && (c = nxmle_get_string (cur, NULL)))
	    data->description = c;

	  /* link */
	  else if (!strcmp (cur->value, "link") && !data->link
		   && (c = nxmle_get_string (cur, NULL)))
	    data->link = c;

	  /* language */
	  else if (!strcmp (cur->value, "language") && !data->language
		   && (c = nxmle_get_string (cur, NULL)))
	    data->language = c;

	  /* rating */
	  else if (!strcmp (cur->value, "rating") && !data->rating
		   && (c = nxmle_get_string (cur, NULL)))
	    data->rating = c;

	  /* copyright */
	  else if (!strcmp (cur->value, "copyright") && !data->copyright
		   && (c = nxmle_get_string (cur, NULL)))
	    data->copyright = c;

	  /* pubDate */
	  else if (!strcmp (cur->value, "pubDate") && !data->pubDate
		   && (c = nxmle_get_string (cur, NULL)))
	    data->pubDate = c;

	  /* lastBuildDate */
	  else if (!strcmp (cur->value, "lastBuildDate")
		   && !data->lastBuildDate
		   && (c = nxmle_get_string (cur, NULL)))
	    data->lastBuildDate = c;

	  /* docs */
	  else if (!strcmp (cur->value, "docs") && !data->docs
		   && (c = nxmle_get_string (cur, NULL)))
	    data->docs = c;

	  /* managingeditor */
	  else if (!strcmp (cur->value, "managingeditor")
		   && !data->managingeditor
		   && (c = nxmle_get_string (cur, NULL)))
	    data->managingeditor = c;

	  /* webMaster */
	  else if (!strcmp (cur->value, "webMaster") && !data->webMaster
		   && (c = nxmle_get_string (cur, NULL)))
	    data->webMaster = c;

	  /* image */
	  else if (!strcmp (cur->value, "image"))
	    __mrss_parser_rss_image (doc, cur, data);

	  /* textinput */
	  else if (!strcmp (cur->value, "textinput"))
	    __mrss_parser_rss_textinput (doc, cur, data);

	  /* skipHours */
	  else if (!strcmp (cur->value, "skipHours"))
	    __mrss_parser_rss_skipHours (doc, cur, data);

	  /* skipDays */
	  else if (!strcmp (cur->value, "skipDays"))
	    __mrss_parser_rss_skipDays (doc, cur, data);

	  /* item */
	  else if (!strcmp (cur->value, "item"))
	    __mrss_parser_rss_item (doc, cur, data);

	  /* category */
	  else if (!strcmp (cur->value, "category")
		   && (c = nxmle_get_string (cur, NULL)))
	    {
	      mrss_category_t *category;

	      if (!
		  (category =
		   (mrss_category_t *) malloc (sizeof (mrss_category_t))))
		{
		  mrss_free ((mrss_generic_t *) data);
		  free (c);
		  return MRSS_ERR_POSIX;
		}

	      memset (category, 0, sizeof (mrss_category_t));

	      category->element = MRSS_ELEMENT_CATEGORY;
	      category->allocated = 1;
	      category->category = c;

	      if ((attr = nxmle_find_attribute (cur, "domain", NULL)))
		category->domain = attr;

	      if (!data->category)
		data->category = category;
	      else
		{
		  mrss_category_t *tmp;

		  tmp = data->category;
		  while (tmp->next)
		    tmp = tmp->next;
		  tmp->next = category;
		}
	    }

	  /* enclosure */
	  else if (!strcmp (cur->value, "cloud") && !data->cloud)
	    {
	      data->cloud = nxmle_get_string (cur, NULL);

	      if (!data->cloud_domain
		  && (attr = nxmle_find_attribute (cur, "domain", NULL)))
		data->cloud_domain = attr;

	      if (!data->cloud_port
		  && (attr = nxmle_find_attribute (cur, "port", NULL)))
		data->cloud_port = atoi (attr);

	      if (!data->cloud_registerProcedure
		  && (attr =
		      nxmle_find_attribute (cur, "registerProcedure", NULL)))
		data->cloud_registerProcedure = attr;

	      if (!data->cloud_protocol
		  && (attr = nxmle_find_attribute (cur, "protocol", NULL)))
		data->cloud_protocol = attr;
	    }

	  /* generator */
	  else if (!strcmp (cur->value, "generator") && !data->generator
		   && (c = nxmle_get_string (cur, NULL)))
	    data->generator = c;

	  /* ttl */
	  else if (!strcmp (cur->value, "ttl") && !data->ttl
		   && (c = nxmle_get_string (cur, NULL)))
	    {
	      data->ttl = atoi (c);
	      free (c);
	    }

	}
    }

  *ret = data;

  return MRSS_OK;
}
Exemplo n.º 7
0
int
main (int argc, char **argv)
{
  mrss_t *data;
  mrss_error_t ret;
  char *buffer;
  int i;

  data = NULL;
  fprintf (stdout, "New data... ");
  ret = mrss_new (&data);
  check (ret);

  fprintf (stdout, "Set some values... ");
  ret = mrss_set (data,
		  MRSS_FLAG_VERSION, MRSS_VERSION_2_0,
		  MRSS_FLAG_TITLE, "a title",
		  MRSS_FLAG_DESCRIPTION, "a description",
		  MRSS_FLAG_LINK, "a link",
		  MRSS_FLAG_LANGUAGE, "it_IT",
		  MRSS_FLAG_RATING, "rating",
		  MRSS_FLAG_COPYRIGHT, "the copyright",
		  MRSS_FLAG_PUBDATE, "today",
		  MRSS_FLAG_LASTBUILDDATE, "yesterday",
		  MRSS_FLAG_DOCS, "http://autistici.org/bakunin",
		  MRSS_FLAG_MANAGINGEDITOR, "vim",
		  MRSS_FLAG_WEBMASTER, "b",
		  MRSS_FLAG_GENERATOR, "none!",
		  MRSS_FLAG_TTL, 255,
		  MRSS_FLAG_IMAGE_TITLE, "title of the image",
		  MRSS_FLAG_IMAGE_URL, "http://autistici.org/bakunin/img.png",
		  MRSS_FLAG_IMAGE_LINK, "http://autistici.org/bakunin/",
		  MRSS_FLAG_IMAGE_WIDTH, 1000,
		  MRSS_FLAG_IMAGE_HEIGHT, 2000,
		  MRSS_FLAG_IMAGE_DESCRIPTION, "no image description",
		  MRSS_FLAG_TEXTINPUT_TITLE, "textinput title",
		  MRSS_FLAG_TEXTINPUT_DESCRIPTION, "textinput description",
		  MRSS_FLAG_TEXTINPUT_NAME, "textinput name",
		  MRSS_FLAG_TEXTINPUT_LINK, "http://autistici.org/bakunin",
		  MRSS_FLAG_CLOUD, "Cloud!",
		  MRSS_FLAG_CLOUD_DOMAIN, "autistici.org",
		  MRSS_FLAG_CLOUD_PORT, 8080,
		  MRSS_FLAG_CLOUD_PATH, "/bakunin/rss",
		  MRSS_FLAG_CLOUD_REGISTERPROCEDURE, "none",
		  MRSS_FLAG_CLOUD_PROTOCOL, "gopher", MRSS_FLAG_END);
  check (ret);

  for (i = 0; i < 10; i++)
    {
      mrss_hour_t *hour = NULL;
      char s[1024];

      fprintf (stdout, "New skipHours element... ");
      ret = mrss_new_subdata (data, MRSS_ELEMENT_SKIPHOURS, &hour);
      check (ret);

      snprintf (s, sizeof (s), "Element %d", i);
      fprintf (stdout, "Set skipHours value... ");
      ret = mrss_set (hour, MRSS_FLAG_HOUR, s, MRSS_FLAG_END);
      check (ret);
    }

  for (i = 0; i < 10; i++)
    {
      mrss_day_t *day = NULL;
      char s[1024];

      fprintf (stdout, "New skipDays element... ");
      ret = mrss_new_subdata (data, MRSS_ELEMENT_SKIPDAYS, &day);
      check (ret);

      snprintf (s, sizeof (s), "Element %d", i);
      fprintf (stdout, "Set skipDays value... ");
      ret = mrss_set (day, MRSS_FLAG_DAY, s, MRSS_FLAG_END);
      check (ret);
    }

  for (i = 0; i < 10; i++)
    {
      mrss_category_t *category = NULL;
      char s1[1024];
      char s2[1024];

      fprintf (stdout, "New category element... ");
      ret = mrss_new_subdata (data, MRSS_ELEMENT_CATEGORY, &category);
      check (ret);

      snprintf (s1, sizeof (s1), "Element %d", i);
      snprintf (s2, sizeof (s2), "Domain %d", i);
      fprintf (stdout, "Set category values... ");
      ret = mrss_set (category,
		      MRSS_FLAG_CATEGORY, s1,
		      MRSS_FLAG_CATEGORY_DOMAIN, s2, MRSS_FLAG_END);
      check (ret);
    }

  for (i = 0; i < 10; i++)
    {
      mrss_tag_t *tag = NULL;
      char s1[1024];
      char s2[1024];
      char s3[1024];

      fprintf (stdout, "New tag element... ");
      ret = mrss_new_subdata (data, MRSS_ELEMENT_TAG, &tag);
      check (ret);

      snprintf (s1, sizeof (s1), "Element %d", i);
      snprintf (s2, sizeof (s2), "element_%d", i);
      snprintf (s3, sizeof (s3), "http://www.something.net/");
      fprintf (stdout, "Set tag value... ");
      ret = mrss_set (tag, MRSS_FLAG_TAG_NAME, s2,
		      MRSS_FLAG_TAG_VALUE, s1,
		      MRSS_FLAG_TAG_NS, s3, MRSS_FLAG_END);
      check (ret);
    }

  for (i = 0; i < 10; i++)
    {
      mrss_item_t *item = NULL;
      int j;

      fprintf (stdout, "New item element... ");
      ret = mrss_new_subdata (data, MRSS_ELEMENT_ITEM, &item);
      check (ret);

      fprintf (stdout, "Set item values... ");
      ret = mrss_set (item,
		      MRSS_FLAG_ITEM_TITLE, "item title",
		      MRSS_FLAG_ITEM_LINK, "item link",
		      MRSS_FLAG_ITEM_DESCRIPTION, "item description",
		      MRSS_FLAG_ITEM_AUTHOR, "item author",
		      MRSS_FLAG_ITEM_COMMENTS, "item comments",
		      MRSS_FLAG_ITEM_PUBDATE, "item pubdate",
		      MRSS_FLAG_ITEM_GUID, "item guid",
		      MRSS_FLAG_ITEM_GUID_ISPERMALINK, 1 /* 0 is false */ ,
		      MRSS_FLAG_ITEM_SOURCE, "item source",
		      MRSS_FLAG_ITEM_SOURCE_URL, "item source url",
		      MRSS_FLAG_ITEM_ENCLOSURE, "item enclosure",
		      MRSS_FLAG_ITEM_ENCLOSURE_URL, "item enclosure url",
		      MRSS_FLAG_ITEM_ENCLOSURE_LENGTH, 1234,
		      MRSS_FLAG_ITEM_ENCLOSURE_TYPE, "item enclosure type",
		      MRSS_FLAG_END);

      for (j = 0; j < 10; j++)
	{
	  mrss_category_t *category = NULL;
	  char s1[1024];
	  char s2[1024];

	  fprintf (stdout, "New category element... ");
	  ret = mrss_new_subdata (item, MRSS_ELEMENT_CATEGORY, &category);
	  check (ret);

	  snprintf (s1, sizeof (s1), "Element %d", j);
	  snprintf (s2, sizeof (s2), "Domain %d", j);
	  fprintf (stdout, "Set category values... ");
	  ret = mrss_set (category,
			  MRSS_FLAG_CATEGORY, s1,
			  MRSS_FLAG_CATEGORY_DOMAIN, s2, MRSS_FLAG_END);
	  check (ret);
	}

      for (i = 0; i < 10; i++)
	{
	  mrss_tag_t *tag = NULL;
	  char s1[1024];
	  char s2[1024];
	  char s3[1024];
	  int j;

	  fprintf (stdout, "New tag element... ");
	  ret = mrss_new_subdata (item, MRSS_ELEMENT_TAG, &tag);
	  check (ret);

	  snprintf (s1, sizeof (s1), "Element %d", i);
	  snprintf (s2, sizeof (s2), "element_%d", i);
	  snprintf (s3, sizeof (s3), "http://www.something%d.net/", i);
	  fprintf (stdout, "Set tag value... ");
	  ret = mrss_set (tag, MRSS_FLAG_TAG_NAME, s2,
			  MRSS_FLAG_TAG_VALUE, s1,
			  MRSS_FLAG_TAG_NS, s3, MRSS_FLAG_END);
	  check (ret);

	  for (j = 0; j < 10; j++)
	    {
	      mrss_attribute_t *attribute = NULL;
	      char s1[1024];
	      char s2[1024];
	      char s3[1024];

	      fprintf (stdout, "New attribute element... ");
	      ret =
		mrss_new_subdata (tag, MRSS_ELEMENT_ATTRIBUTE, &attribute);
	      check (ret);

	      snprintf (s1, sizeof (s1), "Element %d", j);
	      snprintf (s2, sizeof (s2), "element_%d", j);
	      snprintf (s3, sizeof (s3), "http://www.something%d.net/", j);
	      fprintf (stdout, "Set attribute value... ");
	      ret = mrss_set (attribute, MRSS_FLAG_ATTRIBUTE_NAME, s2,
			      MRSS_FLAG_ATTRIBUTE_VALUE, s1,
			      MRSS_FLAG_ATTRIBUTE_NS, s3, MRSS_FLAG_END);
	      check (ret);
	    }
	}

      check (ret);
    }

  buffer = NULL;
  fprintf (stdout, "Create the RSS in memory... ");
  ret = mrss_write_buffer (data, &buffer);
  check (ret);

  puts (buffer);
  free (buffer);
  mrss_free (data);

  return 0;
}
Exemplo n.º 8
0
Arquivo: tpod.c Projeto: grafoo/tpod
/* todo: save podcast episodes to db rather than loading them every time */
char *load_episodes() {
  int i;
  int podcast_uris_num;
  char **podcast_uris = select_podcasts(&podcast_uris_num);

  mrss_t *feed;
  mrss_item_t *episode;
  mrss_tag_t *other_tags;

  json_t *jsn_podcasts_obj = json_object();
  json_t *jsn_podcasts_arr = json_array();

  for (i = 0; i < podcast_uris_num; i++) {
    mrss_parse_url_with_options_and_error(podcast_uris[i], &feed, NULL, NULL);
    json_t *jsn_podcast_obj = json_object();
    json_object_set_new(jsn_podcast_obj, "title", json_string(feed->title));
    json_t *jsn_episodes_arr = json_array();
    episode = feed->item;
    while (episode) {
      struct tm tm_publish;
      time_t time_now, time_publish;

      memset(&tm_publish, 0, sizeof(struct tm));
      time(&time_now);

      /*
       episode->pubDate is formated like e.g. Sat, 30 Jul 2016 00:00:00 +0200
       when parsing the datetime string only year, month and day will be used
       for windows something like e.g.
         char month[4];
         int day, year;
         sscanf(episode->pubDate, "%*s %d %s %d %*d:%*d:%*d %*s", &day, month,
       &year);
       could be used instead of relying on strptime
      */

      /* time string format like "Sat, 06 Aug 2016 08:14:24 +0200" */
      if (strptime(episode->pubDate, "%a, %0d %b %Y %T %z", &tm_publish) !=
          NULL) {
        double time_diff = difftime(time_now, mktime(&tm_publish));
        if (time_diff / 86400.0 > 30.0) {
          break;
        }
      }
      /* time string format like "Sat, 30 Jul 2016 01:00:00 GMT" */
      else if (strptime(episode->pubDate, "%a, %0d %b %Y %T %Z", &tm_publish) !=
               NULL) {
        double time_diff = difftime(time_now, mktime(&tm_publish));
        if (time_diff / 86400.0 > 30.0) {
          break;
        }
      } else {
        printf("unsopported time format: %s\n", episode->pubDate);
        break;
      }

      json_t *jsn_episode_obj = json_object();
      json_object_set_new(jsn_episode_obj, "title",
                          json_string(episode->title));
      json_object_set_new(jsn_episode_obj, "description",
                          json_string(episode->description));
      json_object_set_new(jsn_episode_obj, "stream_uri",
                          json_string(episode->enclosure_url));
      if (episode->other_tags) {
        other_tags = episode->other_tags;
        while (other_tags) {
          if (strcmp(other_tags->name, "duration") == 0) {
            json_object_set_new(jsn_episode_obj, "duration",
                                json_string(other_tags->value));
          }
          other_tags = other_tags->next;
        }
      }
      episode = episode->next;
      json_array_append_new(jsn_episodes_arr, jsn_episode_obj);
    }
    mrss_free(feed);
    json_object_set_new(jsn_podcast_obj, "episodes", jsn_episodes_arr);
    json_array_append_new(jsn_podcasts_arr, jsn_podcast_obj);
    free(podcast_uris[i]);
  }

  free(podcast_uris);

  json_object_set_new(jsn_podcasts_obj, "podcasts", jsn_podcasts_arr);

  return json_dumps(jsn_podcasts_obj, JSON_COMPACT);
}
Exemplo n.º 9
0
static mrss_error_t
__mrss_parser_atom (nxml_t * doc, nxml_data_t * cur, mrss_t ** ret)
{
  mrss_t *data;
  char *c = NULL;

  if (!(data = malloc (sizeof (mrss_t))))
    return MRSS_ERR_POSIX;

  memset (data, 0, sizeof (mrss_t));
  data->element = MRSS_ELEMENT_CHANNEL;
  data->allocated = 1;
  data->version = MRSS_VERSION_ATOM_1_0;

  if (doc->encoding && !(data->encoding = strdup (doc->encoding)))
    {
      mrss_free (data);
      return MRSS_ERR_POSIX;
    }

  if (!data->language && (c = nxmle_find_attribute (cur, "xml:lang", NULL)))
    data->language = c;

  if ((c = nxmle_find_attribute (cur, "version", NULL)))
    {
      if (!strcmp (c, "0.3"))
	data->version = MRSS_VERSION_ATOM_0_3;

      free (c);
    }

  for (cur = cur->children; cur; cur = cur->next)
    {
      if (cur->type == NXML_TYPE_ELEMENT)
	{
	  /* title -> title */
	  if (!strcmp (cur->value, "title") && !data->title
	      && (c = nxmle_get_string (cur, NULL)))
	    data->title = c;

	  /* subtitle -> description */
	  else if (!strcmp (cur->value, "subtitle")
		   && data->version == MRSS_VERSION_ATOM_1_0
		   && !data->description
		   && (c = nxmle_get_string (cur, NULL)))
	    data->description = c;

	  /* tagline -> description (Atom 0.3) */
	  else if (!strcmp (cur->value, "tagline")
		   && data->version == MRSS_VERSION_ATOM_0_3
		   && !data->description
		   && (c = nxmle_get_string (cur, NULL)))
	    data->description = c;

	  /* link href -> link */
	  else if (!strcmp (cur->value, "link") && !data->link
		   && (c = nxmle_find_attribute (cur, "href", NULL)))
	    data->link = c;

	  /* id -> id */
	  else if (!strcmp (cur->value, "id") && !data->id
		   && (c = nxmle_get_string (cur, NULL)))
	    data->id = c;

	  /* rights -> copyright */
	  else if (!strcmp (cur->value, "rights") && !data->copyright
		   && (c = nxmle_get_string (cur, NULL)))
	    data->copyright = c;

	  /* updated -> lastBuildDate */
	  else if (!strcmp (cur->value, "updated")
		   && (c = nxmle_get_string (cur, NULL)))
	    {
	      data->lastBuildDate = __mrss_atom_prepare_date (data, c);
	      free (c);
	    }

	  /* author -> managingeditor */
	  else if (!strcmp (cur->value, "author"))
	    __mrss_parser_atom_author (cur, &data->managingeditor,
				       &data->managingeditor_email,
				       &data->managingeditor_uri);

	  /* contributor */
	  else if (!strcmp (cur->value, "contributor"))
	    __mrss_parser_atom_author (cur, &data->contributor,
				       &data->contributor_email,
				       &data->contributor_uri);

	  /* generator -> generator */
	  else if (!strcmp (cur->value, "generator") && !data->generator
		   && (c = nxmle_get_string (cur, NULL)))
	    {
	      char *attr;

	      data->generator = c;

	      if ((attr = nxmle_find_attribute (cur, "uri", NULL)))
		data->generator_uri = attr;

	      if ((attr = nxmle_find_attribute (cur, "version", NULL)))
		data->generator_version = attr;
	    }

	  /* icon -> image_url */
	  else if (!strcmp (cur->value, "icon") && !data->image_url
		   && (c = nxmle_get_string (cur, NULL)))
	    data->image_url = c;

	  /* logo -> image_logo */
	  else if (!strcmp (cur->value, "logo") && !data->image_logo
		   && (c = nxmle_get_string (cur, NULL)))
	    data->image_logo = c;

	  /* category */
	  else if (!strcmp (cur->value, "category"))
	    __mrss_parser_atom_category (cur, &data->category);

	  /* entry -> item */
	  else if (!strcmp (cur->value, "entry"))
	    __mrss_parser_atom_entry (doc, cur, data);

	  else
	    {
	      mrss_tag_t *tag;
	      if ((tag = __mrss_parse_tag (doc, cur)))
		__mrss_parse_tag_insert (&data->other_tags, tag);
	    }

	}
    }

  *ret = data;

  return MRSS_OK;
}
Exemplo n.º 10
0
static mrss_tag_t *
__mrss_parse_tag (nxml_t * doc, nxml_data_t * cur)
{
  mrss_tag_t *tag;
  mrss_attribute_t *attribute;
  nxml_attr_t *nxml_attr;

  if (!(tag = (mrss_tag_t *) calloc (1, sizeof (mrss_tag_t))))
    return NULL;

  tag->element = MRSS_ELEMENT_TAG;
  tag->allocated = 1;

  if (!(tag->name = strdup (cur->value)))
    {
      mrss_free (tag);
      return NULL;
    }

  if (cur->ns && cur->ns->ns && !(tag->ns = strdup (cur->ns->ns)))
    {
      mrss_free (tag);
      return NULL;
    }

  for (nxml_attr = cur->attributes; nxml_attr; nxml_attr = nxml_attr->next)
    {

      if (!
	  (attribute =
	   (mrss_attribute_t *) calloc (1, sizeof (mrss_attribute_t))))
	return NULL;

      attribute->element = MRSS_ELEMENT_ATTRIBUTE;
      attribute->allocated = 1;

      if (!(attribute->name = strdup (nxml_attr->name)))
	{
	  mrss_free (tag);
	  return NULL;
	}

      if (!(attribute->value = strdup (nxml_attr->value)))
	{
	  mrss_free (tag);
	  return NULL;
	}

      if (nxml_attr->ns && nxml_attr->ns->ns
	  && !(attribute->ns = strdup (nxml_attr->ns->ns)))
	{
	  mrss_free (tag);
	  return NULL;
	}

      if (!tag->attributes)
	tag->attributes = attribute;
      else
	{
	  mrss_attribute_t *tmp = tag->attributes;

	  while (tmp->next)
	    tmp = tmp->next;

	  tmp->next = attribute;
	}

    }

  for (cur = cur->children; cur; cur = cur->next)
    {
      if (cur->type == NXML_TYPE_TEXT)
	{
	  if (!tag->value && !(tag->value = strdup (cur->value)))
	    {
	      mrss_free (tag);
	      return NULL;
	    }
	}
      else if (cur->type == NXML_TYPE_ELEMENT)
	{
	  mrss_tag_t *child = __mrss_parse_tag (doc, cur);

	  if (child)
	    __mrss_parse_tag_insert (&tag->children, child);
	}
    }

  return tag;
}
Exemplo n.º 11
0
mrss_error_t
mrss_parse_url_with_options_and_error (char *url, mrss_t ** ret,
				       mrss_options_t * options,
				       CURLcode * code)
{
  nxml_t *doc;
  mrss_error_t err;
  char *buffer;
  size_t size;

  if (!url || !ret)
    return MRSS_ERR_DATA;

  if (nxml_new (&doc) != NXML_OK)
    return MRSS_ERR_POSIX;

  if (options)
    {
      if (options->timeout >= 0)
	nxml_set_timeout (doc, options->timeout);

      if (options->proxy)
	nxml_set_proxy (doc, options->proxy, options->proxy_authentication);

      if (options->authentication)
	nxml_set_authentication (doc, options->authentication);

      if (options->user_agent)
	nxml_set_user_agent (doc, options->user_agent);

      nxml_set_certificate (doc, options->certfile, options->password,
			    options->cacert, options->verifypeer);
    }

  if (!(buffer = __mrss_download_file (doc, url, &size, &err, code)))
    return err;

  if (nxml_parse_buffer (doc, buffer, size) != NXML_OK)
    {
      free (buffer);
      nxml_free (doc);

      return MRSS_ERR_PARSER;
    }

  if (!(err = __mrss_parser (doc, ret)))
    {
      if (!((*ret)->file = strdup (url)))
	{
	  free (buffer);

	  mrss_free (*ret);
	  nxml_free (doc);

	  return MRSS_ERR_POSIX;
	}

      (*ret)->size = size;
    }

  free (buffer);
  nxml_free (doc);

  return err;
}