Instantly share code, notes, and snippets.

Embed
What would you like to do?
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()
@ahamid

This comment has been minimized.

Show comment
Hide comment
@ahamid

ahamid Dec 30, 2011

thanks this worked for me

ahamid commented Dec 30, 2011

thanks this worked for me

@kennym

This comment has been minimized.

Show comment
Hide comment
@kennym

kennym Dec 30, 2011

Owner

kennym commented Dec 30, 2011

@joshuatbrown

This comment has been minimized.

Show comment
Hide comment
@joshuatbrown

joshuatbrown Jan 2, 2012

Worked for me - thanks!

joshuatbrown commented Jan 2, 2012

Worked for me - thanks!

@bebraw

This comment has been minimized.

Show comment
Hide comment
@bebraw

bebraw Apr 23, 2012

I had to add require ''rubygems" before feedzirra to make the script work on OS X Lion.

I also had to change the way dates are parsed like this:

created_datetime = post.updated
creation_date = Date.parse(created_datetime.to_s)

I guess the Blogger RSS format must have changed at some point or something.

bebraw commented Apr 23, 2012

I had to add require ''rubygems" before feedzirra to make the script work on OS X Lion.

I also had to change the way dates are parsed like this:

created_datetime = post.updated
creation_date = Date.parse(created_datetime.to_s)

I guess the Blogger RSS format must have changed at some point or something.

@kennym

This comment has been minimized.

Show comment
Hide comment
@kennym

kennym Apr 23, 2012

That's quite probable. I am glad to receive patches.

Owner

kennym commented Apr 23, 2012

That's quite probable. I am glad to receive patches.

@bebraw

This comment has been minimized.

Show comment
Hide comment
@bebraw

bebraw Apr 23, 2012

Gotcha. I threw in the changes at my fork. Feel free to merge. Might want to test first to make sure I didn't bork things up (I'm a Pythonista :) ).

bebraw commented Apr 23, 2012

Gotcha. I threw in the changes at my fork. Feel free to merge. Might want to test first to make sure I didn't bork things up (I'm a Pythonista :) ).

@kennym

This comment has been minimized.

Show comment
Hide comment
@kennym

kennym Apr 23, 2012

I just merged your changes. Sorry, that I couldn't figure out a way to keep the credits, but your work is most appreciated! Thank you, sir

Owner

kennym commented Apr 23, 2012

I just merged your changes. Sorry, that I couldn't figure out a way to keep the credits, but your work is most appreciated! Thank you, sir

@bebraw

This comment has been minimized.

Show comment
Hide comment
@bebraw

bebraw Apr 23, 2012

No probs. Thanks. :)

bebraw commented Apr 23, 2012

No probs. Thanks. :)

@bebraw

This comment has been minimized.

Show comment
Hide comment
@bebraw

bebraw Apr 23, 2012

Hi, one more thing... I noticed it is better to use "created_datetime = post.published" instead of "created_datetime = post.updated". Might want to change that in your gist. You might want to store the updated time in YAML front matter btw. Probably doesn't hurt.

bebraw commented Apr 23, 2012

Hi, one more thing... I noticed it is better to use "created_datetime = post.published" instead of "created_datetime = post.updated". Might want to change that in your gist. You might want to store the updated time in YAML front matter btw. Probably doesn't hurt.

@kennym

This comment has been minimized.

Show comment
Hide comment
@kennym

kennym Apr 23, 2012

You might want to store the updated time in YAML front matter btw. Probably doesn't hurt.

You lost me. YAML?

Owner

kennym commented Apr 23, 2012

You might want to store the updated time in YAML front matter btw. Probably doesn't hurt.

You lost me. YAML?

@bebraw

This comment has been minimized.

Show comment
Hide comment
@bebraw

bebraw Apr 24, 2012

See this. It's just that little snippet in front of a page.

I updated my Gist to contain the change mentioned above. Feel free to merge.

bebraw commented Apr 24, 2012

See this. It's just that little snippet in front of a page.

I updated my Gist to contain the change mentioned above. Feel free to merge.

@kennym

This comment has been minimized.

Show comment
Hide comment
@kennym

kennym Apr 24, 2012

Merged. :)

Owner

kennym commented Apr 24, 2012

Merged. :)

@basav

This comment has been minimized.

Show comment
Hide comment
@basav

basav Aug 6, 2012

Thanks for this gist. Works

basav commented Aug 6, 2012

Thanks for this gist. Works

@jorgeramirez

This comment has been minimized.

Show comment
Hide comment
@jorgeramirez

jorgeramirez Oct 12, 2012

After changing Config to RbConfig it worked. Thanks!

jorgeramirez commented Oct 12, 2012

After changing Config to RbConfig it worked. Thanks!

@coolaj86

This comment has been minimized.

Show comment
Hide comment
@coolaj86

coolaj86 Jan 24, 2013

FYI, if you'd also like to migrate the comments: http://blog.coolaj86.com/articles/migrate-from-blogger-to-ruhoh-with-proper-redirects.html

This requires changing your template (explained in the walkthrough) and exporting a backup of your blog (also explained in the walkthrough)

coolaj86 commented Jan 24, 2013

FYI, if you'd also like to migrate the comments: http://blog.coolaj86.com/articles/migrate-from-blogger-to-ruhoh-with-proper-redirects.html

