diff options
author | Mikhail Grigoryev <sleuthhound@gmail.com> | 2013-05-22 09:48:12 +0000 |
---|---|---|
committer | Mikhail Grigoryev <sleuthhound@gmail.com> | 2013-05-22 09:48:12 +0000 |
commit | 273b10c5ce28a955e6b7a6b384cba736f1762d77 (patch) | |
tree | dbbea2f0fad1523ddac35d4eefe3581a977cc970 /plugins/MirandaNGHistoryToDB/MsgExport.pas | |
parent | be91c27a63f26c845a8f16b4a12cb048152ef182 (diff) |
Added plugin MirandaNGHistoryToDB (www.im-history.ru)
git-svn-id: http://svn.miranda-ng.org/main/trunk@4793 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins/MirandaNGHistoryToDB/MsgExport.pas')
-rw-r--r-- | plugins/MirandaNGHistoryToDB/MsgExport.pas | 452 |
1 files changed, 452 insertions, 0 deletions
diff --git a/plugins/MirandaNGHistoryToDB/MsgExport.pas b/plugins/MirandaNGHistoryToDB/MsgExport.pas new file mode 100644 index 0000000000..e36e3b1c8a --- /dev/null +++ b/plugins/MirandaNGHistoryToDB/MsgExport.pas @@ -0,0 +1,452 @@ +{ ############################################################################ }
+{ # # }
+{ # MirandaNG HistoryToDB Plugin v2.5 # }
+{ # # }
+{ # License: GPLv3 # }
+{ # # }
+{ # Author: Grigorev Michael (icq: 161867489, email: sleuthhound@gmail.com) # }
+{ # # }
+{ ############################################################################ }
+
+unit MsgExport;
+
+interface
+
+uses
+ Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
+ Dialogs, JvWizard, JvExControls, JvWizardRouteMapNodes, ComCtrls, StdCtrls,
+ JvComponentBase, JvThread, JclStringConversions, Global, Contacts, m_api;
+
+type
+ TContactRecord = record
+ hContact: Cardinal;
+ ContactID: AnsiString;
+ ContactName: AnsiString;
+ ProtoName: AnsiString;
+ Selected: Boolean;
+ end;
+ TExportForm = class(TForm)
+ IMExportWizard: TJvWizard;
+ Page1: TJvWizardWelcomePage;
+ Page2: TJvWizardInteriorPage;
+ Page3: TJvWizardInteriorPage;
+ Page4: TJvWizardInteriorPage;
+ LExportDesc: TLabel;
+ IMExportThread: TJvThread;
+ CBSelectAll: TCheckBox;
+ ContactList: TListView;
+ PBTotalExport: TProgressBar;
+ LExportDesc2: TLabel;
+ CBSyncRequest: TCheckBox;
+ LExportDone: TLabel;
+ procedure FormCreate(Sender: TObject);
+ procedure FormShow(Sender: TObject);
+ procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
+ procedure FormClose(Sender: TObject; var Action: TCloseAction);
+ procedure Page3Page(Sender: TObject);
+ procedure IMExportWizardCancelButtonClick(Sender: TObject);
+ procedure IMExportWizardFinishButtonClick(Sender: TObject);
+ procedure IMExportThreadExecute(Sender: TObject; Params: Pointer);
+ procedure CBSelectAllClick(Sender: TObject);
+ procedure ContactListChanging(Sender: TObject; Item: TListItem; Change: TItemChange; var AllowChange: Boolean);
+ procedure ContactListChange(Sender: TObject; Item: TListItem; Change: TItemChange);
+ procedure BringFormToFront(Form: TForm);
+ function CheckStopExportAndExit: Boolean;
+ private
+ { Private declarations }
+ StartExport: Boolean;
+ // Для мультиязыковой поддержки
+ procedure OnLanguageChanged(var Msg: TMessage); message WM_LANGUAGECHANGED;
+ procedure LoadLanguageStrings;
+ public
+ { Public declarations }
+ end;
+
+var
+ ExportForm: TExportForm;
+ ExportContactRecords: Array of TContactRecord;
+
+implementation
+
+{$R *.dfm}
+{$R icons.res}
+
+procedure TExportForm.FormCreate(Sender: TObject);
+begin
+ StartExport := False;
+ ExportFormDestroy := False;
+ // Для мультиязыковой поддержки
+ ExportFormHandle := Handle;
+ SetWindowLong(Handle, GWL_HWNDPARENT, 0);
+ SetWindowLong(Handle, GWL_EXSTYLE, GetWindowLong(Handle, GWL_EXSTYLE) or WS_EX_APPWINDOW);
+ // Загружаем язык интерфейса
+ LoadLanguageStrings;
+end;
+
+procedure TExportForm.FormShow(Sender: TObject);
+var
+ ListItem: TListItem;
+ hContact: Cardinal;
+ ContactProto, ContactID, ContactName: AnsiString;
+ Count: Integer;
+begin
+ IMExportWizard.ActivePage := Page1;
+ StartExport := False;
+ // Получаем список контактов
+ hContact := CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+ ContactList.Columns[0].MaxWidth := 190;
+ ContactList.Columns[1].MaxWidth := 90;
+ ContactList.Columns[2].MaxWidth := 140;
+ ContactList.Items.BeginUpdate;
+ Count := 0;
+ while hContact <> 0 do
+ begin
+ ContactProto := GetContactProto(hContact);
+ ContactID := GetContactID(hContact, ContactProto);
+ ContactName := GetContactDisplayName(hContact, '', True);
+ // Доп. проверка протокола
+ if ContactProto = MyAccount then
+ ContactProto := 'ICQ';
+ if ContactName = '' then
+ ContactName := 'NoContactName';
+ if ContactID = '' then
+ ContactID := 'NoContactID';
+ SetLength(ExportContactRecords, Count + 1);
+ ExportContactRecords[Count].hContact := hContact;
+ ExportContactRecords[Count].ContactID := ContactID;
+ ExportContactRecords[Count].ContactName := ContactName;
+ ExportContactRecords[Count].ProtoName := ContactProto;
+ ExportContactRecords[Count].Selected := False;
+ Inc(Count);
+ ListItem := ContactList.Items.Add;
+ ListItem.Caption := ContactName;
+ ListItem.SubItems.Add(ContactProto);
+ ListItem.SubItems.Add(ContactID);
+ {if StrContactProtoToInt(ContactProto) = 15 then // 15 - Unknown Proto
+ ListItem.Checked := False
+ else
+ ListItem.Checked := True;}
+ hContact := CallService(MS_DB_CONTACT_FINDNEXT, hContact, 0);
+ end;
+ ContactList.Items.EndUpdate;
+end;
+
+procedure TExportForm.FormClose(Sender: TObject; var Action: TCloseAction);
+begin
+ ExportFormDestroy := True;
+ Action := caFree;
+end;
+
+procedure TExportForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
+begin
+ CanClose := CheckStopExportAndExit;
+end;
+
+procedure TExportForm.IMExportWizardCancelButtonClick(Sender: TObject);
+begin
+ Close;
+end;
+
+procedure TExportForm.IMExportWizardFinishButtonClick(Sender: TObject);
+begin
+ if IMExportWizard.ActivePage = Page4 then
+ begin
+ if CBSyncRequest.Checked then
+ OnSendMessageToAllComponent('002');
+ Close;
+ end;
+end;
+
+procedure TExportForm.Page3Page(Sender: TObject);
+begin
+ StartExport := True;
+ Page3.EnabledButtons := [bkCancel];
+ if not IMExportThread.Terminated then
+ begin
+ IMExportThread.Terminate;
+ while not (IMExportThread.Terminated) do
+ Sleep(1);
+ end;
+ IMExportThread.Execute(Self);
+end;
+
+procedure TExportForm.IMExportThreadExecute(Sender: TObject; Params: Pointer);
+var
+ I, J, K, ProtoType: Integer;
+ SelectedCount, BlobSize: Integer;
+ hDbEvent: Cardinal;
+ DBEventInfo: TDBEventInfo;
+ msgA: PAnsiChar;
+ msgW: PChar;
+ msgLen, LenW: Cardinal;
+ Msg_Date: TDateTime;
+ Msg_RcvrNick, Msg_RcvrAcc, Msg_SenderNick, Msg_SenderAcc, Msg_Text, MD5String: WideString;
+ Date_Str, MsgStatus: String;
+ ContactProto, ContactID, ContactName: AnsiString;
+ MyContactName, MyContactID: AnsiString;
+begin
+ LExportDesc2.Caption := 'Export...';
+ // Подсчитываем количество выделенных элементов
+ SelectedCount := 0;
+ for J := 0 to Length(ExportContactRecords) do
+ begin
+ if ExportContactRecords[J].Selected = True then
+ Inc(SelectedCount);
+ if IMExportThread.Terminated then // Выход из потока в случае закрытия окна
+ Exit;
+ end;
+ LExportDesc.Caption := Format(GetLangStr('TotalSelect'), [IntToStr(SelectedCount), IntToStr(Length(ExportContactRecords))]);
+ // Начинаем перебор всех элементов
+ PBTotalExport.Position := 0;
+ PBTotalExport.Max := SelectedCount;
+ SelectedCount := 0;
+ for I := 0 to Length(ExportContactRecords) do
+ begin
+ // Если выделен, то экспортируем его историю
+ if ExportContactRecords[I].Selected = True then
+ begin
+ LExportDesc2.Caption := Format(GetLangStr('ContactExport'), [ExportContactRecords[I].ContactName, ExportContactRecords[I].ContactID]);
+ Inc(SelectedCount);
+ PBTotalExport.Position := SelectedCount;
+ if IMExportThread.Terminated then // Выход из потока в случае закрытия окна
+ Exit;
+ hDbEvent := CallService(MS_DB_EVENT_FINDFIRST, ExportContactRecords[I].hContact, 0);
+ while hDbEvent <> 0 do
+ begin
+ ZeroMemory(@DBEventInfo, SizeOf(DBEventInfo));
+ DBEventInfo.cbSize := SizeOf(DBEventInfo);
+ DBEventInfo.pBlob := nil;
+ BlobSize := CallService(MS_DB_EVENT_GETBLOBSIZE, hDbEvent, 0);
+ GetMem(DBEventInfo.pBlob, BlobSize);
+ DBEventInfo.cbBlob := BlobSize;
+ if IMExportThread.Terminated then // Выход из потока в случае закрытия окна
+ begin
+ if ImportLogOpened then
+ CloseLogFile(5);
+ Exit;
+ end;
+ if (CallService(MS_DB_EVENT_GET, hDbEvent, Integer(@DBEventInfo)) = 0) and (DBEventInfo.eventType = EVENTTYPE_MESSAGE and EVENTTYPE_URL) then
+ begin
+ // Получаем текст сообщения
+ msgA := PAnsiChar(DBEventInfo.pBlob);
+ msgW := nil;
+ msgLen := lstrlenA(PAnsiChar(DBEventInfo.pBlob)) + 1;
+ if msgLen > DBEventInfo.cbBlob then
+ msgLen := DBEventInfo.cbBlob;
+ if Boolean(DBEventInfo.flags and DBEF_UTF) then
+ begin
+ SetLength(Msg_Text, msgLen);
+ LenW := Utf8ToWideChar(PChar(Msg_Text), msgLen, msgA, msgLen - 1, CP_ACP);
+ if Integer(LenW) > 0 then
+ SetLength(Msg_Text, LenW - 1)
+ else
+ Msg_Text := AnsiToWideString(msgA, CP_ACP, msgLen - 1);
+ end
+ else
+ begin
+ LenW := 0;
+ if DBEventInfo.cbBlob >= msgLen * SizeOf(Char) then
+ begin
+ msgW := PChar(msgA + msgLen);
+ for K := 0 to ((DBEventInfo.cbBlob - msgLen) div SizeOf(Char)) - 1 do
+ if msgW[K] = #0 then
+ begin
+ LenW := K;
+ Break;
+ end;
+ end;
+ if (LenW > 0) and (LenW < msgLen) then
+ SetString(Msg_Text, msgW, LenW)
+ else
+ Msg_Text := AnsiToWideString(msgA, CP_ACP, msgLen - 1);
+ end;
+ // Тип истории
+ ContactProto := GetContactProto(ExportContactRecords[I].hContact);
+ // Данные собеседника
+ ContactID := GetContactID(ExportContactRecords[I].hContact, ContactProto);
+ ContactName := GetContactDisplayName(ExportContactRecords[I].hContact, '', True);
+ // Мои данные
+ MyContactName := GetMyContactDisplayName(ContactProto);
+ MyContactID := GetMyContactID(ContactProto);
+ // Доп. проверка протокола
+ if ContactProto = MyAccount then
+ ContactProto := 'ICQ';
+ // Тип истории
+ ProtoType := StrContactProtoToInt(ContactProto);
+ if ContactID = '' then
+ ContactID := 'NoContactID';
+ if ContactName = '' then
+ ContactName := 'NoContactName';
+ if MyContactID = '' then
+ MyContactID := 'NoMyContactID';
+ if MyContactName = '' then
+ MyContactName := 'NoMyContactName';
+ // Экранирование, перекодирование и т.п.
+ Msg_SenderNick := PrepareString(pWideChar(AnsiToWideString(MyContactName, CP_ACP)));
+ Msg_SenderAcc := PrepareString(pWideChar(AnsiToWideString(MyContactID, CP_ACP)));
+ Msg_SenderNick := WideStringToUTF8(Msg_SenderNick);
+ Msg_SenderAcc := WideStringToUTF8(Msg_SenderAcc);
+ Msg_RcvrNick := PrepareString(pWideChar(AnsiToWideString(ContactName, CP_ACP)));
+ Msg_RcvrAcc := PrepareString(pWideChar(AnsiToWideString(ContactID, CP_ACP)));
+ Msg_RcvrNick := WideStringToUTF8(Msg_RcvrNick);
+ Msg_RcvrAcc := WideStringToUTF8(Msg_RcvrAcc);
+ Msg_Text := WideStringToUTF8(PrepareString(pWideChar(Msg_Text)));
+ MD5String := Msg_RcvrAcc + FormatDateTime('YYYY-MM-DD HH:MM:SS', UnixToLocalTime(DBEventInfo.timestamp)) + Msg_Text;
+ if (DBType = 'oracle') or (DBType = 'oracle-9i') then
+ Date_Str := FormatDateTime('DD.MM.YYYY HH:MM:SS', UnixToLocalTime(DBEventInfo.timestamp))
+ else
+ Date_Str := FormatDateTime('YYYY-MM-DD HH:MM:SS', UnixToLocalTime(DBEventInfo.timestamp));
+ if MatchStrings(LowerCase(ContactProto), 'skype*') then
+ begin
+ // Определяем направление отправки (мы отправили или нам прислали)
+ if (DBEventInfo.flags and DBEF_SENT) = 0 then
+ MsgStatus := '0' // Входящее
+ else
+ MsgStatus := '1'; // Исходящее
+ // Лог отладки
+ if EnableDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - Функция OnEventAdded: ' + 'Contact ID: ' + ContactID + ' | Contact Name: ' + ContactName + ' | Proto: ' + ContactProto + ' | My Contact ID: ' + MyContactID + ' | My Contact Name: ' + MyContactName + ' | Contact Proto = ' + ContactProto + ' | MsgStatus = ' + MsgStatus + ' | DateTime = ' + FormatDateTime('DD.MM.YYYY HH:MM:SS', UnixToLocalTime(DBEventInfo.timestamp)) + ' | Message = ' + Msg_Text, 2);
+ if (MatchStrings(DBType, 'oracle*')) then // Если Oracle, то пишем SQL-лог в формате CHAT_MSG_LOG_ORACLE
+ WriteInLog(ProfilePath, Format(CHAT_MSG_LOG_ORACLE, [DBUserName, MsgStatus, 'to_date('''+Date_Str+''', ''dd.mm.yyyy hh24:mi:ss'')', Msg_RcvrNick, 'Skype', Msg_RcvrNick+' ('+Msg_RcvrAcc+')', BoolToIntStr(True), BoolToIntStr(False), BoolToIntStr(False), Msg_Text, EncryptMD5(MD5String)]), 5)
+ else
+ WriteInLog(ProfilePath, Format(CHAT_MSG_LOG, [DBUserName, MsgStatus, Date_Str, Msg_RcvrNick, 'Skype', Msg_RcvrNick+' ('+Msg_RcvrAcc+')', BoolToIntStr(True), BoolToIntStr(False), BoolToIntStr(False), Msg_Text, EncryptMD5(MD5String)]), 5);
+ end
+ else
+ begin
+ // Определяем направление отправки (мы отправили или нам прислали)
+ if (DBEventInfo.flags and DBEF_SENT) = 0 then
+ MsgStatus := '1' // Входящее
+ else
+ MsgStatus := '0'; // Исходящее
+ // Лог отладки
+ if EnableDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - Функция OnEventAdded: ' + 'Contact ID: ' + ContactID + ' | Contact Name: ' + ContactName + ' | Proto: ' + ContactProto + ' | My Contact ID: ' + MyContactID + ' | My Contact Name: ' + MyContactName + ' | Contact Proto = ' + ContactProto + ' | MsgStatus = ' + MsgStatus + ' | DateTime = ' + FormatDateTime('DD.MM.YYYY HH:MM:SS', UnixToLocalTime(DBEventInfo.timestamp)) + ' | Message = ' + Msg_Text, 2);
+ if (MatchStrings(DBType, 'oracle*')) then // Если Oracle, то пишем SQL-лог в формате MSG_LOG_ORACLE
+ WriteInLog(ProfilePath, Format(MSG_LOG_ORACLE, [DBUserName, IntToStr(ProtoType), Msg_SenderNick, Msg_SenderAcc, Msg_RcvrNick, Msg_RcvrAcc, MsgStatus, 'to_date('''+Date_Str+''', ''dd.mm.yyyy hh24:mi:ss'')', Msg_Text, EncryptMD5(MD5String)]), 5)
+ else
+ WriteInLog(ProfilePath, Format(MSG_LOG, [DBUserName, IntToStr(ProtoType), Msg_SenderNick, Msg_SenderAcc, Msg_RcvrNick, Msg_RcvrAcc, MsgStatus, Date_Str, Msg_Text, EncryptMD5(MD5String)]), 5);
+ end;
+ end;
+ hDbEvent := CallService(MS_DB_EVENT_FINDNEXT, hDbEvent, 0);
+ end;
+ end;
+ if IMExportThread.Terminated then // Выход из потока в случае закрытия окна
+ Exit;
+ end;
+ Page3.EnabledButtons := [bkCancel,bkNext];
+ StartExport := False;
+ if ImportLogOpened then
+ CloseLogFile(5);
+ LExportDesc2.Caption := GetLangStr('ExportDone');
+end;
+
+procedure TExportForm.BringFormToFront(Form: TForm);
+begin
+ if Form.WindowState = wsMaximized then
+ ShowWindow(Form.Handle, SW_SHOWMAXIMIZED)
+ else
+ ShowWindow(Form.Handle, SW_SHOWNORMAL);
+ Form.BringToFront;
+end;
+
+function TExportForm.CheckStopExportAndExit: Boolean;
+begin
+ if StartExport then
+ begin
+ case MessageBox(Handle, pWideChar(GetLangStr('ExportAbort')), pWideChar(htdPluginShortName + ' - ' +GetLangStr('ExportAbortCaption')),36) of
+ 6:
+ begin
+ if not IMExportThread.Terminated then
+ begin
+ IMExportThread.Terminate;
+ while not (IMExportThread.Terminated) do
+ begin
+ Sleep(1);
+ Forms.Application.ProcessMessages;
+ end;
+ end;
+ Result := True;
+ end;
+ 7:
+ begin
+ Result := False;
+ Exit;
+ end;
+ end;
+ end
+ else
+ Result := True;
+end;
+
+procedure TExportForm.ContactListChange(Sender: TObject; Item: TListItem; Change: TItemChange);
+begin
+ if Item.Checked <> ExportContactRecords[Item.Index].Selected then // Юзер изменил значение Item.Checked
+ begin
+ ExportContactRecords[Item.Index].Selected := Item.Checked; // Изменяем значение переменной на новое значение
+ { Здесь можно делать что хотим....}
+ end;
+end;
+
+procedure TExportForm.ContactListChanging(Sender: TObject; Item: TListItem; Change: TItemChange; var AllowChange: Boolean);
+begin
+ ExportContactRecords[Item.Index].Selected := Item.Checked; // Запоминаем значение Item.Checked, до того как юзер на нее нажал
+ AllowChange := True; // Разрешаем юзеру нажать :)
+end;
+
+procedure TExportForm.CBSelectAllClick(Sender: TObject);
+var
+ I: Integer;
+begin
+ for I := 0 to ContactList.Items.Count-1 do
+ begin
+ ContactList.Items[I].Checked := CBSelectAll.Checked;
+ ExportContactRecords[I].Selected := CBSelectAll.Checked;
+ end;
+ //LExportDesc.Caption := IntToStr(Length(ExportContactRecords)) + ' - ' + IntToStr(ContactList.Items.Count);
+end;
+
+// Для мультиязыковой поддержки
+procedure TExportForm.OnLanguageChanged(var Msg: TMessage);
+begin
+ LoadLanguageStrings;
+end;
+
+// Для мультиязыковой поддержки
+procedure TExportForm.LoadLanguageStrings;
+var
+ ExportBitmap: TBitmap;
+begin
+ Caption := htdPluginShortName + ' - ' + GetLangStr('ExortFormCaption');
+ IMExportWizard.ButtonBack.Caption := '< ' + GetLangStr('ButtonBack');
+ IMExportWizard.ButtonNext.Caption := GetLangStr('ButtonNext') + ' >';
+ IMExportWizard.ButtonFinish.Caption := GetLangStr('ButtonFinish');
+ IMExportWizard.ButtonCancel.Caption := GetLangStr('ButtonCancel');
+ IMExportWizard.Pages.Items[0].Title.Text := GetLangStr('IMExportWizardPage0Title');
+ IMExportWizard.Pages.Items[0].Subtitle.Text := Format(GetLangStr('IMExportWizardPage0SubTitle'), [htdIMClientName]);
+ IMExportWizard.Pages.Items[1].Title.Text := GetLangStr('IMExportWizardPage1Title');
+ IMExportWizard.Pages.Items[1].Subtitle.Text := GetLangStr('IMExportWizardPage1SubTitle');
+ IMExportWizard.Pages.Items[2].Title.Text := GetLangStr('IMExportWizardPage2Title');
+ IMExportWizard.Pages.Items[2].Subtitle.Text := GetLangStr('IMExportWizardPage2SubTitle');
+ IMExportWizard.Pages.Items[3].Title.Text := GetLangStr('IMExportWizardPage3Title');
+ IMExportWizard.Pages.Items[3].Subtitle.Text := GetLangStr('IMExportWizardPage3SubTitle');
+ CBSelectAll.Caption := GetLangStr('SelectAll');
+ ContactList.Columns[0].Caption := GetLangStr('NickName');
+ ContactList.Columns[1].Caption := GetLangStr('Protocol');
+ ContactList.Columns[2].Caption := GetLangStr('Number');
+ LExportDone.Caption := GetLangStr('ExportDoneDesc');
+ CBSyncRequest.Caption := GetLangStr('SendSyncRequest');
+ // Грузим битовый образы из файла ресурсов
+ if IMExportWizard.ActivePage = Page1 then
+ begin
+ ExportBitmap := TBitmap.Create;
+ try
+ if DefaultLanguage = 'Russian' then
+ ExportBitmap.LoadFromResourceName(HInstance, 'Export_Ru')
+ else
+ ExportBitmap.LoadFromResourceName(HInstance, 'Export_En');
+ Page1.WaterMark.Image.Picture.Assign(ExportBitmap);
+ finally
+ ExportBitmap.Free;
+ end;
+ end;
+end;
+
+end.
|