現在のページの位置: くろねこスクエア Labs > 2009年

くろねこスクエア Labs

CodeColorer – WordPressプラグイン

とっつきにくいソースコードなどを色分け表示したい時はありませんか?Syntax Highlighterにはいろいろ種類がありますが、先日、WordPressプラグイン CodeColorerに拙作の日本語リソースを同梱していただきました。

CodeColorerの特徴は…

  • プラグインを無効にしても問題なく表示される
  • サーバサイド処理
  • CSSで色を指定可能

CodeColorerのコアライブラリはGeSHiなので、対応言語の多さには定評があります。例えばgnuplotとかDOT languageにも対応しているんですよ。

コード表示には、この手のツールが、お便利です。

YFeed オークション検索 アップデート

このたび「YFeed」のアップデートを行いました。Yahoo!オークション関連での出力項目を追加したほか、Yahoo!オークションのオリジナルRSSフィードとのパラメータ互換性を高めました。

主な変更点は以下のとおりです。

  • Yahoo!オークションで取得できるRSSフィードのパラメータを、YFeedでもそのまま使用できるようにしました。
  • 即決価格や出品者ID、画像など、オリジナルRSSフィードでは取得できない項目を追加しました。

BASICでパスワード認証

Basic認証に関する話ではありませんので悪しからず。

かつてのBASICは高水準言語として抽象化されていて扱いやすいのですが、抽象化されていない処理については当たり前ながら具体的な手続きを書く必要があります。以下のコードはQuickBASICでの例で、入力されたパスワードをアスタリスク(*)で表示するために行っていた処理です。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
'/for QuickBASIC
'$lang: "qb"

'------- GUI パスワード入力サンプルプログラム

'------設定
CLS 0: WIDTH 80, 25
COLOR 1

pass$ = "abc" 'パスワード
word$ = "" '入力されたパスワード
inword$ = "" '入力途中のパスワード

'------変数の宣言
x = 21'x座標
y = 11 'y座標
r = 0 '一つづづ "*" を描くための座標

'------表示
CLS 0
LINE (140, 140)-(500, 195), 7, BF, 15
LINE (140 + 5, 140 + 5)-(500 - 5, 195 - 5), 1, B

start:
LOCATE y, x, 1'文字の座標へ移動
PRINT "ENTER PASSWORD :" '入力待ち

'------パスワード入力
in:
LOCATE y, x + 17 + r: inword$ = INPUT$(1)

IF inword$ = CHR$(8) THEN GOTO backspace 'BackSpace を押したとき
IF inword$ = CHR$(13) THEN GOTO yorn 'Enter を押したとき
IF r <= 22 THEN PRINT "*": r = r + 1  '"*" を描く

'------入力したパスワードを合成
word$ = word$ + inword$

'------パスワード入力に戻る
back:
inword$ = ""
GOTO in

'------バックスペース
backspace:
IF r >= 1 THEN r = r - 1 ELSE GOTO yorn
LOCATE y, x + 17 + r
PRINT " "
GOTO in

'------パスワードの比較・確認
yorn:
IF word$ = pass$ THEN GOTO exeexit

'------入力された情報の削除
word$ = ""
inword$ = ""
r = 0
CLS 2
GOTO start 'やりなおし

'------終了
exeexit:
CLS 0
END

ある程度構造化してあるので判りやすいかと思います。このような処理は利用機会も多いのでクラスとして抽象化してしまえば再利用しやすいのですが、往年のQuickBASICにはそのような仕組みがなく、プログラムごとに手直しする必要がありました。昨今のBASICはオブジェクト指向を念頭に設計されているものが多いので、初期のBASICに比べれば格段に扱いやすくなっています。もっとも、FreeBASICではクラスの継承は「まだ」実装されていませんが…

それにしても、「パスワードを入力する」というUI自体は10年経っても20年経っても、それほど変わらないですね。

1990年代のあみだくじ

かなり前に作ったあみだくじのプログラムは、以下のようなコードでした。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
'/for QuickBASIC
'$lang: "qb"

DIM a(20), b(10)

