]> git.sesse.net Git - vlc/commitdiff
Allow lua "meta reader" and implement a meta reader from filename.
authorPierre d'Herbemont <pdherbemont@free.fr>
Thu, 7 Jan 2010 00:07:02 +0000 (01:07 +0100)
committerPierre d'Herbemont <pdherbemont@free.fr>
Thu, 7 Jan 2010 01:37:34 +0000 (02:37 +0100)
"filename.lua"
  will check if the file name respects the following form:
    "Show.Name S19E01-jde.DEf.avi"
  upon success, it will fill the show name, the episode number and
  season number in the meta data.
  It will also set the title to "Show Name S19E01"

modules/misc/lua/meta.c
modules/misc/lua/vlc.c
modules/misc/lua/vlc.h
share/Makefile.am
share/lua/meta/art/01_musicbrainz.lua [moved from share/lua/meta/01_musicbrainz.lua with 89% similarity]
share/lua/meta/art/10_googleimage.lua [moved from share/lua/meta/10_googleimage.lua with 77% similarity]
share/lua/meta/art/README.txt [moved from share/lua/meta/README.txt with 97% similarity]
share/lua/meta/reader/README.txt [new file with mode: 0644]
share/lua/meta/reader/filename.lua [new file with mode: 0644]

index 5eb2ef0d9f475589671593f3929a2f0c02b8cd67..fa389bd36736cc9ae3e5dba4a21edf3d7b5a02b1 100644 (file)
@@ -37,6 +37,7 @@
 #include <vlc_input.h>
 #include <vlc_playlist.h>
 #include <vlc_meta.h>
+#include <vlc_demux.h>
 #include <vlc_art_finder.h>
 #include <vlc_url.h>
 #include <vlc_strings.h>
 #include "vlc.h"
 #include "libs.h"
 
-
-/*****************************************************************************
- * Local prototypes
- *****************************************************************************/
-static int fetch_art( vlc_object_t *p_this, const char * psz_filename,
-                      lua_State * L, void * user_data );
-static lua_State *vlclua_meta_init( vlc_object_t *p_this,
-                                    input_item_t * p_item );
-
-
 /*****************************************************************************
  * Init lua
  *****************************************************************************/
 static const luaL_Reg p_reg[] = { { NULL, NULL } };
 
