[Fswiki-dev] 添付ファイルのインターフェース

Back to archive index

Kousuke Taniguchi tinse****@u01*****
2003年 6月 18日 (水) 23:44:36 JST


tinsep19です。
At Wed, 18 Jun 2003 22:58:35 +0900,
Naoki Takezoe wrote:
> なるほど。data_dirを書き換えるよりキレイに実現できますね。
> 方向性は正しいと思います。実際にどのくらい実装されている
> のでしょうか?
> 
> 既にある程度できあがっているのであれば動かないものでも
> 構わないのでコードを見せていただきたいのですが・・・。

ではDefaultFarmStorageとFarm.pmを添付します。

DefaultFarmStorageについては、現Wikiと互換性があります。
DefaultStorageと差し変えてもWiki本体の方は完全に動きます。

Farm部分については基本部分(新規Wiki、ページの編集など)
についてはほぼ動いています。
プラグインもログとかを使わないものであれば動いています。

しかし各Wiki毎のユーザー情報もとれないですし
添付、アクセスログ、このあたりは厳しいところです。
あとはどのWikiもログが全部同じファイルに吐かれていますし、
添付ファイルは上書きしほうだいです。

Wikiにattach,logのインターフェースが無いので
作ろうかというとこで添付のインターフェースのメールを出しました。

wiki.cgiは冒頭部のみ以下の変更です。

require "setup.pl";

my $cgi = CGI2->new();
my $proj = $cgi->path_info();
if(length($proj)>0){ 
    if($proj =~ /^(\/\w+)+$/){
	$main::script_name = basename($proj);
    }else{
	die $!;
    }
}
my $wiki = Farm->new($cgi,$proj);

-------------- next part --------------
############################################################
#
# デフォルトのFarmストレージプラグイン
# DefaultStrageの全てのメソッドに$proj引数が加わっています。
# 形式は '/xxx/yyy/zzz'
#
############################################################
package Wiki::DefaultFarmStorage;
use File::Copy;
use strict;
#===========================================================
# コンストラクタ
#===========================================================
sub new {
	my $class = shift;
	my $self  = {};

	return bless $self,$class;
}

#===========================================================
# ページを取得
#===========================================================
sub get_page {
	my $self = shift;
	my $page = shift;
	my $content = "";
	my $proj = shift; 

	my $filename = Util::make_filename($main::data_dir.$proj,
					   Util::url_encode($page),
					   "wiki");
	if(-e $filename){
		open(DATA,$filename) or die $!;
		binmode(DATA);
		while(<DATA>){
			$content = $content.$_;
		}
		close(DATA);
	}
	#$content =~ s/\r\n/\n/g;
	#$content =~ s/\r/\n/g;
	return $content;
}

#==============================================================================
# ページを保存
#==============================================================================
sub save_page {
	my $self = shift;
	my $page = shift;
	my $content = shift;
	my $proj = shift;
	
	$content = '' if($content =~ /^[\r\n]+$/s); # added for opera
	
	# ページ名とページ内容の補正
	$page = Util::trim($page);
	$content =~ s/\r\n/\n/g;
	$content =~ s/\r/\n/g;
    
	# バックアップ
	my $BACKUP = $self->get_page($page);
	if($BACKUP ne ""){
		open(DATA,">".Util::make_filename($main::backup_dir.$proj,
						  Util::url_encode($page),
						  "bak")) or die $!;
		binmode(DATA);
		print DATA $BACKUP;
		close(DATA);
	}
	
	# 書き込む
	if($content eq ""){
		unlink(Util::make_filename($main::data_dir.$proj,
					   Util::url_encode($page),
					   "wiki"));
		unlink(Util::make_filename($main::backup_dir.$proj,
					   Util::url_encode($page),
					   "bak"));
	} else {
		open(DATA,">".Util::make_filename($main::data_dir.$proj,
						  Util::url_encode($page),
						  "wiki")) or die $!;
		binmode(DATA);
		print DATA $content;
		close(DATA);
	}
}

#===========================================================
# ページの一覧を取得
#===========================================================
sub get_page_list {
	my $self = shift;
	my $proj = shift;

	opendir(DIR,$main::data_dir.$proj) or die $!;
	my ($entry, @ list);
	while($entry = readdir(DIR)){
		my $name = substr($entry,0,rindex($entry,"."));
		my $type = substr($entry,rindex($entry,"."));
		if($type eq ".wiki"){
			push(@list,Util::url_decode($name));
		}
	}
	closedir(DIR);
	@list = sort { $a cmp $b } @list;
	return @list;
}

