123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234 |
- require "sequel"
- require "sinatra"
- require 'newrelic_rpm' if production?
- require "slim"
- require "pry" unless production?
- require "envyable"
- require "hashids"
- require "set"
- Envyable.load("config/env.yaml", ENV['RACK_ENV'])
- if ENV['RACK_ENV'] != "test"
- DB = Sequel.connect(:adapter=>'postgres', :host=>ENV['SV_HOST'], :database=>ENV['SV_DB'], :user=>ENV['SV_USER'], :password=>ENV['SV_PASSWORD'], :sslmode => "require")
- end
- class Schueler < Sequel::Model(:schueler)
- one_to_many :sprecher_stimmen, :class => :Sprecher
- one_to_many :schuko_stimmen, :class => :Schuko
- end
- class Lehrer < Sequel::Model(:lehrer)
- one_to_many :lehrer_stimmen, :class => :Verbindungslehrer
- end
- class Info < Sequel::Model(:infos);end
- class Sprecher < Sequel::Model(:sprecher)
- many_to_one :schueler, :class => :Schueler
- end
- class Schuko < Sequel::Model(:schuko)
- many_to_one :schueler, :class => :Schueler
- end
- class Verbindungslehrer < Sequel::Model(:verbindungslehrer)
- many_to_one :lehrer, :key => :lehrer_id, :class => :Lehrer
- end
- class SV < Sinatra::Application
- configure do
- STOP_ZEIT = 'Oct 3, 2017, 18:00'
- enable :sessions
- set :session_secret, (ENV['SV_SESSION_SECRET'] || 'your_secret')
- Slim::Engine.set_options pretty: true
- enable :static
- set :public_folder, File.dirname(__FILE__) + '/public'
- end
- configure :production do
- newrelic_ignore '/ping'
- end
- helpers do
- def ende
- Time.now > time_for(STOP_ZEIT)
- end
- def protected!
- return if authorized?
- headers['WWW-Authenticate'] = 'Basic realm="Bitte anmelden"'
- halt 401, "Not authorized\n"
- end
- def authorized?
- @auth ||= Rack::Auth::Basic::Request.new(request.env)
- @auth.provided? and @auth.basic? and @auth.credentials and @auth.credentials == [ENV['SV_BASIC_AUTH_USER'], ENV['SV_BASIC_AUTH_PASSWORD']]
- end
- def hashids
- hashids = Hashids.new(ENV['SV_SESSION_SECRET'], 5, "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz23456789")
- end
- end
- error do
- 'Es ist ein Fehler aufgetreten. Sollte das nochmal passieren, schreiben Sie mir doch bitte eine eMail: bk@hmt.im'
- end
- before do
- if session[:flash] && session[:flash][0] == 0
- logger.info session[:flash][1]
- end
- end
- get '/' do
- if ende
- redirect to("/ergebnis")
- end
- infos = Info.all
- slim :home, :locals => {:infos => infos}
- end
- get '/ping' do
- [200]
- end
- post "/wahl" do
- if ende
- session[:flash] = [0, "Sie können sich nicht mehr aufstellen lassen, die Wahl hat bereits begonnen"]
- redirect back
- end
- schueler = Schueler.where(:hashid => params[:hashid]).first
- if schueler.update_fields params, [:info, :email, :schuko, :sprecher, :nachname]
- session[:flash] = [1, "Ihre Eingabe wurde gespeichert"]
- else
- session[:flash] = [0, "Es gab einen Fehler beim Speichern"]
- end
- redirect back
- end
- post '/info' do
- protected!
- if DB[:infos].insert(params)
- session[:flash] = [1, "Die Info wurde gespeichert"]
- else
- session[:flash] = [0, "Es gab einen Fehler beim Speichern der Info"]
- end
- redirect to("/")
- end
- get '/info_loeschen/:id' do |id|
- protected!
- Info.where(:id => id).first.delete
- redirect back
- end
- get '/info' do
- protected!
- infos = Info.all
- slim :info, :locals => {:infos => infos}
- end
- get '/ergebnis' do
- protected! if !ende
- sprecher, schuko, lehrer, waehler = [], [], [], 0
- DB.transaction do
- sprecher = Schueler.where(:sprecher => true).all
- schuko = Schueler.where(:schuko => true).all
- lehrer = Lehrer.all
- waehler = Schueler.where(:gewaehlt => true).count
- end
- slim :ergebnis, :locals => {:sprecher => sprecher, :schuko => schuko, :lehrer => lehrer, :waehler => waehler}
- end
- post "/hashcheck" do
- redirect back if params[:stimm_hash].nil?
- arrays = params[:stimm_hash].split("l").map{|a| hashids.decode a}
- sprecher = Sprecher.where(:id => arrays[0])
- schuko = Schuko.where(:id => arrays[1])
- lehrer = Verbindungslehrer.where(:id => arrays[2])
- slim :hashcheck, :locals => {:sprecher => sprecher, :schuko => schuko, :lehrer => lehrer}
- end
- post "/hashid" do
- redirect to("/#{params[:hashid]}")
- end
- get "/:hashid" do
- schueler = Schueler.where(:hashid => params[:hashid]).first
- if schueler.nil?
- halt 404, "Adresse richtig abgetippt? Eventuell geht es mit dem QR-Code am Telefon leichter?"
- end
- lehrer = Lehrer.all
- slim :hashid, :locals => {:schueler => schueler, :lehrer => lehrer}
- end
- post "/:hashid" do
- if ende
- session[:flash] = [0, "Der Wahlzeitraum ist seit 3. Oktober 18:00 Uhr abgelaufen."]
- redirect back
- else
- session[:flash] = [0, "Der Wahlzeitraum beginnt erst am 30. September um 18:00 Uhr."]
- redirect back
- end
- schueler = Schueler.where(:hashid => params[:hashid]).first
- if schueler.nil?
- halt 404, "Hier stimmt etwas nicht mit Ihrem persönlichen Code"
- end
- if schueler.gewaehlt
- session[:flash] = [0, "Sie haben schon gewählt"]
- redirect back
- end
- sprecher, schuko, lehrer = params[:sprecher], params[:schuko], params[:lehrer]
- if sprecher && sprecher.count > 2
- session[:flash] = [0, "Zu viele Sprecher gewählt (max. 2)"]
- redirect back
- elsif schuko && schuko.count > 8
- session[:flash] = [0, "Zu viele Vertreter für die Schulkonferenz gewählt (max. 8)"]
- redirect back
- elsif lehrer && lehrer.count > 2
- session[:flash] = [0, "Zu viele Vertrauenslehrer gewählt (max. 2)"]
- redirect back
- end
- stimm_ids = []
- sprecher_ids, schuko_ids, lehrer_ids =[], [], []
- stimmabgabe = DB.transaction do
- sprecher && sprecher.to_set.each do |s|
- if Schueler[s].sprecher
- sprecher_ids << DB[:sprecher].insert(:schueler_id => s)
- else
- raise Sequel::Rollback
- session[:flash] = [0, "Es wurde ein nichtaufgestellter Sprecher gewählt"]
- redirect back
- end
- end
- schuko && schuko.to_set.each do |s|
- if Schueler[s].schuko
- schuko_ids << DB[:schuko].insert(:schueler_id => s)
- else
- raise Sequel::Rollback
- session[:flash] = [0, "Es wurde ein nichtaufgestellter Vertreter zur Schulkonferenz gewählt"]
- redirect back
- end
- end
- lehrer && lehrer.to_set.each do |l|
- lehrer_ids << DB[:verbindungslehrer].insert(:lehrer_id => l)
- end
- schueler.update(:gewaehlt => true)
- end
- stimm_ids << sprecher_ids << schuko_ids << lehrer_ids
- stimm_hash = stimm_ids.map do |s_id|
- return "" if s_id.nil?
- hashids.encode s_id
- end
- if stimmabgabe
- session[:flash] = [1, "Ihre Wahl wurde gespeichert"]
- session[:stimm_hash] = stimm_hash.join("l")
- else
- session[:flash] = [0, "Es gab einen Fehler bei der Speicherung der Wahlergebnisse"]
- end
- redirect back
- end
- end
|