Commit 801b6eb9 authored by Rémi Duraffort's avatar Rémi Duraffort

video_filter_rss: use a dedicate function to parse the feeds (and fix a bug due

to wrong variable scope).
parent 7dd25734
...@@ -100,7 +100,6 @@ typedef struct rss_feed_t ...@@ -100,7 +100,6 @@ typedef struct rss_feed_t
struct filter_sys_t struct filter_sys_t
{ {
vlc_mutex_t lock; vlc_mutex_t lock;
vlc_mutex_t *p_lock;
int i_xoff, i_yoff; /* offsets for the display string in the video window */ int i_xoff, i_yoff; /* offsets for the display string in the video window */
int i_pos; /* permit relative positioning (top, bottom, left, right, center) */ int i_pos; /* permit relative positioning (top, bottom, left, right, center) */
...@@ -669,76 +668,20 @@ static int ParseUrls( filter_t *p_filter, char *psz_urls ) ...@@ -669,76 +668,20 @@ static int ParseUrls( filter_t *p_filter, char *psz_urls )
} }
/**************************************************************************** /****************************************************************************
* FetchRSS (or Atom) feeds * Parse the rss feed
***************************************************************************/ ***************************************************************************/
static int FetchRSS( filter_t *p_filter) static bool ParseFeed( filter_t *p_filter, xml_reader_t *p_xml_reader,
rss_feed_t *p_feed )
{ {
filter_sys_t *p_sys = p_filter->p_sys; VLC_UNUSED(p_filter);
stream_t *p_stream;
xml_t *p_xml;
xml_reader_t *p_xml_reader;
int i_ret = 1;
char *psz_eltname = NULL; char *psz_eltname = NULL;
char *psz_eltvalue = NULL;
int i_feed; bool b_is_item = false;
int i_item; bool b_is_image = false;
bool b_is_item;
bool b_is_image;
p_xml = xml_Create( p_filter ); int i_item = 0;
if( !p_xml )
{
msg_Err( p_filter, "Failed to open XML parser" );
return 1;
}
for( i_feed = 0; i_feed < p_sys->i_feeds; i_feed++ )
{
rss_feed_t *p_feed = p_sys->p_feeds+i_feed;
FREENULL( p_feed->psz_title );
FREENULL( p_feed->psz_description );
FREENULL( p_feed->psz_link );
FREENULL( p_feed->psz_image );
if( p_feed->p_pic )
{
picture_Release( p_feed->p_pic );
p_feed->p_pic = NULL;
}
for( int i = 0; i < p_feed->i_items; i++ )
{
rss_item_t *p_item = p_feed->p_items + i;
free( p_item->psz_title );
free( p_item->psz_link );
free( p_item->psz_description );
}
p_feed->i_items = 0;
FREENULL( p_feed->p_items );
msg_Dbg( p_filter, "opening %s RSS/Atom feed ...", p_feed->psz_url );
p_stream = stream_UrlNew( p_filter, p_feed->psz_url );
if( !p_stream )
{
msg_Err( p_filter, "Failed to open %s for reading", p_feed->psz_url );
p_xml_reader = NULL;
goto error;
}
p_xml_reader = xml_ReaderCreate( p_xml, p_stream );
if( !p_xml_reader )
{
msg_Err( p_filter, "Failed to open %s for parsing", p_feed->psz_url );
goto error;
}
i_item = 0;
b_is_item = false;
b_is_image = false;
while( xml_ReaderRead( p_xml_reader ) == 1 ) while( xml_ReaderRead( p_xml_reader ) == 1 )
{ {
...@@ -746,57 +689,50 @@ static int FetchRSS( filter_t *p_filter) ...@@ -746,57 +689,50 @@ static int FetchRSS( filter_t *p_filter)
{ {
// Error // Error
case -1: case -1:
goto error; goto end;
case XML_READER_STARTELEM: case XML_READER_STARTELEM:
free( psz_eltname ); free( psz_eltname );
psz_eltname = xml_ReaderName( p_xml_reader ); psz_eltname = xml_ReaderName( p_xml_reader );
if( !psz_eltname ) if( !psz_eltname )
goto error; goto end;
# ifdef RSS_DEBUG #ifdef RSS_DEBUG
msg_Dbg( p_filter, "element name: %s", psz_eltname ); msg_Dbg( p_filter, "element name: %s", psz_eltname );
# endif #endif
if( !strcmp( psz_eltname, "item" ) /* rss */ /* rss or atom */
|| !strcmp( psz_eltname, "entry" ) ) /* atom */ if( !strcmp( psz_eltname, "item" ) || !strcmp( psz_eltname, "entry" ) )
{ {
b_is_item = true; b_is_item = true;
p_feed->i_items++; p_feed->i_items++;
p_feed->p_items = realloc( p_feed->p_items, p_feed->i_items * sizeof( rss_item_t ) ); p_feed->p_items = realloc( p_feed->p_items,
p_feed->i_items * sizeof( rss_item_t ) );
p_feed->p_items[p_feed->i_items-1].psz_title = NULL; p_feed->p_items[p_feed->i_items-1].psz_title = NULL;
p_feed->p_items[p_feed->i_items-1].psz_description p_feed->p_items[p_feed->i_items-1].psz_description = NULL;
= NULL;
p_feed->p_items[p_feed->i_items-1].psz_link = NULL; p_feed->p_items[p_feed->i_items-1].psz_link = NULL;
} }
else if( !strcmp( psz_eltname, "image" ) ) /* rss */ /* rss */
else if( !strcmp( psz_eltname, "image" ) )
{ {
b_is_image = true; b_is_image = true;
} }
else if( !strcmp( psz_eltname, "link" ) ) /* atom */ /* atom */
else if( !strcmp( psz_eltname, "link" ) )
{ {
char *psz_href = NULL; char *psz_href = NULL;
char *psz_rel = NULL; char *psz_rel = NULL;
while( xml_ReaderNextAttr( p_xml_reader ) while( xml_ReaderNextAttr( p_xml_reader ) == VLC_SUCCESS )
== VLC_SUCCESS )
{ {
char *psz_name = xml_ReaderName( p_xml_reader ); char *psz_name = xml_ReaderName( p_xml_reader );
char *psz_value = xml_ReaderValue( p_xml_reader ); char *psz_value = xml_ReaderValue( p_xml_reader );
if( !strcmp( psz_name, "rel" ) ) if( !strcmp( psz_name, "rel" ) )
{ {
if( psz_rel )
{
msg_Dbg( p_filter, "\"rel\" attribute of link atom duplicated (last value: %s)", psz_value );
free( psz_rel ); free( psz_rel );
}
psz_rel = psz_value; psz_rel = psz_value;
} }
else if( !strcmp( psz_name, "href" ) ) else if( !strcmp( psz_name, "href" ) )
{ {
if( psz_href )
{
msg_Dbg( p_filter, "\"href\" attribute of link atom duplicated (last value: %s)", psz_href );
free( psz_href ); free( psz_href );
}
psz_href = psz_value; psz_href = psz_value;
} }
else else
...@@ -805,20 +741,19 @@ static int FetchRSS( filter_t *p_filter) ...@@ -805,20 +741,19 @@ static int FetchRSS( filter_t *p_filter)
} }
free( psz_name ); free( psz_name );
} }
/* "rel" and "href" must be defined */
if( psz_rel && psz_href ) if( psz_rel && psz_href )
{ {
if( !strcmp( psz_rel, "alternate" ) if( !strcmp( psz_rel, "alternate" ) && !b_is_item &&
&& b_is_item == false !b_is_image && !p_feed->psz_link )
&& b_is_image == false
&& !p_feed->psz_link )
{ {
p_feed->psz_link = psz_href; p_feed->psz_link = psz_href;
} }
/* this isn't in the rfc but i found some ... */ /* this isn't in the rfc but i found some ... */
else if( ( !strcmp( psz_rel, "logo" ) else if( ( !strcmp( psz_rel, "logo" ) ||
|| !strcmp( psz_rel, "icon" ) ) !strcmp( psz_rel, "icon" ) )
&& b_is_item == false && !b_is_item && !b_is_image
&& b_is_image == false
&& !p_feed->psz_image ) && !p_feed->psz_image )
{ {
p_feed->psz_image = psz_href; p_feed->psz_image = psz_href;
...@@ -840,18 +775,19 @@ static int FetchRSS( filter_t *p_filter) ...@@ -840,18 +775,19 @@ static int FetchRSS( filter_t *p_filter)
free( psz_eltname ); free( psz_eltname );
psz_eltname = xml_ReaderName( p_xml_reader ); psz_eltname = xml_ReaderName( p_xml_reader );
if( !psz_eltname ) if( !psz_eltname )
goto error; goto end;
# ifdef RSS_DEBUG #ifdef RSS_DEBUG
msg_Dbg( p_filter, "element end : %s", psz_eltname ); msg_Dbg( p_filter, "element end : %s", psz_eltname );
# endif #endif
if( !strcmp( psz_eltname, "item" ) /* rss */ /* rss or atom */
|| !strcmp( psz_eltname, "entry" ) ) /* atom */ if( !strcmp( psz_eltname, "item" ) || !strcmp( psz_eltname, "entry" ) )
{ {
b_is_item = false; b_is_item = false;
i_item++; i_item++;
} }
else if( !strcmp( psz_eltname, "image" ) ) /* rss */ /* rss */
else if( !strcmp( psz_eltname, "image" ) )
{ {
b_is_image = false; b_is_image = false;
} }
...@@ -859,26 +795,26 @@ static int FetchRSS( filter_t *p_filter) ...@@ -859,26 +795,26 @@ static int FetchRSS( filter_t *p_filter)
break; break;
case XML_READER_TEXT: case XML_READER_TEXT:
if( !psz_eltname ) break;
psz_eltvalue = xml_ReaderValue( p_xml_reader );
if( !psz_eltvalue )
{
goto error;
}
else
{ {
if( !psz_eltname )
break;
char *psz_eltvalue = xml_ReaderValue( p_xml_reader );
if( !psz_eltvalue )
goto end;
char *psz_clean = removeWhiteChars( psz_eltvalue ); char *psz_clean = removeWhiteChars( psz_eltvalue );
free( psz_eltvalue ); free( psz_eltvalue );
psz_eltvalue = psz_clean; psz_eltvalue = psz_clean;
}
# ifdef RSS_DEBUG #ifdef RSS_DEBUG
msg_Dbg( p_filter, " text : <%s>", psz_eltvalue ); msg_Dbg( p_filter, " text : <%s>", psz_eltvalue );
# endif #endif
if( b_is_item == true ) /* Is it an item ? */
if( b_is_item )
{ {
rss_item_t *p_item = p_feed->p_items+i_item; rss_item_t *p_item = p_feed->p_items+i_item;
if( !strcmp( psz_eltname, "title" ) /* rss/atom */ /* rss/atom */
&& !p_item->psz_title ) if( !strcmp( psz_eltname, "title" ) && !p_item->psz_title )
{ {
p_item->psz_title = psz_eltvalue; p_item->psz_title = psz_eltvalue;
} }
...@@ -887,81 +823,152 @@ static int FetchRSS( filter_t *p_filter) ...@@ -887,81 +823,152 @@ static int FetchRSS( filter_t *p_filter)
{ {
p_item->psz_link = psz_eltvalue; p_item->psz_link = psz_eltvalue;
} }
else if((!strcmp( psz_eltname, "description" ) /* rss */ /* rss/atom */
|| !strcmp( psz_eltname, "summary" ) ) /* atom */ else if( ( !strcmp( psz_eltname, "description" ) ||
!strcmp( psz_eltname, "summary" ) )
&& !p_item->psz_description ) && !p_item->psz_description )
{ {
p_item->psz_description = psz_eltvalue; p_item->psz_description = psz_eltvalue;
} }
else else
{ {
FREENULL( psz_eltvalue ); free( psz_eltvalue );
} }
} }
else if( b_is_image == true ) /* Is it an image ? */
{ else if( b_is_image )
if( !strcmp( psz_eltname, "url" ) /* rss */
&& !p_feed->psz_image )
{ {
if( !strcmp( psz_eltname, "url" ) && !p_feed->psz_image )
p_feed->psz_image = psz_eltvalue; p_feed->psz_image = psz_eltvalue;
}
else else
{ free( psz_eltvalue );
FREENULL( psz_eltvalue );
}
} }
else else
{ {
if( !strcmp( psz_eltname, "title" ) /* rss/atom */ /* rss/atom */
&& !p_feed->psz_title ) if( !strcmp( psz_eltname, "title" ) && !p_feed->psz_title )
{ {
p_feed->psz_title = psz_eltvalue; p_feed->psz_title = psz_eltvalue;
} }
else if( !strcmp( psz_eltname, "link" ) /* rss */ /* rss */
&& !p_feed->psz_link ) else if( !strcmp( psz_eltname, "link" ) && !p_feed->psz_link )
{ {
p_feed->psz_link = psz_eltvalue; p_feed->psz_link = psz_eltvalue;
} }
else if((!strcmp( psz_eltname, "description" ) /* rss */ /* rss ad atom */
|| !strcmp( psz_eltname, "subtitle" ) ) /* atom */ else if( ( !strcmp( psz_eltname, "description" ) ||
!strcmp( psz_eltname, "subtitle" ) )
&& !p_feed->psz_description ) && !p_feed->psz_description )
{ {
p_feed->psz_description = psz_eltvalue; p_feed->psz_description = psz_eltvalue;
} }
else if( ( !strcmp( psz_eltname, "logo" ) /* atom */ /* rss */
|| !strcmp( psz_eltname, "icon" ) ) /* atom */ else if( ( !strcmp( psz_eltname, "logo" ) ||
!strcmp( psz_eltname, "icon" ) )
&& !p_feed->psz_image ) && !p_feed->psz_image )
{ {
p_feed->psz_image = psz_eltvalue; p_feed->psz_image = psz_eltvalue;
} }
else else
{ {
FREENULL( psz_eltvalue ); free( psz_eltvalue );
} }
} }
break; break;
} }
} }
}
free( psz_eltname );
return true;
end:
free( psz_eltname );
return false;
}
/****************************************************************************
* FetchRSS (or Atom) feeds
***************************************************************************/
static int FetchRSS( filter_t *p_filter )
{
filter_sys_t *p_sys = p_filter->p_sys;
stream_t *p_stream;
xml_t *p_xml;
xml_reader_t *p_xml_reader;
p_xml = xml_Create( p_filter );
if( !p_xml )
{
msg_Err( p_filter, "Failed to open XML parser" );
return 1;
}
/* Fetch all feeds and parse them */
for( int i_feed = 0; i_feed < p_sys->i_feeds; i_feed++ )
{
rss_feed_t *p_feed = p_sys->p_feeds+i_feed;
/* Free the ressources */
FREENULL( p_feed->psz_title );
FREENULL( p_feed->psz_description );
FREENULL( p_feed->psz_link );
FREENULL( p_feed->psz_image );
if( p_feed->p_pic )
{
picture_Release( p_feed->p_pic );
p_feed->p_pic = NULL;
}
for( int i = 0; i < p_feed->i_items; i++ )
{
rss_item_t *p_item = p_feed->p_items + i;
free( p_item->psz_title );
free( p_item->psz_link );
free( p_item->psz_description );
}
p_feed->i_items = 0;
FREENULL( p_feed->p_items );
/* Fetch the feed */
msg_Dbg( p_filter, "opening %s RSS/Atom feed ...", p_feed->psz_url );
p_stream = stream_UrlNew( p_filter, p_feed->psz_url );
if( !p_stream )
{
msg_Err( p_filter, "Failed to open %s for reading", p_feed->psz_url );
p_xml_reader = NULL;
goto error;
}
p_xml_reader = xml_ReaderCreate( p_xml, p_stream );
if( !p_xml_reader )
{
msg_Err( p_filter, "Failed to open %s for parsing", p_feed->psz_url );
goto error;
}
/* Parse the feed */
if( !ParseFeed( p_filter, p_xml_reader, p_feed ) )
goto error;
/* If we have a image: load it if requiere */
if( p_sys->b_images == true if( p_sys->b_images == true
&& p_feed->psz_image && !p_feed->p_pic ) && p_feed->psz_image && !p_feed->p_pic )
{ {
p_feed->p_pic = LoadImage( p_filter, p_feed->psz_image ); p_feed->p_pic = LoadImage( p_filter, p_feed->psz_image );
} }
msg_Dbg( p_filter, "done with %s RSS/Atom feed", p_feed->psz_url );
xml_ReaderDelete( p_xml, p_xml_reader ); xml_ReaderDelete( p_xml, p_xml_reader );
stream_Delete( p_stream ); stream_Delete( p_stream );
msg_Dbg( p_filter, "done with %s RSS/Atom feed", p_feed->psz_url );
} }
free( psz_eltname );
free( psz_eltvalue );
xml_Delete( p_xml ); xml_Delete( p_xml );
return 0; return 0;
error: error:
free( psz_eltname );
free( psz_eltvalue );
if( p_xml_reader ) if( p_xml_reader )
xml_ReaderDelete( p_xml, p_xml_reader ); xml_ReaderDelete( p_xml, p_xml_reader );
...@@ -970,7 +977,7 @@ error: ...@@ -970,7 +977,7 @@ error:
if( p_xml ) if( p_xml )
xml_Delete( p_xml ); xml_Delete( p_xml );
return i_ret; return 1;
} }
/**************************************************************************** /****************************************************************************
......
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