class DK::Autofixer

Constants

CONFIGDIR
ERRO
ERROR
INFO
POSTS
VERSION
WARN

Attributes

clear[RW]
config_dir[RW]
dk[RW]
hide_pics[RW]
last_tag[RW]
limit[RW]
postfix[RW]
prefix[RW]
processed[RW]
reprocess[RW]
review[RW]
show_results[RW]
simulate[RW]
spliter[RW]
summary[RW]
tag_idx[RW]
updated[RW]
use_test[RW]

Public Class Methods

new(opts = {}) click to toggle source
# File lib/autofixer/autofixer.rb, line 19
def initialize(opts = {})
  set_instance_vars(opts)
  installed_test_configuration?
  read_configuration
end

Public Instance Methods

apply_tag_matcher_to(posts) click to toggle source

Mass processing based on whitelisted tags return: [Array] Unmatched Posts

# File lib/autofixer/autofixer.rb, line 97
def apply_tag_matcher_to(posts)
  return posts unless @gtags
  return posts if @gtags.empty?
  not_matched = []
  while (post = posts.shift)
    next if post.tags.empty?
    new_comment = tag_matcher(post.tags)
    if new_comment.eql?(ERROR)
      not_matched << post
      next
    end
    success = update_post_comment(post, new_comment)
    (success ? @updated : not_matched) << post
  end
  not_matched
end
capitalize(s) click to toggle source
# File lib/autofixer/helpers.rb, line 8
def capitalize(s)
  return if s.nil?
  res = s.gsub(/\d/,'').split(' ').map(&:strip).map(&:capitalize)
  return res[0] if res.size < 2
  res.join(' ')
end
generate_tags_yml() click to toggle source

Command

# File lib/autofixer/commands/generate_tags_yml.rb, line 4
def generate_tags_yml
  return unless @options.include?('g:tags')
  GenerateTagsYml.new(ARGV)
  exit(0)
end
get_filtered_posts() click to toggle source

Load data and filter out processed or seemingly unprocessible posts

# File lib/autofixer/autofixer.rb, line 48
def get_filtered_posts
  drafts = @usetestdata ? load_test_data : @dk.get_posts
  @total = drafts.size
  drafts.map do |draft|
    draft = DK::Post.new draft
    next if filter_processed? draft
    next if filter_by_info?   draft
    next if filter_by_trail?  draft
    draft
  end.compact
end
normalize(tag, from='') click to toggle source
# File lib/autofixer/helpers.rb, line 3
def normalize(tag, from='')
  return ERROR if tag.nil?
  affix(capitalize(tag))
end
open_results() click to toggle source
# File lib/autofixer/commands/open_results.rb, line 3
def open_results
  return unless @options.include?('open')
  file = confile('updated.html')
  `open #{file}` && exit(0) if File.exist?(file)
  puts
  puts 'Error:'
  puts '  No results have been generated yet.'
  puts
  exit(0)
end
pad(value, reference, prefix=nil) click to toggle source
# File lib/autofixer/helpers.rb, line 19
def pad(value, reference, prefix=nil)
  s = value.to_s
  r = reference.to_s.length
  if prefix
    s = ' ' + s while (s.length < r)
  else
    s += ' ' while (s.length < r)
  end
  s
end
perform_command?() click to toggle source

Execute Command

# File lib/autofixer/autofixer.rb, line 35
def perform_command?
  show_help
  show_config
  show_version
  open_results
  generate_tags_yml
  if @options.first && !@options.first[0].eql?('-')
    puts "\nCommand '#{@options.first}' not found.\n\n"
    exit(1)
  end
end
process(posts) click to toggle source

Construct new post comments based on available configurations

# File lib/autofixer/autofixer.rb, line 61
def process(posts)
  posts.each_with_index do |post, idx|
    tags    = post.tags
    blog    = post.trail.first.blog.name
    summary = post.summary

    next if ignore? blog, post
    # Scan for configured tag-index
    comment = use_tag_index blog, post
    # Use coded configuration
    comment ||= use_commands blog, summary
    # Use full summary text
    comment ||= use_summary blog, summary
    # Use last tag
    comment ||= use_tag_index blog, post, @last_tag.include?(blog)
    # No automated processing
    comment ||= ERROR

    success = update_post_comment(post, comment)
    (success ? @updated : @review) << post
  end
end
run() click to toggle source

Automated Processing

# File lib/autofixer/autofixer.rb, line 26
def run
  perform_command? # Commands will exit(#)
  process(get_filtered_posts)
  @review = apply_tag_matcher_to(@review)
  @review = clear(@review)
  show_results
end
show_config() click to toggle source
# File lib/autofixer/commands/show_config.rb, line 3
def show_config
  return unless @options.include?('config')
  `open #{@config_dir + 'view_config.html'}`
  exit(0)
