Beispiel #1
0
    private static islandInfo floodSearch(searchBlock *block, int islandIndex, int rowWidth, searchBlock *start, searchBlock *end)
    {
        //create a queue to store pending blocks to
        //be processed.
        PtrQueue queue = new PtrQueue(10000);

        queue.Push(block);
        int count = 1;

        //count how many blocks we found
        int found = 0;

        //used to detect the size and location
        //of the island.
        int minX = 0, minY = 0;
        int maxX = 0, maxY = 0;

        minX = minY = int.MaxValue;

        //process every block
        List <IntPtr> blocks = new List <IntPtr>();

        while (count != 0)
        {
            searchBlock *ptr = (searchBlock *)queue.Pop();
            count--;

            //verify not out of bounds
            if (ptr < start || ptr >= end)
            {
                continue;
            }
            searchBlock deref = *ptr;

            //searched already?
            if (deref.searched)
            {
                continue;
            }

            //mark as processed
            (*ptr).searched = true;

            //we hit the water?
            Block b = (*deref.block);
            if (b.TypeID == Globals.TERRAIN_WATER)
            {
                continue;
            }
            found++;

            //add the block to the island
            blocks.Add((IntPtr)deref.block);

            //calculate x/y and do min/max to
            //detect island size/location
            int x = (int)((long)(ptr - start) % rowWidth);
            int y = (int)((long)(ptr - start) / rowWidth);
            if (x < minX)
            {
                minX = x;
            }
            if (y < minY)
            {
                minY = y;
            }
            if (x > maxX)
            {
                maxX = x;
            }
            if (y > maxY)
            {
                maxY = y;
            }

            #region reiterate for all 8 neighbors
            /*top row*/
            queue.Push(ptr - rowWidth);
            queue.Push(ptr - rowWidth - 1);
            queue.Push(ptr - rowWidth + 1);

            /*bottom row*/
            queue.Push(ptr + rowWidth);
            queue.Push(ptr + rowWidth - 1);
            queue.Push(ptr + rowWidth + 1);

            /*left/right*/
            queue.Push(ptr - 1);
            queue.Push(ptr + 1);

            count += 8;
            #endregion
        }

        return(new islandInfo {
            count = found,
            minX = minX,
            minY = minY,
            maxX = maxX,
            maxY = maxY,
            blocks = blocks
        });
    }
