typepad_to_jekyll 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/LICENSE ADDED
@@ -0,0 +1,8 @@
1
+ License Terms
2
+ =============
3
+
4
+ Distributed under the user's choice of the [GPL Version 2](http://www.gnu.org/licenses/old-licenses/gpl-2.0.html) (see COPYING for details) or the
5
+ [Ruby software license](http://www.ruby-lang.org/en/LICENSE.txt) by
6
+ Chris Stansbury.
7
+
8
+ Feel free to email [Chris Stansbury](mailto:chris@koozie.org) with any questions.
@@ -0,0 +1,47 @@
1
+ Typepad to Jekyll
2
+ =================
3
+
4
+ by Chris Stansbury
5
+
6
+ Description
7
+ -----------
8
+
9
+ TypepadToJekyll is a Ruby command line application to convert a MoveableType or Typepad blog
10
+ backup file, [MTIF format], into Jekyll blog posts. Post files will be stored in the _posts
11
+ and the _drafts sub directories under your jekyll directory.
12
+
13
+
14
+ Install
15
+ -------
16
+
17
+
18
+ gem install typepad_to_jekyll
19
+ gem install thor
20
+
21
+
22
+ Examples
23
+ --------
24
+
25
+ $ typepad_to jekyll <typepad_backup_filename> <jekyll_directory>
26
+
27
+
28
+ Requirements
29
+ ------------
30
+
31
+ Ruby
32
+ Ruby Gems: Thor
33
+
34
+
35
+ Supported Platforms
36
+ -------------------
37
+
38
+ Known to work on
39
+
40
+ 1.9.3
41
+
42
+
43
+
44
+ Questions and/or Comments
45
+ -------------------------
46
+
47
+ Feel free to email [Chris Stansbury](mailto:chris@koozie.org) with any questions.
@@ -0,0 +1,19 @@
1
+
2
+ require "rake/testtask"
3
+ require "rake/clean"
4
+
5
+ CLEAN.include('*.gem')
6
+ CLOBBER.include(FileList['.yardoc/*','doc/*'].exclude('.gitignore'))
7
+
8
+ task :default => [:test]
9
+
10
+ Rake::TestTask.new do |test|
11
+ test.libs << "test"
12
+ test.test_files = Dir[ "test/test_*.rb" ]
13
+ test.verbose = true
14
+ end
15
+
16
+ desc "Build Gem"
17
+ task :build do
18
+ sh "gem build typepad_to_jekyll.gemspec"
19
+ end
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ #$LOAD_PATH.unshift File.expand_path(File.join(File.dirname(__FILE__),'..','lib'))
4
+
5
+ require 'typepad_to_jekyll'
6
+ require 'thor'
7
+
8
+
9
+ class Application < Thor
10
+
11
+ attr_reader :jekyll_dir, :posts_dir, :drafts_dir
12
+
13
+ desc "jekyll BACKUP DIRECTORY", "Convert Typepad Backup file to Jekyll blog posts and store in _posts sub directory"
14
+ long_desc <<-LONGDESC
15
+ `typepad_to jekyll` will parse a TypePad backup file in the MTIF file format and genereate blog posts
16
+ which will be stored in the jekyll sub directory of _posts of _drafts.
17
+
18
+ typepad_to jekyll BACKUP JEKYLL-DIRECTORY
19
+ \x5 BACKUP: the filename of your TypePad backup file.
20
+ \x5 JEKYLL-DIRECTORY: path to your Jekyll directory.
21
+ LONGDESC
22
+ def jekyll(typepad_backup_filename, jekyll_directory)
23
+ abort "ERROR: [#{jekyll_directory}] is not a directory. " unless File.directory?(jekyll_directory)
24
+ app = TypepadToJekyll::Converter.new(typepad_backup_filename, jekyll_directory)
25
+ app.process
26
+ end
27
+
28
+ private
29
+ end
30
+
31
+ Application.start(ARGV)
32
+
33
+
34
+
@@ -0,0 +1,12 @@
1
+
2
+
3
+
4
+ module TypepadToJekyll
5
+ VERSION = "0.0.1".freeze if not defined?(TypepadToJekyll::VERSION)
6
+ end
7
+
8
+ require 'typepad_to_jekyll/post'
9
+ require 'typepad_to_jekyll/parser'
10
+ require 'typepad_to_jekyll/converter'
11
+
12
+
@@ -0,0 +1,58 @@
1
+ require 'fileutils'
2
+
3
+ module TypepadToJekyll
4
+
5
+ # Convert Typepad Backup (MTIF Format) to
6
+ # Jekyll posts. MTIF -> Jekyll _posts
7
+ class Converter
8
+ attr_reader :jekyll_base_dir, :posts_dir, :drafts_dir
9
+ attr_reader :typepad_backup_filename
10
+ attr_accessor :posts
11
+
12
+ def initialize(backup_filename, jekyll_base_directory)
13
+ @typepad_backup_filename = backup_filename
14
+ @jekyll_base_dir = jekyll_base_directory
15
+ @posts_dir = File.join(jekyll_base_dir, '_posts')
16
+ @drafts_dir = File.join(jekyll_base_dir, '_drafts')
17
+ @posts = []
18
+ end
19
+
20
+ def process
21
+ setup_sub_dirs
22
+ parse_backup_file
23
+ write_posts
24
+ end
25
+
26
+ private
27
+
28
+ def parse_backup_file
29
+ app = TypepadToJekyll::Parser.new
30
+ app.source_filename = typepad_backup_filename
31
+ app.process
32
+ @posts = app.posts
33
+ end
34
+
35
+ #write post to _posts directory in jekyll format
36
+ def write_posts
37
+ posts.each do |post|
38
+ if post.status == :publish
39
+ dir = posts_dir
40
+ else
41
+ dir = drafts_dir
42
+ end
43
+ fname = File.join(dir, post.filename)
44
+ File.open(fname, 'w') do |file|
45
+ file.puts post.to_jekyll
46
+ end
47
+ end
48
+ end
49
+
50
+ def setup_sub_dirs
51
+ dirs = [posts_dir, drafts_dir]
52
+ dirs.each do |dir|
53
+ FileUtils.mkdir_p(dir) if not File.directory?(dir)
54
+ end
55
+ end
56
+
57
+ end # class
58
+ end # module
@@ -0,0 +1,191 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'pp'
4
+ require 'date'
5
+
6
+ module TypepadToJekyll
7
+
8
+ # Convert Typepad Backup (MTIF Format) to
9
+ # Jekyll posts. MTIF -> Jekyll _posts
10
+ class Parser
11
+
12
+ attr_accessor :source_filename
13
+ attr_reader :import_status, :current_line, :last_line
14
+ attr_reader :current_post, :posts
15
+ attr_reader :current_comment
16
+
17
+ def initialize
18
+ setup
19
+ end
20
+
21
+ def process
22
+ setup
23
+ process_typepad_file
24
+ end
25
+
26
+ private
27
+
28
+ def process_typepad_file
29
+ new_post
30
+ File.open(source_filename,'r') do |file|
31
+ file.each do |line|
32
+ @last_line = current_line
33
+ @current_line = line
34
+ process_line
35
+ end
36
+ end
37
+ end
38
+
39
+ def new_post
40
+ @import_status = :post_header #:post_header, :body, :extended_body, :excerpt, :keywords, :boundary_5
41
+ @current_post = Post.new
42
+ end
43
+
44
+ def check_boundary
45
+ @import_status = :boundary_5 if current_line =~ /^-----/
46
+ @import_status = :boundary_7 if current_line =~ /^-------/
47
+ end
48
+
49
+ def process_line
50
+ check_boundary
51
+ case import_status
52
+ when :post_header
53
+ process_header_line
54
+ when :comment_header
55
+ process_comment_line
56
+ when :comment_body
57
+ process_comment_body
58
+ when :body
59
+ process_body
60
+ when :extended_body
61
+ process_extended_body
62
+ when :excerpt
63
+ process_excerpt
64
+ when :boundary_7
65
+ #write_post
66
+ posts << current_post
67
+ new_post
68
+ when :boundary_5
69
+ process_boundary5_item
70
+ end
71
+ end
72
+
73
+ def process_boundary5_item
74
+ case current_line
75
+ when /^BODY/
76
+ @import_status = :body
77
+ when /^EXTENDED BODY/
78
+ @import_status = :extended_body
79
+ when /^EXCERPT/
80
+ @import_status = :excerpt
81
+ when /^KEYWORDS/
82
+ @import_status = :keywords
83
+ when /^COMMENT/
84
+ @import_status = :comment_header
85
+ @current_comment = current_post.new_comment
86
+ end
87
+ end
88
+
89
+ def process_body
90
+ current_post.body += current_line
91
+ end
92
+
93
+ def process_extended_body
94
+ current_post.extended_body += current_line
95
+ end
96
+
97
+ def process_excerpt
98
+ current_post.excerpt += current_line if current_line.strip.chomp.size > 0
99
+ end
100
+
101
+ def process_comment_body
102
+ current_comment.body += current_line
103
+ end
104
+
105
+ def process_comment_line
106
+ return if current_line.strip == ""
107
+ case current_line
108
+ when /^AUTHOR/
109
+ current_comment.author = current_line.split('AUTHOR:').last.strip
110
+ when /^EMAIL/
111
+ current_comment.email = current_line.split('EMAIL:').last.strip
112
+ when /^IP/
113
+ current_comment.ip = current_line.split('IP:').last.strip
114
+ when /^URL/
115
+ current_comment.url = current_line.split('URL:').last.strip
116
+ when /^DATE/
117
+ d_str = current_line.split('DATE:').last.strip
118
+ current_comment.date = DateTime.strptime(d_str, "%m/%d/%Y %I:%M:%S %p")
119
+ @import_status = :comment_body #comment body follows directly after comment date
120
+ end
121
+ end
122
+
123
+ def process_header_line
124
+ return if current_line.strip == ""
125
+ case current_line
126
+ when /^AUTHOR/
127
+ current_post.author = current_line.split('AUTHOR:').last.strip
128
+ when /^TITLE/
129
+ current_post.title = current_line.split('TITLE:').last.strip
130
+ when /^STATUS/
131
+ current_post.status = current_line.split('STATUS:').last.strip.downcase.to_sym
132
+ when /^ALLOW COMMENTS/
133
+ current_post.allow_comments = current_line.split('ALLOW COMMENTS:').last.strip == '1' ? true : false
134
+ when /^CONVERT BREAKS/
135
+ current_post.convert_breaks = current_line.split('CONVERT BREAKS:').last.strip
136
+ when /^ALLOW PINGS/
137
+ current_post.allow_pings = current_line.split('ALLOW PINGS:').last.strip == '1' ? true : false
138
+ when /^BASENAME/
139
+ current_post.basename = current_line.split('BASENAME:').last.strip
140
+ when /^CATEGORY/
141
+ category_name = current_line.split('CATEGORY:').last.strip
142
+ current_post.categories << clean_category_name(category_name)
143
+ when /^UNIQUE URL/
144
+ current_post.unique_url = current_line.split('UNIQUE URL:').last.strip
145
+ when /^DATE/
146
+ d_str = current_line.split('DATE:').last.strip
147
+ current_post.date = DateTime.strptime(d_str, "%m/%d/%Y %I:%M:%S %p")
148
+ end
149
+ end
150
+
151
+ def clean_category_name(cat)
152
+ cat.downcase.gsub(/ /,'-')
153
+ end
154
+
155
+ def setup
156
+ @posts = []
157
+ @current_line = ''
158
+ @last_line = ''
159
+ end
160
+
161
+ end # class
162
+ end # module
163
+
164
+ __END__
165
+
166
+
167
+ dirs = [destination_dir, posts_dir, drafts_dir]
168
+ dirs.each do |dir|
169
+ if not File.directory?(dir)
170
+ puts "Not a directory [#{dir}]"
171
+ exit 1
172
+ end
173
+ end
174
+
175
+
176
+
177
+
178
+
179
+ #write post to _posts directory in jekyll format
180
+ def write_post
181
+ if current_post.status == :publish
182
+ dir = posts_dir
183
+ else
184
+ dir = drafts_dir
185
+ end
186
+ fname = File.join(dir, current_post.filename)
187
+ File.open(fname, 'w') do |file|
188
+ file.puts current_post.to_yaml
189
+ end
190
+ end
191
+
@@ -0,0 +1,68 @@
1
+ module TypepadToJekyll
2
+ class Comment
3
+ attr_accessor :author, :email, :ip, :url, :date, :body
4
+
5
+ def initialize
6
+ @body = ''
7
+ end
8
+ end
9
+ end
10
+
11
+
12
+ module TypepadToJekyll
13
+ class Post
14
+ attr_accessor :author, :title, :status, :allow_comments, :convert_breaks
15
+ attr_accessor :allow_pings, :basename, :unique_url, :date, :body
16
+ attr_accessor :extended_body, :excerpt
17
+
18
+ attr_reader :categories, :keywords, :comments
19
+
20
+ def initialize
21
+ @categories = []
22
+ @keywords = []
23
+ @comments = []
24
+ @body = ''
25
+ @extended_body = ''
26
+ @excerpt = ''
27
+ end
28
+
29
+ def filename
30
+ "#{date.strftime("%Y-%m-%d")}-#{basename}.html"
31
+ end
32
+
33
+ def to_jekyll
34
+ str = []
35
+ str << '---'
36
+ str << 'layout: post'
37
+ str << 'title: ' + clean_yaml(title)
38
+ str << "date: #{date.strftime("%Y-%m-%d %H:%M:%S")}"
39
+ if categories.size == 1
40
+ str << "category: #{categories.first}"
41
+ elsif categories.size > 1
42
+ str << "categories: #{categories.join(' ')}"
43
+ end
44
+ str << '---'
45
+ str << body
46
+ str << extended_body
47
+
48
+ return str.join("\n")
49
+ end
50
+
51
+ #handle colons, quotes, and double quotes in string
52
+ def clean_yaml(str)
53
+ if str.include?(':') or str.include?("'") or str.include?('"')
54
+ #return "'" + str.gsub(/"/, '\"').gsub(/'/, "''") + "'"
55
+ return "'" + str.gsub(/'/, "''") + "'"
56
+ else
57
+ return str
58
+ end
59
+ end
60
+
61
+ def new_comment
62
+ c = Comment.new
63
+ comments << c
64
+ return c
65
+ end
66
+
67
+ end
68
+ end
@@ -0,0 +1,113 @@
1
+ AUTHOR: Chris
2
+ TITLE: First Post
3
+ STATUS: Draft
4
+ ALLOW COMMENTS: 1
5
+ CONVERT BREAKS: __default__
6
+ ALLOW PINGS: 0
7
+ BASENAME: first_post
8
+
9
+ UNIQUE URL: http://www.example.org/2003/05/first_post.html
10
+ DATE: 05/29/2003 01:02:06 AM
11
+ -----
12
+ BODY:
13
+ <p>This should be my first post to Moveable Type. I'm still trying to figure this system out. </p>
14
+
15
+ <p>Jerry</p>
16
+ -----
17
+ EXTENDED BODY:
18
+ <p>IDEAS:</p>
19
+
20
+ <p>crayons<br />
21
+ Good Technology<br />
22
+ ONIX File Format<br />
23
+ 419 Scams<br />
24
+ Blat Utility<br />
25
+ Digital Camera Stuff</p>
26
+ -----
27
+ EXCERPT:
28
+
29
+ -----
30
+ KEYWORDS:
31
+
32
+ -----
33
+ COMMENT:
34
+ AUTHOR: Troy Aikman
35
+ EMAIL: troy@example.com
36
+ IP: 208.201.230.101
37
+ URL: http://troy.example.com/
38
+ DATE: 05/30/2003 01:32:14 PM
39
+ Easy, ain't it? :)
40
+ laters
41
+ -----
42
+ --------
43
+ AUTHOR: John Franklin McEnroe
44
+ TITLE: Home Wi-Fi
45
+ STATUS: Publish
46
+ ALLOW COMMENTS: 1
47
+ CONVERT BREAKS: __default__
48
+ ALLOW PINGS: 1
49
+ BASENAME: home_wifi
50
+ CATEGORY: Hardware
51
+
52
+ UNIQUE URL: http://blog.example.org/2003/01/home_wifi.html
53
+ DATE: 01/10/2003 01:39:35 PM
54
+ -----
55
+ BODY:
56
+ <p>I put in <a href="http://www.linksys.com/Products/product.asp?grid=33&scid=35&prid=508">Linksys wireless router/access point</a> on my home network one week ago. I quickly configured the router using its web based configuration tool. I've also been able to get a descent signal ALL over the house.</p>
57
+
58
+ <p>Wireless is just plain cool. I can't believe I waited so long to use it. </p>
59
+
60
+ <p>-Chris</p>
61
+ -----
62
+ EXTENDED BODY:
63
+
64
+ -----
65
+ EXCERPT:
66
+
67
+ -----
68
+ KEYWORDS:
69
+
70
+ -----
71
+ COMMENT:
72
+ AUTHOR: Fred Mike Jones
73
+ EMAIL: fmj@example.com
74
+ IP: 68.166.91.157
75
+ URL: http://www.example.com/blog
76
+ DATE: 08/10/2003 02:54:44 PM
77
+ Yeah, wireless is the way to go. Mrs. Noded has here own laptop. It makes it so much easier. Here, there and everywhere.
78
+
79
+ You posting from the backyard?
80
+ -----
81
+ COMMENT:
82
+ AUTHOR: mike
83
+ EMAIL: mike@example.org
84
+ IP: 65.70.200.35
85
+ URL: http://www.example.org
86
+ DATE: 08/10/2003 03:17:23 PM
87
+ It's to freaking HOT here to be outside longer than 5 minutes. We had tempeartures up to 108 degrees. Maybe I'll try the outside thing this fall.
88
+ -----
89
+ COMMENT:
90
+ AUTHOR: mike
91
+ EMAIL: mike@example.net
92
+ IP: 193.195.87.146
93
+ URL: http://example.net
94
+ DATE: 08/12/2003 08:58:00 AM
95
+ Just wait until your wireless access point dies (just like mine did this week) and then you REALLY realise how much you thought of it. I got good coverage all over the house and the garden. Now I'm stuck to sitting in the office tied by a long piece of cat5 cable :-(
96
+ -----
97
+ COMMENT:
98
+ AUTHOR: Mike
99
+ EMAIL: mike@example.org
100
+ IP: 207.8.15.210
101
+ URL: http://www.example.org
102
+ DATE: 08/12/2003 12:07:13 PM
103
+ Before I had wireless, I connected two 25' cat5 cables together so I could work in the living room instead of the office. :-)
104
+ -----
105
+ COMMENT:
106
+ AUTHOR: Jerry McGuire
107
+ EMAIL: blog@example.net
108
+ IP: 81.86.172.239
109
+ URL: http://example.net
110
+ DATE: 08/13/2003 04:00:09 AM
111
+ I had something similar - a LONG piece of cable through a hole drilled in the ceiling from the upstairs office into the living room and then coiled in a big loop so it would reach anywhere downstairs if stretched across the room....that changed when I got married :-)
112
+ -----
113
+ --------
@@ -0,0 +1,43 @@
1
+ AUTHOR: Chris
2
+ TITLE: First Post
3
+ STATUS: Draft
4
+ ALLOW COMMENTS: 1
5
+ CONVERT BREAKS: __default__
6
+ ALLOW PINGS: 0
7
+ BASENAME: first_post
8
+
9
+ UNIQUE URL: http://www.example.org/2003/05/first_post.html
10
+ DATE: 05/29/2003 01:02:06 AM
11
+ -----
12
+ BODY:
13
+ <p>This should be my first post to Moveable Type. I'm still trying to figure this system out. </p>
14
+
15
+ <p>Jerry</p>
16
+ -----
17
+ EXTENDED BODY:
18
+ <p>IDEAS:</p>
19
+
20
+ <p>crayons<br />
21
+ Good Technology<br />
22
+ ONIX File Format<br />
23
+ 419 Scams<br />
24
+ Blat Utility<br />
25
+ Digital Camera Stuff</p>
26
+ -----
27
+ EXCERPT:
28
+
29
+ -----
30
+ KEYWORDS:
31
+
32
+ -----
33
+ COMMENT:
34
+ AUTHOR: Troy Aikman
35
+ EMAIL: troy@example.com
36
+ IP: 208.201.230.101
37
+ URL: http://troy.example.com/
38
+ DATE: 05/30/2003 01:32:14 PM
39
+ Easy, ain't it? :)
40
+ laters
41
+ -----
42
+ --------
43
+
@@ -0,0 +1,103 @@
1
+ AUTHOR: Frank
2
+ TITLE: Junk Faxes: Redux
3
+ STATUS: Draft
4
+ ALLOW COMMENTS: 1
5
+ CONVERT BREAKS: __default__
6
+ ALLOW PINGS: 1
7
+ BASENAME: junk_faxes
8
+ CATEGORY: SPAM
9
+
10
+ UNIQUE URL: http://www.koozie.org/2003/11/junk_faxes.html
11
+ DATE: 11/06/2003 05:04:49 PM
12
+ -----
13
+ BODY:
14
+ <p>I found some interesting sites today about the piles and piles of junk faxes I seemed to be collecting these days.</p>
15
+
16
+ <p>800-390-1403 is the so-called removal number.</p>
17
+
18
+ <p>1st ad 800-891-2682 Medical Insurance<br />
19
+ 2nd ad pumps some stocks, by OTC Analysis.</p>
20
+
21
+ <p>http://www.junkfaxes.org/</p>
22
+ -----
23
+ EXTENDED BODY:
24
+
25
+ -----
26
+ EXCERPT:
27
+
28
+ -----
29
+ KEYWORDS:
30
+
31
+ -----
32
+ --------
33
+ AUTHOR: Chris
34
+ TITLE: All about Frank's "MIDI" Files
35
+ STATUS: Publish
36
+ ALLOW COMMENTS: 1
37
+ CONVERT BREAKS: __default__
38
+ ALLOW PINGS: 1
39
+ BASENAME: midi_files
40
+ CATEGORY: General IT
41
+ CATEGORY: Programming
42
+
43
+ UNIQUE URL: http://www.koozie.org/2003/11/midi_files.html
44
+ DATE: 11/04/2003 12:07:24 PM
45
+ -----
46
+ BODY:
47
+ <p>I've been busy at work and at home with two daughters, wife and dog. I have managed to squeeze in some playing time on the new piano. I found a couple of articles to help me understand midi files, which is how music is stored in my digital piano. The best analogy I found on describing midi was midi files are like music paper rolls for player pianos.</p>
48
+
49
+ <p>-Chris</p>
50
+
51
+ <p><a href="http://mp3.about.com/library/weekly/aa021797.htm">What is MIDI, Anyway?</a></p>
52
+
53
+ <p><a href="http://mp3.about.com/library/weekly/aa072699.htm">MIDI and MP3: What's the Difference?</a></p>
54
+
55
+ <p><a href="http://mp3.about.com/b/a/037484.htm">How to Convert MIDI to MP3 or CD</a></p>
56
+ -----
57
+ EXTENDED BODY:
58
+
59
+ -----
60
+ EXCERPT:
61
+
62
+ -----
63
+ KEYWORDS:
64
+
65
+ -----
66
+ --------
67
+ AUTHOR: Chris
68
+ TITLE: Comment Spam: Here it comes again, Sue's List of "Crazy" Items
69
+ STATUS: Publish
70
+ ALLOW COMMENTS: 1
71
+ CONVERT BREAKS: __default__
72
+ ALLOW PINGS: 1
73
+ BASENAME: first_comment_s
74
+ CATEGORY: General IT
75
+
76
+ UNIQUE URL: http://www.koozie.org/2003/11/first_comment_s.html
77
+ DATE: 11/04/2003 11:54:18 AM
78
+ -----
79
+ BODY:
80
+ <p>I finally received my first comment spam on MT.</p>
81
+
82
+ <blockquote>
83
+ IP Address: 209.208.9.254
84
+ Name: debt-consolidation
85
+ Email Address: gangastrotagati[at]yahoo.com
86
+ URL: http://www.karmicdebtconsolidation[dot]com/
87
+
88
+ <p>Comments:</p>
89
+
90
+ <p>Marvelous<br />
91
+
92
+
93
+ -----
94
+ EXTENDED BODY:
95
+
96
+ -----
97
+ EXCERPT:
98
+
99
+ -----
100
+ KEYWORDS:
101
+
102
+ -----
103
+ --------
@@ -0,0 +1,123 @@
1
+ gem 'minitest'
2
+ require 'minitest/autorun'
3
+ require 'typepad_to_jekyll'
4
+
5
+ class ParserTestOne < Minitest::Test
6
+
7
+ def setup
8
+ @fn = File.join(File.dirname(__FILE__),'data','typepad_one_post.txt')
9
+ @app = TypepadToJekyll::Parser.new
10
+ @app.source_filename = @fn
11
+ @app.process
12
+ end
13
+
14
+ def test_one_post_front_matter
15
+ assert_equal @fn, @app.source_filename
16
+
17
+ post = @app.posts.first
18
+ assert_equal 'Chris', post.author
19
+ assert_equal 'First Post', post.title
20
+ assert_equal :draft, post.status
21
+ assert_equal 'http://www.example.org/2003/05/first_post.html', post.unique_url
22
+ assert_equal '05/29/2003 01:02:06 AM', post.date.strftime("%m/%d/%Y %I:%M:%S %p")
23
+ end
24
+
25
+ def test_comment_one_post
26
+ post = @app.posts.first
27
+ assert_equal 1, post.comments.size
28
+ comment = post.comments.first
29
+ assert_equal 'Troy Aikman', comment.author
30
+ assert_equal 'troy@example.com', comment.email
31
+ assert_equal '208.201.230.101', comment.ip
32
+ assert_equal '05/30/2003 01:32:14 PM', comment.date.strftime("%m/%d/%Y %I:%M:%S %p")
33
+ assert_equal "Easy, ain't it? :)\nlaters\n", comment.body
34
+ end
35
+ end
36
+
37
+ class ParserTestMultilePosts < Minitest::Test
38
+ def setup
39
+ @fn = File.join(File.dirname(__FILE__),'data','typepad_multiple_posts.txt')
40
+ @app = TypepadToJekyll::Parser.new
41
+ @app.source_filename = @fn
42
+ @app.process
43
+ end
44
+
45
+ def test_last_post_front_matter
46
+ post = @app.posts.last
47
+ assert_equal 'John Franklin McEnroe', post.author
48
+ assert_equal 'Home Wi-Fi', post.title
49
+ assert_equal :publish, post.status
50
+ assert_equal 'http://blog.example.org/2003/01/home_wifi.html', post.unique_url
51
+ assert_equal '01/10/2003 01:39:35 PM', post.date.strftime("%m/%d/%Y %I:%M:%S %p")
52
+ end
53
+
54
+ def test_all_comments_parse_last_post
55
+ post = @app.posts.last
56
+ assert_equal 5, post.comments.size
57
+ end
58
+
59
+ def test_last_comment_from_last_post
60
+ post = @app.posts.last
61
+ comment = post.comments.last
62
+ assert_equal 'Jerry McGuire', comment.author
63
+ assert_equal 'blog@example.net', comment.email
64
+ assert_equal '81.86.172.239', comment.ip
65
+ assert_equal '08/13/2003 04:00:09 AM', comment.date.strftime("%m/%d/%Y %I:%M:%S %p")
66
+ assert_equal "I had something similar - a LONG piece of cable through a hole drilled in the ceiling from the upstairs office into the living room and then coiled in a big loop so it would reach anywhere downstairs if stretched across the room....that changed when I got married :-)\n", comment.body
67
+ end
68
+ end
69
+
70
+
71
+ # Tests for checking blog post title where ' or " or : appears in title
72
+ require 'yaml'
73
+ class ParserTestPostTileYamlIssues < Minitest::Test
74
+ def setup
75
+ @fn = File.join(File.dirname(__FILE__),'data','typepad_posts_yaml.txt')
76
+ @app = TypepadToJekyll::Parser.new
77
+ @app.source_filename = @fn
78
+ @app.process
79
+ end
80
+
81
+ def test_first_post_front_matter
82
+ post = @app.posts.first
83
+ assert_equal 'Junk Faxes: Redux', post.title
84
+ post_yaml = YAML.load(post.to_jekyll)
85
+ assert_equal post_yaml['title'], post.title
86
+ end
87
+
88
+ def test_second_post_front_matter
89
+ post = @app.posts[1]
90
+ assert_equal 'All about Frank\'s "MIDI" Files', post.title
91
+ post_yaml = YAML.load(post.to_jekyll)
92
+ #assert_equal 'All about Frank\'s \"MIDI\" Files' ,post_yaml['title']
93
+ assert_equal 'All about Frank\'s "MIDI" Files' ,post_yaml['title']
94
+ end
95
+ end
96
+
97
+
98
+ # Tests for checking category single or categories multiple
99
+ require 'yaml'
100
+ class ParserTestCategories < Minitest::Test
101
+ def setup
102
+ @fn = File.join(File.dirname(__FILE__),'data','typepad_posts_yaml.txt')
103
+ @app = TypepadToJekyll::Parser.new
104
+ @app.source_filename = @fn
105
+ @app.process
106
+ end
107
+
108
+ def test_first_post_category_single
109
+ post = @app.posts.first
110
+ post_yaml = YAML.load(post.to_jekyll)
111
+ key = 'category'
112
+ assert post_yaml.key?(key)
113
+ assert post_yaml[key].split(' ').size == 1
114
+ end
115
+
116
+ def test_first_post_category_single
117
+ post = @app.posts[1]
118
+ post_yaml = YAML.load(post.to_jekyll)
119
+ key = 'categories'
120
+ assert post_yaml.key?(key)
121
+ assert post_yaml[key].split(' ').size == 2
122
+ end
123
+ end
metadata ADDED
@@ -0,0 +1,61 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: typepad_to_jekyll
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Chris Stansbury
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-07-04 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: A commandline application to convert Typepad and Moveabletype backup
15
+ files into Jekyll posts. Posts to be stored in either the _posts or _drafts directory
16
+ email: Chris@koozie.org
17
+ executables:
18
+ - typepad_to
19
+ extensions: []
20
+ extra_rdoc_files: []
21
+ files:
22
+ - Rakefile
23
+ - bin/typepad_to
24
+ - lib/typepad_to_jekyll/converter.rb
25
+ - lib/typepad_to_jekyll/parser.rb
26
+ - lib/typepad_to_jekyll/post.rb
27
+ - lib/typepad_to_jekyll.rb
28
+ - test/data/typepad_multiple_posts.txt
29
+ - test/data/typepad_one_post.txt
30
+ - test/data/typepad_posts_yaml.txt
31
+ - test/test_converter.rb
32
+ - README.md
33
+ - LICENSE
34
+ homepage: https://github.com/koozie/typepad_to_jekyll
35
+ licenses:
36
+ - GPL-2
37
+ - Ruby Software License
38
+ post_install_message:
39
+ rdoc_options: []
40
+ require_paths:
41
+ - lib
42
+ required_ruby_version: !ruby/object:Gem::Requirement
43
+ none: false
44
+ requirements:
45
+ - - ! '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ required_rubygems_version: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ requirements: []
55
+ rubyforge_project:
56
+ rubygems_version: 1.8.23.2
57
+ signing_key:
58
+ specification_version: 3
59
+ summary: ! '''Typepad to Jekyll'' is a ruby library and commandline app that converts
60
+ a Typepad backup file (MTIF format) into Jekyll post files'
61
+ test_files: []