トップ 差分 一覧 ソース 検索 ヘルプ PDF RSS ログイン

アルバム

サンプル

http://www21051ue.sakura.ne.jp/sample/AutomaticImageMontage/index.html

↑こんなアルバムがほしい〜〜!!! 超カッコいいJQueryのサンプルが見れダウンロード出来るページからjs,sccを拝借

http://www21051ue.sakura.ne.jp/sample/jQuerySimpleImageSlideShow/index.html

opendir my $dh,'images';
print map {"[" . $_->[0] ."]"}
      sort { $b->[1] <=> $a->[1] }
      map { [$_, -M "images/$_" ]} 
      grep ( /^[^.]/,readdir $dh);
$ sudo cpanm Mojolicious
--> Working on Mojolicious
Fetching http://search.cpan.org/CPAN/authors/id/S/SR/SRI/Mojolicious-3.53.tar.gz ... OK
Configuring Mojolicious-3.53 ... OK
Building and testing Mojolicious-3.53 ... OK
Successfully installed Mojolicious-3.53
1 distribution installed

http://yusukebe.com/archives/20120627/181253.html

subversion

http://blog.riywo.com/2008/04/01/054421

$ sudo apt-get install subversion  libapache2-svn
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following extra packages will be installed:
  libdb4.8 libneon27-gnutls libsvn1
Suggested packages:
  db4.8-util subversion-tools
The following NEW packages will be installed:
  libapache2-svn libdb4.8 libneon27-gnutls libsvn1 subversion
0 upgraded, 5 newly installed, 0 to remove and 0 not upgraded.
Need to get 1,953 kB of archives.
After this operation, 5,543 kB of additional disk space will be used.
Do you want to continue [Y/n]? y
Get:1 http://jp.archive.ubuntu.com/ubuntu/ precise/main libdb4.8 amd64 4.8.30- 11ubuntu1 [679 kB]
Get:2 http://jp.archive.ubuntu.com/ubuntu/ precise/main libneon27-gnutls amd64 0.29.6-1 [76.7 kB]
Get:3 http://jp.archive.ubuntu.com/ubuntu/ precise/main libsvn1 amd64 1.6.17dfsg-3ubuntu3 [820 kB]
Get:4 http://jp.archive.ubuntu.com/ubuntu/ precise/universe libapache2-svn amd64 1.6.17dfsg-3ubuntu3 [81.9 kB]
Get:5 http://jp.archive.ubuntu.com/ubuntu/ precise/main subversion amd64 1.6.17dfsg-3ubuntu3 [295 kB]
Fetched 1,953 kB in 1s (1,498 kB/s)
Selecting previously unselected package libdb4.8.
(Reading database ... 53993 files and directories currently installed.)
Unpacking libdb4.8 (from .../libdb4.8_4.8.30-11ubuntu1_amd64.deb) ...
Selecting previously unselected package libneon27-gnutls.
Unpacking libneon27-gnutls (from .../libneon27-gnutls_0.29.6-1_amd64.deb) ...
Selecting previously unselected package libsvn1.
Unpacking libsvn1 (from .../libsvn1_1.6.17dfsg-3ubuntu3_amd64.deb) ...
Selecting previously unselected package libapache2-svn.
Unpacking libapache2-svn (from .../libapache2-svn_1.6.17dfsg-3ubuntu3_amd64.deb) ...
Selecting previously unselected package subversion.
Unpacking subversion (from .../subversion_1.6.17dfsg-3ubuntu3_amd64.deb) ...
Processing triggers for man-db ...
Setting up libdb4.8 (4.8.30-11ubuntu1) ...
Setting up libneon27-gnutls (0.29.6-1) ...
Setting up libsvn1 (1.6.17dfsg-3ubuntu3) ...
Setting up libapache2-svn (1.6.17dfsg-3ubuntu3) ...
Considering dependency dav for dav_svn:
Enabling module dav.
Enabling module dav_svn.
To activate the new configuration, you need to run:
 service apache2 restart
* Restarting web server  apache2                                                             ... waiting .                                                                       [ OK ]
Setting up subversion (1.6.17dfsg-3ubuntu3) ...
Processing triggers for libc-bin ...
ldconfig deferred processing now taking place
$

Start

