mirror of
https://github.com/owntone/owntone-server.git
synced 2024-12-26 07:05:57 -05:00
start of background scanning
This commit is contained in:
parent
13a5b089c0
commit
cff316a742
@ -13,7 +13,7 @@ DBFILE=db-memory.c
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
if COND_NEED_STRCASESTR
|
if COND_NEED_STRCASESTR
|
||||||
STRCASESTR=strcasestr.c
|
STRCASESTR=strcasestr.c strcasestr.h
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if COND_NEED_STRSEP
|
if COND_NEED_STRSEP
|
||||||
@ -41,7 +41,7 @@ mt_daapd_SOURCES = main.c daapd.h rend.h uici.c uici.h webserver.c \
|
|||||||
EXTRA_DIST = mdns/mDNS.c mdns/mDNSClientAPI.h mdns/mDNSDebug.h mdns/mDNSPosix.c \
|
EXTRA_DIST = mdns/mDNS.c mdns/mDNSClientAPI.h mdns/mDNSDebug.h mdns/mDNSPosix.c \
|
||||||
mdns/mDNSUNP.c mdns/mDNSPlatformFunctions.h mdns/mDNSPosix.h mdns/mDNSUNP.h \
|
mdns/mDNSUNP.c mdns/mDNSPlatformFunctions.h mdns/mDNSPosix.h mdns/mDNSUNP.h \
|
||||||
rend-howl.c rend-posix.c rend-osx.c strcasestr.c strsep.c db-memory.c \
|
rend-howl.c rend-posix.c rend-osx.c strcasestr.c strsep.c db-memory.c \
|
||||||
db-gdbm.c
|
db-gdbm.c strcasestr.h
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -171,7 +171,7 @@ int db_init(char *parameters) {
|
|||||||
db_version_no=1;
|
db_version_no=1;
|
||||||
db_song_count=0;
|
db_song_count=0;
|
||||||
|
|
||||||
/* count the actual songs... */
|
/* count the actual songs and build the playlists */
|
||||||
tmp_data=gdbm_firstkey(db_songs);
|
tmp_data=gdbm_firstkey(db_songs);
|
||||||
|
|
||||||
MEMNOTIFY(tmp_data.dptr);
|
MEMNOTIFY(tmp_data.dptr);
|
||||||
@ -560,7 +560,7 @@ int db_add(MP3FILE *pmp3) {
|
|||||||
ppacked->time_modified=ppacked->time_added;
|
ppacked->time_modified=ppacked->time_added;
|
||||||
ppacked->time_played=0;
|
ppacked->time_played=0;
|
||||||
|
|
||||||
if(gdbm_store(db_songs,dkey,*pnew,GDBM_INSERT)) {
|
if(gdbm_store(db_songs,dkey,*pnew,GDBM_REPLACE)) {
|
||||||
log_err(0,"Error inserting file %s in database\n",pmp3->fname);
|
log_err(0,"Error inserting file %s in database\n",pmp3->fname);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -789,6 +789,7 @@ int db_playlist_items_enum_end(void) {
|
|||||||
return pthread_rwlock_unlock(&db_rwlock);
|
return pthread_rwlock_unlock(&db_rwlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* db_find
|
* db_find
|
||||||
*
|
*
|
||||||
@ -901,3 +902,33 @@ char *db_get_playlist_name(int playlistid) {
|
|||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* db_exists
|
||||||
|
*
|
||||||
|
* Check if a particular ID exists or not
|
||||||
|
*/
|
||||||
|
int db_exists(int id) {
|
||||||
|
/* this is wrong and expensive */
|
||||||
|
MP3FILE *pmp3;
|
||||||
|
|
||||||
|
pmp3=db_find(id);
|
||||||
|
return pmp3 ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* db_last_modified
|
||||||
|
*
|
||||||
|
* See when the file was last updated in the database
|
||||||
|
*/
|
||||||
|
int db_last_modified(int id) {
|
||||||
|
MP3FILE *pmp3;
|
||||||
|
|
||||||
|
pmp3=db_find(id);
|
||||||
|
if(!pmp3)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
|
||||||
|
return pmp3->time_modified;
|
||||||
|
}
|
||||||
|
@ -629,3 +629,29 @@ char *db_get_playlist_name(int playlistid) {
|
|||||||
pthread_rwlock_unlock(&db_rwlock);
|
pthread_rwlock_unlock(&db_rwlock);
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* db_exists
|
||||||
|
*
|
||||||
|
* Check if a particular id is in the database
|
||||||
|
*/
|
||||||
|
int db_exists(int id) {
|
||||||
|
MP3FILE *pmp3;
|
||||||
|
|
||||||
|
pmp3=db_find(id);
|
||||||
|
|
||||||
|
return pmp3 ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* db_last_modified
|
||||||
|
*
|
||||||
|
* See when the file was modified (according to the database)
|
||||||
|
*
|
||||||
|
* This is merely a stub for the in-memory db
|
||||||
|
*/
|
||||||
|
int db_last_modified(int id) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -55,4 +55,8 @@ extern int db_playlist_items_enum_end(void);
|
|||||||
|
|
||||||
extern char *db_get_playlist_name(int playlistid);
|
extern char *db_get_playlist_name(int playlistid);
|
||||||
|
|
||||||
|
/* For persistant databases only */
|
||||||
|
extern int db_exists(int id);
|
||||||
|
extern int db_last_modified(int id);
|
||||||
|
|
||||||
#endif /* _DB_MEMORY_H_ */
|
#endif /* _DB_MEMORY_H_ */
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <netinet/in.h> /* htons and friends */
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
@ -46,6 +47,7 @@
|
|||||||
#include "err.h"
|
#include "err.h"
|
||||||
#include "mp3-scanner.h"
|
#include "mp3-scanner.h"
|
||||||
#include "playlist.h"
|
#include "playlist.h"
|
||||||
|
#include "strcasestr.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Typedefs
|
* Typedefs
|
||||||
@ -68,6 +70,8 @@ int scan_br_table[] = {
|
|||||||
0,32,40,48,56,64,80,96,112,128,160,192,224,256,320,0
|
0,32,40,48,56,64,80,96,112,128,160,192,224,256,320,0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int scan_mode_foreground=1;
|
||||||
|
|
||||||
char *scan_winamp_genre[] = {
|
char *scan_winamp_genre[] = {
|
||||||
"Blues", // 0
|
"Blues", // 0
|
||||||
"Classic Rock",
|
"Classic Rock",
|
||||||
@ -226,7 +230,7 @@ char *scan_winamp_genre[] = {
|
|||||||
/*
|
/*
|
||||||
* Forwards
|
* Forwards
|
||||||
*/
|
*/
|
||||||
int scan_foreground(char *path);
|
int scan_path(char *path);
|
||||||
int scan_gettags(char *file, MP3FILE *pmp3);
|
int scan_gettags(char *file, MP3FILE *pmp3);
|
||||||
int scan_get_mp3tags(char *file, MP3FILE *pmp3);
|
int scan_get_mp3tags(char *file, MP3FILE *pmp3);
|
||||||
int scan_get_aactags(char *file, MP3FILE *pmp3);
|
int scan_get_aactags(char *file, MP3FILE *pmp3);
|
||||||
@ -250,37 +254,42 @@ void scan_music_file(char *path, struct dirent *pde, struct stat *psb);
|
|||||||
|
|
||||||
int scan_init(char *path) {
|
int scan_init(char *path) {
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
scan_mode_foreground=0;
|
||||||
if(db_is_empty()) {
|
if(db_is_empty()) {
|
||||||
|
scan_mode_foreground=1;
|
||||||
if(db_start_initial_update())
|
if(db_start_initial_update())
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
DPRINTF(ERR_DEBUG,"%s scanning for MP3s in %s\n",
|
||||||
|
scan_mode_foreground ? "Foreground" : "Background",
|
||||||
|
path);
|
||||||
|
|
||||||
DPRINTF(ERR_DEBUG,"Scanning for MP3s in %s\n",path);
|
err=scan_path(path);
|
||||||
|
|
||||||
err=scan_foreground(path);
|
|
||||||
|
|
||||||
|
if(scan_mode_foreground)
|
||||||
if(db_end_initial_update())
|
if(db_end_initial_update())
|
||||||
return -1;
|
return -1;
|
||||||
} else {
|
|
||||||
/* do deferred updating */
|
scan_mode_foreground=0;
|
||||||
return ENOTSUP;
|
|
||||||
}
|
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* scan_foreground
|
* scan_path
|
||||||
*
|
*
|
||||||
* Do a brute force scan of a path, finding all the MP3 files there
|
* Do a brute force scan of a path, finding all the MP3 files there
|
||||||
*/
|
*/
|
||||||
int scan_foreground(char *path) {
|
int scan_path(char *path) {
|
||||||
DIR *current_dir;
|
DIR *current_dir;
|
||||||
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 mp3_path[PATH_MAX];
|
char mp3_path[PATH_MAX];
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
|
int modified_time;
|
||||||
|
|
||||||
if((current_dir=opendir(path)) == NULL) {
|
if((current_dir=opendir(path)) == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
@ -312,7 +321,7 @@ int scan_foreground(char *path) {
|
|||||||
|
|
||||||
if(sb.st_mode & S_IFDIR) { /* dir -- recurse */
|
if(sb.st_mode & S_IFDIR) { /* dir -- recurse */
|
||||||
DPRINTF(ERR_DEBUG,"Found dir %s... recursing\n",pde->d_name);
|
DPRINTF(ERR_DEBUG,"Found dir %s... recursing\n",pde->d_name);
|
||||||
scan_foreground(mp3_path);
|
scan_path(mp3_path);
|
||||||
} else {
|
} else {
|
||||||
DPRINTF(ERR_DEBUG,"Processing file\n");
|
DPRINTF(ERR_DEBUG,"Processing file\n");
|
||||||
/* process the file */
|
/* process the file */
|
||||||
@ -322,7 +331,16 @@ int scan_foreground(char *path) {
|
|||||||
scan_static_playlist(path, pde, &sb);
|
scan_static_playlist(path, pde, &sb);
|
||||||
} else if (strcasestr(config.extensions,
|
} else if (strcasestr(config.extensions,
|
||||||
(char*)&pde->d_name[strlen(pde->d_name) - 4])) {
|
(char*)&pde->d_name[strlen(pde->d_name) - 4])) {
|
||||||
scan_music_file(path,pde,&sb);
|
|
||||||
|
/* only scan if it's been changed, or empty db */
|
||||||
|
modified_time=sb.st_mtime;
|
||||||
|
if((scan_mode_foreground) ||
|
||||||
|
!db_exists(sb.st_ino) ||
|
||||||
|
db_last_modified(sb.st_ino) < modified_time) {
|
||||||
|
scan_music_file(path,pde,&sb);
|
||||||
|
} else {
|
||||||
|
DPRINTF(ERR_DEBUG,"Skipping file... not modified\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -471,6 +489,7 @@ int scan_get_aactags(char *file, MP3FILE *pmp3) {
|
|||||||
char current_atom[4];
|
char current_atom[4];
|
||||||
char *current_data;
|
char *current_data;
|
||||||
unsigned short us_data;
|
unsigned short us_data;
|
||||||
|
int len;
|
||||||
|
|
||||||
if(!(fin=fopen(file,"rb"))) {
|
if(!(fin=fopen(file,"rb"))) {
|
||||||
DPRINTF(ERR_INFO,"Cannot open file %s for reading\n",file);
|
DPRINTF(ERR_INFO,"Cannot open file %s for reading\n",file);
|
||||||
@ -504,8 +523,12 @@ int scan_get_aactags(char *file, MP3FILE *pmp3) {
|
|||||||
if(fread(current_atom,1,4,fin) != 4)
|
if(fread(current_atom,1,4,fin) != 4)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
current_data=(char*)malloc(current_size - 7); /* extra byte */
|
len=current_size-7; /* for ill-formed too-short tags */
|
||||||
memset(current_data,0x00,current_size - 7);
|
if(len < 22)
|
||||||
|
len=22;
|
||||||
|
|
||||||
|
current_data=(char*)malloc(len); /* extra byte */
|
||||||
|
memset(current_data,0x00,len);
|
||||||
|
|
||||||
if(fread(current_data,1,current_size-8,fin) != current_size-8)
|
if(fread(current_data,1,current_size-8,fin) != current_size-8)
|
||||||
break;
|
break;
|
||||||
@ -812,7 +835,7 @@ int scan_getfileinfo(char *file, MP3FILE *pmp3) {
|
|||||||
if(!pmp3->song_length) /* could have gotten it from the tag */
|
if(!pmp3->song_length) /* could have gotten it from the tag */
|
||||||
pmp3->song_length=time_seconds;
|
pmp3->song_length=time_seconds;
|
||||||
} else {
|
} else {
|
||||||
/* should really scan forward to next sync frame */
|
/* FIXME: should really scan forward to next sync frame */
|
||||||
fclose(infile);
|
fclose(infile);
|
||||||
DPRINTF(ERR_DEBUG,"Could not find sync frame\n");
|
DPRINTF(ERR_DEBUG,"Could not find sync frame\n");
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -89,6 +89,9 @@
|
|||||||
Change History (most recent first):
|
Change History (most recent first):
|
||||||
|
|
||||||
$Log$
|
$Log$
|
||||||
|
Revision 1.16 2004/03/08 19:21:03 rpedde
|
||||||
|
start of background scanning
|
||||||
|
|
||||||
Revision 1.15 2004/03/02 01:35:31 rpedde
|
Revision 1.15 2004/03/02 01:35:31 rpedde
|
||||||
fix domain
|
fix domain
|
||||||
|
|
||||||
@ -240,15 +243,13 @@ static void RegistrationCallback(mDNS *const m, ServiceRecordSet *const thisRegi
|
|||||||
switch (status) {
|
switch (status) {
|
||||||
|
|
||||||
case mStatus_NoError:
|
case mStatus_NoError:
|
||||||
DPRINTF(ERR_DEBUG,"Callback: %##s Name Registered\n",
|
DPRINTF(ERR_DEBUG,"Callback: Name Registered\n");
|
||||||
thisRegistration->RR_SRV.resrec.name.c);
|
|
||||||
// Do nothing; our name was successfully registered. We may
|
// Do nothing; our name was successfully registered. We may
|
||||||
// get more call backs in the future.
|
// get more call backs in the future.
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case mStatus_NameConflict:
|
case mStatus_NameConflict:
|
||||||
DPRINTF(ERR_WARN,"Callback: %##s Name Conflict\n",
|
DPRINTF(ERR_WARN,"Callback: Name Conflict\n");
|
||||||
thisRegistration->RR_SRV.resrec.name.c);
|
|
||||||
|
|
||||||
// In the event of a conflict, this sample RegistrationCallback
|
// In the event of a conflict, this sample RegistrationCallback
|
||||||
// just calls mDNS_RenameAndReregisterService to automatically
|
// just calls mDNS_RenameAndReregisterService to automatically
|
||||||
@ -266,8 +267,7 @@ static void RegistrationCallback(mDNS *const m, ServiceRecordSet *const thisRegi
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case mStatus_MemFree:
|
case mStatus_MemFree:
|
||||||
DPRINTF(ERR_WARN,"Callback: %##s Memory Free\n",
|
DPRINTF(ERR_WARN,"Callback: Memory Free\n");
|
||||||
thisRegistration->RR_SRV.resrec.name.c);
|
|
||||||
|
|
||||||
// When debugging is enabled, make sure that thisRegistration
|
// When debugging is enabled, make sure that thisRegistration
|
||||||
// is not on our gServiceList.
|
// is not on our gServiceList.
|
||||||
@ -287,8 +287,7 @@ static void RegistrationCallback(mDNS *const m, ServiceRecordSet *const thisRegi
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
DPRINTF(ERR_WARN,"Callback: %##s Unknown Status %d\n",
|
DPRINTF(ERR_WARN,"Callback: Unknown Status %d\n",status);
|
||||||
thisRegistration->RR_SRV.resrec.name.c, status);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
6
src/strcasestr.h
Normal file
6
src/strcasestr.h
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _STRCASESTR_H_
|
||||||
|
#define _STRCASESTR_H_
|
||||||
|
|
||||||
|
extern char * strcasestr(char* haystack, char* needle);
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user