コンテンツにスキップ

2014

Redisに用意されたデータ型とその扱い

Redisで扱えるデータ型

  • String
  • List
  • Set
  • Sorted Set
  • Hash

String

文字列型

文字列や数値など、Keyに対して1つに定まる値。

値のset

set [key_name] [value]  # 1つのkey-valueをsetする
mset [key_name_1] [value_1] [key_name_2] [value_2]  # key-valueの組を複数setする

値のget

get [key_name]  # 1つのkeyに対するvalueをgetする
mget [key_name_1] [key_name_2] [key_name_3]  # 複数のkeyに対するvalueをgetする

使用例

redis> set name Steven
OK
redis> get name
"Steven"
redis> mset number 8 color red
OK
redis> mget name number color
1) "Steven"
2) "8"
3) "red"

List

リスト型

順番をもった値の集合。

値の追加

rpush [key_name] [member]  # リストの末尾に値を追加
lpush [key_name] [member]  # リストの先頭に値を追加

値の削除

rpop [key_name]  # リストの末尾の値を削除
lpop [key_name]  # リストの先頭の値を削除

範囲を指定して値を取得

lrange [key_name] 0 3   # 1番目から4番目まで値を取得
lrange [key_name] 0 -1  # 1番目から最後(最後から1番目)までの値を取得

位置を指定して値を取得

lindex [key_name] 2   # 3番目の値を取得
lindex [key_name] -1  # 最後の値を取得

要素の数を取得

llen [key]

使用例

redis> rpush player Steven
redis> rpush player Michael James
redis> lrange player 0 -1
1) "Steven"
2) "Michael"
3) "James"
redis> lrange player 0 1
1) "Steven"
2) "Michael"
redis> lindex player 1
"Michael"
redis> lindex player -1
"James"
redis> rpop player
"James"
redis> lrange player 0 -1
1) "Steven"
2) "Michael"
redis> llen player
(integer) 2

Set

セット型

順不同の値の集合。値の重複を許さない。

値の追加

sadd [key_name] [member]  # keyに対応するセットに指定した値を追加

値の削除

srem [key_name] [member]  # keyに対応するセットから指定した値を削除

値の参照

smembers [key_name]  # keyに対応するセットの値を取得

和集合の取得

sunion [key_name_1] [key_name_2]  # key1に対応するセットとkey2に対応するセットの値の集合を取得

差集合の取得

sdiff [key_name_1] [key_name_2]  # key1に対応するセットとkey2に対応するセットの値の差分の集合を取得

積集合の取得

sinter [key_name_1] [key_name_2]  # key1に対応するセットとkey2に対応するセットの値の重複部分の集合を取得

使用例

redis> sadd reds Steven
(integer) 1
redis> smembers reds
1) "Steven"
redis> sadd reds Steve
(integer) 1
redis> sadd reds Michael
(integer) 1
redis> smembers reds
1) "Steven"
2) "Michael"
3) "Steve"
redis> srem reds Michael
(integer) 1
redis> smembers reds
1) "Steven"
2) "Steve"
redis> sadd three_lions Steven Michael
(integer) 2
redis> smembers three_lions
1) "Steven"
2) "Michael"
redis> sunion reds three_lions
1) "Steven"
2) "Michael"
3) "Steve"
redis> sdiff reds three_lions
1) "Steve"
redis> sdiff three_lions reds  # sdiffの後のkeyの順番により結果が違うことに注意
1) "Michael"
redis> sinter reds three_lions
1) "Steven"

Sorted Set

ソート済みセット型

セット型と同様の特徴に加えて個々の値がスコアを持つ。

値の追加

zadd [key_name] [score] [member]  # keyに対応するセットにスコア付きで値を追加

値の削除

zrem [key_name] [member]  # keyに対応するセットから指定した値を削除

値の取得

zrange [key_name] 0 3     # keyに対応するセットからスコアの低い順に1番目から4番目の値を取得
zrevrange [key_name] 0 3  # keyに対応するセットからスコアの高い順に1番目から4番目の値を取得

値の順位を取得

zrank [key_name] [member]     # 指定した値の、keyに対応するセット中のランクを取得(スコアの低い順)
zrevrank [key_name] [member]  # 指定した値の、keyに対応するセット中のランクを取得(スコアの高い順)

使用例

redis> zadd fifa 1 germany
(integer) 1
redis> zrange fifa 0 0
1) "germany"
redis> zadd fifa 2 argentina
(integer) 1
redis> zadd fifa 3 holland 4 colombia 45 japan
(integer) 3
redis> zrange fifa 0 -1
1) "germany"
2) "argentina"
3) "holland"
4) "colombia"
5) "japan"
redis> zrevrange fifa 0 -1
1) "japan"
2) "colombia"
3) "holland"
4) "argentina"
5) "germany"
redis> zrank fifa japan
(integer) 4                      # 0番目から数えた値が返るので注意
redis> zrevrank fifa argentina
(integer) 3                      # 0番目から数えた値が返るので注意
redis> zrem fifa japan
(integer) 1
redis> zrange fifa 0 -1
1) "germany"
2) "argentina"
3) "holland"
4) "colombia"

Hash

ハッシュ型

field(valueについた名前)とvalueを1セットとする値の集合(ハッシュ)。

値のset

hset [key_name] [field] [value]  # keyにfieldとvalueのハッシュをset
hmset [key_name] [field_1] [value_1] [field_2] [value_2]  # keyにハッシュのfieldとvalueを複数セット

値のget

hget [key_name] [field]               # keyに対応するハッシュから指定したfieldのvalueを取得
hmget [key_name] [field_1] [field_2]  # keyに対応するハッシュから指定した複数のfieldのvalueを取得
hkeys [key_name]                      # keyに対応するハッシュのすべてのfieldを取得
hvals [key_name]                      # keyに対応するハッシュのすべてのvalueを取得

使用例

redis> hset steven position mf
(integer) 1
redis> hget steven position
"mf"
redis> hmset steven nationality england club reds
OK
redis> hmget steven club position
1) "reds"
2) "mf"
redis> hkeys steven
1) "position"
2) "nationality"
3) "club"
redis> hvals steven
1) "mf"
2) "england"
3) "reds"

Canvasとは

  • ブラウザ上に図形を描画するためのHTML5の仕様の一つ
  • プラグインを使わずにJavaScriptベースで図形を描画することができる。
  • アニメーションメソッドはないので動きをつけるためには1コマずつ描画し直す必要がある

今回はCanvasを使った図形の描画とそれを動的に消す操作をしてみる。

今回使う要素

  • メソッド
    • getContext()
    • fillRect()
    • clearRect()
  • プロパティ
    • fillStyle

getContext()

Canvasはこのメソッドから始まる

var targetElement = document.getElementById('target');
ctx = targetElement.getContext('2d');

getElementById などでCanvasの対象となるDOM要素を取得し、その要素に対して getContext() メソッドを呼ぶ

引数は '2d' のみが認められている。(今後'3d'とかつかえるようになるかも)

getContext('2d') で取得した ctx オブジェクトに対してメソッドやプロパティを適用していく

fillRect()

canvas上の指定した位置に指定した大きさの長方形を描画する

ctx.fillRect(80, 100, 40, 40);

fillRect() メソッドは4つの引数を取る。

  • 1つめ: 描画する長方形の左上頂点のx座標
  • 2つめ: 描画する長方形の左上頂点のy座標
  • 3つめ: 描画する長方形の
  • 4つめ: 描画する長方形の高さ

上記例ではcanvasの左上頂点(原点)から

  • 右方向(x軸方向)に80px
  • 下方向(y軸方向)に100px

の点に左上の頂点を持つ、

  • 幅40px
  • 高さ40px

の長方形(正方形)を描画することになる

clearRect()

指定された長方形を消す

ctx.clearRect(0, 0, 200, 400);

