Make iTunes .xml file authoritative for songs outside the mp3_dir, closing #84

This commit is contained in:
Ron Pedde 2006-04-27 06:59:46 +00:00
parent 5ed16bc1ca
commit eba07e1e15
3 changed files with 121 additions and 38 deletions

View File

@ -51,6 +51,7 @@
#include "db-generic.h" #include "db-generic.h"
#include "err.h" #include "err.h"
#include "mp3-scanner.h" #include "mp3-scanner.h"
#include "os.h"
#include "restart.h" #include "restart.h"
#include "ssc.h" #include "ssc.h"
@ -75,7 +76,8 @@ typedef struct {
static int scan_path(char *path); static int scan_path(char *path);
static int scan_get_info(char *file, MP3FILE *pmp3); static int scan_get_info(char *file, MP3FILE *pmp3);
static int scan_freetags(MP3FILE *pmp3); static int scan_freetags(MP3FILE *pmp3);
static void scan_music_file(char *path, struct dirent *pde, struct stat *psb, int is_compdir); static void scan_music_file(char *path, char *fname,struct stat *psb, int is_compdir);
static TAGHANDLER *scan_gethandler(char *type); static TAGHANDLER *scan_gethandler(char *type);
@ -169,6 +171,13 @@ static PLAYLISTLIST scan_playlistlist = { NULL, NULL };
void scan_add_playlistlist(char *path) { void scan_add_playlistlist(char *path) {
PLAYLISTLIST *plist; PLAYLISTLIST *plist;
DPRINTF(E_SPAM,L_SCAN,"Adding playlist %s\n",path);
if(!conf_get_int("general","process_m3u",0)) {
DPRINTF(E_DBG,L_SCAN,"Skipping playlist %s (process_m3u)\n",path);
return;
}
DPRINTF(E_DBG,L_SCAN,"Adding %s for deferred processing.\n",path); DPRINTF(E_DBG,L_SCAN,"Adding %s for deferred processing.\n",path);
plist=(PLAYLISTLIST*)malloc(sizeof(PLAYLISTLIST)); plist=(PLAYLISTLIST*)malloc(sizeof(PLAYLISTLIST));
@ -190,9 +199,12 @@ void scan_process_playlistlist(void) {
PLAYLISTLIST *pnext; PLAYLISTLIST *pnext;
char *ext; char *ext;
DPRINTF(E_DBG,L_SCAN,"Starting playlist loop\n");
while(scan_playlistlist.next) { while(scan_playlistlist.next) {
pnext=scan_playlistlist.next; pnext=scan_playlistlist.next;
DPRINTF(E_DBG,L_SCAN,"About to scan %S\n",pnext->path);
ext=pnext->path; ext=pnext->path;
if(strrchr(pnext->path,'.')) { if(strrchr(pnext->path,'.')) {
ext = strrchr(pnext->path,'.'); ext = strrchr(pnext->path,'.');
@ -200,6 +212,7 @@ void scan_process_playlistlist(void) {
if(strcasecmp(ext,".xml") == 0) { if(strcasecmp(ext,".xml") == 0) {
if(conf_get_int("scanning","process xml",1)) { if(conf_get_int("scanning","process xml",1)) {
DPRINTF(E_LOG,L_SCAN,"Scanning %s\n",pnext->path);
scan_xml_playlist(pnext->path); scan_xml_playlist(pnext->path);
} }
} else if(strcasecmp(ext,".m3u") == 0) { } else if(strcasecmp(ext,".m3u") == 0) {
@ -212,6 +225,7 @@ void scan_process_playlistlist(void) {
scan_playlistlist.next=pnext->next; scan_playlistlist.next=pnext->next;
free(pnext); free(pnext);
} }
DPRINTF(E_DBG,L_SCAN,"Finished playlist loop\n");
} }
/* /*
@ -249,6 +263,7 @@ int scan_init(char **patharray) {
if(db_end_song_scan()) if(db_end_song_scan())
return -1; return -1;
DPRINTF(E_DBG,L_SCAN,"Processing playlists\n");
scan_process_playlistlist(); scan_process_playlistlist();
if(db_end_scan()) if(db_end_scan())
@ -295,9 +310,7 @@ int scan_path(char *path) {
char relative_path[PATH_MAX]; char relative_path[PATH_MAX];
char mp3_path[PATH_MAX]; char mp3_path[PATH_MAX];
struct stat sb; struct stat sb;
int modified_time; char *extensions;
char *ext,*extensions;
MP3FILE *pmp3;
int is_compdir; int is_compdir;
extensions = conf_alloc_string("general","extensions",".mp3,.m4a,.m4p"); extensions = conf_alloc_string("general","extensions",".mp3,.m4a,.m4p");
@ -347,29 +360,7 @@ int scan_path(char *path) {
DPRINTF(E_DBG,L_SCAN,"Found dir %s... recursing\n",pde->d_name); DPRINTF(E_DBG,L_SCAN,"Found dir %s... recursing\n",pde->d_name);
scan_path(mp3_path); scan_path(mp3_path);
} else { } else {
/* process the file */ scan_filename(mp3_path, is_compdir, extensions);
if(strlen(pde->d_name) > 4) {
if((strcasecmp(".m3u",(char*)&pde->d_name[strlen(pde->d_name) - 4]) == 0) &&
conf_get_int("general","process_m3u",0)){
/* we found an m3u file */
scan_add_playlistlist(mp3_path);
} else if((strcasecmp(".xml",(char*)&pde->d_name[strlen(pde->d_name) - 4]) == 0)) {
scan_add_playlistlist(mp3_path);
} else if (((ext = strrchr(pde->d_name, '.')) != NULL) &&
(strcasestr(extensions, ext))) {
/* only scan if it's been changed, or empty db */
modified_time=(int) sb.st_mtime;
pmp3=db_fetch_path(NULL,mp3_path,0);
if((!pmp3) || (pmp3->db_timestamp < modified_time) ||
(pmp3->force_update)) {
scan_music_file(path,pde,&sb,is_compdir);
} else {
DPRINTF(E_DBG,L_SCAN,"Skipping file... not modified\n");
}
db_dispose_item(pmp3);
}
}
} }
} }
} }
@ -489,32 +480,96 @@ int scan_static_playlist(char *path) {
} }
/**
* here, we want to scan a file and add it (if necessary)
* to the database.
*
* @param path path of file to scan
* @param compdir whether or not this is a compdir:
* should be SCAN_TEST_COMPDIR if called form outisde
* mp3-scanner.c
*/
void scan_filename(char *path, int compdir, char *extensions) {
int is_compdir=compdir;
char mp3_path[PATH_MAX];
struct stat sb;
char *fname;
char *ext;
char *all_ext = extensions;
int mod_time;
MP3FILE *pmp3;
if(compdir == 2) {
/* need to really figure it out */
is_compdir = scan_is_compdir(path);
}
if(!all_ext) {
all_ext = conf_alloc_string("general","extensions",".mp3,.m4a,.m4p");
}
realpath(path,mp3_path);
fname = strrchr(mp3_path,PATHSEP);
if(!fname) {
fname = mp3_path;
} else {
fname++;
}
if(stat(mp3_path,&sb)) {
DPRINTF(E_WARN,L_SCAN,"Error statting: %s\n",strerror(errno));
} else {
/* we assume this is regular file */
if(strlen(fname) > 4) {
ext = strrchr(fname, '.');
if(ext) {
if(strcasecmp(".m3u",ext) == 0) {
scan_add_playlistlist(mp3_path);
} else if(strcasecmp(".xml",ext) == 0) {
scan_add_playlistlist(mp3_path);
} else if(strcasestr(all_ext, ext)) {
mod_time = (int)sb.st_mtime;
pmp3 = db_fetch_path(NULL,mp3_path,0);
if((!pmp3) || (pmp3->db_timestamp < mod_time) ||
(pmp3->force_update)) {
scan_music_file(path,fname,&sb,is_compdir);
} else {
DPRINTF(E_DBG,L_SCAN,"Skipping file, not modified\n");
}
db_dispose_item(pmp3);
}
}
}
}
if((all_ext) && (!extensions)) free(all_ext);
return;
}
/* /*
* scan_music_file * scan_music_file
* *
* scan a particular file as a music file * scan a particular file as a music file
*/ */
void scan_music_file(char *path, struct dirent *pde, void scan_music_file(char *path, char *fname,
struct stat *psb, int is_compdir) { struct stat *psb, int is_compdir) {
MP3FILE mp3file; MP3FILE mp3file;
char tmp_path[PATH_MAX];
char mp3_path[PATH_MAX];
char *current=NULL; char *current=NULL;
char *type; char *type;
TAGHANDLER *ptaghandler; TAGHANDLER *ptaghandler;
char fdescr[50]; char fdescr[50];
snprintf(tmp_path,sizeof(mp3_path),"%s/%s",path,pde->d_name);
realpath(tmp_path,mp3_path);
/* we found an mp3 file */ /* we found an mp3 file */
DPRINTF(E_INF,L_SCAN,"Found music file: %s\n",pde->d_name); DPRINTF(E_INF,L_SCAN,"Found music file: %s\n",fname);
memset((void*)&mp3file,0,sizeof(mp3file)); memset((void*)&mp3file,0,sizeof(mp3file));
mp3file.path=strdup(mp3_path); mp3file.path=strdup(path);
mp3file.fname=strdup(pde->d_name); mp3file.fname=strdup(fname);
if(strlen(pde->d_name) > 4) {
type = strrchr(pde->d_name, '.') + 1; if((fname) && (strlen(fname) > 1) && (fname[strlen(fname)-1] != '.')) {
type = strrchr(fname, '.') + 1;
if(type) { if(type) {
/* see if there is "official" format and info for it */ /* see if there is "official" format and info for it */
ptaghandler=scan_gethandler(type); ptaghandler=scan_gethandler(type);

View File

@ -150,8 +150,14 @@ typedef struct tag_packed_mp3file {
#define PL_STATICFILE 2 #define PL_STATICFILE 2
#define PL_STATICXML 3 #define PL_STATICXML 3
#define SCAN_NOT_COMPDIR 0
#define SCAN_IS_COMPDIR 1
#define SCAN_TEST_COMPDIR 2
#define WINAMP_GENRE_UNKNOWN 148 #define WINAMP_GENRE_UNKNOWN 148
extern void scan_filename(char *path, int compdir, char *extensions);
extern char *scan_winamp_genre[]; extern char *scan_winamp_genre[];
extern int scan_init(char **patharray); extern int scan_init(char **patharray);
extern void make_composite_tags(MP3FILE *song); extern void make_composite_tags(MP3FILE *song);

View File

@ -185,6 +185,23 @@ int scan_xml_translate_path(char *pold, char *pnew) {
if((!pold)||(!strlen(pold))) if((!pold)||(!strlen(pold)))
return FALSE; return FALSE;
/* see if it's a valid out-of-root path */
if(strncmp(pold,"file://localhost/",17)==0) {
/* it's a local path.. is it a valid one? */
if(pold[18] == ':') {
/* windows */
realpath((char*)&pold[17],working_path);
} else {
realpath((char*)&pold[16],working_path);
}
if(scan_xml_is_file(working_path)) {
strcpy(pnew,working_path);
return TRUE;
}
/* not a real file... go ahead and brute force it */
}
if(!path_found) { if(!path_found) {
strcpy(working_path,pold); strcpy(working_path,pold);
@ -647,6 +664,11 @@ int scan_xml_tracks_section(int action, char *info) {
if(scan_xml_translate_path(song_path,real_path)) { if(scan_xml_translate_path(song_path,real_path)) {
/* FIXME: Error handling */ /* FIXME: Error handling */
pmp3=db_fetch_path(NULL,real_path,0); pmp3=db_fetch_path(NULL,real_path,0);
if(!pmp3) {
/* file doesn't exist... let's add it? */
scan_filename(real_path,SCAN_TEST_COMPDIR,NULL);
pmp3=db_fetch_path(NULL,real_path,0);
}
if(pmp3) { if(pmp3) {
/* Update the existing record with the /* Update the existing record with the
* updated stuff we got from the iTunes xml file * updated stuff we got from the iTunes xml file