示例#1
0
        public void DeUrl_NoneWithBBCode()
        {
            string content = "『i』Vote『/i』 for stuff";
            string clean   = "『i』Vote『/i』 for stuff";

            Assert.AreEqual(clean, VoteString.DeUrlContent(content));
        }
示例#2
0
        /// <summary>
        /// Adds an individual vote.
        /// </summary>
        /// <param name="vote">The vote that is being added to.</param>
        /// <param name="voter">The voter that is supporting the vote.</param>
        /// <param name="voteType">Type of the vote.</param>
        /// <exception cref="System.ArgumentNullException">vote and voter must not be null or empty.</exception>
        private void AddVote(string vote, string voter, VoteType voteType)
        {
            if (string.IsNullOrEmpty(vote))
            {
                throw new ArgumentNullException(nameof(vote));
            }
            if (string.IsNullOrEmpty(voter))
            {
                throw new ArgumentNullException(nameof(voter));
            }

            string voteKey = GetVoteKey(vote, voteType);
            var    votes   = GetVotesCollection(voteType);

            // Make sure there's a hashset for the voter list available for the vote key.
            if (votes.ContainsKey(voteKey) == false)
            {
                votes[voteKey] = new HashSet <string>(StringComparer.OrdinalIgnoreCase);
                OnPropertyChanged("Votes");
            }

            string cleanVoter = VoteString.RemoveBBCode(voter);

            cleanVoter = VoteString.DeUrlContent(cleanVoter);

            // Update the supporters list if the voter isn't already in it.
            if (votes[voteKey].Contains(cleanVoter))
            {
                return;
            }

            votes[voteKey].Add(cleanVoter);

            OnPropertyChanged("Voters");
        }
示例#3
0
        /// <summary>
        /// Attempt to find any existing vote that matches with the vote we have,
        /// and can be used as a key in the VotesWithSupporters table.
        /// </summary>
        /// <param name="vote">The vote to search for.</param>
        /// <returns>Returns the string that can be used as a key in the VotesWithSupporters table.</returns>
        private string GetVoteKey(string vote, VoteType voteType)
        {
            // Store a lookup of the cleaned version of the vote so we don't have to repeat the processing.
            if (!cleanedKeys.TryGetValue(vote, out string cleaned))
            {
                cleaned           = VoteString.RemoveBBCode(vote);
                cleaned           = VoteString.DeUrlContent(cleaned);
                cleanedKeys[vote] = cleaned;
            }

            var votes = GetVotesCollection(voteType);

            // If the vote already matches an existing key, we don't need to search again.
            if (votes.ContainsKey(vote))
            {
                return(vote);
            }

            // Find any vote that matches using an agnostic string comparison, that ignores
            // case, spacing, and most punctuation.
            string agVote = votes.Keys.FirstOrDefault(k =>
                                                      Agnostic.StringComparer.Equals(cleaned, cleanedKeys[k]));

            // If we found a match, return that; otherwise this is a new vote, so return it unchanged.
            return(agVote ?? vote);
        }
示例#4
0
        public void DeUrl_Empty()
        {
            string content = "";
            string clean   = "";

            Assert.AreEqual(clean, VoteString.DeUrlContent(content));
        }
示例#5
0
        public void DeUrl_None()
        {
            string content = "Vote for stuff";
            string clean   = "Vote for stuff";

            Assert.AreEqual(clean, VoteString.DeUrlContent(content));
        }
示例#6
0
        public void DeUrl_Link()
        {
            string content = "Vote for [url=http://google.com/myhome.html]me[/url]!";
            string clean   = "Vote for me!";

            Assert.AreEqual(clean, VoteString.DeUrlContent(content));
        }
示例#7
0
        public void DeUrl_Image()
        {
            string content = "[url=http://google.com/image/1.jpg]<Image>[/url]";
            string clean   = "<Image>";

            Assert.AreEqual(clean, VoteString.DeUrlContent(content));
        }
示例#8
0
        public void DeUrl_AtUrl()
        {
            string content = "[url=https://forum.questionablequesting.com/members/2392/]@Xryuran[/url]";
            string clean   = "Xryuran";

            Assert.AreEqual(clean, VoteString.DeUrlContent(content));
        }
示例#9
0
        /// <summary>
        /// Cleans the provided content string of problematic components that would
        /// make comparing two strings difficult, by removing excess BBCode.
        /// </summary>
        /// <param name="content">The content.</param>
        /// <returns>Returns vote content suitable for comparison.</returns>
        private string GetComparableContent(string content)
        {
            string clean = VoteString.RemoveBBCode(content);

            clean = VoteString.DeUrlContent(clean);

            return(clean);
        }
