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:
James Turner
2015-09-27 19:42:08 -05:00
parent 3bc53474ed
commit 4e40913aef
8 changed files with 95 additions and 26 deletions
+31 -6
View File
@@ -90,8 +90,13 @@ protected:
virtual void onDone() virtual void onDone()
{ {
if (responseCode() != 200) { if (responseCode() != 200) {
SG_LOG(SG_GENERAL, SG_ALERT, "catalog download failure:" << m_owner->url()); Delegate::StatusCode code = Delegate::FAIL_DOWNLOAD;
m_owner->refreshComplete(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; return;
} }
@@ -106,7 +111,15 @@ protected:
return; 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)) { if (!checkVersion(ver, props)) {
SG_LOG(SG_GENERAL, SG_WARN, "downloaded catalog " << m_owner->url() << ", version mismatch:\n\t" SG_LOG(SG_GENERAL, SG_WARN, "downloaded catalog " << m_owner->url() << ", version mismatch:\n\t"
<< props->getStringValue("version") << " vs required " << ver); << props->getStringValue("version") << " vs required " << ver);
@@ -186,8 +199,8 @@ CatalogRef Catalog::createFromPath(Root* aRoot, const SGPath& aPath)
return NULL; return NULL;
} }
if (!checkVersion(aRoot->catalogVersion(), props)) { if (!checkVersion(aRoot->applicationVersion(), props)) {
std::string redirect = redirectUrlForVersion(aRoot->catalogVersion(), props); std::string redirect = redirectUrlForVersion(aRoot->applicationVersion(), props);
if (!redirect.empty()) { if (!redirect.empty()) {
SG_LOG(SG_GENERAL, SG_WARN, "catalog at " << aPath << ", version mismatch:\n\t" SG_LOG(SG_GENERAL, SG_WARN, "catalog at " << aPath << ", version mismatch:\n\t"
<< "redirecting to alternate URL:" << redirect); << "redirecting to alternate URL:" << redirect);
@@ -385,11 +398,23 @@ PackageRef Catalog::getPackageById(const std::string& aId) const
// works as expected. // works as expected.
PackageWeakMap::const_iterator it = m_variantDict.find(aId); PackageWeakMap::const_iterator it = m_variantDict.find(aId);
if (it == m_variantDict.end()) if (it == m_variantDict.end())
return NULL; return PackageRef();
return it->second; 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 std::string Catalog::id() const
{ {
return m_props->getStringValue("id"); return m_props->getStringValue("id");
+2
View File
@@ -109,6 +109,8 @@ public:
PackageRef getPackageById(const std::string& aId) const; 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 * test if the catalog data was retrieved longer ago than the
* maximum permitted age for this catalog. * maximum permitted age for this catalog.
+5 -4
View File
@@ -44,11 +44,12 @@ public:
STATUS_SUCCESS = 0, STATUS_SUCCESS = 0,
FAIL_UNKNOWN = 1, FAIL_UNKNOWN = 1,
STATUS_IN_PROGRESS, ///< downloading/installation in progress STATUS_IN_PROGRESS, ///< downloading/installation in progress
FAIL_CHECKSUM, ///< package MD5 verificstion failed FAIL_CHECKSUM, ///< package MD5 verificstion failed
FAIL_DOWNLOAD, ///< network issue FAIL_DOWNLOAD, ///< network issue
FAIL_EXTRACT, ///< package archive failed to extract cleanly FAIL_EXTRACT, ///< package archive failed to extract cleanly
FAIL_FILESYSTEM, ///< unknown filesystem error occurred 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, STATUS_REFRESHED,
USER_CANCELLED USER_CANCELLED
} StatusCode; } StatusCode;
+12 -6
View File
@@ -106,8 +106,14 @@ protected:
virtual void onDone() virtual void onDone()
{ {
if (responseCode() != 200) { if (responseCode() != 200) {
SG_LOG(SG_GENERAL, SG_ALERT, "download failure"); SG_LOG(SG_GENERAL, SG_ALERT, "download failure:" << responseCode() <<
doFailure(Delegate::FAIL_DOWNLOAD); "\n\t" << url());
Delegate::StatusCode code = Delegate::FAIL_DOWNLOAD;
if (responseCode() == 404) {
code = Delegate::FAIL_NOT_FOUND;
}
doFailure(code);
return; return;
} }
@@ -137,7 +143,7 @@ protected:
destDir.remove(true /* recursive */); 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()); bool ok = m_extractPath.rename(m_owner->path());
if (!ok) { if (!ok) {
doFailure(Delegate::FAIL_FILESYSTEM); doFailure(Delegate::FAIL_FILESYSTEM);
@@ -296,10 +302,10 @@ Install::~Install()
InstallRef Install::createFromPath(const SGPath& aPath, CatalogRef aCat) InstallRef Install::createFromPath(const SGPath& aPath, CatalogRef aCat)
{ {
std::string id = aPath.file(); std::string path = aPath.file();
PackageRef pkg = aCat->getPackageById(id); PackageRef pkg = aCat->getPackageByPath(path);
if (!pkg) if (!pkg)
throw sg_exception("no package with id:" + id); throw sg_exception("no package with path:" + path);
return new Install(pkg, aPath); return new Install(pkg, aPath);
} }
+15 -2
View File
@@ -117,7 +117,7 @@ SGPath Package::pathOnDisk() const
{ {
SGPath p(m_catalog->installRoot()); SGPath p(m_catalog->installRoot());
p.append("Aircraft"); p.append("Aircraft");
p.append(id()); p.append(dirName());
return p; return p;
} }
@@ -139,7 +139,12 @@ InstallRef Package::install()
InstallRef Package::existingInstall(const InstallCallback& cb) const 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 ) if( cb )
{ {
@@ -167,6 +172,14 @@ std::string Package::md5() const
return m_props->getStringValue("md5"); 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 unsigned int Package::revision() const
{ {
if (!m_props) { if (!m_props) {
+6
View File
@@ -133,6 +133,12 @@ public:
* this will raise an sg_exception. * this will raise an sg_exception.
*/ */
PackageList dependencies() const; 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: private:
SGPath pathOnDisk() const; SGPath pathOnDisk() const;
+12 -2
View File
@@ -247,7 +247,12 @@ Root::~Root()
} }
std::string Root::catalogVersion() const int Root::catalogVersion() const
{
return 4;
}
std::string Root::applicationVersion() const
{ {
return d->version; return d->version;
} }
@@ -443,8 +448,10 @@ void Root::finishInstall(InstallRef aInstall, Delegate::StatusCode aReason)
<< aInstall->package()->id() << ":" << aReason); << 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); startNext(aInstall);
d->fireFinishInstall(aInstall, aReason);
} }
void Root::cancelDownload(InstallRef aInstall) void Root::cancelDownload(InstallRef aInstall)
@@ -545,6 +552,9 @@ InstallRef Root::existingInstallForPackage(PackageRef p) const
return Install::createFromPath(path, p->catalog()); 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(); return InstallRef();
} }
+8 -2
View File
@@ -83,10 +83,16 @@ public:
void makeHTTPRequest(HTTP::Request* req); 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. * 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) * refresh catalogs which are more than the maximum age (24 hours by default)