Скрипт галлереи
Создано: 10-01-2010 15:30:56 изменено: 06-01-2013 18:39:54  Метки: tcl http cgi

Представляю вашему вниманию CGI-скрипт на языке высокого уровня TCL, который позволяет быстро организовать альбом из фотографий. Для его работы нужна JS библиотека с http://highslide.com/, которая позволяет быстро просматривать галлерею. Для организации подобного нужны (для debian/ubuntu):
# ставим необходимое
aptitude install lighttpd tcl8.5 tcllib imagemagick
# правим /etc/lighttpd.conf на предмет  таких строк
...
index-file.names           = ( "index.tcl", "index.php", "index.html",
...
static-file.exclude-extensions = ( ".tcl", ".php", ".pl", ".fcgi" )
...
# разрешаем модуль cgi
lighty-enable-mod cgi
# добавляем в /etc/lighttpd/conf-enabled/10-cgi.conf
...
cgi.assign      = ( ".tcl"  => "/usr/bin/tclsh",
...
# рестартуем lighttpd
/etc/init.d/lighttpd restart

теперь веб-сервер готов к работе, в корень (/var/www) кладем директорию c распакованой JS-библиотекой highslide, еще можно положить файл с фоном (/var/www/images/372.jpg), и белую подложку размером 185x185px (/var/www/images/fon.png).

Затем кладем директорию с изображениями и создаем в ней index.tcl следующего содержания:
#! /usr/bin/tclsh
# нужен imagemagick для генерации предпросмотра
# использован highslide с http://highslide.com/ а также при необходимости подложки из /images

# вспомогательные переменные для генерации html
set ::closetag ""
set ::numclose 0
# число изображений в ряду
set ::rowwidth 5
package require ncgi

### процедура вывода изображений
proc main {} {
header Альбом
div gallery
  div gall
    h2 Альбом
    hr
    if ![file exists thumbs] {
      if [catch {file mkdir thumbs}] {
        puts "Немогу создать директорию для предпросмотра"
      }
    }
    if [catch {set list [exec ls . | egrep -i "\.(jpg|jpeg|png|gif)$"]}] {
      puts "Нет изображений" ; set list ""
    }
    set len [llength $list]
    set n 1
    set r [expr $::rowwidth*int($len/$::rowwidth)+1]
    foreach p $list {
      set st ""
      if {$n==$r} {
        # стиль последней строки
        set st [style "width:[expr 201*($len-$r+1)+2]px;"]
      }
      if ![expr $::rowwidth*int($n/$::rowwidth)-$n+1] {
        div row $st
      }
      # если нет предпросмотра пытаемся создать 
      if ![file exists thumbs/$p] {
        catch {exec convert -resize 160x160 -quality 80% $p thumbs/$p}
      }
      div cell
        div cellprisoner
          link $p {class="highslide" onclick="return hs.expand(this)"}
            img thumbs/$p ""
          closetag
        closetag
      closetag
      if ![expr $::rowwidth*int($n/$::rowwidth)-$n] {closetag}
      incr n
    }
  closetag
closetag
footer
}

### html-теги ###
proc link {src {add ""}} {
    set ::closetag </a>$::closetag
    incr ::numclose
    if {$add ne ""} {set add " $add"}
    puts -nonewline [subst {<a href="$src"$add>}]
}
proc img {src {alt ""} {title ""} {add ""}} {
    if {$add ne ""} {set add " $add"}
    puts -nonewline [subst {<img src="$src" alt="$alt" title="$title"$add>}]
}
proc div {{id ""} {add ""}} {
    set ::closetag </div>$::closetag
    incr ::numclose
    if {$add ne ""} {set add " $add"}
    puts -nonewline [subst {<div class="$id"$add>}]
}
proc h2 arg {
  puts <h2>$arg</h2>
}
proc style arg {
    return [subst {style="$arg"}]
}
proc hr {} {puts <hr>}
proc closetag {} {
if {$::numclose > 0} {
    regexp {^(</[^<]+>)(.*)$} $::closetag => r ::closetag
    incr ::numclose -1
    puts -nonewline $r
}}

###
proc header title {
  ncgi::header
  puts [subst {<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <meta name="description" content="Экспериментальный сайт-блог SanSanych-a">
    <link rel="stylesheet" type="text/css" href="/highslide/highslide.css">
    <script type="text/javascript" src="/highslide/highslide.packed.js"></script>
    <script type="text/javascript"><!--
  hs.lang = {
   loadingText :     'Загружается...',
   loadingTitle :    'Нажмите для отмены',
   focusTitle :      'Нажмите чтобы поместить на передний план',
   fullExpandTitle : 'Развернуть до оригинального размера',
   fullExpandText :  'Оригинальный размер',
   creditsText :     'Использует Highslide JS',
   creditsTitle :    'Перейти на домашнюю страницу Highslide JS',
   previousText :    'Предыдущее',
   previousTitle :   'Предыдущее (стрелка влево)',
   nextText :        'Следующее',
   nextTitle :       'Следующее (стрелка вправо)',
   moveTitle :       'Переместить',
   moveText :        'Переместить',
   closeText :       'Закрыть',
   closeTitle :      'Закрыть (esc)',
   resizeTitle :     'Изменить размер',
   playText :        'Слайдшоу',
   playTitle :       'Начать слайдшоу (пробел)',
   pauseText :       'Пауза',
   pauseTitle :      'Приостановить слайдшоу (пробел)',
   number :          'Изображение %1 из %2',
   restoreTitle :    'Нажмите чтобы закрыть изображение, нажмите и перетащите для изменения местоположения. Для просмотра изображений используйте стрелки.'
  };
  hs.graphicsDir = '/highslide/graphics/';
    --></script>
  <style type="text/css" media="screen">
    img { border:0 none; }
    .gallery { background-image: url(/images/372.jpg); background-attachment: scroll; background-repeat: repeat;
     background-position: center top; width: 100%; float: left; padding-bottom:50px; padding-top:50px; }
    .cell { border: 1px dotted gray; background-image: url(/images/fon.png); width: 185px; height: 185px;
     float: left; margin: 6px; display: table; }
    .cellprisoner { width: 185px; height: 185px; display: table-cell; vertical-align: middle; }
    .row { width: [expr $::rowwidth*201]px; margin: 0 auto;}
    .gall { width: [expr $::rowwidth*201+2]px; margin: 0 auto; text-align: center; }
    .footer {width: 100%; float: left; text-align: center;}
  </style>
  <title>$title</title></head><body>}]
}
proc footer {} {
  div footer
    hr
    puts "gallery script v.0.3"
  closetag
  puts "</body></html>"
}
main

Как работает данный скрипт? При запуске он в текущей директории ищет изображения, если находит то пытается к каждому создать предпросмотр (первый запуск может затянуться на слабой машине), затем выводит в stdout страницу с таблицей на div-ах, содержащей предпросмотр.
1139 просмотров комментировать