mirror of
https://github.com/owntone/owntone-server.git
synced 2025-01-27 06:33:21 -05:00
Fix aeSP icon problem, finish first pass at static playlists
This commit is contained in:
parent
104957bf2f
commit
7b3333df19
@ -354,7 +354,7 @@ int db_sqlite_add_playlist(char *name, int type, char *clause, char *path, int *
|
|||||||
case 2: /* static, from file */
|
case 2: /* static, from file */
|
||||||
result = db_sqlite_exec(E_LOG,"insert into playlists "
|
result = db_sqlite_exec(E_LOG,"insert into playlists "
|
||||||
"(title,type,items,query,db_timestamp,path) "
|
"(title,type,items,query,db_timestamp,path) "
|
||||||
"values ('%q',0,0,NULL,%d)",name,time(NULL),path);
|
"values ('%q',0,0,NULL,%d,'%q')",name,time(NULL),path);
|
||||||
break;
|
break;
|
||||||
case 1: /* smart */
|
case 1: /* smart */
|
||||||
result=db_sqlite_get_int(E_DBG,&cnt,"select count (*) from songs where %s",clause);
|
result=db_sqlite_get_int(E_DBG,&cnt,"select count (*) from songs where %s",clause);
|
||||||
@ -929,8 +929,10 @@ int db_sqlite_get_size(DBQUERYINFO *pinfo, char **valarray) {
|
|||||||
size += 12; /* mimc - you get it whether you want it or not */
|
size += 12; /* mimc - you get it whether you want it or not */
|
||||||
if(db_wantsmeta(pinfo->meta, metaItemId))
|
if(db_wantsmeta(pinfo->meta, metaItemId))
|
||||||
size += 12; /* miid */
|
size += 12; /* miid */
|
||||||
if(db_wantsmeta(pinfo->meta, metaItunesSmartPlaylist))
|
if(db_wantsmeta(pinfo->meta, metaItunesSmartPlaylist)) {
|
||||||
|
if(valarray[plType] && (atoi(valarray[plType])==1))
|
||||||
size += 9; /* aeSP */
|
size += 9; /* aeSP */
|
||||||
|
}
|
||||||
if(db_wantsmeta(pinfo->meta, metaItemName))
|
if(db_wantsmeta(pinfo->meta, metaItemName))
|
||||||
size += (8 + strlen(valarray[plTitle])); /* minm */
|
size += (8 + strlen(valarray[plTitle])); /* minm */
|
||||||
if(valarray[plType] && (atoi(valarray[plType])==1) &&
|
if(valarray[plType] && (atoi(valarray[plType])==1) &&
|
||||||
@ -1079,7 +1081,6 @@ int db_sqlite_build_dmap(DBQUERYINFO *pinfo, char **valarray, char *presult, int
|
|||||||
unsigned char *current = presult;
|
unsigned char *current = presult;
|
||||||
int transcode;
|
int transcode;
|
||||||
int samplerate=0;
|
int samplerate=0;
|
||||||
int smart;
|
|
||||||
|
|
||||||
switch(pinfo->query_type) {
|
switch(pinfo->query_type) {
|
||||||
case queryTypeBrowseArtists: /* simple 'mlit' entry */
|
case queryTypeBrowseArtists: /* simple 'mlit' entry */
|
||||||
@ -1094,10 +1095,8 @@ int db_sqlite_build_dmap(DBQUERYINFO *pinfo, char **valarray, char *presult, int
|
|||||||
current += db_dmap_add_int(current,"miid",atoi(valarray[plID]));
|
current += db_dmap_add_int(current,"miid",atoi(valarray[plID]));
|
||||||
current += db_dmap_add_int(current,"mimc",atoi(valarray[plItems]));
|
current += db_dmap_add_int(current,"mimc",atoi(valarray[plItems]));
|
||||||
if(db_wantsmeta(pinfo->meta,metaItunesSmartPlaylist)) {
|
if(db_wantsmeta(pinfo->meta,metaItunesSmartPlaylist)) {
|
||||||
smart=0;
|
if(valarray[plType] && (atoi(valarray[plType]) == 1))
|
||||||
if(atoi(valarray[plType]) == 1)
|
current += db_dmap_add_char(current,"aeSP",1);
|
||||||
smart=1;
|
|
||||||
current += db_dmap_add_char(current,"aeSP",smart);
|
|
||||||
}
|
}
|
||||||
if(db_wantsmeta(pinfo->meta,metaItemName))
|
if(db_wantsmeta(pinfo->meta,metaItemName))
|
||||||
current += db_dmap_add_string(current,"minm",valarray[plTitle]);
|
current += db_dmap_add_string(current,"minm",valarray[plTitle]);
|
||||||
|
@ -295,7 +295,7 @@ static int scan_get_wavfileinfo(char *file, MP3FILE *pmp3);
|
|||||||
static int scan_get_urlfileinfo(char *file, MP3FILE *pmp3);
|
static int scan_get_urlfileinfo(char *file, MP3FILE *pmp3);
|
||||||
|
|
||||||
static int scan_freetags(MP3FILE *pmp3);
|
static int scan_freetags(MP3FILE *pmp3);
|
||||||
static void scan_static_playlist(char *path, struct dirent *pde, struct stat *psb);
|
static void scan_static_playlist(char *path);
|
||||||
static void scan_music_file(char *path, struct dirent *pde, struct stat *psb);
|
static void scan_music_file(char *path, struct dirent *pde, struct stat *psb);
|
||||||
|
|
||||||
static int scan_decode_mp3_frame(unsigned char *frame, SCAN_FRAMEINFO *pfi);
|
static int scan_decode_mp3_frame(unsigned char *frame, SCAN_FRAMEINFO *pfi);
|
||||||
@ -355,6 +355,56 @@ static TAGHANDLER taghandlers[] = {
|
|||||||
{ NULL, NULL, NULL, NULL, NULL, NULL }
|
{ NULL, NULL, NULL, NULL, NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct tag_playlistlist {
|
||||||
|
char *path;
|
||||||
|
struct tag_playlistlist *next;
|
||||||
|
} PLAYLISTLIST;
|
||||||
|
|
||||||
|
static PLAYLISTLIST scan_playlistlist = { NULL, NULL };
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* add a playlist to the playlistlist. The playlistlist is a
|
||||||
|
* list of playlists that need to be processed once the current
|
||||||
|
* scan is done. THIS IS NOT REENTRANT, and it meant to be
|
||||||
|
* called only inside the rescan loop.
|
||||||
|
*
|
||||||
|
* \param path path of the playlist to add
|
||||||
|
*/
|
||||||
|
void scan_add_playlistlist(char *path) {
|
||||||
|
PLAYLISTLIST *plist;
|
||||||
|
|
||||||
|
DPRINTF(E_DBG,L_SCAN,"Adding %s for deferred processing.\n",path);
|
||||||
|
|
||||||
|
plist=(PLAYLISTLIST*)malloc(sizeof(PLAYLISTLIST));
|
||||||
|
if(!plist) {
|
||||||
|
DPRINTF(E_FATAL,L_SCAN,"Malloc error\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
plist->path=strdup(path);
|
||||||
|
plist->next=scan_playlistlist.next;
|
||||||
|
scan_playlistlist.next=plist;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* process the playlistlist
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void scan_process_playlistlist(void) {
|
||||||
|
PLAYLISTLIST *pnext;
|
||||||
|
|
||||||
|
while(scan_playlistlist.next) {
|
||||||
|
pnext=scan_playlistlist.next;
|
||||||
|
scan_static_playlist(pnext->path);
|
||||||
|
free(pnext->path);
|
||||||
|
scan_playlistlist.next=pnext->next;
|
||||||
|
free(pnext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert mac time to unix time (different epochs)
|
* Convert mac time to unix time (different epochs)
|
||||||
*
|
*
|
||||||
@ -391,7 +441,9 @@ int scan_init(char *path) {
|
|||||||
|
|
||||||
DPRINTF(E_DBG,L_SCAN,"Scanning for MP3s in %s\n",path);
|
DPRINTF(E_DBG,L_SCAN,"Scanning for MP3s in %s\n",path);
|
||||||
|
|
||||||
|
scan_playlistlist.next=NULL;
|
||||||
err=scan_path(path);
|
err=scan_path(path);
|
||||||
|
scan_process_playlistlist();
|
||||||
|
|
||||||
if(db_end_scan())
|
if(db_end_scan())
|
||||||
return -1;
|
return -1;
|
||||||
@ -409,6 +461,7 @@ int scan_path(char *path) {
|
|||||||
char de[sizeof(struct dirent) + MAXNAMLEN + 1]; /* overcommit for solaris */
|
char de[sizeof(struct dirent) + MAXNAMLEN + 1]; /* overcommit for solaris */
|
||||||
struct dirent *pde;
|
struct dirent *pde;
|
||||||
int err;
|
int err;
|
||||||
|
char relative_path[PATH_MAX];
|
||||||
char mp3_path[PATH_MAX];
|
char mp3_path[PATH_MAX];
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
int modified_time;
|
int modified_time;
|
||||||
@ -444,8 +497,10 @@ int scan_path(char *path) {
|
|||||||
if(pde->d_name[0] == '.') /* skip hidden and directories */
|
if(pde->d_name[0] == '.') /* skip hidden and directories */
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
snprintf(mp3_path,PATH_MAX,"%s/%s",path,pde->d_name);
|
snprintf(relative_path,PATH_MAX,"%s/%s",path,pde->d_name);
|
||||||
DPRINTF(E_DBG,L_SCAN,"Found %s\n",mp3_path);
|
mp3_path[0] = '\x0';
|
||||||
|
realpath(relative_path,mp3_path);
|
||||||
|
DPRINTF(E_DBG,L_SCAN,"Found %s\n",relative_path);
|
||||||
if(stat(mp3_path,&sb)) {
|
if(stat(mp3_path,&sb)) {
|
||||||
DPRINTF(E_WARN,L_SCAN,"Error statting: %s\n",strerror(errno));
|
DPRINTF(E_WARN,L_SCAN,"Error statting: %s\n",strerror(errno));
|
||||||
} else {
|
} else {
|
||||||
@ -458,9 +513,7 @@ int scan_path(char *path) {
|
|||||||
if((strcasecmp(".m3u",(char*)&pde->d_name[strlen(pde->d_name) - 4]) == 0) &&
|
if((strcasecmp(".m3u",(char*)&pde->d_name[strlen(pde->d_name) - 4]) == 0) &&
|
||||||
config.process_m3u){
|
config.process_m3u){
|
||||||
/* we found an m3u file */
|
/* we found an m3u file */
|
||||||
DPRINTF(E_LOG,L_SCAN,"Oops... no playlists.. Sorry: %s\n",
|
scan_add_playlistlist(mp3_path);
|
||||||
mp3_path);
|
|
||||||
// scan_static_playlist(path, pde, &sb);
|
|
||||||
} else if (((ext = strrchr(pde->d_name, '.')) != NULL) &&
|
} else if (((ext = strrchr(pde->d_name, '.')) != NULL) &&
|
||||||
(strcasestr(config.extensions, ext))) {
|
(strcasestr(config.extensions, ext))) {
|
||||||
/* only scan if it's been changed, or empty db */
|
/* only scan if it's been changed, or empty db */
|
||||||
@ -490,38 +543,59 @@ int scan_path(char *path) {
|
|||||||
* Scan a file as a static playlist
|
* Scan a file as a static playlist
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void scan_static_playlist(char *path, struct dirent *pde, struct stat *psb) {
|
void scan_static_playlist(char *path) {
|
||||||
char playlist_path[PATH_MAX];
|
char base_path[PATH_MAX];
|
||||||
char m3u_path[PATH_MAX];
|
char file_path[PATH_MAX];
|
||||||
|
char real_path[PATH_MAX];
|
||||||
char linebuffer[PATH_MAX];
|
char linebuffer[PATH_MAX];
|
||||||
int fd;
|
int fd;
|
||||||
int playlistid;
|
int playlistid;
|
||||||
M3UFILE *pm3u;
|
M3UFILE *pm3u;
|
||||||
MP3FILE *pmp3;
|
MP3FILE *pmp3;
|
||||||
|
struct stat sb;
|
||||||
|
char *current;
|
||||||
|
|
||||||
DPRINTF(E_WARN,L_SCAN|L_PL,"Processing static playlist: %s\n",pde->d_name);
|
DPRINTF(E_WARN,L_SCAN|L_PL,"Processing static playlist: %s\n",path);
|
||||||
snprintf(playlist_path,sizeof(playlist_path),"%s/%s",path,pde->d_name);
|
if(stat(path,&sb)) {
|
||||||
|
DPRINTF(E_WARN,L_SCAN,"Error statting %s: %s\n",path,strerror(errno));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
pm3u = db_fetch_playlist(playlist_path,0);
|
if((current=strrchr(path,'/')) == NULL) {
|
||||||
if(pm3u && (pm3u->db_timestamp > psb->st_mtime)) {
|
current = path;
|
||||||
|
} else {
|
||||||
|
current++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* temporarily use base_path for m3u name */
|
||||||
|
strcpy(base_path,current);
|
||||||
|
if((current=strrchr(base_path,'.'))) {
|
||||||
|
*current='\x0';
|
||||||
|
}
|
||||||
|
|
||||||
|
pm3u = db_fetch_playlist(path,0);
|
||||||
|
if(pm3u && (pm3u->db_timestamp > sb.st_mtime)) {
|
||||||
/* already up-to-date */
|
/* already up-to-date */
|
||||||
db_dispose_playlist(pm3u);
|
db_dispose_playlist(pm3u);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
strcpy(m3u_path,pde->d_name);
|
|
||||||
m3u_path[strlen(pde->d_name) - 4] = '\0';
|
|
||||||
|
|
||||||
if(pm3u)
|
if(pm3u)
|
||||||
db_delete_playlist(pm3u->id);
|
db_delete_playlist(pm3u->id);
|
||||||
|
|
||||||
fd=open(playlist_path,O_RDONLY);
|
fd=open(path,O_RDONLY);
|
||||||
if(fd != -1) {
|
if(fd != -1) {
|
||||||
if(db_add_playlist(m3u_path,2,NULL,playlist_path,&playlistid) != DB_E_SUCCESS) {
|
if(db_add_playlist(base_path,2,NULL,path,&playlistid) != DB_E_SUCCESS) {
|
||||||
DPRINTF(E_LOG,L_SCAN,"Error adding m3u playlist %s\n",playlist_path);
|
DPRINTF(E_LOG,L_SCAN,"Error adding m3u playlist %s\n",path);
|
||||||
db_dispose_playlist(pm3u);
|
db_dispose_playlist(pm3u);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
/* now get the *real* base_path */
|
||||||
|
strcpy(base_path,path);
|
||||||
|
if((current=strrchr(base_path,'/'))) {
|
||||||
|
*(current+1) = '\x0';
|
||||||
|
} /* else something is fubar */
|
||||||
|
|
||||||
DPRINTF(E_INF,L_SCAN|L_PL,"Added playlist as id %d\n",playlistid);
|
DPRINTF(E_INF,L_SCAN|L_PL,"Added playlist as id %d\n",playlistid);
|
||||||
|
|
||||||
memset(linebuffer,0x00,sizeof(linebuffer));
|
memset(linebuffer,0x00,sizeof(linebuffer));
|
||||||
@ -537,20 +611,21 @@ void scan_static_playlist(char *path, struct dirent *pde, struct stat *psb) {
|
|||||||
|
|
||||||
// otherwise, assume it is a path
|
// otherwise, assume it is a path
|
||||||
if(linebuffer[0] == '/') {
|
if(linebuffer[0] == '/') {
|
||||||
strcpy(m3u_path,linebuffer);
|
strcpy(file_path,linebuffer);
|
||||||
} else {
|
} else {
|
||||||
snprintf(m3u_path,sizeof(m3u_path),"%s/%s",path,linebuffer);
|
snprintf(file_path,sizeof(file_path),"%s%s",base_path,linebuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINTF(E_DBG,L_SCAN|L_PL,"Checking %s\n",m3u_path);
|
realpath(file_path,real_path);
|
||||||
|
DPRINTF(E_DBG,L_SCAN|L_PL,"Checking %s\n",real_path);
|
||||||
|
|
||||||
// might be valid, might not...
|
// might be valid, might not...
|
||||||
if((pmp3=db_fetch_path(m3u_path))) {
|
if((pmp3=db_fetch_path(real_path))) {
|
||||||
db_add_playlist_item(playlistid,pmp3->id);
|
db_add_playlist_item(playlistid,pmp3->id);
|
||||||
db_dispose_item(pmp3);
|
db_dispose_item(pmp3);
|
||||||
} else {
|
} else {
|
||||||
DPRINTF(E_WARN,L_SCAN|L_PL,"Playlist entry %s bad: %s\n",
|
DPRINTF(E_WARN,L_SCAN|L_PL,"Playlist entry %s bad: %s\n",
|
||||||
m3u_path,strerror(errno));
|
path,strerror(errno));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
close(fd);
|
close(fd);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user