Skip to content

Instantly share code, notes, and snippets.

@kennym
Created July 30, 2011 18:14
Show Gist options
  • Save kennym/1115810 to your computer and use it in GitHub Desktop.
Save kennym/1115810 to your computer and use it in GitHub Desktop.
Migrate your blogger blog posts to jekyll.
#!/usr/bin/env ruby
#
# Convert blogger (blogspot) posts to jekyll posts
#
# Basic Usage
# -----------
#
# ./blogger_to_jekyll.rb feed_url
#
# where `feed_url` can have the following format:
#
# http://{your_blog_name}.blogspot.com/feeds/posts/default
#
# Requirements
# ------------
#
# * feedzirra: https://github.com/pauldix/feedzirra
#
# Notes
# -----
#
# * Make sure Blogger shows full output of article in feeds.
# * Commenting on migrated articles will be set to false by default.
include Config
require 'rubygems' if CONFIG['host_os'].start_with? "darwin"
require 'feedzirra'
require 'date'
require 'optparse'
def parse_post_entries(feed, verbose)
posts = []
feed.entries.each do |post|
obj = Hash.new
created_datetime = post.updated
creation_date = Date.parse(created_datetime.to_s)
title = post.title
file_name = creation_date.to_s + "-" + title.split(/ */).join("-").delete('\/') + ".html"
content = post.content
obj["file_name"] = file_name
obj["title"] = title
obj["creation_datetime"] = created_datetime
obj["updated_datetime"] = post.updated
obj["content"] = content
obj["categories"] = post.categories.join(" ")
posts.push(obj)
end
return posts
end
def write_posts(posts, verbose)
Dir.mkdir("_posts") unless File.directory?("_posts")
total = posts.length, i = 1
posts.each do |post|
file_name = "_posts/".concat(post["file_name"])
header = %{---
layout: post
title: #{post["title"]}
date: #{post["creation_datetime"]}
updated: #{post["updated_datetime"]}
comments: false
categories: #{post["categories"]}
---
}
File.open(file_name, "w+") {|f|
f.write(header)
f.write(post["content"])
f.close
}
if verbose
puts " [#{i}/#{total[0]}] Written post #{file_name}"
i += 1
end
end
end
def main
options = {}
opt_parser = OptionParser.new do |opt|
opt.banner = "Usage: ./blogger_to_jekyll.rb FEED_URL [OPTIONS]"
opt.separator ""
opt.separator "Options"
opt.on("-v", "--verbose", "Print out all.") do
options[:verbose] = true
end
end
opt_parser.parse!
if ARGV[0]
feed_url = ARGV.first
else
puts opt_parser
exit()
end
puts "Fetching feed #{feed_url}..."
feed = Feedzirra::Feed.fetch_and_parse(feed_url)
puts "Parsing feed..."
posts = parse_post_entries(feed, options[:verbose])
puts "Writing posts to _posts/..."
write_posts(posts, options[:verbose])
puts "Done!"
end
main()
@rupeshtiwari
Copy link

I am getting this error <internal:C:/Ruby30-x64/lib/ruby/3.0.0/rubygems/core_ext/kernel_require.rb>:85:in require': cannot load such file -- feedzirra`

@RobbiNespu
Copy link

If anyone looking new changes. This is my fork https://gist.github.com/RobbiNespu/372571e4d271122ece3ee3a1830b4d26

@prabathbr
Copy link

If anyone looking new changes. This is my fork https://gist.github.com/RobbiNespu/372571e4d271122ece3ee3a1830b4d26

Thanks for the update. I have updated the code to fix few more errors which I have encountered.

My Fork: https://gist.github.com/prabathbr/0bb416b2dee7ed18d2a6fd3d8dd4b021

Updates:

  • added <require 'httparty'>
  • created "setup.sh" which will make a ruby environment to run the script in Ubuntu 20.04 LTS
  • fixed script error[Invalid argument @ rb_sysopen --- post name ---- (Errno::EINVAL)] when running on posts with invalid post names with ":" & "*"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment