command: added command "rescan"
"rescan" is the same as "update", but it discards existing songs in the database.
This commit is contained in:
parent
47ab2ad6f3
commit
89ba540e6d
@ -1245,6 +1245,20 @@ OK
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry id="command_rescan">
|
||||
<term>
|
||||
<cmdsynopsis>
|
||||
<command>rescan</command>
|
||||
<arg choice="opt"><replaceable>URI</replaceable></arg>
|
||||
</cmdsynopsis>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Same as <command>update</command>, but also rescans
|
||||
unmodified files.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</section>
|
||||
|
||||
|
@ -1025,7 +1025,28 @@ handle_update(struct client *client, G_GNUC_UNUSED int argc, char *argv[])
|
||||
if (argc == 2)
|
||||
path = argv[1];
|
||||
|
||||
ret = update_enqueue(path);
|
||||
ret = update_enqueue(path, false);
|
||||
if (ret > 0) {
|
||||
client_printf(client, "updating_db: %i\n", ret);
|
||||
return COMMAND_RETURN_OK;
|
||||
} else {
|
||||
command_error(client, ACK_ERROR_UPDATE_ALREADY,
|
||||
"already updating");
|
||||
return COMMAND_RETURN_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
static enum command_return
|
||||
handle_rescan(struct client *client, G_GNUC_UNUSED int argc, char *argv[])
|
||||
{
|
||||
const char *path = NULL;
|
||||
unsigned ret;
|
||||
|
||||
assert(argc <= 2);
|
||||
if (argc == 2)
|
||||
path = argv[1];
|
||||
|
||||
ret = update_enqueue(path, true);
|
||||
if (ret > 0) {
|
||||
client_printf(client, "updating_db: %i\n", ret);
|
||||
return COMMAND_RETURN_OK;
|
||||
@ -1731,6 +1752,7 @@ static const struct command commands[] = {
|
||||
{ "random", PERMISSION_CONTROL, 1, 1, handle_random },
|
||||
{ "rename", PERMISSION_CONTROL, 2, 2, handle_rename },
|
||||
{ "repeat", PERMISSION_CONTROL, 1, 1, handle_repeat },
|
||||
{ "rescan", PERMISSION_ADMIN, 0, 1, handle_rescan },
|
||||
{ "rm", PERMISSION_CONTROL, 1, 1, handle_rm },
|
||||
{ "save", PERMISSION_CONTROL, 1, 1, handle_save },
|
||||
{ "search", PERMISSION_READ, 2, -1, handle_search },
|
||||
|
@ -362,7 +362,7 @@ int main(int argc, char *argv[])
|
||||
if (create_db) {
|
||||
/* the database failed to load: recreate the
|
||||
database */
|
||||
unsigned job = update_enqueue(NULL);
|
||||
unsigned job = update_enqueue(NULL, true);
|
||||
if (job == 0)
|
||||
g_error("directory update failed");
|
||||
}
|
||||
|
12
src/update.c
12
src/update.c
@ -52,6 +52,9 @@ static unsigned update_task_id;
|
||||
/** used by the main thread to notify the update thread */
|
||||
struct notify update_notify;
|
||||
|
||||
/* XXX this flag is passed to update_task() */
|
||||
static bool discard;
|
||||
|
||||
unsigned
|
||||
isUpdatingDB(void)
|
||||
{
|
||||
@ -62,7 +65,7 @@ static void * update_task(void *_path)
|
||||
{
|
||||
const char *path = _path;
|
||||
|
||||
modified = update_walk(path);
|
||||
modified = update_walk(path, discard);
|
||||
g_free(_path);
|
||||
|
||||
if (modified || !db_exists())
|
||||
@ -93,7 +96,7 @@ spawn_update_task(const char *path)
|
||||
}
|
||||
|
||||
unsigned
|
||||
update_enqueue(const char *path)
|
||||
update_enqueue(const char *path, bool _discard)
|
||||
{
|
||||
assert(g_thread_self() == main_task);
|
||||
|
||||
@ -102,13 +105,14 @@ update_enqueue(const char *path)
|
||||
|
||||
if (progress != UPDATE_PROGRESS_IDLE) {
|
||||
unsigned next_task_id =
|
||||
update_queue_push(path, update_task_id);
|
||||
update_queue_push(path, discard, update_task_id);
|
||||
if (next_task_id == 0)
|
||||
return 0;
|
||||
|
||||
return next_task_id > update_task_id_max ? 1 : next_task_id;
|
||||
}
|
||||
|
||||
discard = _discard;
|
||||
spawn_update_task(path);
|
||||
|
||||
idle_add(IDLE_UPDATE);
|
||||
@ -135,7 +139,7 @@ static void update_finished_event(void)
|
||||
idle_add(IDLE_DATABASE);
|
||||
}
|
||||
|
||||
path = update_queue_shift();
|
||||
path = update_queue_shift(&discard);
|
||||
if (path != NULL) {
|
||||
/* schedule the next path */
|
||||
spawn_update_task(path);
|
||||
|
@ -35,6 +35,6 @@ isUpdatingDB(void);
|
||||
* @return the job id, or 0 on error
|
||||
*/
|
||||
unsigned
|
||||
update_enqueue(const char *path);
|
||||
update_enqueue(const char *path, bool discard);
|
||||
|
||||
#endif
|
||||
|
@ -33,10 +33,10 @@ struct directory;
|
||||
extern struct notify update_notify;
|
||||
|
||||
unsigned
|
||||
update_queue_push(const char *path, unsigned base);
|
||||
update_queue_push(const char *path, bool discard, unsigned base);
|
||||
|
||||
char *
|
||||
update_queue_shift(void);
|
||||
update_queue_shift(bool *discard_r);
|
||||
|
||||
void
|
||||
update_walk_global_init(void);
|
||||
@ -48,7 +48,7 @@ update_walk_global_finish(void);
|
||||
* Returns true if the database was modified.
|
||||
*/
|
||||
bool
|
||||
update_walk(const char *path);
|
||||
update_walk(const char *path, bool discard);
|
||||
|
||||
void
|
||||
update_remove_global_init(void);
|
||||
|
@ -25,31 +25,41 @@
|
||||
#include <string.h>
|
||||
|
||||
/* make this dynamic?, or maybe this is big enough... */
|
||||
static char *update_paths[32];
|
||||
static size_t update_paths_nr;
|
||||
static struct {
|
||||
char *path;
|
||||
bool discard;
|
||||
} update_queue[32];
|
||||
|
||||
static size_t update_queue_length;
|
||||
|
||||
unsigned
|
||||
update_queue_push(const char *path, unsigned base)
|
||||
update_queue_push(const char *path, bool discard, unsigned base)
|
||||
{
|
||||
assert(update_paths_nr <= G_N_ELEMENTS(update_paths));
|
||||
assert(update_queue_length <= G_N_ELEMENTS(update_queue));
|
||||
|
||||
if (update_paths_nr == G_N_ELEMENTS(update_paths))
|
||||
if (update_queue_length == G_N_ELEMENTS(update_queue))
|
||||
return 0;
|
||||
|
||||
update_paths[update_paths_nr++] = g_strdup(path);
|
||||
return base + update_paths_nr;
|
||||
update_queue[update_queue_length].path = g_strdup(path);
|
||||
update_queue[update_queue_length].discard = discard;
|
||||
|
||||
++update_queue_length;
|
||||
|
||||
return base + update_queue_length;
|
||||
}
|
||||
|
||||
char *
|
||||
update_queue_shift(void)
|
||||
update_queue_shift(bool *discard_r)
|
||||
{
|
||||
char *path;
|
||||
|
||||
if (update_paths_nr == 0)
|
||||
if (update_queue_length == 0)
|
||||
return NULL;
|
||||
|
||||
path = update_paths[0];
|
||||
memmove(&update_paths[0], &update_paths[1],
|
||||
--update_paths_nr * sizeof(char *));
|
||||
path = update_queue[0].path;
|
||||
*discard_r = update_queue[0].discard;
|
||||
|
||||
memmove(&update_queue[0], &update_queue[1],
|
||||
--update_queue_length * sizeof(update_queue[0]));
|
||||
return path;
|
||||
}
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
static bool walk_discard;
|
||||
static bool modified;
|
||||
|
||||
#ifndef WIN32
|
||||
@ -350,7 +351,8 @@ update_archive_file(struct directory *parent, const char *name,
|
||||
char *filepath;
|
||||
|
||||
directory = dirvec_find(&parent->children, name);
|
||||
if (directory != NULL && directory->mtime == st->st_mtime)
|
||||
if (directory != NULL && directory->mtime == st->st_mtime &&
|
||||
!walk_discard)
|
||||
/* MPD has already scanned the archive, and it hasn't
|
||||
changed since - don't consider updating it */
|
||||
return;
|
||||
@ -405,7 +407,7 @@ update_container_file( struct directory* directory,
|
||||
if (contdir != NULL)
|
||||
{
|
||||
// modification time not eq. file mod. time
|
||||
if (contdir->mtime != st->st_mtime)
|
||||
if (contdir->mtime != st->st_mtime || walk_discard)
|
||||
{
|
||||
g_message("removing container file: %s", pathname);
|
||||
|
||||
@ -470,7 +472,8 @@ update_regular_file(struct directory *directory,
|
||||
{
|
||||
struct song* song = songvec_find(&directory->songs, name);
|
||||
|
||||
if (!(song != NULL && st->st_mtime == song->mtime) &&
|
||||
if (!(song != NULL && st->st_mtime == song->mtime &&
|
||||
!walk_discard) &&
|
||||
plugin->container_scan != NULL)
|
||||
{
|
||||
if (update_container_file(directory, name, st, plugin))
|
||||
@ -491,7 +494,7 @@ update_regular_file(struct directory *directory,
|
||||
modified = true;
|
||||
g_message("added %s/%s",
|
||||
directory_get_path(directory), name);
|
||||
} else if (st->st_mtime != song->mtime) {
|
||||
} else if (st->st_mtime != song->mtime || walk_discard) {
|
||||
g_message("updating %s/%s",
|
||||
directory_get_path(directory), name);
|
||||
if (!song_file_update(song))
|
||||
@ -737,8 +740,9 @@ updatePath(const char *path)
|
||||
}
|
||||
|
||||
bool
|
||||
update_walk(const char *path)
|
||||
update_walk(const char *path, bool discard)
|
||||
{
|
||||
walk_discard = discard;
|
||||
modified = false;
|
||||
|
||||
if (path != NULL && !isRootDirectory(path)) {
|
||||
|
Loading…
Reference in New Issue
Block a user