clearRect()fillRect() 同様に4つの引数を取る

  • 1つめ: 消す長方形の左上頂点のx座標
  • 2つめ: 消す長方形の左上頂点のy座標
  • 3つめ: 消す長方形の
  • 4つめ: 消す長方形の高さ

よって上記例ではcanvasの原点から幅200px、高さ400pxの長方形(範囲)に渡ってクリアする

fillStyle

オブジェクトのStyleを変更する

ctx.fillStyle = 'rgb(255, 0, 0)';

主にオブジェクトの色を指定するのに使う(Canvasではデフォルトの色は黒)

指定の仕方はCSSに準拠している

上記例ではオブジェクトを赤で描画できるようになる

サンプル

赤い正方形を描いたり消したりする

<!DOCTYPE html>
<html>
    <head>
        <meta charset=utf-8>
        <title>Canvas Sample1</title>
        <script type="text/javascript">
            var ctx;

            function load() {
                var targetElement = document.getElementById('target');
                ctx = targetElement.getContext('2d');
                ctx.fillStyle = 'rgb(255, 0, 0)';
            }

            function paint() {
                ctx.fillRect(80, 100, 40, 40);
            }

            function erase() {
                ctx.clearRect(0, 0, 200, 400);
            }


        </script>
    </head>
    <body onload="load()">
        <canvas id="target" style="border: 5px solid gray" width="200" height="400"></canvas>
        <input type="button" value="Paint" onclick="paint()" />
        <input type="button" value="Erase" onclick="erase()" />
    </body>
</html>

幅200px、高さ400pxのcanvasを用意し、そこに正方形を描くpaint関数とクリアするerase関数を定義した

参考資料

シェルの変更について

さくらでレンタルサーバーを借りたが、デフォルトのシェルが使い慣れたbashではなかったので変更した際のメモ。

現在のシェルを確認

% echo $SHELL
/bin/csh

環境変数 $SHELL に現在のシェルのパスが入っている。

変更できるシェルの確認

% cat /etc/shells 
# $FreeBSD: release/9.1.0/etc/shells 59717 2000-04-27 21:58:46Z ache $
#
# List of acceptable shells for chpass(1).
# Ftpd will not allow users to connect who are not using
# one of these shells.

/bin/sh
/bin/csh
/bin/tcsh
/usr/local/bin/bash
/usr/local/bin/rbash
/usr/local/bin/zsh
/usr/local/bin/rzsh
/usr/bin/passwd

bashが使えることが確認できる。

シェルを変更する

% chsh -s /usr/local/bin/bash

chsh はログインシェルを変更するコマンド。 -s オプションを付けないとインタラクティブに動作する。

ログインシェルはユーザー毎に設定できるログイン時に起動されるシェルのことで、 /etc/passwd ファイルで設定されている。

chsh はこのファイルを書き換える。

bashの設定ファイルを書く

ログインシェルをbashに変更したら

  • .bash_profile
  • .bashrc

など、いつもの設定ファイルを記述する

再度サーバーにログイン

設定を終えて再度サーバーにログインするとbashが立ち上がる。

メモ

% exec /usr/local/bin/bash -l

でbashをログインシェルとして立ち上げることもできるが設定ファイルは変わらないのでログインの度にデフォルトのシェルに戻る。

exec コマンドは引数で渡された処理にプロセスを置き換える。

よって上記コマンドが実行されるとbashがログインシェルとして置き換わる。

vimで連番を振る方法

大量のvalueに連番を振りたくなったのでvimの機能を調べて使ってみた。 目標は以下のようにurlのリストをPerlのハッシュ化すること。

example_1.com
example_2.com
example_3.com
~
example_254.com
example_255.com
example_256.com
my %urls = (
    1   => 'example_1.com',
    2   => 'example_2.com',
    3   => 'example_3.com',
~
    254 => 'example_254.com',
    255 => 'example_255.com',
    256 => 'example_256.com',
);

