command: added command "rescan"

"rescan" is the same as "update", but it discards existing songs in
the database.
This commit is contained in:
Max Kellermann 2009-09-24 21:55:40 +02:00
parent 47ab2ad6f3
commit 89ba540e6d
8 changed files with 81 additions and 27 deletions

View File

@ -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>

View File

@ -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 },

View File

@ -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");
}

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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;
}

View File

@ -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)) {