-static lua_State * vlclua_meta_init( vlc_object_t *p_this, input_item_t * p_item )
+static lua_State * init( vlc_object_t *p_this, input_item_t * p_item )
 {
     lua_State * L = luaL_newstate();
     if( !L )
@@ -69,7 +60,6 @@ static lua_State * vlclua_meta_init( vlc_object_t *p_this, input_item_t * p_item
         msg_Err( p_this, "Could not create new Lua State" );
         return NULL;
     }
-    char *psz_meta;
 
     /* Load Lua libraries */
     luaL_openlibs( L ); /* XXX: Don't open all the libs? */
@@ -82,82 +72,69 @@ static lua_State * vlclua_meta_init( vlc_object_t *p_this, input_item_t * p_item
     luaopen_variables( L );
     luaopen_object( L );
     luaopen_misc( L );
+    luaopen_input_item( L, p_item );
 
     lua_pushlightuserdata( L, p_this );
     lua_setfield( L, -2, "private" );
 
-    psz_meta = input_item_GetName( p_item );
-    lua_pushstring( L, psz_meta );
-    lua_setfield( L, -2, "name" );
-    free( psz_meta );
-
-    psz_meta = input_item_GetArtist( p_item );
-    lua_pushstring( L, psz_meta );
-    lua_setfield( L, -2, "artist" );
-    free( psz_meta );
-
-    psz_meta = input_item_GetTitle( p_item ) ;
-    lua_pushstring( L, psz_meta );
-    lua_setfield( L, -2, "title" );
-    free( psz_meta );
-
-    psz_meta = input_item_GetAlbum( p_item );
-    lua_pushstring( L, psz_meta );
-    lua_setfield( L, -2, "album" );
-    free( psz_meta );
-
-    psz_meta = input_item_GetArtURL( p_item );
-    lua_pushstring( L, psz_meta );
-    lua_setfield( L, -2, "arturl" );
-    free( psz_meta );
-    /* XXX: all should be passed ( could use macro ) */
-
     return L;
 }
 
 /*****************************************************************************
- * Called through lua_scripts_batch_execute to call 'fetch_art' on the script
- * pointed by psz_filename.
+ * Run a lua entry point function
  *****************************************************************************/
-static int fetch_art( vlc_object_t *p_this, const char * psz_filename,
-                      lua_State * L, void * user_data )
+static int run( vlc_object_t *p_this, const char * psz_filename,
+                lua_State * L, const char *luafunction )
 {
-    int i_ret = VLC_EGENERIC;
-    input_item_t * p_input = user_data;
-    int s;
-
     /* Ugly hack to delete previous versions of the fetchart()
-    * functions. */
+     * functions. */
     lua_pushnil( L );
-    lua_setglobal( L, "fetch_art" );
+    lua_setglobal( L, luafunction );
 
     /* Load and run the script(s) */
     if( luaL_dofile( L, psz_filename ) )
     {
         msg_Warn( p_this, "Error loading script %s: %s", psz_filename,
-                  lua_tostring( L, lua_gettop( L ) ) );
-        lua_pop( L, 1 );
-        return VLC_EGENERIC;
+                 lua_tostring( L, lua_gettop( L ) ) );
+        goto error;
     }
 
-    lua_getglobal( L, "fetch_art" );
+    lua_getglobal( L, luafunction );
 
     if( !lua_isfunction( L, lua_gettop( L ) ) )
     {
         msg_Warn( p_this, "Error while runing script %s, "
-                  "function fetch_art() not found", psz_filename );
-        lua_pop( L, 1 );
-        return VLC_EGENERIC;
+                 "function %s() not found", psz_filename, luafunction );
+        goto error;
     }
 
     if( lua_pcall( L, 0, 1, 0 ) )
     {
         msg_Warn( p_this, "Error while runing script %s, "
-                  "function fetch_art(): %s", psz_filename,
-                  lua_tostring( L, lua_gettop( L ) ) );
-        lua_pop( L, 1 );
-        return VLC_EGENERIC;
+                 "function %s(): %s", psz_filename, luafunction,
+                 lua_tostring( L, lua_gettop( L ) ) );
+        goto error;
     }
