quickdraw 0.0.2 → 0.0.3
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.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/lib/quickdraw/cli.rb +177 -36
- data/lib/quickdraw/shopify_connector.rb +64 -23
- data/lib/quickdraw/shopify_connector_pool.rb +20 -5
- data/lib/quickdraw/version.rb +1 -1
- data/lib/quickdraw.rb +10 -42
- data/quickdraw.gemspec +1 -0
- metadata +15 -2
- data/lib/auto_compile.rb +0 -53
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: df5b795af0421fe99f0dff6b95e98c966c50f902
|
4
|
+
data.tar.gz: bcb1b8d1b9f20693f925fcad431dbade546606ce
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ddec59e718913624a38977ba8a1320de0c3931438f83d22c61e8697cb1f772aa9d2103b1f92efba15732ffd833d8e2317160c4de002c1ac4c7330d9b2bd6feb9
|
7
|
+
data.tar.gz: c1f685f5aa1c0630fad2c5637cb29c077f4050f496f1b64096d063899b46f0947f63b78b77e4e2e73501e016ca7ac427f70eae2c311dea922700e5a1c1a2ef47
|
data/README.md
CHANGED
@@ -4,7 +4,7 @@ The idea for Quickdraw comes from the 'shopify_theme' gem. I use a lot of code f
|
|
4
4
|
|
5
5
|
### Features
|
6
6
|
|
7
|
-
- MUCH faster downloads and uploads.
|
7
|
+
- MUCH faster downloads and uploads. Unfortunately, Shopify API call limits will slow you down. But in short bursts (10-20 files), Quickdraw is as much as 10x faster or more!
|
8
8
|
|
9
9
|
## Installation
|
10
10
|
|
data/lib/quickdraw/cli.rb
CHANGED
@@ -8,6 +8,8 @@ require 'thor'
|
|
8
8
|
require 'listen'
|
9
9
|
#require 'launchy'
|
10
10
|
require 'benchmark'
|
11
|
+
require 'pathname'
|
12
|
+
require 'filepath'
|
11
13
|
|
12
14
|
module Quickdraw
|
13
15
|
class Cli < Thor
|
@@ -18,74 +20,213 @@ module Quickdraw
|
|
18
20
|
DEFAULT_WHITELIST = %w(layout/ assets/ config/ snippets/ templates/)
|
19
21
|
TIMEFORMAT = "%H:%M:%S"
|
20
22
|
|
21
|
-
desc "
|
22
|
-
|
23
|
-
|
23
|
+
desc "configure API_KEY PASSWORD STORE THEME_ID", "generate a config file for the store to connect to"
|
24
|
+
def configure(api_key=nil, password=nil, store=nil, theme_id=nil)
|
25
|
+
config = {:api_key => api_key, :password => password, :store => store, :theme_id => theme_id}
|
26
|
+
create_file('config.yml', config.to_yaml)
|
27
|
+
end
|
24
28
|
|
25
|
-
|
29
|
+
desc "upload FILES", "upload all theme assets to shop"
|
30
|
+
def upload(filter=nil)
|
26
31
|
|
27
|
-
if filter
|
28
|
-
assets =
|
32
|
+
if filter
|
33
|
+
assets = (FilePath.getwd / 'theme').files(true).select{ |i|
|
34
|
+
i.relative_to(Quickdraw.theme_dir).to_s[/^#{filter.gsub(/[^a-z0-9A-Z\/]/, '')}/]
|
35
|
+
}
|
29
36
|
else
|
30
|
-
assets =
|
37
|
+
assets = (FilePath.getwd / 'theme').files(true)
|
31
38
|
end
|
32
39
|
|
33
40
|
futures = []
|
41
|
+
assets.each do |asset|
|
42
|
+
futures << Celluloid::Actor[:shopify_connector].future.upload_asset(asset)
|
43
|
+
end
|
44
|
+
futures.each do |future|
|
45
|
+
asset, response = future.value
|
46
|
+
if response.success?
|
47
|
+
say("Uploaded: #{asset.relative_to(Quickdraw.getwd)}", :green)
|
48
|
+
else
|
49
|
+
say("[" + Time.now.strftime(TIMEFORMAT) + "] Error: Could not upload #{asset.relative_to(Quickdraw.getwd)}. #{errors_from_response(response)}\n", :red)
|
50
|
+
end
|
51
|
+
end
|
34
52
|
|
53
|
+
say("Done.", :green)
|
54
|
+
end
|
55
|
+
|
56
|
+
desc "download FILES", "download the shops current theme assets"
|
57
|
+
def download(filter=nil)
|
58
|
+
asset_list = Celluloid::Actor[:shopify_connector].get_asset_list
|
59
|
+
|
60
|
+
if filter
|
61
|
+
assets = asset_list.select{ |i| i[/^#{filter.gsub(/[^a-z0-9A-Z\/]/, '')}/] }.map{|a| FilePath.getwd / 'theme' / a }
|
62
|
+
else
|
63
|
+
assets = asset_list.map{|a| FilePath.getwd / 'theme' / a }
|
64
|
+
end
|
65
|
+
|
66
|
+
futures = []
|
35
67
|
assets.each do |asset|
|
36
68
|
futures << Celluloid::Actor[:shopify_connector].future.download_asset(asset)
|
37
69
|
end
|
38
|
-
|
39
70
|
futures.each do |future|
|
40
|
-
|
71
|
+
asset, response = future.value
|
72
|
+
if response.success?
|
73
|
+
say("Downloaded: #{asset.relative_to(Quickdraw.getwd)}", :green)
|
74
|
+
else
|
75
|
+
say("[" + Time.now.strftime(TIMEFORMAT) + "] Error: Could not download #{asset.relative_to(Quickdraw.getwd)}. #{errors_from_response(response)}\n", :red)
|
76
|
+
end
|
41
77
|
end
|
78
|
+
say("Done.", :green)
|
79
|
+
end
|
80
|
+
|
81
|
+
desc "replace FILES", "completely replace shop theme assets with local theme assets"
|
82
|
+
def replace(filter=nil)
|
83
|
+
say("Are you sure you want to completely replace your shop theme assets? This is not undoable.", :yellow)
|
84
|
+
if ask("Continue? (y/n): ") == "y"
|
85
|
+
# only delete files on remote that are not present locally
|
86
|
+
# files present on remote and present locally get overridden anyway
|
87
|
+
asset_list = Celluloid::Actor[:shopify_connector].get_asset_list
|
88
|
+
|
89
|
+
if filter
|
90
|
+
remote_assets = asset_list.select{ |i| i[/^#{filter.gsub(/[^a-z0-9A-Z\/]/, '')}/] }.map{|a| (FilePath.getwd / 'theme' / a) }
|
91
|
+
else
|
92
|
+
remote_assets = asset_list.map{|a| (FilePath.getwd / 'theme' / a) }
|
93
|
+
end
|
94
|
+
|
95
|
+
if filter
|
96
|
+
local_assets = (FilePath.getwd / 'theme').files(true).select{ |i| i.relative_to(Quickdraw.theme_dir).to_s[/^#{filter.gsub(/[^a-z0-9A-Z\/]/, '')}/] }
|
97
|
+
else
|
98
|
+
local_assets = (FilePath.getwd / 'theme').files(true)
|
99
|
+
end
|
42
100
|
|
101
|
+
remote_only_assets = remote_assets.to_a.map{|p| p.to_s} - local_assets.to_a.map{|p| p.to_s}
|
102
|
+
|
103
|
+
futures = []
|
104
|
+
remote_only_assets.each do |asset|
|
105
|
+
futures << Celluloid::Actor[:shopify_connector].future.remove_asset(asset.as_path)
|
106
|
+
end
|
107
|
+
local_assets.each do |asset|
|
108
|
+
futures << Celluloid::Actor[:shopify_connector].future.upload_asset(asset)
|
109
|
+
end
|
110
|
+
futures.each do |future|
|
111
|
+
asset, response = future.value
|
112
|
+
if response.success?
|
113
|
+
if response.request.http_method.to_s == "Net::HTTP::Put"
|
114
|
+
say("Uploaded: #{asset.relative_to(Quickdraw.getwd)}", :green)
|
115
|
+
else
|
116
|
+
say("Removed: #{asset.relative_to(Quickdraw.getwd)}", :green)
|
117
|
+
end
|
118
|
+
else
|
119
|
+
say("[" + Time.now.strftime(TIMEFORMAT) + "] Error: Could not download #{asset.relative_to(Quickdraw.getwd)}. #{errors_from_response(response)}\n", :red)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
say("Done.", :green) unless options['quiet']
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
desc "remove FILES", "remove theme asset"
|
127
|
+
def remove(filter=nil)
|
128
|
+
asset_list = Celluloid::Actor[:shopify_connector].get_asset_list
|
129
|
+
|
130
|
+
if filter
|
131
|
+
assets = asset_list.select{ |i| i[/^#{filter.gsub(/[^a-z0-9A-Z\/]/, '')}/] }.map{|a| FilePath.getwd / 'theme' / a }
|
132
|
+
else
|
133
|
+
assets = asset_list.map{|a| FilePath.getwd / 'theme' / a }
|
134
|
+
end
|
135
|
+
|
136
|
+
futures = []
|
137
|
+
assets.each do |asset|
|
138
|
+
futures << Celluloid::Actor[:shopify_connector].future.remove_asset(asset)
|
139
|
+
end
|
140
|
+
futures.each do |future|
|
141
|
+
asset, response = future.value
|
142
|
+
if response.success?
|
143
|
+
say("Deleted: #{asset.relative_to(Quickdraw.getwd)}", :green)
|
144
|
+
else
|
145
|
+
say("[" + Time.now.strftime(TIMEFORMAT) + "] Error: Could not remove #{asset.relative_to(Quickdraw.getwd)}. #{errors_from_response(response)}\n", :red)
|
146
|
+
end
|
147
|
+
end
|
43
148
|
say("Done.", :green) unless options['quiet']
|
44
149
|
end
|
45
150
|
|
46
|
-
desc "watch", "compile then upload
|
47
|
-
#method_option :quiet, :type => :boolean, :default => false
|
48
|
-
#method_option :keep_files, :type => :boolean, :default => false
|
151
|
+
desc "watch", "compile then upload or delete individual theme assets as they change."
|
49
152
|
def watch
|
50
153
|
puts "Watching current folder: #{Dir.pwd}"
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
154
|
+
|
155
|
+
futures = []
|
156
|
+
|
157
|
+
listener = Listen.to((Quickdraw.getwd/'theme').to_s, (Quickdraw.getwd/'src').to_s, :force_polling => true, :latency => 0.2 ) do |modified, added, removed|
|
158
|
+
modified.each do |asset|
|
159
|
+
asset = asset.as_path
|
160
|
+
say("MODIFIED: #{asset.relative_to(Quickdraw.getwd)}", :green)
|
161
|
+
if theme_file?(asset)
|
162
|
+
futures << Celluloid::Actor[:shopify_connector].future.upload_asset(asset)
|
163
|
+
elsif src_file?(asset)
|
164
|
+
futures << Celluloid::Actor[:shopify_connector].future.compile_asset(asset)
|
165
|
+
end
|
55
166
|
end
|
56
|
-
added.each do |
|
57
|
-
|
58
|
-
|
167
|
+
added.each do |asset|
|
168
|
+
asset = asset.as_path
|
169
|
+
say("ADDED: #{asset}", :green)
|
170
|
+
if theme_file?(asset)
|
171
|
+
futures << Celluloid::Actor[:shopify_connector].future.upload_asset(asset)
|
172
|
+
else
|
173
|
+
end
|
59
174
|
end
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
175
|
+
removed.each do |asset|
|
176
|
+
asset = asset.as_path
|
177
|
+
say("REMOVED: #{asset}", :green)
|
178
|
+
if theme_file?(asset)
|
179
|
+
futures << Celluloid::Actor[:shopify_connector].future.remove_asset(asset)
|
180
|
+
else
|
64
181
|
end
|
65
182
|
end
|
66
183
|
end
|
67
184
|
listener.start
|
68
|
-
|
185
|
+
|
186
|
+
loop do
|
187
|
+
|
188
|
+
futures.each do |future|
|
189
|
+
asset, response = future.value
|
190
|
+
if response
|
191
|
+
unless response.success?
|
192
|
+
say("[" + Time.now.strftime(TIMEFORMAT) + "] Error: #{asset.relative_to(Quickdraw.getwd)} Failed", :red)
|
193
|
+
end
|
194
|
+
else
|
195
|
+
say("Compiled: #{asset.relative_to(Quickdraw.getwd)}")
|
196
|
+
end
|
197
|
+
futures.delete(future)
|
198
|
+
end
|
199
|
+
|
200
|
+
sleep 0.2
|
201
|
+
end
|
202
|
+
|
69
203
|
rescue
|
70
204
|
puts "exiting...."
|
71
205
|
end
|
72
206
|
|
73
207
|
private
|
74
208
|
|
75
|
-
def
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
209
|
+
def errors_from_response(response)
|
210
|
+
return unless response.parsed_response
|
211
|
+
|
212
|
+
errors = response.parsed_response["errors"]
|
213
|
+
|
214
|
+
case errors
|
215
|
+
when NilClass
|
216
|
+
''
|
217
|
+
when String
|
218
|
+
errors
|
219
|
+
else
|
220
|
+
errors.values.join(", ")
|
85
221
|
end
|
222
|
+
end
|
223
|
+
|
224
|
+
def theme_file?(asset)
|
225
|
+
asset.as_path.relative_to(Quickdraw.getwd).to_s[/^theme\//]
|
226
|
+
end
|
86
227
|
|
87
|
-
|
88
|
-
|
228
|
+
def src_file?(asset)
|
229
|
+
asset.as_path.relative_to(Quickdraw.getwd).to_s[/^src\//]
|
89
230
|
end
|
90
231
|
|
91
232
|
end
|
@@ -2,29 +2,26 @@
|
|
2
2
|
require 'httparty'
|
3
3
|
require 'celluloid'
|
4
4
|
require 'pathname'
|
5
|
+
require 'filepath'
|
5
6
|
|
6
7
|
module Quickdraw
|
7
8
|
class ShopifyConnector
|
8
9
|
include Celluloid
|
9
10
|
|
10
11
|
NOOPParser = Proc.new {|data, format| {} }
|
12
|
+
BINARY_EXTENSIONS = %w(png gif jpg jpeg eot svg ttf woff otf swf ico)
|
13
|
+
IGNORE = %w(config.yml)
|
14
|
+
DEFAULT_WHITELIST = %w(layout/ assets/ config/ snippets/ templates/)
|
15
|
+
TIMEFORMAT = "%H:%M:%S"
|
11
16
|
|
12
17
|
def initialize
|
13
18
|
@config = Quickdraw.config
|
14
|
-
@auth = {:username => @config[:
|
15
|
-
end
|
16
|
-
|
17
|
-
def get(path, options={})
|
18
|
-
options.merge!({:basic_auth => @auth})
|
19
|
-
|
20
|
-
response = Celluloid::Actor[:shopify_connector_pool].get(path, options)
|
21
|
-
|
22
|
-
return response
|
19
|
+
@auth = {:username => @config[:api_key], :password => @config[:password]}
|
23
20
|
end
|
24
21
|
|
25
22
|
def get_asset_list(options={})
|
26
23
|
options.merge!({:parser => NOOPParser})
|
27
|
-
response = get
|
24
|
+
response = Celluloid::Actor[:shopify_connector_pool].request(:get, "https://#{@config[:store]}/admin/themes/#{@config[:theme_id]}/assets.json", options)
|
28
25
|
|
29
26
|
if JSON.parse(response.body)["assets"]
|
30
27
|
return JSON.parse(response.body)["assets"].collect {|a| a['key'] }
|
@@ -33,31 +30,75 @@ module Quickdraw
|
|
33
30
|
return nil
|
34
31
|
end
|
35
32
|
|
36
|
-
def
|
37
|
-
|
33
|
+
def upload_asset(asset)
|
34
|
+
time = Time.now
|
35
|
+
data = {:key => asset.relative_to(Quickdraw.theme_dir).to_s}
|
36
|
+
|
37
|
+
content = File.read(asset)
|
38
|
+
if BINARY_EXTENSIONS.include?(File.extname(asset).gsub('.','')) || is_binary_data?(content)
|
39
|
+
content = File.open(asset, "rb") { |io| io.read }
|
40
|
+
data.merge!(:attachment => Base64.encode64(content))
|
41
|
+
else
|
42
|
+
data.merge!(:value => content)
|
43
|
+
end
|
44
|
+
|
45
|
+
data = {:body => {:asset => data}}
|
46
|
+
|
47
|
+
response = Celluloid::Actor[:shopify_connector_pool].request(:put, "https://#{@config[:store]}/admin/themes/#{@config[:theme_id]}/assets.json", data)
|
48
|
+
|
49
|
+
return [asset, response]
|
50
|
+
end
|
51
|
+
|
52
|
+
def download_asset(asset, options={})
|
53
|
+
options.merge!({:query => {:asset => {:key => asset.relative_to(Quickdraw.theme_dir).to_s}}, :parser => NOOPParser})
|
38
54
|
|
39
|
-
response = get
|
55
|
+
response = Celluloid::Actor[:shopify_connector_pool].request(:get, "https://#{@config[:store]}/admin/themes/#{@config[:theme_id]}/assets.json", options)
|
40
56
|
|
41
57
|
# HTTParty json parsing is broken?
|
42
|
-
|
43
|
-
|
58
|
+
data = response.code == 200 ? JSON.parse(response.body)["asset"] : {}
|
59
|
+
data['response'] = response
|
44
60
|
|
45
|
-
if
|
61
|
+
if data['value']
|
46
62
|
# For CRLF line endings
|
47
|
-
content =
|
63
|
+
content = data['value'].gsub("\r", "")
|
48
64
|
format = "w"
|
49
|
-
elsif
|
50
|
-
content = Base64.decode64(
|
65
|
+
elsif data['attachment']
|
66
|
+
content = Base64.decode64(data['attachment'])
|
51
67
|
format = "w+b"
|
52
68
|
end
|
53
69
|
|
54
|
-
|
70
|
+
FileUtils.mkdir_p(File.dirname(asset))
|
71
|
+
File.open(asset, format) {|f| f.write content} if content
|
55
72
|
|
56
|
-
|
57
|
-
|
73
|
+
return [asset, response]
|
74
|
+
end
|
75
|
+
|
76
|
+
def remove_asset(asset, options={})
|
77
|
+
options.merge!({:body => {:asset => {:key => asset.relative_to(Quickdraw.theme_dir).to_s}}})
|
78
|
+
|
79
|
+
response = Celluloid::Actor[:shopify_connector_pool].request(:delete, "https://#{@config[:store]}/admin/themes/#{@config[:theme_id]}/assets.json", options)
|
58
80
|
|
59
|
-
return
|
81
|
+
return [asset, response]
|
82
|
+
end
|
83
|
+
|
84
|
+
def is_binary_data?(string)
|
85
|
+
if string.respond_to?(:encoding)
|
86
|
+
string.encoding == "US-ASCII"
|
87
|
+
else
|
88
|
+
( string.count( "^ -~", "^\r\n" ).fdiv(string.size) > 0.3 || string.index( "\x00" ) ) unless string.empty?
|
89
|
+
end
|
60
90
|
end
|
91
|
+
|
92
|
+
def compile_asset(asset)
|
93
|
+
if File.exists?(asset.to_s)
|
94
|
+
target_asset = "theme/#{asset.relative_to(Quickdraw.src_dir).to_s.gsub('.erb', '')}"
|
95
|
+
template = ERB.new(File.read(asset))
|
96
|
+
File.write("#{target_asset}", template.result)
|
97
|
+
end
|
98
|
+
|
99
|
+
return [asset, nil]
|
100
|
+
end
|
101
|
+
|
61
102
|
end
|
62
103
|
|
63
104
|
ShopifyConnector.supervise_as(:shopify_connector)
|
@@ -1,18 +1,25 @@
|
|
1
1
|
|
2
2
|
require 'httparty'
|
3
3
|
require 'celluloid'
|
4
|
+
require 'filepath'
|
4
5
|
|
5
6
|
module Quickdraw
|
6
7
|
class ShopifyConnectorPool
|
7
8
|
include HTTParty
|
8
9
|
include Celluloid
|
9
10
|
|
10
|
-
def
|
11
|
+
def initialize
|
12
|
+
@config = Quickdraw.config
|
13
|
+
@auth = {:username => @config[:api_key], :password => @config[:password]}
|
14
|
+
end
|
15
|
+
|
16
|
+
def request(call_type, path, options)
|
17
|
+
options.merge!({:basic_auth => @auth})
|
11
18
|
|
12
19
|
begin
|
13
20
|
tries ||= 3
|
14
21
|
|
15
|
-
response = HTTParty.
|
22
|
+
response = HTTParty.send(call_type, path, options)
|
16
23
|
|
17
24
|
if response.code == 429
|
18
25
|
tries += 1
|
@@ -20,14 +27,22 @@ module Quickdraw
|
|
20
27
|
raise "Slow down!"
|
21
28
|
end
|
22
29
|
|
30
|
+
if response.code == 403
|
31
|
+
tries == 0
|
32
|
+
raise "Forbidden"
|
33
|
+
end
|
34
|
+
|
23
35
|
if response.code != 200
|
24
36
|
puts response.inspect
|
25
37
|
raise "Request Failed"
|
26
38
|
end
|
27
39
|
|
28
40
|
rescue => e
|
29
|
-
|
30
|
-
|
41
|
+
tries -= 1
|
42
|
+
if tries > 0
|
43
|
+
sleep 1
|
44
|
+
retry
|
45
|
+
end
|
31
46
|
end
|
32
47
|
|
33
48
|
return response
|
@@ -35,5 +50,5 @@ module Quickdraw
|
|
35
50
|
|
36
51
|
end
|
37
52
|
|
38
|
-
Celluloid::Actor[:shopify_connector_pool] = ShopifyConnectorPool.pool(:size =>
|
53
|
+
Celluloid::Actor[:shopify_connector_pool] = ShopifyConnectorPool.pool(:size => 24)
|
39
54
|
end
|
data/lib/quickdraw/version.rb
CHANGED
data/lib/quickdraw.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
require "quickdraw/version"
|
2
|
+
require 'pathname'
|
3
|
+
require 'filepath'
|
2
4
|
|
3
5
|
module Quickdraw
|
4
6
|
|
@@ -6,18 +8,6 @@ module Quickdraw
|
|
6
8
|
TIMER_RESET = 5 * 60 + 5
|
7
9
|
PERMIT_LOWER_LIMIT = 10
|
8
10
|
|
9
|
-
def self.asset_list
|
10
|
-
# HTTParty parser chokes on assest listing, have it noop
|
11
|
-
# and then use a rel JSON parser.
|
12
|
-
response = Celluloid::Actor[:shopify_connector]
|
13
|
-
response = shopify.get(path, :parser => NOOPParser)
|
14
|
-
#manage_timer(response)
|
15
|
-
|
16
|
-
assets = JSON.parse(response.body)["assets"].collect {|a| a['key'] }
|
17
|
-
# Remove any .css files if a .css.liquid file exists
|
18
|
-
assets.reject{|a| assets.include?("#{a}.liquid") }
|
19
|
-
end
|
20
|
-
|
21
11
|
def self.config
|
22
12
|
@config ||= if File.exist? 'config.yml'
|
23
13
|
config = YAML.load(File.read('config.yml'))
|
@@ -28,38 +18,16 @@ module Quickdraw
|
|
28
18
|
end
|
29
19
|
end
|
30
20
|
|
31
|
-
def self.
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
options.merge!({:basic_auth => @auth})
|
36
|
-
HTTParty.get(path, options)
|
37
|
-
|
38
|
-
begin
|
39
|
-
tries ||= 3
|
40
|
-
response = HTTParty.get(path, options)
|
41
|
-
|
42
|
-
puts response.inspect
|
43
|
-
|
44
|
-
if response.code != 200
|
45
|
-
raise "Request Failed"
|
46
|
-
end
|
47
|
-
|
48
|
-
@api_call_count, @total_api_calls = response.headers['x-shopify-shop-api-call-limit'].split('/')
|
49
|
-
@sleeptime = (5 / (@total_api_calls.to_f / @api_call_count.to_f))
|
50
|
-
|
51
|
-
puts "STATUS: #{@sleeptime} - #{@api_call_count} - #{@total_api_calls}"
|
52
|
-
|
53
|
-
rescue => e
|
54
|
-
puts e.inspect
|
55
|
-
puts "Failed: will retry #{tries} time(s)"
|
56
|
-
sleep 1
|
57
|
-
retry unless (tries -= 1).zero?
|
58
|
-
end
|
59
|
-
|
60
|
-
return response
|
21
|
+
def self.getwd
|
22
|
+
FilePath.getwd
|
23
|
+
end
|
61
24
|
|
25
|
+
def self.theme_dir
|
26
|
+
FilePath.getwd / 'theme'
|
62
27
|
end
|
63
28
|
|
29
|
+
def self.src_dir
|
30
|
+
FilePath.getwd / 'src'
|
31
|
+
end
|
64
32
|
|
65
33
|
end
|
data/quickdraw.gemspec
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: quickdraw
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bryan Morris
|
@@ -94,6 +94,20 @@ dependencies:
|
|
94
94
|
- - '>='
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: filepath
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - '>='
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - '>='
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
97
111
|
description: Quickly develop Shopify themes
|
98
112
|
email:
|
99
113
|
- bryan@internalfx.com
|
@@ -109,7 +123,6 @@ files:
|
|
109
123
|
- README.md
|
110
124
|
- Rakefile
|
111
125
|
- bin/quickdraw
|
112
|
-
- lib/auto_compile.rb
|
113
126
|
- lib/quickdraw.rb
|
114
127
|
- lib/quickdraw/cli.rb
|
115
128
|
- lib/quickdraw/shopify_connector.rb
|
data/lib/auto_compile.rb
DELETED
@@ -1,53 +0,0 @@
|
|
1
|
-
require 'erb'
|
2
|
-
require 'listen'
|
3
|
-
require 'pathname'
|
4
|
-
|
5
|
-
|
6
|
-
class Namespace
|
7
|
-
def initialize(hash={})
|
8
|
-
hash.each do |key, value|
|
9
|
-
singleton_class.send(:define_method, key) { value }
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
def get_binding
|
14
|
-
binding
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
@ns = Namespace.new()
|
19
|
-
@path = Dir.pwd
|
20
|
-
@watched_files = Pathname.glob("#{@path}/**/*.erb")
|
21
|
-
|
22
|
-
def compile_file(filepath)
|
23
|
-
if File.exists?(filepath)
|
24
|
-
pathname = Pathname.new(filepath)
|
25
|
-
relapath = pathname.relative_path_from(Pathname.pwd)
|
26
|
-
targetpath = relapath.to_s.gsub(/^src/, 'theme').gsub('.erb', '')
|
27
|
-
template = ERB.new(File.read(filepath))
|
28
|
-
File.write("#{targetpath}", template.result(@ns.get_binding))
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
#Compile all files on startup
|
33
|
-
puts "Compiling Files..."
|
34
|
-
@watched_files.each do |filepath|
|
35
|
-
compile_file(filepath)
|
36
|
-
end
|
37
|
-
|
38
|
-
puts "Watching for changes..."
|
39
|
-
listener = Listen.to(@path + '/src', :force_polling => true) do |modified, added, removed|
|
40
|
-
modified.each do |filepath|
|
41
|
-
puts "MODIFIED: #{filepath}"
|
42
|
-
compile_file(filepath)
|
43
|
-
end
|
44
|
-
added.each do |filepath|
|
45
|
-
puts "ADDED: #{filepath}"
|
46
|
-
compile_file(filepath)
|
47
|
-
end
|
48
|
-
removed.each do |filepath|
|
49
|
-
puts "REMOVED: #{filepath}"
|
50
|
-
end
|
51
|
-
end
|
52
|
-
listener.start
|
53
|
-
sleep
|