diff options
Diffstat (limited to 'src/SongUpdate.cxx')
-rw-r--r-- | src/SongUpdate.cxx | 142 |
1 files changed, 91 insertions, 51 deletions
diff --git a/src/SongUpdate.cxx b/src/SongUpdate.cxx index 1a873fedc..0245b9117 100644 --- a/src/SongUpdate.cxx +++ b/src/SongUpdate.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 The Music Player Daemon Project + * Copyright (C) 2003-2014 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -18,50 +18,44 @@ */ #include "config.h" /* must be first for large file support */ -#include "Song.hxx" +#include "DetachedSong.hxx" +#include "db/plugins/simple/Song.hxx" +#include "db/plugins/simple/Directory.hxx" +#include "storage/StorageInterface.hxx" +#include "storage/FileInfo.hxx" #include "util/UriUtil.hxx" #include "util/Error.hxx" -#include "Directory.hxx" -#include "Mapper.hxx" #include "fs/AllocatedPath.hxx" #include "fs/Traits.hxx" #include "fs/FileSystem.hxx" -#include "InputStream.hxx" -#include "DecoderPlugin.hxx" -#include "DecoderList.hxx" +#include "decoder/DecoderList.hxx" #include "tag/Tag.hxx" #include "tag/TagBuilder.hxx" #include "tag/TagHandler.hxx" #include "tag/TagId3.hxx" #include "tag/ApeTag.hxx" #include "TagFile.hxx" -#include "thread/Cond.hxx" +#include "TagStream.hxx" #include <assert.h> #include <string.h> -#include <sys/types.h> #include <sys/stat.h> -#include <stdio.h> + +#ifdef ENABLE_DATABASE Song * -Song::LoadFile(const char *path_utf8, Directory *parent) +Song::LoadFile(Storage &storage, const char *path_utf8, Directory &parent) { - Song *song; - bool ret; - - assert((parent == nullptr) == PathTraits::IsAbsoluteUTF8(path_utf8)); assert(!uri_has_scheme(path_utf8)); assert(strchr(path_utf8, '\n') == nullptr); - song = NewFile(path_utf8, parent); + Song *song = NewFile(path_utf8, parent); //in archive ? - if (parent != nullptr && parent->device == DEVICE_INARCHIVE) { - ret = song->UpdateFileInArchive(); - } else { - ret = song->UpdateFile(); - } - if (!ret) { + bool success = parent.device == DEVICE_INARCHIVE + ? song->UpdateFileInArchive(storage) + : song->UpdateFile(storage); + if (!success) { song->Free(); return nullptr; } @@ -69,6 +63,8 @@ Song::LoadFile(const char *path_utf8, Directory *parent) return song; } +#endif + /** * Attempts to load APE or ID3 tags from the specified file. */ @@ -80,59 +76,103 @@ tag_scan_fallback(Path path, tag_id3_scan(path, handler, handler_ctx); } +#ifdef ENABLE_DATABASE + bool -Song::UpdateFile() +Song::UpdateFile(Storage &storage) { - assert(IsFile()); + const auto &relative_uri = GetURI(); - const auto path_fs = map_song_fs(*this); - if (path_fs.IsNull()) + FileInfo info; + if (!storage.GetInfo(relative_uri.c_str(), true, info, IgnoreError())) return false; - struct stat st; - if (!StatFile(path_fs, st) || !S_ISREG(st.st_mode)) + if (!info.IsRegular()) return false; TagBuilder tag_builder; - if (!tag_file_scan(path_fs, - &full_tag_handler, &tag_builder)) - return false; - if (tag_builder.IsEmpty()) - tag_scan_fallback(path_fs, &full_tag_handler, - &tag_builder); + 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)) + return false; + } else { + if (!tag_file_scan(path_fs, full_tag_handler, &tag_builder)) + return false; - mtime = st.st_mtime; + if (tag_builder.IsEmpty()) + tag_scan_fallback(path_fs, &full_tag_handler, + &tag_builder); + } - delete tag; - tag = tag_builder.Commit(); + mtime = info.mtime; + tag_builder.Commit(tag); return true; } bool -Song::UpdateFileInArchive() +Song::UpdateFileInArchive(const Storage &storage) { - const char *suffix; - const struct DecoderPlugin *plugin; - - assert(IsFile()); - /* check if there's a suffix and a plugin */ - suffix = uri_get_suffix(uri); + const char *suffix = uri_get_suffix(uri); if (suffix == nullptr) return false; - plugin = decoder_plugin_from_suffix(suffix, nullptr); - if (plugin == nullptr) + if (!decoder_plugins_supports_suffix(suffix)) return false; - delete tag; + const auto path_fs = parent->IsRoot() + ? storage.MapFS(uri) + : storage.MapChildFS(parent->GetPath(), uri); + if (path_fs.IsNull()) + return false; - //accept every file that has music suffix - //because we don't support tag reading through - //input streams - tag = new Tag(); + TagBuilder tag_builder; + if (!tag_stream_scan(path_fs.c_str(), full_tag_handler, &tag_builder)) + return false; + tag_builder.Commit(tag); return true; } + +#endif + +bool +DetachedSong::Update() +{ + if (IsAbsoluteFile()) { + const AllocatedPath path_fs = + AllocatedPath::FromUTF8(GetRealURI()); + + struct stat st; + if (!StatFile(path_fs, st) || !S_ISREG(st.st_mode)) + return false; + + TagBuilder tag_builder; + if (!tag_file_scan(path_fs, full_tag_handler, &tag_builder)) + return false; + + if (tag_builder.IsEmpty()) + tag_scan_fallback(path_fs, &full_tag_handler, + &tag_builder); + + mtime = st.st_mtime; + tag_builder.Commit(tag); + return true; + } else if (IsRemote()) { + TagBuilder tag_builder; + if (!tag_stream_scan(uri.c_str(), full_tag_handler, + &tag_builder)) + return false; + + mtime = 0; + tag_builder.Commit(tag); + return true; + } else + // TODO: implement + return false; +} |