PageRenderTime 42ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/plugins/gadu_protocol/helpers/gadu-list-helper.cpp

https://gitlab.com/mziab/kadu
C++ | 396 lines | 302 code | 74 blank | 20 comment | 55 complexity | 3cc7358bd48026bb396f4ddabaf259d7 MD5 | raw file
Possible License(s): LGPL-2.1, GPL-3.0, BSD-3-Clause, CC-BY-3.0, GPL-2.0
  1. /*
  2. * %kadu copyright begin%
  3. * Copyright 2012 Piotr Galiszewski (piotr.galiszewski@kadu.im)
  4. * Copyright 2011, 2012 Bartosz Brachaczek (b.brachaczek@gmail.com)
  5. * Copyright 2011, 2012, 2013, 2014 Rafał Przemysław Malinowski (rafal.przemyslaw.malinowski@gmail.com)
  6. * %kadu copyright end%
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License as
  10. * published by the Free Software Foundation; either version 2 of
  11. * the License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  20. */
  21. #include <QtCore/QStringList>
  22. #include <QtCore/QTextCodec>
  23. #include <QtCore/QTextStream>
  24. #include "buddies/buddy-list.h"
  25. #include "buddies/buddy-manager.h"
  26. #include "buddies/group-manager.h"
  27. #include "buddies/group.h"
  28. #include "contacts/contact-manager.h"
  29. #include "contacts/contact.h"
  30. #include "protocols/protocol.h"
  31. #include "misc/misc.h"
  32. #include "debug.h"
  33. #include "gadu-list-helper.h"
  34. QString GaduListHelper::contactToLine70(Contact contact)
  35. {
  36. QStringList list;
  37. Buddy buddy = BuddyManager::instance()->byContact(contact, ActionCreateAndAdd);
  38. list.append(buddy.firstName());
  39. list.append(buddy.lastName());
  40. list.append(buddy.nickName());
  41. list.append(buddy.display());
  42. list.append(buddy.mobile());
  43. QStringList groups;
  44. foreach (const Group &group, buddy.groups())
  45. groups.append(group.name());
  46. list.append(groups.join(","));
  47. list.append(contact.id());
  48. list.append(buddy.email());
  49. list.append(QString()); // alive sound
  50. list.append(QString()); // alive sound
  51. list.append(QString()); // message sound
  52. list.append(QString()); // message sound
  53. list.append(QString::number((int)buddy.isOfflineTo()));
  54. list.append(buddy.homePhone());
  55. return list.join(";");
  56. }
  57. QByteArray GaduListHelper::buddyListToByteArray(Account account, const BuddyList &buddies)
  58. {
  59. auto contacts = QVector<Contact>{};
  60. for (auto &&buddy : buddies)
  61. contacts += buddy.contacts(account);
  62. return contactListToByteArray(contacts);
  63. }
  64. QByteArray GaduListHelper::contactListToByteArray(const QVector<Contact> &contacts)
  65. {
  66. auto result = QStringList{};
  67. result.append("GG70ExportString");
  68. for (auto &&contact : contacts)
  69. result.append(contactToLine70(contact));
  70. return result.join("\n").toUtf8();
  71. }
  72. BuddyList GaduListHelper::byteArrayToBuddyList(Account account, QByteArray &content)
  73. {
  74. QTextStream stream(&content, QIODevice::ReadOnly);
  75. return streamToBuddyList(account, stream);
  76. }
  77. BuddyList GaduListHelper::streamToBuddyList(Account account, QTextStream &content)
  78. {
  79. BuddyList result;
  80. content.setCodec("UTF-8");
  81. QString line = content.readLine(70);
  82. if (line.startsWith(QLatin1String("<ContactBook>")))
  83. result = streamPost70ToBuddyList(line, account, content);
  84. else if (line.startsWith(QLatin1String("GG70ExportString")))
  85. result = stream70ToBuddyList(account, content);
  86. else
  87. result = streamPre70ToBuddyList(line, account, content);
  88. return result;
  89. }
  90. BuddyList GaduListHelper::streamPre70ToBuddyList(const QString &firstLine, Account account, QTextStream &content)
  91. {
  92. BuddyList result;
  93. content.setCodec(QTextCodec::codecForName("CP1250"));
  94. if (firstLine.isEmpty())
  95. return result;
  96. QString line = firstLine;
  97. QStringList sections = line.split(';', QString::KeepEmptyParts);
  98. if (sections.count() > 6)
  99. {
  100. bool ok = false;
  101. sections[6].toULong(&ok);
  102. if (ok)
  103. {
  104. Buddy buddy = line70ToBuddy(account, sections);
  105. if (buddy)
  106. result.append(buddy);
  107. result.append(stream70ToBuddyList(account, content));
  108. return result;
  109. }
  110. else
  111. {
  112. Buddy buddy = linePre70ToBuddy(account, sections);
  113. if (buddy)
  114. result.append(buddy);
  115. }
  116. }
  117. while (!content.atEnd())
  118. {
  119. line = content.readLine();
  120. sections = line.split(';', QString::KeepEmptyParts);
  121. if (sections.count() < 7)
  122. continue;
  123. Buddy buddy = linePre70ToBuddy(account, sections);
  124. if (buddy)
  125. result.append(buddy);
  126. }
  127. return result;
  128. }
  129. BuddyList GaduListHelper::stream70ToBuddyList(Account account, QTextStream &content)
  130. {
  131. BuddyList result;
  132. QString line;
  133. QStringList sections;
  134. while (!content.atEnd())
  135. {
  136. line = content.readLine();
  137. sections = line.split(';', QString::KeepEmptyParts);
  138. Buddy buddy = line70ToBuddy(account, sections);
  139. if (buddy)
  140. result.append(buddy);
  141. }
  142. return result;
  143. }
  144. BuddyList GaduListHelper::streamPost70ToBuddyList(const QString &line, Account account, QTextStream &content)
  145. {
  146. BuddyList result;
  147. QString documentString = line + content.readAll();
  148. QDomDocument document;
  149. document.setContent(documentString);
  150. QDomElement docElement = document.documentElement();
  151. QMap<QString, Group> importedGroups;
  152. QDomNode groupsNode = docElement.firstChildElement("Groups");
  153. if (!groupsNode.isNull())
  154. {
  155. QDomElement groupElement = groupsNode.firstChildElement("Group");
  156. for (; !groupElement.isNull(); groupElement = groupElement.nextSiblingElement("Group"))
  157. {
  158. QDomElement idElement = groupElement.firstChildElement("Id");
  159. if (idElement.text().startsWith(QLatin1String("00000000-0000-0000-0000-")))
  160. continue;
  161. QDomElement nameElement = groupElement.firstChildElement("Name");
  162. if (nameElement.text().isEmpty())
  163. continue;
  164. importedGroups.insert(idElement.text(), GroupManager::instance()->byName(nameElement.text()));
  165. }
  166. }
  167. QDomNode contactsNode = docElement.firstChildElement("Contacts");
  168. if (!contactsNode.isNull())
  169. {
  170. QDomElement contactElement = contactsNode.firstChildElement("Contact");
  171. for (; !contactElement.isNull(); contactElement = contactElement.nextSiblingElement("Contact"))
  172. {
  173. Buddy buddy = Buddy::create();
  174. buddy.setFirstName(contactElement.firstChildElement("FirstName").text());
  175. buddy.setLastName(contactElement.firstChildElement("LastName").text());
  176. buddy.setDisplay(contactElement.firstChildElement("ShowName").text());
  177. buddy.setMobile(contactElement.firstChildElement("MobilePhone").text());
  178. buddy.setHomePhone(contactElement.firstChildElement("HomePhone").text());
  179. buddy.setEmail(contactElement.firstChildElement("Email").text());
  180. buddy.setCity(contactElement.firstChildElement("City").text());
  181. buddy.setWebsite(contactElement.firstChildElement("WwwAddress").text());
  182. buddy.setGender((BuddyGender)contactElement.firstChildElement("Gender").text().toInt());
  183. QSet<Group> groups;
  184. QDomElement groupsElement = contactsNode.firstChildElement("Groups");
  185. QDomElement groupElement = groupsElement.firstChildElement("GroupId");
  186. for (; !groupElement.isNull(); groupElement = groupElement.nextSiblingElement("GroupId"))
  187. if (importedGroups.contains(groupElement.text()))
  188. groups.insert(importedGroups.value(groupElement.text()));
  189. if (!groups.isEmpty())
  190. buddy.setGroups(groups);
  191. QDomElement numberElement = contactElement.firstChildElement("GGNumber");
  192. if (!numberElement.text().isEmpty() && numberElement.text() != account.id())
  193. {
  194. Contact contact = Contact::create();
  195. contact.setContactAccount(account);
  196. contact.setId(numberElement.text());
  197. contact.data()->setState(StorableObject::StateNew);
  198. contact.setOwnerBuddy(buddy);
  199. }
  200. buddy.setAnonymous(false);
  201. result.append(buddy);
  202. }
  203. }
  204. return result;
  205. }
  206. Buddy GaduListHelper::linePre70ToBuddy(Account account, QStringList &sections)
  207. {
  208. QSet<Group> groups;
  209. unsigned int i, secCount;
  210. bool ok = false;
  211. secCount = sections.count();
  212. if (secCount < 5)
  213. return Buddy::null;
  214. Buddy buddy = Buddy::create();
  215. buddy.setFirstName(sections[0]);
  216. buddy.setLastName(sections[1]);
  217. buddy.setNickName(sections[2]);
  218. buddy.setDisplay(sections[3]);
  219. buddy.setMobile(sections[4]);
  220. groups.clear();
  221. if (!sections[5].isEmpty())
  222. groups.insert(GroupManager::instance()->byName(sections[5]));
  223. i = 6;
  224. while (!ok && i < secCount)
  225. {
  226. sections[i].toULong(&ok);
  227. ok = ok || sections[i].isEmpty();
  228. if (!ok)
  229. groups.insert(GroupManager::instance()->byName(sections[i]));
  230. ++i;
  231. }
  232. buddy.setGroups(groups);
  233. --i;
  234. if (i < secCount)
  235. {
  236. UinType uin = sections[i++].toULong(&ok);
  237. if (!ok)
  238. uin = 0;
  239. if (uin && QString::number(uin) != account.id())
  240. {
  241. Contact contact = Contact::create();
  242. contact.setContactAccount(account);
  243. contact.setId(QString::number(uin));
  244. contact.data()->setState(StorableObject::StateNew);
  245. contact.setOwnerBuddy(buddy);
  246. }
  247. }
  248. if (i < secCount)
  249. buddy.setEmail(sections[i++]);
  250. if (i+1 < secCount)
  251. {
  252. i+=2;
  253. }
  254. if (i+1 < secCount)
  255. {
  256. i+=2;
  257. }
  258. if (i < secCount)
  259. {
  260. buddy.setOfflineTo(bool(sections[i].toInt()));
  261. i++;
  262. }
  263. if (i < secCount)
  264. buddy.setHomePhone(sections[i++]);
  265. buddy.setAnonymous(false);
  266. return buddy;
  267. }
  268. Buddy GaduListHelper::line70ToBuddy(Account account, QStringList &sections)
  269. {
  270. QSet<Group> groups;
  271. unsigned int i, secCount;
  272. bool ok = false;
  273. secCount = sections.count();
  274. if (secCount < 6)
  275. return Buddy::null;
  276. Buddy buddy = Buddy::create();
  277. buddy.setFirstName(sections[0]);
  278. buddy.setLastName(sections[1]);
  279. buddy.setNickName(sections[2]);
  280. buddy.setDisplay(sections[3]);
  281. buddy.setMobile(sections[4]);
  282. if (!sections[5].isEmpty())
  283. {
  284. foreach (const QString &group, sections[5].split(',', QString::SkipEmptyParts))
  285. groups.insert(GroupManager::instance()->byName(group));
  286. buddy.setGroups(groups);
  287. }
  288. i = 6;
  289. if (i < secCount)
  290. {
  291. UinType uin = sections[i++].toULong(&ok);
  292. if (!ok)
  293. uin = 0;
  294. if (uin && QString::number(uin) != account.id())
  295. {
  296. Contact contact = Contact::create();
  297. contact.setContactAccount(account);
  298. contact.setId(QString::number(uin));
  299. contact.data()->setState(StorableObject::StateNew);
  300. contact.setOwnerBuddy(buddy);
  301. }
  302. }
  303. if (i < secCount)
  304. buddy.setEmail(sections[i++]);
  305. if (i+1 < secCount)
  306. {
  307. i+=2;
  308. }
  309. if (i+1 < secCount)
  310. {
  311. i+=2;
  312. }
  313. if (i < secCount)
  314. {
  315. buddy.setOfflineTo(bool(sections[i].toInt()));
  316. i++;
  317. }
  318. if (i < secCount)
  319. buddy.setHomePhone(sections[i++]);
  320. buddy.setAnonymous(false);
  321. return buddy;
  322. }