Не возникало ли у вас желания посмотреть, как бы вы выступили, если бы участвовали в каком-то контесте? Вам хотелось бы, чтобы в таблице результатов во время тренировок было больше команд? Или же вы хотели объединить результаты нескольких площадок соревнований в одну? Если да, то эта программа как раз для вас B-). Вашему вниманию представляется Standings Builder — программа на C++, которая умеет объединять результаты соревнований и разворачивать виртуальные контесты. Более того, можно полностью переформатировать результаты, добавив дополнительные поля или удалив лишние. Ссылка на GitHub: https://github.com/knightL/StandingsBuilder .
Можно выделить следующие фичи:
Модульная структура программы. Сборкой данных занимаются классы программы, которые называются парсерами. В конфигурации можно комбинировать их в любых сочетаниях и количествах. В данный момент реализованы 3 парсера для таблиц Ejudge, NEERC и xml файлов NEERC. Для проведения виртуальных контестов включен вспомогательный "парсер" Timer, который на самом деле ничего не парсит, но зато позволяет отсчитывать время от какого-то фиксированного момента. Если же вам не подходят готовые решения, вам всего лишь нужно создать класс-наследник базового класса, реализовать 5 обязательных методов и добавить команду registerParser в main.
Гибкая настройка результирующей таблицы. Таблица строится с помощью пользовательского LUA скрипта, поэтому может иметь любую форму и любое содержание. В дополнение к этому, есть вспомогательные атрибуты у парсеров Prefix и Style. Prefix допишется к названию команд, с которыми парсер работает. Style сохраняется для команд похожим образом, его можно получить при обработке в LUA.
Простая структура конфигурационного файла. Конфигурационный файл представляет из себя XML файл. Все основные параметры программы являются детьми корневого тега. Для обработки можно добавлять произвольное количество парсеров. Каждый парсер представляет из себя тег внутри и может иметь как атрибуты так и вложенные теги. При создании конкретного парсера в программе в конструктор будет передано всё дерево, относящееся к нему. Общая структура следующая:
<Builder>
<ProblemCount>11</ProblemCount>
<RefreshRate>300</RefrestRate>
<OutputFile>output.html</OutputFile>
<OutputScript>script.lua</OutputScript>
<Parsers>
...Список парсеров...
</Parsers>
</Builder>
Основной платформой, под которую программа была написана, является Linux. Ну или, говоря более конкретно Debian и Ubuntu. Графического интерфейса нет. Для установки, если все зависимости удовлетворены, достаточно написать классические ./configure , make и/или make install . Для запуска программе необходимо предоставить один аргумент — .xml файл с конфигурацией. Под Windows старая версия собиралась, но это было давно и с тех пор в проект добавилась зависимость от lua. Как вспомню и соберу, так выложу.
На данный момент в зависимостях у программы 2(+1) библиотеки: две основные: libxml2 и liblua5.2, без которых программа не соберется, и одна дополнительная libcurl, с помощью которой программа скачивает файлы из интернет.
Ну и в завершении я хочу привести пример конфигурации и результата работы программы, которая объединит таблицы 1/8 ACM ICPC Украины, который прошел сегодня. Результаты построены с использованием замороженных таблиц, размороженные еще не все есть.
Результаты восточного региона пришлось скачать вручную в файл southStandings.html, потому что по непонятным причинам curl и wget скачивают что-то двоичное, похожее на архив...
Эта веб-страница была сгенерирована с помощью следующего конфигурационного файла:
<Builder>
<ProblemCount>N</ProblemCount>
<RefreshRate>300</RefreshRate>
<OutputFile>output.html</OutputFile>
<OutputScript>outputEjudgeStyle.lua</OutputScript>
<Parsers>
<EjudgeParser URL="http://olimp.vntu.edu.ua/standings82.php" IgnoreColumns="3" Prefix="Kyiv: " />
<EjudgeParser Path="southStandings.html" IgnoreColumns="3" Prefix="South: "/>
<EjudgeParser URL="http://olymp.franko.lviv.ua/ejudge/standings.html" Prefix="West: " Timeless="Yes"/>
<EjudgeParser URL="http://olimp.vntu.edu.ua/standings78.php" IgnoreColumns="3" Prefix="East: " />
<EjudgeParser URL="http://acm.khnu.km.ua/result021.php" Prefix="Center: " Timeless="Yes"/>
</Parsers>
</Builder>