예제 #1
0
        public Deck Deserialize(FsPath file, FsPath dir)
        {
            State.LastLoadedFile = file;

            Deck deck = Deck.Create();

            deck.File = file;

            int  maxLen = 0x8000000;            // 128 MB
            long length = file.File().Length;

            if (length > maxLen)
            {
                deck.Error = $"File size {length} bytes exceeds maximum of {maxLen} bytes";
                return(deck);
            }

            string serialized;

            try
            {
                serialized = file.ReadAllText();
            }
            catch (IOException ex)
            {
                deck.Error = ex.Message;
                return(deck);
            }

            var format = @"*" + file.Extension();

            var formatter = getFormatter(format, serialized);

            if (formatter == null)
            {
                deck.Error = "Deck format is not supported";
                return(deck);
            }

            deck = LoadSerialized(format, serialized, exact: false);

            deck.File = file;

            if (deck.Name == null)
            {
                string getNestedFileName() =>
                dir.Base().Join(file.RelativeTo(dir)).Value
                .Replace(new string(Path.DirectorySeparatorChar, 1), Environment.NewLine);

                var extension = file.Extension();

                string nameBase = !dir.HasValue()
                                        ? file.Basename()
                                        : getNestedFileName();

                deck.Name = nameBase.Substring(0, nameBase.Length - extension.Length);
            }

            return(deck);
        }
예제 #2
0
        public void SignImages(string setCodesStr, bool small, bool zoom, bool nonToken, bool token)
        {
            foreach (FsPath qualityDir in getQualities(small, zoom))
            {
                foreach ((_, _, FsPath tokenSuffix) in getIsToken(nonToken, token))
                {
                    FsPath outputFile  = getSignatureFile(qualityDir, tokenSuffix);
                    FsPath packagePath = TargetDir.Join(qualityDir).Concat(tokenSuffix);
                    new ImageDirectorySigner().SignFiles(packagePath, outputFile, setCodesStr);

                    FsPath signatureFile           = getSignatureFile(qualityDir, tokenSuffix);
                    FsPath compressedSignatureFile = signatureFile
                                                     .Parent()
                                                     .Join(signatureFile.Basename(extension: false))
                                                     .Concat(SevenZipExtension);

                    if (compressedSignatureFile.IsFile())
                    {
                        compressedSignatureFile.DeleteFile();
                    }

                    new SevenZip(false).Compress(signatureFile, compressedSignatureFile)
                    .Should().BeTrue();
                }
            }
        }
예제 #3
0
        private void load(FsPath fileName)
        {
            string serialized;

            try
            {
                serialized = fileName.ReadAllText();
            }
            catch (Exception ex)
            {
                _log.Error(ex);
                MessageBox.Show($"Failed to open `{fileName}`, {ex}");
                return;
            }

            ReportSettings settings;

            try
            {
                settings = JsonConvert.DeserializeObject <ReportSettings>(serialized);
            }
            catch (Exception ex)
            {
                _log.Error(ex);
                MessageBox.Show($"Failed to read chart from `{fileName}`, {ex}");
                return;
            }

            _formChart.Title = fileName.Basename(extension: false);
            _formChart.LoadSavedChart(settings);
        }
예제 #4
0
        public void RenameWizardsWebpageImages(string htmlFile, string targetSubdir)
        {
            FsPath htmlPath  = HtmlDir.Join(htmlFile);
            FsPath targetDir = DevPaths.GathererOriginalDir.Join(targetSubdir);

            string htmlFileName  = htmlPath.Basename(extension: false);
            FsPath directoryName = htmlPath.Parent();

            if (!directoryName.HasValue())
            {
                throw new ArgumentException(htmlPath.Value, nameof(htmlPath));
            }

            FsPath filesDirectory = directoryName.Join(htmlFileName + "_files");

            string content = htmlPath.ReadAllText();
            var    matches = _imgTagPattern.Matches(content);

            targetDir.CreateDirectory();
            foreach (Match match in matches)
            {
                string originalFileName = match.Groups["file"].Value;
                string ext = Path.GetExtension(originalFileName);

                FsPath filePath = filesDirectory.Join(originalFileName);

                string name = HttpUtility.HtmlDecode(match.Groups["name"].Value)
                              .Replace(" // ", "");

                FsPath defaultTargetPath = targetDir.Join(name + ext);

                bool defaultTargetExists = defaultTargetPath.IsFile();

                if (defaultTargetExists || getTargetPath(1).IsFile())
                {
                    if (defaultTargetExists)
                    {
                        defaultTargetPath.MoveFileTo(getTargetPath(1));
                    }

                    for (int i = 2; i < 12; i++)
                    {
                        FsPath targetPath = getTargetPath(i);
                        if (!targetPath.IsFile())
                        {
                            filePath.CopyFileTo(targetPath, overwrite: false);
                            break;
                        }
                    }
                }
                else
                {
                    filePath.CopyFileTo(defaultTargetPath, overwrite: false);
                }

                FsPath getTargetPath(int num) =>
                targetDir.Join(name + num + ext);
            }
        }
예제 #5
0
        private void convertToJpg(FsPath sourceImage, FsPath targetDir, bool isZoomDir)
        {
            FsPath targetImage = targetDir.Join(sourceImage.Basename(extension: false)).Concat(".jpg");

            if (_keepExisting && targetImage.IsFile() && (isZoomed(targetImage) || !isZoomDir))
            {
                return;
            }

            using var original = new Bitmap(sourceImage.Value);
            new BmpAlphaToBackgroundColorTransformation(original, Color.White)
            .Execute();

            original.Save(targetImage.Value, _jpegCodec, _jpegEncoderParams);
        }
예제 #6
0
        // ReSharper restore StringLiteralTypo
        public void Resample()
        {
            FsPath file      = DevPaths.XlhqDir.Join("XLN - Ixalan", "300DPI Cards", "Adanto, the First Fort.xlhq.jpg");
            string name      = file.Basename(extension: false);
            FsPath targetDir = DevPaths.DataDrive.Join("temp", "img");

            using (var image = new MagickImage(file.Value))
            {
                image.Resize(new Percentage(50));
                image.Write(targetDir.Join(name).Concat("resized.jpg").Value);
            }

            using (var image = new MagickImage(file.Value))
            {
                image.Scale(new Percentage(50));
                image.Write(targetDir.Join(name).Concat("scaled.jpg").Value);
            }
        }
예제 #7
0
        public ImageFile(
            FsPath fileName, FsPath rootPath, string setCode = null, string artist = null,
            bool isArt = false, int?customPriority = null)
        {
            var    fileNameWithoutExtension = fileName.Basename(extension: false);
            FsPath directoryName            = fileName.Parent();

            FullPath = fileName;

            string[] parts        = fileNameWithoutExtension.Split(Sequence.Array('.'), StringSplitOptions.None);
            var      lastNamePart = Enumerable.Range(0, parts.Length)
                                    .Last(i =>
                                          i == 0 ||
                                          // Richard Garfield, Ph.D..xlhq.jpg
                                          // S.N.O.T..xlhq.jpg
                                          // Our Market Research....xlhq.jpg
                                          parts[i].Length <= 1 ||
                                          // Sarpadian Empires, Vol. VII.xlhq.jpg
                                          // Но Thoughtseize.[Size 16x20].jpg
                                          parts[i].Contains(' ') && !(parts[i].StartsWith("[") && parts[i].EndsWith("]")));

            Type = string.Join(".", parts.Skip(1 + lastNamePart));

            string imageNameRaw = string.Join(".", parts.Take(1 + lastNamePart));
            var    imageName    = _patternToRemove.Replace(imageNameRaw, string.Empty);
            var    replacedName = _nameReplacements.TryGet(imageName) ?? imageName;

            ImageName = string.Intern(replacedName);

            var nameParts = ImageName.SplitTailingNumber();

            Name          = string.Intern(nameParts.Item1);
            VariantNumber = nameParts.Item2;

            rootPath = rootPath.ToAppRootedPath();

            if (setCode != null)
            {
                SetCode = string.Intern(setCode);
                SetCodeIsFromAttribute = true;
            }
            else
            {
                var setCodeMatch = _setCodeRegex.Match(directoryName.RelativeTo(rootPath).Value);
                if (setCodeMatch.Success)
                {
                    SetCode = string.Intern(setCodeMatch.Value.ToUpperInvariant());
                }
                else
                {
                    SetCode = string.Empty;
                }
            }

            Priority = customPriority ?? getPriority();

            if (artist != null)
            {
                Artist = string.Intern(artist);
            }

            IsArt   = isArt;
            IsToken = directoryName.Value.IndexOf("Token", Str.Comparison) >= 0;
        }
