コード例 #1
0
        /// <summary>
        /// Merges the current node wiki with the given node wiki.
        /// </summary>
        /// <param name="wiki">Wiki to merge with.</param>
        /// <param name="mergeDescription">Value indicating whether to merge description.</param>
        /// <returns>Merged wiki.</returns>
        public RockClimbingComWiki MergeWikiWith(RockClimbingComWiki wiki, bool mergeDescription)
        {
            RockClimbingComWiki ret = this.Info;

            if (ret != null && wiki != null)
            {
                // Assigning location, if missing
                if (ret.Location == null && wiki.Location != null)
                    ret.Location = wiki.Location;

                // Assigning climbing type, if missing
                if (ret.Climbing == Models.ClimbingTypes.NotSpecified && wiki.Climbing != Models.ClimbingTypes.NotSpecified)
                    ret.Climbing = wiki.Climbing;

                // Assigning climbing season, if missing
                if (ret.Season == Models.Seasons.NotSpecified && wiki.Season != Models.Seasons.NotSpecified)
                    ret.Season = wiki.Season;

                if (mergeDescription)
                {
                    // Overriding description if the name changes
                    if (string.IsNullOrWhiteSpace(ret.Name) && !string.IsNullOrWhiteSpace(wiki.Name))
                    {
                        ret.Name = wiki.Name;
                        ret.Description = wiki.Description;
                    }
                    else if (ret.Description.Length * 3 < wiki.Description.Length)
                    {
                        // Candidate wiki has substantially more rich description - overriding
                        ret.Description = wiki.Description;
                    }
                }
            }

            return ret;
        }
