This repository has been archived on 2020-04-11. You can view files and clone it, but cannot push or open issues or pull requests.
anne-survey/anne-survey.rb

332 lines
8.2 KiB
Ruby
Raw Normal View History

require "camping"
require "camping/session"
require "pathname"
require "markaby"
Markaby::Builder.set(:indent, 2)
Camping.goes :Anne
PUBLIC_DIR = Pathname.new(__FILE__).dirname + "public"
IMAGE_DIR = PUBLIC_DIR + "images"
module Anne
include Camping::Session
secret "JeMoeder"
def self.create
Anne::Models.create_schema
end
end
module Anne::Models
class User < Base
end
class Vote < Base
belongs_to :user
end
class BasicFields < V 1.0
def self.up
create_table User.table_name do |t|
t.string :study, :gender, :spaciousness, :email
t.integer :study_year
t.boolean :colorblind, :prize, :results
t.timestamps
end
create_table Vote.table_name do |t|
t.string :image, :choice
t.integer :user_id
end
end
def self.down
drop_table User.table_name
drop_table Vote.table_name
end
end
end
module Anne::Helpers
def next_image
all_images =
Pathname.glob(IMAGE_DIR + "*-l.png").map { |img| img.basename.to_s.sub("-l.png", "") }
all_votes =
Anne::Models::Vote.find(:all,
:conditions => { :user_id => @state["user"].id })
voted_images = all_votes.map { |vote| vote.image }
remaining_images = all_images - voted_images
return nil, 100 if remaining_images.empty?
return remaining_images.sort_by { rand }.first,
100 - (remaining_images.length * 100.0 / all_images.length).ceil
end
end
module Anne::Controllers
class Index
def get
render :intro
end
end
class Start
def get
return redirect Vote if @state["user"]
render :start
end
def post
@state["user"] = User.create(
:study => @input.user_study,
:study_year => @input.user_study_year,
:gender => @input.user_gender,
:colorblind => @input.user_colorblind == "ja",
:spaciousness => @input.user_spaciousness)
redirect Vote
end
end
class Vote
def get
return redirect Index if not @state["user"]
image, progress = next_image
return redirect Finish if image.nil?
render :vote, image, progress
end
def post
choice = if @input["left.x"] then "left"
elsif @input["right.x"] then "right"
else raise "no choice made!"
end
vote = Anne::Models::Vote.create( :user_id => @state["user"].id,
:image => @input.image,
:choice => choice )
redirect Vote
end
end
class ImageX
def get(file)
unless file =~ /\.\./
headers["Content-Type"] = "image/png"
headers["X-Sendfile"] =
(IMAGE_DIR.relative_path_from(PUBLIC_DIR) + file).to_s
else
@status = 403
"You're not allowed to retrieve #{file}!"
end
end
end
class Finish
def get
return redirect Index if not @state["user"]
return redirect Vote unless next_image.first.nil?
return redirect Thanks unless @state["user"].results.nil?
render :finish
end
def post
user = @state["user"]
raise "unknown user" if user.nil?
user.email = @input.email
user.prize = !@input.prize.nil?
user.results = !@input.results.nil?
user.save
redirect Thanks
end
end
2010-05-18 15:42:54 +02:00
class Style < R '/style\.css'
STYLE = File.read(__FILE__).gsub(/.*__END__/m, '')
def get
@headers['Content-Type'] = 'text/css; charset=utf-8'
STYLE
end
end
class Thanks
def get
render :thanks
end
end
end
module Anne::Views
def layout
xhtml_strict do
head do
title "Enquête ruimtelijke effecten"
2010-05-18 15:42:54 +02:00
link :rel => "stylesheet", :type => "text/css",
:media => "screen", :href => "/style.css"
end
body do
div.header! do
h1 "Enquête ruimtelijke effecten"
end
div.content! { self << yield }
div.footer! do
p "Copyright © 2010 Anne Pijl, Bram Senders, Paul van Tilburg"
end
end
end
end
def intro
p "Met deze enquête worden een aantal ruimtelijke effecten onderzocht. " \
"Je krijgt 45 keer twee afbeeldingen te zien. Je kiest welke afbeelding" \
" je ruimtelijker ervaart. In welke afbeelding zie je meer diepte, " \
"welke afbeelding lijkt jou het meest 3-dimensionaal? Als je het niet " \
"weet, klik je op een willekeurige afbeelding. De test duurt 5 á 10 " \
"minuten. Succes!"
p "Doe de test volledig om kans te maken op de prijs."
p " Anne Pijl"
2010-05-31 19:01:51 +02:00
form :action => R(Start), :method => :get do
input :type => "submit", :value => "Ga verder"
end
end
def make_select(label_name, name, options)
p do
label label_name, :for => name
select :name => name do
options.each { |option_str| option option_str }
end
end
end
def start
h2 "Persoonlijke karakteristieken"
p "Graag zou ik ten behoeve van de statistiek het volgende van je willen weten:"
form :action => R(Start), :method => :post do
2010-05-31 19:01:51 +02:00
make_select "Faculteit", "user_study",
["niet van toepassing",
"Biomedische Technologie",
"Bouwkunde",
"Electrical Engineering",
"Industrial Design",
"Scheikundige Technologie",
"Industrial Engineering & Innovation Sciences",
"Technische Natuurkunde",
"Werktuigbouwkunde",
"Wiskunde & Informatica"]
make_select "Studiejaar", "user_study_year",
["niet van toepassing"] + (1998..2009).to_a
make_select "Geslacht", "user_gender", ["", "man", "vrouw"]
make_select "Ben je kleurenblind?", "user_colorblind", ["nee", "ja"]
make_select "Vind je dat je een goed ruimtelijk voorstellingsvermogen hebt?",
"user_spaciousness", ["neutraal", "ja", "nee"]
2010-05-31 13:25:58 +02:00
input :type => "submit", :value => "Start de enquête!"
end
end
def vote(image, progress = 0)
h2 "Welk beeld is ruimtelijker?"
form :action => R(Vote), :method => :post do
input :type => "hidden", :name => "image", :value => image
input.image :type => "image", :src => R(ImageX, "#{image}-l.png"),
:name => "left", :id => "left"
input.image :type => "image", :src => R(ImageX, "#{image}-r.png"),
:name => "right", :id => "right"
2010-05-31 19:01:51 +02:00
end
div.progressbar! do
div.done! :style => "width: #{progress}%" do end
end
end
def finish
h2 "Dank je wel voor het meedoen aan dit onderzoek."
p "Als je geïnteresseerd bent in de resultaten van de enquête of je wilt " \
"meedingen naar de prijs, vul dan hier je e-mailadres in."
form :action => R(Finish), :method => :post do
p do
label "E-mailadres", :for => "email"
input :type => "text", :name => "email"
end
p do
input :type => "checkbox", :name => "prize", :checked => true
2010-05-31 19:01:51 +02:00
label "Ik wil meedingen naar de prijs.", :for => "prize"
end
p do
input :type => "checkbox", :name => "results", :checked => true
2010-05-31 13:25:58 +02:00
label "Ik wil de resultaten van het onderzoek ontvangen.", :for => "results"
end
2010-05-28 16:36:17 +02:00
p "Je e-mailadres wordt enkel gebruikt voor de enquête-resultaten en " \
"om je op de hoogte te stellen als je gewonnen hebt."
input :type => "submit", :value => "Verstuur"
end
end
def thanks
h2 "Bedankt!"
p "Je antwoorden zijn verstuurd."
end
end
2010-05-18 15:42:54 +02:00
__END__
/* Style sheet for the Anne Survey Camping app */
html { background: #333; }
2010-05-31 19:01:51 +02:00
body {
margin: 10px auto;
padding: 12px;
2010-05-31 19:01:51 +02:00
width: 960px;
font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
color: white;
background-color: black;
-webkit-border-radius: 12px;
-moz-border-radius: 12px;
border-radius: 12px;
2010-05-31 19:01:51 +02:00
}
#header {
background: url('image/tuelogo.gif') no-repeat right;
height: 73px;
}
#header h1 { padding-top: 25px; margin-top: 0px; }
2010-05-31 19:01:51 +02:00
.image { border: thin solid #888; }
#left { margin: 0px 15px 0px 0px; }
#right { margin: 0px 0px 0px 15px; }
2010-05-31 19:01:51 +02:00
#progressbar {
height: 6px;
margin-top: 14px;
2010-05-31 19:01:51 +02:00
background-color: #101073;
}
#progressbar #done {
height: inherit;
2010-05-31 19:01:51 +02:00
background-color: #d6007b;
}
#footer {
padding: 0px 0px 0px 8px;
margin-top: 14px;
2010-05-31 19:01:51 +02:00
border-top: thin #eee solid;
font-size: 69.4%;
}