mirror of
https://github.com/keymanapp/keyman.git
synced 2026-09-18 05:37:40 +00:00
Fixes #4886. This patch includes 5 separate fixes for the various scenarios we encountered during package installation. 1. RunTools.pas: don't attempt to install TIPs if package is not also being installed. 2. Keyman.Setup.System.OnlineResourceCheck.pas, OnlineUpdateCheck.pas: handle online update check for packages with spaces or periods in the id (legacy packages only). 3. Keyman.Setup.System.InstallInfo.pas: Handle browsers renaming downloaded files with `(n)` and `[n]` patterns as well as the current ` (n)` pattern. 4. Keyman.Setup.System.InstallInfo.pas: Handle browsers renaming downloaded files with `_n` pattern. See code comments for details. 5. Keyman.Configuration.System.TIPMaintenance.pas: Avoid crashing if `kmshell -install-tips-for-packages` is passed an invalid package name. The crash is actually fixed in point 5 above, but the root causes are addressed in the other points.
113 lines
3.5 KiB
ObjectPascal
113 lines
3.5 KiB
ObjectPascal
{**
|
|
* Wrapper for checking api.keyman.com for latest version of resources to be
|
|
* installed. Uses the /windows/14.0/update endpoints.
|
|
*}
|
|
unit Keyman.Setup.System.OnlineResourceCheck;
|
|
|
|
interface
|
|
|
|
uses
|
|
Keyman.Setup.System.InstallInfo;
|
|
|
|
type
|
|
TOnlineResourceCheck = class sealed
|
|
class procedure QueryServer(ASilent: Boolean; AInstallInfo: TInstallInfo); static;
|
|
end;
|
|
|
|
implementation
|
|
|
|
uses
|
|
System.SysUtils,
|
|
|
|
GlobalProxySettings,
|
|
httpuploader,
|
|
Keyman.System.UpdateCheckResponse,
|
|
KeymanVersion,
|
|
PackageInfo,
|
|
Upload_Settings,
|
|
versioninfo;
|
|
|
|
class procedure TOnlineResourceCheck.QueryServer(ASilent: Boolean; AInstallInfo: TInstallInfo);
|
|
var
|
|
http: THTTPUploader;
|
|
pack: TInstallInfoPackage;
|
|
ucr: TUpdateCheckResponse;
|
|
ucrpack: TUpdateCheckResponsePackage;
|
|
location: TInstallInfoFileLocation;
|
|
packLocation: TInstallInfoPackageFileLocation;
|
|
currentVersion: string;
|
|
lang: TUpdateCheckResponseLanguage;
|
|
iipl: TInstallInfoPackageLanguage;
|
|
u: AnsiString;
|
|
i: Integer;
|
|
begin
|
|
currentVersion := AInstallInfo.MsiLocations.LatestVersion(SKeymanVersion_Min_Evergreen);
|
|
|
|
http := THttpUploader.Create(nil);
|
|
try
|
|
http.ShowUI := not ASilent;
|
|
http.Request.SetURL(MakeAPIURL(API_Path_UpdateCheck_Windows));
|
|
http.Fields.Add('version', AnsiString(currentVersion));
|
|
http.Fields.Add('tier', AnsiString(AInstallInfo.Tier));
|
|
http.Fields.Add('update', '0'); // This is probably a fresh install of a package, not an update
|
|
http.Fields.Add('manual', '1'); // Treat this as a manual update so the staggered rollout doesn't apply
|
|
for i := 0 to AInstallInfo.Packages.Count - 1 do
|
|
begin
|
|
pack := AInstallInfo.Packages[i];
|
|
// Due to limitations in PHP parsing of query string parameters names with
|
|
// space or period, we need to split the parameters up. The legacy pattern
|
|
// is still supported on the server side. Relates to #4886.
|
|
http.Fields.Add(AnsiString('packageid_'+IntToStr(i)), AnsiString(pack.ID));
|
|
http.Fields.Add(AnsiString('packageversion_'+IntToStr(i)), AnsiString(pack.Locations.LatestVersion));
|
|
end;
|
|
|
|
http.Upload;
|
|
if http.Response.StatusCode <> 200 then
|
|
begin
|
|
// TODO: log failed response
|
|
//raise EOnlineUpdateCheck.Create('Error '+IntToStr(Response.StatusCode));
|
|
Exit;
|
|
end;
|
|
|
|
u := http.response.PMessageBody;
|
|
finally
|
|
http.Free;
|
|
end;
|
|
|
|
if ucr.Parse(u, 'msi', currentVersion) then
|
|
begin
|
|
for ucrpack in ucr.Packages do
|
|
begin
|
|
pack := AInstallInfo.Packages.FindById(ucrpack.ID, False);
|
|
if Assigned(pack) then
|
|
begin
|
|
packLocation := TInstallInfoPackageFileLocation.Create(iilOnline);
|
|
pack.Locations.Add(packLocation);
|
|
packLocation.Name := ucrpack.Name;
|
|
packLocation.Path := ucrpack.FileName;
|
|
packLocation.URL := ucrpack.DownloadURL;
|
|
packLocation.Version := ucrpack.NewVersion;
|
|
packLocation.Size := ucrpack.DownloadSize;
|
|
|
|
for lang in ucrpack.Languages do
|
|
begin
|
|
iipl := TInstallInfoPackageLanguage.Create(lang.ID, lang.displayName);
|
|
packLocation.Languages.Add(iipl);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
if ucr.Status = ucrsUpdateReady then
|
|
begin
|
|
location := TInstallInfoFileLocation.Create(iilOnline);
|
|
location.URL := ucr.InstallURL;
|
|
location.Path := ucr.FileName;
|
|
location.Version := ucr.NewVersion;
|
|
location.VersionWithTag := ucr.NewVersionWithTag;
|
|
location.Size := ucr.InstallSize;
|
|
AInstallInfo.MsiLocations.Add(location);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
end.
|