$ mojo generate app PhotoAlbum
 [mkdir] /var/www/album/photo_album/script
 [write] /var/www/album/photo_album/script/photo_album
 [chmod] photo_album/script/photo_album 744
 [mkdir] /var/www/album/photo_album/lib
 [write] /var/www/album/photo_album/lib/PhotoAlbum.pm
 [mkdir] /var/www/album/photo_album/lib/PhotoAlbum
 [write] /var/www/album/photo_album/lib/PhotoAlbum/Example.pm
 [mkdir] /var/www/album/photo_album/t
 [write] /var/www/album/photo_album/t/basic.t
 [mkdir] /var/www/album/photo_album/log
 [mkdir] /var/www/album/photo_album/public
 [write] /var/www/album/photo_album/public/index.html
 [mkdir] /var/www/album/photo_album/templates/layouts
 [write] /var/www/album/photo_album/templates/layouts/default.html.ep
 [mkdir] /var/www/album/photo_album/templates/example
 [write] /var/www/album/photo_album/templates/example/welcome.html.ep

$ tree
.
└── photo_album
    ├── lib
    │  ├── PhotoAlbum
    │  │  └── Example.pm
    │  └── PhotoAlbum.pm
    ├── log
    ├── public
    │  └── index.html
    ├── script
    │  └── photo_album
    ├── t
    │  └── basic.t
    └── templates
        ├── example
        │  └── welcome.html.ep
        └── layouts
            └── default.html.ep

10 directories, 7 files

デプロイ

http://yanor.net/wiki/?Perl-Mojolicious%2FApache%E3%81%ABCGI%E3%81%A7%E3%83%87%E3%83%97%E3%83%AD%E3%82%A4

http://perl.no-tubo.net/tag/mojolicious/

Subversion

apache CGIで動かす

publicの下にindex.cgiを作成 ここを参考に

[index.cgi]

#!/usr/local/bin/perl
use strict;
use warnings;
use lib qw(
  /var/www/album/photo_album/lib
);
use Mojo::Server::CGI;

$ENV{MOJO_APP} = 'PhotoAlbum';
$ENV{SCRIPT_NAME} = '';
Mojo::Server::CGI->new->run;

http://www21051ue.sakura.ne.jp/album/photo_album/public/index.cgi にアクセス   <- 起動ディレクトリの問題でエラー発生

                                        _ □ X
+---------------------------------------------+
|Your Mojo is working!                        |
|                                             |
|                                             |
+---------------------------------------------+

お〜動いた!!! 後はアルバムを作るだけ っと思ったけどうまく動いていないらしい?!

[index.cgi]

#!/usr/local/bin/perl
use strict;
use warnings;
use lib qw(
        /var/www/album/photo_album/lib
);
use utf8;

$ENV{MOJO_MODE} = 'production';

require Mojolicious::Commands;
Mojolicious::Commands->start_app('PhotoAlbum');

とりあえずサーバーとして起動

cgiで作成

mojoliciousは一旦あきらめてcgiで作成http://www21051ue.sakura.ne.jp/album/album/album.cgi

#!/usr/local/bin/perl
use strict;
use utf8;
use myconstant;
use CGI;
use CGI::Carp qw(fatalsToBrowser);
use File::Temp;

my $cons = myconstant->new();
my $cgi = CGI->new();
my $imagedir = $cons->{imagedir};
my $img = $cons->{img};
my $max_size = $cons->{max_size};
my $img_size = $cons->{img_size};
my $next = 0;
my $preload = 4;
my $base = $cgi->url(-path);
my $count = $cgi->user_agent()  =~ /mobile/i ?
	$cons->{item_count_mobile} :
	$cons->{item_count} ;
$base =~ s|^.*//(.*)/album.cgi.*$|$1|;

