UnitMisc: Update log procedure.
[WineLauncher.git] / Functions / Misc / UnitMisc.pas
blob07ae4db6190e12196021785a2d081178c58e1961
1 { This file is part of WineLauncher.
3 WineLauncher is free software: you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation, version 3 of the License.
7 WineLauncher is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
12 You should have received a copy of the GNU General Public License
13 along with WineLauncher. If not, see <http://www.gnu.org/licenses/>.
16 unit UnitMisc;
18 {$mode objfpc}{$H+}
20 interface
22 uses
23 Classes, SysUtils, XMLCfg, strutils, BaseUnix, Process;
25 procedure Log(Level:integer; Channel:string; LogText:string);
26 {$IFDEF LogVar}
27 procedure LogVar(MyVar:string; MyVarName:string);
28 {$ENDIF}
29 procedure SaveLastUsedConfig();
30 procedure LoadLastUsedConfig();
32 function Wrap(Input:string):string; { Makes Paths look better, E.G. " ( Input ) " }
33 function WinToUnixPath(Path:string):string;
34 function GetUnixDirPath(FilePath:string):string;
35 function FileExistsAndIsExecutable(FullPath:string; JustCheckExists:boolean): boolean ;
36 function WorkDirTemplate(FolderPath:string):string;
37 function DoesFolderExists(Path:string; FolderName:string): boolean;
38 function DoesFoldersExists(Path:string; FolderNames:Tstrings): boolean;
39 function DirExistsIfNotMakeIt(Path:string; FolderName:string ): boolean;
40 function CheckPaths():boolean;
41 function SetupGit():boolean;
42 function MakeFile(FullPath:string;Data:string):boolean;
43 function SetExecutableFlag(FullPath:string):boolean;
45 var
46 XmlLastUsedConfig:TXMLConfig;
47 Loading:boolean;
49 implementation
50 uses UnitMain;
53 function FileExistsAndIsExecutable(FullPath:string; JustCheckExists:boolean): boolean ;
54 var
55 ChannelLocal:string;
56 begin
57 ChannelLocal := ('FileExistsAndIsExecutable');
59 if JustCheckExists = true then
60 begin
61 if FileExists(FullPath) then
62 begin
63 {$IFDEF MoreTrue }
64 if JustCheckExists = true then Log(3, ChannelLocal, 'File' + Wrap(FullPath) + 'exists.');
65 {$ENDIF}
66 Result := true;
67 end
68 else
69 begin
70 Log(4, ChannelLocal,'File' + Wrap(FullPath) + 'does not exists.');
71 Result := false;
72 end;
73 end
74 else
75 begin
76 if FpAccess(FullPath, X_OK {Exe flag check}) <> 0 then
77 begin
78 Log(4, ChannelLocal,'File' + Wrap(FullPath) + 'is not executable.');
79 Result := false;
80 end
81 else
82 begin
83 {$IFDEF MoreTrue }
84 Log(3, ChannelLocal,'File' + Wrap(FullPath) + 'is executable.');
85 {$ENDIF}
86 Result := true;
87 end;
89 end;
90 end;
92 function Wrap(Input: string):string;
93 begin
94 Result := ( ' ( ' + Input + ' ) ' );
95 end;
97 function DoesFoldersExists(Path:string; FolderNames:Tstrings): boolean;
98 var
99 loop:integer;
100 begin
101 Result := true;
102 { Take a path and check to see if the listed folders exists in that path. }
103 { TODO : Add a way to check the result from each one and return it. }
104 for loop := 0 to ( FolderNames.Count - 1 ) do
105 begin
106 if DoesFolderExists(Path, FolderNames[loop]) = false then
107 begin
108 Result := false;
109 Exit;
110 end;
111 end;
112 end;
114 function DoesFolderExists(Path:string; FolderName:string): boolean;
116 ChannelLocal:string;
117 begin
118 ChannelLocal := 'DoesFolderExists';
119 if DirectoryExists(Path + FolderName) = true then
120 begin
121 Result := true ;
122 {$IFDEF MoreTrue }
123 UnitMain.form1.LogWithDebug(3, ChannelLocal, ('Folder' + Wrap(Path + FolderName) + 'exists.'));
124 {$ENDIF}
126 else
127 begin
128 Result := false ;
129 Log(4, ChannelLocal, ('Folder' + Wrap(Path + FolderName) + 'does not exists.'));
130 end;
131 end;
133 procedure Log(Level:integer;Channel:string;LogText:string);
135 LevelString:string;
136 AllFine:boolean;
137 begin
138 AllFine := true;
140 if AllFine = true then
141 begin
142 {Level 0 "Info"}
143 {Level 1 "Error"}
144 {Level 2 "Variable"}
145 {Level 3 "Dev-Info"}
146 {Level 4 "Dev-Error"}
147 {Level 5 is for uses with custom functions.}
148 if Level = 0 then
149 begin
150 LevelString := 'Info';
152 else
153 if Level = 1 then
154 begin
155 LevelString := 'Error';
157 else
158 if Level = 2 then
159 begin
160 LevelString := 'Variable';
162 else
163 if level = 3 then
164 begin
165 LevelString := 'Dev-Info';
167 else
168 if level = 4 then
169 begin
170 LevelString := 'Dev-Error';
172 else
173 if level = 5 then
174 begin
175 WriteLn(LogText);
176 UnitMain.form1.Memo_LogOutPut.Lines.Add(LogText);
177 Exit();
179 else
180 Exit();
183 { Out put }
184 if HideChannel = true then
185 begin
186 WriteLn(LevelString + ': ' + LogText);
187 UnitMain.form1.Memo_LogOutPut.Lines.Add(LevelString + ': ' + LogText);
189 else
190 begin
191 WriteLn(LevelString + ':' + Channel + ': ' + LogText);
192 UnitMain.form1.Memo_LogOutPut.Lines.Add(LevelString + ':' + Channel + ': ' + LogText);
193 end;
194 end;
197 end;
200 procedure SaveLastUsedConfig();
201 begin
202 if Loading = true then exit;
205 XmlLastUsedConfig.SetValue('Version', '2');
206 XmlLastUsedConfig.SetValue('WineVersionInfo/DistributionName', UnitMain.form1.ComboBox_DistributionName.Text );
207 XmlLastUsedConfig.SetValue('WineVersionInfo/DistributionVersion', UnitMain.form1.ComboBox_DistributionVersion.Text );
208 XmlLastUsedConfig.SetValue('WineVersionInfo/Architecture', UnitMain.form1.ComboBox_Architecture.Text );
209 XmlLastUsedConfig.SetValue('WineVersionInfo/WineVersion', UnitMain.form1.ComboBox_WineVersion.Text );
211 XmlLastUsedConfig.SetValue('WineVersionInfo/UsesTerminal', UnitMain.form1.Check_Terminal.Checked );
212 XmlLastUsedConfig.SetValue('WineVersionInfo/UsesSoundWrapper', UnitMain.form1.CheckBox_UseSoundWrapper.Checked );
214 { And Save }
215 XmlLastUsedConfig.Filename := ( ConfigPath + '/LastUsedConfig.xml' );
216 Finally
217 { Clean up }
218 XmlLastUsedConfig.Flush;
219 end;
220 end;
223 procedure LoadLastUsedConfig();
225 LastUsedConfigVersion:string;
226 begin
227 Loading := true;
228 XmlLastUsedConfig:= TXMLConfig.Create(nil);
231 XmlLastUsedConfig.Filename := ( ConfigPath + '/LastUsedConfig.xml' );
233 { Version of Settings }
234 LastUsedConfigVersion := XmlLastUsedConfig.GetValue('Version','');
235 {$IFDEF LogVar}
236 LogVar(LastUsedConfigVersion,'LastUsedConfigVersion');
237 {$ENDIF}
239 { Make sure we can read the file. }
240 if LastUsedConfigVersion = '-1' then
241 begin
242 Log(3, Channel, 'Invalided file version, Never mind we ignore it and wirte over it.');
243 Exit();
244 end;
246 UnitMain.form1.ComboBox_DistributionName.Text := XmlLastUsedConfig.GetValue('WineVersionInfo/DistributionName', '' );
247 UnitMain.form1.ComboBox_DistributionVersion.Text := XmlLastUsedConfig.GetValue('WineVersionInfo/DistributionVersion', '' );
248 UnitMain.form1.ComboBox_Architecture.Text := XmlLastUsedConfig.GetValue('WineVersionInfo/Architecture', '' );
249 UnitMain.form1.ComboBox_WineVersion.Text := XmlLastUsedConfig.GetValue('WineVersionInfo/WineVersion', '' );
251 UnitMain.form1.Check_Terminal.Checked := XmlLastUsedConfig.GetValue('WineVersionInfo/UsesTerminal', false );
252 UnitMain.form1.CheckBox_UseSoundWrapper.Checked := XmlLastUsedConfig.GetValue('WineVersionInfo/UsesSoundWrapper', false );
254 { Clean up }
255 Finally
256 XmlLastUsedConfig.Flush;
257 Loading := false;
258 end;
259 end;
262 function WinToUnixPath(Path:string):string;
264 PathUpToDosdevices:string;
265 DriveNameWithSlash:string;
266 FullUnixPath:string;
267 begin
268 {Get the path up to Dosdevices.}
269 PathUpToDosdevices := (GetEnvironmentVariable('HOME') + '/' + WineUserFolder + '/prefix/' + UnitMain.form1.ComboBox_PreFix.Text + '/dosdevices/' );
270 {Take the DriveName off 'path' and replace '\' with '/'.}
271 DriveNameWithSlash := (AnsiLowerCase( Copy2SymbDel( Path, '\' )) + '/');
272 {Replace all '\' to '/'.}
273 Path := AnsiReplaceText(Path, '\', '/');
274 {Sort then.}
275 FullUnixPath := (PathUpToDosdevices + DriveNameWithSlash + Path);
276 {$IFDEF LogVar}
277 {$IFDEF MOREDEBUG_WinToUnixPath}
278 logVar(PathUpToDosdevices, 'PathUpToDosdevices');
279 logVar(DriveNameWithSlash, 'DriveNameWithSlash');
280 logVar(Path, 'Path');
281 {$ENDIF}
282 logVar(FullUnixPath, 'FullUnixPath');
283 {$ENDIF}
284 Result := FullUnixPath;
286 end;
288 function GetUnixDirPath(FilePath:string):string;
290 DirPath:string;
291 //LocalChannel:string;
292 begin
293 DirPath := LeftStr(FilePath, (Rpos('/',FilePath) ));
294 //log(0, LocalChannel, ( 'VAR ' + DirPath));
296 Result := DirPath;
297 end;
299 function WorkDirTemplate(FolderPath:string):string;
300 begin
301 Result := ('cd "' + FolderPath + '";' + #10 );
302 end;
304 {$IFDEF LogVar}
305 procedure LogVar(MyVar: string; MyVarName: string);
306 begin
307 Log(2, 'LogVar', ( Wrap( MyVarName ) + 'is' + Wrap( MyVar )) );
308 end;
309 {$ENDIF}
311 function CheckPaths():boolean;
312 begin
314 Result := true;
316 if DirExistsIfNotMakeIt(GetEnvironmentVariable('HOME'), '/.config') <> true then
317 begin
318 Result := false;
319 end;
321 {This should use ConfigPath but 'DirExistsIfNotMakeIt' passes it in two bits.}
322 if DirExistsIfNotMakeIt(GetEnvironmentVariable('HOME' ) + '/.config/', 'WineLauncher') <> true then
323 begin
324 Result := false;
325 end;
328 if DirExistsIfNotMakeIt(GetEnvironmentVariable('HOME') + '/' , WineUserFolder) = false then
329 begin
330 Result := false;
331 end;
333 if DirExistsIfNotMakeIt(GetEnvironmentVariable('HOME') + '/' + WineUserFolder + '/', 'prefix') = false then
334 begin
337 else
338 begin
339 if DoesFolderExists(GetEnvironmentVariable('HOME') + '/' + WineUserFolder + '/', 'git') = false then
340 begin
341 SetupGit();
342 end;
343 end;
346 if DirExistsIfNotMakeIt(GetEnvironmentVariable('HOME') + '/' + WineUserFolder + '/', 'wine') = false then
347 begin
348 Result := false;
349 end;
354 end;
357 function SetupGit():boolean;
359 Process:TProcess;
360 script:string;
361 RunYes:boolean;
362 ChannelLocal:string;
363 Terminal:string;
364 begin
365 Process := TProcess.Create(nil);
366 RunYes := true ;
367 ChannelLocal := 'SetupGit';
369 script := '#! /bin/sh' +{linebrake}#10 +
370 'echo This script will fetch Wine and compile it. ;'+{linebrake}#10 +
371 'echo If it fails please install the dependencies and rerun WineLauncher, see http://wiki.winehq.org/Recommended_Packages for more help.' +{linebrake}#10 +
372 'cd ' + GetEnvironmentVariable('HOME') + '/' + WineUserFolder + ' ;' +{linebrake}#10 +
373 'git clone git://source.winehq.org/git/wine.git git ;' +{linebrake}#10 +
374 'cd ./git ;' +{linebrake}#10 +
375 'git checkout -b stable-1.0.1 wine-1.0.1 ;' +{linebrake}#10 +
376 'Dname=`lsb_release -si` ;' +{linebrake}#10 +
377 'Dversion=`lsb_release -sr` ;' +{linebrake}#10 +
378 'Aname=`uname -m` ;' +{linebrake}#10 +
379 './configure --prefix=' + GetEnvironmentVariable('HOME') + '/' + WineUserFolder + '/wine/$Dname/$Dversion/$Aname/stable-1.0.1 ;' +{linebrake}#10 +
380 'make ;' +{linebrake}#10 +
381 'make install;' +{linebrake}#10 +
382 GetEnvironmentVariable('HOME') + '/' + WineUserFolder + '/wine/$Dname/$Dversion/$Aname/stable-1.0.1/bin/wineprefixcreate --prefix "' + GetEnvironmentVariable('HOME') + '/' + WineUserFolder + '/prefix/default/"' +{linebrake}#10 ;
384 {Create Script file}
385 if MakeFile((ConfigPath + '/SetupGit'),script) = true then
386 begin
388 {Set executable flag}
389 if SetExecutableFlag(ConfigPath + '/1') = false then
390 begin
391 RunYes := False ;
392 end;
394 if FileExistsAndIsExecutable('/usr/bin/gnome-terminal',false) = true then
395 begin
396 Terminal := 'gnome-terminal -x ';
398 else
399 begin
400 if FileExistsAndIsExecutable('/usr/bin/gnome-terminal',false) = true then
401 begin
402 Terminal := '/usr/bin/konsole -x ';
404 else
405 if FileExistsAndIsExecutable('/usr/bin/gnome-terminal',false) = true then
406 begin
407 Terminal := '/usr/bin/xterm ';
408 end;
409 end;
411 {Execute script one}
412 if RunYes = true then
413 begin
414 Log(0, ChannelLocal, 'Script One has being executed.');
415 Process.CommandLine := Terminal + ConfigPath +'/SetupGit';
416 Process.Execute;
417 end;
419 while Process.Running = true do
420 begin
421 sleep(5000);
422 end;
424 Result := AProcess.WaitOnExit;
426 end;
429 end;
431 function DirExistsIfNotMakeIt(Path:string; FolderName:string ): boolean;
433 LocalChannel:string; {Ignore this for now}
434 begin
435 LocalChannel := '';
437 if FolderName <> '' then
438 begin
439 if DirectoryExists( Path + FolderName ) = true then
440 begin
441 Log(0, LocalChannel, ('Directory' + Wrap( Path + FolderName ) + 'exists.')) ;
442 Result := true;
444 else
445 begin
446 Log(0, LocalChannel, ('Directory' + Wrap( Path + FolderName ) + ' does not exists.')) ;
447 if CreateDir( Path + FolderName ) then
448 begin
449 Log(0, LocalChannel, ('File' + Wrap( Path + FolderName ) + 'has being created.')) ;
450 Result := true;
452 else
453 begin
454 Log(0, LocalChannel, ('File' + Wrap( Path + FolderName ) + 'can not be created.')) ;
455 Result := true;
456 end;
457 end;
460 else
461 begin
462 Result := false;
463 end;
466 end;
468 function MakeFile(FullPath:string;Data:string):boolean;
470 FD1:Cint;
471 CL:string;
472 begin
473 CL := 'MakeFile';
474 FD1 := fpOpen (FullPath, O_WrOnly or O_Creat);
475 if FD1 > 0 then
476 begin
477 if length(Data)<>fpwrite (FD1,Data[1],Length(Data)) then
478 begin
479 Result := False ;
480 Log(1, CL, ('When writing to' + Wrap(FullPath)) );
482 else
483 begin
484 {$IFDEF MoreTrue }
485 Log(3, CL, ('File' + Wrap(FullPath) + 'has being created'));
486 {$ENDIF}
487 Result := true;
488 end;
489 fpClose(FD1);
490 end;
491 end;
493 function SetExecutableFlag(FullPath:string):boolean;
495 ChannelLocal:string;
496 begin
497 {770 is owner rwx, group rwx, other nothing}
498 if fpChmod (FullPath,&770) <> 0 then {0 = no error}
499 begin
500 Log(1, ChannelLocal, ('Can not set executable flag on' + Wrap(FullPath)) );
501 Result := False;
503 else
504 begin
505 {$IFDEF MoreTrue }
506 Log(0, ChannelLocal, ('Executable flag has being set on' + Wrap(FullPath)) );
507 {$ENDIF}
508 Result := true;
509 end;
510 end;
512 end.