ta$ = RIGHT$(TIME$, 2)
RANDOMIZE (ASC(ta$))
FOR y = 1 TO 8: b(y) = INT(RND * 6) + 1: NEXT y

CLS
LOCATE 5, 10: PRINT "1 2 3 4 5 6 7 8"
LOCATE 15,10: INPUT "番号を選んでください ", k
FOR x = 1 TO 8: a(x) = x: NEXT x
FOR y = 1 TO 7
    n = b(y): GOSUB write_line
    c = a(n): a(n) = a(n + 1): a(n + 1) = c
NEXT y

LOCATE 5 + y, 10
IF c = 1 THEN PRINT "○ × × × × × × ×": z = 1
IF c = 2 THEN PRINT "× ○ × × × × × ×": z = 2
IF c = 3 THEN PRINT "× × ○ × × × × ×": z = 3
IF c = 4 THEN PRINT "× × × ○ × × × ×": z = 4
IF c = 5 THEN PRINT "× × × × ○ × × ×": z = 5
IF c = 6 THEN PRINT "× × × × × ○ × ×": z = 6
IF c = 7 THEN PRINT "× × × × × × ○ ×": z = 7
IF c = 8 THEN PRINT "× × × × × × × ○": z = 8

LOCATE 5 + y + 2, 10
IF a(z) = k THEN PRINT k; "はあたりです          ": END
PRINT k; "ははずれです          ": END

write_line:
LOCATE 5 + y, 10
IF n = 1 THEN PRINT "|---|   |   |   |   |   |   |": RETURN
IF n = 2 THEN PRINT "|   |---|   |   |   |   |   |": RETURN
IF n = 3 THEN PRINT "|   |   |---|   |   |   |   |": RETURN
IF n = 4 THEN PRINT "|   |   |   |---|   |   |   |": RETURN
IF n = 5 THEN PRINT "|   |   |   |   |---|   |   |": RETURN
IF n = 6 THEN PRINT "|   |   |   |   |   |---|   |": RETURN
IF n = 7 THEN PRINT "|   |   |   |   |   |   |---|": RETURN

今や昔のQuickBASICかと思いきや、2004年に登場したFreeBASICでは、lang指定さえすれば、このままコンパイルできるのです。マルチバイトも特に問題なし。FreeBASICならGPLでクロスプラットホームですし、過去のプログラムもそれなりに活用できますね。

さらに、FreeBASICならオブジェクト指向風にも書けます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
'/for FreeBASIC
Type Amida
    Dim a(20) as Byte
    Dim b(10) as Byte
    Declare Constructor()
    Declare Sub wrLine (n as Byte)
    Declare Function get_result (c as Byte) as Byte
    Declare Function judge (a() as Byte, k as Byte, z as Byte) as Byte
End Type
'-----------
Constructor Amida()
    Dim ta as String
    Dim as Byte c, k, n, x, y, z
    ta = Right(Time, 2)
    Randomize (Asc(ta))
    For y = 1 To 8: b(y) = Int(Rnd * 6) + 1: Next y
    Cls
    Locate 5, 10: Print "1 2 3 4 5 6 7 8"
    Locate 15,10: Input "番号を選んでください ", k
    For x = 1 To 8: a(x) = x: Next x
    For y = 1 To 7
        n = b(y)
        Locate 5 + y, 10
        This.wrLine(n)
        c = a(n): a(n) = a(n + 1): a(n + 1) = c
    Next y

    Locate 5 + y, 10
    z = This.get_result(c)
   
    Locate 5 + y + 2, 10
    If This.judge(a(),k,z) = 1 Then
        Print k; "はあたりです          "
    Else
        Print k; "ははずれです          "
    End If
End Constructor
'-----------
Function Amida.get_result(c as Byte) as Byte
    Dim z as Byte
    If c = 1 Then Print "○ × × × × × × ×": z = 1
    If c = 2 Then Print "× ○ × × × × × ×": z = 2
    If c = 3 Then Print "× × ○ × × × × ×": z = 3
    If c = 4 Then Print "× × × ○ × × × ×": z = 4
    If c = 5 Then Print "× × × × ○ × × ×": z = 5
    If c = 6 Then Print "× × × × × ○ × ×": z = 6
    If c = 7 Then Print "× × × × × × ○ ×": z = 7
    If c = 8 Then Print "× × × × × × × ○": z = 8
    Return z
