Beispiel #1
0
        public long BenchmarkGetTimelineData(User user, RetrievalMethod method = RetrievalMethod.Id)
        {
            var timer = Stopwatch.StartNew();

            GetTimelineDataInternal(user, method);
            return(timer.ElapsedMilliseconds);
        }
Beispiel #2
0
    /// <summary>
    /// Calculates a <see cref="ManifestDigest"/> for a retrieval method. Sets missing properties in the process.
    /// </summary>
    /// <param name="retrievalMethod">The retrieval method.</param>
    /// <param name="executor">Used to modify properties in an undoable fashion.</param>
    /// <param name="handler">A callback object used when the the user is to be informed about progress.</param>
    /// <param name="format">The manifest format. Leave <c>null</c> for default.</param>
    /// <returns>The generated digest.</returns>
    /// <exception cref="OperationCanceledException">The user canceled the task.</exception>
    /// <exception cref="WebException">A file could not be downloaded from the internet.</exception>
    public static ManifestDigest CalculateDigest(this RetrievalMethod retrievalMethod, ICommandExecutor executor, ITaskHandler handler, ManifestFormat?format = null)
    {
        #region Sanity checks
        if (retrievalMethod == null)
        {
            throw new ArgumentNullException(nameof(retrievalMethod));
        }
        if (executor == null)
        {
            throw new ArgumentNullException(nameof(executor));
        }
        if (handler == null)
        {
            throw new ArgumentNullException(nameof(handler));
        }
        #endregion

        var builder = new ManifestBuilder(format ?? ManifestFormat.Sha256New);
        builder.Add(retrievalMethod, executor, handler);

        var digest = new ManifestDigest(builder.Manifest.CalculateDigest());
        if (digest.PartialEquals(ManifestDigest.Empty))
        {
            Log.Warn(Resources.EmptyImplementation);
        }
        return(digest);
    }
        public static Implementation Build([NotNull] RetrievalMethod retrievalMethod, [NotNull] ITaskHandler handler, bool keepDownloads = false)
        {
            #region Sanity checks
            if (retrievalMethod == null)
            {
                throw new ArgumentNullException("retrievalMethod");
            }
            if (handler == null)
            {
                throw new ArgumentNullException("handler");
            }
            #endregion

            var implementationDir = retrievalMethod.DownloadAndApply(handler);
            try
            {
                var digest = GenerateDigest(implementationDir, handler, keepDownloads);
                return(new Implementation {
                    ID = @"sha1new=" + digest.Sha1New, ManifestDigest = digest, RetrievalMethods = { retrievalMethod }
                });
            }
            finally
            {
                implementationDir.Dispose();
            }
        }
        /// <summary>
        /// Creates a new <see cref="Implementation"/> by completing a <see cref="RetrievalMethod"/> and calculating the resulting <see cref="ManifestDigest"/>.
        /// </summary>
        /// <param name="retrievalMethod">The <see cref="RetrievalMethod"/> to use.</param>
        /// <param name="handler">A callback object used when the the user is to be informed about progress.</param>
        /// <param name="keepDownloads">Used to retain downloaded implementations; can be <c>null</c>.</param>
        /// <returns>A newly created <see cref="Implementation"/> containing one <see cref="Archive"/>.</returns>
        /// <exception cref="OperationCanceledException">The user canceled the task.</exception>
        /// <exception cref="UriFormatException"><see cref="DownloadRetrievalMethod.Href"/> inside <paramref name="retrievalMethod"/> is a relative URI that cannot be resolved.</exception>
        /// <exception cref="IOException">There was a problem extracting the archive.</exception>
        /// <exception cref="WebException">There was a problem downloading the archive.</exception>
        /// <exception cref="UnauthorizedAccessException">Write access to temporary files was not permitted.</exception>
        /// <exception cref="NotSupportedException">A <see cref="Archive.MimeType"/> is not supported.</exception>
        public static Implementation Build(RetrievalMethod retrievalMethod, ITaskHandler handler, IImplementationStore?keepDownloads = null)
        {
            #region Sanity checks
            if (retrievalMethod == null)
            {
                throw new ArgumentNullException(nameof(retrievalMethod));
            }
            if (handler == null)
            {
                throw new ArgumentNullException(nameof(handler));
            }
            #endregion

            var implementationDir = retrievalMethod.DownloadAndApply(handler);
            try
            {
                var digest = new Implementation {
                    RetrievalMethods = { retrievalMethod }
                };
                digest.UpdateDigest(implementationDir, handler, new SimpleCommandExecutor(), keepDownloads);
                return(digest);
            }
            finally
            {
                implementationDir.Dispose();
            }
        }
        /// <summary>
        /// Executes a specific <see cref="RetrievalMethod"/>.
        /// </summary>
        /// <param name="retrievalMethod">The retrieval method to execute.</param>
        /// <param name="manifestDigest">The digest the result of the retrieval method should produce.</param>
        /// <exception cref="OperationCanceledException">A download or IO task was canceled from another thread.</exception>
        /// <exception cref="WebException">A file could not be downloaded from the internet.</exception>
        /// <exception cref="NotSupportedException">A file format, protocol, etc. is unknown or not supported.</exception>
        /// <exception cref="IOException">A downloaded file could not be written to the disk or extracted.</exception>
        /// <exception cref="UnauthorizedAccessException">Write access to <see cref="IImplementationStore"/> is not permitted.</exception>
        /// <exception cref="DigestMismatchException">An <see cref="Implementation"/>'s <see cref="Archive"/>s don't match the associated <see cref="ManifestDigest"/>.</exception>
        private void Retrieve(RetrievalMethod retrievalMethod, ManifestDigest manifestDigest)
        {
            if (retrievalMethod is ExternalRetrievalMethod externalRetrievalMethod)
            {
                RunNative(externalRetrievalMethod);
                return;
            }

            // Treat single steps as a Recipes for easier handling
            var recipe = retrievalMethod as Recipe ?? new Recipe {
                Steps = { (IRecipeStep)retrievalMethod }
            };

            try
            {
                // Enable Recipe steps to call back to Fetcher
                using (FetchHandle.Register(impl => Fetch(impl, tag: manifestDigest) ?? throw new ImplementationNotFoundException(manifestDigest)))
                    Cook(recipe, manifestDigest);
            }
            #region Error handling
            catch (ImplementationAlreadyInStoreException)
            {}
            catch (DigestMismatchException)
            {
                Log.Error("Damaged download: " + retrievalMethod);
                throw;
            }
            #endregion
        }
