2013年10月31日木曜日

appspot sample

昔appspotで作ったまとめページ。

http://2channelbuster.appspot.com/

最初で最後のpython。

2013年10月28日月曜日

Googleトレンドのキーワードを元に2ちゃんを検索してまとめる#1

トレンド・キーワードを元に2ちゃんの記事を自動でまとめる(まとめてみた)

Googleトレンドを取得するrubygemsを作る


gemの雛形生成

なんとなくoreを使い続けているのでmineで生成。
gem名はpsychobilly-googleにした
sudo gem install ore
mine psychobilly-google --rubygems-tasks --bin --version=0.0.1

http://www.google.co.jp/trends/hottrends/atom/feed をパースしてオブジェクトに詰め込むのみのものを作成。
http://git.psychobil.ly/psychobilly-google

build

gem build psychobilly-google.gemspec

gemsサーバにupload

プライベートgemsサーバを用意したのでそこにuploadする
gem inabox psychobilly-google-0.0.1.gem --host http://gems.psychobil.ly/

インストール

gem sources -l | grep gems.psychobil.ly || sudo gem sources --add http://gems.psychobil.ly/
sudo gem install psychobilly-google

使用例

require 'rubygems' if RUBY_VERSION < "1.9"
require 'psychobilly/google'

Psychobilly::Google.getTrends.sort_by{rand}.each do |item|
  p item.to_s
end

2013年10月26日土曜日

nginx plus::statusモジュールを作る#4

repositoryをgithubからbitbucketに変更した。
変更した理由は独自ドメインが使えたから。
新repository -> git.psychobil.ly


deb packageに自作モジュールを組み込む

コーディングをしていると早く動かしたい衝動にかられることが多いので、nginx.orgが提供しているdebパッケージを元に自作モジュールを組み込む方法

ubuntu12.10

aptの設定

cat /etc/issue.net
Ubuntu 12.10
cat /etc/apt/sources.list.d/nginx.list
deb http://nginx.org/packages/ubuntu/ quantal nginx
deb-src http://nginx.org/packages/ubuntu/ quantal nginx
wget -O - http://nginx.org/keys/nginx_signing.key | sudo apt-key add -
sudo apt-get update

依存を解消するために一度インストールしておく

sudo apt-get install nginx

ソースコードをDLして組み込む

cd /path/to/work
apt-get source nginx
rm nginx_1.4.3*
cd nginx-1.4.3
git clone https://bitbucket.org/psychobilly/ngx_http_json_status_module.git
diff debian/{rules.orig,rules}
54c54,55
<               --with-ipv6
---
>               --with-ipv6 \
>     --add-module=./ngx_http_json_status_module
92c93,94
<               --with-debug
---
>               --with-debug \
>     --add-module=./ngx_http_json_status_module

diff debian/source/{format.orig,format}
1c1
< 3.0 (quilt)
---
> 3.0 (native)
build & install
sudo apt-get -y install libssl-dev libpcre3-dev zlib1g-dev
debuild -us -uc && debclean
sudo dpkg -i ../nginx_1.4.3-1~quantalubuntu2_amd64.deb
#5に続く

nginx plus::statusモジュールを作る#3

create main configuration

モジュール内のメインの設定用の構造体を生成する。


ngx_http_json_status_module.h


struct  ngx_http_json_status_main_conf_s {
  char            hostname[NGX_MAXHOSTNAMELEN];
  u_char          addr[16]; /* xxx.xxx.xxx.xxx\0 */
};
...
static void *ngx_http_json_status_create_main_conf(ngx_conf_t *cf);
static void *ngx_http_json_status_init_main_conf(ngx_conf_t *cf);

ngx_http_json_status_module.c


  • ngx_http_json_status_module_ctxのcreate_main_confに構造体を生成する関数を指定
  • ngx_http_json_status_create_main_confでhostnameとip addressを取得してセットする
  • 今回はinit_main_conf使用しないけど一応用意しておいた

