1 /*****************************************************************************
2 * sd.c: Services discovery related functions
3 *****************************************************************************
4 * Copyright (C) 2007-2008 the VideoLAN team
7 * Authors: Antoine Cellerier <dionoea at videolan tod org>
8 * Fabio Ritrovato <exsephiroth87 at videolan dot org>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23 *****************************************************************************/
25 /*****************************************************************************
27 *****************************************************************************/
36 #include <vlc_common.h>
37 #include <vlc_services_discovery.h>
38 #include <vlc_playlist.h>
40 #include <lua.h> /* Low level lua C API */
41 #include <lauxlib.h> /* Higher level C API */
42 #include <lualib.h> /* Lua libs */
48 /*****************************************************************************
50 *****************************************************************************/
51 static int vlclua_node_add_subitem( lua_State * );
52 static int vlclua_node_add_node( lua_State * );
54 static const luaL_Reg vlclua_node_reg[] = {
55 { "add_subitem", vlclua_node_add_subitem },
56 { "add_node", vlclua_node_add_node },
60 static int vlclua_sd_get_services_names( lua_State *L )
62 playlist_t *p_playlist = vlclua_get_playlist_internal( L );
63 char **ppsz_longnames;
64 char **ppsz_names = vlc_sd_GetNames( p_playlist, &ppsz_longnames );
65 vlclua_release_playlist_internal( p_playlist );
69 char **ppsz_longname = ppsz_longnames;
70 char **ppsz_name = ppsz_names;
73 for( ; *ppsz_name; ppsz_name++,ppsz_longname++ )
75 lua_pushstring( L, *ppsz_longname );
76 lua_setfield( L, -2, *ppsz_name );
78 free( *ppsz_longname );
81 free( ppsz_longnames );
85 static int vlclua_sd_add( lua_State *L )
87 const char *psz_sd = luaL_checkstring( L, 1 );
88 playlist_t *p_playlist = vlclua_get_playlist_internal( L );
89 int i_ret = playlist_ServicesDiscoveryAdd( p_playlist, psz_sd );
90 vlclua_release_playlist_internal( p_playlist );
91 return vlclua_push_ret( L, i_ret );
94 static int vlclua_sd_remove( lua_State *L )
96 const char *psz_sd = luaL_checkstring( L, 1 );
97 playlist_t *p_playlist = vlclua_get_playlist_internal( L );
98 int i_ret = playlist_ServicesDiscoveryRemove( p_playlist, psz_sd );
99 vlclua_release_playlist_internal( p_playlist );
100 return vlclua_push_ret( L, i_ret );
103 static int vlclua_sd_is_loaded( lua_State *L )
105 const char *psz_sd = luaL_checkstring( L, 1 );
106 playlist_t *p_playlist = vlclua_get_playlist_internal( L );
107 lua_pushboolean( L, playlist_IsServicesDiscoveryLoaded( p_playlist, psz_sd ));
108 vlclua_release_playlist_internal( p_playlist );
112 static int vlclua_sd_add_node( lua_State *L )
114 services_discovery_t *p_sd = (services_discovery_t *)vlclua_get_this( L );
115 if( lua_istable( L, -1 ) )
117 lua_getfield( L, -1, "title" );
118 if( lua_isstring( L, -1 ) )
120 input_item_t *p_input = input_item_New( p_sd, "vlc://nop",
121 strdup( lua_tostring( L, -1 ) ) );
123 lua_getfield( L, -1, "arturl" );
124 if( lua_isstring( L, -1 ) )
126 char *psz_value = strdup( lua_tostring( L, -1 ) );
127 EnsureUTF8( psz_value );
128 msg_Dbg( p_sd, "ArtURL: %s", psz_value );
129 input_item_SetArtURL( p_input, psz_value );
132 services_discovery_AddItem( p_sd, p_input, NULL );
133 input_item_t **udata = (input_item_t **)
134 lua_newuserdata( L, sizeof( input_item_t * ) );
136 if( luaL_newmetatable( L, "node" ) )
139 luaL_register( L, NULL, vlclua_node_reg );
140 lua_setfield( L, -2, "__index" );
142 lua_setmetatable( L, -2 );
145 msg_Err( p_sd, "vlc.sd.add_node: the \"title\" parameter can't be empty" );
148 msg_Err( p_sd, "Error parsing add_node arguments" );
152 static int vlclua_sd_add_item( lua_State *L )
154 services_discovery_t *p_sd = (services_discovery_t *)vlclua_get_this( L );
155 if( lua_istable( L, -1 ) )
157 lua_getfield( L, -1, "url" );
158 if( lua_isstring( L, -1 ) )
160 input_item_t *p_input = input_item_New( p_sd,
161 strdup( lua_tostring( L, -1 ) ),
162 strdup( lua_tostring( L, -1 ) ) );
164 vlclua_read_meta_data( p_sd, L, p_input );
165 /* This one is to be tested... */
166 vlclua_read_custom_meta_data( p_sd, L, p_input );
167 lua_getfield( L, -1, "duration" );
168 if( lua_isnumber( L, -1 ) )
169 input_item_SetDuration( p_input, (lua_tonumber( L, -1 )*1e6) );
170 else if( !lua_isnil( L, -1 ) )
171 msg_Warn( p_sd, "Item duration should be a number (in seconds)." );
173 services_discovery_AddItem( p_sd, p_input, NULL );
174 input_item_t **udata = (input_item_t **)
175 lua_newuserdata( L, sizeof( input_item_t * ) );
177 if( luaL_newmetatable( L, "input_item_t" ) )
179 lua_pushstring( L, "none of your business" );
180 lua_setfield( L, -2, "__metatable" );
182 lua_setmetatable( L, -2 );
185 msg_Err( p_sd, "vlc.sd.add_item: the \"url\" parameter can't be empty" );
188 msg_Err( p_sd, "Error parsing add_item arguments" );
192 static int vlclua_sd_remove_item( lua_State *L )
194 services_discovery_t *p_sd = (services_discovery_t *)vlclua_get_this( L );
195 if( !lua_isnil( L, -1 ) )
197 input_item_t **pp_input = luaL_checkudata( L, -1, "input_item_t" );
199 services_discovery_RemoveItem( p_sd, *pp_input );
204 static int vlclua_node_add_subitem( lua_State *L )
206 services_discovery_t *p_sd = (services_discovery_t *)vlclua_get_this( L );
207 input_item_t **pp_node = (input_item_t **)luaL_checkudata( L, 1, "node" );
210 if( lua_istable( L, -1 ) )
212 lua_getfield( L, -1, "url" );
213 if( lua_isstring( L, -1 ) )
215 input_item_node_t *p_input_node = input_item_node_Create( *pp_node );
216 input_item_t *p_input = input_item_New( p_sd,
217 strdup( lua_tostring( L, -1 ) ),
218 strdup( lua_tostring( L, -1 ) ) );
220 vlclua_read_meta_data( p_sd, L, p_input );
221 /* This one is to be tested... */
222 vlclua_read_custom_meta_data( p_sd, L, p_input );
223 lua_getfield( L, -1, "duration" );
224 if( lua_isnumber( L, -1 ) )
225 input_item_SetDuration( p_input, (lua_tonumber( L, -1 )*1e6) );
226 else if( !lua_isnil( L, -1 ) )
227 msg_Warn( p_sd, "Item duration should be a number (in seconds)." );
229 input_item_node_AppendItem( p_input_node, p_input );
230 input_item_node_PostAndDelete( p_input_node );
231 input_item_t **udata = (input_item_t **)
232 lua_newuserdata( L, sizeof( input_item_t * ) );
234 if( luaL_newmetatable( L, "input_item_t" ) )
236 lua_pushstring( L, "none of your business" );
237 lua_setfield( L, -2, "__metatable" );
239 lua_setmetatable( L, -2 );
242 msg_Err( p_sd, "node:add_subitem: the \"url\" parameter can't be empty" );
245 msg_Err( p_sd, "Error parsing add_subitem arguments" );
250 static int vlclua_node_add_node( lua_State *L )
252 services_discovery_t *p_sd = (services_discovery_t *)vlclua_get_this( L );
253 input_item_t **pp_node = (input_item_t **)luaL_checkudata( L, 1, "node" );
256 if( lua_istable( L, -1 ) )
258 lua_getfield( L, -1, "title" );
259 if( lua_isstring( L, -1 ) )
261 input_item_node_t *p_input_node = input_item_node_Create( *pp_node );
262 input_item_t *p_input = input_item_New( p_sd,
264 strdup( lua_tostring( L, -1 ) ) );
266 lua_getfield( L, -1, "arturl" );
267 if( lua_isstring( L, -1 ) )
269 char *psz_value = strdup( lua_tostring( L, -1 ) );
270 EnsureUTF8( psz_value );
271 msg_Dbg( p_sd, "ArtURL: %s", psz_value );
272 input_item_SetArtURL( p_input, psz_value );
275 input_item_node_AppendItem( p_input_node, p_input );
276 input_item_node_PostAndDelete( p_input_node );
277 input_item_t **udata = (input_item_t **)
278 lua_newuserdata( L, sizeof( input_item_t * ) );
280 if( luaL_newmetatable( L, "node" ) )
283 luaL_register( L, NULL, vlclua_node_reg );
284 lua_setfield( L, -2, "__index" );
286 lua_setmetatable( L, -2 );
289 msg_Err( p_sd, "node:add_node: the \"title\" parameter can't be empty" );
292 msg_Err( p_sd, "Error parsing add_node arguments" );
297 /*****************************************************************************
299 *****************************************************************************/
300 static const luaL_Reg vlclua_sd_reg[] = {
301 { "get_services_names", vlclua_sd_get_services_names },
302 { "add", vlclua_sd_add },
303 { "remove", vlclua_sd_remove },
304 { "is_loaded", vlclua_sd_is_loaded },
305 { "add_node", vlclua_sd_add_node },
306 { "add_item", vlclua_sd_add_item },
307 { "remove_item", vlclua_sd_remove_item },
311 void luaopen_sd( lua_State *L )
314 luaL_register( L, NULL, vlclua_sd_reg );
315 lua_setfield( L, -2, "sd" );