Итак, ты достал хороший хостинг с поддежкой cgi. Но пролет с mysql. Бывает и такое... Дело в том, что все самые современные cgi-скрипты дружат с mysql. А когда они в ссоре - помогает искусственная БД, то есть файлы. Итак, сегодня мы напишем простенький сборник фотоальбомов. Его функции:

  • Обзор всех описаний фотографий в разделах фотоальбомов
  • Показ отдельной фотографии

Ну, что же, ближе к телу, как говорится 😉
Полное описание скрипта лежит тут:
http://forb.melkosoft.com/xakep/cgi-lib.zip

Начало скрипта:

#!/usr/bin/perl
print "Content-type: text/html\n\n";
require "cgi-lib.pl";
&ReadParse;
$header="header.html";
$footer="footer.html";
$catalog="$ENV{DOCUMENT_ROOT}/images/catalog";
$area = $in{'area'};
$num = $in{'num'};
$num=~s/\D//g;

Где $header и $footer - размещение html-файлов, отвечающие за заглавие и окончание страницы, дабы придерживаться твоего дизайна. $area - название альбома, $num - номер фотографии. Причем из него нужно вырезать ВСЕ кроме цифр, дабы не получить доступ к практически всем файлам =) что я и делаю в последней строки.

&html("$header");
unless (($num) || ($area)) { &desc }
&init;
print "<h3><center>Фотоальбом \"$name\"</h3><\/center>
Дождитесь загрузки фотографии и жмите \"Далее\" если это возможно
<br>
<center>
<br>";
if (-e "$fotodir/$num\.jpg#26759185") { $exec="jpg"; &loadfoto("$num")
} elsif (-e "$fotodir/$num\.gif") { $exec="gif"; &loadfoto("$num")
} else { &sorry(0,$num) }
&html("$footer");

Далее - распечатка заголовка страницы, переход на процедуру init - получение название альбома, путь размещения фотографий, etc. Распечатка лабуды (хотя надо было ее оформить отдельным файлом). Проверка, есть ли фотография (jpg или gif) и если она есть - процедура ее загрузки, иначе бреемся =) (процедура ошибки с идентификатором 0). Ну и распечатка конца 😉 страницы.

Процедуры - они не дуры 😉
Какие процедуры включает этот скрипт? Это собственно: &html,&loadfoto,&sorry,
&desc,&init и &getcomm. Рассмотрим их по-порядку 😉

sub html {
my ($file)=@_;
open("FILE","$file");
while (<FILE>) { print }
close("FILE");
}

Тут все просто. Получаем параметр процедуры, пытаемся открыть его и распечатать на экран =)

sub loadfoto {
my ($number)=@_;
my ($prev, $next);
&getcomm($area,$num);
print "<table border=1 width=100\%<tr> <td><b><em><center>$comment<\/center>
<\/b><\/em><\/td><\/tr><\/table><br>";
print "\<img src=\"$fotopath/$num\.$exec\" border=1\>\<br\><br>";
$prev=$num-=1;
$next=$num+=2;
if ($prev != 0) {
print "\<a href=\"http://$ENV{SERVER_NAME} $ENV{SCRIPT_NAME}? area=$area&num=$prev\"\>";
print "\<img src=\"\/images\/etc\ /back.gif\" border=0 alt=\"Назад на фото №$prev\"\><\/a>";
print '&nbsp;&nbsp;&nbsp;&nbsp;'
}
print "\<a href=\"http://$ENV{SERVER_NAME} $ENV{SCRIPT_NAME}? area=$area&num=$next\"\>";
print "\<img src=\"\/images\/etc\/next.gif\" border=0 alt=\"Вперед к фото №$next\"\><\/a>"
}

Тут тоже все достаточно просто. Отправляемся на процедуру &getcomm - получение
комментария для текущей фотки, печать html-лабуды, вместе с линками 2 кнопок back.gif и next.gif - это уже на любителя.
Ну и линки вперед-назад соответственно...

