restoready_theme 0.0.2
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 +7 -0
- data/.gitignore +11 -0
- data/CHANGELOG.md +0 -0
- data/CONTRIBUTING +6 -0
- data/Gemfile +4 -0
- data/MIT-LICENSE +20 -0
- data/README.md +92 -0
- data/Rakefile +14 -0
- data/bin/theme +23 -0
- data/lib/restoready_theme/cli.rb +332 -0
- data/lib/restoready_theme/http_client.rb +124 -0
- data/lib/restoready_theme/version.rb +3 -0
- data/lib/restoready_theme.rb +2 -0
- data/restoready_theme.gemspec +31 -0
- data/spec/models/cli_spec.rb +90 -0
- data/spec/spec_helper.rb +7 -0
- metadata +176 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 8fa63eb9380ffed3c2867649c674011429b4516e
|
4
|
+
data.tar.gz: b420d42b574198345b56618fe9937a0bd103d529
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 1bde77bf2cea4eb8e7b3791cbe35e948530f62f5dc0370a5349f41bf304beef44be77518b59c051e8054aa98f51a0db1879bdac90f5e1a2483c4f39769c6da5b
|
7
|
+
data.tar.gz: 12b1e76a208cf1226685c2f6bdf977e34f7b5698e5484a9cd7155b553d5742217148d0c4c12b475a5ec763b3c566a8680259839e4b69a7a83c23f2470e90992b
|
data/.gitignore
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
# See http://help.github.com/ignore-files/ for more about ignoring files.
|
2
|
+
#
|
3
|
+
# If you find yourself ignoring temporary files generated by your text editor
|
4
|
+
# or operating system, you probably want to add a global ignore instead:
|
5
|
+
# git config --global core.excludesfile ~/.gitignore_global
|
6
|
+
|
7
|
+
*.gem
|
8
|
+
.bundle
|
9
|
+
Gemfile.lock
|
10
|
+
pkg/*
|
11
|
+
.project
|
data/CHANGELOG.md
ADDED
File without changes
|
data/CONTRIBUTING
ADDED
@@ -0,0 +1,6 @@
|
|
1
|
+
- If the issue doesn't exist, open one to start a discussion
|
2
|
+
- If the issue is fine (it probably is) start working on your patch
|
3
|
+
- Create a Pull Request
|
4
|
+
- Be sure to update CHANGELOG.md to include the details of your fix
|
5
|
+
- Go through code review
|
6
|
+
- Get it merged
|
data/Gemfile
ADDED
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2014 RestoReady
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
# Edit your RestoReady theme locally
|
2
|
+
|
3
|
+
[](http://badge.fury.io/rb/restoready_theme)
|
4
|
+
|
5
|
+
The RestoReady theme gem is a command line tool that lets you make live changes to themes on your RestoReady site.
|
6
|
+
|
7
|
+
It will watch your local folders for any changes in your theme (including adding and removing files) and will update your .restoready.com site to the latest changes.
|
8
|
+
|
9
|
+
You do not need to make changes to your default theme. You can leverage the theme preview feature of RestoReady
|
10
|
+
that allows you to view what an unpublished theme looks like on your RestoReady site.
|
11
|
+
|
12
|
+
# Requirements
|
13
|
+
|
14
|
+
This gem works with OS X with Ruby 1.9 and 2.x.
|
15
|
+
|
16
|
+
# Installation
|
17
|
+
|
18
|
+
To install the restoready_theme gem use 'gem install'.
|
19
|
+
|
20
|
+
```
|
21
|
+
gem install restoready_theme
|
22
|
+
```
|
23
|
+
|
24
|
+
or add this line in Gemfile
|
25
|
+
|
26
|
+
```
|
27
|
+
gem restoready_theme
|
28
|
+
```
|
29
|
+
|
30
|
+
to update to the latest version
|
31
|
+
|
32
|
+
```
|
33
|
+
gem update restoready_theme
|
34
|
+
```
|
35
|
+
|
36
|
+
# Usage
|
37
|
+
|
38
|
+
Generate the config file. To choose the theme you want to edit, add `theme_id`.
|
39
|
+
|
40
|
+
```
|
41
|
+
theme configure api_key api_url site_url theme_id
|
42
|
+
```
|
43
|
+
|
44
|
+
Example of config.yml. You can use `:whitelist_files:` to specify files for upload. The `assets/`, `config/`,
|
45
|
+
`layouts/`, `snippets/`, `templates/` and `locales/`directories are included by
|
46
|
+
default.
|
47
|
+
|
48
|
+
You can also use `:ignore_files:` to exclude files from getting uploaded, for
|
49
|
+
example your `config/settings.html.liquid` or other configuration driven items
|
50
|
+
|
51
|
+
```yaml
|
52
|
+
---
|
53
|
+
:api_key: api_key
|
54
|
+
:api_url: https://demo.restoready.com
|
55
|
+
:site_url: https://demo.restoready.com
|
56
|
+
:theme_id: '1'
|
57
|
+
:whitelist_files:
|
58
|
+
- directoryToUpload/
|
59
|
+
- importantFile.txt
|
60
|
+
:ignore_files:
|
61
|
+
- config/settings.html.liquid
|
62
|
+
```
|
63
|
+
|
64
|
+
Upload a theme file
|
65
|
+
|
66
|
+
```
|
67
|
+
theme upload assets/layout.liquid
|
68
|
+
```
|
69
|
+
|
70
|
+
Remove a theme file
|
71
|
+
|
72
|
+
```
|
73
|
+
theme remove assets/layout.liquid
|
74
|
+
```
|
75
|
+
|
76
|
+
Completely replace theme assets with the local assets
|
77
|
+
|
78
|
+
```
|
79
|
+
theme replace
|
80
|
+
```
|
81
|
+
|
82
|
+
Watch the theme directory and upload any files as they change
|
83
|
+
|
84
|
+
```
|
85
|
+
theme watch
|
86
|
+
```
|
87
|
+
|
88
|
+
Open the site in the default browser
|
89
|
+
|
90
|
+
```
|
91
|
+
theme open
|
92
|
+
```
|
data/Rakefile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
require 'bundler/gem_tasks'
|
3
|
+
require 'rake/testtask'
|
4
|
+
|
5
|
+
task :default => [:spec]
|
6
|
+
|
7
|
+
Rake::TestTask.new 'spec' do |t|
|
8
|
+
ENV['test'] = 'true'
|
9
|
+
t.libs = ['lib', 'spec']
|
10
|
+
t.ruby_opts << '-rubygems'
|
11
|
+
t.verbose = true
|
12
|
+
t.test_files = FileList['spec/**/*_spec.rb']
|
13
|
+
end
|
14
|
+
|
data/bin/theme
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# This allows restoready_theme to run easily from a git checkout without install.
|
4
|
+
# Hat tip to chriseppstein of Compass fame for the code for this
|
5
|
+
def fallback_load_path(path)
|
6
|
+
retried = false
|
7
|
+
begin
|
8
|
+
yield
|
9
|
+
rescue LoadError
|
10
|
+
unless retried
|
11
|
+
$: << path
|
12
|
+
retried = true
|
13
|
+
retry
|
14
|
+
end
|
15
|
+
raise
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
fallback_load_path(File.join(File.dirname(__FILE__), '..', 'lib')) do
|
20
|
+
require 'restoready_theme'
|
21
|
+
end
|
22
|
+
|
23
|
+
RestoreadyTheme::Cli.start(ARGV)
|
@@ -0,0 +1,332 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'yaml'
|
3
|
+
YAML::ENGINE.yamler = 'syck' if defined? Syck
|
4
|
+
require 'abbrev'
|
5
|
+
require 'base64'
|
6
|
+
require 'fileutils'
|
7
|
+
require 'json'
|
8
|
+
require 'filewatcher'
|
9
|
+
require 'launchy'
|
10
|
+
require 'mimemagic'
|
11
|
+
|
12
|
+
module RestoreadyTheme
|
13
|
+
EXTENSIONS = [
|
14
|
+
{mimetype: 'application/x-liquid', extensions: %w(liquid), parents: 'text/plain'},
|
15
|
+
{mimetype: 'text/x-liquid', extensions: %w(liquid), parents: 'text/plain'},
|
16
|
+
{mimetype: 'application/json', extensions: %w(json), parents: 'text/plain'},
|
17
|
+
{mimetype: 'application/js', extensions: %w(map), parents: 'text/plain'},
|
18
|
+
{mimetype: 'application/vnd.ms-fontobject', extensions: %w(eot)},
|
19
|
+
{mimetype: 'image/svg+xml', extensions: %w(svg svgz)}
|
20
|
+
]
|
21
|
+
|
22
|
+
def self.configureMimeMagic
|
23
|
+
RestoreadyTheme::EXTENSIONS.each do |extension|
|
24
|
+
MimeMagic.add(extension.delete(:mimetype), extension)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class Cli < Thor
|
29
|
+
include Thor::Actions
|
30
|
+
|
31
|
+
DEFAULT_WHITELIST = %w(layouts/ assets/ config/ snippets/ templates/ locales/)
|
32
|
+
TIMEFORMAT = "%H:%M:%S"
|
33
|
+
|
34
|
+
tasks.keys.abbrev.each do |shortcut, command|
|
35
|
+
map shortcut => command.to_sym
|
36
|
+
end
|
37
|
+
|
38
|
+
desc "configure API_KEY API_URL SITE_URL THEME_ID", "generate a config file for the site to connect to"
|
39
|
+
def configure(api_key=nil, api_url=nil, site_url = nil, theme_id=nil)
|
40
|
+
config = {api_key: api_key, api_url: api_url, site_url: site_url, theme_id: theme_id}
|
41
|
+
create_file('config.yml', config.to_yaml)
|
42
|
+
check
|
43
|
+
end
|
44
|
+
|
45
|
+
desc "open", "open the site in your browser"
|
46
|
+
def open(*keys)
|
47
|
+
if Launchy.open restoready_theme_url
|
48
|
+
say("Done.", :green)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
desc "download FILE", "download all the theme files"
|
53
|
+
method_option :quiet, :type => :boolean, :default => false
|
54
|
+
method_option :exclude
|
55
|
+
def download(*keys)
|
56
|
+
assets = keys.empty? ? http_client.asset_list : keys
|
57
|
+
|
58
|
+
if options['exclude']
|
59
|
+
assets = assets.delete_if { |asset| asset =~ Regexp.new(options['exclude']) }
|
60
|
+
end
|
61
|
+
|
62
|
+
assets.each do |asset|
|
63
|
+
download_asset(asset)
|
64
|
+
say("Downloaded: #{asset}", :green) unless options['quiet']
|
65
|
+
end
|
66
|
+
say("Done.", :green) unless options['quiet']
|
67
|
+
end
|
68
|
+
|
69
|
+
desc "upload FILE", "upload all theme assets to theme"
|
70
|
+
method_option :quiet, type: :boolean, default: false
|
71
|
+
def upload(*keys)
|
72
|
+
check
|
73
|
+
assets = keys.empty? ? local_assets_list : keys
|
74
|
+
assets.each do |asset|
|
75
|
+
send_asset(asset, options['quiet'])
|
76
|
+
end
|
77
|
+
say("Done.", :green) unless options['quiet']
|
78
|
+
end
|
79
|
+
|
80
|
+
desc "replace FILE", "completely replace restoready theme assets with local theme assets"
|
81
|
+
method_option :quiet, type: :boolean, default: false
|
82
|
+
def replace(*keys)
|
83
|
+
check
|
84
|
+
say("Are you sure you want to completely replace your restoready theme assets? This is not undoable.", :yellow)
|
85
|
+
if ask("Continue? (Y/N): ") == "Y"
|
86
|
+
# only delete files on remote that are not present locally
|
87
|
+
# files present on remote and present locally get overridden anyway
|
88
|
+
remote_assets = keys.empty? ? (http_client.asset_list - local_assets_list) : keys
|
89
|
+
remote_assets.each do |asset|
|
90
|
+
delete_asset(asset, options['quiet']) unless http_client.ignore_files.any? { |regex| regex =~ asset }
|
91
|
+
end
|
92
|
+
local_assets = keys.empty? ? local_assets_list : keys
|
93
|
+
local_assets.each do |asset|
|
94
|
+
send_asset(asset, options['quiet'])
|
95
|
+
end
|
96
|
+
say("Done.", :green) unless options['quiet']
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
desc "remove FILE", "remove theme asset"
|
101
|
+
method_option :quiet, type: :boolean, default: false
|
102
|
+
def remove(*keys)
|
103
|
+
check
|
104
|
+
keys.each do |key|
|
105
|
+
delete_asset(key, options['quiet'])
|
106
|
+
end
|
107
|
+
say("Done.", :green) unless options['quiet']
|
108
|
+
end
|
109
|
+
|
110
|
+
desc "watch", "upload and delete individual theme assets as they change, use the --keep_files flag to disable remote file deletion"
|
111
|
+
method_option :quiet, type: :boolean, default: false
|
112
|
+
method_option :keep_files, type: :boolean, default: false
|
113
|
+
def watch
|
114
|
+
check
|
115
|
+
puts "Surveille le répertoire courant: #{Dir.pwd}"
|
116
|
+
watcher do |filename, event|
|
117
|
+
filename = filename.gsub("#{Dir.pwd}/", '')
|
118
|
+
|
119
|
+
next if next_watch?(filename, event)
|
120
|
+
action = if [:changed, :new].include?(event)
|
121
|
+
:send_asset
|
122
|
+
elsif event == :delete
|
123
|
+
:delete_asset
|
124
|
+
else
|
125
|
+
raise NotImplementedError, "Unknown event -- #{event} -- #{filename}"
|
126
|
+
end
|
127
|
+
|
128
|
+
send(action, filename, options['quiet'])
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
desc "systeminfo", "print out system information and actively loaded libraries for aiding in submitting bug reports"
|
133
|
+
def systeminfo
|
134
|
+
ruby_version = "#{RUBY_VERSION}"
|
135
|
+
ruby_version += "-p#{RUBY_PATCHLEVEL}" if RUBY_PATCHLEVEL
|
136
|
+
puts "Ruby: v#{ruby_version}"
|
137
|
+
puts "Operating System: #{RUBY_PLATFORM}"
|
138
|
+
%w(Thor Listen HTTParty Launchy).each do |lib|
|
139
|
+
require "#{lib.downcase}/version"
|
140
|
+
puts "#{lib}: v" + Kernel.const_get("#{lib}::VERSION")
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
protected
|
145
|
+
|
146
|
+
def config
|
147
|
+
@config ||= YAML.load_file 'config.yml'
|
148
|
+
end
|
149
|
+
|
150
|
+
def restoready_theme_url
|
151
|
+
url = config[:site_url] ||= ""
|
152
|
+
url += "/fr?preview_theme_id=#{config[:theme_id]}" if config[:theme_id] && config[:theme_id].to_i > 0
|
153
|
+
url
|
154
|
+
end
|
155
|
+
|
156
|
+
def http_client
|
157
|
+
@http_client = RestoreadyTheme::HttpClient.new
|
158
|
+
end
|
159
|
+
|
160
|
+
private
|
161
|
+
|
162
|
+
def watcher
|
163
|
+
FileWatcher.new(Dir.pwd).watch() do |filename, event|
|
164
|
+
yield(filename, event)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
def local_assets_list
|
169
|
+
local_files.reject do |p|
|
170
|
+
@permitted_files ||= (DEFAULT_WHITELIST | http_client.whitelist_files).map{|pattern| Regexp.new(pattern)}
|
171
|
+
@permitted_files.none? { |regex| regex =~ p } || http_client.ignore_files.any? { |regex| regex =~ p }
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
def local_files
|
176
|
+
Dir.glob(File.join('**', '*')).reject do |f|
|
177
|
+
File.directory?(f)
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
def download_asset(key)
|
182
|
+
return unless valid?(key)
|
183
|
+
asset = http_client.get_asset(key)
|
184
|
+
if asset['value']
|
185
|
+
# For CRLF line endings
|
186
|
+
content = asset['value'].gsub("\r", "")
|
187
|
+
format = "w"
|
188
|
+
elsif asset['attachment']
|
189
|
+
content = Base64.decode64(asset['attachment'])
|
190
|
+
format = "w+b"
|
191
|
+
end
|
192
|
+
|
193
|
+
FileUtils.mkdir_p(File.dirname(key))
|
194
|
+
File.open(key, format) {|f| f.write content} if content
|
195
|
+
end
|
196
|
+
|
197
|
+
def send_asset(asset, quiet=false)
|
198
|
+
return unless valid?(asset)
|
199
|
+
data = {key: asset}
|
200
|
+
content = File.read(asset)
|
201
|
+
|
202
|
+
asset_getting = http_client.get_asset(asset)
|
203
|
+
if asset_getting['response'].success?
|
204
|
+
data.merge!(id: asset_getting['id'])
|
205
|
+
end
|
206
|
+
|
207
|
+
if binary_file?(asset) || http_client.is_binary_data?(content)
|
208
|
+
content = File.open(asset, "rb") { |io| io.read }
|
209
|
+
data.merge!(value: Base64.encode64(content), content_type: MimeMagic.by_path(asset).type)
|
210
|
+
else
|
211
|
+
data.merge!(value: content, content_type: MimeMagic.by_path(asset).type)
|
212
|
+
end
|
213
|
+
|
214
|
+
update_response = show_during("[#{timestamp}] Uploading: #{asset}", quiet) do
|
215
|
+
http_client.update_asset(data)
|
216
|
+
end
|
217
|
+
if update_response.success?
|
218
|
+
say("[#{timestamp}] Uploaded: #{asset}", :green) unless quiet
|
219
|
+
return
|
220
|
+
end
|
221
|
+
|
222
|
+
if !http_client.is_creatable?(asset) || update_response.status != 404
|
223
|
+
report_error(Time.now, "Could not upload #{asset}", update_response)
|
224
|
+
return
|
225
|
+
end
|
226
|
+
|
227
|
+
create_response = show_during("[#{timestamp}] Creating: #{asset}", quiet) do
|
228
|
+
http_client.create_asset(data)
|
229
|
+
end
|
230
|
+
if create_response.success?
|
231
|
+
say("[#{timestamp}] #{asset} create", :green) unless quiet
|
232
|
+
return
|
233
|
+
end
|
234
|
+
report_error(Time.now, "Could not created #{asset}", create_response)
|
235
|
+
rescue Errno::ENOENT
|
236
|
+
say("[#{timestamp}] #{asset} not found in the local repository", :red)
|
237
|
+
exit
|
238
|
+
end
|
239
|
+
|
240
|
+
def delete_asset(key, quiet=false)
|
241
|
+
return unless valid?(key)
|
242
|
+
data = {key: key}
|
243
|
+
|
244
|
+
asset_getting = http_client.get_asset(key)
|
245
|
+
if asset_getting['response'].success?
|
246
|
+
data.merge!(id: asset_getting['id'])
|
247
|
+
else
|
248
|
+
report_error(Time.now, "#{key} not found.", asset_getting['response'])
|
249
|
+
end
|
250
|
+
|
251
|
+
response = show_during("[#{timestamp}] Removing: #{key}", quiet) do
|
252
|
+
http_client.delete_asset(data)
|
253
|
+
end
|
254
|
+
if response.success?
|
255
|
+
say("[#{timestamp}] Removed: #{key}", :green) unless quiet
|
256
|
+
else
|
257
|
+
report_error(Time.now, "Could not deleted #{key}", response)
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
def valid?(key)
|
262
|
+
return true if DEFAULT_WHITELIST.include?(key.split('/').first + "/")
|
263
|
+
say("'#{key}' is not in a valid file for theme uploads", :yellow)
|
264
|
+
say("Files need to be in one of the following subdirectories: #{DEFAULT_WHITELIST.join(' ')}", :yellow)
|
265
|
+
false
|
266
|
+
end
|
267
|
+
|
268
|
+
def binary_file?(path)
|
269
|
+
mime = MimeMagic.by_path(path)
|
270
|
+
say("'#{path}' is an unknown file-type, uploading asset as binary", :yellow) if mime.nil? && ENV['TEST'] != 'true'
|
271
|
+
mime.nil? || (!mime.text? && mime.subtype != "svg+xml")
|
272
|
+
end
|
273
|
+
|
274
|
+
def report_error(time, message, response)
|
275
|
+
say("[#{timestamp(time)}] Error: #{message}", :red)
|
276
|
+
say("Error Details: #{errors_from_response(response)}", :yellow)
|
277
|
+
exit
|
278
|
+
end
|
279
|
+
|
280
|
+
def errors_from_response(response)
|
281
|
+
object = {status: response.status}
|
282
|
+
|
283
|
+
errors = JSON.parse(response.body)['errors']
|
284
|
+
|
285
|
+
object[:errors] = case errors
|
286
|
+
when NilClass
|
287
|
+
''
|
288
|
+
when String
|
289
|
+
errors.strip
|
290
|
+
else
|
291
|
+
errors.values.join(", ")
|
292
|
+
end
|
293
|
+
object.delete(:errors) if object[:errors].length <= 0
|
294
|
+
object
|
295
|
+
end
|
296
|
+
|
297
|
+
def show_during(message = '', quiet = false, &block)
|
298
|
+
print(message) unless quiet
|
299
|
+
result = yield
|
300
|
+
print("\r#{' ' * message.length}\r") unless quiet
|
301
|
+
result
|
302
|
+
end
|
303
|
+
|
304
|
+
def timestamp(time = Time.now)
|
305
|
+
time.strftime(TIMEFORMAT)
|
306
|
+
end
|
307
|
+
|
308
|
+
def next_watch?(filename, event)
|
309
|
+
pref = filename.split('/')[0]
|
310
|
+
local_assets_list_tmp = local_assets_list
|
311
|
+
local_assets_list_tmp.push(filename) if event == :delete
|
312
|
+
|
313
|
+
return true unless local_assets_list_tmp.include?(filename)
|
314
|
+
(pref != 'assets' && pref != 'snippets' && event == :new) || (pref != 'assets' && pref != 'snippets' && event == :delete)
|
315
|
+
end
|
316
|
+
|
317
|
+
def check
|
318
|
+
response = show_during("[#{timestamp}] Configuration check") do
|
319
|
+
http_client.check_theme
|
320
|
+
end
|
321
|
+
|
322
|
+
if !response.success?
|
323
|
+
report_error(Time.now, "Configuration [FAIL]", response)
|
324
|
+
exit
|
325
|
+
elsif JSON.parse(response.body)['tenant']['theme_id'] == config[:theme_id].to_i
|
326
|
+
say("Configuration [FAIL] : Can't edit an active theme", :red)
|
327
|
+
exit
|
328
|
+
end
|
329
|
+
end
|
330
|
+
end
|
331
|
+
end
|
332
|
+
RestoreadyTheme.configureMimeMagic
|
@@ -0,0 +1,124 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
module RestoreadyTheme
|
3
|
+
class HttpClient
|
4
|
+
attr_accessor :client
|
5
|
+
|
6
|
+
def initialize(api_url = nil)
|
7
|
+
# api_url = base_url.nil? ? config[:api_url] : base_url
|
8
|
+
@client = ::Faraday.new(url: api_url ||= config[:api_url])
|
9
|
+
end
|
10
|
+
|
11
|
+
def test?
|
12
|
+
ENV['test']
|
13
|
+
end
|
14
|
+
|
15
|
+
def asset_list
|
16
|
+
response = client.get do |req|
|
17
|
+
req.url "#{basepath}"
|
18
|
+
req.headers['Authorization'] = token
|
19
|
+
req.headers['Accept'] = 'application/json'
|
20
|
+
end
|
21
|
+
|
22
|
+
assets = JSON.parse(response.body)["assets"].collect {|a| a['key'] }
|
23
|
+
# Remove any .css files if a .css.liquid file exists
|
24
|
+
assets.reject{|a| assets.include?("#{a}.liquid") }
|
25
|
+
end
|
26
|
+
|
27
|
+
def get_asset(key)
|
28
|
+
asset = {}
|
29
|
+
response = client.get do |req|
|
30
|
+
req.url "#{basepath}/show_by_key?key=#{key}"
|
31
|
+
req.headers['Authorization'] = token
|
32
|
+
req.headers['Accept'] = 'application/json'
|
33
|
+
end
|
34
|
+
|
35
|
+
asset = response.status == 200 ? JSON.parse(response.body)["asset"] : {}
|
36
|
+
asset['response'] = response
|
37
|
+
asset
|
38
|
+
end
|
39
|
+
|
40
|
+
def create_asset(data)
|
41
|
+
response = client.post do |req|
|
42
|
+
req.url "#{basepath}"
|
43
|
+
req.headers['Content-Type'] = 'application/json'
|
44
|
+
req.headers['Accept'] = 'application/json'
|
45
|
+
req.headers['Authorization'] = token
|
46
|
+
req.body = {asset: data}.to_json
|
47
|
+
end
|
48
|
+
response
|
49
|
+
end
|
50
|
+
|
51
|
+
def update_asset(data)
|
52
|
+
response = client.put do |req|
|
53
|
+
req.url "#{basepath}/#{data[:id]}"
|
54
|
+
req.headers['Content-Type'] = 'application/json'
|
55
|
+
req.headers['Accept'] = 'application/json'
|
56
|
+
req.headers['Authorization'] = token
|
57
|
+
req.body = {asset: data}.to_json
|
58
|
+
end
|
59
|
+
response
|
60
|
+
end
|
61
|
+
|
62
|
+
def delete_asset(data)
|
63
|
+
response = client.delete do |req|
|
64
|
+
req.url "#{basepath}/#{data[:id]}"
|
65
|
+
req.headers['Accept'] = 'application/json'
|
66
|
+
req.headers['Authorization'] = token
|
67
|
+
end
|
68
|
+
response
|
69
|
+
end
|
70
|
+
|
71
|
+
def config
|
72
|
+
@config ||= if File.exist? 'config.yml'
|
73
|
+
config = YAML.load(File.read('config.yml'))
|
74
|
+
config
|
75
|
+
else
|
76
|
+
puts "config.yml does not exist!" unless test?
|
77
|
+
{}
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def config=(config)
|
82
|
+
@config = config
|
83
|
+
end
|
84
|
+
|
85
|
+
def basepath
|
86
|
+
@basepath = "/api/v1/themes/#{config[:theme_id]}/assets"
|
87
|
+
end
|
88
|
+
|
89
|
+
def ignore_files
|
90
|
+
(config[:ignore_files] || []).compact.map { |r| Regexp.new(r) }
|
91
|
+
end
|
92
|
+
|
93
|
+
def whitelist_files
|
94
|
+
(config[:whitelist_files] || []).compact
|
95
|
+
end
|
96
|
+
|
97
|
+
def is_binary_data?(string)
|
98
|
+
if string.respond_to?(:encoding)
|
99
|
+
string.encoding == "UTF-8"
|
100
|
+
else
|
101
|
+
( string.count( "^ -~", "^\r\n" ).fdiv(string.size) > 0.3 || string.index( "\x00" ) ) unless string.empty?
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def check_theme
|
106
|
+
response = client.get do |req|
|
107
|
+
req.url "/api/v1/tenant"
|
108
|
+
req.headers['Authorization'] = token
|
109
|
+
req.headers['Accept'] = 'application/json'
|
110
|
+
end
|
111
|
+
response
|
112
|
+
end
|
113
|
+
|
114
|
+
def is_creatable?(asset)
|
115
|
+
true
|
116
|
+
end
|
117
|
+
|
118
|
+
private
|
119
|
+
|
120
|
+
def token
|
121
|
+
"Token token=\"#{config[:api_key]}\""
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "restoready_theme/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "restoready_theme"
|
7
|
+
s.version = RestoreadyTheme::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Derivery Damien"]
|
10
|
+
s.email = ["damien@restoready.com"]
|
11
|
+
s.homepage = "https://github.com/restoready/restoready-theme"
|
12
|
+
s.summary = %q{Command line tool for developing themes}
|
13
|
+
s.description = %q{Command line tool to help with developing RestoReady themes. Provides simple commands to download, upload and delete files from a theme. Also includes the watch command to watch a directory and upload files as they change.}
|
14
|
+
s.license = 'MIT'
|
15
|
+
|
16
|
+
s.rubyforge_project = "restoready_theme"
|
17
|
+
s.add_dependency('thor', '~> 0.14')
|
18
|
+
s.add_dependency('faraday', '~> 0.9')
|
19
|
+
s.add_dependency('json', '~> 1.8')
|
20
|
+
s.add_dependency('mimemagic', '~> 0')
|
21
|
+
s.add_dependency('filewatcher', '~> 0')
|
22
|
+
s.add_dependency('launchy', '~> 2')
|
23
|
+
|
24
|
+
s.add_development_dependency 'rake', '~> 0'
|
25
|
+
s.add_development_dependency 'rspec', '~> 3'
|
26
|
+
|
27
|
+
s.files = `git ls-files`.split("\n")
|
28
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
29
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
30
|
+
s.require_paths = ['lib']
|
31
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'restoready_theme'
|
3
|
+
|
4
|
+
describe RestoreadyTheme::Cli do
|
5
|
+
class CliDouble < RestoreadyTheme::Cli
|
6
|
+
attr_writer :local_files, :mock_config
|
7
|
+
|
8
|
+
desc "",""
|
9
|
+
def config
|
10
|
+
@mock_config || super
|
11
|
+
end
|
12
|
+
|
13
|
+
desc "",""
|
14
|
+
def restoready_theme_url
|
15
|
+
super
|
16
|
+
end
|
17
|
+
|
18
|
+
desc "",""
|
19
|
+
def binary_file?(file)
|
20
|
+
super
|
21
|
+
end
|
22
|
+
|
23
|
+
desc "", ""
|
24
|
+
def local_files
|
25
|
+
@local_files
|
26
|
+
end
|
27
|
+
|
28
|
+
desc "",""
|
29
|
+
def local_assets_list
|
30
|
+
super
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
before do
|
35
|
+
@cli = CliDouble.new
|
36
|
+
@http_client = RestoreadyTheme::HttpClient.new("http://example.com")
|
37
|
+
allow(@cli).to receive(:http_client).and_return(@http_client)
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should remove assets that are not a part of the white list" do
|
41
|
+
@cli.local_files = ['assets/image.png', 'config.yml', 'layouts/theme.liquid', 'locales/en/app.po']
|
42
|
+
local_assets_list = @cli.local_assets_list
|
43
|
+
expect(local_assets_list.length).to eq 3
|
44
|
+
expect(local_assets_list.include?('config.yml')).to be false
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should remove assets that are part of the ignore list" do
|
48
|
+
@http_client.config = {ignore_files: ['config/settings.html']}
|
49
|
+
@cli.local_files = ['assets/image.png', 'layouts/theme.liquid', 'config/settings.html']
|
50
|
+
local_assets_list = @cli.local_assets_list
|
51
|
+
|
52
|
+
expect(local_assets_list.length).to eq 2
|
53
|
+
expect(local_assets_list.include?('config/settings.html')).to be false
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should generate the restoready path URL to the query parameter preview_theme_id if the id is present" do
|
57
|
+
@cli.mock_config = {site_url: 'somethingfancy.com', theme_id: 12345}
|
58
|
+
expect(@cli.restoready_theme_url).to eq "somethingfancy.com?preview_theme_id=12345"
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should generate the restoready path URL withouth the preview_theme_id if the id is not present" do
|
62
|
+
@cli.mock_config = {site_url: 'somethingfancy.com'}
|
63
|
+
expect(@cli.restoready_theme_url).to eq "somethingfancy.com"
|
64
|
+
|
65
|
+
@cli.mock_config = {site_url: 'somethingfancy.com', theme_id: ''}
|
66
|
+
expect(@cli.restoready_theme_url).to eq "somethingfancy.com"
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should report binary files as such" do
|
70
|
+
extensions = %w(png gif jpg jpeg eot ttf woff otf swf ico pdf)
|
71
|
+
extensions.each do |ext|
|
72
|
+
expect(@cli.binary_file?("hello.#{ext}")).to be true
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should report unknown files as binary files" do
|
77
|
+
expect(@cli.binary_file?('omg.wut')).to be true
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should not report text based files as binary" do
|
81
|
+
expect(@cli.binary_file?('theme.liquid')).to be false
|
82
|
+
expect(@cli.binary_file?('style.scss.liquid')).to be false
|
83
|
+
expect(@cli.binary_file?('style.css')).to be false
|
84
|
+
expect(@cli.binary_file?('application.js')).to be false
|
85
|
+
expect(@cli.binary_file?('settings_data.json')).to be false
|
86
|
+
expect(@cli.binary_file?('image.jpg')).to be true
|
87
|
+
expect(@cli.binary_file?('font.eot')).to be true
|
88
|
+
expect(@cli.binary_file?('font.svg')).to be false
|
89
|
+
end
|
90
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,176 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: restoready_theme
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Derivery Damien
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-10-27 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: thor
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.14'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0.14'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: faraday
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.9'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.9'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: json
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.8'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.8'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: mimemagic
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: filewatcher
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: launchy
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '2'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '2'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rake
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rspec
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '3'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '3'
|
125
|
+
description: Command line tool to help with developing RestoReady themes. Provides
|
126
|
+
simple commands to download, upload and delete files from a theme. Also includes
|
127
|
+
the watch command to watch a directory and upload files as they change.
|
128
|
+
email:
|
129
|
+
- damien@restoready.com
|
130
|
+
executables:
|
131
|
+
- theme
|
132
|
+
extensions: []
|
133
|
+
extra_rdoc_files: []
|
134
|
+
files:
|
135
|
+
- ".gitignore"
|
136
|
+
- CHANGELOG.md
|
137
|
+
- CONTRIBUTING
|
138
|
+
- Gemfile
|
139
|
+
- MIT-LICENSE
|
140
|
+
- README.md
|
141
|
+
- Rakefile
|
142
|
+
- bin/theme
|
143
|
+
- lib/restoready_theme.rb
|
144
|
+
- lib/restoready_theme/cli.rb
|
145
|
+
- lib/restoready_theme/http_client.rb
|
146
|
+
- lib/restoready_theme/version.rb
|
147
|
+
- restoready_theme.gemspec
|
148
|
+
- spec/models/cli_spec.rb
|
149
|
+
- spec/spec_helper.rb
|
150
|
+
homepage: https://github.com/restoready/restoready-theme
|
151
|
+
licenses:
|
152
|
+
- MIT
|
153
|
+
metadata: {}
|
154
|
+
post_install_message:
|
155
|
+
rdoc_options: []
|
156
|
+
require_paths:
|
157
|
+
- lib
|
158
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
159
|
+
requirements:
|
160
|
+
- - ">="
|
161
|
+
- !ruby/object:Gem::Version
|
162
|
+
version: '0'
|
163
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
164
|
+
requirements:
|
165
|
+
- - ">="
|
166
|
+
- !ruby/object:Gem::Version
|
167
|
+
version: '0'
|
168
|
+
requirements: []
|
169
|
+
rubyforge_project: restoready_theme
|
170
|
+
rubygems_version: 2.2.2
|
171
|
+
signing_key:
|
172
|
+
specification_version: 4
|
173
|
+
summary: Command line tool for developing themes
|
174
|
+
test_files:
|
175
|
+
- spec/models/cli_spec.rb
|
176
|
+
- spec/spec_helper.rb
|