]> git.sesse.net Git - vlc/blobdiff - modules/video_filter/rss.c
* fix the getlength. It needs to be after the SETUP, so that liveMedia can correct...
[vlc] / modules / video_filter / rss.c
index c6fca699e33434213121df783004b8a07326840f..fc0e2bd3057975f6957cd8225190a87d6961c239 100644 (file)
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  *****************************************************************************/
 
+/*****************************************************************************
+ * Atom : http://www.ietf.org/rfc/rfc4287.txt
+ * RSS : http://www.rssboard.org/rss-specification
+ *****************************************************************************/
+
 /*****************************************************************************
  * Preamble
  *****************************************************************************/
@@ -113,38 +118,42 @@ struct filter_sys_t
     int i_cur_char;
 };
 
-#define MSG_TEXT N_("RSS/Atom feed URLs")
-#define MSG_LONGTEXT N_("RSS/Atom feed '|' (pipe) seperated URLs")
-#define SPEED_TEXT N_("RSS/Atom feed speed")
-#define SPEED_LONGTEXT N_("RSS/Atom feed speed (bigger is slower)")
-#define LENGTH_TEXT N_("RSS/Atom feed max number of chars displayed")
-#define LENGTH_LONGTEXT N_("RSS/Atom feed max number of chars displayed")
-#define TTL_TEXT N_("Number of seconds between each forced refresh of the feeds")
-#define TTL_LONGTEXT N_("Number of seconds between each forced refresh of the feeds. If 0, the feeds will never be updated.")
-#define IMAGE_TEXT N_("Display feed images if available")
-#define IMAGE_LONGTEXT N_("Display feed images if available")
-
-#define POSX_TEXT N_("X offset, from left")
-#define POSX_LONGTEXT N_("X offset, from the left screen edge" )
-#define POSY_TEXT N_("Y offset, from the top")
-#define POSY_LONGTEXT N_("Y offset, down from the top" )
+#define MSG_TEXT N_("Feed URLs")
+#define MSG_LONGTEXT N_("RSS/Atom feed '|' (pipe) seperated URLs.")
+#define SPEED_TEXT N_("Speed of feeds")
+#define SPEED_LONGTEXT N_("Speed of the RSS/Atom feeds (bigger is slower).")
+#define LENGTH_TEXT N_("Max length")
+#define LENGTH_LONGTEXT N_("Maximum number of characters displayed on the " \
+                "screen." )
+#define TTL_TEXT N_("Refresh time")
+#define TTL_LONGTEXT N_("Number of seconds between each forced refresh " \
+        "of the feeds. 0 means that the feeds are never updated." )
+#define IMAGE_TEXT N_("Feed images")
+#define IMAGE_LONGTEXT N_("Display feed images if available.")
+
+#define POSX_TEXT N_("X offset")
+#define POSX_LONGTEXT N_("X offset, from the left screen edge." )
+#define POSY_TEXT N_("Y offset")
+#define POSY_LONGTEXT N_("Y offset, down from the top." )
 #define OPACITY_TEXT N_("Opacity")
-#define OPACITY_LONGTEXT N_("The opacity (inverse of transparency) of " \
-    "overlay text. 0 = transparent, 255 = totally opaque. " )
+#define OPACITY_LONGTEXT N_("Opacity (inverse of transparency) of " \
+    "overlay text. 0 = transparent, 255 = totally opaque." )
+
 #define SIZE_TEXT N_("Font size, pixels")
-#define SIZE_LONGTEXT N_("Specify the font size, in pixels, " \
-    "with -1 = use freetype-fontsize" )
+#define SIZE_LONGTEXT N_("Font size, in pixels. Default is -1 (use default " \
+    "font size)." )
 
-#define COLOR_TEXT N_("Text Default Color")
-#define COLOR_LONGTEXT N_("The color of overlay text. 1 byte for each color, hexadecimal. " \
-    "#000000 = all colors off, " \
-    "0xFF0000 = just Red, 0xFFFFFF = all color on [White]" )
+#define COLOR_TEXT N_("Color")
+#define COLOR_LONGTEXT N_("Color of the text that will be rendered on "\
+    "the video. This must be an hexadecimal (like HTML colors). The first two "\
+    "chars are for red, then green, then blue. #000000 = black, #FF0000 = red,"\
+    " #00FF00 = green, #FFFF00 = yellow (red + green), #FFFFFF = white" )
 
-#define POS_TEXT N_("Marquee position")
+#define POS_TEXT N_("Text position")
 #define POS_LONGTEXT N_( \