示例#10
0
        /// <summary>
        /// Adds the voter post identifier.
        /// </summary>
        /// <param name="voter">The voter.</param>
        /// <param name="postID">The post identifier.</param>
        /// <param name="voteType">Type of the vote.</param>
        /// <exception cref="System.ArgumentNullException">voter and postID may not be null or empty.</exception>
        private void AddVoterPostID(string voter, string postID, VoteType voteType)
        {
            if (string.IsNullOrEmpty(voter))
            {
                throw new ArgumentNullException(nameof(voter));
            }
            if (string.IsNullOrEmpty(postID))
            {
                throw new ArgumentNullException(nameof(postID));
            }

            string cleanVoter = VoteString.RemoveBBCode(voter);

            cleanVoter = VoteString.DeUrlContent(cleanVoter);

            // Store/update the post ID of the voter
            var voters = GetVotersCollection(voteType);

            voters[cleanVoter] = postID;
        }
示例#11
0
        /// <summary>
        /// Find all votes tied to a given vote line.
        /// The "plan name" (possibly user name) is checked with the
        /// standard and alternate extractions (adding a special marker character
        /// depending on whether the word "plan" is used, and whether it's
        /// standard or alt) in order to look up votes that said (possible) voter
        /// supports.
        /// </summary>
        /// <param name="voteLine">The vote line to be checked.</param>
        /// <param name="author">The author of the vote. Prevent circular references.</param>
        /// <returns>Returns a list of all votes supported by the user or plan
        /// specified in the vote line, if found.  Otherwise returns an
        /// empty list.</returns>
        public List <string> GetVotesFromReference(string voteLine, string author)
        {
            if (voteLine == null)
            {
                throw new ArgumentNullException(nameof(voteLine));
            }
            if (author == null)
            {
                throw new ArgumentNullException(nameof(author));
            }

            List <string> results = new List <string>();

            var referenceNames = VoteString.GetVoteReferenceNames(voteLine);

            if (!referenceNames[ReferenceType.Any].Any())
            {
                return(results);
            }

            string proxyName = null;

            if (referenceNames[ReferenceType.Label].Any())
            {
                // If there is a "plan" prefix, then if it's a user reference,
                // check for a ◈plan before checking for the user's base vote.

                // If the reference exists as a plan, use it.
                if (referenceNames[ReferenceType.Plan].Any() && HasPlan(referenceNames[ReferenceType.Plan].First()))
                {
                    // If this is not a user name, get the plan name as the proxy reference.
                    proxyName = PlanNames.First(p => referenceNames[ReferenceType.Plan]
                                                .Contains(VoteString.DeUrlContent(VoteString.RemoveBBCode(p)), Agnostic.StringComparer));
                }
                else if (ReferenceVoters.Contains(referenceNames[ReferenceType.Voter].First(), Agnostic.StringComparer))
                {
                    // If it doesn't exist as a plan, then we can check for users.
                    if (!AdvancedOptions.Instance.DisableProxyVotes)
                    {
                        proxyName = ReferenceVoters.First(n => referenceNames[ReferenceType.Voter].Contains(n, Agnostic.StringComparer));

                        if (proxyName == author)
                        {
                            proxyName = null;
                        }
                    }
                }
            }
            else
            {
                // If there is no "plan" prefix, and if the plan name is a user
                // reference, it may only refer to that user's vote as a whole.

                // If this matches a user name, get that user name as the proxy reference.
                if (ReferenceVoters.Contains(referenceNames[ReferenceType.Voter].First(), Agnostic.StringComparer))
                {
                    if (!AdvancedOptions.Instance.DisableProxyVotes)
                    {
                        proxyName = ReferenceVoters.First(n => referenceNames[ReferenceType.Voter].Contains(n, Agnostic.StringComparer));

                        if (proxyName == author)
                        {
                            proxyName = null;
                        }
                    }
                }
                else if (referenceNames[ReferenceType.Plan].Any() && HasPlan(referenceNames[ReferenceType.Plan].First()))
                {
                    // If this is not a user name, get the plan name as the proxy reference.
                    proxyName = PlanNames.First(p => referenceNames[ReferenceType.Plan].Contains(p, Agnostic.StringComparer));
                }
            }

            if (!string.IsNullOrEmpty(proxyName))
            {
                var planVotes = VotesWithSupporters.Where(v => v.Value.Contains(proxyName));

                results.AddRange(planVotes.Select(v => v.Key));
            }

            return(results);
        }
