1 | /******************************************************************* |
2 | * productmapping.cpp |
3 | * Copyright 2009 Dario Andres Rodriguez <andresbajotierra@gmail.com> |
4 | * |
5 | * This program is free software; you can redistribute it and/or |
6 | * modify it under the terms of the GNU General Public License as |
7 | * published by the Free Software Foundation; either version 2 of |
8 | * the License, or (at your option) any later version. |
9 | * |
10 | * This program is distributed in the hope that it will be useful, |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | * GNU General Public License for more details. |
14 | * |
15 | * You should have received a copy of the GNU General Public License |
16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
17 | * |
18 | ******************************************************************/ |
19 | |
20 | #include "productmapping.h" |
21 | |
22 | #include <KConfig> |
23 | #include <KConfigGroup> |
24 | #include <KDebug> |
25 | |
26 | #include "bugzillalib.h" |
27 | #include "crashedapplication.h" |
28 | |
29 | ProductMapping::ProductMapping(const CrashedApplication * crashedApp, BugzillaManager * bzManager, QObject * parent) |
30 | : QObject(parent) |
31 | , m_crashedAppPtr(crashedApp) |
32 | , m_bugzillaManagerPtr(bzManager) |
33 | , m_bugzillaProductDisabled(false) |
34 | , m_bugzillaVersionDisabled(false) |
35 | |
36 | { |
37 | //Default "fallback" values |
38 | m_bugzillaProduct = crashedApp->fakeExecutableBaseName(); |
39 | m_bugzillaComponent = QLatin1String("general" ); |
40 | m_bugzillaVersionString = QLatin1String("unspecified" ); |
41 | m_relatedBugzillaProducts = QStringList() << m_bugzillaProduct; |
42 | |
43 | map(crashedApp->fakeExecutableBaseName()); |
44 | |
45 | //Get valid versions |
46 | connect(m_bugzillaManagerPtr, SIGNAL(productInfoFetched(Product)), |
47 | this, SLOT(checkProductInfo(Product))); |
48 | |
49 | m_bugzillaManagerPtr->fetchProductInfo(m_bugzillaProduct); |
50 | } |
51 | |
52 | void ProductMapping::map(const QString & appName) |
53 | { |
54 | mapUsingInternalFile(appName); |
55 | getRelatedProductsUsingInternalFile(m_bugzillaProduct); |
56 | } |
57 | |
58 | void ProductMapping::mapUsingInternalFile(const QString & appName) |
59 | { |
60 | KConfig mappingsFile(QString::fromLatin1("mappings" ), KConfig::NoGlobals, "appdata" ); |
61 | const KConfigGroup mappings = mappingsFile.group("Mappings" ); |
62 | if (mappings.hasKey(appName)) { |
63 | QString mappingString = mappings.readEntry(appName); |
64 | if (!mappingString.isEmpty()) { |
65 | QStringList list = mappingString.split('|', QString::SkipEmptyParts); |
66 | if (list.count()==2) { |
67 | m_bugzillaProduct = list.at(0); |
68 | m_bugzillaComponent = list.at(1); |
69 | m_relatedBugzillaProducts = QStringList() << m_bugzillaProduct; |
70 | } else { |
71 | kWarning() << "Error while reading mapping entry. Sections found " << list.count(); |
72 | } |
73 | } else { |
74 | kWarning() << "Error while reading mapping entry. Entry exists but it is empty " |
75 | "(or there was an error when reading)" ; |
76 | } |
77 | } |
78 | } |
79 | |
80 | void ProductMapping::getRelatedProductsUsingInternalFile(const QString & bugzillaProduct) |
81 | { |
82 | //ProductGroup -> kontact=kdepim |
83 | //Groups -> kdepim=kontact|kmail|korganizer|akonadi|pimlibs..etc |
84 | |
85 | KConfig mappingsFile(QString::fromLatin1("mappings" ), KConfig::NoGlobals, "appdata" ); |
86 | const KConfigGroup productGroup = mappingsFile.group("ProductGroup" ); |
87 | |
88 | //Get groups of the application |
89 | QStringList groups; |
90 | if (productGroup.hasKey(bugzillaProduct)) { |
91 | QString group = productGroup.readEntry(bugzillaProduct); |
92 | if (group.isEmpty()) { |
93 | kWarning() << "Error while reading mapping entry. Entry exists but it is empty " |
94 | "(or there was an error when reading)" ; |
95 | return; |
96 | } |
97 | groups = group.split('|', QString::SkipEmptyParts); |
98 | } |
99 | |
100 | //All KDE apps use the KDE Platform (basic libs) |
101 | groups << QLatin1String("kdeplatform" ); |
102 | |
103 | //Add the product itself |
104 | m_relatedBugzillaProducts = QStringList() << m_bugzillaProduct; |
105 | |
106 | //Get related products of each related group |
107 | Q_FOREACH( const QString & group, groups ) { |
108 | const KConfigGroup bzGroups = mappingsFile.group("BZGroups" ); |
109 | if (bzGroups.hasKey(group)) { |
110 | QString bzGroup = bzGroups.readEntry(group); |
111 | if (!bzGroup.isEmpty()) { |
112 | QStringList relatedGroups = bzGroup.split('|', QString::SkipEmptyParts); |
113 | if (relatedGroups.size()>0) { |
114 | m_relatedBugzillaProducts.append(relatedGroups); |
115 | } |
116 | } else { |
117 | kWarning() << "Error while reading mapping entry. Entry exists but it is empty " |
118 | "(or there was an error when reading)" ; |
119 | } |
120 | } |
121 | } |
122 | } |
123 | |
124 | void ProductMapping::checkProductInfo(const Product & product) |
125 | { |
126 | // check whether the product itself is disabled for new reports, |
127 | // which usually means that product/application is unmaintained. |
128 | m_bugzillaProductDisabled = !product.isActive(); |
129 | |
130 | // check whether the product on bugzilla contains the expected component |
131 | if (! product.components().contains(m_bugzillaComponent)) { |
132 | m_bugzillaComponent = QLatin1String("general" ); |
133 | } |
134 | |
135 | // find the appropriate version to use on bugzilla |
136 | const QString version = m_crashedAppPtr->version(); |
137 | const QStringList& allVersions = product.allVersions(); |
138 | |
139 | if (allVersions.contains(version)) { |
140 | //The version the crash application provided is a valid bugzilla version: use it ! |
141 | m_bugzillaVersionString = version; |
142 | } else if (version.endsWith(QLatin1String(".00" ))) { |
143 | //check if there is a version on bugzilla with just ".0" |
144 | const QString shorterVersion = version.left(version.size() - 1); |
145 | if (allVersions.contains(shorterVersion)) { |
146 | m_bugzillaVersionString = shorterVersion; |
147 | } |
148 | } |
149 | |
150 | // check whether that verions is disabled for new reports, which |
151 | // usually means that version is outdated and not supported anymore. |
152 | const QStringList& inactiveVersions = product.inactiveVersions(); |
153 | m_bugzillaVersionDisabled = inactiveVersions.contains(m_bugzillaVersionString); |
154 | |
155 | } |
156 | |
157 | QStringList ProductMapping::relatedBugzillaProducts() const |
158 | { |
159 | return m_relatedBugzillaProducts; |
160 | } |
161 | |
162 | QString ProductMapping::bugzillaProduct() const |
163 | { |
164 | return m_bugzillaProduct; |
165 | } |
166 | |
167 | QString ProductMapping::bugzillaComponent() const |
168 | { |
169 | return m_bugzillaComponent; |
170 | } |
171 | |
172 | QString ProductMapping::bugzillaVersion() const |
173 | { |
174 | return m_bugzillaVersionString; |
175 | } |
176 | |
177 | bool ProductMapping::bugzillaProductDisabled() const |
178 | { |
179 | return m_bugzillaProductDisabled; |
180 | } |
181 | |
182 | bool ProductMapping::bugzillaVersionDisabled() const |
183 | { |
184 | return m_bugzillaVersionDisabled; |
185 | } |
186 | |