if($cgi->param('_action') eq 'UPLOAD'){
	up_load();
}elsif($cgi->param('_action') eq 'next'){
	print "Content-Type:text/html\n\n";
	$next = $cgi->param('_count') || 0;
	print get_images();
	exit;
}elsif($cgi->param('_action') eq 'flick'){
	print "Content-Type:text/html\n\n";
	my $res = <<"End_Json";
{
	"name" : "@{[get_next_image($cgi->param('_count'))]}",
	"preload" : "@{[get_next_image($cgi->param('_count') < 0 ? $preload * -1 : $preload)]}"
}
End_Json
	print $res;
	exit;
}
my $filename = $cgi->param('_name');
if($filename ne '' and $cgi->param('_action') ne 'ALBUM'){
	if($cgi->param('_action') =~ /^\d{1,3}$/){
		system ("/usr/bin/mogrify -rotate @{[$cgi->param('_action')]} $img/$filename");
		system ("/usr/bin/mogrify -rotate @{[$cgi->param('_action')]} $imagedir/$filename");
	}elsif($cgi->param('_action') eq 'touch'){
		system ("/usr/bin/touch $img/$filename");
		system ("/usr/bin/touch $imagedir/$filename");
	}elsif($cgi->param('_action') eq 'delete'){
		unlink "$img/$filename";
		unlink "$imagedir/$filename";
	}
	print main_html();
}else{
	print make_html();
}
sub image_search{
	my $name  = shift;
	my $array = shift;
	my $i = 0;
	for(@$array){
		return $i if ($_ eq $name);
		$i++;
	}
	return;
} 
sub get_next_image{
	my $count = shift;
	my $name = $cgi->param('_name');
	$name =~ s|.*?([^/]+\.[a-zA-Z]*)(\?.*)*$|$1|;
	my @files = get_image_files();
	my $i = image_search($name,\@files);
	$i += $count;
	$i -= ($#files + 1) if($i > $#files);
	$name = $files[$i]||$name;
    return qq{$img/$name};
}
sub get_image_files{
	opendir my $dh,$imagedir or die "Can't open $imagedir";
	my @files = map {$_->[0]}
		sort { $a->[1] <=> $b->[1] }
		map { [$_, -M "$imagedir/$_" ]} 
		grep { ! /(hide\.png|show\.png)/ }
		grep { -s "$imagedir/$_" != 0 }
		grep ( /^[^.]/,readdir $dh);
	return @files;
}
sub get_images{
	my $opt = shift||'';
	opendir my $dh,$imagedir or die "Can't open $imagedir";
	my @files = map {$_->[0]}
		sort { $a->[1] <=> $b->[1] }
		map { [$_, -M "$imagedir/$_" ]} 
		grep { ! /(hide\.png|show\.png)/ }
		grep { -s "$imagedir/$_" != 0 }
		grep ( /^[^.]/,readdir $dh);
	my @select_files = ();
	my $i = -1;
	my $st = $next * $count;
	for(@files){
		$i++;
		next if $i < $st;
		next if ($i >= ($next + 1) * $count);
		push @select_files,$_;
	}

	my $text = join("\n",map 
                    {qq{ <a href="@{[$cgi->url()]}?_name=$_"><img src="$imagedir/$_" $opt></img></a>}} @select_files);

	return $text;
}

sub up_load_form{
	my $text = <<END_FORM;
@{[ $cgi->start_multipart_form(
	-name=>'_upload' 
	,-method=>'post'
	,-action=>$cgi->url())
]}
@{[ $cgi->filefield(-name=>'upload_file',-multiple=>'multiple')]} 
@{[ $cgi->submit(-name=>'_action',-value=>'UPLOAD',-style=>'width:80px') ]}
</form>
END_FORM

	return $text;
}

sub action_form{
	my $text = <<END_FORM;
<a href="@{[$cgi->url()]}"> A L B U M </a> <div id="flick">@{["<br>" x 5]}</div>
END_FORM

	return $text;
}
sub up_load{
   my @fh = $cgi->upload('upload_file');                                       
   my @filename = $cgi->param('upload_file');
   for my $fh (@filename){
       up_load_main($fh);
   }       
}
sub up_load_main{
       my $fh = shift;
	my $basename;
	my $suffix;
#	my $filename = $cgi->param('upload_file');
       my $filename = $fh;
	($basename,$suffix) = ($filename =~ m|([^/]*)(\..*)|);
	$filename = File::Temp->new('DIR'=>$img);
	$filename =~ s|$img/||;
	$filename .= $suffix;
	my $temp_path = $cgi->tmpFileName($fh);
	$filename = $ENV{REMOTE_USER} . "_" . $filename if($ENV{REMOTE_USER});
	rename $temp_path, "$img/$filename";
	if($filename =~ /(.*)\.mp4/i){
		my $outfile = "$1_mp4.jpg";
		system("ffmpeg -i $img/$filename -vframes 1 $imagedir/$outfile");
	}else{
		my $size = -s "$img/$filename";
		if ($size > $max_size){
			system ("convert -resize @{[int($img_size / $size * 100)]}% $img/$filename $imagedir/$filename");
		}else{
			system ("cp $img/$filename $imagedir/$filename");
		}
	}
}

sub make_html{
	my $text = <<END_HTML;
Content-Type:text/html

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>album</title>
		<meta charset="UTF-8" />
		<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> 
		<meta name="viewport" content="width=device-width, initial-scale=1.0"> 
        <meta name="description" content="Automatic Image Montage with jQuery" />
        <meta name="keywords" content="jquery, images, montage, fullscreen, floating, grid, automatic" />
        <link rel="stylesheet" type="text/css" href="$cons->{css}demo.css" />
		<link rel="stylesheet" type="text/css" href="$cons->{css}style.css" />
		<link href='http://fonts.googleapis.com/css?family=PT+Sans+Narrow&v1' rel='stylesheet' type='text/css' />
		<link href='http://fonts.googleapis.com/css?family=Monoton' rel='stylesheet' type='text/css' />

    </head>
    <body>
		<div class="container">
			<div class="header">
				@{[$cgi->param('_action')]}
				<span class="right_ab">
				@{[up_load_form()]}
				</span>
			</div>

			<div id="overlay" class="content">
				<div class="inner">
				$cons->{inner}
					<div class="clr"></div>
					<div id="panel" class="panel hide"></div>
				</div>
			</div>

			<div class="am-container" id="am-container">
				@{[get_images()]}
			</div>
			<div id="loadmore" class="loadmore" style="width:100%;">load more...</div>
		</div>
		<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
		<script type="text/javascript" src="$cons->{js}jquery.montage.min.js"></script>
		<script type="text/javascript">
			var ix= 0;
			\$(function() {
				/* 
				 * just for this demo:
				 */
/*				\$('#showcode').toggle(
					function() {
						\$(this).addClass('up').removeClass('down').next().slideDown();
					},
					function() {
						\$(this).addClass('down').removeClass('up').next().slideUp();
					}
				);
*/				\$('#panel').toggle(
					function() {
						\$(this).addClass('show').removeClass('hide');
						\$('#overlay').stop().animate( { left : - \$('#overlay').width() + 20 + 'px' }, 300 );
					},
					function() {
						\$(this).addClass('hide').removeClass('show');
						\$('#overlay').stop().animate( { left : '20px' }, 300 );
					}
				);
				
				var \$container 	= \$('#am-container'),
					\$imgs		= \$container.find('img').hide(),
					totalImgs	= \$imgs.length,
					cnt			= 0;
				
				\$imgs.each(function(i) {
					var \$img	= \$(this);
					\$('<img/>').load(function() {
						++cnt;
						if( cnt === totalImgs ) {
							\$imgs.show();
							\$container.montage({
								fillLastRow				: true,
								alternateHeight			: true,
								alternateHeightRange	: {
									min	: 90,
									max	: 240
								}
							});
							
							\$('#overlay').fadeIn(500);
							\$('#loadmore').show().bind('click', function() {
								\$.ajax({
									url: 'album.cgi',
									type: 'GET',
									data: {
										_action: 'next',
										_count: ++ix
									},
									success: function( data,textStatus,jqXHR){
										var \$newimages = \$( data );
										\$newimages.imagesLoaded( function(){
											\$container.append( \$newimages ).montage( 'add',\$newimages);
										});
									}
								})
							});
						}
					}).attr('src',\$img.attr('src'));
				});	
			});
		</script>
    </body>
</html>
END_HTML
return $text;
}

sub main_html{
	$count  = 9999;
	my $text = <<END_HTML;
Content-Type:text/html

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>album</title>
		<meta charset="UTF-8" />
		<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> 
        <link rel="stylesheet" type="text/css" href="$cons->{css}demo.css" />
    </head>
    <body>
	<div class="container">
		<div id="header" class="header">
		@{[action_form()]}
		</dev>
			<div id="overlay" class="content">
				<div class="inner">
<style type="text/css">

div.example1 {
overflow-x: auto;
white-space: nowrap;
}

</style>
 @{[ $cgi->start_multipart_form(
	-name=>'_upload' 
	,-method=>'post'
	,-action=>$cgi->url())
]}
@{[ $cgi->hidden(-name=>'_name')]}
@{[ $cgi->submit(-name=>'_action',-value=>'90',-style=>'width:30px') ]}
@{[ $cgi->submit(-name=>'_action',-value=>'270',-style=>'width:30px') ]}
@{[ $cgi->submit(-name=>'_action',-value=>'touch',-style=>'width:60px') ]}
@{[ $cgi->submit(-name=>'_action',-value=>'delete',-style=>'width:60px') ]}
</form>
					<div class="example1">
						@{[get_images("width=80px height=120px")]}
					</div>
					<div class="clr"></div>
					<div id="panel" class="panel hide"></div>
				</div>
			</div>
		</div>
	</div>
	<div id="mainpage">
	@{[imgTag($cgi->param('_name'))]}
	</div>

		<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
		<script type="text/javascript" src="$cons->{js}jquery.montage.min.js"></script>
		<script type="text/javascript">
			\$(function() {
				/* 
				 * just for this demo:
				 */
/*				\$('#showcode').toggle(
					function() {
						\$(this).addClass('up').removeClass('down').next().slideDown();
					},
					function() {
						\$(this).addClass('down').removeClass('up').next().slideUp();
					}
				);
*/				\$('#panel').toggle(
					function() {
						\$(this).addClass('show').removeClass('hide');
						\$('#overlay').stop().animate( { left : - \$('#overlay').width() + 20 + 'px' }, 300 );
					},
					function() {
						\$(this).addClass('hide').removeClass('show');
						\$('#overlay').stop().animate( { left : '20px' }, 300 );
					}
				);
			\$('#overlay').fadeIn(500);
			});
		</script>
		<script type="text/javascript">
			\$(function() {
				\$('#flick').bind("touchstart touchmove touchend",touchHandler);
				function touchHandler(e){
					e.preventDefault();
					var touch = e.originalEvent.touches[0];
					if(e.type == "touchstart"){
						startX = touch.pageX;
					}else if(e.type == "touchmove"){
						diffX = touch.pageX - startX;
					}else if(e.type == "touchend"){
						if(diffX > 50){
							\$.ajax({
								url: 'album.cgi',
								type: 'GET',
								data: {
									_action: 'flick',
									_name: document.img.src,
									_count: '-1',
								},
								success: function( data,textStatus,jqXHR){
									var res = JSON.parse(data); 
									document.img.src=res.name;
                                    \$("#bigimg").attr("href",res.name);
									\$("<img>").attr("src",res.preload);
								}
							})
						}
						if(diffX < -50){
							\$.ajax({
								url: 'album.cgi',
								type: 'GET',
								data: {
									_action: 'flick',
									_name: document.img.src,
									_count: '1',
								},
								success: function( data,textStatus,jqXHR){
									var res = JSON.parse(data); 
									document.img.src=res.name;
                                    \$("#bigimg").attr("href",res.name);
									\$("<img>").attr("src",res.preload);
								}
							})
						}
					}
				}
			});
		</script>
		@{[preload()]}
    </body>
</html>
END_HTML
return $text;
}
sub preload{
	my @files = get_image_files();
	my $name = $cgi->param('_name');
	$name =~ s|.*?([^/]+\.[a-zA-Z]*)(\?.*)*$|$1|;
	my $i = image_search($name,\@files);
	my $text = "<script>\n";
	for my $j (1 .. $preload){
			$text .= qq{\$('<img src="$img/$files[$i + $j]">');\n};
			$text .= qq{\$('<img src="$img/$files[$i - $j]">');\n};
	}
	$text .= "</script>\n";
	return $text;
}
sub imgTag{
	my $file = shift;
	my $text;
	if($file =~ /(.*)_mp4.jpg$/){
		$text = <<TAG_END;
    <br /><br /><br /><br /><br />
    <br /><br /><br /><br /><br />
    <div align="center">
	<video
		src="http://$cons->{user_pass}${base}/$img/$1.mp4"
		preload="none" 
        onclick="this.play();"
		poster="$imagedir/$file" 
		width="640"
		controls>
	<source src="$img/$1.mp4">
	</video>
    </div>
TAG_END
	}else{
		$text = <<TAG_END;
	<a href="$img/$file" id="bigimg">
		<img src="$img/$file?@{[(stat("$img/$file"))[9]]}" width=100% name="img"></img>
	</a>
TAG_END
	}
	return $text;
}