]> git.mxchange.org Git - simgear.git/blob - simgear/package/Root.cxx
8f203def0e0ce9abe2bfc954ce7c77c019f4570e
[simgear.git] / simgear / package / Root.cxx
1
2
3 #include <simgear/package/Root.hxx>
4
5 #include <boost/foreach.hpp>
6 #include <cstring>
7
8 #include <simgear/debug/logstream.hxx>
9 #include <simgear/props/props_io.hxx>
10 #include <simgear/io/HTTPRequest.hxx>
11 #include <simgear/io/HTTPClient.hxx>
12 #include <simgear/misc/sg_dir.hxx>
13 #include <simgear/structure/exception.hxx>
14 #include <simgear/package/Package.hxx>
15 #include <simgear/package/Install.hxx>
16 #include <simgear/package/Catalog.hxx>
17
18 namespace simgear {
19     
20 namespace pkg {
21
22 void Root::setMaxAgeSeconds(int seconds)
23 {
24     m_maxAgeSeconds = seconds;
25 }
26
27 void Root::setHTTPClient(HTTP::Client* aHTTP)
28 {
29     m_http = aHTTP;
30 }
31
32 HTTP::Client* Root::getHTTPClient() const
33 {
34     return m_http;
35 }
36
37 Root::Root(const SGPath& aPath) :
38     m_path(aPath),
39     m_http(NULL),
40     m_maxAgeSeconds(60 * 60 * 24),
41     m_delegate(NULL)
42 {
43     if (getenv("LOCALE")) {
44         m_locale = getenv("LOCALE");
45     }
46     
47     Dir d(aPath);
48     if (!d.exists()) {
49         d.create(0755);
50         return;
51     }
52     
53     BOOST_FOREACH(SGPath c, d.children(Dir::TYPE_DIR)) {
54         Catalog* cat = Catalog::createFromPath(this, c);
55         if (cat) {
56            m_catalogs[cat->id()] = cat;     
57         }
58     } // of child directories iteration
59 }
60
61 Root::~Root()
62 {
63     
64 }
65
66 Catalog* Root::getCatalogById(const std::string& aId) const
67 {
68     CatalogDict::const_iterator it = m_catalogs.find(aId);
69     if (it == m_catalogs.end()) {
70         return NULL;
71     }
72     
73     return it->second;
74 }
75
76 Package* Root::getPackageById(const std::string& aName) const
77 {
78     size_t lastDot = aName.rfind('.');
79     
80     Package* pkg = NULL;
81     if (lastDot == std::string::npos) {
82         // naked package ID
83         CatalogDict::const_iterator it = m_catalogs.begin();
84         for (; it != m_catalogs.end(); ++it) {
85             pkg = it->second->getPackageById(aName);
86             if (pkg) {
87                 return pkg;
88             }
89         }
90         
91         return NULL;
92     }
93     
94     std::string catalogId = aName.substr(0, lastDot);
95     std::string id = aName.substr(lastDot + 1);    
96     Catalog* catalog = getCatalogById(catalogId);
97     if (!catalog) {
98         return NULL;
99     }
100             
101     return catalog->getPackageById(id);
102 }
103
104 CatalogList Root::catalogs() const
105 {
106     CatalogList r;
107     CatalogDict::const_iterator it = m_catalogs.begin();
108     for (; it != m_catalogs.end(); ++it) {
109         r.push_back(it->second);
110     }
111     
112     return r;
113 }
114
115 PackageList
116 Root::packagesMatching(const SGPropertyNode* aFilter) const
117 {
118     PackageList r;
119     
120     CatalogDict::const_iterator it = m_catalogs.begin();
121     for (; it != m_catalogs.end(); ++it) {
122         PackageList r2(it->second->packagesMatching(aFilter));
123         r.insert(r.end(), r2.begin(), r2.end());
124     }
125     
126     return r;
127 }
128
129 PackageList
130 Root::packagesNeedingUpdate() const
131 {
132     PackageList r;
133     
134     CatalogDict::const_iterator it = m_catalogs.begin();
135     for (; it != m_catalogs.end(); ++it) {
136         PackageList r2(it->second->packagesNeedingUpdate());
137         r.insert(r.end(), r2.begin(), r2.end());
138     }
139     
140     return r;
141 }
142
143 void Root::refresh(bool aForce)
144 {
145     CatalogDict::iterator it = m_catalogs.begin();
146     for (; it != m_catalogs.end(); ++it) {
147         if (aForce || (it->second->ageInSeconds() > m_maxAgeSeconds)) {
148             it->second->refresh();
149         }
150     }
151 }
152
153 void Root::setLocale(const std::string& aLocale)
154 {
155     m_locale = aLocale;
156 }
157
158 std::string Root::getLocale() const
159 {
160     return m_locale;
161 }
162
163 void Root::scheduleToUpdate(Install* aInstall)
164 {
165     if (!aInstall) {
166         sg_exception("missing argument to scheduleToUpdate");
167     }
168     
169     PackageList deps = aInstall->package()->dependencies();
170     BOOST_FOREACH(Package* dep, deps) {
171         // will internally schedule for update if required
172         // hence be careful, this method is re-entered in here!
173         dep->install();
174     }
175
176     bool wasEmpty = m_updateDeque.empty();    
177     m_updateDeque.push_back(aInstall);
178     if (wasEmpty) {
179         aInstall->startUpdate();
180     }
181 }
182
183 void Root::startInstall(Install* aInstall)
184 {
185     if (m_delegate) {
186         m_delegate->startInstall(aInstall);
187     }
188 }
189
190 void Root::installProgress(Install* aInstall, unsigned int aBytes, unsigned int aTotal)
191 {
192     if (m_delegate) {
193         m_delegate->installProgress(aInstall, aBytes, aTotal);
194     }
195 }
196
197 void Root::startNext(Install* aCurrent)
198 {
199     if (m_updateDeque.front() != aCurrent) {
200         SG_LOG(SG_GENERAL, SG_ALERT, "current install of package not head of the deque");
201     } else {
202         m_updateDeque.pop_front();
203     }
204     
205     if (!m_updateDeque.empty()) {
206         m_updateDeque.front()->startUpdate();
207     }
208 }
209
210 void Root::finishInstall(Install* aInstall)
211 {
212     if (m_delegate) {
213         m_delegate->finishInstall(aInstall);
214     }
215     
216     startNext(aInstall);
217 }
218
219 void Root::failedInstall(Install* aInstall, Delegate::FailureCode aReason)
220 {
221     SG_LOG(SG_GENERAL, SG_ALERT, "failed to install package:" 
222         << aInstall->package()->id() << ":" << aReason);
223     if (m_delegate) {
224         m_delegate->failedInstall(aInstall, aReason);
225     }
226     
227     startNext(aInstall);
228 }
229
230 void Root::catalogRefreshBegin(Catalog* aCat)
231 {
232     m_refreshing.insert(aCat);
233 }
234
235 void Root::catalogRefreshComplete(Catalog* aCat, bool aSuccess)
236 {
237     m_refreshing.erase(aCat);
238     if (m_refreshing.empty()) {
239         if (m_delegate) {
240             m_delegate->refreshComplete();
241         }
242     }
243 }
244
245 } // of namespace pkg
246
247 } // of namespace simgear