「スクリプト」の編集履歴(バックアップ)一覧に戻る

スクリプト - (2008/01/15 (火) 03:10:27) のソース

#contents()
*スクリプトによる機能拡張

**ランキングを表示する
ソースファイルをメモ帳などに貼り付け、拡張子(.hta)で保存し、実行してください。
動画情報ウィンドウのページがいっぱいになったので、ランキング表示をこちらにもって来ました。pathOfDownloadとpathOfNicoPlayerをそれぞれの環境に合わせて編集してください(セパレータはダブルスラッシュ//です)。青枠がダウンロード済み(再生)、赤枠がまだ(ダウンロード)です。今回は音楽・マイリスト・本日ですが、変更するにはmylist/daily/musicの部分を編集してください。
 <hta:application maximizebutton="no" selection="yes"
                  navigable="no" scroll="no" singleinstance="yes"/>
 <html>
  <head>
   <meta http-equiv="MSThemeCompatible" content="yes">
   <style>
    #dummy { position:absolute; visibility:hidden; }
    td { text-align:center; }
    img { width:80; height:60; margin:3px; cursor:pointer }
    ul { list-style-type:none; margin:1px; }
    li { width:100%; border:3px double; margin:3px; font-size:12px }
   </style>
   <script type="text/javascript" src="prototype.js"></script>
   <script type="text/javascript">
    var pathOfDownload = "ダウンロードパス";
    var pathOfNicoPlayer = "NicoPlayerパス";
    
    var localFlvFiles;
    
    $_ = function( target, key ) {
     return $A( target.getElementsByTagName( key ) );
    }
    $_A = function( target, key ) {
     return target.getAttribute( key );
    }
    
    showRanking = function( link ) {
     resizeTo( 1080, 880 );
     searchFlvFiles();
     var url = "http://www.nicovideo.jp/ranking/mylist/daily/music";
     new Ajax.Request( url, { method : "get", onComplete : parseRankingPage } );
    }
    
    parseRankingPage = function( response ) {
     var dummy = $( "dummy" );
     dummy.innerHTML = response.responseText;
     
     var items = $A();
     var table = $_( dummy, "table" )[7];
     var trs = $_( table, "tr" ).findAll( function( tr, index ) {
      return ( index % 2 == 0 );
     } );
     trs.each( function( tr ) {
      var movieName = $_( tr, "a" )[1].href.match( /sm\d+/ )[0];
      var flag = localFlvFiles[movieName];
      var target = $_( tr, "p" )[1].innerHTML.match( /[\d,]+/ )[0];
      items.push( { date    : $_( tr, "strong" )[1].innerHTML
                  , time    : $_( tr, "strong" )[0].innerHTML
                  , play    : $_( tr, "strong" )[2].innerHTML
                  , comment : $_( tr, "strong" )[3].innerHTML
                  , mylist  : "-"
                  , title   : $_( tr, "a" )[1].innerHTML
                  , name    : movieName
                  , color   : flag ? "blue" : "red"
                  , action  : flag ? "play" : "download"
                  , src     : $_( tr, "img" )[1].src
                  , target  : target
                  } );
     } );
     
     dummy.innerHTML = "";
     showList( items );
    }
    
    showList = function( items ) {
     var template = new Template( "<img width='100' src='#{src}' />" );
     var tr = $( "target" ), td, ul;
     items.each( function( item, index ) {
      if( !( index % 10 ) ) {
       if( td && ul ) {
        td.appendChild( ul );
        tr.appendChild( td );
       }
       td = document.createElement( "td" );
       ul = document.createElement( "ul" );
      }
      var li = document.createElement( "li" );
      li.style.cssText = "border-color:" + item.color;
      var img = document.createElement( "img" );
      img.setAttribute( "src", item.src );
      img.setAttribute( "onclick" , new Function( item.action + "( \'" + item.name + "\' );" ) );
      img.setAttribute( "title", 
       item.title + "\n再生:" + item.play + " コメント:" + item.comment + " ターゲット:" + item.target
      )
      li.appendChild( img )
      ul.appendChild( li );
     } );
     td.appendChild( ul );
     tr.appendChild( td );
    }
    
    searchFlvFiles = function() {
     if( !localFlvFiles ) {
      localFlvFiles = $H();
      var fs = new ActiveXObject( "Scripting.FileSystemObject" );
      var files = new Enumerator( fs.GetFolder( pathOfDownload ).Files );
      while( !files.atEnd() ) {
       if( files.item().Name.match( /(sm\d+).*\.flv/ ) ) {
        localFlvFiles[RegExp.$1] = files.item();
       }
       files.moveNext();
      }
     }
    }
    
    function execBuildupCommand( argument )
    {
     var shellObject = new ActiveXObject( "WScript.Shell" );
     shellObject.Run( "\"" + pathOfNicoPlayer + "\\NicoPlayer.exe\" " + argument, 0, true );
     shellObject = null;
    }
    
    var play = function( movieName ) {
     execBuildupCommand( "\"" + localFlvFiles[movieName].Path + "\"" );
    }
    
    var download = function( movieName ) {
     execBuildupCommand( "http://www.nicovideo.jp/watch/" + movieName );
    }
   </script>
  </head>
  <body onload="showRanking();">
   <table border="0">
    <tr>
     <th> 1-10</th><th>11-20</th><th>21-30</th><th>31-40</th><th>41-50</th>
     <th>51-60</th><th>61-70</th><th>71-80</th><th>81-90</th><th>91-100</th>
    </tr>
    <tr id="target" />
   </table>
   <div id="dummy"></div>
   <div id="debug"></div>
  </body>
 </html>

**ローカルファイルを検索し表示
最上部のテキストボックスにキーワードを入力してTabキーを押すと、ローカルファイルを検索しマッチするファイルをリストアップします。お好きなファイルをクリックして再生してください。onchangeではなくonkeyupを使うとインクリメンタル検索になるのですが、このロジックだと重すぎて実用的ではないのでやめました。
 <hta:application maximizebutton="no" selection="yes"
                  navigable="no" scroll="yes" singleinstance="yes"/>
 <html>
  <head>
   <meta http-equiv="MSThemeCompatible" content="yes">
   <style>
    ul { list-style-type:none; margin:1px; }
    li { cursor:pointer; width:100%; border:3px double; margin:3px; font-size:12px }
   </style>
   <script type="text/javascript" src="prototype.js"></script>
   <script type="text/javascript">
    var pathOfDownload = "ダウンロードパス"; // ex) D:\\Download
    var pathOfNicoPlayer = "NicoPlayerインストールパス";
    
    var localFlvFiles;
    
    $_ = function( target, key ) {
     return $A( target.getElementsByTagName( key ) );
    }
    $_A = function( target, key ) {
     return target.getAttribute( key );
    }
    
    onLoad = function( link ) {
     resizeTo( 500, 800 );
     showList();
    }
    
    showList = function() {
     searchFlvFiles();
     
     // 検索
     var keyword = $F( "keyword" );
     if( keyword ) {
      localFlvFiles = localFlvFiles.findAll( function( file ) {
       return RegExp( keyword, "i" ).test( file.Name );
      } );
     }
     
     // リストクリア
     var ul = $( "target" );
     $A( ul.childNodes ).each( function( child ) {
      ul.removeChild( child );
     } );
     
     // リスト追加
     localFlvFiles.each( function( file, index ) {
      var li = document.createElement( "li" );
      li.setAttribute( "onclick", new Function( "play( \'" + index + "\' );" ) );
      file.Name.match( /(.*)\.flv$/ );
      var text = document.createTextNode( RegExp.$1 );
      li.appendChild( text );
      ul.appendChild( li );
     } );
    }
    
    searchFlvFiles = function() {
     if( !localFlvFiles ) {
      localFlvFiles = $A();
     } else {
      localFlvFiles.clear();
     }
     
     var fs = new ActiveXObject( "Scripting.FileSystemObject" );
     var files = new Enumerator( fs.GetFolder( pathOfDownload ).Files );
     while( !files.atEnd() ) {
      if( files.item().Name.match( /(sm\d+).*\.flv$/ ) ) {
       localFlvFiles.push( files.item() );
      }
      files.moveNext();
     }
    }
    
    execBuildupCommand = function( argument )
    {
     var shell = new ActiveXObject( "WScript.Shell" );
     shell.Run( "\"" + pathOfNicoPlayer + "\\NicoPlayer.exe\" " + argument, 0, true );
     shell = null;
    }
    
    play = function( index ) {
     execBuildupCommand( "\"" + localFlvFiles[index].Path + "\"" );
    }
   </script>
  </head>
  <body onload="onLoad();">
   <input type="text" id="keyword" onchange="showList();" />
   <ul id="target" />
  </body>
 </html>


**マイページに登録されているうち、ダウンロード済みアイテムのプレイリストを作成し開く
ソースファイルをメモ帳などに貼り付け、拡張子(.js)で保存してください。
pathOfNicoPlayerとpathOfDownloadをそれぞれの環境にあったパスに変更してください。
使う時はクリップボードにマイページのアドレス(http://~/0000000/000000:省略不可)を
コピーしてダブルクリックしてください。
またNicoPlayerのプレイリストウィンドウが表示されていれば、自動的に開きます。
 // 環境設定
 var pathOfNicoPlayer = "NicoPlayerのインストールパス(パスセパレータ \\)";
 var pathOfDownload = "動画ファイルのダウンロードパス(同上)";
 
 // クリップボードからマイページのアドレスを取得
 var ieObject = new ActiveXObject( "InternetExplorer.Application" );
 ieObject.Navigate( "about:blank" );
 while ( ieObject.Busy ) {
  WScript.Sleep( 100 );
 }
 var addressOfMypage = ieObject.Document.parentWindow.clipboardData.getData( "text" );
 ieObject.Quit();
 
 // マイページアドレスが取得できなかった場合入力ウィンドウを表示(Excelのインストールが必要)
 if( !addressOfMypage.match( /.*\/([0-9]+)\/([0-9]+)/ ) ) {
  var excelObject = WScript.CreateObject( "Excel.Application" );
  if( excelObject != null )
  {
   addressOfMypage  = excelObject.InputBox( "マイページのアドレスを入力してください" );
   excelObject.Quit();
  }
 }
 
 // Msxml2(IE6標準)によりマイページのGETリクエスト送出
 var httpObject = WScript.CreateObject( "Msxml2.XMLHTTP" );
 httpObject.onreadystatechange = function()
 {
  if( httpObject.readyState == 4 )
  {
   getRequestPage( httpObject );
  }
 }
 // open( , , false )は同期指定(さもないと取得前にプログラムが終了する)
 httpObject.open( "GET", addressOfMypage, false );
 httpObject.send( "" );
 
 function getRequestPage( httpObject )
 {
  // マイページのテキストを検索しID(sm[0-9]+)をリストアップ
  var requestPageText = httpObject.responseText;
  var mypageIdList = requestPageText.match( /sm[0-9]+/g );
  if( mypageIdList == null ) {
   return; // IDが見つからず
  }
  
  // ダウンロードフォルダを検索し.flvファイルをIDに基づいてリストアップ
  var filesHash = {};
  var fsoObject = WScript.CreateObject( "Scripting.FileSystemObject" );
  var filesCollection = fsoObject.GetFolder( pathOfDownload ).Files;
  for( var file = new Enumerator( filesCollection ); !file.atEnd(); file.moveNext() ) {
   var fileName = file.item().Name;
   if( fsoObject.GetExtensionName( fileName ) == "flv" ) {
    filesHash[fileName.match( /sm[0-9]+/ )] = file.item().Path;
   }
  }
  
  // マイページのIDとローカルファイルを紐付けプレイリスト形式にする
  var newPlaylistText = "", newDownloadListText = "";
  for( var i = 0; i < mypageIdList.length; i += 2 ) {
   if( filesHash[mypageIdList[i] ] != undefined ) {
    newPlaylistText += filesHash[mypageIdList[i] ] + "\n";
   }
  }
  
  // プレイリストファイル(.m3u)に落とす
  addressOfMypage.match( /.*\/([0-9]+)\/([0-9]+)/ );
  var newPlylistFileName = RegExp.$1 + "_" + RegExp.$2 + ".m3u";
  // OpenTextFile( , 2, true )の2は書出指定(読込1・追記8)、trueは新規作成あり
  var pathOfNewPlaylistFile = pathOfNicoPlayer + "\\" + newPlylistFileName;
  var newPlaylistFile = fsoObject.OpenTextFile( pathOfNewPlaylistFile, 2, true );
  newPlaylistFile.Write( newPlaylistText );
  newPlaylistFile.Close();
  
  // NicoPlayerが.m3uファイルのD&Dに対応すると、以下の全ては次の1行になります
  // shellObject.Run( "\"" + pathOfNicoPlayer + "\\NicoPlayer.exe\" \"" + pathOfNewPlaylistFile + "\"" );
  
  // プレイリストファイルパスをクリップボードへコピー
  var ieObject = new ActiveXObject( "InternetExplorer.Application" );
  ieObject.Navigate( "about:blank" );
  while ( ieObject.Busy ) {
   WScript.Sleep( 100 );
  }
  ieObject.Document.parentWindow.clipboardData.setData( "text", pathOfNewPlaylistFile );
  ieObject.Quit();
  
  // NicoPlayerのプレイリストウィンドウに登録する
  var shellObject = WScript.CreateObject( "WScript.Shell" );
  shellObject.AppActivate( "NicoPlayer - プレイリスト" );
  WScript.Sleep( 100 );
  shellObject.SendKeys( "^O" );
  WScript.Sleep( 100 );
  shellObject.SendKeys( "^V" );
  WScript.Sleep( 100 );
  shellObject.SendKeys( "%O" );
 }

**プレイリストウィンドウにプレイリストファイルをドラッグ&ドロップする(Cランタイム使用)
使い勝手向上のためぜひともD&Dを実装したかったが、スクリプトのみでは実装できなかった。
WindowsAPIをVBAでラップすれば可能だが、あまりに煩雑なので断念した。

[マイページに登録されているうち、ダウンロード済みアイテムのプレイリストを作成し開く]の
\// NicoPlayerが.m3uファイルのD&Dに対応すると、以下の全ては次の1行になります
以下を次のように置き換える。
 var shellObject = new ActiveXObject( "WScript.Shell" );
 shellObject.Run( "\"ランタイム名.exe\" \"CWndPlayList\" \"NicoPlayer - プレイリスト\" \"" + pathOfNewPlaylistFile + "\"", 0 );
 shellObject = null;
ランタイム(正確には違うが)のコードは以下の通り。
開発環境は[[Microsoft公式>http://www.microsoft.com/japan/msdn/vstudio/express/visualc/usingpsdk/]]を参考にしてください。
 #define STRICT
 #include <windows.h>
 #include <cstring>
 
 // DnD操作におけるOS領域のメモリ構造定義
 typedef struct drop_files{
  DWORD pFiles;
  POINT pt;
  bool fNC;
  bool fWide;
 } DropFiles;
 
 int main( int argc, char *argv[] )
 {
  // パラメータが3個([0]は実行ファイルのパス)未満なら終了
  if( argc < 4 ) {
   return 0;
  }
  
  // 指定窓が見つからなければ終了
  // ([1]:クラス名・[2]タイトル、空文字列も検索条件、無効にするにはNULL)
  HWND hWndTarget = FindWindowExA( NULL, NULL, argv[1], argv[2] );
  if( !hWndTarget ) {
   return 0;
  }
  
  // D&D操作のための情報を作成
  DropFiles df = { sizeof( DropFiles ), { 0, 0 }, false, false };
  char *file = argv[3];
  
  // OS領域のメモリリソースを確保し情報を転送
  HGLOBAL hGlobalMemory = GlobalAlloc( GHND, sizeof( DropFiles ) + strlen( file ) + 1 );
  void *p = GlobalLock( hGlobalMemory );
  memcpy( p, ( void * )&df, sizeof( DropFiles ) );
  memcpy( ( char * )p + sizeof( DropFiles ), ( void * )file, strlen( file ) + 1 );
  GlobalUnlock( hGlobalMemory );
  
  // 指定窓に通知
  PostMessageA( hWndTarget, WM_DROPFILES, ( WPARAM )hGlobalMemory, 0 );
  
  // OS領域のメモリリソースを開放
  GlobalFree( hGlobalMemory );
  
  return 0;
 }

*コメント
#pcomment()
目安箱バナー