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

287 lines
7.6 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 "pathname"
require "markaby"
require "camping/session"
Markaby::Builder.set(:indent, 2)
Camping.goes :Anne
IMAGE_DIR = Pathname.new(__FILE__).dirname + "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 + "*.jpg").map { |img| img.basename.to_s }
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 then "left"
elsif @input.right 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/jpeg"
headers["X-Sendfile"] = (IMAGE_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?
# FIXME: check whether email/prize/results have been sent, and redirect to Thanks.
render :finish
end
def post
user = User.find(@state["user"].id)
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
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 "Enquête ruimtelijke effecten"
end
div.content! { self << yield }
div.footer! { "Copyright &copy; 2010 Anne Pijl, Bram Senders, Paul van Tilburg" }
end
end
end
def intro
p "Met deze enquête worden een aantal ruimtelijke effecten onderzocht. " +
"Je krijgt 39 keer een plaatje met twee afbeeldingen te zien. " +
"Je kiest welke afbeelding, de linker of de rechter afbeelding, " +
"je ruimtelijker ervaart. " +
"In welk plaatje zie je meer diepte, welk plaatje 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"
a "Start de enquête!", :href => R(Start)
p "(Jij logt in vanaf #{@env["REMOTE_ADDR"]}.)"
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 enquete"
end
end
def vote(image, progress = 0)
h2 "Welk beeld is ruimtelijker?"
# FIXME: resize all images
# FIXME: split all images in two parts and make it possible two select an image.
img :src => R(ImageX, image), :width => "80%"
form :action => R(Vote), :method => :post do
input :type => "hidden", :name => "image", :value => image
input :type => "submit", :name => "left", :value => "Links"
input :type => "submit", :name => "right", :value => "Rechts"
end
# FIXME: make a nice div with two spans of the following.
p "Woep, je bent al op #{progress}%!"
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
label "Ik wil een vette prijs winnen!", :for => "prize"
end
p do
input :type => "checkbox", :name => "results", :checked => true
label "Ik ben een nieuwsgierig aagje en ik wil het naadje van je kous weten!", :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."
input :type => "submit", :value => "Verstuur"
end
end
def thanks
h2 "Bedankt!"
p "Je antwoorden zijn verstuurd."
end
end
# FIXME: Insert some TU/e styling here
__END__
/* Style sheet for the Anne Survey Camping app */
body {
color: white;
background-color: black;
}