tmus

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

commit c8c0a86f492c9423a6330f9deaa86a718ef08c54
parent f1996f51ba1744260bba4d7c3aa5d9a84c97236e
Author: Louis Burda <quent.burda@gmail.com>
Date:   Thu, 16 Mar 2023 19:21:26 +0100

Allow saving reordered tracks in tag

Diffstat:
Msrc/cmd.c | 12++++++++++--
Msrc/data.c | 151++++++++++++++++++++++++++++++++++++-------------------------------------------
Msrc/data.h | 9++++++---
Msrc/tui.c | 14++++++++++++--
4 files changed, 96 insertions(+), 90 deletions(-)

diff --git a/src/cmd.c b/src/cmd.c @@ -51,7 +51,15 @@ cmd_status_from_errno(int err) bool cmd_save(const char *args) { - data_save(); + struct link *link; + struct tag *tag; + + for (LIST_ITER(&tags, link)) { + tag = UPCAST(link, struct tag, link); + if (tag->index_dirty || tag->reordered) + tag_save_tracks(tag); + } + return true; } @@ -191,7 +199,7 @@ cmd_reindex(const char *name) /* update each tag specified */ for (LIST_ITER(&matches, link)) { ref = UPCAST(link, struct ref, link); - if (!tracks_update(ref->data)) + if (!tag_reindex_tracks(ref->data)) goto cleanup; } diff --git a/src/data.c b/src/data.c @@ -30,8 +30,7 @@ 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 void tracks_load(struct tag *tag); -static void tracks_save(struct tag *tag); +static bool tag_name_cmp(struct link *l1, struct link *l2); struct tag * tag_alloc(const char *path, const char *fname) @@ -44,6 +43,7 @@ tag_alloc(const char *path, const char *fname) tag->fpath = aprintf("%s/%s", path, fname); tag->name = astrdup(fname); tag->index_dirty = false; + tag->reordered = false; tag->link = LINK_EMPTY; tag->link_sel = LINK_EMPTY; list_init(&tag->tracks); @@ -88,62 +88,15 @@ track_free(struct track *t) free(t); } -void -tracks_load(struct tag *tag) +bool +tag_name_cmp(struct link *l1, struct link *l2) { - char linebuf[1024]; - char *index_path; - FILE *file; - - index_path = aprintf("%s/index", tag->fpath); - file = fopen(index_path, "r"); - if (file == NULL) { - index_update(tag); /* create index */ - file = fopen(index_path, "r"); - if (!file) ERROR(SYSTEM, "fopen %s", tag->name); - } + struct tag *t1, *t2; - while (fgets(linebuf, sizeof(linebuf), file)) { - if (!*linebuf) continue; - if (linebuf[strlen(linebuf) - 1] == '\n') - linebuf[strlen(linebuf) - 1] = '\0'; - track_add(tag, linebuf); - } + t1 = LINK_UPCAST(l1, struct tag, link); + t2 = LINK_UPCAST(l2, struct tag, link); - tag->index_dirty = false; - - fclose(file); - free(index_path); -} - -void -tracks_save(struct tag *tag) -{ - struct track *track; - struct link *link; - char *index_path; - FILE *file; - - /* write playlist back to index file */ - - index_path = aprintf("%s/index", tag->fpath); - file = fopen(index_path, "w+"); - if (!file) { - WARNX(SYSTEM, "Failed to write to index file: %s", - index_path); - free(index_path); - return; - } - - for (LIST_ITER(&tag->tracks, link)) { - track = UPCAST(link, struct track, link_tt); - fprintf(file, "%s\n", track->name); - } - - tag->index_dirty = false; - - fclose(file); - free(index_path); + return strcmp(t1->name, t2->name) <= 0; } bool @@ -259,55 +212,85 @@ move_file(const char *src, const char *dst) } void -index_update(struct tag *tag) +tag_clear_tracks(struct tag *tag) { - struct dirent *ent; + struct link *link; + struct track *track; + + while (!list_empty(&tag->tracks)) { + link = list_pop_front(&tag->tracks); + track = UPCAST(link, struct track, link_tt); + track_rm(track, false); + } +} + +void +tag_load_tracks(struct tag *tag) +{ + char linebuf[1024]; char *index_path; FILE *file; - DIR *dir; - - dir = opendir(tag->fpath); - if (!dir) ERROR(SYSTEM, "opendir %s", tag->fpath); index_path = aprintf("%s/index", tag->fpath); + file = fopen(index_path, "r"); + if (file == NULL) { + tag_reindex_tracks(tag); + return; + } - file = fopen(index_path, "w+"); - if (!file) ERROR(SYSTEM, "fopen %s/index", tag->name); + while (fgets(linebuf, sizeof(linebuf), file)) { + if (!*linebuf) continue; + if (linebuf[strlen(linebuf) - 1] == '\n') + linebuf[strlen(linebuf) - 1] = '\0'; + track_add(tag, linebuf); + } + + tag->index_dirty = false; + + fclose(file); free(index_path); +} - while ((ent = readdir(dir))) { - if (!strcmp(ent->d_name, ".")) - continue; - if (!strcmp(ent->d_name, "..")) - continue; +void +tag_save_tracks(struct tag *tag) +{ + struct track *track; + struct link *link; + char *index_path; + FILE *file; - /* skip files without extension */ - if (!strchr(ent->d_name + 1, '.')) - continue; + /* write playlist back to index file */ - fprintf(file, "%s\n", ent->d_name); + index_path = aprintf("%s/index", tag->fpath); + file = fopen(index_path, "w+"); + if (!file) { + WARNX(SYSTEM, "Failed to write to index file: %s", + index_path); + free(index_path); + return; } - closedir(dir); + for (LIST_ITER(&tag->tracks, link)) { + track = UPCAST(link, struct track, link_tt); + fprintf(file, "%s\n", track->name); + } + + tag->index_dirty = false; + fclose(file); + free(index_path); } bool -tracks_update(struct tag *tag) +tag_reindex_tracks(struct tag *tag) { - struct link *link; - struct track *track; struct dirent *ent; DIR *dir; dir = opendir(tag->fpath); if (!dir) return false; - while (!list_empty(&tag->tracks)) { - link = list_pop_front(&tag->tracks); - track = UPCAST(link, struct track, link_tt); - track_rm(track, false); - } + tag_clear_tracks(tag); while ((ent = readdir(dir))) { if (!strcmp(ent->d_name, ".")) @@ -690,11 +673,13 @@ data_load(void) tag = tag_add(ent->d_name); if (!strcmp(tag->name, "trash")) trash_tag = tag; - tracks_load(tag); + tag_load_tracks(tag); } free(path); } + list_sort(&tags, false, tag_name_cmp); + playlist_outdated = true; closedir(dir); @@ -709,7 +694,7 @@ data_save(void) for (LIST_ITER(&tags, link)) { tag = UPCAST(link, struct tag, link); if (tag->index_dirty) - tracks_save(tag); + tag_save_tracks(tag); } release_lock(datadir); diff --git a/src/data.h b/src/data.h @@ -8,6 +8,7 @@ struct tag { char *name, *fpath; struct list tracks; bool index_dirty; + bool reordered; struct link link; /* tags list */ struct link link_sel; /* selected tags list */ @@ -33,9 +34,6 @@ bool copy_file(const char *dst, const char *src); bool dup_file(const char *dst, const char *src); bool move_file(const char *dst, const char *src); -void index_update(struct tag *tag); -bool tracks_update(struct tag *tag); - struct track *tracks_vis_track(struct link *link); void playlist_clear(void); @@ -47,6 +45,11 @@ struct tag *tag_find(const char *name); bool tag_rm(struct tag *tag, bool sync_fs); bool tag_rename(struct tag *tag, const char *name); +void tag_clear_tracks(struct tag *tag); +void tag_load_tracks(struct tag *tag); +void tag_save_tracks(struct tag *tag); +bool tag_reindex_tracks(struct tag *tag); + 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); diff --git a/src/tui.c b/src/tui.c @@ -660,7 +660,17 @@ track_vis_name_cmp(struct link *l1, struct link *l2) void sort_visible_tracks(void) { + struct link *link; + struct tag *tag; + list_sort(tracks_vis, false, track_vis_name_cmp); + + if (!track_show_playlist) { + link = list_at(&tags, tag_nav.sel); + if (!link) return; + tag = LINK_UPCAST(link, struct tag, link); + tag->reordered = true; + } } bool @@ -1160,13 +1170,13 @@ reindex_selected_tags(void) if (track_show_playlist) { for (LIST_ITER(&tags_sel, link)) { tag = UPCAST(link, struct tag, link_sel); - tracks_update(tag); + tag_reindex_tracks(tag); } } else { link = list_at(&tags, tag_nav.sel); if (!link) return; tag = UPCAST(link, struct tag, link); - tracks_update(tag); + tag_reindex_tracks(tag); } if (playing_tag) {