SongUpdate: use the Storage interface, support remote files
This commit finally allows the database update to scan remote files, e.g. using the smbclient storage plugin. However, it is not yet possible to configure that, therefore the feature is not accessible yet.
This commit is contained in:
parent
ad309cdeae
commit
29b18d9ab7
@ -21,7 +21,10 @@
|
|||||||
#include "DetachedSong.hxx"
|
#include "DetachedSong.hxx"
|
||||||
#include "db/Song.hxx"
|
#include "db/Song.hxx"
|
||||||
#include "db/Directory.hxx"
|
#include "db/Directory.hxx"
|
||||||
|
#include "storage/StorageInterface.hxx"
|
||||||
|
#include "storage/FileInfo.hxx"
|
||||||
#include "util/UriUtil.hxx"
|
#include "util/UriUtil.hxx"
|
||||||
|
#include "util/Error.hxx"
|
||||||
#include "Mapper.hxx"
|
#include "Mapper.hxx"
|
||||||
#include "fs/AllocatedPath.hxx"
|
#include "fs/AllocatedPath.hxx"
|
||||||
#include "fs/Traits.hxx"
|
#include "fs/Traits.hxx"
|
||||||
@ -42,7 +45,7 @@
|
|||||||
#ifdef ENABLE_DATABASE
|
#ifdef ENABLE_DATABASE
|
||||||
|
|
||||||
Song *
|
Song *
|
||||||
Song::LoadFile(const char *path_utf8, Directory &parent)
|
Song::LoadFile(Storage &storage, const char *path_utf8, Directory &parent)
|
||||||
{
|
{
|
||||||
assert(!uri_has_scheme(path_utf8));
|
assert(!uri_has_scheme(path_utf8));
|
||||||
assert(strchr(path_utf8, '\n') == nullptr);
|
assert(strchr(path_utf8, '\n') == nullptr);
|
||||||
@ -52,7 +55,7 @@ Song::LoadFile(const char *path_utf8, Directory &parent)
|
|||||||
//in archive ?
|
//in archive ?
|
||||||
bool success = parent.device == DEVICE_INARCHIVE
|
bool success = parent.device == DEVICE_INARCHIVE
|
||||||
? song->UpdateFileInArchive()
|
? song->UpdateFileInArchive()
|
||||||
: song->UpdateFile();
|
: song->UpdateFile(storage);
|
||||||
if (!success) {
|
if (!success) {
|
||||||
song->Free();
|
song->Free();
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -77,27 +80,36 @@ tag_scan_fallback(Path path,
|
|||||||
#ifdef ENABLE_DATABASE
|
#ifdef ENABLE_DATABASE
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Song::UpdateFile()
|
Song::UpdateFile(Storage &storage)
|
||||||
{
|
{
|
||||||
const auto path_fs = map_song_fs(*this);
|
const auto &relative_uri = GetURI();
|
||||||
if (path_fs.IsNull())
|
|
||||||
|
FileInfo info;
|
||||||
|
if (!storage.GetInfo(relative_uri.c_str(), true, info, IgnoreError()))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
struct stat st;
|
if (!info.IsRegular())
|
||||||
if (!StatFile(path_fs, st) || !S_ISREG(st.st_mode))
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
TagBuilder tag_builder;
|
TagBuilder tag_builder;
|
||||||
if (!tag_file_scan(path_fs,
|
|
||||||
|
const auto path_fs = storage.MapFS(relative_uri.c_str());
|
||||||
|
if (path_fs.IsNull()) {
|
||||||
|
const auto absolute_uri =
|
||||||
|
storage.MapUTF8(relative_uri.c_str());
|
||||||
|
if (!tag_stream_scan(absolute_uri.c_str(),
|
||||||
full_tag_handler, &tag_builder))
|
full_tag_handler, &tag_builder))
|
||||||
return false;
|
return false;
|
||||||
|
} else {
|
||||||
|
if (!tag_file_scan(path_fs, full_tag_handler, &tag_builder))
|
||||||
|
return false;
|
||||||
|
|
||||||
if (tag_builder.IsEmpty())
|
if (tag_builder.IsEmpty())
|
||||||
tag_scan_fallback(path_fs, &full_tag_handler,
|
tag_scan_fallback(path_fs, &full_tag_handler,
|
||||||
&tag_builder);
|
&tag_builder);
|
||||||
|
}
|
||||||
|
|
||||||
mtime = st.st_mtime;
|
mtime = info.mtime;
|
||||||
|
|
||||||
tag_builder.Commit(tag);
|
tag_builder.Commit(tag);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
struct LightSong;
|
struct LightSong;
|
||||||
struct Directory;
|
struct Directory;
|
||||||
class DetachedSong;
|
class DetachedSong;
|
||||||
|
class Storage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A song file inside the configured music directory.
|
* A song file inside the configured music directory.
|
||||||
@ -91,11 +92,12 @@ struct Song {
|
|||||||
* data, nullptr is returned.
|
* data, nullptr is returned.
|
||||||
*/
|
*/
|
||||||
gcc_malloc
|
gcc_malloc
|
||||||
static Song *LoadFile(const char *path_utf8, Directory &parent);
|
static Song *LoadFile(Storage &storage, const char *name_utf8,
|
||||||
|
Directory &parent);
|
||||||
|
|
||||||
void Free();
|
void Free();
|
||||||
|
|
||||||
bool UpdateFile();
|
bool UpdateFile(Storage &storage);
|
||||||
bool UpdateFileInArchive();
|
bool UpdateFileInArchive();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -65,7 +65,7 @@ UpdateWalk::UpdateArchiveTree(Directory &directory, const char *name)
|
|||||||
Song *song = directory.FindSong(name);
|
Song *song = directory.FindSong(name);
|
||||||
db_unlock();
|
db_unlock();
|
||||||
if (song == nullptr) {
|
if (song == nullptr) {
|
||||||
song = Song::LoadFile(name, directory);
|
song = Song::LoadFile(storage, name, directory);
|
||||||
if (song != nullptr) {
|
if (song != nullptr) {
|
||||||
db_lock();
|
db_lock();
|
||||||
directory.AddSong(song);
|
directory.AddSong(song);
|
||||||
|
@ -61,7 +61,7 @@ UpdateWalk::UpdateSongFile2(Directory &directory,
|
|||||||
if (song == nullptr) {
|
if (song == nullptr) {
|
||||||
FormatDebug(update_domain, "reading %s/%s",
|
FormatDebug(update_domain, "reading %s/%s",
|
||||||
directory.GetPath(), name);
|
directory.GetPath(), name);
|
||||||
song = Song::LoadFile(name, directory);
|
song = Song::LoadFile(storage, name, directory);
|
||||||
if (song == nullptr) {
|
if (song == nullptr) {
|
||||||
FormatDebug(update_domain,
|
FormatDebug(update_domain,
|
||||||
"ignoring unrecognized file %s/%s",
|
"ignoring unrecognized file %s/%s",
|
||||||
@ -79,7 +79,7 @@ UpdateWalk::UpdateSongFile2(Directory &directory,
|
|||||||
} else if (info.mtime != song->mtime || walk_discard) {
|
} else if (info.mtime != song->mtime || walk_discard) {
|
||||||
FormatDefault(update_domain, "updating %s/%s",
|
FormatDefault(update_domain, "updating %s/%s",
|
||||||
directory.GetPath(), name);
|
directory.GetPath(), name);
|
||||||
if (!song->UpdateFile()) {
|
if (!song->UpdateFile(storage)) {
|
||||||
FormatDebug(update_domain,
|
FormatDebug(update_domain,
|
||||||
"deleting unrecognized file %s/%s",
|
"deleting unrecognized file %s/%s",
|
||||||
directory.GetPath(), name);
|
directory.GetPath(), name);
|
||||||
|
Loading…
Reference in New Issue
Block a user