mirror of
https://github.com/owntone/owntone-server.git
synced 2025-01-14 08:15:02 -05:00
[library] support forced metadata scan of library, via '.meta-rescan' file
This commit is contained in:
parent
b240460469
commit
8f311d4360
@ -417,6 +417,9 @@ Now you can make a cron job that runs this command:
|
|||||||
When forked-daapd detects a file with filename ending .init-rescan it will
|
When forked-daapd detects a file with filename ending .init-rescan it will
|
||||||
perform a bulk scan similar to the startup scan.
|
perform a bulk scan similar to the startup scan.
|
||||||
|
|
||||||
|
Alternatively, you can force a metadata scan of the library even if the
|
||||||
|
files have not changed by creating a filename ending `.meta-rescan`.
|
||||||
|
|
||||||
|
|
||||||
### Troubleshooting library issues
|
### Troubleshooting library issues
|
||||||
|
|
||||||
|
@ -294,6 +294,49 @@ rescan(void *arg, int *ret)
|
|||||||
return COMMAND_END;
|
return COMMAND_END;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static enum command_state
|
||||||
|
metarescan(void *arg, int *ret)
|
||||||
|
{
|
||||||
|
time_t starttime;
|
||||||
|
time_t endtime;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
DPRINTF(E_LOG, L_LIB, "Library meta rescan triggered\n");
|
||||||
|
listener_notify(LISTENER_UPDATE);
|
||||||
|
starttime = time(NULL);
|
||||||
|
|
||||||
|
for (i = 0; sources[i]; i++)
|
||||||
|
{
|
||||||
|
if (!sources[i]->disabled && sources[i]->metarescan)
|
||||||
|
{
|
||||||
|
DPRINTF(E_INFO, L_LIB, "Meta rescan library source '%s'\n", sources[i]->name);
|
||||||
|
sources[i]->metarescan();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DPRINTF(E_INFO, L_LIB, "Library source '%s' is disabled\n", sources[i]->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
purge_cruft(starttime);
|
||||||
|
|
||||||
|
DPRINTF(E_DBG, L_LIB, "Running post library scan jobs\n");
|
||||||
|
db_hook_post_scan();
|
||||||
|
|
||||||
|
endtime = time(NULL);
|
||||||
|
DPRINTF(E_LOG, L_LIB, "Library meta rescan completed in %.f sec (%d changes)\n", difftime(endtime, starttime), deferred_update_notifications);
|
||||||
|
scanning = false;
|
||||||
|
|
||||||
|
if (handle_deferred_update_notifications())
|
||||||
|
listener_notify(LISTENER_UPDATE | LISTENER_DATABASE);
|
||||||
|
else
|
||||||
|
listener_notify(LISTENER_UPDATE);
|
||||||
|
|
||||||
|
*ret = 0;
|
||||||
|
return COMMAND_END;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static enum command_state
|
static enum command_state
|
||||||
fullrescan(void *arg, int *ret)
|
fullrescan(void *arg, int *ret)
|
||||||
{
|
{
|
||||||
@ -382,6 +425,18 @@ library_rescan()
|
|||||||
commands_exec_async(cmdbase, rescan, NULL);
|
commands_exec_async(cmdbase, rescan, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
library_metarescan()
|
||||||
|
{
|
||||||
|
if (scanning)
|
||||||
|
{
|
||||||
|
DPRINTF(E_INFO, L_LIB, "Scan already running, ignoring request to trigger metadata scan\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
scanning = true; // TODO Guard "scanning" with a mutex
|
||||||
|
commands_exec_async(cmdbase, metarescan, NULL);
|
||||||
|
}
|
||||||
void
|
void
|
||||||
library_fullrescan()
|
library_fullrescan()
|
||||||
{
|
{
|
||||||
|
@ -61,6 +61,11 @@ struct library_source
|
|||||||
*/
|
*/
|
||||||
int (*rescan)(void);
|
int (*rescan)(void);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Run a metadata rescan of library even if files not changed (called from the library thread)
|
||||||
|
*/
|
||||||
|
int (*metarescan)(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Run a full rescan (purge library entries and rescan) (called from the library thread)
|
* Run a full rescan (purge library entries and rescan) (called from the library thread)
|
||||||
*/
|
*/
|
||||||
@ -99,6 +104,9 @@ library_queue_add(const char *path, int position, int *count, int *new_item_id);
|
|||||||
void
|
void
|
||||||
library_rescan();
|
library_rescan();
|
||||||
|
|
||||||
|
void
|
||||||
|
library_metarescan();
|
||||||
|
|
||||||
void
|
void
|
||||||
library_fullrescan();
|
library_fullrescan();
|
||||||
|
|
||||||
|
@ -76,6 +76,7 @@
|
|||||||
#define F_SCAN_RESCAN (1 << 1)
|
#define F_SCAN_RESCAN (1 << 1)
|
||||||
#define F_SCAN_FAST (1 << 2)
|
#define F_SCAN_FAST (1 << 2)
|
||||||
#define F_SCAN_MOVED (1 << 3)
|
#define F_SCAN_MOVED (1 << 3)
|
||||||
|
#define F_SCAN_METARESCAN (1 << 4)
|
||||||
|
|
||||||
#define F_SCAN_TYPE_FILE (1 << 0)
|
#define F_SCAN_TYPE_FILE (1 << 0)
|
||||||
#define F_SCAN_TYPE_PODCAST (1 << 1)
|
#define F_SCAN_TYPE_PODCAST (1 << 1)
|
||||||
@ -96,6 +97,7 @@ enum file_type {
|
|||||||
FILE_CTRL_LASTFM,
|
FILE_CTRL_LASTFM,
|
||||||
FILE_CTRL_SPOTIFY,
|
FILE_CTRL_SPOTIFY,
|
||||||
FILE_CTRL_INITSCAN,
|
FILE_CTRL_INITSCAN,
|
||||||
|
FILE_CTRL_METASCAN, // forced scan for meta, preserves existing db records
|
||||||
FILE_CTRL_FULLSCAN,
|
FILE_CTRL_FULLSCAN,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -366,6 +368,9 @@ file_type_get(const char *path) {
|
|||||||
if (strcasecmp(ext, ".init-rescan") == 0)
|
if (strcasecmp(ext, ".init-rescan") == 0)
|
||||||
return FILE_CTRL_INITSCAN;
|
return FILE_CTRL_INITSCAN;
|
||||||
|
|
||||||
|
if (strcasecmp(ext, ".meta-rescan") == 0)
|
||||||
|
return FILE_CTRL_METASCAN;
|
||||||
|
|
||||||
if (strcasecmp(ext, ".full-rescan") == 0)
|
if (strcasecmp(ext, ".full-rescan") == 0)
|
||||||
return FILE_CTRL_FULLSCAN;
|
return FILE_CTRL_FULLSCAN;
|
||||||
|
|
||||||
@ -477,9 +482,12 @@ process_regular_file(const char *file, struct stat *sb, int type, int flags, int
|
|||||||
|
|
||||||
// Will return 0 if file is not in library or if file mtime is newer than library timestamp
|
// Will return 0 if file is not in library or if file mtime is newer than library timestamp
|
||||||
// - note if mtime is 0 then we always scan the file
|
// - note if mtime is 0 then we always scan the file
|
||||||
ret = db_file_ping_bypath(file, sb->st_mtime);
|
if (!(flags & F_SCAN_METARESCAN))
|
||||||
if ((sb->st_mtime != 0) && (ret != 0))
|
{
|
||||||
return;
|
ret = db_file_ping_bypath(file, sb->st_mtime);
|
||||||
|
if ((sb->st_mtime != 0) && (ret != 0))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// File is new or modified - (re)scan metadata and update file in library
|
// File is new or modified - (re)scan metadata and update file in library
|
||||||
memset(&mfi, 0, sizeof(struct media_file_info));
|
memset(&mfi, 0, sizeof(struct media_file_info));
|
||||||
@ -624,6 +632,15 @@ process_file(char *file, struct stat *sb, int type, int flags, int dir_id)
|
|||||||
library_rescan();
|
library_rescan();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case FILE_CTRL_METASCAN:
|
||||||
|
if (flags & F_SCAN_BULK)
|
||||||
|
break;
|
||||||
|
|
||||||
|
DPRINTF(E_LOG, L_SCAN, "Meta rescan triggered, found meta-rescan file: %s\n", file);
|
||||||
|
|
||||||
|
library_metarescan();
|
||||||
|
break;
|
||||||
|
|
||||||
case FILE_CTRL_FULLSCAN:
|
case FILE_CTRL_FULLSCAN:
|
||||||
if (flags & F_SCAN_BULK)
|
if (flags & F_SCAN_BULK)
|
||||||
break;
|
break;
|
||||||
@ -1630,6 +1647,24 @@ filescanner_rescan()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
filescanner_metarescan()
|
||||||
|
{
|
||||||
|
DPRINTF(E_LOG, L_SCAN, "meta rescan triggered\n");
|
||||||
|
|
||||||
|
inofd_event_unset(); // Clears all inotify watches
|
||||||
|
db_watch_clear();
|
||||||
|
inofd_event_set();
|
||||||
|
bulk_scan(F_SCAN_BULK | F_SCAN_METARESCAN);
|
||||||
|
|
||||||
|
if (!library_is_exiting())
|
||||||
|
{
|
||||||
|
/* Enable inotify */
|
||||||
|
event_add(inoev, NULL);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
filescanner_fullrescan()
|
filescanner_fullrescan()
|
||||||
{
|
{
|
||||||
@ -2133,6 +2168,7 @@ struct library_source filescanner =
|
|||||||
.deinit = filescanner_deinit,
|
.deinit = filescanner_deinit,
|
||||||
.initscan = filescanner_initscan,
|
.initscan = filescanner_initscan,
|
||||||
.rescan = filescanner_rescan,
|
.rescan = filescanner_rescan,
|
||||||
|
.metarescan = filescanner_metarescan,
|
||||||
.fullrescan = filescanner_fullrescan,
|
.fullrescan = filescanner_fullrescan,
|
||||||
.playlist_add = playlist_add,
|
.playlist_add = playlist_add,
|
||||||
.playlist_remove = playlist_remove,
|
.playlist_remove = playlist_remove,
|
||||||
|
Loading…
Reference in New Issue
Block a user