Beispiel #6
0
        /// <summary>
        /// Executes a specific <see cref="RetrievalMethod"/>.
        /// </summary>
        /// <param name="retrievalMethod">The retrieval method to execute.</param>
        /// <param name="manifestDigest">The digest the result of the retrieval method should produce.</param>
        /// <exception cref="OperationCanceledException">A download or IO task was canceled from another thread.</exception>
        /// <exception cref="WebException">A file could not be downloaded from the internet.</exception>
        /// <exception cref="NotSupportedException">A file format, protocal, etc. is unknown or not supported.</exception>
        /// <exception cref="IOException">A downloaded file could not be written to the disk or extracted.</exception>
        /// <exception cref="UnauthorizedAccessException">Write access to <see cref="IStore"/> is not permitted.</exception>
        /// <exception cref="DigestMismatchException">An <see cref="Implementation"/>'s <see cref="Archive"/>s don't match the associated <see cref="ManifestDigest"/>.</exception>
        private void Retrieve([NotNull] RetrievalMethod retrievalMethod, ManifestDigest manifestDigest)
        {
            var externalRetrievalMethod = retrievalMethod as ExternalRetrievalMethod;

            if (externalRetrievalMethod != null)
            {
                RunNative(externalRetrievalMethod);
                return;
            }

            // Treat single steps as a Recipes for easier handling
            var recipe = retrievalMethod as Recipe ?? new Recipe {
                Steps = { (IRecipeStep)retrievalMethod }
            };

            try
            {
                Cook(recipe, manifestDigest);
            }
            #region Error handling
            catch (ImplementationAlreadyInStoreException)
            {}
            catch (DigestMismatchException ex)
            {
                // Wrap exception to add context information
                throw new DigestMismatchException("Damaged download: " + retrievalMethod, ex);
            }
            #endregion
        }
Beispiel #7
0
        public static TemporaryDirectory DownloadAndApply([NotNull] this RetrievalMethod retrievalMethod, [NotNull] ITaskHandler handler, [CanBeNull] ICommandExecutor executor = null)
        {
            #region Sanity checks
            if (retrievalMethod == null)
            {
                throw new ArgumentNullException("retrievalMethod");
            }
            if (handler == null)
            {
                throw new ArgumentNullException("handler");
            }
            #endregion

            var download = retrievalMethod as DownloadRetrievalMethod;
            if (download != null)
            {
                return(download.DownloadAndApply(handler, executor));
            }

            var recipe = retrievalMethod as Recipe;
            if (recipe != null)
            {
                return(recipe.DownloadAndApply(handler, executor));
            }

            throw new NotSupportedException(Resources.UnknownRetrievalMethodType);
        }
