dugway 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
@@ -0,0 +1,144 @@
1
+ module Dugway
2
+ class Cart
3
+ attr_accessor :items
4
+
5
+ def initialize
6
+ reset
7
+ end
8
+
9
+ def reset
10
+ self.items = []
11
+ end
12
+
13
+ def item_count
14
+ items.map { |item| item.quantity }.inject(:+) || 0
15
+ end
16
+
17
+ def subtotal
18
+ items.map { |item| item.price }.inject(:+) || 0.0
19
+ end
20
+
21
+ def total
22
+ subtotal + shipping['amount'] + tax['amount'] - discount['amount']
23
+ end
24
+
25
+ def country
26
+ nil
27
+ end
28
+
29
+ def shipping
30
+ {
31
+ 'enabled' => false,
32
+ 'amount' => 0.0,
33
+ 'strict' => false,
34
+ 'pending' => false
35
+ }
36
+ end
37
+
38
+ def tax
39
+ {
40
+ 'enabled' => false,
41
+ 'amount' => 0.0
42
+ }
43
+ end
44
+
45
+ def discount
46
+ {
47
+ 'enabled' => false,
48
+ 'pending' => false,
49
+ 'amount' => 0.0
50
+ }
51
+ end
52
+
53
+ def update(params)
54
+ add, adds, updates = params.delete(:add), params.delete(:adds), params.delete(:update)
55
+ add_item(add) if add
56
+ add_item(adds) if adds
57
+ update_quantities(updates) if updates
58
+ end
59
+
60
+ def empty?
61
+ items.empty?
62
+ end
63
+
64
+ def as_json(options=nil)
65
+ {
66
+ :item_count => item_count,
67
+ :subtotal => subtotal,
68
+ :price => subtotal, # deprecated but need this for backwards JS compatibility
69
+ :total => total,
70
+ :items => items,
71
+ :country => country,
72
+ :shipping => shipping,
73
+ :discount => discount
74
+ }
75
+ end
76
+
77
+ private
78
+
79
+ def add_item(add)
80
+ id = add[:id].to_i
81
+
82
+ unless item = items.find { |i| i.option['id'] == id.to_i }
83
+ product, option = Dugway.store.product_and_option(id)
84
+
85
+ if product && option
86
+ item = CartItem.new
87
+ item.id = items.size + 1
88
+ item.name = option['name'] == 'Default' ? product['name'] : "#{ product['name'] } - #{ option['name'] }"
89
+ item.unit_price = option['price']
90
+ item.product = product
91
+ item.option = option
92
+ item.quantity = 0
93
+
94
+ items << item
95
+ end
96
+ end
97
+
98
+ if item
99
+ item.quantity += add[:quantity] ? add[:quantity].to_i : 1
100
+ end
101
+
102
+ item
103
+ end
104
+
105
+ def add_items(adds)
106
+ if adds.kind_of?(Array)
107
+ adds.each { |add| add_item(add) }
108
+ elsif adds.kind_of?(Hash)
109
+ adds.each_pair { |key, add| add_item(add.reverse_merge(:id => key)) }
110
+ end
111
+ end
112
+
113
+ def update_quantities(updates)
114
+ updates.each_pair { |id, qty|
115
+ if item = items.find { |i| i.id == id.to_i }
116
+ item.quantity = qty.to_i
117
+ end
118
+ }
119
+
120
+ items.reject! { |item| item.quantity == 0 }
121
+ end
122
+ end
123
+
124
+ CartItem = Struct.new(:id, :name, :unit_price, :quantity, :product, :option) do
125
+ def price
126
+ unit_price * quantity
127
+ end
128
+
129
+ def as_json(options=nil)
130
+ {
131
+ :id => id,
132
+ :name => name,
133
+ :price => price,
134
+ :unit_price => unit_price,
135
+ :shipping => 0.0,
136
+ :tax => 0.0,
137
+ :total => price,
138
+ :quantity => quantity,
139
+ :product => product['permalink'],
140
+ :option => option['id']
141
+ }
142
+ end
143
+ end
144
+ end
data/lib/dugway/cli.rb ADDED
@@ -0,0 +1,22 @@
1
+ require 'thor'
2
+ require 'active_support/all'
3
+
4
+ require 'dugway'
5
+ require 'dugway/cli/build'
6
+ require 'dugway/cli/create'
7
+ require 'dugway/cli/server'
8
+
9
+ module Dugway
10
+ module Cli
11
+ class Base < Thor
12
+ register Create, 'create', 'create', 'Create a new Big Cartel theme'
13
+ register Build, 'build', 'build', 'Build your Big Cartel theme for use'
14
+ register Server, 'server', 'server', 'Run your Big Cartel theme in the browser'
15
+
16
+ desc 'version', 'Show version of Dugway'
17
+ def version
18
+ say "Dugway #{ Dugway::VERSION }"
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,56 @@
1
+ require 'zip/zip'
2
+
3
+ module Dugway
4
+ module Cli
5
+ class Build < Thor::Group
6
+ include Thor::Actions
7
+
8
+ def self.source_root
9
+ File.join(Dir.pwd, 'source')
10
+ end
11
+
12
+ def self.destination_root
13
+ File.join(Dir.pwd, 'build')
14
+ end
15
+
16
+ def validate
17
+ unless theme.valid?
18
+ theme.errors.each { |error| say(error, :red) }
19
+ raise "Theme is invalid"
20
+ end
21
+ end
22
+
23
+ def create_destination
24
+ empty_directory self.class.destination_root
25
+ end
26
+
27
+ def build
28
+ Zip::ZipFile.open(build_file, Zip::ZipFile::CREATE) { |zipfile|
29
+ theme.files.each { |file|
30
+ zipfile.get_output_stream(file) { |f|
31
+ f << theme.build_file(file)
32
+ }
33
+ }
34
+ }
35
+ end
36
+
37
+ def success
38
+ say_status(:create, "build/#{ build_name }")
39
+ end
40
+
41
+ private
42
+
43
+ def theme
44
+ @theme ||= Theme.new(self.class.source_root)
45
+ end
46
+
47
+ def build_name
48
+ @build_name ||= "#{ theme.name.parameterize }-#{ theme.version }.zip"
49
+ end
50
+
51
+ def build_file
52
+ @build_file ||= File.join(self.class.destination_root, build_name)
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,71 @@
1
+ module Dugway
2
+ module Cli
3
+ class Create < Thor::Group
4
+ include Thor::Actions
5
+
6
+ argument :name
7
+
8
+ class_option 'skip-source',
9
+ :type => :boolean,
10
+ :default => false,
11
+ :desc => "Don't create a starter theme"
12
+
13
+ class_option 'skip-git',
14
+ :type => :boolean,
15
+ :default => false,
16
+ :desc => "Don't create a .gitignore file"
17
+
18
+ class_option 'skip-bundle',
19
+ :type => :boolean,
20
+ :default => false,
21
+ :desc => "Don't run bundle install"
22
+
23
+ def self.source_root
24
+ File.join(File.dirname(__FILE__), 'templates')
25
+ end
26
+
27
+ def core
28
+ template('Gemfile.tt', "#{ theme_dir }/Gemfile")
29
+ template('config.tt', "#{ theme_dir }/config.ru")
30
+ template('source/settings.json', "#{ source_dir }/settings.json")
31
+ end
32
+
33
+ def source
34
+ unless options['skip-source']
35
+ Dir.glob("#{ self.class.source_root }/source/**/*.{html,jpg,png,js,coffee,css,sass}") do |file|
36
+ file_name = file.gsub("#{ self.class.source_root }/source/", '')
37
+ copy_file "source/#{ file_name }", "#{ source_dir }/#{ file_name }"
38
+ end
39
+ end
40
+ end
41
+
42
+ def git
43
+ unless options['skip-git']
44
+ copy_file('gitignore.tt', "#{ theme_dir }/.gitignore")
45
+ end
46
+ end
47
+
48
+ def bundle
49
+ unless options['skip-bundle']
50
+ inside theme_dir, {} do
51
+ run('bundle install --without development test')
52
+ end
53
+ end
54
+ end
55
+
56
+ def done
57
+ say("#{ name } is ready!", :blue)
58
+ end
59
+
60
+ private
61
+
62
+ def theme_dir
63
+ name.parameterize
64
+ end
65
+
66
+ def source_dir
67
+ "#{ theme_dir }/source"
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,37 @@
1
+ require 'rack'
2
+
3
+ module Dugway
4
+ module Cli
5
+ class Server < Thor::Group
6
+ include Thor::Actions
7
+
8
+ class_option :host,
9
+ :type => :string,
10
+ :aliases => '-h',
11
+ :default => '0.0.0.0',
12
+ :desc => 'The host address to bind to'
13
+
14
+ class_option :port,
15
+ :type => :numeric,
16
+ :aliases => '-p',
17
+ :default => 9292,
18
+ :desc => "The port address to bind to"
19
+
20
+ class_option :daemonize,
21
+ :type => :boolean,
22
+ :aliases => '-d',
23
+ :default => false,
24
+ :desc => "Run daemonized in the background"
25
+
26
+ def start
27
+ Rack::Server.start({
28
+ :config => File.join(Dir.pwd, 'config.ru'),
29
+ :environment => 'none',
30
+ :Host => options[:host],
31
+ :Port => options[:port],
32
+ :daemonize => options[:daemonize]
33
+ })
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,2 @@
1
+ source :rubygems
2
+ gem 'dugway'
@@ -0,0 +1,24 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'dugway'
4
+
5
+ options = {}
6
+
7
+ # Use data from any store to make sure your theme looks great with all sorts of products, pages,
8
+ # categories, and more. Just give us the subdomain. Default is "dugway" for dugway.bigcartel.com.
9
+ # options[:store] = 'mystore'
10
+
11
+ # Simulate the customization done by store owners by passing values to different variables.
12
+ # Default values are based on the "default" for each setting in your settings.json.
13
+ # options[:customization] = {
14
+ # :logo => {
15
+ # :url => 'http://placehold.it/200x50/000000/ffffff&text=My+Logo',
16
+ # :width => 200,
17
+ # :height => 50
18
+ # },
19
+ # :background_color => '#CCCCCC',
20
+ # :show_search => true,
21
+ # :twitter_username => 'mytwitter'
22
+ # }
23
+
24
+ run Dugway.application(options)
@@ -0,0 +1,9 @@
1
+ .DS_Store
2
+
3
+ build
4
+ tmp
5
+ log
6
+
7
+ *.tmproj
8
+ *.esproj
9
+ *.sublime*
@@ -0,0 +1,40 @@
1
+ {% if cart.items != blank %}
2
+
3
+ <form method="post" action="/cart">
4
+ <ul>
5
+ {% for item in cart.items %}
6
+ <li>
7
+ <a href="{{ item.product.url }}">
8
+ <img src="{{ item.product.image | product_image_url size:"thumb" }}">
9
+ </a>
10
+ <h2>
11
+ <a href="{{ item.product.url }}">
12
+ {{ item.product.name }}
13
+ {% unless item.product.has_default_option %}
14
+ <em>{{ item.option.name }}</em>
15
+ {% endunless %}
16
+ </a>
17
+ </h2>
18
+ <p>
19
+ {{ item | item_quantity_input }}
20
+ {{ item.price | money_with_sign }}
21
+ <a href="#" class="remove">&times;</a>
22
+ </p>
23
+ </li>
24
+ {% endfor %}
25
+ </ul>
26
+
27
+ <p>
28
+ <strong>Subtotal</strong>
29
+ <span>{{ cart.subtotal | money_with_sign }}</span>
30
+ </p>
31
+ <button type="submit" name="checkout" title="Checkout">Checkout</button>
32
+ </form>
33
+
34
+ {% else %}
35
+
36
+ <div>
37
+ <p><strong>Your cart is empty!</strong> Sounds like a good time to <a href="/">start shopping &rarr;</a></p>
38
+ </div>
39
+
40
+ {% endif %}
@@ -0,0 +1,33 @@
1
+ <!DOCTYPE html>
2
+ <head>
3
+ <title>{{ store.name }} &mdash; {{ page.name }}</title>
4
+
5
+ <meta charset="utf-8">
6
+ <meta name="description" content="{{ page.meta_description }}">
7
+ <meta name="keywords" content="{{ page.meta_keywords }}">
8
+
9
+ <link href="{{ theme | theme_css_url }}" media="screen" rel="stylesheet" type="text/css">
10
+
11
+ <script type="text/javascript" charset="utf-8">
12
+ function checkout() {
13
+ if(top != self) {
14
+ top.location.replace(self.location.href);
15
+ } else {
16
+ document.checkout_form.submit();
17
+ }
18
+ }
19
+ </script>
20
+
21
+ {{ head_content }}
22
+ </head>
23
+
24
+ <body id="{{ page.permalink }}" class="{{ page.category }}" onload="checkout();">
25
+ <h1>One moment&hellip;</h1>
26
+
27
+ {% checkoutform %}
28
+ <noscript>
29
+ <button type="submit" name="checkout" title="Checkout">Checkout</button>
30
+ </noscript>
31
+ {% endcheckoutform %}
32
+ </body>
33
+ </html>