(Chromeでも動作するようにしました⇒「ドットインストール用のGreasemonkeyスクリプト (2)」)
プログラミング学習サイトの「ドットインストール」には非常にお世話になっているが、閲覧画面では「次のレッスンへ移動」する「次へ」ボタンと「そのレッスンを完了」にする「完了」ボタンが別個に用意されているので、動画を見終わって次の動画へ移動する際にうっかり「次へ」のみを押してその回が「完了」されておらず、またその回に戻っていちいち完了しなければならないことがある。
当たり前と言えばそうなのだが、見終わって次へ移動しているので自動で「完了」してくれるようなグリモンスクリプトを組んでみた。
また、レッスンページの表示時には動画は停止状態になっていて、次々にレッスン動画を眺めたい場合には「次へ」⇒「ページ移動」⇒「再生されない」⇒「再生ボタンクリック」の流れがネックになるので、未完了(「完了ボタン」がある)の場合には自動再生するようにもした。
それと、レッスンの最後の回では、本来は「次へ」のボタンは無効なのだが、この動作変更を組み込むと最後の回でも「完了」の動作になっていたほうがよさそうなので、それを有効化してさらに、最後の回の「次へ」の動作としてレッスン一覧へ移動(戻る)ようにしてみた。
現在のドットインストールでは、動画表示にはVimeoを使って(以前はYouTubeだった)いて、内部でHMHMというオブジェクトから操作しているようだ。また、「完了」ボタンの押下をグリモンから実行するためにはunsafeWindowを用いないとダメなようだった。
動作の切り替えチェックボックスも付けました。
http://mechsys.tec.u-ryukyu.ac.jp/http://dotinstall.com/lessons/http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js
http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.4/jquery-ui.min.js
(function(){
$("#lesson-complete-button").parent().append('<div>')
.append('<input id="auto-play" name="autoplay" type="checkbox">自動再生')
.append('<input id="next-complete" name="nextcomplete" type="checkbox">自動完了チェック')
.append('<input id="return-list" name="returnlist" type="checkbox">全完了時に一覧へ');
$('#auto-play').prop("checked", GM_getValue('DotInstallAutoPlay', true));
$('#next-complete').prop("checked", GM_getValue('DotInstallNextComplete', true));
$('#return-list').prop("checked", GM_getValue('DotInstallReturnList', true));
$('#auto-play').change(function(){GM_setValue('DotInstallAutoPlay', $('#auto-play').prop("checked"));});
$('#next-complete').change(function(){GM_setValue('DotInstallNextComplete', $('#next-complete').prop("checked"));});
$('#return-list').change(function(){GM_setValue('DotInstallReturnList', $('#return-list').prop("checked"));});
if ($('#completeButtonLabel')[0].innerHTML.match(/^\s*完了\s*$/)) { if ($('#auto-play').prop('checked')) {
addEventListener('load', function(){unsafeWindow.HMHM.movie.vimeo.player.playVideo();});
}
}
$('#lesson-complete-button').next().click(function() {
var href = $(this).attr('href');
if ($('#return-list').prop('checked') && $(this).hasClass('disabled')) {href = window.location.href.replace(/[^/]+$/, '');} // 最後のリンクではレッスン一覧へ
if ($('#completeButtonLabel')[0].innerHTML.match(/^\s*完了\s*$/) && $('#next-complete').prop('checked')) {
unsafeWindow.$('#lesson-complete-button').click();
//alert('完了しました!');
}
if (!$('#lesson-complete-button').next().hasClass('disabled') || $('#return-list').prop('checked')) {
setTimeout(function(){window.location=href;}, 800); // レッスンの「完了」操作が終わるくらいまで待って移動
}
return false;
});
})();
リンク
CM情報を見ようと思って「野菜は皿か!」で検索しても何も出て来ない…(泣)。
検索語が「名言野郎」ならよかったのか?その名言自体で検索にかからないとは…。
早くクロールされますように…。
Firefoxでカスタマイズをして終了しようとしたら、ボタンを押しても反応しない。
タブバーで他のタブを押すことはできるのだが、表示が切り替わらない。しょうがないので、ウィンドウを閉じて再起動してもこのカスタマイズが残ったまま。この表示を消すには、ウィンドウを閉じる前にカスタマイズバーを閉じてからFirefoxを再起動する。
プラグインが怪しいとみて、いくつか無効化して試していたら、EPSON E-Web Print が見つかった。
で、このプラグインは、印刷時にFlashを有効にしていると不具合が出る場合があるという表記があったので、これをオフにもしてみたが変りがない。
↓
やはりこのプラグインを無効化しないとダメだった…。
C#を勉強してみようかと、Visual Studio 2013を導入しようとしたら、Vistaだとインストーラのダウンロードはできて起動もするものの「VS 2013 requires newer version of Windows」「VS2013 works best with IE10」だとか言ってきて、インストールできない。
Vista用のIEは9で終了らしく、更新も無理のようなので、VS2013はあきらめ、VS2012を探してみることに。
で、MicrosoftのサイトでVS2012を選択したつもりだったが、VS2013以前の版としてはVS2010しか用意されていないようだった。
とりあえず、これをインストールし、さらにサービスパック(SP1)を適用せよと言ってくるので、これを作業。
2014年5月29日 in
未分類 | tags:
C#,
VS2010,
VS2013 |
No Comments
SQLite 3.6.20での話。
次のような2つのテーブルX,Yを用意して、Xにはname、Yにはそれぞれに対応づけしたyearを保存するものとした。
sqlite> CREATE TABLE X (id INTEGER PRIMARY KEY, name TEXT);
sqlite> INSERT INTO X (name) VALUES ('A');
sqlite> INSERT INTO X (name) VALUES ('B');
sqlite> INSERT INTO X (name) VALUES ('C');
sqlite> INSERT INTO X (name) VALUES ('D');
sqlite> CREATE TABLE Y (id INTEGER PRIMARY KEY, year INTEGER, x_id INTEGER);
sqlite> INSERT INTO Y (year, x_id) VALUES (2010, (SELECT id FROM X WHERE name='A'));
sqlite> INSERT INTO Y (year, x_id) VALUES (2011, (SELECT id FROM X WHERE name='B'));
sqlite> INSERT INTO Y (year, x_id) VALUES (2012, (SELECT id FROM X WHERE name='C'));
sqlite> INSERT INTO Y (year, x_id) VALUES (2013, (SELECT id FROM X WHERE name='D'));
sqlite> SELECT Y.id,Y.year,X.name FROM Y LEFT JOIN X ON Y.x_id=X.id;
1|2010|A
2|2011|B
3|2012|C
4|2013|D
YからXを参照する際にXのidとして、x_idというカラム名にしている点に注意。
で、これを更新する際にまとめて指定しようとして WHERE 句での IN を使って正しくは
sqlite> UPDATE Y SET year=2014 WHERE x_id IN (SELECT id FROM X WHERE name IN ('B','C'));
sqlite> SELECT Y.id,Y.year,X.name FROM Y LEFT JOIN X ON Y.x_id=X.id;
1|2010|A
2|2014|B
3|2014|C
4|2013|D
とすべきところを、うっかりYでのx_idに引きずられて、Xのテーブル指定時にもidとせず次のようにx_idとやってしまった。
sqlite> UPDATE Y SET year=2014 WHERE x_id IN (SELECT x_id FROM X WHERE name in ('B','C'));
丸括弧内のサブクエリのSELECTでは存在しないカラム名を指定しているので、通常なら
sqlite> SELECT x_id FROM X WHERE name IN ('B','C');
Error: no such column: x_id
とエラーになるのだが、サブクエリ内にあるとどうもエラーにならず、かつすべての項目が対象になってしまうらしい。
sqlite> UPDATE Y SET year=2014 WHERE x_id IN (SELECT x_id FROM X WHERE name in ('B','C'));
sqlite> SELECT Y.id,Y.year,X.name FROM Y LEFT JOIN X ON Y.x_id=X.id;
1|2014|A
2|2014|B
3|2014|C
4|2014|D
なんてこった…(エラーが発生しないのは、UPDATEのときだけかと思ったら、他のSELECTなどでも同様のようだ)。
これは正しい動作なんだろうか?
サブクエリ内が空になるからかと、次のように試してみたが、
sqlite> UPDATE Y SET year=2014 WHERE x_id IN ();
sqlite> SELECT Y.id,Y.year,X.name FROM Y left JOIN X ON Y.x_id=X.id;
1|2010|A
2|2011|B
3|2012|C
4|2013|D
この場合はINの対象にマッチしないんだから、(当然)更新されなかった。
で、このときうっかりサブクエリ内のINの対象を()にしてしまったが、
sqlite> UPDATE Y SET year=2014 WHERE x_id IN (SELECT x_id FROM X WHERE name IN ());
sqlite> SELECT Y.id,Y.year,X.name FROM Y LEFT JOIN X ON Y.x_id=X.id;
1|2010|A
2|2011|B
3|2012|C
4|2013|D
カラム名でエラーが出ていて先の例からするとすべてが更新対象になりそうなのに、この場合は更新されなかった。
よくわからん…。
SQLiteの最新版は3.8.4.3らしいが、そちらでは動作が変わっているのかな?
[追記]
INに限らず、=でも同様にエラー時にすべてを対象に更新されてしまった。
sqlite> UPDATE Y SET year=2014 WHERE x_id=(SELECT x_id FROM X WHERE name='B');
sqlite> SELECT Y.id,Y.year,X.name FROM Y LEFT JOIN X ON Y.x_id=X.id;
1|2014|A
2|2014|B
3|2014|C
4|2014|D
[追記]
当初、タイトルを「updateの落とし穴」としていましたがupdate時に限らないようなので、当面の原因っぽい「サブクエリの落とし穴」に変更しました。
2014年5月29日 in
未分類 | tags:
SQLite |
1 Comment