{** Provides internet version checking. * * Queries an URL for XML version information. *

* * Last changed: $Date$
* Revision: $Rev$
* Author: $Author$
*} unit X2UtInetVersion; interface uses Classes, IdHTTP, IdHTTPHeaderInfo, XMLIntf; type TX2InetVersionType = (vtUnknown, vtStable, vtBeta, vtReleaseCandidate); TX2InetVersionInfo = class(TCollectionItem) private FBuild: Integer; FMajor: Integer; FMinor: Integer; FNewer: Boolean; FRelease: Integer; FVersionType: TX2InetVersionType; FVersionTypeString: String; FWhatsNew: TStrings; protected procedure LoadFromNode(const ANode: IXMLNode); public constructor Create(Collection: TCollection); override; destructor Destroy(); override; property VersionType: TX2InetVersionType read FVersionType; property VersionTypeString: String read FVersionTypeString; property Major: Integer read FMajor; property Minor: Integer read FMinor; property Release: Integer read FRelease; property Build: Integer read FBuild; property Newer: Boolean read FNewer; property WhatsNew: TStrings read FWhatsNew; end; TX2InetVersions = class(TCollection) private function GetItem(Index: Integer): TX2InetVersionInfo; procedure SetItem(Index: Integer; Value: TX2InetVersionInfo); public constructor Create(); function Add(): TX2InetVersionInfo; property Items[Index: Integer]: TX2InetVersionInfo read GetItem write SetItem; default; end; TX2InetVersion = class(TThread) private FAppID: String; FURL: String; FProxyParams: TIdProxyConnectionInfo; FHTTP: TIdHTTP; FApplicationURL: String; FVersions: TX2InetVersions; protected procedure Execute(); override; public constructor Create(); destructor Destroy(); override; procedure Terminate(); property AppID: String read FAppID write FAppID; property URL: String read FURL write FURL; property ProxyParams: TIdProxyConnectionInfo read FProxyParams; property ApplicationURL: String read FApplicationURL; property Versions: TX2InetVersions read FVersions; end; implementation uses ActiveX, SysUtils, XMLDoc, IdURI, X2UtApp; { TX2InetVersionInfo } constructor TX2InetVersionInfo.Create(Collection: TCollection); begin inherited; FWhatsNew := TStringList.Create(); end; destructor TX2InetVersionInfo.Destroy(); begin FreeAndNil(FWhatsNew); inherited; end; procedure TX2InetVersionInfo.LoadFromNode(const ANode: IXMLNode); function GetVersion(const AName: String): Integer; var xmlVersion: IXMLNode; begin Result := 0; xmlVersion := ANode.ChildNodes.FindNode(AName); if Assigned(xmlVersion) then Result := StrToIntDef(xmlVersion.Text, 0); end; var xmlItem: IXMLNode; xmlWhatsNew: IXMLNode; begin FVersionTypeString := ANode.Attributes['type']; FVersionType := vtUnknown; if FVersionTypeString = 'stable' then FVersionType := vtStable else if FVersionTypeString = 'beta' then FVersionType := vtBeta else if FVersionTypeString = 'releasecandidate' then FVersionType := vtReleaseCandidate; FMajor := GetVersion('major'); FMinor := GetVersion('minor'); FRelease := GetVersion('release'); FBuild := GetVersion('build'); with App.Version do FNewer := (FMajor > Major) or ((FMajor = Major) and (FMinor > Minor)) or ((FMajor = Major) and (FMinor = Minor) and (FRelease > Release)) or ((FMajor = Major) and (FMinor = Minor) and (FRelease = Release) and (FBuild > Build)); xmlWhatsNew := ANode.ChildNodes.FindNode('whatsnew'); if Assigned(xmlWhatsNew) then begin xmlItem := xmlWhatsNew.ChildNodes.First(); while Assigned(xmlItem) do begin if xmlItem.NodeName = 'item' then FWhatsNew.Add(xmlItem.Text); xmlItem := xmlItem.NextSibling(); end; end; end; { TX2InetVersions } constructor TX2InetVersions.Create(); begin inherited Create(TX2InetVersionInfo); end; function TX2InetVersions.Add(): TX2InetVersionInfo; begin Result := TX2InetVersionInfo(inherited Add()); end; function TX2InetVersions.GetItem(Index: Integer): TX2InetVersionInfo; begin Result := TX2InetVersionInfo(inherited GetItem(Index)); end; procedure TX2InetVersions.SetItem(Index: Integer; Value: TX2InetVersionInfo); begin inherited SetItem(Index, Value); end; { TX2InetVersion } constructor TX2InetVersion.Create(); begin inherited Create(True); FProxyParams := TIdProxyConnectionInfo.Create(); FVersions := TX2InetVersions.Create(); end; destructor TX2InetVersion.Destroy(); begin FreeAndNil(FVersions); FreeAndNil(FProxyParams); inherited; end; procedure TX2InetVersion.Execute(); var memData: TMemoryStream; xmlDoc: IXMLDocument; xmlRoot: IXMLNode; xmlURL: IXMLNode; xmlVersion: IXMLNode; begin CoInitialize(nil); FHTTP := TIdHTTP.Create(nil); try FHTTP.ProxyParams.Assign(FProxyParams); memData := TMemoryStream.Create(); try FHTTP.Get(Format('%s?appid=%s', [FURL, TIdURI.ParamsEncode(FAppID)]), memData); memData.Seek(0, soFromBeginning); if Terminated then exit; xmlDoc := TXMLDocument.Create(nil); try xmlDoc.LoadFromStream(memData); xmlRoot := xmlDoc.DocumentElement; if Terminated then exit; if xmlRoot.NodeName <> 'application' then exit; xmlURL := xmlRoot.ChildNodes.FindNode('url'); if Assigned(xmlURL) then FApplicationURL := xmlURL.Text; xmlVersion := xmlRoot.ChildNodes.First(); while Assigned(xmlVersion) do begin if xmlVersion.NodeName = 'version' then FVersions.Add().LoadFromNode(xmlVersion); xmlVersion := xmlVersion.NextSibling(); end; finally xmlDoc := nil; end; finally FreeAndNil(memData); end; finally FreeAndNil(FHTTP); end; end; procedure TX2InetVersion.Terminate(); begin inherited Terminate(); if Assigned(FHTTP) then FHTTP.Disconnect(); end; end.