--- make_poll.pl 2003/04/24 17:55:17 1.5
+++ make_poll.pl 2003/11/08 21:59:25 1.18
@@ -10,6 +10,7 @@
use XML::Parser;
use common;
+use Carp;
$|=1;
@@ -19,18 +20,19 @@
my @Modes = qw(object pass skip);
-my $dir;
+my $poll;
my $dowarn = 1;
-my $pitanje_nr = 0; # curr. pitanje
-my $pitanje_tag = ""; # originalni oblik broja pitanja
-my $page_nr = 1; # prvo pitanje na strani
+my $q_type = "q"; # q=question, u=unnumbered question
+my %question_nr; # curr. question numbers
+my $question_tag = ""; # originalni oblik broja questions
+my $page_nr = 1; # prvo question na strani
my $p_suffix=""; # if more than one box per question
my $curr_suffix=""; # trenutni suffix
-my @stack_pit; # stack pitanja (pitanje, suffix)
+my @stack_que; # stack of questions (question, suffix)
my @sql_create = ("id serial",
"http_referer character varying(500)",
@@ -53,10 +55,64 @@
# this is usename in database
my $db_user="dpavlin";
+# This option allows users to fill poll without using invitation URL.
+# That also means it's unpossible for them to return to exiting poll
+# because they don't have thair own unique ID. Howver, it enables simple
+# polls to be conducted by just publishing URL to them.
+my $without_invitation=0;
+
+# This will remove numbers before answers. That enables you to have
+# answers written like:
+# 1.1 red
+# 1.2 black
+# and users will see just "red" and "black"
+my $remove_nrs_in_answers=0;
+
+# This defines files which will be included in various places to produce
+# design. You could desing them using your faviourite html editor (vim :-)
+# and then split them into separate files
+
+my %include_files = (
+# this file is included at top of each paAge
+ 'header' => "header.html",
+# this file is used to separate questions
+ 'separator' => "separator.html",
+# this file is used to show "submit" button, which under multi-page
+# polls will also bring next page
+ 'submit' => "next.html",
+# this file is included at bottom of each page
+ 'footer' => "footer.html",
+# this file will be showen after poll is completed
+ 'thanks' => "thanks.html"
+);
+
+# buffer for suck(_file)ed html files
+# and additional markup before and after tags
+my %html = (
+ 'hr_before' => " ",
+ 'hr_after' => "
",
+ 'que_before' => "
",
+ 'que_after' => "
",
+ 'subque_before' => '
',
+ 'subque_after' => "
",
+ 'ans_before' => "
",
+ 'ans_after' => "
",
+ 'html_before' => "
",
+ 'html_after' => "
",
+
+);
+
+# name of database colums
+# for questions
+my $q_db_col = "q";
+# for unnumbered questions
+my $u_db_col = "u";
+
+
#------------------------------------------------------------------
sub suck_file {
- my $file = shift @_;
+ my $file = shift || croak "suck_file called without argument";
open(H,$file) || die "can't open '$file': $!";
my $content;
while () { $content .= $_; } ;
@@ -64,28 +120,28 @@
return $content;
}
-my $html_header=suck_file("header.html");
-my $html_separator=suck_file("separator.html");
-my $html_next=suck_file("next.html");
-my $html_footer=suck_file("footer.html");
+$html{'header'}=suck_file($include_files{'header'});
+$html{'separator'}=suck_file($include_files{'separator'});
+$html{'submit'}=suck_file($include_files{'submit'});
+$html{'footer'}=suck_file($include_files{'footer'});
#------------------------------------------------------------------
sub php_header {
my ($page_nr,@sql_update) = @_;
my $out='$sql";
$result=pg_Exec($conn,fix_sql($sql));
- } elseif($do_stranice != $PHP_SELF) {
+ } elseif($do_stranice != $PHP_SELF && isset($do_uri) && isset($a)) {
Header("Location: $do_uri?a=$a");
exit;
}
@@ -104,7 +160,7 @@
#------------------------------------------------------------------
-my $html_kraj=suck_file("thanks.html");
+$html{'thanks'}=suck_file($include_files{'thanks'});
#------------------------------------------------------------------
@@ -123,18 +179,18 @@
die "Can't read $xmlfile" unless -r $xmlfile;
-if (defined $dir) {
- die "$dir isn't a directory" unless -d $dir;
+if (defined $poll) {
+ die "$poll isn't a directory" unless -d $poll;
}
else {
$xmlfile =~ m!([^/.]+)(?:\.[^/.]*)?$!;
- $dir = $1;
- if (-e $dir) {
- die "$dir exists but isn't a directory"
- unless -d $dir;
+ $poll = $1;
+ if (-e $poll) {
+ die "$poll exists but isn't a directory"
+ unless -d $poll;
}
else {
- mkdir $dir, 0755;
+ mkdir $poll, 0755;
}
}
@@ -178,7 +234,7 @@
print "p[$page_nr] ";
-open(PAGE, ">$dir/$last_fn") or die "Couldn't open $last_fn for writing:\n$!";
+open(PAGE, ">$poll/$last_fn") or die "Couldn't open $last_fn for writing:\n$!";
print PAGE php_header($page_nr,@prelast_sql_update);
my $next_fn=sprintf("%02d.php",$page_nr);
$last_page=~s/##NEXTPAGE##/$next_fn/;
@@ -186,34 +242,38 @@
close(PAGE);
$page_nr++;
-open(PAGE, ">$dir/$next_fn") or die "Couldn't open $next_fn for writing:\n$!";
+open(PAGE, ">$poll/$next_fn") or die "Couldn't open $next_fn for writing:\n$!";
print PAGE php_header($page_nr,@last_sql_update);
-print PAGE "$html_header $html_kraj $html_footer";
+print PAGE "$html{'header'} $html{'thanks'} $html{'footer'}";
close(PAGE);
# dump sql structure
-open(SQL,">$dir/$dir.sql") || die "$dir.sql: $!";
+open(SQL,">$poll/$poll.sql") || die "$poll.sql: $!";
+print SQL "drop database ".$prefix.$poll.";\n";
+print SQL "create database ".$prefix.$poll.";\n";
+print SQL "\\connect ".$prefix.$poll.";\n";
print SQL "create table poslani ( member_id int4 not null, unesen timestamp default now() );\n";
-print SQL "create table $dir (do_stranice text default null, ",join(",\n",@sql_create),");\n";
+print SQL "create table $poll (do_stranice text default null, ",join(",\n",@sql_create),");\n";
close(SQL);
# dump common.php
-open(PHP,">$dir/common.php") || die "common.php: $!";
-$common_php =~ s/##DB##/$dir/g;
-my $db_name = $prefix.$dir;
+open(PHP,">$poll/common.php") || die "common.php: $!";
+$common_php =~ s/##DB##/$poll/g;
+my $db_name = $prefix.$poll;
$common_php =~ s/##DB_NAME##/$db_name/g;
$common_php =~ s/##PREFIX##/$prefix/g;
$common_php =~ s/##DB_USER##/$db_user/g;
$common_php =~ s/##PREFIX##/$prefix/g;
my $members_db = $prefix."members";
$common_php =~ s/##MEMBERS_DB##/$members_db/g;
+$common_php =~ s/##WITHOUT_INVITATION##/$without_invitation/g;
print PHP $common_php;
close(PHP);
-open(PHP,">$dir/head.php") || die "head.php: $!";
+open(PHP,">$poll/head.php") || die "head.php: $!";
my $max_page = $page_nr - 1;
$head_php=~ s/##MAXPAGE##/$max_page/;
$head_php=~ s/##TEXT##/Ispunili ste %02d%% ankete/;
@@ -221,217 +281,203 @@
close(PHP);
# 01.php -> index.php
-rename "$dir/01.php","$dir/index.php" || die "can't rename '$dir/01.php' to index.php";
+rename "$poll/01.php","$poll/index.php" || die "can't rename '$poll/01.php' to index.php";
################
## End of main
################
-# return unique name of pitanje
-sub new_pit {
- my $out="p".$pitanje_nr.$p_suffix;
+# return unique name of question
+sub new_que {
+ my $out=$q_type.( $question_nr{$q_type} || 0 );
+ $out .= "_".$p_suffix if ($p_suffix);
$curr_suffix=$p_suffix;
$p_suffix++;
return $out;
}
-# current pitanje
-sub curr_pit {
- return "p".$pitanje_nr.$curr_suffix;
+# current question
+sub curr_que {
+ return $q_type.( $question_nr{$q_type} || 0 ).$curr_suffix;
}
#----------------------------------------------------------
sub starthndl {
- my ($xp, $el, %atts) = @_;
+ my ($xp, $el, %atts) = @_;
-# return unless ($in_poll or $el eq 'slideshow');
+# return unless ($in_poll or $el eq 'slideshow');
- unless ($in_poll) {
- $in_poll = $xp->depth + 1;
- return;
- }
+ unless ($in_poll) {
+ $in_poll = $xp->depth + 1;
+ return;
+ }
+
+ if ($Mode) {
+ if ($Mode eq 'pass') {
+ $Markedup_Text .= "\n" . $xp->recognized_string;
+ } elsif ($Mode eq 'object') {
+ push(@Ostack, $Object);
+
+ $Object = {
+ _Atts => \%atts,
+ _Text => ''
+ };
+ bless $Object, "Slideobj::$el";
+ }
- if ($Mode) {
+ # skip does nothing
+ return;
+ }
- if ($Mode eq 'pass') {
- $Markedup_Text .= "\n" . $xp->recognized_string;
- }
- elsif ($Mode eq 'object') {
- push(@Ostack, $Object);
+ unless ($after_head) {
+ if ($el eq 'head') {
+ $after_head = 1;
+ start_mode($xp, 'object');
- $Object = {_Atts => \%atts,
- _Text => ''
- };
- bless $Object, "Slideobj::$el";
- }
+ push(@closure_stack, $closure);
+ $closure = sub {
+ my ($xp, $text) = @_;
- # skip does nothing
- return;
- }
-
- unless ($after_head) {
- if ($el eq 'head') {
- $after_head = 1;
- start_mode($xp, 'object');
-
- push(@closure_stack, $closure);
- $closure =
- sub {
- my ($xp, $text) = @_;
-
- unless (defined $text) {
-
- $header = $Object;
- }
- };
+ unless (defined $text) {
+ $header = $Object;
+ }
+ };
+ return;
+ }
- return;
- }
+# die "The head element must be the first thing in the slideshow";
+ }
-# die "The head element must be the first thing in the slideshow";
- }
+ my $new_closure;
- my $new_closure;
+ my $subname = "Poll::$el";
- my $subname = "Poll::$el";
+ if (defined &$subname) {
+ no strict 'refs';
- if (defined &$subname) {
- no strict 'refs';
+ &$subname($xp, $el, \%atts, \$new_closure);
+ } else {
+ $body .= x($xp->recognized_string);
+ $new_closure = sub {
+ my ($xp, $text) = @_;
- &$subname($xp, $el, \%atts, \$new_closure);
- }
- else {
- $body .= $xp->recognized_string;
- $new_closure =
- sub {
- my ($xp, $text) = @_;
-
- if (defined $text) {
- $body .= $text;
- }
- else {
- $body .= "$el>";
+ if (defined $text) {
+ $body .= x($text);
+ } else {
+ $body .= x("$el>");
+ }
+ };
}
- };
- }
- push(@closure_stack, $closure);
- $closure = $new_closure;
-} # End starthndl
+ push(@closure_stack, $closure);
+ $closure = $new_closure;
+} # End starthndl
sub endhndl {
- my ($xp, $el) = @_;
+ my ($xp, $el) = @_;
- return unless $in_poll;
+ return unless $in_poll;
- my $lev = $xp->depth;
+ my $lev = $xp->depth;
- if ($lev == $in_poll - 1) {
- $in_poll = 0;
- $xp->finish;
- return;
- }
-
- if ($Mode_level == $lev) {
-
- if ($Mode eq 'pass') {
- &$closure($xp, $Markedup_Text)
- if (defined $closure);
- }
+ if ($lev == $in_poll - 1) {
+ $in_poll = 0;
+ $xp->finish;
+ return;
+ }
+
+ if ($Mode_level == $lev) {
+
+ if ($Mode eq 'pass') {
+ &$closure($xp, $Markedup_Text) if (defined $closure);
+ }
- $Mode = $Mode_level = 0;
- }
+ $Mode = $Mode_level = 0;
+ }
+
+ if ($Mode) {
+ if ($Mode eq 'pass') {
+ $Markedup_Text .= "$el>";
+ } elsif ($Mode eq 'object') {
+ my $this = $Object;
+ if (2 == keys %$this) {
+ $this = $this->{_Text};
+ }
- if ($Mode) {
- if ($Mode eq 'pass') {
- $Markedup_Text .= "$el>";
- }
- elsif ($Mode eq 'object') {
- my $this = $Object;
- if (2 == keys %$this) {
- $this = $this->{_Text};
- }
-
- $Object = pop(@Ostack);
-
- my $slot = $Object->{$el};
- if (defined $slot) {
- if (ref($slot) eq 'ARRAY') {
- push(@$slot, $this);
- }
- else {
- $Object->{$el} = [$slot, $this];
- }
- }
- else {
- $Object->{$el} = $this;
- }
- }
+ $Object = pop(@Ostack);
- return;
- }
+ my $slot = $Object->{$el};
+ if (defined $slot) {
+ if (ref($slot) eq 'ARRAY') {
+ push(@$slot, $this);
+ } else {
+ $Object->{$el} = [$slot, $this];
+ }
+ } else {
+ $Object->{$el} = $this;
+ }
+ }
- &$closure($xp)
- if defined $closure;
+ return;
+ }
+
+ &$closure($xp) if defined $closure;
- $closure = pop(@closure_stack);
+ $closure = pop(@closure_stack);
} # End endhndl
#----------------------------------------------------------
sub text {
- my ($xp, $data) = @_;
+ my ($xp, $data) = @_;
- return unless $in_poll;
+ return unless $in_poll;
- if ($Mode ) {
+ if ($Mode) {
- if ($Mode eq 'pass') {
- my $safe = sgml_escape($data);
+ if ($Mode eq 'pass') {
+ my $safe = sgml_escape($data);
- $Text .= $safe;
- $Markedup_Text .= $safe;
- }
- elsif ($Mode eq 'object') {
- $Object->{_Text} .= $data
- if $data =~ /\S/;
- }
+ $Text .= $safe;
+ $Markedup_Text .= $safe;
+ } elsif ($Mode eq 'object') {
+ $Object->{_Text} .= $data if $data =~ /\S/;
+ }
- return;
- }
+ return;
+ }
- &$closure($xp, sgml_escape($data))
- if (defined $closure);
+ &$closure($xp, sgml_escape($data)) if (defined $closure);
} # End text
sub start_mode {
- my ($xp, $mode) = @_;
+ my ($xp, $mode) = @_;
- if ($mode eq 'pass') {
- $Text = '';
- $Markedup_Text = '';
- }
- elsif ($mode eq 'object') {
- $Object = {_Atts => undef,
- _Text => undef
- };
- }
+ if ($mode eq 'pass') {
+ $Text = '';
+ $Markedup_Text = '';
+ } elsif ($mode eq 'object') {
+ $Object = {
+ _Atts => undef,
+ _Text => undef
+ };
+ }
- $Mode = $mode;
- $Mode_level = $xp->depth;
+ $Mode = $mode;
+ $Mode_level = $xp->depth;
} # End start_mode
sub sgml_escape {
- my ($str) = @_;
+ my ($str) = @_;
- $str =~ s/\&/\&/g;
- $str =~ s/\</g;
- $str =~ s/>/\>/g;
+ $str =~ s/\&/\&/g;
+ $str =~ s/\</g;
+ $str =~ s/>/\>/g;
- $str;
+ $str;
} # End sgml_escape
################################################################
@@ -451,30 +497,8 @@
print "p[$page_nr] ";
if (defined $last_fn) {
- open(PAGE, ">$dir/$last_fn") or die "Couldn't open $last_fn for writing:\n$!";
- if ($page_nr == 2) {
- print PAGE '$sql";
- $result=pg_Exec($conn,fix_sql($sql));
- $lastoid=pg_getlastoid($result);
- $result = pg_Exec($conn,fix_sql("select id from '.$dir.' where oid=$lastoid"));
- $row=pg_fetch_row($result,0);
- $id=$row[0];
-?>';
-
- } else {
- print PAGE php_header($page_nr,@prelast_sql_update);
- } # last_sql_update
-
-
+ open(PAGE, ">$poll/$last_fn") or die "Couldn't open $last_fn for writing:\n$!";
+ print PAGE php_header($page_nr,@prelast_sql_update);
my $next_fn=sprintf("%02d.php",$page_nr);
$last_page=~s/##NEXTPAGE##/$next_fn/;
print PAGE $last_page;
@@ -486,7 +510,7 @@
@sql_update = ();
$last_fn=sprintf("%02d.php",$page_nr);
- $last_page="$html_header $body $html_next $html_footer";
+ $last_page="$html{'header'} $body $html{'submit'} $html{'footer'}";
# delete vars for next page
$page_nr++;
$body="";
@@ -499,18 +523,18 @@
my ($xp, $el, $attref, $ncref) = @_;
- $pitanje_tag="";
+ $question_tag="";
$$ncref = sub {
my ($xp, $text) = @_;
if (defined($text)) {
$body.=x($text);
chomp $text;
- $pitanje_tag .= x($text);
+ $question_tag .= x($text);
} else {
- $pitanje_nr = $pitanje_tag;
- $pitanje_nr =~ s/[^0-9a-zA-Z]//g;
- print "$pitanje_nr ";
+ $question_nr{$q_type} = $question_tag;
+ $question_nr{$q_type} =~ s/[^0-9a-zA-Z]//g;
+ print "$question_nr{$q_type} ";
}
$p_suffix="";
};
@@ -518,19 +542,24 @@
sub hr {
- $body .= "