Catalog install feedback.
- also support removing (uninstalling) a catalog and all installs relating to it.
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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,11 +154,14 @@ 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
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -73,9 +73,11 @@ public:
|
|||||||
bool hasUpdate() const;
|
bool hasUpdate() const;
|
||||||
|
|
||||||
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
|
||||||
* completes.
|
* completes.
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user