Repo for the search and displace ingest module that takes odf, docx and pdf and transforms it into .md to be used with search and displace operations
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

174 lines
3.7 KiB

3 years ago
  1. unit Runner;
  2. interface
  3. uses
  4. Classes, SysUtils, UTF8Process, StdCtrls, ExtCtrls, Options;
  5. type
  6. TFinishReason = (
  7. frFinished,
  8. frStopped,
  9. frFailure
  10. );
  11. TFinishedEvent = procedure(Sender: TObject; Reason: TFinishReason) of object;
  12. TProgressEvent = procedure(Sender: TObject; Index: Integer) of object;
  13. { TRunner }
  14. TRunner = class
  15. private
  16. FProcess: TProcessUTF8;
  17. FTimer: TTimer;
  18. FOutputMemo: TCustomMemo;
  19. FOnFinished: TFinishedEvent;
  20. FOnProgress: TProgressEvent;
  21. FInputPos: Integer;
  22. FFailures: Integer;
  23. FOptions: TOptions;
  24. FRunning: Boolean;
  25. FStopped: Boolean;
  26. procedure ReadProcessOutput;
  27. procedure TimerTicked(Sender: TObject);
  28. procedure RunNextItem(IsFirstRun: Boolean = False);
  29. procedure Finish(Reason: TFinishReason);
  30. public
  31. constructor Create(AOutputMemo: TCustomMemo);
  32. destructor Destroy; override;
  33. procedure Run(AOptions: TOptions);
  34. procedure Stop;
  35. property IsRunning: Boolean read FRunning;
  36. property Failures: Integer read FFailures;
  37. property InputPos: Integer read FInputPos;
  38. property OnFinished: TFinishedEvent read FOnFinished write FOnFinished;
  39. property OnProgress: TProgressEvent read FOnProgress write FOnProgress;
  40. end;
  41. implementation
  42. uses
  43. Process, Dialogs;
  44. { TRunner }
  45. constructor TRunner.Create(AOutputMemo: TCustomMemo);
  46. begin
  47. // Unfortunatelly, we cannot use TAsyncProcess since it does not work reliably on all platforms
  48. FProcess := TProcessUTF8.Create(nil);
  49. FProcess.Options := [poUsePipes, {$IFDEF MSWINDOWS}poNoConsole,{$ENDIF} poStderrToOutPut];
  50. FTimer := TTimer.Create(nil);
  51. FTimer.Enabled := False;
  52. FTimer.Interval := 50;
  53. FTimer.OnTimer := TimerTicked;
  54. FOutputMemo := AOutputMemo;
  55. end;
  56. destructor TRunner.Destroy;
  57. begin
  58. FProcess.Free;
  59. FTimer.Free;
  60. inherited Destroy;
  61. end;
  62. procedure TRunner.ReadProcessOutput;
  63. var
  64. BufStr: string;
  65. begin
  66. while FProcess.Output.NumBytesAvailable > 0 do
  67. begin
  68. SetLength(BufStr, FProcess.Output.NumBytesAvailable);
  69. FProcess.Output.Read(BufStr[1], Length(BufStr));
  70. FOutputMemo.Append(BufStr);
  71. end;
  72. end;
  73. procedure TRunner.TimerTicked(Sender: TObject);
  74. begin
  75. ReadProcessOutput;
  76. if not FProcess.Running then
  77. RunNextItem;
  78. end;
  79. procedure TRunner.RunNextItem(IsFirstRun: Boolean);
  80. begin
  81. if not IsFirstRun and (FProcess.ExitCode <> 0) then
  82. Inc(FFailures);
  83. Inc(FInputPos);
  84. if FInputPos >= FOptions.Files.Count then
  85. begin
  86. if FFailures = 0 then
  87. Finish(frFinished)
  88. else
  89. Finish(frFailure);
  90. Exit;
  91. end;
  92. if FStopped then
  93. begin
  94. Finish(frStopped);
  95. Exit;
  96. end;
  97. if Assigned(FOnProgress) then
  98. FOnProgress(Self, FInputPos);
  99. FOptions.ToCmdLineParameters(FProcess.Parameters, FInputPos);
  100. try
  101. FProcess.Execute;
  102. except
  103. on Ex: Exception do
  104. begin
  105. FOutputMemo.Append(Ex.ClassName + ': ' + Ex.Message);
  106. Dialogs.MessageDlg('Failed to execute Deskew',
  107. 'Deskew command line executable failed to start. Check that it is in the correct location ' +
  108. 'and has the right permissions.' + sLineBreak + sLineBreak +
  109. 'Executable path used: ' + FProcess.Executable,
  110. mtError, [mbOK], '');
  111. Finish(frFailure);
  112. Exit;
  113. end;
  114. end;
  115. if IsFirstRun then
  116. FTimer.Enabled := True;
  117. end;
  118. procedure TRunner.Finish(Reason: TFinishReason);
  119. begin
  120. FTimer.Enabled := False;
  121. FRunning := False;
  122. if Assigned(FOnFinished) then
  123. FOnFinished(Self, Reason);
  124. end;
  125. procedure TRunner.Run(AOptions: TOptions);
  126. begin
  127. FInputPos := -1;
  128. FFailures := 0;
  129. FOptions := AOptions;
  130. FStopped := False;
  131. FRunning := True;
  132. FProcess.Executable := FOptions.EffectiveExecutablePath;
  133. RunNextItem(True);
  134. end;
  135. procedure TRunner.Stop;
  136. begin
  137. FStopped := True;
  138. end;
  139. end.