[첫화면으로]Perl/Plack

마지막으로 [b]

음, 웹 프로그래밍에 대해서는 영 쥐약이라1 솔직히 무슨 말인지 영 어렵다만, 대충 다음과 같이 이해가 된다.

1. 사용 사례

주인장의 연구실 컴퓨터에는 실험 결과가 담긴 폴더가 매우 많이 있었다. 이게 어떤 구조로 진화했냐 하면:
  1. 한 번 실험하면 폴더 하나에 결과가 담긴다. 그래프는 이미지 뷰어로 쉽게 볼 수 있도록 jpg로도 저장하고, 파라메터나 기타 코멘트 등은 txt로 저장했다.
  2. 생각해보니 txt 따로 jpg 따로 볼 게 아니라, html로 만들면 html만 더블클릭하면 텍스트와 그림을 한 번에 볼 수 있겠더라. html로도 저장했다.
  3. 이렇게 폴더 하나에 jpg, txt, html 각각 수십개가 생겼고, 다시 이런 폴더가 시간이 흐르면서 계속 늘어났다.
  4. 폴더 하나를 들여다 볼 때마다 수십개의 html파일을 일일이 열어보자니 귀찮아졌다. 그래서 그 폴더 내의 모든 html의 body 부분을 모아서 하나의 all.html 파일로 다시 만드는 스크립트 collect.pl을 만들었다.
  5. 그런데 이런 폴더가 다시 수십, 수백개가 되어 가니까 일일이 들어가서 열면서 보는 것도 힘들고, 검색을 했으면 좋겠더라. 그래서 index.pl 파일을 만들어서 최상위 폴더에 두었다. 이 index.pl에는 텍스트 입력창이 있어서 거기에 입력을 하면 하위 폴더들을 뒤지면서 html의 텍스트에서 일치하는 부분이 있는 것들만 모아서 출력해준다. 이 시점에서 CGI를 쓰게 되어서, public_html 아래쪽에 마운트를 하였다.
  6. 어떤 폴더의 데이타는 영 쓸데가 없어서 며칠 안에 삭제하고, 어떤 폴더는 별도의 폴더에 복사해서 따로 보관하고 싶어졌다. 그래서 collect.pl을 수정하여, all.html 파일 내에는 각 그림-html 쌍마다 삭제 또는 보관 여부를 묻는 체크박스를 달고, 이 체크박스에 체크한 후 submit 버튼을 누르면 move.pl이 불려서 체크된 파일에 대해 삭제 또는 복사 동작을 한다.

즉 다음과 같은 구조로 파일이 보관되어 있었다:
/
 `- index.pl           --> data/ 폴더 내에 있는 텍스트를 검색해서 결과를 출력해주는 CGI
 `- collect.pl         --> data/ 내 특정 폴더에 저장된 파일들을 모아 all.html을 생성해주는 스크립트
 `- move.pl            --> all.html에서 submit버튼을 누르면 호출하여 특정 번호만 삭제
 `- data/
   `- 0001/            --> 이런 데이타 폴더가 수천개
     `- 0001_1.jpg     --> 데이타 그림과, 데이타 설명이 붙은 텍스트와 HTML이 수십개씩
     `- 0001_1.txt
     `- 0001_1.html
     `- 0001_2.jpg, 0001_2.txt, ...
     `- all.html       --> 폴더 안의 모든 html, jpg를 하나의 html안에 합쳐둔 것
   `- 0002/
   `- 0003/
    ...

문제는 이 결과 폴더를 나중에 윈도우 쪽으로 다 옮기고 시간이 흐르고 나니 정말 필요한 부분만 남기고 이젠 지워버리고 싶은데, html을 보는 거야 상관이 없는데 삭제 또는 복사를 하려니 CGI를 동작시킬 방법이 필요했다.

그래서 저 advent calendar 의 24개 기사를 앞에서부터 훑어 보면서 참고하여 해 보았다.
# app.psgi
use CGI::Emulate::PSGI;
CGI::Emulate::PSGI->handler(sub {
    do "./index.pl";
    CGI::initialize_globals() if &CGI::initialize_globals;
});
use CGI::Emulate::PSGI;
use Plack::Builder;

my $index = CGI::Emulate::PSGI->handler(sub {
    do "index.pl";
    CGI::initialize_globals() if defined &CGI::initialize_globals;
});

my $move  = CGI::Emulate::PSGI->handler(sub {
    do "move.pl";
    CGI::initialize_globals() if defined &CGI::initialize_globals;
});

builder {
    mount "/" => $index;
    mount "/move.pl" => $move;
}
# 최종 버전 app.psgi 파일
use CGI::Emulate::PSGI;
use Plack::Builder;
use Plack::App::Directory;

my $index = CGI::Emulate::PSGI->handler(sub {
    do "index.pl";
    CGI::initialize_globals() if defined &CGI::initialize_globals;
});

my $move  = CGI::Emulate::PSGI->handler(sub {
    do "move.pl";
    CGI::initialize_globals() if defined &CGI::initialize_globals;
});

builder {
    mount "/" => $index;
    mount "/data" => Plack::App::Directory->new( root => './data' );
    mount "/move.pl" => $move;
}

d:\Temp\placktest>plackup -L Shotgun --access-log access.log app.psgi
HTTP::Server::PSGI: Accepting connections at http://0:5000/

실제로 실행해보니, 워낙 간단한 스크립트라서 그랬는지는 몰라도, 기존 스크립트를 거의 건드리지 않고 실행할 수 있었다. 손을 대야 했던 곳은 딱 두 곳:

아주 만족스럽군.

2. 기타 & Comments

cgi 파일 하나마다 핸들러를 따로 붙여 주셨네요.
https://metacpan.org/module/Plack::App::CGIBin 사용하면 cgi들어있는 디렉토리만 지정해주면 되는거 같습니다.
-- aero 2011-12-15 1:07 pm

근데 그게 잘 안 되더라고요. move.pl은 잘 불러오는데, index.pl은 못 찾거나, 찾아도 new CGI를 못 실행하는지 $q = new CGI의 결과가 undef이 되거나...
-- Raymundo 2011-12-15 5:12 pm
이름:  
Homepage:
내용:
 


기타분류
각주:
1. UseModWiki소스수정을 하고 있는 처지에 이런 소리해도 되나ㅋ
2. 저 글에서 권하고 있는 Cpan:Task::Plack도 설치하려고 했는데 의존성이 걸린 모듈 중에 Cpan:Plack::App::Proxy가 계속 make test 단계에서 진행이 안 되어서 실패
3. 이 경우는 애플리케이션 내에서 따로 로그를 켜주거나 하라고 되어 있음

마지막 편집일: 2021-12-3 3:23 pm (변경사항 [d])
1585 hits | Permalink | 변경내역 보기 [h] | 페이지 소스 보기