使うvimの機能

  • 数字のインクリメント/デクリメント
  • 操作の記録(complex repeat)

①数字のインクリメント/デクリメント

数字のインクリメント

数字にカーソルを合わせて

Ctrl + a

数字のデクリメント

数字にカーソルを合わせて

Ctrl + x

②操作の記録(complex repeat)

操作の記録は以下の順序で行う

  1. 準備
  2. 一連の操作に名前をつけて記録を開始
  3. 一連の操作を行う
  4. 記録を終了
  5. 記録した操作を繰り返し実行

1. 準備

1 => example_1.com
example_2.com
example_3.com
~

最初のキーである1だけ用意しておく。

2. 一連の操作に名前をつけて記録を開始

q
a

操作を開始する位置(キー1の上)にカーソルを合わせ、q, aの順でキーを押すと、'a'という名前で操作が記録される。

操作の名前は'a'の大文字、小文字のアルファベット、もしくは数字から1字を選んで付けることができる。

3. 一連の操作を行う

v (visual mode)
llllll (=> までを選択)
y (yank)
j P (1行下がってpaste)
0 (行頭へカーソルを移動)
Ctrl + a (インクリメント)
0 (行頭へカーソルを移動)

4. 記録を終了

q

qを押して記録を終了

5. 記録した操作を繰り返し実行

254 (繰り返す回数)
@a ('a'と名付けた操作を指定)

ここまで完了時点で以下のようになる。

1   => example_1.com
2   => example_2.com
3   => example_3.com
~
254 => example_254.com
255 => example_255.com
256 => example_256.com

Perlの記法に合わせて整形

vimの矩形選択( Ctrl + v )などをつかって正しいハッシュの文法に整形する

Octopressのテーマを変える

Octopressのテーマを変更する

今回は既に作られ、公開されているテーマを拝借する

好みのテーマを探す

3rd Party Octopress Themesにテーマリストが公開されている。ここから使いたいテーマを探す。

Octopress ThemesにPreviewが見やすくまとめられている

今回使用するテーマ

テーマのインストール

テーマをダウンロード

テーマ毎にclone元とclone先のpathを指定する

$ cd git/octopress
$ git clone GIT_URL .themes/THEME_NAME

テーマ: Whitespaceの場合

$ git clone git://github.com/lucaslew/whitespace.git .themes/whitespace

テーマをインストール

テーマを指定して rake install

$ rake install['THEME_NAME']
$ rake generate

テーマ: Whitespaceの場合

$ rake install['whitespace']
A theme is already installed, proceeding will overwrite existing files. Are you sure? [y/n] y
## Copying whitespace theme into ./source and ./sass
mkdir -p source
cp -r .themes/whitespace/source/. source
mkdir -p sass
cp -r .themes/whitespace/sass/. sass
mkdir -p source/_posts
mkdir -p public

テーマを上書きするか?と聞かれたので y で答える

$ rake generate
## Generating Site with Jekyll
overwrite source/stylesheets/screen.css 
Configuration from /Users/user.name/git/octopress/_config.yml
Building site: source -> public
Successfully generated site: source -> public

デプロイ

テーマをインストールしたらデプロイ

$ rake deploy

ページにアクセスしてテーマが変更されていることを確認できればok

テーマがアップデートされたら

テーマが開発者によってアップデートされたら手元のファイルもアップデートする

$ cd octopress/.themes/THEME_NAME
$ git pull
$ rake install['THEME_NAME']
$ rake generate

テーマ: Whitespaceの場合

$ cd octopress/.themes/whitespace
$ git pull
$ rake install['whitespace']
$ rake generate

デプロイしてアップデート完了

$ rake deploy

Github PagesとOctopressを使ったブログの作成

①Octopress のインストール

octopressリポジトリをクローン

$ cd git/
$ git clone git://github.com/imathis/octopress.git octopress

Bundlerを使って必要なパッケージをインストール

$ cd octopress/
$ sudo gem install bundler
$ sudo bundle install

