Skip to content

Instantly share code, notes, and snippets.

@joriki
Last active November 6, 2019 14:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save joriki/ff85aa483b88414435368e7cca9cabbe to your computer and use it in GitHub Desktop.
Save joriki/ff85aa483b88414435368e7cca9cabbe to your computer and use it in GitHub Desktop.
Extract results of FIDE Grand Swiss Tournament 2019 in Wikipedia table format
package games.chess.fide;
import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
public class GrandSwissResultExtracter {
public static final Map<String,String> nameReplacements = new HashMap<>();
public static final Set<String> disambiguations = new HashSet<>();
static {
nameReplacements.put("B Adhiban", "Baskaran Adhiban");
nameReplacements.put("Ngoc Nguyen", "Nguyễn Ngọc Trường Sơn");
nameReplacements.put("Santosh Vidit", "Santosh Gujrathi Vidit");
nameReplacements.put("Guijarro Anton", "David Antón Guijarro");
nameReplacements.put("Luke Mcshane", "Luke McShane");
nameReplacements.put("Foreest Van", "Jorden van Foreest");
nameReplacements.put("Erwin L'ami", "Erwin l'Ami");
nameReplacements.put("S Narayanan", "S. L. Narayanan");
nameReplacements.put("Viktor Erdos", "Viktor Erdős");
nameReplacements.put("Vidal Gonzalez", "Yuri Gonzalez Vidal");
nameReplacements.put("D Gukesh", "Gukesh D");
nameReplacements.put("Pons Vallejo", "Francisco Vallejo Pons");
nameReplacements.put("Sarin Nihal", "Nihal Sarin");
nameReplacements.put("De Henderson", "Lance Henderson de La Fuente");
nameReplacements.put("Fy Rakotomaharo", "Fy Antenaina Rakotomaharo");
nameReplacements.put("Bonelli Iturrizaga", "Eduardo Iturrizaga");
nameReplacements.put("S Sethuraman", "S. P. Sethuraman");
nameReplacements.put("Surya Ganguly", "Surya Shekhar Ganguly");
nameReplacements.put("Matthias Bluebaum", "Matthias Blübaum");
nameReplacements.put("Batkhuyag Munguntuul", "Batkhuyagiin Möngöntuul");
nameReplacements.put("Mustafa Yilmaz", "Mustafa Yılmaz");
nameReplacements.put("Jonas Bjerre", "Jonas Buhl Bjerre");
nameReplacements.put("Swaminathan Soumya", "Soumya Swaminathan");
nameReplacements.put("Quang Le", "Lê Quang Liêm");
nameReplacements.put("Elisabeth Paehtz", "Elisabeth Pähtz");
nameReplacements.put("Mircea-Emilian Parligras", "Mircea Pârligras");
nameReplacements.put("Ivan Saric", "Ivan Šarić");
nameReplacements.put("Andriy Vovk", "Andrey Vovk");
nameReplacements.put("Gupta Prithu", "Prithu Gupta");
disambiguations.add("Wang Hao");
disambiguations.add("Li Wu");
disambiguations.add("Keith Allen");
disambiguations.add("Brandon Clarke");
disambiguations.add("Ivan Šarić");
disambiguations.add("Andrey Vovk");
disambiguations.add("David Howell");
disambiguations.add("Evgeny Alekseev");
disambiguations.add("Eric Hansen");
disambiguations.add("Robert Hess");
}
public static void main(String [] args) throws IOException {
Document document = Jsoup.connect ("http://chess-results.com/tnr478041.aspx?lan=1&art=4&turdet=YES&flag=30&zeilen=99999").get();
Elements rows = document.select ("table.CRs1 > tbody > tr");
StringBuffer wikiTable = new StringBuffer();
wikiTable.append("{| class=\"wikitable sortable\"\n! Rank !! Name !! Rating");
for (int r = 0;r < rows.get(1).childNodeSize() - 10;r++)
wikiTable.append(" !! ").append(r + 1);
wikiTable.append("!! Total\n");
String [] opponents = new String [rows.size()];
for (int i = 1;i < rows.size();i++) {
Element row = rows.get(i);
String country = row.attr("class").split(" ") [1];
String [] names = row.child(3).text().split("[ .]");
int firstName = "CHN".equals(country) ? 0 : 1;
String name = names [firstName] + " " + names [1 - firstName];
if (nameReplacements.containsKey(name))
name = nameReplacements.get(name);
int rating = Integer.parseInt(row.child(4).text());
opponents [i] = name + " (" + country + "), " + rating;
}
for (int i = 1;i < rows.size();i++) {
Element row = rows.get(i);
String country = row.attr("class").split(" ") [1];
int rank = Integer.parseInt(row.child(0).text());
if (rank != i)
throw new Error();
int firstName = "CHN".equals(country) ? 0 : 1;
String [] names = row.child(3).text().split("[ .]");
String name = names [firstName] + " " + names [1 - firstName];
if (nameReplacements.containsKey(name))
name = nameReplacements.get(name);
int rating = Integer.parseInt(row.child(4).text());
String points = row.child(row.childNodeSize() - 5).text().replace(',', '.');
wikiTable.append("|- align=center\n");
wikiTable.append("| ").append(rank).append('\n');
wikiTable.append("| align=left | {{flagathlete|[[");
if (disambiguations.contains(name))
wikiTable.append(name).append(" (chess player)|");
wikiTable.append(name).append ("]]| ").append(country).append("}}\n");
wikiTable.append("| ").append(rating).append('\n');
for (int r = 0;r < row.childNodeSize() - 10;r++) {
boolean lastColumn = r == row.childNodeSize() - 11;
String result = row.child(r + 5).text();
boolean unpaired = result.charAt(0) == '-';
int white = result.indexOf('w');
int black = result.indexOf('b');
if (white < 0 == black < 0 && !unpaired)
throw new Error();
boolean isWhite = white >= 0;
String [] results = result.split(unpaired ? "-" : isWhite ? "w" : "b",2);
String score = results [1];
if (score.equals("+"))
score = "1";
else if (score.equals("-"))
score = "0";
wikiTable.append("| style=\"background:").append(unpaired ? "lightgray" : isWhite ? "white" : "black").append(";color:").append(unpaired || isWhite ? "black" : "white").append('"');
if (!score.isEmpty())
wikiTable.append(" data-sort-value=").append(score.equals("½") ? "0.5" : score);
wikiTable.append(" | {{Hover title|").append(unpaired ? (score.equals("0") ? "Not paired" : "Bye") : opponents [Integer.parseInt(results [0])]).append('|').append(score.isEmpty() || lastColumn ? "–" : score).append("|dotted=no}}\n");
}
wikiTable.append("| ").append(points).append('\n');
}
wikiTable.append("|}\n");
System.out.println(wikiTable);
}
}
@Griphomaniac
Copy link