static ngx_http_module_t ngx_http_json_status_module_ctx = {
NULL,                              /* preconfiguration */
NULL,                              /* postconfiguration */

ngx_http_json_status_create_main_conf, /* create main configuration */
ngx_http_json_status_init_main_conf,   /* init main configuration */

NULL,                              /* create server configuration */
NULL,                              /* merge server configuration */

NULL,                              /* create location configuration */
NULL                               /* merge location configuration */
};
...
static void *
ngx_http_json_status_create_main_conf(ngx_conf_t *cf)
{
  ngx_http_json_status_main_conf_t *jsmcf;
  struct hostent *host;
  
  jsmcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_json_status_main_conf_t));
  if (jsmcf == NULL) {
    return NULL;
  }

  if (gethostname(jsmcf->hostname, NGX_MAXHOSTNAMELEN) == -1) {
    ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "gethostname() failed");
    return NULL;
  }
  host = gethostbyname(jsmcf->hostname);
  if (host == NULL) {
    ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "gethostbyname() failed");
    return NULL;
  }
  ngx_sprintf(jsmcf->addr, "%d.%d.%d.%d",
        (BYTE)*(host->h_addr),
        (BYTE)*(host->h_addr + 1),
        (BYTE)*(host->h_addr + 2),
        (BYTE)*(host->h_addr + 3));

  ngx_conf_log_error(NGX_LOG_DEBUG, cf, 0, "hostname:%s, address:%s", &jsmcf->hostname, jsmcf->addr);

  return jsmcf;
}

static char *
ngx_http_json_status_init_main_conf(ngx_conf_t *cf, void *conf)
{
  return NGX_CONF_OK;
}
#4に続く 

2013年10月22日火曜日

nginx plus::statusモジュールを作る#2

ヘッダファイルを追加

ヘッダファイルを作りたくなった場合configに一行追加する。
今回はngx_http_json_status_module.hを追加するのでconfigに以下を追加。
NGX_ADDON_DEPS="$NGX_ADDON_DEPS $ngx_addon_dir/ngx_http_json_status_module.h"

ngx_command_t

ディレクティブの定義をした ngx_command_t 構造体は以下の様になっている。
typedef struct ngx_command_s     ngx_command_t;

struct ngx_command_s {
    ngx_str_t             name;
    ngx_uint_t            type;
    char               *(*set)(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
    ngx_uint_t            conf;
    ngx_uint_t            offset;
    void                 *post;
};
set要素はname要素のディレクティブが設定されたときに呼び出される関数。

ngx_command_tのset要素:ngx_http_json_status

status; が設定されているときに呼び出す関数。
内部でhandlerを設定する。

ngx_http_json_status_module.h

static char *ngx_http_json_status(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);

ngx_http_json_status_module.c

static char *
ngx_http_json_status(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
  ngx_http_core_loc_conf_t  *clcf;

  clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
  clcf->handler = ngx_http_json_status_handler;

  return NGX_CONF_OK;
}

handler:ngx_http_json_status_handler

status;が設定されたlocationにリクエストが来た時に実行される。

ngx_http_json_status_module.h

static ngx_int_t ngx_http_json_status_handler(ngx_http_request_t *r);

ngx_http_json_status_module.c

jsonで空データを返すところまで。
データを詰めてレスポンスを返すのはどれもこんな感じで実装している。
static ngx_int_t
ngx_http_json_status_handler(ngx_http_request_t *r)
{
  size_t       size;
  ngx_buf_t   *b;
  ngx_int_t    rc;
  ngx_chain_t  out;

  /* GET or HEAD only */
  if (r->method != NGX_HTTP_GET && r->method != NGX_HTTP_HEAD) {
    return NGX_HTTP_NOT_ALLOWED;
  }

  /* request bodyは不要なので破棄する */
  rc = ngx_http_discard_request_body(r);
  if (rc != NGX_OK) {
    return rc;
  }

  size = sizeof("{}");

  b = ngx_create_temp_buf(r->pool, size);
  if (b == NULL) {
    return NGX_HTTP_INTERNAL_SERVER_ERROR;
  }

  out.buf = b;
  out.next = NULL;

  b->last = ngx_sprintf(b->last, "{}");

  b->memory = 1;
  b->flush = 1;
  b->last_buf = 1;
  b->last_in_chain = 1;

  ngx_str_set(&r->headers_out.content_type, "application/json; charset=utf-8");
  r->headers_out.status = NGX_HTTP_OK;
  r->headers_out.content_length_n = b->last - b->pos;
  rc = ngx_http_send_header(r);
  if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
    ngx_log_error(NGX_LOG_DEBUG, r->connection->log, 0, "#return. %s:%d", __FUNCTION__, __LINE__);
    return rc;
  }

  return ngx_http_output_filter(r, &out);
}


repository


成果はここに置くことにした。


#3に続く

nginx plus::statusモジュールを作る#1

nginxの商用版nginx plusには魅力的な機能がありますが、個人利用ではお値段高め。
awsでインストール済みのイメージがある様なのでそれを使用してみるのも一つの手ではある。

もう一つの手として公開されている仕様を元に自作でモジュールを作ってしまう。

作ったものを公開するところまでやってみようと思った。

先ずはstatusモジュールから挑戦。

仕様は概ねこれをパクる。


雛形を作る