コード例 #2
0
ファイル: RockClimbingComWiki.cs プロジェクト: volpav/toprope
        /// <summary>
        /// Parses page from the given content.
        /// </summary>
        /// <param name="content">Content.</param>
        /// <returns>Page.</returns>
        public static RockClimbingComWiki Parse(string content)
        {
            Match m = null;
            double parsed = -1;
            string[] seasons = null;
            string[] climbingTypes = null;
            RockClimbingComWiki ret = null;
            bool hasGeneralDescription = false;
            StringBuilder description = new StringBuilder();
            Models.Seasons season = Models.Seasons.NotSpecified;
            Models.ClimbingTypes climbing = Models.ClimbingTypes.NotSpecified;

            Func<string, string> getFieldValue = (name) =>
                {
                    string result = string.Empty;

                    m = Regex.Match(content, string.Format("{0}:\\s*</strong>\\s*</td>\\s*<td[^>]+>([^<]+)</td>", name), RegexOptions.IgnoreCase | RegexOptions.Singleline);

                    if (m != null && m.Success)
                        result = FixPunctiation(m.Groups[1].Value.Trim());

                    return result;
                };

            Action<string> appendToDescription = (name) =>
                {
                    string nearest = string.Empty;
                    string v = getFieldValue(name);
                    string approachTime = string.Empty;

                    if (string.Compare(name, "Directions", StringComparison.InvariantCultureIgnoreCase) == 0)
                    {
                        nearest = getFieldValue("Nearest town or city");

                        if (!string.IsNullOrEmpty(nearest))
                            v = string.Concat(string.Format("The nearest town or city is {0}. ", nearest.Trim().TrimEnd('.')), v);
                    }
                    else if (string.Compare(name, "Approach", StringComparison.InvariantCultureIgnoreCase) == 0)
                    {
                        approachTime = getFieldValue("Approach Time");

                        if (!string.IsNullOrEmpty(approachTime))
                        {
                            approachTime = Regex.Replace(Regex.Replace(approachTime, @"([0-9]+)", " $1 ", RegexOptions.IgnoreCase).Trim(), @"\s+", " ").Trim();

                            if (Regex.IsMatch(approachTime, "[a-zA-Z]+", RegexOptions.IgnoreCase))
                                v = string.Concat(string.Format("The approach time is {0}. ", approachTime.Trim().TrimEnd('.').Trim()), v);
                        }
                    }

                    if (!string.IsNullOrEmpty(v))
                    {
                        v = v.Trim();

                        if (description.Length > 0)
                            description.AppendLine();

                        if (hasGeneralDescription)
                            description.AppendLine(string.Format("### {0}", name));

                        description.Append(v);
                        hasGeneralDescription = v.Length > 0;
                    }
                };

            m = Regex.Match(content, "<h2>([^>]+)</h2>", RegexOptions.IgnoreCase);

            if (m != null && m.Success)
            {
                ret = new RockClimbingComWiki();

                ret.Name = NormalizeName(m.Groups[1].Value.Trim(), true);

                if (!string.IsNullOrEmpty(ret.Name))
                {
                    m = Regex.Match(content, "<td[^>]+>\\s*<!--[^>]+Description[^>]+-->([^<]+)</td>", RegexOptions.IgnoreCase | RegexOptions.Singleline);

                    if (m != null && m.Success)
                    {
                        description.Append(FixPunctiation(m.Groups[1].Value.Trim()));
                        hasGeneralDescription = description.Length > 0;
                    }

                    appendToDescription("Directions");
                    appendToDescription("Approach");
                    appendToDescription("Access issues");

                    ret.Description = description.ToString();

                    m = Regex.Match(content, "<td[^>]+>(\\-?\\d+(\\.\\d+)?),\\s*(\\-?\\d+(\\.\\d+)?)</td>", RegexOptions.IgnoreCase);

                    if (m != null && m.Success)
                    {
                        ret.Location = new Models.Location();

                        if (double.TryParse(m.Groups[1].Value, NumberStyles.AllowLeadingSign, LocationCulture, out parsed) ||
                            double.TryParse(m.Groups[1].Value, NumberStyles.Any, LocationCulture, out parsed))
                        {
                            ret.Location.Latitude = parsed;
                        }

                        if (double.TryParse(m.Groups[3].Value, NumberStyles.AllowLeadingSign, LocationCulture, out parsed) ||
                            double.TryParse(m.Groups[3].Value, NumberStyles.Any, LocationCulture, out parsed))
                        {
                            ret.Location.Longitude = parsed;
                        }

                        if (ret.Location.Latitude < -90 || ret.Location.Latitude > 90)
                            ret.Location = null;
                    }

                    seasons = getFieldValue("When to Climb").Split(new char[] { ' ', '\n', '/' },
                        StringSplitOptions.RemoveEmptyEntries).Select(v => v.Trim()).ToArray();

                    if (seasons != null && seasons.Any())
                    {
                        foreach (string s in seasons)
                        {
                            if (Enum.TryParse<Models.Seasons>(s.Trim().Trim(',', '.', ';').Trim(), true, out season))
                            {
                                if (ret.Season == Models.Seasons.NotSpecified)
                                    ret.Season = season;
                                else
                                    ret.Season |= season;
                            }
                        }
                    }

                    climbingTypes = getFieldValue("Type of Climbing").Split(new char[] { ' ', '\n', '/' },
                        StringSplitOptions.RemoveEmptyEntries).Select(v => v.Trim()).ToArray();

                    if (climbingTypes != null && climbingTypes.Any())
                    {
                        foreach (string c in climbingTypes)
                        {
                            if (Enum.TryParse<Models.ClimbingTypes>(c.Trim().Trim(',', '.', ';').Trim(), true, out climbing))
                            {
                                if (ret.Climbing == Models.ClimbingTypes.NotSpecified)
                                    ret.Climbing = climbing;
                                else
                                    ret.Climbing |= climbing;
                            }
                        }
                    }

                    if (ret.Climbing == Models.ClimbingTypes.NotSpecified)
                        ret.Climbing = Models.ClimbingTypes.Sport;
                }
                else
                    ret = null;
            }

            return ret;
        }