Beispiel #8
0
 public PuzzleRetriever(string defaultFile, int level, RetrievalMethod mode, Size generationSize, int maxColor)
 {
     this.mode     = mode;
     this.level    = level - 1; // the -1 is because .Next() immediately increments level
     puzzlegen     = new PuzzleGenerator();
     puzzleparser  = new FileParser(defaultFile);
     genSize       = generationSize;
     this.maxColor = maxColor;
     //puzzlegen.QueueLevels(levelsToGenerateAtOnce, genSize.Width, genSize.Height, maxColor);
 }
    public T Get(RetrievalMethod rm)
    {
        switch (rm)
        {
        case RetrievalMethod.Basic:
            return(GetBasic());

        case RetrievalMethod.Existing:
            return(GetExisting());
        }
    }
Beispiel #10
0
        public TimelineData GetTimelineData(User user, RetrievalMethod method = RetrievalMethod.Id)
        {
            var cacheKey = CacheKey(user, "TimelineData");

            if (!_memoryCache.TryGetValue(cacheKey, out TimelineData timelineData))
            {
                var options = new MemoryCacheEntryOptions().SetAbsoluteExpiration(TimeSpan.FromSeconds(300));
                timelineData = GetTimelineDataInternal(user, method);
                _memoryCache.Set(cacheKey, timelineData, options);
            }
            return(timelineData);
        }
        /// <summary>
        /// Downloads and applies a <see cref="RetrievalMethod"/> and adds missing properties.
        /// </summary>
        /// <param name="retrievalMethod">The <see cref="RetrievalMethod"/> to be downloaded.</param>
        /// <param name="handler">A callback object used when the the user is to be informed about progress.</param>
        /// <param name="executor">Used to apply properties in an undoable fashion.</param>
        /// <returns>A temporary directory containing the extracted content.</returns>
        /// <exception cref="OperationCanceledException">The user canceled the task.</exception>
        /// <exception cref="UriFormatException"><see cref="DownloadRetrievalMethod.Href"/> inside <paramref name="retrievalMethod"/> is a relative URI that cannot be resolved.</exception>
        /// <exception cref="IOException">There is a problem access a temporary file.</exception>
        /// <exception cref="WebException">A file could not be downloaded from the internet.</exception>
        /// <exception cref="UnauthorizedAccessException">Read or write access to a temporary file is not permitted.</exception>
        /// <exception cref="NotSupportedException">A <see cref="Archive.MimeType"/> is not supported.</exception>
        public static TemporaryDirectory DownloadAndApply(this RetrievalMethod retrievalMethod, ITaskHandler handler, ICommandExecutor?executor = null)
        {
            #region Sanity checks
            if (retrievalMethod == null)
            {
                throw new ArgumentNullException(nameof(retrievalMethod));
            }
            if (handler == null)
            {
                throw new ArgumentNullException(nameof(handler));
            }
            #endregion

            return(retrievalMethod switch
            {
                DownloadRetrievalMethod download => download.DownloadAndApply(handler, executor),
                Recipe recipe => recipe.DownloadAndApply(handler, executor),
                _ => throw new NotSupportedException(Resources.UnknownRetrievalMethodType)
            });
Beispiel #12
0
        private TimelineData GetTimelineDataInternal(User user, RetrievalMethod method)
        {
#if !DEBUG
            if (method != RetrievalMethod.Id)
            {
                throw new InvalidEnumArgumentException($"Only retrieval by id can be used in a non-debug environment");
            }
#endif
            switch (method)
            {
            case RetrievalMethod.Id: return(LoadTimelineDataByIdAggregation(user));

            case RetrievalMethod.Include: return(LoadTimelineDataByInclude(user));

            case RetrievalMethod.Load: return(LoadTimelineDataByExplicitLoad(user));

            case RetrievalMethod.Predicate: return(LoadTimelineDataByPredicateAggregation(user));
            }
            throw new InvalidEnumArgumentException($"Method does not support provided Enum {method}");
        }
Beispiel #13
0
        /// <summary>
        /// Executes a specific <see cref="RetrievalMethod"/>.
        /// </summary>
        /// <param name="retrievalMethod">The retrieval method to execute.</param>
        /// <param name="manifestDigest">The digest the result of the retrieval method should produce.</param>
        private void Retrieve(RetrievalMethod retrievalMethod, ManifestDigest manifestDigest)
        {
            var externalRetrievalMethod = retrievalMethod as ExternalRetrievalMethod;

            if (externalRetrievalMethod != null)
            {
                RunNative(externalRetrievalMethod);
                return;
            }

            // Treat single steps as a Recipes for easier handling
            var recipe = retrievalMethod as Recipe ?? new Recipe {
                Steps = { (IRecipeStep)retrievalMethod }
            };

            try
            {
                Cook(recipe, manifestDigest);
            }
            catch (ImplementationAlreadyInStoreException)
            {}
        }
Beispiel #14
0
 public void SetMethod(RetrievalMethod m)
 {
     mode = m;
 }
Beispiel #15
0
 /// <summary>
 /// Asserts that <paramref name="x"/> is ranked over <paramref name="y"/>.
 /// </summary>
 private static void AssertOver(RetrievalMethod x, RetrievalMethod y)
 {
     Assert.Less(RetrievalMethodRanker.Instance.Compare(x, y), 0);
     Assert.Greater(RetrievalMethodRanker.Instance.Compare(y, x), 0);
 }
 private static bool IsDownloadSizeMissing(this RetrievalMethod retrievalMethod)
 => retrievalMethod is DownloadRetrievalMethod downloadRetrievalMethod && downloadRetrievalMethod.Size == 0;
 private static bool IsDownloadSizeMissing(RetrievalMethod retrievalMethod)
 => retrievalMethod is DownloadRetrievalMethod
 {
        private static bool IsDownloadSizeMissing([NotNull] this RetrievalMethod retrievalMethod)
        {
            var downloadRetrievalMethod = retrievalMethod as DownloadRetrievalMethod;

            return(downloadRetrievalMethod != null && downloadRetrievalMethod.Size == 0);
        }
Beispiel #19
0
 public PuzzleRetriever(string defaultFile, int level, RetrievalMethod mode, Size generationSize) : this(defaultFile, level, mode, generationSize, 10)
 {
 }
Beispiel #20
0
 public PuzzleRetriever(string defaultFile, int level, RetrievalMethod mode) : this(defaultFile, level, mode, new Size(5, 5))
 {
 }
Beispiel #21
0
 public PuzzleRetriever(string defaultFile, RetrievalMethod mode, int maxColor) : this(defaultFile, 0, mode, new Size(5, 5), maxColor)
 {
 }
Beispiel #22
0
 public PuzzleRetriever(string defaultFile, RetrievalMethod mode) : this(defaultFile, 0, mode)
 {
 }
    /// <summary>
    /// Applies a retrieval method to the implementation. Sets missing properties in the process.
    /// </summary>
    /// <param name="builder">The builder.</param>
    /// <param name="retrievalMethod">The retrieval method.</param>
    /// <param name="executor">Used to modify properties in an undoable fashion.</param>
    /// <param name="handler">A callback object used when the the user needs to be informed about IO tasks.</param>
    /// <exception cref="OperationCanceledException">The user canceled the task.</exception>
    /// <exception cref="WebException">A file could not be downloaded from the internet.</exception>
    public static void Add(this IBuilder builder, RetrievalMethod retrievalMethod, ICommandExecutor executor, ITaskHandler handler)
    {
        #region Sanity checks
        if (builder == null)
        {
            throw new ArgumentNullException(nameof(builder));
        }
        if (retrievalMethod == null)
        {
            throw new ArgumentNullException(nameof(retrievalMethod));
        }
        if (executor == null)
        {
            throw new ArgumentNullException(nameof(executor));
        }
        if (handler == null)
        {
            throw new ArgumentNullException(nameof(handler));
        }
        #endregion

        void Apply(IRecipeStep step)
        {
            switch (step)
            {
            case DownloadRetrievalMethod download:
                builder.Add(download, executor, handler);
                break;

            case RemoveStep remove:
                builder.Remove(remove);
                break;

            case RenameStep rename:
                builder.Rename(rename);
                break;

            case CopyFromStep copyFrom:
                builder.CopyFrom(copyFrom, handler);
                break;

            default:
                throw new NotSupportedException($"Unknown recipe step: ${step}");
            }
        }

        switch (retrievalMethod)
        {
        case DownloadRetrievalMethod download:
            Apply(download);
            break;

        case Recipe recipe:
            foreach (var step in recipe.Steps)
            {
                Apply(step);
            }
            break;

        default:
            throw new NotSupportedException($"Unknown retrieval method: ${retrievalMethod}");
        }
    }
 /// <summary>
 /// Asserts that <paramref name="x"/> is ranked over <paramref name="y"/>.
 /// </summary>
 private static void AssertOver(RetrievalMethod x, RetrievalMethod y)
 {
     RetrievalMethodRanker.Instance.Compare(x, y).Should().BeLessThan(0);
     RetrievalMethodRanker.Instance.Compare(y, x).Should().BeGreaterThan(0);
 }