DetachedSong: add attribute "real_uri"
Prepare for UPnP songs that retain there database identity.
This commit is contained in:
parent
483b1f51c9
commit
5d4b450c52
@ -402,7 +402,7 @@ decoder_run(DecoderControl &dc)
|
||||
|
||||
const std::string uri = song.IsFile()
|
||||
? map_song_fs(song).c_str()
|
||||
: song.GetURI();
|
||||
: song.GetRealURI();
|
||||
|
||||
if (uri.empty()) {
|
||||
dc.state = DecoderState::ERROR;
|
||||
|
@ -32,13 +32,23 @@ DetachedSong::DetachedSong(const LightSong &other)
|
||||
bool
|
||||
DetachedSong::IsRemote() const
|
||||
{
|
||||
return uri_has_scheme(uri.c_str());
|
||||
return uri_has_scheme(GetRealURI());
|
||||
}
|
||||
|
||||
bool
|
||||
DetachedSong::IsAbsoluteFile() const
|
||||
{
|
||||
return PathTraitsUTF8::IsAbsolute(uri.c_str());
|
||||
return PathTraitsUTF8::IsAbsolute(GetRealURI());
|
||||
}
|
||||
|
||||
bool
|
||||
DetachedSong::IsInDatabase() const
|
||||
{
|
||||
/* here, we use GetURI() and not GetRealURI() because
|
||||
GetRealURI() is never relative */
|
||||
|
||||
const char *_uri = GetURI();
|
||||
return !uri_has_scheme(_uri) && !PathTraitsUTF8::IsAbsolute(_uri);
|
||||
}
|
||||
|
||||
double
|
||||
|
@ -47,6 +47,16 @@ class DetachedSong {
|
||||
*/
|
||||
std::string uri;
|
||||
|
||||
/**
|
||||
* The "real" URI, the one to be used for opening the
|
||||
* resource. If this attribute is empty, then #uri shall be
|
||||
* used.
|
||||
*
|
||||
* This attribute is used for songs from the database which
|
||||
* have a relative URI.
|
||||
*/
|
||||
std::string real_uri;
|
||||
|
||||
Tag tag;
|
||||
|
||||
time_t mtime;
|
||||
@ -97,6 +107,29 @@ public:
|
||||
uri = std::forward<T>(_uri);
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this object have a "real" URI different from the
|
||||
* displayed URI?
|
||||
*/
|
||||
gcc_pure
|
||||
bool HasRealURI() const {
|
||||
return !real_uri.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns "real" URI (#real_uri) and falls back to just
|
||||
* GetURI().
|
||||
*/
|
||||
gcc_pure
|
||||
const char *GetRealURI() const {
|
||||
return (HasRealURI() ? real_uri : uri).c_str();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void SetRealURI(T &&_uri) {
|
||||
real_uri = std::forward<T>(_uri);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if both objects refer to the same physical
|
||||
* song.
|
||||
@ -123,9 +156,7 @@ public:
|
||||
bool IsAbsoluteFile() const;
|
||||
|
||||
gcc_pure
|
||||
bool IsInDatabase() const {
|
||||
return IsFile() && !IsAbsoluteFile();
|
||||
}
|
||||
bool IsInDatabase() const;
|
||||
|
||||
const Tag &GetTag() const {
|
||||
return tag;
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "Directory.hxx"
|
||||
#include "Song.hxx"
|
||||
#include "DetachedSong.hxx"
|
||||
#include "LightSong.hxx"
|
||||
#include "fs/AllocatedPath.hxx"
|
||||
#include "fs/Traits.hxx"
|
||||
#include "fs/Charset.hxx"
|
||||
@ -220,7 +221,15 @@ map_detached_song_fs(const char *uri_utf8)
|
||||
DetachedSong
|
||||
map_song_detach(const LightSong &song)
|
||||
{
|
||||
return DetachedSong(song);
|
||||
DetachedSong detached(song);
|
||||
|
||||
if (detached.IsInDatabase()) {
|
||||
const auto uri = song.GetURI();
|
||||
detached.SetRealURI(PathTraitsUTF8::Build(music_dir_utf8.c_str(),
|
||||
uri.c_str()));
|
||||
}
|
||||
|
||||
return detached;
|
||||
}
|
||||
|
||||
AllocatedPath
|
||||
@ -235,7 +244,7 @@ AllocatedPath
|
||||
map_song_fs(const DetachedSong &song)
|
||||
{
|
||||
if (song.IsAbsoluteFile())
|
||||
return AllocatedPath::FromUTF8(song.GetURI());
|
||||
return AllocatedPath::FromUTF8(song.GetRealURI());
|
||||
else
|
||||
return map_uri_fs(song.GetURI());
|
||||
}
|
||||
|
@ -38,7 +38,8 @@
|
||||
void
|
||||
playlist_print_song(FILE *file, const DetachedSong &song)
|
||||
{
|
||||
if (playlist_saveAbsolutePaths && song.IsInDatabase()) {
|
||||
if (playlist_saveAbsolutePaths &&
|
||||
song.IsInDatabase() && song.IsFile()) {
|
||||
const auto path = map_song_fs(song);
|
||||
if (!path.IsNull())
|
||||
fprintf(file, "%s\n", path.c_str());
|
||||
|
@ -30,7 +30,7 @@
|
||||
static bool
|
||||
UpdatePlaylistSong(const Database &db, DetachedSong &song)
|
||||
{
|
||||
if (!song.IsInDatabase())
|
||||
if (!song.IsInDatabase() || !song.IsFile())
|
||||
/* only update Songs instances that are "detached"
|
||||
from the Database */
|
||||
return false;
|
||||
|
@ -130,7 +130,7 @@ DetachedSong::Update()
|
||||
{
|
||||
if (IsAbsoluteFile()) {
|
||||
const AllocatedPath path_fs =
|
||||
AllocatedPath::FromUTF8(uri.c_str());
|
||||
AllocatedPath::FromUTF8(GetRealURI());
|
||||
|
||||
struct stat st;
|
||||
if (!StatFile(path_fs, st) || !S_ISREG(st.st_mode))
|
||||
|
Loading…
Reference in New Issue
Block a user