class GooglePlusMarkdown

Public Instance Methods

convert(data) click to toggle source
# File lib/googleplus_markdown.rb, line 11
def convert(data)
  # Let's declare the output string.
  markdown = ""

  # I need the creation date so I can set the file name.
  # Of course, Google can't just call it a 'created' date.
  date_created = data['published']
  file_name = "#{date_created}.md"

  # Instead of doing multiple writes to a file, I'm going to
  # build a string that I can pass around to various functions.
  # When I'm done, I'll write *that* to the file.
  markdown.concat(generate_front_matter(data))

  # I'm getting the raw text of the post, with Google+'s half-assed
  # implementation of Textile for markup.
  markdown.concat("#{retrieve_post_content(data)}\n\n")

  # Let's get some photos tacked onto the end, shall we?
  markdown.concat("#{attach_images(data)}\n")

  # If anybody replied to these posts, let's retrieve the replies
  # and tack them onto the end. Some of them are actually worth a damn.
  replies = data['object']['replies']['items']
  unless(replies == nil)
    markdown.concat("#{retrieve_replies(replies)}")
  end

  handle_file_io(markdown, file_name)
end

Private Instance Methods

attach_images(data) click to toggle source
# File lib/googleplus_markdown.rb, line 190
def attach_images(data)
  content = ""
  attachments = data['object']['attachments']

  unless(attachments == nil)
    attachments.each do |attachment|
      object_type = attachment['objectType']

      unless(object_type != "photo")
        id = attachment['id']
        url = attachment['fullImage']['url']

        content.concat("![#{id}](#{url})")
      end
    end
  end

  return content
end
generate_front_matter(data) click to toggle source
# File lib/googleplus_markdown.rb, line 44
def generate_front_matter(data)
  content = ""

  attachment = Hash.new
  unless data['object']['attachments'] == nil
    attachment = data['object']['attachments'][0]
  end

  # you need this before and after a YAML front matter block.
  yaml_delimiter = "---"

  # Google+ post titles are wonky. Let's just take the first line.
  # by default. You can always edit the markdown file afterward.
  # I'm also stripping out the newline character at the end.
  if attachment != nil && attachment['displayName']
    post_title = attachment['displayName']
  elsif data['title'].length != 0
    post_title = data['title'].lines.first.delete!("\n")
  else
    post_title = "No Title Available"
  end

  # I'm getting the raw text of the post, with Google+'s half-assed
  # implementation of Textile for markup.
  post_content = data['object']['originalContent']

  # We'll use the first 150 charcters as the post excerpt.
  # If you use the Markdown output in Jekyll, it'll put this
  # in the description meta tag, which used to be good for SEO.
  # Maybe it still is, but I don't get paid to give a shit.
  # We'll replace newlines with spaces here. Edit as needed.
  if post_content != nil
    post_excerpt = post_content[0..150].gsub("\n", " ")
  elsif attachment != nil && attachment['objectType'] == "video"
    post_excerpt = attachment['displayName']
  else
    post_excerpt = "No Excerpt Available"
  end

  # Let's clean up the excerpt a bit.
  processed_excerpt = process_post_content(post_excerpt)

  # Google can't use "created" and "modified"; that would
  # make too much sense. They used "published" and "updated"
  # instead, respectively. We'll use the published date
  # to name the Markdown output file, and include it in the
  # YAML front matter. If the updated date is different,
  # I'll include that too.
  #
  # Of course, you'll want to rename each markdown file to match
  # the format specified in the Jekyll documentation at
  # http://jekyllrb.com/docs/posts/. Otherwise, your permalinks
  # will probably look like shit.
  date_created = data['published']
  date_modified = data['updated']

  # let's build the output string now.
  content.concat("#{yaml_delimiter}\n")
  content.concat("layout: post\n")
  content.concat("title: \"#{post_title}\"\n")
  content.concat("categories: blog\n")
  content.concat("excerpt: \"#{processed_excerpt}\"\n")

  # Let's see if there's an article attached.
  unless(attachment == nil)
    object_type = attachment['objectType']

    case object_type
    when "video"
      video_url = attachment['url']
      content.concat("link: \"#{video_url}\"\n")
    when "article"
      article_url = attachment['url']
      article_title = attachment['displayName']

      content.concat("link: \"#{article_url}\"\n")
      content.concat("linkTitle: \"#{article_title}\"\n")
    end
  end

  # Check for an updated date and add it if it exists.
  content.concat("date: #{date_created}\n")
  unless(date_created == date_modified)
    content.concat("updated: #{date_modified}\n")
  end
  content.concat("#{yaml_delimiter}\n")

  return content
end
handle_file_io(content, filename) click to toggle source
# File lib/googleplus_markdown.rb, line 210
def handle_file_io(content, filename)
  # Now the fun begins. First, let's see if the output directory exists.
  # If it doesn't, create it.
  output_dir = "./markdown"
  unless(Dir.exist?(output_dir))
    Dir.mkdir(output_dir)
  end

  # Generate the file path.
  file_path = File.join(output_dir, filename)

  # Now let's open the file to write...
  output = File.open(file_path, "w")

  # Put in the post content, close the file, and we're done.
  output.puts(content)
  output.close
end
process_post_content(content) click to toggle source
# File lib/googleplus_markdown.rb, line 134
def process_post_content(content)
  # Pretty much the only thing Google+ took from Textile markup
  # is their notation for bold and italic text. I'm converting it
  # to Markdown style here in a quick and dirty 2 stage process.
  content.gsub!("\*", "\*\*")
  content.gsub!("\_", "\*")

  # Google+ mentions are complicated. They resolve to names when
  # rendered in the desktop or mobile app, but are stored as
  # 21-digit numbers prefixed with an @ symbol. I can convert these
  # to Markdown-formatted links with URLs you can paste into your
  # browser to actually get the names.
  mentions = content.scan(/\@(?:[0-9]{21})/).flatten
  mentions.each { |m| content.gsub!(m, "[SOMEBODY](https://plus.google.com/#{m.gsub("@", "")})") }

  return content
end
retrieve_post_content(data) click to toggle source
# File lib/googleplus_markdown.rb, line 152
def retrieve_post_content(data)
  post_content = data['object']['originalContent']

  attachment = Hash.new
  unless data['object']['attachments'] == nil
    attachment = data['object']['attachments'][0]
  end

  if post_content != nil
    # Processing the content gets complicated when you factor
    # in mentions. We'll define a function for this.
    processed_content = process_post_content(post_content)
  elsif attachment['objectType'] == "video"
    processed_content = data['annotation']
  else
    processed_content = "No Post Text Available"
  end

  return processed_content
end
retrieve_replies(replies) click to toggle source
# File lib/googleplus_markdown.rb, line 173
def retrieve_replies(replies)
  content = "\#\# Comments from Google+ users\n\n"

  replies.each do |reply|
    name = reply['actor']['displayName']
    profile_url = reply['actor']['url']
    reply_date = Date.parse(reply['published'])
    reply_text = reply['object']['content']

    content.concat("\#\#\#\#[#{name}](#{profile_url})\n")
    content.concat("**posted on #{reply_date.strftime("%A, %m/%d/%Y at %I:%M%P %Z")}**\n\n")
    content.concat("#{reply_text}\n\n")
  end

  return content
end