// ==UserScript==
// @name RZD Ticket export to calendars
// @description Exports information from RZD (Russian Railroad) ticket description to Google Calendar and Yandex Calendar
// @author Mikhail Dvorkin, [email protected]
// @namespace http://dvorkin.me/
// @website http://dvorkin.me/
// @version 2.0.0
// @include http://ticket.rzd.ru/*
// @include https://ticket.rzd.ru/*
// ==/UserScript==
// a function that loads jQuery and calls a callback function when jQuery has finished loading
// http://erikvold.com/blog/index.cfm/2010/6/14/using-jquery-with-a-user-script
function addJQuery(callback) {
var script = document.createElement("script");
script.setAttribute("src", "http://yandex.st/jquery/1.8.2/jquery.min.js"); // TODO add Google-hosted one, if Yandex doesn't load
script.addEventListener('load', function() {
var script = document.createElement("script");
script.textContent = "(" + callback.toString() + ")();";
document.body.appendChild(script);
}, false);
document.body.appendChild(script);
}
function eventor_main() {
if ($(".tstatus").length && $(".tstatus").html().match(/запрос/i)) {
setTimeout(eventor_main, 300);
return;
}
elreg = $(".money").html().match(/Пройдена электронная регистрация/im);
year = $("body").html().match(/Год совершения поездки: (\d+)/im)[1];
depart = rzd_findDateTime("Departure", year);
arrive = rzd_findDateTime("Arrival", year);
car = $(".traindata-cdat").html().trim().split(/\s+/)[0];
train = $(".traindata-tdat").html().trim().match(/\d+/)[0];
event = "Поезд " + parseInt(train, 10) + ", вагон " + parseInt(car, 10);
details = $(".topinfo-ticketnum").html().trim();
place = $(".route-data .route-points tr:eq(0)");
place = $("td:eq(0)", place).html() + " — " + $("td:eq(1)", place).html().replace(/- > /, "");
busy = "true";
if (elreg) {
details = "Номер заказа: " + details + "\nЭлектронная регистрация";
} else {
event += ", заказ " + details;
details = "";
}
$(".trainfin-carr").append(handleEvent(event, depart, arrive, details, place, busy));
function rzd_findDateTime(s, year) {
td = $("td.route-action:contains('" + s + "')");
table = td.closest("table");
date = $("td.route-date", table).html().trim();
time = $("td.route-time", table).html().trim();
return parseDate(date + "." + year + " " + time);
}
function addTime(timeObj, millis) {
return new Date(timeObj.getTime() + millis);
}
function parseTime(s) {
ss = s.replace(/^[\D]+/, "").split(/[\D]+/);
hour = parseInt(ss[0], 10);
minute = parseInt(ss[1], 10);
return hour * 60 + minute;
}
// 15.09.1987 16:55
function parseDate(s) {
ss = s.replace(/^[\D]+/, "").split(/[\D]+/);
day = parseInt(ss[0], 10);
month = parseInt(ss[1], 10);
year = parseInt(ss[2], 10);
if (year < 100) {
year += 2000;
}
hour = parseInt(ss[3], 10);
minute = parseInt(ss[4], 10);
return new Date(year, month - 1, day, hour, minute);
}
function handleEvent(event, start, end, desc, place, busy) {
return button(event, start, end, desc, place, busy);
}
function button(event, start, end, desc, place, busy) {
links = document.createElement("div");
links.appendChild(make_a("<img src=\"http://www.google.com/calendar/images/ext/gc_button6_ru.gif\" alt=\"Add to Google Calender\" style=\"margin: inherit; padding: inherit\" border=\"0\">", href = href_google(event, start, end, desc, place, busy)));
// links.appendChild(document.createElement("br"));
links.appendChild(make_a("<img src=\"http://calendar.yandex.ru/i/calendar-button.gif\" alt=\"Добавить в Яндекс.Календарь\" style=\"margin: inherit; padding: inherit\" border=\"0\"/>", href_yandex(event, start, end, desc, place, busy)));
// links.appendChild(document.createElement("br"));
links.appendChild(make_a("Download iCal file", href_ical(event, start, end, desc, place, busy)));
links.style.display = "none";
links.style.position = "absolute";
links.style.backgroundColor = "white";
links.style.left = "0px";
links.style.top = "0px";
links.style.padding = "0px";
links.style.margin = "4px";
links.style.border = "3px solid #E05000";
links.style.textAlign = "center";
links.id = "cal_links_" + start + "_" + Math.floor(Math.random() * 1000000000);
links.style.zIndex = "1";
img = document.createElement("img");
img.src = "http://infrared.als.lbl.gov/content/images/stories/calendar_icon.gif";
img.alt = "Add to calendar";
img.style.border = "none";
a = document.createElement("a");
a.href = href;
a.target = "_blank";
a.style.border = "none";
a.setAttribute("oncontextmenu", "return false;");
a.setAttribute("onmousedown",
"if (event.button == 2) {" +
"s = document.getElementById(\'" + links.id + "\').style;" +
"s.display = (s.display == \'block\' ? \'none\' : \'block\');" +
"}" +
"return false;");
links.setAttribute("oncontextmenu", a.getAttribute("oncontextmenu"));
links.setAttribute("onmousedown", a.getAttribute("onmousedown"));
a.appendChild(img);
span = document.createElement("div");
span.style.display = "inline";
span.style.position = "relative";
span.appendChild(a);
span.appendChild(links);
return span;
}
function make_a(html, url) {
a = document.createElement("a");
a.href = url;
a.target = "_blank";
a.innerHTML = html;
a.style.display = "block";
a.style.margin = "inherit";
a.style.padding = "inherit";
//a.appendChild(document.createTextNode(text));
return a;
}
function href_google(event, start, end, desc, place, busy) {
url = "http://www.google.com/calendar/event?action=TEMPLATE";
url += "&text=" + urlFormat(event);
url += "&dates=" + icalDate(start) + "/" + icalDate(end);
url += "&details=" + urlFormat(desc);
url += "&location=" + urlFormat(place);
url += "&trp=" + busy;
url += "&sprop=" + urlFormat("http://dvorkin.me/");
url += "&sprop=name:" + urlFormat("Mikhail Dvorkin");
return url;
}
function href_yandex(event, start, end, desc, place, busy) {
url = "http://calendar.yandex.ru/event-add?";
url += "name=" + urlFormat(event);
url += "&description=" + urlFormat(desc);
url += "&location=" + urlFormat(place);
url += "&start_ts=" + yandexDate(start);
url += "&end_ts=" + yandexDate(end);
return url;
}
function href_ical(event, start, end, desc, place, busy) {
ical = "BEGIN:VCALENDAR";
ical += "\nVERSION:2.0";
ical += "\nMETHOD:PUBLISH";
ical += "\nBEGIN:VEVENT";
ical += "\nDTSTART:" + icalDate(start);
ical += "\nDTEND:" + icalDate(end);
ical += "\nDTSTAMP:" + icalDate(new Date());
ical += "\nUID:" + urlFormat(document.URL);
ical += "\nCREATED:19000101T120000Z";
ical += "\nDESCRIPTION:" + desc;
ical += "\nLAST-MODIFIED:" + icalDate(new Date());
ical += "\nLOCATION:" + place;
ical += "\nSEQUENCE:0";
ical += "\nSTATUS:CONFIRMED";
ical += "\nSUMMARY:" + event;
ical += "\nTRANSP:" + (busy ? "OPAQUE" : "TRANSPARENT");
ical += "\nEND:VEVENT";
ical += "\nEND:VCALENDAR";
return "data:text/calendar;charset=utf-8," + urlFormat(ical);
}
function icalDate(timeObj) {
var dateStr = "" + timeObj.getUTCFullYear();
dateStr += f2(timeObj.getUTCMonth() + 1);
dateStr += f2(timeObj.getUTCDate());
dateStr += "T" + f2(timeObj.getUTCHours());
dateStr += f2(timeObj.getUTCMinutes()) + "00Z";
return dateStr;
}
function yandexDate(timeObj) {
var dateStr = "" + timeObj.getFullYear();
dateStr += "-" + f2(timeObj.getMonth() + 1);
dateStr += "-" + f2(timeObj.getDate());
dateStr += "T" + f2(timeObj.getHours());
dateStr += ":" + f2(timeObj.getMinutes()) + ":00Z";
return dateStr;
}
function f2(s) {
s = "" + s;
return (s.length == 1) ? "0" + s : s;
}
function urlFormat(s) {
return encodeURIComponent(trim(s));
}
function strip(s) {
// TODO it doesn't process <!-- <tag> -->
return trim(s.replace(/(<([^>]+)>)/g, "").replace(/[\n|\r| |\s]+/g, " "));
}
function trim(s) {
return s.replace(/^\s+/, "").replace(/\s+$/, "");
}
}
addJQuery(eventor_main);
Comments