I have some local code doing a similar thing to https://en.wikipedia.org/wiki/FIDE_Grand_Swiss_Tournament_2019 and will double check your imports over time too. Some further suggestions:

Additional name replacements (to avoid redirects, and in some cases, incorrect articles)

  • Surya Ganguly -> Surya Shekhar Ganguly
  • Matthias Bluebaum -> Matthias Blübaum
  • Batkhuyag Munguntuul -> Batkhuyagiin Möngöntuul
  • Mustafa Yilmaz -> Mustafa Yılmaz
  • Jonas Bjerre -> Jonas Buhl Bjerre
  • Swaminathan Soumya -> Soumya Swaminathan
  • Quang Le -> Lê Quang Liêm
  • Elisabeth Paehtz -> Elisabeth Pähtz
  • Mircea-Emilian Parligras -> Mircea Pârligras

Additional name disambiguations:

  • Ivan Saric
  • Andrey Vovk
  • David Howell
  • Evgeny Alekseev
  • Eric Hansen
  • Robert Hess

Also should add in a "data-sort-value=0|0.5|1" after the style to allow the ½ to be sorted correctly. For example:
style="background:white; color:black" data-sort-value=0.5 | {{Hover title|Mustafa Yılmaz (TUR), 2595|½|dotted=no}}

@Griphomaniac
Copy link

Also suggest "Not paired" and "Bye" records to have style="background-color:lightgray; color:black"

@joriki
Copy link
Author

joriki commented Oct 12, 2019

@Griphomaniac Cool, thanks! I made all those changes (in the code and in the article) (except I stuck with "background" instead of "background-color").

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment