コード例 #1
0
        public static async Task <bool> UpgradeAsync(CancellationToken cancellationToken)
        {
            await using (var db = new BotDb())
                if (!await UpgradeAsync(db, Config.Cts.Token))
                {
                    return(false);
                }

            await using (var db = new ThumbnailDb())
            {
                if (!await UpgradeAsync(db, Config.Cts.Token))
                {
                    return(false);
                }

                if (!await ImportNamesPool(db, Config.Cts.Token))
                {
                    return(false);
                }
            }

            return(true);
        }
コード例 #2
0
        private static async Task <bool> ImportNamesPool(ThumbnailDb db, CancellationToken cancellationToken)
        {
            Config.Log.Debug("Importing name pool...");
            var rootDir = Environment.CurrentDirectory;

            while (rootDir is not null && !Directory.EnumerateFiles(rootDir, "names_*.txt", SearchOption.TopDirectoryOnly).Any())
            {
                rootDir = Path.GetDirectoryName(rootDir);
            }
            if (rootDir is null)
            {
                Config.Log.Error("Couldn't find any name sources");
                return(db.NamePool.Any());
            }

            var resources = Directory.GetFiles(rootDir, "names_*.txt", SearchOption.TopDirectoryOnly)
                            .OrderBy(f => f)
                            .ToList();

            if (resources.Count == 0)
            {
                Config.Log.Error("Couldn't find any name sources (???)");
                return(db.NamePool.Any());
            }

            var timestamp = -1L;

            using (var sha256 = System.Security.Cryptography.SHA256.Create())
            {
                byte[] buf;
                foreach (var path in resources)
                {
                    var fileInfo = new FileInfo(path);
                    buf = BitConverter.GetBytes(fileInfo.Length);
                    sha256.TransformBlock(buf, 0, buf.Length, null, 0);
                }
                buf       = Encoding.UTF8.GetBytes(Config.RenameNameSuffix);
                buf       = sha256.TransformFinalBlock(buf, 0, buf.Length);
                timestamp = BitConverter.ToInt64(buf, 0);
            }

            const string renameStateKey = "rename-name-pool";
            var          stateEntry     = db.State.FirstOrDefault(n => n.Locale == renameStateKey);

            if (stateEntry?.Timestamp == timestamp)
            {
                Config.Log.Info("Name pool is up-to-date");
                return(true);
            }

            Config.Log.Info("Updating name pool...");
            try
            {
                var names = new HashSet <string>();
                foreach (var resourcePath in resources)
                {
                    await using var stream = File.Open(resourcePath, FileMode.Open, FileAccess.Read, FileShare.Read);
                    using var reader       = new StreamReader(stream);
                    while (await reader.ReadLineAsync().ConfigureAwait(false) is string line)
                    {
                        if (line.Length < 2 || line.StartsWith("#"))
                        {
                            continue;
                        }

                        var commentPos = line.IndexOf(" (");
                        if (commentPos > 1)
                        {
                            line = line.Substring(0, commentPos);
                        }
                        line = line.Trim()
                               .Replace("  ", " ")
                               .Replace('`', '\'') // consider ’
                               .Replace("\"", "\\\"");
                        if (line.Length + Config.RenameNameSuffix.Length > 32)
                        {
                            continue;
                        }

                        if (line.Contains('@') ||
                            line.Contains('#') ||
                            line.Contains(':'))
                        {
                            continue;
                        }

                        names.Add(line);
                    }
                }
                await using var tx = await db.Database.BeginTransactionAsync(cancellationToken).ConfigureAwait(false);

                db.NamePool.RemoveRange(db.NamePool);
                foreach (var name in names)
                {
                    await db.NamePool.AddAsync(new() { Name = name }, cancellationToken).ConfigureAwait(false);
                }
                if (stateEntry is null)
                {
                    await db.State.AddAsync(new() { Locale = renameStateKey, Timestamp = timestamp }, cancellationToken).ConfigureAwait(false);
                }
                else
                {
                    stateEntry.Timestamp = timestamp;
                }
                await db.SaveChangesAsync(cancellationToken).ConfigureAwait(false);

                await tx.CommitAsync(cancellationToken).ConfigureAwait(false);

                return(names.Count > 0);
            }
            catch (Exception e)
            {
                Config.Log.Error(e);
                return(false);
            }
        }