type_pad_template 0.1.0
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/README.md +31 -0
- data/bin/type_pad_template +6 -0
- data/lib/type_pad_template.rb +15 -0
- data/lib/type_pad_template/account.rb +90 -0
- data/lib/type_pad_template/blog.rb +50 -0
- data/lib/type_pad_template/command.rb +117 -0
- data/lib/type_pad_template/form.rb +37 -0
- data/lib/type_pad_template/request.rb +65 -0
- data/lib/type_pad_template/response.rb +23 -0
- data/lib/type_pad_template/template.rb +77 -0
- data/lib/type_pad_template/version.rb +3 -0
- metadata +124 -0
data/README.md
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
TypePad Temlpate
|
2
|
+
================
|
3
|
+
|
4
|
+
This is gem and command interface to manipulate TypePad advanced templates from command line.
|
5
|
+
|
6
|
+
Usage
|
7
|
+
-----
|
8
|
+
|
9
|
+
Install gem which provides ``type_pad_template`` command.
|
10
|
+
|
11
|
+
gem install type_pad_template
|
12
|
+
|
13
|
+
To see the usage, use help command.
|
14
|
+
|
15
|
+
type_pad_template help
|
16
|
+
|
17
|
+
Download and upload templates
|
18
|
+
-----------------------------
|
19
|
+
|
20
|
+
First you need to login to typepad using your email address and password.
|
21
|
+
|
22
|
+
type_pad_template login -u 'your-email@address'
|
23
|
+
|
24
|
+
Then list blogs on your account to get a blog id.
|
25
|
+
|
26
|
+
type_pad_template blogs
|
27
|
+
|
28
|
+
To download, upload templates, use each command with ``-b`` option.
|
29
|
+
|
30
|
+
type_pad_template download -b 'your-blog-id'
|
31
|
+
type_pad_template upload -b 'your-blog-id'
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require "type_pad_template/version"
|
2
|
+
require "nokogiri"
|
3
|
+
require "typhoeus"
|
4
|
+
require "uri"
|
5
|
+
require "forwardable"
|
6
|
+
|
7
|
+
module TypePadTemplate
|
8
|
+
autoload :Command, "type_pad_template/command"
|
9
|
+
autoload :Form, "type_pad_template/form"
|
10
|
+
autoload :Request, "type_pad_template/request"
|
11
|
+
autoload :Response, "type_pad_template/response"
|
12
|
+
autoload :Account, "type_pad_template/account"
|
13
|
+
autoload :Blog, "type_pad_template/blog"
|
14
|
+
autoload :Template, "type_pad_template/template"
|
15
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
module TypePadTemplate
|
2
|
+
class Account
|
3
|
+
def self.login(username, password)
|
4
|
+
account = new.tap do |a|
|
5
|
+
a.login(username, password)
|
6
|
+
end
|
7
|
+
|
8
|
+
account if account.logged_in?
|
9
|
+
end
|
10
|
+
|
11
|
+
attr_reader :login_cookies
|
12
|
+
|
13
|
+
def initialize(login_cookies = nil)
|
14
|
+
@login_cookies = login_cookies
|
15
|
+
end
|
16
|
+
|
17
|
+
def login(username, password)
|
18
|
+
form_element = Request.new("/secure/services/signin", :ssl => true).
|
19
|
+
dispatch.
|
20
|
+
response.
|
21
|
+
doc.
|
22
|
+
at("//form[@id='signin-form-typepad']")
|
23
|
+
|
24
|
+
form = Form.new(form_element).tap do |f|
|
25
|
+
f[:username] = username
|
26
|
+
f[:password] = password
|
27
|
+
end
|
28
|
+
|
29
|
+
@login_cookies = Request.new("/secure/services/signin/save", {
|
30
|
+
:ssl => true,
|
31
|
+
:method => :post,
|
32
|
+
:params => form.to_hash
|
33
|
+
}).
|
34
|
+
dispatch.
|
35
|
+
response.
|
36
|
+
cookies
|
37
|
+
|
38
|
+
self
|
39
|
+
end
|
40
|
+
|
41
|
+
def blogs
|
42
|
+
return [] unless logged_in?
|
43
|
+
|
44
|
+
request("/dashboard") do |response|
|
45
|
+
response.
|
46
|
+
doc.
|
47
|
+
search("//ul[@id='blogs-list']//a[@class='blog-name']").
|
48
|
+
map do |element|
|
49
|
+
if %r{/([0-9a-f]+)/dashboard$} === element["href"]
|
50
|
+
id = $1
|
51
|
+
Blog.new(self, id, element.text)
|
52
|
+
end
|
53
|
+
end.
|
54
|
+
compact
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def logged_in?
|
59
|
+
!@login_cookies.empty?
|
60
|
+
end
|
61
|
+
|
62
|
+
def request(path, options = {})
|
63
|
+
# FIXME raise a proper exception instead.
|
64
|
+
return nil unless logged_in?
|
65
|
+
|
66
|
+
request = Request.new(path, merge_login_cookie_header(options))
|
67
|
+
|
68
|
+
if block_given?
|
69
|
+
yield request.
|
70
|
+
dispatch.
|
71
|
+
response
|
72
|
+
else
|
73
|
+
request
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
def merge_login_cookie_header(options)
|
80
|
+
options.dup.tap do |options|
|
81
|
+
headers = options[:headers] ||= {}
|
82
|
+
headers["Cookie"] = [login_cookies_string, headers["Cookie"]].compact.join("; ")
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def login_cookies_string
|
87
|
+
@login_cookies.map{|key, value| "#{key}=#{value}"}.join("; ")
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module TypePadTemplate
|
2
|
+
class Blog
|
3
|
+
extend Forwardable
|
4
|
+
|
5
|
+
def_delegator :account, :request
|
6
|
+
|
7
|
+
attr_reader :account, :blog_id, :name
|
8
|
+
|
9
|
+
def initialize(account, blog_id, name)
|
10
|
+
@account = account
|
11
|
+
@blog_id = blog_id
|
12
|
+
@name = name
|
13
|
+
end
|
14
|
+
|
15
|
+
def templates
|
16
|
+
return [] unless design_id = current_design_id
|
17
|
+
|
18
|
+
request("/site/blogs/#{@blog_id}/design/#{design_id}/templates") do |response|
|
19
|
+
response.
|
20
|
+
doc.
|
21
|
+
search("//td[@class='index-templates' or @class='archive-templates' or @class='template-modules']/a[@class='link']").
|
22
|
+
map do |element|
|
23
|
+
name = element.text
|
24
|
+
|
25
|
+
output_file_element = element.at("../..//td[@class='output-file']")
|
26
|
+
|
27
|
+
filename = if output_file_element
|
28
|
+
output_file_element.text
|
29
|
+
else
|
30
|
+
"#{name.downcase.gsub(/[\- ]/, "_")}.template"
|
31
|
+
end
|
32
|
+
|
33
|
+
Template.new(self, name, filename, element["href"])
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def current_design_id
|
41
|
+
request("/site/blogs/#{@blog_id}/design") do |response|
|
42
|
+
response.
|
43
|
+
doc.
|
44
|
+
css(".design-current .design-actions a").find do |a|
|
45
|
+
%r{/([0-9a-f]+)/templates$} === a["href"]
|
46
|
+
end and $1
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
require "thor"
|
2
|
+
require "yaml"
|
3
|
+
require "highline"
|
4
|
+
|
5
|
+
module TypePadTemplate
|
6
|
+
SESSION_FILE = File.expand_path("~/.type_pad_template_session")
|
7
|
+
|
8
|
+
class Command < Thor
|
9
|
+
def self.blog_id_option
|
10
|
+
method_option(:blog_id, {
|
11
|
+
:type => :string,
|
12
|
+
:aliases => "-b",
|
13
|
+
:required => true,
|
14
|
+
:desc => "Blog ID which blogs command shows"
|
15
|
+
})
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.directory_option
|
19
|
+
method_option(:directory, {
|
20
|
+
:type => :string,
|
21
|
+
:aliases => "-d",
|
22
|
+
:desc => "Path to templates directory"
|
23
|
+
})
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.pattern_option
|
27
|
+
method_option(:pattern, {
|
28
|
+
:type => :string,
|
29
|
+
:aliases => "-p",
|
30
|
+
:desc => "Pattern to select templates"
|
31
|
+
})
|
32
|
+
end
|
33
|
+
|
34
|
+
desc "login", "Login to TypePad"
|
35
|
+
method_option :username, :type => :string, :aliases => "-u", :desc => "Login email address"
|
36
|
+
method_option :password, :type => :string, :aliases => "-p", :desc => "Password"
|
37
|
+
def login
|
38
|
+
username = options[:username] || highline.ask("Enter login email address: ")
|
39
|
+
password = options[:password] || highline.ask("Enter password: "){|q| q.echo = false }
|
40
|
+
|
41
|
+
account = Account.login(username, password)
|
42
|
+
|
43
|
+
File.open(SESSION_FILE, "w") do |file|
|
44
|
+
YAML.dump(account.login_cookies, file)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
desc "logout", "Logout from TypePad"
|
49
|
+
def logout
|
50
|
+
File.unlink(SESSION_FILE)
|
51
|
+
end
|
52
|
+
|
53
|
+
desc "blogs", "List current blogs"
|
54
|
+
def blogs
|
55
|
+
print_table account.blogs.map{|blog| [blog.blog_id, blog.name]}
|
56
|
+
end
|
57
|
+
|
58
|
+
desc "templates", "List current templates"
|
59
|
+
blog_id_option
|
60
|
+
def templates
|
61
|
+
print_table blog.templates.map{|template| [template.filename, template.name]}
|
62
|
+
end
|
63
|
+
|
64
|
+
desc "download", "Download templates from TypePad"
|
65
|
+
blog_id_option
|
66
|
+
directory_option
|
67
|
+
pattern_option
|
68
|
+
def download(filenames = nil)
|
69
|
+
pattern_select(blog.templates).each do |template|
|
70
|
+
template.enqueue_get do |text|
|
71
|
+
say "Downloaded #{template.filename}"
|
72
|
+
File.open(File.join(directory, template.filename), "w"){|f| f.write(text)}
|
73
|
+
end
|
74
|
+
end
|
75
|
+
Request.dispatch
|
76
|
+
end
|
77
|
+
|
78
|
+
desc "upload", "Upload templates from local"
|
79
|
+
blog_id_option
|
80
|
+
directory_option
|
81
|
+
pattern_option
|
82
|
+
def upload
|
83
|
+
pattern_select(blog.templates).each do |template|
|
84
|
+
path = File.join(directory, template.filename)
|
85
|
+
template.enqueue_post(File.read(path)) do |response|
|
86
|
+
say "Uploaded #{template.filename}"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
Request.dispatch
|
90
|
+
end
|
91
|
+
|
92
|
+
private
|
93
|
+
|
94
|
+
def account
|
95
|
+
@account ||= Account.new(YAML.load(File.read(SESSION_FILE)))
|
96
|
+
end
|
97
|
+
|
98
|
+
def blog
|
99
|
+
@blog ||= account.blogs.find{|blog| blog.blog_id == options[:blog_id]}
|
100
|
+
end
|
101
|
+
|
102
|
+
def directory
|
103
|
+
@directory ||= File.expand_path(options[:directory] || Dir.pwd)
|
104
|
+
end
|
105
|
+
|
106
|
+
def pattern_select(list)
|
107
|
+
return list unless options[:pattern]
|
108
|
+
list.select do |item|
|
109
|
+
File.fnmatch(options[:pattern], item.filename)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def highline
|
114
|
+
@highline ||= HighLine.new
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module TypePadTemplate
|
2
|
+
class Form
|
3
|
+
def initialize(form_element)
|
4
|
+
@form_element = form_element
|
5
|
+
@values = default_values
|
6
|
+
end
|
7
|
+
|
8
|
+
def [](key)
|
9
|
+
@values[key.to_sym]
|
10
|
+
end
|
11
|
+
|
12
|
+
def []=(key, value)
|
13
|
+
@values[key.to_sym] = value
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_hash
|
17
|
+
@values.dup
|
18
|
+
end
|
19
|
+
|
20
|
+
def method
|
21
|
+
@form_element["method"].downcase.to_sym rescue :get
|
22
|
+
end
|
23
|
+
|
24
|
+
def url
|
25
|
+
@form_element["action"]
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def default_values
|
31
|
+
@form_element.search("input[@name!='']").inject({}) do |hash, input|
|
32
|
+
hash[input["name"].to_sym] = input["value"] if input["name"]
|
33
|
+
hash
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module TypePadTemplate
|
2
|
+
class Request
|
3
|
+
DEFAULT_HOST_NAME = "www.typepad.com"
|
4
|
+
MAX_CONCURRENCY = 10
|
5
|
+
|
6
|
+
def self.dispatch
|
7
|
+
hydra.run
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.hydra
|
11
|
+
@@hydra ||= Typhoeus::Hydra.new(:max_concurrency => MAX_CONCURRENCY)
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize(url_or_path, options = {})
|
15
|
+
@url_or_path = url_or_path
|
16
|
+
@options = options
|
17
|
+
end
|
18
|
+
|
19
|
+
def enqueue(&block)
|
20
|
+
request.on_complete = lambda do |response|
|
21
|
+
block.call(Response.new(response))
|
22
|
+
end
|
23
|
+
self.class.hydra.queue(request)
|
24
|
+
self
|
25
|
+
end
|
26
|
+
|
27
|
+
def dispatch
|
28
|
+
hydra = Typhoeus::Hydra.new
|
29
|
+
hydra.queue(request)
|
30
|
+
hydra.run
|
31
|
+
self
|
32
|
+
end
|
33
|
+
|
34
|
+
def response
|
35
|
+
@response ||= Response.new(request.response) if request.response
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def ssl?
|
41
|
+
@options[:ssl]
|
42
|
+
end
|
43
|
+
|
44
|
+
def protocol
|
45
|
+
ssl? ? "https" : "http"
|
46
|
+
end
|
47
|
+
|
48
|
+
def url
|
49
|
+
@url ||= begin
|
50
|
+
uri = URI.parse(@url_or_path)
|
51
|
+
unless uri.scheme
|
52
|
+
"#{protocol}://#{DEFAULT_HOST_NAME}#{uri.path}"
|
53
|
+
else
|
54
|
+
uri.to_s
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def request
|
60
|
+
@request ||= Typhoeus::Request.new(url, @options.merge({
|
61
|
+
:disable_ssl_peer_verification => ssl?
|
62
|
+
}))
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module TypePadTemplate
|
2
|
+
class Response
|
3
|
+
def initialize(response)
|
4
|
+
@response = response
|
5
|
+
end
|
6
|
+
|
7
|
+
def successful?
|
8
|
+
@response.code == 200
|
9
|
+
end
|
10
|
+
|
11
|
+
def cookies
|
12
|
+
@cokies ||= Array(@response.headers_hash["Set-Cookie"]).inject({}) do |hash, cookie|
|
13
|
+
key, value = cookie.split(/;/, 2).first.split(/=/, 2)
|
14
|
+
hash[key] = value
|
15
|
+
hash
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def doc
|
20
|
+
@doc ||= Nokogiri::HTML.parse(@response.body)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module TypePadTemplate
|
2
|
+
class Template
|
3
|
+
extend Forwardable
|
4
|
+
|
5
|
+
def_delegator :blog, :request
|
6
|
+
|
7
|
+
attr_reader :blog, :name, :filename, :url, :text
|
8
|
+
|
9
|
+
def initialize(blog, name, filename, edit_url)
|
10
|
+
@blog = blog
|
11
|
+
@name = name
|
12
|
+
@filename = filename
|
13
|
+
@edit_path = URI.parse(edit_url).path
|
14
|
+
end
|
15
|
+
|
16
|
+
def enqueue_get(&block)
|
17
|
+
request(@edit_path).enqueue do |response|
|
18
|
+
@text = get_text_from_response(response)
|
19
|
+
block.call(text)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def get
|
24
|
+
request(@edit_path) do |response|
|
25
|
+
@text = get_text_from_response(response)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def enqueue_post(text, &block)
|
30
|
+
request(@edit_path).enqueue do |response|
|
31
|
+
form = get_form_for_body(response).tap do |f|
|
32
|
+
f[:text] = text
|
33
|
+
end
|
34
|
+
request_for_form(form).enqueue do |response|
|
35
|
+
@text = text
|
36
|
+
block.call(response)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def post(text)
|
42
|
+
request(@edit_path) do |response|
|
43
|
+
form = get_form_for_body(response).tap do |f|
|
44
|
+
f[:text] = text
|
45
|
+
end
|
46
|
+
|
47
|
+
response = request_for_form(form).dispatch.response
|
48
|
+
@text = text
|
49
|
+
|
50
|
+
response
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def get_form_for_body(response)
|
57
|
+
Form.new(response.
|
58
|
+
doc.
|
59
|
+
at("form[@id='template-form']"))
|
60
|
+
end
|
61
|
+
|
62
|
+
def get_text_from_response(response)
|
63
|
+
response.
|
64
|
+
doc.
|
65
|
+
at("//form[@id='template-form']//textarea[@name='text']").
|
66
|
+
text
|
67
|
+
end
|
68
|
+
|
69
|
+
# FIXME make this works in Form.
|
70
|
+
def request_for_form(form)
|
71
|
+
request(form.url, {
|
72
|
+
:method => form.method,
|
73
|
+
:params => form.to_hash
|
74
|
+
})
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
metadata
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: type_pad_template
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Yoshimasa Niwa
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-03-08 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: typhoeus
|
16
|
+
requirement: &70329624589040 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70329624589040
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: nokogiri
|
27
|
+
requirement: &70329624588600 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70329624588600
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: thor
|
38
|
+
requirement: &70329624588060 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :runtime
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70329624588060
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: highline
|
49
|
+
requirement: &70329624587140 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :runtime
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *70329624587140
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: bundler
|
60
|
+
requirement: &70329624586680 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
type: :development
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *70329624586680
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rake
|
71
|
+
requirement: &70329624586140 !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ! '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: *70329624586140
|
80
|
+
description: ''
|
81
|
+
email:
|
82
|
+
- niw@niw.at
|
83
|
+
executables:
|
84
|
+
- type_pad_template
|
85
|
+
extensions: []
|
86
|
+
extra_rdoc_files:
|
87
|
+
- README.md
|
88
|
+
files:
|
89
|
+
- bin/type_pad_template
|
90
|
+
- lib/type_pad_template.rb
|
91
|
+
- lib/type_pad_template/account.rb
|
92
|
+
- lib/type_pad_template/blog.rb
|
93
|
+
- lib/type_pad_template/command.rb
|
94
|
+
- lib/type_pad_template/form.rb
|
95
|
+
- lib/type_pad_template/request.rb
|
96
|
+
- lib/type_pad_template/response.rb
|
97
|
+
- lib/type_pad_template/template.rb
|
98
|
+
- lib/type_pad_template/version.rb
|
99
|
+
- README.md
|
100
|
+
homepage: http://niw.at/
|
101
|
+
licenses: []
|
102
|
+
post_install_message:
|
103
|
+
rdoc_options: []
|
104
|
+
require_paths:
|
105
|
+
- lib
|
106
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
107
|
+
none: false
|
108
|
+
requirements:
|
109
|
+
- - ! '>='
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '0'
|
112
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ! '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
requirements: []
|
119
|
+
rubyforge_project: type_pad_template
|
120
|
+
rubygems_version: 1.8.11
|
121
|
+
signing_key:
|
122
|
+
specification_version: 3
|
123
|
+
summary: ''
|
124
|
+
test_files: []
|