Merge pull request #25959 from neo1973/TagLib_deprecation_warnings
[xbmc.git] / lib / libUPnP / patches / 0027-platinum-add-support-for-xbmc-specific-fields-datead.patch
blobba7593fa8a0df16c4179a2554d4d1e9779ef4144
1 From ac80794eedc6e240671ce3b60ecb4a24c58f84ab Mon Sep 17 00:00:00 2001
2 From: montellese <montellese@xbmc.org>
3 Date: Mon, 19 May 2014 20:56:25 +0200
4 Subject: [PATCH 04/11] platinum: add support for xbmc specific fields
5 dateadded, rating, votes and artwork
7 xbmc:dateadded to pass dateadded with items and not need to stat upnp resources for that
8 xbmc:rating for number-based rating
9 xbmc:votes for string-based votes number
10 xbmc:artwork for a type-url-based mapping of artwork
11 ---
12 .../Source/Devices/MediaServer/PltDidl.cpp | 12 ++-
13 .../Platinum/Source/Devices/MediaServer/PltDidl.h | 11 +++
14 .../Source/Devices/MediaServer/PltMediaItem.cpp | 109 +++++++++++++++++++++
15 .../Source/Devices/MediaServer/PltMediaItem.h | 23 +++++
16 .../Devices/MediaServer/PltSyncMediaBrowser.h | 2 +-
17 5 files changed, 155 insertions(+), 2 deletions(-)
19 diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltDidl.cpp b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltDidl.cpp
20 index 0758ad5..2bb6a04 100644
21 --- a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltDidl.cpp
22 +++ b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltDidl.cpp
23 @@ -47,11 +47,13 @@ NPT_SET_LOCAL_LOGGER("platinum.media.server.didl")
24 const char* didl_header = "<DIDL-Lite xmlns=\"urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/\""
25 " xmlns:dc=\"http://purl.org/dc/elements/1.1/\""
26 " xmlns:upnp=\"urn:schemas-upnp-org:metadata-1-0/upnp/\""
27 - " xmlns:dlna=\"urn:schemas-dlna-org:metadata-1-0/\">";
28 + " xmlns:dlna=\"urn:schemas-dlna-org:metadata-1-0/\""
29 + " xmlns:xbmc=\"urn:schemas-xbmc-org:metadata-1-0/\">";
30 const char* didl_footer = "</DIDL-Lite>";
31 const char* didl_namespace_dc = "http://purl.org/dc/elements/1.1/";
32 const char* didl_namespace_upnp = "urn:schemas-upnp-org:metadata-1-0/upnp/";
33 const char* didl_namespace_dlna = "urn:schemas-dlna-org:metadata-1-0/";
34 +const char* didl_namespace_xbmc = "urn:schemas-xbmc-org:metadata-1-0/";
36 /*----------------------------------------------------------------------
37 | PLT_Didl::ConvertFilterToMask
38 @@ -160,6 +162,14 @@ PLT_Didl::ConvertFilterToMask(const NPT_String& filter)
39 mask |= PLT_FILTER_MASK_EPISODE_COUNT;
40 } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_EPISODE_SEASON, len, true) == 0) {
41 mask |= PLT_FILTER_MASK_EPISODE_SEASON;
42 + } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_XBMC_DATEADDED, len, true) == 0) {
43 + mask |= PLT_FILTER_MASK_XBMC_DATEADDED;
44 + } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_XBMC_RATING, len, true) == 0) {
45 + mask |= PLT_FILTER_MASK_XBMC_RATING;
46 + } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_XBMC_VOTES, len, true) == 0) {
47 + mask |= PLT_FILTER_MASK_XBMC_VOTES;
48 + } else if (NPT_String::CompareN(s+i, PLT_FILTER_FIELD_XBMC_ARTWORK, len, true) == 0) {
49 + mask |= PLT_FILTER_MASK_XBMC_ARTWORK;
52 if (next_comma < 0) {
53 diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltDidl.h b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltDidl.h
54 index 2271162..0f7c892 100644
55 --- a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltDidl.h
56 +++ b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltDidl.h
57 @@ -95,6 +95,11 @@
58 #define PLT_FILTER_MASK_EPISODE_COUNT NPT_UINT64_C(0x0000001000000000)
59 #define PLT_FILTER_MASK_EPISODE_SEASON NPT_UINT64_C(0x0000002000000000)
61 +#define PLT_FILTER_MASK_XBMC_DATEADDED NPT_UINT64_C(0x0000100000000000)
62 +#define PLT_FILTER_MASK_XBMC_RATING NPT_UINT64_C(0x0000200000000000)
63 +#define PLT_FILTER_MASK_XBMC_VOTES NPT_UINT64_C(0x0000300000000000)
64 +#define PLT_FILTER_MASK_XBMC_ARTWORK NPT_UINT64_C(0x0000400000000000)
66 #define PLT_FILTER_FIELD_TITLE "dc:title"
67 #define PLT_FILTER_FIELD_CREATOR "dc:creator"
68 #define PLT_FILTER_FIELD_DATE "dc:date"
69 @@ -139,11 +144,17 @@
70 #define PLT_FILTER_FIELD_EPISODE_COUNT "upnp:episodeCount"
71 #define PLT_FILTER_FIELD_EPISODE_SEASON "upnp:episodeSeason"
73 +#define PLT_FILTER_FIELD_XBMC_DATEADDED "xbmc:dateadded"
74 +#define PLT_FILTER_FIELD_XBMC_RATING "xbmc:rating"
75 +#define PLT_FILTER_FIELD_XBMC_VOTES "xbmc:votes"
76 +#define PLT_FILTER_FIELD_XBMC_ARTWORK "xbmc:artwork"
78 extern const char* didl_header;
79 extern const char* didl_footer;
80 extern const char* didl_namespace_dc;
81 extern const char* didl_namespace_upnp;
82 extern const char* didl_namespace_dlna;
83 +extern const char* didl_namespace_xbmc;
85 /*----------------------------------------------------------------------
86 | PLT_Didl
87 diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.cpp b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.cpp
88 index a8855cc..5c2ec84 100644
89 --- a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.cpp
90 +++ b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.cpp
91 @@ -110,6 +110,62 @@ PLT_PersonRoles::FromDidl(const NPT_Array<NPT_XmlElementNode*>& nodes)
94 /*----------------------------------------------------------------------
95 +| PLT_Artworks::Add
96 ++---------------------------------------------------------------------*/
97 +NPT_Result
98 +PLT_Artworks::Add(const NPT_String& type, const NPT_String& url)
100 + PLT_Artwork artwork;
101 + artwork.type = type;
102 + artwork.url = url;
104 + return NPT_List<PLT_Artwork>::Add(artwork);
107 +/*----------------------------------------------------------------------
108 +| PLT_Artworks::ToDidl
109 ++---------------------------------------------------------------------*/
110 +NPT_Result
111 +PLT_Artworks::ToDidl(NPT_String& didl, const NPT_String& tag)
113 + NPT_String tmp;
114 + for (NPT_List<PLT_Artwork>::Iterator it =
115 + NPT_List<PLT_Artwork>::GetFirstItem(); it; it++) {
116 + if (it->type.IsEmpty()) continue;
118 + tmp += "<xbmc:" + tag;
119 + if (!it->type.IsEmpty()) {
120 + tmp += " type=\"";
121 + PLT_Didl::AppendXmlEscape(tmp, it->type);
122 + tmp += "\"";
124 + tmp += ">";
125 + PLT_Didl::AppendXmlEscape(tmp, it->url);
126 + tmp += "</xbmc:" + tag + ">";
129 + didl += tmp;
130 + return NPT_SUCCESS;
133 +/*----------------------------------------------------------------------
134 +| PLT_Artworks::ToDidl
135 ++---------------------------------------------------------------------*/
136 +NPT_Result
137 +PLT_Artworks::FromDidl(const NPT_Array<NPT_XmlElementNode*>& nodes)
139 + for (NPT_Cardinal i=0; i<nodes.GetItemCount(); i++) {
140 + PLT_Artwork artwork;
141 + const NPT_String* url = nodes[i]->GetText();
142 + const NPT_String* type = nodes[i]->GetAttribute("type");
143 + if (type) artwork.type = *type;
144 + if (url) artwork.url = *url;
145 + NPT_CHECK(NPT_List<PLT_Artwork>::Add(artwork));
147 + return NPT_SUCCESS;
150 +/*----------------------------------------------------------------------
151 | PLT_MediaItemResource::PLT_MediaItemResource
152 +---------------------------------------------------------------------*/
153 PLT_MediaItemResource::PLT_MediaItemResource()
154 @@ -200,6 +256,11 @@ PLT_MediaObject::Reset()
156 m_Resources.Clear();
158 + m_XbmcInfo.date_added = "";
159 + m_XbmcInfo.rating = 0.0f;
160 + m_XbmcInfo.votes = "";
161 + m_XbmcInfo.artwork.Clear();
163 m_Didl = "";
165 return NPT_SUCCESS;
166 @@ -472,6 +533,32 @@ PLT_MediaObject::ToDidl(NPT_UInt64 mask, NPT_String& didl)
170 + // xbmc dateadded
171 + if ((mask & PLT_FILTER_MASK_XBMC_DATEADDED) && !m_XbmcInfo.date_added.IsEmpty()) {
172 + didl += "<xbmc:dateadded>";
173 + PLT_Didl::AppendXmlEscape(didl, m_XbmcInfo.date_added);
174 + didl += "</xbmc:dateadded>";
175 + }
177 + // xbmc rating
178 + if (mask & PLT_FILTER_MASK_XBMC_RATING) {
179 + didl += "<xbmc:rating>";
180 + didl += NPT_String::Format("%.1f", m_XbmcInfo.rating);
181 + didl += "</xbmc:rating>";
184 + // xbmc votes
185 + if (mask & PLT_FILTER_MASK_XBMC_VOTES && !m_XbmcInfo.votes.IsEmpty()) {
186 + didl += "<xbmc:votes>";
187 + PLT_Didl::AppendXmlEscape(didl, m_XbmcInfo.votes);
188 + didl += "</xbmc:votes>";
191 + // xbmc artwork
192 + if (mask & PLT_FILTER_MASK_XBMC_ARTWORK) {
193 + m_XbmcInfo.artwork.ToDidl(didl, "artwork");
196 // class is required
197 didl += "<upnp:class";
198 if (!m_ObjectClass.friendly_name.IsEmpty()) {
199 @@ -672,6 +759,28 @@ PLT_MediaObject::FromDidl(NPT_XmlElementNode* entry)
200 m_Resources.Add(resource);
203 + PLT_XmlHelper::GetChildText(entry, "dateadded", m_XbmcInfo.date_added, didl_namespace_xbmc, 256);
204 + // parse date and make sure it's valid
205 + for (int format=0; format<=NPT_DateTime::FORMAT_RFC_1036; format++) {
206 + NPT_DateTime date;
207 + if (NPT_SUCCEEDED(date.FromString(m_XbmcInfo.date_added, (NPT_DateTime::Format)format))) {
208 + parsed_date = date.ToString((NPT_DateTime::Format)format);
209 + break;
212 + m_XbmcInfo.date_added = parsed_date;
214 + PLT_XmlHelper::GetChildText(entry, "rating", str, didl_namespace_xbmc);
215 + NPT_Float floatValue;
216 + if (NPT_FAILED(str.ToFloat(floatValue))) floatValue = 0.0;
217 + m_XbmcInfo.rating = floatValue;
219 + PLT_XmlHelper::GetChildText(entry, "votes", m_XbmcInfo.votes, didl_namespace_xbmc, 256);
221 + children.Clear();
222 + PLT_XmlHelper::GetChildren(entry, children, "artwork", didl_namespace_xbmc);
223 + m_XbmcInfo.artwork.FromDidl(children);
225 // re serialize the entry didl as a we might need to pass it to a renderer
226 // we may have modified the tree to "fix" issues, so as not to break a renderer
227 // (don't write xml prefix as this didl could be part of a larger document)
228 diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.h b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.h
229 index 34a69b7..56291a7 100644
230 --- a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.h
231 +++ b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaItem.h
232 @@ -151,6 +151,26 @@ typedef struct {
233 NPT_UInt32 episode_season;
234 } PLT_RecordedInfo;
236 +typedef struct {
237 + NPT_String type;
238 + NPT_String url;
239 +} PLT_Artwork;
241 +class PLT_Artworks : public NPT_List<PLT_Artwork>
243 +public:
244 + NPT_Result Add(const NPT_String& type, const NPT_String& url);
245 + NPT_Result ToDidl(NPT_String& didl, const NPT_String& tag);
246 + NPT_Result FromDidl(const NPT_Array<NPT_XmlElementNode*>& nodes);
249 +typedef struct {
250 + NPT_String date_added;
251 + NPT_Float rating;
252 + NPT_String votes;
253 + PLT_Artworks artwork;
254 +} PLT_XbmcInfo;
256 /*----------------------------------------------------------------------
257 | PLT_MediaItemResource
258 +---------------------------------------------------------------------*/
259 @@ -229,6 +249,9 @@ public:
260 /* resources related */
261 NPT_Array<PLT_MediaItemResource> m_Resources;
263 + /* XBMC specific */
264 + PLT_XbmcInfo m_XbmcInfo;
266 /* original DIDL for Control Points to pass to a renderer when invoking SetAVTransportURI */
267 NPT_String m_Didl;
269 diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltSyncMediaBrowser.h b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltSyncMediaBrowser.h
270 index 3c14dff..ffdddda 100644
271 --- a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltSyncMediaBrowser.h
272 +++ b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltSyncMediaBrowser.h
273 @@ -118,7 +118,7 @@ protected:
274 NPT_Int32 index,
275 NPT_Int32 count,
276 bool browse_metadata = false,
277 - const char* filter = "dc:date,dc:description,upnp:longDescription,upnp:genre,res,res@duration,res@size,upnp:albumArtURI,upnp:rating,upnp:lastPlaybackPosition,upnp:lastPlaybackTime,upnp:playbackCount,upnp:originalTrackNumber,upnp:episodeNumber,upnp:programTitle,upnp:seriesTitle,upnp:album,upnp:artist,upnp:author,upnp:director,dc:publisher,searchable,childCount,dc:title,dc:creator,upnp:actor,res@resolution,upnp:episodeCount,upnp:episodeSeason", // explicitely specify res otherwise WMP won't return a URL!
278 + const char* filter = "dc:date,dc:description,upnp:longDescription,upnp:genre,res,res@duration,res@size,upnp:albumArtURI,upnp:rating,upnp:lastPlaybackPosition,upnp:lastPlaybackTime,upnp:playbackCount,upnp:originalTrackNumber,upnp:episodeNumber,upnp:programTitle,upnp:seriesTitle,upnp:album,upnp:artist,upnp:author,upnp:director,dc:publisher,searchable,childCount,dc:title,dc:creator,upnp:actor,res@resolution,upnp:episodeCount,upnp:episodeSeason,xbmc:dateadded,xbmc:rating,xbmc:votes,xbmc:artwork", // explicitely specify res otherwise WMP won't return a URL!
279 const char* sort = "");
280 private:
281 NPT_Result Find(const char* ip, PLT_DeviceDataReference& device);
283 1.7.11.msysgit.0