예제 #8
0
        public async Task DownloadGathererImages(string setCodesStr, bool nonToken, bool token)
        {
            var clients = new List <ImageDownloaderBase>(2)
            {
                // new GathererClient(),
                new ScryfallClient(),
            };

            var setCodes = setCodesStr?.Split(',').ToHashSet(StringComparer.OrdinalIgnoreCase);
            var repo     = new CardRepository(new CardFormatter(), () => null)
            {
                FilterSetCode = setCode => setCodes?.Contains(setCode) != false,
            };

            repo.LoadFile();
            repo.Load();

            foreach (Set set in repo.SetsByCode.Values)
            {
                if (setCodes?.Contains(set.Code) == false)
                {
                    continue;
                }

                foreach ((bool isToken, FsPath typeSubdir, _) in getIsToken(nonToken, token))
                {
                    var cards = set.List(isToken);
                    if (cards.Count == 0)
                    {
                        continue;
                    }

                    var missingCardsByClient = clients.ToDictionary(_ => _, _ => 0);

                    FsPath setSubdir        = new FsPath(set.Code + (Str.Equals(set.Code, "con") ? " escape" : string.Empty));
                    FsPath downloadRootDir  = DevPaths.MtgContentDir.Join(_createZoom ? OriginalSubdir : PreProcessedSubdir);
                    FsPath rootDirZoom      = DevPaths.MtgContentDir.Join(PreProcessedSubdir);
                    FsPath setDirectory     = downloadRootDir.Join(typeSubdir, setSubdir);
                    FsPath setDirectoryZoom = rootDirZoom.Join(typeSubdir, setSubdir);
                    FsPath setDirectoryPng  = setDirectory.Concat(".png");

                    bool dirExisted = setDirectoryPng.IsDirectory();
                    if (!dirExisted)
                    {
                        setDirectoryPng.CreateDirectory();
                    }

                    foreach (var card in cards)
                    {
                        FsPath targetFile        = setDirectoryPng.Join(card.ImageName + ".png");
                        FsPath processedFile     = setDirectory.Join(card.ImageName + ".jpg");
                        FsPath processedFileZoom = setDirectoryZoom.Join(card.ImageName + ".jpg");
                        if (targetFile.IsFile() || processedFile.IsFile() && processedFileZoom.IsFile())
                        {
                            continue;
                        }

                        if (targetFile.Basename(extension: false).EndsWith("1"))
                        {
                            var unnumbered = targetFile.WithName(_ => _.Replace("1.png", ".png"));
                            if (unnumbered.IsFile())
                            {
                                unnumbered.MoveFileTo(targetFile);
                                continue;
                            }
                        }

                        foreach (ImageDownloaderBase client in clients)
                        {
                            int attempts = 5;

                            for (int i = 0; i < attempts; i++)
                            {
                                var cancellation = new CancellationTokenSource();
                                var time         = DateTime.UtcNow;

                                var downloadTask = client.DownloadCardImage(card, targetFile, cancellation.Token);
                                var waitTask     = Task.Delay(TimeSpan.FromSeconds(5), cancellation.Token);

                                await Task.WhenAny(downloadTask, waitTask);

                                cancellation.Cancel();

                                var elapsed = DateTime.UtcNow - time;
                                var delta   = TimeSpan.FromSeconds(0.5) - elapsed;
                                if (delta.TotalSeconds > 0)
                                {
                                    await Task.Delay(delta);
                                }

                                if (targetFile.IsFile())
                                {
                                    break;
                                }
                            }

                            if (targetFile.IsFile())
                            {
                                break;
                            }

                            missingCardsByClient[client]++;
                        }
                    }

                    if (!dirExisted && !setDirectoryPng.EnumerateFiles().Any())
                    {
                        setDirectoryPng.DeleteDirectory();
                    }
                }
            }
        }
