diff --git a/MoeLoaderP.Core/Ex.cs b/MoeLoaderP.Core/Ex.cs index 2fd8ceb..23e870b 100644 --- a/MoeLoaderP.Core/Ex.cs +++ b/MoeLoaderP.Core/Ex.cs @@ -21,6 +21,9 @@ namespace MoeLoaderP.Core; /// public static class Ex { + private static string _logListOriginalString; + private static string _logItemString; + public static int GetXIntValue(this XElement el, string xpath) { return (el.XPathSelectElement(xpath)?.Value ?? "0").ToInt(); @@ -55,8 +58,30 @@ public enum MessagePos public static ObservableCollection LogCollection { get; set; } = new(); + public static string LogListOriginalString + { + get => _logListOriginalString; + set + { + _logListOriginalString = value; + if(value!=null) LogListOriginalStringAction?.Invoke(value); + } + } + + public static string LogItemString + { + get => _logItemString; + set + { + _logItemString = value; LogItemStringAction?.Invoke(value); + } + } + public static Action LogAction { get; set; } + public static event Action LogListOriginalStringAction; + public static event Action LogItemStringAction; + public static dynamic GetValue(this HtmlNode rootNode, CustomXpath xpath) { if (xpath == null) return null; @@ -139,7 +164,15 @@ public static string ToPairsString(this Pairs pairs) if (pairs == null) return query; foreach (var para in pairs.Where(para => !para.Value.IsEmpty())) { - query += $"{(i > 0 ? "&" : "?")}{para.Key}={para.Value}"; + if (para.Value == null) + { + query += $"{(i > 0 ? "&" : "?")}{para.Key}"; + } + else + { + query += $"{(i > 0 ? "&" : "?")}{para.Key}={para.Value}"; + } + i++; } diff --git a/MoeLoaderP.Core/MoeItem.cs b/MoeLoaderP.Core/MoeItem.cs index 88abd97..e7246a7 100644 --- a/MoeLoaderP.Core/MoeItem.cs +++ b/MoeLoaderP.Core/MoeItem.cs @@ -130,7 +130,7 @@ public bool IsFav public string Description { get; set; } public List Tags { get; set; } = new(); - public bool IsExplicit { get; set; } + public bool IsNsfw { get; set; } public string DetailUrl { get; set; } public string OriginString { get; set; } @@ -280,8 +280,8 @@ public void LocalFilter() { switch (set.IsXMode) { - case false or false when IsExplicit: - case true when para.IsShowExplicitOnly && IsExplicit == false: + case false or false when IsNsfw: + case true when para.IsShowExplicitOnly && IsNsfw == false: isNotFilter = false; break; } diff --git a/MoeLoaderP.Core/MoeLoaderP.Core.csproj b/MoeLoaderP.Core/MoeLoaderP.Core.csproj index 04b8bb4..5452650 100644 --- a/MoeLoaderP.Core/MoeLoaderP.Core.csproj +++ b/MoeLoaderP.Core/MoeLoaderP.Core.csproj @@ -1,15 +1,15 @@ - + net6.0 - - - - - + + + + + diff --git a/MoeLoaderP.Core/NetOperator.cs b/MoeLoaderP.Core/NetOperator.cs index 303ecde..54d45f9 100644 --- a/MoeLoaderP.Core/NetOperator.cs +++ b/MoeLoaderP.Core/NetOperator.cs @@ -38,8 +38,6 @@ public NetOperator(Settings settings,MoeSite site, double timeout = 40) Settings = settings; Site = site; Timeout = timeout; - - HttpClientHandler = new HttpClientHandler { Proxy = GetProxy(), @@ -53,21 +51,38 @@ public NetOperator(Settings settings,MoeSite site, double timeout = 40) ProgressMessageHandler = new ProgressMessageHandler(HttpClientHandler); Client = new HttpClient(ProgressMessageHandler); var agent = Agents[new Random().Next(0, Agents.Length - 1)]; - Client.DefaultRequestHeaders.UserAgent.ParseAdd(agent); + var header = Client.DefaultRequestHeaders; + //header.UserAgent.ParseAdd(agent); + //header.TryAddWithoutValidation("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7"); + //header.TryAddWithoutValidation("Accept-Encoding", "gzip, deflate"); + if (site is DanbooruSite) + { + header.TryAddWithoutValidation("User-Agent", "gdl/1.24.5"); + } + else + { + header.TryAddWithoutValidation("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36"); + } + //header.TryAddWithoutValidation("Accept-Charset", "ISO-8859-1"); + //header.TryAddWithoutValidation("Sec-Fetch-Dest", "document"); + //header.TryAddWithoutValidation("Accept-Language", "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2"); + //header.TryAddWithoutValidation("Connection", "keep-alive"); + //header.TryAddWithoutValidation("Sec-Fetch-Dest", "document"); + //header.TryAddWithoutValidation("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8"); + //header.TryAddWithoutValidation("Sec-Fetch-Dest", "document"); + //header.TryAddWithoutValidation("Sec-Fetch-Dest", "document"); + //header.TryAddWithoutValidation("Sec-Fetch-User", "?1"); + //header.TryAddWithoutValidation("Upgrade-Insecure-Requests", "1"); + + Client.Timeout = TimeSpan.FromSeconds(Timeout); } public static string[] Agents = { - "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36", - //"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36", - //"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36", - //"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36", - //"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36", - //"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.182 Safari/537.36", - //"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36", - //"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36", + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36", + //"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36", }; public IWebProxy GetProxy() @@ -148,6 +163,7 @@ public async Task GetAsync(string api, bool showSearchMessa { try { + return await Client.GetAsync(api, token); } catch (Exception) @@ -178,15 +194,34 @@ public async Task GetStringAsync(string api, Pairs parapairs = null, boo } } - public async Task GetJsonAsync(string api, Pairs parapairs = null, bool showSearchMessage = true, CancellationToken token = default) + public async Task GetJsonAsync(string api, Pairs parapairs = null, bool showSearchMessage = true, bool saveListOriginalString = false, bool tryWebView = false, + CancellationToken token = default) { var query = parapairs.ToPairsString(); try { - var response = await GetAsync($"{api}{query}", showSearchMessage, 3,token: token); - + var response = await GetAsync($"{api}{query}", showSearchMessage,token: token); + var res = response.Headers; var s = await response.Content.ReadAsStringAsync(token); - return JsonConvert.DeserializeObject(s); + if (saveListOriginalString) + { + Ex.LogListOriginalString = s; + } + + dynamic deo = JsonConvert.DeserializeObject(s); + //try + //{ + // deo = JsonConvert.DeserializeObject(s); + //} + //catch (Exception e) + //{ + // if (e.Message.Contains("Unexpected character", StringComparison.OrdinalIgnoreCase)) + // { + // // if (WebView == null) InitWebView(); + + // } + //} + return deo; } catch (Exception e) { @@ -196,6 +231,45 @@ public async Task GetJsonAsync(string api, Pairs parapairs = null, bool } } + //public void InitWebView() + //{ + // WebView = new WebView2(); + // try + // { + // WebView.CoreWebView2InitializationCompleted += WebViewOnCoreWebView2InitializationCompleted; + + // var option = new CoreWebView2EnvironmentOptions(); + // switch (GetProxyMode(Settings, Site.SiteSettings)) + // { + // case Settings.ProxyModeEnum.None: + // option.AdditionalBrowserArguments = "--no-proxy-server"; + // break; + // case Settings.ProxyModeEnum.Custom: + // option.AdditionalBrowserArguments = $"--proxy-server=http://{Settings.ProxySetting}"; + // break; + // case Settings.ProxyModeEnum.Ie: + // break; + // } + // Environment = await CoreWebView2Environment.CreateAsync(null, App.AppDataDir, option); + + // AuthButton.Click += AuthButtonOnClick; + // GoToLoginPageButton.Click += GoToLoginPageButtonOnClick; + // var _ = MainBrowser.EnsureCoreWebView2Async(Environment); + // } + // catch (Exception ex) + // { + // var result = MessageBox.Show(this, "未找到WebView2组件,需要下载吗?(需要Webview2组件才能显示网页登录界面)", App.DisplayName, MessageBoxButton.YesNo, MessageBoxImage.Question); + // if (result == MessageBoxResult.Yes) + // { + // "https://go.microsoft.com/fwlink/p/?LinkId=2124703".GoUrl(); + + // } + // Ex.Log(ex); + // Close(); + // } + //} + + public async Task GetHtmlAsync(string api, Pairs parapairs = null, bool showSearchMessage = true, CancellationToken token = default) { var query = parapairs.ToPairsString(); @@ -235,7 +309,7 @@ public async Task GetXmlAsync(string api, Pairs pairs = null, bool return xml; } - public async Task GetXDocAsync(string api, Pairs pairs = null, bool showSearchMessage = true, + public async Task GetXDocAsync(string api, Pairs pairs = null, bool showSearchMessage = true,bool tryWebView = false, CancellationToken token = default) { var query = pairs.ToPairsString(); diff --git a/MoeLoaderP.Core/SearchSession.cs b/MoeLoaderP.Core/SearchSession.cs index 4ac9b62..2925781 100644 --- a/MoeLoaderP.Core/SearchSession.cs +++ b/MoeLoaderP.Core/SearchSession.cs @@ -28,6 +28,7 @@ public SearchSession(SearchPara para) public string Name { get; set; } + public Settings Settings { get; set; } @@ -185,7 +186,7 @@ public async Task TryGetRealPage(SearchPara para) rp.CurrentPageItemsOutputCount = rp.Count(item=> item.IsLocalFilter == false); var mes = $"第{rp.CurrentPageNum}页获取到图片{rp.CurrentPageItemsOriginCount}张,条件过滤{rp.CurrentPageItemsOriginCount - rp.CurrentPageItemsOutputCount}张"; - + Ex.LogListOriginalString = rp.OriginString?.ToString(); Ex.ShowMessage(mes, pos: Ex.MessagePos.Searching); return rp; } diff --git a/MoeLoaderP.Core/Settings.cs b/MoeLoaderP.Core/Settings.cs index 7c41d54..ed5e98e 100644 --- a/MoeLoaderP.Core/Settings.cs +++ b/MoeLoaderP.Core/Settings.cs @@ -29,6 +29,22 @@ public SearchSession CurrentSession #region Window size / Display + private double _logWindowWidth = 500d; + + public double LogWindowWidth + { + get => _logWindowWidth; + set => SetField(ref _logWindowWidth, value, nameof(LogWindowWidth)); + } + + private double _logWindowHeight = 350d; + + public double LogWindowHeight + { + get => _logWindowHeight; + set => SetField(ref _logWindowHeight, value, nameof(LogWindowHeight)); + } + private bool _isLowPerformanceMode; public bool IsLowPerformanceMode diff --git a/MoeLoaderP.Core/SiteManager.cs b/MoeLoaderP.Core/SiteManager.cs index e17454f..56f50a0 100644 --- a/MoeLoaderP.Core/SiteManager.cs +++ b/MoeLoaderP.Core/SiteManager.cs @@ -20,7 +20,7 @@ public SiteManager(Settings settings) Settings = settings; Sites = new MoeSites(settings); Settings.PropertyChanged += SettingsOnPropertyChanged; - SetDefaultSiteList(); + RefreshSiteList(); } public Settings Settings { get; set; } @@ -48,13 +48,14 @@ public void SetDefaultSiteList() Sites.Add(new GelbooruSite()); Sites.Add(new SankakuChanSite()); if (x) Sites.Add(new SankakuIdolSite()); + Sites.Add(new DanbooruSite()); Sites.Add(new DeviantartSite()); - Sites.Add(new DonmaiSite()); + Sites.Add(new BilibiliSite()); Sites.Add(new YuriimgSite()); Sites.Add(new BehoimiSite()); Sites.Add(new SafebooruSite()); - if (x) Sites.Add(new LolibooruSite()); + Sites.Add(new LolibooruSite()); if (x) Sites.Add(new AtfbooruSite()); if (x) Sites.Add(new Rule34Site()); @@ -101,30 +102,39 @@ public bool R18Check() if (!Settings.HaveEnteredXMode) { ClickTimes++; - if (ClickTimes <= 3) return false; - if (ClickTimes is > 3 and < 10) + switch (ClickTimes) { - Ex.ShowMessage($"还剩 {10 - ClickTimes} 次粉碎!"); - return false; + case <= 3: + return false; + case > 3 and < 10: + Ex.ShowMessage($"还剩 {10 - ClickTimes} 次击破!"); + return false; + case >= 10: + Settings.HaveEnteredXMode = true; + break; } - - if (ClickTimes >= 10) Settings.HaveEnteredXMode = true; } - Ex.ShowMessage(Settings.IsXMode ? "已关闭 R18 模式" : "已开启 R18 模式"); + Ex.ShowMessage(Settings.IsXMode ? "已关闭 NSFW 模式" : "已开启 NSFW 模式"); Settings.IsXMode = !Settings.IsXMode; Sites.Clear(); - SetDefaultSiteList(); + RefreshSiteList(); return true; } private void SettingsOnPropertyChanged(object sender, PropertyChangedEventArgs e) { - if (e.PropertyName == nameof(Settings.IsCustomSiteMode)) - { - Sites.Clear(); - if (Settings.IsCustomSiteMode) SetCustomSitesFormJson(Settings.CustomSitesDir); - else SetDefaultSiteList(); - } + //if (e.PropertyName == nameof(Settings.IsCustomSiteMode)) + //{ + // Sites.Clear(); + // if (Settings.IsCustomSiteMode) SetCustomSitesFormJson(Settings.CustomSitesDir); + // else SetDefaultSiteList(); + //} + } + + public void RefreshSiteList() + { + SetDefaultSiteList(); + SetCustomSitesFormJson(Settings.CustomSitesDir); } } \ No newline at end of file diff --git a/MoeLoaderP.Core/Sites/AtfbooruSite.cs b/MoeLoaderP.Core/Sites/AtfbooruSite.cs index 6edb6ac..48631d4 100644 --- a/MoeLoaderP.Core/Sites/AtfbooruSite.cs +++ b/MoeLoaderP.Core/Sites/AtfbooruSite.cs @@ -5,7 +5,7 @@ /// public class AtfbooruSite : BooruSite { - public override string HomeUrl => "https://booru.allthefallen.moe/"; + public override string HomeUrl => "https://booru.allthefallen.moe"; public override string DisplayName => "Atfbooru"; public override string ShortName => "atfbooru"; diff --git a/MoeLoaderP.Core/Sites/BilibiliSite.cs b/MoeLoaderP.Core/Sites/BilibiliSite.cs index 29412a1..dacc2ad 100644 --- a/MoeLoaderP.Core/Sites/BilibiliSite.cs +++ b/MoeLoaderP.Core/Sites/BilibiliSite.cs @@ -31,7 +31,7 @@ public BilibiliSite() public override string ShortName => "bilibili"; - public override bool VerifyCookieAndSave(CookieCollection ccol) + public override bool VerifyCookie(CookieCollection ccol) { return ccol.Any(cookie => cookie.Name.Equals("DedeUserID", StringComparison.OrdinalIgnoreCase)); } diff --git a/MoeLoaderP.Core/Sites/BooruSite.cs b/MoeLoaderP.Core/Sites/BooruSite.cs index 504d60e..d552ab5 100644 --- a/MoeLoaderP.Core/Sites/BooruSite.cs +++ b/MoeLoaderP.Core/Sites/BooruSite.cs @@ -16,7 +16,13 @@ public abstract class BooruSite : MoeSite public enum SiteTypeEnum { Xml, + /// + /// gelbooru + /// Xml2, + /// + /// danbooru + /// Json } @@ -59,6 +65,7 @@ public void Login() public override async Task GetAutoHintItemsAsync(SearchPara para, CancellationToken token) { if(Net == null) Login(); + if (Net == null) return null; var net = Net.CloneWithCookie(); var list = new AutoHintItems(); @@ -78,7 +85,7 @@ public override async Task GetAutoHintItemsAsync(SearchPara para, }); return list; case SiteTypeEnum.Json: - var json = await net.GetJsonAsync(GetHintQuery(para), token: token); + var json = await net.GetJsonAsync(GetHintQuery(para), saveListOriginalString:true, token: token); foreach (var item in Ex.GetList(json)) list.Add(new AutoHintItem { @@ -128,7 +135,11 @@ public async Task GetRealPageImagesAsyncFromXml(SearchPara para, C img.Height = post.Attribute("height")?.Value.ToInt() ?? 0; img.Uploader = post.Attribute("author")?.Value; img.Source = post.Attribute("source")?.Value; - img.IsExplicit = post.Attribute("rating")?.Value.ToLower() != "s"; + img.IsNsfw = post.Attribute("rating")?.Value.ToLower() != "s"; + if (this is SafebooruSite) + { + img.IsNsfw = false; + } img.DetailUrl = GetDetailPageUrl(img); img.Date = post.Attribute("created_at")?.Value.ToDateTime(); if (img.Date == null) img.DateString = post.Attribute("created_at")?.Value; @@ -185,7 +196,7 @@ public async Task GetRealPageImagesAsyncFromXml2(SearchPara para, img.Height = post.GetXIntValue("height"); img.Uploader = post.GetXStringValue("author"); img.Source = post.GetXStringValue("source"); - img.IsExplicit = post.GetXStringValue("rating") != "safe"; + img.IsNsfw = post.GetXStringValue("rating") != "general"; img.DetailUrl = GetDetailPageUrl(img); var dateStr = post.GetXStringValue("created_at"); img.Date= dateStr.ToDateTime(); @@ -239,7 +250,12 @@ public async Task GetRealPageImagesAsyncFromJson(SearchPara para, { var net = Net.CloneWithCookie(); - var list = await net.GetJsonAsync(GetPageQuery(para), token: token); + var p = GetPageQuery(para); + //if (para.Site is DanbooruSite) + //{ + // p = "https://danbooru.donmai.us/posts.json?api_key=PzRGhnUwMjDHpgYmGqPtHwsS&login=plusky&page=1&limit=60&tags="; + //} + var list = await net.GetJsonAsync(p,saveListOriginalString:true, token: token); SearchedPage GetImgsFromJson() { @@ -259,7 +275,7 @@ SearchedPage GetImgsFromJson() foreach (var tag in $"{item.tag_string}".Split(' ').SkipWhile(string.IsNullOrWhiteSpace)) img.Tags.Add(tag.Trim()); - img.IsExplicit = $"{item.rating}" == "e"; + img.IsNsfw = $"{item.rating}" != "s"; img.DetailUrl = GetDetailPageUrl(img); img.Date = $"{item.created_at}".ToDateTime(); if (img.Date == null) img.DateString = $"{item.created_at}"; diff --git a/MoeLoaderP.Core/Sites/CustomSite.cs b/MoeLoaderP.Core/Sites/CustomSite.cs index bed8ead..dbc5a11 100644 --- a/MoeLoaderP.Core/Sites/CustomSite.cs +++ b/MoeLoaderP.Core/Sites/CustomSite.cs @@ -30,7 +30,7 @@ public CustomSite(CustomSiteConfig config) } - public override bool VerifyCookieAndSave(CookieCollection ccol) + public override bool VerifyCookie(CookieCollection ccol) { return CustomConfig.CookieLoginAuthKey == null || ccol.Any(cookie => cookie.Name.Equals(CustomConfig.CookieLoginAuthKey, StringComparison.OrdinalIgnoreCase)); } @@ -71,6 +71,7 @@ public async Task AddCat() var url = item.PageUrl ?? CustomConfig.HomeUrl; var html = await net.GetHtmlAsync(url); var nodes = html.DocumentNode.SelectNodes(item.Menus.Path); + if(nodes == null)break; foreach (var node in nodes) { var cat = new CustomCategory(); @@ -129,8 +130,10 @@ public override async Task GetRealPageAsync(SearchPara para, Cance var rapi = api.Replace("{pagenum}", $"{para.PageIndex}").Replace("{pagenum-1}", $"{para.PageIndex - 1}"); var html = await net.GetHtmlAsync(rapi, token: token); if (html == null) return null; - var moes = new SearchedPage(); - moes.OriginString = new StringBuilder(html.Text); + var moes = new SearchedPage + { + OriginString = new StringBuilder(html.Text) + }; var pa = cat.OverridePagePara ?? CustomConfig.PagePara; var list = (HtmlNodeCollection) html.DocumentNode.GetValue(pa.ImagesList); @@ -225,19 +228,19 @@ public async Task GetNewItems(string url, MoeItem father, CustomPagePa public MoeItem GetChildrenItem(HtmlNode img, CustomPagePara pa, MoeItem father) { - var newMoeitem = new MoeItem(this, father.Para); + var newMoeItem = new MoeItem(this, father.Para); if (pa.DetailImageItemOriginUrlFromDetailImagesList != null) { var imgurl = img.GetValue(pa.DetailImageItemOriginUrlFromDetailImagesList); if (imgurl != null) - newMoeitem.Urls.Add(DownloadTypeEnum.Origin, imgurl, referer: pa.DetailImageItemOriginUrlFromDetailImagesList.Referer); + newMoeItem.Urls.Add(DownloadTypeEnum.Origin, imgurl, referer: pa.DetailImageItemOriginUrlFromDetailImagesList.Referer); } if (pa.DetailImageItemThumbnailUrlFromDetailImagesList != null) { var imgurl = img.GetValue(pa.DetailImageItemThumbnailUrlFromDetailImagesList); if (imgurl != null) - newMoeitem.Urls.Add(DownloadTypeEnum.Thumbnail, imgurl, + newMoeItem.Urls.Add(DownloadTypeEnum.Thumbnail, imgurl, referer: pa.DetailImageItemThumbnailUrlFromDetailImagesList.Referer); } @@ -246,15 +249,15 @@ public MoeItem GetChildrenItem(HtmlNode img, CustomPagePara pa, MoeItem father) var imgurl = img.GetValue(pa.DetailImageItemDetailUrlFromDetailImagesList); if (imgurl != null) { - newMoeitem.DetailUrl = $"{imgurl}"; + newMoeItem.DetailUrl = $"{imgurl}"; var url = new UrlInfo(DownloadTypeEnum.Origin, "", resolveUrlFunc: (item, url, token) => GetDetailLv2(pa, item, url, token)); - newMoeitem.Urls.Add(url); + newMoeItem.Urls.Add(url); } } - return newMoeitem; + return newMoeItem; } public async Task GetDetailLv2(CustomPagePara pa, MoeItem currentItem, UrlInfo urlinfo, CancellationToken token) diff --git a/MoeLoaderP.Core/Sites/CustomSiteConfig.cs b/MoeLoaderP.Core/Sites/CustomSiteConfig.cs index ba5972c..f525c0a 100644 --- a/MoeLoaderP.Core/Sites/CustomSiteConfig.cs +++ b/MoeLoaderP.Core/Sites/CustomSiteConfig.cs @@ -44,6 +44,13 @@ public class CustomLv2MenuItem public class CustomSiteConfigList : ObservableCollection { + public void Adds( CustomSiteConfig[] items) + { + foreach (var item in items) + { + Add(item); + } + } } public class CustomCategory : Category @@ -161,4 +168,10 @@ public enum CustomXpathMode Attribute, InnerText, Node +} + +public enum CustomSiteType +{ + Html, + Booru, } \ No newline at end of file diff --git a/MoeLoaderP.Core/Sites/DanbooruSite.cs b/MoeLoaderP.Core/Sites/DanbooruSite.cs new file mode 100644 index 0000000..deb7e24 --- /dev/null +++ b/MoeLoaderP.Core/Sites/DanbooruSite.cs @@ -0,0 +1,76 @@ +using System; +using System.Net; +using System.Threading; +using System.Threading.Tasks; + +namespace MoeLoaderP.Core.Sites; + +/// +/// danbooru.donmai.us fixed 2022.1.26 +/// +public class DanbooruSite : BooruSite +{ + public override string HomeUrl => "https://danbooru.donmai.us"; + public override string DisplayName => "Danbooru"; + public override string ShortName => "danbooru"; + + public override SiteTypeEnum SiteType => SiteTypeEnum.Json; + + public DanbooruSite() + { + Config.IsSupportAccount = true; + Config.ImageOrders.Add("最热", ImageOrderBy.Popular); + LoginPageUrl = "https://danbooru.donmai.us/login"; + } + public override bool VerifyCookie(CookieCollection ccol) + { + foreach (Cookie cookie in ccol) + { + if (cookie.Name.Equals("_danbooru2_session", StringComparison.OrdinalIgnoreCase)) + { + SiteSettings.SetSetting("_danbooru2_session", cookie.Value); + return true; + } + } + + return false; + } + + public override string GetHintQuery(SearchPara para) + { + return + $"{HomeUrl}/autocomplete?search%5Bquery%5D={para.Keyword.ToEncodedUrl()}&search%5Btype%5D=tag_query&version=1&limit=20"; + } + + public override string GetPageQuery(SearchPara para) + { + var r18 = para.IsShowExplicit + ? (para.IsShowExplicitOnly ? "%20rating:explicit" : "") + : "%20rating:safe"; + return + $"{HomeUrl}/posts.json?page={para.PageIndex}&limit={para.CountLimit}&tags={para.Keyword.ToEncodedUrl()}{r18}"; + } + + public override string GetDetailPageUrl(MoeItem item) + { + return $"{HomeUrl}/posts/{item.Id}"; + } + + public override async Task GetAutoHintItemsAsync(SearchPara para, CancellationToken token) + { + var list = new AutoHintItems(); + if (Net == null) Login(); + if (Net == null) return null; + var net = Net.CloneWithCookie(); + var json = await net.GetJsonAsync(GetHintQuery(para), token: token); + foreach (var item in Ex.GetList(json)) + { + list.Add(new AutoHintItem + { + Word = $"{item.value}", + Count = $"{item.post_count}" + }); + } + return list; + } +} \ No newline at end of file diff --git a/MoeLoaderP.Core/Sites/DeviantartSite.cs b/MoeLoaderP.Core/Sites/DeviantartSite.cs index 12ad6ff..d46b685 100644 --- a/MoeLoaderP.Core/Sites/DeviantartSite.cs +++ b/MoeLoaderP.Core/Sites/DeviantartSite.cs @@ -25,7 +25,7 @@ public DeviantartSite() public override string DisplayName => "Deviantart"; public override string ShortName => "deviantart"; - public override bool VerifyCookieAndSave(CookieCollection ccol) + public override bool VerifyCookie(CookieCollection ccol) { var b = false; foreach (Cookie cookie in ccol) @@ -79,8 +79,8 @@ public override async Task GetRealPageAsync(SearchPara para, Cance } if (!para.PageIndexCursor.IsEmpty()) pairs.Add("cursor", para.PageIndexCursor); - var json = await net.GetJsonAsync($"{HomeUrl}{api}", pairs, true, - token); + var json = await net.GetJsonAsync($"{HomeUrl}{api}", pairs, true, true, + token:token); foreach (var devi in Ex.GetList(json.deviations)) { if (!$"{devi.type}".Equals("image", StringComparison.OrdinalIgnoreCase)) continue; diff --git a/MoeLoaderP.Core/Sites/GelbooruSite.cs b/MoeLoaderP.Core/Sites/GelbooruSite.cs index 6bd431f..cde6aaa 100644 --- a/MoeLoaderP.Core/Sites/GelbooruSite.cs +++ b/MoeLoaderP.Core/Sites/GelbooruSite.cs @@ -1,4 +1,5 @@ using System; +using System.Net; using System.Threading; using System.Threading.Tasks; @@ -12,6 +13,24 @@ public class GelbooruSite : BooruSite public override string HomeUrl => "https://gelbooru.com"; public override string DisplayName => "Gelbooru"; public override string ShortName => "gelbooru"; + + public GelbooruSite() + { + Config.IsSupportAccount = true; + LoginPageUrl = "https://gelbooru.com/index.php?page=account&s=login&code=00"; + } + public override bool VerifyCookie(CookieCollection ccol) + { + foreach (Cookie cookie in ccol) + { + if (cookie.Name.Equals("user_id", StringComparison.OrdinalIgnoreCase)) + { + return true; + } + } + + return false; + } public override SiteTypeEnum SiteType => SiteTypeEnum.Xml2; public override Func GetDetailTaskFunc { get; set; } = GetDetailTask; @@ -28,8 +47,11 @@ public override string GetHintQuery(SearchPara para) public override string GetPageQuery(SearchPara para) { + var r18 = para.IsShowExplicit + ? (para.IsShowExplicitOnly ? "%20rating%3Aexplicit" : "") + : "%20rating%3Ageneral"; return - $"{HomeUrl}/index.php?page=dapi&s=post&q=index&pid={para.PageIndex - 1}&limit={para.CountLimit}&tags={para.Keyword.ToEncodedUrl()}"; + $"{HomeUrl}/index.php?page=dapi&s=post&q=index&pid={para.PageIndex - 1}&limit={para.CountLimit}&tags={para.Keyword.ToEncodedUrl()}{r18}"; } public override async Task GetAutoHintItemsAsync(SearchPara para, CancellationToken token) diff --git a/MoeLoaderP.Core/Sites/KonachanSite.cs b/MoeLoaderP.Core/Sites/KonachanSite.cs index 4bf677c..5d120fe 100644 --- a/MoeLoaderP.Core/Sites/KonachanSite.cs +++ b/MoeLoaderP.Core/Sites/KonachanSite.cs @@ -27,16 +27,19 @@ public override async Task GetRealPageAsync(SearchPara para, Cance { //var homeUrl = para.IsShowExplicit ? HomeUrl : SafeHomeUrl; var homeUrl = HomeUrl; + var r18 = para.IsShowExplicit + ? (para.IsShowExplicitOnly ? "%20rating:explicit" : "") + : "%20rating:safe"; var pairs = new Pairs { {"page", $"{para.PageIndex}"}, {"limit", $"{para.CountLimit}"}, - {"tags", para.Keyword.ToEncodedUrl()} + {"tags", $"{para.Keyword.ToEncodedUrl()}{r18}" }, }; var query = $"{homeUrl}/post.json{pairs.ToPairsString()}"; var net = new NetOperator(Settings, this); - var json = await net.GetJsonAsync(query, token: token); + var json = await net.GetJsonAsync(query, saveListOriginalString:true, token: token); var imageItems = new SearchedPage(); foreach (var item in Ex.GetList(json)) { @@ -50,7 +53,7 @@ public override async Task GetRealPageAsync(SearchPara para, Cance foreach (var tag in $"{item.tags}".Split(' ').SkipWhile(string.IsNullOrWhiteSpace)) img.Tags.Add(tag.Trim()); - img.IsExplicit = $"{item.rating}" == "e"; + img.IsNsfw = $"{item.rating}" != "s"; img.DetailUrl = $"{homeUrl}/post/show/{img.Id}"; img.Date = $"{item.created_at}".ToDateTime(); if (img.Date == null) img.DateString = $"{item.created_at}"; diff --git a/MoeLoaderP.Core/Sites/LolibooruSite.cs b/MoeLoaderP.Core/Sites/LolibooruSite.cs index e7860e4..91affe7 100644 --- a/MoeLoaderP.Core/Sites/LolibooruSite.cs +++ b/MoeLoaderP.Core/Sites/LolibooruSite.cs @@ -16,7 +16,10 @@ public override string GetHintQuery(SearchPara para) public override string GetPageQuery(SearchPara para) { + var r18 = para.IsShowExplicit + ? (para.IsShowExplicitOnly ? "%20rating:explicit" : "") + : "%20rating:safe"; return - $"{HomeUrl}/post.xml?page={para.PageIndex}&limit={para.CountLimit}&tags={para.Keyword.ToEncodedUrl()}"; + $"{HomeUrl}/post.xml?page={para.PageIndex}&limit={para.CountLimit}&tags={para.Keyword.ToEncodedUrl()}{r18}"; } } \ No newline at end of file diff --git a/MoeLoaderP.Core/Sites/MoeSite.cs b/MoeLoaderP.Core/Sites/MoeSite.cs index efcc8f3..242e3e1 100644 --- a/MoeLoaderP.Core/Sites/MoeSite.cs +++ b/MoeLoaderP.Core/Sites/MoeSite.cs @@ -30,6 +30,7 @@ public abstract class MoeSite : BindingObject public abstract string ShortName { get; } public virtual Uri Icon => new($"/Assets/SiteIcon/{ShortName}.ico", UriKind.Relative); + public Categories Lv2Cat { get; set; } @@ -104,7 +105,7 @@ public bool IsUserLogin set => SetField(ref _isUserLogin, value, nameof(IsUserLogin)); } - public virtual bool VerifyCookieAndSave(CookieCollection ccol) + public virtual bool VerifyCookie(CookieCollection ccol) { return false; } diff --git a/MoeLoaderP.Core/Sites/PixivSite.cs b/MoeLoaderP.Core/Sites/PixivSite.cs index 80bdf17..4a29e50 100644 --- a/MoeLoaderP.Core/Sites/PixivSite.cs +++ b/MoeLoaderP.Core/Sites/PixivSite.cs @@ -81,6 +81,8 @@ public void InitCat() Config.IsSupportResolution = true; Config.IsSupportScore = true; Config.IsSupportAccount = true; + Config.IsSupportRating = false; + Lv2Cat = new Categories(Config); // 最新/搜索 + 作者ID搜索 @@ -102,7 +104,7 @@ public void InitCat() rank.SubCategories.EachSubAdds("综合", "插画", "漫画", "动图"); } - public override bool VerifyCookieAndSave(CookieCollection ccol) + public override bool VerifyCookie(CookieCollection ccol) { var b = false; foreach (Cookie cookie in ccol) diff --git a/MoeLoaderP.Core/Sites/SafebooruSite.cs b/MoeLoaderP.Core/Sites/SafebooruSite.cs index a2fae16..dcfbe5b 100644 --- a/MoeLoaderP.Core/Sites/SafebooruSite.cs +++ b/MoeLoaderP.Core/Sites/SafebooruSite.cs @@ -14,6 +14,11 @@ public class SafebooruSite : BooruSite public override string UrlPre => ""; + public SafebooruSite() + { + Config.IsSupportRating = false; + } + public override string GetHintQuery(SearchPara para) { return $"{HomeUrl}/index.php?page=dapi&s=tag&q=index&order=name&limit=8&name={para.Keyword.ToEncodedUrl()}"; diff --git a/MoeLoaderP.Core/Sites/SankakuChanSite.cs b/MoeLoaderP.Core/Sites/SankakuChanSite.cs index 22486d3..06869fc 100644 --- a/MoeLoaderP.Core/Sites/SankakuChanSite.cs +++ b/MoeLoaderP.Core/Sites/SankakuChanSite.cs @@ -89,7 +89,7 @@ public NetOperator CloneNet() return net; } - public override bool VerifyCookieAndSave(CookieCollection ccol) + public override bool VerifyCookie(CookieCollection ccol) { foreach (Cookie cookie in ccol) if (cookie.Name.Equals("accessToken", StringComparison.OrdinalIgnoreCase)) @@ -127,7 +127,9 @@ public async Task GetNewAndTagAsync(SearchPara para, CancellationT var safekw = ConbimeMultiKeywords("rating:safe", para.Keyword.Trim().Replace(" ", "_")); var explicitkw = para.Keyword.Trim().Replace(" ", "_"); - var kw = para.IsShowExplicit == false ? safekw : explicitkw; + var kw = para.IsShowExplicit == false + ? safekw + : (para.IsShowExplicitOnly ? ConbimeMultiKeywords("rating:e", para.Keyword.Trim().Replace(" ", "_")) : explicitkw); var pairs = new Pairs { @@ -189,7 +191,7 @@ public async Task GetNewAndTagAsync(SearchPara para, CancellationT img.Urls.Add(1, $"{jitem.preview_url}", BetaApi); img.Urls.Add(2, $"{jitem.sample_url}", BetaApi); img.Urls.Add(4, $"{jitem.file_url}", $"{BetaApi}/post/show/{img.Id}"); - img.IsExplicit = $"{jitem.rating}" != "s"; + img.IsNsfw = $"{jitem.rating}" != "s"; img.Date = $"{jitem.created_at?.s}".ToDateTime(); img.Uploader = $"{jitem.author?.name}"; img.DetailUrl = $"{BetaApi}/post/show/{img.Id}"; diff --git a/MoeLoaderP.Core/Sites/SankakuIdolSite.cs b/MoeLoaderP.Core/Sites/SankakuIdolSite.cs index 213281d..6175601 100644 --- a/MoeLoaderP.Core/Sites/SankakuIdolSite.cs +++ b/MoeLoaderP.Core/Sites/SankakuIdolSite.cs @@ -90,7 +90,7 @@ public override async Task GetRealPageAsync(SearchPara para, Cance img.DetailUrl = $"{HomeUrl}/post/show/{img.Id}"; img.Date = $"{item.created_at?.s}".ToDateTime(); foreach (var tag in Ex.GetList(item.tags)) img.Tags.Add($"{tag.name}"); - img.IsExplicit = $"{item.rating}" == "e"; + img.IsNsfw = $"{item.rating}" == "e"; img.Urls.Add(DownloadTypeEnum.Thumbnail, $"{https}{item.preview_url}", img.DetailUrl); img.Urls.Add(DownloadTypeEnum.Medium, $"{https}{item.sample_url}", img.DetailUrl); img.Urls.Add(DownloadTypeEnum.Origin, $"{https}{item.file_url}", img.DetailUrl); diff --git a/MoeLoaderP.Core/Sites/WorldCosplaySite.cs b/MoeLoaderP.Core/Sites/WorldCosplaySite.cs index a7b26df..4034a13 100644 --- a/MoeLoaderP.Core/Sites/WorldCosplaySite.cs +++ b/MoeLoaderP.Core/Sites/WorldCosplaySite.cs @@ -26,7 +26,7 @@ public WorldCosplaySite() public override async Task GetRealPageAsync(SearchPara para, CancellationToken token) { - Net ??= new NetOperator(); + Net ??= new NetOperator(Settings, this); //http://worldcosplay.net/api/photo/list?page=3&limit=2&sort=created_at&direction=descend var url = $"{HomeUrl}/api/photo/list"; diff --git a/MoeLoaderP.Core/Sites/YandeSite.cs b/MoeLoaderP.Core/Sites/YandeSite.cs index 2485dab..d5a99c9 100644 --- a/MoeLoaderP.Core/Sites/YandeSite.cs +++ b/MoeLoaderP.Core/Sites/YandeSite.cs @@ -18,7 +18,7 @@ public YandeSite() Config.IsSupportAccount = true; LoginPageUrl = "https://yande.re/user/login"; } - public override bool VerifyCookieAndSave(CookieCollection ccol) + public override bool VerifyCookie(CookieCollection ccol) { return ccol.Any(cookie => cookie.Name.Equals("user_id", StringComparison.OrdinalIgnoreCase)); } @@ -35,12 +35,19 @@ public override string GetHintQuery(SearchPara para) public override string GetPageQuery(SearchPara para) { + var r18 = ""; + if (!para.IsShowExplicit) + { + r18 = "%20rating%3As"; + + } var pairs = new Pairs { {"page", $"{para.PageIndex}"}, {"limit", $"{para.CountLimit}"}, - {"tags", para.Keyword.ToEncodedUrl()} + {"tags", $"{para.Keyword.ToEncodedUrl()}{r18}" } }; + return $"{HomeUrl}/post.xml{pairs.ToPairsString()}"; } } \ No newline at end of file diff --git a/MoeLoaderP.Core/Sites/YuriimgSite.cs b/MoeLoaderP.Core/Sites/YuriimgSite.cs index e03743a..3586663 100644 --- a/MoeLoaderP.Core/Sites/YuriimgSite.cs +++ b/MoeLoaderP.Core/Sites/YuriimgSite.cs @@ -116,8 +116,8 @@ public override async Task GetRealPageAsync(SearchPara para, Cance foreach (var post in json.posts) { var img = new MoeItem(this, para); - img.IsExplicit = $"{post.rating}" == "e"; - if (SiteSettings.GetCookieContainer() == null && img.IsExplicit) continue; + img.IsNsfw = $"{post.rating}" == "e"; + if (SiteSettings.GetCookieContainer() == null && img.IsNsfw) continue; img.Id = $"{post.pid}".ToInt(); img.Sid = $"{post.id}"; img.Width = $"{post.width}".ToInt(); diff --git a/MoeLoaderP.Core/Sites/ZeroChanSite.cs b/MoeLoaderP.Core/Sites/ZeroChanSite.cs index b385278..ec1a116 100644 --- a/MoeLoaderP.Core/Sites/ZeroChanSite.cs +++ b/MoeLoaderP.Core/Sites/ZeroChanSite.cs @@ -1,4 +1,5 @@ -using System.Text.RegularExpressions; +using System; +using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; @@ -65,8 +66,8 @@ public override async Task GetRealPageAsync(SearchPara para, Cance { var img = new MoeItem(this, para); var mo = imgNode.SelectSingleNode(".//b")?.InnerText?.Trim(); - if (mo?.ToLower().Trim().Contains("members only") == true) continue; - var strId = imgNode.SelectSingleNode("a").Attributes["href"].Value; + if (mo?.ToLower().Trim().Contains("members only", StringComparison.OrdinalIgnoreCase) == true) continue; + var strId = imgNode.SelectSingleNode(".//a")?.Attributes["href"]?.Value; var fav = imgNode.SelectSingleNode("a/span")?.InnerText; if (!fav.IsEmpty()) img.Score = Regex.Replace(fav, @"[^0-9]+", "")?.ToInt() ?? 0; var imgHref = imgNode.SelectSingleNode(".//img"); @@ -104,7 +105,7 @@ public override async Task GetRealPageAsync(SearchPara para, Cance img.Description = title; img.Title = title; - img.Id = strId[1..].ToInt(); + if(!strId.IsEmpty()) img.Id = strId[1..].ToInt(); img.Urls.Add(DownloadTypeEnum.Thumbnail, previewUrl, HomeUrl); img.Urls.Add(DownloadTypeEnum.Medium, sampleUrl, HomeUrl); diff --git a/MoeLoaderP.Wpf/.vs/MoeLoaderP/v15/Server/sqlite3/db.lock b/MoeLoaderP.Wpf/.vs/MoeLoaderP/v15/Server/sqlite3/db.lock deleted file mode 100644 index e69de29..0000000 diff --git a/MoeLoaderP.Wpf/.vs/MoeLoaderP/v15/Server/sqlite3/storage.ide b/MoeLoaderP.Wpf/.vs/MoeLoaderP/v15/Server/sqlite3/storage.ide deleted file mode 100644 index 56758a8..0000000 Binary files a/MoeLoaderP.Wpf/.vs/MoeLoaderP/v15/Server/sqlite3/storage.ide and /dev/null differ diff --git a/MoeLoaderP.Wpf/.vs/MoeLoaderP/v15/Server/sqlite3/storage.ide-shm b/MoeLoaderP.Wpf/.vs/MoeLoaderP/v15/Server/sqlite3/storage.ide-shm deleted file mode 100644 index 9a0fc5e..0000000 Binary files a/MoeLoaderP.Wpf/.vs/MoeLoaderP/v15/Server/sqlite3/storage.ide-shm and /dev/null differ diff --git a/MoeLoaderP.Wpf/.vs/MoeLoaderP/v15/Server/sqlite3/storage.ide-wal b/MoeLoaderP.Wpf/.vs/MoeLoaderP/v15/Server/sqlite3/storage.ide-wal deleted file mode 100644 index d026380..0000000 Binary files a/MoeLoaderP.Wpf/.vs/MoeLoaderP/v15/Server/sqlite3/storage.ide-wal and /dev/null differ diff --git a/MoeLoaderP.Wpf/Assets/Lang/zh-CN.xaml b/MoeLoaderP.Wpf/Assets/Lang/zh-CN.xaml index e6fab43..401babe 100644 --- a/MoeLoaderP.Wpf/Assets/Lang/zh-CN.xaml +++ b/MoeLoaderP.Wpf/Assets/Lang/zh-CN.xaml @@ -17,8 +17,8 @@ 参数 起始搜索页码 每页图片数量 - 显示R-18图片 - 仅显示R-18图片 + 显示限制级图片 + 仅显示限制级图片 过滤掉此分辨率以下图片(宽/高) 图片方向 任意 diff --git a/MoeLoaderP.Wpf/Assets/MoeResource.xaml b/MoeLoaderP.Wpf/Assets/MoeResource.xaml index 6beb222..7230718 100644 --- a/MoeLoaderP.Wpf/Assets/MoeResource.xaml +++ b/MoeLoaderP.Wpf/Assets/MoeResource.xaml @@ -77,7 +77,7 @@ #FF00B9FF - + @@ -253,6 +253,9 @@ + + + @@ -582,15 +585,20 @@ - + + + - - - - - - - - - - - - -