public override async Task <JobResult> Execute(SqlService sql, AppSettings settings)
        {
            using (var queue = new WorkQueue(4))
            {
                Utils.Log($"Indexing game files");
                var states = GameRegistry.Games.Values
                             .Where(game => game.TryGetGameLocation() != null && game.MainExecutable != null)
                             .SelectMany(game => game.GameLocation().EnumerateFiles()
                                         .Select(file => new GameFileSourceDownloader.State(game.InstalledVersion)
                {
                    Game     = game.Game,
                    GameFile = file.RelativeTo(game.GameLocation()),
                }))
                             .ToList();

                var pks = states.Select(s => s.PrimaryKeyString).ToHashSet();
                Utils.Log($"Found {pks.Count} archives to cross-reference with the database");

                var found = await sql.FilterByExistingPrimaryKeys(pks);

                states = states.Where(s => !found.Contains(s.PrimaryKeyString)).ToList();
                Utils.Log($"Found {states.Count} archives to index");

                await states.PMap(queue, async state =>
                {
                    var path = state.Game.MetaData().GameLocation().Combine(state.GameFile);
                    Utils.Log($"Hashing Game file {path}");
                    try
                    {
                        state.Hash = await path.FileHashAsync();
                    }
                    catch (IOException)
                    {
                        Utils.Log($"Unable to hash {path}");
                    }
                });

                var with_hash = states.Where(state => state.Hash != default).ToList();
                Utils.Log($"Inserting {with_hash.Count} jobs.");
                var jobs = states.Select(state => new IndexJob {
                    Archive = new Archive(state)
                    {
                        Name = state.GameFile.FileName.ToString()
                    }
                })
                           .Select(j => new Job {
                    Payload = j, RequiresNexus = j.UsesNexus
                })
                           .ToList();

                foreach (var job in jobs)
                {
                    await sql.EnqueueJob(job);
                }

                return(JobResult.Success());
            }
        }
示例#2
0
        public override async Task <JobResult> Execute(SqlService sql, AppSettings settings)
        {
            int retries = 0;

TOP:
            var file = await sql.UploadedFileById(FileId);

            if (settings.BunnyCDN_User == "TEST" && settings.BunnyCDN_Password == "TEST")
            {
                return(JobResult.Success());
            }

            using (var client = new FtpClient("storage.bunnycdn.com"))
            {
                client.Credentials = new NetworkCredential(settings.BunnyCDN_User, settings.BunnyCDN_Password);
                await client.ConnectAsync();

                using (var stream = File.OpenRead(Path.Combine("public", "files", file.MungedName)))
                {
                    try
                    {
                        await client.UploadAsync(stream, file.MungedName, progress : new Progress((RelativePath)file.MungedName));
                    }
                    catch (Exception ex)
                    {
                        if (retries > 10)
                        {
                            throw;
                        }
                        Utils.Log(ex.ToString());
                        Utils.Log("Retrying FTP Upload");
                        retries++;
                        goto TOP;
                    }
                }

                await sql.EnqueueJob(new Job
                {
                    Priority = Job.JobPriority.High,
                    Payload  = new IndexJob
                    {
                        Archive = new Archive(new HTTPDownloader.State(file.Uri))
                        {
                            Name = file.MungedName,
                            Size = file.Size,
                            Hash = file.Hash,
                        }
                    }
                });
            }
            return(JobResult.Success());
        }
示例#3
0
        private static async Task EnqueueFromList(SqlService sql, ModlistMetadata list, WorkQueue queue)
        {
            var modlistPath = Consts.ModListDownloadFolder.Combine(list.Links.MachineURL + Consts.ModListExtension);

            if (list.NeedsDownload(modlistPath))
            {
                modlistPath.Delete();

                var state = DownloadDispatcher.ResolveArchive(list.Links.Download);
                Utils.Log($"Downloading {list.Links.MachineURL} - {list.Title}");
                await state.Download(modlistPath);
            }
            else
            {
                Utils.Log($"No changes detected from downloaded ModList");
            }

            Utils.Log($"Loading {modlistPath}");

            var installer = AInstaller.LoadFromFile(modlistPath);

            var archives = installer.Archives;

            Utils.Log($"Found {archives.Count} archives in {installer.Name} to index");
            var searching = archives.Select(a => a.Hash).ToHashSet();

            Utils.Log($"Looking for missing archives");
            var knownArchives = await sql.FilterByExistingIndexedArchives(searching);

            Utils.Log($"Found {knownArchives.Count} pre-existing archives");
            var missing = archives.Where(a => !knownArchives.Contains(a.Hash)).ToList();

            Utils.Log($"Found {missing.Count} missing archives, enqueing indexing jobs");

            var jobs = missing.Select(a => new Job {
                Payload = new IndexJob {
                    Archive = a
                }, Priority = Job.JobPriority.Low
            });

            Utils.Log($"Writing jobs to the database");

            foreach (var job in jobs)
            {
                await sql.EnqueueJob(job);
            }

            Utils.Log($"Done adding archives for {installer.Name}");
        }
示例#4
0
        public override async Task <JobResult> Execute(SqlService sql, AppSettings settings)
        {
            var doc  = new HtmlDocument();
            var body = await new HttpClient().GetStringAsync(new Uri(
                                                                 "https://forum.step-project.com/topic/13894-dyndolod-beta-for-skyrim-special-edition-and-skyrim-vr-279/"));

            doc.LoadHtml(body);

            var matches =
                doc.DocumentNode
                .Descendants()
                .Where(d => d.NodeType == HtmlNodeType.Element && d.Attributes.Contains("href"))
                .Select(d => d.Attributes["href"].Value)
                .Select(m => Uri.TryCreate(m.ToString(), UriKind.Absolute, out var result) ? result : null)
                .Where(uri => uri != null && uri.Host == "mega.nz")
                .Select(url => new Job()
            {
                Payload = new IndexJob
                {
                    Archive = new Archive(new MegaDownloader.State(url.ToString()))
                    {
                        Name = Guid.NewGuid() + ".7z",
                    }
                }
            })
                .ToList();


            foreach (var job in matches)
            {
                var key   = ((MegaDownloader.State)((IndexJob)job.Payload).Archive.State).PrimaryKeyString;
                var found = await sql.DownloadStateByPrimaryKey(key);

                if (found != null)
                {
                    continue;
                }

                Utils.Log($"Queuing {key} for indexing");
                await sql.EnqueueJob(job);
            }

            return(JobResult.Success());
        }
示例#5
0
        private async Task ScheduledJob <T>(TimeSpan span, Job.JobPriority priority) where T : AJobPayload, new()
        {
            if (!Settings.RunBackEndJobs && typeof(T).ImplementsInterface(typeof(IBackEndJob)))
            {
                return;
            }
            if (!Settings.RunFrontEndJobs && typeof(T).ImplementsInterface(typeof(IFrontEndJob)))
            {
                return;
            }
            try
            {
                var jobs = (await Sql.GetUnfinishedJobs())
                           .Where(j => j.Payload is T)
                           .OrderByDescending(j => j.Created)
                           .Take(10);

                foreach (var job in jobs)
                {
                    if (job.Started == null || job.Ended == null)
                    {
                        return;
                    }
                    if (DateTime.Now - job.Ended < span)
                    {
                        return;
                    }
                }
                await Sql.EnqueueJob(new Job
                {
                    Priority = priority,
                    Payload  = new T()
                });
            }
            catch (Exception ex)
            {
                Logger.Log(LogLevel.Error, ex, $"Error in JobScheduler when scheduling {typeof(T).Name}");
            }
        }