diff options
Diffstat (limited to 'plugins/Msg_Export')
-rw-r--r-- | plugins/Msg_Export/src/export.cpp | 259 | ||||
-rw-r--r-- | plugins/Msg_Export/src/main.cpp | 1 | ||||
-rw-r--r-- | plugins/Msg_Export/src/stdafx.cxx | 2 | ||||
-rw-r--r-- | plugins/Msg_Export/src/utils.cpp | 47 | ||||
-rw-r--r-- | plugins/Msg_Export/src/utils.h | 6 | ||||
-rw-r--r-- | plugins/Msg_Export/src/version.h | 6 |
6 files changed, 205 insertions, 116 deletions
diff --git a/plugins/Msg_Export/src/export.cpp b/plugins/Msg_Export/src/export.cpp index 6615db1315..76bc9c3e5e 100644 --- a/plugins/Msg_Export/src/export.cpp +++ b/plugins/Msg_Export/src/export.cpp @@ -1,5 +1,5 @@ /* -Copyright (C) 2012-24 Miranda NG team (https://miranda-ng.org) +Copyright (C) 2012-25 Miranda NG team (https://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 @@ -23,13 +23,7 @@ bool bIsUtf8Header(uint8_t *pucByteOrder) return memcmp(pucByteOrder, szUtf8ByteOrderHeader, 3) == 0; } -///////////////////////////////////////////////////////////////////// -// Member Function : bWriteToFile -// Type : Global -// Parameters : hFile - ? -// pszSrc - in UTF8 or ANSII -// nLen - ? -// Returns : Returns true if all the data was written to the file +///////////////////////////////////////////////////////////////////////////////////////// static bool bWriteToFile(HANDLE hFile, const char *pszSrc, int nLen = -1) { @@ -40,14 +34,7 @@ static bool bWriteToFile(HANDLE hFile, const char *pszSrc, int nLen = -1) return WriteFile(hFile, pszSrc, nLen, &dwBytesWritten, nullptr) && (dwBytesWritten == (uint32_t)nLen); } - -///////////////////////////////////////////////////////////////////// -// Member Function : bWriteTextToFile -// Type : Global -// Parameters : hFile - ? -// pszSrc - ? -// bUtf8File - ? -// Returns : Returns true if +///////////////////////////////////////////////////////////////////////////////////////// static bool bWriteTextToFile(HANDLE hFile, const wchar_t *pszSrc, bool bUtf8File, int nLen = -1) { @@ -66,12 +53,7 @@ static bool bWriteTextToFile(HANDLE hFile, const wchar_t *pszSrc, bool bUtf8File return bWriteToFile(hFile, T2Utf(pszSrc), -1); } -///////////////////////////////////////////////////////////////////// -// Member Function : bWriteNewLine -// Type : Global -// Parameters : hFile - ? -// nIndent - ? -// Returns : Returns true if all the data was written to the file +///////////////////////////////////////////////////////////////////////////////////////// const wchar_t wszNewLineIndent[] = L"\r\n "; void bWriteNewLine(CMStringW &str, int dwIndent) @@ -82,12 +64,7 @@ void bWriteNewLine(CMStringW &str, int dwIndent) str.Append(wszNewLineIndent, dwIndent + 2); } -///////////////////////////////////////////////////////////////////// -// Member Function : bWriteHexToFile -// Type : Global -// Parameters : hFile - ? -// - ? -// nSize - ? +///////////////////////////////////////////////////////////////////////////////////////// bool bWriteHexToFile(HANDLE hFile, void *pData, int nSize) { @@ -101,13 +78,7 @@ bool bWriteHexToFile(HANDLE hFile, void *pData, int nSize) return true; } -///////////////////////////////////////////////////////////////////// -// Member Function : bWriteIndentedToFile -// Type : Global -// Parameters : hFile - ? -// nIndent - ? -// pszSrc - -// Returns : Returns true if +///////////////////////////////////////////////////////////////////////////////////////// static bool bWriteIndentedToFile(CMStringW &str, int nIndent, const wchar_t *pszSrc) { @@ -177,14 +148,7 @@ SuperBreak: return bOk; } -///////////////////////////////////////////////////////////////////// -// Member Function : ExportDBEventInfo -// Type : Global -// Parameters : hContact - handle to contact -// hFile - handle to file -// sFilePath - path to file -// dbei - Event to export -// Returns : false on serious error, when file should be closed to not lost/overwrite any data +///////////////////////////////////////////////////////////////////////////////////////// const char *pSettings[] = { @@ -201,11 +165,77 @@ const char *pSettings[] = LPGEN("About") }; -static bool ExportDBEventInfo(MCONTACT hContact, HANDLE hFile, const wstring &sFilePath, DB::EventInfo &dbei, bool bAppendOnly) +static bool bPrepareHeader(MCONTACT hContact, HANDLE hFile, bool &bWriteUTF8Format, const wstring &sRemoteUser) { - wstring sLocalUser; - wstring sRemoteUser; - string::size_type nFirstColumnWidth; + const char *szProto = Proto_GetBaseAccountName(hContact); + + DWORD dwHighSize = 0; + DWORD dwLowSize = GetFileSize(hFile, &dwHighSize); + if (dwLowSize == INVALID_FILE_SIZE || dwLowSize != 0 || dwHighSize != 0) { + DWORD dwDataRead = 0; + uint8_t ucByteOrder[3]; + if (ReadFile(hFile, ucByteOrder, 3, &dwDataRead, nullptr)) + bWriteUTF8Format = bIsUtf8Header(ucByteOrder); + + DWORD dwPtr = SetFilePointer(hFile, 0, nullptr, FILE_END); + if (dwPtr == INVALID_SET_FILE_POINTER) + return false; + } + else { + bWriteUTF8Format = g_plugin.bUseUtf8InNewFiles; + if (bWriteUTF8Format) + if (!bWriteToFile(hFile, szUtf8ByteOrderHeader, sizeof(szUtf8ByteOrderHeader) - 1)) + return false; + + CMStringW output = L"------------------------------------------------\r\n"; + output.AppendFormat(L"%s\r\n", TranslateT(" History for")); + + // This is written this way because I expect this will become a string the user may set + // in the options dialog. + output.AppendFormat(L"%-10s: %s\r\n", TranslateT("User"), sRemoteUser.c_str()); + output.AppendFormat(L"%-10s: %S\r\n", TranslateT("Account"), szProto); + + ptrW id(Contact::GetInfo(CNF_UNIQUEID, hContact, szProto)); + if (id != NULL) + output.AppendFormat(L"%-10s: %s\r\n", TranslateT("User ID"), id.get()); + + int c = db_get_b(hContact, szProto, "Gender", 0); + if (c) + output.AppendFormat(L"%-10s: %c\r\n", TranslateT("Gender"), c); + + int age = db_get_w(hContact, szProto, "Age", 0); + if (age != 0) + output.AppendFormat(L"%-10s: %d\r\n", TranslateT("Age"), age); + + for (auto &it : pSettings) { + wstring szValue = _DBGetStringW(hContact, szProto, it, L""); + if (!szValue.empty()) + output.AppendFormat(L"%-10s: %s\r\n", TranslateW(_A2T(it)), szValue.c_str()); + } + + output += L"------------------------------------------------\r\n"; + + if (!bWriteTextToFile(hFile, output, bWriteUTF8Format, output.GetLength())) + return false; + } + + return true; +} + +///////////////////////////////////////////////////////////////////////////////////////// + +bool bExportEvent(MCONTACT hContact, MEVENT hDbEvent, HANDLE hFile, const wstring &sFilePath, bool bAppendOnly) +{ + DB::EventInfo dbei(hDbEvent); + if (!dbei) + return true; + + if (db_mc_isMeta(hContact)) + hContact = dbei.hContact; + + // Write the event + wstring sLocalUser, sRemoteUser; + size_t nFirstColumnWidth; auto *pJson = (MDatabaseExport *)hFile; const char *szProto = Proto_GetBaseAccountName(hContact); @@ -238,57 +268,8 @@ static bool ExportDBEventInfo(MCONTACT hContact, HANDLE hFile, const wstring &sF if (!pJson->BeginExport()) pJson->ExportContact(hContact); } - else { - DWORD dwHighSize = 0; - DWORD dwLowSize = GetFileSize(hFile, &dwHighSize); - if (dwLowSize == INVALID_FILE_SIZE || dwLowSize != 0 || dwHighSize != 0) { - DWORD dwDataRead = 0; - uint8_t ucByteOrder[3]; - if (ReadFile(hFile, ucByteOrder, 3, &dwDataRead, nullptr)) - bWriteUTF8Format = bIsUtf8Header(ucByteOrder); - - DWORD dwPtr = SetFilePointer(hFile, 0, nullptr, FILE_END); - if (dwPtr == INVALID_SET_FILE_POINTER) - return false; - } - else { - bWriteUTF8Format = g_plugin.bUseUtf8InNewFiles; - if (bWriteUTF8Format) - if (!bWriteToFile(hFile, szUtf8ByteOrderHeader, sizeof(szUtf8ByteOrderHeader) - 1)) - return false; - - CMStringW output = L"------------------------------------------------\r\n"; - output.AppendFormat(L"%s\r\n", TranslateT(" History for")); - - // This is written this way because I expect this will become a string the user may set - // in the options dialog. - output.AppendFormat(L"%-10s: %s\r\n", TranslateT("User"), sRemoteUser.c_str()); - output.AppendFormat(L"%-10s: %S\r\n", TranslateT("Account"), szProto); - - ptrW id(Contact::GetInfo(CNF_UNIQUEID, hContact, szProto)); - if (id != NULL) - output.AppendFormat(L"%-10s: %s\r\n", TranslateT("User ID"), id.get()); - - int c = db_get_b(hContact, szProto, "Gender", 0); - if (c) - output.AppendFormat(L"%-10s: %c\r\n", TranslateT("Gender"), c); - - int age = db_get_w(hContact, szProto, "Age", 0); - if (age != 0) - output.AppendFormat(L"%-10s: %d\r\n", TranslateT("Age"), age); - - for (auto &it : pSettings) { - wstring szValue = _DBGetStringW(hContact, szProto, it, L""); - if (!szValue.empty()) - output.AppendFormat(L"%-10s: %s\r\n", TranslateW(_A2T(it)), szValue.c_str()); - } - - output += L"------------------------------------------------\r\n"; - - if (!bWriteTextToFile(hFile, output, bWriteUTF8Format, output.GetLength())) - return false; - } - } + else if (!bPrepareHeader(hContact, hFile, bWriteUTF8Format, sRemoteUser)) + return false; } if (g_bUseJson) { @@ -308,10 +289,10 @@ static bool ExportDBEventInfo(MCONTACT hContact, HANDLE hFile, const wstring &sF // Get time stamp CMStringW output; - output.AppendFormat(L"%-*s", (int)nFirstColumnWidth, dbei.flags & DBEF_SENT ? sLocalUser.c_str() : sRemoteUser.c_str()); + output.AppendFormat(L"%-*s", (int)nFirstColumnWidth, dbei.bSent ? sLocalUser.c_str() : sRemoteUser.c_str()); { wchar_t buf[100]; - TimeZone_ToStringW(dbei.timestamp, g_sTimeFormat.c_str(), buf, _countof(buf)); + TimeZone_ToStringW(dbei.getUnixtime(), g_sTimeFormat.c_str(), buf, _countof(buf)); output.Append(buf); } @@ -323,7 +304,7 @@ static bool ExportDBEventInfo(MCONTACT hContact, HANDLE hFile, const wstring &sF switch (dbei.eventType) { case EVENTTYPE_MESSAGE: - output += ptrW(dbei.getText()); + bWriteIndentedToFile(output, nIndent, ptrW(dbei.getText())); break; case EVENTTYPE_FILE: @@ -429,20 +410,76 @@ static bool ExportDBEventInfo(MCONTACT hContact, HANDLE hFile, const wstring &sF } ///////////////////////////////////////////////////////////////////////////////////////// -// Module entry point -bool bExportEvent(MCONTACT hContact, MEVENT hDbEvent, HANDLE hFile, const wstring &sFilePath, bool bAppendOnly) +bool bExportReaction(const DB::EventInfo &dbei, const DBEventReaction &p, HANDLE hFile, const wstring &sFilePath) { - bool result = true; + // Write the event + wstring sLocalUser, sRemoteUser; + size_t nFirstColumnWidth; + auto *pJson = (MDatabaseExport *)hFile; - DB::EventInfo dbei(hDbEvent); - if (dbei) { - if (db_mc_isMeta(hContact)) - hContact = dbei.hContact; + const char *szProto = Proto_GetBaseAccountName(p.hContact); + if (szProto == nullptr) { + Netlib_Logf(0, MODULENAME ": cannot write message for a contact %d without protocol", p.hContact); + return false; + } + + if (g_plugin.bUseAngleBrackets) { + sLocalUser = L"<<"; + sRemoteUser = L">>"; + nFirstColumnWidth = 4; + } + else { + sLocalUser = ptrW(GetMyOwnNick(p.hContact)); + sRemoteUser = Clist_GetContactDisplayName(p.hContact); + + nFirstColumnWidth = max(sRemoteUser.size(), clFileTo1ColWidth[sFilePath]); + nFirstColumnWidth = max(sLocalUser.size(), nFirstColumnWidth); + nFirstColumnWidth += 2; + } + + bool bWriteUTF8Format = false; + + if (g_bUseJson) { + if (!pJson->BeginExport()) + pJson->ExportContact(p.hContact); - // Write the event - result = ExportDBEventInfo(hContact, hFile, sFilePath, dbei, bAppendOnly); + pJson->ExportEvent(dbei); + return true; } - return result; + if (!bPrepareHeader(p.hContact, hFile, bWriteUTF8Format, sRemoteUser)) + return false; + + // Get time stamp + CMStringW output; + output.AppendFormat(L"%-*s", (int)nFirstColumnWidth, dbei.bSent ? sLocalUser.c_str() : sRemoteUser.c_str()); + + wchar_t buf[100]; + TimeZone_ToStringW(time(0), g_sTimeFormat.c_str(), buf, _countof(buf)); + output.Append(buf); + + output.AppendChar(' '); + int nIndent = output.GetLength(); + + ptrW wszMessageText(dbei.getText()); + if (mir_wstrlen(wszMessageText) > 30) + mir_wstrcpy(wszMessageText.get() + 27, L"..."); + + Utf2T wszReaction(p.pszReaction); + + TimeZone_ToStringW(dbei.getUnixtime(), g_sTimeFormat.c_str(), buf, _countof(buf)); + CMStringW wszText; + if (p.bAdded) + wszText.Format(TranslateT("%s reacted with %s to message \"%s\" from %s"), sRemoteUser.c_str(), wszReaction.get(), wszMessageText.get(), buf); + else + wszText.Format(TranslateT("%s remove reaction %s to message \"%s\" from %s"), sRemoteUser.c_str(), wszReaction.get(), wszMessageText.get(), buf); + bWriteIndentedToFile(output, nIndent, wszText); + + output.Append(g_plugin.bAppendNewLine ? L"\r\n\r\n" : L"\r\n"); + if (!bWriteTextToFile(hFile, output, bWriteUTF8Format, output.GetLength())) + return false; + + UpdateFileViews(sFilePath.c_str()); + return true; } diff --git a/plugins/Msg_Export/src/main.cpp b/plugins/Msg_Export/src/main.cpp index 5b43b06505..638db5a903 100644 --- a/plugins/Msg_Export/src/main.cpp +++ b/plugins/Msg_Export/src/main.cpp @@ -127,6 +127,7 @@ int CMPlugin::Load() HookEvent(ME_DB_EVENT_ADDED, nExportEvent);
HookEvent(ME_DB_EVENT_EDITED, nExportEvent);
+ HookEvent(ME_DB_EVENT_REACTION, nExportReaction);
HookEvent(ME_DB_CONTACT_DELETED, nContactDeleted);
HookEvent(ME_OPT_INITIALISE, OptionsInitialize);
HookEvent(ME_SYSTEM_MODULESLOADED, MainInit);
diff --git a/plugins/Msg_Export/src/stdafx.cxx b/plugins/Msg_Export/src/stdafx.cxx index 13f28e1314..f111565f38 100644 --- a/plugins/Msg_Export/src/stdafx.cxx +++ b/plugins/Msg_Export/src/stdafx.cxx @@ -1,5 +1,5 @@ /*
-Copyright (C) 2012-24 Miranda NG team (https://miranda-ng.org)
+Copyright (C) 2012-25 Miranda NG team (https://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
diff --git a/plugins/Msg_Export/src/utils.cpp b/plugins/Msg_Export/src/utils.cpp index 8544154802..b56e401369 100644 --- a/plugins/Msg_Export/src/utils.cpp +++ b/plugins/Msg_Export/src/utils.cpp @@ -554,3 +554,50 @@ int nExportEvent(WPARAM hContact, LPARAM hDbEvent) return 0;
}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+int nExportReaction(WPARAM wParam, LPARAM lParam)
+{
+ auto *dbei = (DB::EventInfo *)wParam;
+ auto *p = (DBEventReaction *)lParam;
+ if (!p || !dbei)
+ return 0;
+
+ if (!bIsExportEnabled(p->hContact))
+ return 0;
+
+ // Open/create file for writing
+ wstring sFilePath = GetFilePathFromUser(p->hContact);
+ MDatabaseExport *pJson = nullptr;
+ HANDLE hFile;
+
+ if (g_bUseJson) {
+ pJson = g_pDriver->Export(sFilePath.c_str());
+ if (pJson == nullptr) {
+ DisplayErrorDialog(LPGENW("Failed to open or create file:\n"), sFilePath);
+ return 0;
+ }
+
+ hFile = pJson;
+ }
+ else {
+ hFile = openCreateFile(sFilePath);
+ if (hFile == INVALID_HANDLE_VALUE) {
+ DisplayErrorDialog(LPGENW("Failed to open or create file:\n"), sFilePath);
+ return 0;
+ }
+ }
+
+ // Write the event
+ bExportReaction(*dbei, *p, hFile, sFilePath);
+
+ // Close the file
+ if (pJson) {
+ pJson->EndExport();
+ delete pJson;
+ }
+ else CloseHandle(hFile);
+
+ return 0;
+}
diff --git a/plugins/Msg_Export/src/utils.h b/plugins/Msg_Export/src/utils.h index c39b0770ae..12323d13be 100644 --- a/plugins/Msg_Export/src/utils.h +++ b/plugins/Msg_Export/src/utils.h @@ -45,9 +45,13 @@ void DisplayErrorDialog(const wchar_t *pszError, wstring &sFilePath); bool bIsExportEnabled(MCONTACT hContact);
HANDLE openCreateFile(const wstring &sFilePath);
-bool bExportEvent(MCONTACT hContact, MEVENT hDbEvent, HANDLE hFile, const wstring &sFilePath, bool bAppendOnly);
+bool bExportEvent(MCONTACT hContact, MEVENT hDbEvent, HANDLE hFile, const wstring &sFilePath, bool bAppendOnly);
int nExportEvent(WPARAM wparam, LPARAM lparam);
+
+bool bExportReaction(const DB::EventInfo &dbei, const DBEventReaction &p, HANDLE, const wstring &sFilePath);
+int nExportReaction(WPARAM wparam, LPARAM lparam);
+
int nContactDeleted(WPARAM wparam, LPARAM lparam);
wchar_t* GetMyOwnNick(MCONTACT hContact);
diff --git a/plugins/Msg_Export/src/version.h b/plugins/Msg_Export/src/version.h index 2755bd63b5..63e1cdcbde 100644 --- a/plugins/Msg_Export/src/version.h +++ b/plugins/Msg_Export/src/version.h @@ -1,7 +1,7 @@ #define __MAJOR_VERSION 3
#define __MINOR_VERSION 1
-#define __RELEASE_NUM 2
-#define __BUILD_NUM 10
+#define __RELEASE_NUM 3
+#define __BUILD_NUM 1
#include <stdver.h>
@@ -10,4 +10,4 @@ #define __DESCRIPTION "Exports every message, URL or file you receive to a text file."
#define __AUTHOR "Kennet Nielsen, mod by ring0"
#define __AUTHORWEB "https://miranda-ng.org/p/Msg_Export"
-#define __COPYRIGHT "© 2002 Kennet Nielsen, 2012-24 Miranda NG team"
+#define __COPYRIGHT "© 2002 Kennet Nielsen, 2012-25 Miranda NG team"
|