+    return VLC_SUCCESS;
+
+error:
+    lua_pop( L, 1 );
+    return VLC_EGENERIC;
+}
+
+/*****************************************************************************
+ * Called through lua_scripts_batch_execute to call 'fetch_art' on the script
+ * pointed by psz_filename.
+ *****************************************************************************/
+static int fetch_art( vlc_object_t *p_this, const char * psz_filename,
+                      lua_State * L, void * user_data )
+{
+    input_item_t * p_input = user_data;
+    int s;
+
+    int i_ret = run(p_this, psz_filename, L, "fetch_art");
+    if(i_ret != VLC_SUCCESS)
+        return i_ret;
 
     if((s = lua_gettop( L )))
     {
@@ -170,7 +147,7 @@ static int fetch_art( vlc_object_t *p_this, const char * psz_filename,
             {
                 lua_Dbg( p_this, "setting arturl: %s", psz_value );
                 input_item_SetArtURL ( p_input, psz_value );
-                i_ret = VLC_SUCCESS;
+                return VLC_SUCCESS;
             }
         }
         else if( !lua_isnil( L, s ) )
@@ -184,6 +161,39 @@ static int fetch_art( vlc_object_t *p_this, const char * psz_filename,
         msg_Err( p_this, "Script went completely foobar" );
     }
 
+    return VLC_EGENERIC;
+}
+
+/*****************************************************************************
+ * Called through lua_scripts_batch_execute to call 'fetch_art' on the script
+ * pointed by psz_filename.
+ *****************************************************************************/
+static int read_meta( vlc_object_t *p_this, const char * psz_filename,
+                     lua_State * L, void * user_data )
+{
+    VLC_UNUSED(user_data);
+
+    int i_ret = run(p_this, psz_filename, L, "read_meta");
+    if(i_ret != VLC_SUCCESS)
+        return i_ret;
+
+    // Continue, all "meta reader" are always run.
+    return 1;
+}
+
+/*****************************************************************************
+ * Read meta.
+ *****************************************************************************/
+
+int ReadMeta( vlc_object_t *p_this )
+{
+    demux_meta_t *p_demux_meta = (demux_meta_t *)p_this;
+    input_item_t *p_item = p_demux_meta->p_item;
+
+    lua_State *L = init( p_this, p_item );
+    int i_ret = vlclua_scripts_batch_execute( p_this, "meta/reader", &read_meta, L, NULL );
+    lua_close( L );
+
     return i_ret;
 }
 
@@ -198,8 +208,8 @@ int FindArt( vlc_object_t *p_this )
     if( !p_playlist )
         return VLC_EGENERIC;
 
-    lua_State *L = vlclua_meta_init( p_this, p_item );
-    int i_ret = vlclua_scripts_batch_execute( p_this, "meta", &fetch_art, L, p_item );
+    lua_State *L = init( p_this, p_item );
+    int i_ret = vlclua_scripts_batch_execute( p_this, "meta/art", &fetch_art, L, p_item );
     lua_close( L );
 
     pl_Release( p_this );
index 275fcc0722a68365a605e09254b798c34dda2f13..3613e11354aab3e46a55e2f93810c732f4e209c6 100644 (file)
@@ -63,6 +63,12 @@ vlc_module_begin ()
         set_capability( "art finder", 10 )
         set_callbacks( FindArt, NULL )
 
+    add_submodule ()
+        set_shortname( N_( "Lua Meta Reader" ) )
+        set_description( N_("Fetch meta data using lua scripts") )
+        set_capability( "meta reader", 10 )
+        set_callbacks( ReadMeta, NULL )
+
     add_submodule ()
         add_shortcut( "luaplaylist" )
         set_category( CAT_INPUT )
index f455f4e0dc84dda7cd3e7c94592c05d9f29a24c2..ba7fd052835dfcf8430b4023ff7a5b1b0d1c78ae 100644 (file)
@@ -48,6 +48,8 @@
 /*****************************************************************************
  * Module entry points
  *****************************************************************************/
+int ReadMeta( vlc_object_t * );
+
 int FindArt( vlc_object_t * );
 
 int Import_LuaPlaylist( vlc_object_t * );
index 43f2347f889d8874415a67baeedc4f81fa7d2d9c..dce8c2c80c8dcd5c2c98e19b55273e001310936e 100644 (file)
@@ -190,9 +190,11 @@ DIST_osdmenu_default = \
 
 DIST_lua= \
        lua/README.txt \
-       lua/meta/README.txt \
-       lua/meta/01_musicbrainz.lua \
-       lua/meta/10_googleimage.lua \
+       lua/meta/art/README.txt \
+       lua/meta/art/01_musicbrainz.lua \
+       lua/meta/art/10_googleimage.lua \
+       lua/meta/reader/README.txt \
+       lua/meta/reader/filename.lua \
        lua/playlist/README.txt \
        lua/playlist/anevia_streams.lua \
        lua/playlist/appletrailers.lua \
similarity index 89%
rename from share/lua/meta/01_musicbrainz.lua
rename to share/lua/meta/art/01_musicbrainz.lua
index f12139690585d097f709acc12d07fd990451adf6..ac21ae3ac379dcd2a039028864861cb778aed565 100644 (file)
@@ -22,8 +22,9 @@
 -- Return the artwork
 function fetch_art()
     local query
-    if vlc.artist and vlc.album then
-        query = "http://musicbrainz.org/ws/1/release/?type=xml&artist="..vlc.strings.encode_uri_component(vlc.artist).."&title="..vlc.strings.encode_uri_component(vlc.album)
+    local meta = vlc.item.metas(vlc.item)
+    if meta["artist"] and meta["album"] then
+        query = "http://musicbrainz.org/ws/1/release/?type=xml&artist="..vlc.strings.encode_uri_component(meta["artist"]).."&title="..vlc.strings.encode_uri_component(meta["album"])
     else
         return nil
     end
similarity index 77%
rename from share/lua/meta/10_googleimage.lua
rename to share/lua/meta/art/10_googleimage.lua
index 8dc1e04c46d3c1ec99a7aa55d3b3ae361aa23a08..8893699cbc3f5f0a9f08fe1caec23b3f6f888218 100644 (file)
@@ -29,15 +29,17 @@ end
 
 -- Return the artwork
 function fetch_art()
-    if vlc.artist and vlc.album then
-        title = vlc.artist.." "..vlc.album
-    elseif vlc.title and vlc.artist then
-        title = vlc.artist.." "..vlc.title
-    elseif vlc.title then
-        title = vlc.title
-    elseif vlc.name then
-        title = vlc.name
+    local meta = vlc.item.metas(vlc.item)
+    if meta["artist"] and meta["album"] then
+        title = meta["artist"].." "..meta["album"]
+    elseif meta["title"] and meta["artist"] then
+        title = meta["artist"].." "..meta["title"]
+    elseif meta["title"] then
+        title = meta["title"]
+    elseif meta["filename"] then
+        title = meta["filename"]
     else
+        vlc.msg.err("No filename")
         return nil
     end
     fd = vlc.stream( "http://images.google.com/images?q=" .. get_query( title ) )
similarity index 97%
rename from share/lua/meta/README.txt
rename to share/lua/meta/art/README.txt
index 0d5d6feb17ddd5ac2ada7681eb423d7a42db6819..f969329010a4ed0f98082adb48ffc50f3002c5e1 100644 (file)
@@ -8,5 +8,5 @@ Examples: See googleimage.lua .
 VLC Lua meta modules should define one of the following functions:
  * fetch_art(): returns a path to an artwork for the given item
 
-Available VLC specific Lua modules: msg, stream, strings, variables,
+Available VLC specific Lua modules: msg, stream, strings, variables, item,
 objects and misc. See lua/README.txt
diff --git a/share/lua/meta/reader/README.txt b/share/lua/meta/reader/README.txt
new file mode 100644 (file)
index 0000000..8ac70fd
--- /dev/null
@@ -0,0 +1,14 @@
+Instructions to code your own VLC Lua meta script.
+$Id$
+
+See lua/README.txt for generic documentation about Lua usage in VLC.
+
+Examples: See filename.lua .
+
+VLC Lua "meta reader" modules should define one of the following functions:
+ * read_meta(): returns a path to an artwork for the given item
+
+Available VLC specific Lua modules: msg, stream, strings, variables, item,
+objects and misc. See lua/README.txt
+
+Note, those scripts are supposed to be fast. Read non blocking, no IO.
\ No newline at end of file
diff --git a/share/lua/meta/reader/filename.lua b/share/lua/meta/reader/filename.lua
new file mode 100644 (file)
index 0000000..1f8665b
--- /dev/null
@@ -0,0 +1,52 @@
+--[[
+ Gets an artwork for french TV channels
+
+ $Id$
+ Copyright © 2007 the VideoLAN team
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+--]]
+
+function trim (s)
+  return (string.gsub(s, "^%s*(.-)%s*$", "%1"))
+end
+
+function read_meta()
+    local metas = vlc.item.metas(vlc.item)
+
+    -- Don't do anything if there is already a title
+    if metas["title"] then
+        return
+    end
+
+    local name = metas["filename"];
+    if not name then
+        return
+    end
+
+    -- Find "Show.Name.S01E12-blah.avi"
+    local title, seasonNumber
+    _, _, showName, seasonNumber, episodeNumber = string.find(name, "(.+)S(%d%d)E(%d%d).*")
+    if not showName then
+        return
+    end
+
+    -- Remove . in showName
+    showName = trim(string.gsub(showName, "%.", " "))
+    vlc.item.set_meta(vlc.item, "title", showName.." S"..seasonNumber.."E"..episodeNumber)
+    vlc.item.set_meta(vlc.item, "showName", showName)
+    vlc.item.set_meta(vlc.item, "episodeNumber", episodeNumber)
+    vlc.item.set_meta(vlc.item, "seasonNumber", seasonNumber)
+end