/// <summary> /// Creates a new selection candidate. /// </summary> /// <param name="feedUri">The file name or URL of the feed listing the implementation.</param> /// <param name="feedPreferences">The <see cref="FeedPreferences"/> for <see cref="FeedUri"/>.</param> /// <param name="implementation">The implementation this selection candidate references.</param> /// <param name="requirements">A set of requirements/restrictions the <paramref name="implementation"/> needs to fullfill for <see cref="IsSuitable"/> to be <c>true</c>.</param> /// <param name="offlineUncached">Mark this candidate as unsuitable because it is uncached and <see cref="Config.NetworkUse"/> is set to <see cref="NetworkLevel.Offline"/>.</param> /// <exception cref="InvalidDataException"><paramref name="implementation"/>'s <see cref="ImplementationBase.ID"/> is empty.</exception> public SelectionCandidate([NotNull] FeedUri feedUri, [NotNull] FeedPreferences feedPreferences, [NotNull] Implementation implementation, [NotNull] Requirements requirements, bool offlineUncached = false) { #region Sanity checks if (feedUri == null) { throw new ArgumentNullException(nameof(feedUri)); } if (feedPreferences == null) { throw new ArgumentNullException(nameof(feedPreferences)); } if (implementation == null) { throw new ArgumentNullException(nameof(implementation)); } if (requirements == null) { throw new ArgumentNullException(nameof(requirements)); } #endregion if (string.IsNullOrEmpty(implementation.ID)) { throw new InvalidDataException(string.Format(Resources.ImplementationMissingID, implementation, feedUri)); } FeedUri = feedUri; FeedPreferences = feedPreferences; Implementation = implementation; _implementationPreferences = feedPreferences[implementation.ID]; CheckSuitabilty(requirements, offlineUncached); }
private IEnumerable <SelectionCandidate> GetCandidates(FeedUri feedUri, Feed feed, Requirements requirements) { var feedPreferences = FeedPreferences.LoadForSafe(feedUri); foreach (var element in feed.Elements) { var packageImplementation = element as PackageImplementation; if (packageImplementation != null) { // Each <package-implementation> provides 0..n selection candidates var externalImplementations = _packageManager.Query(packageImplementation, requirements.Distributions.ToArray()); foreach (var externalImplementation in externalImplementations) { _externalImplementations[externalImplementation.ID] = externalImplementation; yield return(new SelectionCandidate(new FeedUri(FeedUri.FromDistributionPrefix + feedUri), feedPreferences, externalImplementation, requirements)); } } else if (requirements.Distributions.ContainsOrEmpty(Restriction.DistributionZeroInstall)) { var implementation = element as Implementation; if (implementation != null) { // Each <implementation> provides 1 selection candidate yield return(new SelectionCandidate(feedUri, feedPreferences, implementation, requirements, offlineUncached: (_config.NetworkUse == NetworkLevel.Offline) && !_isCached(implementation))); } } } }
/// <inheritdoc/> public void ImportFeed(string path, FeedUri uri, FeedUri mirrorUrl = null) { #region Sanity checks if (uri == null) { throw new ArgumentNullException("uri"); } if (string.IsNullOrEmpty(path)) { throw new ArgumentNullException("path"); } #endregion if (uri.IsFile) { throw new UriFormatException(Resources.FeedUriLocal); } Log.Debug("Importing feed " + uri.ToStringRfc() + " from: " + path); var data = File.ReadAllBytes(path); var newSignature = _trustManager.CheckTrust(data, uri, mirrorUrl); DetectAttacks(data, uri, newSignature); // Add to cache and remember time _feedCache.Add(uri, data); var preferences = FeedPreferences.LoadForSafe(uri); preferences.LastChecked = DateTime.UtcNow; preferences.Normalize(); preferences.SaveFor(uri); }
public void TestNormalize() { var keep = new ImplementationPreferences {ID = "id1", UserStability = Stability.Testing}; var superflous = new ImplementationPreferences {ID = "id2"}; var preferences = new FeedPreferences {Implementations = {keep, superflous}}; preferences.Normalize(); preferences.Implementations.Should().BeEquivalentTo(keep); }
public void TestNormalize() { var keep = new ImplementationPreferences {ID = "id1", UserStability = Stability.Testing}; var superflous = new ImplementationPreferences {ID = "id2"}; var preferences = new FeedPreferences {Implementations = {keep, superflous}}; preferences.Normalize(); CollectionAssert.AreEquivalent(new[] {keep}, preferences.Implementations); }
private void AddToCache(byte[] data, FeedUri feedUri) { _feedCache.Add(feedUri, data); var preferences = FeedPreferences.LoadForSafe(feedUri); preferences.LastChecked = DateTime.UtcNow; preferences.Normalize(); preferences.SaveFor(feedUri); }
public void TestGetImplementationPreferences() { var preferences = new FeedPreferences(); var prefs1 = preferences["id1"]; Assert.AreSame(prefs1, preferences["id1"], "Second call with same ID should return same reference"); var prefs2 = new ImplementationPreferences {ID = "id2"}; preferences.Implementations.Add(prefs2); Assert.AreSame(prefs2, preferences["id2"], "Call with pre-existing ID should return existing reference"); CollectionAssert.AreEquivalent(new[] {prefs1, prefs2}, preferences.Implementations); }
/// <inheritdoc/> public bool IsStale(FeedUri feedUri) { #region Sanity checks if (feedUri == null) { throw new ArgumentNullException(nameof(feedUri)); } #endregion var preferences = FeedPreferences.LoadForSafe(feedUri); TimeSpan lastChecked = DateTime.UtcNow - preferences.LastChecked; TimeSpan lastCheckAttempt = DateTime.UtcNow - GetLastCheckAttempt(feedUri); return(lastChecked > _config.Freshness && lastCheckAttempt > _failedCheckDelay); }
private IEnumerable <SelectionCandidate> GenerateDummyCandidates(FeedUri feedUri) { if (feedUri.IsFromDistribution) { return(Enumerable.Empty <SelectionCandidate>()); } try { var feed = _feedManager[feedUri]; var feedPreferences = FeedPreferences.LoadForSafe(feedUri); return(feed.Implementations.Select(implementation => GenerateDummyCandidate(feedUri, feedPreferences, implementation))); } #region Error handling catch (KeyNotFoundException) { return(Enumerable.Empty <SelectionCandidate>()); } #endregion }
private static void ApplyVersionRestrictions(Requirements requirements, Selections selections) { if (requirements.ExtraRestrictions.Count == 0) { return; } // TODO Log.Warn($"You have applied a version restriction to this app. Zero Install will continue to apply this restriction to any future updates. You will need to run '0install select --customize {requirements.InterfaceUri}' to undo this."); foreach (var restriction in requirements.ExtraRestrictions) { var selection = selections.GetImplementation(restriction.Key); if (selection != null) { var pref = FeedPreferences.LoadForSafe(restriction.Key); pref.Implementations.Clear(); pref[selection.ID].UserStability = Stability.Preferred; pref.SaveFor(restriction.Key); } } }
private SelectionCandidate GenerateDummyCandidate(FeedUri feedUri, FeedPreferences feedPreferences, Implementation implementation) { return new SelectionCandidate(feedUri, feedPreferences, implementation, new Requirements(_interfaceUri, Command.NameRun, new Architecture(Architecture.CurrentSystem.OS, Cpu.All))); }
private SelectionCandidate GenerateDummyCandidate(FeedUri feedUri, FeedPreferences feedPreferences, Implementation implementation) => new SelectionCandidate(feedUri, feedPreferences, implementation, new Requirements(_interfaceUri, "", new Architecture(Architecture.CurrentSystem.OS, Cpu.All)));
public void TestGetImplementationPreferences() { var preferences = new FeedPreferences(); var prefs1 = preferences["id1"]; preferences["id1"].Should().BeSameAs(prefs1, because: "Second call with same ID should return same reference"); var prefs2 = new ImplementationPreferences {ID = "id2"}; preferences.Implementations.Add(prefs2); preferences["id2"].Should().BeSameAs(prefs2, because: "Call with pre-existing ID should return existing reference"); preferences.Implementations.Should().BeEquivalentTo(prefs1, prefs2); }
private SelectionCandidate GenerateDummyCandidate(FeedUri feedUri, FeedPreferences feedPreferences, Implementation implementation) => new(feedUri, feedPreferences, implementation,