1 // Copyright (C) 2013 James Turner - zakalawe@mac.com
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Library General Public
5 // License as published by the Free Software Foundation; either
6 // version 2 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Library General Public License for more details.
13 // You should have received a copy of the GNU General Public License
14 // along with this program; if not, write to the Free Software
15 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 #include <simgear/io/HTTPClient.hxx>
19 #include <simgear/package/Catalog.hxx>
20 #include <simgear/package/Package.hxx>
21 #include <simgear/package/Install.hxx>
22 #include <simgear/package/Root.hxx>
23 #include <simgear/misc/sg_dir.hxx>
25 #include <boost/foreach.hpp>
29 using namespace simgear;
32 bool keepRunning = true;
34 class MyDelegate : public pkg::Delegate
37 virtual void catalogRefreshed(pkg::CatalogRef aCatalog, StatusCode aReason)
39 if (aReason == STATUS_REFRESHED) {
40 if (aCatalog.ptr() == NULL) {
41 cout << "refreshed all catalogs" << endl;
43 cout << "refreshed catalog " << aCatalog->url() << endl;
45 } else if (aReason == STATUS_IN_PROGRESS) {
46 cout << "started refresh of " << aCatalog->url() << endl;
48 cerr << "failed refresh of " << aCatalog->url() << ":" << aReason << endl;
52 virtual void startInstall(pkg::InstallRef aInstall)
55 cout << "starting install of " << aInstall->package()->name() << endl;
58 virtual void installProgress(pkg::InstallRef aInstall, unsigned int bytes, unsigned int total)
60 unsigned int percent = (bytes * 100) / total;
61 if (percent == _lastPercent) {
65 _lastPercent = percent;
66 cout << percent << "%" << endl;
69 virtual void finishInstall(pkg::InstallRef aInstall, StatusCode aReason)
71 if (aReason == STATUS_SUCCESS) {
72 cout << "done install of " << aInstall->package()->name() << endl;
74 cerr << "failed install of " << aInstall->package()->name() << endl;
79 unsigned int _lastPercent;
83 void printRating(pkg::Package* pkg, const std::string& aRating, const std::string& aLabel)
85 SGPropertyNode* ratings = pkg->properties()->getChild("rating");
86 cout << "\t" << aLabel << ":" << ratings->getIntValue(aRating) << endl;
89 void printPackageInfo(pkg::Package* pkg)
91 cout << "Package:" << pkg->catalog()->id() << "." << pkg->id() << endl;
92 cout << "Revision:" << pkg->revision() << endl;
93 cout << "Name:" << pkg->name() << endl;
94 cout << "Description:" << pkg->description() << endl;
95 cout << "Long description:\n" << pkg->getLocalisedProp("long-description") << endl << endl;
97 if (pkg->properties()->hasChild("author")) {
98 cout << "Authors:" << endl;
99 BOOST_FOREACH(SGPropertyNode* author, pkg->properties()->getChildren("author")) {
100 if (author->hasChild("name")) {
101 cout << "\t" << author->getStringValue("name") << endl;
104 // simple author structure
105 cout << "\t" << author->getStringValue() << endl;
114 cout << "Ratings:" << endl;
115 printRating(pkg, "fdm", "Flight-model ");
116 printRating(pkg, "cockpit", "Cockpit ");
117 printRating(pkg, "model", "3D model ");
118 printRating(pkg, "systems", "Aircraft systems");
121 int main(int argc, char** argv)
124 HTTP::Client* http = new HTTP::Client();
125 pkg::Root* root = new pkg::Root(Dir::current().path(), "");
128 root->addDelegate(&dlg);
130 cout << "Package root is:" << Dir::current().path() << endl;
131 cout << "have " << root->catalogs().size() << " catalog(s)" << endl;
133 root->setHTTPClient(http);
135 if (!strcmp(argv[1], "add")) {
136 std::string url(argv[2]);
137 pkg::Catalog::createFromUrl(root, url);
138 } else if (!strcmp(argv[1], "refresh")) {
140 } else if (!strcmp(argv[1], "install")) {
141 pkg::PackageRef pkg = root->getPackageById(argv[2]);
143 cerr << "unknown package:" << argv[2] << endl;
147 if (pkg->isInstalled()) {
148 cout << "package " << pkg->id() << " is already installed at " << pkg->install()->path() << endl;
152 pkg::CatalogRef catalog = pkg->catalog();
153 cout << "Will install:" << pkg->id() << " from " << catalog->id() <<
154 "(" << catalog->description() << ")" << endl;
156 } else if (!strcmp(argv[1], "uninstall") || !strcmp(argv[1], "remove")) {
157 pkg::PackageRef pkg = root->getPackageById(argv[2]);
159 cerr << "unknown package:" << argv[2] << endl;
163 if (!pkg->isInstalled()) {
164 cerr << "package " << argv[2] << " not installed" << endl;
168 cout << "Will uninstall:" << pkg->id() << endl;
169 pkg->install()->uninstall();
170 } else if (!strcmp(argv[1], "update-all")) {
171 pkg::PackageList updates = root->packagesNeedingUpdate();
172 BOOST_FOREACH(pkg::Package* p, updates) {
173 root->scheduleToUpdate(p->install());
175 } else if (!strcmp(argv[1], "list-updated")) {
176 pkg::PackageList updates = root->packagesNeedingUpdate();
177 if (updates.empty()) {
178 cout << "no packages with updates" << endl;
182 cout << updates.size() << " packages have updates" << endl;
183 BOOST_FOREACH(pkg::Package* p, updates) {
184 cout << "\t" << p->id() << " " << p->getLocalisedProp("name") << endl;
186 } else if (!strcmp(argv[1], "info")) {
187 pkg::PackageRef pkg = root->getPackageById(argv[2]);
189 cerr << "unknown package:" << argv[2] << endl;
193 printPackageInfo(pkg);
195 cerr << "unknown command:" << argv[1] << endl;
199 while (http->hasActiveRequests()) {