-  "You can enforce the marquee position on the video " \
-  "(0=center, 1=left, 2=right, 4=top, 8=bottom, you can " \
-  "also use combinations of these values by adding them).")
+  "You can enforce the text position on the video " \
+  "(0=center, 1=left, 2=right, 4=top, 8=bottom; you can " \
+  "also use combinations of these values, eg 6 = top-right).")
 
 static int pi_pos_values[] = { 0, 1, 2, 4, 8, 5, 6, 9, 10 };
 static char *ppsz_pos_descriptions[] =
@@ -156,7 +165,7 @@ static char *ppsz_pos_descriptions[] =
  *****************************************************************************/
 vlc_module_begin();
     set_capability( "sub filter", 0 );
-    set_shortname( "RSS" );
+    set_shortname( "RSS / Atom" );
     set_callbacks( CreateFilter, DestroyFilter );
     set_category( CAT_VIDEO );
     set_subcategory( SUBCAT_VIDEO_SUBPIC );
@@ -481,6 +490,8 @@ static subpicture_t *Filter( filter_t *p_filter, mtime_t date )
  * functions
  ***************************************************************************/
 
+#undef LoadImage /* do not conflict with Win32 API */
+
 /****************************************************************************
  * download and resize image located at psz_url
  ***************************************************************************/
