zlp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. #!/usr/bin/perl -w -CSDA
  2. use v5.14;
  3. use strict;
  4. use warnings;
  5. use utf8;
  6. use CGI::Fast qw/header param/;
  7. use CGI::Fast qw/Vars/;
  8. use Data::Dumper;
  9. use Email::Simple;
  10. use Email::Sender::Simple qw/sendmail/;
  11. use File::Slurp qw/append_file/;
  12. use JSON qw/encode_json/;
  13. use YAML::Any qw/Dump LoadFile/;
  14. use Fcntl qw/LOCK_EX LOCK_UN/;
  15. use List::Util qw/sum/;
  16. ##################################################
  17. # Inceput setari
  18. my %events = (
  19. balti => {
  20. date => 'duminică, 29 septembrie 2013',
  21. locul => '',
  22. sala => '',
  23. locuri => 60,
  24. link => 'http://ceata.org/evenimente/zlp-2013-%C8%99i-30-de-ani-de-gnu-%C3%AEn-b%C4%83l%C8%9Bi',
  25. image => '',
  26. },
  27. bucuresti => {
  28. date => 'duminică, 22 septembrie 2013',
  29. locul => '',
  30. sala => '',
  31. locuri => 60,
  32. link => 'http://ceata.org/evenimente/zlp-2013-%C8%99i-30-de-ani-de-gnu-%C3%AEn-bucure%C8%99ti',
  33. image => '',
  34. },
  35. chisinau => {
  36. date => 'sâmbătă, 28 septembrie 2013',
  37. locul => '',
  38. sala => '',
  39. locuri => 60,
  40. link => 'http://ceata.org/evenimente/zlp-2013-%C8%99i-30-de-ani-de-gnu-%C3%AEn-chi%C8%99in%C4%83u',
  41. image => '',
  42. },
  43. cluj => {
  44. date => 'sâmbătă, 28 septembrie 2013',
  45. locul => '',
  46. sala => '',
  47. locuri => 60,
  48. link => 'http://ceata.org/evenimente/zlp-2013-%C8%99i-30-de-ani-de-gnu-%C3%AEn-cluj-napoca',
  49. image => '',
  50. },
  51. constanta => {
  52. date => 'sâmbătă, 21 septembrie 2013',
  53. locul => '',
  54. sala => '',
  55. locuri => 60,
  56. link => 'http://ceata.org/evenimente/zlp-2013-%C8%99i-30-de-ani-de-gnu-%C3%AEn-constan%C8%9Ba',
  57. image => '',
  58. },
  59. valcea => {
  60. date => 'sâmbătă, 28 septembrie 2013',
  61. locul => '',
  62. sala => '',
  63. locuri => 60,
  64. link => 'http://ceata.org/evenimente/zlp-2013-%C8%99i-30-de-ani-de-gnu-%C3%AEn-r%C3%A2mnicu-v%C3%A2lcea',
  65. image => '',
  66. }
  67. );
  68. use constant EMAIL_FROM => 'Ziua Libertății Programelor — Fundația Ceata <zlp@ceata.org>';
  69. use constant ADMIN_EMAIL => 'zlp@ceata.org';
  70. use constant DATAFILE => 'date.yml';
  71. # Sfarsit setari
  72. ##################################################
  73. open LOCK, '<', DATAFILE;
  74. sub nr_participanti { my $oras = shift; sum 0, map { $_->{numar} } grep { $_->{oras} eq $oras } @_ }
  75. sub append{
  76. flock LOCK, LOCK_EX;
  77. eval {
  78. my $prenume = param('prenume') or die 'Nu ați completat prenumele';
  79. utf8::decode($prenume);
  80. my $nume = param('nume') // '';
  81. utf8::decode($nume);
  82. my $adresa = param('adresa') or die 'Nu ați completat adresa de poștă electronică';
  83. utf8::decode($adresa);
  84. my $oras = param('oras') or die 'Nu ați ales orașul cu evenimentul';
  85. die 'Ziua Libertății Programelor nu se ține în orașul ales' unless exists $events{$oras};
  86. my $numar = int param('numar') or die 'Nu ați ales numărul de participanți';
  87. die 'Numărul de participanți trebuie să fie între 1 și 5' unless $numar >= 1 && $numar <= 5;
  88. my $captcha = param('captcha') or die 'Nu ați completat anul de lansare al proiectului GNU';
  89. die 'Ați completat greșit anul de lansare al proiectului GNU' unless $captcha == 83;
  90. my $referinta = param('referinta') || param('referinta2');
  91. my $anunturi = param('anunturi') or 0;
  92. my @db = grep { $_->{oras} eq $oras } LoadFile DATAFILE;
  93. die 'Această adresă de poștă electronică este deja folosită' if grep { $_->{adresa} eq $adresa } @db;
  94. my $participanti = nr_participanti $oras, @db;
  95. die 'Nu sunt suficiente locuri libere' if $events{$oras}{locuri} < $participanti + $numar;
  96. my %entry = (
  97. prenume => $prenume,
  98. nume => $nume,
  99. adresa => $adresa,
  100. oras => $oras,
  101. numar => $numar,
  102. referinta => $referinta,
  103. anunturi => defined($anunturi) && $anunturi ? 1 : 0,
  104. );
  105. my $success_email = Email::Simple->create(
  106. header => [
  107. To => "$nume <$adresa>",
  108. Subject => 'Confirmarea de înscriere la Ziua Libertății Programelor',
  109. From => EMAIL_FROM,
  110. ],
  111. body => "Aceasta este o confirmare automată de înscriere la unul din evenimentele organizate de Fundația Ceata de Ziua Libertății Programelor și aniversarea a 30 de ani de GNU.\n\n" . Dump \%entry,
  112. );
  113. sendmail $success_email, { to => [$adresa, ADMIN_EMAIL]};
  114. append_file DATAFILE, Dump \%entry;
  115. };
  116. flock LOCK, LOCK_UN;
  117. if ($@) {
  118. my $eroare = $@ =~ s/ at .*//r;
  119. my $error_email = Email::Simple->create(
  120. header => [
  121. To => "Administrator <" . ADMIN_EMAIL . ">",
  122. Subject => 'Eroare de înscriere la Ziua Libertății Programelor',
  123. From => EMAIL_FROM,
  124. ],
  125. body => "Eroare: $eroare\n" . Dumper scalar Vars,
  126. );
  127. sendmail $error_email;
  128. print header('text/html; charset=utf-8', '500 Internal Server Error');
  129. print $eroare;
  130. } else {
  131. print header('text/html; charset=utf-8');
  132. print 'Ați fost înscris cu succes';
  133. }
  134. }
  135. sub info{
  136. my $oras = param('oras');
  137. eval {
  138. die 'Eveniment inexistent' unless defined $oras && exists $events{$oras};
  139. my %out = %{$events{$oras}};
  140. my $participanti = nr_participanti $oras, LoadFile DATAFILE;
  141. $out{locuri} = $out{locuri} - $participanti;
  142. print header('application/json; charset=utf-8');
  143. print encode_json \%out;
  144. };
  145. if ($@) {
  146. $@ =~ s/ at .*//;
  147. print header('text/html; charset=utf-8', '500 Internal Server Error');
  148. print $@;
  149. }
  150. }
  151. sub view{
  152. my $oras = param('oras');
  153. unless (exists $events{$oras}) {
  154. print header('text/html; charset=utf-8', '500 Internal Server Error');
  155. print 'Acest eveniment nu există';
  156. return;
  157. }
  158. my @db = grep { $_->{oras} eq $oras } LoadFile DATAFILE;
  159. my $participanti = nr_participanti $oras, @db;
  160. print header('text/html; charset=utf-8');
  161. print "Sunt $participanti participanți înscriși<p>";
  162. # for my $p(@db) {
  163. # print "Nume: $p->{nume}<br>Prenume: $p->{prenume}<br>Adresa: $p->{adresa}<br>Oras: $p->{oras}<br>Numar: $p->{numar}<br>Anunturi: $p->{anunturi}<p>";
  164. # }
  165. }
  166. while (CGI::Fast->new) {
  167. my $op = param 'op' // '';
  168. append if $op eq 'append';
  169. info if $op eq 'info';
  170. view if $op eq 'view';
  171. }
  172. 1;
  173. __END__
  174. =head1 NAME
  175. zlp - Formular de înscriere la Ziua Libertății Programelor
  176. =head1 AUTHOR
  177. Marius Gavrilescu E<lt>marius@ieval.roE<gt>
  178. =head1 COPYRIGHT AND LICENSE
  179. Copyright (C) 2013 Fundația Ceata
  180. This program is free software: you can redistribute it and/or modify
  181. it under the terms of the GNU Affero General Public License as published by
  182. the Free Software Foundation, either version 3 of the License, or
  183. (at your option) any later version.
  184. This program is distributed in the hope that it will be useful,
  185. but WITHOUT ANY WARRANTY; without even the implied warranty of
  186. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  187. GNU Affero General Public License for more details.
  188. You should have received a copy of the GNU Affero General Public License
  189. along with this program. If not, see <http://www.gnu.org/licenses/>.
  190. =cut