{%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% osCommerce Product Manager for Windows (oscpmwin). Copyright ©2003-2006 by Mario A. Valdez-Ramirez. You can contact Mario A. Valdez-Ramirez by email at mario@mariovaldez.org or paper mail at Olmos 809, San Nicolas, NL. 66495, Mexico. 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; either version 2 of the License, or (at your option) any later version. 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, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%} unit modules; interface USES Classes, menus, IdTCPClient; CONST opmC_Max_Modules_PerList = 50; opmC_Def_ModPort = 27572; opmC_Min_ModPort = 1; opmC_Max_ModPort = 65535; opmC_DirModules = 'modules'; opmC_Def_ModulesExt = 'ini'; opmC_RKModule = 'module'; opmC_ModQuitCommand = 'QUIT OSCPM1'; opmC_ModStatCommand = 'STATS OSCPM1'; opmC_TCPTimeout = 10000; opmC_Localhost = '127.0.0.1'; opmC_ModOKCode = 'OK'; opmC_ModStatCode = 'STAT'; opmC_ModStatCodeEnd = 'STAT END'; opmC_ModNACode = 'NOT FOUND'; opmC_ModErrorCode = 'ERROR ERROR'; opmC_Max_ModNameWidth = 100; opmC_Max_ModCMDWidth = 500; opmC_ModStartupWait = 1000; opmC_Max_Exchanges_PerList = 8192; opmC_Def_LoadModExt = 'exe'; opmC_Def_LoadModFilename = ''; opmC_Def_LoadModFilter = '*.exe'; opmC_ModRet_Null = 0; opmC_ModRet_Data = 1; opmC_ModRet_Stat = 2; opmC_SyncField_ProductID = 'products_id'; opmC_SyncField_ProductModel = 'products_model'; opmC_SyncField_ProductQuantity = 'products_quantity'; opmC_SyncField_ProductPrice = 'products_price'; opmC_SyncField_ProductImage = 'products_image'; opmC_SyncField_ProductWeight = 'products_weight'; opmC_SyncField_ProductStatus = 'products_status'; opmC_SyncField_ProductOrdered = 'products_ordered'; opmC_SyncResult_Any = 0; opmC_SyncResult_Equal = 1; opmC_SyncResult_Diff = 2; opmC_SyncResult_Unknown = 3; opmC_SyncResult_Error = 4; opmC_SyncResult_Restricted = 5; TYPE opmR_Module = RECORD Name : STRING; CommandFile : STRING; CommandPara : STRING; Port : LONGINT; Remote : LONGINT; IndexData : STRING; ResultData : STRING; JustRun : LONGINT; OnSelection : LONGINT; END; opmT_ModuleList = ARRAY [0..opmC_Max_Modules_PerList] OF opmR_Module; opmR_ExchangeData = RECORD IndexString : STRING; CurrentString : STRING; ResultString : STRING; Status : LONGINT; END; opmT_ExchangeList = ARRAY [0..opmC_Max_Exchanges_PerList] OF opmR_ExchangeData; opmT_MenuMethod = CLASS PROCEDURE opm_PRRunModuleMenu (Sender: TObject); END; VAR opm_TotalModules : LONGINT; opm_CurrentModuleRecord : opmR_Module; opmG_ModuleList : opmT_ModuleList; opm_ModuleDirectory : STRING; opmG_ModIndexData_BoxList : TStringList; opmG_ModResultData_BoxList : TStringList; opm_MenuClick : opmT_MenuMethod; opm_TCPClientModule : TIdTCPClient; opmG_ExchangeList : opmT_ExchangeList; opmG_TotalExchangeItems : LONGINT; FUNCTION opm_FNLoad_ModuleData (ModIniFile : STRING) : opmR_Module; PROCEDURE opm_PRLoad_ModuleList; FUNCTION opm_FNSave_ModuleData (CurModule : opmR_Module) : BOOLEAN; PROCEDURE opm_PRDelete_ModuleData (ModIniFile : STRING); FUNCTION opm_FNGetListIndexByString (ListString : STRING; VAR FieldList : TStringList) : LONGINT; PROCEDURE opm_PRAddModules_ToMenu (ParentMenu : TMenuItem); PROCEDURE opm_PRSetValidModules (ParentMenu : TMenuItem; SelCount : LONGINT); PROCEDURE opm_PRExecModule (ModCommandFile, ModCommandParam : STRING); FUNCTION opm_FNConnectMod (ModHost : STRING; ModPort : LONGINT) : BOOLEAN; FUNCTION opm_FNQueryMod (Query : STRING; VAR Answer : STRING) : LONGINT; FUNCTION opm_PRAskStatsMod : STRING; PROCEDURE opm_PRDisconnectMod; IMPLEMENTATION USES gnugettext, regconfig, Windows, sysutils, forms, dataman, runmod, main, oscpmdata, Controls; {%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%} {%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%} FUNCTION opm_FNLoad_ModuleData (ModIniFile : STRING) : opmR_Module; VAR CurModule : opmR_Module; BEGIN IF (ModIniFile <> '') THEN BEGIN CurModule.Name := COPY (ModIniFile, 1, LENGTH (ModIniFile) - LENGTH (ExtractFileExt (ModIniFile))); CurModule.CommandFile := FNINI_ReadSetting ('OSCModCommandFile', '', opm_ModuleDirectory + ModIniFile, opmC_RKModule); CurModule.CommandPara := FNINI_ReadSetting ('OSCModCommandPara', '', opm_ModuleDirectory + ModIniFile, opmC_RKModule); CurModule.Port := FNopm_StrToInt (FNINI_ReadSetting ('OSCModPort', INTTOSTR (opmC_Def_ModPort), opm_ModuleDirectory + ModIniFile, opmC_RKModule)); CurModule.Remote := FNopm_StrToInt (FNINI_ReadSetting ('OSCModRemote', '0', opm_ModuleDirectory + ModIniFile, opmC_RKModule)); CurModule.IndexData := FNINI_ReadSetting ('OSCModIndex', '', opm_ModuleDirectory + ModIniFile, opmC_RKModule); CurModule.ResultData := FNINI_ReadSetting ('OSCModResult', '', opm_ModuleDirectory + ModIniFile, opmC_RKModule); CurModule.JustRun := FNopm_StrToInt (FNINI_ReadSetting ('OSCModJustRun', '0', opm_ModuleDirectory + ModIniFile, opmC_RKModule)); CurModule.OnSelection := FNopm_StrToInt (FNINI_ReadSetting ('OSCModOnSelection', '0', opm_ModuleDirectory + ModIniFile, opmC_RKModule)); IF ((CurModule.CommandFile = '') OR (CurModule.Port < opmC_Min_ModPort) OR (CurModule.Port > opmC_Max_ModPort) OR (CurModule.Name <> FNopm_CleanUploadName (CurModule.Name))) THEN CurModule.Name := ''; END ELSE BEGIN CurModule.Name := ''; CurModule.CommandFile := ''; CurModule.CommandPara := ''; CurModule.Port := 0; CurModule.Remote := 0; CurModule.IndexData := ''; CurModule.ResultData := ''; CurModule.JustRun := 0; CurModule.OnSelection := 0; END; opm_FNLoad_ModuleData := CurModule; END; {%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%} {%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%} FUNCTION opm_FNSave_ModuleData (CurModule : opmR_Module) : BOOLEAN; VAR NewModFile : STRING; BEGIN IF ((CurModule.CommandFile <> '') AND (CurModule.Port > opmC_Min_ModPort) AND (CurModule.Port < opmC_Max_ModPort) AND (CurModule.Name = FNopm_CleanUploadName (CurModule.Name))) THEN BEGIN NewModFile := opm_ModuleDirectory + CurModule.Name + '.' + opmC_Def_ModulesExt; PRINI_WriteSetting ('OSCModCommandFile', CurModule.CommandFile, NewModFile, opmC_RKModule); PRINI_WriteSetting ('OSCModCommandPara', CurModule.CommandPara, NewModFile, opmC_RKModule); PRINI_WriteSetting ('OSCModPort', INTTOSTR (CurModule.Port), NewModFile, opmC_RKModule); PRINI_WriteSetting ('OSCModRemote', INTTOSTR (CurModule.Remote), NewModFile, opmC_RKModule); PRINI_WriteSetting ('OSCModIndex', CurModule.IndexData, NewModFile, opmC_RKModule); PRINI_WriteSetting ('OSCModResult', CurModule.ResultData, NewModFile, opmC_RKModule); PRINI_WriteSetting ('OSCModJustRun', INTTOSTR (CurModule.JustRun), NewModFile, opmC_RKModule); PRINI_WriteSetting ('OSCModOnSelection', INTTOSTR (CurModule.OnSelection), NewModFile, opmC_RKModule); opm_FNSave_ModuleData := TRUE; END ELSE opm_FNSave_ModuleData := FALSE; END; {%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%} {%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%} PROCEDURE opm_PRLoad_ModuleList; VAR DirRecord : TSearchRec; ModCount, ModCount2, ModIndex : LONGINT; opm_SwapModRecord : opmR_Module; BEGIN opm_TotalModules := 0; IF (SysUtils.FINDFIRST (opm_ModuleDirectory + '*.' + opmC_Def_ModulesExt, faAnyFile, DirRecord) = 0) THEN BEGIN REPEAT opm_CurrentModuleRecord := opm_FNLoad_ModuleData (DirRecord.Name); IF (opm_CurrentModuleRecord.Name <> '') THEN BEGIN opmG_ModuleList[opm_TotalModules] := opm_CurrentModuleRecord; INC (opm_TotalModules); END; UNTIL (SysUtils.FINDNEXT (DirRecord) <> 0); SysUtils.FINDCLOSE (DirRecord); END; { Sort the list... } FOR ModCount := 0 TO (opm_TotalModules - 1) DO BEGIN ModIndex := ModCount; FOR ModCount2 := (ModCount + 1) TO (opm_TotalModules - 1) DO IF (ANSIUPPERCASE (opmG_ModuleList[ModIndex].Name) > ANSIUPPERCASE (opmG_ModuleList[ModCount2].Name)) THEN ModIndex := ModCount2; opm_SwapModRecord := opmG_ModuleList[ModIndex]; opmG_ModuleList[ModIndex] := opmG_ModuleList[ModCount]; opmG_ModuleList[ModCount] := opm_SwapModRecord; END; END; {%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%} {%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%} PROCEDURE opm_PRDelete_ModuleData (ModIniFile : STRING); BEGIN SysUtils.DELETEFILE (opm_ModuleDirectory + ModIniFile); END; {%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%} {%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%} FUNCTION opm_FNGetListIndexByString (ListString : STRING; VAR FieldList : TStringList) : LONGINT; VAR ListCounter : LONGINT; BEGIN opm_FNGetListIndexByString := 0; FOR ListCounter := 0 TO (FieldList.Count - 1) DO IF (FieldList.Strings [ListCounter] = ListString) THEN BEGIN opm_FNGetListIndexByString := ListCounter; BREAK; END; END; {%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%} {%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%} PROCEDURE opm_PRAddModules_ToMenu (ParentMenu : TMenuItem); VAR NewMenu : TMenuItem; ModCounter : LONGINT; BEGIN IF (ParentMenu.Count > 0) THEN REPEAT NewMenu := ParentMenu.Items [0]; ParentMenu.Remove (NewMenu); UNTIL (ParentMenu.Count = 0); IF (opm_TotalModules > 0) THEN FOR ModCounter := 0 TO (opm_TotalModules - 1) DO BEGIN NewMenu := TMenuItem.Create (ParentMenu); NewMenu.Caption := STRINGREPLACE (opmG_ModuleList[ModCounter].Name, '_', ' ', [rfReplaceAll, rfIgnoreCase]); NewMenu.Tag := ModCounter; NewMenu.OnClick := opm_MenuClick.opm_PRRunModuleMenu; ParentMenu.Add (NewMenu); END; END; {%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%} {%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%} PROCEDURE opm_PRSetValidModules (ParentMenu : TMenuItem; SelCount : LONGINT); VAR ModCounter : LONGINT; BEGIN IF ((opm_TotalModules > 0) AND (ParentMenu.Count = opm_TotalModules)) THEN FOR ModCounter := 0 TO (opm_TotalModules - 1) DO BEGIN IF (opmG_ModuleList[ModCounter].OnSelection > 0) THEN IF (SelCount > 0) THEN ParentMenu.Items[ModCounter].Enabled := TRUE ELSE ParentMenu.Items[ModCounter].Enabled := FALSE ELSE ParentMenu.Items[ModCounter].Enabled := TRUE; END; END; {%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%} {%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%} PROCEDURE opmT_MenuMethod.opm_PRRunModuleMenu (Sender: TObject); BEGIN opm_CurrentModuleRecord := opmG_ModuleList[(Sender AS TMenuItem).Tag]; IF (opm_CurrentModuleRecord.Remote > 0) THEN BEGIN IF (opm_Form_Runmod.ShowModal = mrAll) THEN opm_Form_Main.PRopm_Reload_ProductList (opm_WeAreSearching); END ELSE IF (opm_CurrentModuleRecord.JustRun > 0) THEN BEGIN opm_PRExecModule (opm_CurrentModuleRecord.CommandFile, opm_CurrentModuleRecord.CommandPara); END ELSE BEGIN opm_PRExecModule (opm_CurrentModuleRecord.CommandFile, opm_CurrentModuleRecord.CommandPara); IF (opm_Form_Runmod.ShowModal = mrAll) THEN opm_Form_Main.PRopm_Reload_ProductList (opm_WeAreSearching); END; END; {%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%} {%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%} PROCEDURE opm_PRExecModule (ModCommandFile, ModCommandParam : STRING); VAR ExeDir : STRING; StartupTime : DOUBLE; BEGIN ExeDir := opm_ModuleDirectory; IF (FNopm_RunExternalApp (opm_ModuleDirectory + ModCommandFile, ModCommandParam, ExeDir, FALSE, TRUE, 0) > 0) THEN BEGIN StartupTime := GetTickCount; REPEAT Application.ProcessMessages; UNTIL ((GetTickCount - StartupTime) > opmC_ModStartupWait); END; END; {%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%} {%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%} FUNCTION opm_FNConnectMod (ModHost : STRING; ModPort : LONGINT) : BOOLEAN; BEGIN opm_TCPClientModule.Port := ModPort; opm_TCPClientModule.Host := ModHost; TRY opm_TCPClientModule.Connect (opmC_TCPTimeout); opm_FNConnectMod := TRUE; EXCEPT opm_FNConnectMod := FALSE; END; END; {%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%} {%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%} FUNCTION opm_FNQueryMod (Query : STRING; VAR Answer : STRING) : LONGINT; BEGIN opm_FNQueryMod := opmC_ModRet_Null; Answer := ''; TRY IF (Query <> '') THEN opm_TCPClientModule.WriteLn (Query); Answer := opm_TCPClientModule.ReadLn (#13#10, opmC_TCPTimeout, -1); EXCEPT Answer := ''; opm_FNQueryMod := opmC_ModRet_Null; END; IF (Answer <> '') THEN BEGIN IF (COPY (Answer, 1, LENGTH (opmC_ModOKCode)) = opmC_ModOKCode) THEN BEGIN Answer := COPY (Answer, (LENGTH (opmC_ModOKCode) + 2), LENGTH (Answer)); opm_FNQueryMod := opmC_ModRet_Data; END ELSE BEGIN IF (COPY (Answer, 1, LENGTH (opmC_ModStatCode)) = opmC_ModStatCode) THEN BEGIN Answer := COPY (Answer, (LENGTH (opmC_ModStatCode) + 2), LENGTH (Answer)); opm_FNQueryMod := opmC_ModRet_Stat; END ELSE BEGIN Answer := ''; opm_FNQueryMod := opmC_ModRet_Null; END; END; END; Application.ProcessMessages; END; {%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%} {%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%} FUNCTION opm_PRAskStatsMod : STRING; VAR Answer, FullAnswer : STRING; BEGIN Answer := ''; FullAnswer := ''; TRY opm_TCPClientModule.WriteLn (opmC_ModStatCommand); REPEAT Answer := opm_TCPClientModule.ReadLn (#13#10, opmC_TCPTimeout, -1); FullAnswer := FullAnswer + COPY (Answer, (LENGTH (opmC_ModStatCode) + 1), LENGTH (Answer)) + #13#10; UNTIL ((Answer = '') OR (Answer = opmC_ModStatCodeEnd)); EXCEPT END; opm_PRAskStatsMod := FullAnswer; END; {%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%} {%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%} PROCEDURE opm_PRDisconnectMod; BEGIN TRY opm_TCPClientModule.WriteLn (opmC_ModQuitCommand); opm_TCPClientModule.Disconnect; EXCEPT END; END; INITIALIZATION opm_TotalModules := 0; opm_ModuleDirectory := ExtractFilePath (Application.Exename) + opmC_DirModules + '\'; opmG_ModIndexData_BoxList := TStringList.Create; opmG_ModResultData_BoxList := TStringList.Create; opmG_ModIndexData_BoxList.Add (''); opmG_ModIndexData_BoxList.Add (opmC_SyncField_ProductID); opmG_ModIndexData_BoxList.Add (opmC_SyncField_ProductModel); opmG_ModResultData_BoxList.Add (''); opmG_ModResultData_BoxList.Add (opmC_SyncField_ProductQuantity); opmG_ModResultData_BoxList.Add (opmC_SyncField_ProductPrice); opmG_ModResultData_BoxList.Add (opmC_SyncField_ProductImage); opmG_ModResultData_BoxList.Add (opmC_SyncField_ProductWeight); opmG_ModResultData_BoxList.Add (opmC_SyncField_ProductStatus); opm_TCPClientModule := TIdTCPClient.Create (opm_TCPClientModule); FINALIZATION opm_TCPClientModule.Free; FreeAndNIL (opmG_ModIndexData_BoxList); FreeAndNIL (opmG_ModResultData_BoxList); end.