No longer needed, and fixes crash on shutdown.
#include <simgear/package/Install.hxx>
namespace simgear {
-
-namespace pkg {
-CatalogList static_catalogs;
+namespace pkg {
//////////////////////////////////////////////////////////////////////////////
Downloader(CatalogRef aOwner, const std::string& aUrl) :
HTTP::Request(aUrl),
m_owner(aOwner)
- {
+ {
}
-
+
protected:
virtual void gotBodyData(const char* s, int n)
{
m_buffer += std::string(s, n);
}
-
+
virtual void onDone()
- {
+ {
if (responseCode() != 200) {
SG_LOG(SG_GENERAL, SG_ALERT, "catalog download failure:" << m_owner->url());
m_owner->refreshComplete(Delegate::FAIL_DOWNLOAD);
return;
}
-
+
SGPropertyNode* props = new SGPropertyNode;
-
+
try {
readProperties(m_buffer.data(), m_buffer.size(), props);
m_owner->parseProps(props);
m_owner->refreshComplete(Delegate::FAIL_EXTRACT);
return;
}
-
+
std::string ver(m_owner->root()->catalogVersion());
if (!checkVersion(ver, props)) {
SG_LOG(SG_GENERAL, SG_WARN, "downloaded catalog " << m_owner->url() << ", version mismatch:\n\t"
m_owner->refreshComplete(Delegate::FAIL_VERSION);
return;
}
-
+
// cache the catalog data, now we have a valid install root
Dir d(m_owner->installRoot());
SGPath p = d.file("catalog.xml");
std::ofstream f(p.c_str(), std::ios::out | std::ios::trunc);
f.write(m_buffer.data(), m_buffer.size());
f.close();
-
+
time(&m_owner->m_retrievedTime);
m_owner->writeTimestamp();
m_owner->refreshComplete(Delegate::FAIL_SUCCESS);
}
-
+
private:
bool checkVersion(const std::string& aVersion, SGPropertyNode* aProps)
{
}
return false;
}
-
+
CatalogRef m_owner;
std::string m_buffer;
};
//////////////////////////////////////////////////////////////////////////////
-CatalogList Catalog::allCatalogs()
-{
- return static_catalogs;
-}
-
Catalog::Catalog(Root *aRoot) :
m_root(aRoot),
m_retrievedTime(0)
{
- static_catalogs.push_back(this);
}
Catalog::~Catalog()
{
- CatalogList::iterator it = std::find(static_catalogs.begin(), static_catalogs.end(), this);
- static_catalogs.erase(it);
}
CatalogRef Catalog::createFromUrl(Root* aRoot, const std::string& aUrl)
c->m_url = aUrl;
Downloader* dl = new Downloader(c, aUrl);
aRoot->makeHTTPRequest(dl);
-
+
return c;
}
-
+
CatalogRef Catalog::createFromPath(Root* aRoot, const SGPath& aPath)
{
SGPath xml = aPath;
if (!xml.exists()) {
return NULL;
}
-
+
SGPropertyNode_ptr props;
try {
props = new SGPropertyNode;
readProperties(xml.str(), props);
} catch (sg_exception& e) {
- return NULL;
+ return NULL;
}
-
+
if (props->getStringValue("version") != aRoot->catalogVersion()) {
SG_LOG(SG_GENERAL, SG_WARN, "skipping catalog at " << aPath << ", version mismatch:\n\t"
<< props->getStringValue("version") << " vs required " << aRoot->catalogVersion());
return NULL;
}
-
+
CatalogRef c = new Catalog(aRoot);
c->m_installRoot = aPath;
c->parseProps(props);
c->parseTimestamp();
-
+
return c;
}
if (!p->isInstalled()) {
continue;
}
-
+
if (p->install()->hasUpdate()) {
r.push_back(p);
}
}
return r;
}
-
+
InstallRef Catalog::installForPackage(PackageRef pkg) const
{
PackageInstallDict::const_iterator it = m_installed.find(pkg);
if (p.exists()) {
return Install::createFromPath(p, CatalogRef(const_cast<Catalog*>(this)));
}
-
+
return NULL;
}
-
+
return it->second;
}
-
+
void Catalog::refresh()
{
Downloader* dl = new Downloader(this, url());
<< " is now at: " << m_props->getStringValue("url"));
}
}
-
+
m_url = m_props->getStringValue("url");
if (m_installRoot.isNull()) {
m_installRoot = m_root->path();
m_installRoot.append(id());
-
+
Dir d(m_installRoot);
d.create(0755);
}
{
return getLocalisedString(m_props, "description");
}
-
+
SGPropertyNode* Catalog::properties() const
{
return m_props.ptr();
unsigned int maxAge = m_props->getIntValue("max-age-sec", m_root->maxAgeSeconds());
return (ageInSeconds() > maxAge);
}
-
+
std::string Catalog::getLocalisedString(const SGPropertyNode* aRoot, const char* aName) const
{
if (aRoot->hasChild(m_root->getLocale())) {
return localeRoot->getStringValue(aName);
}
}
-
+
return aRoot->getStringValue(aName);
}
if (!ins || ins->package()->catalog() != this) {
return;
}
-
+
m_installed[ins->package()] = ins;
}
if (!ins || ins->package()->catalog() != this) {
return;
}
-
+
m_installed.erase(ins->package());
}
namespace simgear
{
-
+
namespace HTTP { class Client; }
-
+
namespace pkg
{
class Catalog;
class Root;
class Install;
-
+
typedef SGSharedPtr<Package> PackageRef;
typedef SGSharedPtr<Catalog> CatalogRef;
typedef SGSharedPtr<Install> InstallRef;
-
+
typedef std::vector<PackageRef> PackageList;
typedef std::vector<CatalogRef> CatalogList;
{
public:
virtual ~Catalog();
-
+
static CatalogRef createFromUrl(Root* aRoot, const std::string& aUrl);
-
+
static CatalogRef createFromPath(Root* aRoot, const SGPath& aPath);
-
- static CatalogList allCatalogs();
-
+
Root* root() const
{ return m_root;};
-
+
/**
* perform a refresh of the catalog contents
*/
/**
* retrieve all the packages in the catalog which are installed
* and have a pendig update
- */
+ */
PackageList packagesNeedingUpdate() const;
-
+
SGPath installRoot() const
{ return m_installRoot; }
-
+
std::string id() const;
-
+
std::string url() const;
-
+
std::string description() const;
-
+
PackageRef getPackageById(const std::string& aId) const;
-
+
InstallRef installForPackage(PackageRef pkg) const;
-
+
/**
* test if the catalog data was retrieved longer ago than the
* maximum permitted age for this catalog.
*/
bool needsRefresh() const;
-
+
unsigned int ageInSeconds() const;
-
+
/**
* access the raw property data in the catalog
*/
SGPropertyNode* properties() const;
private:
Catalog(Root* aRoot);
-
+
class Downloader;
friend class Downloader;
-
+
friend class Install;
void registerInstall(Install* ins);
void unregisterInstall(Install* ins);
-
+
void parseProps(const SGPropertyNode* aProps);
-
+
void refreshComplete(Delegate::FailureCode aReason);
-
+
void parseTimestamp();
void writeTimestamp();
-
+
std::string getLocalisedString(const SGPropertyNode* aRoot, const char* aName) const;
-
+
Root* m_root;
SGPropertyNode_ptr m_props;
SGPath m_installRoot;
typedef std::map<std::string, Package*> PackageWeakMap;
PackageWeakMap m_variantDict;
-
+
// important that this is a weak-ref to Installs,
// since it is only cleaned up in the Install destructor
typedef std::map<PackageRef, Install*> PackageInstallDict;
PackageInstallDict m_installed;
};
-
+
} // of namespace pkg
} // of namespace simgear
#include <iostream>
#include <cstring>
-using namespace simgear;
+using namespace simgear;
using namespace std;
bool keepRunning = true;
virtual void refreshComplete()
{
}
-
+
virtual void failedRefresh(pkg::Catalog* aCatalog, FailureCode aReason)
{
cerr << "failed refresh of " << aCatalog->description() << ":" << aReason << endl;
}
-
+
virtual void startInstall(pkg::Install* aInstall)
{
_lastPercent = 999;
cout << "starting install of " << aInstall->package()->name() << endl;
}
-
+
virtual void installProgress(pkg::Install* aInstall, unsigned int bytes, unsigned int total)
{
unsigned int percent = (bytes * 100) / total;
if (percent == _lastPercent) {
return;
}
-
+
_lastPercent = percent;
cout << percent << "%" << endl;
}
-
+
virtual void finishInstall(pkg::Install* aInstall)
{
cout << "done install of " << aInstall->package()->name() << endl;
}
private:
unsigned int _lastPercent;
-
+
};
void printRating(pkg::Package* pkg, const std::string& aRating, const std::string& aLabel)
cout << "Name:" << pkg->name() << endl;
cout << "Description:" << pkg->description() << endl;
cout << "Long description:\n" << pkg->getLocalisedProp("long-description") << endl << endl;
-
+
if (pkg->properties()->hasChild("author")) {
cout << "Authors:" << endl;
BOOST_FOREACH(SGPropertyNode* author, pkg->properties()->getChildren("author")) {
if (author->hasChild("name")) {
cout << "\t" << author->getStringValue("name") << endl;
-
+
} else {
// simple author structure
cout << "\t" << author->getStringValue() << endl;
}
-
-
+
+
}
-
+
cout << endl;
}
-
+
cout << "Ratings:" << endl;
printRating(pkg, "fdm", "Flight-model ");
printRating(pkg, "cockpit", "Cockpit ");
HTTP::Client* http = new HTTP::Client();
pkg::Root* root = new pkg::Root(Dir::current().path(), "");
-
+
MyDelegate dlg;
root->setDelegate(&dlg);
-
+
cout << "Package root is:" << Dir::current().path() << endl;
- cout << "have " << pkg::Catalog::allCatalogs().size() << " catalog(s)" << endl;
-
+ cout << "have " << root->catalogs().size() << " catalog(s)" << endl;
+
root->setHTTPClient(http);
-
+
if (!strcmp(argv[1], "add")) {
std::string url(argv[2]);
pkg::Catalog::createFromUrl(root, url);
cerr << "unknown package:" << argv[2] << endl;
return EXIT_FAILURE;
}
-
+
if (pkg->isInstalled()) {
cout << "package " << pkg->id() << " is already installed at " << pkg->install()->path() << endl;
return EXIT_SUCCESS;
}
-
+
pkg::CatalogRef catalog = pkg->catalog();
cout << "Will install:" << pkg->id() << " from " << catalog->id() <<
"(" << catalog->description() << ")" << endl;
cerr << "unknown package:" << argv[2] << endl;
return EXIT_FAILURE;
}
-
+
if (!pkg->isInstalled()) {
cerr << "package " << argv[2] << " not installed" << endl;
return EXIT_FAILURE;
}
-
+
cout << "Will uninstall:" << pkg->id() << endl;
pkg->install()->uninstall();
} else if (!strcmp(argv[1], "update-all")) {
cout << "no packages with updates" << endl;
return EXIT_SUCCESS;
}
-
+
cout << updates.size() << " packages have updates" << endl;
BOOST_FOREACH(pkg::Package* p, updates) {
cout << "\t" << p->id() << " " << p->getLocalisedProp("name") << endl;
cerr << "unknown package:" << argv[2] << endl;
return EXIT_FAILURE;
}
-
+
printPackageInfo(pkg);
} else {
cerr << "unknown command:" << argv[1] << endl;
return EXIT_FAILURE;
}
-
+
while (http->hasActiveRequests()) {
http->update();
}