Added more debug info
[meego-garage:opensuse-appstore-garage-client-services.git] / src / catalog.cpp
1 #include <QTimer>
2 #include <QtDebug>
3 #include <QFile>
4 #include <QStringList>
5 #include <QListIterator>
6 #include <QNetworkAccessManager>
7 #include "applicationmanager.h"
8 #include <garageclientservices.h>
9 #include "errorhandler.h"
10 #include "category.h"
11 #include "garagesettings.h"
12 #include "utils.h"
13 #include "catalog.h"
14 #include "jobtypes.h"
15 #include "application.h"
16
17 using namespace MeeGoGarage;
18
19 Catalog::Catalog(QObject *parent) :
20     QObject(parent),
21     m_categoryListRequested(false),
22     m_userLoggedIn(false)
23 {
24 }
25
26 CategoryList Catalog::categoryList()
27 {
28     if (!m_categoryListRequested) {
29         CategoryListJob *job = requestCategoryList();
30         if (job) {
31             m_categoryListRequested = true;
32             gcsDebug() << "requested category list for caching";
33             job->setCancellable(false);
34             connect(job, SIGNAL(jobOver()), job, SLOT(deleteLater()));
35             job->start();
36         }
37     }
38     return m_categoryList;
39 }
40
41 void Catalog::onCategoryListJobOver()
42 {
43     gcsDebug();
44
45     CategoryListJob * job = static_cast<CategoryListJob*> (sender());
46     if (job && job->isSuccessful()) {
47         CategoryList categoryList = job->result();
48         this->mergeCategoryList(categoryList);
49     }
50 }
51
52 bool Catalog::categoryNameLessThan(Category *&a1, Category *&a2)
53 {
54     Q_ASSERT(a1);
55     Q_ASSERT(a2);
56     return a1->name() < a2->name();
57 }
58
59 bool Catalog::mergeCategoryList(const CategoryList &categoryList)
60 {
61     gcsDebug();
62
63     // process all categories to check if new ones have been added
64     bool updatedCategories = false;
65     Category * category;
66     foreach(category, categoryList) {
67         updatedCategories |= mergeCategory(category, false, false);
68     }
69
70     // sort the catogires by name
71     qSort(m_categoryList.begin(), m_categoryList.end(), categoryNameLessThan);
72
73     // emit the signal so applications can refresh the categories
74     // also in the corner case of empty category list
75     if (updatedCategories || m_categoryList.count() <= 0) {
76         emit categoryListUpdated();
77     }
78
79     return updatedCategories;
80 }
81
82 bool Catalog::mergeCategory(Category * category, bool sortCategories, bool emitUpdated)
83 {
84     Q_ASSERT(category);
85
86     bool updatedCategories = false;
87     Category * foundCategory = findCategoryByName(category->name());
88     if (!foundCategory) {
89         m_categoryList.append(category);
90         updatedCategories = true;
91     } else {
92         foundCategory->mergeCategory(category);
93     }
94
95     if (sortCategories) {
96         qSort(m_categoryList.begin(), m_categoryList.end(), categoryNameLessThan);
97     }
98
99     if (updatedCategories && emitUpdated) {
100         emit categoryListUpdated();
101     }
102
103     return updatedCategories;
104 }
105
106 Category *Catalog::findCategoryById(const QString & id)
107 {
108     Category *category;
109     foreach(category, m_categoryList) {
110         Q_ASSERT(category);
111         if (category->id() == id) {
112             return category;
113         }
114     }
115
116     return 0;
117 }
118
119 Category *Catalog::findCategoryByName(const QString & name)
120 {
121     Category *category;
122     foreach(category, m_categoryList) {
123         Q_ASSERT(category);
124         if (category->name() == name) {
125             return category;
126         }
127     }
128
129     return 0;
130 }
131
132 CategoryListJob *Catalog::requestCategoryList()
133 {
134     CategoryListJob * job = requestCategoryListAux();
135     Q_ASSERT(!job || job->isInactive());
136     if (job) {
137         connect(job, SIGNAL(jobOver()), SLOT(onCategoryListJobOver()));
138     }
139     return job;
140 }
141
142 ApplicationSearchJob *Catalog::requestApplicationSearch(
143         const QString &searchString,
144         ApplicationListSortType sortType,
145         const CategoryList &categoryList,
146         int pageNumber,
147         int itemsPerPage)
148 {
149     ApplicationSearchJob * job = requestApplicationSearchAux(searchString, sortType, categoryList, pageNumber, itemsPerPage);
150     Q_ASSERT(!job || job->isInactive());
151     if (job) {
152         connect(job, SIGNAL(jobOver()), SLOT(onApplicationSearchJobOver()));
153     }
154     return job;
155 }
156
157 void Catalog::onApplicationSearchJobOver()
158 {
159     gcsDebug();
160
161     ApplicationSearchJob * job = static_cast<ApplicationSearchJob*> (sender());
162     if (job && job->isSuccessful()) {
163         ApplicationList applicationList = job->result();
164         this->mergeApplicationList(applicationList);
165     }
166 }
167
168 void Catalog::dumpCategories()
169 {
170     Utils::dumpCategoryList(m_categoryList);
171 }
172
173 QNetworkAccessManager *Catalog::networkAccessManager()
174 {
175     return GarageClientServices::instance()->networkAccessManager();
176 }
177
178 bool Catalog::mergeApplicationList(const ApplicationList &applicationList)
179 {
180     gcsDebug();
181
182     bool updated = false;
183     ApplicationList::const_iterator m;
184     ApplicationList newApplicationList;
185     for (m = applicationList.constBegin(); m != applicationList.constEnd(); m++) {
186         Application *app1 = *m;
187         Q_ASSERT(app1);
188         Application *app2 = findApplicationById(app1->id());
189         if (!app2) {
190             m_applicationIdMap.insert(app1->id(), app1);
191             m_applicationNameMap.insert(app1->name(), app1);
192             updated = true;
193             newApplicationList.append(app1);
194         }
195     }
196
197     ApplicationManager::instance()->registerApplications(newApplicationList);
198
199     return updated;
200 }
201
202 Application * Catalog::findApplicationById(const QString &id)
203 {
204     QHash<QString, Application*>::const_iterator i = m_applicationIdMap.find(id);
205     if (i == m_applicationIdMap.constEnd()) {
206         return 0;
207     }
208
209     return i.value();
210 }
211
212 Application * Catalog::findApplicationByName(const QString &name)
213 {
214     QMap<QString, Application*>::const_iterator i = m_applicationNameMap.find(name);
215     if (i == m_applicationNameMap.constEnd()) {
216         return 0;
217     }
218
219     return i.value();
220 }
221
222 Application * Catalog::findApplicationByPackageName(const QString &packageName)
223 {
224     QMap<QString, Application*>::const_iterator i = m_applicationNameMap.constBegin();
225     while (i != m_applicationNameMap.constEnd()) {
226         Q_ASSERT(i.value());
227         gcsDebug() << " checking " << i.value()->packageName();
228         if (i.value()->packageName() == packageName) {
229             return i.value();
230         }
231         i++;
232     }
233
234     return 0;
235 }
236
237 void Catalog::dumpApplicationList()
238 {
239     Utils::dumpApplicationList(m_applicationNameMap.values());
240 }
241
242 LoginJob *Catalog::requestLogin(const QString & userName, const QString & password)
243 {
244     LoginJob * loginJob = requestLoginAux(userName, password);
245     if (loginJob) {
246         connect(loginJob, SIGNAL(jobOver()), SLOT(onLoginJobOver()));
247     }
248
249     return loginJob;
250 }
251
252 LoginJob *Catalog::requestLoginAux(const QString & userName, const QString & password)
253 {
254     return new LoginJob(this, userName, password);
255 }
256
257 void Catalog::logout()
258 {
259     m_userLoggedIn = false;
260     m_username.clear();
261     m_password.clear();
262     emit loginStatusChanged();
263 }
264
265 bool Catalog::isUserLoggedIn() const
266 {
267     return m_userLoggedIn;
268 }
269
270 QString Catalog::currentUser() const
271 {
272     return m_username;
273 }
274
275 void Catalog::onLoginJobOver()
276 {
277     LoginJob * loginJob = static_cast<LoginJob*>(sender());
278     if (!loginJob) {
279         return;
280     }
281
282     if (loginJob->result()) {
283         m_username = loginJob->username();
284         m_password = loginJob->password();
285         m_userLoggedIn = true;
286     } else {
287         m_userLoggedIn = false;
288         m_username.clear();
289         m_password.clear();
290     }
291
292     emit loginStatusChanged();
293 }
294
295 QString Catalog::urlLicense(const QString & /*licenseName*/)
296 {
297     return QString();
298 }