示例#1
0
        internal HtmlPage(WebBytes wb, WebString prelimContent) : base(wb.Location)
        {
            HeadersCharset = wb.CharacterSet;
            EncHeaders     = prelimContent.UsedEncoding;

            DetermineEncoding(wb.Data, prelimContent.Document);
        }
示例#2
0
        /// <summary>
        /// Get post associated with post number.
        /// </summary>
        /// <returns><see cref="ChanPost">ChanPost</see> detailing the post</returns>
        ///
        /// <exception cref="ArgumentNullException">Thrown if board is null.</exception>
        /// <exception cref="ArgumentException">Thrown if board is empty or whitespace.</exception>
        /// <exception cref="ArgumentOutOfRangeException">Thrown if postNo &lt= 0.</exception>
        ///
        /// <param name="board">Board where post is located.</param>
        /// <param name="postNo">Post number.</param>
        public static ChanPost GetPost(string board, int postNo)
        {
            board.ThrowIfNullOrWhiteSpace("board");
            if (postNo < 1)
            {
                throw new ArgumentOutOfRangeException("post", "Cannot be 0 or negative.");
            }

            var jsonReq = string.Format("http://archive.moe/_/api/chan/post/?board={0}&num={1}", board, postNo);
            var json    = WebString.Download(jsonReq);

            if (!json.Success)
            {
                return(new ChanPost(json));
            }

            dynamic postJson = JsonConvert.DeserializeObject(json.Document);
            int     threadNo = postJson.thread_num;
            string  subject  = postJson.title;
            string  comment  = postJson.comment_sanitized;

            return(new ChanPost(json.Location,
                                board, ChanTools.GetBoardName(board),
                                threadNo, postNo,
                                subject, comment));
        }
示例#3
0
        public WeatherConditions GetConditions(WeatherLocation location)
        {
            if (location == null)
            {
                throw new ArgumentNullException(nameof(location));
            }
            if (!location.IsValidQuery)
            {
                throw new ArgumentException("WeatherLocation must have a valid value.", nameof(location));
            }

            var queryResult = WebString.Download(MakeQuery(location));

            if (!queryResult.Success)
            {
                return(new WeatherConditions(queryResult));
            }

            var json    = JObject.Parse(queryResult.Document);
            var message = (string)json["message"];

            if (string.IsNullOrEmpty(message))
            {
                return(new WeatherConditions(queryResult.Location, json));
            }
            else
            {
                var ex = new JsonErrorException(message);
                return(new WeatherConditions(queryResult.Location, ex));
            }
        }
示例#4
0
        FetcherResult Load(Uri uri, bool useCookies, int redirects, string previousPage)
        {
            var req = SetupRequest(uri, useCookies);
            var wb  = WebBytes.Create(req, MaxSizeHtml, MaxSizeNonHtml);

            if (wb.ContentIsHtml)
            {
                var page = WebString.Create(wb, EncHelp.Windows1252);

                Uri refreshUrl;
                if (redirects < MaxRefreshes &&
                    TryGetMetaRefresh(page, out refreshUrl) &&
                    VerifyRefresh(page.Location, refreshUrl))
                {
                    // If during the redirects we get a different page/HTML string, refrain from following more
                    // redirects. It probably means we've arrived, but only more real world testing will tell us
                    // if that's true.
                    // Otherwise keep trying to follow the redirects.
                    if (redirects == 0 || page.Document == previousPage)
                    {
                        return(Load(refreshUrl, useCookies, (redirects + 1), page.Document));
                    }
                }

                return(new FetcherResult(wb, page));
            }
            // Silently handle cookie exceptions, Mono/.NET can be very strict with which cookies it accepts.
            if (!wb.Success && wb.Exception.InnerException is CookieException)
            {
                return(Load(uri, false, redirects, previousPage));
            }

            // If either not HTML or there was an error in getting the resource, return as-is.
            return(new FetcherResult(wb));
        }
示例#5
0
        /// <summary>
        /// Get info of a Danbooru post.
        /// </summary>
        /// <returns><see cref="DanboPost">DanboPost</see> detailing a post.</returns>
        /// <exception cref="ArgumentOutOfRangeException">Thrown if postNo is &lt;= 0.</exception>
        /// <param name="postNo">Post number.</param>
        public static DanboPost GetPostInfo(int postNo)
        {
            if (postNo < 1)
            {
                throw new ArgumentOutOfRangeException(nameof(postNo), "Can't be 0 or negative.");
            }

            var jsonReq = string.Format("https://danbooru.donmai.us/posts/{0}.json", postNo);
            var json    = WebString.Download(jsonReq);

            if (!json.Success)
            {
                return(new DanboPost(json));
            }

            dynamic postJson   = JsonConvert.DeserializeObject(json.Document);
            string  copyrights = postJson.tag_string_copyright;
            string  characters = postJson.tag_string_character;
            string  artists    = postJson.tag_string_artist;
            string  general    = postJson.tag_string_general;
            string  meta       = postJson.tag_string_meta;
            string  all        = postJson.tag_string;
            string  rating     = postJson.rating;

            return(new DanboPost(json.Location, postNo,
                                 copyrights, characters, artists, general, meta, all, rating));
        }
