Now uses proper xform functions, removed all playlist writing related
code. Seems like something that should be implemented client-side.

Now iterates through each line of the stream, extracting urls from
anchors instead of reading the entire thing into memory and
g_strsplit-ing it.

Added more magic signatures and extensions.
---
 src/plugins/html/html.c  |  491 +++++++++-------------------------------------
 src/plugins/html/wscript |    2 +-
 2 files changed, 91 insertions(+), 402 deletions(-)

diff --git a/src/plugins/html/html.c b/src/plugins/html/html.c
index 5570fe9..e13eac8 100644
--- a/src/plugins/html/html.c
+++ b/src/plugins/html/html.c
@@ -14,428 +14,119 @@
  *  Lesser General Public License for more details.
  */
 
-
-
-
-#include "xmms/xmms_plugin.h"
-#include "xmms/xmms_transport.h"
-#include "xmms/xmms_log.h"
-#include "xmms/xmms_plsplugins.h"
-#include "xmms/xmms_medialib.h"
-
 #include <string.h>
 #include <stdio.h>
 #include <stdlib.h>
 
 #include <glib.h>
-#include <glib/gprintf.h>
 
-/*
- * Function prototypes
- */
+#include "xmms/xmms_xformplugin.h"
+#include "xmms/xmms_log.h"
+#include "xmms/xmms_medialib.h"
+#include "xmms/xmms_util.h"
 
-static gboolean xmms_html_read_playlist (xmms_transport_t *transport, guint 
playlist_id);
-static GString *xmms_html_write_playlist (guint32 *list);
+/* xform methods */
+static gboolean xmms_html_setup (xmms_xform_plugin_t *xform);
+static gboolean xmms_html_init (xmms_xform_t *xform); 
+static gboolean xmms_html_browse (xmms_xform_t *xform,
+               const gchar *url, xmms_error_t *error);
 
-static gchar *escape_html (const gchar *in);
-static gboolean valid_suffix (gchar **suffix, gchar *path);
+/* for extracting the href attribute out of a tags */
 static gchar* parse_tag (const gchar *tag, const gchar *plspath);
-static gchar* build_url (const gchar *plspath, const gchar *file);
-static gchar* path_get_body (const gchar *path);
-
-static gchar html_header[] =
-"<?xml version=\"1.0\" encoding=\"utf8\"?>\n"
-"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" 
\"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\";>\n"
-"<html xmlns=\"http://www.w3.org/1999/xhtml\"; xml:lang=\"en\">\n"
-"<head>\n"
-"      <title>XMMS2 Playlist</title>\n"
-"      <meta name=\"generator\" content=\"XMMS2\"/>\n"
-"      <meta http-equiv=\"content-type\" content=\"text/xhtml; 
charset=utf8\"/>\n"
-"      <meta http-equiv=\"content-style-type\" content=\"text/css\"/>\n"
-"      <link href=\"playlist.css\" rel=\"stylesheet\" type=\"text/css\"/>\n"
-"</head>\n"
-"<body>\n"
-"      <h1>XMMS2 Playlist</h1>\n"
-"\n"
-"      <div id=\"container\">\n"
-"              <p>\n"
-"                      Number of tracks: %i\n"
-"                      <br/>\n"
-"                      Total playtime: %i:%02i:%02i\n"
-"              </p>\n"
-"\n"
-"              <h2>Tracks</h2>\n"
-"\n"
-"              <ol id=\"playlist\">\n";
 
-static gchar html_entry_even[] = "\t\t\t<li class=\"entry_even\">%s</li>\n";
-static gchar html_entry_odd[] = "\t\t\t<li class=\"entry_odd\">%s</li>\n";
-static gchar html_footer[] =
-"              </div>\n"
-"      </div>\n"
-"</body>\n"
-"</html>\n";
-
-/*
- * Plugin header
- */
+/* declare the plugin */
+XMMS_XFORM_PLUGIN ("html",
+               "HTML Playlist Reader",
+               XMMS_VERSION,
+               "Reads HTML playlists",
+               xmms_html_setup);
 
