db/upnp/Object: add attribute "tag"
Replaces "m_title" and "m_props". More bloat removed.
This commit is contained in:
parent
4bcaf5d306
commit
676d8bb624
|
@ -210,21 +210,7 @@ upnpItemToSong(const UPnPDirObject &dirent, const char *uri)
|
||||||
uri = dirent.url.c_str();
|
uri = dirent.url.c_str();
|
||||||
|
|
||||||
Song *s = Song::NewFile(uri, nullptr);
|
Song *s = Song::NewFile(uri, nullptr);
|
||||||
|
s->tag = new Tag(dirent.tag);
|
||||||
TagBuilder tag;
|
|
||||||
|
|
||||||
if (dirent.duration > 0)
|
|
||||||
tag.SetTime(dirent.duration);
|
|
||||||
|
|
||||||
tag.AddItem(TAG_TITLE, dirent.m_title.c_str());
|
|
||||||
|
|
||||||
for (auto i = upnp_tags; i->name != nullptr; ++i) {
|
|
||||||
const char *value = dirent.getprop(i->name);
|
|
||||||
if (value != nullptr)
|
|
||||||
tag.AddItem(i->type, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
s->tag = tag.CommitNew();
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -267,27 +253,6 @@ UpnpDatabase::GetSong(const char *uri, Error &error) const
|
||||||
return song;
|
return song;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve the value for an MPD tag from an object entry.
|
|
||||||
*/
|
|
||||||
gcc_pure
|
|
||||||
static const char *
|
|
||||||
getTagValue(const UPnPDirObject &dirent, TagType tag)
|
|
||||||
{
|
|
||||||
if (tag == TAG_TITLE) {
|
|
||||||
if (!dirent.m_title.empty())
|
|
||||||
return dirent.m_title.c_str();
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *name = tag_table_lookup(upnp_tags, tag);
|
|
||||||
if (name == nullptr)
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
return dirent.getprop(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Double-quote a string, adding internal backslash escaping.
|
* Double-quote a string, adding internal backslash escaping.
|
||||||
*/
|
*/
|
||||||
|
@ -801,7 +766,7 @@ UpnpDatabase::VisitUniqueTags(const DatabaseSelection &selection,
|
||||||
dirent.item_class != UPnPDirObject::ItemClass::MUSIC)
|
dirent.item_class != UPnPDirObject::ItemClass::MUSIC)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const char *value = getTagValue(dirent, tag);
|
const char *value = dirent.tag.GetValue(tag);
|
||||||
if (value != nullptr) {
|
if (value != nullptr) {
|
||||||
#if defined(__clang__) || GCC_CHECK_VERSION(4,8)
|
#if defined(__clang__) || GCC_CHECK_VERSION(4,8)
|
||||||
values.emplace(value);
|
values.emplace(value);
|
||||||
|
|
|
@ -21,6 +21,9 @@
|
||||||
#include "Directory.hxx"
|
#include "Directory.hxx"
|
||||||
#include "Util.hxx"
|
#include "Util.hxx"
|
||||||
#include "Expat.hxx"
|
#include "Expat.hxx"
|
||||||
|
#include "Tags.hxx"
|
||||||
|
#include "tag/TagBuilder.hxx"
|
||||||
|
#include "tag/TagTable.hxx"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -28,14 +31,6 @@
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
static const char *const upnptags[] = {
|
|
||||||
"upnp:artist",
|
|
||||||
"upnp:album",
|
|
||||||
"upnp:genre",
|
|
||||||
"upnp:originalTrackNumber",
|
|
||||||
nullptr,
|
|
||||||
};
|
|
||||||
|
|
||||||
gcc_pure
|
gcc_pure
|
||||||
static UPnPDirObject::ItemClass
|
static UPnPDirObject::ItemClass
|
||||||
ParseItemClass(const char *name)
|
ParseItemClass(const char *name)
|
||||||
|
@ -77,6 +72,7 @@ titleToPathElt(std::string &&s)
|
||||||
class UPnPDirParser final : public CommonExpatParser {
|
class UPnPDirParser final : public CommonExpatParser {
|
||||||
std::vector<std::string> m_path;
|
std::vector<std::string> m_path;
|
||||||
UPnPDirObject m_tobj;
|
UPnPDirObject m_tobj;
|
||||||
|
TagBuilder tag;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
UPnPDirParser(UPnPDirContent& dir)
|
UPnPDirParser(UPnPDirContent& dir)
|
||||||
|
@ -130,7 +126,7 @@ protected:
|
||||||
const char *duration =
|
const char *duration =
|
||||||
GetAttribute(attrs, "duration");
|
GetAttribute(attrs, "duration");
|
||||||
if (duration != nullptr)
|
if (duration != nullptr)
|
||||||
m_tobj.duration = ParseDuration(duration);
|
tag.SetTime(ParseDuration(duration));
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -150,8 +146,10 @@ protected:
|
||||||
virtual void EndElement(const XML_Char *name)
|
virtual void EndElement(const XML_Char *name)
|
||||||
{
|
{
|
||||||
if ((!strcmp(name, "container") || !strcmp(name, "item")) &&
|
if ((!strcmp(name, "container") || !strcmp(name, "item")) &&
|
||||||
checkobjok())
|
checkobjok()) {
|
||||||
|
tag.Commit(m_tobj.tag);
|
||||||
m_dir.objects.push_back(std::move(m_tobj));
|
m_dir.objects.push_back(std::move(m_tobj));
|
||||||
|
}
|
||||||
|
|
||||||
m_path.pop_back();
|
m_path.pop_back();
|
||||||
}
|
}
|
||||||
|
@ -160,14 +158,19 @@ protected:
|
||||||
{
|
{
|
||||||
std::string str(s, len);
|
std::string str(s, len);
|
||||||
trimstring(str);
|
trimstring(str);
|
||||||
switch (m_path.back()[0]) {
|
|
||||||
case 'd':
|
|
||||||
if (!m_path.back().compare("dc:title")) {
|
|
||||||
m_tobj.m_title = str;
|
|
||||||
m_tobj.name = titleToPathElt(std::move(str));
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
TagType type = tag_table_lookup(upnp_tags,
|
||||||
|
m_path.back().c_str());
|
||||||
|
if (type != TAG_NUM_OF_ITEM_TYPES) {
|
||||||
|
tag.AddItem(type, str.c_str());
|
||||||
|
|
||||||
|
if (type == TAG_TITLE)
|
||||||
|
m_tobj.name = titleToPathElt(std::move(str));
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (m_path.back()[0]) {
|
||||||
case 'r':
|
case 'r':
|
||||||
if (!m_path.back().compare("res")) {
|
if (!m_path.back().compare("res")) {
|
||||||
m_tobj.url = str;
|
m_tobj.url = str;
|
||||||
|
@ -178,10 +181,6 @@ protected:
|
||||||
m_tobj.item_class = ParseItemClass(str.c_str());
|
m_tobj.item_class = ParseItemClass(str.c_str());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto i = upnptags; *i != nullptr; ++i)
|
|
||||||
if (!m_path.back().compare(*i))
|
|
||||||
m_tobj.m_props[*i] += str;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,8 +20,9 @@
|
||||||
#ifndef MPD_UPNP_OBJECT_HXX
|
#ifndef MPD_UPNP_OBJECT_HXX
|
||||||
#define MPD_UPNP_OBJECT_HXX
|
#define MPD_UPNP_OBJECT_HXX
|
||||||
|
|
||||||
|
#include "tag/Tag.hxx"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <map>
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* UpnP Media Server directory entry, converted from XML data.
|
* UpnP Media Server directory entry, converted from XML data.
|
||||||
|
@ -61,43 +62,21 @@ public:
|
||||||
std::string m_title; // dc:title. Directory name for a container.
|
std::string m_title; // dc:title. Directory name for a container.
|
||||||
Type type;
|
Type type;
|
||||||
ItemClass item_class;
|
ItemClass item_class;
|
||||||
// Properties as gathered from the XML document (url, artist, etc.)
|
|
||||||
// The map keys are the XML tag or attribute names.
|
|
||||||
std::map<std::string, std::string> m_props;
|
|
||||||
|
|
||||||
/**
|
Tag tag;
|
||||||
* Song duration in seconds. 0 if unknown.
|
|
||||||
*/
|
|
||||||
int duration;
|
|
||||||
|
|
||||||
UPnPDirObject() = default;
|
UPnPDirObject() = default;
|
||||||
UPnPDirObject(UPnPDirObject &&) = default;
|
UPnPDirObject(UPnPDirObject &&) = default;
|
||||||
UPnPDirObject &operator=(UPnPDirObject &&) = default;
|
UPnPDirObject &operator=(UPnPDirObject &&) = default;
|
||||||
|
|
||||||
/** Get named property
|
|
||||||
* @param property name (e.g. upnp:artist, upnp:album,
|
|
||||||
* upnp:originalTrackNumber, upnp:genre). Use m_title instead
|
|
||||||
* for dc:title.
|
|
||||||
* @param[out] value
|
|
||||||
* @return true if found.
|
|
||||||
*/
|
|
||||||
const char *getprop(const char *_name) const {
|
|
||||||
auto it = m_props.find(_name);
|
|
||||||
if (it == m_props.end())
|
|
||||||
return nullptr;
|
|
||||||
return it->second.c_str();
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear()
|
void clear()
|
||||||
{
|
{
|
||||||
m_id.clear();
|
m_id.clear();
|
||||||
m_pid.clear();
|
m_pid.clear();
|
||||||
url.clear();
|
url.clear();
|
||||||
m_title.clear();
|
|
||||||
type = Type::UNKNOWN;
|
type = Type::UNKNOWN;
|
||||||
item_class = ItemClass::UNKNOWN;
|
item_class = ItemClass::UNKNOWN;
|
||||||
m_props.clear();
|
tag.Clear();
|
||||||
duration = -1;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue