veto

Simple Sinatra voting website.
git clone git://git.knutsen.co/veto
Log | Files | Refs | README | LICENSE

commit f72ef76487c75395bd3218ac430c1254c0a624ab
parent 9dca03d24813d9dfe0c76e66ea0f61d6f41a7e62
Author: Fredrik <moi@knutsen.co>
Date:   Tue, 23 Oct 2018 21:30:37 +0100

Merge pull request #1 from Demonstrandum/devel

One vote per IP and save JSON files at myjson.com
Diffstat:
MDockerfile | 4+---
MGemfile.lock | 3++-
Anow.json | 5+++++
Mpublic/poller.js | 1+
Mserver.rb | 60++++++++++++++++++++++++++++++++++++++++++++++++++++--------
Mviews/poll.erb | 6+++---
6 files changed, 64 insertions(+), 15 deletions(-)

diff --git a/Dockerfile b/Dockerfile @@ -1,6 +1,4 @@ -FROM ruby:2.5.2-alpine - - +FROM ruby:2.5.0-alpine RUN apk update && apk --update --no-cache add libstdc++ RUN apk --update --no-cache add --virtual .build_deps git g++ musl-dev make diff --git a/Gemfile.lock b/Gemfile.lock @@ -15,6 +15,7 @@ GEM rack (~> 2.0) rack-protection (= 2.0.4) tilt (~> 2.0) + symbolized (0.0.1) thin (1.7.2) daemons (~> 1.0, >= 1.0.9) eventmachine (~> 1.0, >= 1.0.4) @@ -25,11 +26,11 @@ PLATFORMS ruby DEPENDENCIES - eventmachine json rack (~> 2.0, >= 2.0.5) rack-ssl (~> 1.4) sinatra (~> 2.0, >= 2.0.1) + symbolized thin BUNDLED WITH diff --git a/now.json b/now.json @@ -0,0 +1,5 @@ +{ + "name": "Veto", + "alias": "veto.vote", + "type": "docker" +} diff --git a/public/poller.js b/public/poller.js @@ -16,6 +16,7 @@ const get_votes = () => { const cast_button = name => { $('#vote').val(name); $('#cast').submit(); + $('#vote').val(''); setTimeout(update_votes, 70); }; diff --git a/server.rb b/server.rb @@ -1,5 +1,7 @@ -require 'sinatra' +require 'net/http' +require 'json' +require 'sinatra' set :run, true set :server, %w{ thin } @@ -7,20 +9,57 @@ set :server, %w{ thin } set :port, 8080 enable :sessions +$INDIFFERENT = proc do |h, k| + case k + when String then sym = k.to_sym; h[sym] if h.key?(sym) + when Symbol then str = k.to_s; h[str] if h.key?(str) + end +end + $polls = { 'this-is-a-poll-name' => { :name => 'This is a poll name', :votes => {}, - :alternatives => true + :alt => true, + :voters => [] } -} +} # Example. + +$JSON_ID = '1arifg' +$JSON_BASE = 'https://api.myjson.com' + +String.class_eval { def to_uri; URI(self); end } +$polls.default_proc = $INDIFFERENT + +def request_json + puts "[!!] Requesting JSON, ID: #{$JSON_ID}" + response = Net::HTTP.get "#{$JSON_BASE}/bins/#{$JSON_ID}".to_uri + $polls = JSON.parse response, {:symbolize_names => true} + $polls.default_proc = $INDIFFERENT + pp $polls +end + +def save_json + puts "[!!] Saving JSON, ID: #{$JSON_ID}" + uri = "#{$JSON_BASE}/bins/#{$JSON_ID}".to_uri + puts "[!!]\tURI: #{uri}" + req = Net::HTTP::Put.new uri + req.set_content_type 'application/json' + req.body = $polls.to_json + res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request req } + puts "[!!]\tResponse: #{res.inspect}" +end + +request_json # Initial JSON retrieval def make_poll code, name, alt $polls[code] = { :name => name, :votes => {}, - :alt => alt + :alt => alt, + :voters => [] } + save_json end get '/' do @@ -43,25 +82,29 @@ post '/new' do params[:name], params[:alt]) - puts params[:primary] params[:primary].each do |option| $polls[params[:code]][:votes][option] = { :number => 0, :primary => true } end + save_json end get '/poll/:poll' do - unless $polls.keys.include? params[:poll] + unless $polls.keys.map(&:to_s).include? params[:poll] return "This poll has not been created/does not exist!" end - session.merge! $polls[params[:poll]] - erb :poll + local = {:code => params[:poll]} + local.merge! $polls[params[:poll]] + erb :poll, :locals => local end post '/poll/:poll/cast' do + return nil if $polls[params[:poll]][:voters].include? request.ip + $polls[params[:poll]][:voters].push request.ip + if $polls[params[:poll]][:votes].keys.include? params[:vote] $polls[params[:poll]][:votes][params[:vote]][:number] += 1 else @@ -70,6 +113,7 @@ post '/poll/:poll/cast' do :primary => false } end + save_json end get '/poll/:poll/votes.json' do diff --git a/views/poll.erb b/views/poll.erb @@ -1,10 +1,10 @@ <!DOCTYPE html> <html> <head> - <title><%= session[:name] %> | Lopper</title> + <title><%= name %> | Lopper</title> </head> <body> - <h1><%= session[:name] %></h1> + <h1><%= name %></h1> <h2>Cast a Vote</h2> <ul id="live"></ul> @@ -14,7 +14,7 @@ <input type="submit" id="submit" value="Submit Vote" /> </form> - <% unless session[:alt] == true %> + <% unless alt %> <style> #cast { display: none;