Last active
December 15, 2016 13:40
-
-
Save ismasan/b9d0d7f82fcd0d723ef553298bcfbf98 to your computer and use it in GitHub Desktop.
Backup a Bootic theme using the Bootic CLI
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require "fileutils" | |
require "open-uri" | |
require "thread" | |
require "listen" | |
# dependencies: | |
# gem install listen | |
# | |
# Put this file in ~/btc/themes.rb | |
# Theme management | |
# Downloads a shop's theme templates and assets | |
# Usage | |
# | |
# # if shop is acme.bootic.net | |
# | |
# btc themes download acme -d ~/backups | |
# | |
# cd acme | |
# | |
# btc themes watch | |
# | |
class Themes < BooticCli::Command | |
desc "download acme", "download a shop's theme" | |
option :d, banner: "<target_directory>", default: Dir.pwd | |
def download(subdomain = nil) | |
shop = if subdomain | |
root.all_shops(subdomains: subdomain).first | |
else | |
root.shops.first | |
end | |
say("no shop with subdomain #{subdomain}") and return unless shop | |
dir = File.join(options["d"], shop.subdomain) | |
FileUtils.rm_rf(dir) if File.directory?(dir) | |
pull dir | |
end | |
desc "pull", "pull latest theme changes into current directory" | |
def pull(dir = ".") | |
# re-fetch theme | |
theme = shop.theme | |
assets_dir = File.join(dir, "assets") | |
FileUtils.mkdir_p assets_dir | |
download_templates(dir, theme.templates) | |
download_assets(assets_dir, theme.assets) | |
end | |
desc "push", "push all theme files to current shop" | |
def push(dir = ".") | |
theme = shop.theme | |
Dir.glob(File.join(dir, "**/*")).each do |path| | |
upsert theme, File.expand_path(path) unless File.directory?(path) | |
end | |
end | |
desc "watch acme", "watch and update" | |
def watch(dir = ".") | |
theme = shop.theme | |
listener = Listen.to(dir) do |modified, added, removed| | |
if modified.any? | |
modified.each do |path| | |
upsert theme, path | |
end | |
end | |
if added.any? | |
added.each do |path| | |
upsert theme, path | |
end | |
end | |
if removed.any? | |
removed.each do |path| | |
delete theme, path | |
end | |
end | |
# update local cache | |
theme = theme.self | |
end | |
puts "watching #{dir}" | |
listener.start | |
# ctrl-c | |
Signal.trap("INT") { | |
listener.stop | |
puts "bye bye" | |
exit | |
} | |
sleep | |
end | |
private | |
def upsert(theme, path) | |
if path =~ /assets/ | |
upsert_asset theme, path | |
else | |
upsert_template theme, path | |
end | |
end | |
def delete(theme, path) | |
if path =~ /assets/ | |
delete_asset theme, path | |
else | |
delete_template theme, path | |
end | |
end | |
def delete_template(theme, path) | |
fname = File.basename(path) | |
tpl = theme.templates.find{|t| t.file_name == fname} | |
return unless tpl | |
if tpl.has?(:delete_template) | |
puts "deleting #{path}" | |
tpl.delete_template | |
else | |
puts "template cannot be deleted. Re-fetching" | |
write(path, tpl.body, "w") | |
end | |
end | |
def delete_asset(theme, path) | |
fname = File.basename(path) | |
asset = theme.assets.find{|t| t.file_name == fname} | |
return unless asset | |
puts "deleting #{path}" | |
asset.delete_theme_asset | |
end | |
def upsert_template(theme, path) | |
confirm_upload(theme.create_template( | |
file_name: File.basename(path), | |
body: File.read(path) | |
), path) | |
end | |
def upsert_asset(theme, path) | |
confirm_upload(theme.create_theme_asset( | |
file_name: File.basename(path), | |
data: File.new(path) | |
), path) | |
end | |
def confirm_upload(entity, path) | |
if entity.has?(:errors) | |
entity.errors.each do |e| | |
puts [e.field, e.messages.join(", ")].join(": ") | |
end | |
else | |
puts "modified absolute path: #{path}" | |
end | |
end | |
def download_templates(dir, templates) | |
templates.each do |t| | |
puts write(File.join(dir, t.file_name), t.body, "w") | |
end | |
end | |
def download_assets(dir, assets) | |
queue = Queue.new | |
threads = assets.map do |a| | |
Thread.new do | |
file = open(a.rels[:file].href) | |
queue << write(File.join(dir, a.file_name), file.read, "wb") | |
end | |
end | |
printer = Thread.new do | |
while path = queue.pop | |
puts path | |
end | |
end | |
threads.map &:join | |
queue << false | |
printer.join | |
end | |
def write(path, content, mode) | |
File.open(path, mode) do |io| | |
io.write content | |
end | |
path | |
end | |
declare self, "manage shop themes" | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment