Topcoder SRM開催日時取得プログラム

Topcoderで行われているSRMの開催日時をTopcoderのサイトのカレンダーのページから取得するプログラムを書いた.使ってる部分の訂正ついでに,簡単なプログラムに書き直して公開.使用は各自の責任で行ってください.

使用ライブラリ:HTMLParser(http://htmlparser.sourceforge.net/)

今日(2010年12月22日時点)での出力結果は以下の通り.

[Main$SRM[name=SRM 490,url=http://www.topcoder.com/tc?module=MatchDetails&rd=14243,registrationTime=2010年12月08日(水) 22時00分,competitionTime=2010年12月09日(木) 01時02分], Main$SRM[name=Member SRM 491,url=http://www.topcoder.com/tc?module=MatchDetails&rd=14244,registrationTime=2010年12月18日(土) 23時00分,competitionTime=2010年12月19日(日) 02時02分], Main$SRM[name=SRM 492,url=http://www.topcoder.com/tc?module=MatchDetails&rd=14245,registrationTime=2010年12月29日(水) 08時00分,competitionTime=2010年12月29日(水) 11時00分]]
[Main$SRM[name=SRM 490,url=http://www.topcoder.com/tc?module=MatchDetails&rd=14243,registrationTime=2010年12月08日(水) 22時00分,competitionTime=2010年12月09日(木) 01時02分], Main$SRM[name=Member SRM 491,url=http://www.topcoder.com/tc?module=MatchDetails&rd=14244,registrationTime=2010年12月18日(土) 23時00分,competitionTime=2010年12月19日(日) 02時02分], Main$SRM[name=SRM 492,url=http://www.topcoder.com/tc?module=MatchDetails&rd=14245,registrationTime=2010年12月29日(水) 08時00分,competitionTime=2010年12月29日(水) 11時00分]]
[Main$SRM[name=SRM 493,url=http://www.topcoder.com/tc?module=MatchDetails&rd=14422,registrationTime=2011年01月13日(木) 08時00分,competitionTime=2011年01月13日(木) 11時00分], Main$SRM[name=Member SRM 494,url=http://www.topcoder.com/tc?module=MatchDetails&rd=14423,registrationTime=2011年01月22日(土) 23時00分,competitionTime=2011年01月23日(日) 02時00分], Main$SRM[name=SRM 495,url=http://www.topcoder.com/tc?module=MatchDetails&rd=14424,registrationTime=2011年01月27日(木) 22時00分,competitionTime=2011年01月28日(金) 01時00分]]

コード

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Locale;
import java.util.TimeZone;

import org.htmlparser.Node;
import org.htmlparser.Parser;
import org.htmlparser.filters.HasAttributeFilter;
import org.htmlparser.filters.TagNameFilter;
import org.htmlparser.tags.LinkTag;
import org.htmlparser.util.NodeList;
import org.htmlparser.util.SimpleNodeIterator;

public class Main {
	private static final String calendarURL = "http://www.topcoder.com/tc?module=Static&d1=calendar&d2=";
	private static final Locale japan = Locale.JAPAN;
	private static final SimpleDateFormat printFormat;
	private static final SimpleDateFormat parseFormat = new SimpleDateFormat(
			"MM.dd.yyyyhh:mmaz", Locale.US);

	private static final String[] months = { "jan", "feb", "mar", "apr", "may",
			"jun", "jul", "aug", "sep", "oct", "nov", "dec" };
	static {
		printFormat = new SimpleDateFormat("yyyy年MM月dd日(E) HH時mm分", japan);
		printFormat.setTimeZone(TimeZone.getTimeZone("GMT+09:00"));
	}

	public static void main(String[] args) {
		Main main = new Main();
		// 今月の開催SRMを取得
		List<SRM> list = main.getSRMs("thisMonth");
		System.out.println(list);
		// 今月の開催SRMを取得(上記と同じ)
		GregorianCalendar cal = new GregorianCalendar();
		int thisMonth = cal.get(Calendar.MONTH);
		int thisYear = cal.get(Calendar.YEAR) % 100;
		List<SRM> list2 = main.getSRMs(months[thisMonth] + "_" + thisYear);
		System.out.println(list2);
		// 来月の開催SRMを取得
		cal.add(Calendar.MONTH, 1);
		int nextMonth = cal.get(Calendar.MONTH);
		int nextMonthYear = cal.get(Calendar.YEAR) % 100;
		List<SRM> list3 = main.getSRMs(months[nextMonth] + "_" + nextMonthYear);
		System.out.println(list3);

	}

	private List<SRM> getSRMs(String month) {
		ArrayList<SRM> result = new ArrayList<SRM>();
		try {
			Parser parser = new Parser(calendarURL + month);
			NodeList list = parser
					.parse(new HasAttributeFilter("class", "srm"));
			SimpleNodeIterator it = list.elements();
			while (it.hasMoreNodes()) {
				NodeList children = it.nextNode().getChildren();
				children.keepAllNodesThatMatch(new TagNameFilter("a"));
				Node a = children.elementAt(0);
				if (a instanceof LinkTag) {
					LinkTag link = (LinkTag) a;
					SRM srm = new SRM();
					srm.setName(link.toPlainTextString());
					srm.setUrl(link.getLink());
					List<Date> dates = getTimes(srm.getUrl());
					srm.setRegistrationTime(dates.get(0));
					srm.setCompetitionTime(dates.get(1));
					result.add(srm);
				}
			}
		} catch (Exception e) {
			// log
		}
		return result;
	}

	private List<Date> getTimes(String url) {
		ArrayList<Date> dates = new ArrayList<Date>();
		try {
			Parser parser = new Parser(url);
			NodeList list = parser.parse(new HasAttributeFilter("class",
					"statText"));
			SimpleNodeIterator it = list.elements();
			String day = "";
			while (it.hasMoreNodes()) {
				Node node = it.nextNode();
				String text = node.toPlainTextString().replaceAll("\\s", "");
				if (text.matches("..\\..+")) {
					day = text;
				} else {
					dates.add(parseFormat.parse(day + text));
				}
			}
		} catch (Exception e) {
			// log
		}
		return dates;
	}

	public class SRM {
		private String name;
		private String url;
		private Date registrationTime;
		private Date competitionTime;

		@Override
		public String toString() {
			return this.getClass().getName() + "[name=" + name + ",url=" + url
					+ ",registrationTime=" + printFormat.format(registrationTime)
					+ ",competitionTime=" + printFormat.format(competitionTime) + "]";
		}

		public void setName(String name) {
			this.name = name;
		}

		public String getName() {
			return name;
		}

		public void setUrl(String url) {
			this.url = url;
		}

		public String getUrl() {
			return url;
		}

		public void setRegistrationTime(Date registrationTime) {
			this.registrationTime = registrationTime;
		}

		public Date getRegistrationTime() {
			return registrationTime;
		}

		public void setCompetitionTime(Date competitionTime) {
			this.competitionTime = competitionTime;
		}

		public Date getCompetitionTime() {
			return competitionTime;
		}
	}
}