Advertisement
Guest User

PopupStatusYoutube.js

a guest
May 7th, 2015
283
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 23.80 KB | None | 0 0
  1. //【登録場所】リンク、URLExec
  2. //【ラベル】Youtube動画情報
  3. //【内容】Youtube動画情報のポップアップ
  4. //【コマンド】${SCRIPT:FrxS} PopupStatusYoutube.js
  5. //【URLExec*】https?://(?:\w+\.)?youtube\.(?:\w+|co\.\w+)/.*?v=[\-_\w]{11}.* $& ${V2CSCRIPT:FrxS} PopupStatusYoutube.js
  6. //【URLExec*(短縮URL用)】http://youtu\.be/[\-_\w]{11} $& ${V2CSCRIPT:FrxS} PopupStatusYoutube.js
  7. //【更新日時】2013/09/11 再生できない動画のステータスのyt:state name=processing時にスクリプトエラーが発生するケースの回避コードを追加
  8. //【更新日時】2015/05/07 古いYouTube Data APIが使えなくなったんで勝手に暫定対応、Googe APIs Console(https://code.google.com/apis/console)でAPIキーの取得が必要
  9. //【スクリプト】
  10.  
  11. // 実行時間計測用
  12. // var odate = new Date;
  13.  
  14. // ============ 設定ここから ============
  15. var closePopup = true;// リンククリックでポップアップを閉じるかどうか
  16. var browseExt = false;// リンククリック時、外部ブラウザで開くかどうか(urlExecが優先)
  17. var urlExec = true;// リンククリック時、URLExec.datの設定に従うかどうか
  18. var browserPath = 'C:/Program Files/Internet Explorer/iexplore.exe';//URLEcex.datの設定に従うときに使用する規定のブラウザのパス(「\」は「/」に置換してください)
  19. var zeroDate = true;// 日付の桁揃えをするかどうか
  20. var zeroTime = true;// 時間の桁揃えをするかどうか
  21. var commentMax = 500;// 表示する投稿者コメントの最大文字数(0で無制限)
  22. var formatType = 2;// 数値のフォーマット(0:なし 1:3桁カンマ区切り 2:日本語表記)
  23. var tagSeparater = ' ';//タグの区切り文字(半角スペースは )
  24. var maxPopupWidth = 500;// ポップアップの最大横幅
  25. var closeOnMouseExit = true;// ポップアップからマウスカーソルを外した時、自動的に閉じるかどうか
  26. var errorPopup = true;// エラーの時、エラー内容をポップアップとして表示
  27. var ratingBarWidth = 150;// レーティングバーの長さ(単位pxを想定)
  28. var downloaderPath = '';// ダウンローダのパス(「\」は「/」に置換してください)
  29. var downloaderArgs = '$PSYURL';// ダウンローダに渡す引数($PSYURLを動画URLに置換して渡します)
  30. var popupFocusable = true;// ポップアップの文字列を選択できるようにするかどうか
  31.  
  32. var API_key = '取得したAPIキー';//YouTube Data API v3対応
  33. // ============ 設定ここまで ============
  34.  
  35. var info = [];
  36. v2c.setStatus('PopupStatusYoutubeスクリプト実行中...');
  37. PopupStatusYoutube();
  38.  
  39. // v2c.print( '実行時間:'+ (new Date - odate) + 'msec\n' );
  40.  
  41. // リンククリック時に呼ばれる関数
  42. function redirectURL( u ) {
  43. if ( u ) {
  44. // ポップアップを再度開く
  45. if ( !closePopup ) {
  46. v2c.context.setPopupHTML( html );
  47. v2c.context.setMaxPopupWidth( maxPopupWidth );
  48. v2c.context.setRedirectURL( true );
  49. v2c.context.setPopupID( info.vid );
  50. v2c.context.setPopupFocusable( popupFocusable );
  51. }
  52. // URLExec
  53. if ( urlExec ) {
  54. v2c.println('teste');
  55. var f = openURLExec( u );
  56. if (f) return;
  57. }
  58. // 外部ブラウザで開く
  59. if ( browseExt ) {
  60. v2c.println('teste');
  61. v2c.browseURLExt( u );
  62. }
  63. // JDICがあれば内部ブラウザで開く
  64. else{
  65. v2c.browseURL( u );
  66. }
  67. }
  68. return;
  69. }
  70.  
  71. function formSubmitted ( u, sm, sd ) {
  72. var data = '';
  73. if ( sd.match( /(.+)=.+/i ) ) {
  74. var data = RegExp.$1;
  75. data = decodeURIComponent(data);
  76. switch (data) {
  77. case 'Fix':
  78. v2c.context.closeOriginalPanel();
  79. closePopup = true;
  80. v2c.context.setPopupHTML( html );
  81. v2c.context.setCloseOnLinkClick( false )
  82. v2c.context.setCloseOnMouseExit( false );
  83. v2c.context.setMaxPopupWidth( maxPopupWidth );
  84. v2c.context.setTrapFormSubmission( true );
  85. v2c.context.setRedirectURL( true );
  86. v2c.context.setPopupID( info.vid );
  87. v2c.context.setPopupFocusable( popupFocusable );
  88. break;
  89. case 'DL':
  90. if ( downloaderPath ) {
  91. downloaderArgs = downloaderArgs.replace( /\$PSYURL/, info.url );
  92. v2c.exec( [ downloaderPath, downloaderArgs ] );
  93. } else {
  94. v2c.alert( 'ダウンローダーのパスを設定してください' );
  95. }
  96. break;
  97. case 'Ext':
  98. // 外部ブラウザボタンクリック時、
  99. // ポップアップを閉じない場合はこの下の行をコメントアウト
  100. v2c.context.closeOriginalPanel();
  101. v2c.browseURLExt( info.url );
  102. break;
  103. case 'CopyTitle':
  104. v2c.context.setClipboardText( info.title );
  105. break;
  106. case 'CopyURL':
  107. v2c.context.setClipboardText( info.url );
  108. break;
  109. case 'CopyTytle+URL':
  110. v2c.context.setClipboardText( info.title + '\n' + info.url );
  111. break;
  112. case 'CopyInfo':
  113. var str = info.title + '\n'
  114. + info.url + '\n'
  115. + '再生時間:' + info.time
  116. + '\n投稿者名:' + info.name
  117. + '\n投稿日時:' + info.ye + '/' + info.mo + '/' + info.da + ' ' + info.ho + ':' + info.mi + ':' + info.se
  118. + '\n再生回数:' + info.viewCount
  119. + '回\nお気に入り:' + info.favCount
  120. + '\n評価:高評価 ' + info.like + ' 人、低評価 ' + info.dislike + ' 人';
  121. v2c.context.setClipboardText( str );
  122. break;
  123. }
  124. }
  125. return;
  126. }
  127.  
  128. function PopupStatusYoutube() {
  129. info.vid = ''; // 動画ID
  130. info.url = ''; // 動画URL
  131. info.thumb = ''; // サムネイルURL
  132. info.title = ''; // 動画タイトル
  133. info.date = ''; // 投稿日時
  134. info.ye = ''; // 西暦
  135. info.mo = ''; // 月
  136. info.da = ''; // 日
  137. info.ho = ''; // 時
  138. info.mi = ''; // 分
  139. info.se = ''; // 秒
  140. info.ms = ''; // ミリ秒 ※多分常に0
  141. info.name = ''; // 投稿者名
  142. info.uri = ''; // 投稿者URI
  143. info.keywords = 'なし'; // キーワード(タグ)
  144. info.time = ''; // 再生時間
  145. info.viewCount = '0'; // 再生回数
  146. info.favCount = '0'; // お気に入り数
  147. info.comment = '説明はありません'; // 投稿者コメント
  148. info.like = 0; // 高評価
  149. info.dislike = 0; // 低評価
  150. info.likeWidth = 0; // 高評価バーの長さ
  151. info.state = ''; // エラー情報
  152.  
  153. // ポップアップIDの初期化
  154. var pid = 'idstring';
  155.  
  156. // URLオブジェクトの取得
  157. var url = v2c.context.link;
  158. info.url = url;
  159.  
  160. // URLオブジェクトがあるかどうかの確認
  161. if ( !url ) {
  162. v2c.print( 'URL取得失敗\n\n' );
  163. if ( errorPopup ) onErrorPopup( 'URL取得失敗' );
  164. return;
  165. }
  166.  
  167. // URLがYoutubeかどうか
  168. if ( url.toString().match( /h?t?tps?:\/\/(?:\w+\.)?youtube\.(?:\w+|co\.\w+)\/.*?v=([\-_\w]{11}).*/i ) ) {
  169. info.vid = RegExp.$1;
  170. var xmlUrl = 'https://www.googleapis.com/youtube/v3/videos?id=' + info.vid + '&key=' + API_key + '&part=snippet,contentDetails,statistics,status';
  171. } else if ( url.toString().match( /h?t?tps?:\/\/youtu\.be\/([\-_\w]{11})/i ) ) {
  172. info.vid = RegExp.$1;
  173. var xmlUrl = 'https://www.googleapis.com/youtube/v3/videos?id=' + info.vid + '&key=' + API_key + '&part=snippet,contentDetails,statistics,status';
  174. }
  175. else{
  176. if ( errorPopup ) onErrorPopup( 'YoutubeのURLではない' );
  177. v2c.print( 'Error:YoutubeのURLではない\n' );
  178. return;
  179. }
  180.  
  181. // VIDEO_ID取得失敗
  182. if ( !info.vid ) {
  183. v2c.print( 'Error:VIDEO_ID取得失敗\n' + url + '\n' );
  184. if ( errorPopup ) onErrorPopup( 'VIDEO_ID取得失敗' );
  185. return;
  186. }
  187.  
  188. // 同じURLのポップアップを開いていたら終了
  189. if ( v2c.context.getPopupOfID( info.vid ) ) {
  190. v2c.print( 'Error:同じURLのポップアップ\n' );
  191. return;
  192. }
  193.  
  194. // // XML DOMオブジェクトの作成
  195. // try {
  196. // var dbf = javax.xml.parsers.DocumentBuilderFactory.newInstance();
  197. // var db = dbf.newDocumentBuilder();
  198. // var doc = db.parse( xmlUrl ); // GET
  199. // }
  200. // catch (e) {
  201. // v2c.print( 'Error:XMLの取得に失敗\n' + e + '\n' );
  202. // if ( errorPopup ) {
  203. // if ( e.toString().indexOf('java.io.FileNotFoundException') != -1 ) {
  204. // onErrorPopup( 'この動画は削除されています', info.vid );
  205. // } else if ( e.toString().indexOf('Server returned HTTP response code: 403') != -1 ) {
  206. // onErrorPopup( '動画情報にアクセス出来ません\nこの動画は非公開等の理由で閲覧できない可能性があります', info.vid );
  207. // } else {
  208. // onErrorPopup( '動画情報へのアクセスに失敗しました', info.vid );
  209. // }
  210. // }
  211. // return;
  212. // }
  213.  
  214. // // XML解析
  215. // //traceNodes( doc );
  216.  
  217. getInfoFromDataAPIv3(info, xmlUrl);
  218.  
  219. // 投稿日時をUTC→ローカル時間に ISO8601形式 例:2010-01-01T00:00:00.000Z
  220. if( info.date.match( /(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})\.(\d{3})Z/ ) ) {
  221. var dd = new Date( RegExp.$1, RegExp.$2, RegExp.$3, RegExp.$4, RegExp.$5, RegExp.$6, RegExp.$7 );
  222. info.ye = dd.getUTCFullYear().toString();
  223. info.mo = dd.getUTCMonth().toString();
  224. info.da = dd.getUTCDate().toString();
  225. info.ho = dd.getUTCHours().toString();
  226. info.mi = dd.getUTCMinutes().toString();
  227. info.se = dd.getUTCSeconds().toString();
  228. info.ms = dd.getUTCMilliseconds().toString();
  229.  
  230. // 12月=0月?
  231. if ( info.mo==0 ) {
  232. info.mo = '12';
  233. }
  234.  
  235. // 日付の桁揃え
  236. if ( zeroDate ) {
  237. info.mo = zeroPlus( info.mo );
  238. info.da = zeroPlus( info.da );
  239. }
  240.  
  241. // 時間の桁揃え
  242. if ( zeroTime ) {
  243. info.ho = zeroPlus( info.ho );
  244. info.mi = zeroPlus( info.mi );
  245. info.se = zeroPlus( info.se );
  246. }
  247. }
  248.  
  249. // キーワードにリンクを付ける
  250. info.keywords = info.keywords.replace( ' ', '' );
  251. info.keywords = info.keywords.replace( ' ', '' );
  252. tmp = info.keywords.split( ',' );
  253. if ( info.keywords != 'なし' ) {
  254. info.keywords = '';
  255. for ( i = 0; i < tmp.length; i++ ) {
  256. info.keywords = info.keywords
  257. + '<a href="http://www.youtube.com/results?search_query='
  258. + encodeURIComponent( tmp[i] ) + '&search=tag">'
  259. + tmp[i] + '</a>' + tagSeparater;
  260. }
  261. }
  262.  
  263. // 再生時間の整形
  264. info.time = zeroPlus( parseInt( info.time / 3600 ) ) + ':'
  265. + zeroPlus( parseInt ( ( info.time % 3600 ) / 60 ) ) + ':'
  266. + zeroPlus( ( info.time % 3600 ) % 60 );
  267.  
  268. // コメントの文字数制限の適用
  269. // コメントをjavascriptのString形式に変換
  270. info.comment += '';
  271. if ( commentMax ) {
  272. tmp = info.comment;
  273. tmp2 = 0;
  274. reg = new RegExp( '(https?:\/\/[\-_\.!~*\'\(\)a-zA-Z0-9;\/\?:\@&=?+\$,%#]+)', 'i' );
  275. // コメント中のURLが途中で切れないようにするための処理
  276. while(1){
  277. if( tmp.match( reg ) ) {
  278. tmp2 = tmp2 + RegExp.leftContext.length + RegExp.$1.length;
  279. if( tmp2 > commentMax ){
  280. commentMax = tmp2;
  281. break;
  282. }
  283. tmp = RegExp.rightContext;
  284. }
  285. else{
  286. break;
  287. }
  288. }
  289. // コメントのカット
  290. if ( info.comment.length > commentMax ) {
  291. info.comment = info.comment.slice( 0, commentMax ) + ' ...';
  292. }
  293. }
  294. // コメントにリンクを付ける
  295. tmp = info.comment;
  296. info.comment = '';
  297. while (1) {
  298. if ( tmp.match( reg ) ) {
  299. info.comment = info.comment + RegExp.leftContext
  300. + '<a href="' + RegExp.$1 + '">' + RegExp.$1 + '</a>';
  301. tmp = RegExp.rightContext;
  302. }
  303. else {
  304. info.comment += tmp;
  305. break;
  306. }
  307. }
  308.  
  309. // 数値の整形
  310. info.viewCount = formatNum( info.viewCount, formatType );
  311. info.favCount = formatNum( info.favCount, formatType );
  312.  
  313. // 置換文字に「$」が入っているとエラーが出る問題の修正
  314. info.title = (info.title+'').replace( /\$/g, '$' );
  315. info.comment = (info.comment+'').replace( /\$/g, '$' );
  316. info.keywords = (info.keywords+'').replace( /\$/g, '$' );
  317.  
  318. // エラーの場合コメントにエラーの理由を設定
  319. if ( !info.thumb && info.state ) {
  320. if ( errorPopup ) onErrorPopup( info.state );
  321. v2c.print( 'Error:' + info.state + '\n' );
  322. return;
  323. }
  324.  
  325. // テンプレートを読み込み
  326. var fs = java.io.File.separator;
  327. html = v2c.readFile( v2c.saveDir + fs + 'script' + fs + 'PopupStatusYoutube'
  328. + fs + 'template.txt' );
  329.  
  330. // デバッグ用 変数出力
  331. //for ( i in info ) { v2c.print( 'info.' + i + ' = ' + info[i] + '\n' ); }
  332.  
  333. // パラメータの置換
  334. html = html.replaceAll( '%vid%', info.vid )
  335. .replaceAll( '%thumb%', info.thumb )
  336. .replaceAll( '%title%', info.title )
  337. .replaceAll( '%ye%', info.ye )
  338. .replaceAll( '%mo%', info.mo )
  339. .replaceAll( '%da%', info.da )
  340. .replaceAll( '%ho%', info.ho )
  341. .replaceAll( '%mi%', info.mi )
  342. .replaceAll( '%comment%', info.comment )
  343. .replaceAll( '%name%', info.name )
  344. .replaceAll( '%uri%', info.uri )
  345. .replaceAll( '%keywords%', info.keywords )
  346. .replaceAll( '%time%', info.time )
  347. .replaceAll( '%viewCount%', info.viewCount )
  348. .replaceAll( '%favCount%', info.favCount )
  349. .replaceAll( '%movie%', url )
  350. .replaceAll( '%like%', info.like )
  351. .replaceAll( '%dislike%', info.dislike )
  352. .replaceAll( '%likeWidth%', info.likeWidth );
  353.  
  354. // ポップアップの設定
  355. v2c.context.setPopupHTML( html );
  356. v2c.context.setMaxPopupWidth( maxPopupWidth );
  357. v2c.context.setCloseOnMouseExit( closeOnMouseExit );
  358. v2c.context.setTrapFormSubmission( true );
  359. v2c.context.setRedirectURL( true );
  360. v2c.context.setPopupID( info.vid );
  361. v2c.context.setPopupFocusable( popupFocusable );
  362. }
  363.  
  364. // 全てのXMLノードを走査
  365. function traceNodes( node ) {
  366. var child = node.getFirstChild();
  367.  
  368. // 子ノードが無くなるまで繰り返し
  369. while ( child != null ) {
  370.  
  371. // ノードが持つ属性(NamedNodeMap)
  372. var attrs = child.getAttributes();
  373.  
  374. // 動画タイトルの取得
  375. if ( child.getNodeName() == 'title' ) {
  376. // テキストノード
  377. info.title = child.getFirstChild().getNodeValue();
  378. }
  379.  
  380. // サムネイルURLの取得
  381. if ( child.getNodeName() == 'media:thumbnail' ) {
  382. var tmp = attrs.getNamedItem( 'url' ).getNodeValue();
  383. if ( tmp.match( /http:\/\/.+?0\.jpg/i ) ) {
  384. info.thumb = tmp;
  385. }
  386. }
  387.  
  388. // 投稿日時の取得 <published>
  389. if ( child.getNodeName() == 'published' ) {
  390. info.date = child.getFirstChild().getNodeValue();
  391. }
  392.  
  393. // 投稿者コメントの取得
  394. if ( child.getNodeName() == 'content' ) {
  395. //存在しない場合もある為、存在チェック
  396. if( child.getFirstChild() ) {
  397. info.comment = child.getFirstChild().getNodeValue();
  398. }
  399. }
  400.  
  401. // 投稿者名の取得
  402. if ( child.getNodeName() == 'name' ) {
  403. info.name = child.getFirstChild().getNodeValue();
  404. info.uri = 'http://www.youtube.com/user/' + info.name;
  405. }
  406.  
  407. // 投稿者URLの取得
  408.  
  409. // キーワード(タグ)の取得
  410. if ( child.getNodeName() == 'media:keywords' ) {
  411. // 存在しない場合もある為、存在チェック
  412. if( child.getFirstChild() ) {
  413. info.keywords = child.getFirstChild().getNodeValue();
  414. }
  415. }
  416.  
  417. // 再生時間の取得
  418. if ( child.getNodeName() == 'yt:duration' ) {
  419. // タグの属性として格納されている
  420. if( attrs ) {
  421. // 再生時間(秒)の取得
  422. if( attrs.getNamedItem( 'seconds' ) ) {
  423. info.time = attrs.getNamedItem( 'seconds' ).getNodeValue();
  424. }
  425. }
  426. }
  427.  
  428. // 再生回数、お気に入り数の取得
  429. if ( child.getNodeName() == 'yt:statistics' ) {
  430. if(attrs){
  431. // 再生回数の取得
  432. if( attrs.getNamedItem( 'viewCount' ) ) {
  433. info.viewCount = attrs.getNamedItem('viewCount').getNodeValue();
  434. }
  435. // お気に入り数の取得
  436. if( attrs.getNamedItem( 'favoriteCount' ) ) {
  437. info.favCount = attrs.getNamedItem('favoriteCount').getNodeValue();
  438. }
  439. }
  440. }
  441.  
  442. // 評価の取得
  443. if ( child.getNodeName() == 'gd:rating' ) {
  444. if(attrs){
  445. var average = attrs.getNamedItem('average').getNodeValue();
  446. var numRaters = attrs.getNamedItem('numRaters').getNodeValue();
  447. // ratingは、高評価=5・低評価=1の2種のみとして算出
  448. if ( average && numRaters ) {
  449. info.like = Math.round( numRaters * ( average - 1 ) / 4 );
  450. info.dislike = numRaters - info.like ;
  451. info.likeWidth = Math.round( ratingBarWidth * ( info.like / numRaters ) );
  452. }
  453. }
  454. }
  455.  
  456. // 再生できない動画のステータス
  457. if ( child.getNodeName() == 'yt:state' ) {
  458. if(attrs){
  459. var name = attrs.getNamedItem('name').getNodeValue();
  460. if ( name == 'processing') {
  461. info.state = 'この動画は現在閲覧できません。';
  462. } else {
  463. var reasonCode = attrs.getNamedItem('reasonCode').getNodeValue();
  464. if ( reasonCode ) {
  465. if ( reasonCode == 'requesterRegion' ) info.state = 'この動画はユーザーの地域では利用できません。';
  466. // これ以下は通常403が返る?
  467. else if ( reasonCode == 'private' ) info.state = 'この動画は非公開動画です。';
  468. else if ( reasonCode == 'copyright' ) info.state = '動画が著作権を侵害しています。';
  469. else if ( reasonCode == 'inappropriate' ) info.state = '動画に不適切なコンテンツが含まれています。';
  470. else if ( reasonCode == 'termsOfUse' ) info.state = '動画が利用規約に違反しています。';
  471. else if ( reasonCode == 'suspended' ) info.state = '動画に関連付けられたアカウントは停止されています。';
  472. else if ( reasonCode == 'blocked' ) info.state = '動画がコンテンツの所有者によりブロックされています';
  473. else info.state = '';
  474. }
  475. }
  476. }
  477. }
  478.  
  479.  
  480. // 再帰
  481. traceNodes( child );
  482. child = child.getNextSibling();
  483. }
  484. return;
  485. }
  486.  
  487. // 桁揃え関数
  488. function zeroPlus( str ) {
  489. return ( '0' + str ).slice( -2 );
  490. }
  491.  
  492. // フォーマット関数
  493. function formatNum( num, type ) {
  494. var str = java.lang.String.valueOf(num);
  495. var tmp = new Array();
  496. var mod,i;
  497. // 3桁カンマ区切り
  498. if ( type == 1 ) {
  499. mod = str.length() % 3;
  500. if ( mod ) {
  501. tmp.push( str.substring( 0, mod ) );
  502. }
  503. for ( i = 0; i < parseInt( str.length() / 3 ); i++) {
  504. tmp.push( str.substring( mod, mod + 3 ) );
  505. mod += 3;
  506. }
  507. return tmp.join(',');
  508. }
  509. // 日本語表記、億まで対応
  510. if ( type == 2 ) {
  511. mod = str.length() % 4;
  512. // 億以上
  513. if ( 2 <= parseInt( str.length() / 4 ) ){
  514. if ( mod ) {
  515. tmp.push( str.substring( 0, mod ) + '億' );
  516. }
  517. if ( str.substring( mod, mod + 4 ).match( /0{0,3}([1-9](\d+)?)/ ) ) {
  518. tmp.push( RegExp.$1 + '万' );
  519. }
  520. if ( str.substring( mod + 4, mod + 8 ).match( /0{0,3}([1-9](\d+)?)/ ) ) {
  521. tmp.push( RegExp.$1 );
  522. }
  523. }
  524. // 億未満、万以上
  525. else if ( 1 <= parseInt( str.length() / 4 ) ) {
  526. if ( mod ) {
  527. tmp.push( str.substring( 0, mod ) + '万' );
  528. }
  529. if ( str.substring( mod, mod + 4 ).match( /0{0,3}([1-9](\d+)?)/ ) ) {
  530. tmp.push( RegExp.$1 );
  531. }
  532. }
  533. // 万未満
  534. else {
  535. tmp.push( str );
  536. }
  537. return tmp.join('');
  538. }
  539. // そのまま
  540. else {
  541. return str;
  542. }
  543. }
  544.  
  545. function onErrorPopup( errStr, vid ) {
  546. if ( !vid ) vid = 'None';
  547. v2c.context.setPopupText( errStr );
  548. v2c.context.setMaxPopupWidth( maxPopupWidth );
  549. v2c.context.setCloseOnMouseExit( true );
  550. v2c.context.setTrapFormSubmission( false );
  551. v2c.context.setRedirectURL( false );
  552. v2c.context.setPopupID( 'PSY_' + vid );
  553. }
  554.  
  555. function openURLExec( url ) {
  556. var url = new java.lang.String( url );
  557. var fs = java.io.File.separator;
  558. var tmp = v2c.readFile( v2c.saveDir + fs + 'URLExec.dat', 'Shift-JIS' );
  559. if ( !tmp ) {
  560. v2c.println( 'URLExec.datが見つかりませんでした' );
  561. return false;
  562. }
  563. var lines = tmp.split( '\n' );
  564. var ptn = java.util.regex.Pattern.compile("^(?<!;|'|//)([^\t]+\t){2}[^\t]+$");
  565. for( var i=0,len=lines.length; i<len; i++ ) {
  566. var matcher = ptn.matcher(lines[i]);
  567. if ( matcher.matches() ) {
  568. //v2c.println( '有効行:' + matcher.group(0) );
  569. } else {
  570. //v2c.println( '!無効行:' + lines[i] );
  571. continue;
  572. }
  573.  
  574. var matchFlg = false;
  575. var item = lines[i].split( '\t' );
  576. if ( item.length != 3 ) { // 念のため
  577. v2c.println( 'Tabの数が不正:' + (item.length-1) );
  578. continue;
  579. }
  580. item[1] = (new java.lang.String(item[1])).replaceAll( '\\$&', '\\$0' );
  581.  
  582. try {
  583. var ptn2 = java.util.regex.Pattern.compile(item[0]);
  584. } catch( e ) { // 不正な正規表現を無視
  585. v2c.println( e );
  586. continue;
  587. }
  588. if ( ptn2.matcher(url).find() ) {
  589. matchFlg = true;
  590. url = url.replaceFirst( item[0], item[1] );
  591. break;
  592. }
  593. }
  594. if ( !matchFlg ) {
  595. v2c.println( 'URLExec.dat:マッチなし\n' + url );
  596. return false;
  597. }
  598.  
  599. var cmds = item[2].split( ' ' );
  600. if ( cmds.length == 0 ) {
  601. v2c.println( 'URLExec.dat:コマンドがありません' );
  602. return false;
  603. }
  604. for ( i=0; i<cmds.length; i++ ) {
  605. var matcher = java.util.regex.Pattern.compile('\\$VIEW').matcher(cmds[i]);
  606. if ( matcher.find() ) {
  607. if ( i==0 ){
  608. v2c.println( 'URLExec.dat:無効なキーワード"$VEIW"' );
  609. return false;
  610. }
  611. }
  612.  
  613. // $BROWSER
  614. if ( browserPath ) {
  615. cmds[i] = cmds[i].replaceAll( '\\$BROWSER', browserPath );
  616. } else {
  617. // ブラウザを指定していない場合で、更にURLExec.datのコマンドが、
  618. // ブラウザにURLを渡すだけの場合はデフォルト外部ブラウザで開く(応急処置)
  619. if( item[2].matches( '"?\\$BROWSER"? "?\\$(URL|LINK)"?' ) ) { //完全一致
  620. v2c.browseURLDefExt(url);
  621. v2c.println( 'cmd='+item[2] );
  622. return true;
  623. }
  624. }
  625.  
  626. // $LINK 置換しない場合は、この下の行をコメントアウト
  627. cmds[i] = cmds[i].replaceAll( '\\$LINK', url );
  628.  
  629. // $URL 置換しない場合は、この下行をコメントアウト
  630. cmds[i] = cmds[i].replaceAll( '\\$URL', url );
  631.  
  632. // $BASEPATH
  633. if ( i==0 ) { // コマンドの場合
  634. cmds[i] = cmds[i].replaceAll( '\\$BASEPATH', v2c.saveDir.toString()
  635. .replaceAll( '\\\\', '/' ) + '/' );
  636. } else { // 引数の場合
  637. cmds[i] = cmds[i].replaceAll( '\\$BASEPATH', v2c.saveDir.toString()
  638. .replaceAll( '\\\\', '\\\\\\\\' ) + '\\\\' );
  639. }
  640.  
  641. // $POSX $POSY
  642. var p = v2c.context.mousePos;
  643. if ( p ) {
  644. cmds[i] = cmds[i].replaceAll( '\\$POSX', p.x );
  645. cmds[i] = cmds[i].replaceAll( '\\$POSY', p.y );
  646. }
  647. v2c.println( 'cmd['+i+']='+cmds[i] );
  648. }
  649. v2c.exec(cmds);
  650. return true;
  651. }
  652.  
  653. //YouTube Data API v3 などから情報を取得
  654. function getInfoFromDataAPIv3(info, xmlUrl){
  655. //YouTube Data API v3から情報を取得
  656. var hr = v2c.createHttpRequest(xmlUrl);
  657. eval('var jso = ' + hr.getContentsAsString());
  658.  
  659. if(jso['items'].length < 1){
  660. return;
  661. };
  662.  
  663. info.thumb = jso['items'][0]['snippet']['thumbnails']['high']['url'];
  664. info.title = jso['items'][0]['snippet']['title'];
  665. info.date = jso['items'][0]['snippet']['publishedAt'];
  666. info.keywords = 'なし';// キーワード(タグ)
  667. info.time = jso['items'][0]['contentDetails']['duration']; // PT5M23S
  668. var temp = info.time.split(/[A-Z]/gi);
  669. info.time = 0;
  670. var cnt = 0;
  671. for(var hms=temp.length-1; hms>=0; hms--){
  672. if(temp[hms] != ''){
  673. info.time = info.time + (cnt==0?Number(temp[hms]):cnt*60*Number(temp[hms]));
  674. cnt++;
  675. if(cnt>=3) break;
  676. }
  677. }
  678. info.viewCount = jso['items'][0]['statistics']['viewCount']
  679. info.favCount = jso['items'][0]['statistics']['favoriteCount']
  680. info.comment = jso['items'][0]['snippet']['description'];
  681. info.like = Number(jso['items'][0]['statistics']['likeCount']);
  682. info.dislike = Number(jso['items'][0]['statistics']['dislikeCount']);
  683. info.likeWidth = 0; // 高評価バーの長さ
  684. info.state = ''; // エラー情報
  685.  
  686. //xmlから情報を取得
  687. var hr = v2c.createHttpRequest('http://www.youtube.com/oembed?format=xml&url=http%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3D' + info.vid);
  688. var xml = (hr.getContentsAsString()+'').replace(/\n|\r/gi, '');
  689. if(xml.match( /<author_name>(.+)?<\/author_name>/)){
  690. info.name = RegExp.$1;
  691. }
  692. if(xml.match( /<author_url>(.+)?<\/author_url>/)){
  693. info.uri = RegExp.$1;
  694. }
  695. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement