gitでhttp-backendをつかってpush

結構はまったので、めも。

ubuntu 10.04
apache2, git, gitwebをapt経由でインストール済み。

目的: http:///repos/test.git にpushしたい。
プロジェクトの位置は /var/www/repos/test.git

まず、/etc/apache2/conf.d/git.confに設定情報を記述

SetEnv GIT_PROJECT_ROOT /var/www/repos
SetEnv GIT_HTTP_EXPORT_ALL
ScriptAlias /repos/ /usr/lib/git-core/git-http-backend/

<LocationMatch "^/repos/.*">
  AuthType Basic
  AuthName "Git Access"
  Require valid-user
  AuthUserFile /etc/apache2/passwd.git
</LocationMatch>

で、/etc/apache2/passwd.gitを作成。

htpasswd -c /etc/apache2/passwd.git


ついでに、gitwebも/etc/apache2/gitwebに設定。
こっちは http:///gitweb/ でアクセスする。

Alias /gitweb /usr/share/gitweb

<Directory /usr/share/gitweb>
  Options FollowSymLinks +ExecCGI
  AddHandler cgi-script .cgi
</Directory>

プロジェクトの位置をgitwebに教える
/etc/gitweb.conf

$projectroot = "/var/www/repos"
...

apache2をrestart

/etc/init.d/apache2 restart

以上で設定完了。

gitserverにレポジトリ作成.

cd /var/www/repos
mkdir test.git
cd test.git
git init --bare --shared=true

クライアント側でcloneとpushしてみる。

git clone http://<gitserver>/repos/test.git
cd test
touch README
git add .
git commit -m "first"
git remote -v # 確認
git push origin master

できた。
何度もpasswordを聞かれるのがうるさいので、 ~/.netrcにパスワードを記述。

machine <gitserver>
login <htpasswdのuser>
passwd <htpasswdのpassword>

特にはまったところは、gitのapacheの設定で、LocationMatchを "^/repos/.*/git-receive-pack$"としていた際に、git cloneができても、その後のgit pushが次のようなエラーが出て失敗したこと。

error: Cannot access URL http://<gitserver>/repos/test.git/, return code 22
fatal: git-http-push failed

git-receive-packだけを対象とせず "^/repos/.*"としたらうまく行った。

SRM534 DIV2

一応システムテスト済み。
致命的なミスがあるかもしれません・・・

250 point

入力:ファイルリスト {".","..","ContenstApplet.jnlp",...} みたいなかんじ
出力:"."と".."が最後の2つになっているようなファイルリスト。
条件:末尾でない場所に"."か".."があったら、末尾に追加するようにswap。
注意:swapする際に末尾が"."か".."があってもかならず末尾に挿入

public class EllysDirectoryListing {
	public String[] getFiles (String[] files) {
		int last = files.length -1;
		for (int i=0;i<files.length-2;i++) {
			if (files[i].equals(".") || files[i].equals("..")) {
				if (files[last].equals(".") || files[last].equals("..")) {
					String swp = files[last];
					files[last] = files[last-1];
					files[last-1] = swp;
				}
				String swp = files[i];
				files[i] = files[last];
				files[last] = swp;
				last--;
			}
		}
		return files;
	}
}

500 point

入力:右から順に.かoのString, ".o.." みたいなかんじ
出力:初めのプレーヤーがゲームに勝てるかどうか
条件:2人が交互にプレイして、oを右に動かす。動かせなくなったほうが負け。右に1つ動かすか、右に3つジャンプして動かすかを選択できる。ただし一番はじにoが移動したらその場でそのoは消える。
注意:右に1つ動かすのを3回するのと、右に3動かすのを行うのは等価。

考え方:
移動にかかる最短の手数を考える。

...ooooooooo
...432321210

といった具合に、右からの位置pに対して移動量はp/3+p%3。
すべての石に対して移動量を加算して、その和が奇数であれば初手の勝ち。

public class EllysCheckers {
	public String getWinner (String board) {
		int sum = 0;
		for (int i=0;i<board.length();i++) {
			if (board.charAt(i)=='o') {
				int p = board.length() -1 - i;
				sum += p/3 + p%3;
			}
		}
		if (sum%2==1) return "YES";
		return "NO";
	}
}

wordpressのプラグインでウィジェット作成をためす。

プラグインウィジェットを作る。

