siteleaf 1.0.10 → 2.0.0.pre.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +0 -3
- data/README.md +33 -61
- data/bin/siteleaf +191 -165
- data/lib/siteleaf.rb +14 -31
- data/lib/siteleaf/asset.rb +32 -25
- data/lib/siteleaf/client.rb +17 -9
- data/lib/siteleaf/collection.rb +21 -0
- data/lib/siteleaf/content.rb +36 -0
- data/lib/siteleaf/document.rb +15 -0
- data/lib/siteleaf/entity.rb +1 -1
- data/lib/siteleaf/file.rb +9 -0
- data/lib/siteleaf/page.rb +3 -86
- data/lib/siteleaf/post.rb +2 -27
- data/lib/siteleaf/site.rb +24 -88
- data/lib/siteleaf/upload.rb +9 -0
- data/lib/siteleaf/version.rb +1 -1
- data/siteleaf.gemspec +6 -6
- metadata +20 -19
- data/.rbenv-vars +0 -2
- data/lib/patches/time_with_zone_encode_with.rb +0 -12
- data/lib/siteleaf/server.rb +0 -81
- data/lib/siteleaf/theme.rb +0 -25
data/lib/siteleaf.rb
CHANGED
@@ -1,32 +1,37 @@
|
|
1
|
-
libdir = File.dirname(__FILE__)
|
1
|
+
libdir = ::File.dirname(__FILE__)
|
2
2
|
$LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
|
3
3
|
|
4
4
|
require 'siteleaf/version'
|
5
5
|
require 'siteleaf/client'
|
6
6
|
require 'siteleaf/entity'
|
7
7
|
require 'siteleaf/asset'
|
8
|
+
require 'siteleaf/file'
|
9
|
+
require 'siteleaf/upload'
|
8
10
|
require 'siteleaf/job'
|
11
|
+
require 'siteleaf/content'
|
9
12
|
require 'siteleaf/page'
|
10
13
|
require 'siteleaf/post'
|
11
|
-
require 'siteleaf/
|
14
|
+
require 'siteleaf/collection'
|
15
|
+
require 'siteleaf/document'
|
12
16
|
require 'siteleaf/site'
|
13
|
-
require 'siteleaf/theme'
|
14
17
|
require 'siteleaf/user'
|
15
|
-
require 'patches/time_with_zone_encode_with'
|
16
18
|
require 'rbconfig'
|
17
19
|
require 'uri'
|
18
20
|
require 'yaml'
|
19
21
|
|
20
22
|
module Siteleaf
|
21
23
|
|
22
|
-
@
|
24
|
+
@api_key = ENV['SITELEAF_API_KEY']
|
25
|
+
@api_secret = ENV['SITELEAF_API_SECRET']
|
26
|
+
@api_base = 'http://api.v2.siteleaf.com'
|
27
|
+
@api_version = 'v2'
|
23
28
|
|
24
29
|
class << self
|
25
|
-
attr_accessor :api_key, :api_secret, :api_base
|
30
|
+
attr_accessor :api_key, :api_secret, :api_base, :api_version
|
26
31
|
end
|
27
32
|
|
28
|
-
def self.api_url(url='')
|
29
|
-
|
33
|
+
def self.api_url(url = '')
|
34
|
+
::File.join(@api_base, @api_version, url)
|
30
35
|
end
|
31
36
|
|
32
37
|
def self.settings_file
|
@@ -45,15 +50,8 @@ module Siteleaf
|
|
45
50
|
settings.each{|k,v| symbolized_settings[k.to_sym] = v}
|
46
51
|
|
47
52
|
symbolized_settings
|
48
|
-
|
49
|
-
# read legacy settings, upgrade old marshal format into yaml
|
50
|
-
elsif self.load_legacy_settings
|
51
|
-
symbolized_settings = {api_key: self.api_key, api_secret: self.api_secret}
|
52
|
-
self.save_settings(symbolized_settings)
|
53
|
-
::File.unlink(self.legacy_settings_file)
|
54
|
-
symbolized_settings
|
55
53
|
end
|
56
|
-
rescue
|
54
|
+
rescue
|
57
55
|
nil
|
58
56
|
end
|
59
57
|
|
@@ -65,20 +63,5 @@ module Siteleaf
|
|
65
63
|
|
66
64
|
settings
|
67
65
|
end
|
68
|
-
|
69
|
-
# here for v1 legacy purposes
|
70
|
-
def self.legacy_settings_file
|
71
|
-
::File.expand_path('~/.siteleaf')
|
72
|
-
end
|
73
|
-
|
74
|
-
def self.load_legacy_settings
|
75
|
-
if ::File.exist?(legacy_settings_file)
|
76
|
-
config = ::File.open(legacy_settings_file) do|file|
|
77
|
-
Marshal.load(file)
|
78
|
-
end
|
79
|
-
self.api_key = config[:api_key] if config.has_key?(:api_key)
|
80
|
-
self.api_secret = config[:api_secret] if config.has_key?(:api_secret)
|
81
|
-
end
|
82
|
-
end
|
83
66
|
|
84
67
|
end
|
data/lib/siteleaf/asset.rb
CHANGED
@@ -1,36 +1,43 @@
|
|
1
1
|
module Siteleaf
|
2
2
|
class Asset < Entity
|
3
3
|
|
4
|
-
attr_accessor :file, :filename, :
|
5
|
-
attr_reader :id, :url, :content_type, :filesize, :
|
6
|
-
|
7
|
-
def
|
8
|
-
if
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
4
|
+
attr_accessor :file, :filename, :path, :basename, :directory, :permalink, :replace, :site_id, :metadata
|
5
|
+
attr_reader :id, :basename, :directory, :url, :content_type, :filesize, :sha, :static, :created_at, :updated_at
|
6
|
+
|
7
|
+
def site
|
8
|
+
Site.find(self.site_id) if self.site_id
|
9
|
+
end
|
10
|
+
|
11
|
+
def filename
|
12
|
+
# todo: temporary fix
|
13
|
+
(directory == '.') ? basename : ::File.join(directory, basename)
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_file
|
17
|
+
if static?
|
18
|
+
body
|
14
19
|
else
|
15
|
-
"
|
20
|
+
[frontmatter, "---\n\n".freeze, body].join('')
|
16
21
|
end
|
17
22
|
end
|
18
|
-
|
19
|
-
|
20
|
-
|
23
|
+
|
24
|
+
protected
|
25
|
+
|
26
|
+
def frontmatter
|
27
|
+
attrs = metadata || {}
|
28
|
+
attrs.delete('name') # todo: temporary fix
|
29
|
+
attrs['permalink'] = permalink unless permalink.nil?
|
30
|
+
|
31
|
+
attrs.empty? ? "---\n".freeze : attrs.to_yaml
|
21
32
|
end
|
22
|
-
|
23
|
-
def
|
24
|
-
|
33
|
+
|
34
|
+
def body
|
35
|
+
open(file['url'], 'r:UTF-8') { |f| f.read }
|
25
36
|
end
|
26
|
-
|
27
|
-
def
|
28
|
-
|
29
|
-
end
|
30
|
-
|
31
|
-
def site
|
32
|
-
Site.find(self.site_id) if self.site_id
|
37
|
+
|
38
|
+
def static?
|
39
|
+
static == true
|
33
40
|
end
|
34
|
-
|
41
|
+
|
35
42
|
end
|
36
43
|
end
|
data/lib/siteleaf/client.rb
CHANGED
@@ -5,8 +5,7 @@ module Siteleaf
|
|
5
5
|
def self.auth(email, password)
|
6
6
|
begin
|
7
7
|
request = HTTParty.post(Siteleaf.api_url('auth'), {
|
8
|
-
:basic_auth => {:username => email, :password => password}
|
9
|
-
:headers => {"User-Agent" => "Siteleaf Gem/#{Siteleaf::VERSION}"}
|
8
|
+
:basic_auth => {:username => email, :password => password}
|
10
9
|
})
|
11
10
|
return request.parsed_response # parse JSON
|
12
11
|
rescue => e
|
@@ -14,7 +13,8 @@ module Siteleaf
|
|
14
13
|
end
|
15
14
|
end
|
16
15
|
|
17
|
-
def self.get(path, params =
|
16
|
+
def self.get(path, params = {})
|
17
|
+
params['limit'] = 9999
|
18
18
|
self.execute(:get, path, params)
|
19
19
|
end
|
20
20
|
|
@@ -33,12 +33,20 @@ module Siteleaf
|
|
33
33
|
def self.execute(method, path, params = nil)
|
34
34
|
Siteleaf.load_settings if !Siteleaf.api_key
|
35
35
|
begin
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
36
|
+
if (method == :post || method == :put) && !params.has_key?('file')
|
37
|
+
request = HTTParty.send(method, Siteleaf.api_url(path), {
|
38
|
+
:headers => { 'Content-Type' => 'application/json' },
|
39
|
+
:body => params.to_json,
|
40
|
+
:basic_auth => {:username => Siteleaf.api_key, :password => Siteleaf.api_secret},
|
41
|
+
:timeout => 300
|
42
|
+
})
|
43
|
+
else
|
44
|
+
request = HTTMultiParty.send(method, Siteleaf.api_url(path), {
|
45
|
+
:query => params,
|
46
|
+
:basic_auth => {:username => Siteleaf.api_key, :password => Siteleaf.api_secret},
|
47
|
+
:timeout => 300
|
48
|
+
})
|
49
|
+
end
|
42
50
|
if request.respond_to?('parsed_response')
|
43
51
|
return request.parsed_response # parse JSON
|
44
52
|
else
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Siteleaf
|
2
|
+
class Collection < Entity
|
3
|
+
|
4
|
+
attr_accessor :title, :path, :output, :site_id, :metadata
|
5
|
+
attr_reader :id, :basename, :directory, :created_at, :updated_at
|
6
|
+
|
7
|
+
def create_endpoint
|
8
|
+
"sites/#{self.site_id}/collections"
|
9
|
+
end
|
10
|
+
|
11
|
+
def site
|
12
|
+
Site.find(self.site_id)
|
13
|
+
end
|
14
|
+
|
15
|
+
def documents
|
16
|
+
result = Client.get "collections/#{self.id}/documents"
|
17
|
+
result.map { |r| Document.new(r) } if result
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Siteleaf
|
2
|
+
class Content < Entity
|
3
|
+
|
4
|
+
attr_accessor :title, :body, :path, :permalink, :visibility, :published_at, :user_id, :site_id, :metadata
|
5
|
+
attr_reader :id, :filename, :basename, :directory, :url, :filesize, :sha, :published, :created_at, :updated_at
|
6
|
+
|
7
|
+
def site
|
8
|
+
Site.find(self.site_id) if self.site_id
|
9
|
+
end
|
10
|
+
|
11
|
+
def draft?
|
12
|
+
!published?
|
13
|
+
end
|
14
|
+
|
15
|
+
def published?
|
16
|
+
published != false
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_file
|
20
|
+
[frontmatter, "---\n\n".freeze, body].join('')
|
21
|
+
end
|
22
|
+
|
23
|
+
protected
|
24
|
+
|
25
|
+
def frontmatter
|
26
|
+
attrs = metadata || {}
|
27
|
+
attrs['title'] = title
|
28
|
+
attrs['date'] = Time.parse(published_at).utc.strftime('%F %T %z')
|
29
|
+
attrs['published'] = false if draft?
|
30
|
+
attrs['permalink'] = permalink unless permalink.nil?
|
31
|
+
|
32
|
+
attrs.empty? ? "---\n".freeze : attrs.to_yaml
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
data/lib/siteleaf/entity.rb
CHANGED
data/lib/siteleaf/page.rb
CHANGED
@@ -1,92 +1,9 @@
|
|
1
1
|
module Siteleaf
|
2
|
-
class Page <
|
3
|
-
|
4
|
-
attr_accessor :title, :custom_slug, :body, :visibility, :published_at, :user_id, :site_id, :parent_id, :meta, :user
|
5
|
-
attr_reader :id, :slug, :url, :created_at, :updated_at, :assets
|
6
|
-
|
7
|
-
def self.find(id)
|
8
|
-
super "#{id}?include=user"
|
9
|
-
end
|
2
|
+
class Page < Content
|
10
3
|
|
11
4
|
def create_endpoint
|
12
5
|
"sites/#{self.site_id}/pages"
|
13
6
|
end
|
14
|
-
|
15
|
-
def site
|
16
|
-
Site.find(self.site_id) if self.site_id
|
17
|
-
end
|
18
|
-
|
19
|
-
def assets
|
20
|
-
result = Client.get "pages/#{self.id}/assets"
|
21
|
-
result.map { |r| Asset.new(r) } if result
|
22
|
-
end
|
23
|
-
|
24
|
-
def posts
|
25
|
-
result = Client.get "pages/#{self.id}/posts"
|
26
|
-
result.map { |r| Post.new(r) } if result
|
27
|
-
end
|
28
|
-
|
29
|
-
def pages
|
30
|
-
result = Client.get "pages/#{self.id}?include=pages"
|
31
|
-
result["pages"].map { |r| Page.new(r) } if result
|
32
|
-
end
|
33
|
-
|
34
|
-
def page
|
35
|
-
Page.find(self.parent_id) if self.parent_id
|
36
|
-
end
|
37
|
-
|
38
|
-
def draft?
|
39
|
-
visibility == 'draft'
|
40
|
-
end
|
41
|
-
|
42
|
-
def published?
|
43
|
-
visibility == 'visible'
|
44
|
-
end
|
45
|
-
|
46
|
-
def filename
|
47
|
-
"#{url.sub('/','')}.markdown"
|
48
|
-
end
|
49
|
-
|
50
|
-
def frontmatter
|
51
|
-
attrs = {}
|
52
|
-
attrs['title'] = title
|
53
|
-
attrs['date'] = Time.parse(published_at).utc if published_at
|
54
|
-
attrs['published'] = false if !published?
|
55
|
-
attrs['author'] = user['fullname'] if user && user['fullname']
|
56
|
-
|
57
|
-
meta.each{|m| attrs[m['key'].to_s.downcase] = m['value'].to_s == '' ? nil : m['value'].to_s.gsub("\r\n","\n")} unless meta.nil?
|
58
|
-
|
59
|
-
unless assets.to_a.empty?
|
60
|
-
attrs['assets'] = assets.map do |a|
|
61
|
-
asset = {'path' => "/uploads/#{a.filename}"}
|
62
|
-
a.meta.each{|m| asset[m['key'].to_s.downcase] = m['value'].to_s == '' ? nil : m['value'].to_s.gsub("\r\n","\n")} unless meta.nil?
|
63
|
-
asset
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
if defined?(taxonomy) && !taxonomy.nil?
|
68
|
-
taxonomy.each do |t|
|
69
|
-
next if t['values'].empty?
|
70
|
-
key = t['key']
|
71
|
-
key.downcase! if key =~ /^(tags|category|categories)$/i
|
72
|
-
attrs[key] = t['values'].map{|v| v['value'] }
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
attrs
|
77
|
-
end
|
78
|
-
|
79
|
-
def to_file(dir = 'export')
|
80
|
-
assets = Dir.glob("#{dir}/_uploads/**/*").each_with_object({}) do |var, hash|
|
81
|
-
# remap assets to _uploads
|
82
|
-
hash[var.sub("#{dir}/_uploads",'/assets')] = var.sub("#{dir}/_uploads",'/uploads')
|
83
|
-
end
|
84
|
-
|
85
|
-
attrs = frontmatter
|
86
|
-
attrs_yaml = attrs.empty? ? "---\n".freeze : attrs.to_yaml
|
87
|
-
|
88
|
-
(attrs_yaml + "---\n\n".freeze + body.to_s.gsub("\r\n","\n")).gsub(Regexp.union(assets.keys), assets)
|
89
|
-
end
|
90
|
-
|
7
|
+
|
91
8
|
end
|
92
|
-
end
|
9
|
+
end
|
data/lib/siteleaf/post.rb
CHANGED
@@ -1,35 +1,10 @@
|
|
1
1
|
module Siteleaf
|
2
|
-
class Post <
|
2
|
+
class Post < Content
|
3
3
|
|
4
4
|
attr_accessor :taxonomy
|
5
5
|
|
6
6
|
def create_endpoint
|
7
|
-
"
|
8
|
-
end
|
9
|
-
|
10
|
-
def parent
|
11
|
-
Page.find(self.parent_id)
|
12
|
-
end
|
13
|
-
|
14
|
-
def assets
|
15
|
-
result = Client.get "posts/#{self.id}/assets"
|
16
|
-
result.map { |r| Asset.new(r) } if result
|
17
|
-
end
|
18
|
-
|
19
|
-
def filename(posts_path = 'posts')
|
20
|
-
paths = url.sub('/','').split('/')
|
21
|
-
basename = "#{paths.pop}.markdown"
|
22
|
-
path = paths.join('_')
|
23
|
-
if path == posts_path
|
24
|
-
if draft?
|
25
|
-
path = 'drafts'
|
26
|
-
else
|
27
|
-
path = 'posts'
|
28
|
-
date = Time.parse(published_at).strftime('%Y-%m-%d')
|
29
|
-
basename = "#{date}-#{basename}"
|
30
|
-
end
|
31
|
-
end
|
32
|
-
"_#{path}/#{basename}"
|
7
|
+
"sites/#{self.parent_id}/posts"
|
33
8
|
end
|
34
9
|
|
35
10
|
end
|
data/lib/siteleaf/site.rb
CHANGED
@@ -1,108 +1,44 @@
|
|
1
1
|
module Siteleaf
|
2
2
|
class Site < Entity
|
3
3
|
|
4
|
-
attr_accessor :title, :domain, :timezone, :
|
4
|
+
attr_accessor :title, :domain, :timezone, :metadata
|
5
5
|
attr_reader :id, :user_id, :created_at, :updated_at
|
6
|
-
|
6
|
+
|
7
7
|
def self.find_by_domain(domain)
|
8
|
-
|
9
|
-
|
8
|
+
results = Client.get self.endpoint
|
9
|
+
result = results.find {|d| d['domain'] == domain }
|
10
|
+
self.new(result) if result
|
10
11
|
end
|
11
|
-
|
12
|
-
def
|
13
|
-
|
14
|
-
|
15
|
-
theme.site_id = self.id
|
16
|
-
theme
|
17
|
-
end
|
12
|
+
|
13
|
+
def files
|
14
|
+
result = Client.get "sites/#{self.id}/files"
|
15
|
+
result.map { |r| File.new(r) } if result
|
18
16
|
end
|
19
|
-
|
20
|
-
def
|
21
|
-
result = Client.get "sites/#{self.id}/
|
22
|
-
result.map { |r|
|
17
|
+
|
18
|
+
def uploads
|
19
|
+
result = Client.get "sites/#{self.id}/uploads"
|
20
|
+
result.map { |r| Upload.new(r) } if result
|
23
21
|
end
|
24
|
-
|
22
|
+
|
25
23
|
def pages
|
26
|
-
result = Client.get "sites/#{self.id}/pages
|
24
|
+
result = Client.get "sites/#{self.id}/pages"
|
27
25
|
result.map { |r| Page.new(r) } if result
|
28
26
|
end
|
29
|
-
|
27
|
+
|
30
28
|
def posts
|
31
|
-
result = Client.get "sites/#{self.id}/posts
|
29
|
+
result = Client.get "sites/#{self.id}/posts"
|
32
30
|
result.map { |r| Post.new(r) } if result
|
33
31
|
end
|
34
|
-
|
35
|
-
def
|
36
|
-
Client.get "sites/#{self.id}/
|
37
|
-
|
38
|
-
|
39
|
-
def preview(url = '/', template = nil)
|
40
|
-
Client.post "sites/#{self.id}/preview", {"url" => url, "template" => template}
|
32
|
+
|
33
|
+
def collections
|
34
|
+
result = Client.get "sites/#{self.id}/collections"
|
35
|
+
result.map { |r| Collection.new(r) } if result
|
41
36
|
end
|
42
|
-
|
37
|
+
|
43
38
|
def publish
|
44
39
|
result = Client.post "sites/#{self.id}/publish", {}
|
45
40
|
Job.new(id: result.parsed_response["job_id"]) if result
|
46
41
|
end
|
47
|
-
|
48
|
-
def posts_path
|
49
|
-
@posts_path || 'posts'
|
50
|
-
end
|
51
|
-
|
52
|
-
def filename
|
53
|
-
"_config.yml"
|
54
|
-
end
|
55
|
-
|
56
|
-
def config
|
57
|
-
attrs = {}
|
58
|
-
attrs['title'] = title
|
59
|
-
attrs['url'] = "http://#{domain}"
|
60
|
-
attrs['timezone'] = timezone
|
61
|
-
attrs['permalink'] = 'pretty'
|
62
|
-
attrs['markdown'] = 'kramdown'
|
63
|
-
|
64
|
-
meta.each{|m| attrs[m['key'].to_s.downcase] = m['value'].to_s == '' ? nil : m['value'].to_s.gsub("\r\n","\n")} unless meta.nil?
|
65
|
-
|
66
|
-
# output uploads using v1 /assets path
|
67
|
-
attrs['collections'] = {
|
68
|
-
'uploads' => {
|
69
|
-
'title' => 'Uploads',
|
70
|
-
'output' => true
|
71
|
-
}
|
72
|
-
}
|
73
|
-
|
74
|
-
# use collections for any set of posts not called "posts"
|
75
|
-
pages.each do |page|
|
76
|
-
path = page.url.sub('/','').gsub('/','_')
|
77
|
-
if path != posts_path && page.posts.size > 0
|
78
|
-
attrs['collections'][path] = {'output' => true}
|
79
|
-
# output permalink for non-standard urls (e.g. posts inside sub-pages)
|
80
|
-
attrs['collections'][path]['permalink'] = "#{page.url}/:path" if path != page.slug
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
# set permalink style for posts
|
85
|
-
attrs['defaults'] = [{
|
86
|
-
'scope' => {
|
87
|
-
'path' => '',
|
88
|
-
'type' => 'posts'
|
89
|
-
},
|
90
|
-
'values' => {
|
91
|
-
'permalink' => "/#{posts_path}/:title/"
|
92
|
-
}
|
93
|
-
}]
|
94
|
-
|
95
|
-
attrs
|
96
|
-
end
|
97
|
-
|
98
|
-
def to_file(dir = 'export')
|
99
|
-
assets = Dir.glob("#{dir}/_uploads/**/*").each_with_object({}) do |var, hash|
|
100
|
-
# remap assets to _uploads
|
101
|
-
hash[var.sub("#{dir}/_uploads",'/assets')] = var.sub("#{dir}/_uploads",'/uploads')
|
102
|
-
end
|
103
|
-
|
104
|
-
config.to_yaml.gsub(Regexp.union(assets.keys), assets)
|
105
|
-
end
|
106
|
-
|
42
|
+
|
107
43
|
end
|
108
|
-
end
|
44
|
+
end
|