Package support progress
- check the catalog version explicitly when refreshing - handle packages with distinct dir name / primary ID correctly (requires an updated catalog XML format)
This commit is contained in:
@@ -90,8 +90,13 @@ protected:
|
||||
virtual void onDone()
|
||||
{
|
||||
if (responseCode() != 200) {
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "catalog download failure:" << m_owner->url());
|
||||
m_owner->refreshComplete(Delegate::FAIL_DOWNLOAD);
|
||||
Delegate::StatusCode code = Delegate::FAIL_DOWNLOAD;
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "catalog download failure:" << m_owner->url()
|
||||
<< "\n\t" << responseCode());
|
||||
if (responseCode() == 404) {
|
||||
code = Delegate::FAIL_NOT_FOUND;
|
||||
}
|
||||
m_owner->refreshComplete(code);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -106,7 +111,15 @@ protected:
|
||||
return;
|
||||
}
|
||||
|
||||
std::string ver(m_owner->root()->catalogVersion());
|
||||
if (m_owner->root()->catalogVersion() != props->getIntValue("catalog-version")) {
|
||||
SG_LOG(SG_GENERAL, SG_WARN, "catalog:" << m_owner->url() << " is not version "
|
||||
<< m_owner->root()->catalogVersion());
|
||||
m_owner->refreshComplete(Delegate::FAIL_VERSION);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
std::string ver(m_owner->root()->applicationVersion());
|
||||
if (!checkVersion(ver, props)) {
|
||||
SG_LOG(SG_GENERAL, SG_WARN, "downloaded catalog " << m_owner->url() << ", version mismatch:\n\t"
|
||||
<< props->getStringValue("version") << " vs required " << ver);
|
||||
@@ -186,8 +199,8 @@ CatalogRef Catalog::createFromPath(Root* aRoot, const SGPath& aPath)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!checkVersion(aRoot->catalogVersion(), props)) {
|
||||
std::string redirect = redirectUrlForVersion(aRoot->catalogVersion(), props);
|
||||
if (!checkVersion(aRoot->applicationVersion(), props)) {
|
||||
std::string redirect = redirectUrlForVersion(aRoot->applicationVersion(), props);
|
||||
if (!redirect.empty()) {
|
||||
SG_LOG(SG_GENERAL, SG_WARN, "catalog at " << aPath << ", version mismatch:\n\t"
|
||||
<< "redirecting to alternate URL:" << redirect);
|
||||
@@ -385,11 +398,23 @@ PackageRef Catalog::getPackageById(const std::string& aId) const
|
||||
// works as expected.
|
||||
PackageWeakMap::const_iterator it = m_variantDict.find(aId);
|
||||
if (it == m_variantDict.end())
|
||||
return NULL;
|
||||
return PackageRef();
|
||||
|
||||
return it->second;
|
||||
}
|
||||
|
||||
PackageRef Catalog::getPackageByPath(const std::string& aPath) const
|
||||
{
|
||||
PackageList::const_iterator it;
|
||||
for (it = m_packages.begin(); it != m_packages.end(); ++it) {
|
||||
if ((*it)->dirName() == aPath) {
|
||||
return *it;
|
||||
}
|
||||
}
|
||||
|
||||
return PackageRef();
|
||||
}
|
||||
|
||||
std::string Catalog::id() const
|
||||
{
|
||||
return m_props->getStringValue("id");
|
||||
|
||||
@@ -109,6 +109,8 @@ public:
|
||||
|
||||
PackageRef getPackageById(const std::string& aId) const;
|
||||
|
||||
PackageRef getPackageByPath(const std::string& aPath) const;
|
||||
|
||||
/**
|
||||
* test if the catalog data was retrieved longer ago than the
|
||||
* maximum permitted age for this catalog.
|
||||
|
||||
@@ -44,11 +44,12 @@ public:
|
||||
STATUS_SUCCESS = 0,
|
||||
FAIL_UNKNOWN = 1,
|
||||
STATUS_IN_PROGRESS, ///< downloading/installation in progress
|
||||
FAIL_CHECKSUM, ///< package MD5 verificstion failed
|
||||
FAIL_DOWNLOAD, ///< network issue
|
||||
FAIL_EXTRACT, ///< package archive failed to extract cleanly
|
||||
FAIL_CHECKSUM, ///< package MD5 verificstion failed
|
||||
FAIL_DOWNLOAD, ///< network issue
|
||||
FAIL_EXTRACT, ///< package archive failed to extract cleanly
|
||||
FAIL_FILESYSTEM, ///< unknown filesystem error occurred
|
||||
FAIL_VERSION, ///< version check mismatch
|
||||
FAIL_VERSION, ///< version check mismatch
|
||||
FAIL_NOT_FOUND, ///< package URL returned a 404
|
||||
STATUS_REFRESHED,
|
||||
USER_CANCELLED
|
||||
} StatusCode;
|
||||
|
||||
@@ -106,8 +106,14 @@ protected:
|
||||
virtual void onDone()
|
||||
{
|
||||
if (responseCode() != 200) {
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "download failure");
|
||||
doFailure(Delegate::FAIL_DOWNLOAD);
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "download failure:" << responseCode() <<
|
||||
"\n\t" << url());
|
||||
Delegate::StatusCode code = Delegate::FAIL_DOWNLOAD;
|
||||
if (responseCode() == 404) {
|
||||
code = Delegate::FAIL_NOT_FOUND;
|
||||
}
|
||||
|
||||
doFailure(code);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -137,7 +143,7 @@ protected:
|
||||
destDir.remove(true /* recursive */);
|
||||
}
|
||||
|
||||
m_extractPath.append(m_owner->package()->id());
|
||||
m_extractPath.append(m_owner->package()->dirName());
|
||||
bool ok = m_extractPath.rename(m_owner->path());
|
||||
if (!ok) {
|
||||
doFailure(Delegate::FAIL_FILESYSTEM);
|
||||
@@ -296,10 +302,10 @@ Install::~Install()
|
||||
|
||||
InstallRef Install::createFromPath(const SGPath& aPath, CatalogRef aCat)
|
||||
{
|
||||
std::string id = aPath.file();
|
||||
PackageRef pkg = aCat->getPackageById(id);
|
||||
std::string path = aPath.file();
|
||||
PackageRef pkg = aCat->getPackageByPath(path);
|
||||
if (!pkg)
|
||||
throw sg_exception("no package with id:" + id);
|
||||
throw sg_exception("no package with path:" + path);
|
||||
|
||||
return new Install(pkg, aPath);
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ SGPath Package::pathOnDisk() const
|
||||
{
|
||||
SGPath p(m_catalog->installRoot());
|
||||
p.append("Aircraft");
|
||||
p.append(id());
|
||||
p.append(dirName());
|
||||
return p;
|
||||
}
|
||||
|
||||
@@ -139,7 +139,12 @@ InstallRef Package::install()
|
||||
|
||||
InstallRef Package::existingInstall(const InstallCallback& cb) const
|
||||
{
|
||||
InstallRef install = m_catalog->root()->existingInstallForPackage(const_cast<Package*>(this));
|
||||
InstallRef install;
|
||||
try {
|
||||
install = m_catalog->root()->existingInstallForPackage(const_cast<Package*>(this));
|
||||
} catch (std::exception& e) {
|
||||
return InstallRef();
|
||||
}
|
||||
|
||||
if( cb )
|
||||
{
|
||||
@@ -167,6 +172,14 @@ std::string Package::md5() const
|
||||
return m_props->getStringValue("md5");
|
||||
}
|
||||
|
||||
std::string Package::dirName() const
|
||||
{
|
||||
std::string r(m_props->getStringValue("dir"));
|
||||
if (r.empty())
|
||||
throw sg_exception("missing dir property on catalog package entry for " + m_id);
|
||||
return r;
|
||||
}
|
||||
|
||||
unsigned int Package::revision() const
|
||||
{
|
||||
if (!m_props) {
|
||||
|
||||
@@ -133,6 +133,12 @@ public:
|
||||
* this will raise an sg_exception.
|
||||
*/
|
||||
PackageList dependencies() const;
|
||||
|
||||
/**
|
||||
* Name of the package directory on disk. This may or may not be the
|
||||
* same as the primary ID, depending on the aircraft author
|
||||
*/
|
||||
std::string dirName() const;
|
||||
private:
|
||||
SGPath pathOnDisk() const;
|
||||
|
||||
|
||||
@@ -246,8 +246,13 @@ Root::~Root()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int Root::catalogVersion() const
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
|
||||
std::string Root::catalogVersion() const
|
||||
std::string Root::applicationVersion() const
|
||||
{
|
||||
return d->version;
|
||||
}
|
||||
@@ -442,11 +447,13 @@ void Root::finishInstall(InstallRef aInstall, Delegate::StatusCode aReason)
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "failed to install package:"
|
||||
<< aInstall->package()->id() << ":" << aReason);
|
||||
}
|
||||
|
||||
d->fireFinishInstall(aInstall, aReason);
|
||||
|
||||
// order matters here, so a call to 'isQueued' from a finish-install
|
||||
// callback returns false, not true
|
||||
startNext(aInstall);
|
||||
d->fireFinishInstall(aInstall, aReason);
|
||||
}
|
||||
|
||||
|
||||
void Root::cancelDownload(InstallRef aInstall)
|
||||
{
|
||||
RootPrivate::UpdateDeque::iterator it =
|
||||
@@ -544,7 +551,10 @@ InstallRef Root::existingInstallForPackage(PackageRef p) const
|
||||
// this will add to our cache, and hence, modify m_installs
|
||||
return Install::createFromPath(path, p->catalog());
|
||||
}
|
||||
|
||||
|
||||
// insert a null reference into the dictionary, so we don't call
|
||||
// the pathOnDisk -> exists codepath repeatedley
|
||||
d->m_installs[p] = InstallRef();
|
||||
return InstallRef();
|
||||
}
|
||||
|
||||
|
||||
@@ -83,11 +83,17 @@ public:
|
||||
void makeHTTPRequest(HTTP::Request* req);
|
||||
|
||||
/**
|
||||
* the version string of the root. Catalogs must match this version,
|
||||
* The catalog XML/property version in use. This is used to make incomaptible
|
||||
* changes to the package/catalog syntax
|
||||
*/
|
||||
int catalogVersion() const;
|
||||
|
||||
/**
|
||||
* the version string of the application. Catalogs must match this version,
|
||||
* or they will be ignored / rejected.
|
||||
*/
|
||||
std::string catalogVersion() const;
|
||||
|
||||
std::string applicationVersion() const;
|
||||
|
||||
/**
|
||||
* refresh catalogs which are more than the maximum age (24 hours by default)
|
||||
* set force to true, to download all catalogs regardless of age.
|
||||
|
||||
Reference in New Issue
Block a user