Exemplo n.º 1
0
 private static bool isKattisState(string line, ref KattisState state)
 {
     if (string.Equals(line, "ignore", StringComparison.OrdinalIgnoreCase))
     {
         state = KattisState.IGNORE;
     }
     else if (string.Equals(line, "url", StringComparison.OrdinalIgnoreCase))
     {
         state = KattisState.URL;
     }
     else if (string.Equals(line, "folder", StringComparison.OrdinalIgnoreCase))
     {
         state = KattisState.FOLDER;
     }
     else
     {
         return(false);
     }
     return(true);
 }
Exemplo n.º 2
0
        public static void Main(string[] args)
        {
            log.StartTimer();
            Dictionary <string, string> idToNameMap = new Dictionary <string, string> (2500);
            const string mapfile = @"KattisIDNameMapping.txt";

            if (!File.Exists(mapfile))
            {
                log.WriteLine("Recommendation: You should run KattisMapGenerator.dll to ensure fast speeds");
                File.Create(mapfile).Close();
            }
            CustomReader sc = new CustomReader(mapfile);
            string       line;

            while ((line = sc.NextLine()) != null)
            {
                string id   = line;
                string name = sc.NextLine();
                if (name == null)
                {
                    throw new EndOfStreamException("Missing name for ID '" + id + "'. To fix this, you could delete KattisIDNameMapping.txt and run KattisMappingProgram.cs, or manually fix it by editing KattisIDNameMapping.txt.");
                }
                idToNameMap.Add(id, name);
            }
            const string file = @"Config.txt";

            if (!File.Exists(file))
            {
                log.WriteLine("No Config.txt found");
                File.Create(file).Close();
            }
            HashSet <string> ignore, urls;
            Stack <Tuple <string, Queue <string> > > folders;

            ignore  = new HashSet <string> (10);
            urls    = new HashSet <string> (5);
            folders = new Stack <Tuple <string, Queue <string> > > ();
            KattisState state = KattisState.NONE;

            sc = new CustomReader(file);
            while ((line = sc.NextLine()) != null)
            {
                // skip blank lines
                if (line.Length == 0)
                {
                    continue;
                }
                if (!isKattisState(line, ref state))
                {
                    if (state == KattisState.IGNORE)
                    {
                        if (line.Length > 0 && Regex.IsMatch(line, @"^[a-zA-Z\d]*(\.[a-zA-Z\d]+)?$"))
                        {
                            if (!ignore.Contains(line))
                            {
                                ignore.Add(line);
                            }
                        }
                        else
                        {
                            log.WriteLine("'" + line + "' does not match IGNORE regex (^[a-zA-Z\\d]*(\\.[a-zA-Z\\d]+)?$). Valid examples (ensure they're on separate lines and no commas): 2048, .cpp, abc.java");
                            throw new InvalidDataException("'" + line + "' does not match IGNORE regex (^[a-zA-Z\\d]*(\\.[a-zA-Z\\d]+)?$). Valid examples (ensure they're on separate lines and no commas): 2048, .cpp, abc.java");
                        }
                    }
                    else if (state == KattisState.URL)
                    {
                        if (!line.StartsWith("https://github.com", StringComparison.Ordinal))
                        {
                            log.WriteLine("'" + line + "' does not begin with https://github.com.");
                            throw new InvalidDataException("'" + line + "' does not begin with https://github.com.");
                        }
                        if (!urls.Contains(line))
                        {
                            urls.Add(line);
                        }
                    }
                    else if (state == KattisState.FOLDER)
                    {
                        if (line.StartsWith("to:", StringComparison.OrdinalIgnoreCase))
                        {
                            if (line.Length > 3)
                            {
                                folders.Push(new Tuple <string, Queue <string> > (line.Substring(3), new Queue <string> ()));
                            }
                            else
                            {
                                log.WriteLine("'to:' requires a folder");
                                throw new InvalidDataException("'to:' requires a folder");
                            }
                        }
                        else
                        {
                            folders.Peek().Item2.Enqueue(line);
                        }
                    }
                    else
                    {
                        log.WriteLine(line + " | First line read should be an action.");
                        throw new InvalidDataException(line + " | First line read should be an action.");
                    }
                }
            }
            sc.Close();

            SortedDictionary <string, SortedSet <KattisProblem> > table = new SortedDictionary <string, SortedSet <KattisProblem> > ();
            HashSet <string> IDsAddedToTable = new HashSet <string> ();

            // folder check
            while (folders.Count > 0)
            {
                Tuple <string, Queue <string> > t = folders.Pop();
                string loc = t.Item1;
                // try to replace the tree to blob in link
                // example: https://github.com/MiniDomo/Kattis/tree/master/Java
                // to https://github.com/MiniDomo/Kattis/blob/master/Java/
                Match match = Regex.Match(loc, "^https://github.com/[^/]*/[^/]*/tree/");
                if (match.Success)
                {
                    string res = match.Value;
                    int    len = res.Length;
                    res = res.Substring(0, len - 5) + "blob/";
                    loc = res + loc.Substring(len) + "/";
                }
                else
                {
                    log.WriteLine("Invalid link for FOLDER: " + loc + " did not match regex ^https://github.com/[^/]*/[^/]*/tree/ resulting in skipping the link.");
                    continue;
                }
                while (t.Item2.Count > 0)
                {
                    string        folder = t.Item2.Dequeue();
                    DirectoryInfo dir    = new DirectoryInfo(folder);
                    if (!dir.Exists)
                    {
                        log.WriteLine(folder + " was not found, resulting in being skipped");
                        continue;
                    }
                    foreach (FileInfo info in dir.GetFiles())
                    {
                        string githubProblemURL, githubProblemID, githubProblemExt;
                        // check if proper formatting
                        if (!Regex.IsMatch(info.Name, @"^[a-zA-Z\d]+\.[a-zA-Z\d]+$"))
                        {
                            log.WriteLine("File " + info.Name + " does not match ^[a-zA-Z\\d]+\\.[a-zA-Z\\d]+$ regex, skipping");
                            continue;
                        }
                        int periodPos = info.Name.IndexOf(".", StringComparison.Ordinal);
                        githubProblemID  = info.Name.Substring(0, periodPos);
                        githubProblemExt = info.Name.Substring(periodPos);
                        githubProblemURL = loc + githubProblemID + githubProblemExt;
                        check(githubProblemURL, githubProblemID, githubProblemExt, ignore, IDsAddedToTable, table, idToNameMap);
                    }
                }
            }
            // folder end

            // URL check
            if (urls.Count > 0)
            {
                ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;
                foreach (string link in urls)
                {
                    // check if it's an actual URL like https://www.google.com/ and not <sfghsdh-3wtsdfg>asd,.sg
                    if (!Uri.IsWellFormedUriString(link, UriKind.Absolute))
                    {
                        continue;
                    }
                    Stream githubStream = getURLStream(link);
                    // true if github link is nonexistent
                    if (githubStream == null)
                    {
                        log.WriteLine("Invalid link found '" + link + "'");
                        continue;
                    }
                    CustomReader githubReader = new CustomReader(githubStream);
                    while ((line = githubReader.NextLine()) != null)
                    {
                        // indicates that we've reached towards the bottom of the page where nothing below it will have problems/solutions to account for
                        if (line.Contains("model-backdrop", StringComparison.Ordinal))
                        {
                            break;
                        }
                        // if the line does have 'a class="js-navigation-open"', then it has the information we need
                        if (!line.Contains("a class=\"js-navigation-open\""))
                        {
                            continue;
                        }
                        string githubProblemURL, githubProblemID, githubProblemExt;
                        assignURLandIDandLang(line, out githubProblemURL, out githubProblemID, out githubProblemExt);
                        check(githubProblemURL, githubProblemID, githubProblemExt, ignore, IDsAddedToTable, table, idToNameMap);
                    }
                    githubStream.Close();
                    githubReader.Close();
                }
            }
            // URL end

            string output = "# Kattis Solutions\nSome solutions may be outdated and could be improved.\n\n";
            string other  = "";
            int    count  = 0;

            foreach (KeyValuePair <string, SortedSet <KattisProblem> > pair in table)
            {
                foreach (KattisProblem p in pair.Value)
                {
                    other += p.ToString() + "\n";
                    count++;
                }
            }
            output += "| " + count + " Problem" + (count == 1 ? "" : "s") + " | Languages |\n| - | - |\n";
            const string readme = @"README.md";
            StreamWriter dc     = new StreamWriter(readme, false, UnicodeEncoding.Default, 1 << 16);

            dc.Write(output + other);
            dc.Close();
            log.StopTimer();
            log.WriteLine("Program finished");
            log.Close();
            Console.WriteLine("Press any key to exit...");
            Console.ReadKey();
        }