Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
api.nicodic.jp依存部分を改修。ニコ百APIが死んでても稼働するように。
// ==UserScript==
// @name nicoLiveTweet 2
// @namespace http://nicolivemac.wordpress.com/
// @description ニコ生お知らせTwitterボタン(Web/Mac用Twitterクライアント対応)
// @include http://live.nicovideo.jp/watch/*
// @include http://live.nicovideo.jp/gate/*
// @include http://live.nicovideo.jp/editstream/lv*
// ==/UserScript==
(function(){
// -----------------------------------------------------------------
// 設定
// -----------------------------------------------------------------
var ownerTitle = new Array( '放送開始', 'On air: ' ); // 放送開始ボタン (ボタンテキスト,挿入テキスト)
var guestTitle = new Array( 'ゲスト出演', 'As a guest: ' ); // ゲスト通知ボタン (ボタンテキスト,挿入テキスト)
var watchTitle = new Array( '視聴', 'Watching: ' ); // 視聴通知ボタン (ボタンテキスト,挿入テキスト)
var waitingTitle = new Array( '順番待ち', 'Waiting... ' ); // 順番待ち通知ボタン (ボタンテキスト,挿入テキスト)
var pastTitle = new Array( 'ツイート', '終了番組: ' ); // 順番待ち通知ボタン (ボタンテキスト,挿入テキスト)
var comingTitle = new Array( 'ツイート', '放送予定: ' ); // 順番待ち通知ボタン (ボタンテキスト,挿入テキスト)
var hashTagText = '#nicolive'; // 固定ハッシュタグ (英数字のみ)
// GM_setValue, GM_getValueが使えない場合Cookieに書き込む
if ( typeof ( GM_setValue ) != 'function' && typeof ( GM_getValue ) != 'function') {
function GM_setValue(name, value) {
document.cookie = [
name, '=', escape(value),
';expires=', (new Date(new Date().getTime() + 365 * 1000 * 60 * 60 * 24)).toGMTString()
].join('');
}
function GM_getValue(name, value) {
var r = new RegExp(name + '=([^;]*)'), m;
if (m = document.cookie.match(r)) return unescape(m[1]);
return value;
}
function GM_delValue(name, value) {
if (GM_getValue(name, false)) document.cookie = name + '=;expires=Thu, 01-Jan-1970 00:00:01 GMT';
}
} else {
var GM_delValue = GM_setValue;
}
// 初期化
if ( GM_getValue( 'tagActivityCheck', '' ) == '' ) GM_setValue( 'tagActivityCheck', 1 ); // タグ追加
if ( GM_getValue( 'liveMasterCheck', '' ) == '' ) GM_setValue( 'liveMasterCheck', 1 ); // 放送主名
if ( GM_getValue( 'seatNumCheck', '' ) == '' ) GM_setValue( 'seatNumCheck', 1 ); // 席番号
if ( GM_getValue( 'staticURLCheck', '' ) == '' ) GM_setValue( 'staticURLCheck', 0 ); // 固定URL
if ( GM_getValue( 'trashboxActivityCheck', '' ) == '' ) GM_setValue( 'trashboxActivityCheck', 0 ); // box自動消
if ( GM_getValue( 'tweetOpt', '' ) == '' ) GM_setValue( 'tweetOpt', 'web' ); // ツイート方法
if ( GM_getValue( 'prefHidden', '' ) == '' ) GM_setValue( 'prefHidden', 0 ); // UI表示(初期値:表示)
// -----------------------------------------------------------------
// Greasemonkey/GreaseKit compatibility
// http://henrik.nyh.se/2009/07/jquery-in-greasekit
// -----------------------------------------------------------------
if (typeof(unsafeWindow) === 'undefined') unsafeWindow = window;
// 放送タイトル取得
var liveTitle = document.title;
liveTitle = liveTitle.replace('&' , '&');
liveTitle = liveTitle.replace(' - ニコニコ生放送' , '');
// 各種判定
var gatePage = document.getElementsByClassName('infobox')[0]; // gateページを判定
if ( gatePage ) var comingPage = document.getElementById('gates'); // 放送予定ページを判定
var checkWaitPage = document.getElementById('wait'); // 順番待ちページを判定
var userLive = document.getElementsByClassName('cominfo')[0]; // ユーザー生放送を判定
if ( gatePage ) var userLive = document.getElementsByClassName('com')[0]
var liveMasterPage = document.getElementById('utility_container'); // 配信ページを判定
var officialLive = document.getElementsByClassName('lvof')[0]; // 運営生を判定
var chLive = document.getElementsByClassName('chinfo')[0]; // チャンネル放送を判定
if ( gatePage ) var chLive = document.getElementsByClassName('chan')[0]
if ( unsafeWindow.room_label ) var ichibaDisplay = 'ichibaDisplay'; // 市場表示判定(席番号取得用)
// 席番号取得
if ( ichibaDisplay && !liveMasterPage ) {
var roomLabel = unsafeWindow.room_label;
var seatNum = unsafeWindow.seet_no;
var seat = ' [';
if ( seatNum == '2525' ) seat += 'タイムシフト';
else if ( roomLabel == 'バックステージパス' ) seat += 'BSPで視聴';
else if ( !(roomLabel.match(/(co\d+)/) || roomLabel.match(/(ch\d+)/)) ) seat += roomLabel + ':' + seatNum + '';
else seat += seatNum + '';
seat += ']';
}
// 放送開始時刻を取得
if ( comingPage ) var comingStartTime
= document.getElementsByClassName('kaijo')[0].getElementsByTagName('strong')[0].innerHTML
+ document.getElementsByClassName('kaijo')[0].getElementsByTagName('strong')[2].innerHTML;
// 放送ID取得
if ( checkWaitPage ) var liveID = location.href.match(/(lv\d+)/)[1];
else var liveID = unsafeWindow.VideoId;
// コミュニティ/チャンネルIDを取得
if ( checkWaitPage ) {
var comURL = document.getElementById('form_box').innerHTML.match(/http:\/\/[\w\.\/]+community[\w\.\/]+/g)[0];
} else if ( gatePage ) {
if ( chLive ) var comURL = document.getElementsByClassName('smn')[0].childNodes[3].getAttribute('href');
if ( userLive ) var comURL = document.getElementsByClassName('smn')[0].childNodes[1].getAttribute('href');
} else {
if ( chLive ) var comURL = document.getElementsByClassName('thumb')[0].childNodes[3].childNodes[3].getAttribute('href');
if ( userLive ) var comURL = document.getElementsByClassName('thumb')[0].childNodes[1].childNodes[3].getAttribute('href');
}
if ( chLive ) var comID = comURL.match(/(ch\d+)/)[1];
if ( userLive || checkWaitPage ) var comID = comURL.match(/(co\d+)/)[1];
// 放送主の名前を取得
if ( userLive && !liveMasterPage ) {
if ( gatePage ) var liveMaster = document.getElementsByClassName('nicopedia_nushi')[0].getElementsByTagName('a')[0].innerHTML;
else var liveMaster = document.getElementsByClassName('date')[0].getElementsByTagName('a')[0].innerHTML;
liveMaster = ' (生主:' + liveMaster + ')';
}
// 放送用ハッシュタグを取得
if ( checkWaitPage ) { // 順番待ち
liveHashTagText = document.getElementById( 'input_twitter_tag' ).getAttribute('value');
if ( liveHashTagText !== '' ) liveHashTagText = ' ' + liveHashTagText;
} else {
// gateページ
if ( gatePage ) {
tweetBtnSrc = document.getElementsByClassName('infobox')[0].childNodes[5].getElementsByTagName('a')[0].getAttribute('data-text');
// 放送ページ
} else {
tweetBtnSrc = document.getElementById('player_btm').getElementsByTagName('a')[0].getAttribute('data-text');
}
liveHashTagTextArray = tweetBtnSrc.match(/\#(\w+)/g);
liveHashTagText = '';
for ( i=0; i<liveHashTagTextArray.length; i+=1 ) {
chk = new RegExp(liveHashTagTextArray[i],'g');
if ( ( liveHashTagTextArray[i] !== hashTagText ) && ( !liveHashTagText.match(chk) ) ) {
liveHashTagText += ' ' + liveHashTagTextArray[i];
}
}
}
// liveTitleにハッシュタグが含まれる場合に削除する
if ( liveTitle.match(liveHashTagText) ) liveTitle = liveTitle.replace(liveHashTagText,'');
if ( liveTitle.match(hashTagText) ) liveTitle = liveTitle.replace(hashTagText,'');
/* debug
if ( liveTitle ) console.log("放送タイトル:" + liveTitle );
if ( liveID ) console.log("放送ID:" + liveID );
if ( comID ) console.log("comID:" + comID );
if ( gatePage ) console.log("gateページ");
if ( comingPage ) console.log("放送予定ページ");
if ( comingStartTime ) console.log(comingStartTime + "放送開始");
if ( checkWaitPage ) console.log("順番待ちページ");
if ( liveMasterPage ) console.log("配信ページ");
if ( userLive ) console.log("ユーザー生");
if ( chLive ) console.log("チャンネル生");
if ( officialLive ) console.log("運営生");
if ( ichibaDisplay ) console.log("市場表示");
if ( seat ) console.log("seat:" + seat);
if ( liveMaster ) console.log("liveMaster:" + liveMaster);
if ( liveHashTagText ) console.log("liveHashTagText:" + liveHashTagText);
*/
// -----------------------------------------------------------------
// jQuery読込み後に実行
// -----------------------------------------------------------------
function jQueryIsReady($) {
// Pluginを読込み
var pluginScript = document.createElement('script');
pluginScript.src = 'http://jquery.thewikies.com/browser/jquery.browser.min.js?';
pluginScript.type = 'text/javascript';
pluginScript.addEventListener("load",function(){
// OS判定
thisOS = $.os.name;
// Main Div Element 生成
var mainFrame = document.createElement('div');
mainFrame.id = 'nicoLiveTweetBox';
mainFrame.style.color = '#000';
mainFrame.style.fontSize = '12px';
mainFrame.style.borderRadius = '5px';
mainFrame.style.MozBorderRadius = '5px'; // FireFox
mainFrame.style.background = '#94e4e8';
mainFrame.style.padding = '3px 15px 3px 3px';
mainFrame.style.position = 'relative';
mainFrame.style.float = 'left';
mainFrame.style.cssFloat = 'left'; // FireFox
mainFrame.style.clear = 'both';
// ボックスを生成
var pushElement;
if ( liveMasterPage ){ // 放送ページ
pushElement = $("#mainContents");
mainFrame.style.margin = '5px 0 5px';
mainFrame.appendChild( createBtn( ownerTitle ) );
} else if ( checkWaitPage ) { // 順番待ちページ
pushElement = $("#wait");
mainFrame.appendChild( createBtn( waitingTitle ) );
} else if ( gatePage ) { // gateページ
pushElement = $("#bn_gbox");
mainFrame.style.margin = '5px 0 5px';
if ( comingPage ) {
comingTitle[1] = comingStartTime + comingTitle[1];
mainFrame.appendChild( createBtn( comingTitle ) );
} else {
mainFrame.appendChild( createBtn( pastTitle ) );
}
} else { // 視聴ページ
if ( officialLive ) pushElement = $("#mainContents_of");
else pushElement = $("#mainContents");
mainFrame.style.margin = '5px 0 5px';
mainFrame.appendChild( createBtn( guestTitle ) );
mainFrame.appendChild( createBtn( watchTitle ) );
}
// 設定ボックスを設置
var prefBox = document.createElement('div');
prefBox.id = 'prefBox';
prefBox.style.lineHeight = '150%';
if ( GM_getValue( 'prefHidden' ) == 1 ) prefBox.style.display = 'none';
// チェックボックスを設置
var checkHeader = document.createElement('div');
checkHeader.innerHTML = 'ツイート内容の選択';
checkHeader.style.fontWeight = 'bold';
checkHeader.style.color = '#007';
var checkDiv = document.createElement('div');
checkDiv.id = 'checkDiv';
checkDiv.style.width = '300px';
checkDiv.style.margin = '0 1px 5px';
checkDiv.appendChild( createCheckBox ( 'tagActivityCheck', 'ハッシュタグ' ) );
checkDiv.appendChild( createCheckBox ( 'tagNicoliveActivityCheck', hashTagText ) );
if ( liveMaster ) checkDiv.appendChild( createCheckBox ( 'liveMasterCheck', '放送主名' ) );
if ( seat ) checkDiv.appendChild( createCheckBox ( 'seatNumCheck', '席番号' ) );
if ( comID ) checkDiv.appendChild( createCheckBox ( 'staticURLCheck', '固定URL' ) );
checkDiv.appendChild( document.createElement('hr') );
checkDiv.appendChild( createCheckBox ( 'trashboxActivityCheck', 'ツイート後にこのボックスを自動消去' ) );
prefBox.appendChild( checkHeader );
prefBox.appendChild( checkDiv );
// ラジオボタンを設置
if ( thisOS == 'mac' ) {
var radioDiv = document.createElement('div');
radioDiv.id = 'radioDiv';
radioDiv.style.width = '300px';
radioDiv.style.margin = '0 0 2px';
radioDiv.appendChild( createRadioBtn ( 'web', 'Web' ) );
radioDiv.appendChild( createRadioBtn ( 'Tw', 'Tweetie' ) );
radioDiv.appendChild( createRadioBtn ( 'YF', '夜フクロウ' ) );
radioDiv.appendChild( createRadioBtn ( 'Ef', 'Echofon' ) );
radioDiv.appendChild( createRadioBtn ( 'Twi', 'Twitter for Mac' ) );
var radioHeader = document.createElement('div');
radioHeader.innerHTML = 'クライアント選択(Macのみ)';
radioHeader.style.fontWeight = 'bold';
radioHeader.style.color = '#007';
prefBox.appendChild( radioHeader );
prefBox.appendChild( radioDiv );
}
// 設定ボックスを挿入
mainFrame.appendChild( prefBox );
// 削除ボタンを設置
var trashboxBtn = document.createElement('span');
trashboxBtn.innerHTML = '×'
trashboxBtn.id = 'trashbox';
trashboxBtn.title = 'お知らせボックスを消す';
trashboxBtn.style.display = 'block';
trashboxBtn.style.textAlign = 'center';
trashboxBtn.style.lineHeight = '15px';
trashboxBtn.style.width = '15px';
trashboxBtn.style.height = '15px';
trashboxBtn.style.color = '#FFF';
trashboxBtn.style.backgroundColor = '#94e4e8';
trashboxBtn.style.border = '#FFF 2px solid';
trashboxBtn.style.position = 'absolute';
trashboxBtn.style.top = '-5px';
trashboxBtn.style.right = '-5px';
trashboxBtn.style.cursor = 'pointer';
trashboxBtn.addEventListener ( 'click', function(){ displaynone(); }, false );
mainFrame.appendChild( trashboxBtn );
// 伸縮ボタンを設置
var animateBtn = document.createElement('div');
animateBtn.id = 'animateBtn';
animateBtn.innerHTML = '=';
animateBtn.style.color = '#FFF';
animateBtn.style.lineHeight = '100%';
animateBtn.style.backgroundColor = '#baefef';
animateBtn.style.textAlign = 'center';
animateBtn.style.margin = '3px 0 0';
animateBtn.title = '詳細設定を開く/隠す';
animateBtn.style.cursor = 'pointer';
mainFrame.appendChild( animateBtn );
// Twitter送信ボタンをページに挿入
pushElement.append( mainFrame );
// アニメーションを追加
$("#animateBtn").click(function(){
$("#prefBox").animate({height:"toggle",width:"toggle",opacity:"toggle"},"fast");
if ( GM_getValue( 'prefHidden' ) == 0 ) GM_setValue('prefHidden', 1);
else GM_setValue('prefHidden', 0);
});
}, false);
document.getElementsByTagName('head')[0].appendChild(pluginScript);
}
// -----------------------------------------------------------------
// jQueryIsReady($) END
// -----------------------------------------------------------------
// ボタン生成
function createBtn ( data ){
var buttonName = data[0];
var twitterText = data[1];
var tweetBtn = document.createElement('button');
var tweetBtnTxt = document.createTextNode( buttonName );
tweetBtn.addEventListener ( 'click', function(){ tweetWindowOpen( twitterText ); }, true );
tweetBtn.appendChild( tweetBtnTxt );
tweetBtn.style.border = '2px outset #AAA';
tweetBtn.style.borderRadius = '4px';
tweetBtn.style.MozBorderRadius = '4px'; // FireFox
tweetBtn.style.backgroundColor = '#EEE';
tweetBtn.style.width = '80px';
tweetBtn.style.marginRight = '3px';
tweetBtn.style.cursor = 'pointer';
return tweetBtn;
}
// チェックボックス生成
function createCheckBox ( id, txt ) {
var checkboxLabel = document.createElement('label');
checkboxLabel.style.margin = '0 4px 0 0';
checkboxLabel.style.display = 'inline-block';
var checkboxLabelText = document.createTextNode(txt);
var activityCheckBox = document.createElement('input');
activityCheckBox.id = id;
activityCheckBox.type = 'checkbox';
activityCheckBox.style.margin = '0 2px 0 0';
activityCheckBox.addEventListener ( 'click', function(){ swapValue( id ); }, true );
if ( GM_getValue( id ) == 1 ) activityCheckBox.checked = true;
checkboxLabel.appendChild( activityCheckBox );
checkboxLabel.appendChild( checkboxLabelText );
return checkboxLabel;
}
// GM関数に保持するチェックボックスの値を反転
function swapValue ( setValue ) {
if ( GM_getValue( setValue ) == 1 ) GM_setValue( setValue, 0 );
else GM_setValue( setValue, 1 );
}
// ラジオボタン生成
function createRadioBtn ( value, txt ) {
var radioLabel = document.createElement('label');
radioLabel.style.display = 'inline-block';
radioLabel.style.margin = '0 5px 0 0';
radioLabel.style.padding = '0';
radioLabel.addEventListener ( 'click', function(){GM_setValue( 'tweetOpt', value );}, true );
var radioLabelText = document.createTextNode(txt);
var radioButton = document.createElement('input');
radioButton.type = 'radio';
radioButton.name = 'tweetOpt';
radioButton.value = value;
radioButton.style.margin = '0 2px 0 0';
if ( GM_getValue( 'tweetOpt' ) == value ) radioButton.checked = true;
radioLabel.appendChild( radioButton );
radioLabel.appendChild( radioLabelText );
return radioLabel;
}
// ツイート方法の選択
function tweetStepFlag() {
var radioDiv = document.getElementById('radioDiv');
if ( thisOS == 'mac' ) { // for Mac
for ( i = 0; i < radioDiv.childNodes.length; i++ )
if ( radioDiv.getElementsByTagName('input')[i].checked ) flag = i;
return flag;
} else { // for Win
return 0;
}
}
// statusテキスト生成
function setText( txt, liveTitle, liveID, hashTag ){
var tweetBody;
if ( ( GM_getValue( 'staticURLCheck' ) == 1 ) && ( comID ) ) var liveURL = ' http://nico.ms/l/' + comID;
else var liveURL = ' http://nico.ms/' + liveID;
if ( checkWaitPage ) {
var waitNum = document.getElementById('que_count').innerHTML;
var startTime = document.getElementById('que_start_time').innerHTML;
tweetBody = txt + waitNum + '人待ち ' + startTime + '開始予定';
tweetBody += hashTag;
if ( tweetStepFlag() !== 0 ) tweetBody += liveURL;
} else {
// 140文字制限
var totalLength = txt.length + liveTitle.length;
if ( userLive && !liveMasterPage && document.getElementById( 'liveMasterCheck' ).checked ) totalLength += liveMaster.length;
if ( seat && document.getElementById( 'seatNumCheck' ).checked ) totalLength += seat.length;
if ( hashTag ) totalLength += hashTag.length;
if ( tweetStepFlag() != 0 ) totalLength += liveURL.length;
else totalLength += 22; // t.co短縮URL分(適当です…)
var trim = ( totalLength - 139 );
if ( totalLength > 140 ) var liveTitle = liveTitle.substring( 0, liveTitle.length - trim ) + '';
// テキスト生成
tweetBody = txt + liveTitle;
if ( userLive && !liveMasterPage && document.getElementById( 'liveMasterCheck' ).checked ) tweetBody += liveMaster;
if ( seat && document.getElementById( 'seatNumCheck' ).checked ) tweetBody += seat;
if ( hashTag ) tweetBody += hashTag;
if ( tweetStepFlag() != 0 ) tweetBody += liveURL;
}
return tweetBody;
}
// Tweetウィンドウを開く/クライアントにテキストを渡す関数
function tweetWindowOpen ( postText ) {
// ハッシュタグ挿入を選択
var hashTag = '';
if ( GM_getValue( 'tagActivityCheck' ) == 1 ) {
if ( ( hashTagText !== '' ) && ( GM_getValue( 'tagNicoliveActivityCheck' ) == 1 ) ) hashTag = ' ' + hashTagText;
if ( liveHashTagText ) hashTag += liveHashTagText;
}
// nicoLiveTweetボックス自動消去を選択・チェック入りの場合は自動消去
if ( document.getElementById('trashboxActivityCheck').checked ) displaynone();
var tweetText = setText( postText, liveTitle, liveID, hashTag );
// ウィンドウを開く・クライアントを呼びだす
if ( tweetStepFlag() == 0 ) { // Web
var pageURL = "http://twitter.com/share?text=" + encodeURIComponent( tweetText );
if ( ( GM_getValue( 'staticURLCheck' ) == 1 ) && comID ) {
var tweetURL = "http://live.nicovideo.jp/watch/" + comID;
pageURL = pageURL + "&url=" + encodeURIComponent( tweetURL );
}
var tweetPostWindow = window.open( pageURL, "postWindow", "width=500,height=400,menubar=no,toolbar=no,status=no,resize=no,scrollbars=no" );
} else if ( tweetStepFlag() == 1 ) { // Tweetie
window.location='tweetie:'+tweetText;
} else if ( tweetStepFlag() == 2 ) { // 夜フクロウ
window.location='yorufukurou://pasteurl/'+tweetText;
} else if ( tweetStepFlag() == 3 ) { // Echofon
window.location='echofon:'+tweetText;
} else if ( tweetStepFlag() == 4 ) { // Twitter for Mac
window.location='twitter://post?message='+encodeURIComponent(tweetText);
}
}
// お知らせボックスを消す関数
function displaynone(){
document.getElementById('nicoLiveTweetBox').style.display = 'none';
return false;
}
// -----------------------------------------------------------------
// jQuery
// http://henrik.nyh.se/2009/07/jquery-in-greasekit
// -----------------------------------------------------------------
var script = document.createElement('script');
script.src = 'http://jquery.com/src/jquery-latest.js?';
script.type = 'text/javascript';
script.addEventListener("load", function() {
unsafeWindow.jQuery.noConflict();
jQueryIsReady(unsafeWindow.jQuery);
}, false);
document.getElementsByTagName('head')[0].appendChild(script);
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment