int playlist_FindArtInCacheUsingItemUID( input_item_t *p_item ) { char *uid = input_item_GetInfo( p_item, "uid", "md5" ); if ( ! *uid ) { free( uid ); return VLC_EGENERIC; } /* we have an input item uid set */ bool b_done = false; char *psz_byuiddir = GetDirByItemUIDs( uid ); char *psz_byuidfile = GetFileByItemUID( psz_byuiddir, "arturl" ); free( psz_byuiddir ); if( psz_byuidfile ) { FILE *fd = vlc_fopen( psz_byuidfile, "rb" ); if ( fd ) { char sz_cachefile[2049]; /* read the cache hash url */ if ( fgets( sz_cachefile, 2048, fd ) != NULL ) { input_item_SetArtURL( p_item, sz_cachefile ); b_done = true; } fclose( fd ); } free( psz_byuidfile ); } free( uid ); if ( b_done ) return VLC_SUCCESS; return VLC_EGENERIC; }
void formatSnapshotItem( input_item_t *p_item ) { if( !p_item ) return; if( !p_item->p_meta ) p_item->p_meta = vlc_meta_New(); /* copy the snapshot mrl as a ArtURL */ if( p_item->p_meta ) { char* psz_uri = NULL; psz_uri = input_item_GetURI( p_item ); if( psz_uri ) input_item_SetArtURL( p_item, psz_uri ); free( psz_uri ); } /** * TODO: select the best mrl for displaying snapshots * - vlc://pause:10 => snapshot are displayed as Art * - file:///path/image.ext => snapshot are displayed as videos **/ input_item_SetURI( p_item, "vlc://pause:10" ); // input_item_AddOption( p_item, "fake-duration=10000", // VLC_INPUT_OPTION_TRUSTED ); }
int playlist_SaveArt( playlist_t *p_playlist, input_item_t *p_item, const uint8_t *p_buffer, int i_buffer, const char *psz_type ) { char *psz_filename = ArtCacheName( p_item, psz_type ); if( !psz_filename ) return VLC_EGENERIC; char *psz_uri = make_URI( psz_filename ); if( !psz_uri ) { free( psz_filename ); return VLC_EGENERIC; } /* Check if we already dumped it */ struct stat s; if( !utf8_stat( psz_filename, &s ) ) { input_item_SetArtURL( p_item, psz_uri ); free( psz_filename ); free( psz_uri ); return VLC_SUCCESS; } /* Dump it otherwise */ FILE *f = utf8_fopen( psz_filename, "wb" ); if( f ) { if( fwrite( p_buffer, i_buffer, 1, f ) != 1 ) { msg_Err( p_playlist, "%s: %m", psz_filename ); } else { msg_Dbg( p_playlist, "album art saved to %s", psz_filename ); input_item_SetArtURL( p_item, psz_uri ); } fclose( f ); } free( psz_filename ); free( psz_uri ); return VLC_SUCCESS; }
static int vlclua_node_add_node( lua_State *L ) { services_discovery_t *p_sd = (services_discovery_t *)vlclua_get_this( L ); input_item_t **pp_node = (input_item_t **)luaL_checkudata( L, 1, "node" ); if( *pp_node ) { if( lua_istable( L, -1 ) ) { lua_getfield( L, -1, "title" ); if( lua_isstring( L, -1 ) ) { const char *psz_name = lua_tostring( L, -1 ); input_item_node_t *p_input_node = input_item_node_Create( *pp_node ); input_item_t *p_input = input_item_NewWithType( VLC_OBJECT( p_sd ), "vlc://nop", psz_name, 0, NULL, 0, -1, ITEM_TYPE_NODE ); lua_pop( L, 1 ); if( p_input ) { lua_getfield( L, -1, "arturl" ); if( lua_isstring( L, -1 ) && strcmp( lua_tostring( L, -1 ), "" ) ) { char *psz_value = strdup( lua_tostring( L, -1 ) ); EnsureUTF8( psz_value ); msg_Dbg( p_sd, "ArtURL: %s", psz_value ); input_item_SetArtURL( p_input, psz_value ); free( psz_value ); } input_item_node_AppendItem( p_input_node, p_input ); input_item_node_PostAndDelete( p_input_node ); input_item_t **udata = (input_item_t **) lua_newuserdata( L, sizeof( input_item_t * ) ); *udata = p_input; if( luaL_newmetatable( L, "node" ) ) { lua_newtable( L ); luaL_register( L, NULL, vlclua_node_reg ); lua_setfield( L, -2, "__index" ); } lua_setmetatable( L, -2 ); } } else msg_Err( p_sd, "node:add_node: the \"title\" parameter can't be empty" ); } else msg_Err( p_sd, "Error parsing add_node arguments" ); } return 1; }
void formatSnapshotItem( input_item_t *p_item ) { if( !p_item ) return; char* psz_uri = input_item_GetURI( p_item ); /* copy the snapshot mrl as a ArtURL */ if( psz_uri ) input_item_SetArtURL( p_item, psz_uri ); free( psz_uri ); }
static int vlclua_sd_add_node( lua_State *L ) { services_discovery_t *p_sd = (services_discovery_t *)vlclua_get_this( L ); if( lua_istable( L, -1 ) ) { lua_getfield( L, -1, "title" ); if( lua_isstring( L, -1 ) ) { const char *psz_name = lua_tostring( L, -1 ); input_item_t *p_input = input_item_NewWithType( "vlc://nop", psz_name, 0, NULL, 0, -1, ITEM_TYPE_NODE ); lua_pop( L, 1 ); if( p_input ) { lua_getfield( L, -1, "arturl" ); if( lua_isstring( L, -1 ) && strcmp( lua_tostring( L, -1 ), "" ) ) { char *psz_value = strdup( lua_tostring( L, -1 ) ); EnsureUTF8( psz_value ); msg_Dbg( p_sd, "ArtURL: %s", psz_value ); /** @todo Ask for art download if not local file */ input_item_SetArtURL( p_input, psz_value ); free( psz_value ); } lua_pop( L, 1 ); lua_getfield( L, -1, "category" ); if( lua_isstring( L, -1 ) ) services_discovery_AddItem( p_sd, p_input, luaL_checkstring( L, -1 ) ); else services_discovery_AddItem( p_sd, p_input, NULL ); input_item_t **udata = (input_item_t **) lua_newuserdata( L, sizeof( input_item_t * ) ); *udata = p_input; if( luaL_newmetatable( L, "node" ) ) { lua_newtable( L ); luaL_register( L, NULL, vlclua_node_reg ); lua_setfield( L, -2, "__index" ); } lua_setmetatable( L, -2 ); } } else msg_Err( p_sd, "vlc.sd.add_node: the \"title\" parameter can't be empty" ); } else msg_Err( p_sd, "Error parsing add_node arguments" ); return 1; }
void InputManager::setArt( input_item_t *p_item, QString fileUrl ) { if( hasInput() ) { char *psz_cachedir = config_GetUserDir( VLC_CACHE_DIR ); QString old_url = THEMIM->getIM()->decodeArtURL( p_item ); old_url = QDir( old_url ).canonicalPath(); if( old_url.startsWith( QString::fromUtf8( psz_cachedir ) ) ) QFile( old_url ).remove(); /* Purge cached artwork */ free( psz_cachedir ); input_item_SetArtURL( p_item , fileUrl.toUtf8().constData() ); UpdateArt(); } }
int playlist_FindArtInCache( input_item_t *p_item ) { char *psz_path = ArtCachePath( p_item ); if( !psz_path ) return VLC_EGENERIC; /* Check if file exists */ DIR *p_dir = utf8_opendir( psz_path ); if( !p_dir ) { free( psz_path ); return VLC_EGENERIC; } bool b_found = false; char *psz_filename; while( !b_found && (psz_filename = utf8_readdir( p_dir )) ) { if( !strncmp( psz_filename, "art", 3 ) ) { char *psz_file; if( asprintf( &psz_file, "%s" DIR_SEP "%s", psz_path, psz_filename ) != -1 ) { char *psz_uri = make_URI( psz_file ); if( psz_uri ) { input_item_SetArtURL( p_item, psz_uri ); free( psz_uri ); } free( psz_file ); } b_found = true; } free( psz_filename ); } /* */ closedir( p_dir ); free( psz_path ); return b_found ? VLC_SUCCESS : VLC_EGENERIC; }
static int fetch_art( vlc_object_t *p_this, const char * psz_filename, const luabatch_context_t *p_context ) { lua_State *L = init( p_this, p_context->p_item, psz_filename ); if( !L ) return VLC_EGENERIC; int i_ret = run(p_this, psz_filename, L, "fetch_art", p_context); if(i_ret != VLC_SUCCESS) { lua_close( L ); return i_ret; } if(lua_gettop( L )) { const char * psz_value; if( lua_isstring( L, -1 ) ) { psz_value = lua_tostring( L, -1 ); if( psz_value && *psz_value != 0 ) { lua_Dbg( p_this, "setting arturl: %s", psz_value ); input_item_SetArtURL ( p_context->p_item, psz_value ); lua_close( L ); return VLC_SUCCESS; } } else if( !lua_isnoneornil( L, -1 ) ) { msg_Err( p_this, "Lua art fetcher script %s: " "didn't return a string", psz_filename ); } } else { msg_Err( p_this, "Script went completely foobar" ); } lua_close( L ); return VLC_EGENERIC; }
static int Demux( demux_t *p_demux ) { char *psz_line; char *psz_name = NULL; char *psz_artist = NULL; char *psz_album_art = NULL; int i_parsed_duration = 0; mtime_t i_duration = -1; const char**ppsz_options = NULL; char * (*pf_dup) (const char *) = p_demux->p_sys->pf_dup; int i_options = 0; bool b_cleanup = false; input_item_t *p_input; input_item_t *p_current_input = GetCurrentItem(p_demux); input_item_node_t *p_subitems = input_item_node_Create( p_current_input ); psz_line = vlc_stream_ReadLine( p_demux->s ); while( psz_line ) { char *psz_parse = psz_line; /* Skip leading tabs and spaces */ while( *psz_parse == ' ' || *psz_parse == '\t' || *psz_parse == '\n' || *psz_parse == '\r' ) psz_parse++; if( *psz_parse == '#' ) { /* Parse extra info */ /* Skip leading tabs and spaces */ while( *psz_parse == ' ' || *psz_parse == '\t' || *psz_parse == '\n' || *psz_parse == '\r' || *psz_parse == '#' ) psz_parse++; if( !*psz_parse ) goto error; if( !strncasecmp( psz_parse, "EXTINF:", sizeof("EXTINF:") -1 ) ) { /* Extended info */ psz_parse += sizeof("EXTINF:") - 1; FREENULL( psz_name ); FREENULL( psz_artist ); parseEXTINF( psz_parse, &psz_artist, &psz_name, &i_parsed_duration ); if( i_parsed_duration >= 0 ) i_duration = i_parsed_duration * INT64_C(1000000); if( psz_name ) psz_name = pf_dup( psz_name ); if( psz_artist ) psz_artist = pf_dup( psz_artist ); } else if( !strncasecmp( psz_parse, "EXTVLCOPT:", sizeof("EXTVLCOPT:") -1 ) ) { /* VLC Option */ char *psz_option; psz_parse += sizeof("EXTVLCOPT:") -1; if( !*psz_parse ) goto error; psz_option = pf_dup( psz_parse ); if( psz_option ) INSERT_ELEM( ppsz_options, i_options, i_options, psz_option ); } /* Special case for jamendo which provide the albumart */ else if( !strncasecmp( psz_parse, "EXTALBUMARTURL:", sizeof( "EXTALBUMARTURL:" ) -1 ) ) { psz_parse += sizeof( "EXTALBUMARTURL:" ) - 1; free( psz_album_art ); psz_album_art = pf_dup( psz_parse ); } } else if( !strncasecmp( psz_parse, "RTSPtext", sizeof("RTSPtext") -1 ) ) { ;/* special case to handle QuickTime RTSPtext redirect files */ } else if( *psz_parse ) { char *psz_mrl; psz_parse = pf_dup( psz_parse ); if( !psz_name && psz_parse ) /* Use filename as name for relative entries */ psz_name = strdup( psz_parse ); psz_mrl = ProcessMRL( psz_parse, p_demux->p_sys->psz_prefix ); b_cleanup = true; if( !psz_mrl ) { free( psz_parse ); goto error; } p_input = input_item_NewExt( psz_mrl, psz_name, i_duration, ITEM_TYPE_UNKNOWN, ITEM_NET_UNKNOWN ); free( psz_parse ); free( psz_mrl ); if( !p_input ) goto error; input_item_AddOptions( p_input, i_options, ppsz_options, 0 ); input_item_CopyOptions( p_input, p_current_input ); if( !EMPTY_STR(psz_artist) ) input_item_SetArtist( p_input, psz_artist ); if( psz_name ) input_item_SetTitle( p_input, psz_name ); if( !EMPTY_STR(psz_album_art) ) input_item_SetArtURL( p_input, psz_album_art ); input_item_node_AppendItem( p_subitems, p_input ); vlc_gc_decref( p_input ); } error: /* Fetch another line */ free( psz_line ); psz_line = vlc_stream_ReadLine( p_demux->s ); if( !psz_line ) b_cleanup = true; if( b_cleanup ) { /* Cleanup state */ while( i_options-- ) free( (char*)ppsz_options[i_options] ); FREENULL( ppsz_options ); i_options = 0; FREENULL( psz_name ); FREENULL( psz_artist ); FREENULL( psz_album_art ); i_parsed_duration = 0; i_duration = -1; b_cleanup = false; } } input_item_node_PostAndDelete( p_subitems ); vlc_gc_decref(p_current_input); var_Destroy( p_demux, "m3u-extvlcopt" ); return 0; /* Needed for correct operation of go back */ }
/* "specs" : http://phobos.apple.com/static/iTunesRSS.html */ static int ReadDir( stream_t *p_demux, input_item_node_t *p_subitems ) { bool b_item = false; bool b_image = false; xml_reader_t *p_xml_reader; char *psz_elname = NULL; char *psz_item_mrl = NULL; char *psz_item_size = NULL; char *psz_item_type = NULL; char *psz_item_name = NULL; char *psz_item_date = NULL; char *psz_item_author = NULL; char *psz_item_category = NULL; char *psz_item_duration = NULL; char *psz_item_keywords = NULL; char *psz_item_subtitle = NULL; char *psz_item_summary = NULL; char *psz_art_url = NULL; const char *node; int i_type; input_item_t *p_input; input_item_t *p_current_input = GetCurrentItem(p_demux); p_xml_reader = xml_ReaderCreate( p_demux, p_demux->s ); if( !p_xml_reader ) goto error; /* xml */ /* check root node */ if( xml_ReaderNextNode( p_xml_reader, &node ) != XML_READER_STARTELEM ) { msg_Err( p_demux, "invalid file (no root node)" ); goto error; } if( strcmp( node, "rss" ) ) { msg_Err( p_demux, "invalid root node <%s>", node ); goto error; } while( (i_type = xml_ReaderNextNode( p_xml_reader, &node )) > 0 ) { switch( i_type ) { case XML_READER_STARTELEM: { free( psz_elname ); psz_elname = strdup( node ); if( unlikely(!psz_elname) ) goto error; if( !strcmp( node, "item" ) ) b_item = true; else if( !strcmp( node, "image" ) ) b_image = true; // Read the attributes const char *attr, *value; while( (attr = xml_ReaderNextAttr( p_xml_reader, &value )) ) { if( !strcmp( node, "enclosure" ) ) { char **p = NULL; if( !strcmp( attr, "url" ) ) p = &psz_item_mrl; else if( !strcmp( attr, "length" ) ) p = &psz_item_size; else if( !strcmp( attr, "type" ) ) p = &psz_item_type; if( p != NULL ) { free( *p ); *p = strdup( value ); } else msg_Dbg( p_demux,"unhandled attribute %s in <%s>", attr, node ); } else msg_Dbg( p_demux,"unhandled attribute %s in <%s>", attr, node ); } break; } case XML_READER_TEXT: { if(!psz_elname) break; /* item specific meta data */ if( b_item ) { char **p; if( !strcmp( psz_elname, "title" ) ) p = &psz_item_name; else if( !strcmp( psz_elname, "itunes:author" ) || !strcmp( psz_elname, "author" ) ) /* <author> isn't standard iTunes podcast stuff */ p = &psz_item_author; else if( !strcmp( psz_elname, "itunes:summary" ) || !strcmp( psz_elname, "description" ) ) /* <description> isn't standard iTunes podcast stuff */ p = &psz_item_summary; else if( !strcmp( psz_elname, "pubDate" ) ) p = &psz_item_date; else if( !strcmp( psz_elname, "itunes:category" ) ) p = &psz_item_category; else if( !strcmp( psz_elname, "itunes:duration" ) ) p = &psz_item_duration; else if( !strcmp( psz_elname, "itunes:keywords" ) ) p = &psz_item_keywords; else if( !strcmp( psz_elname, "itunes:subtitle" ) ) p = &psz_item_subtitle; else break; free( *p ); *p = strdup( node ); } /* toplevel meta data */ else if( !b_image ) { if( !strcmp( psz_elname, "title" ) ) input_item_SetName( p_current_input, node ); #define ADD_GINFO( info, name ) \ else if( !strcmp( psz_elname, name ) ) \ input_item_AddInfo( p_current_input, _("Podcast Info"), \ info, "%s", node ); ADD_GINFO( _("Podcast Link"), "link" ) ADD_GINFO( _("Podcast Copyright"), "copyright" ) ADD_GINFO( _("Podcast Category"), "itunes:category" ) ADD_GINFO( _("Podcast Keywords"), "itunes:keywords" ) ADD_GINFO( _("Podcast Subtitle"), "itunes:subtitle" ) #undef ADD_GINFO else if( !strcmp( psz_elname, "itunes:summary" ) || !strcmp( psz_elname, "description" ) ) { /* <description> isn't standard iTunes podcast stuff */ input_item_AddInfo( p_current_input, _( "Podcast Info" ), _( "Podcast Summary" ), "%s", node ); } } else { if( !strcmp( psz_elname, "url" ) && *node ) { free( psz_art_url ); psz_art_url = strdup( node ); } else msg_Dbg( p_demux, "unhandled text in element <%s>", psz_elname ); } break; } // End element case XML_READER_ENDELEM: { FREENULL( psz_elname ); if( !strcmp( node, "item" ) ) { if( psz_item_mrl == NULL ) { if (psz_item_name) msg_Warn( p_demux, "invalid XML item, skipping %s", psz_item_name ); else msg_Warn( p_demux, "invalid XML item, skipped" ); FREENULL( psz_item_name ); FREENULL( psz_item_size ); FREENULL( psz_item_type ); FREENULL( psz_item_date ); FREENULL( psz_item_author ); FREENULL( psz_item_category ); FREENULL( psz_item_duration ); FREENULL( psz_item_keywords ); FREENULL( psz_item_subtitle ); FREENULL( psz_item_summary ); FREENULL( psz_art_url ); FREENULL( psz_elname ); continue; } vlc_xml_decode( psz_item_mrl ); vlc_xml_decode( psz_item_name ); p_input = input_item_New( psz_item_mrl, psz_item_name ); FREENULL( psz_item_mrl ); FREENULL( psz_item_name ); if( p_input == NULL ) break; /* FIXME: meta data memory leaks? */ /* Set the duration if available */ if( psz_item_duration ) p_input->i_duration = strTimeToMTime( psz_item_duration ); #define ADD_INFO( info, field ) \ if( field ) { \ input_item_AddInfo( p_input, _( "Podcast Info" ), (info), "%s", \ (field) ); \ FREENULL( field ); } ADD_INFO( _("Podcast Publication Date"), psz_item_date ); ADD_INFO( _("Podcast Author"), psz_item_author ); ADD_INFO( _("Podcast Subcategory"), psz_item_category ); ADD_INFO( _("Podcast Duration"), psz_item_duration ); ADD_INFO( _("Podcast Keywords"), psz_item_keywords ); ADD_INFO( _("Podcast Subtitle"), psz_item_subtitle ); ADD_INFO( _("Podcast Summary"), psz_item_summary ); ADD_INFO( _("Podcast Type"), psz_item_type ); #undef ADD_INFO /* Add the global art url to this item, if any */ if( psz_art_url ) { vlc_xml_decode( psz_art_url ); input_item_SetArtURL( p_input, psz_art_url ); } if( psz_item_size ) { input_item_AddInfo( p_input, _( "Podcast Info" ), _( "Podcast Size" ), _("%s bytes"), psz_item_size ); FREENULL( psz_item_size ); } input_item_node_AppendItem( p_subitems, p_input ); input_item_Release( p_input ); b_item = false; } else if( !strcmp( node, "image" ) ) { b_image = false; } break; } } }
int playlist_SaveArt( vlc_object_t *obj, input_item_t *p_item, const void *data, size_t length, const char *psz_type ) { char *psz_filename = ArtCacheName( p_item, psz_type ); if( !psz_filename ) return VLC_EGENERIC; char *psz_uri = vlc_path2uri( psz_filename, "file" ); if( !psz_uri ) { free( psz_filename ); return VLC_EGENERIC; } /* Check if we already dumped it */ struct stat s; if( !vlc_stat( psz_filename, &s ) ) { input_item_SetArtURL( p_item, psz_uri ); free( psz_filename ); free( psz_uri ); return VLC_SUCCESS; } /* Dump it otherwise */ FILE *f = vlc_fopen( psz_filename, "wb" ); if( f ) { if( fwrite( data, 1, length, f ) != length ) { msg_Err( obj, "%s: %s", psz_filename, vlc_strerror_c(errno) ); } else { msg_Dbg( obj, "album art saved to %s", psz_filename ); input_item_SetArtURL( p_item, psz_uri ); } fclose( f ); } free( psz_uri ); /* save uid info */ char *uid = input_item_GetInfo( p_item, "uid", "md5" ); if ( ! *uid ) { free( uid ); goto end; } char *psz_byuiddir = GetDirByItemUIDs( uid ); char *psz_byuidfile = GetFileByItemUID( psz_byuiddir, "arturl" ); ArtCacheCreateDir( psz_byuiddir ); free( psz_byuiddir ); if ( psz_byuidfile ) { f = vlc_fopen( psz_byuidfile, "wb" ); if ( f ) { if( fputs( "file://", f ) < 0 || fputs( psz_filename, f ) < 0 ) msg_Err( obj, "Error writing %s: %s", psz_byuidfile, vlc_strerror_c(errno) ); fclose( f ); } free( psz_byuidfile ); } free( uid ); /* !save uid info */ end: free( psz_filename ); return VLC_SUCCESS; }
static int FindMeta( vlc_object_t *p_this ) { art_finder_t *p_finder = (art_finder_t *)p_this; input_item_t *p_item = p_finder->p_item; bool b_have_art = false; struct stat statinfo; char *psz_path = NULL; if( !p_item ) return VLC_EGENERIC; char *psz_uri = input_item_GetURI( p_item ); if( !psz_uri ) return VLC_EGENERIC; if ( *psz_uri && psz_uri[strlen( psz_uri ) - 1] != DIR_SEP_CHAR ) { if ( asprintf( &psz_path, "%s"DIR_SEP, psz_uri ) == -1 ) { free( psz_uri ); return VLC_EGENERIC; } char *psz_basedir = make_path( psz_path ); FREENULL( psz_path ); if( psz_basedir == NULL ) { free( psz_uri ); return VLC_EGENERIC; } if( vlc_stat( psz_basedir, &statinfo ) == 0 && S_ISDIR(statinfo.st_mode) ) psz_path = psz_basedir; else free( psz_basedir ); } if ( psz_path == NULL ) { char *psz_basedir = make_path( psz_uri ); if( psz_basedir == NULL ) { free( psz_uri ); return VLC_EGENERIC; } char *psz_buf = strrchr( psz_basedir, DIR_SEP_CHAR ); if( psz_buf ) *++psz_buf = '\0'; else *psz_basedir = '\0'; /* relative path */ psz_path = psz_basedir; } free( psz_uri ); for( int i = -1; !b_have_art && i < i_covers; i++ ) { const char *filename; char *filebuf, *filepath; if( i == -1 ) /* higher priority : configured filename */ { filebuf = var_InheritString( p_this, "album-art-filename" ); if( filebuf == NULL ) continue; filename = filebuf; } else { filename = cover_files[i]; filebuf = NULL; } if( asprintf( &filepath, "%s%s", psz_path, filename ) == -1 ) filepath = NULL; free( filebuf ); if( unlikely(filepath == NULL) ) continue; if( vlc_stat( filepath, &statinfo ) == 0 && S_ISREG(statinfo.st_mode) ) { char *psz_uri = vlc_path2uri( filepath, "file" ); if( psz_uri ) { input_item_SetArtURL( p_item, psz_uri ); free( psz_uri ); b_have_art = true; } } free( filepath ); } free( psz_path ); return b_have_art ? VLC_SUCCESS : 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 ) { 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" ); /* 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_getglobal( L, "fetch_art" ); 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; } 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; } if((s = lua_gettop( L ))) { const char * psz_value; if( lua_isstring( L, s ) ) { psz_value = lua_tostring( L, s ); if( psz_value && *psz_value != 0 ) { lua_Dbg( p_this, "setting arturl: %s", psz_value ); input_item_SetArtURL ( p_input, psz_value ); i_ret = VLC_SUCCESS; } } else if( !lua_isnil( L, s ) ) { msg_Err( p_this, "Lua art fetcher script %s: " "didn't return a string", psz_filename ); } } else { msg_Err( p_this, "Script went completely foobar" ); } return i_ret; }
static int FindMeta( vlc_object_t *p_this ) { art_finder_t *p_finder = (art_finder_t *)p_this; input_item_t *p_item = p_finder->p_item; bool b_have_art = false; if( !p_item ) return VLC_EGENERIC; char *psz_dir = input_item_GetURI( p_item ); if( !psz_dir ) return VLC_EGENERIC; char *psz_path = make_path( psz_dir ); free( psz_dir ); if( psz_path == NULL ) return VLC_EGENERIC; char *psz_buf = strrchr( psz_path, DIR_SEP_CHAR ); if( psz_buf ) *++psz_buf = '\0'; else *psz_path = '\0'; /* relative path */ for( int i = -1; !b_have_art && i < i_covers; i++ ) { const char *filename; char *filebuf, *filepath; if( i == -1 ) /* higher priority : configured filename */ { filebuf = var_InheritString( p_this, "album-art-filename" ); if( filebuf == NULL ) continue; filename = filebuf; } else { filename = cover_files[i]; filebuf = NULL; } if( asprintf( &filepath, "%s%s", psz_path, filename ) == -1 ) filepath = NULL; free( filebuf ); if( unlikely(filepath != NULL) ) continue; struct stat dummy; if( vlc_stat( filepath, &dummy ) == 0 ) { char *psz_uri = make_URI( filepath, "file" ); if( psz_uri ) { input_item_SetArtURL( p_item, psz_uri ); free( psz_uri ); b_have_art = true; } } free( filepath ); } free( psz_path ); return b_have_art ? VLC_SUCCESS : VLC_EGENERIC; }
int playlist_SaveArt( playlist_t *p_playlist, input_item_t *p_item, const uint8_t *p_buffer, int i_buffer, const char *psz_type ) { char *psz_filename = ArtCacheName( p_item, psz_type ); if( !psz_filename ) return VLC_EGENERIC; char *psz_uri = make_URI( psz_filename, "file" ); if( !psz_uri ) { free( psz_filename ); return VLC_EGENERIC; } /* Check if we already dumped it */ struct stat s; if( !vlc_stat( psz_filename, &s ) ) { input_item_SetArtURL( p_item, psz_uri ); free( psz_filename ); free( psz_uri ); return VLC_SUCCESS; } /* Dump it otherwise */ FILE *f = vlc_fopen( psz_filename, "wb" ); if( f ) { if( fwrite( p_buffer, i_buffer, 1, f ) != 1 ) { msg_Err( p_playlist, "%s: %m", psz_filename ); } else { msg_Dbg( p_playlist, "album art saved to %s", psz_filename ); input_item_SetArtURL( p_item, psz_uri ); } fclose( f ); } free( psz_uri ); /* save uid info */ char *uid = input_item_GetInfo( p_item, "uid", "md5" ); if ( ! *uid ) { free( uid ); goto end; } char *psz_byuiddir = GetDirByItemUIDs( uid ); char *psz_byuidfile = GetFileByItemUID( psz_byuiddir, "arturl" ); ArtCacheCreateDir( psz_byuiddir ); free( psz_byuiddir ); if ( psz_byuidfile ) { f = vlc_fopen( psz_byuidfile, "wb" ); if ( f ) { if( fputs( "file://", f ) < 0 || fputs( psz_filename, f ) < 0 ) msg_Err( p_playlist, "Error writing %s: %m", psz_byuidfile ); fclose( f ); } free( psz_byuidfile ); } free( uid ); /* !save uid info */ end: free( psz_filename ); return VLC_SUCCESS; }