Files
HDCApi/_custom/Gornicky/winSvc/impl.inc
2025-05-21 21:14:32 +02:00

463 lines
17 KiB
PHP

constructor THeoGorDownPDFThread.Create (AOnTerminate: TNotifyEvent; AService: TService);
begin
inherited Create (false); // Create thread in NOT suspended mode
FMainService:= AService;
FLock:= TCriticalSection.Create;
FRunning:= false;
FTermEvent:= TEvent.Create (nil, False, False, '');
// OnTerminate:= AOnTerminate;
// FreeOnTerminate:= true;
FreeOnTerminate:= false; // Ensure manual freeing of thread resources
end;
destructor THeoGorDownPDFThread.Destroy;
begin
{$IFDEF DEBUG}
Write('Ukoncuji thread GOR Download PDF...');
{$ENDIF}
if (FTimer<>0) then
CloseHandle (FTimer);
FTermEvent.Free;
FRunning:= false;
FMainService:= nil;
Terminate;
FLock.Free;
inherited;
{$IFDEF DEBUG}
WriteLn('OK');
{$ENDIF}
end;
procedure THeoGorDownPDFThread.TerminatedSet;
begin
FTermEvent.SetEvent;
end;
procedure THeoGorDownPDFThread.ThreadTerminate;
begin
Terminate;
WaitFor;
end;
procedure THeoGorDownPDFThread.Execute;
const _Second = 10_000_000;
var lSQL, errMsg, url, outData, fName, loopCasTyp: string;
lLoop, idDigiFile, cnt, idx: Integer;
lLoopMax, koefProCas: integer;
logRunCnt: integer;
Msg: TMsg;
firstRun, inProg, inDL: boolean;
lQry: TFDQuery;
sqlConnX, sqlConnX2: TFDConnection;
sqlTrans: IFDPhysTransaction;
f, lOpenSSLLib: string;
lBusy: LongInt;
liDueTime: LARGE_INTEGER;
mamSSLLibs: boolean;
sslLibPath: string;
http1: System.Net.HTTPClient.THTTPClient;
iResp: System.Net.HTTPClient.IHTTPResponse;
aResp: TMemoryStream;
http2: TIdHttp;
sslHndlr: TIdSSLIOHandlerSocketOpenSSL;
respHttp2: TStream;
i: integer;
sTemp, outData2: string;
cfgFile: string;
specCfgXML: XML.XmlIntf.IXMLDocument;
n1: XML.XmlIntf.IXMLNode;
attribs: IXMLNodeList;
attrIdx: integer;
function StringToHex (const inStr: string): string;
var i: integer;
begin
result:= '';
for i:=1 to Length(inStr) do
result:= result + IntToHex(Ord(inStr[i]), 2); // 2 means two hex digits per character
end;
function MemStreamToHex (aStream: TMemoryStream): string;
var i: integer;
b: byte;
begin
result:= '';
for i:=0 to aStream.Size-1 do
begin
b:= PByte(TMemoryStream(aStream).Memory)[i];
result:= result + IntToHex(b,2);
end;
end;
begin
lLoop:= 0;
idDigiFile:= 0;
logRunCnt:= 1;
{
koefProCas:= 0; // default vteriny
loopCasTyp:= '???';
case DZTaksZapisTypCas of
0: koefProCas:= 1;
1: koefProCas:= 60;
2: koefProCas:= 3600;
end;
lLoopMax:= koefProCas * intProcessDZTasksSec;
case DZTaksZapisTypCas of
0: loopCasTyp:= 'sek';
1: loopCasTyp:= 'min';
2: loopCasTyp:= 'hod';
end;
}
lLoopMax:= 10; // v minutach !!!!
try
try
CoInitialize(nil);
cfgFile:= ExtractFilePath(ParamStr(0)) + 'gornicky.xml';
if (FileExists(cfgFile)) then
begin
specCfgXML:= Xml.XMLDoc.TXMLDocument.Create(nil);
specCfgXML.LoadFromFile (cfgFile);
specCfgXML.Active:= true;
if not(specCfgXML.IsEmptyDoc) then
begin
if (specCfgXML.DocumentElement<>nil) then
begin
n1:= specCfgXML.DocumentElement;
if (n1.NodeName='config') then
begin
attribs:= n1.AttributeNodes;
attrIdx:= attribs.IndexOf('downPDFintMins');
if (attrIdx>-1) then
if (attribs.Get(attrIdx).NodeValue<>null) then
lLoopMax:= attribs.Get(i).NodeValue;
end; // n1 = config
end; // specCfgXML.DocumentElement<>nil
end; // not specCfgXML.IsEmptyDoc
end; // FileExists(cfgFile)
except
end;
finally
begin
if (specCfgXML<>nil) then
specCfgXML:= nil;
CoUninitialize;
end;
end;
datMod.LogInfo (Quick.Logger.etInfo, 'Download PDF interval: ' + lLoopMax.ToString + ' min.');
lLoopMax:= lLoopMax * 60; // minuty na vteriny
firstRun:= true;
inProg:= false;
sslLibPath:= '';
f:= ExtractFilePath (ParamStr(0));
mamSSLLibs:= false;
for lOpenSSLLib in OPENSSL_LIBS do
begin
if (FileExists(TPath.Combine(f, lOpenSSLLib))) then
begin
mamSSLLibs:= true;
sslLibPath:= ExcludeTrailingPathDelimiter (f);
end;
end;
FRunning:= false;
if not(datMod.SQLTableExists(tblAPIDigiSoubory)) then
Exit;
FRunning:= true;
if (1=1) then // pro rychle vypnuti
begin
FTimer:= CreateWaitableTimer (nil, true, 'GorDownloadPDFWaitableTimer');
liDueTime.QuadPart:= -1*_Second;
try
while not(Terminated) or not(FRunning) do
begin
if (HDCDZApiService<>nil) then
if (HDCDZApiService.Terminated) then
begin
Terminate;
FRunning:= false;
end;
PeekMessage (&Msg, 0, 0, 0, PM_NOREMOVE); { Create message queue }
if (lLoop=lLoopMax) or (firstRun) then // pri startu a pak kazdou minutu
begin
idDigiFile:= 0;
firstRun:= false;
if (logRunCnt<4) then
datMod.LogInfo (Quick.Logger.etInfo, 'Spoustim download ' + logRunCnt.toString + '...');
if (logRunCnt=4) then
datMod.LogInfo (Quick.Logger.etInfo, 'Spoustim download - bezi ale dal neloguju');
try
if not(inProg) then // nebezi uz ?
begin
if (1=1) then // pro rychle vypnuti
begin
sqlConnX:= TFDConnection.Create (nil);
sqlConnX.Params.SetStrings (datMod.sqlConnParams);
// sqlConnX.TxOptions.AutoCommit:= false;
sqlConnX.Open;
if (sqlConnX.Connected) then
begin
// sqlConnX.ExecSQL('DECLARE @i INT; SET @i=ISNULL( (SELECT MAX(ID) FROM dbo.TabDokumenty), 1); DBCC CHECKIDENT (TabDokumenty, RESEED, @i)');
lSQL:= '/* hdcDZApiSvc */ SELECT ID FROM ' + tblAPIDigiSoubory + ' WHERE Blokovano=0 AND Zpracovano=0 AND Zpracovat=1'
+ ' AND IDDokument IS NULL ORDER BY ID';
lQry:= TFDQuery.Create(nil);
try
lQry.Connection:= sqlConnX;
lQry.Open(lSQL);
if (lQry.RecordCount>0) then
begin
lQry.First;
if (sqlConnX.TxOptions.AutoCommit=false) then
sqlConnX.StartTransaction;
inProg:= true;
while not(lQry.EOF) do
begin
idDigiFile:= lQry.FieldByName('ID').asInteger;
if (idDigiFile>0) then
begin
try
// musim to zablokovat uz tady aby se to nezpracovavalo znovu
sqlConnX.ExecSQL('UPDATE ' + tblAPIDigiSoubory + ' SET Blokovano=1 WHERE ID=' + idDigiFile.ToString);
// datMod.LogInfo (Quick.Logger.etInfo, 'Zablokovani downloadPDF id ' + idDigiFile.ToString + ' pred zpracovanim');
url:= datMod.SQLGetString ('SELECT DocURL FROM ' + tblAPIDigiSoubory + ' WHERE ID=' + idDigiFile.ToString);
if (url<>'') then
begin
datMod.LogInfo (Quick.Logger.etInfo, 'Mam URL downloadPDF id ' + idDigiFile.ToString);
outData:= '';
if (sslLibPath='') then
begin
try
http1:= System.Net.HTTPClient.THTTPClient.Create;
datMod.LogInfo (Quick.Logger.etInfo, 'HTTP klient NET vytvoren downloadPDF id ' + idDigiFile.ToString);
aResp:= TMemoryStream.Create;
// datMod.LogInfo (Quick.Logger.etInfo, 'Vytvoren memStream downloadPDF id ' + idDigiFile.ToString);
try
if (Assigned(http1)) then
begin
http1.AllowCookies:= false;
http1.UserAgent:= 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:134.0) Gecko/20100101 Firefox/134.0';
http1.Accept:= 'application/pdf';
datMod.LogInfo (Quick.Logger.etInfo, 'Nacitam data PDF pro downloadPDF id ' + idDigiFile.ToString);
iResp:= http1.Get (url);
aResp:= (iResp.ContentStream as TMemoryStream);
outData:= MemStreamToHex (aResp);
datMod.LogInfo (Quick.Logger.etInfo, 'Mam data PDF pro downloadPDF id ' + idDigiFile.ToString);
end;
except on E:Exception do
begin
datMod.LogInfo (Quick.Logger.etError, 'Chyba zpracovani downloadPDF id ' + idDigiFile.ToString + ' : ' + E.Message);
{$IFDEF DEBUG}
WriteLn ('Chyba zpracovani downloadPDF id ' + idDigiFile.ToString + ' >> ' + E.Message);
{$ENDIF}
end;
end;
finally
http1.Free;
http1:= nil;
aResp.Free;
aResp:= nil;
// datMod.LogInfo (Quick.Logger.etInfo, 'Uvolnen Net HTTP klient a memStream pro downloadPDF id ' + idDigiFile.ToString);
end;
end
else
begin
IdOpenSSLSetLibPath (sslLibPath);
http2:= TIdHttp.Create (nil);
sslHndlr:= TIdSSLIOHandlerSocketOpenSSL.Create (http2);
try
sslHndlr.SSLOptions.Method:= sslvTLSv1_2;
sslHndlr.SSLOptions.SSLVersions := [sslvTLSv1_2, sslvTLSv1_1];
http2.IOHandler:= sslHndlr;
http2.Request.Accept:= 'application/pdf';
http2.Request.BasicAuthentication := False;
http2.HTTPOptions:= http2.HTTPOptions + [hoKeepOrigProtocol] + [hoNoProtocolErrorException];
http2.Request.ContentType:= 'application/pdf; charset=utf-8';
respHttp2:= TMemoryStream.Create;
http2.Get (url, respHttp2);
outData:= MemStreamToHex (respHttp2 as TMemoryStream);
finally
FreeAndNil (sslHndlr); // must be freed before IdHttp
FreeAndNil (http2);
FreeAndNil (respHttp2);
// datMod.LogInfo (Quick.Logger.etInfo, 'Uvolnen Indy HTTP klient a memStream pro downloadPDF id ' + idDigiFile.ToString);
end;
end;
if (outData<>'') then
begin
// datMod.LogInfo (Quick.Logger.etInfo, 'Mam data 2 PDF pro downloadPDF id ' + idDigiFile.ToString);
fName:= '';
i:= LastDelimiter ('/\', url);
if (i>0) then
fName:= Copy (url, i+1, Length(url)-i);
if (LeftStr(outData,4)='5025') then
begin
outData2:= '';
for i:=1 to Length(outData) div 2 do
outData2:= outData2 + MidStr(outData, (4*i)-1, 2) + MidStr(outData, (4*i)-3, 2);
if (outData2<>'') then
outData:= outData2;
end;
lSQL:= 'DECLARE @i INT' + CRLF + 'SET @i=(SELECT ID FROM dbo.TabDokumenty WHERE JmenoACesta=N' + url.QuotedString
+ ')' + CRLF + 'IF (@i IS NULL)' + CRLF
+ ' BEGIN' + CRLF + ' INSERT dbo.TabDokumenty (Popis, JmenoACesta, Poznamka, Autor, Dokument) SELECT N' + fName.QuotedString
+ ', N' + fName.QuotedString + ', N' + url.QuotedString + ', N''apiImport'''
+ ', CONVERT(varbinary(max), 0x' + outData +', 1)' + CRLF + ' SET @i=SCOPE_IDENTITY()' + CRLF + ' END'
+ CRLF + 'SELECT @i';
sTemp:= datMod.SQLGetString (lSQL);
if (sTemp<>'') then
begin
// datMod.LogInfo (Quick.Logger.etInfo, 'Update zapisu downloadPDF id ' + idDigiFile.ToString);
lSQL:= 'UPDATE ' + tblAPIDigiSoubory + ' SET IDDokument=' + sTemp + ', DatZpracovani=GETDATE(), Blokovano=0 WHERE ID=' + idDigiFile.ToString;
sqlConnX.ExecSQL(lSQL);
// datMod.LogInfo (Quick.Logger.etInfo, 'Update zapisu/odblokovani downloadPDF id ' + idDigiFile.ToString + ' - OK');
end;
end;
end; // url<>''
if (url='') then
begin
lSQL:= 'UPDATE ' + tblAPIDigiSoubory + ' SET DatZpracovani=GETDATE(), Blokovano=0 WHERE ID=' + idDigiFile.ToString;
sqlConnX.ExecSQL (lSQL);
end;
except on E:Exception do
begin
errMsg:= E.Message; // datMod.sqlQry11.FieldByName('ErrMsg').AsString;
{$IFDEF DEBUG}
WriteLn ('Chyba 2 zpracovani downloadPDF id ' + idDigiFile.ToString + ' >> ' + errMsg);
{$ENDIF}
// sqlConnX.ExecSQL('UPDATE ' + tblAPIDigiSoubory + ' SET PosledniChyba=N' + errMsg.QuotedString + ' WHERE ID=' + idDigiFile.ToString);
datMod.LogInfo(Quick.Logger.etError, 'Chyba 2 zpracovani downloadPDF ID ' + idDigiFile.ToString + ' : ' + errMsg);
end;
end;
end;
lQry.Next;
end;
end;
finally
lQry.Close;
FreeAndNil (lQry);
// lQry.Free;
// lQry:= nil;
end;
// datMod.LogInfo (Quick.Logger.etInfo, 'Uzavrena SQL query - downloadPDF id ' + idDigiFile.ToString);
if (sqlConnX.InTransaction) then
sqlConnX.Commit;
inProg:= false;
end; // sql Connected
sqlConnX.Close;
FreeAndNil (sqlConnX);
// sqlConnX.Free;
// sqlConnX:= nil;
// datMod.LogInfo (Quick.Logger.etInfo, 'Zrusena SQL connection - downloadPDF id ' + idDigiFile.ToString);
end;
end;
except on E:Exception do
begin
inProg:= false;
if (lQry<>nil) then
begin
lQry.Close;
FreeAndNil (lQry);
end;
if (sqlConnX<>nil) then
begin
if (sqlConnX.InTransaction) then
sqlConnX.Rollback;
sqlConnX.Close;
FreeAndNil (sqlConnX);
// sqlConnX.Free;
// sqlConnX:= nil;
end;
errMsg:= E.Message; // datMod.sqlQry11.FieldByName('ErrMsg').AsString;
if (mamTabPrijataData) then
datMod.LogInfo (Quick.Logger.etError, 'Chyba zpracovani API souboru ID ' + idDigiFile.ToString + ' : ' + errMsg);
end;
end;
lLoop:= 0;
if (logRunCnt<5) then
Inc (logRunCnt);
end;
Inc (lLoop);
if (FTimer<>0) then
SetWaitableTimer (FTimer, TLargeInteger(liDueTime), 0, nil, nil, false);
repeat
lBusy:= MsgWaitForMultipleObjects (1, FTimer, false, INFINITE, QS_ALLINPUT);
until lBusy = WAIT_OBJECT_0;
// Sleep (998);
end;
finally
end;
end;
if (sqlConnX2<>nil) then
begin
if (sqlConnX2.Connected) then
sqlConnX2.Close;
FreeAndNil (sqlConnX2);
end;
end;