$ pwd
/path/to/wordpressproject/wp-content/plugins
$ tree helloworld/
helloworld/
`-- helloworld.php

0 directories, 1 file

helloworld.phpの中身。

<?php
/*
Plugin Name: HelloWorld
Plugin URI: http://d.hatena.ne.jp/mustankatti/
Description: description of hello world.
Author: mustankatti
Version: 0.0
Author URI: http://d.hatena.ne.jp/mustankatti/
Description: no description
 */

class HelloWorld_Widget extends WP_Widget {
        public function __construct() {
                parent::__construct(
                        'helloworld_widget', // Base ID
                        'HelloWorld_Widget', // Name
                        array( 'description' => __('A Hello World Widget', 'text_domain'), )
                );
        }

        public function widget( $args, $instance) {
                extract($args);
                $title = apply_filters('widget_title', $instance['title']);
                echo $before_widget;
                if (!empty($title))
                        echo $before_title . $title . $after_title;
                ?>Hello, World!<?php
                echo $after_widget;
        }

        public function update( $new_instance, $old_instance ) {
                $instance = $old_instance;
                $instance['title'] = strip_tags($new_instance['title']);
                return $instance;
        }
        public function form( $instance ) {
                if ( $instance ) {
                        $title = esc_attr($instance['title']);
                }
                else {
                        $title = __('New title', 'text_domain');
                }
                ?>
                <p>
                <label for="<?php echo $this->get_field_id('title'); ?>"><?php _e('Title:'); ?></label>
                <input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo $title; ?>" />
                </p>
                <?php
        }
}

add_action('widgets_init',
        create_function('', 'register_widget("helloworld_widget");')
);

?>

プラグインより有効化。
外観のwidgetからサイドバーに追加。

leiningen windows

leiningenがwindowsでの使えるときいて驚き。

curlwgetwindowsバージョンをとってきてPATHに通す。

https://github.com/technomancy/leiningen のInstallationよりlein.batを取ってきてPATHを通す。

lein self-installで終わり。

ファイルエンコードの指定

emacs でファイル編集する際に、ファイルごとに文字コードを指定して開く方法。

ファイル1行目にコメントアウトして -*- coding: utf-8 -*- というぐあいに、 -*-で設定値を囲んで書く。

c言語, java, javascript, css, ...

// -*- coding: utf-8 -*-

Ruby, Python, Perl, ...

# -*- coding: euc-jp -*-

Emacs-Lisp, Common-Lisp, Scheme, Clojure, ...

; -*- coding: sjis -*-

Sphinxのrst ファイル

.. -*- coding: utf-8 -*-

html, xml, ...

<!-- -*- coding: utf-8 -*- -->

tex

% -*- coding: euc-jp -*-

また、メジャーモードの設定などほかの変数もこの欄に指定できます。

// -*- mode: C; coding: utf-8; -*-
// -*- mode: java; coding: utf-8; -*-
// -*- mode: javascript; coding: utf-8 -*-
// -*- mode: css; coding: utf-8; -*-
# -*- mode: python; coding: utf-8; -*-
# -*- mode: ruby; coding: utf-8; -*-
# -*- mode: perl; coding: utf-8; -*-
; -*- mode: clojure; coding: utf-8; -*-
.. -*- mode: rst; coding: utf-8 -*-
<!-- -*- mode: html; coding: sjis -*- -->
<!-- -*- mode: xml; coding: utf-8 -*- -->
% -*- mode: tex; coding: euc-jp; -*-

ファイル拡張子がおかしいときなど、モード設定しておくと便利です。

clojureのprintfは?

printfなんてないから、
clojure.core/formatを使えということらしい。

;; こんなかんじ
(defn hello [name]
  (println (format "hello %s!!" name)))

;; マクロにしてみる。
(defmacro sayf [tmplate & body]
    `(println (format ~tmplate ~@body)))

;; こんなかんじ
(sayf "hello %s!!" "Clojure")

javacvつかってみよう。

とりあえず、サンプルを頼りに表示。

public void SimpleTest(){
	IplImage src = opencv_highgui.cvLoadImage("/path/to/image/test.jpg");
	
	final CanvasFrame canvas = new CanvasFrame("my frame");
	canvas.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
	canvas.showImage(src);
}

CanvasFrameってJFrameに肉付けしたものなんだな。
内部でBufferedImageに変換してる。

平滑化してみよう。

public void SimpleTest(){
	IplImage src = opencv_highgui.cvLoadImage("/path/to/image/danboo.jpg");
	IplImage dst = IplImage.create(src.width(), src.height(), src.depth(), src.nChannels());
		
	opencv_imgproc.cvSmooth(src, dst, opencv_imgproc.CV_GAUSSIAN, 3);
		
	final CanvasFrame srcframe = new CanvasFrame("src");
	final CanvasFrame dstframe = new CanvasFrame("dst");
	srcframe.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
	dstframe.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
	srcframe.showImage(src);
	dstframe.showImage(dst);
}

さて、これをclojureからよびだしたいんだけど、それはまた今度に。