dugway 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (125) hide show
  1. data/.gitignore +7 -0
  2. data/.travis.yml +3 -0
  3. data/Gemfile +2 -0
  4. data/README.md +151 -0
  5. data/Rakefile +12 -0
  6. data/bin/dugway +7 -0
  7. data/dugway.gemspec +43 -0
  8. data/lib/dugway.rb +66 -0
  9. data/lib/dugway/application.rb +147 -0
  10. data/lib/dugway/cart.rb +144 -0
  11. data/lib/dugway/cli.rb +22 -0
  12. data/lib/dugway/cli/build.rb +56 -0
  13. data/lib/dugway/cli/create.rb +71 -0
  14. data/lib/dugway/cli/server.rb +37 -0
  15. data/lib/dugway/cli/templates/Gemfile.tt +2 -0
  16. data/lib/dugway/cli/templates/config.tt +24 -0
  17. data/lib/dugway/cli/templates/gitignore.tt +9 -0
  18. data/lib/dugway/cli/templates/source/cart.html +40 -0
  19. data/lib/dugway/cli/templates/source/checkout.html +33 -0
  20. data/lib/dugway/cli/templates/source/contact.html +37 -0
  21. data/lib/dugway/cli/templates/source/home.html +25 -0
  22. data/lib/dugway/cli/templates/source/images/badge.png +0 -0
  23. data/lib/dugway/cli/templates/source/javascripts/cart.js.coffee +7 -0
  24. data/lib/dugway/cli/templates/source/javascripts/product.js.coffee +7 -0
  25. data/lib/dugway/cli/templates/source/layout.html +101 -0
  26. data/lib/dugway/cli/templates/source/maintenance.html +20 -0
  27. data/lib/dugway/cli/templates/source/product.html +65 -0
  28. data/lib/dugway/cli/templates/source/products.html +25 -0
  29. data/lib/dugway/cli/templates/source/screenshot.jpg +0 -0
  30. data/lib/dugway/cli/templates/source/scripts.js +19 -0
  31. data/lib/dugway/cli/templates/source/settings.json +71 -0
  32. data/lib/dugway/cli/templates/source/styles.css +27 -0
  33. data/lib/dugway/cli/templates/source/stylesheets/cart.css.sass +38 -0
  34. data/lib/dugway/cli/templates/source/stylesheets/layout.css.sass +103 -0
  35. data/lib/dugway/cli/templates/source/stylesheets/product.css.sass +19 -0
  36. data/lib/dugway/cli/templates/source/stylesheets/products.css.sass +20 -0
  37. data/lib/dugway/cli/templates/source/stylesheets/vendor/normalize.css +396 -0
  38. data/lib/dugway/cli/templates/source/success.html +5 -0
  39. data/lib/dugway/controller.rb +148 -0
  40. data/lib/dugway/data/locales/cs.yml +26 -0
  41. data/lib/dugway/data/locales/da.yml +26 -0
  42. data/lib/dugway/data/locales/en-AU.yml +26 -0
  43. data/lib/dugway/data/locales/en-GB.yml +26 -0
  44. data/lib/dugway/data/locales/en-PH.yml +27 -0
  45. data/lib/dugway/data/locales/en-US.yml +26 -0
  46. data/lib/dugway/data/locales/es-MX.yml +26 -0
  47. data/lib/dugway/data/locales/eu.yml +26 -0
  48. data/lib/dugway/data/locales/gsw-CH.yml +26 -0
  49. data/lib/dugway/data/locales/hu.yml +26 -0
  50. data/lib/dugway/data/locales/il.yml +26 -0
  51. data/lib/dugway/data/locales/ja.yml +30 -0
  52. data/lib/dugway/data/locales/ms-MY.yml +26 -0
  53. data/lib/dugway/data/locales/nb.yml +22 -0
  54. data/lib/dugway/data/locales/pl.yml +27 -0
  55. data/lib/dugway/data/locales/pt-BR.yml +26 -0
  56. data/lib/dugway/data/locales/sv-SE.yml +26 -0
  57. data/lib/dugway/data/locales/th.yml +26 -0
  58. data/lib/dugway/data/locales/tr.yml +29 -0
  59. data/lib/dugway/data/locales/zh-TW.yml +30 -0
  60. data/lib/dugway/data/theme_fonts.yml +151 -0
  61. data/lib/dugway/extensions/time.rb +15 -0
  62. data/lib/dugway/liquid/drops/account_drop.rb +17 -0
  63. data/lib/dugway/liquid/drops/artist_drop.rb +9 -0
  64. data/lib/dugway/liquid/drops/artists_drop.rb +13 -0
  65. data/lib/dugway/liquid/drops/base_drop.rb +59 -0
  66. data/lib/dugway/liquid/drops/cart_drop.rb +13 -0
  67. data/lib/dugway/liquid/drops/cart_item_drop.rb +21 -0
  68. data/lib/dugway/liquid/drops/categories_drop.rb +13 -0
  69. data/lib/dugway/liquid/drops/category_drop.rb +9 -0
  70. data/lib/dugway/liquid/drops/contact_drop.rb +29 -0
  71. data/lib/dugway/liquid/drops/country_drop.rb +6 -0
  72. data/lib/dugway/liquid/drops/currency_drop.rb +6 -0
  73. data/lib/dugway/liquid/drops/image_drop.rb +6 -0
  74. data/lib/dugway/liquid/drops/page_drop.rb +13 -0
  75. data/lib/dugway/liquid/drops/pages_drop.rb +9 -0
  76. data/lib/dugway/liquid/drops/product_drop.rb +101 -0
  77. data/lib/dugway/liquid/drops/product_option_drop.rb +27 -0
  78. data/lib/dugway/liquid/drops/products_drop.rb +75 -0
  79. data/lib/dugway/liquid/drops/shipping_option_drop.rb +13 -0
  80. data/lib/dugway/liquid/drops/theme_drop.rb +23 -0
  81. data/lib/dugway/liquid/filters/comparison_filters.rb +48 -0
  82. data/lib/dugway/liquid/filters/core_filters.rb +138 -0
  83. data/lib/dugway/liquid/filters/default_pagination.rb +35 -0
  84. data/lib/dugway/liquid/filters/font_filters.rb +9 -0
  85. data/lib/dugway/liquid/filters/url_filters.rb +66 -0
  86. data/lib/dugway/liquid/filters/util_filters.rb +119 -0
  87. data/lib/dugway/liquid/tags/checkout_form.rb +9 -0
  88. data/lib/dugway/liquid/tags/get.rb +58 -0
  89. data/lib/dugway/liquid/tags/paginate.rb +129 -0
  90. data/lib/dugway/liquifier.rb +122 -0
  91. data/lib/dugway/logger.rb +16 -0
  92. data/lib/dugway/request.rb +36 -0
  93. data/lib/dugway/store.rb +166 -0
  94. data/lib/dugway/template.rb +44 -0
  95. data/lib/dugway/theme.rb +145 -0
  96. data/lib/dugway/theme_font.rb +68 -0
  97. data/lib/dugway/version.rb +3 -0
  98. data/spec/fixtures/store/page/about-us.js +1 -0
  99. data/spec/fixtures/store/products.js +1 -0
  100. data/spec/fixtures/store/store.js +1 -0
  101. data/spec/fixtures/theme/cart.html +33 -0
  102. data/spec/fixtures/theme/checkout.html +31 -0
  103. data/spec/fixtures/theme/contact.html +37 -0
  104. data/spec/fixtures/theme/home.html +38 -0
  105. data/spec/fixtures/theme/images/bc_badge.png +0 -0
  106. data/spec/fixtures/theme/javascripts/one.js +3 -0
  107. data/spec/fixtures/theme/javascripts/two.js.coffee +2 -0
  108. data/spec/fixtures/theme/layout.html +77 -0
  109. data/spec/fixtures/theme/maintenance.html +17 -0
  110. data/spec/fixtures/theme/product.html +73 -0
  111. data/spec/fixtures/theme/products.html +41 -0
  112. data/spec/fixtures/theme/screenshot.jpg +0 -0
  113. data/spec/fixtures/theme/scripts.js +2 -0
  114. data/spec/fixtures/theme/settings.json +55 -0
  115. data/spec/fixtures/theme/styles.css +4 -0
  116. data/spec/fixtures/theme/stylesheets/one.css +3 -0
  117. data/spec/fixtures/theme/stylesheets/two.css.sass +4 -0
  118. data/spec/fixtures/theme/success.html +5 -0
  119. data/spec/spec_helper.rb +24 -0
  120. data/spec/units/dugway/request_spec.rb +206 -0
  121. data/spec/units/dugway/store_spec.rb +194 -0
  122. data/spec/units/dugway/template_spec.rb +145 -0
  123. data/spec/units/dugway/theme_font_spec.rb +136 -0
  124. data/spec/units/dugway_spec.rb +9 -0
  125. metadata +549 -0
data/.gitignore ADDED
@@ -0,0 +1,7 @@
1
+ .DS_Store
2
+
3
+ Gemfile.lock
4
+
5
+ *.gem
6
+ *.tmproj
7
+ *.sublime*
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source :rubygems
2
+ gemspec
data/README.md ADDED
@@ -0,0 +1,151 @@
1
+ # Dugway [![Build Status](https://travis-ci.org/bigcartel/dugway.png)](https://travis-ci.org/bigcartel/dugway)
2
+
3
+ **_The easy way to build Big Cartel themes._**
4
+
5
+ Dugway allows you to run your Big Cartel theme on your computer, test it in any browser, write code in your favorite editor, and use fancy new tools like CoffeeScript, Sass, and LESS. It's awesome.
6
+
7
+ ## Disclaimer
8
+
9
+ **Dugway is a very new project and likely has several bugs, rough edges, and missing features.** If you run into something weird or have a cool idea, see if it's a [known issue](https://github.com/bigcartel/dugway/issues), and otherwise [report it](https://github.com/bigcartel/dugway/issues/new) and we'll do our best to hook you up. Thanks.
10
+
11
+ ## Install
12
+
13
+ Dugway is Ruby gem so you'll need to have Ruby installed. Ruby is usually pre-installed on Mac OS X and Linux, and Windows users can install it using [RubyInstaller](http://rubyinstaller.org). From there, simply install the **dugway** gem from the terminal.
14
+
15
+ gem install dugway
16
+
17
+ ## Creating a new theme
18
+
19
+ With Dugway installed, you can now create a new theme, simply give it a name.
20
+
21
+ dugway create mytheme
22
+
23
+ This will create a new directory named *mytheme* that contains a few configuration files and a starter theme to get you going.
24
+
25
+ mytheme
26
+ ├── source
27
+ │ ├── images
28
+ │ │ └── all image files for your theme
29
+ │ ├── javascripts
30
+ │ │ └── all JavaScript files for your theme
31
+ │ ├── stylesheets
32
+ │ │ └── all CSS files for your theme
33
+ │ ├── cart.html
34
+ │ ├── checkout.html
35
+ │ ├── contact.html
36
+ │ ├── home.html
37
+ │ ├── layout.html
38
+ │ ├── maintenance.html
39
+ │ ├── product.html
40
+ │ ├── products.html
41
+ │ ├── screenshot.jpg
42
+ │ ├── scripts.js
43
+ │ ├── settings.json
44
+ │ ├── styles.css
45
+ │ └── success.html
46
+ ├── config.ru
47
+ └── Gemfile
48
+
49
+
50
+ ## Developing your theme
51
+
52
+ All of the assets and source code for your theme goes in the **source** directory.
53
+
54
+ ### HTML
55
+
56
+ Develop the HTML for your theme using our [Theme API](http://help.bigcartel.com/customer/portal/articles/772788-creating-a-custom-theme). Barebones versions of all of the required HTML pages for your theme are provided by default, so feel free to expand on those or replace them entirely.
57
+
58
+ ### CSS & JavaScript
59
+
60
+ All CSS for your theme is handled by the **styles.css** file, and all JavaScript by **scripts.js**. If you don't have much CSS or JavaScript, or you're just a glutton for punishment, you could simply put all of your code in these two files. However, we recommend you use [Sprockets](http://getsprockets.org) to break your code into multiple files in separate directories.
61
+
62
+ #### Using Sprockets
63
+
64
+ [Sprockets](http://getsprockets.org) allows you to bring in CSS and JavaScript from different directories into a single file. We've created **stylesheets** and **javascripts** directories by default that you can put your code in, but you could delete those and put files anywhere you'd like. After that, use [Sprockets directives](https://github.com/sstephenson/sprockets#the-directive-processor) to package them into **styles.css** and **scripts.js**.
65
+
66
+ ##### styles.css
67
+
68
+ /*
69
+ *= require stylesheets/example_1
70
+ *= require stylesheets/example_2
71
+ */
72
+
73
+ ##### scripts.js
74
+
75
+ //= require javascripts/example_1
76
+ //= require javascripts/example_2
77
+
78
+ #### Using Sass, LESS, and CoffeeScript
79
+
80
+ Sprockets also allows you to use [Sass](http://sass-lang.com) in your separate files by appending the **.sass** or **.scss** extension after **.css**. Prefer [LESS](http://lesscss.org)? No problem, just append the **.less** extension instead. For you JavaScript folks, you can use [CoffeeScript](http://coffeescript.org) in your separate files by appending the **.coffee** extension after **.js**.
81
+
82
+ #### Embedding CSS & JavaScript
83
+
84
+ You can embed the CSS and JavaScript into your theme by passing the theme variable to the [theme_css_url](http://help.bigcartel.com/customer/portal/articles/772749-filters#url) and [theme_js_url](http://help.bigcartel.com/customer/portal/articles/772749-filters#url) filters.
85
+
86
+ ##### CSS (styles.css)
87
+
88
+ <link href="{{ theme | theme_css_url }}" media="screen" rel="stylesheet" type="text/css">
89
+
90
+ ##### JavaScript (scripts.js)
91
+
92
+ <script src="{{ theme | theme_js_url }}" type="text/javascript"></script>
93
+
94
+ ### Images
95
+
96
+ And as you've probably guessed by now, all images for your theme go in the **images** directory. You can reference an image in your code by passing its name to the [theme_image_url](http://help.bigcartel.com/customer/portal/articles/772749-filters#url) filter.
97
+
98
+ {{ 'sample.png' | theme_image_url }}
99
+
100
+ ### Settings
101
+
102
+ Set your theme's name, version, and customizable options in the **settings.json** file. We'll be documenting more about this soon, but for now see the starter file generated for you.
103
+
104
+ ## Running your theme
105
+
106
+ Run your theme in any browser by starting the Dugway server:
107
+
108
+ dugway server
109
+
110
+ By default this will serve your theme at http://0.0.0.0:9292. You can then stop the server by hitting CTRL+C.
111
+
112
+ ### Pow
113
+
114
+ Tired of all the manual starting and stopping? Good news, Dugway is built on top of Rack, which means you can use [Pow](http://pow.cx) on Mac. This also allows you to access your theme at a pretty URL like _mytheme.dev_.
115
+
116
+ ## Testing your theme
117
+
118
+ Part of building a great theme is making sure it works well in a variety of contexts and with a variety of content. Dugway makes it easy to test your theme's versatility by customizing the **options** in the **config.ru** file.
119
+
120
+ *Note:* changing the **config.ru** file will require you to restart the [server](#running-your-theme).
121
+
122
+ ### Store content
123
+
124
+ The best way to see your theme under a different light is by previewing it with a different store's products, categories, pages, currency, and other content. To do this, simply set the **:store** option to any Big Cartel store's subdomain, and Dugway will bring in their content using the standard [Big Cartel API](http://help.bigcartel.com/customer/portal/articles/772771-api). By default we use **dugway** for [dugway.bigcartel.com](http://dugway.bigcartel.com).
125
+
126
+ options[:store] = 'beeteeth'
127
+
128
+ *Note:* don't worry, any sensitive data like inventory levels and discount codes is faked by Dugway.
129
+
130
+ ### Store customization
131
+
132
+ Another important thing to consider is how store owners will customize your theme. You establish what can be customized in your [settings.json](#settings) file, and Dugway allows you to simulate potential values people could choose by setting them in the **:customization** option. By default we use the **default** values from your **[settings.json](#settings)** file.
133
+
134
+ options[:customization] = {
135
+ :logo => {
136
+ :url => 'http://placehold.it/200x50/000000/ffffff&text=My+Logo',
137
+ :width => 200,
138
+ :height => 50
139
+ },
140
+ :background_color => '#CCCCCC',
141
+ :show_search => true,
142
+ :twitter_username => 'mytwitter'
143
+ }
144
+
145
+ ## Building your theme
146
+
147
+ When you're finished with a new version of your theme, it's time to build it.
148
+
149
+ dugway build
150
+
151
+ This will create a zip file for the current version in your **build** directory containing all HTML, images, and packaged JS and CSS.
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+
4
+ require 'rake'
5
+ require 'rspec/core/rake_task'
6
+
7
+ desc "Run all examples"
8
+ RSpec::Core::RakeTask.new(:spec) do |t|
9
+ t.rspec_opts = %w[--color]
10
+ end
11
+
12
+ task :default => [:spec]
data/bin/dugway ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
4
+
5
+ require 'dugway/cli'
6
+
7
+ Dugway::Cli::Base.start
data/dugway.gemspec ADDED
@@ -0,0 +1,43 @@
1
+ # encoding: utf-8
2
+ $:.push File.expand_path('../lib', __FILE__)
3
+ require 'dugway/version'
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = 'dugway'
7
+ s.version = Dugway::VERSION
8
+ s.authors = ['Big Cartel']
9
+ s.email = 'dev@bigcartel.com'
10
+ s.homepage = 'https://github.com/bigcartel/dugway'
11
+ s.summary = 'Easily build and test Big Cartel themes locally.'
12
+ s.description = 'Easily build and test Big Cartel themes locally.'
13
+
14
+ s.files = `git ls-files`.split($\)
15
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
16
+ s.platform = Gem::Platform::RUBY
17
+ s.require_path = 'lib'
18
+ s.executable = 'dugway'
19
+
20
+ s.add_dependency('bundler', '~> 1.1')
21
+ s.add_dependency('rack', '~> 1.4.1')
22
+ s.add_dependency('rack-mount', '~> 0.8.3')
23
+ s.add_dependency('activesupport', '~> 3.2.6')
24
+ s.add_dependency('liquid', '~> 2.4.1')
25
+ s.add_dependency('therubyracer', '~> 0.11.3')
26
+ s.add_dependency('coffee-script', '~> 2.2.0')
27
+ s.add_dependency('sass', '~> 3.2.5')
28
+ s.add_dependency('less', '~> 2.2.2')
29
+ s.add_dependency('sprockets', '~> 2.0')
30
+ s.add_dependency('httparty', '~> 0.10.0')
31
+ s.add_dependency('better_errors', '~> 0.6.0')
32
+ s.add_dependency('binding_of_caller', '~> 0.7.1')
33
+ s.add_dependency('will_paginate', '~> 3.0.4')
34
+ s.add_dependency('i18n', '~> 0.6.1')
35
+ s.add_dependency('htmlentities', '~> 4.3.1')
36
+ s.add_dependency('thor', '~> 0.17.0')
37
+ s.add_dependency('rubyzip', '~> 0.9.9')
38
+ s.add_dependency('yui-compressor', '~> 0.9.6')
39
+
40
+ s.add_development_dependency('rake', '~> 10.0.3')
41
+ s.add_development_dependency('rspec', '~> 2.12.0')
42
+ s.add_development_dependency('webmock', '~> 1.9.3')
43
+ end
data/lib/dugway.rb ADDED
@@ -0,0 +1,66 @@
1
+ require 'active_support/all'
2
+ require 'i18n'
3
+
4
+ require 'rack/builder'
5
+ require 'rack/commonlogger'
6
+ require 'better_errors'
7
+
8
+ require 'dugway/version'
9
+ require 'dugway/application'
10
+ require 'dugway/cart'
11
+ require 'dugway/liquifier'
12
+ require 'dugway/logger'
13
+ require 'dugway/request'
14
+ require 'dugway/store'
15
+ require 'dugway/template'
16
+ require 'dugway/theme'
17
+ require 'dugway/theme_font'
18
+ require 'dugway/extensions/time'
19
+
20
+ module Dugway
21
+ class << self
22
+ def application(options={})
23
+ @logger = Logger.new if options[:log]
24
+ @source_dir = File.join(Dir.pwd, 'source')
25
+ @store = Store.new(options[:store] || 'dugway')
26
+ @theme = Theme.new(options[:customization] || {})
27
+ @cart = Cart.new
28
+
29
+ I18n.load_path += Dir[File.join(File.dirname(__FILE__), 'data', 'locales', '*.yml').to_s]
30
+ I18n.default_locale = 'en-US'
31
+ I18n.locale = Dugway.store.locale
32
+
33
+ Rack::Builder.app do
34
+ use Rack::Session::Cookie, :secret => 'stopwarningmeaboutnothavingasecret'
35
+ use BetterErrors::Middleware
36
+
37
+ if options[:log]
38
+ BetterErrors.logger = Dugway.logger
39
+ use Rack::CommonLogger, Dugway.logger
40
+ end
41
+
42
+ run Application.new
43
+ end
44
+ end
45
+
46
+ def store
47
+ @store
48
+ end
49
+
50
+ def theme
51
+ @theme
52
+ end
53
+
54
+ def cart
55
+ @cart
56
+ end
57
+
58
+ def source_dir
59
+ @source_dir
60
+ end
61
+
62
+ def logger
63
+ @logger
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,147 @@
1
+ require 'dugway/controller'
2
+
3
+ module Dugway
4
+ class Application < Controller
5
+ # Home
6
+
7
+ get '/' do
8
+ render_page
9
+ end
10
+
11
+ # Products
12
+
13
+ get '/products(.js)' do
14
+ if request.html?
15
+ render_page
16
+ elsif request.js?
17
+ render_json(store.products)
18
+ end
19
+ end
20
+
21
+ get '/category/:category(.js)' do
22
+ if category = store.category(params[:category])
23
+ if request.html?
24
+ page['name'] = category['name']
25
+ render_page(:category => category)
26
+ elsif request.js?
27
+ render_json(store.category_products(params[:category]))
28
+ end
29
+ else
30
+ render_not_found
31
+ end
32
+ end
33
+
34
+ get '/artist/:artist(.js)' do
35
+ if artist = store.artist(params[:artist])
36
+ if request.html?
37
+ page['name'] = artist['name']
38
+ render_page(:artist => artist)
39
+ elsif request.js?
40
+ render_json(store.artist_products(params[:artist]))
41
+ end
42
+ else
43
+ render_not_found
44
+ end
45
+ end
46
+
47
+ # Product
48
+
49
+ get '/product/:product(.js)' do
50
+ if product = store.product(params[:product])
51
+ if request.html?
52
+ page['name'] = product['name']
53
+ render_page(:product => product)
54
+ elsif request.js?
55
+ render_json(product)
56
+ end
57
+ else
58
+ render_not_found
59
+ end
60
+ end
61
+
62
+ # Cart
63
+
64
+ any '/cart(.js)' do
65
+ if cart_params = params[:cart].try(:with_indifferent_access)
66
+ cart.update(cart_params)
67
+ end
68
+
69
+ if params[:checkout]
70
+ redirect_to('/checkout')
71
+ else
72
+ if request.html?
73
+ render_page
74
+ elsif request.js?
75
+ render_json(cart)
76
+ end
77
+ end
78
+ end
79
+
80
+ # Checkout
81
+
82
+ any '/checkout' do
83
+ if cart.empty?
84
+ error('Must have at least one product to checkout')
85
+ redirect_to('/cart')
86
+ else
87
+ render_page
88
+ end
89
+ end
90
+
91
+ # Success
92
+
93
+ get '/success' do
94
+ render_page
95
+ end
96
+
97
+ post '/success' do
98
+ sleep(3) # Give the checkout page time
99
+ cart.reset
100
+ render_page
101
+ end
102
+
103
+ # Contact
104
+
105
+ get '/contact' do
106
+ render_page
107
+ end
108
+
109
+ post '/contact' do
110
+ if [ :name, :email, :subject, :message, :captcha ].any? { |f| params[f].blank? }
111
+ error('All fields are required')
112
+ elsif !(params[:email] =~ /^([^@\s]+)@((?:[-a-zA-Z0-9]+\.)+[a-zA-Z]{2,})$/)
113
+ error('Invalid email address')
114
+ elsif !(params[:captcha] =~ /^rQ9pC$/i)
115
+ error('Spam check was incorrect')
116
+ end
117
+
118
+ render_page
119
+ end
120
+
121
+ # Maintenance
122
+
123
+ get '/maintenance' do
124
+ render_page
125
+ end
126
+
127
+ # Custom page
128
+
129
+ get '/:permalink' do
130
+ render_page
131
+ end
132
+
133
+ # Assets
134
+
135
+ get '/styles.css' do
136
+ render_file('styles.css')
137
+ end
138
+
139
+ get '/scripts.js' do
140
+ render_file('scripts.js')
141
+ end
142
+
143
+ get %r{^/images/.+\.(jpg|jpeg|gif|png)$} do
144
+ Rack::File.new(Dugway.source_dir).call(request.env)
145
+ end
146
+ end
147
+ end