End Function
'-----------
Sub Amida.wrLine(n as Byte)
    If n = 1 Then Print "|---|   |   |   |   |   |   |"
    If n = 2 Then Print "|   |---|   |   |   |   |   |"
    If n = 3 Then Print "|   |   |---|   |   |   |   |"
    If n = 4 Then Print "|   |   |   |---|   |   |   |"
    If n = 5 Then Print "|   |   |   |   |---|   |   |"
    If n = 6 Then Print "|   |   |   |   |   |---|   |"
    If n = 7 Then Print "|   |   |   |   |   |   |---|"
End Sub
'-----------
Function Amida.judge(a() as Byte, k as Byte, z as  Byte) as Byte
    If a(z) = k Then
        Return 1
    Else
        Return 0
    End If
End Function
'-----------
Dim ObjAMD as Amida
End

なかなか登場機会の少ないBASICですが、この手軽さと生産性の高さにはやはり根強い需要があるような気がします。

Maildirをバックアップするシェルスクリプト

参考程度になるかもしれませんので、当サイトでMaildirをバックアップするために使っているスクリプトを載せておきます。curとnewディレクトリだけを保存し、古いファイルを削除できます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#!/bin/sh

# Remains at least these days
keepday=14

HOMEDIR=/usr/local
MAILDIR=$HOMEDIR/Maildir
BACKUPDIR=$HOMEDIR/backup_mail
FOLDERS="kuroneko-square.net"

# Get timestamp
timestamp=`date +%Y%m%d`
old_date=`date "-d$keepday days ago" +%Y%m%d`

cd $MAILDIR

for F in $FOLDERS; do
  NAME=$BACKUPDIR/INBOX-$F-$timestamp.tar.gz
  FILES_CUR="`find $F -regex ".*cur.*"`"
  FILES_NEW="`find $F -regex ".*new.*"`"
  tar -cvzf $NAME $FILES_CUR $FILES_NEW

  rmfile=$BACKUPDIR/INBOX-$F-$old_date.tar.gz
  if [ -e $rmfile ]; then
  rm -f $rmfile
  fi
done

exit

VALUE DOMAIN のフィード

くろねこスクエアで使用しているドメインはVALUE DOMAINというところで管理しているのですが、頻繁にチェックしているわけではないため、新しいお知らせがあっても気づかない時があります。ATOMフィードやRSSフィードなどの配信があればフィードリーダーで更新チェックができるので言うことなしですが、なかなか対応は望めないようなので、試験的にではありますがVALUE DOMAINのアナウンスをフィードで取得できるようにしてみました。これでもう、期間限定割引なども見逃しませんよ。

しばらくは様子見・テスト運用ですが、特に問題なければGPL程度で公開したいと思います。追記:一部、最新情報を取得できない場合があるようですので修正しましたが、引き続き調査中です。

もし欲しいドメインがなかなか決まらないという方は、空きドメイン検索もできますのでご活用ください。

GeoIP 用のアップデートスクリプト

ちょっとした環境変数を確認するために簡単なENV Checkerを置いてみたのですが、せっかくなので接続元地域の判定も入れてあります。

ただし、IPアドレスのデータベースを持つのは大変なので、MaxMind 社が配布している GeoLite Countryを利用させていただいています。このデータは毎月更新されるようなので、GeoIPの利用方法のシェルスクリプトを参考に、過去2ヶ月分を残し、それより前のデータを削除するスクリプトを追加してみました。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#! /bin/sh

# Remains at least these months
keepmonth=2

TMPDIR=$HOME/tmp
GEODIR=$HOME/share/GeoIP
DAT=GeoIP.dat

# Get timestamp
timestamp=`date +%Y%m`
old_date=`date "-d$keepmonth months ago" +%Y%m`

