Files
simgear/simgear/package/Root.cxx
2013-02-21 14:03:08 +01:00

237 lines
5.0 KiB
C++

#include <simgear/package/Root.hxx>
#include <boost/foreach.hpp>
#include <cstring>
#include <simgear/debug/logstream.hxx>
#include <simgear/props/props_io.hxx>
#include <simgear/io/HTTPRequest.hxx>
#include <simgear/io/HTTPClient.hxx>
#include <simgear/misc/sg_dir.hxx>
#include <simgear/structure/exception.hxx>
#include <simgear/package/Package.hxx>
#include <simgear/package/Install.hxx>
#include <simgear/package/Catalog.hxx>
namespace simgear {
namespace pkg {
void Root::setMaxAgeSeconds(int seconds)
{
m_maxAgeSeconds = seconds;
}
void Root::setHTTPClient(HTTP::Client* aHTTP)
{
m_http = aHTTP;
}
HTTP::Client* Root::getHTTPClient() const
{
return m_http;
}
Root::Root(const SGPath& aPath) :
m_path(aPath),
m_http(NULL),
m_maxAgeSeconds(60 * 60 * 24),
m_delegate(NULL)
{
if (getenv("LOCALE")) {
m_locale = getenv("LOCALE");
}
Dir d(aPath);
if (!d.exists()) {
d.create(0755);
return;
}
BOOST_FOREACH(SGPath c, d.children(Dir::TYPE_DIR)) {
Catalog* cat = Catalog::createFromPath(this, c);
if (cat) {
m_catalogs[cat->id()] = cat;
}
} // of child directories iteration
}
Root::~Root()
{
}
Catalog* Root::getCatalogById(const std::string& aId) const
{
CatalogDict::const_iterator it = m_catalogs.find(aId);
if (it == m_catalogs.end()) {
return NULL;
}
return it->second;
}
Package* Root::getPackageById(const std::string& aName) const
{
size_t lastDot = aName.rfind('.');
Package* pkg = NULL;
if (lastDot == std::string::npos) {
// naked package ID
CatalogDict::const_iterator it = m_catalogs.begin();
for (; it != m_catalogs.end(); ++it) {
pkg = it->second->getPackageById(aName);
if (pkg) {
return pkg;
}
}
return NULL;
}
std::string catalogId = aName.substr(0, lastDot);
std::string id = aName.substr(lastDot + 1);
Catalog* catalog = getCatalogById(catalogId);
if (!catalog) {
return NULL;
}
return catalog->getPackageById(id);
}
CatalogList Root::catalogs() const
{
CatalogList r;
CatalogDict::const_iterator it = m_catalogs.begin();
for (; it != m_catalogs.end(); ++it) {
r.push_back(it->second);
}
return r;
}
PackageList
Root::packagesMatching(const SGPropertyNode* aFilter) const
{
PackageList r;
CatalogDict::const_iterator it = m_catalogs.begin();
for (; it != m_catalogs.end(); ++it) {
PackageList r2(it->second->packagesMatching(aFilter));
r.insert(r.end(), r2.begin(), r2.end());
}
return r;
}
PackageList
Root::packagesNeedingUpdate() const
{
PackageList r;
CatalogDict::const_iterator it = m_catalogs.begin();
for (; it != m_catalogs.end(); ++it) {
PackageList r2(it->second->packagesNeedingUpdate());
r.insert(r.end(), r2.begin(), r2.end());
}
return r;
}
void Root::refresh(bool aForce)
{
CatalogDict::iterator it = m_catalogs.begin();
for (; it != m_catalogs.end(); ++it) {
if (aForce || (it->second->ageInSeconds() > m_maxAgeSeconds)) {
it->second->refresh();
}
}
}
void Root::setLocale(const std::string& aLocale)
{
m_locale = aLocale;
}
std::string Root::getLocale() const
{
return m_locale;
}
void Root::scheduleToUpdate(Install* aInstall)
{
bool wasEmpty = m_updateDeque.empty();
m_updateDeque.push_back(aInstall);
if (wasEmpty) {
aInstall->startUpdate();
}
}
void Root::startInstall(Install* aInstall)
{
if (m_delegate) {
m_delegate->startInstall(aInstall);
}
}
void Root::installProgress(Install* aInstall, unsigned int aBytes, unsigned int aTotal)
{
if (m_delegate) {
m_delegate->installProgress(aInstall, aBytes, aTotal);
}
}
void Root::startNext(Install* aCurrent)
{
if (m_updateDeque.front() != aCurrent) {
SG_LOG(SG_GENERAL, SG_ALERT, "current install of package not head of the deque");
} else {
m_updateDeque.pop_front();
}
if (!m_updateDeque.empty()) {
m_updateDeque.front()->startUpdate();
}
}
void Root::finishInstall(Install* aInstall)
{
if (m_delegate) {
m_delegate->finishInstall(aInstall);
}
startNext(aInstall);
}
void Root::failedInstall(Install* aInstall, Delegate::FailureCode aReason)
{
SG_LOG(SG_GENERAL, SG_ALERT, "failed to install package:"
<< aInstall->package()->id() << ":" << aReason);
if (m_delegate) {
m_delegate->failedInstall(aInstall, aReason);
}
startNext(aInstall);
}
void Root::catalogRefreshBegin(Catalog* aCat)
{
m_refreshing.insert(aCat);
}
void Root::catalogRefreshComplete(Catalog* aCat, bool aSuccess)
{
m_refreshing.erase(aCat);
if (m_refreshing.empty()) {
if (m_delegate) {
m_delegate->refreshComplete();
}
}
}
} // of namespace pkg
} // of namespace simgear