tmus

TUI Music Player
git clone https://git.sinitax.com/sinitax/tmus
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

commit 777bd77b64b4ca9c5e38c9cb5971a62684215f2a
parent e883c2678838f60970d7e1008635cda28472cb28
Author: Louis Burda <quent.burda@gmail.com>
Date:   Sat, 28 Jan 2023 15:51:20 +0100

If trash tag exists, move tracks there on delete

Diffstat:
Msrc/cmd.c | 80+++++++++++++++++++++++++------------------------------------------------------
Msrc/data.c | 75++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------
Msrc/data.h | 4++++
Msrc/tui.c | 10++++++++--
4 files changed, 99 insertions(+), 70 deletions(-)

diff --git a/src/cmd.c b/src/cmd.c @@ -7,12 +7,16 @@ #include "tui.h" #include "util.h" +#include <asm-generic/errno-base.h> +#include <errno.h> #include <stdbool.h> #include <string.h> static const struct cmd *last_cmd; static char *last_args; +static void cmd_status_from_errno(int err); + static bool cmd_save(const char *args); static bool cmd_move(const char *args); static bool cmd_copy(const char *args); @@ -33,6 +37,17 @@ const struct cmd commands[] = { const size_t command_count = ARRLEN(commands); +void +cmd_status_from_errno(int err) +{ + if (err == EACCES || err == EPERM) + CMD_SET_STATUS("Missing permissions"); + else if (err == EEXIST) + CMD_SET_STATUS("Path already exists"); + else + CMD_SET_STATUS("Unknown error"); +} + bool cmd_save(const char *args) { @@ -44,9 +59,8 @@ bool cmd_move(const char *name) { struct link *link; - struct track *track, *new; + struct track *track; struct tag *tag; - char *newpath; tag = tag_find(name); if (!tag) { @@ -66,33 +80,8 @@ cmd_move(const char *name) return false; } - newpath = aprintf("%s/%s", tag->fpath, track->name); - if (path_exists(newpath)) { - free(newpath); - CMD_SET_STATUS("File already exists"); - return false; - } - - if (!dup_file(track->fpath, newpath)) { - free(newpath); - CMD_SET_STATUS("Failed to move track"); - return false; - } - - free(newpath); - - new = track_add(tag, track->name); - if (!new) { - track_rm(new, true); - CMD_SET_STATUS("Failed to move track"); - return false; - } - - if (player.track == track) - player.track = new; - - if (!track_rm(track, true)) { - CMD_SET_STATUS("Failed to move track"); + if (!track_move(track, tag)) { + cmd_status_from_errno(errno); return false; } @@ -229,31 +218,17 @@ cleanup: bool cmd_add_tag(const char *name) { - struct link *link; struct tag *tag; - char *fpath; - for (LIST_ITER(&tags, link)) { - tag = UPCAST(link, struct tag, link); - if (!strcmp(tag->name, name)) { - CMD_SET_STATUS("Tag already exists"); - return false; - } - } - - fpath = aprintf("%s/%s", datadir, name); - - if (!make_dir(fpath)) { - free(fpath); - CMD_SET_STATUS("Failed to create dir"); + tag = tag_find(name); + if (tag) { + CMD_SET_STATUS("Tag already exists"); return false; } - free(fpath); - - tag = tag_add(name); + tag = tag_create(name); if (!tag) { - CMD_SET_STATUS("Failed to add tag"); + CMD_SET_STATUS("Failed to create tag"); return false; } @@ -271,13 +246,8 @@ cmd_rm_tag(const char *name) if (!link) return false; tag = UPCAST(link, struct tag, link); } else { - for (LIST_ITER(&tags, link)) { - tag = UPCAST(link, struct tag, link); - if (!strcmp(tag->name, name)) - break; - } - - if (!LIST_INNER(link)) { + tag = tag_find(name); + if (!tag) { CMD_SET_STATUS("No such tag"); return false; } diff --git a/src/data.c b/src/data.c @@ -6,6 +6,7 @@ #include "log.h" #include <fts.h> +#include <errno.h> #include <dirent.h> #include <sys/stat.h> #include <unistd.h> @@ -18,6 +19,8 @@ struct list tracks; /* struct track (link) */ struct list tags; /* struct track (link) */ struct list tags_sel; /* struct tag (link_sel) */ +struct tag *trash_tag; + bool playlist_outdated; static struct tag *tag_alloc(const char *path, const char *fname); @@ -25,7 +28,6 @@ static void tag_free(struct tag *tag); static struct track *track_alloc(const char *path, const char *fname); static void track_free(struct track *t); -static int track_name_compare(struct link *a, struct link *b); static void tracks_load(struct tag *tag); static void tracks_save(struct tag *tag); @@ -85,17 +87,6 @@ track_free(struct track *t) free(t); } -int -track_name_compare(struct link *a, struct link *b) -{ - struct track *ta, *tb; - - ta = UPCAST(a, struct track, link); - tb = UPCAST(b, struct track, link); - - return strcmp(ta->name, tb->name); -} - void tracks_load(struct tag *tag) { @@ -379,12 +370,34 @@ playlist_update(void) } struct tag * +tag_create(const char *fname) +{ + struct tag *tag; + char *path; + + path = aprintf("%s/%s", datadir, fname); + if (!make_dir(path)) { + free(path); + return NULL; + } + free(path); + + tag = tag_add(fname); + if (!tag) { + rm_dir(path, false); + return NULL; + } + + return tag; +} + +struct tag * tag_add(const char *fname) { struct tag *tag; - /* add to tags list */ tag = tag_alloc(datadir, fname); + if (!tag) return NULL; list_push_back(&tags, &tag->link); return tag; @@ -547,6 +560,39 @@ track_rename(struct track *track, const char *name) } bool +track_move(struct track *track, struct tag *tag) +{ + struct track *new; + char *newpath; + + newpath = aprintf("%s/%s", tag->fpath, track->name); + if (path_exists(newpath)) { + free(newpath); + return false; + } + + if (!dup_file(track->fpath, newpath)) { + free(newpath); + return false; + } + + free(newpath); + + new = track_add(tag, track->name); + if (!new) return false; + + if (player.track == track) + player.track = new; + + if (!track_rm(track, true)) { + track_rm(new, true); + return false; + } + + return true; +} + +bool acquire_lock(const char *datadir) { char *lockpath, *procpath; @@ -623,6 +669,7 @@ data_load(void) dir = opendir(datadir); if (!dir) ERROR(SYSTEM, "opendir %s", datadir); + trash_tag = NULL; while ((ent = readdir(dir))) { if (!strcmp(ent->d_name, ".")) continue; @@ -632,6 +679,8 @@ data_load(void) path = aprintf("%s/%s", datadir, ent->d_name); if (!stat(path, &st) && S_ISDIR(st.st_mode)) { tag = tag_add(ent->d_name); + if (!strcmp(tag->name, "trash")) + trash_tag = tag; tracks_load(tag); } free(path); diff --git a/src/data.h b/src/data.h @@ -41,6 +41,7 @@ struct track *tracks_vis_track(struct link *link); void playlist_clear(void); void playlist_update(void); +struct tag *tag_create(const char *fname); struct tag *tag_add(const char *fname); struct tag *tag_find(const char *name); bool tag_rm(struct tag *tag, bool sync_fs); @@ -49,6 +50,7 @@ bool tag_rename(struct tag *tag, const char *name); struct track *track_add(struct tag *tag, const char *fname); bool track_rm(struct track *track, bool sync_fs); bool track_rename(struct track *track, const char *name); +bool track_move(struct track *track, struct tag *tag); bool acquire_lock(const char *path); bool release_lock(const char *path); @@ -63,4 +65,6 @@ extern struct list tracks; /* struct track (link) */ extern struct list tags; /* struct track (link) */ extern struct list tags_sel; /* struct tag (link_sel) */ +extern struct tag *trash_tag; + extern bool playlist_outdated; diff --git a/src/tui.c b/src/tui.c @@ -551,8 +551,14 @@ delete_selected_track(void) if (!link) return false; track = tracks_vis_track(link); - if (!track_rm(track, true)) - CMD_SET_STATUS("Failed to remove track"); + + if (!trash_tag || !strcmp(track->tag->name, "trash")) { + if (!track_rm(track, true)) + CMD_SET_STATUS("Failed to remove track"); + } else { + if (!track_move(track, trash_tag)) + CMD_SET_STATUS("Failed to trash track"); + } return true; }