using aeqw89.DataKeys; using Beam.Dynamic; using System; using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; using Beam.Models; namespace Beam.Temporary.Cli { public static class NovelStatics { //public static void Define_LightNovelWorld_Novel_TheLegendaryMechanic(SharedDataDictionary sdd) { // var lnwAggregator = new DataKey("aeqw89:document:aggregators:light_novel_world"); // var lnwAuxiliary = new DataKey("aeqw89:document:auxillaries:light_novel_world"); // var novel = new TextResource() { // Key = new DataKey("novels:the_legendary_mechanic"), // AssociatedSource = lnwAggregator, // AssociatedMetaSource = lnwAuxiliary, // TemplateInitialData = ["the-legendary-mechanic-245", "1"], // MetaTemplateInitialData = ["the-legendary-mechanic"] // }; // sdd.Novels.TryAdd(novel.Key, novel); // sdd.AggregatorNovels.TryAdd(lnwAggregator, [novel.Key]); //} //public static void Define_LightNovelWorl_Novel_IAloneLevelUp(SharedDataDictionary sdd) { // var lnwAggregator = new DataKey("light_novel_world").ToAggregator().As(); // var lnwAuxiliary = new DataKey("light_novel_world").ToAuxiliary().As(); // var novel = new TextResource() { // Key = new DataKey("novels:i_alone_level_up"), // AssociatedSource = lnwAggregator, // AssociatedMetaSource = lnwAuxiliary, // TemplateInitialData = ["i-alone-level-up-236", "1"], // MetaTemplateInitialData = ["i-alone-level-up-solo-leveling-05122225"] // }; // sdd.Novels.TryAdd(novel.Key, novel); // sdd.AggregatorNovels.TryAdd(lnwAggregator, [novel.Key]); //} //// ----------------------------------------------------------------------------- //// Helper: same as in the WoDuShu file //private static (DataKey, DataKey) CreateKeyPair( // string pref1, string pref2, string common, string @namespace) { // return ( // new DataKey($"{pref1}:{common}").WithNamespace(@namespace), // new DataKey($"{pref2}:{common}").WithNamespace(@namespace) // ); //} // ----------------------------------------------------------------------------- // 1) Site-wide definition – YeBiQuge (m.yebiquge.com) public static void Define_YeBiQuge(BeamDataContext sdd) { // ---------- keys ---------- var yb = new DataKey("aeqw89:yebiquge"); var bindings = new DataKey($"aeqw89:yebiquge:{nameof(IDocument).ToLower()}:bindings"); var bindings_info = new DataKey($"aeqw89:yebiquge:{nameof(ArticleData).ToLower()}:bindings"); var bindings_toc = new DataKey($"aeqw89:yebiquge:{nameof(TableOfContentsData).ToLower()}:bindings"); // ---------- web resources ---------- var aggregator = new WebResource(yb.InsertEnd(nameof(IDocument).ToLower())) { Name = "YeBiQuge – Chapters", Description = "Chapter pages (mobile)", Domain = "https://m.yebiquge.com", Bindings = bindings }; var bookInfo = new WebResource(yb.InsertEnd(nameof(ArticleData).ToLower())) { Name = "YeBiQuge – Book Info", Description = "Book information / latest updates page", Domain = "https://m.yebiquge.com", Bindings = bindings_info }; var tocPage = new WebResource(yb.InsertEnd(nameof(TableOfContentsData).ToLower())) { Name = "YeBiQuge – TOC", Description = "Full chapter list (index*.html)", Domain = "https://m.yebiquge.com", Bindings = bindings_toc }; sdd.Resources.TryAdd(aggregator.Key, aggregator); sdd.Resources.TryAdd(bookInfo.Key, bookInfo); sdd.Resources.TryAdd(tocPage.Key, tocPage); // ---------- URL templates ---------- // 1-a) Chapter page /{catId}/{bookId}/{chapterId}.html sdd.Templates.TryAdd(aggregator.Key, new() { Factory = new(StateChangerFactory.LastAsNumber), Builder = new SourceLinkBuilder("m.yebiquge.com") .WithSegments("", "", "") // /// .WithParameters(0, "") .WithParameters(1, "") .WithParameters(2, (".html", Position.After)) // chapId.html }); // 1-b) Book-info page /{catId}/{bookId}/ sdd.Templates.TryAdd(bookInfo.Key, new() { Factory = new(StateChangerFactory.Constant), Builder = new SourceLinkBuilder("m.yebiquge.com") .WithSegments("", "") // /// .WithParameters(0, "") .WithParameters(1, "") }); // 1-c) TOC page /{catId}/{bookId}/index.html (first page) sdd.Templates.TryAdd(tocPage.Key, new() { Factory = new(StateChangerFactory.Constant), Builder = new SourceLinkBuilder("m.yebiquge.com") .WithSegments("", "", "index.html") // ///index.html .WithParameters(0, "") .WithParameters(1, "") }); // ---------- bindings ---------- // ── chapter page ──────────────────────────────────────────────── sdd.Bindings.Add(bindings, new() { Title = new ContentsDataProvider { Content = new Binding { XPath = "//*[@id='nr_title']" } }, Content = new ParagraphedContentDataProvider { Content = new Binding { XPath = "//*[@id='chaptercontent']" } }, }); // ── book-info page ────────────────────────────────────────────── sdd.Bindings.Add(bindings_info, new() { Title = new ContentsDataProvider { Content = new Binding { XPath = "//div[@class='book_info']//dt[@class='name']" } }, Authors = new ContentsArrayDataProvider { Content = new Binding { XPath = "//div[@class='book_info']//span[contains(text(),'作者')]" } }, Description = new ParagraphedContentDataProvider { Content = new Binding { XPath = "//div[@class='book_about']/dl/dd" } } }); // ── TOC page ──────────────────────────────────────────────────── sdd.Bindings.Add(bindings_toc, new() { PagesDropDown = new DropDownDataProvider { Content = new Binding { XPath = "//div[@class='fenye']//select" }, RelativeTo = tocPage.Domain }, TableOfContents = new AnchorCollectionDataProvider { Content = new Binding { XPath = "//div[@class='book_last']/dl" }, RelativeTo = tocPage.Domain } }); } // ----------------------------------------------------------------------------- // 2) Concrete novel – 《诡秘之主》 / Lord of the Mysteries public static void Define_YeBiQuge_LordOfMysteries(BeamDataContext sdd) { var yb = new DataKey("aeqw89:yebiquge:novels:lord_of_the_mysteries"); var ybAgg = yb.InsertEnd(nameof(IDocument).ToLower()); var ybInfo = yb.InsertEnd(nameof(ArticleData).ToLower()); var ybToc = yb.InsertEnd(nameof(TableOfContentsData).ToLower()); var novel = new ResourceDictionary { Key = yb.To(), FriendlyName = "Lord of the Mysteries", Resources = { { nameof(IDocument) , ybAgg }, // chapters { nameof(ArticleData) , ybInfo }, // book info { nameof(TableOfContentsData), ybToc } // full TOC }, // catId = 2 , bookId = 2958 , sample chapterId = 8699808 InitialStates = new Dictionary, ImmutableState> { { ybAgg, new ImmutableState(["2","2958","8699808"]) }, { ybInfo, new ImmutableState(["2","2958"]) }, { ybToc, new ImmutableState(["2","2958"]) }, } }; sdd.ResourceDictionaries.TryAdd(novel.Key, novel); sdd.AggregatorNovels.TryAdd(ybAgg, [novel.Key]); } // ----------------------------------------------------------------------------- // 1) Site-wide definition – KuaiShu5 (www.kuaishu5.com) public static void Define_KuaiShu5(BeamDataContext sdd) { // ---------- keys ---------- var ks = new DataKey("aeqw89:kuaishu5"); var bindings_chapter = new DataKey($"aeqw89:kuaishu5:{nameof(IDocument).ToLower()}:bindings"); var bindings_info = new DataKey($"aeqw89:kuaishu5:{nameof(ArticleData).ToLower()}:bindings"); var bindings_toc = new DataKey($"aeqw89:kuaishu5:{nameof(TableOfContentsData).ToLower()}:bindings"); // ---------- web resources ---------- var chapters = new WebResource(ks.InsertEnd(nameof(IDocument).ToLower())) { Name = "KuaiShu5 – Chapters", Description = "Chapter pages", Domain = "https://www.kuaishu5.com", Bindings = bindings_chapter }; var bookInfo = new WebResource(ks.InsertEnd(nameof(ArticleData).ToLower())) { Name = "KuaiShu5 – Book Info", Description = "Book information / landing page", Domain = "https://www.kuaishu5.com", Bindings = bindings_info }; var tocPage = new WebResource(ks.InsertEnd(nameof(TableOfContentsData).ToLower())) { Name = "KuaiShu5 – TOC", Description = "Full chapter list (index page)", Domain = "https://www.kuaishu5.com", Bindings = bindings_toc }; sdd.Resources.TryAdd(chapters.Key, chapters); sdd.Resources.TryAdd(bookInfo.Key, bookInfo); sdd.Resources.TryAdd(tocPage.Key, tocPage); // ---------- URL templates ---------- // 1-a) Chapter page /b{bookId}/{chapterId}.html sdd.Templates.TryAdd(chapters.Key, new() { Factory = new(StateChangerFactory.LastAsNumber), Builder = new SourceLinkBuilder("www.kuaishu5.com") .WithSegments("", "") // // .WithParameters(0, ("b", Position.Before)) // seg0: b{bookId} .WithParameters(1, (".html", Position.After)) // seg1: {chapterId}.html }); // 1-b) Book-info page /b{bookId}/ sdd.Templates.TryAdd(bookInfo.Key, new() { Factory = new(StateChangerFactory.Constant), Builder = new SourceLinkBuilder("www.kuaishu5.com") .WithSegments("") // / .WithParameters(0, ("b", Position.Before)) // seg0: b{bookId} }); // 1-c) TOC page /b{bookId}/ (same as book-info) sdd.Templates.TryAdd(tocPage.Key, new() { Factory = new(StateChangerFactory.Constant), Builder = new SourceLinkBuilder("www.kuaishu5.com") .WithSegments("") // / .WithParameters(0, ("b", Position.Before)) // seg0: b{bookId} }); // ---------- bindings ---------- // ── chapter page ──────────────────────────────────────────────── sdd.Bindings.Add(bindings_chapter, new() { Title = new ContentsDataProvider { Content = new Binding { XPath = "//h1[@class='bookname']" } }, Content = new ParagraphedContentDataProvider { Content = new Binding { XPath = "//*[@id='booktxt']" } } }); // ── book-info page ────────────────────────────────────────────── sdd.Bindings.Add(bindings_info, new() { Title = new ContentsDataProvider { Content = new Binding { XPath = "//*[@id='info']/h1" } }, Authors = new ContentsArrayDataProvider { Content = new Binding { XPath = "//*[@id='info']//p[contains(text(),'作者')]/a" } }, Description = new ParagraphedContentDataProvider { Content = new Binding { XPath = "//*[@id='intro']" } } }); // ── TOC page ──────────────────────────────────────────────────── sdd.Bindings.Add(bindings_toc, new() { PagesDropDown = new DropDownDataProvider { Content = new Binding { XPath = "//*[@id='indexselect']" }, RelativeTo = tocPage.Domain }, TableOfContents = new AnchorCollectionDataProvider { Content = new Binding { XPath = "//*[@id='content_1']" }, RelativeTo = tocPage.Domain } }); } // ----------------------------------------------------------------------------- // 2) Concrete novel – 《诡秘之主》 / Lord of the Mysteries public static void Define_KuaiShu5_LordOfMysteries(BeamDataContext sdd) { var ks = new DataKey("aeqw89:kuaishu5"); var ksChapters = ks.InsertEnd(nameof(IDocument).ToLower()); var ksInfo = ks.InsertEnd(nameof(ArticleData).ToLower()); var ksToc = ks.InsertEnd(nameof(TableOfContentsData).ToLower()); var novel = new ResourceDictionary { Key = new DataKey("kuaishu5:novels:lord_of_the_mysteries"), FriendlyName = "Lord of the Mysteries", Resources = { { nameof(IDocument) , ksChapters }, { nameof(ArticleData) , ksInfo }, { nameof(TableOfContentsData), ksToc } } }; // bookId = 122722 , sample chapterId = 288372 sdd.InitialStates = new Dictionary, ImmutableState> { { ksChapters.To(), new ImmutableState(["122722", "288372"]) }, { ksInfo .To(), new ImmutableState(["122722"]) }, { ksToc .To(), new ImmutableState(["122722"]) } }; sdd.ResourceDictionaries.TryAdd(novel.Key, novel); sdd.AggregatorNovels.TryAdd(ksChapters, [novel.Key]); } //public static void Define_WoDuShu_HouseOfHorrors(BeamDataDictionary sdd) { // var (wdsAgg, wdsAux) = CreateKeyPair("aggregators", "auxillaries", "wodushu", "aeqw89:document"); // var novel = new ResourceDictionary() { // Key = new DataKey("novels:house_of_horrors"), // FriendlyName = "My House Of Horrors", // AssociatedSource = wdsAgg, // AssociatedMetaSource = wdsAux, // TemplateInitialData = new ImmutableState(["24349", "2896325"]), // MetaTemplateInitialData = new ImmutableState(["24349"]) // }; // sdd.ResourceDictionaries.TryAdd(novel.Key, novel); // sdd.AggregatorNovels.TryAdd(wdsAgg, [novel.Key]); //} private static (DataKey, DataKey) CreateKeyPair(string pref1, string pref2, string common, string @namespace) { return ( new DataKey(pref1 + ":" + common).InsertStart(@namespace), new DataKey(pref2 + ":" + common).InsertStart(@namespace) ); } //public static void Define_WoDuShu(BeamDataDictionary sdd) { // var (wdsAgg, wdsAux) = CreateKeyPair("aggregators", "auxillaries", "wodushu", "aeqw89:document"); // var bindings = new DataKey("aeqw89:bindings:wodushu"); // var aggregator = new WebResource(wdsAgg) { // Name = "WoDuShu.com", // Description = "A Chinese novel aggregator site", // Domain = "https://wodushu.com", // Bindings = bindings // }; // var auxiliary = new WebResource(wdsAux) { // Name = "WoDuShu.com", // Description = "A Chinese novel aggregator site", // Domain = "https://wodushu.com", // Bindings = bindings.WithSuffix("_aux") // }; // sdd.Templates.TryAdd(wdsAgg, new() { // Factory = new(StateChangerFactory.LastAsNumber), // Builder = new SourceLinkBuilder("www.wodushu.com") // .WithSegments("read", "", "") // .WithParameters(1, "") // .WithParameters(2, (".html", Position.After)) // }); // sdd.Templates.TryAdd(wdsAux, new() { // Factory = new(StateChangerFactory.Constant), // Builder = new SourceLinkBuilder("www.wodushu.com") // .WithSegments("book", "") // .WithParameters(1, "") // }); // sdd.Resources.TryAdd(wdsAgg, aggregator); // sdd.Auxillaries.TryAdd(wdsAux, auxiliary); // var binding_agg = new DataKey("aeqw89:bindings:wodushu"); // var binding_aux = new DataKey("aeqw89:bindings:wodushu_aux"); // sdd.Bindings.Add(binding_agg, new() { // Title = new ContentsDataProvider() { // Content = new Binding() { // XPath = "/html/body/div[4]/div/div/div[2]/h1" // } // }, // Content = new ParagraphedContentDataProvider() { // Content = new Binding() { // XPath = "//*[@id=\"content\"]" // } // }, // }); // sdd.Bindings.Add(binding_aux, new() { // Title = new ContentsDataProvider() { // Content = new Binding() { // XPath = "/html/body/div[3]/div[1]/div/div/div[2]/div[1]/h1" // } // }, // Authors = new ContentsArrayDataProvider() { // Content = new Binding() { // XPath = "/html/body/div[3]/div[1]/div/div/div[2]/div[1]/div/p[1]/a" // } // }, // Description = new ParagraphedContentDataProvider() { // Content = new Binding() { // XPath = "/html/body/div[3]/div[1]/div/div/div[2]/div[2]" // } // }, // }); //} //public static void Define_NovelFull(SharedDataDictionary sdd) { // var docNamespace = "aeqw89:document"; // var nfAgg = new DataKey("aggregators:novel_full").WithNamespace(docNamespace); // var nfAux = new DataKey("auxillaries:novel_full").WithNamespace(docNamespace); // var nfBindings = new DataKey("aeqw89:bindings:light_novel_world"); // var aggregator = new WebResource(nfAgg) { // Name = "Novel Full", // Description = "A novel aggregator site", // Domain = "https://novelfull.net", // Bindings = nfBindings // }; // var auxiliary = new WebResource(nfAux) { // Name = "Novel Full", // Description = "A novel aggregator site", // Domain = "https://novelfull.net", // Bindings = nfBindings.WithSuffix("_aux") // }; // sdd.Templates.TryAdd(nfAux, new(StateChangerFactory.LastAsNumberPrefixed)); // sdd.Aggregators.TryAdd(nfAgg, aggregator); // sdd.Auxillaries.TryAdd(nfAux, auxiliary); // var binding_agg = new DataKey("aeqw89:bindings:be") //} //public static void Define_LightNovelWorld(SharedDataDictionary sdd) { // var lnwAggregator = new DataKey("aeqw89:document:aggregators:light_novel_world"); // var lnwAuxiliary = new DataKey("aeqw89:document:auxillaries:light_novel_world"); // const string lnwBindingsA = "aeqw89:bindings:light_novel_world"; // var aggregator = new WebResource(lnwAggregator) { // Name = "Light Novel World", // Description = "A novel aggregator site maintained by NetherClaw", // Domain = "https://www.lightnovelworld.co", // Bindings = new DataKey(lnwBindingsA) // }; // const string lnwBindingsB = "aeqw89:bindings:light_novel_world_aux"; // var auxiliary = new WebResource(lnwAuxiliary) { // Name = "Light Novel World", // Description = "A novel aggregator site maintained by NetherClaw", // Domain = "https://www.lightnovelworld.co", // Bindings = new DataKey(lnwBindingsB) // }; // sdd.Templates.TryAdd(lnwAuxiliary, new() { // Template = "https://www.lightnovelworld.co/novel/{0}", // IndexOfChapterIndex = -1 // }); // sdd.Templates.TryAdd(lnwAggregator, new() { // Template = "https://www.lightnovelworld.co/novel/{0}/chapter-{1}", // IndexOfChapterIndex = 1 // }); // sdd.Aggregators.TryAdd(aggregator.Key, aggregator); // sdd.Auxillaries.TryAdd(auxiliary.Key, auxiliary); // var lnwBindings = new DataKey(lnwBindingsA); // var lnwBindingsAux = new DataKey(lnwBindingsB); // sdd.Bindings.TryAdd(lnwBindings, new DataBindings() { // Title = new Binding("aeqw89:binding:light_novel_world:title") { // XPath = "/html/body/main/article/section/div[1]/h1/span[2]", // Type = BindingType.Single // }, // Content = new("aeqw89:binding:light_novel_world:content") { // Provider = new ParagraphedContentDataProvider() { // Content = new Binding() { // XPath = "//*[@id=\"chapter-container\"]" // } // }, // Type = BindingType.UseProvider // }, // }); // sdd.Bindings.TryAdd(lnwBindingsAux, new DataBindings() { // Title = new("aeqw89:binding:light_novel_world_aux:title") { // XPath = "/html/body/main/article/header/div[2]/div[2]/div[1]/h1", // Type = BindingType.Single // }, // Authors = new("aeqw89:binding:light_novel_world_aux:authors") { // XPath = "/html/body/main/article/header/div[2]/div[2]/div[1]/div[1]/a", // Type = BindingType.Single // }, // Description = new("aeqw89:binding:light_novel_world_aux:description") { // Provider = new ParagraphedContentDataProvider() { // Content = new() { // XPath = "/html/body/main/article/div/section/div[1]/div" // } // }, // Type = BindingType.UseProvider // }, // Tags = new("aeqw89:binding:light_novel_world_aux:tags") { // Provider = new ListContentDataProvider() { // Content = new() { // XPath = "/html/body/main/article/header/div[2]/div[2]/div[3]/ul" // } // }, // Type = BindingType.UseProvider // } // }); //} } }