예제 #9
0
        public void PreProcessImages(string setCodesStr, bool nonToken, bool token)
        {
            setupImageConversion();

            FsPath smallDir    = DevPaths.GathererOriginalDir;
            FsPath zoomDir     = DevPaths.GathererPreprocessedDir;
            FsPath smallDirBak = BakDir.Join(smallDir.Basename());
            FsPath zoomDirBak  = BakDir.Join(zoomDir.Basename());

            var setCodes = setCodesStr?.Split(',').ToHashSet(StringComparer.OrdinalIgnoreCase);

            IEnumerable <FsPath> getSetSubdirs(FsPath typeSubdir)
            {
                FsPath typeDir = smallDir.Join(typeSubdir);

                return(typeDir
                       .EnumerateDirectories(_fromPng ? "*.png" : "*", SearchOption.TopDirectoryOnly)
                       .Select(_ => new FsPath(
                                   Regex.Replace(
                                       _.Basename(),
                                       @"\.png$",
                                       string.Empty))));
            }

            foreach ((_, FsPath typeSubdir, _) in getIsToken(nonToken, token))
            {
                foreach (FsPath setSubdir in getSetSubdirs(typeSubdir))
                {
                    if (setCodes?.Contains(setSubdir.Value) == false)
                    {
                        continue;
                    }

                    FsPath smallJpgDir = smallDir.Join(typeSubdir, setSubdir);
                    FsPath zoomJpgDir  = zoomDir.Join(typeSubdir, setSubdir);

                    if (!_fromPng)
                    {
                        if (!_createZoom)
                        {
                            return;
                        }

                        zoomJpgDir.CreateDirectory();
                        foreach (FsPath smallImg in smallJpgDir.EnumerateFiles())
                        {
                            FsPath zoomImg = smallImg.ChangeDirectory(smallDir, zoomDir);
                            if (_keepExisting && zoomImg.IsFile() && isZoomed(zoomImg))
                            {
                                continue;
                            }

                            scale(smallImg, zoomImg);
                        }
                    }
                    else
                    {
                        FsPath setPngSubdir   = setSubdir.Concat(".png");
                        FsPath smallPngDir    = smallDir.Join(typeSubdir, setPngSubdir);
                        FsPath smallPngDirBak = smallDirBak.Join(typeSubdir, setPngSubdir);
                        FsPath zoomPngDir     = zoomDir.Join(typeSubdir, setPngSubdir);
                        FsPath zoomPngDirBak  = zoomDirBak.Join(typeSubdir, setPngSubdir);

                        var dirs = new List <(FsPath pngDir, FsPath pngDirBak, FsPath jpgDir, bool isZoom)>();
                        if (_createZoom)
                        {
                            zoomPngDir.CreateDirectory();
                            foreach (FsPath smallImg in smallPngDir.EnumerateFiles())
                            {
                                FsPath zoomImg      = smallImg.ChangeDirectory(smallDir, zoomDir);
                                FsPath convertedImg = zoomImg.ChangeDirectory(zoomPngDir, zoomJpgDir)
                                                      .WithName(_ => _.Replace(".png", ".jpg"));

                                if (_keepExisting && (
                                        zoomImg.IsFile() && isZoomed(zoomImg) ||
                                        convertedImg.IsFile() && isZoomed(convertedImg)))
                                {
                                    continue;
                                }

                                scale(smallImg, zoomImg);
                            }

                            dirs.Add((pngDir: zoomPngDir, pngDirBak: zoomPngDirBak, jpgDir: zoomJpgDir, isZoom: true));
                        }

                        dirs.Add((pngDir: smallPngDir, pngDirBak: smallPngDirBak, jpgDir: smallJpgDir, isZoom: false));

                        foreach ((FsPath pngDir, FsPath pngDirBak, FsPath jpgDir, bool isZoom) in dirs)
                        {
                            jpgDir.CreateDirectory();

                            var pngImages = pngDir.EnumerateFiles();
                            foreach (FsPath sourceImage in pngImages)
                            {
                                convertToJpg(sourceImage, jpgDir, isZoom);
                            }

                            moveDirectoryToBackup(pngDir, pngDirBak);
                        }
                    }
                }
            }
        }
예제 #10
0
 private FsPath getReadNewsFile(FsPath file)
 {
     return(_readNewsDir.Join(file.Basename()));
 }
예제 #11
0
        public void RenameImages(string setCodes)
        {
            var unnamedImagesDirectory = DevPaths.GathererOriginalCardsDir.Join("iko");

            var fileNames =
                unnamedImagesDirectory.EnumerateFiles("*.jpg")
                .Concat(unnamedImagesDirectory.EnumerateFiles("*.png")).ToArray();

            var setCodesArr = setCodes.Split(';').ToHashSet(Str.Comparer);

            var repo = new CardRepository(new CardFormatter(), () => null)
            {
                FilterSetCode = setCodesArr.Contains
            };

            repo.LoadFile();
            repo.Load();

            // because we only have setCodes loaded to Repo
            var cardNames = repo.CardsByName.Keys.ToArray();

            float[] distances = new float[cardNames.Length];

            foreach (var fileName in fileNames)
            {
                var extension = fileName.Extension();
                var directory = fileName.Parent();

                var name = ocr(fileName, new Rectangle(20, 20, 170, 17));

                for (int i = 0; i < cardNames.Length; i++)
                {
                    distances[i] = _distance.GetPrefixDistance(name, cardNames[i]);
                }

                int indexOfMostSimilarName = Enumerable.Range(0, cardNames.Length)
                                             .AtMin(i => distances[i])
                                             .Find();

                float distance             = distances[indexOfMostSimilarName];
                var   invalidFileNameChars = Path.GetInvalidFileNameChars().ToHashSet();

                var mostSimilarName = distance <= (name.Length * 2f) * 0.4f
                                        ? cardNames[indexOfMostSimilarName]
                                        : new string(name.Select(c => invalidFileNameChars.Contains(c) ? '_' : c).ToArray());

                FsPath renamed = directory.Join(mostSimilarName + extension);

                if (renamed == fileName)
                {
                    continue;
                }

                int    suffix   = 0;
                string baseName = renamed.Basename(extension: false);

                while (renamed.IsFile())
                {
                    renamed = directory.Join(baseName + ++suffix + extension);
                }

                try
                {
                    fileName.MoveFileTo(renamed);
                }
                catch (IOException)
                {
                }
            }
        }