-
Notifications
You must be signed in to change notification settings - Fork 60
/
Copy pathPythonLoad.pas
157 lines (132 loc) · 5.74 KB
/
PythonLoad.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
(**************************************************************************)
(* *)
(* Module: Unit 'PythonLoad' Copyright (c) 2021 *)
(* *)
(* Lucas Moura Belo - lmbelo *)
(* lucas.belo@live.com *)
(* Brazil *)
(* *)
(**************************************************************************)
(* Functionality: Load python distribution *)
(* *)
(* *)
(**************************************************************************)
(* This source code is distributed with no WARRANTY, for no reason or use.*)
(* Everyone is allowed to use and change this code free for his own tasks *)
(* and projects, as long as this header and its copyright text is intact. *)
(* For changed versions of this code, which are public distributed the *)
(* following additional conditions have to be fullfilled: *)
(* 1) The header has to contain a comment on the change and the author of *)
(* it. *)
(* 2) A copy of the changed source has to be sent to the above E-Mail *)
(* address or my then valid address, if this is possible to the *)
(* author. *)
(* The second condition has the target to maintain an up to date central *)
(* version of the component. If this condition is not acceptable for *)
(* confidential or legal reasons, everyone is free to derive a component *)
(* or to generate a diff file to my or other original sources. *)
(**************************************************************************)
unit PythonLoad;
interface
uses
System.SysUtils, System.Zip, PythonEngine;
type
TExtractEvent = reference to procedure(const AFolderExists: boolean; var AReplaceFiles: boolean);
TPythonLoad = class
public
class function FindPythonVer(): integer; static;
class function GetPyZip(): string; static;
class function GetPyRoot(): string; static;
class function GetPyHome(): string; static;
class function GetPyBin(): string; static;
class function GetPyLib(): string; static;
class function GetPyTmp(): string; static;
class function GetPyInterpreter(): string; static;
class procedure Extract(const AExtractEvent: TExtractEvent;
const AZipProgress: TZipProgressEvent); static;
class procedure Configure(const APythonEngine: TPythonEngine;
const ACheckPyLib: boolean = true); static;
end;
implementation
uses
System.IOUtils,
Androidapi.Helpers,
Androidapi.JNI.JavaTypes;
{ TPythonLoad }
class procedure TPythonLoad.Extract(const AExtractEvent: TExtractEvent;
const AZipProgress: TZipProgressEvent);
begin
var LPyRoot := TPythonLoad.GetPyRoot();
var LFolderExists := TDirectory.Exists(LPyRoot);
var LReplaceFiles := false;
if Assigned(AExtractEvent) then
AExtractEvent(LFolderExists, LReplaceFiles);
if LFolderExists then
if not LReplaceFiles then
Exit()
else
TDirectory.Delete(LPyRoot, true);
var LPyZip := TPythonLoad.GetPyZip();
if not TFile.Exists(LPyZip) then
raise Exception.Create('Python compressed distribution not found.');
TZipFile.ExtractZipFile(LPyZip, LPyRoot, AZipProgress);
end;
class function TPythonLoad.FindPythonVer: integer;
begin
if TFile.Exists(TPath.Combine(TPath.GetLibraryPath(), 'libpython3.8.so')) then
Result := 6
else if TFile.Exists(TPath.Combine(TPath.GetLibraryPath(), 'libpython3.9.so')) then
Result := 7
else if TFile.Exists(TPath.Combine(TPath.GetLibraryPath(), 'libpython3.10.so')) then
Result := 8
else
raise Exception.Create('Python shared library not found');
end;
class function TPythonLoad.GetPyBin: string;
begin
Result := TPath.Combine(GetPyHome(), 'bin');
end;
class function TPythonLoad.GetPyHome: string;
begin
Result := TPath.Combine(GetPyRoot(), 'usr');
end;
class function TPythonLoad.GetPyInterpreter: string;
begin
Result := TPath.Combine(TPath.GetLibraryPath(), 'python3.9')
end;
class function TPythonLoad.GetPyLib: string;
begin
Result := TPath.Combine(GetPyHome(), 'lib');
end;
class function TPythonLoad.GetPyRoot: string;
begin
Result := TPath.Combine(TPath.GetDocumentsPath(), 'build');
end;
class function TPythonLoad.GetPyTmp: string;
begin
Result := TPath.GetTempPath();
end;
class function TPythonLoad.GetPyZip: string;
begin
Result := TPath.Combine(TPath.GetDocumentsPath(), 'build.zip');
end;
class procedure TPythonLoad.Configure(const APythonEngine: TPythonEngine;
const ACheckPyLib: boolean);
begin
var LPythonVer := FindPythonVer();
if ACheckPyLib then begin
var LPyLibFile := TPath.Combine(TPath.GetLibraryPath(),
PYTHON_KNOWN_VERSIONS[LPythonVer].DllName);
if not TFile.Exists(LPyLibFile) then
raise Exception.Create('Python library not found at application''s data folder.'
+ #13#10
+ LPyLibFile);
end;
APythonEngine.UseLastKnownVersion := false;
APythonEngine.ProgramName := TPythonLoad.GetPyBin();
APythonEngine.PythonHome := TPythonLoad.GetPyHome();
APythonEngine.RegVersion := PYTHON_KNOWN_VERSIONS[LPythonVer].RegVersion;
APythonEngine.DllName := PYTHON_KNOWN_VERSIONS[LPythonVer].DllName;
APythonEngine.APIVersion := PYTHON_KNOWN_VERSIONS[LPythonVer].APIVersion;
end;
end.