end
show_help() click to toggle source
# File lib/autofixer/commands/show_help.rb, line 3
def show_help
  return unless (@options.include?('help') || @options.find_index('-h'))
  puts 'Usage: '
  puts '  $ taf [options*]'
  puts '  $ taf <command> [command-options*]'
  puts
  puts ' Commands:'
  puts '    help    Show this menu.'
  puts '    open    Open a webpage with the latest taf results.'
  puts '  g:tags    Generate a list of tags from your latest posts to serve as a whitelist for the Tag Matcher.'
  puts
  puts ' Options:'
  puts '    -s             Simulate Run (no changes saved)'
  puts '    -p [STRING]    Prefix for generated comments'
  puts '    -P [STRING]    Prefix for generated comments'
  puts '    -S [STRING]    Separator used between prefix/postfix and generated comment text.'
  puts '    -l [INTEGER]   Number of Drafts to select for processing.'
  puts '    --clear        Clear unprocessible Drafts by adding the given prefix (-p [STRING])'
  puts '                    causing these posts to show as "Already Processed" in future runs.'
  puts '    --show         Open the results webpage after processing is complete.'
  puts
  puts ' Command Options:'
  puts '   g:tags'
  puts '     -l [INTEGER]         Number of Drafts to select for processing.'
  puts '     -b [STRING]          Blog name, only needed if targeting secondary blog.'
  puts '     --source [STRING]    draft | queue | published '
  puts
  exit(0)
end
show_version() click to toggle source
# File lib/autofixer/commands/show_version.rb, line 3
def show_version
  return unless @options.include?('-v') || @options.include?('--version')
  puts "\ntumblr_autofixer v#{VERSION}"
  puts
  exit(0)
end
tag_matcher(tags) click to toggle source

Contruct a comment using any whitelisted tags return: [String] Normalized Comment

# File lib/autofixer/autofixer.rb, line 86
def tag_matcher(tags)
  return ERROR if tags.empty?
  joiner = ' | '
  matches = tags.select{ |tag| @gtags.include? tag.downcase }
  return ERROR if matches.empty?
  new_comment = matches.join(joiner)
  normalize(new_comment)
end

Private Instance Methods

affix(s) click to toggle source
# File lib/autofixer/autofixer.rb, line 168
def affix(s)
  result = ''
  result += "#{@prefix}" if @prefix
  result += "#{' ' + @spliter + ' '}"
  result += "#{s}"
  if @postfix
    result += "#{' ' + @spliter + ' '}"
    result += "#{@postfix}"
  end
  result
end
bfrom(post) click to toggle source
# File lib/autofixer/results.rb, line 5
def bfrom(post)
  post.trail.first.blog.name rescue '-no trail-'
end
cli_header() click to toggle source
# File lib/autofixer/results.rb, line 92
def cli_header
  puts ' '*80 + "\r\n"  # Clear any lingering text
  if @simulate
    puts '*'*40
    puts '*'*14 + ' SIMULATION ' + '*'*14
    puts '*'*40
    puts
  end
  puts '_'*40
  puts
  puts "#{@total} drafts were retrieved."
  puts "#{pad(@updated.size, @total, 1)} drafts were Autofixed."
  puts "#{pad(@processed.size, @total, 1)} drafts were marked 'already processed'."
  puts "#{pad(@review.size, @total, 1)} drafts require visual review."
  puts '_'*40
  puts
end
confile(fname) click to toggle source
# File lib/autofixer/autofixer.rb, line 228
def confile(fname)
  @config_dir + fname
end
dk_opts() click to toggle source

************************************************************************** Configuration Methods **************************************************************************

# File lib/autofixer/autofixer.rb, line 220
def dk_opts
  { simulate: @simulate, limit: @limit }
end
filter_by_info?(draft) click to toggle source
# File lib/autofixer/autofixer.rb, line 195
def filter_by_info?(draft)
  unless draft.has_info?
    @review << draft
    return true
  end
  false
end
filter_by_trail?(draft) click to toggle source
# File lib/autofixer/autofixer.rb, line 203
def filter_by_trail?(draft)
  unless draft.has_trail?
    @review << draft
    return true
  end
  false
end
filter_processed?(draft) click to toggle source

************************************************************************** Filtration Methods **************************************************************************

# File lib/autofixer/autofixer.rb, line 187
def filter_processed?(draft)
  if draft.processed?(skip: @reprocess, prefix: @prefix)
    @processed << draft
    return true
  end
  false