示例#12
0
        /// <summary>
        /// Find all votes tied to a given vote line.
        /// The "plan name" (possibly user name) is checked with the
        /// standard and alternate extractions (adding a special marker character
        /// depending on whether the word "plan" is used, and whether it's
        /// standard or alt) in order to look up votes that said (possible) voter
        /// supports.
        /// </summary>
        /// <param name="voteLine">The vote line to be checked.</param>
        /// <param name="author">The author of the vote. Prevent circular references.</param>
        /// <returns>Returns a list of all votes supported by the user or plan
        /// specified in the vote line, if found.  Otherwise returns an
        /// empty list.</returns>
        public List <string> GetVotesFromReference(string voteLine, string author)
        {
            if (voteLine == null)
            {
                throw new ArgumentNullException(nameof(voteLine));
            }
            if (author == null)
            {
                throw new ArgumentNullException(nameof(author));
            }

            List <string> results = new List <string>();

            var referenceNames = VoteString.GetVoteReferenceNames(voteLine);

            if (!referenceNames[ReferenceType.Any].Any())
            {
                return(results);
            }

            string proxyName = null;


            // Label ^ or 'pin' means it must be a user reference.
            // Label 'plan' means it might be user or plan reference.

            if (referenceNames[ReferenceType.Label].Contains("plan"))
            {
                // If it's labeled as a 'plan', check plans first, then users.

                // If the reference exists as a plan, use it.
                if (referenceNames[ReferenceType.Plan].Any() && HasPlan(referenceNames[ReferenceType.Plan].First()))
                {
                    // Get the plan name from the recorded plan names collection.
                    proxyName = PlanNames.First(p => referenceNames[ReferenceType.Plan]
                                                .Contains(VoteString.DeUrlContent(VoteString.RemoveBBCode(p)), Agnostic.StringComparer));
                }
                // If it doesn't exist as a plan, then we can check for users, as long as the quest hasn't disabled proxy votes.
                else if (!Quest.DisableProxyVotes &&
                         ReferenceVoters.Contains(referenceNames[ReferenceType.Voter].First(), Agnostic.InsensitiveComparer))
                {
                    proxyName = ReferenceVoters.First(n => referenceNames[ReferenceType.Voter].Contains(n, Agnostic.InsensitiveComparer));

                    // But don't allow self-references.  Some user names conflict with normal vote lines.
                    if (proxyName == author)
                    {
                        proxyName = null;
                    }
                }
            }
            else
            {
                // If it's not labeled as a 'plan', then it's either a pin or an unlabeled reference.
                // Either way, check for users first.

                // See if any voter names match the line (as long as we're allowing proxy votes).  If so, use that.
                if (!Quest.DisableProxyVotes &&
                    ReferenceVoters.Contains(referenceNames[ReferenceType.Voter].First(), Agnostic.InsensitiveComparer))
                {
                    proxyName = ReferenceVoters.First(n => referenceNames[ReferenceType.Voter].Contains(n, Agnostic.InsensitiveComparer));

                    // And make sure it's not the user using their own name.  Some user names conflict with normal vote lines.
                    if (proxyName == author)
                    {
                        proxyName = null;
                    }
                }
                // If a user isn't found, only check for regular plans if there's not a non-plan label being used,
                // but not if the quest requires plan vote lines to be labeled.
                else if (!Quest.ForcePlanReferencesToBeLabeled && !referenceNames[ReferenceType.Label].Any())
                {
                    if (referenceNames[ReferenceType.Plan].Any() && HasPlan(referenceNames[ReferenceType.Plan].First()))
                    {
                        // Get the plan name from the recorded plan names collection.
                        proxyName = PlanNames.First(p => referenceNames[ReferenceType.Plan]
                                                    .Contains(VoteString.DeUrlContent(VoteString.RemoveBBCode(p)), Agnostic.StringComparer));
                    }
                }
            }

            if (!string.IsNullOrEmpty(proxyName))
            {
                var planVotes = VotesWithSupporters.Where(v => v.Value.Contains(proxyName));

                if (planVotes.Count() > 1)
                {
                    planVotes = VotesWithSupporters.Where(v => v.Value.Contains(proxyName, Agnostic.StringComparer));
                }

                results.AddRange(planVotes.Select(v => v.Key));
            }

            return(results);
        }