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
|
||||
|
||||
if COND_NEED_STRCASESTR
|
||||
STRCASESTR=strcasestr.c
|
||||
STRCASESTR=strcasestr.c strcasestr.h
|
||||
endif
|
||||
|
||||
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 \
|
||||
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 \
|
||||
db-gdbm.c
|
||||
db-gdbm.c strcasestr.h
|
||||
|
||||
|
||||
|
||||
|
@ -171,7 +171,7 @@ int db_init(char *parameters) {
|
||||
db_version_no=1;
|
||||
db_song_count=0;
|
||||
|
||||
/* count the actual songs... */
|
||||
/* count the actual songs and build the playlists */
|
||||
tmp_data=gdbm_firstkey(db_songs);
|
||||
|
||||
MEMNOTIFY(tmp_data.dptr);
|
||||
@ -560,7 +560,7 @@ int db_add(MP3FILE *pmp3) {
|
||||
ppacked->time_modified=ppacked->time_added;
|
||||
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);
|
||||
}
|
||||
|
||||
@ -789,6 +789,7 @@ int db_playlist_items_enum_end(void) {
|
||||
return pthread_rwlock_unlock(&db_rwlock);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* db_find
|
||||
*
|
||||
@ -901,3 +902,33 @@ char *db_get_playlist_name(int playlistid) {
|
||||
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);
|
||||
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);
|
||||
|
||||
/* For persistant databases only */
|
||||
extern int db_exists(int id);
|
||||
extern int db_last_modified(int id);
|
||||
|
||||
#endif /* _DB_MEMORY_H_ */
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <netinet/in.h> /* htons and friends */
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
@ -46,6 +47,7 @@
|
||||
#include "err.h"
|
||||
#include "mp3-scanner.h"
|
||||
#include "playlist.h"
|
||||
#include "strcasestr.h"
|
||||
|
||||
/*
|
||||
* 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
|
||||
};
|
||||
|
||||
int scan_mode_foreground=1;
|
||||
|
||||
char *scan_winamp_genre[] = {
|
||||
"Blues", // 0
|
||||
"Classic Rock",
|
||||
@ -226,7 +230,7 @@ char *scan_winamp_genre[] = {
|
||||
/*
|
||||
* Forwards
|
||||
*/
|
||||
int scan_foreground(char *path);
|
||||
int scan_path(char *path);
|
||||
int scan_gettags(char *file, MP3FILE *pmp3);
|
||||
int scan_get_mp3tags(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 err;
|
||||
|
||||
scan_mode_foreground=0;
|
||||
if(db_is_empty()) {
|
||||
scan_mode_foreground=1;
|
||||
if(db_start_initial_update())
|
||||
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_foreground(path);
|
||||
err=scan_path(path);
|
||||
|
||||
if(scan_mode_foreground)
|
||||
if(db_end_initial_update())
|
||||
return -1;
|
||||
} else {
|
||||
/* do deferred updating */
|
||||
return ENOTSUP;
|
||||
}
|
||||
|
||||
scan_mode_foreground=0;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* scan_foreground
|
||||
* scan_path
|
||||
*
|
||||
* 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;
|
||||
char de[sizeof(struct dirent) + MAXNAMLEN + 1]; /* overcommit for solaris */
|
||||
struct dirent *pde;
|
||||
int err;
|
||||
char mp3_path[PATH_MAX];
|
||||
struct stat sb;
|
||||
int modified_time;
|
||||
|
||||
if((current_dir=opendir(path)) == NULL) {
|
||||
return -1;
|
||||
@ -312,7 +321,7 @@ int scan_foreground(char *path) {
|
||||
|
||||
if(sb.st_mode & S_IFDIR) { /* dir -- recurse */
|
||||
DPRINTF(ERR_DEBUG,"Found dir %s... recursing\n",pde->d_name);
|
||||
scan_foreground(mp3_path);
|
||||
scan_path(mp3_path);
|
||||
} else {
|
||||
DPRINTF(ERR_DEBUG,"Processing file\n");
|
||||
/* process the file */
|
||||
@ -322,7 +331,16 @@ int scan_foreground(char *path) {
|
||||
scan_static_playlist(path, pde, &sb);
|
||||
} else if (strcasestr(config.extensions,
|
||||
(char*)&pde->d_name[strlen(pde->d_name) - 4])) {
|
||||
|
||||
/* 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_data;
|
||||
unsigned short us_data;
|
||||
int len;
|
||||
|
||||
if(!(fin=fopen(file,"rb"))) {
|
||||
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)
|
||||
break;
|
||||
|
||||
current_data=(char*)malloc(current_size - 7); /* extra byte */
|
||||
memset(current_data,0x00,current_size - 7);
|
||||
len=current_size-7; /* for ill-formed too-short tags */
|
||||
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)
|
||||
break;
|
||||
@ -812,7 +835,7 @@ int scan_getfileinfo(char *file, MP3FILE *pmp3) {
|
||||
if(!pmp3->song_length) /* could have gotten it from the tag */
|
||||
pmp3->song_length=time_seconds;
|
||||
} else {
|
||||
/* should really scan forward to next sync frame */
|
||||
/* FIXME: should really scan forward to next sync frame */
|
||||
fclose(infile);
|
||||
DPRINTF(ERR_DEBUG,"Could not find sync frame\n");
|
||||
return -1;
|
||||
|
@ -89,6 +89,9 @@
|
||||
Change History (most recent first):
|
||||
|
||||
$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
|
||||
fix domain
|
||||
|
||||
@ -240,15 +243,13 @@ static void RegistrationCallback(mDNS *const m, ServiceRecordSet *const thisRegi
|
||||
switch (status) {
|
||||
|
||||
case mStatus_NoError:
|
||||
DPRINTF(ERR_DEBUG,"Callback: %##s Name Registered\n",
|
||||
thisRegistration->RR_SRV.resrec.name.c);
|
||||
DPRINTF(ERR_DEBUG,"Callback: Name Registered\n");
|
||||
// Do nothing; our name was successfully registered. We may
|
||||
// get more call backs in the future.
|
||||
break;
|
||||
|
||||
case mStatus_NameConflict:
|
||||
DPRINTF(ERR_WARN,"Callback: %##s Name Conflict\n",
|
||||
thisRegistration->RR_SRV.resrec.name.c);
|
||||
DPRINTF(ERR_WARN,"Callback: Name Conflict\n");
|
||||
|
||||
// In the event of a conflict, this sample RegistrationCallback
|
||||
// just calls mDNS_RenameAndReregisterService to automatically
|
||||
@ -266,8 +267,7 @@ static void RegistrationCallback(mDNS *const m, ServiceRecordSet *const thisRegi
|
||||
break;
|
||||
|
||||
case mStatus_MemFree:
|
||||
DPRINTF(ERR_WARN,"Callback: %##s Memory Free\n",
|
||||
thisRegistration->RR_SRV.resrec.name.c);
|
||||
DPRINTF(ERR_WARN,"Callback: Memory Free\n");
|
||||
|
||||
// When debugging is enabled, make sure that thisRegistration
|
||||
// is not on our gServiceList.
|
||||
@ -287,8 +287,7 @@ static void RegistrationCallback(mDNS *const m, ServiceRecordSet *const thisRegi
|
||||
break;
|
||||
|
||||
default:
|
||||
DPRINTF(ERR_WARN,"Callback: %##s Unknown Status %d\n",
|
||||
thisRegistration->RR_SRV.resrec.name.c, status);
|
||||
DPRINTF(ERR_WARN,"Callback: Unknown Status %d\n",status);
|
||||
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