// Copyright (C) 2024, The Duplicati Team // https://duplicati.com, hello@duplicati.com // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. using System; using System.Linq; namespace Duplicati.Library.AutoUpdater { /// /// The different kinds of releases supported /// public enum ReleaseType { Unknown, Stable, Beta, Experimental, Canary, Nightly, Debug } public enum UpdateSeverity { None, Low, Normal, High, Critical } public class UpdateInfo { public string UpdateFromV1Url; public string UpdateFromV2Url; public string Displayname; public string Version; public DateTime ReleaseTime; public string ReleaseType; public string UpdateSeverity; public string ChangeInfo; public int PackageUpdaterVersion; /// /// Legacy entry, do not use /// [Obsolete("Only kept to avoid v2.0.7.x and earlier releases from crashing on nulls")] public string[] RemoteURLS = Array.Empty(); /// /// List of installer packages /// public PackageEntry[] Packages; /// /// Link to a generic download page /// public string GenericUpdatePageUrl = string.Empty; /// /// Finds a package that matches the /// /// The package type id; null uses the currently installed package type id /// The matching package or null public PackageEntry? FindPackage(string packageTypeId = null) { if (!string.IsNullOrWhiteSpace(UpdateFromV2Url) || PackageUpdaterVersion != UpdaterManager.SUPPORTED_PACKAGE_UPDATER_VERSION) return null; packageTypeId ??= UpdaterManager.PackageTypeId; if (string.IsNullOrWhiteSpace(packageTypeId) || Packages == null) return null; return Packages.FirstOrDefault(x => string.Equals(x.PackageTypeId, packageTypeId, StringComparison.OrdinalIgnoreCase)); } /// /// Gets the generic update page url for the /// /// The package type id; null uses the currently installed package type id /// The generic update page url public string GetGenericUpdatePageUrl(string packageTypeId = null) { var baseurl = string.IsNullOrWhiteSpace(UpdateFromV2Url) ? GenericUpdatePageUrl : UpdateFromV2Url; packageTypeId ??= UpdaterManager.PackageTypeId; if (string.IsNullOrWhiteSpace(packageTypeId)) return GenericUpdatePageUrl; return GenericUpdatePageUrl + $"{(GenericUpdatePageUrl.IndexOf('?') > 0 ? "&" : "?")}packagetypeid={Uri.EscapeDataString(packageTypeId ?? "")}"; } /// /// Gets the updated package urls for the /// /// The package type id; null uses the currently installed package type id /// The matching update urls public string[] GetUpdateUrls(string packageTypeId = null) { packageTypeId ??= UpdaterManager.PackageTypeId; var package = FindPackage(packageTypeId); if (package != null) return package.RemoteUrls; var generic = GetGenericUpdatePageUrl(packageTypeId); if (!string.IsNullOrWhiteSpace(generic)) return [generic]; return Array.Empty(); } /// /// Creates a copy of the instance by serializing and deseriaizing the data /// /// A cloned copy public UpdateInfo Clone() => System.Text.Json.JsonSerializer.Deserialize( System.Text.Json.JsonSerializer.Serialize(this) ); } }