end
generate_review_webpage(post_info, fname, msg1='') click to toggle source
# File lib/autofixer/results.rb, line 47
def generate_review_webpage(post_info, fname, msg1='')
  page = "<html><head>#{style}</head><body>"
  page += page_nav
  page += messages_html unless @messages.empty?
  page += '<table>'
  page += '<caption>'
  page += "<p>***** SIMULATION RUN *****</p>" if @simulate
  page += "<p>#{msg1}</p>"
  page += "<p>Click a photo to be taken to it's edit page.</p>"
  page += '</caption>'
  page += table_header
  post_info.each_slice(1) do |posts|
    page += '<tr>'
    posts.each{|post| page += post_image_code(post)}
    page += '</tr>'
  end
  page += '</table>'
  page += "</body></html>"

  # Create directory structure and file if it doesn't exist
  File.open(fname, 'w'){|f| f.puts page}
  puts "** Updated file: #{fname} **:\n"
end
home_file(file) click to toggle source
# File lib/autofixer/autofixer.rb, line 224
def home_file(file)
  DK::Config.home_path_file(file)
end
ignore?(blog, post) click to toggle source
# File lib/autofixer/autofixer.rb, line 211
def ignore?(blog, post)
  return false unless @ignore.include? blog
  @review << post
  true
end
image_missing() click to toggle source
# File lib/autofixer/results.rb, line 146
def image_missing
  'https://image.freepik.com/free-icon/male-user-shadow_318-34042.jpg'
end
installed_test_configuration?(result=nil) click to toggle source
# File lib/autofixer/autofixer.rb, line 278
def installed_test_configuration?(result=nil)
  data_yml    = home_file('/coding/ruby/tumblr_autofixer/data.yml.bak')
  summary_yml = home_file('/coding/ruby/tumblr_autofixer/summary.yml')
  if File.exist? data_yml
    `cp #{data_yml} #{confile('data.yml')}`
    result = true
  end
  if File.exist? summary_yml
    `cp #{summary_yml} #{confile('summary.yml')}`
    result = true
  end
  result
end
load_test_data() click to toggle source
# File lib/autofixer/autofixer.rb, line 270
def load_test_data
  return eval(File.open(POSTS, 'r').read) if File.exist? POSTS
  log INFO, "Saved post data to #{POSTS}"
  posts = @dk.get_posts
  File.open(POSTS, 'w') { |f| f.write posts }
  posts
end
log(type, msg) click to toggle source
# File lib/autofixer/autofixer.rb, line 180
def log(type, msg)
  @messages << "#{type.capitalize}: #{msg}"
end
messages_html() click to toggle source
# File lib/autofixer/results.rb, line 71
def messages_html
  msgs = @messages.map { |msg| "<p class='log'>#{msg}</p>"  }
  "<div>#{msgs}</div>"
end
page_nav() click to toggle source
post_image_code(post) click to toggle source
# File lib/autofixer/results.rb, line 76
def post_image_code(post)
  # Alt Sizes (0 - 6) Large to Small
  count = post.photos.size
  photo = post.photos.first.alt_sizes[4].url rescue image_missing
  photo = image_missing if @hide_pics
  from = bfrom(post)
  url = 'http://' + tumblr_url(from)
  # byebug unless url
  res  = "<td><a target='_blank' href='#{link_to_edit(post.id)}'>"
  res += "<img src='#{photo}'>#{'  (' + count.to_s + ')' if count > 1}</a></td>"
  res += "<td><p><a class='blog_link' href='#{url}' target='_blank'>#{from}</a></p></td>"
  res += "<td><p>#{post.comment.empty? ? '' : post.comment}</p></td>"
  res += "<td><p>#{post.summary.empty? ? '' : post.summary}</p></td>"
  res += "<td><p>#{post.tags.empty? ? '-no tags-' : post.tags.join(', ')}</p></td>"
end
prep_user_data_files() click to toggle source
# File lib/autofixer/data_store.rb, line 17
def prep_user_data_files
  ex_blog_name = 'example-blog-name'
  keys = [:no_names, :last_tag, :tag_idx, :summary]
  keys.each do |key|
    unless restore(@ystore, key)
      value = []
      case key
      when :no_names
        value << 'Ignore the following blogs during processing.'
        value << ex_blog_name
      when :last_tag
        value << 'Use the last available tag for these blogs.'
        value << ex_blog_name
      when :tag_idx
        value = [
          ['Use tag #1 for these blogs.', ex_blog_name],
          ['Use tag #2 for these blogs.', ex_blog_name],
          ['Use tag #3 for these blogs.', ex_blog_name]
        ]
      when :summary
        value << 'Capitalize, add prefix and postfix to existing summary text'
        value << ex_blog_name
      end
      store(@ystore, key, value)
    end
  end
