1 // Copyright (C) 2013 James Turner - zakalawe@mac.com
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Library General Public
5 // License as published by the Free Software Foundation; either
6 // version 2 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Library General Public License for more details.
13 // You should have received a copy of the GNU General Public License
14 // along with this program; if not, write to the Free Software
15 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 #include <simgear/package/Root.hxx>
20 #include <boost/foreach.hpp>
23 #include <simgear/debug/logstream.hxx>
24 #include <simgear/props/props_io.hxx>
25 #include <simgear/io/HTTPRequest.hxx>
26 #include <simgear/io/HTTPClient.hxx>
27 #include <simgear/misc/sg_dir.hxx>
28 #include <simgear/structure/exception.hxx>
29 #include <simgear/package/Package.hxx>
30 #include <simgear/package/Install.hxx>
31 #include <simgear/package/Catalog.hxx>
37 void Root::setMaxAgeSeconds(int seconds)
39 m_maxAgeSeconds = seconds;
42 void Root::setHTTPClient(HTTP::Client* aHTTP)
47 HTTP::Client* Root::getHTTPClient() const
52 Root::Root(const SGPath& aPath) :
55 m_maxAgeSeconds(60 * 60 * 24),
58 if (getenv("LOCALE")) {
59 m_locale = getenv("LOCALE");
68 BOOST_FOREACH(SGPath c, d.children(Dir::TYPE_DIR)) {
69 Catalog* cat = Catalog::createFromPath(this, c);
71 m_catalogs[cat->id()] = cat;
73 } // of child directories iteration
81 Catalog* Root::getCatalogById(const std::string& aId) const
83 CatalogDict::const_iterator it = m_catalogs.find(aId);
84 if (it == m_catalogs.end()) {
91 Package* Root::getPackageById(const std::string& aName) const
93 size_t lastDot = aName.rfind('.');
96 if (lastDot == std::string::npos) {
98 CatalogDict::const_iterator it = m_catalogs.begin();
99 for (; it != m_catalogs.end(); ++it) {
100 pkg = it->second->getPackageById(aName);
109 std::string catalogId = aName.substr(0, lastDot);
110 std::string id = aName.substr(lastDot + 1);
111 Catalog* catalog = getCatalogById(catalogId);
116 return catalog->getPackageById(id);
119 CatalogList Root::catalogs() const
122 CatalogDict::const_iterator it = m_catalogs.begin();
123 for (; it != m_catalogs.end(); ++it) {
124 r.push_back(it->second);
131 Root::packagesMatching(const SGPropertyNode* aFilter) const
135 CatalogDict::const_iterator it = m_catalogs.begin();
136 for (; it != m_catalogs.end(); ++it) {
137 PackageList r2(it->second->packagesMatching(aFilter));
138 r.insert(r.end(), r2.begin(), r2.end());
145 Root::packagesNeedingUpdate() const
149 CatalogDict::const_iterator it = m_catalogs.begin();
150 for (; it != m_catalogs.end(); ++it) {
151 PackageList r2(it->second->packagesNeedingUpdate());
152 r.insert(r.end(), r2.begin(), r2.end());
158 void Root::refresh(bool aForce)
160 CatalogDict::iterator it = m_catalogs.begin();
161 for (; it != m_catalogs.end(); ++it) {
162 if (aForce || (it->second->ageInSeconds() > m_maxAgeSeconds)) {
163 it->second->refresh();
168 void Root::setLocale(const std::string& aLocale)
173 std::string Root::getLocale() const
178 void Root::scheduleToUpdate(Install* aInstall)
181 sg_exception("missing argument to scheduleToUpdate");
184 PackageList deps = aInstall->package()->dependencies();
185 BOOST_FOREACH(Package* dep, deps) {
186 // will internally schedule for update if required
187 // hence be careful, this method is re-entered in here!
191 bool wasEmpty = m_updateDeque.empty();
192 m_updateDeque.push_back(aInstall);
194 aInstall->startUpdate();
198 void Root::startInstall(Install* aInstall)
201 m_delegate->startInstall(aInstall);
205 void Root::installProgress(Install* aInstall, unsigned int aBytes, unsigned int aTotal)
208 m_delegate->installProgress(aInstall, aBytes, aTotal);
212 void Root::startNext(Install* aCurrent)
214 if (m_updateDeque.front() != aCurrent) {
215 SG_LOG(SG_GENERAL, SG_ALERT, "current install of package not head of the deque");
217 m_updateDeque.pop_front();
220 if (!m_updateDeque.empty()) {
221 m_updateDeque.front()->startUpdate();
225 void Root::finishInstall(Install* aInstall)
228 m_delegate->finishInstall(aInstall);
234 void Root::failedInstall(Install* aInstall, Delegate::FailureCode aReason)
236 SG_LOG(SG_GENERAL, SG_ALERT, "failed to install package:"
237 << aInstall->package()->id() << ":" << aReason);
239 m_delegate->failedInstall(aInstall, aReason);
245 void Root::catalogRefreshBegin(Catalog* aCat)
247 m_refreshing.insert(aCat);
250 void Root::catalogRefreshComplete(Catalog* aCat, bool aSuccess)
252 m_refreshing.erase(aCat);
253 if (m_refreshing.empty()) {
255 m_delegate->refreshComplete();
260 } // of namespace pkg
262 } // of namespace simgear