hullapp 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.DS_Store +0 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +66 -0
- data/Rakefile +1 -0
- data/bin/hull +15 -0
- data/hullapp.gemspec +27 -0
- data/lib/hull.rb +6 -0
- data/lib/hull/cli.rb +124 -0
- data/lib/hull/version.rb +3 -0
- data/templates/.DS_Store +0 -0
- data/templates/hullenv.tt +4 -0
- data/templates/ruby/.gitignore +7 -0
- data/templates/ruby/.powenv +8 -0
- data/templates/ruby/.powrc +5 -0
- data/templates/ruby/.rvmrc.tt +1 -0
- data/templates/ruby/Gemfile +50 -0
- data/templates/ruby/Guardfile +8 -0
- data/templates/ruby/Procfile +4 -0
- data/templates/ruby/README.md +198 -0
- data/templates/ruby/Rakefile +40 -0
- data/templates/ruby/application/assets.rb +7 -0
- data/templates/ruby/application/assets/images/icons/facebook.png +0 -0
- data/templates/ruby/application/assets/images/icons/twitter.png +0 -0
- data/templates/ruby/application/assets/images/socialmedia/app-store.png +0 -0
- data/templates/ruby/application/assets/images/socialmedia/dribbble.png +0 -0
- data/templates/ruby/application/assets/images/socialmedia/facebook.png +0 -0
- data/templates/ruby/application/assets/images/socialmedia/flickr.png +0 -0
- data/templates/ruby/application/assets/images/socialmedia/forrst.png +0 -0
- data/templates/ruby/application/assets/images/socialmedia/foursquare.png +0 -0
- data/templates/ruby/application/assets/images/socialmedia/github.png +0 -0
- data/templates/ruby/application/assets/images/socialmedia/google-plus.png +0 -0
- data/templates/ruby/application/assets/images/socialmedia/google.png +0 -0
- data/templates/ruby/application/assets/images/socialmedia/instagram.png +0 -0
- data/templates/ruby/application/assets/images/socialmedia/linkedin.png +0 -0
- data/templates/ruby/application/assets/images/socialmedia/skype.png +0 -0
- data/templates/ruby/application/assets/images/socialmedia/social-email.png +0 -0
- data/templates/ruby/application/assets/images/socialmedia/social-rss.png +0 -0
- data/templates/ruby/application/assets/images/socialmedia/spotify.png +0 -0
- data/templates/ruby/application/assets/images/socialmedia/tumblr.png +0 -0
- data/templates/ruby/application/assets/images/socialmedia/twitter-2.png +0 -0
- data/templates/ruby/application/assets/images/socialmedia/twitter.png +0 -0
- data/templates/ruby/application/assets/images/socialmedia/vimeo.png +0 -0
- data/templates/ruby/application/assets/images/socialmedia/youtube.png +0 -0
- data/templates/ruby/application/assets/javascripts/app.js +11 -0
- data/templates/ruby/application/assets/javascripts/main.coffee +17 -0
- data/templates/ruby/application/assets/javascripts/template.js.erb +1 -0
- data/templates/ruby/application/assets/stylesheets/partials/_base.scss +17 -0
- data/templates/ruby/application/assets/stylesheets/partials/_boilerplate.scss +291 -0
- data/templates/ruby/application/assets/stylesheets/partials/_colors.scss +0 -0
- data/templates/ruby/application/assets/stylesheets/partials/_fonts.scss +1 -0
- data/templates/ruby/application/assets/stylesheets/partials/_h5bp.scss +298 -0
- data/templates/ruby/application/assets/stylesheets/partials/_layout.scss +12 -0
- data/templates/ruby/application/assets/stylesheets/partials/_normalize.scss +504 -0
- data/templates/ruby/application/assets/stylesheets/partials/_variables.scss +28 -0
- data/templates/ruby/application/assets/stylesheets/style.scss +16 -0
- data/templates/ruby/application/assets/templates/hello.hbs +1 -0
- data/templates/ruby/application/compass.rb +27 -0
- data/templates/ruby/application/core.rb +15 -0
- data/templates/ruby/application/core_extensions/blank.rb +111 -0
- data/templates/ruby/application/core_extensions/hash.rb +34 -0
- data/templates/ruby/application/core_extensions/sprockets.rb +74 -0
- data/templates/ruby/application/core_extensions/try.rb +57 -0
- data/templates/ruby/application/helpers.rb +121 -0
- data/templates/ruby/application/helpers/form_tag_helpers.rb +127 -0
- data/templates/ruby/application/helpers/notification_helpers.rb +20 -0
- data/templates/ruby/application/helpers/run_later.rb +111 -0
- data/templates/ruby/application/settings.rb +8 -0
- data/templates/ruby/application/views/demo.erb +27 -0
- data/templates/ruby/application/views/index.erb +9 -0
- data/templates/ruby/application/views/layout.erb +45 -0
- data/templates/ruby/application/workers.rb +0 -0
- data/templates/ruby/config.ru +84 -0
- data/templates/ruby/config/settings.yml +53 -0
- data/templates/ruby/config/sidekiq.yml +11 -0
- data/templates/ruby/config/unicorn.rb +91 -0
- data/templates/ruby/public/.htaccess +538 -0
- data/templates/ruby/public/404.html +157 -0
- data/templates/ruby/public/apple-touch-icon-114x114-precomposed.png +0 -0
- data/templates/ruby/public/apple-touch-icon-144x144-precomposed.png +0 -0
- data/templates/ruby/public/apple-touch-icon-57x57-precomposed.png +0 -0
- data/templates/ruby/public/apple-touch-icon-72x72-precomposed.png +0 -0
- data/templates/ruby/public/apple-touch-icon-precomposed.png +0 -0
- data/templates/ruby/public/apple-touch-icon.png +0 -0
- data/templates/ruby/public/crossdomain.xml +15 -0
- data/templates/ruby/public/favicon.ico +0 -0
- data/templates/ruby/public/humans.txt +15 -0
- data/templates/ruby/public/robots.txt +5 -0
- data/templates/ruby/vendor/assets/images/glyphicons-halflings-white.png +0 -0
- data/templates/ruby/vendor/assets/images/glyphicons-halflings.png +0 -0
- data/templates/ruby/vendor/assets/javascripts/backbone.js +1431 -0
- data/templates/ruby/vendor/assets/javascripts/bootstrap.js +2027 -0
- data/templates/ruby/vendor/assets/javascripts/index.js +0 -0
- data/templates/ruby/vendor/assets/javascripts/jquery.js +9227 -0
- data/templates/ruby/vendor/assets/javascripts/modernizr.js +11 -0
- data/templates/ruby/vendor/assets/javascripts/underscore.js +1059 -0
- data/templates/ruby/vendor/assets/javascripts/vendor.js +2 -0
- data/templates/ruby/vendor/assets/stylesheets/bootstrap-responsive.css +1040 -0
- data/templates/ruby/vendor/assets/stylesheets/bootstrap.css +5624 -0
- data/templates/ruby/vendor/assets/stylesheets/vendor.scss +2 -0
- metadata +243 -0
@@ -0,0 +1,127 @@
|
|
1
|
+
# ================
|
2
|
+
# = Form Helpers =
|
3
|
+
# ================
|
4
|
+
module Sinatra
|
5
|
+
module FormTagHelpers
|
6
|
+
|
7
|
+
# input_for creates an <input> tag with a number of configurable options
|
8
|
+
# if `param` is set in the `params` hash, the values from the `params` hash will be populated in the tag.
|
9
|
+
#
|
10
|
+
# <%= input_for 'something_hidden', :type => 'hidden', :value => 'Shhhhhh' %>
|
11
|
+
#
|
12
|
+
# Yields:
|
13
|
+
#
|
14
|
+
# <input type='hidden' name='something_hidden' id='something_hidden' value='Shhhhhh'>
|
15
|
+
#
|
16
|
+
def input_for(param, attributes = {})
|
17
|
+
# default values when not specified.
|
18
|
+
attributes = {
|
19
|
+
:type => 'text', # can be any HTML input type ('email', 'submit', 'password', etc.)
|
20
|
+
:value => h(params[param.to_sym]) || '',
|
21
|
+
:name => param,
|
22
|
+
:id => attributes[:id] || param
|
23
|
+
}.merge(attributes)
|
24
|
+
|
25
|
+
"<input #{ attributes.to_attr }>"
|
26
|
+
end
|
27
|
+
|
28
|
+
# radio_for creates an input tag of type radio and marks it `checked` if the param argument is set to the same value in the `params` hash
|
29
|
+
def radio_for(param, attributes = {})
|
30
|
+
attributes = {
|
31
|
+
:type => 'radio'
|
32
|
+
}.merge(attributes)
|
33
|
+
|
34
|
+
if params[param.to_sym].to_s == attributes[:value].to_s
|
35
|
+
attributes.merge!({ :checked => nil })
|
36
|
+
end
|
37
|
+
|
38
|
+
input_for param, attributes
|
39
|
+
end
|
40
|
+
|
41
|
+
# checkbox_for creates an input of type checkbox with a `checked_if` argument to determine if it should be checked
|
42
|
+
#
|
43
|
+
# <%= checkbox_for 'is_cool', User.is_cool? %>
|
44
|
+
#
|
45
|
+
# Yields:
|
46
|
+
#
|
47
|
+
# <input type='checkbox' name='is_cool' id='is_cool' value='true'>
|
48
|
+
#
|
49
|
+
# Which will be marked with `checked` if `User.is_cool?` evaluates to true
|
50
|
+
#
|
51
|
+
def checkbox_for(param, checked_if, attributes = {})
|
52
|
+
attributes = {
|
53
|
+
:type => 'checkbox',
|
54
|
+
:value => 'true'
|
55
|
+
}.merge(attributes)
|
56
|
+
|
57
|
+
if checked_if || params[param.to_sym] == 'true'
|
58
|
+
attributes.merge!({ :checked => nil })
|
59
|
+
end
|
60
|
+
|
61
|
+
input_for param, attributes
|
62
|
+
end
|
63
|
+
|
64
|
+
# creates a simple <textarea> tag
|
65
|
+
def textarea_for(param, attributes = {})
|
66
|
+
# default values to include
|
67
|
+
attributes = {
|
68
|
+
:name => param,
|
69
|
+
:id => attributes[:id] || param
|
70
|
+
}.merge(attributes)
|
71
|
+
|
72
|
+
"<textarea #{ attributes.to_attr }>#{ h(params[param.to_sym]) || '' }</textarea>"
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
# option_for creates an <option> element with the specified attributes
|
77
|
+
# if the param specified is set to the value of this option tag then it is marked as 'selected'
|
78
|
+
# designed to be used within a <select> element
|
79
|
+
#
|
80
|
+
# <%= option_for 'turtles', :key => 'I love them', :value => 'love' %>
|
81
|
+
#
|
82
|
+
# Yields:
|
83
|
+
#
|
84
|
+
# <option value='love'>I love them</option>
|
85
|
+
#
|
86
|
+
# If params[:turtle] is set to 'love' this yields:
|
87
|
+
#
|
88
|
+
# <option value='love' selected>I love them</option>
|
89
|
+
#
|
90
|
+
def option_for(param, attributes = {})
|
91
|
+
if params[param.to_sym]
|
92
|
+
default = params[param].to_s
|
93
|
+
elsif attributes[:default]
|
94
|
+
default = attributes.delete(:default).to_s
|
95
|
+
else
|
96
|
+
default = ''
|
97
|
+
end
|
98
|
+
|
99
|
+
attributes.merge!({ :selected => nil }) if default == attributes[:value].to_s
|
100
|
+
|
101
|
+
"<option #{ attributes.to_attr }>#{ attributes.delete(:key) }</option>"
|
102
|
+
end
|
103
|
+
|
104
|
+
|
105
|
+
# select_for creates a <select> element with the specified attributes
|
106
|
+
# options are the available <option> tags within the <select> box
|
107
|
+
#
|
108
|
+
# <%= select_for 'days', { :monday => 'Monday', :myday => 'MY DAY!' } %>
|
109
|
+
#
|
110
|
+
# Yields:
|
111
|
+
#
|
112
|
+
# <select name='days' id='days' size='1'>
|
113
|
+
# <option value='monday'>Monday</option>
|
114
|
+
# <option value='myday'>MY DAY!</option>
|
115
|
+
# </select>
|
116
|
+
#
|
117
|
+
def select_for(param, options, attributes = {})
|
118
|
+
"<select #{ attributes.to_attr } name='#{ param }' id='#{ param }' size='1'>
|
119
|
+
#{ options.collect { |key, val| option_for(param, :key => key, :value => val, :default => attributes[:default]) }.join(' ').chomp }
|
120
|
+
</select>"
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
# comment this out if you don't want these methods included
|
125
|
+
# or want to include them on your own
|
126
|
+
helpers FormTagHelpers
|
127
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Sinatra
|
2
|
+
module NotificationHelpers
|
3
|
+
def notify_devs(err)
|
4
|
+
exception = err
|
5
|
+
from = Settings.notifications.sender
|
6
|
+
subject = "A #{ exception.class.to_s } Occurred on Your Rack Application"
|
7
|
+
body = ERB.new(EMAIL_TEMPLATE).result(binding) # not sure about this (binding) thing
|
8
|
+
html_body = ERB.new(HTML_EMAIL_TEMPLATE).result(binding)
|
9
|
+
|
10
|
+
# loop and email
|
11
|
+
Settings.notifications.recipients.each do |email|
|
12
|
+
Pony.mail :to => email, :from => from, :subject => subject, :body => body, :html_body => html_body, :via => :sendmail
|
13
|
+
end
|
14
|
+
rescue
|
15
|
+
# shhhh
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
helpers NotificationHelpers
|
20
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
# =============
|
2
|
+
# = Run Later =
|
3
|
+
# =============
|
4
|
+
module Sinatra
|
5
|
+
module RunLater
|
6
|
+
require 'timeout'
|
7
|
+
|
8
|
+
@@run_now = false
|
9
|
+
@@queue = ::Queue.new
|
10
|
+
|
11
|
+
def self.queue
|
12
|
+
@@queue
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.run_now?
|
16
|
+
@@run_now
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.run_now=(run_now)
|
20
|
+
@@run_now = run_now
|
21
|
+
end
|
22
|
+
|
23
|
+
module InstanceMethods
|
24
|
+
def run_later(&block)
|
25
|
+
if RunLater.run_now?
|
26
|
+
block.call
|
27
|
+
else
|
28
|
+
@@run_later ||= RunLater::Worker.instance
|
29
|
+
RunLater.queue << block
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class Worker
|
35
|
+
attr_accessor :thread
|
36
|
+
attr_accessor :logger
|
37
|
+
|
38
|
+
def initialize
|
39
|
+
@thread = Thread.new {
|
40
|
+
|
41
|
+
# removing this seems to allow it shut down nicely
|
42
|
+
# trap :INT do
|
43
|
+
# RunLater::Worker.shutdown
|
44
|
+
# exit
|
45
|
+
# end
|
46
|
+
|
47
|
+
loop {
|
48
|
+
process_queue
|
49
|
+
}
|
50
|
+
}
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.instance
|
54
|
+
@worker ||= RunLater::Worker.new
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.shutdown
|
58
|
+
begin
|
59
|
+
Timeout::timeout 10 do
|
60
|
+
loop { break unless instance.thread[:running] }
|
61
|
+
end
|
62
|
+
rescue Timeout::Error
|
63
|
+
# logger.error("Worker thread timed out. Forcing shutdown.")
|
64
|
+
ensure
|
65
|
+
instance.thread.kill
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def self.cleanup
|
70
|
+
begin
|
71
|
+
Timeout::timeout 10 do
|
72
|
+
loop do
|
73
|
+
break unless instance.thread[:running]
|
74
|
+
|
75
|
+
# When run in Passenger, explicitly pass control to another thread
|
76
|
+
# which will in return hand over control to the worker thread.
|
77
|
+
# However, it doesn't work in Passenger 2.1.0, since it removes
|
78
|
+
# all its classes before handing the request over to Rails.
|
79
|
+
|
80
|
+
# Thread.pass if defined?(::Passenger)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
rescue Timeout::Error
|
84
|
+
# logger.warn("Worker thread takes too long and will be killed.")
|
85
|
+
# logger.flush
|
86
|
+
instance.thread.kill
|
87
|
+
@worker = RunLater::Worker.new
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def process_queue
|
92
|
+
begin
|
93
|
+
while block = RunLater.queue.pop
|
94
|
+
Thread.pass
|
95
|
+
Thread.current[:running] = true
|
96
|
+
block.call
|
97
|
+
Thread.current[:running] = false
|
98
|
+
# logger.flush
|
99
|
+
end
|
100
|
+
rescue Exception => e
|
101
|
+
# logger.error("Worker thread crashed, retrying. Error was: #{e}")
|
102
|
+
# logger.flush
|
103
|
+
Thread.current[:running] = false
|
104
|
+
retry
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
helpers RunLater::InstanceMethods
|
111
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
<!-- WE NEED MORE JS!!!!! -->
|
2
|
+
<script>
|
3
|
+
Modernizr.load({
|
4
|
+
complete: function(){
|
5
|
+
log("Whoa, this is inline in my view file!", "But is jQuery loaded?", $, "Yup.");
|
6
|
+
}
|
7
|
+
});
|
8
|
+
</script>
|
9
|
+
|
10
|
+
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
|
11
|
+
<p><%= link_to 'Go home', '/' %> <code><==</code> <em>made with <code>link_to</code> helper!</em></p>
|
12
|
+
|
13
|
+
<h2>Form Tag Helpers</h2>
|
14
|
+
<form action='/'>
|
15
|
+
<p>
|
16
|
+
<b><code>input_for</code></b><br>
|
17
|
+
<%= input_for 'input' %><br>
|
18
|
+
<%= link_to 'See this filled with "here is some input"', '/?input=here is some input' %>
|
19
|
+
<%= '<br>notice how the value gets set to the value of <code>params[:input]</code> :)' if params[:input] %>
|
20
|
+
</p>
|
21
|
+
<p>
|
22
|
+
<b><code>select_for</code></b><br>
|
23
|
+
<%= select_for 'select', { 'Nothing' => :zero, 'One' => :one, 'The second' => :two } %><br>
|
24
|
+
<%= link_to 'See the second option selected', '/?select=one' %>
|
25
|
+
<%= '<br>oooooh... <b>ahhhhhh</b>' if params[:select] %>
|
26
|
+
</p>
|
27
|
+
</form>
|
@@ -0,0 +1,45 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
|
3
|
+
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
|
4
|
+
<!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]-->
|
5
|
+
<!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]-->
|
6
|
+
<head>
|
7
|
+
<meta charset="utf-8">
|
8
|
+
<link rel="shortcut icon" href="<%= image_path('favicon.ico') %>">
|
9
|
+
<title><%= @title %></title>
|
10
|
+
<meta name="description" content="">
|
11
|
+
<meta name="viewport" content="width=device-width">
|
12
|
+
|
13
|
+
<meta property="og:title" content="<%=@title%>" />
|
14
|
+
<meta property="og:type" content="company" />
|
15
|
+
<meta property="og:site_name" content="site_name" />
|
16
|
+
<meta property="og:url" content="http://site_url" />
|
17
|
+
<meta property="og:image" content="null" />
|
18
|
+
<meta property="og:description" content="<%=@description%>" />
|
19
|
+
|
20
|
+
<link rel="stylesheet" href="<%= stylesheet_path('vendor') %>" media="all">
|
21
|
+
<link rel="stylesheet" href="<%= stylesheet_path('style') %>" media="all">
|
22
|
+
|
23
|
+
</head>
|
24
|
+
<body data-spy="scroll" data-target=".navbar">
|
25
|
+
<!--[if lt IE 7]>
|
26
|
+
<p class="chromeframe">You are using an outdated browser. <a href="http://browsehappy.com/">Upgrade your browser today</a> or <a href="http://www.google.com/chromeframe/?redirect=true">install Google Chrome Frame</a> to better experience this site.</p>
|
27
|
+
<![endif]-->
|
28
|
+
<div class="container">
|
29
|
+
<%=yield%>
|
30
|
+
</div>
|
31
|
+
|
32
|
+
<footer class='container'>
|
33
|
+
<div class='row'>
|
34
|
+
<div class='span12'>
|
35
|
+
Footer
|
36
|
+
</div>
|
37
|
+
</div>
|
38
|
+
</footer>
|
39
|
+
<script src='//ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js'></script>
|
40
|
+
<script src='<%= javascript_path('vendor') %>'></script>
|
41
|
+
<script src='<%= javascript_path('app') %>'></script>
|
42
|
+
<style type="text/css">
|
43
|
+
</style>
|
44
|
+
</body>
|
45
|
+
</html>
|
File without changes
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# = bundle that shit
|
2
|
+
require 'rubygems' if RUBY_VERSION < '1.9'
|
3
|
+
require 'bundler' # gem requires
|
4
|
+
Bundler.require
|
5
|
+
|
6
|
+
PROJECT_ROOT = File.expand_path(File.dirname(__FILE__))
|
7
|
+
|
8
|
+
# core Ruby requires, modules and the main app file
|
9
|
+
%w(securerandom timeout cgi date ./application/settings ./application/core).each do |requirement|
|
10
|
+
require requirement
|
11
|
+
end
|
12
|
+
|
13
|
+
# = Middleware =
|
14
|
+
if Settings.dalli
|
15
|
+
use Rack::Session::Dalli, # session via memcached that sets a cookie reference
|
16
|
+
:expire_after => 1800, # 30 minutes
|
17
|
+
:key => 'rack_session', # cookie name (probably change this)
|
18
|
+
:secret => 'change me', # Use `SecureRandom.hex(32)` to generate an unpredictable, 256bit randomly signed session cookies.
|
19
|
+
:httponly => true, # bad js! No cookies for you!
|
20
|
+
:compress => true,
|
21
|
+
:secure => false, # NOTE: if you're storing user authentication information in session set this to true and provide pages via SSL instead of standard HTTP or, to quote nkp, "risk the firesheep!"
|
22
|
+
:path => '/'
|
23
|
+
else
|
24
|
+
use Rack::Session::Cookie
|
25
|
+
end
|
26
|
+
# rack middleware
|
27
|
+
use Rack::Deflect, # prevents DOS attacks https://github.com/rack/rack-contrib/blob/master/lib/rack/contrib/deflect.rb
|
28
|
+
:log => $stdout, # should log appropriately
|
29
|
+
:request_threshold => 100, # number of requests
|
30
|
+
:interval => 5, # number of seconds to watch for :request_threshold
|
31
|
+
:block_duration => 600 # number of seconds to block after :request_threshold has been hit
|
32
|
+
use Rack::CommonLogger
|
33
|
+
use Rack::Protection::SessionHijacking # records a few pieces of browser info and stores in session
|
34
|
+
use Rack::Protection::IPSpoofing # checks & protects against forwarded-for madness
|
35
|
+
use Rack::Protection::PathTraversal # prevents path traversal
|
36
|
+
|
37
|
+
if Settings.livereload
|
38
|
+
use Rack::LiveReload
|
39
|
+
end
|
40
|
+
|
41
|
+
# = Configuration =
|
42
|
+
set :run, false
|
43
|
+
set :server, %w(unicorn)
|
44
|
+
set :views, './application/views'
|
45
|
+
set :show_exceptions, Settings.debug
|
46
|
+
set :raise_errors, Settings.debug
|
47
|
+
set :logging, true
|
48
|
+
set :static, Settings.serve_static # your upstream server should deal with those (nginx, Apache)
|
49
|
+
#
|
50
|
+
# . . . . . . . . . . . . . . . . _,,,--~~~~~~~~--,_
|
51
|
+
# . . . . . . . . . . . . . . ,-' : : : :::: :::: :: : : : : :º '-, ITS A TRAP!
|
52
|
+
# . . . . . . . . . . . . .,-' :: : : :::: :::: :::: :::: : : :o : '-,
|
53
|
+
# . . . . . . . . . . . ,-' :: ::: :: : : :: :::: :::: :: : : : : :O '-,
|
54
|
+
# . . . . . . . . . .,-' : :: :: :: :: :: : : : : : , : : :º :::: :::: ::';
|
55
|
+
# . . . . . . . . .,-' / / : :: :: :: :: : : :::: :::-, ;; ;; ;; ;; ;; ;; ;\
|
56
|
+
# . . . . . . . . /,-',' :: : : : : : : : : :: :: :: : '-, ;; ;; ;; ;; ;; ;;|
|
57
|
+
# . . . . . . . /,',-' :: :: :: :: :: :: :: : ::_,-~~,_'-, ;; ;; ;; ;; |
|
58
|
+
# . . . . . _/ :,' :/ :: :: :: : : :: :: _,-'/ : ,-';'-'''''~-, ;; ;; ;;,'
|
59
|
+
# . . . ,-' / : : : : : : ,-''' : : :,--'' :|| /,-'-'--'''__,''' \ ;; ;,-'/
|
60
|
+
# . . . \ :/,, : : : _,-' --,,_ : : \ :\ ||/ /,-'-'x### ::\ \ ;;/
|
61
|
+
# . . . . \/ /---'''' : \ #\ : :\ : : \ :\ \| | : (O##º : :/ /-''
|
62
|
+
# . . . . /,'____ : :\ '-#\ : \, : :\ :\ \ \ : '-,___,-',-`-,,
|
63
|
+
# . . . . ' ) : : : :''''--,,--,,,,,,¯ \ \ :: ::--,,_''-,,'''¯ :'- :'-,
|
64
|
+
# . . . . .) : : : : : : ,, : ''''~~~~' \ :: :: :: :'''''¯ :: ,-' :,/\
|
65
|
+
# . . . . .\,/ /|\\| | :/ / : : : : : : : ,'-, :: :: :: :: ::,--'' :,-' \ \
|
66
|
+
# . . . . .\\'|\\ \|/ '/ / :: :_--,, : , | )'; :: :: :: :,-'' : ,-' : : :\ \,
|
67
|
+
# . . . ./¯ :| \ |\ : |/\ :: ::----, :\/ :|/ :: :: ,-'' : :,-' : : : : : : ''-,,
|
68
|
+
# . . ..| : : :/ ''-(, :: :: :: '''''~,,,,,'' :: ,-'' : :,-' : : : : : : : : :,-'''\\
|
69
|
+
# . ,-' : : : | : : '') : : :¯''''~-,: : ,--''' : :,-'' : : : : : : : : : ,-' :¯'''''-,_ .
|
70
|
+
# ./ : : : : :'-, :: | :: :: :: _,,-''''¯ : ,--'' : : : : : : : : : : : / : : : : : : :''-,
|
71
|
+
# / : : : : : -, :¯'''''''''''¯ : : _,,-~'' : : : : : : : : : : : : : :| : : : : : : : : :
|
72
|
+
# : : : : : : : :¯''~~~~~~''' : : : : : : : : : : : : : : : : : : | : : : : : : : : :
|
73
|
+
#
|
74
|
+
|
75
|
+
# = map it out for me
|
76
|
+
# sprockets
|
77
|
+
map Settings.sprockets.assets_prefix do
|
78
|
+
run Sinatra::Application.sprockets
|
79
|
+
end
|
80
|
+
|
81
|
+
# main app
|
82
|
+
map '/' do
|
83
|
+
run Sinatra::Application
|
84
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
defaults: &defaults
|
2
|
+
livereload: true
|
3
|
+
dalli: false
|
4
|
+
debug: false
|
5
|
+
logging: true
|
6
|
+
serve_static: false
|
7
|
+
app_title: Your app title here
|
8
|
+
google_analytics: UA-XXX-XXX
|
9
|
+
notifications:
|
10
|
+
sender: service@example.com
|
11
|
+
recipients:
|
12
|
+
- you@example.com
|
13
|
+
- me@example.com
|
14
|
+
- him@example.com
|
15
|
+
sprockets:
|
16
|
+
digest: true
|
17
|
+
assets_prefix: /assets
|
18
|
+
precompile:
|
19
|
+
- app.js
|
20
|
+
- vendor.js
|
21
|
+
- vendor.css
|
22
|
+
- style.css
|
23
|
+
paths:
|
24
|
+
js: javascripts
|
25
|
+
css: stylesheets
|
26
|
+
images: images
|
27
|
+
templates: templates
|
28
|
+
fonts: stylesheets/fonts
|
29
|
+
static:
|
30
|
+
- images
|
31
|
+
- fonts
|
32
|
+
hull:
|
33
|
+
clientId: <%=ENV['CLIENT_ID']%>
|
34
|
+
appId: <%=ENV['APP_ID']%>
|
35
|
+
appSecret: <%=ENV['APP_SECRET']%>
|
36
|
+
|
37
|
+
development:
|
38
|
+
<<: *defaults
|
39
|
+
debug: true
|
40
|
+
|
41
|
+
test:
|
42
|
+
<<: *defaults
|
43
|
+
|
44
|
+
production:
|
45
|
+
<<: *defaults
|
46
|
+
livereload: false
|
47
|
+
google_analytics: <%=ENV['GA_CODE']%>
|
48
|
+
notifications:
|
49
|
+
sender: <%=ENV['NOTIFICATIONS_SENDER']%>
|
50
|
+
recipients:
|
51
|
+
- you@example.com
|
52
|
+
- me@example.com
|
53
|
+
- him@example.com
|