| 1 | /* |
|---|
| 2 | * WengoPhone, a voice over Internet phone |
|---|
| 3 | * Copyright (C) 2004-2006 Wengo |
|---|
| 4 | * |
|---|
| 5 | * This program is free software; you can redistribute it and/or modify |
|---|
| 6 | * it under the terms of the GNU General Public License as published by |
|---|
| 7 | * the Free Software Foundation; either version 2 of the License, or |
|---|
| 8 | * (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, write to the Free Software |
|---|
| 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|---|
| 18 | */ |
|---|
| 19 | |
|---|
| 20 | #include "ConfigImporter.h" |
|---|
| 21 | |
|---|
| 22 | #include "Config.h" |
|---|
| 23 | #include "ConfigManager.h" |
|---|
| 24 | |
|---|
| 25 | #include <model/account/wengo/WengoAccount.h> |
|---|
| 26 | #include <model/contactlist/Contact.h> |
|---|
| 27 | #include <model/contactlist/ContactList.h> |
|---|
| 28 | #include <model/contactlist/ContactListXMLSerializer.h> |
|---|
| 29 | #include <model/contactlist/ContactListXMLSerializer1.h> |
|---|
| 30 | #include <model/profile/EnumSex.h> |
|---|
| 31 | #include <model/profile/StreetAddress.h> |
|---|
| 32 | #include <model/profile/UserProfile.h> |
|---|
| 33 | #include <model/profile/UserProfileHandler.h> |
|---|
| 34 | #include <model/profile/UserProfileFileStorage1.h> |
|---|
| 35 | #include <model/profile/UserProfileXMLSerializer.h> |
|---|
| 36 | |
|---|
| 37 | #include <imwrapper/IMAccountListXMLSerializer.h> |
|---|
| 38 | #include <imwrapper/IMAccountListXMLSerializer1.h> |
|---|
| 39 | |
|---|
| 40 | #include <cutil/global.h> |
|---|
| 41 | |
|---|
| 42 | #include <util/Base64.h> |
|---|
| 43 | #include <util/File.h> |
|---|
| 44 | #include <util/Logger.h> |
|---|
| 45 | #include <util/Path.h> |
|---|
| 46 | #include <util/String.h> |
|---|
| 47 | |
|---|
| 48 | #include <settings/SettingsXMLSerializer.h> |
|---|
| 49 | |
|---|
| 50 | #include <map> |
|---|
| 51 | #include <string> |
|---|
| 52 | #include <vector> |
|---|
| 53 | #include <sstream> |
|---|
| 54 | #include <iostream> |
|---|
| 55 | |
|---|
| 56 | using namespace std; |
|---|
| 57 | |
|---|
| 58 | typedef struct telNumber_s { |
|---|
| 59 | string key; |
|---|
| 60 | string value; |
|---|
| 61 | } telNumber_t; |
|---|
| 62 | |
|---|
| 63 | typedef std::list<telNumber_t *> telNumberList; |
|---|
| 64 | typedef std::list<telNumber_t *>::iterator telNumberIt; |
|---|
| 65 | |
|---|
| 66 | typedef struct address_s { |
|---|
| 67 | string street; |
|---|
| 68 | string city; |
|---|
| 69 | string post_code; |
|---|
| 70 | string state; |
|---|
| 71 | string country; |
|---|
| 72 | } address_t; |
|---|
| 73 | |
|---|
| 74 | typedef struct birthday_s { |
|---|
| 75 | int day; |
|---|
| 76 | int month; |
|---|
| 77 | int year; |
|---|
| 78 | } birthday_t; |
|---|
| 79 | |
|---|
| 80 | #define MALE 0 |
|---|
| 81 | #define FEMALE 1 |
|---|
| 82 | #define UNKNOWN 2 |
|---|
| 83 | |
|---|
| 84 | typedef struct vcard_s { |
|---|
| 85 | string id; |
|---|
| 86 | string fname; |
|---|
| 87 | string lname; |
|---|
| 88 | int gender; |
|---|
| 89 | string company; |
|---|
| 90 | string website; |
|---|
| 91 | birthday_t birthday; |
|---|
| 92 | string note; |
|---|
| 93 | address_t address; |
|---|
| 94 | telNumberList numbers; |
|---|
| 95 | StringList emails; |
|---|
| 96 | string owner; |
|---|
| 97 | bool blocked; |
|---|
| 98 | } vcard_t; |
|---|
| 99 | |
|---|
| 100 | typedef std::list<vcard_t *> vcardList; |
|---|
| 101 | typedef std::list<vcard_t *>::iterator vcardIt; |
|---|
| 102 | |
|---|
| 103 | static const char * HOME_NUMBER_KEY = "home"; |
|---|
| 104 | static const char * WORK_NUMBER_KEY = "work"; |
|---|
| 105 | static const char * CELL_NUMBER_KEY = "cell"; |
|---|
| 106 | static const char * FAX_NUMBER_KEY = "fax"; |
|---|
| 107 | static const char * OTHER_NUMBER_KEY = "other"; |
|---|
| 108 | |
|---|
| 109 | telNumber_t * createNewNodeNumber(const std::string & key, const std::string & value) { |
|---|
| 110 | telNumber_t * number = new telNumber_t(); |
|---|
| 111 | |
|---|
| 112 | memset(number, 0, sizeof(telNumber_t)); |
|---|
| 113 | number->key = key; |
|---|
| 114 | number->value = value; |
|---|
| 115 | |
|---|
| 116 | return number; |
|---|
| 117 | } |
|---|
| 118 | |
|---|
| 119 | StringList mySplit(const std::string & str, char sep) { |
|---|
| 120 | string word; |
|---|
| 121 | StringList wordList; |
|---|
| 122 | istringstream strStream(str); |
|---|
| 123 | |
|---|
| 124 | while (std::getline(strStream, word, sep)) { |
|---|
| 125 | wordList += word; |
|---|
| 126 | } |
|---|
| 127 | |
|---|
| 128 | return wordList; |
|---|
| 129 | } |
|---|
| 130 | |
|---|
| 131 | static void initVcard(vcard_t * mVcard) { |
|---|
| 132 | if (mVcard) { |
|---|
| 133 | mVcard->gender = UNKNOWN; |
|---|
| 134 | mVcard->blocked = false; |
|---|
| 135 | mVcard->birthday.day = 1; |
|---|
| 136 | mVcard->birthday.month = 1; |
|---|
| 137 | mVcard->birthday.year = 1900; |
|---|
| 138 | } |
|---|
| 139 | } |
|---|
| 140 | |
|---|
| 141 | static const int CONFIG_UNKNOWN = 0; |
|---|
| 142 | static const int CONFIG_VERSION1 = 1; |
|---|
| 143 | static const int CONFIG_VERSION2 = 2; |
|---|
| 144 | static const int CONFIG_VERSION3 = 3; |
|---|
| 145 | static const int CONFIG_VERSION4 = 4; |
|---|
| 146 | static const int CONFIG_VERSION5 = 5; |
|---|
| 147 | static const int CONFIG_VERSION6 = 6; |
|---|
| 148 | static const int CONFIG_VERSION7 = 7; |
|---|
| 149 | static const int CONFIG_VERSION8 = 8; |
|---|
| 150 | static const int CONFIG_VERSION9 = 9; |
|---|
| 151 | static const int CONFIG_VERSION10 = 10; |
|---|
| 152 | static const int CONFIG_VERSION11 = 11; |
|---|
| 153 | static const int CONFIG_VERSION12 = 12; |
|---|
| 154 | static const int CONFIG_VERSION13 = 13; |
|---|
| 155 | static const int CONFIG_VERSION14 = 14; |
|---|
| 156 | static const int CONFIG_VERSION15 = 15; |
|---|
| 157 | |
|---|
| 158 | static const std::string USERPROFILE_FILENAME = "userprofile.xml"; |
|---|
| 159 | static const std::string USERCONFIG_FILENAME = "user.config"; |
|---|
| 160 | static const std::string IMACCOUNTS_FILENAME = "imaccounts.xml"; |
|---|
| 161 | static const std::string CONTACTLIST_FILENAME = "contactlist.xml"; |
|---|
| 162 | static const std::string NEW_HISTORY_FILENAME = "history.xml"; |
|---|
| 163 | static const std::string OLD_HISTORY_FILENAME = "_history"; |
|---|
| 164 | static const std::string CONFIG_FILENAME = "config.xml"; |
|---|
| 165 | static const std::string FAKE_LOGIN = "**fake_identity**"; |
|---|
| 166 | static const std::string FAKE_PASSWORD = "**fake_password**"; |
|---|
| 167 | static const std::string CONTACT_PREFIX = "#IMPORTED_CONTACT#"; |
|---|
| 168 | |
|---|
| 169 | void ConfigImporter::importConfig() { |
|---|
| 170 | Config& config = ConfigManager::getInstance().getCurrentConfig(); |
|---|
| 171 | int systemVersion = boost::any_cast<int>( config.getDefaultValue(Config::CONFIG_VERSION_KEY) ); |
|---|
| 172 | int localVersion = detectLastVersion(); |
|---|
| 173 | |
|---|
| 174 | if (localVersion != CONFIG_UNKNOWN && localVersion < systemVersion) { |
|---|
| 175 | if (localVersion == CONFIG_VERSION1) { |
|---|
| 176 | importConfigFromV1toV3(); |
|---|
| 177 | localVersion = CONFIG_VERSION3; |
|---|
| 178 | } |
|---|
| 179 | |
|---|
| 180 | if (localVersion == CONFIG_VERSION2) { |
|---|
| 181 | importConfigFromV2toV3(); |
|---|
| 182 | localVersion = CONFIG_VERSION3; |
|---|
| 183 | } |
|---|
| 184 | |
|---|
| 185 | if (localVersion == CONFIG_VERSION3) { |
|---|
| 186 | importConfigFromV3toV4(); |
|---|
| 187 | localVersion = CONFIG_VERSION4; |
|---|
| 188 | } |
|---|
| 189 | |
|---|
| 190 | if (localVersion == CONFIG_VERSION4) { |
|---|
| 191 | importConfigFromV4toV5(); |
|---|
| 192 | localVersion = CONFIG_VERSION5; |
|---|
| 193 | } |
|---|
| 194 | |
|---|
| 195 | if (localVersion == CONFIG_VERSION5) { |
|---|
| 196 | importConfigFromV5toV6(); |
|---|
| 197 | localVersion = CONFIG_VERSION6; |
|---|
| 198 | } |
|---|
| 199 | |
|---|
| 200 | if (localVersion == CONFIG_VERSION6) { |
|---|
| 201 | importConfigFromV6toV7(); |
|---|
| 202 | localVersion = CONFIG_VERSION7; |
|---|
| 203 | } |
|---|
| 204 | |
|---|
| 205 | if (localVersion == CONFIG_VERSION7) { |
|---|
| 206 | importConfigFromV7toV8(); |
|---|
| 207 | localVersion = CONFIG_VERSION8; |
|---|
| 208 | } |
|---|
| 209 | |
|---|
| 210 | if (localVersion == CONFIG_VERSION8) { |
|---|
| 211 | // Nothing to do, just bump the version number |
|---|
| 212 | localVersion = CONFIG_VERSION9; |
|---|
| 213 | } |
|---|
| 214 | |
|---|
| 215 | if (localVersion == CONFIG_VERSION9) { |
|---|
| 216 | // Nothing to do, just bump the version number |
|---|
| 217 | localVersion = CONFIG_VERSION10; |
|---|
| 218 | } |
|---|
| 219 | |
|---|
| 220 | if (localVersion == CONFIG_VERSION10) { |
|---|
| 221 | // Nothing to do, just bump the version number |
|---|
| 222 | localVersion = CONFIG_VERSION11; |
|---|
| 223 | } |
|---|
| 224 | |
|---|
| 225 | if (localVersion == CONFIG_VERSION11) { |
|---|
| 226 | // Nothing to do, just bump the version number |
|---|
| 227 | localVersion = CONFIG_VERSION12; |
|---|
| 228 | } |
|---|
| 229 | |
|---|
| 230 | if (localVersion == CONFIG_VERSION12) { |
|---|
| 231 | // Nothing to do, just bump the version number |
|---|
| 232 | localVersion = CONFIG_VERSION13; |
|---|
| 233 | } |
|---|
| 234 | |
|---|
| 235 | if (localVersion == CONFIG_VERSION13) { |
|---|
| 236 | // Nothing to do, just bump the version number |
|---|
| 237 | localVersion = CONFIG_VERSION14; |
|---|
| 238 | } |
|---|
| 239 | |
|---|
| 240 | if (localVersion == CONFIG_VERSION14) { |
|---|
| 241 | // Nothing to do, just bump the version number |
|---|
| 242 | localVersion = CONFIG_VERSION15; |
|---|
| 243 | } |
|---|
| 244 | |
|---|
| 245 | if (localVersion < systemVersion) { |
|---|
| 246 | LOG_FATAL("importer: config=" + String::fromNumber(localVersion) |
|---|
| 247 | + " failed to reach config=" + String::fromNumber(systemVersion)); |
|---|
| 248 | } |
|---|
| 249 | |
|---|
| 250 | // Set the new version number |
|---|
| 251 | Settings settings = readConfigFile(); |
|---|
| 252 | settings.set(Config::CONFIG_VERSION_KEY, systemVersion); |
|---|
| 253 | writeConfigFile(settings); |
|---|
| 254 | } |
|---|
| 255 | } |
|---|
| 256 | |
|---|
| 257 | unsigned ConfigImporter::detectLastVersion() { |
|---|
| 258 | string ConfigPathV1 = getWengoClassicConfigPath(); |
|---|
| 259 | string ConfigPathV2 = Config::getConfigDir(); |
|---|
| 260 | |
|---|
| 261 | bool dirV1Exists = !ConfigPathV1.empty() |
|---|
| 262 | && File::exists(ConfigPathV1.substr(0, ConfigPathV1.size() - 1)); |
|---|
| 263 | bool dirV2Exists = !ConfigPathV2.empty() |
|---|
| 264 | && File::exists(ConfigPathV2.substr(0, ConfigPathV2.size() - 1)); |
|---|
| 265 | |
|---|
| 266 | if (dirV2Exists) { |
|---|
| 267 | if (File::exists(ConfigPathV2 + "profiles")) { |
|---|
| 268 | |
|---|
| 269 | std::string configFilename = ConfigPathV2 + CONFIG_FILENAME; |
|---|
| 270 | if (!File::exists(configFilename)) { |
|---|
| 271 | return CONFIG_UNKNOWN; |
|---|
| 272 | } |
|---|
| 273 | Settings settings = readConfigFile(); |
|---|
| 274 | if (settings.contains(Config::CONFIG_VERSION_KEY)) { |
|---|
| 275 | return settings.getIntegerKeyValue(Config::CONFIG_VERSION_KEY); |
|---|
| 276 | } else { |
|---|
| 277 | // If the config version does not exist, it means that the |
|---|
| 278 | // config is older than version 4. |
|---|
| 279 | return CONFIG_VERSION3; |
|---|
| 280 | } |
|---|
| 281 | } else if (File::exists(ConfigPathV2 + "user.config")) { |
|---|
| 282 | return CONFIG_VERSION2; |
|---|
| 283 | } else if (dirV1Exists) { |
|---|
| 284 | return CONFIG_VERSION1; |
|---|
| 285 | } |
|---|
| 286 | } else if (dirV1Exists) { |
|---|
| 287 | return CONFIG_VERSION1; |
|---|
| 288 | } |
|---|
| 289 | |
|---|
| 290 | return CONFIG_UNKNOWN; |
|---|
| 291 | } |
|---|
| 292 | |
|---|
| 293 | string ConfigImporter::getWengoClassicConfigPath() { |
|---|
| 294 | string result; |
|---|
| 295 | |
|---|
| 296 | #if defined(OS_WINDOWS) |
|---|
| 297 | result = File::convertPathSeparators(Path::getHomeDirPath() + "wengo/"); |
|---|
| 298 | #elif defined(OS_LINUX) |
|---|
| 299 | result = File::convertPathSeparators(Path::getHomeDirPath() + ".wengo/"); |
|---|
| 300 | #endif |
|---|
| 301 | |
|---|
| 302 | return result; |
|---|
| 303 | } |
|---|
| 304 | |
|---|
| 305 | /** |
|---|
| 306 | * Works like std::getline() but will remove any ending '\r'. This is necessary |
|---|
| 307 | * because the WengoPhone Classic creates files ending with '\r\n', regardless |
|---|
| 308 | * of the platform |
|---|
| 309 | */ |
|---|
| 310 | static void getStrippedLine(std::ifstream& stream, std::string& line) { |
|---|
| 311 | std::getline(stream, line); |
|---|
| 312 | if (line[line.size() - 1] == '\r') { |
|---|
| 313 | line = line.substr(0, line.size() - 1); |
|---|
| 314 | } |
|---|
| 315 | } |
|---|
| 316 | |
|---|
| 317 | bool ConfigImporter::classicVcardParser(const string & vcardFile, void * structVcard) { |
|---|
| 318 | vcard_t * mVcard = (vcard_t *) structVcard; |
|---|
| 319 | std::ifstream fileStream; |
|---|
| 320 | string lastLine; |
|---|
| 321 | |
|---|
| 322 | fileStream.open(vcardFile.c_str()); |
|---|
| 323 | if (!fileStream) { |
|---|
| 324 | LOG_ERROR("cannot open the file: " + vcardFile); |
|---|
| 325 | return false; |
|---|
| 326 | } |
|---|
| 327 | |
|---|
| 328 | getStrippedLine(fileStream, lastLine); |
|---|
| 329 | if (lastLine != "BEGIN:VCARD") { |
|---|
| 330 | return false; |
|---|
| 331 | } |
|---|
| 332 | |
|---|
| 333 | String key, value, tmp; |
|---|
| 334 | |
|---|
| 335 | getStrippedLine(fileStream, tmp); |
|---|
| 336 | |
|---|
| 337 | while (!lastLine.empty()) { |
|---|
| 338 | int pos = lastLine.find(":", 0); |
|---|
| 339 | key = lastLine.substr(0, pos); |
|---|
| 340 | value = lastLine.substr(pos + 1, lastLine.length() - (pos + 1)); |
|---|
| 341 | |
|---|
| 342 | if (!value.empty()) { |
|---|
| 343 | if (!key.compare("N")) { |
|---|
| 344 | StringList mList = mySplit(value, ';'); |
|---|
| 345 | mVcard->lname = mList[0]; |
|---|
| 346 | mVcard->fname = mList[1]; |
|---|
| 347 | |
|---|
| 348 | if (!mList[4].compare("Mme.")) { |
|---|
| 349 | mVcard->gender = FEMALE; |
|---|
| 350 | } |
|---|
| 351 | else if (!mList[4].compare("Mr.")) { |
|---|
| 352 | mVcard->gender = MALE; |
|---|
| 353 | } |
|---|
| 354 | else { |
|---|
| 355 | mVcard->gender = UNKNOWN; |
|---|
| 356 | } |
|---|
| 357 | } |
|---|
| 358 | else if (!key.compare("TEL;TYPE=home")) { |
|---|
| 359 | mVcard->numbers.push_back(createNewNodeNumber(HOME_NUMBER_KEY, value)); |
|---|
| 360 | } |
|---|
| 361 | |
|---|
| 362 | else if (!key.compare("TEL;TYPE=work")) { |
|---|
| 363 | mVcard->numbers.push_back (createNewNodeNumber(WORK_NUMBER_KEY, value)); |
|---|
| 364 | } |
|---|
| 365 | |
|---|
| 366 | else if (!key.compare("TEL;TYPE=cell")) { |
|---|
| 367 | mVcard->numbers.push_back(createNewNodeNumber(CELL_NUMBER_KEY, value)); |
|---|
| 368 | } |
|---|
| 369 | |
|---|
| 370 | else if (!key.compare("TEL;TYPE=pref")) { |
|---|
| 371 | mVcard->id = CONTACT_PREFIX + value; |
|---|
| 372 | } |
|---|
| 373 | |
|---|
| 374 | else if (!key.compare("TEL;TYPE=fax")) { |
|---|
| 375 | mVcard->numbers.push_back(createNewNodeNumber(FAX_NUMBER_KEY, value)); |
|---|
| 376 | } |
|---|
| 377 | |
|---|
| 378 | else if (!key.compare("TEL;TYPE=other")) { |
|---|
| 379 | mVcard->numbers.push_back(createNewNodeNumber(OTHER_NUMBER_KEY, value)); |
|---|
| 380 | } |
|---|
| 381 | |
|---|
| 382 | else if (!key.compare("EMAIL")) { |
|---|
| 383 | mVcard->emails += value; |
|---|
| 384 | } |
|---|
| 385 | |
|---|
| 386 | else if (!key.compare("ORG")) { |
|---|
| 387 | mVcard->company = value; |
|---|
| 388 | } |
|---|
| 389 | |
|---|
| 390 | else if (!key.compare("URL")) { |
|---|
| 391 | mVcard->website = value; |
|---|
| 392 | } |
|---|
| 393 | |
|---|
| 394 | else if (!key.compare("BDAY")) { |
|---|
| 395 | StringList mList = mySplit(value, '-'); |
|---|
| 396 | mVcard->birthday.year = atoi(mList[0].c_str()); |
|---|
| 397 | mVcard->birthday.month = atoi(mList[1].c_str()); |
|---|
| 398 | mVcard->birthday.day = atoi(mList[2].c_str()); |
|---|
| 399 | } |
|---|
| 400 | else if (!key.compare("NOTE")) { |
|---|
| 401 | mVcard->note = value; |
|---|
| 402 | } |
|---|
| 403 | |
|---|
| 404 | else if (!key.compare("ADR;TYPE=home;TYPE=pref")) { |
|---|
| 405 | StringList mList = mySplit(value, ';'); |
|---|
| 406 | mVcard->address.street = mList[2]; |
|---|
| 407 | mVcard->address.city = mList[3]; |
|---|
| 408 | mVcard->address.state = mList[4]; |
|---|
| 409 | mVcard->address.post_code = mList[5]; |
|---|
| 410 | mVcard->address.country = mList[6]; |
|---|
| 411 | } |
|---|
| 412 | else { |
|---|
| 413 | LOG_DEBUG("KEY " + key + " not supported"); |
|---|
| 414 | } |
|---|
| 415 | } |
|---|
| 416 | |
|---|
| 417 | lastLine = tmp.trim(); |
|---|
| 418 | getStrippedLine(fileStream, tmp); |
|---|
| 419 | |
|---|
| 420 | if (!tmp.empty()) { |
|---|
| 421 | if (tmp.find(":", 0) == string::npos) { |
|---|
| 422 | lastLine += tmp.trim(); |
|---|
| 423 | getStrippedLine(fileStream, tmp); |
|---|
| 424 | } |
|---|
| 425 | } |
|---|
| 426 | } |
|---|
| 427 | |
|---|
| 428 | return true; |
|---|
| 429 | } |
|---|
| 430 | |
|---|
| 431 | bool ConfigImporter::classicXMLParser(const string & xmlFile, void *structVcard) { |
|---|
| 432 | vcard_t *mVcard = (vcard_t *) structVcard; |
|---|
| 433 | std::ifstream fileStream; |
|---|
| 434 | String lastLine; |
|---|
| 435 | |
|---|
| 436 | mVcard->blocked = false; |
|---|
| 437 | |
|---|
| 438 | fileStream.open(xmlFile.c_str()); |
|---|
| 439 | if (!fileStream) { |
|---|
| 440 | LOG_ERROR("cannot open the file: " + xmlFile); |
|---|
| 441 | return false; |
|---|
| 442 | } |
|---|
| 443 | |
|---|
| 444 | std::getline(fileStream, lastLine); |
|---|
| 445 | |
|---|
| 446 | while (!lastLine.empty()) { |
|---|
| 447 | lastLine = lastLine.trim(); |
|---|
| 448 | |
|---|
| 449 | if (!strncmp(lastLine.c_str(), "<blocked>", 9)) { |
|---|
| 450 | int pos1 = lastLine.find_first_of('>'); |
|---|
| 451 | int pos2 = lastLine.find_last_of('<'); |
|---|
| 452 | string resp = ((String)lastLine.substr(pos1 + 1, pos2 - (pos1 + 1))).trim(); |
|---|
| 453 | |
|---|
| 454 | if (resp == "true") { |
|---|
| 455 | mVcard->blocked = true; |
|---|
| 456 | } |
|---|
| 457 | } |
|---|
| 458 | |
|---|
| 459 | std::getline(fileStream, lastLine); |
|---|
| 460 | } |
|---|
| 461 | |
|---|
| 462 | return true; |
|---|
| 463 | } |
|---|
| 464 | |
|---|
| 465 | string ConfigImporter::classicVCardToString(void *structVcard) { |
|---|
| 466 | vcard_t * mVcard = (vcard_t *) structVcard; |
|---|
| 467 | string res = "<wgcard version=\"1.0\" xmlns=\"http://www.openwengo.org/wgcard/1.0\">\n"; |
|---|
| 468 | |
|---|
| 469 | //Todo: look at ProfileXMLSerializer and try to use the same serializer |
|---|
| 470 | if (!mVcard->id.empty()) { |
|---|
| 471 | res += ("<wengoid>" + mVcard->id + "</wengoid>\n"); |
|---|
| 472 | } |
|---|
| 473 | |
|---|
| 474 | res += "<name>\n"; |
|---|
| 475 | if (!mVcard->fname.empty()) { |
|---|
| 476 | res += ("<first><![CDATA[" + mVcard->fname + "]]></first>\n"); |
|---|
| 477 | } |
|---|
| 478 | if (!mVcard->lname.empty()) { |
|---|
| 479 | res += ("<last><![CDATA[" + mVcard->lname + "]]></last>\n"); |
|---|
| 480 | } |
|---|
| 481 | res += "</name>\n"; |
|---|
| 482 | |
|---|
| 483 | if (mVcard->gender == MALE) { |
|---|
| 484 | res += ("<sex>male</sex>\n"); |
|---|
| 485 | } |
|---|
| 486 | else if (mVcard->gender == FEMALE) { |
|---|
| 487 | res += ("<sex>female</sex>\n"); |
|---|
| 488 | } |
|---|
| 489 | |
|---|
| 490 | if (!mVcard->website.empty()) { |
|---|
| 491 | res += ("<url type=\"website\">" + mVcard->website + "</url>\n"); |
|---|
| 492 | } |
|---|
| 493 | |
|---|
| 494 | if (mVcard->birthday.day && mVcard->birthday.month && mVcard->birthday.year) { |
|---|
| 495 | res += "<birthday>\n<date>\n"; |
|---|
| 496 | res += ("<day>" + String::fromNumber(mVcard->birthday.day) + "</day>\n"); |
|---|
| 497 | res += ("<month>" + String::fromNumber(mVcard->birthday.month) + "</month>\n"); |
|---|
| 498 | res += ("<year>" + String::fromNumber(mVcard->birthday.year) + "</year>\n"); |
|---|
| 499 | res += "</date>\n</birthday>\n"; |
|---|
| 500 | } |
|---|
| 501 | |
|---|
| 502 | if (!mVcard->company.empty()) { |
|---|
| 503 | res += "<organization>" + mVcard->company + "</organization>\n"; |
|---|
| 504 | } |
|---|
| 505 | |
|---|
| 506 | telNumberIt it; |
|---|
| 507 | for (it = mVcard->numbers.begin(); it != mVcard->numbers.end(); it++) { |
|---|
| 508 | if (!(*it)->key.compare("home") && !((*it)->value.empty())) { |
|---|
| 509 | res += "<tel type=\"home\">" + (*it)->value + "</tel>\n"; |
|---|
| 510 | } |
|---|
| 511 | else if (!(*it)->key.compare("work") && !((*it)->value.empty())) { |
|---|
| 512 | res += "<tel type=\"work\">" + (*it)->value + "</tel>\n"; |
|---|
| 513 | } |
|---|
| 514 | else if (!(*it)->key.compare("cell") && !((*it)->value.empty())) { |
|---|
| 515 | res += "<tel type=\"cell\">" + (*it)->value + "</tel>\n"; |
|---|
| 516 | } |
|---|
| 517 | else if (!(*it)->key.compare("fax") && !((*it)->value.empty())) { |
|---|
| 518 | res += "<fax type=\"home\">" + (*it)->value + "</fax>\n"; |
|---|
| 519 | } |
|---|
| 520 | } |
|---|
| 521 | |
|---|
| 522 | res += "<address type=\"home\">\n"; |
|---|
| 523 | if (!mVcard->address.street.empty()) { |
|---|
| 524 | res += ("<street><![CDATA[" + mVcard->address.street + "]]></street>\n"); |
|---|
| 525 | } |
|---|
| 526 | if (!mVcard->address.city.empty()) { |
|---|
| 527 | res += ("<locality><![CDATA[" + mVcard->address.city + "]]></locality>\n"); |
|---|
| 528 | } |
|---|
| 529 | if (!mVcard->address.state.empty()) { |
|---|
| 530 | res += ("<region><![CDATA[" + mVcard->address.state + "]]></region>\n"); |
|---|
| 531 | } |
|---|
| 532 | if (!mVcard->address.post_code.empty()) { |
|---|
| 533 | res += ("<postcode><![CDATA[" + mVcard->address.post_code + "]]></postcode>\n"); |
|---|
| 534 | } |
|---|
| 535 | if (!mVcard->address.country.empty()) { |
|---|
| 536 | res += ("<country><![CDATA[" + mVcard->address.country + "]]></country>\n"); |
|---|
| 537 | } |
|---|
| 538 | res += "</address>\n"; |
|---|
| 539 | |
|---|
| 540 | if (!mVcard->id.empty()) { |
|---|
| 541 | res += "<im protocol=\"SIP/SIMPLE\">\n"; |
|---|
| 542 | res += ("<id>" + mVcard->id + "</id>\n"); |
|---|
| 543 | res += ("<account>" + mVcard->owner + "</account>"); |
|---|
| 544 | res += "</im>\n"; |
|---|
| 545 | } |
|---|
| 546 | |
|---|
| 547 | if (mVcard->emails.size() >= 1 && !mVcard->emails[0].empty()) { |
|---|
| 548 | res += ("<email type=\"home\">" + mVcard->emails[0] + "</email>\n"); |
|---|
| 549 | } |
|---|
| 550 | if (mVcard->emails.size() >= 2 && !mVcard->emails[1].empty()) { |
|---|
| 551 | res += ("<email type=\"work\">" + mVcard->emails[1] + "</email>\n"); |
|---|
| 552 | } |
|---|
| 553 | if (mVcard->emails.size() >= 3 && !mVcard->emails[2].empty()) { |
|---|
| 554 | res += ("<email type=\"other\">" + mVcard->emails[2] + "</email>\n"); |
|---|
| 555 | } |
|---|
| 556 | |
|---|
| 557 | if (!mVcard->note.empty()) { |
|---|
| 558 | res += ("<notes><![CDATA[" + mVcard->note + "]]></notes>\n"); |
|---|
| 559 | } |
|---|
| 560 | |
|---|
| 561 | res += ("<group><![CDATA[Wengo]]></group>\n"); |
|---|
| 562 | |
|---|
| 563 | res += "</wgcard>\n"; |
|---|
| 564 | return res; |
|---|
| 565 | } |
|---|
| 566 | |
|---|
| 567 | void ConfigImporter::addContactDetails(Contact & contact, void * structVcard) { |
|---|
| 568 | vcard_t * mVcard = (vcard_t *) structVcard; |
|---|
| 569 | |
|---|
| 570 | contact.setFirstName(mVcard->fname); |
|---|
| 571 | contact.setLastName(mVcard->lname); |
|---|
| 572 | contact.setCompany(mVcard->company); |
|---|
| 573 | contact.setBirthdate(Date(mVcard->birthday.day, mVcard->birthday.month, mVcard->birthday.year)); |
|---|
| 574 | contact.setNotes(mVcard->note); |
|---|
| 575 | contact.setWebsite(mVcard->website); |
|---|
| 576 | if (!mVcard->address.city.empty()) { |
|---|
| 577 | StreetAddress adress; |
|---|
| 578 | adress.setStreet(mVcard->address.street); |
|---|
| 579 | adress.setCity(mVcard->address.city); |
|---|
| 580 | adress.setZipCode(mVcard->address.post_code); |
|---|
| 581 | adress.setStateProvince(mVcard->address.state); |
|---|
| 582 | adress.setCountry(mVcard->address.country); |
|---|
| 583 | contact.setStreetAddress(adress); |
|---|
| 584 | } |
|---|
| 585 | |
|---|
| 586 | if (mVcard->gender != UNKNOWN) { |
|---|
| 587 | contact.setSex(mVcard->gender == MALE ? EnumSex::SexMale : EnumSex::SexFemale); |
|---|
| 588 | } |
|---|
| 589 | |
|---|
| 590 | telNumberIt it; |
|---|
| 591 | for (it = mVcard->numbers.begin(); it != mVcard->numbers.end(); it++) { |
|---|
| 592 | if (!(*it)->key.compare(HOME_NUMBER_KEY) && !((*it)->value.empty())) { |
|---|
| 593 | contact.setHomePhone((*it)->value); |
|---|
| 594 | } |
|---|
| 595 | else if (!(*it)->key.compare(WORK_NUMBER_KEY) && !((*it)->value.empty())) { |
|---|
| 596 | contact.setWorkPhone((*it)->value); |
|---|
| 597 | } |
|---|
| 598 | else if (!(*it)->key.compare(CELL_NUMBER_KEY) && !((*it)->value.empty())) { |
|---|
| 599 | contact.setMobilePhone((*it)->value); |
|---|
| 600 | } |
|---|
| 601 | else if (!(*it)->key.compare(FAX_NUMBER_KEY) && !((*it)->value.empty())) { |
|---|
| 602 | contact.setFax((*it)->value); |
|---|
| 603 | } |
|---|
| 604 | else if (!(*it)->key.compare(OTHER_NUMBER_KEY) && !((*it)->value.empty())) { |
|---|
| 605 | contact.setOtherPhone((*it)->value); |
|---|
| 606 | } |
|---|
| 607 | } |
|---|
| 608 | |
|---|
| 609 | if (mVcard->emails.size() >= 1 && !mVcard->emails[0].empty()) { |
|---|
| 610 | contact.setPersonalEmail(mVcard->emails[0]); |
|---|
| 611 | } |
|---|
| 612 | if (mVcard->emails.size() >= 2 && !mVcard->emails[1].empty()) { |
|---|
| 613 | contact.setWorkPhone(mVcard->emails[1]); |
|---|
| 614 | } |
|---|
| 615 | if (mVcard->emails.size() >= 3 && !mVcard->emails[2].empty()) { |
|---|
| 616 | contact.setOtherPhone(mVcard->emails[2]); |
|---|
| 617 | } |
|---|
| 618 | } |
|---|
| 619 | |
|---|
| 620 | bool ConfigImporter::importContactsFromV1toV3(const string & fromDir, UserProfile & userProfile) { |
|---|
| 621 | File mDir(fromDir); |
|---|
| 622 | StringList fileList = mDir.getFileList(); |
|---|
| 623 | ContactList & contactList = userProfile.getContactList(); |
|---|
| 624 | |
|---|
| 625 | contactList.addContactGroup("Classic"); |
|---|
| 626 | |
|---|
| 627 | IMAccountList imAccountList = |
|---|
| 628 | userProfile.getIMAccountManager().getIMAccountsOfProtocol(EnumIMProtocol::IMProtocolWengo); |
|---|
| 629 | |
|---|
| 630 | if (!imAccountList.size()) { |
|---|
| 631 | return false; |
|---|
| 632 | } |
|---|
| 633 | |
|---|
| 634 | for (unsigned i = 0; i < fileList.size(); i++) { |
|---|
| 635 | File mFile(fromDir + fileList[i]); |
|---|
| 636 | string Id = fileList[i].substr(0, fileList[i].find("_", 0)); |
|---|
| 637 | vcard_t mVcard; |
|---|
| 638 | |
|---|
| 639 | initVcard(&mVcard); |
|---|
| 640 | if (!mFile.getExtension().compare("vcf")) { |
|---|
| 641 | if (classicVcardParser(fromDir + fileList[i], &mVcard) == false) { |
|---|
| 642 | continue; |
|---|
| 643 | } |
|---|
| 644 | |
|---|
| 645 | int extPos = fileList[i].find_last_of('.'); |
|---|
| 646 | string fileWoExt = fileList[i].substr(0, extPos + 1); |
|---|
| 647 | classicXMLParser(fromDir + fileWoExt + "xml", &mVcard); |
|---|
| 648 | |
|---|
| 649 | IMContact imContact(*imAccountList.begin(), mVcard.id); |
|---|
| 650 | Contact & contact = contactList.createContact(); |
|---|
| 651 | contact.setGroupId(contactList.getContactGroupIdFromName("Classic")); |
|---|
| 652 | addContactDetails(contact, &mVcard); |
|---|
| 653 | contact.addIMContact(imContact); |
|---|
| 654 | } |
|---|
| 655 | } |
|---|
| 656 | return true; |
|---|
| 657 | } |
|---|
| 658 | |
|---|
| 659 | typedef struct last_user_s { |
|---|
| 660 | string login; |
|---|
| 661 | string password; |
|---|
| 662 | bool auto_login; |
|---|
| 663 | } last_user_t; |
|---|
| 664 | |
|---|
| 665 | void * ConfigImporter::getLastWengoUser(const std::string & configUserFile, int version) { |
|---|
| 666 | std::ifstream fileStream; |
|---|
| 667 | String lastLine; |
|---|
| 668 | |
|---|
| 669 | last_user_t * lastUser = new last_user_t(); |
|---|
| 670 | fileStream.open(configUserFile.c_str()); |
|---|
| 671 | if (!fileStream) { |
|---|
| 672 | LOG_ERROR("cannot open the file: " + configUserFile); |
|---|
| 673 | return NULL; |
|---|
| 674 | } |
|---|
| 675 | |
|---|
| 676 | std::getline(fileStream, lastLine); |
|---|
| 677 | |
|---|
| 678 | while (!lastLine.empty()) { |
|---|
| 679 | lastLine = lastLine.trim(); |
|---|
| 680 | |
|---|
| 681 | if (!strncmp(lastLine.c_str(), "<login>", 7)) { |
|---|
| 682 | int pos1, pos2; |
|---|
| 683 | if (version == CONFIG_VERSION2) { |
|---|
| 684 | pos1 = lastLine.find_first_of('>'); |
|---|
| 685 | pos2 = lastLine.find_last_of('<'); |
|---|
| 686 | } else { |
|---|
| 687 | pos2 = lastLine.find_first_of(']'); |
|---|
| 688 | pos1 = lastLine.find_last_of('['); |
|---|
| 689 | } |
|---|
| 690 | |
|---|
| 691 | lastUser->login = ((String)lastLine.substr(pos1 + 1, pos2 - (pos1 + 1))).trim(); |
|---|
| 692 | } |
|---|
| 693 | else if (!strncmp(lastLine.c_str(), "<password>", 10)) { |
|---|
| 694 | int pos1, pos2; |
|---|
| 695 | if (version == CONFIG_VERSION2) { |
|---|
| 696 | pos1 = lastLine.find_first_of('>'); |
|---|
| 697 | pos2 = lastLine.find_last_of('<'); |
|---|
| 698 | } else { |
|---|
| 699 | pos2 = lastLine.find_first_of(']'); |
|---|
| 700 | pos1 = lastLine.find_last_of('['); |
|---|
| 701 | } |
|---|
| 702 | |
|---|
| 703 | lastUser->password = ((String) lastLine.substr(pos1 + 1, pos2 - (pos1 + 1))).trim(); |
|---|
| 704 | } |
|---|
| 705 | else if (!strncmp(lastLine.c_str(), "<autoLogin>", 11)) { |
|---|
| 706 | int pos1 = lastLine.find_first_of('>'); |
|---|
| 707 | int pos2 = lastLine.find_last_of('<'); |
|---|
| 708 | string resp = ((String) lastLine.substr(pos1 + 1, pos2 - (pos1 + 1))).trim(); |
|---|
| 709 | |
|---|
| 710 | if (resp == (version == CONFIG_VERSION2 ? "1" : "true")) { |
|---|
| 711 | lastUser->auto_login = true; |
|---|
| 712 | } else { |
|---|
| 713 | lastUser->auto_login = false; |
|---|
| 714 | } |
|---|
| 715 | } |
|---|
| 716 | |
|---|
| 717 | std::getline(fileStream, lastLine); |
|---|
| 718 | } |
|---|
| 719 | |
|---|
| 720 | return lastUser; |
|---|
| 721 | } |
|---|
| 722 | |
|---|
| 723 | bool ConfigImporter::importConfigFromV1toV3() { |
|---|
| 724 | string classicPath = getWengoClassicConfigPath(); |
|---|
| 725 | File mDir(classicPath); |
|---|
| 726 | last_user_t * lastUser = (last_user_t *) getLastWengoUser(classicPath + USERCONFIG_FILENAME, CONFIG_VERSION1); |
|---|
| 727 | if (lastUser) { |
|---|
| 728 | UserProfile userProfile; |
|---|
| 729 | WengoAccount wAccount(lastUser->login, lastUser->password, true); |
|---|
| 730 | userProfile.setSipAccount(wAccount, false); |
|---|
| 731 | |
|---|
| 732 | // An SSO request was made here before. |
|---|
| 733 | // The SSO request was made to get the SIP identity of the user and link Wengo contacts to this id. |
|---|
| 734 | // Faking this SSO request. |
|---|
| 735 | IMAccount imAccount(FAKE_LOGIN, FAKE_PASSWORD, EnumIMProtocol::IMProtocolWengo); |
|---|
| 736 | userProfile.addIMAccount(imAccount); |
|---|
| 737 | |
|---|
| 738 | string sep = mDir.getPathSeparator(); |
|---|
| 739 | String oldPath = classicPath + lastUser->login + sep + "contacts" + sep; |
|---|
| 740 | importContactsFromV1toV3(oldPath, userProfile); |
|---|
| 741 | |
|---|
| 742 | String accountDir(userProfile.getProfileDirectory()); |
|---|
| 743 | File::createPath(accountDir); |
|---|
| 744 | UserProfileFileStorage1 fStorage(userProfile); |
|---|
| 745 | fStorage.save(userProfile.getName()); |
|---|
| 746 | |
|---|
| 747 | Settings settings = readConfigFile(); |
|---|
| 748 | settings.set(Config::PROFILE_LAST_USED_NAME_KEY, userProfile.getName()); |
|---|
| 749 | writeConfigFile(settings); |
|---|
| 750 | } |
|---|
| 751 | |
|---|
| 752 | return true; |
|---|
| 753 | } |
|---|
| 754 | |
|---|
| 755 | bool ConfigImporter::importConfigFromV2toV3() { |
|---|
| 756 | String configDir = Config::getConfigDir(); |
|---|
| 757 | |
|---|
| 758 | FileReader file(configDir + USERPROFILE_FILENAME); |
|---|
| 759 | if (file.open()) { |
|---|
| 760 | string data = file.read(); |
|---|
| 761 | |
|---|
| 762 | last_user_t * lastUser = (last_user_t *) getLastWengoUser(configDir + USERCONFIG_FILENAME, CONFIG_VERSION2); |
|---|
| 763 | if (lastUser == NULL) { |
|---|
| 764 | return false; |
|---|
| 765 | } |
|---|
| 766 | |
|---|
| 767 | UserProfile userProfile; |
|---|
| 768 | |
|---|
| 769 | UserProfileXMLSerializer serializer(userProfile); |
|---|
| 770 | serializer.unserialize(data); |
|---|
| 771 | |
|---|
| 772 | WengoAccount wAccount(lastUser->login, Base64::decode(lastUser->password), true); |
|---|
| 773 | userProfile.setSipAccount(wAccount, false); |
|---|
| 774 | |
|---|
| 775 | // An SSO request was made here before. |
|---|
| 776 | // The SSO request was made to get the SIP identity of the user and link Wengo contacts to this id. |
|---|
| 777 | // Faking this SSO request. |
|---|
| 778 | IMAccount imAccount(FAKE_LOGIN, FAKE_PASSWORD, EnumIMProtocol::IMProtocolWengo); |
|---|
| 779 | userProfile.addIMAccount(imAccount); |
|---|
| 780 | |
|---|
| 781 | //remove user.config and userprofile.xml from the main directory |
|---|
| 782 | File userConfigFile(configDir + USERCONFIG_FILENAME); |
|---|
| 783 | userConfigFile.remove(); |
|---|
| 784 | File userProfileFile(configDir + USERPROFILE_FILENAME); |
|---|
| 785 | userProfileFile.remove(); |
|---|
| 786 | |
|---|
| 787 | String accountDir(userProfile.getProfileDirectory()); |
|---|
| 788 | File::createPath(accountDir); |
|---|
| 789 | UserProfileFileStorage1 fStorage(userProfile); |
|---|
| 790 | fStorage.save(userProfile.getName()); |
|---|
| 791 | |
|---|
| 792 | File mFile1(configDir + IMACCOUNTS_FILENAME); |
|---|
| 793 | mFile1.move(accountDir + IMACCOUNTS_FILENAME, true); |
|---|
| 794 | |
|---|
| 795 | File mFile2(configDir + CONTACTLIST_FILENAME); |
|---|
| 796 | mFile2.move(accountDir + CONTACTLIST_FILENAME, true); |
|---|
| 797 | |
|---|
| 798 | File mDir(configDir); |
|---|
| 799 | StringList dirList = mDir.getFileList(); |
|---|
| 800 | for (unsigned i = 0; i < dirList.size(); i++) { |
|---|
| 801 | if (dirList[i].length() > OLD_HISTORY_FILENAME.length()) { |
|---|
| 802 | if (dirList[i].substr(dirList[i].length() - OLD_HISTORY_FILENAME.length()) == OLD_HISTORY_FILENAME) { |
|---|
| 803 | File mFile3(configDir + dirList[i]); |
|---|
| 804 | mFile3.move(accountDir + NEW_HISTORY_FILENAME, true); |
|---|
| 805 | break; |
|---|
| 806 | } |
|---|
| 807 | } |
|---|
| 808 | } |
|---|
| 809 | |
|---|
| 810 | Settings settings = readConfigFile(); |
|---|
| 811 | settings.set(Config::PROFILE_LAST_USED_NAME_KEY, userProfile.getName()); |
|---|
| 812 | writeConfigFile(settings); |
|---|
| 813 | } |
|---|
| 814 | |
|---|
| 815 | return true; |
|---|
| 816 | } |
|---|
| 817 | |
|---|
| 818 | bool ConfigImporter::importConfigFromV3toV4() { |
|---|
| 819 | StringList list = UserProfileHandler::getUserProfileNames(); |
|---|
| 820 | std::string sipSimpleProtocol = EnumIMProtocol::toString(EnumIMProtocol::IMProtocolSIPSIMPLE); |
|---|
| 821 | std::string wengoProtocol = EnumIMProtocol::toString(EnumIMProtocol::IMProtocolWengo); |
|---|
| 822 | |
|---|
| 823 | for (StringList::const_iterator it = list.begin(); |
|---|
| 824 | it != list.end(); |
|---|
| 825 | ++it) { |
|---|
| 826 | |
|---|
| 827 | std::string userProfileDirectory = File::convertPathSeparators(Config::getConfigDir() + "profiles/" + *it + "/"); |
|---|
| 828 | |
|---|
| 829 | //Replacing in imaccounts.xml |
|---|
| 830 | FileReader iIMAccountsFile(userProfileDirectory + "imaccounts.xml"); |
|---|
| 831 | iIMAccountsFile.open(); |
|---|
| 832 | String data = iIMAccountsFile.read(); |
|---|
| 833 | |
|---|
| 834 | data.replace(sipSimpleProtocol, wengoProtocol); |
|---|
| 835 | |
|---|
| 836 | FileWriter oIMAccountsFile(userProfileDirectory + "imaccounts.xml"); |
|---|
| 837 | oIMAccountsFile.write(data); |
|---|
| 838 | //// |
|---|
| 839 | |
|---|
| 840 | //Replacing in contactlist.xml |
|---|
| 841 | FileReader iContactListFile(userProfileDirectory + "contactlist.xml"); |
|---|
| 842 | iContactListFile.open(); |
|---|
| 843 | data = iContactListFile.read(); |
|---|
| 844 | |
|---|
| 845 | data.replace(sipSimpleProtocol, wengoProtocol); |
|---|
| 846 | |
|---|
| 847 | FileWriter oContactListFile(userProfileDirectory + "contactlist.xml"); |
|---|
| 848 | oContactListFile.write(data); |
|---|
| 849 | //// |
|---|
| 850 | } |
|---|
| 851 | |
|---|
| 852 | return true; |
|---|
| 853 | } |
|---|
| 854 | |
|---|
| 855 | bool ConfigImporter::importConfigFromV4toV5() { |
|---|
| 856 | std::string configFilename = Config::getConfigDir() + CONFIG_FILENAME; |
|---|
| 857 | //Replacing in config.xml |
|---|
| 858 | FileReader iConfigFile(configFilename); |
|---|
| 859 | iConfigFile.open(); |
|---|
| 860 | String data = iConfigFile.read(); |
|---|
| 861 | |
|---|
| 862 | // Fix video.quality key (int to string) |
|---|
| 863 | data.replace("<video.quality><int>0</int></video.quality>", |
|---|
| 864 | "<video.quality><string>VideoQualityNormal</string></video.quality>"); |
|---|
| 865 | data.replace("<video.quality><int>1</int></video.quality>", |
|---|
| 866 | "<video.quality><string>VideoQualityGood</string></video.quality>"); |
|---|
| 867 | data.replace("<video.quality><int>2</int></video.quality>", |
|---|
| 868 | "<video.quality><string>VideoQualityVeryGood</string></video.quality>"); |
|---|
| 869 | data.replace("<video.quality><int>3</int></video.quality>", |
|---|
| 870 | "<video.quality><string>VideoQualityExcellent</string></video.quality>"); |
|---|
| 871 | |
|---|
| 872 | FileWriter oConfigFile(configFilename); |
|---|
| 873 | oConfigFile.write(data); |
|---|
| 874 | //// |
|---|
| 875 | |
|---|
| 876 | return true; |
|---|
| 877 | } |
|---|
| 878 | |
|---|
| 879 | Settings ConfigImporter::readConfigFile() { |
|---|
| 880 | Settings settings; |
|---|
| 881 | std::string configFilename = Config::getConfigDir() + CONFIG_FILENAME; |
|---|
| 882 | FileReader iConfigFile(configFilename); |
|---|
| 883 | if (iConfigFile.open()) { |
|---|
| 884 | std::string data = iConfigFile.read(); |
|---|
| 885 | SettingsXMLSerializer serializer(settings); |
|---|
| 886 | serializer.unserialize(data); |
|---|
| 887 | } |
|---|
| 888 | return settings; |
|---|
| 889 | } |
|---|
| 890 | |
|---|
| 891 | void ConfigImporter::writeConfigFile(Settings& settings) { |
|---|
| 892 | std::string configFilename = Config::getConfigDir() + CONFIG_FILENAME; |
|---|
| 893 | SettingsXMLSerializer serializer(settings); |
|---|
| 894 | std::string data = serializer.serialize(); |
|---|
| 895 | |
|---|
| 896 | FileWriter oConfigFile(configFilename); |
|---|
| 897 | oConfigFile.write(data); |
|---|
| 898 | } |
|---|
| 899 | |
|---|
| 900 | bool ConfigImporter::importConfigFromV5toV6() { |
|---|
| 901 | Settings settings = readConfigFile(); |
|---|
| 902 | |
|---|
| 903 | // In V5 (WengoPhone 2.0), the values of GENERAL_SHOW_OFFLINE_CONTACTS_KEY |
|---|
| 904 | // and GENERAL_SHOW_GROUPS_KEY were the opposite of their meaning. |
|---|
| 905 | if (settings.contains(Config::GENERAL_SHOW_OFFLINE_CONTACTS_KEY)) { |
|---|
| 906 | settings.set(Config::GENERAL_SHOW_OFFLINE_CONTACTS_KEY, |
|---|
| 907 | !settings.getBooleanKeyValue(Config::GENERAL_SHOW_OFFLINE_CONTACTS_KEY) |
|---|
| 908 | ); |
|---|
| 909 | } |
|---|
| 910 | |
|---|
| 911 | if (settings.contains(Config::GENERAL_SHOW_GROUPS_KEY)) { |
|---|
| 912 | settings.set(Config::GENERAL_SHOW_GROUPS_KEY, |
|---|
| 913 | !settings.getBooleanKeyValue(Config::GENERAL_SHOW_GROUPS_KEY) |
|---|
| 914 | ); |
|---|
| 915 | } |
|---|
| 916 | |
|---|
| 917 | writeConfigFile(settings); |
|---|
| 918 | return true; |
|---|
| 919 | } |
|---|
| 920 | |
|---|
| 921 | bool ConfigImporter::importConfigFromV6toV7() { |
|---|
| 922 | StringList list = UserProfileHandler::getUserProfileNames(); |
|---|
| 923 | std::map<std::string, EnumIMProtocol::IMProtocol> accountMap; |
|---|
| 924 | |
|---|
| 925 | for (StringList::const_iterator it = list.begin(); |
|---|
| 926 | it != list.end(); |
|---|
| 927 | ++it) { |
|---|
| 928 | |
|---|
| 929 | std::string userProfileDirectory = File::convertPathSeparators(Config::getConfigDir() + "profiles/" + *it + "/"); |
|---|
| 930 | |
|---|
| 931 | //Replacing AIM/ICQ in imaccounts.xml |
|---|
| 932 | FileReader iIMAccountsFile(userProfileDirectory + "imaccounts.xml"); |
|---|
| 933 | iIMAccountsFile.open(); |
|---|
| 934 | String data = iIMAccountsFile.read(); |
|---|
| 935 | static const std::string AIMICQACCSTR = "<account protocol=\"AIM/ICQ\">"; |
|---|
| 936 | static const std::string LOGINSTR = "<login>"; |
|---|
| 937 | |
|---|
| 938 | std::string::size_type accPos = data.find(AIMICQACCSTR); |
|---|
| 939 | while (accPos != std::string::npos) { |
|---|
| 940 | // Gets login and protocol |
|---|
| 941 | std::string::size_type loginPos = data.find(LOGINSTR, accPos + AIMICQACCSTR.size()); |
|---|
| 942 | std::string login = data.substr(loginPos + LOGINSTR.size(), |
|---|
| 943 | data.find("</login>", loginPos) - loginPos - LOGINSTR.size()); |
|---|
| 944 | bool beginsWithDigit = (String(login.substr(0, 1)).toInteger() != 0); |
|---|
| 945 | EnumIMProtocol::IMProtocol protocol = EnumIMProtocol::IMProtocolAIM; |
|---|
| 946 | if (beginsWithDigit) { |
|---|
| 947 | protocol = EnumIMProtocol::IMProtocolICQ; |
|---|
| 948 | } |
|---|
| 949 | //// |
|---|
| 950 | |
|---|
| 951 | // Changing protocol line |
|---|
| 952 | data.replaceInRange(accPos, AIMICQACCSTR.size(), "AIM/ICQ", EnumIMProtocol::toString(protocol)); |
|---|
| 953 | //// |
|---|
| 954 | |
|---|
| 955 | // Inserting account in map for changing contactlist.xml |
|---|
| 956 | accountMap[login] = protocol; |
|---|
| 957 | //// |
|---|
| 958 | |
|---|
| 959 | accPos += AIMICQACCSTR.size(); |
|---|
| 960 | accPos = data.find(AIMICQACCSTR); |
|---|
| 961 | } |
|---|
| 962 | |
|---|
| 963 | FileWriter oIMAccountsFile(userProfileDirectory + "imaccounts.xml"); |
|---|
| 964 | oIMAccountsFile.write(data); |
|---|
| 965 | //// |
|---|
| 966 | |
|---|
| 967 | //Replacing in contactlist.xml |
|---|
| 968 | FileReader iContactListFile(userProfileDirectory + "contactlist.xml"); |
|---|
| 969 | iContactListFile.open(); |
|---|
| 970 | data = iContactListFile.read(); |
|---|
| 971 | static const std::string AIMICQIMSTR = "<im protocol=\"AIM/ICQ\">"; |
|---|
| 972 | static const std::string ACCOUNTSTR = "<account>"; |
|---|
| 973 | |
|---|
| 974 | std::string::size_type imPos = data.find(AIMICQIMSTR); |
|---|
| 975 | while (imPos != std::string::npos) { |
|---|
| 976 | std::string::size_type accountPos = data.find(ACCOUNTSTR, imPos + AIMICQIMSTR.size()); |
|---|
| 977 | std::string account = data.substr(accountPos + ACCOUNTSTR.size(), |
|---|
| 978 | data.find("</account>", accountPos) - accountPos - ACCOUNTSTR.size()); |
|---|
| 979 | data.replaceInRange(imPos, AIMICQIMSTR.size(), "AIM/ICQ", EnumIMProtocol::toString(accountMap[account])); |
|---|
| 980 | |
|---|
| 981 | imPos += AIMICQIMSTR.size(); |
|---|
| 982 | imPos = data.find(AIMICQIMSTR); |
|---|
| 983 | } |
|---|
| 984 | |
|---|
| 985 | FileWriter oContactListFile(userProfileDirectory + "contactlist.xml"); |
|---|
| 986 | oContactListFile.write(data); |
|---|
| 987 | //// |
|---|
| 988 | } |
|---|
| 989 | |
|---|
| 990 | return true; |
|---|
| 991 | } |
|---|
| 992 | |
|---|
| 993 | bool ConfigImporter::importConfigFromV7toV8() { |
|---|
| 994 | StringList list = UserProfileHandler::getUserProfileNames(); |
|---|
| 995 | std::map<std::string, EnumIMProtocol::IMProtocol> accountMap; |
|---|
| 996 | |
|---|
| 997 | for (StringList::const_iterator it = list.begin(); |
|---|
| 998 | it != list.end(); |
|---|
| 999 | ++it) { |
|---|
| 1000 | |
|---|
| 1001 | std::string userProfileDirectory = File::convertPathSeparators(Config::getConfigDir() + "profiles/" + *it + "/"); |
|---|
| 1002 | |
|---|
| 1003 | //Loading data |
|---|
| 1004 | FileReader iIMAccountsFile(userProfileDirectory + "imaccounts.xml"); |
|---|
| 1005 | iIMAccountsFile.open(); |
|---|
| 1006 | String data = iIMAccountsFile.read(); |
|---|
| 1007 | |
|---|
| 1008 | IMAccountList imAccountList; |
|---|
| 1009 | IMAccountListXMLSerializer1 imAccountListSerializer1(imAccountList); |
|---|
| 1010 | imAccountListSerializer1.unserialize(data); |
|---|
| 1011 | |
|---|
| 1012 | FileReader iContactListFile(userProfileDirectory + "contactlist.xml"); |
|---|
| 1013 | iContactListFile.open(); |
|---|
| 1014 | data = iContactListFile.read(); |
|---|
| 1015 | |
|---|
| 1016 | UserProfile userProfile; |
|---|
| 1017 | ContactList contactList(userProfile); |
|---|
| 1018 | ContactListXMLSerializer1 contactListSerializer1(contactList, imAccountList); |
|---|
| 1019 | contactListSerializer1.unserialize(data); |
|---|
| 1020 | |
|---|
| 1021 | // Look for IMAccount and Contact link to the IMAccount with login FAKE_LOGIN. It has been introduced by a previous importation step |
|---|
| 1022 | // to avoid the SSO request. |
|---|
| 1023 | for (IMAccountList::iterator ait = imAccountList.begin(); ait != imAccountList.end(); ++ait) { |
|---|
| 1024 | if (((*ait).getProtocol() == EnumIMProtocol::IMProtocolWengo) |
|---|
| 1025 | && ((*ait).getLogin() == FAKE_LOGIN)) { |
|---|
| 1026 | |
|---|
| 1027 | // Update contact links to this IMAccount (update UUID and remove CONTACT_PREFIX). |
|---|
| 1028 | for (ContactList::Contacts::iterator cit = const_cast<ContactList::Contacts &>(contactList.getContacts()).begin(); |
|---|
| 1029 | cit != contactList.getContacts().end(); |
|---|
| 1030 | cit++) { |
|---|
| 1031 | IMContactSet & imContactSet = const_cast<IMContactSet &>((*cit).getIMContactSet()); |
|---|
| 1032 | for (IMContactSet::iterator imit = imContactSet.begin(); |
|---|
| 1033 | imit != imContactSet.end(); |
|---|
| 1034 | imit++) { |
|---|
| 1035 | if (String((*imit).getContactId()).beginsWith(CONTACT_PREFIX)) { |
|---|
| 1036 | const_cast<IMContact &>(*imit).setContactId((*imit).getContactId().substr(CONTACT_PREFIX.size())); |
|---|
| 1037 | const_cast<IMContact &>(*imit).setIMAccount(&(*ait)); |
|---|
| 1038 | } |
|---|
| 1039 | } |
|---|
| 1040 | } |
|---|
| 1041 | |
|---|
| 1042 | // Removing the IMAccount |
|---|
| 1043 | imAccountList.erase(ait); |
|---|
| 1044 | break; |
|---|
| 1045 | } |
|---|
| 1046 | } |
|---|
| 1047 | //// |
|---|
| 1048 | |
|---|
| 1049 | IMAccountListXMLSerializer lastIMAccountListSerializer(imAccountList); |
|---|
| 1050 | data = lastIMAccountListSerializer.serialize(); |
|---|
| 1051 | FileWriter oIMAccountsFile(userProfileDirectory + "imaccounts.xml"); |
|---|
| 1052 | oIMAccountsFile.write(data); |
|---|
| 1053 | |
|---|
| 1054 | ContactListXMLSerializer lastContactListSerializer(contactList, imAccountList); |
|---|
| 1055 | data = lastContactListSerializer.serialize(); |
|---|
| 1056 | FileWriter oContactListFile(userProfileDirectory + "contactlist.xml"); |
|---|
| 1057 | oContactListFile.write(data); |
|---|
| 1058 | //// |
|---|
| 1059 | } |
|---|
| 1060 | |
|---|
| 1061 | return true; |
|---|
| 1062 | } |
|---|