cd $TMPDIR

#/usr/bin/wget http://www.maxmind.com/download/geoip/database/$DAT.gz
/usr/bin/wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/$DAT.gz
if [ $? != 0 ] ; then
    echo "wget failed"
    exit 1
fi

/bin/gunzip $DAT.gz
if [ $? != 0 ] ; then
    echo "gunzip failed"
    exit 2
fi

cd $GEODIR
/bin/mv $DAT $DAT.$timestamp
/bin/mv $TMPDIR/$DAT .

rmfile=$DAT.$old_date

if [ -e $rmfile ]; then
rm -f $rmfile
fi

exit

1ヶ月ごとにcronを回せばデータベースを自動更新してくれるので、いわゆるメンテナンスフリーになります。

KakakuFeed Ver1.0仕様へアップデート

キーワードに合った価格.comの情報を、使いやすい形で取得するためのWebサービス「KakakuFeed」をアップデートしました。これまで同様、価格.comの商品をキーワードやジャンルで絞り込み、RSS/ATOMなどのデータとして取得することができます。

アップデートの詳細

2009年8月末をもって、従来のVer1およびVer1.1のAPI提供が終了したため、このたび価格.com ウェブサービス Ver1.0(1ではなく1.0)の仕様に準拠いたしました。

従来から使用させていただいているPEAR::Services_KakakuComを価格.com ウェブサービス Ver1.0に(適当に)対応させたものを置いておきます。

  • ApiKeyパラメータを追加
  • リクエストURL変更

ブログパーツを作ってみました

Roonys Paradiseのブログパーツを作ってみました。

Adobe Flex SDKで作ったのですが、サンプル通りに進めると簡単にFlashファイルができあがりました。いわゆるAdobe Flashという(高価で)わかりにくいソフトのことなど全く考えなくていいのですね。ActionScriptを書くだけなので、タイムラインとも無縁。ちなみに、Flex SDKはオープンソースです。

以下はbp_roony_news.mxmlの例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" initialize="init();" width="160" height="240" horizontalScrollPolicy="off" verticalScrollPolicy="off">
    <mx:Style>
        Application
        {
        padding-top: 0;
        padding-bottom: 0;
        padding-left: 0;
        padding-right: 0;
        border-style: solid;
        background-color: #d0c2a8;
        }
        .links{
        textDecoration: underline;
        }
    </mx:Style>
    <!--mx:Panel-->
        <mx:VBox styleName="logo">
        <mx:Image source="bp_01.png" click="openUrl()" buttonMode="true" />
        </mx:VBox>
        <mx:VBox styleName="links">
            <mx:LinkButton id="link0" label="" click="openNews(event)" />
            <mx:LinkButton id="link1" label="" click="openNews(event)" />
            <mx:LinkButton id="link2" label="" click="openNews(event)" />
            <mx:LinkButton id="link3" label="" click="openNews(event)" />
            <mx:LinkButton id="link4" label="" click="openNews(event)" />
        </mx:VBox>
        <mx:Image source="bp_03.png" />
    <!--/mx:Panel-->
    <mx:Script>
    <![CDATA[
        import flash.net.URLLoader;
        import flash.net.URLRequest;
        import flash.net.URLVariables;
            import flash.net.navigateToURL;
        import flash.events.Event;
           
        public var links:Array = new Array();
       
        public function init():void {
            var request:URLRequest = new URLRequest("http://roony.kuroneko-square.net/feed/rss2");
            var loader:URLLoader = new URLLoader();
            loader.addEventListener(Event.COMPLETE, setNews);
            loader.load(request);
        }
        private function setNews(event:Event):void {
            var loader:URLLoader = event.target as URLLoader;
            var xml:XML = XML(loader.data);
            var itemNode:XMLList = xml.child("item");
            link0.label = "◆"+xml.channel.item[0].title;
            link1.label = "◆"+xml.channel.item[1].title;
            link2.label = "◆"+xml.channel.item[2].title;
            link3.label = "◆"+xml.channel.item[3].title;
            link4.label = "◆"+xml.channel.item[4].title;
            for (var i:int = 0; i < 5; i++) {
                links[i] = xml.channel.item[i].link;
            }
        }
        private function openNews(event:Event):void {
            var id:String = event.target.id;
            id = id.replace("link", "");
            navigateToURL(new URLRequest(links[id]));
        }
        private function openUrl():void {
            navigateToURL(new URLRequest("http://roony.kuroneko-square.net/"));
        }
        ]]>
    </mx:Script>
