Für Ihren PINGO-Account wurde soeben ein Link zum Zurücksetzen des Kennworts angefordert. Klicken Sie den folgenden Link an, um ein neues PINGO-Kennwort zu vergeben:
<%= link_to 'Delete', survey, confirm: 'Do you really want to delete ' + survey.name + '?', method: :delete %>
31 |
32 | <% end %>
33 |
34 | <% else %>
35 |
36 | <% end %>
37 |
38 |
39 |
40 | <%= link_to '» Create a new survey', new_survey_path %>
41 |
42 | <% if current_user.admin? %>
43 |
44 |
45 |
ADMIN:
46 | <% if(params[:all]) %>
47 | <%= link_to '» List only your surveys', surveys_path %>
48 | <% else %>
49 | As an admin you can <%= link_to '» View all surveys in the system', surveys_path(:all => "yes") %>
50 | <% end %>
51 |
52 |
53 | <% end %>
--------------------------------------------------------------------------------
/app/views/surveys/new.html.erb:
--------------------------------------------------------------------------------
1 |
30 |
31 |
36 |
--------------------------------------------------------------------------------
/app/views/user_mailer/welcome.text.erb:
--------------------------------------------------------------------------------
1 | <%= @name %>, <%= t ".header" %>
2 |
3 | <%= t ".intro_and_tour" %>
4 |
5 | <%= t ".start_tour_button" %>:
6 | http://pingo.upb.de/?tour=true
7 |
8 | <% if I18n.locale == :de %>
9 | Das Handbuch mit ausführlicheren Anweisungen finden Sie unter:
10 | http://pingo.upb.de/tutorial/tutorial.html
11 | <% end %>
12 |
13 | <%= t ".more_info_text" %>
14 |
15 | <%= t ".more_info_button" %>:
16 | http://www.upb.de/pingo
17 |
18 | Blog:
19 | http://blogs.upb.de/pingo
20 |
21 | <%= t ".videos" %>:
22 | http://www.youtube.com/channel/UCoA4vCzvqmc3oRLeEpGfayQ
23 |
24 | <%= t ".contact_text "%>: pingo-support@upb.de
25 |
26 |
27 | Imprint/Impressum:
28 | PINGO - Peer Instruction for very large groups (Fak. Wiwi)
29 | Universitaet Paderborn, Warburger Str. 100, 33098 Paderborn, Germany.
--------------------------------------------------------------------------------
/app/views/users/show.html.erb:
--------------------------------------------------------------------------------
1 |
Users#show
2 |
Find me in app/views/users/show.html.erb
3 |
4 |
User: <%= @user.name %>
5 |
--------------------------------------------------------------------------------
/app/workers/countdown_worker.rb:
--------------------------------------------------------------------------------
1 | if ENV["PLATFORM"] == "heroku"
2 | class CountdownWorker < SimpleWorker::Base
3 | #used for Heroku, where we can launce SimpleWorkers in the cloud
4 |
5 | merge_gem "redis"
6 | merge_gem "juggernaut"
7 | merge_gem "mongo"
8 | merge_gem "mongoid", :require => "mongoid"
9 | merge_gem "mongoid_token"
10 |
11 | merge "../models/survey.rb"
12 | merge "../models/option.rb"
13 | merge "../models/event.rb"
14 |
15 | attr_accessor :sid, :url, :mongodb_settings
16 |
17 | # The run method is what SimpleWorker calls to run your worker
18 | def run
19 | init_mongodb
20 | iterations = 0
21 |
22 | Juggernaut.url = @url
23 |
24 | survey = Survey.find(@sid).worker_fields.service
25 |
26 | if survey.running? && survey.ends
27 |
28 | loop {
29 | iterations += 1
30 | Juggernaut.publish("s"+survey.id.to_s,
31 | {:type => "countdown", :payload => survey.time_left(true), "iteration" => iterations}
32 | )
33 | if iterations % 5 == 0
34 | #break #################
35 | survey.reload
36 | Juggernaut.publish("v"+survey.id.to_s,
37 | {:type => "voter_count", :payload => survey.total_votes, "timestamp" => Time.new}
38 | )
39 | break unless survey.running? && survey.ends
40 | end
41 | sleep 0.5
42 | }
43 |
44 | end
45 |
46 | end
47 |
48 | def init_mongodb
49 | Mongoid.configure do |config|
50 | config.from_hash(@mongodb_settings)
51 | end
52 | end
53 |
54 | end
55 | end
--------------------------------------------------------------------------------
/app/workers/resque_countdown_worker.rb:
--------------------------------------------------------------------------------
1 | if ENV["PLATFORM"] != "heroku"
2 | class ResqueCountdownWorker
3 | #used for own servers, i. e. at maxcluster
4 |
5 | @queue = :timer_workers
6 |
7 | def self.perform(sid, url)
8 | iterations = 0
9 |
10 | Juggernaut.url = url
11 |
12 | survey = Survey.find(sid).service
13 |
14 | if survey.running? && survey.ends
15 |
16 | loop {
17 | iterations += 1
18 | Juggernaut.publish("s"+survey.id.to_s,
19 | {:type => "countdown", :payload => survey.time_left(true), "iteration" => iterations}
20 | )
21 | if iterations % 5 == 0
22 | #break #################
23 | survey.reload
24 | Juggernaut.publish("v"+survey.id.to_s,
25 | {:type => "voter_count", :payload => survey.total_votes, "timestamp" => Time.new}
26 | )
27 | break unless survey.running? && survey.ends
28 | end
29 | sleep 0.5
30 | }
31 |
32 | end
33 |
34 | end
35 |
36 | end
37 | end
--------------------------------------------------------------------------------
/config.ru:
--------------------------------------------------------------------------------
1 | # This file is used by Rack-based servers to start the application.
2 |
3 | require ::File.expand_path('../config/environment', __FILE__)
4 |
5 | if Rails.env.production? || Rails.env.staging?
6 | rescue_exception = Proc.new { |env, exception| [503, {}, "We're really sorry, something did not work as expected. Please go back and try again later. Check http://status.pingo-projekt.de for a current system status; contact pingo-support@upb.de if error persists (and tell them 'it's the fibers'). Thanks!"] }
7 | use Rack::FiberPool, :rescue_exception => rescue_exception, :size => 1000
8 | puts "using FiberPool"
9 | end
10 |
11 | run Eclickr::Application
12 |
--------------------------------------------------------------------------------
/config/boot.rb:
--------------------------------------------------------------------------------
1 | require 'rubygems'
2 |
3 | # Set up gems listed in the Gemfile.
4 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
5 |
6 | require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])
7 |
--------------------------------------------------------------------------------
/config/cucumber.yml:
--------------------------------------------------------------------------------
1 | <%
2 | rerun = File.file?('rerun.txt') ? IO.read('rerun.txt') : ""
3 | rerun_opts = rerun.to_s.strip.empty? ? "--format #{ENV['CUCUMBER_FORMAT'] || 'progress'} features" : "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} #{rerun}"
4 | std_opts = "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} --strict --tags ~@wip"
5 | %>
6 | default: <%= std_opts %> features
7 | wip: --tags @wip:3 --wip features
8 | rerun: <%= rerun_opts %> --format rerun --out rerun.txt --strict --tags ~@wip
9 |
--------------------------------------------------------------------------------
/config/environment.rb:
--------------------------------------------------------------------------------
1 | # Load the rails application
2 | require File.expand_path('../application', __FILE__)
3 |
4 | # Initialize the rails application
5 | Eclickr::Application.initialize!
6 |
7 | # https://github.com/logentries/le_ruby
8 | if ENV["LOGENTRIES_TOKEN"] && ENV["LOGENTRIES_TOKEN"] != "" && defined?(Le)
9 | Rails.logger = Le.new(ENV["LOGENTRIES_TOKEN"])
10 | end
--------------------------------------------------------------------------------
/config/environments/development.rb:
--------------------------------------------------------------------------------
1 | Eclickr::Application.configure do
2 | # Settings specified here will take precedence over those in config/application.rb
3 |
4 | # In the development environment your application's code is reloaded on
5 | # every request. This slows down response time but is perfect for development
6 | # since you don't have to restart the web server when you make code changes.
7 | config.cache_classes = false
8 |
9 | # Log error messages when you accidentally call methods on nil.
10 | config.whiny_nils = true
11 |
12 | # Show full error reports and disable caching
13 | config.consider_all_requests_local = true
14 | config.action_controller.perform_caching = false
15 |
16 | # Don't care if the mailer can't send
17 | config.action_mailer.raise_delivery_errors = false
18 |
19 | # Print deprecation notices to the Rails logger
20 | config.active_support.deprecation = :log
21 |
22 | # Only use best-standards-support built into browsers
23 | config.action_dispatch.best_standards_support = :builtin
24 |
25 | # Do not compress assets
26 | config.assets.compress = false
27 |
28 | # Expands the lines which load the assets
29 | config.assets.debug = true
30 |
31 | config.action_mailer.default_url_options = { :host => 'localhost:3000' }
32 |
33 | # Raise exception on mass assignment protection for Active Record models
34 | # config.active_record.mass_assignment_sanitizer = :strict
35 |
36 | # Log the query plan for queries taking more than this (works
37 | # with SQLite, MySQL, and PostgreSQL)
38 | # config.active_record.auto_explain_threshold_in_seconds = 0.5
39 | end
40 |
41 |
42 | # Juggernaut Server
43 | ENV["USE_JUGGERNAUT"] = "false"
44 | ENV["JUGGERNAUT_HOST"] = "localhost"
45 | ENV["JUGGERNAUT_PORT"] = "8080"
46 |
47 | # Domain without slash
48 | ENV["URL_PREFIX"] = "http://localhost:3000"
49 |
50 | ENV["ANALYTICS"] = "false"
51 |
52 | # Pretty print for console output
53 | require "pp"
54 | def pprint(arg)
55 | pp arg
56 | end
57 |
58 | # Git version display in logo
59 | begin
60 | repo = Grit::Repo.new(Rails.root + '.git')
61 | last_commit = repo.commits.first
62 | ENV['COMMIT_HASH'] = last_commit.id+"/"+last_commit.authored_date.to_s
63 | rescue
64 | ENV['COMMIT_HASH'] = 'unknown'
65 | end
--------------------------------------------------------------------------------
/config/errorapp_notifier.yml:
--------------------------------------------------------------------------------
1 | # Place this file into config folder of your RailsRoot
2 | api-key: ''
3 | development:
4 | enabled: false
5 | production:
6 | enabled: true
7 | staging:
8 | api-key: '' # You can change if you have create different project
9 | enabled: true
10 |
--------------------------------------------------------------------------------
/config/initializers/backtrace_silencers.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces.
4 | # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ }
5 |
6 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code.
7 | # Rails.backtrace_cleaner.remove_silencers!
8 |
--------------------------------------------------------------------------------
/config/initializers/inflections.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Add new inflection rules using the following format
4 | # (all these examples are active by default):
5 | # ActiveSupport::Inflector.inflections do |inflect|
6 | # inflect.plural /^(ox)$/i, '\1en'
7 | # inflect.singular /^(ox)en/i, '\1'
8 | # inflect.irregular 'person', 'people'
9 | # inflect.uncountable %w( fish sheep )
10 | # end
11 |
--------------------------------------------------------------------------------
/config/initializers/juggernaut.rb:
--------------------------------------------------------------------------------
1 | Juggernaut.options = {driver: :synchrony} if (Rails.env.production? || Rails.env.staging? ) && !$rails_rake_task
2 | Juggernaut.url = ENV["REDISTOGO_URL"]
--------------------------------------------------------------------------------
/config/initializers/maktoub.rb:
--------------------------------------------------------------------------------
1 | Maktoub.from = "" # the email the newsletter is sent from
2 | # Maktoub.twitter_url = "https://twitter.com/" # your twitter page
3 | # Maktoub.facebook_url = "https://www.facebook.com/" # your facebook oage
4 | Maktoub.subscription_preferences_url = "https://" #subscribers management url
5 | Maktoub.logo = "logo.png" # path to your logo asset
6 | Maktoub.home_domain = "" # your domain
7 | Maktoub.app_name = "PINGO" # your app name
8 | # Maktoub.unsubscribe_method = "unsubscribe" # method to call from unsubscribe link (doesn't include link by default)
9 |
10 | # pass a block to subscribers_extractor that returns an object that reponds to :name and :email
11 | # (fields can be configured as shown below)
12 |
13 | # require "ostruct"
14 | Maktoub.subscribers_extractor do
15 | User.where(newsletter: true).to_a
16 | end
17 |
18 | # uncomment lines below to change subscriber fields that contain email and
19 | # Maktoub.email_field = :address
20 | # Maktoub.name_field = :nickname
--------------------------------------------------------------------------------
/config/initializers/mime_types.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Add new mime types for use in respond_to blocks:
4 | # Mime::Type.register "text/richtext", :rtf
5 | # Mime::Type.register_alias "text/html", :iphone
6 |
--------------------------------------------------------------------------------
/config/initializers/mongoid.rb:
--------------------------------------------------------------------------------
1 | if Rails.env.production?
2 | Mongoid.add_language("de")
3 | Mongoid.add_language("es")
4 | end
--------------------------------------------------------------------------------
/config/initializers/obscenity.rb:
--------------------------------------------------------------------------------
1 | Obscenity.configure do |config|
2 | config.blacklist = :international
3 | end
--------------------------------------------------------------------------------
/config/initializers/rack_middleware.rb:
--------------------------------------------------------------------------------
1 | require 'rack/contrib' # https://github.com/rack/rack-contrib
2 |
3 | module Eclickr
4 | class Application < Rails::Application
5 | # Detects the client locale using the Accept-Language request header and sets a rack.locale variable in the environment.
6 | config.middleware.use 'Rack::Locale'
7 | end
8 | end
--------------------------------------------------------------------------------
/config/initializers/redis.rb:
--------------------------------------------------------------------------------
1 | if !(ENV["USE_JUGGERNAUT"] == "false") && !(ENV["RAILS_GROUPS"] == "assets") && !$rails_rake_task
2 | if Rails.env.production? || Rails.env.staging?
3 | PINGO_REDIS = Redis.new(url: ENV["REDISTOGO_URL"], driver: :synchrony)
4 | else
5 | PINGO_REDIS = Redis.new(url: ENV["REDISTOGO_URL"])
6 | end
7 | end
--------------------------------------------------------------------------------
/config/initializers/requires.rb:
--------------------------------------------------------------------------------
1 | require 'ipaddr'
2 | require 'bigdecimal'
3 | require "statistics"
4 | require "cluster"
5 | require "clusterer"
6 | require "csv"
7 |
--------------------------------------------------------------------------------
/config/initializers/secret_token.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Your secret key for verifying the integrity of signed cookies.
4 | # If you change this key, all old signed cookies will become invalid!
5 | # Make sure the secret is at least 30 characters and all random,
6 | # no regular words or you'll be exposed to dictionary attacks.
7 | Eclickr::Application.config.secret_token = ENV["PINGO_RAILS_SECRET_TOKEN"] || ''
8 |
--------------------------------------------------------------------------------
/config/initializers/session_store.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | Eclickr::Application.config.session_store :cookie_store, :key => '_eclickr_session'
4 |
5 | # Use the database for sessions instead of the cookie-based default,
6 | # which shouldn't be used to store highly confidential information
7 | # (create the session table with "rails generate session_migration")
8 | # Eclickr::Application.config.session_store :active_record_store
9 |
--------------------------------------------------------------------------------
/config/initializers/simple_worker.rb:
--------------------------------------------------------------------------------
1 | # the workers need to connect to the DB in order to return the accurate time
2 | filename = File.join(File.dirname(__FILE__), "..", "mongoid.yml")
3 | DATABASE = YAML.load(ERB.new(File.new(filename).read).result)
4 |
5 | if ENV["PLATTFORM"] == "heroku"
6 | SimpleWorker.configure do |config|
7 | config.token = ENV['SIMPLE_WORKER_TOKEN']
8 | config.project_id = ENV['SIMPLE_WORKER_PROJECT_ID']
9 | config.global_attributes[:mongodb_settings] = DATABASE[Rails.env]
10 | end
11 | elsif (Rails.env.production? || Rails.env.staging?) && ENV["PLATTFORM"] != "heroku" && ENV["RAILS_GROUPS"] != "assets"
12 | uri = URI.parse(ENV["REDISTOGO_URL"])
13 | require "resque"
14 | Resque.redis = Redis.new(:host => uri.host, :port => uri.port, :password => uri.password)
15 | end
--------------------------------------------------------------------------------
/config/initializers/smtp.rb:
--------------------------------------------------------------------------------
1 | if Rails.env.production?
2 | ActionMailer::Base.smtp_settings = {
3 | }
4 | elsif Rails.env.staging?
5 | ActionMailer::Base.smtp_settings = {
6 | }
7 | end
--------------------------------------------------------------------------------
/config/initializers/synchrony.rb:
--------------------------------------------------------------------------------
1 | require "em-synchrony"
2 | require "em-synchrony/mongoid"
3 | require "em-synchrony/em-http"
4 |
5 | require 'rss'
--------------------------------------------------------------------------------
/config/initializers/uuid.rb:
--------------------------------------------------------------------------------
1 | @@uuid = UUID.new
--------------------------------------------------------------------------------
/config/initializers/wrap_parameters.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 | #
3 | # This file contains settings for ActionController::ParamsWrapper which
4 | # is enabled by default.
5 |
6 | # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array.
7 | ActiveSupport.on_load(:action_controller) do
8 | wrap_parameters :format => [:json]
9 | end
10 |
11 |
--------------------------------------------------------------------------------
/config/locales/models/questions.de.yml:
--------------------------------------------------------------------------------
1 | de:
2 | mongoid:
3 | models:
4 | question: Frage
5 | attributes:
6 | question:
7 | question_options: "Antwortmöglichkeit(en)"
8 | name: Frage
9 | formtastic:
10 | labels:
11 | question:
12 | name: Frage
--------------------------------------------------------------------------------
/config/locales/models/questions.en.yml:
--------------------------------------------------------------------------------
1 | en:
2 | mongoid:
3 | attributes:
4 | question:
5 | name: question
--------------------------------------------------------------------------------
/config/locales/models/survey.de.yml:
--------------------------------------------------------------------------------
1 | de:
2 | mongoid:
3 | models:
4 | survey: Umfrage
5 | attributes:
6 | survey:
7 | options: "Antwortoption(en)"
--------------------------------------------------------------------------------
/config/locales/views/home.de.yml:
--------------------------------------------------------------------------------
1 | # nothing
2 | de:
3 | home:
4 | index:
5 | participate: "Teilnehmen"
6 | enter_access: "Bitte geben Sie die Zugangsnummer ein"
7 | open_vote: "Auf geht's zur Abstimmung!"
--------------------------------------------------------------------------------
/config/locales/views/home.en.yml:
--------------------------------------------------------------------------------
1 | # nothing
2 | en:
3 | home:
4 | index:
5 | participate: "Participate"
6 | enter_access: "Please enter the access number"
7 | open_vote: "Rock the vote!"
--------------------------------------------------------------------------------
/config/locales/views/invitations.de.yml:
--------------------------------------------------------------------------------
1 | de:
2 | invitations:
3 | new:
4 | header: Freunde und Kollegen zu PINGO einladen
5 | placeholder: "Mailadresse des Empfängers"
6 | invite: "Einladen!"
--------------------------------------------------------------------------------
/config/locales/views/invitations.en.yml:
--------------------------------------------------------------------------------
1 | en:
2 | invitations:
3 | new:
4 | header: Invite colleagues and friends to PINGO
5 | placeholder: "Recipient's mail address"
6 | invite: "Invite!"
--------------------------------------------------------------------------------
/config/locales/views/mailers.en.yml:
--------------------------------------------------------------------------------
1 | en:
2 | user_mailer:
3 | welcome:
4 | subject: "Welcome to PINGO"
5 | header: "welcome to PINGO!"
6 | intro_and_tour: "You successfully signed up and are ready to use PINGO. We recommend to spend a few minutes taking our interactive tour, which will introduce you to the most important PINGO features"
7 | start_tour_button: "Start tour"
8 | more_info_text: "PINGO is an acronym for 'Peer Instruction for very large groups' is the web-based classroom response system that has been developed at the University of Paderborn. You can find out more about our project online. We also blog about PINGO (currently in German, though)."
9 | more_info_button: "Find out more about PINGO"
10 | videos: "To explain the Peer Instruction concept in general as well as the idealtype Peer Discussion, we have developed some video tutorials"
11 | contact_text: "Please do not hesitate to contact us, if you got further questions concerning PINGO"
12 | invite_mailer:
13 | invite_email:
14 | subject: "Invitation to PINGO"
15 | intro_text: 'PINGO PINGO is a web-based classroom response system that has been developed at the University of Paderborn. The acronym PINGO stands for “Peer Instruction for very large groups”. PINGO is designed to encourage active student participation – especially in large lectures.'
16 | subheader: "You've been invited by %{name} to join PINGO."
17 | sign_up_now: 'Sign up now!'
18 | wwbm_text: 'Comparable to the ask-the-audience life-line in “Who Wants to Be a Millionaire?”, students can actively participate in the lecture by answering questions posed by the instructor using their Internet-enabled devices (smartphones, tablets, laptops etc.).'
19 | features: 'PINGO is offered as a hosted service free of charge to universities worldwide.'
20 | more_info: More information about PINGO
21 | footer: "You've been invited by %{name}. You have not been subscribed to a newsletter nor will your mail address be saved."
22 |
23 |
24 |
--------------------------------------------------------------------------------
/config/mongoid.yml:
--------------------------------------------------------------------------------
1 | development:
2 | host: localhost
3 | database: eclickr_development
4 |
5 | test:
6 | uri: <%= ENV['MONGOTEST_URL'] %>
7 |
8 | staging:
9 | uri: <%= ENV['MONGOHQ_URL'] %>
10 | logger: false
11 |
12 | # set these environment variables on your prod server
13 | production:
14 | uri: <%= ENV['MONGOHQ_URL'] %>
15 | logger: false
--------------------------------------------------------------------------------
/config/newrelic.yml:
--------------------------------------------------------------------------------
1 | ---
2 | production:
3 | error_collector:
4 | capture_source: true
5 | enabled: true
6 | ignore_errors: ActionController::RoutingError
7 | apdex_t: 0.5
8 | ssl: false
9 | monitor_mode: true
10 | license_key:
11 | developer_mode: false
12 | app_name: eclickr-mc
13 | transaction_tracer:
14 | record_sql: obfuscated
15 | enabled: true
16 | stack_trace_threshold: 0.5
17 | transaction_threshold: apdex_f
18 | capture_params: false
19 | log_level: info
--------------------------------------------------------------------------------
/db/seeds.rb:
--------------------------------------------------------------------------------
1 | # This file should contain all the record creation needed to seed the database with its default values.
2 | # The data can then be loaded with the rake db:seed (or created alongside the db with db:setup).
3 | #
4 | # Examples:
5 | #
6 | # cities = City.create([{ :name => 'Chicago' }, { :name => 'Copenhagen' }])
7 | # Mayor.create(:name => 'Emanuel', :city => cities.first)
8 | require 'securerandom'
9 |
10 | puts 'EMPTY THE MONGODB DATABASE'
11 | Mongoid.master.collections.reject { |c| c.name =~ /^system/}.each(&:drop)
12 | puts 'SETTING UP DEFAULT USER LOGIN'
13 | random_password = SecureRandom.urlsafe_base64(6)
14 | user = User.create! :name => 'admin', :email => 'user@example.com', :password => random_password,
15 | :password_confirmation => random_password, :admin => true,
16 | :first_name => 'Max', :last_name => 'Mustermann',
17 | :organization => 'Meine Uni',
18 | :faculty => 'Meine Fakultaet',
19 | :chair => 'PINGO'
20 | puts 'user@example.com created with password: ' << random_password
--------------------------------------------------------------------------------
/doc/README_FOR_APP:
--------------------------------------------------------------------------------
1 | Use this README file to introduce your application and point to useful places in the API for learning more.
2 | Run "rake doc:app" to generate API documentation for your models, controllers, helpers, and libraries.
3 |
--------------------------------------------------------------------------------
/features/step_definitions/event_steps.rb:
--------------------------------------------------------------------------------
1 | Given /^there exists an event$/ do
2 | @event = FactoryGirl.create(:event, user: @user)
3 | end
4 |
5 | Given /^there exists an event with the name "(.*?)"$/ do |name|
6 | @event = FactoryGirl.create(:event, name: name, user: @user)
7 | end
8 |
9 | When /^I add the first question in the list$/ do
10 | page.find(:css, ".add_question_link").click
11 | end
--------------------------------------------------------------------------------
/features/step_definitions/questions_steps.rb:
--------------------------------------------------------------------------------
1 | Given /^there exists a single choice question with the name "(.*?)" for "(.*?)"$/ do |name, user|
2 | @question = Question.create!(name: name, type: "single", user: get_user_by_mail(user))
3 | end
4 |
5 | Given /^there exists a multiple choice question with the name "(.*?)" for "(.*?)"$/ do |name, user|
6 | @question = Question.create!(name: name, type: "multi", user: get_user_by_mail(user))
7 | end
8 |
9 | Given /^there exists a public question with the name "(.*?)"$/ do |name|
10 | @question = Question.create!(name: name, type:"multi", public: true)
11 | end
12 |
13 | When /^I create the single choice question "(.*?)" with the answers "(.*?)"$/ do |name, answers|
14 | @question = Question.create!(name: name, type: "single", user: @user)
15 | populate_question_with_answers!(@question, answers)
16 | end
17 |
18 | When /^I create the multiple choice question "(.*?)" with the answers "(.*?)"$/ do |name, answers|
19 | @question = Question.create!(name: name, type: "multiple", user: @user)
20 | populate_question_with_answers!(@question, answers)
21 | end
22 |
23 | Given /^I tag "(.*?)" with "(.*?)"$/ do |name, tag|
24 | q = Question.where(name: name).first
25 | q.tags = tag
26 | q.save!
27 | end
28 |
29 | def get_user_by_mail(user) # Model.find_by_ATTR will be deprecated in Rails 4
30 | user_obj = User.where(email: user).first
31 | raise "E-Mail '#{user}' not found (while creating a user's question)" if user_obj.nil?
32 | user_obj
33 | end
34 |
35 | def populate_question_with_answers!(q, answers, delimiter = ", ")
36 | answers.split(delimiter).each do |answer|
37 | q.question_options.create!(name: answer)
38 | end
39 | end
40 |
--------------------------------------------------------------------------------
/features/step_definitions/survey_steps.rb:
--------------------------------------------------------------------------------
1 | Given /^a survey exists$/ do
2 | if @event
3 | @survey = FactoryGirl.create(:survey, event: @event)
4 | else
5 | @survey = FactoryGirl.create(:survey)
6 | end
7 | end
8 |
9 | Given /^a survey with some options exists$/ do
10 | if @event
11 | @survey = FactoryGirl.create(:survey_with_options, event: @event)
12 | else
13 | @survey = FactoryGirl.create(:survey_with_options)
14 | end
15 | end
16 |
17 | Given /^a text survey exists$/ do
18 | if @event
19 | @survey = FactoryGirl.create(:text_survey, event: @event)
20 | else
21 | @survey = FactoryGirl.create(:text_survey)
22 | end
23 | end
24 |
25 | Given /^a numeric survey exists$/ do
26 | if @event
27 | @survey = FactoryGirl.create(:numeric_survey, event: @event)
28 | else
29 | @survey = FactoryGirl.create(:numeric_survey)
30 | end
31 | end
32 |
33 | Given /^the survey is running$/ do
34 | if @survey
35 | @survey.service.start!
36 | else
37 | raise "No current @survey obj found"
38 | end
39 | end
--------------------------------------------------------------------------------
/features/step_definitions/voting_steps.rb:
--------------------------------------------------------------------------------
1 | Given /^I fill in "(.*?)" with the event's number$/ do |field|
2 | fill_in(field, :with => @event.token)
3 | end
4 |
5 | When /^I select the first option$/ do
6 | page.find(:css, "input[name='option']").click
7 | end
--------------------------------------------------------------------------------
/features/support/paths.rb:
--------------------------------------------------------------------------------
1 | module NavigationHelpers
2 | # Maps a name to a path. Used by the
3 | #
4 | # When /^I go to (.+)$/ do |page_name|
5 | #
6 | # step definition in web_steps.rb
7 | #
8 | def path_to(page_name)
9 | case page_name
10 |
11 | when /the home\s?page/
12 | '/'
13 |
14 | when /the sign up page/
15 | '/users/sign_up'
16 |
17 | when /the sign in page/
18 | '/users/sign_in'
19 |
20 | when /the event's page/
21 | event_path(@event)
22 |
23 | when /the event's edit page/
24 | edit_event_path(@event)
25 |
26 | when /the question's page/
27 | question_path(@question)
28 |
29 |
30 | # Add more mappings here.
31 | # Here is an example that pulls values out of the Regexp:
32 | #
33 | # when /^(.*)'s profile page$/i
34 | # user_profile_path(User.find_by_login($1))
35 |
36 | else
37 | begin
38 | page_name =~ /the (.*) page/
39 | path_components = $1.split(/\s+/)
40 | self.send(path_components.push('path').join('_').to_sym)
41 | rescue Object => e
42 | raise "Can't find mapping from \"#{page_name}\" to a path.\n" +
43 | "Now, go and add a mapping in #{__FILE__}"
44 | end
45 | end
46 | end
47 | end
48 |
49 | World(NavigationHelpers)
50 |
--------------------------------------------------------------------------------
/features/support/selectors.rb:
--------------------------------------------------------------------------------
1 | module HtmlSelectorsHelpers
2 | # Maps a name to a selector. Used primarily by the
3 | #
4 | # When /^(.+) within (.+)$/ do |step, scope|
5 | #
6 | # step definitions in web_steps.rb
7 | #
8 | def selector_for(locator)
9 | case locator
10 |
11 | when "the page"
12 | "html > body"
13 |
14 | # Add more mappings here.
15 | # Here is an example that pulls values out of the Regexp:
16 | #
17 | # when /^the (notice|error|info) flash$/
18 | # ".flash.#{$1}"
19 |
20 | # You can also return an array to use a different selector
21 | # type, like:
22 | #
23 | # when /the header/
24 | # [:xpath, "//header"]
25 |
26 | # This allows you to provide a quoted selector as the scope
27 | # for "within" steps as was previously the default for the
28 | # web steps:
29 | when /^"(.+)"$/
30 | $1
31 |
32 | else
33 | raise "Can't find mapping from \"#{locator}\" to a selector.\n" +
34 | "Now, go and add a mapping in #{__FILE__}"
35 | end
36 | end
37 | end
38 |
39 | World(HtmlSelectorsHelpers)
40 |
--------------------------------------------------------------------------------
/features/support/warden.rb:
--------------------------------------------------------------------------------
1 | # http://stackoverflow.com/a/8713889/238931
2 | Warden.test_mode!
3 | World Warden::Test::Helpers
4 | After { Warden.test_reset! }
--------------------------------------------------------------------------------
/features/users/sign_in.feature:
--------------------------------------------------------------------------------
1 | Feature: Sign in
2 | In order to get access to protected sections of the site
3 | A user
4 | Should be able to sign in
5 |
6 | Scenario: User is not signed up
7 | Given I do not exist as a user
8 | When I sign in with valid credentials
9 | Then I see an invalid login message
10 | And I should be signed out
11 |
12 | Scenario: User signs in successfully
13 | Given I exist as a user
14 | And I am not logged in
15 | When I sign in with valid credentials
16 | Then I see a successful sign in message
17 | When I return to the site
18 | Then I should be signed in
19 |
20 | Scenario: User enters wrong email
21 | Given I exist as a user
22 | And I am not logged in
23 | When I sign in with a wrong email
24 | Then I see an invalid login message
25 | And I should be signed out
26 |
27 | Scenario: User enters wrong password
28 | Given I exist as a user
29 | And I am not logged in
30 | When I sign in with a wrong password
31 | Then I see an invalid login message
32 | And I should be signed out
--------------------------------------------------------------------------------
/features/users/sign_out.feature:
--------------------------------------------------------------------------------
1 | Feature: Sign out
2 | To protect my account from unauthorized access
3 | A signed in user
4 | Should be able to sign out
5 |
6 | Scenario: User signs out
7 | Given I am logged in
8 | When I sign out
9 | Then I should see a signed out message
10 | When I return to the site
11 | Then I should be signed out
--------------------------------------------------------------------------------
/features/users/sign_up.feature:
--------------------------------------------------------------------------------
1 | Feature: Sign up
2 | In order to get access to protected sections of the site
3 | As a user
4 | I want to be able to sign up
5 |
6 | Background:
7 | Given I am not logged in
8 |
9 | Scenario: User signs up with valid data
10 | When I sign up with valid user data
11 | Then I should see a successful sign up message
12 |
13 | Scenario: User signs up with invalid email
14 | When I sign up with an invalid email
15 | Then I should see an invalid email message
16 |
17 | Scenario: User signs up without password
18 | When I sign up without a password
19 | Then I should see a missing password message
20 |
21 | Scenario: User signs up without password confirmation
22 | When I sign up without a password confirmation
23 | Then I should see a missing password confirmation message
24 |
25 | Scenario: User signs up with mismatched password and confirmation
26 | When I sign up with a mismatched password confirmation
27 | Then I should see a mismatched password message
--------------------------------------------------------------------------------
/features/users/user_edit.feature:
--------------------------------------------------------------------------------
1 | Feature: Edit User
2 | As a registered user of the website
3 | I want to edit my user profile
4 | so I can change my username
5 |
6 | Scenario: I sign in and edit my account
7 | Given I am logged in
8 | When I edit my account details
9 | Then I should see an account edited message
--------------------------------------------------------------------------------
/features/users/user_show.feature:
--------------------------------------------------------------------------------
1 | Feature: Show Users
2 | As a admin to the website
3 | I want to see registered users listed on the admin page
4 | so I can know if the site has users
5 |
6 | @wip
7 | Scenario: Viewing users
8 | Given I am a user named "admin" with an email "admin@test.com" and password "superadmin"
9 | And I sign in as "admin@test.com/superadmin"
10 | When I go to the admin users page
11 | Then I should see "foo"
12 |
--------------------------------------------------------------------------------
/features/voting.feature:
--------------------------------------------------------------------------------
1 | Feature: Voting
2 | As a student
3 | I want to vote on surveys
4 | In order to participate in the lecture
5 |
6 | Background:
7 | Given I exist as a user
8 | And there exists an event
9 |
10 | @javascript
11 | Scenario: Vote for single choice questions
12 | Given a survey with some options exists
13 | And the survey is running
14 | And I am on the root page
15 | And I fill in "id" with the event's number
16 | And I press "Rock the vote"
17 | When I select the first option
18 | And I press "Vote!"
19 | Then I should see "Thanks for voting"
20 |
21 | @javascript
22 | Scenario: Voting twice for single choice questions is not allowed
23 | Given a survey with some options exists
24 | And the survey is running
25 | And I am on the root page
26 | And I fill in "id" with the event's number
27 | And I press "Rock the vote"
28 | When I select the first option
29 | And I press "Vote!"
30 | And I select the first option
31 | And I press "Vote!"
32 | Then I should see "you cannot vote on this survey anymore"
33 | But I should not see "Thanks for voting"
34 |
35 | Scenario: Vote for text questions
36 | Given a text survey exists
37 | And the survey is running
38 | And I am on the root page
39 | And I fill in "id" with the event's number
40 | And I press "Rock the vote"
41 | When I fill in "option[]" with "My Answer"
42 | And I press "Vote!"
43 | Then I should see "Thanks for voting"
44 |
45 | Scenario: Vote for numeric questions
46 | Given a numeric survey exists
47 | And the survey is running
48 | And I am on the root page
49 | And I fill in "id" with the event's number
50 | And I press "Rock the vote"
51 | When I fill in "option" with "42"
52 | And I press "Vote!"
53 | Then I should see "Thanks for voting"
--------------------------------------------------------------------------------
/lib/assets/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/lib/assets/.gitkeep
--------------------------------------------------------------------------------
/lib/cluster.rb:
--------------------------------------------------------------------------------
1 | class Cluster
2 | include Comparable
3 | @items = []
4 | attr_reader:items
5 |
6 | def initialize (fl)
7 | @items = [BigDecimal(fl.to_s)]
8 | end
9 |
10 | def <=> (x)
11 | to_f<=>(x.to_f)
12 | end
13 |
14 | def points
15 | @items.flatten
16 | end
17 |
18 | def to_d
19 | Statistics.avg points
20 | end
21 |
22 | def merge(c)
23 | @items = [@items] << c.items
24 | self
25 | end
26 |
27 | def items
28 | @items
29 | end
30 |
31 | end
--------------------------------------------------------------------------------
/lib/clusterer.rb:
--------------------------------------------------------------------------------
1 | class Clusterer
2 | @clusters = []
3 | attr_reader :clusters
4 |
5 | def initialize(arr)
6 | @clusters = []
7 | arr.sort.each do |f|
8 | @clusters.push Cluster.new(f)
9 | end
10 |
11 | end
12 |
13 | def minDist
14 | min = distTo(@clusters[0],@clusters[1])
15 | c1 = @clusters[1]
16 | i=2
17 | j=0
18 | while i<@clusters.length
19 | if (min > distTo(@clusters[i],@clusters[i-1]))
20 | c1 = @clusters[i]
21 | j=i-1
22 | min = distTo(@clusters[i],@clusters[i-1])
23 | end
24 | i+=1
25 | end
26 | c1.merge(@clusters.delete_at(j))
27 | end
28 |
29 | def distTo (c1,c2)
30 | (c1.to_d - c2.to_d).abs
31 | end
32 |
33 | def clustering
34 | while @clusters.size > 1
35 | minDist
36 | end
37 | @clusters
38 | end
39 |
40 |
41 | end
--------------------------------------------------------------------------------
/lib/statistics.rb:
--------------------------------------------------------------------------------
1 | class Statistics
2 | def self.avg(arr)
3 | arr.sum / arr.length
4 | end
5 |
6 | def self.median(arr)
7 | sorted = arr.sort
8 | if arr.length.odd?
9 | sorted[arr.length/2]
10 | else
11 | (sorted[arr.length/2 - 1] + sorted[arr.length/2]).to_f / 2
12 | end
13 | end
14 |
15 | def self.stdev(arr)
16 | if arr.size > 1
17 | standard_deviation arr
18 | else
19 | 0
20 | end
21 | end
22 |
23 | def self.histogram(arr, no_buckets = 10)
24 | # TODO: find optimal no of buckets and filter outliers using Grubb's Test
25 | no_buckets = arr.length if no_buckets > arr.length
26 | bins, freqs = arr.histogram(no_buckets)
27 | bins.map! do |i|
28 | Statistics.sigfig_to_s(i,2)
29 | end
30 | bins.zip freqs
31 | end
32 |
33 | def self.cluster(arr, threshold = nil)
34 | threshold = arr.flatten.group_by{|x|x}.values.map(&:size).sort.last unless threshold
35 | cl = Clusterer.new(arr)
36 | clusters = cl.clustering
37 | recursive_cluster(cl.clusters.first.items, threshold, [])
38 | end
39 |
40 | def self.sigfig_to_s(number, digits)
41 | f = sprintf("%.#{digits - 1}e", number).to_f
42 | i = f.to_i
43 | (i == f ? i : f).to_s
44 | end
45 |
46 | private
47 |
48 | def self.standard_deviation(array)
49 | result = 0
50 | total = array.sum
51 |
52 | if array.size >= 1
53 | mean = avg array
54 | total_distance_from_mean = array.map do |i|
55 | (i - mean) ** 2
56 | end.sum
57 | (total_distance_from_mean / ([1, array.size - 1].max)) ** 0.5 # TODO: talk with Philipp
58 | else
59 | 0
60 | end
61 | end
62 |
63 | def self.recursive_cluster(arr, threshold, agg)
64 | arr.each do |cluster|
65 | if cluster.respond_to? :flatten and cluster.flatten.size > threshold
66 |
67 | recursive_cluster(cluster, threshold, agg)
68 | else
69 | cluster = cluster.flatten if cluster.respond_to? :flatten
70 | agg << cluster
71 | end
72 | end
73 |
74 | agg.sort
75 | end
76 |
77 |
78 | end
--------------------------------------------------------------------------------
/lib/tasks/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/lib/tasks/.gitkeep
--------------------------------------------------------------------------------
/lib/tasks/resque.rake:
--------------------------------------------------------------------------------
1 | require 'resque/tasks'
2 | task "resque:setup" => :environment
--------------------------------------------------------------------------------
/log/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/log/.gitkeep
--------------------------------------------------------------------------------
/public/404.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | PINGO - Not found
5 |
6 |
23 |
24 |
25 |
26 |
404
27 |
Die von Ihnen gewünschte Seite existiert nicht. / The page you were looking for doesn't exist. / No encontrado.
28 |
Evtl. haben Sie sich nur bei der Adresseingabe verschrieben. / You may have mistyped the address or the page may have moved.
Wir bitten vielmals um Entschuldigung, leider ist etwas schief gelaufen oder PINGO ist vorrübergehend nicht verfügbar.
34 |
Wir werden uns den Fehler anschauen und bald beheben. Bitte probieren Sie es später noch mal. Auf unserer Status-Seite finden Sie aktuelle Informationen.
35 |
We're sorry, but something went wrong.
36 |
We've been notified about this issue and we'll take a look at it shortly. You might try it again, later. Find current information at the PINGO status page.
37 |
38 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/public/apple-touch-icon-114.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/apple-touch-icon-114.png
--------------------------------------------------------------------------------
/public/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/apple-touch-icon.png
--------------------------------------------------------------------------------
/public/bell_sound.OGG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/bell_sound.OGG
--------------------------------------------------------------------------------
/public/bell_sound.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/bell_sound.mp3
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/favicon.ico
--------------------------------------------------------------------------------
/public/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/favicon.png
--------------------------------------------------------------------------------
/public/humans.txt:
--------------------------------------------------------------------------------
1 | PEOPLE BEHIND *PINGO*:
2 | ============================
3 |
4 | * Michael Whittaker (michael-whittaker.de / mwhittak@campus.uni-paderborn.de)
5 | * Juergen Neumann (juergen.neumann@wiwi.uni-paderborn.de)
6 | * Christoph Bach (the-inspired-ones.de / chbach@mail.upb.de)
7 | * Philipp Bednarek (philipp.bednarek@wiwi.uni-paderborn.de) - first bunch of question importers and exporters
8 | * Filip Krakowski (@filkra) - nicer CSV export and a new JSON export for sessions (https://github.com/PingoUPB/PINGOWebApp/pull/17).
9 | * many more from the Chair of Prof. Kundisch (upb.de/winfo2), the IMT (imt.upb.de) and the PPI-Team (upb.de/ppi)
10 |
11 |
12 | STORY:
13 | ======
14 | The PINGO software originated from an "eClickr" software developed by **Michael Whittaker** for a project paper.
15 | Together with **Juergen Neumann** we polished the software. In mid-2013 **Christoph Bach** joined our team.
16 | We develop at the Chair for Information Management & E-Finance at the University of Paderborn (www.upb.de/winfo2).
--------------------------------------------------------------------------------
/public/pingo_sad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/pingo_sad.png
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | # See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file
2 | User-Agent: *
3 | Disallow: /*
4 | Allow: /$
--------------------------------------------------------------------------------
/public/splash-screen-320x460.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/splash-screen-320x460.png
--------------------------------------------------------------------------------
/public/splash-screen-640x1096.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/splash-screen-640x1096.png
--------------------------------------------------------------------------------
/public/splash-screen-640x920.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/splash-screen-640x920.png
--------------------------------------------------------------------------------
/public/stylesheets/formtastic_changes.css:
--------------------------------------------------------------------------------
1 | /* -------------------------------------------------------------------------------------------------
2 |
3 | Load this stylesheet after formtastic.css in your layouts to override the CSS to suit your needs.
4 | This will allow you to update formtastic.css with new releases without clobbering your own changes.
5 |
6 | For example, to make the inline hint paragraphs a little darker in color than the standard #666:
7 |
8 | form.formtastic fieldset > ol > li p.inline-hints { color:#333; }
9 |
10 | HINT:
11 | The following style may be *conditionally* included for improved support on older versions of IE(<8)
12 | form.formtastic fieldset ol li fieldset legend { margin-left: -6px;}
13 |
14 | --------------------------------------------------------------------------------------------------*/
15 |
--------------------------------------------------------------------------------
/public/templates/csv-import-template.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/templates/csv-import-template.xlsx
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image001.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image001.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image002.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image002.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image003.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image003.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image004.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image004.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image005.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image005.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image006.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image006.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image007.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image007.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image008.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image008.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image009.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image009.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image010.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image010.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image011.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image011.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image012.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image012.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image013.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image013.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image014.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image014.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image015.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image015.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image016.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image016.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image017.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image017.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image018.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image018.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image019.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image019.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image020.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image020.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image021.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image021.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image022.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image022.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image023.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image023.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image024.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image025.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image025.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image026.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image026.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image027.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image027.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image028.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image028.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image029.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image029.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image030.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image030.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image031.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image031.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image032.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image032.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image033.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image033.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image034.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image034.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image035.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image035.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image036.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image036.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image037.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image037.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image038.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image038.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image039.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image039.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image040.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image040.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image041.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image041.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image042.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image042.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image043.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image043.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image044.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image044.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image045.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image045.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image046.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image046.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image047.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image047.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image048.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image048.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image049.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image049.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image050.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image050.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image051.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image051.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image052.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image052.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image053.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image053.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image054.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image054.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image055.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image055.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image056.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image056.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image057.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image057.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image058.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image058.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image059.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image059.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image060.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image060.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image061.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image061.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image062.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image062.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image063.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image063.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image064.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image064.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image065.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image065.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image066.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image066.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image067.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image067.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image068.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image068.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image069.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image069.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image070.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image070.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image071.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image071.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image072.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image072.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image073.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image073.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image074.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image074.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image075.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image075.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image076.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image076.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image077.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image077.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image078.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image078.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image079.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image079.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image080.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image080.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image081.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image081.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image082.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image082.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image083.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image083.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image084.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image084.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image085.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image085.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image086.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image086.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image087.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image087.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image088.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image088.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image089.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image089.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/image090.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/image090.png
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/item0001.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/props0002.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/public/tutorial/tutorial-Dateien/themedata.xml:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial-Dateien/themedata.xml
--------------------------------------------------------------------------------
/public/tutorial/tutorial.html:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/public/tutorial/tutorial.html
--------------------------------------------------------------------------------
/script/cucumber:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 |
3 | vendored_cucumber_bin = Dir["#{File.dirname(__FILE__)}/../vendor/{gems,plugins}/cucumber*/bin/cucumber"].first
4 | if vendored_cucumber_bin
5 | load File.expand_path(vendored_cucumber_bin)
6 | else
7 | require 'rubygems' unless ENV['NO_RUBYGEMS']
8 | require 'cucumber'
9 | load Cucumber::BINARY
10 | end
11 |
--------------------------------------------------------------------------------
/script/rails:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
3 |
4 | APP_PATH = File.expand_path('../../config/application', __FILE__)
5 | require File.expand_path('../../config/boot', __FILE__)
6 | require 'rails/commands'
7 |
--------------------------------------------------------------------------------
/spec/controllers/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/spec/controllers/.keep
--------------------------------------------------------------------------------
/spec/controllers/api_controller_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | describe ApiController do
4 |
5 |
6 | def create_test_session
7 | @user = FactoryGirl.create(:user)
8 | @user.ensure_authentication_token!
9 | end
10 |
11 | describe "save_ppt_settings" do
12 |
13 | it "saves the given data to the ppt_settings hash" do
14 | create_test_session
15 |
16 | posted_hash = {"key"=>"value"}
17 | posted_filename = "test"
18 |
19 | post :save_ppt_settings, auth_token: @user.authentication_token, file: posted_filename, json_hash: posted_hash, format: :json
20 | assert_equal response.status, 200
21 | assert_equal JSON.parse(response.body)["ppt_settings"][posted_filename], posted_hash
22 | end
23 |
24 | end
25 |
26 |
27 | end
--------------------------------------------------------------------------------
/spec/controllers/events_controller_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | describe EventsController do
4 |
5 | def create_test_session
6 | @survey = FactoryGirl.create(:survey)
7 | @event = @survey.event
8 | @user = @event.user
9 | end
10 |
11 | def set_browser_locale(locale)
12 | request.env['HTTP_ACCEPT_LANGUAGE'] = "#{locale};q=1.0"
13 | end
14 |
15 | describe "show" do
16 | render_views
17 |
18 | it "displays the lecturers session page in his German browser locale" do
19 | pending
20 | create_test_session
21 | sign_in @user
22 |
23 | set_browser_locale("de") # does not work
24 | get :show, id: @event.token
25 | assert_select "html[lang=?]", /de/
26 | end
27 |
28 | it "displays the lecturers session page in his English browser locale" do
29 | pending
30 | create_test_session
31 | sign_in @user
32 |
33 | set_browser_locale("en") # does not work
34 | get :show, id: @event.token
35 | assert_select "html[lang=?]", /en/
36 | end
37 |
38 | it "displays the lecturers session page in the session locale, if set" do
39 | create_test_session
40 | sign_in @user
41 |
42 | set_browser_locale("en")
43 |
44 | @event.update_attribute(:custom_locale, "de")
45 |
46 | get :show, id: @event.token
47 | assert_select "html[lang=?]", /de/
48 | end
49 | end
50 |
51 |
52 | end
53 |
--------------------------------------------------------------------------------
/spec/factories.rb:
--------------------------------------------------------------------------------
1 | require 'factory_girl'
2 |
3 | FactoryGirl.define do
4 | factory :user do
5 | first_name 'Testy'
6 | last_name 'McUserton'
7 | email 'example@example.com'
8 | password 'please'
9 | password_confirmation 'please'
10 | organization "test orga"
11 | faculty "test fac"
12 | chair "test chair"
13 | # required if the Devise Confirmable module is used
14 | # confirmed_at Time.now
15 |
16 | factory :admin do
17 | admin true
18 | end
19 | end
20 |
21 | factory :hacker, class: User do
22 | first_name 'Hacky'
23 | last_name 'McCracker'
24 | email 'hack@example.com'
25 | password 'please'
26 | password_confirmation 'please'
27 | organization "test orga"
28 | faculty "test fac"
29 | chair "test chair"
30 | end
31 |
32 | factory :event do
33 | name 'Test Session'
34 | user
35 | end
36 |
37 | factory :option do
38 | sequence :name do |n|
39 | "Option ##{n}"
40 | end
41 | end
42 |
43 | factory :survey do
44 | name 'Test survey'
45 | event
46 | type "single"
47 | # survey_with_options will create answer options after the survey has been created
48 | factory :survey_with_options do
49 | # options_count is declared as an ignored attribute and available in
50 | # attributes on the factory, as well as the callback via the evaluator
51 | ignore do
52 | options_count 4
53 | end
54 |
55 | # the after(:create) yields two values; the user instance itself and the
56 | # evaluator, which stores all values from the factory, including ignored
57 | # attributes; `create_list`'s second argument is the number of records
58 | # to create and we make sure the option is associated properly to the survey
59 | after(:create) do |survey, evaluator|
60 | FactoryGirl.create_list(:option, evaluator.options_count, survey: survey)
61 | end
62 | end
63 |
64 |
65 | factory :text_survey do
66 | name 'Tag cloud test survey'
67 | type "text"
68 | end
69 |
70 | factory :numeric_survey do
71 | name 'Numeric test survey'
72 | type "number"
73 | end
74 | end
75 | end
76 |
--------------------------------------------------------------------------------
/spec/mailers/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/spec/mailers/.keep
--------------------------------------------------------------------------------
/spec/models/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/spec/models/.keep
--------------------------------------------------------------------------------
/spec/routing/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/spec/routing/.keep
--------------------------------------------------------------------------------
/spec/services/multiple_choice_question_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | describe MultipleChoiceQuestion do
4 | it "keeps a single correct answer when transforming" do
5 | question = create_multiple_choice_question
6 | question.question_options = [QuestionOption.new(name: "Foo", correct: true), QuestionOption.new(name: "Bar", correct: false)]
7 | question.save!
8 |
9 | question.transform
10 | correct_answers = question.question_options.select{|o| o.correct }
11 | correct_answers.size.should eq(1)
12 | correct_answers.first.name.should eq("Foo")
13 | end
14 |
15 | it "sets multiple correct answers to false when transforming" do
16 | question = create_multiple_choice_question
17 | question.question_options = [QuestionOption.new(name: "Foo", correct: true), QuestionOption.new(name: "Bar", correct: true)]
18 | question.save!
19 |
20 | question.transform
21 | question.question_options.select{|o| o.correct }.size.should eq(0)
22 | end
23 | end
24 |
--------------------------------------------------------------------------------
/spec/spec_helper.rb:
--------------------------------------------------------------------------------
1 | # This file is copied to spec/ when you run 'rails generate rspec:install'
2 | ENV["RAILS_ENV"] ||= 'test'
3 | require File.expand_path("../../config/environment", __FILE__)
4 | require 'rspec/rails'
5 |
6 | # Requires supporting ruby files with custom matchers and macros, etc,
7 | # in spec/support/ and its subdirectories.
8 | Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
9 |
10 | RSpec.configure do |config|
11 | # == Mock Framework
12 | #
13 | # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
14 | #
15 | # config.mock_with :mocha
16 | # config.mock_with :flexmock
17 | # config.mock_with :rr
18 | config.mock_with :rspec
19 |
20 | # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
21 | #config.fixture_path = "#{::Rails.root}/spec/fixtures"
22 |
23 | # If you're not using ActiveRecord, or you'd prefer not to run each of your
24 | # examples within a transaction, remove the following line or assign false
25 | # instead of true.
26 | #config.use_transactional_fixtures = true
27 |
28 | config.include PINGOSpecHelpers
29 |
30 | # Clean up the database
31 | require 'database_cleaner'
32 | config.before(:suite) do
33 | DatabaseCleaner[:mongoid].strategy = :truncation
34 | #DatabaseCleaner.orm = "mongoid"
35 | end
36 |
37 | config.before(:each) do
38 | DatabaseCleaner.clean
39 | end
40 | end
41 |
--------------------------------------------------------------------------------
/spec/support/devise.rb:
--------------------------------------------------------------------------------
1 | RSpec.configure do |config|
2 | config.include Devise::TestHelpers, :type => :controller
3 | end
4 |
--------------------------------------------------------------------------------
/spec/support/helpers.rb:
--------------------------------------------------------------------------------
1 | module PINGOSpecHelpers
2 | def create_multiple_choice_question
3 | question = MultipleChoiceQuestion.new
4 | question.name = "My Question"
5 | question
6 | end
7 |
8 | def login_user
9 | @request.env["devise.mapping"] = Devise.mappings[:user]
10 | user = FactoryGirl.create(:user)
11 | sign_in user
12 | @user = user
13 | end
14 |
15 | def login_hacker
16 | @request.env["devise.mapping"] = Devise.mappings[:user]
17 | user = FactoryGirl.create(:hacker)
18 | sign_in user
19 | @hacker = user
20 | end
21 | end
22 |
--------------------------------------------------------------------------------
/spec/support/mongoid.rb:
--------------------------------------------------------------------------------
1 | RSpec.configure do |config|
2 | config.include Mongoid::Matchers
3 | end
--------------------------------------------------------------------------------
/vendor/assets/stylesheets/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/vendor/assets/stylesheets/.gitkeep
--------------------------------------------------------------------------------
/vendor/plugins/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PingoUPB/PINGOWebApp/6176b541053082642817e8444ff60646a15bfd65/vendor/plugins/.gitkeep
--------------------------------------------------------------------------------
20 |