diff --git a/GChan/Controllers/MainController.cs b/GChan/Controllers/MainController.cs index 63b1b00..bdec53e 100644 --- a/GChan/Controllers/MainController.cs +++ b/GChan/Controllers/MainController.cs @@ -352,7 +352,6 @@ private void ScanRoutine() var idCodeMatch = board.SiteName switch { Board_4Chan.SITE_NAME => Regex.Match(url, Thread_4Chan.ID_CODE_REGEX), - Board_8Kun.SITE_NAME => Regex.Match(url, Thread_8Kun.ID_CODE_REGEX), _ => null, }; diff --git a/GChan/GChan.csproj b/GChan/GChan.csproj index 4632341..37468a9 100644 --- a/GChan/GChan.csproj +++ b/GChan/GChan.csproj @@ -130,9 +130,7 @@ Resources.resx - - diff --git a/GChan/Helpers/Utils.cs b/GChan/Helpers/Utils.cs index 3bb3494..db64739 100644 --- a/GChan/Helpers/Utils.cs +++ b/GChan/Helpers/Utils.cs @@ -82,19 +82,11 @@ public static Tracker CreateNewTracker(string url) { return new Thread_4Chan(url); } - else if (Thread_8Kun.UrlIsThread(url)) - { - return new Thread_8Kun(url); - } if (Board_4Chan.UrlIsBoard(url)) { return new Board_4Chan(url); } - else if (Board_8Kun.UrlIsBoard(url)) - { - return new Board_8Kun(url); - } return null; } diff --git a/GChan/TodoList.txt b/GChan/TodoList.txt index 81d739c..d990a87 100644 --- a/GChan/TodoList.txt +++ b/GChan/TodoList.txt @@ -1,7 +1,6 @@ Todo items: Add (proper scaled) icons to all context menus. Archived thread indicator (with red text/highlight or seperate column (archived yes/no)). - Add support for 8kun.top. Asynchronous General.DownloadToDir downloads files as 0bytes empty files, fix this immediately. Make boards view a datagridview and make it use databinding. Add options to task bar right click diff --git a/GChan/Trackers/ImageLink.cs b/GChan/Trackers/ImageLink.cs index c4cef1c..480dc78 100644 --- a/GChan/Trackers/ImageLink.cs +++ b/GChan/Trackers/ImageLink.cs @@ -14,7 +14,6 @@ public class ImageLink : IDownloadable, IEquatable { /// /// For 4chan: Unix timestamp with microseconds at which the image was uploaded. - /// For 8kun: The ID of the post this image belongs to (same as No). /// public long Tim; diff --git a/GChan/Trackers/Sites/Board_8Kun.cs b/GChan/Trackers/Sites/Board_8Kun.cs deleted file mode 100644 index b047e45..0000000 --- a/GChan/Trackers/Sites/Board_8Kun.cs +++ /dev/null @@ -1,62 +0,0 @@ -using GChan.Properties; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Net; -using System.Text; -using System.Text.RegularExpressions; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; - -namespace GChan.Trackers -{ - public class Board_8Kun : Board - { - public const string SITE_NAME = "8kun"; - public const string boardRegex = @"8kun.top/[a-zA-Z0-9]*?/"; - public const string boardCodeRegex = @"(?<=(8kun.top/))[a-zA-Z0-9]*(?=(/index.html))"; - - public Board_8Kun(string url) : base(url) - { - SiteName = SITE_NAME; - - Match boardCodeMatch = Regex.Match(url, boardCodeRegex); - BoardCode = boardCodeMatch.Groups[0].Value; - - SaveTo = Path.Combine(Settings.Default.SavePath, SiteName, BoardCode); - } - - public static bool UrlIsBoard(string url) - { - return Regex.IsMatch(url, boardRegex); - } - - override public string[] GetThreadLinks() - { - string url = "http://8kun.top/" + BoardCode + "/catalog.json"; - List threadUrls = new List(); - - try - { - JArray jArray; - using (var web = Utils.CreateWebClient()) - { - string json = web.DownloadString(url); - jArray = JArray.Parse(json); - } - - threadUrls = jArray - .SelectTokens("..no") - .Select(x => "http://8kun.top/" + BoardCode + "/res/" + x + ".html") - .ToList(); - } - catch (WebException webEx) - { - logger.Error(webEx, $"Connection error trying to find threads in a board {this}."); - } - - threadCount = threadUrls.Count; - return threadUrls.ToArray(); - } - } -} diff --git a/GChan/Trackers/Sites/Thread_8Kun.cs b/GChan/Trackers/Sites/Thread_8Kun.cs deleted file mode 100644 index fb5deaa..0000000 --- a/GChan/Trackers/Sites/Thread_8Kun.cs +++ /dev/null @@ -1,203 +0,0 @@ -using GChan.Helpers; -using GChan.Properties; -using Newtonsoft.Json.Linq; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Net; -using System.Text.RegularExpressions; - -namespace GChan.Trackers -{ - public class Thread_8Kun : Thread - { - public const string threadRegex = @"8kun.top/[a-zA-Z0-9]*?/res/[0-9]*.[^0-9]*"; - public const string boardCodeRegex = @"(?<=(8kun.top/))[a-zA-Z0-9]+(?=(/res/))"; - public const string ID_CODE_REGEX = @"(?<=(res/))[0-9]+(?=(.html))"; - - public Thread_8Kun(string url) : base(url) - { - SiteName = Board_8Kun.SITE_NAME; - - //Match simplifiedThreadUrlMatch = Regex.Match(url, threadRegex); - //URL = "https://" + simplifiedThreadUrlMatch.Groups[0].Value; // simplify thread url - - Match boardCodeMatch = Regex.Match(url, boardCodeRegex); - BoardCode = boardCodeMatch.Groups[0].Value; - - Match idCodeMatch = Regex.Match(url, ID_CODE_REGEX); - ID = idCodeMatch.Groups[0].Value; - - SaveTo = Path.Combine(Settings.Default.SavePath, SiteName, BoardCode, ID); - - if (subject == null) - { - Subject = GetThreadSubject(); - } - } - - public static bool UrlIsThread(string url) - { - return Regex.IsMatch(url, threadRegex); - } - - protected override ImageLink[] GetImageLinksImpl(bool includeAlreadySaved = false) - { - string Fpath0Url(string boardcode, string tim, string ext) => $"https://8kun.top/{boardcode}/src/{tim}{ext}"; - string Fpath1Url(string tim, string ext) => $"https://8kun.top/file_store/{tim}{ext}"; - - using var webClient = Utils.CreateWebClient(); - var jsonUrl = $"http://8kun.top/{BoardCode}/res/{ID}.json"; // Thread JSON url - var json = webClient.DownloadString(jsonUrl); - var jObject = JObject.Parse(json); - var links = new List(); - - // Get the numbers of replies that have 1 or more images. - var nos = jObject.SelectTokens("posts[?(@.tim)].no").Select(x => x.Value()).ToList(); - - // Loop through each reply. - foreach (var no in nos) - { - // Get the tims, filenames and extensions of each image in this reply. - var tims = jObject.SelectTokens($"posts[?(@.no == {no})]..tim").Select(x => x.ToString()).ToList(); - var filenames = jObject.SelectTokens($"posts[?(@.no == {no})]..filename").Select(x => x.ToString()).ToList(); - var exts = jObject.SelectTokens($"posts[?(@.no == {no})]..ext").Select(x => x.ToString()).ToList(); - var fpaths = jObject.SelectTokens($"posts[?(@.no == {no})]..fpath").Select(x => x.ToString()).ToList(); - - for (int j = 0; j < tims.Count; j++) - { - if (exts[j] != "deleted") - { - var url = fpaths[j] == "0" ? - Fpath0Url(BoardCode, tims[j], exts[j]) : - Fpath1Url(tims[j], exts[j]); // "1" - - // Save image link using reply no (number) as tim because 8kun tims have letters and numbers in them. The reply number will work just fine. - links.Add(new ImageLink(no, url, filenames[j], no, this)); - } - } - } - - FileCount = links.Count; - return links.MaybeRemoveAlreadySavedLinks(includeAlreadySaved, SavedIds).ToArray(); - } - - public override void DownloadHtmlImpl() - { - var thumbs = new List(); - var htmlPage = ""; - - JObject jObject; - using (var web = Utils.CreateWebClient()) - { - htmlPage = web.DownloadString(Url); - - var jsonUrl = Url.Replace(".html", ".json"); - - var json = web.DownloadString(jsonUrl); - jObject = JObject.Parse(json); - } - - // get single images - var posts = jObject - .SelectTokens("posts[*]") - .Where(x => x["ext"] != null) - .ToList(); - - foreach (var post in posts) - { - var tim = post["tim"].ToString(); - var ext = post["ext"].ToString(); - // if(ext == ".webm") - // ext = ".jpg"; - thumbs.Add("https://8kun.top/file_store/thumb/" + post["tim"] + ext); - - htmlPage = htmlPage.Replace("https://8kun.top/file_store/thumb/" + tim + ext, "thumb/" + tim + ext); - htmlPage = htmlPage.Replace("=\"/file_store/thumb/" + tim + ext, "=\"thumb/" + tim + ext); - htmlPage = htmlPage.Replace("=\"/file_store/" + tim + ext, "=\"" + tim + ext); - htmlPage = htmlPage.Replace("https://media.8kun.top/file_store/thumb/" + tim + ext, "thumb/" + tim + ext); - htmlPage = htmlPage.Replace("https://media.8kun.top/file_store/" + tim + ext, tim + ext); - htmlPage = htmlPage.Replace("https://8kun.top/file_store/" + tim + ext, tim + ext); - } - - // get images of posts with multiple images - var extras = jObject - .SelectTokens("posts.extra_files[*]") - .Where(x => x["ext"] != null) - .ToList(); - - foreach (var extra in extras) - { - var tim = extra["tim"].ToString(); - var ext = extra["ext"].ToString(); - // if(ext == ".webm") - // ext = ".jpg"; - thumbs.Add("https://8kun.top/file_store/thumb/" + tim + ext); - - htmlPage = htmlPage.Replace("https://8kun.top/file_store/thumb/" + tim + ext, "thumb/" + tim + ext); - htmlPage = htmlPage.Replace("=\"/file_store/thumb/" + tim + ext, "=\"thumb/" + tim + ext); - htmlPage = htmlPage.Replace("=\"/file_store/" + tim + ext, "=\"" + tim + ext); - htmlPage = htmlPage.Replace("https://media.8kun.top/file_store/thumb/" + tim + ext, "thumb/" + tim + ext); - htmlPage = htmlPage.Replace("https://media.8kun.top/file_store/" + tim + ext, tim + ext); - htmlPage = htmlPage.Replace("https://8kun.top/file_store/" + tim + ext, tim + ext); - } - - htmlPage = htmlPage.Replace("=\"/", "=\"https://8kun.top/"); - - if (Settings.Default.SaveThumbnails) - { - for (int i = 0; i < thumbs.Count; i++) - { - Utils.DownloadFileIfDoesntExist(thumbs[i], SaveTo + "\\thumb"); - } - } - - if (!string.IsNullOrWhiteSpace(htmlPage)) - { - File.WriteAllText(SaveTo + "\\Thread.html", htmlPage); // save thread - } - } - - protected override string GetThreadSubject() - { - string subject = NO_SUBJECT; - - try - { - string JSONUrl = "http://8kun.top/" + BoardCode + "/res/" + ID + ".json"; - - const string SUB_HEADER = "\"sub\":\""; - const string SUB_ENDER = "\","; - const string ITEM_ENDER = "},"; - - using (var web = Utils.CreateWebClient()) - { - string rawjson = web.DownloadString(JSONUrl); - int subStartIndex = rawjson.IndexOf(SUB_HEADER); - int firstItemEnderIndex = rawjson.IndexOf(ITEM_ENDER); - - // If "sub":" was found in json then there is a subject. - if (subStartIndex >= 0 && subStartIndex < firstItemEnderIndex) - { - //Increment along the rawjson until the ending ", sequence is found, then substring it to extract the subject. - for (int i = subStartIndex; i < rawjson.Length; i++) - { - if (rawjson.Substring(i, SUB_ENDER.Length) == SUB_ENDER) - { - subject = rawjson.Substring(subStartIndex + SUB_HEADER.Length, i - (subStartIndex + SUB_HEADER.Length)); - subject = Utils.SanitiseSubject(WebUtility.HtmlDecode(subject)); - break; - } - } - } - } - } - catch - { - subject = NO_SUBJECT; - } - - return subject; - } - } -} diff --git a/README.md b/README.md index f0d59fd..3e9b4aa 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,6 @@ GChan is a fork of YChan which aims to improve stability and add extra features ### Supported Websites: * [4chan.org](http://4chan.org/) -* [8kun.top](https://8kun.top/index.html) [Pending Release] Requires .NET Framework 4.8 or higher, made with Windows Forms.