sub sorry {
my ($type,$number)=@_;
if ($type eq 0) { 
print "<br><br>Сожалею, но фотография №$number не найдена в данном фотоальбоме. Когда она появится, я ее тут же залью ;)<br><br>";
}
if ($type eq 1) { 
print "<br><br>Сожалею, но фотоальбом с идентификатором \"$number\" не найден в базе фотоальбомов.<br><br>";
}
&html("$footer");
exit;
}

Процедура ошибок.. Ошибки пока 2 - не найдена фотка и не найден альбом. Затем быстрая распечатка конца страницы и выход.

sub desc {
my ($i,$j,@lines,$size,@files);
print "<h3><center>Сборник фотоальбомов</h3><\/center>
Ознакомьтесь с фотографиями, которые находятся в моих фотоальбомах 
<br><br>";
opendir(LSDIR,"$catalog");
@files=readdir("LSDIR");
closedir ("LSDIR");
for ($j=2;$j<=scalar(@files)-1;$j++) {
$curname=$files[$j];
open ("FILE","$catalog/$curname");
@lines=<FILE>;
close(FILE);
$size=scalar(@lines)-2;
open ("FILE","$catalog/$curname");
$i=0;

### Тут посложнее: Читаем каталог фотоальбомов. Открываем все файлы кроме "." и ".." 😉 

while (<FILE>) {
chomp;

if (/^Фотоальбом/) {
print "<em><b>$_ (фотографий в альбоме: $size)<\/em><\/b>\n";
print "<ul><ol>\n";
} elsif (!(/^\//)) {
$i++;
print "<li>";
print "<a href=\"\/cgi-bin\/page\/foto.cgi?area=$curname\&num=$i\" target=_blank>$_<\/a>\n";
}
}
print "<\/ul><br>\n";
}
&html("$footer");
exit;
}

Формат файла такой: его название - соответствие переменной $area. В первой его строке - путь к фотографиям данного альбома, во второй: 'Фотоальбом "название альбома" ', а в последующих - описание к каждой фотографии... Данная процедура вызывается, если скрипт был запущен без параметров - простой показ содержимого базы.

sub init {
my ($j,@files,$curname,$find);
opendir(LSDIR,"$catalog");
$find=0;
@files=readdir("LSDIR");
closedir ("LSDIR");
for ($j=2;$j<=scalar(@files)-1;$j++) {
$curname=$files[$j];
if ($area eq $curname) {
$find=1;
open ("FILE","$catalog/$curname");
while (<FILE>) {
chomp;
if (/^\//) { $fotopath=$_ }
if (/^Фотоальбом/) { $name=$_; break }
}
close(FILE);
}
}
if ($find eq 0) { &sorry(1,$area) }
$name=~/("[^"]*")/;
$name=$1;
$name=~s/^"|"$//g;
$fotodir="$ENV{DOCUMENT_ROOT}$fotopath";
}

Процедура init получает название фотоальбома и каталог фотографий. Если альбом не найден - сообщение об ошибке.

sub getcomm {
my ($zone,$number)=@_;
my ($i);
open(FILE,"$catalog/$zone");
$i=0;
while (<FILE>) {
chomp;
$i++;
if ($i == $number+2) { $comment=$_; break }
}
}

Ну и последняя процедура - получение описание к запрошенной фотографии... Тут все просто (смещение 2 строки - пропуск пути и название альбома).

Фотографии в каталоге расположены в порядке возрастания от 1 до N 😉 и имеют расширение jpg или gif.

Итак, скрипт весит около 3.5 кб, а пользы у него очень много.. Создаешь базу за 5 минут и НИКАКИХ лишних html. Удобно и просто.

Пример работающего фотоальбома лежит тут: http://forb.melkosoft.com/cgi-bin/page/foto.cgi

Check Also

Разведка в Active Directory. Получаем пользовательские данные в сетях Windows без привилегий

Представь, что кто-то проводит атаку на корпоративную сеть Windows. Вначале у злоумышленни…

Оставить мнение