#==============================================================================
# ページの最終更新時刻を取得
#==============================================================================
sub get_last_modified {
	my $self = shift;
	my $page = shift;
	my $proj = shift;
	
	my @status = stat(Util::make_filename($main::data_dir.$proj,
					      Util::url_encode($page),
					      "wiki"));
	return @status[9];
}

#===============================================================================
# ページが存在するかどうか調べる
#===============================================================================
sub page_exists {
	my $self = shift;
	my $page = shift;
	my $proj = shift;

	return (-e Util::make_filename($main::data_dir.$proj,
				       Util::url_encode($page),
				       "wiki"));
}

#==============================================================================
# バックアップタイプを取得(single|all)
#==============================================================================
sub backup_type {
	return "single";
}

#==============================================================================
# バックアップ時刻の一覧を取得します。
#==============================================================================
sub get_backup_list {
	return undef;
}

#==============================================================================
# バックアップを取得します。
# ※backup_type=allの場合は第二引数で世代(0〜)を指定します。
#==============================================================================
sub get_backup {
	my $self = shift;
	my $page = shift;
	my $content = "";
	my $proj = shift;
	
	my $filename = Util::make_filename($main::backup_dir.$proj,
					   Util::url_encode($page),
					   "bak");
	if(-e $filename){
		open(DATA,$filename) or die $!;
		binmode(DATA);
		while(<DATA>){
			$content = $content.$_;
		}
		close(DATA);
	}
	
	#$content =~ s/\r\n/\n/g;
	#$content =~ s/\r/\n/g;
	return $content;
}

#==============================================================================
# ページを凍結します
#==============================================================================
sub freeze_page {
	my $self = shift;
	my $pagename = shift;
	my $proj = shift;

	my $prefix = Util::url_encode($proj)."." if($proj ne "");
	
	if(!$self->is_freeze($pagename)){
		open(DATA,">>$main::log_dir/".$prefix.$main::freeze_file) 
		    or die $!;
		binmode(DATA);
		print DATA $pagename."\n";
		close(DATA);
	}
}

#==============================================================================
# ページの凍結を解除します
#==============================================================================
sub un_freeze_page {
	my $self = shift;
	my $pagename = shift;
	my $proj = shift;

	my $prefix = Util::url_encode($proj)."." if($proj ne "");

	if($self->is_freeze($pagename)){
		my $buf = "";
		open(DATA,"$main::log_dir/".$prefix.$main::freeze_file) 
		    or die $!;
		while(<DATA>){
			chomp $_;
			if($pagename ne $_){
				$buf .= $_."\n";
			}
		}
		close(DATA);
		
		open(DATA,">$main::log_dir/".$prefix.$main::freeze_file) 
		    or die $!;
		binmode(DATA);
		print DATA $buf;
		close(DATA);
	}
}

#==============================================================================
# 凍結リストを取得
#==============================================================================
sub get_freeze_list {
	my $self = shift;
	my $proj = shift;

	my $prefix = Util::url_encode($proj)."." if($proj ne "");

	my @list;
	if(!-e "$main::log_dir/".$prefix.$main::freeze_file){
		return @list;
	}
	open(DATA,"$main::log_dir/".$prefix.$main::freeze_file) or die $!;
	while(<DATA>){
		chomp $_;
		push @list,$_;
	}
	close(DATA);
	return @list;
}

#==============================================================================
# 引数で渡したページが凍結中かどうかしらべます
#==============================================================================
sub is_freeze {
	my $self = shift;
	my $pagename = shift;
	my $proj = shift;

	foreach($self->get_freeze_list($proj)){
		if($_ eq $pagename){
			return 1;
		}
	}
	return 0;
}

#==============================================================================
# Wikiを作成します。
#==============================================================================
sub create_wiki {
    my $self = shift;
    my $proj = shift;

    my $prefix = Util::url_encode($proj)."." if($proj ne "");

    unless($self->wiki_exists($proj)){
	mkdir($main::data_dir.$proj, 0777) or die $!;
	mkdir($main::backup_dir.$proj, 0777) or die $!;

	#configは掘るほどではないか
	copy("$main::config_dir/".$main::config_file,
	     "$main::config_dir/".$prefix.$main::config_file) or die $!;
	copy("$main::config_dir/".$main::usercss_file,
	     "$main::config_dir/".$prefix.$main::usercss_file) or die $!;
	copy("$main::config_dir/".$main::userdat_file,
	     "$main::config_dir/".$prefix.$main::userdat_file) or die $!;
	copy("$main::config_dir/".$main::plugin_file,
	     "$main::config_dir/".$prefix.$main::plugin_file) or die $!;

	mkdir($main::attach_dir.$proj,0777) or die $!;
	mkdir($main::pdf_dir.$proj,0777) or die $!;
    }
}

