Skip to content

Commit

Permalink
Add "added" timestamp to song database
Browse files Browse the repository at this point in the history
addedtime is only set to mtime, if a new song is added to the database.

Code for proxy plugin is missing, this needs a patch for libmpdclient.

closes #378
  • Loading branch information
jcorporation committed Oct 5, 2023
1 parent b81cac3 commit c800010
Show file tree
Hide file tree
Showing 15 changed files with 83 additions and 0 deletions.
6 changes: 6 additions & 0 deletions src/SongPrint.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ song_print_info(Response &r, const LightSong &song, bool base) noexcept
if (!IsNegative(song.mtime))
time_print(r, "Last-Modified", song.mtime);

if (!IsNegative(song.addedtime))
time_print(r, "Added", song.addedtime);

if (song.audio_format.IsDefined())
r.Fmt(FMT_STRING("Format: {}\n"), song.audio_format);

Expand All @@ -100,6 +103,9 @@ song_print_info(Response &r, const DetachedSong &song, bool base) noexcept
if (!IsNegative(song.GetLastModified()))
time_print(r, "Last-Modified", song.GetLastModified());

if (!IsNegative(song.GetAdded()))
time_print(r, "Added", song.GetAdded());

if (const auto &f = song.GetAudioFormat(); f.IsDefined())
r.Fmt(FMT_STRING("Format: {}\n"), f);

Expand Down
11 changes: 11 additions & 0 deletions src/SongSave.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <stdlib.h>

#define SONG_MTIME "mtime"
#define SONG_ADDEDTIME "addedtime"
#define SONG_END "song_end"

static void
Expand Down Expand Up @@ -54,6 +55,10 @@ song_save(BufferedOutputStream &os, const Song &song)
if (!IsNegative(song.mtime))
os.Fmt(FMT_STRING(SONG_MTIME ": {}\n"),
std::chrono::system_clock::to_time_t(song.mtime));

if (!IsNegative(song.addedtime))
os.Fmt(FMT_STRING(SONG_ADDEDTIME ": {}\n"),
std::chrono::system_clock::to_time_t(song.addedtime));
os.Write(SONG_END "\n");
}

Expand All @@ -69,6 +74,10 @@ song_save(BufferedOutputStream &os, const DetachedSong &song)
if (!IsNegative(song.GetLastModified()))
os.Fmt(FMT_STRING(SONG_MTIME ": {}\n"),
std::chrono::system_clock::to_time_t(song.GetLastModified()));

if (!IsNegative(song.GetAdded()))
os.Fmt(FMT_STRING(SONG_ADDEDTIME ": {}\n"),
std::chrono::system_clock::to_time_t(song.GetAdded()));
os.Write(SONG_END "\n");
}

