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

348 lines
8.9 KiB
Ruby
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

require "camping"
require "camping/session"
require "pathname"
require "markaby"
Markaby::Builder.set(:indent, 2)
Camping.goes :Anne
unless defined? PUBLIC_DIR
PUBLIC_DIR = Pathname.new(__FILE__).dirname + "public"
IMAGE_DIR = PUBLIC_DIR + "images"
end
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, :comments
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.comments = @input.comments
user.save
redirect Thanks
end
end
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"
link :rel => "stylesheet", :type => "text/css",
:media => "screen", :href => "/style.css"
end
body do
div.header! do
h1 do
span.left "Enquête ruimtelijke effecten"
img.right :src => R(ImageX, "tuelogo.gif"),
:alt => "[TU/e logo]",
:style => "right: 180px";
img.right :src => R(ImageX, "philipslogo.gif"),
:alt => "[Philips logo]",
:style => "padding: 5px 5px; margin: 13px 0px; background: white;"
end
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 " \
"minuten. Succes!"
p "Doe de test volledig om kans te maken op eerste prijs van een " \
"Philips Living Colors lamp of de tweede prijs van 20 euro."
p " Anne Pijl"
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
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"]
input :type => "submit", :value => "Start de enquête!"
end
end
def vote(image, progress = 0)
h2 "Welk beeld is ruimtelijker?"
form.images! :action => R(Vote), :method => :post do
input :type => "hidden", :name => "image", :value => image
input :type => "image", :src => R(ImageX, "#{image}-l.png"),
:name => "left", :class => "left image"
input :type => "image", :src => R(ImageX, "#{image}-r.png"),
:name => "right", :class => "right image"
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 Philips Living Colors lamp of de prijs van 20 " \
"euro, 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
label "Ik wil meedingen naar de prijs.", :for => "prize"
end
p do
input :type => "checkbox", :name => "results", :checked => true
label "Ik wil de resultaten van het onderzoek ontvangen.", :for => "results"
end
p "Je e-mailadres wordt enkel gebruikt voor de enquête-resultaten en " \
"om je op de hoogte te stellen als je gewonnen hebt."
p do
label "Opmerkingen over dit onderzoek", :for => "comments"
br
textarea :name => "comments", :cols => 80, :rows => 5
end
input :type => "submit", :value => "Verstuur"
end
end
def thanks
h2 "Bedankt!"
p "Je antwoorden zijn verstuurd."
end
end
__END__
/* Style sheet for the Anne Survey Camping app */
html { background: #333; }
body {
margin: 10px auto;
padding: 10px;
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;
}
#header { position: relative; height: 73px; }
#header span { bottom: 10px; }
#images { position: relative; height: 470px; }
.image { border: thin solid #888; }
.left { position: absolute; left: 0px; }
.right { position: absolute; right: 0px; }
#progressbar {
height: 6px;
margin-top: 8px;
background-color: #101073;
}
#progressbar #done {
height: 6px;
background-color: #d6007b;
}
#footer {
padding: 0px 0px 0px 8px;
margin-top: 14px;
border-top: thin #eee solid;
font-size: 69.4%;
}