foobar2000のwsh panel modのサンプルコード再び(その6)



そういえばテキストファイルに書き込むなんてことを説明するの忘れてたなあと。
このシリーズは不定期に続くかもしれないからそのつもりで。

*注:ファイル操作にかかわるプログラムには注意が必要です。意図しないファイルの上書きや削除などが生じる可能性があります。

*注2:上の注意書きを理解した上で、このスクリプトを動かすためには、設定ー>WSH Panel Modの項目のSafe modeのチェックを外す必要があります。


サンプルファイル
Sample9 TextFile

Image_computer/text.png

現在演奏している曲の曲名とアルバムアーティスト名をファイルに保存するスクリプトです。
書き込みだけだと片手落ちなので読み込みの方も無理やり入れてあります。



// ==PREPROCESSOR==
// @name "Sample9 TextFile"
// @author "Junya Renno"
// ==/PREPROCESSOR==

var WshShell = new ActiveXObject("WScript.Shell");
var fso = new ActiveXObject("Scripting.FileSystemObject");

var g_font = gdi.Font("MS 明朝", 14);
var filename = fb.ProfilePath + "nowtitle.txt";
var tf_query = "";
var from_file_data = "";

if (fb.GetNowPlaying()){
tf_query = get_tf("%title%,%album artist%");
}

function RGB(r, g, b) {
return (0xff000000 | (r << 16) | (g << 8) | (b));
}

function on_paint(gr){
if (tf_query){
tf_query_view = "--- Now Playing ---\n" + tf_query.replace(/,/g,"\n");
gr.DrawString(tf_query_view,g_font,RGB(0,0,0),20,20,window.Width-20,100);
}
if (from_file_data){
from_file_data_view = "--- Read File Data ---\n" + from_file_data.replace(/,/g,"\n");
gr.DrawString(from_file_data_view,g_font,RGB(0,0,0),20,100,window.Width-20,100);
}
}

function on_playback_new_track(){
if(fso.FileExists(filename)){
from_file_data = read_file();
}
tf_query = get_tf("%title%,%album artist%");
if (tf_query){
write_file(tf_query);
}
window.Repaint();
}

function on_playback_stop(){
window.Repaint();
}
function get_tf(tf){
if (fb.GetNowPlaying()){
return fb.Titleformat(tf).eval();
}
}

function write_file(text){
stream = new ActiveXObject("ADODB.Stream");
stream.type = 2;
stream.charset = "utf-8";

stream.open();
stream.writeText(text+"\r\n");
stream.saveToFile(filename, 2);
stream.close();
}

function read_file(){
stream = new ActiveXObject("ADODB.Stream");
stream.type = 2;
stream.charset = "utf-8";

stream.open();
stream.loadFromFile(filename);
text_line = stream.readText(-2);
stream.close();
return text_line;
}


えーと、ファイルが既に存在しているかどうか調べるのに、ActiveXObjectのファイル関係のコマンドを使います。その準備。


var WshShell = new ActiveXObject("WScript.Shell");
var fso = new ActiveXObject("Scripting.FileSystemObject");


細かい初期設定。


var g_font = gdi.Font("MS 明朝", 14);
var filename = fb.ProfilePath + "nowtitle.txt";
var tf_query = "";
var from_file_data = "";


テキストファイルnowtitle.txtはプロファイルのフォルダの下に作るよう、パス(filename)を設定します。
on_paint()は普通に文字を表示しているだけなので省略。


function on_playback_new_track(){
if(fso.FileExists(filename)){
from_file_data = read_file();
}
tf_query = get_tf("%title%,%album artist%");
if (tf_query){
write_file(tf_query);
}
window.Repaint();
}


新しい曲がスタートした時点で、もしファイルが存在すれば(fso.FileExists(ファイルパス)=真)読み込みルーチンread_file()を呼んでfrom_file_dataオブジェクトに収納します。
それからtf_queryにTitle Formattingで問い合わせた結果を入れ、write_file(tf_query)でファイルに書き込みます。
最後にパネルに変更を再描写させて終わりです。


今回の本題、書き込みルーチンですが。


function write_file(text){
stream = new ActiveXObject("ADODB.Stream");
stream.type = 2;
stream.charset = "utf-8";

stream.open();
stream.writeText(text+"\r\n");
stream.saveToFile(filename, 2);
stream.close();
}


今回はADODB.Streamを使っております。理由はutf-8を扱うのに楽だから。

資料としては
●主に言語とシステム開発に関して

●AOK's JavaScript Library

あたりが素晴らしいのではないかと思います。

今回は一行だけなのでアレですが、要は作ったstreamオブジェクトに内容を突っ込んでファイルに書き込めばよろしい。
openした後、きちんとcloseすることを忘れないようにねー。

出来るだけシンプルにするため、例によってエラー処理をまったくしていないので、そこんとこヨロシク。
パス周りに空白文字があると(フォルダ名とか)メンドくさいバグの元になるので注意してください。知ってる人は最初からフォルダやファイル名に空白文字使わずにアンダーバー_で代用してるのさ。

ディスクにアクセスするような比較的重い処理は順番とタイミングを一考することが大事です。


では。


*追記:今回はデータの区切り文字にコンマ[,]を使いましたが、曲タイトル中に存在する可能性のある文字であるため、タブ区切りとか別の工夫をした方が良かったのかな?と思いました。(でも直さない)



 

コメントは日本語でお願いします。(URLは入力禁止:Do not URL writing.) :System message: コメントを受けつけています。