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 @@
#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>
......@@ -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. */
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;
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,
"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 );
......
......@@ -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 )
......
......@@ -48,6 +48,8 @@
/*****************************************************************************
* Module entry points
*****************************************************************************/
int ReadMeta( vlc_object_t * );
int FindArt( vlc_object_t * );
int Import_LuaPlaylist( vlc_object_t * );
......
......@@ -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 \
......
......@@ -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
......
......@@ -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 ) )
......
......@@ -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
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