<commit_before>﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using System.Web.Hosting;
using EPiServer;
using EPiServer.Core;
using EPiServer.Framework.Blobs;
using EPiServer.Framework.Configuration;
using EPiServer.Logging;
using EPiServer.Web.Routing;
using ImageProcessor.Configuration;
using ImageProcessor.Imaging.Formats;
using ImageProcessor.Web.Caching;

namespace ImageProcessor.Web.Episerver
{
    /// <summary>
    /// Provides an <see cref="IImageCache"/> implementation that uses the configured Episerver Blob storage.
    /// The cache is self healing and cleaning.
    /// </summary>
    public class FileBlobCache : ImageCacheBase
    {
        /// <summary>
        /// Use the configured logging mechanism
        /// </summary>
        private static readonly ILogger logger = LogManager.GetLogger();

        /// <summary>
        /// Used to lock against when checking the cached folder path.
        /// </summary>
        private static object cachePathValidatorLock = new object();

        /// <summary>
        /// Whether the cached path has been checked.
        /// </summary>
        private static bool cachePathValidatorCheck;

        /// <summary>
        /// Stores the resulting validated absolute cache folder path
        /// </summary>
        private static string validatedAbsoluteCachePath;

        /// <summary>
        /// Stores the resulting validated virtual cache folder path - if it's within the web root
        /// </summary>
        private static string validatedVirtualCachePath;
        /// <summary>
        /// The virtual cache path.
        /// </summary>
        private readonly string virtualCachePath;

        /// <summary>
        /// The absolute path to virtual cache path on the server.
        /// </summary>
        private readonly string absoluteCachePath;

        /// <summary>
        /// The virtual path to the cached file.
        /// </summary>
        private string virtualCachedFilePath;

        /// <summary>
        /// The container where the blob is stored in.
        /// </summary>
        private string container;

        /// <summary>
        /// The cached generated filename
        /// </summary>
        private string cachedFilename;

        /// <summary>
        /// The create time of the cached image
        /// </summary>
        private DateTime cachedImageCreationTimeUtc = DateTime.MinValue;

        private const string prefix = "3p!_";

        /// <summary>
        /// Initializes a new instance of the <see cref="FileBlobCache"/> class.
        /// </summary>
        /// <param name="requestPath">
        /// The request path for the image.
        /// </param>
        /// <param name="fullPath">
        /// The full path for the image.
        /// </param>
        /// <param name="querystring">
        /// The querystring containing instructions.
        /// </param>
        public FileBlobCache(string requestPath, string fullPath, string querystring)
            : base(requestPath, fullPath, querystring)
        {
            string basePath = (EPiServerFrameworkSection.Instance.AppData.BasePath.IndexOf(@"\\") == 0 || EPiServerFrameworkSection.Instance.AppData.BasePath.Contains(":\\"))
                                        ? EPiServerFrameworkSection.Instance.AppData.BasePath
                                        : "~/" + EPiServerFrameworkSection.Instance.AppData.BasePath;

            string configuredPath = Settings.ContainsKey("VirtualCachePath")
                                        ? Settings["VirtualCachePath"]
                                        : basePath + "/blobs";

            absoluteCachePath = GetAbsolutePath(configuredPath, out virtualCachePath);
        }

        /// <summary>
        /// Gets a value indicating whether the image is new or updated in an asynchronous manner.
        /// </summary>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        public override async Task<bool> IsNewOrUpdatedAsync()
        {<commit_msg>Allow for a relative app data path as well<commit_after>﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using System.Web.Hosting;
using EPiServer;
using EPiServer.Core;
using EPiServer.Framework.Blobs;
using EPiServer.Framework.Configuration;
using EPiServer.Logging;
using EPiServer.Web.Routing;
using ImageProcessor.Configuration;
using ImageProcessor.Imaging.Formats;
using ImageProcessor.Web.Caching;

namespace ImageProcessor.Web.Episerver
{
    /// <summary>
    /// Provides an <see cref="IImageCache"/> implementation that uses the configured Episerver Blob storage.
    /// The cache is self healing and cleaning.
    /// </summary>
    public class FileBlobCache : ImageCacheBase
    {
        /// <summary>
        /// Use the configured logging mechanism
        /// </summary>
        private static readonly ILogger logger = LogManager.GetLogger();

        /// <summary>
        /// Used to lock against when checking the cached folder path.
        /// </summary>
        private static object cachePathValidatorLock = new object();

        /// <summary>
        /// Whether the cached path has been checked.
        /// </summary>
        private static bool cachePathValidatorCheck;

        /// <summary>
        /// Stores the resulting validated absolute cache folder path
        /// </summary>
        private static string validatedAbsoluteCachePath;

        /// <summary>
        /// Stores the resulting validated virtual cache folder path - if it's within the web root
        /// </summary>
        private static string validatedVirtualCachePath;
        /// <summary>
        /// The virtual cache path.
        /// </summary>
        private readonly string virtualCachePath;

        /// <summary>
        /// The absolute path to virtual cache path on the server.
        /// </summary>
        private readonly string absoluteCachePath;

        /// <summary>
        /// The virtual path to the cached file.
        /// </summary>
        private string virtualCachedFilePath;

        /// <summary>
        /// The container where the blob is stored in.
        /// </summary>
        private string container;

        /// <summary>
        /// The cached generated filename
        /// </summary>
        private string cachedFilename;

        /// <summary>
        /// The create time of the cached image
        /// </summary>
        private DateTime cachedImageCreationTimeUtc = DateTime.MinValue;

        private const string prefix = "3p!_";

        /// <summary>
        /// Initializes a new instance of the <see cref="FileBlobCache"/> class.
        /// </summary>
        /// <param name="requestPath">
        /// The request path for the image.
        /// </param>
        /// <param name="fullPath">
        /// The full path for the image.
        /// </param>
        /// <param name="querystring">
        /// The querystring containing instructions.
        /// </param>
        public FileBlobCache(string requestPath, string fullPath, string querystring)
            : base(requestPath, fullPath, querystring)
        {
            string basePath = (EPiServerFrameworkSection.Instance.AppData.BasePath.IndexOf(@"\\") == 0 || EPiServerFrameworkSection.Instance.AppData.BasePath.StartsWith(@"..\") || EPiServerFrameworkSection.Instance.AppData.BasePath.Contains(":\\"))
                                        ? EPiServerFrameworkSection.Instance.AppData.BasePath
                                        : "~/" + EPiServerFrameworkSection.Instance.AppData.BasePath;

            string configuredPath = Settings.ContainsKey("VirtualCachePath")
                                        ? Settings["VirtualCachePath"]
                                        : basePath + "/blobs";

            absoluteCachePath = GetAbsolutePath(configuredPath, out virtualCachePath);
        }

        /// <summary>
        /// Gets a value indicating whether the image is new or updated in an asynchronous manner.
        /// </summary>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        public override async Task<bool> IsNewOrUpdatedAsync()
        {
{'fraction_non_alphanumeric': 0.10944686873452059, 'fraction_numerical': 0.00047175374454534735, 'mean_word_length': 1.9444444444444444, 'pattern_counts': {'":': 2, '<': 83, '<?xml version=': 0, '>': 83, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 16, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2973742', 'n_tokens_mistral': 2027, 'n_tokens_neox': 1973, 'n_words': 631}