summaryrefslogtreecommitdiff
path: root/plugins/Import/src
diff options
context:
space:
mode:
authorGeorge Hazan <ghazan@miranda.im>2019-05-04 13:59:29 +0300
committerGeorge Hazan <ghazan@miranda.im>2019-05-04 13:59:29 +0300
commita35ef5357c0cdfea74c0aa0ff78eae446ff050aa (patch)
tree94c44464dfd80e5108df1dc1c0ab31d38a5c9706 /plugins/Import/src
parent4a615270331b2f9d21fa66814e1ad1ea1d5f91a7 (diff)
first version of direct QIP2005 import that works
Diffstat (limited to 'plugins/Import/src')
-rw-r--r--plugins/Import/src/patterns.cpp141
-rw-r--r--plugins/Import/src/stdafx.h3
2 files changed, 106 insertions, 38 deletions
diff --git a/plugins/Import/src/patterns.cpp b/plugins/Import/src/patterns.cpp
index 53641e7589..994618f364 100644
--- a/plugins/Import/src/patterns.cpp
+++ b/plugins/Import/src/patterns.cpp
@@ -87,13 +87,20 @@ void CMPlugin::LoadPattern(const wchar_t *pwszFileName)
if (GetPrivateProfileStringW(L"Message", L"Out", L"", buf, _countof(buf), pwszFileName))
pNew->wszOutgoing = buf;
- pNew->iDirection = GetPrivateProfileIntW(L"General", L"Direction", 0, pwszFileName);
- pNew->iDay = GetPrivateProfileIntW(L"General", L"Day", 0, pwszFileName);
- pNew->iMonth = GetPrivateProfileIntW(L"General", L"Month", 0, pwszFileName);
- pNew->iYear = GetPrivateProfileIntW(L"General", L"Year", 0, pwszFileName);
- pNew->iHours = GetPrivateProfileIntW(L"General", L"Hours", 0, pwszFileName);
- pNew->iMinutes = GetPrivateProfileIntW(L"General", L"Minutes", 0, pwszFileName);
- pNew->iSeconds = GetPrivateProfileIntW(L"General", L"Seconds", 0, pwszFileName);
+ pNew->iDirection = GetPrivateProfileIntW(L"Message", L"Direction", 0, pwszFileName);
+ pNew->iDay = GetPrivateProfileIntW(L"Message", L"Day", 0, pwszFileName);
+ pNew->iMonth = GetPrivateProfileIntW(L"Message", L"Month", 0, pwszFileName);
+ pNew->iYear = GetPrivateProfileIntW(L"Message", L"Year", 0, pwszFileName);
+ pNew->iHours = GetPrivateProfileIntW(L"Message", L"Hours", 0, pwszFileName);
+ pNew->iMinutes = GetPrivateProfileIntW(L"Message", L"Minutes", 0, pwszFileName);
+ pNew->iSeconds = GetPrivateProfileIntW(L"Message", L"Seconds", 0, pwszFileName);
+
+ if (pNew->iUsePreMsg) {
+ pNew->preRN = GetPrivateProfileIntW(L"PreMessage", L"PreRN", -1, pwszFileName);
+ pNew->preSP = GetPrivateProfileIntW(L"PreMessage", L"PreSP", 0, pwszFileName);
+ pNew->afterRN = GetPrivateProfileIntW(L"PreMessage", L"AfterRN", -1, pwszFileName);
+ pNew->afterSP = GetPrivateProfileIntW(L"PreMessage", L"AfterSP", 0, pwszFileName);
+ }
if (pNew->iUseFilename) {
if (!GetPrivateProfileStringW(L"FileName", L"Pattern", L"", buf, _countof(buf), pwszFileName))
@@ -122,7 +129,6 @@ class CDbxPattern : public MDatabaseReadonly, public MZeroedObject
CMStringW m_buf;
std::vector<DWORD> m_events;
- std::vector<DWORD>::iterator m_curr;
public:
CDbxPattern()
@@ -130,15 +136,13 @@ public:
~CDbxPattern()
{
- if (m_hMap != nullptr)
- ::CloseHandle(m_hMap);
-
- if (m_hFile != INVALID_HANDLE_VALUE)
- ::CloseHandle(m_hFile);
}
void Load()
{
+ // mcontacts operates with the only contact with pseudo id=1
+ m_cache->AddContactToCache(1);
+
switch (g_pActivePattern->iCodePage) {
case CP_UTF8:
m_buf = mir_utf8decodeW(m_pFile);
@@ -164,6 +168,12 @@ public:
m_events.push_back(offsets[0]);
iOffset = offsets[1];
}
+
+ if (m_hMap != nullptr)
+ ::CloseHandle(m_hMap);
+
+ if (m_hFile != INVALID_HANDLE_VALUE)
+ ::CloseHandle(m_hFile);
}
int Open(const wchar_t *profile)
@@ -190,7 +200,17 @@ public:
return EGROKPRF_NOERROR;
}
- // mcontacts format always store history for one contact only
+ // patterns file always stores history for the single contact only
+ STDMETHODIMP_(LONG) GetBlobSize(MEVENT idx) override
+ {
+ if (m_events.size() == 0 || idx < 1 || idx > m_events.size())
+ return 0;
+
+ int iStart = m_events[idx-1], iEnd = (idx == m_events.size()) ? m_buf.GetLength() : m_events[idx];
+ CMStringW msg = m_buf.Mid(iStart, iEnd - iStart);
+ return (LONG)mir_strlen(ptrA(mir_utf8encodeW(msg))) + 1;
+ }
+
STDMETHODIMP_(LONG) GetContactCount(void) override
{
return 1;
@@ -201,58 +221,103 @@ public:
return (LONG)m_events.size();
}
- STDMETHODIMP_(BOOL) GetEvent(MEVENT dwOffset, DBEVENTINFO *dbei) override
+ ////////////////////////////////////////////////////////////////////////////////////////
+
+ static int str2int(const wchar_t* str)
{
+ if (str == nullptr || *str == 0)
+ return 0;
+
+ return _wtoi(str);
+ }
+
+ STDMETHODIMP_(BOOL) GetEvent(MEVENT idx, DBEVENTINFO *dbei) override
+ {
+ if (m_events.size() == 0 || idx < 1 || idx > m_events.size())
+ return 1;
+
int offsets[99];
- int nMatch = pcre16_exec(g_pActivePattern->regMessage.pattern, g_pActivePattern->regMessage.extra, m_buf, m_buf.GetLength(), dwOffset, PCRE_NEWLINE_ANYCRLF, offsets, _countof(offsets));
+ int nMatch = pcre16_exec(g_pActivePattern->regMessage.pattern, g_pActivePattern->regMessage.extra, m_buf, m_buf.GetLength(), m_events[idx - 1], PCRE_NEWLINE_ANYCRLF, offsets, _countof(offsets));
if (nMatch <= 0)
return 1;
- const wchar_t** substrings;
+ dbei->eventType = EVENTTYPE_MESSAGE;
+ dbei->flags = DBEF_READ | DBEF_UTF;
+
+ int h1 = offsets[1], h2 = (idx == m_events.size()) ? m_buf.GetLength() : m_events[idx];
+ int prn = -1, arn = -1;
+ if (g_pActivePattern->iUsePreMsg)
+ prn = g_pActivePattern->preRN, arn = g_pActivePattern->afterRN;
+
+ if (prn != 0) {
+ int i = 0;
+ while (m_buf[h1] == '\r' && m_buf[h1 + 1] == '\n' && i < prn)
+ h1 += 2, i++;
+ }
+
+ if (arn != 0) {
+ int i = 0;
+ while (m_buf[h2-2] == '\r' && m_buf[h2 - 1] == '\n' && i < arn)
+ h2 -= 2, i++;
+ }
+
+ if (dbei->cbBlob) {
+ CMStringW wszBody = m_buf.Mid(h1, h2-h1).Trim();
+ if (!wszBody.IsEmpty()) {
+ ptrA tmp(mir_utf8encodeW(wszBody));
+ int copySize = min(dbei->cbBlob - 1, (int)mir_strlen(tmp));
+ memcpy(dbei->pBlob, tmp, copySize);
+ dbei->pBlob[copySize] = 0;
+ dbei->cbBlob = copySize;
+ }
+ else dbei->cbBlob = 0;
+ }
+
+ const wchar_t **substrings;
if (pcre16_get_substring_list(m_buf, offsets, nMatch, &substrings) >= 0) {
struct tm st = {};
- st.tm_year = _wtoi(substrings[g_pActivePattern->iYear]);
- st.tm_mon = _wtoi(substrings[g_pActivePattern->iMonth]);
- st.tm_mday = _wtoi(substrings[g_pActivePattern->iDay]);
- st.tm_hour = _wtoi(substrings[g_pActivePattern->iHours]);
- st.tm_min = _wtoi(substrings[g_pActivePattern->iMinutes]);
- st.tm_sec = (g_pActivePattern->iSeconds) ? _wtoi(substrings[g_pActivePattern->iSeconds]) : 0;
+ st.tm_year = str2int(substrings[g_pActivePattern->iYear]);
+ if (st.tm_year > 1900)
+ st.tm_year -= 1900;
+ st.tm_mon = str2int(substrings[g_pActivePattern->iMonth]) - 1;
+ st.tm_mday = str2int(substrings[g_pActivePattern->iDay]);
+ st.tm_hour = str2int(substrings[g_pActivePattern->iHours]);
+ st.tm_min = str2int(substrings[g_pActivePattern->iMinutes]);
+ st.tm_sec = (g_pActivePattern->iSeconds) ? str2int(substrings[g_pActivePattern->iSeconds]) : 0;
dbei->timestamp = mktime(&st);
+ if (g_pActivePattern->iDirection)
+ if (g_pActivePattern->wszOutgoing == substrings[g_pActivePattern->iDirection])
+ dbei->flags |= DBEF_SENT;
+
+
pcre16_free_substring_list(substrings);
}
- return 1;
+ return 0;
}
STDMETHODIMP_(MEVENT) FindFirstEvent(MCONTACT) override
{
- m_curr = m_events.begin();
- return *m_curr;
+ return m_events.size() > 0 ? 1 : 0;
}
- STDMETHODIMP_(MEVENT) FindNextEvent(MCONTACT, MEVENT) override
+ STDMETHODIMP_(MEVENT) FindNextEvent(MCONTACT, MEVENT idx) override
{
- if (m_curr == m_events.end())
+ if (idx >= m_events.size())
return 0;
- ++m_curr;
- return *m_curr;
+ return idx + 1;
}
STDMETHODIMP_(MEVENT) FindLastEvent(MCONTACT) override
{
- m_curr = m_events.end();
- return *m_curr;
+ return m_events.size() > 0 ? (MEVENT)m_events.size() : 0;
}
- STDMETHODIMP_(MEVENT) FindPrevEvent(MCONTACT, MEVENT) override
+ STDMETHODIMP_(MEVENT) FindPrevEvent(MCONTACT, MEVENT idx) override
{
- if (m_curr == m_events.begin())
- return 0;
-
- --m_curr;
- return *m_curr;
+ return (idx >= 1) ? idx - 1 : 0;
}
};
diff --git a/plugins/Import/src/stdafx.h b/plugins/Import/src/stdafx.h
index 1e8bd8432a..70c795a33d 100644
--- a/plugins/Import/src/stdafx.h
+++ b/plugins/Import/src/stdafx.h
@@ -80,6 +80,9 @@ struct CImportPattern : public MZeroedObject
CRegexp regFilename;
int iInNick, iInUID, iOutNick, iOutUID;
+
+ // symbols pre & after a messages
+ int preRN, afterRN, preSP, afterSP;
};
struct CMPlugin : public PLUGIN<CMPlugin>