Expand Down Expand Up @@ -109,6 +118,8 @@ song_load(LineReader &file, const char *uri,
tag.SetHasPlaylist(StringIsEqual(value, "yes"));
} else if (StringIsEqual(line, SONG_MTIME)) {
song.SetLastModified(std::chrono::system_clock::from_time_t(atoi(value)));
} else if (StringIsEqual(line, SONG_ADDEDTIME)) {
song.SetAdded(std::chrono::system_clock::from_time_t(atoi(value)));
} else if (StringIsEqual(line, "Range")) {
char *endptr;

Expand Down
3 changes: 3 additions & 0 deletions src/command/DatabaseCommands.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ ParseSortTag(const char *s)
if (StringIsEqualIgnoreCase(s, "Last-Modified"))
return TagType(SORT_TAG_LAST_MODIFIED);

if (StringIsEqualIgnoreCase(s, "Added"))
return TagType(SORT_TAG_ADDED);

TagType tag = tag_name_parse_i(s);
if (tag == TAG_NUM_OF_ITEM_TYPES)
throw ProtocolError(ACK_ERROR_ARG, "Unknown sort tag");
Expand Down
3 changes: 3 additions & 0 deletions src/command/QueueCommands.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,9 @@ ParseSortTag(const char *s)
if (StringIsEqualIgnoreCase(s, "Last-Modified"))
return TagType(SORT_TAG_LAST_MODIFIED);

if (StringIsEqualIgnoreCase(s, "Added"))
return TagType(SORT_TAG_ADDED);

if (StringIsEqualIgnoreCase(s, "prio"))
return TagType(SORT_TAG_PRIO);

Expand Down
7 changes: 7 additions & 0 deletions src/db/VHelper.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,13 @@ DatabaseVisitorHelper::Commit()
? a.GetLastModified() > b.GetLastModified()
: a.GetLastModified() < b.GetLastModified();
});
else if (sort == TagType(SORT_TAG_ADDED))
std::stable_sort(songs.begin(), songs.end(),
[descending](const DetachedSong &a, const DetachedSong &b){
return descending
? a.GetAdded() > b.GetAdded()
: a.GetAdded() < b.GetAdded();
});
else
std::stable_sort(songs.begin(), songs.end(),
[sort, descending](const DetachedSong &a,
Expand Down
4 changes: 4 additions & 0 deletions src/db/plugins/simple/Song.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Song::Song(DetachedSong &&other, Directory &_parent) noexcept
filename(other.GetURI()),
tag(std::move(other.WritableTag())),
mtime(other.GetLastModified()),
addedtime(other.GetAdded()),
start_time(other.GetStartTime()),
end_time(other.GetEndTime()),
audio_format(other.GetAudioFormat())
Expand Down Expand Up @@ -117,6 +118,9 @@ Song::Export() const noexcept
dest.mtime = IsNegative(mtime) && target_song != nullptr
? target_song->mtime
: mtime;
dest.addedtime = IsNegative(addedtime) && target_song != nullptr
? target_song->addedtime
: addedtime;
dest.start_time = start_time.IsZero() && target_song != nullptr
? target_song->start_time
: start_time;
Expand Down
7 changes: 7 additions & 0 deletions src/db/plugins/simple/Song.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,13 @@ struct Song : IntrusiveListHook<> {
std::chrono::system_clock::time_point mtime =
std::chrono::system_clock::time_point::min();

/**
* The time stamp when the file was added. A negative
* value means that this is unknown/unavailable.
*/
std::chrono::system_clock::time_point addedtime =
std::chrono::system_clock::time_point::min();

/**
* Start of this sub-song within the file.
*/
Expand Down
1 change: 1 addition & 0 deletions src/db/update/UpdateSong.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ try {
}

new_song->mark = true;
new_song->addedtime = new_song->mtime;

{
const ScopeDatabaseLock protect;
Expand Down
1 change: 1 addition & 0 deletions src/playlist/PlaylistSong.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ merge_song_metadata(DetachedSong &add, const DetachedSong &base) noexcept
}

add.SetLastModified(base.GetLastModified());
add.SetAdded(base.GetAdded());

if (add.GetStartTime().IsZero()) {
add.SetStartTime(base.GetStartTime());
Expand Down
1 change: 1 addition & 0 deletions src/queue/PlaylistUpdate.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ UpdatePlaylistSong(const Database &db, DetachedSong &song)
}

song.SetLastModified(original->mtime);
song.SetAdded(original->addedtime);
song.SetTag(original->tag);

db.ReturnSong(original);
Expand Down
11 changes: 11 additions & 0 deletions src/queue/Print.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,17 @@ PrintSortedQueue(Response &r, const Queue &queue,

return a.GetLastModified() < b.GetLastModified();
});
else if (sort == TagType(SORT_TAG_ADDED))
std::stable_sort(v.begin(), v.end(),
[&queue, descending](unsigned a_pos, unsigned b_pos){
if (descending)
std::swap(a_pos, b_pos);

const auto &a = queue.Get(a_pos);
const auto &b = queue.Get(b_pos);

return a.GetAdded() < b.GetAdded();
});
else if (sort == TagType(SORT_TAG_PRIO))
std::stable_sort(v.begin(), v.end(),
[&queue, descending](unsigned a_pos, unsigned b_pos){
Expand Down
2 changes: 2 additions & 0 deletions src/song/DetachedSong.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ DetachedSong::DetachedSong(const LightSong &other) noexcept
real_uri(other.real_uri != nullptr ? other.real_uri : ""),
tag(other.tag),
mtime(other.mtime),
addedtime(other.addedtime),
start_time(other.start_time),
end_time(other.end_time),
audio_format(other.audio_format) {}
Expand All @@ -21,6 +22,7 @@ DetachedSong::operator LightSong() const noexcept
result.directory = nullptr;
result.real_uri = real_uri.empty() ? nullptr : real_uri.c_str();
result.mtime = mtime;
result.addedtime = addedtime;
result.start_time = start_time;
result.end_time = end_time;
return result;
Expand Down
15 changes: 15 additions & 0 deletions src/song/DetachedSong.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,13 @@ class DetachedSong {
std::chrono::system_clock::time_point mtime =
std::chrono::system_clock::time_point::min();

/**
* The time stamp when the file was added to db. A negative
* value means that this is unknown/unavailable.
*/
std::chrono::system_clock::time_point addedtime =
std::chrono::system_clock::time_point::min();

/**
* Start of this sub-song within the file.
*/
Expand Down Expand Up @@ -212,6 +219,14 @@ public:
mtime = _value;
}

std::chrono::system_clock::time_point GetAdded() const noexcept {
return mtime;
}

void SetAdded(std::chrono::system_clock::time_point _value) noexcept {
addedtime = _value;
}

SongTime GetStartTime() const noexcept {
return start_time;
}
Expand Down
5 changes: 5 additions & 0 deletions src/song/Filter.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@
*/
#define SORT_TAG_PRIO (TAG_NUM_OF_ITEM_TYPES + 4)

/**
* Special value for the db_selection_print() sort parameter.
*/
#define SORT_TAG_ADDED (TAG_NUM_OF_ITEM_TYPES + 5)

enum TagType : uint8_t;
struct LightSong;

Expand Down
6 changes: 6 additions & 0 deletions src/song/LightSong.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@ struct LightSong {
*/
std::chrono::system_clock::time_point mtime = std::chrono::system_clock::time_point::min();

/**
* The time stamp when the file was added. A negative
* value means that this is unknown/unavailable.
*/
std::chrono::system_clock::time_point addedtime = std::chrono::system_clock::time_point::min();

/**
* Start of this sub-song within the file.
*/
Expand Down

0 comments on commit c800010

Please sign in to comment.