bundle installがエラーになる

$ sudo bundle install
Fetching gem metadata from https://rubygems.org/.......
Fetching additional metadata from https://rubygems.org/..
Using rake 0.9.2.2

Gem::Installer::ExtensionBuildError: ERROR: Failed to build gem native extension.

    /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/ruby extconf.rb 
checking for main() in -lc... yes
creating Makefile

make "DESTDIR="
compiling redcloth_attributes.c
compiling redcloth_inline.c
compiling redcloth_scan.c
linking shared-object redcloth_scan.bundle
clang: error: unknown argument: '-multiply_definedsuppress' [-Wunused-command-line-argument-hard-error-in-future]
clang: note: this will be a hard error (cannot be downgraded to a warning) in the future
make: *** [redcloth_scan.bundle] Error 1


Gem files will remain installed in /Library/Ruby/Gems/2.0.0/gems/RedCloth-4.2.9 for inspection.
Results logged to /Library/Ruby/Gems/2.0.0/gems/RedCloth-4.2.9/ext/redcloth_scan/gem_make.out
An error occurred while installing RedCloth (4.2.9), and Bundler cannot continue.
Make sure that `gem install RedCloth -v '4.2.9'` succeeds before bundling.

Xcodeのアップデートでコンパイラが更新されたことが原因のよう

オプションをつけてやり直し

$ sudo ARCHFLAGS=-Wno-error=unused-command-line-argument-hard-error-in-future bundle install

ビルドツール、rakeをインストール

$ rake install

②GitHubにリポジトリを作成

  • [username].github.io

という名前でリポジトリを作る。今回は

  • sojiro14.github.io

③Octopressでのデプロイ

デプロイ設定する

rake setup_github_pages

途中でリポジトリのurlを聞かれるので入力。今回は

git@github.com:sojiro14/sojiro14.github.io.git

を入力した

$ rake setup_github_pages
Enter the read/write url for your repository
(For example, 'git@github.com:your_username/your_username.github.io.git)
           or 'https://github.com/your_username/your_username.github.io')
Repository url: git@github.com:sojiro14/sojiro14.github.io.git
Added remote git@github.com:sojiro14/sojiro14.github.io.git as origin
Set origin as default remote
Master branch renamed to 'source' for committing your blog source files

・・・・(略)

 1 file changed, 1 insertion(+)
 create mode 100644 index.html
cd -

---
## Now you can deploy to git@github.com:sojiro14/sojiro14.github.io.git with `rake deploy` ##

ページの作成

必要ファイルを作成

$ rake generate
## Generating Site with Jekyll
directory source/stylesheets/ 
   create source/stylesheets/screen.css 
Configuration from /Your/Octopress/Directory/git/octopress/_config.yml
Building site: source -> public
Successfully generated site: source -> public

deploy

$ rake deploy
## Deploying branch to Github Pages 
## Pulling any updates from Github Pages 
cd _deploy

・・・・(略)

## Github Pages deploy complete
cd -

deployの確認

実際にページにアクセスして確認する

http://sojiro14.github.io

確認できればok。反映には少々(5分ほど)時間がかかる。

④Octopressの初期設定を変更

_config.ymlの編集

_config.ymlファイルにてブログのタイトル、サブタイトル、筆者などを設定できる

$ vim _config.yml

例えばタイトル、サブタイトルは以下のように設定

title: Sojiro's Blog
subtitle: This is nothing much.

設定したらdeploy。Task: gen_deployを使う

$ rake gen_deploy

もう一度ページにアクセスしてタイトルなどが変更されているのを確認できればok

⑤記事の投稿

記事を書く

new_postの後には記事のタイトルを指定。英数字のみ使用可

$ rake new_post["IRC-bot by HUBOT"]
mkdir -p source/_posts
Creating new post: source/_posts/2014-04-19-irc-bot-by-hubot.markdown

source/_posts/2014-04-19-irc-bot-by-hubot.markdownというファイルが生成されるのでそこに内容をマークダウンで記述

