22 #include <KLocalizedString>
24 #include <KStandardDirs>
45 m_accountId = accountId;
50 QStringList files = findKopeteLogs(m_accountId);
51 if (files.isEmpty()) {
52 Q_EMIT
error(i18n(
"No Kopete logs found"));
56 Q_FOREACH (
const QString &file, files) {
57 convertKopeteLog(file);
61 QString LogsImporter::Private::accountIdToAccountName(
const QString &accountId)
const
63 int plugin = accountId.indexOf(QLatin1Char(
'/'));
64 int protocol = accountId.indexOf(QLatin1Char(
'/'), plugin + 1);
66 QString username = accountId.mid(protocol + 1);
69 if (username.startsWith(QLatin1Char(
'_'))) {
70 username = username.remove(0, 2);
77 username.replace(QLatin1String(
"_2e"), QLatin1String(
"-"));
78 username.replace(QLatin1String(
"_2f"), QLatin1String(
"-"));
79 username.replace(QLatin1String(
"_7e"), QLatin1String(
"-"));
80 username.replace(QLatin1String(
"_3f"), QLatin1String(
"-"));
81 username.replace(QLatin1String(
"_2a"), QLatin1String(
"-"));
84 username.replace(QLatin1String(
"_40"), QLatin1String(
"@"));
89 QString LogsImporter::Private::accountIdToProtocol(
const QString &accountId)
const
91 if (accountId.startsWith(QLatin1String(
"haze/aim/"))) {
92 return QLatin1String(
"AIMProtocol");
93 }
else if (accountId.startsWith(QLatin1String(
"haze/msn/"))) {
94 return QLatin1String(
"WlmProtocol");
95 }
else if (accountId.startsWith(QLatin1String(
"haze/icq/"))) {
96 return QLatin1String(
"ICQProtocol");
97 }
else if (accountId.startsWith(QLatin1String(
"haze/yahoo/"))) {
98 return QLatin1String(
"YahooProtocol");
99 }
else if (accountId.startsWith(QLatin1String(
"gabble/jabber/"))) {
100 return QLatin1String(
"JabberProtocol");
101 }
else if (accountId.startsWith(QLatin1String(
"sunshine/gadugadu/")) ||
102 accountId.startsWith(QLatin1String(
"haze/gadugadu/"))) {
103 return QLatin1String(
"GaduProtocol");
114 kWarning() << accountId <<
"is an unsupported protocol";
123 QString protocol = accountIdToProtocol(accountId);
124 if (protocol.isEmpty()) {
125 kWarning() <<
"Unsupported protocol";
129 QString kopeteAccountId = accountIdToAccountName(accountId);
130 if (kopeteAccountId.isEmpty()) {
131 kWarning() <<
"Unable to parse account ID";
135 QDir dir(KStandardDirs::locateLocal(
"data", QLatin1String(
"kopete/logs/") +
136 protocol + QDir::separator() + kopeteAccountId));
139 QFileInfoList entries = dir.entryInfoList(QStringList() << QLatin1String(
"*.xml"), QDir::Files | QDir::NoDotAndDotDot | QDir::Readable);
140 Q_FOREACH (
const QFileInfo &finfo, entries) {
141 files << finfo.filePath();
148 void LogsImporter::Private::initKTpDocument()
150 m_ktpDocument.clear();
151 m_ktpLogElement.clear();
153 QDomNode xmlNode = m_ktpDocument.createProcessingInstruction(
154 QLatin1String(
"xml"), QLatin1String(
"version='1.0' encoding='utf-8'"));
155 m_ktpDocument.appendChild(xmlNode);
157 xmlNode = m_ktpDocument.createProcessingInstruction(
158 QLatin1String(
"xml-stylesheet"), QLatin1String(
"type=\"text/xsl\" href=\"log-store-xml.xsl\""));
159 m_ktpDocument.appendChild(xmlNode);
161 m_ktpLogElement = m_ktpDocument.createElement(QLatin1String(
"log"));
162 m_ktpDocument.appendChild(m_ktpLogElement);
165 void LogsImporter::Private::saveKTpDocument()
167 QString filename = QString(QLatin1String(
"%1%2%3.log"))
169 .arg(m_month, 2, 10, QLatin1Char(
'0'))
170 .arg(m_day, 2, 10, QLatin1Char(
'0'));
173 QString path = dirs.localxdgdatadir() + QDir::separator() + QLatin1String(
"TpLogger") + QDir::separator() + QLatin1String(
"logs");
176 path += QDir::separator() + QLatin1String(
"chatrooms");
178 QString accountId = m_accountId;
180 if (m_accountId.contains(QLatin1Char(
'/'))) {
181 accountId.replace(QLatin1Char(
'/'), QLatin1String(
"_"));
183 path += QDir::separator() + accountId;
186 path += QDir::separator() + m_contactId;
191 QDir::home().mkpath(QDir::home().relativeFilePath(dir.path()));
194 path += QDir::separator() + filename;
197 if (outFile.exists()) {
198 kWarning() << path <<
"already exists, not importing logs";
202 outFile.open(QIODevice::WriteOnly);
203 QTextStream stream(&outFile);
204 m_ktpDocument.save(stream, 0);
206 kDebug() <<
"Stored as" << path;
209 KDateTime LogsImporter::Private::parseKopeteTime(
const QDomElement& kopeteMessage)
const
211 QString strtime = kopeteMessage.attribute(QLatin1String(
"time"));
212 if (strtime.isEmpty()) {
218 QStringList dateTime = strtime.split(QLatin1Char(
' '), QString::SkipEmptyParts);
219 if (dateTime.length() != 2) {
223 QStringList time = dateTime.at(1).split(QLatin1Char(
':'));
225 QString str = QString(QLatin1String(
"%1-%2-%3T%4:%5:%6Z"))
227 .arg(m_month, 2, 10, QLatin1Char(
'0'))
228 .arg(dateTime.at(0).toInt(), 2, 10, QLatin1Char(
'0'))
229 .arg(time.at(0).toInt(), 2, 10, QLatin1Char(
'0'))
230 .arg(time.at(1).toInt(), 2, 10, QLatin1Char(
'0'))
231 .arg(time.at(2).toInt(), 2, 10, QLatin1Char(
'0'));
236 KDateTime localTz = KDateTime::fromString(str, KDateTime::ISODate);
237 KDateTime utc = localTz.addSecs(-KDateTime::currentLocalDateTime().timeZone().offset(localTz.toTime_t()));
242 QDomElement LogsImporter::Private::convertKopeteMessage(
const QDomElement& kopeteMessage)
244 KDateTime time = parseKopeteTime(kopeteMessage);
245 if (!time.isValid()) {
246 kWarning() <<
"Failed to parse message time, skipping message";
247 return QDomElement();
253 m_day = time.date().day();
258 if (time.date().day() != m_day) {
260 m_day = time.date().day();
265 QDomElement ktpMessage = m_ktpDocument.createElement(QLatin1String(
"message"));
266 ktpMessage.setAttribute(QLatin1String(
"time"), time.toUtc().toString(QLatin1String(
"%Y%m%dT%H:%M:%S")));
268 QString sender = kopeteMessage.attribute(QLatin1String(
"from"));
269 if (!m_isMUCLog && sender.startsWith(m_contactId) && sender.length() > m_contactId.length()) {
276 sender = sender.remove(m_contactId);
279 ktpMessage.setAttribute(QLatin1String(
"id"), sender);
280 ktpMessage.setAttribute(QLatin1String(
"name"), kopeteMessage.attribute(QLatin1String(
"nick")));
282 if (sender == m_meId) {
283 ktpMessage.setAttribute(QLatin1String(
"isuser"), QLatin1String(
"true"));
285 ktpMessage.setAttribute(QLatin1String(
"isuser"), QLatin1String(
"false"));
289 ktpMessage.setAttribute(QLatin1String(
"token"), QString());
290 ktpMessage.setAttribute(QLatin1String(
"message-token"), QString());
291 ktpMessage.setAttribute(QLatin1String(
"type"), QLatin1String(
"normal"));
294 QDomText message = m_ktpDocument.createTextNode(kopeteMessage.text());
295 ktpMessage.appendChild(message);
300 void LogsImporter::Private::convertKopeteLog(
const QString& filepath)
302 kDebug() <<
"Converting" << filepath;
315 f.open(QIODevice::ReadOnly);
317 QByteArray ba = f.readAll();
319 m_kopeteDocument.setContent(ba);
321 QDomElement history = m_kopeteDocument.documentElement();
323 QDomNodeList kopeteMessages = history.elementsByTagName(QLatin1String(
"msg"));
326 QDomNodeList heads = history.elementsByTagName(QLatin1String(
"head"));
327 if (heads.isEmpty()) {
328 Q_EMIT
error(i18n(
"Invalid Kopete log format"));
332 QDomNode head = heads.item(0);
333 QDomNodeList headData = head.childNodes();
334 if (headData.length() < 3) {
335 Q_EMIT
error(i18n(
"Invalid Kopete log format"));
339 for (
int i = 0; i < headData.count(); i++) {
340 QDomElement el = headData.item(i).toElement();
342 if (el.tagName() == QLatin1String(
"date")) {
343 m_year = el.attribute(QLatin1String(
"year"), QString()).toInt();
344 m_month = el.attribute(QLatin1String(
"month"), QString()).toInt();
345 }
else if (el.tagName() == QLatin1String(
"contact")) {
346 if (el.attribute(QLatin1String(
"type")) == QLatin1String(
"myself")) {
347 m_meId = el.attribute(QLatin1String(
"contactId"));
349 m_contactId = el.attribute(QLatin1String(
"contactId"));
354 if ((m_year == 0) || (m_month == 0) || m_meId.isEmpty() || m_contactId.isEmpty()) {
355 kWarning() <<
"Failed to correctly parse header. Possibly invalid log format";
359 for (
int i = 0; i < kopeteMessages.count(); i++) {
360 QDomElement kopeteMessage = kopeteMessages.item(i).toElement();
362 QDomElement ktpMessage = convertKopeteMessage(kopeteMessage);
364 m_ktpLogElement.appendChild(ktpMessage);