end
read_configuration() click to toggle source
# File lib/autofixer/autofixer.rb, line 252
def read_configuration
  # Ensure directory structure exists
  FileUtils::makedirs @config_dir unless Dir.exist?(@config_dir)

  # Ensure configuration files are present
  @ystore   = YAML::Store.new("#{confile('data.yml')}")
  @sstore   = YAML::Store.new("#{confile('summary.yml')}")
  @tstore   = YAML::Store.new("#{confile('tags.yml')}")
  prep_user_data_files

  # Cache config data
  @last_tag = restore(@ystore, :last_tag)
  @tag_idx  = restore(@ystore, :tag_idx)
  @summary  = restore(@ystore, :summary)
  @ignore   = restore(@ystore, :ignore)
  @gtags    = restore(@tstore, :good)
end
restore(dstore, key, default=nil) click to toggle source
# File lib/autofixer/data_store.rb, line 11
def restore(dstore, key, default=nil)
  dstore.transaction do
    dstore[key] || default
  end
end
set_instance_vars(opts) click to toggle source
# File lib/autofixer/autofixer.rb, line 232
def set_instance_vars(opts)
  @options  = opts
  @simulate = @options.include?('-s')
  @limit    = @options[@options.find_index('-l') + 1].to_i rescue nil
  @spliter  = @options[@options.find_index('-S') + 1] rescue ' '
  @prefix   = @options[@options.find_index('-p') + 1] rescue nil
  @postfix  = @options[@options.find_index('-P') + 1] rescue nil
  @clear    = @options.find_index('--clear')
  @reprocess    = @options.find_index('--reprocess')
  @hide_pics    = @options.find_index('--no-pics')
  @usetestdata  = @options.find_index('--test')
  @show_results = @options.find_index('--show')
  @config_dir   = home_file(CONFIGDIR)
  @dk = DK::Client.new(dk_opts)
  @messages  = []
  @processed = []
  @updated   = []
  @review    = []
end
special_summary(summary, from, commands) click to toggle source
# File lib/autofixer/autofixer.rb, line 148
def special_summary(summary, from, commands)
  return nil if summary.nil? || from.nil?
  return nil unless commands
  lines = summary.split("\n")
  res   = summary.downcase
  b     = binding
  commands.each{ |x| eval(x, b) }
  normalize(res)
end
store(dstore, key, value) click to toggle source
# File lib/autofixer/data_store.rb, line 5
def store(dstore, key, value)
  dstore.transaction do
    dstore[key] = value
  end
end
style() click to toggle source
# File lib/autofixer/results.rb, line 128
def style
  %q(
    <style>
      table, tr, nav { width: 100%; text-align: center; vertical-align: middle; }
      th { background-color: grey; border: 1px solid black; color: white; }
      td { width: 25%; border: 1px solid gainsboro; }
      table caption { background-color: rgb(43, 171, 171); }
      nav { height: 100px; background-color: black; color: white; }
      nav ul li { display: inline-block; width: 30%}
      nav ul li a { display: inline-block; width: 100%; }
      nav ul li:hover { background-color: rgb(43, 171, 171); }
      a, a:visited { color: white; vertical-align: middle; line-height: 100px; }
      a.blog_link { color: black; }
      p.log { width: 100%; background-color: rgb(56, 103, 103); color: white; text-align: center; }
    </style>
  )
end
table_header() click to toggle source
# File lib/autofixer/results.rb, line 118
def table_header
  res = '<thead><tr>'
  res += '<th>Photo</th>'
  res += '<th>Source</th>'
  res += '<th>Comment</th>'
  res += '<th>Summary</th>'
  res += '<th>Tags</th>'
  res += '</tr></thead>'
end
update_post_comment(post, comment) click to toggle source
# File lib/autofixer/autofixer.rb, line 142
def update_post_comment(post, comment)
  return false if comment.eql? ERROR
  post.replace_comment_with(comment)
  post.save(client: @dk.client, simulate: @dk.simulate)
end
use_commands(blog, summary) click to toggle source

************************************************************************** Processing Methods ************************************************************************** Use the user coded processing for this blog

# File lib/autofixer/autofixer.rb, line 120
def use_commands(blog, summary)
  commands = restore(@sstore, blog.to_sym)
  special_summary(summary, blog, commands)
end
use_summary(blog, summary) click to toggle source

Normalize and use the full summary text

# File lib/autofixer/autofixer.rb, line 126
def use_summary(blog, summary)
  return nil unless @summary.include?(blog)
  special_summary(summary, blog, [])
end
use_tag_index(blog_name, post, last=nil) click to toggle source

Use the tag at the configured index, if available return: [boolean] Success?

# File lib/autofixer/autofixer.rb, line 133
def use_tag_index(blog_name, post, last=nil)
  return normalize post.tags.last if last
  @tag_idx.each_with_index do |names, idx|
    next unless names.include?(blog_name)
    return normalize(post.tags[idx])
  end
  nil
end