jekyll-import 0.1.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source "https://rubygems.org"
2
+ gemspec
data/History.txt ADDED
@@ -0,0 +1,7 @@
1
+ == HEAD
2
+ * Major Enhancements
3
+ * Improve MovableType importer (#13)
4
+ * Minor Enhancements
5
+ * Bug Fixes
6
+ * Site Enhancements
7
+ * Development fixes
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ (The MIT License)
2
+
3
+ Copyright (c) 2013 Tom Preston-Werner
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the 'Software'), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,4 @@
1
+ jekyll-import
2
+ =============
3
+
4
+ The Jekyll import command for importing from various blogs to Jekyll format.
data/Rakefile ADDED
@@ -0,0 +1,151 @@
1
+ # require 'rake/testtask'
2
+
3
+ # Rake::TestTask.new do |t|
4
+ # t.libs << 'test'
5
+ # end
6
+
7
+ # desc "Run tests"
8
+ # task :default => :test
9
+
10
+ require 'rubygems'
11
+ require 'rake'
12
+ require 'date'
13
+
14
+ #############################################################################
15
+ #
16
+ # Helper functions
17
+ #
18
+ #############################################################################
19
+
20
+ def name
21
+ @name ||= Dir['*.gemspec'].first.split('.').first
22
+ end
23
+
24
+ def version
25
+ line = File.read("lib/#{name}.rb")[/^\s*VERSION\s*=\s*.*/]
26
+ line.match(/.*VERSION\s*=\s*['"](.*)['"]/)[1]
27
+ end
28
+
29
+ def date
30
+ Date.today.to_s
31
+ end
32
+
33
+ def rubyforge_project
34
+ name
35
+ end
36
+
37
+ def gemspec_file
38
+ "#{name}.gemspec"
39
+ end
40
+
41
+ def gem_file
42
+ "#{name}-#{version}.gem"
43
+ end
44
+
45
+ def replace_header(head, header_name)
46
+ head.sub!(/(\.#{header_name}\s*= ').*'/) { "#{$1}#{send(header_name)}'"}
47
+ end
48
+
49
+ #############################################################################
50
+ #
51
+ # Standard tasks
52
+ #
53
+ #############################################################################
54
+
55
+ task :default => :test
56
+
57
+ require 'rake/testtask'
58
+ Rake::TestTask.new(:test) do |test|
59
+ test.libs << 'lib' << 'test'
60
+ test.pattern = 'test/**/test_*.rb'
61
+ test.verbose = true
62
+ end
63
+
64
+ require 'rdoc/task'
65
+ Rake::RDocTask.new do |rdoc|
66
+ rdoc.rdoc_dir = 'rdoc'
67
+ rdoc.title = "#{name} #{version}"
68
+ rdoc.rdoc_files.include('README*')
69
+ rdoc.rdoc_files.include('lib/**/*.rb')
70
+ end
71
+
72
+ desc "Open an irb session preloaded with this library"
73
+ task :console do
74
+ sh "irb -rubygems -r ./lib/#{name}.rb"
75
+ end
76
+
77
+ #############################################################################
78
+ #
79
+ # Custom tasks (add your own tasks here)
80
+ #
81
+ #############################################################################
82
+
83
+ namespace :migrate do
84
+ desc "Migrate from mephisto in the current directory"
85
+ task :mephisto do
86
+ sh %q(ruby -r './lib/jekyll/migrators/mephisto' -e 'Jekyll::Mephisto.postgres(:database => "#{ENV["SERVER"]}", "#{ENV["DB"]}")')
87
+ end
88
+ desc "Migrate from Movable Type in the current directory"
89
+ task :mt do
90
+ sh %q(ruby -r './lib/jekyll/migrators/mt' -e 'Jekyll::MT.process("#{ENV["DB"]}", "#{ENV["USER"]}", "#{ENV["PASS"]}")')
91
+ end
92
+ desc "Migrate from Typo in the current directory"
93
+ task :typo do
94
+ sh %q(ruby -r './lib/jekyll/migrators/typo' -e 'Jekyll::Typo.process("#{ENV["DB"]}", "#{ENV["USER"]}", "#{ENV["PASS"]}")')
95
+ end
96
+ end
97
+
98
+ #############################################################################
99
+ #
100
+ # Packaging tasks
101
+ #
102
+ #############################################################################
103
+
104
+ desc "Create tag v#{version} and build and push #{gem_file} to Rubygems"
105
+ task :release => :build do
106
+ unless `git branch` =~ /^\* master$/
107
+ puts "You must be on the master branch to release!"
108
+ exit!
109
+ end
110
+ sh "git commit --allow-empty -a -m 'Release #{version}'"
111
+ sh "git tag v#{version}"
112
+ sh "git push origin master"
113
+ sh "git push origin v#{version}"
114
+ sh "gem push pkg/#{name}-#{version}.gem"
115
+ end
116
+
117
+ desc "Build #{gem_file} into the pkg directory"
118
+ task :build => :gemspec do
119
+ sh "mkdir -p pkg"
120
+ sh "gem build #{gemspec_file}"
121
+ sh "mv #{gem_file} pkg"
122
+ end
123
+
124
+ desc "Generate #{gemspec_file}"
125
+ task :gemspec do
126
+ # read spec file and split out manifest section
127
+ spec = File.read(gemspec_file)
128
+ head, manifest, tail = spec.split(" # = MANIFEST =\n")
129
+
130
+ # replace name version and date
131
+ replace_header(head, :name)
132
+ replace_header(head, :version)
133
+ replace_header(head, :date)
134
+ #comment this out if your rubyforge_project has a different name
135
+ replace_header(head, :rubyforge_project)
136
+
137
+ # determine file list from git ls-files
138
+ files = `git ls-files`.
139
+ split("\n").
140
+ sort.
141
+ reject { |file| file =~ /^\./ }.
142
+ reject { |file| file =~ /^(rdoc|pkg)/ }.
143
+ map { |file| " #{file}" }.
144
+ join("\n")
145
+
146
+ # piece file back together and write
147
+ manifest = " s.files = %w[\n#{files}\n ]\n"
148
+ spec = [head, manifest, tail].join(" # = MANIFEST =\n")
149
+ File.open(gemspec_file, 'w') { |io| io.write(spec) }
150
+ puts "Updated #{gemspec_file}"
151
+ end
@@ -0,0 +1,80 @@
1
+ Gem::Specification.new do |s|
2
+ s.specification_version = 2 if s.respond_to? :specification_version=
3
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
4
+ s.rubygems_version = '1.3.5'
5
+
6
+ s.name = 'jekyll-import'
7
+ s.version = '0.1.0.beta1'
8
+ s.date = '2013-03-19'
9
+ s.rubyforge_project = 'jekyll-import'
10
+
11
+ s.summary = "Import command for Jekyll (static site generator)."
12
+ s.description = "Provides the Import command for Jekyll."
13
+
14
+ s.authors = ["Tom Preston-Werner"]
15
+ s.email = 'tom@mojombo.com'
16
+ s.homepage = 'http://github.com/mojombo/jekyll-import'
17
+
18
+ s.require_paths = %w[lib]
19
+
20
+ s.rdoc_options = ["--charset=UTF-8"]
21
+ s.extra_rdoc_files = %w[README.md LICENSE]
22
+
23
+ s.add_runtime_dependency('jekyll')
24
+ s.add_runtime_dependency('fastercsv')
25
+ s.add_runtime_dependency('nokogiri')
26
+ s.add_runtime_dependency('safe_yaml', '~> 0.7')
27
+
28
+ # development dependencies
29
+ s.add_development_dependency('rake', "~> 10.0.3")
30
+ s.add_development_dependency('rdoc', "~> 4.0.0")
31
+
32
+ # test dependencies:
33
+ s.add_development_dependency('redgreen', "~> 1.2")
34
+ s.add_development_dependency('shoulda', "~> 3.3.2")
35
+ s.add_development_dependency('rr', "~> 1.0")
36
+ s.add_development_dependency('simplecov', "~> 0.7")
37
+ s.add_development_dependency('simplecov-gem-adapter', "~> 1.0.1")
38
+
39
+ # migrator dependencies:
40
+ s.add_development_dependency('sequel', "~> 3.42")
41
+ s.add_development_dependency('htmlentities', "~> 4.3")
42
+ s.add_development_dependency('hpricot', "~> 0.8")
43
+ s.add_development_dependency('mysql', "~> 2.8")
44
+ s.add_development_dependency('pg', "~> 0.12")
45
+
46
+ # = MANIFEST =
47
+ s.files = %w[
48
+ Gemfile
49
+ History.txt
50
+ LICENSE
51
+ README.md
52
+ Rakefile
53
+ jekyll-import.gemspec
54
+ lib/jekyll-import.rb
55
+ lib/jekyll/commands/import.rb
56
+ lib/jekyll/jekyll-import/csv.rb
57
+ lib/jekyll/jekyll-import/drupal6.rb
58
+ lib/jekyll/jekyll-import/drupal7.rb
59
+ lib/jekyll/jekyll-import/enki.rb
60
+ lib/jekyll/jekyll-import/joomla.rb
61
+ lib/jekyll/jekyll-import/marley.rb
62
+ lib/jekyll/jekyll-import/mephisto.rb
63
+ lib/jekyll/jekyll-import/mt.rb
64
+ lib/jekyll/jekyll-import/posterous.rb
65
+ lib/jekyll/jekyll-import/rss.rb
66
+ lib/jekyll/jekyll-import/s9y.rb
67
+ lib/jekyll/jekyll-import/textpattern.rb
68
+ lib/jekyll/jekyll-import/tumblr.rb
69
+ lib/jekyll/jekyll-import/typo.rb
70
+ lib/jekyll/jekyll-import/wordpress.rb
71
+ lib/jekyll/jekyll-import/wordpressdotcom.rb
72
+ test/helper.rb
73
+ test/test_mt_importer.rb
74
+ test/test_wordpress_importer.rb
75
+ test/test_wordpressdotcom_importer.rb
76
+ ]
77
+ # = MANIFEST =
78
+
79
+ s.test_files = s.files.select { |path| path =~ /^test\/test_.*\.rb/ }
80
+ end
@@ -0,0 +1,7 @@
1
+ $:.unshift File.dirname(__FILE__) # For use/testing when no gem is installed
2
+ require 'rubygems'
3
+ require 'jekyll/commands/import'
4
+
5
+ module JekyllImport
6
+ VERSION = '0.1.0.beta1'
7
+ end
@@ -0,0 +1,51 @@
1
+ $:.unshift File.expand_path("../../", File.dirname(__FILE__)) # load from jekyll-import/lib
2
+ require 'jekyll/command'
3
+
4
+ module Jekyll
5
+ module Commands
6
+ class Import < Command
7
+ IMPORTERS = {
8
+ :csv => 'CSV',
9
+ :drupal6 => 'Drupal6',
10
+ :drupal7 => 'Drupal7',
11
+ :enki => 'Enki',
12
+ :joomla => 'Joomla',
13
+ :marley => 'Marley',
14
+ :mephisto => 'Mephisto',
15
+ :mt => 'MT',
16
+ :posterous => 'Posterous',
17
+ :rss => 'RSS',
18
+ :s9y => 'S9Y',
19
+ :textpattern => 'TextPattern',
20
+ :tumblr => 'Tumblr',
21
+ :typo => 'Typo',
22
+ :wordpress => 'WordPress',
23
+ :wordpressdotcom => 'WordpressDotCom'
24
+ }
25
+
26
+ def self.abort_on_invalid_migator
27
+ msg = "You must specify a valid migrator. Valid choices:\n"
28
+ IMPORTERS.keys.each do |k, v|
29
+ msg += "* #{k}\n"
30
+ end
31
+ abort msg
32
+ end
33
+
34
+ def self.process(migrator, options)
35
+ if IMPORTERS.keys.include?(migrator.to_sym)
36
+ migrator = migrator.downcase
37
+
38
+ require File.join(File.dirname(__FILE__), "..", "jekyll-import", "#{migrator}.rb")
39
+
40
+ if JekyllImport.const_defined?(IMPORTERS[migrator.to_sym])
41
+ puts 'Importing...'
42
+ klass = JekyllImport.const_get(IMPORTERS[migrator.to_sym])
43
+ klass.process(options.__hash__)
44
+ end
45
+ else
46
+ abort_on_invalid_migator
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,26 @@
1
+ module JekyllImport
2
+ module CSV
3
+ # Reads a csv with title, permalink, body, published_at, and filter.
4
+ # It creates a post file for each row in the csv
5
+ def self.process(file = "posts.csv")
6
+ FileUtils.mkdir_p "_posts"
7
+ posts = 0
8
+ FasterCSV.foreach(file) do |row|
9
+ next if row[0] == "title"
10
+ posts += 1
11
+ name = row[3].split(" ")[0]+"-"+row[1]+(row[4] =~ /markdown/ ? ".markdown" : ".textile")
12
+ File.open("_posts/#{name}", "w") do |f|
13
+ f.puts <<-HEADER
14
+ ---
15
+ layout: post
16
+ title: #{row[0]}
17
+ ---
18
+
19
+ HEADER
20
+ f.puts row[2]
21
+ end
22
+ end
23
+ "Created #{posts} posts!"
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,102 @@
1
+ require 'rubygems'
2
+ require 'sequel'
3
+ require 'fileutils'
4
+ require 'safe_yaml'
5
+
6
+ # NOTE: This converter requires Sequel and the MySQL gems.
7
+ # The MySQL gem can be difficult to install on OS X. Once you have MySQL
8
+ # installed, running the following commands should work:
9
+ # $ sudo gem install sequel
10
+ # $ sudo gem install mysql -- --with-mysql-config=/usr/local/mysql/bin/mysql_config
11
+
12
+ module JekyllImport
13
+ module Drupal6
14
+ # Reads a MySQL database via Sequel and creates a post file for each story
15
+ # and blog node in table node.
16
+ QUERY = "SELECT n.nid, \
17
+ n.title, \
18
+ nr.body, \
19
+ n.created, \
20
+ n.status \
21
+ FROM node AS n, \
22
+ node_revisions AS nr \
23
+ WHERE (n.type = 'blog' OR n.type = 'story') \
24
+ AND n.vid = nr.vid"
25
+
26
+ def self.process(dbname, user, pass, host = 'localhost', prefix = '')
27
+ db = Sequel.mysql(dbname, :user => user, :password => pass, :host => host, :encoding => 'utf8')
28
+
29
+ if prefix != ''
30
+ QUERY[" node "] = " " + prefix + "node "
31
+ QUERY[" node_revisions "] = " " + prefix + "node_revisions "
32
+ end
33
+
34
+ FileUtils.mkdir_p "_posts"
35
+ FileUtils.mkdir_p "_drafts"
36
+
37
+ # Create the refresh layout
38
+ # Change the refresh url if you customized your permalink config
39
+ File.open("_layouts/refresh.html", "w") do |f|
40
+ f.puts <<EOF
41
+ <!DOCTYPE html>
42
+ <html>
43
+ <head>
44
+ <meta http-equiv="content-type" content="text/html; charset=utf-8" />
45
+ <meta http-equiv="refresh" content="0;url={{ page.refresh_to_post_id }}.html" />
46
+ </head>
47
+ </html>
48
+ EOF
49
+ end
50
+
51
+ db[QUERY].each do |post|
52
+ # Get required fields and construct Jekyll compatible name
53
+ node_id = post[:nid]
54
+ title = post[:title]
55
+ content = post[:body]
56
+ created = post[:created]
57
+ time = Time.at(created)
58
+ is_published = post[:status] == 1
59
+ dir = is_published ? "_posts" : "_drafts"
60
+ slug = title.strip.downcase.gsub(/(&|&amp;)/, ' and ').gsub(/[\s\.\/\\]/, '-').gsub(/[^\w-]/, '').gsub(/[-_]{2,}/, '-').gsub(/^[-_]/, '').gsub(/[-_]$/, '')
61
+ name = time.strftime("%Y-%m-%d-") + slug + '.md'
62
+
63
+ # Get the relevant fields as a hash, delete empty fields and convert
64
+ # to YAML for the header
65
+ data = {
66
+ 'layout' => 'post',
67
+ 'title' => title.to_s,
68
+ 'created' => created,
69
+ }.delete_if { |k,v| v.nil? || v == ''}.to_yaml
70
+
71
+ # Write out the data and content to file
72
+ File.open("#{dir}/#{name}", "w") do |f|
73
+ f.puts data
74
+ f.puts "---"
75
+ f.puts content
76
+ end
77
+
78
+ # Make a file to redirect from the old Drupal URL
79
+ if is_published
80
+ aliases = db["SELECT dst FROM #{prefix}url_alias WHERE src = ?", "node/#{node_id}"].all
81
+
82
+ aliases.push(:dst => "node/#{node_id}")
83
+
84
+ aliases.each do |url_alias|
85
+ FileUtils.mkdir_p url_alias[:dst]
86
+ File.open("#{url_alias[:dst]}/index.md", "w") do |f|
87
+ f.puts "---"
88
+ f.puts "layout: refresh"
89
+ f.puts "refresh_to_post_id: /#{time.strftime("%Y/%m/%d/") + slug}"
90
+ f.puts "---"
91
+ end
92
+ end
93
+ end
94
+ end
95
+
96
+ # TODO: Make dirs & files for nodes of type 'page'
97
+ # Make refresh pages for these as well
98
+
99
+ # TODO: Make refresh dirs & files according to entries in url_alias table
100
+ end
101
+ end
102
+ end