/* Copyright (c) 2015 Miranda NG project (http://miranda-ng.org) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "common.h" bool CSkypeProto::IsOnline() { return m_iStatus > ID_STATUS_OFFLINE && m_hPollingThread; } MEVENT CSkypeProto::AddEventToDb(MCONTACT hContact, WORD type, DWORD timestamp, DWORD flags, DWORD cbBlob, PBYTE pBlob) { DBEVENTINFO dbei = { sizeof(dbei) }; dbei.szModule = this->m_szModuleName; dbei.timestamp = timestamp; dbei.eventType = type; dbei.cbBlob = cbBlob; dbei.pBlob = pBlob; dbei.flags = flags; return db_event_add(hContact, &dbei); } time_t CSkypeProto::IsoToUnixTime(const TCHAR *stamp) { TCHAR date[9]; int i, y; if (stamp == NULL) return 0; TCHAR *p = NEWTSTR_ALLOCA(stamp); // skip '-' chars int si = 0, sj = 0; while (true) { if (p[si] == _T('-')) si++; else if (!(p[sj++] = p[si++])) break; } // Get the date part for (i = 0; *p != '\0' && i < 8 && isdigit(*p); p++, i++) date[i] = *p; // Parse year if (i == 6) { // 2-digit year (1970-2069) y = (date[0] - '0') * 10 + (date[1] - '0'); if (y < 70) y += 100; } else if (i == 8) { // 4-digit year y = (date[0] - '0') * 1000 + (date[1] - '0') * 100 + (date[2] - '0') * 10 + date[3] - '0'; y -= 1900; } else return 0; struct tm timestamp; timestamp.tm_year = y; // Parse month timestamp.tm_mon = (date[i - 4] - '0') * 10 + date[i - 3] - '0' - 1; // Parse date timestamp.tm_mday = (date[i - 2] - '0') * 10 + date[i - 1] - '0'; // Skip any date/time delimiter for (; *p != '\0' && !isdigit(*p); p++); // Parse time if (_stscanf(p, _T("%d:%d:%d"), ×tamp.tm_hour, ×tamp.tm_min, ×tamp.tm_sec) != 3) return (time_t)0; timestamp.tm_isdst = 0; // DST is already present in _timezone below time_t t = mktime(×tamp); _tzset(); t -= _timezone; return (t >= 0) ? t : 0; } struct HtmlEntity { const char *entity; char symbol; }; const HtmlEntity htmlEntities[] = { { "nbsp", ' ' }, { "amp", '&' }, { "quot", '"' }, { "lt", '<' }, { "gt", '>' }, { "apos", '\'' }, { "copy", '©' }, // TODO: add more }; char *CSkypeProto::RemoveHtml(const char *text) { std::string new_string = ""; std::string data = text; if (data.find("\x1b\xe3\xac\x8d\x1d") != -1) data = "CONVERSATION MEMBERS:" + data.substr(5, data.length() - 5); for (std::string::size_type i = 0; i < data.length(); i++) { if (data.at(i) == '<' && data.at(i + 1) != ' ') { i = data.find(">", i); if (i == std::string::npos) break; continue; } if (data.at(i) == '&') { std::string::size_type begin = i; i = data.find(";", i); if (i == std::string::npos) { i = begin; } else { std::string entity = data.substr(begin + 1, i - begin - 1); bool found = false; for (int j = 0; j < SIZEOF(htmlEntities); j++) { if (!stricmp(entity.c_str(), htmlEntities[j].entity)) { new_string += htmlEntities[j].symbol; found = true; break; } } if (found) continue; else i = begin; } } new_string += data.at(i); } return mir_strdup(new_string.c_str()); } bool CSkypeProto::IsMe(const char *skypeName) { ptrA mySkypeName(getStringA(SKYPE_SETTINGS_ID)); ptrA SelfEndpointName(getStringA("SelfEndpointName")); if (!mir_strcmp(skypeName, mySkypeName) || !mir_strcmp(skypeName, SelfEndpointName)) return true; return false; } char *CSkypeProto::MirandaToSkypeStatus(int status) { switch (status) { case ID_STATUS_AWAY: return "Away"; case ID_STATUS_DND: return "Busy"; case ID_STATUS_IDLE: return "Idle"; case ID_STATUS_INVISIBLE: return "Hidden"; } return "Online"; } int CSkypeProto::SkypeToMirandaStatus(const char *status) { if (!mir_strcmpi(status, "Online")) return ID_STATUS_ONLINE; else if (!mir_strcmpi(status, "Hidden")) return ID_STATUS_INVISIBLE; else if (!mir_strcmpi(status, "Away")) return ID_STATUS_AWAY; else if (!mir_strcmpi(status, "Idle")) return /*ID_STATUS_IDLE*/ID_STATUS_AWAY; else if (!mir_strcmpi(status, "Busy")) return ID_STATUS_DND; else return ID_STATUS_OFFLINE; } void CSkypeProto::ShowNotification(const TCHAR *caption, const TCHAR *message, int flags, MCONTACT hContact) { if (Miranda_Terminated()) return; if (ServiceExists(MS_POPUP_ADDPOPUPT) && db_get_b(NULL, "Popup", "ModuleIsEnabled", 1)) { POPUPDATAT ppd = { 0 }; ppd.lchContact = hContact; wcsncpy(ppd.lpwzContactName, caption, MAX_CONTACTNAME); wcsncpy(ppd.lpwzText, message, MAX_SECONDLINE); ppd.lchIcon = Skin_GetIcon("Skype_main"); if (!PUAddPopupT(&ppd)) return; } MessageBox(NULL, message, caption, MB_OK | flags); } void CSkypeProto::ShowNotification(const TCHAR *message, int flags, MCONTACT hContact) { ShowNotification(_T(MODULE), message, flags, hContact); } bool CSkypeProto::IsFileExists(std::tstring path) { return _taccess(path.c_str(), 0) == 0; } // url parsing char *CSkypeProto::ParseUrl(const char *url, const char *token) { const char *start = strstr(url, token); if (start == NULL) return NULL; start = start + mir_strlen(token); const char *end = strchr(start, '/'); if (end == NULL) return mir_strdup(start); return mir_strndup(start, end - start); } char *CSkypeProto::ContactUrlToName(const char *url) { return ParseUrl(url, "/8:"); } char *CSkypeProto::SelfUrlToName(const char *url) { return ParseUrl(url, "/1:"); } char *CSkypeProto::ChatUrlToName(const char *url) { return ParseUrl(url, "/19:"); } char *CSkypeProto::GetServerFromUrl(const char *url) { return ParseUrl(url, "://"); }