Created
December 30, 2010 19:23
-
-
Save rosylilly/760170 to your computer and use it in GitHub Desktop.
ニコニコ動画歌詞メンテ支援Greasemonkey
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name NicoLyricManager | |
// @namespace NicoLyricManager | |
// @description ニコ動の歌詞職人支援ツール | |
// @include http://www.nicovideo.jp/watch/* | |
// @include http://nine.nicovideo.jp/watch/* | |
// @excludes | |
// ==/UserScript== | |
(function(){ | |
const GETFLV_URL = 'http://flapi.' + location.host.replace(/^(www|nine)\./, '') + '/api/getflv'; | |
const TABLE_HEAD = '<thead><tr><th>' + [ 'Date', 'No', 'From', 'Pos', 'Cmd', 'Body' ].join('</th><th>') + '</th></thead>'; | |
// All Storage | |
var storage = { | |
user_id: 0, | |
thread_id: 0, | |
length: 0, | |
message_server: '', | |
chats: [] | |
}; | |
// parse URL Query | |
var parseUrlQuery = function(orig){ | |
var orig_ary = orig.split('&'); | |
var params = {}; | |
for(var i=0,l=orig_ary.length; i<l; i++){ | |
var pair = orig_ary[i].split('='); | |
params[unescape(pair.shift())] = unescape(pair.join('=')); | |
}; | |
return params; | |
}; | |
// get video information | |
var getInfo = function(videoId, callback){ | |
var xhr = new XMLHttpRequest(); | |
var params = {}; | |
xhr.open('GET', GETFLV_URL + '?v='+videoId.toString()); | |
xhr.withCredentials = true; | |
xhr.addEventListener('readystatechange', function(e){ | |
if(xhr.status == 200 && xhr.readyState == 4){ | |
params = parseUrlQuery(xhr.responseText); | |
callback(params); | |
}; | |
}, false); | |
xhr.send(); | |
}; | |
// message server | |
var getThread = function(callback){ | |
var xhr = new XMLHttpRequest(); | |
var packet = ( | |
'thread?version=20090904&thread=' + | |
storage.thread_id.toString() + | |
'&user_id=' + | |
storage.user_id.toString() | |
); | |
xhr.addEventListener('readystatechange', function(e){ | |
if(xhr.status == 200 && xhr.readyState == 4){ | |
var xhr2 = new XMLHttpRequest(); | |
var leaves_request = '0-' + parseInt((storage.length / 60) + 1).toString() +':100'; | |
var packet = ( | |
'thread_leaves?version=20090904&thread=' + | |
escape(storage.thread_id.toString()) + | |
'&user_id=' + | |
escape(storage.user_id.toString()) + | |
'&body=' + | |
escape(leaves_request) | |
); | |
xhr2.addEventListener('readystatechange', function(e){ | |
if(xhr2.status == 200 && xhr2.readyState == 4){ | |
callback(xhr2.responseXML); | |
}; | |
}, false); | |
xhr2.open('GET', storage.message_server.toString() + packet); | |
xhr2.send(); | |
}; | |
}, false); | |
xhr.open('GET', storage.message_server.toString() + packet); | |
xhr.send(); | |
}; | |
// video id | |
var videoId = location.pathname.replace(/.*\//,''); | |
// unix time to Date object | |
var unixToDate = function(orig){ | |
var date = new Date(orig * 1000); | |
date.setTime(date.getTime() + (60*60*1000*9)); | |
return date; | |
}; | |
// 1/100 sec position to 00:00 | |
var vposToString = function(vpos){ | |
vpos = parseInt(vpos / 100); | |
var ret = []; | |
var min = parseInt(vpos / 60); | |
var sec = parseInt(vpos % 60); | |
ret.push(min); | |
ret.push(sec < 10 ? '0'+sec.toString() : sec); | |
return ret.join(':'); | |
}; | |
// format date | |
var formatDate = function(date){ | |
var days = ([date.getFullYear(), date.getMonth()+1, date.getDate()]).join('/'); | |
var times = ([date.getHours(), date.getMinutes(), date.getSeconds()]).join(':'); | |
return (days+' '+times); | |
}; | |
// dom ex | |
var setView = function(){ | |
var view_area = document.getElementById('lyric_view'); | |
if(!view_area){ | |
var tab = document.getElementById('itab_description'); | |
view_area = document.createElement('div'); | |
view_area.id = 'lyric_view'; | |
view_area.setAttribute('style', 'border:3px solid #333;padding:5px;'); | |
tab.appendChild(view_area); | |
}; | |
var html_content = []; | |
for(var i=0, l=storage.chats.length; i<l; i++){ | |
var chat = storage.chats[i]; | |
var index = 0; | |
for(var ii=0,ll=storage.leafIndex[chat.leaf].length; ii<ll; ii++){ | |
if(storage.leafIndex[chat.leaf][ii] == chat.no){ | |
index = ii; | |
}; | |
}; | |
html_content.push([ | |
formatDate(chat.date), | |
chat.no, | |
'-' + index.toString(), | |
vposToString(chat.vpos), | |
chat.command.toString(), | |
chat.body].join('</td><td style="padding:2px;">')); | |
}; | |
html_content = ('<tr><td style="padding:2px;">' + html_content.join('</td></tr><tr><td style="padding:2px;">') + '</td></tr>'); | |
html_content = '<tbody>' + html_content + '</tbody>'; | |
html_content = '<table style="font:12px monospace;width:100%;">' + TABLE_HEAD + html_content + '</table>'; | |
view_area.innerHTML = html_content; | |
// reload | |
var reload = document.createElement('a'); | |
reload.setAttribute('href', '#lyric_view'); | |
reload.addEventListener('click', function(e){ | |
e.preventDefault(); | |
getData(); | |
}, false); | |
reload.innerHTML = '更新'; | |
view_area.appendChild(reload); | |
// target change | |
var t_id_input = document.createElement('input') | |
t_id_input.setAttribute('type', 'text'); | |
if(storage.prev_target){ | |
t_id_input.value = storage.prev_target; | |
}; | |
view_area.appendChild(t_id_input); | |
var changeTarget = document.createElement('a'); | |
changeTarget.setAttribute('href', '#lyric_view'); | |
changeTarget.addEventListener('click', function(e){ | |
e.preventDefault(); | |
var target = 0; | |
target = t_id_input.value; | |
getData(target); | |
}, false); | |
changeTarget.innerHTML = '監視ユーザー変更(ID)'; | |
view_area.appendChild(changeTarget); | |
}; | |
var commentSort = function(a, b){ | |
if(a.vpos != b.vpos){ | |
return a.vpos - b.vpos; | |
} else { | |
return a.no - b.no; | |
}; | |
}; | |
var getLeafIndex = function(chats){ | |
var leafs = []; | |
chats.sort(commentSort); | |
for(var i=0, l=chats.length; i<l; i++){ | |
var chat = chats[i]; | |
if(leafs[chat.leaf] == undefined || leafs[chat.leaf] == null){ | |
leafs[chat.leaf] = []; | |
}; | |
leafs[chat.leaf].push(chat.no); | |
}; | |
for(var i=0, l=leafs.length; i<l; i++){ | |
if(leafs[i] == undefined || leafs[i] == null){ | |
leafs[i] = []; | |
}; | |
}; | |
return leafs; | |
}; | |
var getData = function(target){ | |
var target_id = target != null ? target : storage.prev_target; | |
if(!target_id){ | |
target_id = storage.user_id; | |
}; | |
getThread(function(xml){ | |
var nodes = xml.firstChild.childNodes; | |
var chats = []; | |
storage.chats = []; | |
for(var i=0,l=nodes.length; i<l; i++){ | |
var node = nodes[i]; | |
if(node.nodeName.toString().toLowerCase() == 'chat'){ | |
if(node.getAttribute('deleted') != null){ | |
continue; | |
}; | |
if(node.getAttribute('user_id').toString() == target_id){ | |
storage.chats.push({ | |
body: node.textContent.toString(), | |
vpos: parseInt(node.getAttribute('vpos').toString()), | |
command: node.getAttribute('mail') ? node.getAttribute('mail').toString() : '', | |
no: parseInt(node.getAttribute('no').toString()), | |
leaf: parseInt(parseInt(node.getAttribute('vpos').toString())/(100 * 60)), | |
date: unixToDate(parseInt(node.getAttribute('date'))) | |
}); | |
}; | |
chats.push({ | |
vpos: parseInt(node.getAttribute('vpos').toString()), | |
no: parseInt(node.getAttribute('no').toString()), | |
leaf: parseInt(parseInt(node.getAttribute('vpos').toString())/(100 * 60)) | |
}); | |
}; | |
}; | |
chats.sort(commentSort); | |
storage.chats.sort(commentSort); | |
storage.leafIndex = getLeafIndex(chats); | |
storage.prev_target = target_id; | |
setView(); | |
}); | |
}; | |
getInfo(videoId, function(params){ | |
storage.user_id = params['user_id'].toString(); | |
storage.thread_id = params['thread_id']; | |
storage.length = params['l']; | |
storage.message_server = params['ms']; | |
getData(); | |
}); | |
})(); |
Author
rosylilly
commented
Jan 6, 2011
- 2011/1/7 2:50
- コメントリストを表示するタブを変更
- 2011/1/7 3:58
- 自分のユーザーID以外のコメントのリストを取得できるよう変更
- 匿名のユーザーIDでも対象指定できるように変更
- 最新インデックスの計算方法にバグがあったのを修正
- 表示順を動画位置順に変更
- 2011/1/9 2:33
- コメントのソートがおかしいバグを修正
- 日付のカラム表示を追加
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment