Catalog install feedback.

- also support removing (uninstalling) a catalog and
all installs relating to it.
This commit is contained in:
James Turner
2015-03-15 21:55:54 +01:00
parent a67a984d29
commit 596591bb64
7 changed files with 129 additions and 8 deletions
+57 -2
View File
@@ -45,6 +45,8 @@ public:
HTTP::Request(aUrl), HTTP::Request(aUrl),
m_owner(aOwner) m_owner(aOwner)
{ {
// refreshing
m_owner->changeStatus(Delegate::FAIL_IN_PROGRESS);
} }
protected: protected:
@@ -90,7 +92,7 @@ protected:
time(&m_owner->m_retrievedTime); time(&m_owner->m_retrievedTime);
m_owner->writeTimestamp(); m_owner->writeTimestamp();
m_owner->refreshComplete(Delegate::FAIL_SUCCESS); m_owner->refreshComplete(Delegate::CATALOG_REFRESHED);
} }
private: private:
@@ -112,6 +114,7 @@ private:
Catalog::Catalog(Root *aRoot) : Catalog::Catalog(Root *aRoot) :
m_root(aRoot), m_root(aRoot),
m_status(Delegate::FAIL_UNKNOWN),
m_retrievedTime(0) m_retrievedTime(0)
{ {
} }
@@ -154,12 +157,39 @@ CatalogRef Catalog::createFromPath(Root* aRoot, const SGPath& aPath)
CatalogRef c = new Catalog(aRoot); CatalogRef c = new Catalog(aRoot);
c->m_installRoot = aPath; c->m_installRoot = aPath;
c->parseProps(props); c->parseProps(props); // will set status
c->parseTimestamp(); c->parseTimestamp();
return c; return c;
} }
bool Catalog::uninstall()
{
bool ok;
bool atLeastOneFailure = false;
BOOST_FOREACH(PackageRef p, installedPackages()) {
ok = p->existingInstall()->uninstall();
if (!ok) {
SG_LOG(SG_GENERAL, SG_WARN, "uninstall of package " <<
p->id() << " failed");
// continue trying other packages, bailing out here
// gains us nothing
atLeastOneFailure = true;
}
}
Dir d(m_installRoot);
ok = d.remove(true /* recursive */);
if (!ok) {
atLeastOneFailure = true;
}
changeStatus(atLeastOneFailure ? Delegate::FAIL_FILESYSTEM
: Delegate::FAIL_SUCCESS);
return ok;
}
PackageList const& PackageList const&
Catalog::packages() const Catalog::packages() const
{ {
@@ -226,6 +256,7 @@ InstallRef Catalog::installForPackage(PackageRef pkg) const
void Catalog::refresh() void Catalog::refresh()
{ {
Downloader* dl = new Downloader(this, url()); Downloader* dl = new Downloader(this, url());
// will iupdate status to IN_PROGRESS
m_root->makeHTTPRequest(dl); m_root->makeHTTPRequest(dl);
m_root->catalogRefreshBegin(this); m_root->catalogRefreshBegin(this);
} }
@@ -294,6 +325,9 @@ void Catalog::parseProps(const SGPropertyNode* aProps)
Dir d(m_installRoot); Dir d(m_installRoot);
d.create(0755); d.create(0755);
} }
// parsed XML ok, mark status as valid
changeStatus(Delegate::FAIL_SUCCESS);
} }
PackageRef Catalog::getPackageById(const std::string& aId) const PackageRef Catalog::getPackageById(const std::string& aId) const
@@ -372,6 +406,7 @@ std::string Catalog::getLocalisedString(const SGPropertyNode* aRoot, const char*
void Catalog::refreshComplete(Delegate::FailureCode aReason) void Catalog::refreshComplete(Delegate::FailureCode aReason)
{ {
m_root->catalogRefreshComplete(this, aReason); m_root->catalogRefreshComplete(this, aReason);
changeStatus(aReason);
} }
void Catalog::registerInstall(Install* ins) void Catalog::registerInstall(Install* ins)
@@ -392,6 +427,26 @@ void Catalog::unregisterInstall(Install* ins)
m_installed.erase(ins->package()); m_installed.erase(ins->package());
} }
void Catalog::changeStatus(Delegate::FailureCode newStatus)
{
if (m_status == newStatus) {
return;
}
m_status = newStatus;
m_statusCallbacks(this);
}
void Catalog::addStatusCallback(const Callback& cb)
{
m_statusCallbacks.push_back(cb);
}
Delegate::FailureCode Catalog::status() const
{
return m_status;
}
} // of namespace pkg } // of namespace pkg
} // of namespace simgear } // of namespace simgear
+25
View File
@@ -22,11 +22,14 @@
#include <ctime> #include <ctime>
#include <map> #include <map>
#include <boost/bind.hpp>
#include <simgear/misc/sg_path.hxx> #include <simgear/misc/sg_path.hxx>
#include <simgear/props/props.hxx> #include <simgear/props/props.hxx>
#include <simgear/structure/SGReferenced.hxx> #include <simgear/structure/SGReferenced.hxx>
#include <simgear/structure/SGSharedPtr.hxx> #include <simgear/structure/SGSharedPtr.hxx>
#include <simgear/structure/function_list.hxx>
#include <simgear/package/Delegate.hxx> #include <simgear/package/Delegate.hxx>
@@ -63,6 +66,11 @@ public:
Root* root() const Root* root() const
{ return m_root;}; { return m_root;};
/**
* uninstall this catalog entirely, including all installed packages
*/
bool uninstall();
/** /**
* perform a refresh of the catalog contents * perform a refresh of the catalog contents
*/ */
@@ -115,6 +123,18 @@ public:
* access the raw property data in the catalog * access the raw property data in the catalog
*/ */
SGPropertyNode* properties() const; SGPropertyNode* properties() const;
Delegate::FailureCode status() const;
typedef boost::function<void(Catalog*)> Callback;
void addStatusCallback(const Callback& cb);
template<class C>
void addStatusCallback(C* instance, void (C::*mem_func)(Catalog*))
{
return addStatusCallback(boost::bind(mem_func, instance, _1));
}
private: private:
Catalog(Root* aRoot); Catalog(Root* aRoot);
@@ -134,10 +154,13 @@ private:
std::string getLocalisedString(const SGPropertyNode* aRoot, const char* aName) const; std::string getLocalisedString(const SGPropertyNode* aRoot, const char* aName) const;
void changeStatus(Delegate::FailureCode newStatus);
Root* m_root; Root* m_root;
SGPropertyNode_ptr m_props; SGPropertyNode_ptr m_props;
SGPath m_installRoot; SGPath m_installRoot;
std::string m_url; std::string m_url;
Delegate::FailureCode m_status;
PackageList m_packages; PackageList m_packages;
time_t m_retrievedTime; time_t m_retrievedTime;
@@ -149,6 +172,8 @@ private:
// since it is only cleaned up in the Install destructor // since it is only cleaned up in the Install destructor
typedef std::map<PackageRef, Install*> PackageInstallDict; typedef std::map<PackageRef, Install*> PackageInstallDict;
PackageInstallDict m_installed; PackageInstallDict m_installed;
function_list<Callback> m_statusCallbacks;
}; };
} // of namespace pkg } // of namespace pkg
+2 -1
View File
@@ -42,7 +42,8 @@ public:
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
CATALOG_REFRESHED
} FailureCode; } FailureCode;
+12 -2
View File
@@ -313,11 +313,21 @@ void Install::startUpdate()
m_package->catalog()->root()->startInstall(this); m_package->catalog()->root()->startInstall(this);
} }
void Install::uninstall() bool Install::uninstall()
{ {
Dir d(m_path); Dir d(m_path);
d.remove(true); if (!d.remove(true)) {
SG_LOG(SG_GENERAL, SG_ALERT, "package uninstall failed: couldn't remove path " << m_path);
return false;
}
m_package->catalog()->unregisterInstall(this); m_package->catalog()->unregisterInstall(this);
return true;
}
bool Install::isDownloading() const
{
return (m_download != NULL);
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
+3 -1
View File
@@ -74,7 +74,9 @@ public:
void startUpdate(); void startUpdate();
void uninstall(); bool uninstall();
bool isDownloading() const;
/** /**
* Set the handler to be called when the installation successfully * Set the handler to be called when the installation successfully
+22
View File
@@ -336,6 +336,28 @@ void Root::catalogRefreshComplete(CatalogRef aCat, Delegate::FailureCode aReason
} }
} }
bool Root::removeCatalogById(const std::string& aId)
{
CatalogDict::iterator catIt = d->catalogs.find(aId);
if (catIt == d->catalogs.end()) {
SG_LOG(SG_GENERAL, SG_WARN, "removeCatalogById: unknown ID:" << aId);
return false;
}
CatalogRef cat = catIt->second;
// drop the reference
d->catalogs.erase(catIt);
bool ok = cat->uninstall();
if (!ok) {
SG_LOG(SG_GENERAL, SG_WARN, "removeCatalogById: catalog :" << aId
<< "failed to uninstall");
}
return ok;
}
} // of namespace pkg } // of namespace pkg
} // of namespace simgear } // of namespace simgear
+6
View File
@@ -109,6 +109,12 @@ public:
CatalogRef getCatalogById(const std::string& aId) const; CatalogRef getCatalogById(const std::string& aId) const;
void scheduleToUpdate(InstallRef aInstall); void scheduleToUpdate(InstallRef aInstall);
/**
* remove a catalog. Will uninstall all packages originating
* from the catalog too.
*/
bool removeCatalogById(const std::string& aId);
private: private:
friend class Install; friend class Install;
friend class Catalog; friend class Catalog;