</mx:Application>

むしろ、Flashを表示するための実装がブラウザによってまちまちなので、結局JavaScriptに頼らざるを得ない点が問題だと感じました。

バーコード作成 リリース

バーコードを作成するためのWebサービス「バーコード作成」と「QRコード作成」をリリースしました。各種バーコードに対応しています。

バーコードの作成」を参考にさせていただきました。

今回対応したバーコード

  • JAN-13/EAN-13/ISBN-13
  • UPC-A
  • CODE 39
  • Code 25 Interleaved 2 of 5(ITF)
  • CODE 128
  • PostNet
  • 日本郵便 カスタマバーコード

ところで「日本郵便 カスタマバーコード」は需要がないのかライブラリがないのでバーコードに必要な文字情報の抜き出し法を参考にして書いてみたのが以下のPHPコード。漢数字は面倒なので対応していません。もう少しスマートなやり方はないだろうか?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
<?php
function validator_imbjp($text){
    $text = trim($text);
    $text = strtoupper($text);
    $rep_pat= array("&","/","・",".");
    $text = str_replace($rep_pat,'',$text);
    $text = preg_replace('/[A-Z]{2,}/','',$text);

    // /[0-9]F/ -> [0-9]-, 2-3-$ => 2-3
    if(preg_match_all('/[0-9]F/',$text, $matches)){
        foreach($matches[0] as $key => $value){
            $mat[$key] = str_replace('F','-',$value);
        }
        $text = str_replace($matches[0],$mat,$text);
        $text = preg_replace('/-$/','',$text);
    }

    if(preg_match_all('/[A-Z0-9\-]+/', $text, $matches)){
        $text = implode('-', $matches[0]);
    } else {
        return;
    }

    // A-2 => A2, L-B => LB
    if(preg_match_all('/-*[A-Z]-*/',$text, $matches)){
        foreach($matches[0] as $key => $value){
            $mat[$key] = str_replace('-','',$value);
        }
        $text = str_replace($matches[0],$mat,$text);
    }

    $text = str_replace('--','-',$text);
    if(substr($text,3,1)=='-'){
        $text = substr_replace($text,'',3,1);
    }
    if(substr($text,7,1)=='-'){
        $text = substr_replace($text,'',7,1);
    }

    //numstring
    for ($idx = 0; $idx < strlen($text); $idx++) {
        $char  = substr($text, $idx, 1);
        for ($baridx = 0; $baridx < strlen($this->_coding_map[$char]);) {
            $numstring[] = substr($this->_coding_map[$char], $baridx, 3);
            $baridx = $baridx+3;
        }
    }

    //numstring length check(add and remove)
    if(count($numstring) < 20){
        for($idx = count($numstring); $idx < 20; $idx++){
            $numstring[] = '432';
        }
    }
    $numstring = array_slice($numstring,0,20);
   
    //Check digit
    foreach($numstring as $value) {
        $checksum = $checksum + $this->_checkdg_map[$value];
    }
    if(($checksum % 19) == 0) {
        $checkdigit = 0;
    } else {
        $checkdigit = (19 - ($checksum % 19));
    }

    //leader + number + checkdigit + trailer
    $numstring = $this->_coding_map['leader'].implode('',$numstring).$this->_coding_map[$checkdigit].$this->_coding_map['trailer'];
    return $numstring;
}

最終的な出力はPEAR::Image_Barcodeにおまかせ。参考までに、Image_Barcodeで使える「日本郵便 カスタマバーコード」クラスを置いておきます。

カテゴリー

Feed

メタ情報