1 /*MT*
2
3 MediaTomb - http://www.mediatomb.cc/
4
5 items.cc - this file is part of MediaTomb.
6
7 Copyright (C) 2005 Gena Batyan <bgeradz@mediatomb.cc>,
8 Sergey 'Jin' Bostandzhyan <jin@mediatomb.cc>
9
10 Copyright (C) 2006-2010 Gena Batyan <bgeradz@mediatomb.cc>,
11 Sergey 'Jin' Bostandzhyan <jin@mediatomb.cc>,
12 Leonhard Wimmer <leo@mediatomb.cc>
13
14 MediaTomb is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License version 2
16 as published by the Free Software Foundation.
17
18 MediaTomb is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 version 2 along with MediaTomb; if not, write to the Free Software
25 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
26
27 $Id$
28 */
29
30 /// \file items.cc
31
32 #include "pages.h" // API
33
34 #include "cds_objects.h"
35 #include "content/autoscan.h"
36 #include "database/database.h"
37 #include "server.h"
38 #include "upnp_xml.h"
39
Items(std::shared_ptr<ContentManager> content,std::shared_ptr<UpnpXMLBuilder> xmlBuilder)40 Web::Items::Items(std::shared_ptr<ContentManager> content, std::shared_ptr<UpnpXMLBuilder> xmlBuilder)
41 : WebRequestHandler(std::move(content))
42 , xmlBuilder(std::move(xmlBuilder))
43 {
44 }
45
46 /// \brief orocess request for item list in ui
process()47 void Web::Items::process()
48 {
49 check_request();
50
51 int parentID = intParam("parent_id");
52 int start = intParam("start");
53 int count = intParam("count");
54 if (start < 0)
55 throw_std_runtime_error("illegal start parameter");
56 if (count < 0)
57 throw_std_runtime_error("illegal count parameter");
58
59 // set result options
60 auto root = xmlDoc->document_element();
61 auto items = root.append_child("items");
62 xml2JsonHints->setArrayName(items, "item");
63 xml2JsonHints->setFieldType("title", "string");
64 items.append_attribute("parent_id") = parentID;
65
66 auto container = database->loadObject(parentID);
67 auto param = BrowseParam(container, BROWSE_DIRECT_CHILDREN | BROWSE_ITEMS);
68 param.setRange(start, count);
69
70 auto c = container->getClass();
71 if (c == UPNP_CLASS_MUSIC_ALBUM || c == UPNP_CLASS_PLAYLIST_CONTAINER)
72 param.setFlag(BROWSE_TRACK_SORT);
73
74 // get contents of request
75 auto arr = database->browse(param);
76 items.append_attribute("virtual") = container->isVirtual();
77 items.append_attribute("start") = start;
78 //items.append_attribute("returned") = arr->size();
79 items.append_attribute("total_matches") = param.getTotalMatches();
80
81 bool protectContainer = false;
82 bool protectItems = false;
83 std::string autoscanMode = "none";
84
85 auto parentDir = database->getAutoscanDirectory(parentID);
86 int autoscanType = 0;
87 if (parentDir) {
88 autoscanType = parentDir->persistent() ? 2 : 1;
89 autoscanMode = "timed";
90 }
91
92 #ifdef HAVE_INOTIFY
93 if (config->getBoolOption(CFG_IMPORT_AUTOSCAN_USE_INOTIFY)) {
94 // check for inotify mode
95 int startpoint_id = INVALID_OBJECT_ID;
96 if (autoscanType == 0) {
97 auto pathIDs = database->getPathIDs(parentID);
98 for (int pathId : pathIDs) {
99 auto pathDir = database->getAutoscanDirectory(pathId);
100 if (pathDir && pathDir->getRecursive()) {
101 startpoint_id = pathId;
102 break;
103 }
104 }
105 } else {
106 startpoint_id = parentID;
107 }
108
109 if (startpoint_id != INVALID_OBJECT_ID) {
110 auto startPtDir = database->getAutoscanDirectory(startpoint_id);
111 if (startPtDir && startPtDir->getScanMode() == ScanMode::INotify) {
112 protectItems = true;
113 if (autoscanType == 0 || startPtDir->persistent())
114 protectContainer = true;
115
116 autoscanMode = "inotify";
117 }
118 }
119 }
120 #endif
121 items.append_attribute("autoscan_mode") = autoscanMode.c_str();
122 items.append_attribute("autoscan_type") = mapAutoscanType(autoscanType).data();
123 items.append_attribute("protect_container") = protectContainer;
124 items.append_attribute("protect_items") = protectItems;
125
126 // ouput objects of container
127 for (auto&& arrayObj : arr) {
128 auto item = items.append_child("item");
129 item.append_attribute("id") = arrayObj->getID();
130 item.append_child("title").append_child(pugi::node_pcdata).set_value(arrayObj->getTitle().c_str());
131
132 auto objItem = std::static_pointer_cast<CdsItem>(arrayObj);
133 std::string res = UpnpXMLBuilder::getFirstResourcePath(objItem);
134 item.append_child("res").append_child(pugi::node_pcdata).set_value(res.c_str());
135
136 auto [url, artAdded] = xmlBuilder->renderItemImage(server->getVirtualUrl(), objItem);
137 if (artAdded) {
138 item.append_child("image").append_child(pugi::node_pcdata).set_value(url.c_str());
139 }
140 }
141 }
142