Beispiel #2
0
        public async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query)
        {
            var releases = new List <ReleaseInfo>();

            searchBlock Search = Definition.Search;

            // init template context
            var variables = getTemplateVariablesFromConfigData();

            variables[".Query.Type"]       = query.QueryType;
            variables[".Query.Q"]          = query.SearchTerm;
            variables[".Query.Series"]     = null;
            variables[".Query.Ep"]         = query.Episode;
            variables[".Query.Season"]     = query.Season;
            variables[".Query.Movie"]      = null;
            variables[".Query.Year"]       = null;
            variables[".Query.Limit"]      = query.Limit;
            variables[".Query.Offset"]     = query.Offset;
            variables[".Query.Extended"]   = query.Extended;
            variables[".Query.Categories"] = query.Categories;
            variables[".Query.APIKey"]     = query.ApiKey;
            variables[".Query.TVDBID"]     = null;
            variables[".Query.TVRageID"]   = query.RageID;
            variables[".Query.IMDBID"]     = query.ImdbID;
            variables[".Query.TVMazeID"]   = null;
            variables[".Query.TraktID"]    = null;

            variables[".Query.Episode"] = query.GetEpisodeSearchString();
            variables[".Categories"]    = MapTorznabCapsToTrackers(query);

            var KeywordTokens    = new List <string>();
            var KeywordTokenKeys = new List <string> {
                "Q", "Series", "Movie", "Year"
            };

            foreach (var key in KeywordTokenKeys)
            {
                var Value = (string)variables[".Query." + key];
                if (!string.IsNullOrWhiteSpace(Value))
                {
                    KeywordTokens.Add(Value);
                }
            }

            if (!string.IsNullOrWhiteSpace((string)variables[".Query.Episode"]))
            {
                KeywordTokens.Add((string)variables[".Query.Episode"]);
            }
            variables[".Query.Keywords"] = string.Join(" ", KeywordTokens);
            variables[".Keywords"]       = variables[".Query.Keywords"];

            // build search URL
            var searchUrl       = SiteLink + applyGoTemplateText(Search.Path, variables) + "?";
            var queryCollection = new NameValueCollection();

            if (Search.Inputs != null)
            {
                foreach (var Input in Search.Inputs)
                {
                    var value = applyGoTemplateText(Input.Value, variables);
                    if (Input.Key == "$raw")
                    {
                        searchUrl += value;
                    }
                    else
                    {
                        queryCollection.Add(Input.Key, value);
                    }
                }
            }
            searchUrl += "&" + queryCollection.GetQueryString();

            // send HTTP request
            var response = await RequestBytesWithCookies(searchUrl);

            var results = Encoding.GetEncoding("iso-8859-1").GetString(response.Content);

            try
            {
                var SearchResultParser   = new HtmlParser();
                var SearchResultDocument = SearchResultParser.Parse(results);

                var             RowsDom = SearchResultDocument.QuerySelectorAll(Search.Rows.Selector);
                List <IElement> Rows    = new List <IElement>();
                foreach (var RowDom in RowsDom)
                {
                    Rows.Add(RowDom);
                }

                // merge following rows for After selector
                var After = Definition.Search.Rows.After;
                if (After > 0)
                {
                    for (int i = 0; i < Rows.Count; i += 1)
                    {
                        var CurrentRow = Rows[i];
                        for (int j = 0; j < After; j += 1)
                        {
                            var          MergeRowIndex = i + j + 1;
                            var          MergeRow      = Rows[MergeRowIndex];
                            List <INode> MergeNodes    = new List <INode>();
                            foreach (var node in MergeRow.QuerySelectorAll("td"))
                            {
                                MergeNodes.Add(node);
                            }
                            CurrentRow.Append(MergeNodes.ToArray());
                        }
                        Rows.RemoveRange(i + 1, After);
                    }
                }

                foreach (var Row in Rows)
                {
                    try
                    {
                        var release = new ReleaseInfo();
                        release.MinimumRatio    = 1;
                        release.MinimumSeedTime = 48 * 60 * 60;

                        // Parse fields
                        foreach (var Field in Search.Fields)
                        {
                            string value = handleSelector(Field.Value, Row);
                            value = ParseUtil.NormalizeSpace(value);
                            try
                            {
                                switch (Field.Key)
                                {
                                case "download":
                                    if (value.StartsWith("magnet:"))
                                    {
                                        release.MagnetUri = new Uri(value);
                                        release.Link      = release.MagnetUri;
                                    }
                                    else
                                    {
                                        release.Link = resolvePath(value);
                                    }
                                    break;

                                case "details":
                                    var url = resolvePath(value);
                                    release.Guid = url;
                                    if (release.Comments == null)
                                    {
                                        release.Comments = url;
                                    }
                                    break;

                                case "comments":
                                    var CommentsUrl = resolvePath(value);
                                    release.Comments = CommentsUrl;
                                    if (release.Guid == null)
                                    {
                                        release.Guid = CommentsUrl;
                                    }
                                    break;

                                case "title":
                                    release.Title = value;
                                    break;

                                case "description":
                                    release.Description = value;
                                    break;

                                case "category":
                                    release.Category = MapTrackerCatToNewznab(value);
                                    break;

                                case "size":
                                    release.Size = ReleaseInfo.GetBytes(value);
                                    break;

                                case "leechers":
                                    if (release.Peers == null)
                                    {
                                        release.Peers = ParseUtil.CoerceInt(value);
                                    }
                                    else
                                    {
                                        release.Peers += ParseUtil.CoerceInt(value);
                                    }
                                    break;

                                case "seeders":
                                    release.Seeders = ParseUtil.CoerceInt(value);
                                    if (release.Peers == null)
                                    {
                                        release.Peers = release.Seeders;
                                    }
                                    else
                                    {
                                        release.Peers += release.Seeders;
                                    }
                                    break;

                                case "date":
                                    release.PublishDate = DateTimeUtil.FromUnknown(value);
                                    break;

                                case "files":
                                    release.Files = ParseUtil.CoerceLong(value);
                                    break;

                                case "grabs":
                                    release.Grabs = ParseUtil.CoerceLong(value);
                                    break;

                                case "downloadvolumefactor":
                                    release.DownloadVolumeFactor = ParseUtil.CoerceDouble(value);
                                    break;

                                case "uploadvolumefactor":
                                    release.UploadVolumeFactor = ParseUtil.CoerceDouble(value);
                                    break;

                                default:
                                    break;
                                }
                            }
                            catch (Exception ex)
                            {
                                throw new Exception(string.Format("Error while parsing field={0}, selector={1}, value={2}: {3}", Field.Key, Field.Value.Selector, value, ex.Message));
                            }
                        }

                        // if DateHeaders is set go through the previous rows and look for the header selector
                        var DateHeaders = Definition.Search.Rows.Dateheaders;
                        if (DateHeaders != null)
                        {
                            var    PrevRow = Row.PreviousElementSibling;
                            string value   = null;
                            while (PrevRow != null)
                            {
                                try
                                {
                                    value = handleSelector(DateHeaders, PrevRow);
                                    break;
                                }
                                catch (Exception ex)
                                {
                                    // do nothing
                                }
                                PrevRow = PrevRow.PreviousElementSibling;
                            }

                            if (value == null)
                            {
                                throw new Exception(string.Format("No date header row found for {0}", release.ToString()));
                            }

                            release.PublishDate = DateTimeUtil.FromUnknown(value);
                        }

                        releases.Add(release);
                    }
                    catch (Exception ex)
                    {
                        logger.Error(string.Format("CardigannIndexer ({0}): Error while parsing row '{1}': {2}", ID, Row.OuterHtml, ex));
                    }
                }
            }
            catch (Exception ex)
            {
                OnParseError(results, ex);
            }

            return(releases);
        }
        public async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query)
        {
            var releases = new List <ReleaseInfo>();

            searchBlock Search = Definition.Search;

            // init template context
            var variables = getTemplateVariablesFromConfigData();

            variables[".Query.Type"]       = query.QueryType;
            variables[".Query.Q"]          = query.SearchTerm;
            variables[".Query.Series"]     = null;
            variables[".Query.Ep"]         = query.Episode;
            variables[".Query.Season"]     = query.Season;
            variables[".Query.Movie"]      = null;
            variables[".Query.Year"]       = null;
            variables[".Query.Limit"]      = query.Limit;
            variables[".Query.Offset"]     = query.Offset;
            variables[".Query.Extended"]   = query.Extended;
            variables[".Query.Categories"] = query.Categories;
            variables[".Query.APIKey"]     = query.ApiKey;
            variables[".Query.TVDBID"]     = null;
            variables[".Query.TVRageID"]   = query.RageID;
            variables[".Query.IMDBID"]     = query.ImdbID;
            variables[".Query.TVMazeID"]   = null;
            variables[".Query.TraktID"]    = null;

            variables[".Query.Episode"] = query.GetEpisodeSearchString();
            variables[".Categories"]    = MapTorznabCapsToTrackers(query);

            var KeywordTokens    = new List <string>();
            var KeywordTokenKeys = new List <string> {
                "Q", "Series", "Movie", "Year"
            };

            foreach (var key in KeywordTokenKeys)
            {
                var Value = (string)variables[".Query." + key];
                if (!string.IsNullOrWhiteSpace(Value))
                {
                    KeywordTokens.Add(Value);
                }
            }

            if (!string.IsNullOrWhiteSpace((string)variables[".Query.Episode"]))
            {
                KeywordTokens.Add((string)variables[".Query.Episode"]);
            }
            variables[".Query.Keywords"] = string.Join(" ", KeywordTokens);
            variables[".Keywords"]       = variables[".Query.Keywords"];

            // build search URL
            var searchUrl       = SiteLink + applyGoTemplateText(Search.Path, variables) + "?";
            var queryCollection = new NameValueCollection();

            if (Search.Inputs != null)
            {
                foreach (var Input in Search.Inputs)
                {
                    var value = applyGoTemplateText(Input.Value, variables);
                    if (Input.Key == "$raw")
                    {
                        searchUrl += value;
                    }
                    else
                    {
                        queryCollection.Add(Input.Key, value);
                    }
                }
            }
            searchUrl += "&" + queryCollection.GetQueryString();

            // send HTTP request
            var response = await RequestBytesWithCookies(searchUrl);

            var results = Encoding.GetEncoding("iso-8859-1").GetString(response.Content);

            try
            {
                var SearchResultParser   = new HtmlParser();
                var SearchResultDocument = SearchResultParser.Parse(results);

                var Rows = SearchResultDocument.QuerySelectorAll(Search.Rows.Selector);
                foreach (var Row in Rows)
                {
                    try
                    {
                        var release = new ReleaseInfo();
                        release.MinimumRatio    = 1;
                        release.MinimumSeedTime = 48 * 60 * 60;

                        // Parse fields
                        foreach (var Field in Search.Fields)
                        {
                            string value = handleSelector(Field.Value, Row);
                            try
                            {
                                switch (Field.Key)
                                {
                                case "download":
                                    release.Link = resolvePath(value);
                                    break;

                                case "details":
                                    var url = resolvePath(value);
                                    release.Guid = url;
                                    if (release.Comments == null)
                                    {
                                        release.Comments = url;
                                    }
                                    break;

                                case "comments":
                                    release.Comments = resolvePath(value);
                                    break;

                                case "title":
                                    release.Title = value;
                                    break;

                                case "description":
                                    release.Description = value;
                                    break;

                                case "category":
                                    release.Category = MapTrackerCatToNewznab(value);
                                    break;

                                case "size":
                                    release.Size = ReleaseInfo.GetBytes(value);
                                    break;

                                case "leechers":
                                    if (release.Peers == null)
                                    {
                                        release.Peers = ParseUtil.CoerceInt(value);
                                    }
                                    else
                                    {
                                        release.Peers += ParseUtil.CoerceInt(value);
                                    }
                                    break;

                                case "seeders":
                                    release.Seeders = ParseUtil.CoerceInt(value);
                                    if (release.Peers == null)
                                    {
                                        release.Peers = release.Seeders;
                                    }
                                    else
                                    {
                                        release.Peers += release.Seeders;
                                    }

                                    break;

                                case "date":
                                    release.PublishDate = DateTimeUtil.FromUnknown(value);
                                    break;

                                default:
                                    break;
                                }
                            }
                            catch (Exception ex)
                            {
                                throw new Exception(string.Format("Error while parsing field={0}, selector={1}, value={2}: {3}", Field.Key, Field.Value.Selector, value, ex.Message));
                            }
                        }

                        releases.Add(release);
                    }
                    catch (Exception ex)
                    {
                        logger.Error(string.Format("CardigannIndexer ({0}): Error while parsing row '{1}': {2}", ID, Row.OuterHtml, ex.Message));
                    }
                }
            }
            catch (Exception ex)
            {
                OnParseError(results, ex);
            }

            return(releases);
        }