#==============================================================================
# Wikiが存在するかどうかを調べます。
# backupなど全部調べた方がいいだろうか?
#==============================================================================
sub wiki_exists{
    my $self = shift;
    my $proj = shift;

    return (-d $main::data_dir.$proj);
}

#=================================================================
# 引数のWikiの子Wikiのリストを返します
# 引数は""(空文字)もしくは/aaa/bbb/cccの形
# 戻り値は文字の配列です("xxx","yyy","zzz")
#=================================================================
sub get_wiki_list {
    my $self = shift;
    my $proj = shift;

    opendir(DIR,$main::data_dir.$proj) or die $!;
    my @list;

    while(my $entry = readdir(DIR)){
	next if($entry =~ /^\.+$/);
	push(@list,$entry) if(-d $main::data_dir.$proj."/".$entry);
    }
    closedir(DIR);

    @list = sort {$a cmp $b} @list;
    return @list;
}

1;
-------------- next part --------------
##############################################################################
#
# Farm API
#
##############################################################################
package Farm;
use Wiki;
use Wiki::DefaultFarmStorage;
use vars qw(@ISA);
use strict;
@ISA = qw(Wiki);

#============================================================================
# コンストラクタ
#============================================================================
sub new {
    my $class = shift;
    my $cgi = shift;
    my $self = Wiki->new($cgi);
    my $proj = shift;
    my $storage = Wiki::DefaultFarmStorage->new();
    $self->set_storage($storage);
    $self->{project} = $proj;

    return bless $self,$class;
}

#==============================================================================
# 現在のWikiに子Wikiを作成します
# 引数の$childは /^\w+$/ でチェックしてください
#==============================================================================
sub create_wiki{
    my $self = shift;
    my $child = shift;
    my $proj = $self->{project};
    $self->{storage}->create_wiki("$proj/$child");
}

#==============================================================================
# 子Wikiが存在するどうかを調べます  child_exists かな ??
#==============================================================================
sub wiki_exists{
    my $self = shift;
    my $child = shift;
    my $proj = $self->{project};
    return $self->{storage}->wiki_exists("$proj/$child");
}

#==============================================================================
# 子Wikiのリストを配列にして返します get_child_listかな ??
#==============================================================================
sub get_wiki_list{
    my $self = shift;
    my $proj = $self->{project};

    return $self->{storage}->get_wiki_list($proj);
}
###############################################################################
# Wiki APIのオーバーライド
# 基本的には引数の最後にprojectを加えます。
###############################################################################
sub is_freeze {
    my $self = shift;
    my $proj = $self->{project};
    push(@_,$proj);
    return $self->{storage}->is_freeze(@_);
}

sub freeze_page {
    my $self = shift;
    my $proj = $self->{project};
    push(@_,$proj);
    $self->{storage}->freeze_page(@_);
}

sub un_freeze_page {
    my $self = shift;
    my $proj = $self->{project};
    push(@_,$proj);
    $self->{storage}->un_freeze_page(@_);
}

sub get_freeze_list{
    my $self = shift;
    my $proj = $self->{project};
    return $self->{storage}->get_freeze_list($proj);
}

sub get_page_list {
    my $self = shift;
    my $proj = $self->{project};
    push(@_,$proj);
    return $self->{storage}->get_page_list(@_);
}

sub get_last_modified {
    my $self = shift;
    my $proj = $self->{project};
    push(@_,$proj);
    return $self->{storage}->get_last_modified(@_);
}

sub get_page {
    my $self = shift;
    my $proj = $self->{project};
    push(@_,$proj);
    return $self->{storage}->get_page(@_);
}

sub get_backup {
    my $self = shift;
    my $proj = $self->{project};
    push(@_,$proj);
    return $self->{storage}->get_backup(@_);
}

sub save_page {
    my $self = shift;
    my $pagename = shift;
    my $content  = shift;
    my $proj = $self->{project};

    $self->do_hook("save_before");
	
    $self->{"storage"}->save_page($pagename,$content,$proj);
    $self->get_CGI->param("page"   ,$pagename);
    $self->get_CGI->param("content",$content);
	
    if($content ne ""){
	$self->do_hook("save_after");
    } else {
	$self->do_hook("delete");
    }
}

sub page_exists{
    my $self = shift;
    my $proj = $self->{project};
    push(@_,$proj);
    return $self->{storage}->page_exists(@_);
}

1;


Fswiki-dev メーリングリストの案内
Back to archive index