This requires changing your template (explained in the walkthrough) and exporting a backup of your blog (also explained in the walkthrough)

@mpenkov

This comment has been minimized.

Show comment
Hide comment
@mpenkov

mpenkov Nov 1, 2013

Thanks for this script! Everything worked well, except the handling of colon characters in the title. They make Jekyll fall over and die, for some reason. Relevant: jekyll/jekyll#549

mpenkov commented Nov 1, 2013

Thanks for this script! Everything worked well, except the handling of colon characters in the title. They make Jekyll fall over and die, for some reason. Relevant: jekyll/jekyll#549

@nikhil91

This comment has been minimized.

Show comment
Hide comment
@nikhil91

nikhil91 commented Feb 16, 2014

thanks:)

@shiv4289

This comment has been minimized.

Show comment
Hide comment
@shiv4289

shiv4289 Apr 22, 2014

Hi Kennym,

Worked for me. Works like a charm. But I had some trouble because the feedzirra module is now renamed to feedjira.
You need to update the script to show that. I did the same and I could do the import then.

I have one question though: I lost the comments I had on blogger in the process. How do I migrate the comments?

shiv4289 commented Apr 22, 2014

Hi Kennym,

Worked for me. Works like a charm. But I had some trouble because the feedzirra module is now renamed to feedjira.
You need to update the script to show that. I did the same and I could do the import then.

I have one question though: I lost the comments I had on blogger in the process. How do I migrate the comments?

@raphink

This comment has been minimized.

Show comment
Hide comment
@raphink

raphink Aug 13, 2014

+1 for feedjira

raphink commented Aug 13, 2014

+1 for feedjira

@DrizzlingCattus

This comment has been minimized.

Show comment
Hide comment
@DrizzlingCattus

DrizzlingCattus Jan 9, 2015

thanks for script!
when I rename feedzirra to feedjira, it work.
but feeds/posts/default option parse only some part of all my posts.
so, I change feeds/posts/default to feeds/posts/default?max-results=100 and it parse all my post.

I link about parsing all post.
http://too-clever-by-half.blogspot.kr/2011/12/blog-feed-500-post-limit-for-more-than.html

DrizzlingCattus commented Jan 9, 2015

thanks for script!
when I rename feedzirra to feedjira, it work.
but feeds/posts/default option parse only some part of all my posts.
so, I change feeds/posts/default to feeds/posts/default?max-results=100 and it parse all my post.

I link about parsing all post.
http://too-clever-by-half.blogspot.kr/2011/12/blog-feed-500-post-limit-for-more-than.html

@caipivara

This comment has been minimized.

Show comment
Hide comment
@caipivara

caipivara Jun 28, 2015

I´m getting blogspot_to_jekyll.rb:25:in

': Use RbConfig instead of obsolete and deprecated Config.
blogspot_to_jekyll.rb:27:in <main>': uninitialized constant CONFIG (NameError) after rename it to feedjira, why?

caipivara commented Jun 28, 2015

I´m getting blogspot_to_jekyll.rb:25:in

': Use RbConfig instead of obsolete and deprecated Config.
blogspot_to_jekyll.rb:27:in <main>': uninitialized constant CONFIG (NameError) after rename it to feedjira, why?

@lolobosse

This comment has been minimized.

Show comment
Hide comment
@lolobosse

lolobosse Sep 5, 2015

@danielgomezrico I got the same problem and solved it on my fork @kennym if you want, you can update yours from my code 😄 👍

lolobosse commented Sep 5, 2015

@danielgomezrico I got the same problem and solved it on my fork @kennym if you want, you can update yours from my code 😄 👍

@mwschwehr

This comment has been minimized.

Show comment
Hide comment
@mwschwehr

mwschwehr Feb 9, 2016

Hi kennym,
Great code. Worked for me on Yosemite with some minor changes.

I removed the deprecated CONFIG call. I think rubygems is now required for El Capitan anyway.

Feedzirra is now called feedjira, so I made the appropriate changes in the code.

After these two minor changes, the code worked perfectly 10.11.3

Feel free to do a pull and merge. In my commit message, i inadvertently stated I was updated for Yosemite. This is my first fork, edit, and push of code on Git, and my first time working in Ruby.

mwschwehr commented Feb 9, 2016

Hi kennym,
Great code. Worked for me on Yosemite with some minor changes.

I removed the deprecated CONFIG call. I think rubygems is now required for El Capitan anyway.

Feedzirra is now called feedjira, so I made the appropriate changes in the code.

After these two minor changes, the code worked perfectly 10.11.3

Feel free to do a pull and merge. In my commit message, i inadvertently stated I was updated for Yosemite. This is my first fork, edit, and push of code on Git, and my first time working in Ruby.

@savita20

This comment has been minimized.

Show comment
Hide comment
@savita20

savita20 May 3, 2018

Even I need help to migrate my blog 'https://shindesavita87.blogspot.co.uk' from blogspot to GitHub blog. Can you suggest me is it doable and if yes and how can we do that?

savita20 commented May 3, 2018

Even I need help to migrate my blog 'https://shindesavita87.blogspot.co.uk' from blogspot to GitHub blog. Can you suggest me is it doable and if yes and how can we do that?

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