public void Execute(DataSetCollection dataSets)
        {
            var spells = ReadSpells();

            AddSpellLists(spells);

            GenerateIds(spells);

            // Adding to dataset
            foreach (var sourceSpells in spells.GroupBy(s => s.Source.Id).Where(s => !string.IsNullOrEmpty(s.Key)))
            {
                var dataSet = dataSets.ResolveDataSet(sourceSpells.Key);
                dataSet.Sources.GetOrAdd(s => s.Id.Equals(sourceSpells.Key), () => new Source {Id = sourceSpells.Key});
                dataSet.Spells.AddRange(sourceSpells);
            }

            // Spells dataset
            //var ds = dataSets.ResolveDataSet("spells");
            //ds.Spells.AddRange(spells);
            //foreach (var source in spells.Select(s => s.Source.Id).Distinct().Where(s => !string.IsNullOrEmpty(s)))
            //{
            //    ds.Sources.Add(new Source { Id = source });
            //}
        }
        public void Execute(DataSetCollection dataSets)
        {
            var ignoredPages = EmbeddedResources.LoadString("Resources.MonsterIgnoredPages.txt").Split(new[] {Environment.NewLine}, StringSplitOptions.None);

            // Index d'après la page "Monstres"
            var indexPage = Wiki.Pages[WikiName.FromString("Pathfinder-RPG.Monstres")];
            var pages = indexPage
                .OutLinks
                .Where(p => !ignoredPages.Any(i => i.Equals(p.Name, StringComparison.OrdinalIgnoreCase)))
                .Where(p => !p.Name.EndsWith("archétype", StringComparison.OrdinalIgnoreCase))
                .ToDictionary(p => p.WikiName);
            Log.Information("{0} pages chargées depuis l'index", pages.Count);

            // Index d'après la page "Glossaire des monstres"
            indexPage = Wiki.Pages[WikiName.FromString("Pathfinder-RPG.Glossaire des monstres")];
            var glossaryOutPages = indexPage
                .OutLinks
                .Where(p => !ignoredPages.Any(i => i.Equals(p.Name, StringComparison.OrdinalIgnoreCase)))
                .Where(p => !p.Name.EndsWith("archétype", StringComparison.OrdinalIgnoreCase))
                .ToList();

            Log.Information("{0} pages chargées depuis le glossaire", glossaryOutPages.Count);

            var addedCount = 0;
            foreach (var glossaryOutPage in glossaryOutPages.Where(glossaryOutPage => !pages.ContainsKey(glossaryOutPage.WikiName)))
            {
                pages.Add(glossaryOutPage.WikiName, glossaryOutPage);
                addedCount++;
            }
            Log.Information("{0} monstres ajoutés depuis le glossaire", addedCount);

            var monsters = new List<Monster>(pages.Count);

            var parser = new MonsterParser(Log);
            foreach (var monsterPage in pages)
            {
                List<Monster> pageMonsters;
                if (TryParse(parser, monsterPage.Value, Wiki, out pageMonsters, Log))
                {
                    monsters.AddRange(pageMonsters);
                }
            }

            Log.Information("Nombre total de monstres lus : {0}", monsters.Count);

            Log.Information("Chargement du glossaire des monstres...");
            var glossaryPage = Wiki.Pages[WikiName.FromString("Pathfinder-RPG.Glossaire des monstres")];
            var glossaryParser = new MonsterGlossaryParser(Log);
            glossaryParser.ParseAll(glossaryPage, monsters);

            // Adding to dataset
            foreach (var source in monsters.GroupBy(s => s.Source.Id).Where(s => !string.IsNullOrEmpty(s.Key)))
            {
                var localSource = source;
                var dataSet = dataSets.ResolveDataSet(source.Key);
                dataSet.Sources.GetOrAdd(s => s.Id.Equals(localSource.Key), () => new Source {Id = localSource.Key});
                dataSet.Monsters.AddRange(source.OrderBy(m => m.Id));
            }

            // Monsters dataset
            //var ds = dataSets.ResolveDataSet("monsters");
            //ds.Monsters.AddRange(monsters);
            //foreach (var source in monsters.Select(s => s.Source.Id).Distinct().Where(s => !string.IsNullOrEmpty(s)))
            //{
            //    ds.Sources.Add(new Source { Id = source });
            //}

            parser.Flush();
        }
        public void Execute(DataSetCollection dataSets)
        {
            var export = Wiki;

            var featPages = export.Pages
                // Toutes les pages ayant la catégorie "Don"
                .Where(p => p.Categories.Any(c => c.Name.Equals("Don", StringComparison.OrdinalIgnoreCase)))
                // Sauf celles explicitement exclues
                .Where(p => !IgnoredPages.Any(i => i.Equals(p.Title, StringComparison.OrdinalIgnoreCase)))
                .ToList();

            Log.Information("{0} Dons chargés", featPages.Count);

            var feats = ReadFeats(featPages);

            // Feats by source
            foreach (var sourceFeats in feats.GroupBy(s => s.Source.Id).Where(s => !string.IsNullOrEmpty(s.Key)))
            {
                var dataSet = dataSets.ResolveDataSet(sourceFeats.Key);
                dataSet.Sources.GetOrAdd(s => s.Id.Equals(sourceFeats.Key), () => new Source {Id = sourceFeats.Key});
                dataSet.Feats.AddRange(sourceFeats);
            }

            // Feats dataset
            //var ds = dataSets.ResolveDataSet("feats");
            //ds.Feats.AddRange(feats);
            //foreach (var source in feats.Select(s => s.Source.Id).Distinct().Where(s => !string.IsNullOrEmpty(s)))
            //{
            //    ds.Sources.Add(new Source { Id = source });
            //}
        }