示例#6
0
        /// <summary>
        /// Get post associated with post number.
        /// </summary>
        /// <returns><see cref="ChanPost">ChanPost</see> detailing the post.</returns>
        ///
        /// <exception cref="ArgumentNullException">Thrown if board is null.</exception>
        /// <exception cref="ArgumentException">Thrown if board is empty or whitespace.</exception>
        /// <exception cref="ArgumentOutOfRangeException">Thrown if threadNo and/or postNo &lt= 0.</exception>
        ///
        /// <param name="board">Board where thread/post is located.</param>
        /// <param name="threadNo">Thread number.</param>
        /// <param name="postNo">Post number.</param>
        public static ChanPost GetPost(string board, int threadNo, int postNo)
        {
            board.ThrowIfNullOrWhiteSpace("board");
            if (threadNo < 1)
            {
                throw new ArgumentOutOfRangeException("thread", "Cannot be 0 or negative.");
            }
            else if (postNo < 1)
            {
                throw new ArgumentOutOfRangeException("post", "Cannot be 0 or negative.");
            }

            var jsonReq = string.Format("http://a.4cdn.org/{0}/res/{1}.json", board, threadNo);
            var json    = WebString.Download(jsonReq);

            if (!json.Success)
            {
                return(new ChanPost(json));
            }

            dynamic threadJson = JsonConvert.DeserializeObject(json.Document);
            string  subject    = null;
            string  comment    = null;

            // Simple linear search, seems fast enough for the 100s of posts it needs to look through.
            foreach (var post in threadJson.posts)
            {
                if (post.no == postNo)
                {
                    subject = post.sub;
                    if (!string.IsNullOrEmpty(subject))
                    {
                        subject = HttpUtility.HtmlDecode(subject);
                    }

                    comment = post.com;
                    if (!string.IsNullOrEmpty(comment))
                    {
                        comment = Fix4chanPost(comment);
                    }

                    break;
                }
            }

            return(new ChanPost(json.Location,
                                board, ChanTools.GetBoardName(board),
                                threadNo, postNo,
                                subject, comment));
        }
示例#7
0
        public static SearchResults Search(string query)
        {
            if (query == null)
            {
                throw new ArgumentNullException(nameof(query));
            }

            var results = WebString.Download(GoogleUrl(query));

            if (!results.Success)
            {
                return(new SearchResults(results));
            }

            var matches       = resultsRegexp.Matches(results.Document);
            var parsedResults = ParseMatches(matches);

            return(new SearchResults(results, Deduplication(parsedResults)));
        }
示例#8
0
        /// <summary>
        /// Get info of a Gelbooru post.
        /// </summary>
        /// <returns><see cref="BooruPost">BooruPost</see> detailing a post.</returns>
        /// <exception cref="ArgumentOutOfRangeException">Thrown if postNo is &lt;= 0.</exception>
        /// <param name="postNo">Post number.</param>
        public static BooruPost GetPostInfo(int postNo)
        {
            if (postNo < 1)
            {
                throw new ArgumentOutOfRangeException(nameof(postNo), "Can't be 0 or negative.");
            }

            var xmlReq = string.Format("https://gelbooru.com/index.php?page=dapi&s=post&q=index&id={0}", postNo);
            var xml    = WebString.Download(xmlReq);

            if (!xml.Success)
            {
                return(new BooruPost(xml));
            }

            var    postXml = XElement.Parse(xml.Document).Element("post");
            string tags    = postXml.Attribute("tags").Value;
            string rated   = postXml.Attribute("rating").Value;

            return(new BooruPost(xml.Location, postNo, tags, rated));
        }
示例#9
0
        static bool TryGetMetaRefresh(WebString page, out Uri refreshUrl)
        {
            string metaRefresh = HtmlTagExtract.GetMetaRefresh(page.Document);

            if (metaRefresh != null)
            {
                // Relative refresh URL.
                // Try this one first, because creating an absolute URL out of a relative one starting with a '/' can
                // lead to it being interpreted as a file:/// URI.
                if (Uri.TryCreate(page.Location, metaRefresh, out refreshUrl))
                {
                    return(true);
                }
                // Absolute refresh URL.
                if (Uri.TryCreate(metaRefresh, UriKind.Absolute, out refreshUrl))
                {
                    return(true);
                }
            }

            refreshUrl = null;
            return(false);
        }
示例#10
0
 internal FetcherResult(WebBytes bytes, WebString page)
 {
     Bytes = bytes;
     Page  = new HtmlPage(bytes, page);
 }