class GhostBackup

Constants

API_VERSION
CONFIG_KEYS

Attributes

config_file[RW]

Public Class Methods

new(config_file: "ghost-backup.yml") click to toggle source
# File bin/ghost-backup, line 29
def initialize(config_file: "ghost-backup.yml")
  @dirty = false
  if config_file.nil?
    @config_file = "ghost-backup.yml"
  else
    @config_file = config_file
  end
  @username = nil
  # backup_dir is passed to strftime
  @backup_dir = 'ghost-backup/%Y-%m-%d-%H%M%S'
  @ghost_dir = "/var/www/ghost"
  @base_url = 'https://localhost'
  @refresh_token = nil
  load_config
  unless @base_url.include? '://'
    @base_url = 'https://' + @base_url
  end
end

Public Instance Methods

api_url() click to toggle source

the base API url

# File bin/ghost-backup, line 88
def api_url
  "#{@base_url}/ghost/api/#{API_VERSION}"
end
authorize() click to toggle source

ensure we are logged in refreshes token if we are, prompts for user/password if we are not

# File bin/ghost-backup, line 128
def authorize
  if @refresh_token
    begin
      refresh
    rescue RestClient::Exception
      STDERR.puts "refresh token expired"
      @refresh_token = nil
    end
  end
  
  if @refresh_token.nil?
    puts "Need username, password to generate new token (only used once, not stored)."
    username = @username = ask("Username: ") do |q|
      q.default = @username
      q.validate = /\S+/
    end
    password = ask("Password (not stored): ") { |q| q.echo = '*' }
    new_token(username, password)
    puts "Login success!"
  end
end
backup() click to toggle source

run a real backup

# File bin/ghost-backup, line 162
def backup
  now = DateTime.now
  dest_root = now.strftime(@backup_dir)
  puts "Backing up '#{@base_url}' to '#{dest_root}'"
  FileUtils.mkdir_p(dest_root)
  if File.exists? @ghost_dir
    from = File.join(@ghost_dir, 'content')
    to = File.join(dest_root, 'content')
    puts "Copying #{from} → #{to}"
    FileUtils.cp_r(from, to)
  else
    STDERR.puts "Ghost directory '#{@ghost_dir}' doesn't exist, not backing up assets."
  end
  db_dest = File.join(dest_root, "ghost-db.json")
  db = download_db
  puts "Backing up database to '#{db_dest}'"
  File.open(db_dest, 'w') { |f| f.write(db) }
end
cfg() click to toggle source

gen config as a hash

# File bin/ghost-backup, line 51
def cfg
  Hash[
    CONFIG_KEYS.map { |key|
      [key, self.instance_variable_get("@#{key}")]
    }
  ]
end
db_url() click to toggle source

the url for downloading the database as JSON

# File bin/ghost-backup, line 98
def db_url
  "#{api_url}/db/"
end
download_db() click to toggle source

download the JSON dump of the database

# File bin/ghost-backup, line 153
def download_db
  puts "Downloading ghost database #{db_url}"
  if @access_token.nil?
    authorize
  end
  RestClient.get db_url, {:params => {:access_token => @access_token}}
end
load_config() click to toggle source

load yaml config file

# File bin/ghost-backup, line 60
def load_config
  if not File.exists? @config_file
    @dirty = true
    return
  end
  d = YAML.load_file @config_file
  if not d
    return
  end
  if not d.instance_of? Hash
    throw Error("Bad config: #{config_file}")
  end
  d.each_pair do |key, value|
    self.instance_variable_set("@#{key}", value)
  end
end
new_token(username, password) click to toggle source

generate a new token with username/password via API request

# File bin/ghost-backup, line 103
def new_token(username, password)
  reply = JSON.parse RestClient.post token_url, {
    :grant_type => 'password',
    :username => username,
    :password => password,
    :client_id => 'ghost-admin',
  }
  @refresh_token = reply['refresh_token']
  @access_token = reply['access_token']
  @dirty = true
end
refresh() click to toggle source

refresh authorization token

# File bin/ghost-backup, line 116
def refresh
  reply = JSON.parse RestClient.post token_url, {
    :grant_type => 'refresh_token',
    :refresh_token => @refresh_token,
    :client_id => 'ghost-admin',
  }
  @access_token = reply['access_token']
end
save_config() click to toggle source

save yaml config file, if there have been changes

# File bin/ghost-backup, line 78
def save_config
  return unless @dirty
  puts "Writing config to #{@config_file}"
  File.open(@config_file, 'w') do |f|
    f.write(YAML.dump(cfg))
  end
  @dirty = false
end
token_url() click to toggle source

the url for getting a new token

# File bin/ghost-backup, line 93
def token_url
  "#{api_url}/authentication/token"
end