$ vim source/_posts/2014-04-19-irc-bot-by-hubot.markdown
---
layout: post
title: "IRC-bot by HUBOT"
date: 2014-04-19
comments: true
categories:
---
ここ以下に内容をマークダウンで書いていく

記事をデプロイ

記事を書いたらデプロイする

$ rake gen_deploy

記事が投稿されていることを確認できればok

⑥Google Analyticsを導入する

Google AnalyticsのトラッキングIDを取得する

Google Analyticsのサイトからアカウントを作成し、

  • username.github.io

のトラッキングIDを取得する

取得したトラッキングIDを設定

_config.ymlにトラッキングIDを設定する

$ vim _config.yml

場所はこちら

# Google Analytics
google_analytics_tracking_id: XX-12345678-9

設定が終わったらデプロイ

$ rake gen_deploy

Google Analyticsのサイト上でトラッキングできていることを確認できればok

参考

HUBOTを使ったirc-bot作成メモ

①HUBOTを動かすために必要な諸々のインストール

準備として以下をインストールする

  • node.js(サーバー)
  • npm(パッケージ管理コマンド)
  • Redis(KVS)

上記をインストールするためにHomebrewのインストールから始める

$ ruby -e "$(curl -fsSL https://raw.github.com/mxcl/homebrew/go/install)"

これでHomebrewが入るはず

次にHomebrewを使ってそれぞれインストールする

まずnode.jsとnpm

$ brew install node

このコマンド一発でnode.jsとnpmが入るはず

$ node -v
v0.10.26
$ npm -v
1.4.6

Redisもインストール

$ brew install redis

Redisを起動しておく

$ redis-server &

②HUBOTをインストールする

GitHubからリポジトリをクローンしてインストール

$ cd git/
$ git clone git://github.com/github/hubot.git
$ cd hubot/
$ npm install -g hubot coffee-script

動くか確認

$ hubot
Hubot> 

OK

③HUBOTをircと連携させる

自分用のHUBOTを作る

$ hubot --create myhubot

myhubotの部分は自由に変更可。この名前のディレクトリが作られる

自分用HUBOTにhubot-ircをインストール

$ cd myhubot/
$ npm install hubot-irc --save && npm install

irc連携のためのスクリプトを書く

$ vim runhubot

中身はこんな感じ

$ cat runhubot
#!/bin/bash

export HUBOT_IRC_NICK="bot_kun"
export HUBOT_IRC_ROOMS="#target_channel"
export HUBOT_IRC_SERVER="irc.hogehoge.local"
#export HUBOT_IRC_PASSWORD="hoge"

bin/hubot -a irc --name myhubot

スクリプトの実行権限追加

$ chmod u+x runhubot 

起動スクリプト実行!

$ ./runhubot &

irc上でbotがいるか確認する

bot_kunがいたのでOK

④botにさせたいことを設定する

HUBOTにさせたいことはscriptsディレクトリ以下にCoffeeScriptもしくはJavaScriptで記述する

最初からいくつかのスクリプトが存在するので、それを参考に書けばOK

$ vim scripts/tell_fuga.coffee
$ cat scripts/tell_fuga.coffee
module.exports = (robot) ->

    robot.hear /hoge/, (msg) ->
        msg.send "fuga"

スクリプトを書いたら、再起動すると読み込んでくれる

$ ./runhubot &

⑤cronが使えるようにする

node-cronをインストール

$ npm install cron

cronを使ったスクリプトを書く

$ vim scripts/mention_hoge.coffee

今回は2時間おきに発言するスクリプトを書いてみた

$ cat scripts/mention_hoge.coffee 
cron = require('cron').CronJob
module.exports = (robot) ->
  robot.enter ->
  new cron
    cronTime: "0 0 */2 * * *"
    start: true
    timeZone: "Asia/Tokyo"
    onTick: ->
      robot.send {room: "#target_channel"}, "hoge"

参考資料