Commit 555cb288 authored by Pierre d'Herbemont's avatar Pierre d'Herbemont

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"
parent 855c0ab2
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#include <vlc_input.h> #include <vlc_input.h>
#include <vlc_playlist.h> #include <vlc_playlist.h>
#include <vlc_meta.h> #include <vlc_meta.h>
#include <vlc_demux.h>
#include <vlc_art_finder.h> #include <vlc_art_finder.h>
#include <vlc_url.h> #include <vlc_url.h>
#include <vlc_strings.h> #include <vlc_strings.h>
...@@ -46,22 +47,12 @@ ...@@ -46,22 +47,12 @@
#include "vlc.h" #include "vlc.h"
#include "libs.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 * Init lua
*****************************************************************************/ *****************************************************************************/
static const luaL_Reg p_reg[] = { { NULL, NULL } }; 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(); lua_State * L = luaL_newstate();
if( !L ) if( !L )
...@@ -69,7 +60,6 @@ static lua_State * vlclua_meta_init( vlc_object_t *p_this, input_item_t * p_item ...@@ -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" ); msg_Err( p_this, "Could not create new Lua State" );
return NULL; return NULL;
} }
char *psz_meta;
/* Load Lua libraries */ /* Load Lua libraries */
luaL_openlibs( L ); /* XXX: Don't open all the libs? */ 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 ...@@ -82,82 +72,69 @@ static lua_State * vlclua_meta_init( vlc_object_t *p_this, input_item_t * p_item
luaopen_variables( L ); luaopen_variables( L );
luaopen_object( L ); luaopen_object( L );
luaopen_misc( L ); luaopen_misc( L );
luaopen_input_item( L, p_item );
lua_pushlightuserdata( L, p_this ); lua_pushlightuserdata( L, p_this );
lua_setfield( L, -2, "private" ); 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; return L;
} }
/***************************************************************************** /*****************************************************************************
* Called through lua_scripts_batch_execute to call 'fetch_art' on the script * Run a lua entry point function
* pointed by psz_filename.
*****************************************************************************/ *****************************************************************************/
static int fetch_art( vlc_object_t *p_this, const char * psz_filename, static int run( vlc_object_t *p_this, const char * psz_filename,
lua_State * L, void * user_data ) 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() /* Ugly hack to delete previous versions of the fetchart()
* functions. */ * functions. */
lua_pushnil( L ); lua_pushnil( L );
lua_setglobal( L, "fetch_art" ); lua_setglobal( L, luafunction );
/* Load and run the script(s) */ /* Load and run the script(s) */
if( luaL_dofile( L, psz_filename ) ) if( luaL_dofile( L, psz_filename ) )
{ {
msg_Warn( p_this, "Error loading script %s: %s", psz_filename, msg_Warn( p_this, "Error loading script %s: %s", psz_filename,
lua_tostring( L, lua_gettop( L ) ) ); lua_tostring( L, lua_gettop( L ) ) );
lua_pop( L, 1 ); goto error;
return VLC_EGENERIC;
} }
lua_getglobal( L, "fetch_art" ); lua_getglobal( L, luafunction );
if( !lua_isfunction( L, lua_gettop( L ) ) ) if( !lua_isfunction( L, lua_gettop( L ) ) )
{ {
msg_Warn( p_this, "Error while runing script %s, " msg_Warn( p_this, "Error while runing script %s, "
"function fetch_art() not found", psz_filename ); "function %s() not found", psz_filename, luafunction );
lua_pop( L, 1 ); goto error;
return VLC_EGENERIC;
} }
if( lua_pcall( L, 0, 1, 0 ) ) if( lua_pcall( L, 0, 1, 0 ) )
{ {
msg_Warn( p_this, "Error while runing script %s, " msg_Warn( p_this, "Error while runing script %s, "
"function fetch_art(): %s", psz_filename, "function %s(): %s", psz_filename, luafunction,
lua_tostring( L, lua_gettop( L ) ) ); lua_tostring( L, lua_gettop( L ) ) );
lua_pop( L, 1 ); goto error;
return VLC_EGENERIC;
} }
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 ))) if((s = lua_gettop( L )))
{ {
...@@ -170,7 +147,7 @@ static int fetch_art( vlc_object_t *p_this, const char * psz_filename, ...@@ -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 ); lua_Dbg( p_this, "setting arturl: %s", psz_value );
input_item_SetArtURL ( p_input, psz_value ); input_item_SetArtURL ( p_input, psz_value );
i_ret = VLC_SUCCESS; return VLC_SUCCESS;
} }
} }
else if( !lua_isnil( L, s ) ) else if( !lua_isnil( L, s ) )
...@@ -184,6 +161,39 @@ static int fetch_art( vlc_object_t *p_this, const char * psz_filename, ...@@ -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" ); 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; return i_ret;
} }
...@@ -198,8 +208,8 @@ int FindArt( vlc_object_t *p_this ) ...@@ -198,8 +208,8 @@ int FindArt( vlc_object_t *p_this )
if( !p_playlist ) if( !p_playlist )
return VLC_EGENERIC; return VLC_EGENERIC;
lua_State *L = vlclua_meta_init( p_this, p_item ); lua_State *L = init( p_this, p_item );
int i_ret = vlclua_scripts_batch_execute( p_this, "meta", &fetch_art, L, p_item ); int i_ret = vlclua_scripts_batch_execute( p_this, "meta/art", &fetch_art, L, p_item );
lua_close( L ); lua_close( L );
pl_Release( p_this ); pl_Release( p_this );
......
...@@ -63,6 +63,12 @@ vlc_module_begin () ...@@ -63,6 +63,12 @@ vlc_module_begin ()
set_capability( "art finder", 10 ) set_capability( "art finder", 10 )
set_callbacks( FindArt, NULL ) 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_submodule ()
add_shortcut( "luaplaylist" ) add_shortcut( "luaplaylist" )
set_category( CAT_INPUT ) set_category( CAT_INPUT )
......
...@@ -48,6 +48,8 @@ ...@@ -48,6 +48,8 @@
/***************************************************************************** /*****************************************************************************
* Module entry points * Module entry points
*****************************************************************************/ *****************************************************************************/
int ReadMeta( vlc_object_t * );
int FindArt( vlc_object_t * ); int FindArt( vlc_object_t * );
int Import_LuaPlaylist( vlc_object_t * ); int Import_LuaPlaylist( vlc_object_t * );
......
...@@ -190,9 +190,11 @@ DIST_osdmenu_default = \ ...@@ -190,9 +190,11 @@ DIST_osdmenu_default = \
DIST_lua= \ DIST_lua= \
lua/README.txt \ lua/README.txt \
lua/meta/README.txt \ lua/meta/art/README.txt \
lua/meta/01_musicbrainz.lua \ lua/meta/art/01_musicbrainz.lua \
lua/meta/10_googleimage.lua \ lua/meta/art/10_googleimage.lua \
lua/meta/reader/README.txt \
lua/meta/reader/filename.lua \
lua/playlist/README.txt \ lua/playlist/README.txt \
lua/playlist/anevia_streams.lua \ lua/playlist/anevia_streams.lua \
lua/playlist/appletrailers.lua \ lua/playlist/appletrailers.lua \
......
...@@ -22,8 +22,9 @@ ...@@ -22,8 +22,9 @@
-- Return the artwork -- Return the artwork
function fetch_art() function fetch_art()
local query local query
if vlc.artist and vlc.album then local meta = vlc.item.metas(vlc.item)
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) 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 else
return nil return nil
end end
......
...@@ -29,15 +29,17 @@ end ...@@ -29,15 +29,17 @@ end
-- Return the artwork -- Return the artwork
function fetch_art() function fetch_art()
if vlc.artist and vlc.album then local meta = vlc.item.metas(vlc.item)
title = vlc.artist.." "..vlc.album if meta["artist"] and meta["album"] then
elseif vlc.title and vlc.artist then title = meta["artist"].." "..meta["album"]
title = vlc.artist.." "..vlc.title elseif meta["title"] and meta["artist"] then
elseif vlc.title then title = meta["artist"].." "..meta["title"]
title = vlc.title elseif meta["title"] then
elseif vlc.name then title = meta["title"]
title = vlc.name elseif meta["filename"] then
title = meta["filename"]
else else
vlc.msg.err("No filename")
return nil return nil
end end
fd = vlc.stream( "http://images.google.com/images?q=" .. get_query( title ) ) fd = vlc.stream( "http://images.google.com/images?q=" .. get_query( title ) )
......
...@@ -8,5 +8,5 @@ Examples: See googleimage.lua . ...@@ -8,5 +8,5 @@ Examples: See googleimage.lua .
VLC Lua meta modules should define one of the following functions: VLC Lua meta modules should define one of the following functions:
* fetch_art(): returns a path to an artwork for the given item * 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 objects and misc. See lua/README.txt
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
--[[
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
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