Better ATND

ATNDをより便利にする

Vous devrez installer une extension telle que Tampermonkey, Greasemonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Userscripts pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey pour installer ce script.

Vous devrez installer une extension de gestionnaire de script utilisateur pour installer ce script.

(J'ai déjà un gestionnaire de scripts utilisateur, laissez-moi l'installer !)

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

(J'ai déjà un gestionnaire de style utilisateur, laissez-moi l'installer!)

// ==UserScript==
// @name           Better ATND
// @namespace      http://efcl.info/
// @description    ATNDをより便利にする
// @include        http://atnd.org/events/*
// @include        https://atnd.org/events/*
// @version 0.2.0.20140518104253
// @grant GM_log
// @grant GM_xmlhttpRequest
// ==/UserScript==
/* TEST PAGE
 http://atnd.org/events/13389
 http://atnd.org/events/10996
 */
var DEBUG = false;
function log(m) {
    console.log(arguments);
}
var atndGM = {};
atndGM.eventID = window.location.pathname.split("/").pop();
(function () {
    // ATND APIからイベント情報取得
    function getEventJSON(eventID, callback) {
        if (typeof atndGM[atndGM.eventID] !== 'undefined') {
            callback(atndGM[atndGM.eventID]);
        } else {
            var endpoint = "http://api.atnd.org/events/?event_id=" + eventID + "&format=json";
            GM_xmlhttpRequest({
                method: "GET",
                url: endpoint,
                onload: function (res) {
                    var json = JSON.parse(res.responseText);
                    DEBUG && log(res.statusText, json);
                    atndGM[atndGM.eventID] = json;// キャッシュしておく
                    callback(json);
                },
                onerror: function (res) {
                    GM_log(res.statusText + " : " + res.responseText);
                }
            });
        }
    }

    // 緯度経度情報の取得
    function getGeoinfo(json) {
        var event = json.events[0].event;
        var lon = event.lon,
            lat = event.lat;
        DEBUG && log('lon' + lon, 'lat' + lat);
        if ((lon && lat)
            && (parseFloat(lon) != 0.0 && parseFloat(lat) != 0.0)) {
            // 緯度経度情報が取得できた場合は最寄り駅を取得する
            return {
                'lon': lon,
                'lat': lat
            };
        }
    }

    // 緯度経度から最寄り駅情報を取得
    function getNearsideStation(geo, callback) {
        var endpoint = "http://map.simpleapi.net/stationapi?x=" + String(geo.lon) + "&y=" + String(geo.lat) + "&output=json";
        var count = 0;
        GM_xmlhttpRequest({
            method: "GET",
            url: endpoint,
            onload: function (res) {
                var json = JSON.parse(res.responseText),
                    resultHTML = document.createDocumentFragment();
                var dl = document.createElement('dl');
                dl.setAttribute('class', "clearfix station-info");
                DEBUG && log("near Stations JSON", json);
                for (var i = 0, len = json.length; i < len; i++) {
                    var name = json[i].name;
                    var line = json[i].line;
                    var distance = json[i].distanceKm || json[i].distanceM;
                    var traveltime = json[i].traveltime;
                    var stationInfo = line + "/" + name + "/" + distance + "/" + traveltime;

                    var dt = document.createElement('dt');
                    dt.innerHTML = "最寄り駅 / ST:";
                    var dd = document.createElement('dd');
                    dd.appendChild(document.createTextNode(stationInfo));
                    dl.appendChild(dt);
                    dl.appendChild(dd);
                }
                resultHTML.appendChild(dl);
                DEBUG && log("resultHTML", resultHTML);
                callback(resultHTML);
            },
            onerror: function (res) {
                GM_log(res.statusText + " : " + res.responseText);
            }
        });

    }

    function getStationHTML(callback) {
        getEventJSON(atndGM.eventID, function (res) {
            atndGM.st.geo = getGeoinfo(res);
            if (atndGM.st.geo) {
                getNearsideStation(atndGM.st.geo, function (resHTML) {
                    DEBUG && log("getStationHTML", resHTML);
                    callback(resHTML);
                });
            } else {
                DEBUG && log("getStationHTML : GEO INFO doesn't exist");
                callback();
            }
        });
    }


    atndGM.st = {
        'getEventJSON': getEventJSON,
        'getNearsideStation': getNearsideStation,
        'getStationHTML': getStationHTML
    };
})();
(function gCal() {
    function formatToUTCDate(jstDateTime) {
        if (!jstDateTime) {
            return;
        }
        var dateTime = jstDateTime.replace(/[-,:]/g, "").replace(/.....$/, "");
        var jstDate = Number(dateTime.slice(0, 8));
        var jstTime = Number(dateTime.slice(9, 15));
        var utcDate;
        if (jstTime < 90000) {
            utcDate = jstDate - 1;
        } else {
            utcDate = jstDate;
        }
        var utcTime = String((jstTime + 240000 - 90000) % 240000);
        utcTime = utcTime.length == 6 ? utcTime : '0' + utcTime;
        return utcDate + 'T' + utcTime + 'Z';
    }

    function createCalendarLink(json) {
        json = json || atndGM[atndGM.eventID] || atndGM.st.getEventJSON(createCalendarLink);
        var event = json.events[0].event;// イベントの情報が入ってる
        var descrition = location.href + '\n_' + document.getElementById("post-body").textContent.trim();// API経由だと記法が入ってしまう
        if ("catch" in event) {
            descrition = event["catch"] + "\n" + descrition;// キャッチを追加する
        }
        var description = encodeURIComponent((descrition.length < 300) ? // 文字数が多いとRequest-URI Too Largeになる
                                             descrition : descrition.substring(0, 100) + '...');
        var title = encodeURIComponent(event.title),
            started_at = formatToUTCDate(event.started_at || ""),
            ended_at = formatToUTCDate(event.ended_at || ""),
            address = encodeURIComponent(event.address || "");

        var dates = "&dates=" + started_at + "/"
        if (ended_at) {
            dates += ended_at;
        } else {
            dates += started_at;// ないなら開始時間と同じ
        }
        // カレンダーリンクを生成
        var link = document.createElement('a');
        link.innerHTML = "<img src='http://www.google.com/calendar/images/ext/gc_button1_ja.gif' border=0></a>";
        link.setAttribute('href',
                'https://www.google.com/calendar/event?action=TEMPLATE&text=' + title
                + dates
                + "&details=" + description + "&location=" + address + "&trp=false&sprop=website:atnd.org&sprop;=name:ATND");
        return link;
    }

    atndGM.gCal = {
        'createCalendarLink': createCalendarLink
    }
})();
(function main() {
    var insertArea = document.querySelector('#events-show > div.main');
    var stationArea = insertArea.querySelector('div.events-show-info');
    var mapArea = insertArea.querySelector('div.events-show-map');
    atndGM.st.getStationHTML(function (stationHTML) {
        if (typeof stationHTML !== 'undefined') {
            stationArea.appendChild(stationHTML);
            var stationMapImg = document.createElement("img");
            stationMapImg.src = "http://map.simpleapi.net/stationmap?x=" + atndGM.st.geo.lon + "&y=" + atndGM.st.geo.lat;
            mapArea.appendChild(stationMapImg);
        }
        // Google Calendar
        var title_ul = document.querySelector('div.title-btn > ul');
        var link = atndGM.gCal.createCalendarLink();
        var li = document.createElement("li");
        li.appendChild(link);
        title_ul.appendChild(li);
    });

})();