예제 #1
0
        public static void SetPath(this IFileRef self, FileEntry file)
        {
            UPath value = file.Path;

            self.dir      = "" + value.GetDirectory();
            self.fileName = value.GetName();
        }
예제 #2
0
        private static bool IsAlreadyDownloaded(this IFileRef self, Headers headers, FileEntry targetFile)
        {
            if (targetFile.Exists)
            {
                // Cancel download if etag header matches the locally stored one:
                if (self.HasMatchingChecksum(headers.GetEtagHeader()))
                {
                    return(true);
                }
                // Cancel download if local file with the same MD5 hash exists:
                var onlineMD5 = headers.GetMD5Checksum();
                if (!onlineMD5.IsNullOrEmpty())
                {
                    if (self.HasMatchingChecksum(onlineMD5))
                    {
                        return(true);
                    }
                    if (onlineMD5 == targetFile.CalcFileMd5Hash())
                    {
                        return(true);
                    }
                    return(false);
                }

                /*
                 * // Cancel download if local file with the exact last-write timestamp exists:
                 * if (headers.GetRawLastModifiedString() != null) {
                 *  var distance = headers.GetLastModifiedUtcDate(DateTime.MinValue) - targetFile.LastWriteTime.ToUniversalTime();
                 *  Log.d("distance.Milliseconds: " + distance.Milliseconds);
                 *  if (distance.Milliseconds == 0) { return true; }
                 * }
                 */
            }
            return(false);
        }
예제 #3
0
        public static async Task <bool> DownloadTo(this IFileRef self, RestRequest request, DirectoryEntry targetDir)
        {
            var fileName   = CalculateFileName(self, await request.GetResultHeaders());
            var targetFile = targetDir.GetChild(EnvironmentV2.SanatizeToFileName(fileName));

            return(await self.DownloadTo(request, targetFile));
        }
예제 #4
0
 public static DirectoryEntry GetDirectoryEntry(this IFileRef self, IFileSystem fs)
 {
     if (self.dir.IsNullOrEmpty())
     {
         throw new InvalidDataException("IFileRef.dir not set");
     }
     return(new DirectoryEntry(fs, self.dir));
 }
예제 #5
0
 private static void AddCheckSum(this IFileRef self, string type, string hash)
 {
     hash.ThrowErrorIfNull($"The passed {type}-hash was null");
     if (self.checksums == null)
     {
         self.checksums = new Dictionary <string, object>();
     }
     self.checksums.Add(type, hash);
 }
예제 #6
0
 private static void AssertValidDirectory(this IFileRef self, DirectoryEntry targetDirectory)
 {
     if (!targetDirectory.IsNotNullAndExists())
     {
         throw new ArgumentException("Cant download into non existing directory=" + targetDirectory);
     }
     if (self.dir != null && targetDirectory.FullName != self.dir)
     {
         throw new ArgumentException($"Dir already set, wont change from '{self.dir}' to '{targetDirectory}'");
     }
 }
예제 #7
0
        public static async Task <bool> DownloadTo(this IFileRef self, DirectoryEntry targetDirectory, Action <float> onProgress = null)
        {
            self.AssertValidDirectory(targetDirectory);
            RestRequest request = new Uri(self.url).SendGET();

            if (onProgress != null)
            {
                request.onProgress = onProgress;
            }
            return(await self.DownloadTo(request, targetDirectory));
        }
        private static async Task <bool> TestDownloadTo(IFileRef f, DirectoryEntry targetDirectory)
        {
            var t = Log.MethodEntered("Download", f.url, targetDirectory.GetFullFileSystemPath());
            var downloadWasNeeded = await f.DownloadTo(targetDirectory);

            Log.MethodDone(t);
            Assert.NotNull(f.dir);
            Assert.NotNull(f.fileName);
            Assert.NotNull(f.url);
            return(downloadWasNeeded);
        }
예제 #9
0
        public static async Task <Texture2D> LoadAndPersistTo(IFileRef imgRef, DirectoryEntry targetDir, int thumbnailPixelWidth, Action <Texture2D> showTexture)
        {
            Texture2D tempThumbTexture = null;

            if (imgRef.fileName != null)   // Try load local thumbnail as quick as possible:
            {
                var i = targetDir.GetChild(imgRef.fileName);
                var t = i.Parent.GetChild(i.NameWithoutExtension + ".thm");
                tempThumbTexture = await LoadThumbnailIfFound(showTexture, t, tempThumbTexture);
            }

            var fileWasDownloaded = await imgRef.DownloadTo(targetDir, useAutoCachedFileRef : true);

            var       imageFile     = imgRef.GetFileEntry(targetDir.FileSystem);
            FileEntry thumbnailFile = GetThumbnailFile(imgRef, targetDir);

            if (!fileWasDownloaded && tempThumbTexture == null)
            {
                // If there was no new file downloaded and the thumbnail is available and not loaded yet:
                tempThumbTexture = await LoadThumbnailIfFound(showTexture, thumbnailFile, tempThumbTexture);
            }
            if (!imageFile.Exists)
            {
                return(null);
            }

            // Load the full image as a texture and show it in the UI:
            Texture2D texture2d = await imageFile.LoadTexture2D();

            showTexture(texture2d);
            if (tempThumbTexture != null)
            {
                tempThumbTexture.Destroy(true);
            }

            if (fileWasDownloaded || !thumbnailFile.Exists)   // Store a thumbnail file if needed:
            {
                Texture2D thumbnail = texture2d.CopyTexture();
                thumbnail.ResizeV2(thumbnailPixelWidth);
                if (imgRef.IsJpgFile())
                {
                    thumbnail.SaveToJpgFile(thumbnailFile);
                }
                else
                {
                    thumbnail.SaveToPngFile(thumbnailFile);
                }

                thumbnail.Destroy(true);
            }
            return(texture2d);
        }
예제 #10
0
        public static async Task <bool> DownloadTo(this IFileRef self, RestRequest request, FileEntry targetFile)
        {
            var headers = await request.GetResultHeaders();

            if (self.IsAlreadyDownloaded(headers, targetFile))
            {
                return(false);
            }
            await request.DownloadTo(targetFile);

            self.CheckMD5AfterDownload(headers, targetFile);
            self.SetLocalFileInfosFrom(headers, targetFile);
            return(true);
        }
예제 #11
0
 public static bool IsJpgFile(this IFileRef self)
 {
     if (!self.mimeType.IsNullOrEmpty())
     {
         return(self.mimeType == "image/jpeg");
     }
     if (!self.fileName.IsNullOrEmpty())
     {
         bool endsWithJpg  = self.fileName.EndsWith(".jpg");
         bool endsWithJpeg = self.fileName.EndsWith(".jpeg");
         return(endsWithJpg || endsWithJpeg);
     }
     Log.e("Could not resolve if image is of type jpg");
     return(false);
 }
예제 #12
0
 private static void SetLocalFileInfosFrom(this IFileRef self, Headers headers, FileEntry targetFile)
 {
     self.AssertValidDirectory(targetFile.Parent);
     self.dir      = targetFile.Parent.FullName;
     self.fileName = targetFile.Name;
     self.mimeType = headers.GetContentMimeType(null);
     if (headers.GetRawLastModifiedString() != null)
     {
         targetFile.LastWriteTime = headers.GetLastModifiedUtcDate(DateTime.MinValue);
     }
     if (headers.GetEtagHeader() != null)
     {
         self.AddCheckSum(CHECKSUM_ETAG, headers.GetEtagHeader());
     }
 }
예제 #13
0
        private static FileEntry LoadAutoCachedFileRef(this IFileRef self, DirectoryEntry targetDirectory, bool useAutoCachedFileRef)
        {
            self.url.ThrowErrorIfNullOrEmpty("IFileRef.url");
            var cachedFile = targetDirectory.GetChild("fileRef-" + self.url.GetMD5Hash() + ".json");

            if (cachedFile.IsNotNullAndExists())
            {
                if (!useAutoCachedFileRef)
                {
                    Log.w("A file exists that seems to contain the fileRef details but it will not be used");
                    return(null);
                }
                FillFileRefValuesFrom(cachedFile, self);
            }
            return(cachedFile);
        }
예제 #14
0
        private static bool CheckMD5AfterDownload(this IFileRef self, Headers headers, FileEntry targetFile)
        {
            var onlineMD5 = headers.GetMD5Checksum();

            if (onlineMD5.IsNullOrEmpty())
            {
                return(false);
            }
            string localMD5 = targetFile.CalcFileMd5Hash();

            if (localMD5 == onlineMD5)
            {
                throw new InvalidDataException($"Missmatch in MD5 hashes, local={localMD5} & online={onlineMD5}");
            }
            self.AddCheckSum(CHECKSUM_MD5, localMD5);
            return(true);
        }
예제 #15
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="self"></param>
        /// <param name="targetDirectory"></param>
        /// <param name="onProgress"> A float from 0 to 100 </param>
        /// <param name="useAutoCachedFileRef"> If true the fileRef will create itself a cache file in the targetDirectory </param>
        /// <returns></returns>
        public static async Task <bool> DownloadTo(this IFileRef self, DirectoryEntry targetDirectory, Action <float> onProgress = null, bool useAutoCachedFileRef = false, int maxNrOfRetries = 4)
        {
            self.AssertValidDirectory(targetDirectory);
            FileEntry   cachedFileRef = self.LoadAutoCachedFileRef(targetDirectory, useAutoCachedFileRef);
            RestRequest request       = new Uri(self.url).SendGET();

            if (onProgress != null)
            {
                request.onProgress = onProgress;
            }
            bool downloadWasNeeded = await self.DownloadTo(request, targetDirectory, maxNrOfRetries);

            if (useAutoCachedFileRef)
            {
                cachedFileRef.SaveAsJson(self, true);
            }
            return(downloadWasNeeded);
        }
예제 #16
0
        private static string CalculateFileName(IFileRef self, Headers headers)
        {
            if (!self.fileName.IsNullOrEmpty())
            {
                return(self.fileName);
            }
            var nameOnServer = headers.GetFileNameOnServer();

            if (!nameOnServer.IsNullOrEmpty())
            {
                return(nameOnServer);
            }
            var hashedHeaders = headers.GenerateHashNameFromHeaders();

            if (!hashedHeaders.IsNullOrEmpty())
            {
                return(hashedHeaders);
            }
            return(self.url.GetMD5Hash());
        }
예제 #17
0
 private static void FillFileRefValuesFrom(FileEntry source, IFileRef targetToFill)
 {
     try {
         var loaded = source.LoadAs(targetToFill.GetType()) as IFileRef;
         if (targetToFill.dir.IsNullOrEmpty())
         {
             targetToFill.dir = loaded.dir;
         }
         if (targetToFill.fileName.IsNullOrEmpty())
         {
             targetToFill.fileName = loaded.fileName;
         }
         if (targetToFill.checksums.IsNullOrEmpty())
         {
             targetToFill.checksums = loaded.checksums;
         }
         if (targetToFill.mimeType.IsNullOrEmpty())
         {
             targetToFill.mimeType = loaded.mimeType;
         }
     } catch (Exception e) { Log.e(e); }
 }
예제 #18
0
        public static async Task <bool> DownloadTo(this IFileRef self, RestRequest request, DirectoryEntry targetDir, int maxNrOfRetries)
        {
            self.AssertValidDirectory(targetDir);
            var  fileName   = CalculateFileName(self, await request.GetResultHeaders());
            var  targetFile = targetDir.GetChild(fileName);
            bool downloadWasNeeded;

            if (maxNrOfRetries == 0)
            {
                downloadWasNeeded = await self.DownloadTo(request, targetFile);
            }
            else
            {
                int initialExponent = 9; // 2^9 = 512ms (for first delay if fails)
                downloadWasNeeded = await TaskV2.TryWithExponentialBackoff(async() => {
                    return(await self.DownloadTo(request, targetFile));
                }, maxNrOfRetries : maxNrOfRetries, initialExponent : initialExponent);
            }
            if (self.fileName.IsNullOrEmpty() && targetFile.Exists)
            {
                throw new MissingFieldException("IFileRef.fileName not set after successful download, must not happen!");
            }
            return(downloadWasNeeded);
        }
예제 #19
0
        private static FileEntry GetThumbnailFile(IFileRef self, DirectoryEntry targetDir)
        {
            var imageFile = self.GetFileEntry(targetDir.FileSystem);

            return(imageFile.Parent.GetChild(imageFile.NameWithoutExtension + ".thm"));
        }
예제 #20
0
 /// <summary> Downloads and shows the passed IFileRef and if a local thumbnail exists first loads the
 /// thumbnail as a placeholder which is especially helpful when loading larger images </summary>
 /// <param name="imgRef"> The IFileRef that contains the url and target dir </param>
 /// <param name="targetDir"> The directory that should be used to download to </param>
 /// <param name="thumbnailPixelWidth"> The pixel width of the automatic thumbnail, e.g 256 </param>
 /// <returns> The loaded Texture2D of the image </returns>
 public static async Task <Texture2D> LoadAndPersistTo(this Renderer self, IFileRef imgRef, DirectoryEntry targetDir, int thumbnailPixelWidth)
 {
     return(await LoadAndPersistTo(imgRef, targetDir, thumbnailPixelWidth, (tex2d) => self.material.mainTexture = tex2d));
 }
예제 #21
0
 public static FileEntry GetFileEntry(this IFileRef self, IFileSystem fs)
 {
     return(self.GetDirectoryEntry(fs).GetChild(self.fileName));
 }
예제 #22
0
 public static UPath GetPath(this IFileRef self)
 {
     return((UPath)self.dir / self.fileName);
 }
예제 #23
0
 /// <summary> Downloads and shows the passed IFileRef and if a local thumbnail exists first loads the
 /// thumbnail as a placeholder which is especially helpful when loading larger images </summary>
 /// <param name="imgRef"> The IFileRef that contains the url and target dir </param>
 /// <param name="targetDir"> The directory that should be used to download to </param>
 /// <param name="thumbnailPixelWidth"> The pixel width of the automatic thumbnail, e.g 256 </param>
 /// <returns> The loaded Texture2D of the image </returns>
 public static async Task <Texture2D> LoadAndPersistTo(this Image self, IFileRef imgRef, DirectoryEntry targetDir, int thumbnailPixelWidth)
 {
     return(await LoadAndPersistTo(imgRef, targetDir, thumbnailPixelWidth, (tex2d) => self.sprite = tex2d.ToSprite()));
 }
예제 #24
0
 private static bool HasMatchingChecksum(this IFileRef self, string hash)
 {
     return(!hash.IsNullOrEmpty() && self.checksums != null && self.checksums.Any(x => {
         return hash.Equals(x.Value);
     }));
 }