apacheの場合apxsで雛形が作れるのだけどnginxの場合は特に標準で用意されてなく、こういうのを作成している人が居たので使わせて頂く。
モジュール名はngx_http_json_status_module とする。
sudo gem install ngxmodgen
mkdir ngx_http_json_status_module
cd ngx_http_json_status_module
ngxmodgen -n json_status
tree
.
├── config
└── ngx_http_json_status_module.c

0 directories, 2 files

ディレクティブの設定

引数は取らないでlocation内にstatus;を記述すれば有効になるようにする。
ngx_http_json_status_module.cを編集。
static char *ngx_http_json_status(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
...
static ngx_command_t
ngx_http_json_status_commands[] = {
  {
    ngx_string("status"),
    NGX_HTTP_LOC_CONF|NGX_CONF_NOARGS,
    ngx_http_json_status,
    0,
    0,
    NULL
  },
  ngx_null_command
};
仮にstatus on|off; で切り替えたい場合は以下の様にする。
static char *ngx_http_json_status(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
...
static ngx_command_t
ngx_http_json_status_commands[] = {
  {
    ngx_string("status"),
    NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
    ngx_http_json_status,
    0,
    0,
    NULL
  },
  ngx_null_command
};

#2に続く

2013年10月21日月曜日

aptサーバ構築::repreproのインストール(未完成)

プライベートaptサーバ構築手順

参照

http://davehall.com.au/blog/dave/2010/02/06/howto-setup-private-package-repository-reprepro-nginx

パッケージインストール

sudo apt-get install reprepro nginx 

ディレクトリ作成

sudo mkdir -p /srv/reprepro/{debian,ubuntu}/{conf,dists,incoming,indices,logs,pool,project,tmp}
sudo chown -R $USER /srv/reprepro/{debian,ubuntu}

gpg鍵生成

while : ; do echo xxx | mail $USER ; sleep 0.1 ; done

gpg --gen-key
...+++++
gpg: /home/$USER/.gnupg/trustdb.gpg: 信用データベースができました
gpg: 鍵E77D0B99を絶対的に信用するよう記録しました
公開鍵と秘密鍵を作成し、署名しました。

gpg: 信用データベースの検査
gpg: 最小の「ある程度の信用」3、最小の「全面的信用」1、PGP信用モデル
gpg: 深さ: 0  有効性:   1  署名:   0  信用: 0-, 0q, 0n, 0m, 0f, 1u
pub   2048R/E77D0B99 2013-09-20
                 指紋 = 6DE6 56D6 D208 F0EF 5FDD  B3A5 EB97 6907 E77D 0B99
uid                  $USER
sub   2048R/A7DFF5BF 2013-09-20

confファイル設定

cat /srv/reprepro/debian/conf/distributions
Origin: psychobilly
Label: psychobilly
Codename: squeeze
Architectures: i386 amd64 source
Components: main
Description: local repository
SignWith: E77D0B99 # 上で生成したgpgkey

cat /srv/reprepro/debian/conf/options
ask-passphrase
basedir .

リポジトリ準備/サンプルパッケージ登録

reprepro -Vb /srv/reprepro/debian export
reprepro -vb /srv/reprepro/debian includedeb squeeze sample-package.deb

loalhostでの設定

gpg -a --export E77D0B99 | sudo apt-key add -

remotehostでの設定

wget -O - http://remotehost/debian/signing.key | sudo apt-key add -

2013年10月13日日曜日

ubuntuにfessをインストール

特定のジャンルに特化した検索サイトを作りたくなり、ossの検索エンジン(http://fess.codelibs.org/ja/)を導入してみようと思い。

jreとその他ツールをインストールする

cat /etc/issue.net
Ubuntu 12.10

sudo apt-get update && sudo apt-get --yes --force-yes install openjdk-7-jre mysql-server-5.5 w3m

fessをダウンロードする

w3m http://sourceforge.jp/projects/fess/downloads/59462/fess-server-8.2.0.zip/
# または
# w3m http://sourceforge.jp/projects/fess/downloads/59462/fess-server-mysql-8.2.0.zip/

fessをインストールする

unzip fess-server-mysql-8.2.0.zip
cd fess-server-8.2.0/
chmod +x bin/*.sh
./bin/startup.sh

2013年10月1日火曜日

[mysql] databaseのcharacter変更

既存確認

mysql> status
...
Server characterset:    latin1
Db     characterset:    latin1
Client characterset:    utf8
Conn.  characterset:    utf8
...

Dbをutf8に変更

mysql> alter database {db_name} character set utf8;
mysql> status
...
Server characterset:    latin1
Db     characterset:    utf8
Client characterset:    utf8
Conn.  characterset:    utf8
...