X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fplaylist%2Fart.c;h=315fd4e62b19ca5ed6678b132f25b52b6f101b65;hb=0ab429bb1ac49fa95dd460b3d7bef9545b246982;hp=8d6b0d8b34b9dc7c519276f7ba9cd5dcf31d48c7;hpb=0021e6aae975b09163afdc52ad1740649a8265a6;p=vlc diff --git a/src/playlist/art.c b/src/playlist/art.c index 8d6b0d8b34..315fd4e62b 100644 --- a/src/playlist/art.c +++ b/src/playlist/art.c @@ -29,9 +29,13 @@ #include #include #include -#include +#include #include #include +#include +#include + +#include /* PATH_MAX */ #ifdef HAVE_SYS_STAT_H # include @@ -53,90 +57,79 @@ static void ArtCacheCreateDir( const char *psz_dir ) if( !*psz ) break; *psz = 0; if( !EMPTY_STR( psz_newdir ) ) - utf8_mkdir( psz_newdir, 0700 ); + vlc_mkdir( psz_newdir, 0700 ); *psz = DIR_SEP_CHAR; psz++; } - utf8_mkdir( psz_dir, 0700 ); + vlc_mkdir( psz_dir, 0700 ); } -static char *ArtCacheGetSanitizedFileName( const char *psz ) +static char* ArtCacheGetDirPath( const char *psz_arturl, const char *psz_artist, + const char *psz_album ) { - char *dup = strdup(psz); - int i; - - filename_sanitize( dup ); - - /* Doesn't create a filename with invalid characters - * TODO: several filesystems forbid several characters: list them all - */ - for( i = 0; dup[i] != '\0'; i++ ) - { - if( dup[i] == DIR_SEP_CHAR ) - dup[i] = ' '; - } - return dup; -} - -static void ArtCacheGetDirPath( char *psz_dir, - const char *psz_title, - const char *psz_artist, const char *psz_album ) -{ - char *psz_cachedir = config_GetCacheDir(); + char *psz_dir; + char *psz_cachedir = config_GetUserDir(VLC_CACHE_DIR); if( !EMPTY_STR(psz_artist) && !EMPTY_STR(psz_album) ) { - char * psz_album_sanitized = ArtCacheGetSanitizedFileName( psz_album ); - char * psz_artist_sanitized = ArtCacheGetSanitizedFileName( psz_artist ); - snprintf( psz_dir, PATH_MAX, "%s" DIR_SEP - "art" DIR_SEP "artistalbum" DIR_SEP "%s" DIR_SEP "%s", - psz_cachedir, psz_artist_sanitized, psz_album_sanitized ); + char *psz_album_sanitized = strdup( psz_album ); + filename_sanitize( psz_album_sanitized ); + char *psz_artist_sanitized = strdup( psz_artist ); + filename_sanitize( psz_artist_sanitized ); + if( asprintf( &psz_dir, "%s" DIR_SEP "art" DIR_SEP "artistalbum" + DIR_SEP "%s" DIR_SEP "%s", psz_cachedir, + psz_artist_sanitized, psz_album_sanitized ) == -1 ) + psz_dir = NULL; free( psz_album_sanitized ); free( psz_artist_sanitized ); } else { - char * psz_title_sanitized = ArtCacheGetSanitizedFileName( psz_title ); - snprintf( psz_dir, PATH_MAX, "%s" DIR_SEP - "art" DIR_SEP "title" DIR_SEP "%s", - psz_cachedir, psz_title_sanitized ); - free( psz_title_sanitized ); + /* If artist or album missing cache by art download URL. The download + URL will be md5 hashed to form a valid cache filename. We assume that + psz_arturl is always the download URL and not the already hashed filename. + (We should never need to call this function if art has already been + downloaded anyway). */ + struct md5_s md5; + InitMD5( &md5 ); + AddMD5( &md5, psz_arturl, strlen( psz_arturl ) ); + EndMD5( &md5 ); + char * psz_arturl_sanitized = psz_md5_hash( &md5 ); + if( asprintf( &psz_dir, "%s" DIR_SEP "art" DIR_SEP "arturl" DIR_SEP + "%s", psz_cachedir, psz_arturl_sanitized ) == -1 ) + psz_dir = NULL; + free( psz_arturl_sanitized ); } free( psz_cachedir ); + return psz_dir; } static char *ArtCachePath( input_item_t *p_item ) { - char psz_path[PATH_MAX+1]; /* FIXME */ + char* psz_path = NULL; + const char *psz_artist; + const char *psz_album; + const char *psz_arturl; vlc_mutex_lock( &p_item->lock ); if( !p_item->p_meta ) p_item->p_meta = vlc_meta_New(); if( !p_item->p_meta ) - { - vlc_mutex_unlock( &p_item->lock ); - return NULL; - } + goto end; - const char *psz_artist = vlc_meta_Get( p_item->p_meta, vlc_meta_Artist ); - const char *psz_album = vlc_meta_Get( p_item->p_meta, vlc_meta_Album ); - const char *psz_title = vlc_meta_Get( p_item->p_meta, vlc_meta_Title ); + psz_artist = vlc_meta_Get( p_item->p_meta, vlc_meta_Artist ); + psz_album = vlc_meta_Get( p_item->p_meta, vlc_meta_Album ); + psz_arturl = vlc_meta_Get( p_item->p_meta, vlc_meta_ArtworkURL ); - if( !psz_title ) - psz_title = p_item->psz_name; + if( (!psz_artist || !psz_album ) && !psz_arturl ) + goto end; - if( (!psz_artist || !psz_album ) && !psz_title ) - { - vlc_mutex_unlock( &p_item->lock ); - return NULL; - } - - ArtCacheGetDirPath( psz_path, psz_title, psz_artist, psz_album ); + psz_path = ArtCacheGetDirPath( psz_arturl, psz_artist, psz_album ); +end: vlc_mutex_unlock( &p_item->lock ); - - return strdup( psz_path ); + return psz_path; } static char *ArtCacheName( input_item_t *p_item, const char *psz_type ) @@ -149,9 +142,8 @@ static char *ArtCacheName( input_item_t *p_item, const char *psz_type ) char *psz_ext = strdup( psz_type ? psz_type : "" ); filename_sanitize( psz_ext ); - char *psz_filename; - if( asprintf( &psz_filename, "file://%s" DIR_SEP "art%s", psz_path, psz_ext ) < 0 ) + if( asprintf( &psz_filename, "%s" DIR_SEP "art%s", psz_path, psz_ext ) < 0 ) psz_filename = NULL; free( psz_ext ); @@ -160,6 +152,7 @@ static char *ArtCacheName( input_item_t *p_item, const char *psz_type ) return psz_filename; } +/* */ int playlist_FindArtInCache( input_item_t *p_item ) { char *psz_path = ArtCachePath( p_item ); @@ -168,7 +161,7 @@ int playlist_FindArtInCache( input_item_t *p_item ) return VLC_EGENERIC; /* Check if file exists */ - DIR *p_dir = utf8_opendir( psz_path ); + DIR *p_dir = vlc_opendir( psz_path ); if( !p_dir ) { free( psz_path ); @@ -177,17 +170,22 @@ int playlist_FindArtInCache( input_item_t *p_item ) bool b_found = false; char *psz_filename; - while( !b_found && (psz_filename = utf8_readdir( p_dir )) ) + while( !b_found && (psz_filename = vlc_readdir( p_dir )) ) { if( !strncmp( psz_filename, "art", 3 ) ) { char *psz_file; - if( asprintf( &psz_file, "file://%s" DIR_SEP "%s", - psz_path, psz_filename ) < 0 ) - psz_file = NULL; - if( psz_file ) - input_item_SetArtURL( p_item, psz_file ); - free( 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; } @@ -200,71 +198,6 @@ int playlist_FindArtInCache( input_item_t *p_item ) return b_found ? VLC_SUCCESS : VLC_EGENERIC; } -/** - * Download the art using the URL or an art downloaded - * This function should be called only if data is not already in cache - */ -int playlist_DownloadArt( playlist_t *p_playlist, input_item_t *p_item ) -{ - char *psz_arturl = input_item_GetArtURL( p_item ); - assert( *psz_arturl ); - - if( !strncmp( psz_arturl , "file://", 7 ) ) - { - msg_Dbg( p_playlist, "Album art is local file, no need to cache" ); - free( psz_arturl ); - return VLC_SUCCESS; - } - - if( !strncmp( psz_arturl , "APIC", 4 ) ) - { - msg_Warn( p_playlist, "APIC fetch not supported yet" ); - goto error; - } - - stream_t *p_stream = stream_UrlNew( p_playlist, psz_arturl ); - if( !p_stream ) - goto error; - - uint8_t *p_data = NULL; - int i_data = 0; - for( ;; ) - { - int i_read = 65536; - - if( i_data + i_read <= i_data ) /* Protect gainst overflow */ - break; - - p_data = realloc( p_data, i_data + i_read ); - if( !p_data ) - break; - - i_read = stream_Read( p_stream, &p_data[i_data], i_read ); - if( i_read <= 0 ) - break; - - i_data += i_read; - } - stream_Delete( p_stream ); - - if( p_data && i_data > 0 ) - { - char *psz_type = strrchr( psz_arturl, '.' ); - if( psz_type && strlen( psz_type ) > 5 ) - psz_type = NULL; /* remove extension if it's > to 4 characters */ - - playlist_SaveArt( p_playlist, p_item, p_data, i_data, psz_type ); - } - - free( p_data ); - - free( psz_arturl ); - return VLC_SUCCESS; - -error: - free( psz_arturl ); - return VLC_EGENERIC; -} /* */ int playlist_SaveArt( playlist_t *p_playlist, input_item_t *p_item, @@ -275,16 +208,25 @@ int playlist_SaveArt( playlist_t *p_playlist, input_item_t *p_item, 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+7, &s ) ) + if( !vlc_stat( psz_filename, &s ) ) { - input_item_SetArtURL( p_item, psz_filename ); + 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+7, "w" ); + FILE *f = vlc_fopen( psz_filename, "wb" ); if( f ) { if( fwrite( p_buffer, i_buffer, 1, f ) != 1 ) @@ -293,11 +235,13 @@ int playlist_SaveArt( playlist_t *p_playlist, input_item_t *p_item, } else { - msg_Dbg( p_playlist, "album art saved to %s\n", psz_filename ); - input_item_SetArtURL( p_item, psz_filename ); + 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; }