Runner in the High

技術のことをかくこころみ

みくったーの最新版をチェックするPerlスクリプトを作った

 

LWP::UserAgentHTML::TreeBuilderとかいう便利なライブラリを見つけた。
勢いにまかせてみくったーの最新版があるかどうかをチェックするスクリプトPerlで組んでみた。
やってることはダウンロードページのhtmlを無理やりスクレイピングしてるだけです。

#!/usr/bin/perl

#
# みくったーの最新版があるのかどうかを調べるPerlスクリプト
#

use strict;
use warnings;
use LWP::UserAgent;
use HTML::TreeBuilder;

my $target = 'http://mikutter.hachune.net/download';
my $conf = '/home/izumi/mikutter.0.2.2.1328/core/config.rb';
my $installed;
my $string;
my @vers;
my $ver;
my $rev;

# コンピューターにインストールされているバージョンを取得する
open (FILE, $conf) || die "Can't open: $!\n";
while () {
if ($_ =~ /REVISION/ && $_ !~ /TWITTER_AUTHENTICATE_REVISION/) {
if ($_ =~ /VERSION/) { $ver = $_; }
else { $rev = $_; }
}
}
close(FILE);

# ドットを取り除いて比較のために数値へ変換する
@vers = split(/,/, $ver);
$_ =~ s/[^0-9]//g foreach (@vers);
$rev =~ s/[^0-9]//g;
$vers[$#vers] = $rev;
$installed = $installed.$_ foreach (@vers);
$installed += 0;

# 表示のためにまたドットを含むフォーマットに戻す
foreach (@vers) {
$string = $string.$_;
$string = $string."." if ($_ ne $vers[$#vers])
}
print "\nInstalled Ver: ".$string."\n";

# 最新版のバージョンをウェブサイトから取得する
my $ua = LWP::UserAgent->new('agent' => "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)");
my $res = $ua->get($target);
my $content = $res->content;
my $tree = HTML::TreeBuilder->new;
my @items;
my $current;

$tree->parse($content);
@items = $tree->look_down('class', 'accordion versions')->find('li');
foreach (@items) {
$current = $_->as_text;
$current =~ s/[^0-9]//g;
$current += 0;
if ($current > $installed) {
print "Curent Ver: ".$_->as_text,"\n\n";
print "There is a new version!\n";
print "You have to update it ASAP.\n";
exit(1);
}
}

print "\nThere isn't a new version.\n";
print "You don't have to update it :P\n";
exit(0);

すっごい汚いスクリプトになったけど動くからいいだろ(すっとぼけ)

RadioTrayのプラグインを作る

RadioTrayというネットラジオを聴くためのアプリケーションに、プラグインの機能があるので
ちょろっとなにか作ってみる

必要なファイル

- 処理本体を記述するPythonスクリプト
- プラグインそのものの情報を記述するpluginファイル

インストール

/usr/share/radiotray/plugins/に2つのファイルを放り込むだけ

作る

ということでさっそく、簡単なプラグインを書いてみる

[RadioTrayPlugin]
name=Website Jumper
desc=Open the website of the current radio
script=WebsiteJumper.py
class=WebsiteJumper
author=IzumiSy
from events.EventSubscriber import EventSubscriber
from events.EventManager import EventManager
from Plugin import Plugin
import webbrowser

class WebsiteJumper(Plugin):

# 初期化時に実行される関数
def __init__(self):
super(WebsiteJumper, self).__init__()

# 何に使うのかはわからないが必要らしい
def getName(self):
return self.name

# プラグインの設定から有効化されたときに実行される関数
def activate(self):

# SONG_CHANGEDにフックする関数を登録
self.eventSubscriber.bind(EventManager.SONG_CHANGED, self.on_song_changed)

# プラグインメニューに登録
self.tooltip.addSource(self.def_tooltip)

# プラグインのメニューに表示するために必要な関数
def hasMenuItem(self):
return True

# メニューに登録する名前を返す
def def_tooltip(self):
return "Website Jumper"

# SONG_CHANGEDにフックされる関数
def on_song_changed(self, data):
global location

if ('location' in data.keys()):
location = data['location']

# メニューから選択された場合の処理
def on_menu(self, data):
print "[WebsiteJumper] open %s" % (location)
webbrowser.open(location)

コードを見てくれればほとんど解説はいらないはず。
アプリケーションを起動して、ラジオを聴くとSONG_CHANGEDイベントが起きるので、その際に今聴いているラジオ局のウェブサイトのURLをブラウザで開くだけのプラグインです。

ちなみに、ソースコードを見る限りプラグインからフックできるイベントは、いろいろあるらしい。

  • STATE_CHANGED... ラジオのON/OFFとかそういったときに発生するイベント
  • SONG_CHANGED... 聴いているラジオの音楽がかわったときに発生するイベント
  • BOOKMARKS_CHANGED... ブックマークが編集されたとき?に発生するイベント(未検証)
  • STATION_ERROR... ラジオ局に関連するエラーが起きた時に発生するイベント(未検証)
  • VOLUME_CHANGED... ボリュームが変えられたときに発生するイベント(未検証)
  • BOOKMARKS_RELOADED... ブックマークの再読み込み時?に発生するイベント(未検証)
  • NOTIFICATION... 通知に関するイベント?(未検証)

まあ他にもあるんだろうけど、それは自分で調べてください
ソースコードを読むといろいろ書いてあります。(適当)

IzumiSy/WebsiteJumper - Gist

NGC224(UPLIFT SPICE)のタブ譜を作りました


作りました。
CD音源だとギターが2本とシンセ的なのがいるように聴こえますが
そこらへんは面倒なので楽譜にしてません。
ちなみにベースは自分でコピーしたものじゃないのでご了承を。
楽譜ファイルにあるコピーライトの欄をご覧ください。

P.S. 2017/6/21
リンク切れになっていたのを更新しました

(Contents: Gt, Vo, Ba)
DOWNLOAD .ptb format

Android Studio がクソ重い

ちょっとだけ軽くするためのTips的なエントリ

【環境】
Xubuntu 12.04 LTS 32-bit
Intel® Core™ i5 CPU M 560 @ 2.67GHz × 4
RAM 2G

1. Power Save Mode を使う

バックグラウンドでのコード分析とかそういうのを無効にしてちょっと軽くするオプション。
なにが無効になってるのかよくわからないが、結構効果アリ。
 
2. ウィンドウアニメーションを無効にする
Settings -> Appearance -> Window Option の項目から"Animate Windows"のチェックを外す。
いらないでしょこんなもん。

3. テーマを雰囲気軽そうなものにする
UbuntuならGTK+かな? Darculaのがイカしてるけど。
ていうかこれはあんまり効果ないかもしれない。

4. 必要のないプラグインを切る
GitとかSubversionとかターミナルから使うのであれば切れそう。
あとはMavenとかさ。使う人は切れないだろうけど。

オメガリズム(UPLIFT SPICE)のタブ譜を作りました

 
おそらくUPLIFT SPICEが発表している楽曲の中で一番知名度の高いであろう曲
オメガリズム(Omega Rhythm)のタブ譜を作りました。

イントロがクリアできればあとはもう全部簡単?な気がする。
ギターソロも落ち着いてやればきっと問題なし。
いわゆるストリングスキッピングを多用した曲ですな。

P.S. 2017/6/21
リンク切れになっていたのを修正しました

(Contents: Gt1, Gt2)
DOWNLOAD ptb format.

カノジョ(UPLIFT SPICE)のタブ譜作りました


サークルでの演奏のためにUPLIFT SPICEから割と有名?な「カノジョ」のタブ譜を作りました。
ギターから見ると全体的に難易度も高くないので一日あればコピーできるんじゃないでしょうかね。
リズムギターはボーカルと兼ねることを前提に作っていますので簡単です。
おかしなところがあったら自分で直してください。

P.S. 9/15
音源的に見るとこの曲にはギターが二本必要なのですが
ライヴ演奏用に一本にまとめたタブ譜も作りました。
もしかするとこっちのほうがしっくりくるかもしれません。

P.S. 2017/6/21
Dropboxの共有リンクの仕様変更の関係でリンク切れになっていたのを修正しました。

(Contents: Gt1, Gt2 - CD ver.)
DOWNLOAD ptb format.
(Contents: Gt1 - LIVE ver.)
DOWNLOAD ptb format.

Qtでメニューにファビコンを表示したいときのメモ

ファビコン!
 

タイトル通り。
メニューにかっこよくファビコンを表示したい!という人のためのメモ。

QIcon MainWindow::getFavicon(QString url)
{
QEventLoop wait;
QPixmap icon;
QImage img;
QUrl request;

request.setUrl(QString("http://favicon.hatena.ne.jp/?url=%1").arg(url));

netReq = new QNetworkRequest(request);
netRep = netMan->get(*netReq);
connect(netMan, SIGNAL(finished(QNetworkReply*)), &wait, SLOT(quit()));
wait.exec();

img = QImage::fromData(netRep->readAll(), "PNG");
icon = QPixmap::fromImage(img.convertToFormat(QImage::Format_RGB32));

return icon;
}

ファビコンを取得するAPIはてなの非公式のものを使う。

http://favicon.hatena.ne.jp/?url=[URL]

いかんせん非公式なものなのでいつ使えなくなるかはわからない。
でも取得の精度も高いしなくならないといいな。
ちなみに指定するURLにはスキームをちゃんと指定しておかないとまともに動かないので注意。

9、10行目あたりで急に出現するnetRepとかnetReqとかはほとんどQNetwork系の変数。
QNetworkRequestとかQNetworkReplyとか調べればたぶんすぐ分かる、はず。
取得の際にはQEventLoopを用いてこの関数内だけで完結させる。
(排他処理とかがちゃんとしてないのでそこら辺は直したほうがいいかも)

ファビコンのデータが取得できたら上のコードのようにQIconへ変換する。
QImage::convertToFormatにてFormatを指定する際には
QImage::Format_RGB32QImage::Format_Indexed8が指定できる。
取得されるデータは前者を使うと高品質、後者だと低品質なものになる。
他にも指定するともしかしたらなにかが起きるんだろうけどそれは未検証()

void MainWindow::setMenuIcon(void)
{
ui->actionGoogle->setIconVisibleInMenu(true);
ui->actionGoogle->setIcon(getFavicon("http://www.google.co.jp"));

ui->actionAmazon->setIconVisibleInMenu(true);
ui->actionAmazon->setIcon(getFavicon("http://www.amazon.co.jp"));

ui->actionBing->setIconVisibleInMenu(true);
ui->actionBing->setIcon(getFavicon("http://www.bing.com"));

ui->actionYahoo->setIconVisibleInMenu(true);
ui->actionYahoo->setIcon(getFavicon("http://www.yahoo.co.jp"));
}

で、まあこんな感じでひとつひとつメニューアイテムにアイコンをセットしていく。
actionGoogleとかactionBingとかはご覧の通りどれもQActionの変数。
このときにsetIconVisibleInMenuでちゃんと表示するように設定するのを忘れないこと。
以外にこの存在を知らなくてずっと悩んでる人がQtCentreには結構いたような気がする。

PNG形式のファイルを取得してQIconに変換するっていう処理だけで正直結構ハマった。
加えて、あんまりQIconとかQPixmapの変換に関する詳しい資料がネットにない。
ここらへんはまたいつか記事にしてまとめないといかんね。

今回のソースファイルは全てGitHubにて公開してあります
IzumiSy/qfavicon

QUrlQueryとQUrlのメモ

Qt4.xでビルドが通っていたソースコードがQt5.1でなぜかビルドエラーを吐くようになった。
調べてみると、Qt5からQUrlメンバ関数だったaddQueryItemが廃止され
変わりにQUrlQueryというクラスが導入されたとのこと。
ということでそれについてのメモ

QUrl target("http://www.example.com/ex.html");

target.addEncodedQueryItem("AAA", "1234");
target.addEncodedQueryItem("BBB", "5678");

上のコードにおいて変数targetには
 http://www.example.com/ex.html?AAA=1234&BBB=5678
といったようなURLが格納される。
デリミタはsetQueryDelimitersを用いて自由に変更できる。
また、QPairでQListコンテナを作りsetQueryItemsでいくつかのクエリを一気に追加することもできる。

このクエリの追加に関して、新たに導入されたのがQUrlQueryとかいうクラス
使い方は実はすごい簡単

QUrl target("http://www.example.com/ex.html");
QUrlQuery q;

q.addQueryItem("AAA", "1234");
q.addQueryItem("BBB", "5678");
target.setQuery(q);

このコードで、上と同じURLが変数targetに格納される。
可読性は上がるんだろうけど、コードそのものは長くなる気がする。
あとはhasQueryItemとか、いくつかのちょっとしたメンバ関数が増えたくらいか。

参考: How do you port QUrl addQueryItem to Qt5's QUrlQuery? - Stack Overflow