class AsciiPress::WordPressSyncer

Public Class Methods

new(hostname, username, password, post_type, renderer, options = {}) click to toggle source

Creates a synchronizer object which can be used to synchronize a set of asciidoc files to WordPress posts @param hostname [String] Hostname for WordPress blog @param username [String] Wordpress username @param password [String] Wordpress password @param post_type [String] Wordpress post type to synchronize posts with @param renderer [Renderer] Renderer object which will be used to process asciidoctor files @param options [Hash] @option options [Logger] :logger Logger to be used for informational output. Defaults to {AsciiPress.logger} @option options [Proc] :filter_proc Proc which is given an AsciiDoctor::Document object and returns true or false to decide if a document should be synchronized @option options [Boolean] :delete_not_found Should posts on the WordPress server which don't match any documents locally get deleted? @option options [Boolean] :generate_tags Should asciidoctor tags be synchronized to WordPress? (defaults to false) @option options [String] :post_status The status to assign to posts when they are synchronized. Defaults to +'draft'+. See the {github.com/zachfeldman/rubypress rubypress} documentation

# File lib/ascii_press.rb, line 137
def initialize(hostname, username, password, post_type, renderer, options = {})
  @hostname = hostname
  @wp_client = Rubypress::Client.new(host: @hostname, username: username, password: password)
  @post_type = post_type
  @logger = options[:logger] || AsciiPress.logger
  @renderer = renderer || Renderer.new
  @filter_proc = options[:filter_proc] || Proc.new { true }
  @delete_not_found = options[:delete_not_found]
  @generate_tags = options[:generate_tags]
  @options = options

  all_pages = @wp_client.getPosts(filter: {post_type: @post_type, number: 1000})
  @all_pages_by_post_name = all_pages.index_by {|post| post['post_name'] }
  log :info, "Got #{@all_pages_by_post_name.size} pages from the database"
end

Public Instance Methods

sync(adoc_file_paths, custom_fields = {}) click to toggle source

@param adoc_file_path [Array <String>] Paths of the asciidoctor files to synchronize @param custom_fields [Hash] Custom fields for WordPress.

# File lib/ascii_press.rb, line 155
def sync(adoc_file_paths, custom_fields = {})
  synced_post_names = []

  adoc_file_paths.each do |adoc_file_path|
    synced_post_names << sync_file_path(adoc_file_path, custom_fields)
  end

  if @delete_not_found
    (@all_pages_by_post_name.keys - synced_post_names).each do |post_name_to_delete|
      post_id = @all_pages_by_post_name[post_name_to_delete]['post_id']

      log :info, "Deleting missing post_name: #{post_name_to_delete} (post ##{post_id})"

      send_message(:deletePost, blog_id: @hostname, post_id: post_id)
    end

  end
end

Private Instance Methods

log(level, message) click to toggle source
# File lib/ascii_press.rb, line 239
def log(level, message)
  @logger.send(level, "WORDPRESS: #{message}")
end
new_content_same_as_page?(content, page) click to toggle source
# File lib/ascii_press.rb, line 228
def new_content_same_as_page?(content, page)
  main_keys_different = %i(post_content post_title post_name post_status).any? do |key|
    content[key] != page[key.to_s]
  end

  page_fields = page['custom_fields'].each_with_object({}) {|field, h| h[field['key']] = field['value'] }
  content_fields = content[:custom_fields].each_with_object({}) {|field, h| h[field[:key].to_s] = field[:value] }

  !main_keys_different && oyyyy
end
send_message(message, *args) click to toggle source
# File lib/ascii_press.rb, line 243
def send_message(message, *args)
  @wp_client.send(message, *args).tap do |result|
    raise "WordPress #{message} failed!" if !result
  end
end
sync_file_path(adoc_file_path, custom_fields = {}) click to toggle source
# File lib/ascii_press.rb, line 176
def sync_file_path(adoc_file_path, custom_fields = {})
  rendering = @renderer.render(adoc_file_path)

  return if !@filter_proc.call(rendering.doc)

  if !(slug = rendering.attribute_value(:slug))
    log :warn, "WARNING: COULD NOT POST DUE TO NO SLUG FOR: #{adoc_file_path}"
    return
  end

  title = rendering.title
  html = rendering.html

  log :info, "Syncing to WordPress: #{title} (slug: #{slug})"

  # log :info, "data: #{rendering.data.inspect}"

  custom_fields_array = custom_fields.merge('adoc_attributes' => rendering.doc.attributes.to_json).map {|k, v| {key: k, value: v} }
  content = {
              post_type:     @post_type,
              post_date:     Time.now - 60*60*24,
              post_content:  html,
              post_title:    title,
              post_name:     slug,
              post_status:   @options[:post_status] || 'draft',
              custom_fields: custom_fields_array
            }

  content[:terms_names] = {post_tag: rendering.tags} if @generate_tags

  if page = @all_pages_by_post_name[slug]
    if page['custom_fields']
      content[:custom_fields].each do |f|
        found = page['custom_fields'].find { |field| field['key'] == f[:key] }
        f['id'] = found['id'] if found
      end
    end

    post_id = page['post_id'].to_i

    log :info, "Editing Post ##{post_id} on _#{@hostname}_ custom-field #{content[:custom_fields].inspect}"

    send_message(:editPost, blog_id: @hostname, post_id: post_id, content: content)
  else
    log :info, "Making a new post for '#{title}' on _#{@hostname}_"

    send_message(:newPost, blog_id: @hostname, content: content)
  end

  slug
end