-xmms_plugin_t *
-xmms_plugin_get (void)
+static gboolean xmms_html_setup (xmms_xform_plugin_t *xform)
 {
-       xmms_plugin_t *plugin;
-
-       plugin = xmms_plugin_new (XMMS_PLUGIN_TYPE_PLAYLIST,
-                                 XMMS_PLAYLIST_PLUGIN_API_VERSION,
-                                 "html",
-                                 "HTML Playlist",
-                                 XMMS_VERSION,
-                                 "HTML Playlist reader");
-
-       if (!plugin) {
-               return NULL;
-       }
+       xmms_xform_methods_t methods;
+       XMMS_XFORM_METHODS_INIT (methods);
+
+       methods.init = xmms_html_init;
+       methods.browse = xmms_html_browse;
+       xmms_xform_plugin_methods_set (xform, &methods);
+
+       xmms_xform_plugin_indata_add (xform,
+                       XMMS_STREAM_TYPE_MIMETYPE,
+                       "text/html",
+                       NULL);
+
+       xmms_magic_extension_add ("text/html", "*.html");
+       xmms_magic_extension_add ("text/html", "*.xhtml");
+       
+       xmms_magic_add ("html ucase doctype", "text/html",
+                       "0 string <!DOCTYPE HTML ");
+       
+       xmms_magic_add ("html ucase tag", "text/html",
+                       "0 string <HTML ");
+       
+       xmms_magic_add ("html w/ doctype", "text/html",
+                       "0 string <!DOCTYPE html ");
+       
+       xmms_magic_add ("html tag", "text/html",
+                       "0 string <html ");
+       
+       xmms_magic_add ("html header tag", "text/html",
+                       "0 string <head ");
+       
+       xmms_magic_add ("xml tag", "text/html",
+                       "0 string <?xml ");
 
-       xmms_plugin_info_add (plugin, "URL", "http://www.xmms.org/";);
-       xmms_plugin_info_add (plugin, "Author", "XMMS Team");
-
-       xmms_plugin_method_add (plugin, XMMS_PLUGIN_METHOD_READ_PLAYLIST, 
xmms_html_read_playlist);
-       xmms_plugin_method_add (plugin, XMMS_PLUGIN_METHOD_WRITE_PLAYLIST, 
xmms_html_write_playlist);
-
-       xmms_plugin_config_property_register (plugin, "suffixes",
-                                             "mp3,ogg,flac,wav,spx,sid",
-                                             NULL, NULL);
-
-       xmms_plugin_magic_add (plugin, "html w/ doctype", "text/html",
-                              "0 string <!DOCTYPE html ", NULL);
-
-       /* we accept broken HTML, too */
-       xmms_plugin_magic_add (plugin, "html tag", "text/html",
-                              "0 string <html ", NULL);
-       xmms_plugin_magic_add (plugin, "html header tag", "text/html",
-                              "0 string <head ", NULL);
-
-       /* XHTML */
-       xmms_plugin_magic_add (plugin, "xml tag", "text/html",
-                              "0 string <?xml ", NULL);
-
-       return plugin;
+       return TRUE;
 }
 
-static gboolean
-xmms_html_read_playlist (xmms_transport_t *transport,
-                         guint32 playlist_id)
+static gboolean xmms_html_init (xmms_xform_t *xform)
 {
-       gchar *buffer;
-       const gchar *plsurl;
-       gchar **tags;
-       gchar **suffix;
-       xmms_config_property_t *val;
-       xmms_medialib_session_t *session;
-       xmms_error_t error;
-
-       gint cnt, readlen, buflen;
-
-       g_return_val_if_fail (transport, FALSE);
-       g_return_val_if_fail (playlist_id, FALSE);
-
-       buflen = xmms_transport_size (transport);
-       if (buflen == 0) {
-               XMMS_DBG ("Empty playlist, nothing to add here");
-               return TRUE;
-       }
-
-       if (buflen == -1) {
-               buflen = 4096;
-       }
-
-       buffer = g_malloc0 (buflen);
-       g_return_val_if_fail (buffer, FALSE);
-
-       readlen = 0;
-       while (readlen < buflen) {
-               gint ret;
-
-               ret = xmms_transport_read (transport, buffer + readlen,
-                                          buflen - readlen, &error);
-
-               XMMS_DBG ("Got %d bytes", ret);
-               if (ret <= 0) {
-                       if (readlen > 0) {
-                               break;
-                       }
-
-                       g_free (buffer);
-
-                       return FALSE;
-               }
-
-               readlen += ret;
-               g_assert (readlen >= 0);
-       }
-
-       tags = g_strsplit (buffer, "<", 0);
-       g_free (buffer);
-
-       val = xmms_config_lookup ("playlist.html.suffixes");
-       suffix = g_strsplit (xmms_config_property_get_string (val), ",", 0);
-
-       plsurl = xmms_transport_url_get (transport);
-
-       session = xmms_medialib_begin_write ();
-
-       for (cnt = 0; tags[cnt] != NULL; cnt++) {
-               gchar *url, *full;
-               xmms_medialib_entry_t entry;
-
-               url = parse_tag (tags[cnt], plsurl);
-               if (!url) {
-                       continue;
-               }
-
-               if (!valid_suffix (suffix, url)) {
-                       g_free (url);
-                       continue;
-               }
-
-               full = build_url (plsurl, url);
-
-               entry = xmms_medialib_entry_new (session, full, &error);
-               if (entry)
-                       xmms_medialib_playlist_add (session, playlist_id, 
entry);
-
-               g_free (url);
-               g_free (full);
-       }
-
-       g_strfreev (suffix);
-       g_strfreev (tags);
-
-       xmms_medialib_end (session);
-
+       xmms_xform_outdata_type_add (xform,
+                       XMMS_STREAM_TYPE_MIMETYPE,
+                       "application/x-xmms2-playlist-entries",
+                       XMMS_STREAM_TYPE_END);
        return TRUE;
 }
 
-static GString *
-xmms_html_write_playlist (guint32 *list)
+static gboolean xmms_html_browse (xmms_xform_t *xform, const gchar *url,
+               xmms_error_t *error)
 {
-       GString *ret;
-       xmms_medialib_session_t *session;
-       gboolean is_even = TRUE;
-       guint num_entries = 0, total_len = 0;
-       guint i;
-
-       g_return_val_if_fail (list, FALSE);
-
-       session = xmms_medialib_begin ();
-
-       /* get the playlists total playtime */
-       while (list[num_entries]) {
-               xmms_medialib_entry_t entry = list[num_entries];
-
-               total_len += xmms_medialib_entry_property_get_int (session, 
entry,
-                                                                  
XMMS_MEDIALIB_ENTRY_PROPERTY_DURATION);
-
-               num_entries++;
-       }
-
-       ret = g_string_new (NULL);
-       g_string_append_printf (ret, html_header, num_entries,
-                               total_len / 3600000, (total_len / 60000) % 60,
-                               (total_len / 1000) % 60);
-
-       i = 0;
-
-       while (list[i]) {
-               gchar buf[256], *artist, *title, *url;
-               xmms_medialib_entry_t entry;
-               guint len;
-
-               entry = list[i];
-
-               artist = escape_html (xmms_medialib_entry_property_get_str 
(session, entry,
-                   XMMS_MEDIALIB_ENTRY_PROPERTY_ARTIST));
-               title = escape_html (xmms_medialib_entry_property_get_str 
(session, entry,
-                   XMMS_MEDIALIB_ENTRY_PROPERTY_TITLE));
-               len = xmms_medialib_entry_property_get_int (session, entry,
-                   XMMS_MEDIALIB_ENTRY_PROPERTY_DURATION);
-               url = escape_html (xmms_medialib_entry_property_get_str 
(session, entry,
-                   XMMS_MEDIALIB_ENTRY_PROPERTY_URL));
-
-               if (!artist && !title) {
-                       g_snprintf (buf, sizeof (buf), "%s (%02i:%02i)",
-                                   url, len / 60000, (len / 1000) % 60);
-               } else {
-                       g_snprintf (buf, sizeof (buf), "%s - %s (%02i:%02i)",
-                                   artist ? artist : "Unknown artist",
-                                   title ? title : "Unknown title",
-                                   len / 60000, (len / 1000) % 60);
+       g_return_val_if_fail (xform, FALSE);
+
+       gchar buffer[XMMS_XFORM_MAX_LINE_SIZE];
+       const gchar *plsurl = xmms_xform_get_url (xform);
+
+       g_return_val_if_fail (plsurl, FALSE);
+
+       xmms_error_reset(error);
+
+       xmms_medialib_session_t *session = xmms_medialib_begin_write ();
+       g_return_val_if_fail (session, FALSE);
+
+       while (xmms_xform_read_line (xform, buffer, error))
+       {
+               gchar *tagbeg = buffer;
+               while ((tagbeg = strchr (tagbeg, '<')))
+               {
+                       gchar *aurl=NULL;
+                       if ((aurl = parse_tag(++tagbeg, plsurl)))
+                       {
+                               gchar *full = xmms_build_playlist_url (plsurl, 
+                                               aurl);
+                               xmms_xform_browse_add_symlink (xform, 
+                                               NULL, full);
+                               g_free (full);
+                               g_free(aurl);
+                       }
                }
-
-               if (artist)
-                       g_free (artist);
-               if (title)
-                       g_free (title);
-               if (url)
-                       g_free (url);
-
-               g_string_append_printf (ret, is_even ? html_entry_even
-                                                    : html_entry_odd, buf);
-               is_even = !is_even;
-
-               i++;
        }
 
        xmms_medialib_end (session);
-       g_string_append (ret, html_footer);
-
-       return ret;
-}
-
-static gchar *
-escape_html (const gchar *in)
-{
-       gchar *ret = NULL, *retptr;
-       const gchar *inptr;
-       gsize len = 0;
-       gboolean need_escape = FALSE;
-
-       if (!in)
-               return NULL;
-
-       /* check whether we need to escape this string at all,
-        * and if we do, get the required length of the new buffer.
-        */
-       for (inptr = in; *inptr; inptr++) {
-               switch (*inptr) {
-                       case '"':
-                               need_escape = TRUE;
-                               len += 6; /* &quot; */
-                               break;
-                       case '&':
-                               need_escape = TRUE;
-                               len += 5; /* &amp; */
-                               break;
-                       case '>':
-                       case '<':
-                               need_escape = TRUE;
-                               len += 4; /* &gt; resp &lt; */
-                               break;
-                       default:
-                               len++;
-               }
-       }
-
-       if (!need_escape)
-               return g_strdup (in);
-
-       len++; /* terminating NUL */
-       retptr = ret = g_malloc (len);
-       *ret = '\0';
-
-       for (inptr = in; *inptr; inptr++) {
-               gint n;
-
-               switch (*inptr) {
-                       case '"':
-                               n = g_snprintf (retptr, len, "&quot;");
-                               break;
-                       case '&':
-                               n = g_snprintf (retptr, len, "&amp;");
-                               break;
-                       case '>':
-                               n = g_snprintf (retptr, len, "&gt;");
-                               break;
-                       case '<':
-                               n = g_snprintf (retptr, len, "&lt;");
-                               break;
-                       default:
-                               n = g_snprintf (retptr, len, "%c", *inptr);
-               }
-
-               len -= n;
-               retptr += n;
-       }
 
-       return ret;
-}
-
-static gboolean
-valid_suffix (gchar **suffix, gchar *path)
-{
-       guint current;
-
-       g_return_val_if_fail (suffix, FALSE);
-       g_return_val_if_fail (path, FALSE);
-
-       for (current = 0; suffix[current] != NULL; current++) {
-               if (g_str_has_suffix (path, g_strstrip (suffix[current])))
-                       return TRUE;
-       }
-
-       return FALSE;
-}
-
-static gchar *
-build_url (const gchar *plspath, const gchar *file)
-{
-       gchar *url;
-       gchar *path;
-
-       g_return_val_if_fail (plspath, NULL);
-       g_return_val_if_fail (file, NULL);
-
-       if (strstr (file, "://") != NULL) {
-               return g_strdup (file);
-       }
-
-       if (file[0] == '/') {
-               path = path_get_body (plspath);
-               url = g_build_filename (path, file, NULL);
-
-               g_free (path);
-
-               return url;
-       }
-
-       path = g_path_get_dirname (plspath);
-       url = g_build_filename (path, file, NULL);
-
-       g_free (path);
-
-       return url;
-}
-
-/*
- * proto://domain/dir/file -> proto://domain
- * domain/dir/file -> domain
- **/
-
-static gchar *
-path_get_body (const gchar *path)
-{
-       gchar *beg, *end;
-
-       g_return_val_if_fail (path, NULL);
-
-       beg = strstr (path, "://");
-
-       if (!beg) {
-               return g_strndup (path, strcspn (path, "/"));
-       }
-
-       beg += 3;
-       end = strchr (beg, '/');
-
-       if (!end) {
-               return g_strdup (path);
-       }
-
-       return g_strndup (path, end - path);
+       return TRUE;
 }
 
-static gchar *
-parse_tag (const gchar *tag, const gchar *plspath)
+static gchar *parse_tag (const gchar *tag, const gchar *plspath)
 {
        size_t urlend;
        gchar *href, *url;
@@ -443,19 +134,16 @@ parse_tag (const gchar *tag, const gchar *plspath)
        g_return_val_if_fail (tag, NULL);
        g_return_val_if_fail (plspath, NULL);
 
-       if (g_ascii_strncasecmp (tag, "a ", 2) != 0) {
+       if (g_ascii_strncasecmp (tag, "a ", 2) != 0)
                return NULL;
-       }
 
        href = strstr (tag, "href=\"");
 
-       if (!href) {
+       if (!href)
                href = strstr (tag, "HREF=\"");
-       }
 
-       if (!href) {
+       if (!href)
                return NULL;
-       }
 
        urlend = strcspn (href + 6, "\"");
 
@@ -463,3 +151,4 @@ parse_tag (const gchar *tag, const gchar *plspath)
 
        return url;
 }
+
diff --git a/src/plugins/html/wscript b/src/plugins/html/wscript
index 5de9a97..57d8382 100644
--- a/src/plugins/html/wscript
+++ b/src/plugins/html/wscript
@@ -1,3 +1,3 @@
 from waftools.plugin import plugin
 
-configure, build = plugin('html', broken=True)
+configure, build = plugin('html', broken=False)
-- 
1.6.0.3


--
_______________________________________________
Xmms2-devel mailing list
[email protected]
http://lists.xmms.se/cgi-bin/mailman/listinfo/xmms2-devel

Reply via email to