From 555cb288eea92ac9b2b5416225f678323f439ece Mon Sep 17 00:00:00 2001 From: Pierre d'Herbemont Date: Thu, 7 Jan 2010 01:07:02 +0100 Subject: [PATCH] Allow lua "meta reader" and implement a meta reader from filename. "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 | 134 +++++++++++--------- modules/misc/lua/vlc.c | 6 + modules/misc/lua/vlc.h | 2 + share/Makefile.am | 8 +- share/lua/meta/{ => art}/01_musicbrainz.lua | 5 +- share/lua/meta/{ => art}/10_googleimage.lua | 18 +-- share/lua/meta/{ => art}/README.txt | 2 +- share/lua/meta/reader/README.txt | 14 ++ share/lua/meta/reader/filename.lua | 52 ++++++++ 9 files changed, 165 insertions(+), 76 deletions(-) rename share/lua/meta/{ => art}/01_musicbrainz.lua (89%) rename share/lua/meta/{ => art}/10_googleimage.lua (77%) rename share/lua/meta/{ => art}/README.txt (97%) create mode 100644 share/lua/meta/reader/README.txt create mode 100644 share/lua/meta/reader/filename.lua diff --git a/modules/misc/lua/meta.c b/modules/misc/lua/meta.c index 5eb2ef0d9f..fa389bd367 100644 --- a/modules/misc/lua/meta.c +++ b/modules/misc/lua/meta.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -46,22 +47,12 @@ #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 ); diff --git a/modules/misc/lua/vlc.c b/modules/misc/lua/vlc.c index 275fcc0722..3613e11354 100644 --- a/modules/misc/lua/vlc.c +++ b/modules/misc/lua/vlc.c @@ -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 ) diff --git a/modules/misc/lua/vlc.h b/modules/misc/lua/vlc.h index f455f4e0dc..ba7fd05283 100644 --- a/modules/misc/lua/vlc.h +++ b/modules/misc/lua/vlc.h @@ -48,6 +48,8 @@ /***************************************************************************** * Module entry points *****************************************************************************/ +int ReadMeta( vlc_object_t * ); + int FindArt( vlc_object_t * ); int Import_LuaPlaylist( vlc_object_t * ); diff --git a/share/Makefile.am b/share/Makefile.am index 43f2347f88..dce8c2c80c 100644 --- a/share/Makefile.am +++ b/share/Makefile.am @@ -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 \ diff --git a/share/lua/meta/01_musicbrainz.lua b/share/lua/meta/art/01_musicbrainz.lua similarity index 89% rename from share/lua/meta/01_musicbrainz.lua rename to share/lua/meta/art/01_musicbrainz.lua index f121396905..ac21ae3ac3 100644 --- a/share/lua/meta/01_musicbrainz.lua +++ b/share/lua/meta/art/01_musicbrainz.lua @@ -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 diff --git a/share/lua/meta/10_googleimage.lua b/share/lua/meta/art/10_googleimage.lua similarity index 77% rename from share/lua/meta/10_googleimage.lua rename to share/lua/meta/art/10_googleimage.lua index 8dc1e04c46..8893699cbc 100644 --- a/share/lua/meta/10_googleimage.lua +++ b/share/lua/meta/art/10_googleimage.lua @@ -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 ) ) diff --git a/share/lua/meta/README.txt b/share/lua/meta/art/README.txt similarity index 97% rename from share/lua/meta/README.txt rename to share/lua/meta/art/README.txt index 0d5d6feb17..f969329010 100644 --- a/share/lua/meta/README.txt +++ b/share/lua/meta/art/README.txt @@ -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 index 0000000000..8ac70fdc40 --- /dev/null +++ b/share/lua/meta/reader/README.txt @@ -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 index 0000000000..1f8665bf2c --- /dev/null +++ b/share/lua/meta/reader/filename.lua @@ -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 -- 2.39.2