@@ -557,7 +568,7 @@ char *removeWhiteChars( char *psz_src )
 }
 
 /****************************************************************************
- * FetchRSS
+ * FetchRSS (or Atom) feeds
  ***************************************************************************/
 static int FetchRSS( filter_t *p_filter)
 {
@@ -615,7 +626,7 @@ static int FetchRSS( filter_t *p_filter)
         p_feed->i_items = 0;
         p_feed->p_items = NULL;
 
-        msg_Dbg( p_filter, "Opening %s RSS feed ...", psz_feed );
+        msg_Dbg( p_filter, "opening %s RSS/Atom feed ...", psz_feed );
 
         p_stream = stream_UrlNew( p_filter, psz_feed );
         if( !p_stream )
@@ -654,12 +665,11 @@ static int FetchRSS( filter_t *p_filter)
                     {
                         return 1;
                     }
-#                   define RSS_DEBUG
 #                   ifdef RSS_DEBUG
-                    msg_Dbg( p_filter, "element name : %s", psz_eltname );
+                    msg_Dbg( p_filter, "element name: %s", psz_eltname );
 #                   endif
-                    if( !strcmp( psz_eltname, "item" )
-                     || !strcmp( psz_eltname, "entry" ) )
+                    if( !strcmp( psz_eltname, "item" ) /* rss */
+                     || !strcmp( psz_eltname, "entry" ) ) /* atom */
                     {
                         b_is_item = VLC_TRUE;
                         p_feed->i_items++;
@@ -669,10 +679,62 @@ static int FetchRSS( filter_t *p_filter)
                                                                      = NULL;
                         p_feed->p_items[p_feed->i_items-1].psz_link = NULL;
                     }
-                    else if( !strcmp( psz_eltname, "image" ) )
+                    else if( !strcmp( psz_eltname, "image" ) ) /* rss */
                     {
                         b_is_image = VLC_TRUE;
                     }
+                    else if( !strcmp( psz_eltname, "link" ) ) /* atom */
+                    {
+                        char *psz_href = NULL;
+                        char *psz_rel = NULL;
+                        while( xml_ReaderNextAttr( p_xml_reader )
+                               == VLC_SUCCESS )
+                        {
+                            char *psz_name = xml_ReaderName( p_xml_reader );
+                            char *psz_value = xml_ReaderValue( p_xml_reader );
+                            if( !strcmp( psz_name, "rel" ) )
+                            {
+                                psz_rel = psz_value;
+                            }
+                            else if( !strcmp( psz_name, "href" ) )
+                            {
+                                psz_href = psz_value;
+                            }
+                            else
+                            {
+                                free( psz_value );
+                            }
+                            free( psz_name );
+                        }
+                        if( psz_rel && psz_href )
+                        {
+                            if( !strcmp( psz_rel, "alternate" )
+                                && b_is_item == VLC_FALSE
+                                && b_is_image == VLC_FALSE
+                                && !p_feed->psz_link )
+                            {
+                                p_feed->psz_link = psz_href;
+                            }
+                            /* this isn't in the rfc but i found some ... */
+                            else if( ( !strcmp( psz_rel, "logo" )
+                                    || !strcmp( psz_rel, "icon" ) )
+                                    && b_is_item == VLC_FALSE
+                                    && b_is_image == VLC_FALSE
+                                    && !p_feed->psz_image )
+                            {
+                                p_feed->psz_image = psz_href;
+                            }
+                            else
+                            {
+                                free( psz_href );
+                            }
+                        }
+                        else
+                        {
+                            if( psz_href ) free( psz_href );
+                        }
+                        if( psz_rel ) free( psz_rel );
+                    }
                     break;
 
                 case XML_READER_ENDELEM:
@@ -689,13 +751,13 @@ static int FetchRSS( filter_t *p_filter)
 #                   ifdef RSS_DEBUG
                     msg_Dbg( p_filter, "element end : %s", psz_eltname );
 #                   endif
-                    if( !strcmp( psz_eltname, "item" )
-                     || !strcmp( psz_eltname, "entry" ) )
+                    if( !strcmp( psz_eltname, "item" ) /* rss */
+                     || !strcmp( psz_eltname, "entry" ) ) /* atom */
                     {
                         b_is_item = VLC_FALSE;
                         i_item++;
                     }
-                    else if( !strcmp( psz_eltname, "image" ) )
+                    else if( !strcmp( psz_eltname, "image" ) ) /* rss */
                     {
                         b_is_image = VLC_FALSE;
                     }
@@ -723,15 +785,19 @@ static int FetchRSS( filter_t *p_filter)
                     {
                         struct rss_item_t *p_item;
                         p_item = p_feed->p_items+i_item;
-                        if( !strcmp( psz_eltname, "title" ) )
+                        if( !strcmp( psz_eltname, "title" ) /* rss/atom */
+                            && !p_item->psz_title )
                         {
                             p_item->psz_title = psz_eltvalue;
                         }
-                        else if( !strcmp( psz_eltname, "link" ) )
+                        else if( !strcmp( psz_eltname, "link" ) /* rss */
+                                 && !p_item->psz_link )
                         {
                             p_item->psz_link = psz_eltvalue;
                         }
-                        else if( !strcmp( psz_eltname, "description" ) )
+                        else if((!strcmp( psz_eltname, "description" ) /* rss */
+                              || !strcmp( psz_eltname, "summary" ) ) /* atom */
+                              && !p_item->psz_description )
                         {
                             p_item->psz_description = psz_eltvalue;
                         }
@@ -743,12 +809,10 @@ static int FetchRSS( filter_t *p_filter)
                     }
                     else if( b_is_image == VLC_TRUE )
                     {
-                        if( !strcmp( psz_eltname, "url" ) )
+                        if( !strcmp( psz_eltname, "url" ) /* rss */
+                            && !p_feed->psz_image )
                         {
                             p_feed->psz_image = psz_eltvalue;
-                            if( p_sys->b_images == VLC_TRUE )
-                                p_feed->p_pic = LoadImage( p_filter,
-                                                           p_feed->psz_image );
                         }
                         else
                         {
@@ -758,19 +822,28 @@ static int FetchRSS( filter_t *p_filter)
                     }
                     else
                     {
-                        if( !strcmp( psz_eltname, "title" ) )
+                        if( !strcmp( psz_eltname, "title" ) /* rss/atom */
+                            && !p_feed->psz_title )
                         {
                             p_feed->psz_title = psz_eltvalue;
                         }
-                        else if( !strcmp( psz_eltname, "link" ) )
+                        else if( !strcmp( psz_eltname, "link" ) /* rss */
+                                 && !p_feed->psz_link )
                         {
                             p_feed->psz_link = psz_eltvalue;
                         }
-                        else if( !strcmp( psz_eltname, "description" )
-                              || !strcmp( psz_eltname, "subtitle" ) )
+                        else if((!strcmp( psz_eltname, "description" ) /* rss */
+                              || !strcmp( psz_eltname, "subtitle" ) ) /* atom */
+                              && !p_feed->psz_description )
                         {
                             p_feed->psz_description = psz_eltvalue;
                         }
+                        else if( ( !strcmp( psz_eltname, "logo" ) /* atom */
+                              || !strcmp( psz_eltname, "icon" ) ) /* atom */
+                              && !p_feed->psz_image )
+                        {
+                            p_feed->psz_image = psz_eltvalue;
+                        }
                         else
                         {
                             free( psz_eltvalue );
@@ -781,9 +854,15 @@ static int FetchRSS( filter_t *p_filter)
             }
         }
 
+        if( p_sys->b_images == VLC_TRUE
+            && p_feed->psz_image && !p_feed->p_pic )
+        {
+            p_feed->p_pic = LoadImage( p_filter, p_feed->psz_image );
+        }
+
         if( p_xml_reader && p_xml ) xml_ReaderDelete( p_xml, p_xml_reader );
         if( p_stream ) stream_Delete( p_stream );
-        msg_Dbg( p_filter, "Done with %s RSS feed.", psz_feed );
+        msg_Dbg( p_filter, "done with %s RSS/Atom feed", psz_feed );
     }
     free( psz_buffer_2 );
     if( p_xml ) xml_Delete( p_xml );