siteleaf 2.0.0.pre.beta7 → 2.0.0.pre.beta9

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4b323d004281cc83a6c93bb857122cb9cfcdf919
4
- data.tar.gz: 255f89f85b0e20da5cbf28696358fb41774d6973
3
+ metadata.gz: ffdf39daf59542b67cb85f8953690eed8e4878f6
4
+ data.tar.gz: cefb58dc50c17b2704cda475ace5d0c6aa35ccf6
5
5
  SHA512:
6
- metadata.gz: 295888d2c12d9f1863d2891a7691911aa6981c8dfb3008fe798875bfae29eb751e586650d7d8df4d173067b26abf70cefe60cc7a4a052ba4274675f717e61c27
7
- data.tar.gz: 188f454e20e56a245cfff4238181b1be54fd5abb197401c7219558e44c76da26bef6d9ad0738b6f2833665ca508e66a2a1c77636ca90b6dcc806caae02c87943
6
+ metadata.gz: b817f87f1733ef8aacfe0199dd0aab699ab04ecd6e1179094905743637213ef4dfefd4b09bdc5b5c5226cb27a0399ccd58509e94a5770095041e6a2b0474a8d8
7
+ data.tar.gz: d11c229b37885a7a89c166c24c81f0225058953f0bfee21161f2d653d34b2238f695a83376554440b210687b1487600109b49b22b5637f265140ff993c9183e3
data/README.md CHANGED
@@ -118,44 +118,68 @@ site.publish
118
118
  # delete site
119
119
  site.delete
120
120
 
121
- # delete site by id
122
- Siteleaf::Site.delete('5196f137cc8591956b000001')
123
-
124
121
  # get all pages in site
125
122
  pages = site.pages
126
123
 
127
124
  # create new page in site
128
125
  page = Siteleaf::Page.create({
129
- :site_id => site.id,
130
126
  :title => 'My Page',
131
- :body => 'This is my first page.'
127
+ :body => 'This is my first page.',
128
+ :site_id => site.id
132
129
  })
133
130
 
134
131
  # get page by id
135
132
  page = Siteleaf::Page.find('519719ddcc85910626000001')
136
133
 
137
- # create new post in page
138
- post = Siteleaf::Post.create({
139
- :title => 'My Post',
140
- :body => 'This is my first post.'
134
+ # delete page by id
135
+ Siteleaf::Page.delete('519719ddcc85910626000001')
136
+
137
+ # get posts
138
+ posts = site.posts # or Collection.new(path: 'posts', site_id: site.id).documents
139
+
140
+ # create new post
141
+ post = Siteleaf::Documents.create({
142
+ :title => 'My Post',
143
+ :body => 'This is my first post.',
144
+ :collection_path => 'posts',
145
+ :site_id => site.id
141
146
  })
142
147
 
143
- # update page, add metadata
148
+ # update post, add metadata
144
149
  post.title = 'New Title'
145
- post.meta = {'foo' => 'bar'}
150
+ post.metadata = {'foo' => 'bar'}
146
151
  post.save
147
152
 
148
- # upload file
149
- asset = Siteleaf::File.create({
150
- :file => File.open("~/image.png"),
151
- :path => "image.png"
152
- })
153
-
154
153
  # delete post
155
154
  post.delete
156
155
 
157
- # delete page by id
158
- Siteleaf::Page.delete('519719ddcc85910626000001')
156
+ # get files in "uploads" collection
157
+ files = site.uploads # or Collection.new(path: 'uploads', site_id: site.id).files
158
+
159
+ # upload image into "uploads" collection
160
+ file = Siteleaf::File.create({
161
+ :file => File.new('~/image.png'),
162
+ :path => 'image.png'
163
+ :collection_path => 'uploads',
164
+ :site_id => site.id
165
+ })
166
+
167
+ # get source files
168
+ files = site.source_files
169
+
170
+ # upload source file
171
+ file = Siteleaf::SourceFile.create({
172
+ :file => File.new('~/foo.html'),
173
+ :name => '_includes/foo.html',
174
+ :site_id => site.id
175
+ })
176
+
177
+ # delete file
178
+ file.delete
179
+
180
+ # delete file by name
181
+ Siteleaf::SourceFile.new(name: '_includes/foo.html', site_id: site.id).delete
182
+
159
183
  ```
160
184
 
161
185
  Troubleshooting
@@ -52,102 +52,77 @@ def auth(re_auth = false)
52
52
  return false
53
53
  end
54
54
  end
55
- end
56
-
57
- def config(site)
58
- Siteleaf.save_settings({site_id: site.id}, '.siteleaf.yml')
59
- puts "=> Site configured."
60
- end
61
-
62
- def get_site_id
63
- # check env vars
64
- [:api_key, :api_secret, :api_base, :api_version].each do |key|
65
- if value = ENV['SITELEAF_'+key.to_s.upcase]
66
- Siteleaf.send "#{key}=", value
67
- end
68
- end
69
-
70
- ENV['SITELEAF_SITE_ID'] || if settings = Siteleaf.load_settings('.siteleaf.yml')
71
- settings[:site_id]
72
- end
55
+ rescue Exception => e
56
+ print "Error: #{e.message}\n"
73
57
  end
74
58
 
75
59
  def pull(site_id)
60
+ print "Reading site...\n"
61
+
76
62
  # get all the things
77
63
  site = Siteleaf::Site.find(site_id)
78
- files = site.files
79
- uploads = site.uploads
80
- pages = site.pages
81
- posts = site.posts
82
- collections = site.collections
83
- documents = collections.map{ |collection| collection.documents }.flatten
84
-
85
- assets = [site] + files + uploads + pages + posts + documents
86
-
64
+ site_files = site.source_tree
87
65
  updated_count = 0
88
66
 
89
- assets.each do |asset|
90
- sha = ::File.exist?(asset.filename) && Digest::SHA1.hexdigest(::File.read(asset.filename))
91
- if asset.sha == sha
92
- # file is up to date
93
- else
94
- print "Downloading #{asset.filename}..."
95
- FileUtils.mkdir_p(::File.dirname(asset.filename))
96
- ::File.open(asset.filename, 'w:UTF-8') { |f| f.write(asset.to_file) }
67
+ # download unmatched files
68
+ site_files.each do |file|
69
+ sha = ::File.exist?(file.name) && Siteleaf::GitHash.file(file.name)
70
+ if file.sha != sha
71
+ print "Downloading #{file.name}..."
72
+ FileUtils.mkdir_p(::File.dirname(file.name))
73
+ ::File.open(file.name, 'w') { |f| f.write(file.to_file) }
97
74
  updated_count += 1
98
75
  print "complete.\n"
99
76
  end
100
77
  end
101
78
 
102
- puts "=> #{updated_count} file(s) downloaded.\n"
79
+ # check for old files
80
+ local_files = read_dir
81
+ missing_files = []
82
+ local_files.each do |path|
83
+ missing_files << path if !site_files.find{|a| a.name.casecmp(path) == 0 }
84
+ end
85
+ if missing_files.empty?
86
+ puts "=> #{updated_count} file(s) downloaded.\n"
87
+ else
88
+ print "=> #{updated_count} file(s) downloaded. Delete the following #{missing_files.size} unmatched local file(s)?\n"
89
+ missing_files.each do |path|
90
+ puts path
91
+ end
92
+ print '(y/n)? '
93
+ if $stdin.gets.chomp == 'y'
94
+ missing_files.each do |path|
95
+ print "Deleting #{path}..."
96
+ ::File.delete(path)
97
+ print "complete.\n"
98
+ end
99
+ puts "=> #{missing_files.size} file(s) deleted.\n"
100
+ end
101
+ end
102
+ rescue Exception => e
103
+ print "Error: #{e.message}\n"
103
104
  end
104
105
 
105
106
  def push(site_id)
106
- # check config
107
- config = ::File.exist?('_config.yml') ? YAML::load(::File.read('_config.yml')) : {}
108
- markdown_ext = (config['markdown_ext'] || 'markdown,mdw,mdwn,md,text').split(',')
107
+ print "Reading site...\n"
109
108
 
110
109
  # get all the things
111
110
  site = Siteleaf::Site.find(site_id)
112
- files = site.files
113
- uploads = site.uploads
114
- pages = site.pages
115
- posts = site.posts
116
- collections = site.collections
117
- documents = []
118
- collections.each do |collection|
119
- documents += collection.documents
120
- end
121
-
122
- assets = files + uploads + pages + posts + documents
123
-
111
+ site_files = site.source_tree
112
+ local_files = read_dir
124
113
  updated_count = 0
125
- ignore_paths = ['_config.yml', 'config.ru', '.*', '_site/*', 'Gemfile', 'Gemfile.lock']
126
- ignore_paths += ::File.read('.siteleafignore').split(/\r?\n/) if ::File.exists?('.siteleafignore')
127
- ignore_paths += config['exclude'] if config['exclude'].is_a? Array
128
114
 
129
- # push site config
130
- path = '_config.yml'
131
- if site.sha != Digest::SHA1.hexdigest(::File.read(path))
132
- print "Uploading #{path}..."
133
-
134
- metadata = config.dup
135
- metadata.delete('collections')
136
- attrs = { 'id' => site_id }
137
- attrs['title'] = metadata.delete('title') if metadata['title']
138
- attrs['domain'] = metadata.delete('url') if metadata['url']
139
- attrs['timezone'] = metadata.delete('timezone') if metadata['timezone']
140
- attrs['defaults'] = metadata.delete('defaults').map{|default|
141
- {
142
- 'path' => default['scope']['path'],
143
- 'type' => default['scope']['type'],
144
- 'values' => default['values']
145
- }
146
- } if metadata['defaults']
147
- attrs['metadata'] = metadata
148
-
149
- response = Siteleaf::Site.new(attrs).save
150
-
115
+ # find changed files
116
+ changed_files = local_files.reject do |path|
117
+ file = site_files.find{|a| a.name.casecmp(path) == 0 }
118
+ file && Siteleaf::GitHash.file(path) == file.sha
119
+ end
120
+ changed_files.unshift('_config.yml') if changed_files.delete('_config.yml')
121
+
122
+ # upload changed files
123
+ changed_files.each do |path|
124
+ print "Uploading #{path}..."
125
+ response = Siteleaf::SourceFile.create(site_id: site_id, name: path, file: ::File.new(path))
151
126
  if error = !response || response.error || response.message
152
127
  print (error) ? "error: #{error}\n" : "error.\n"
153
128
  return
@@ -157,153 +132,30 @@ def push(site_id)
157
132
  end
158
133
  end
159
134
 
160
- # create collections
161
- collection_paths = []
162
- collections_config = config['collections'] || {}
163
- collections_config.each do |path, metadata|
164
- path = path.gsub(/[^a-z0-9_\-\.]/i, '')
165
- collection_paths << "_#{path}"
166
- collection = collections.find{|c| c.path.casecmp(path) == 0 }
167
- title = metadata.delete('title') || path
168
- output = metadata.delete('output')
169
- permalink = metadata.delete('permalink')
170
-
171
- if !collection
172
- # create any new collections
173
- collections << Siteleaf::Collection.create(site_id: site.id, title: title, path: path, output: output, permalink: permalink, metadata: metadata)
174
- elsif collection.title != title || collection.output != output || collection.permalink != permalink || collection.metadata != metadata
175
- # update any changed collections
176
- collections.delete(collection)
177
- colllection = Siteleaf::Collection.new(id: collection.id, title: title, path: path, output: output, permalink: permalink, metadata: metadata).save
178
- collections << colllection
179
- end
180
- end
181
-
182
- # upload files
183
- paths = Dir.glob("**/*")
184
- paths.each do |path|
185
- if !::File.directory?(path) && !ignore_paths.any?{|i| ::File.fnmatch?(i, path, File::FNM_CASEFOLD) || ::File.fnmatch?(i, ::File.basename(path), File::FNM_CASEFOLD) }
186
-
187
- asset = assets.find{|a| a.filename.casecmp(path) == 0 }
188
- basedir = ::File.dirname(path).split('/').first
189
- basename = ::File.basename(path)
190
- ext = ::File.extname(path).sub('.', '')
191
- sha = Digest::SHA1.hexdigest(::File.read(path))
192
- static = !has_yaml_header?(path)
193
- collection_id = nil
194
-
195
- model = if ['_drafts', '_posts'].include?(basedir)
196
- Siteleaf::Post
197
- elsif basedir == '_uploads'
198
- Siteleaf::Upload
199
- elsif collection_paths.include?(basedir) && (collection = collections.find {|c| basedir == "_#{c.path}" })
200
- collection_id = collection.id
201
- Siteleaf::Document
202
- elsif !static && markdown_ext.include?(ext)
203
- Siteleaf::Page
204
- else
205
- Siteleaf::File
206
- end
207
-
208
- if asset.nil? || asset.sha != sha || !asset.is_a?(model) || asset.filename != path
209
-
210
- print "Uploading #{path}..."
211
-
212
- response = if [Siteleaf::Post, Siteleaf::Document, Siteleaf::Page].include?(model)
213
-
214
- # handle content
215
- metadata = {}
216
- unless static
217
- body, metadata = read_frontmatter(path)
218
- end
219
-
220
- clean_path = path.sub("#{basedir}/",'').sub(".#{ext}",'')
221
- title = metadata.delete('title') || ::File.basename(clean_path)
222
-
223
- attrs = {site_id: site.id, title: title, path: clean_path, static: static}
224
- attrs[:body] = body if body && body != ""
225
- attrs[:metadata] = metadata if metadata && !metadata.empty?
226
-
227
- if basedir == '_drafts'
228
- attrs[:visibility] = 'draft'
229
- elsif basedir == '_posts'
230
- attrs[:visibility] = (metadata['published'].delete == false) ? 'hidden' : 'visible'
231
- elsif model == Siteleaf::Document
232
- attrs[:collection_id] = collection_id
233
- else
234
- attrs[:path] = path.sub(".#{ext}",'')
235
- end
236
-
237
- if asset && asset.is_a?(model)
238
- attrs[:id] = asset.id
239
- asset = model.new(attrs).save
240
- else
241
- asset.delete if asset
242
- asset = model.create(attrs)
243
- end
244
-
245
- else
246
-
247
- # handle assets
248
- file = path
249
- metadata = {}
250
- unless static
251
- body, metadata = read_frontmatter(path)
252
- file = Tempfile.new(basename)
253
- ::File.open(file, 'w:UTF-8') { |f| f.write(body) }
254
- end
255
-
256
- attrs = {site_id: site.id, file: ::File.new(file), path: path, static: static}
257
- if basedir == '_uploads'
258
- attrs[:path] = path.sub("#{basedir}/",'')
259
- end
260
-
261
- asset.delete if asset
262
- asset = model.create(attrs)
263
- if metadata && !metadata.empty?
264
- asset = model.new(id: asset.id, metadata: metadata).save
265
- end
266
- asset
267
-
268
- end
269
-
270
- if error = !response || response.error || response.message
271
- print (error) ? "error: #{error}\n" : "error.\n"
272
- return
273
- else
274
- updated_count += 1
275
- print "complete.\n"
276
- end
277
-
278
- end
279
- end
280
- end
281
-
282
135
  # check for old files
283
136
  missing_assets = []
284
- collections.each do |collection|
285
- missing_assets << collection if !collection_paths.find{|p| p.casecmp("_#{collection.path}") == 0}
286
- end
287
- assets.each do |asset|
288
- missing_assets << asset if !paths.find{|p| p.casecmp(asset.filename) == 0 }
137
+ site_files.each do |asset|
138
+ missing_assets << asset if !local_files.find{|p| p.casecmp(asset.name) == 0 }
289
139
  end
290
140
  if missing_assets.empty?
291
141
  puts "=> #{updated_count} file(s) uploaded.\n"
292
142
  else
293
- print "=> #{updated_count} file(s) uploaded. Delete the following #{missing_assets.size} unmatched file(s)?\n"
143
+ print "=> #{updated_count} file(s) uploaded. Delete the following #{missing_assets.size} unmatched remote file(s)?\n"
294
144
  missing_assets.each do |asset|
295
- puts asset.filename
145
+ puts asset.name
296
146
  end
297
147
  print '(y/n)? '
298
148
  if $stdin.gets.chomp == 'y'
299
149
  missing_assets.each do |asset|
300
- print "Deleting #{asset.filename}..."
150
+ print "Deleting #{asset.name}..."
301
151
  asset.delete
302
152
  print "complete.\n"
303
153
  end
304
154
  puts "=> #{missing_assets.size} file(s) deleted.\n"
305
155
  end
306
156
  end
157
+ rescue Exception => e
158
+ print "Error: #{e.message}\n"
307
159
  end
308
160
 
309
161
  def import(file, quiet = true)
@@ -321,6 +173,8 @@ def import(file, quiet = true)
321
173
  end
322
174
  puts "=> Import completed.\n"
323
175
  end
176
+ rescue Exception => e
177
+ print "Error: #{e.message}\n"
324
178
  end
325
179
 
326
180
  def publish(site_id, quiet = true)
@@ -339,20 +193,39 @@ def publish(site_id, quiet = true)
339
193
  end
340
194
  puts "=> Publish completed.\n"
341
195
  end
196
+ rescue Exception => e
197
+ print "Error: #{e.message}\n"
198
+ end
199
+
200
+ def config(site)
201
+ Siteleaf.save_settings({site_id: site.id}, '.siteleaf.yml')
202
+ puts "=> Site configured."
342
203
  end
343
204
 
344
- def has_yaml_header?(file)
345
- !!(File.open(file, 'rb') { |f| f.read(5) } =~ /\A---\r?\n/)
205
+ def get_site_id
206
+ # check env vars
207
+ [:api_key, :api_secret, :api_base, :api_version].each do |key|
208
+ if value = ENV['SITELEAF_'+key.to_s.upcase]
209
+ Siteleaf.send "#{key}=", value
210
+ end
211
+ end
212
+
213
+ ENV['SITELEAF_SITE_ID'] || if settings = Siteleaf.load_settings('.siteleaf.yml')
214
+ settings[:site_id]
215
+ end
346
216
  end
347
217
 
348
- def read_frontmatter(file)
349
- content = ::File.read(file)
350
- metadata = {}
351
- if content =~ /\A(---\s*\n.*?\n?)^((---|\.\.\.)\s*$\n?)/m
352
- content = $POSTMATCH
353
- metadata = YAML.load($1)
218
+ def read_dir
219
+ jekyll_config = ::File.exist?('_config.yml') ? YAML::load(::File.read('_config.yml')) : {}
220
+
221
+ ignore_paths = ['config.ru', '.*', '_site/*', 'Gemfile', 'Gemfile.lock']
222
+ ignore_paths += ::File.read('.siteleafignore').split(/\r?\n/) if ::File.exists?('.siteleafignore')
223
+ ignore_paths += jekyll_config['exclude'] if jekyll_config['exclude'].is_a? Array
224
+
225
+ Dir.glob("**/*").reject do |path|
226
+ ::File.directory?(path) ||
227
+ ignore_paths.any? {|i| ::File.fnmatch?(i, path, File::FNM_CASEFOLD) || ::File.fnmatch?(i, ::File.basename(path), File::FNM_CASEFOLD) }
354
228
  end
355
- return content, metadata
356
229
  end
357
230
 
358
231
  case ARGV[0]
@@ -382,8 +255,7 @@ when 'n', 'new'
382
255
  end
383
256
  end
384
257
  when 'pull'
385
- #case ARGV[1]
386
- #when 'theme'
258
+ if ARGV.size == 1
387
259
  site_id = get_site_id
388
260
  if auth != false
389
261
  if site_id
@@ -392,12 +264,11 @@ when 'pull'
392
264
  puts "Site not configured, run `siteleaf config yoursite.com`.\n"
393
265
  end
394
266
  end
395
- #else
396
- # puts "`#{ARGV[0]}` command not found.\n"
397
- #end
267
+ else
268
+ puts "`#{ARGV.join(' ')}` command not found.\n"
269
+ end
398
270
  when 'push'
399
- #case ARGV[1]
400
- #when 'theme'
271
+ if ARGV.size == 1
401
272
  site_id = get_site_id
402
273
  if auth != false
403
274
  if site_id
@@ -406,9 +277,9 @@ when 'push'
406
277
  puts "Site not configured, run `siteleaf config yoursite.com`.\n"
407
278
  end
408
279
  end
409
- #else
410
- # puts "`#{ARGV[0]}` command not found.\n"
411
- #end
280
+ else
281
+ puts "`#{ARGV.join(' ')}` command not found.\n"
282
+ end
412
283
  when 'publish'
413
284
  site_id = get_site_id
414
285
  if auth != false
@@ -2,20 +2,18 @@ libdir = ::File.dirname(__FILE__)
2
2
  $LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
3
3
 
4
4
  require 'siteleaf/version'
5
+ require 'siteleaf/git_hash'
5
6
  require 'siteleaf/client'
6
7
  require 'siteleaf/entity'
7
- require 'siteleaf/asset'
8
8
  require 'siteleaf/file'
9
- require 'siteleaf/upload'
10
9
  require 'siteleaf/job'
11
10
  require 'siteleaf/content'
12
11
  require 'siteleaf/page'
13
- require 'siteleaf/post'
14
12
  require 'siteleaf/collection'
15
13
  require 'siteleaf/document'
16
14
  require 'siteleaf/site'
15
+ require 'siteleaf/source_file'
17
16
  require 'siteleaf/user'
18
- require 'patches/time_with_zone_encode_with'
19
17
  require 'digest/sha1'
20
18
  require 'rbconfig'
21
19
  require 'uri'
@@ -25,7 +23,7 @@ module Siteleaf
25
23
 
26
24
  @api_key = ENV['SITELEAF_API_KEY']
27
25
  @api_secret = ENV['SITELEAF_API_SECRET']
28
- @api_base = 'https://api.v2.siteleaf.com'
26
+ @api_base = 'https://api.siteleaf.com'
29
27
  @api_version = 'v2'
30
28
 
31
29
  class << self
@@ -5,7 +5,8 @@ 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}
8
+ :basic_auth => {:username => email, :password => password},
9
+ :headers => {"User-Agent" => "Siteleaf Gem/#{Siteleaf::VERSION}"}
9
10
  })
10
11
  return request.parsed_response # parse JSON
11
12
  rescue => e
@@ -14,7 +15,7 @@ module Siteleaf
14
15
  end
15
16
 
16
17
  def self.get(path, params = {})
17
- params['limit'] = 9999
18
+ params['per_page'] = 9999 # todo: paginate
18
19
  self.execute(:get, path, params)
19
20
  end
20
21
 
@@ -35,15 +36,19 @@ module Siteleaf
35
36
  begin
36
37
  if (method == :post || method == :put) && !params.has_key?('file') && !params.has_key?(:file)
37
38
  request = HTTParty.send(method, Siteleaf.api_url(path), {
38
- :headers => { 'Content-Type' => 'application/json' },
39
39
  :body => params.to_json,
40
40
  :basic_auth => {:username => Siteleaf.api_key, :password => Siteleaf.api_secret},
41
+ :headers => {
42
+ "Content-Type" => "application/json",
43
+ "User-Agent" => "Siteleaf Gem/#{Siteleaf::VERSION}"
44
+ },
41
45
  :timeout => 300
42
46
  })
43
47
  else
44
48
  request = HTTMultiParty.send(method, Siteleaf.api_url(path), {
45
49
  :query => params,
46
50
  :basic_auth => {:username => Siteleaf.api_key, :password => Siteleaf.api_secret},
51
+ :headers => {"User-Agent" => "Siteleaf Gem/#{Siteleaf::VERSION}"},
47
52
  :timeout => 300
48
53
  })
49
54
  end
@@ -1,22 +1,35 @@
1
1
  module Siteleaf
2
2
  class Collection < Entity
3
3
 
4
- attr_accessor :title, :path, :permalink, :output, :site_id, :metadata
4
+ attr_accessor :title, :path, :permalink, :output, :site_id, :user_id, :metadata
5
5
  attr_reader :id, :directory, :created_at, :updated_at
6
6
 
7
7
  def create_endpoint
8
- "sites/#{self.site_id}/collections"
8
+ ::File.join("sites", site_id, "collections")
9
+ end
10
+
11
+ def entity_endpoint
12
+ ::File.join(create_endpoint, identifier)
13
+ end
14
+
15
+ def identifier
16
+ path
9
17
  end
10
18
 
11
19
  def site
12
- Site.find(self.site_id)
20
+ Site.find(site_id)
13
21
  end
14
22
 
15
23
  def documents
16
- result = Client.get "collections/#{self.id}/documents"
24
+ result = Client.get "#{entity_endpoint}/documents"
17
25
  result.map { |r| Document.new(r) } if result.is_a? Array
18
26
  end
19
27
 
28
+ def files
29
+ result = Client.get "#{entity_endpoint}/files"
30
+ result.map { |r| File.new(r) } if result.is_a? Array
31
+ end
32
+
20
33
  def output?
21
34
  output == true
22
35
  end
@@ -1,11 +1,11 @@
1
1
  module Siteleaf
2
2
  class Content < Entity
3
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
4
+ attr_accessor :title, :body, :path, :permalink, :visibility, :date, :user_id, :site_id, :metadata
5
+ attr_reader :id, :filename, :basename, :directory, :url, :sha, :created_at, :updated_at
6
6
 
7
7
  def site
8
- Site.find(self.site_id) if self.site_id
8
+ Site.find(site_id) if site_id
9
9
  end
10
10
 
11
11
  def draft?
@@ -20,21 +20,9 @@ module Siteleaf
20
20
  visibility == 'visible'
21
21
  end
22
22
  alias_method :published?, :visible?
23
-
23
+
24
24
  def to_file
25
- frontmatter + "---\n\n".freeze + body.to_s
26
- end
27
-
28
- protected
29
-
30
- def frontmatter
31
- attrs = metadata || {}
32
- attrs['title'] = title
33
- attrs['date'] = Time.parse(published_at).utc unless published_at.nil?
34
- attrs['published'] = false if hidden?
35
- attrs['permalink'] = permalink unless permalink.nil?
36
-
37
- attrs.empty? ? "---\n".freeze : attrs.to_yaml
25
+ SourceFile.new(site_id: site_id, name: filename).to_file
38
26
  end
39
27
 
40
28
  end
@@ -1,14 +1,18 @@
1
1
  module Siteleaf
2
2
  class Document < Content
3
3
 
4
- attr_accessor :collection_id
4
+ attr_accessor :collection_path
5
5
 
6
6
  def create_endpoint
7
- "collections/#{self.collection_id}/documents"
7
+ ::File.join("sites", site_id, "collections", collection_identifier, "documents")
8
8
  end
9
9
 
10
10
  def collection
11
- Collection.find(self.collection_id)
11
+ Collection.find(collection_identifier)
12
+ end
13
+
14
+ def collection_identifier
15
+ collection_path || directory.match(/_(.*)/).try(:last)
12
16
  end
13
17
 
14
18
  end
@@ -8,24 +8,28 @@ module Siteleaf
8
8
  end
9
9
 
10
10
  def self.all
11
- result = Client.get "#{self.endpoint}"
12
- result.map { |r| self.new(r) } if result.is_a? Array
11
+ result = Client.get endpoint
12
+ result.map { |r| new(r) } if result.is_a? Array
13
13
  end
14
14
 
15
- def self.find(id)
16
- result = Client.get "#{self.endpoint}/#{id}"
17
- self.new(result) if result
15
+ def self.find(identifier)
16
+ result = Client.get "#{endpoint}/#{identifier}"
17
+ new(result) if result
18
18
  end
19
19
 
20
20
  def self.create(attributes = {})
21
- self.new(attributes).save
21
+ new(attributes).save
22
+ end
23
+
24
+ def self.delete(identifier)
25
+ Client.delete "#{endpoint}/#{identifier}"
22
26
  end
23
27
 
24
28
  def save
25
- if self.id
26
- result = Client.put "#{self.class.endpoint}/#{self.id}", self.attributes
29
+ if identifier
30
+ result = Client.put entity_endpoint, attributes
27
31
  else
28
- result = Client.post "#{self.create_endpoint}", self.attributes
32
+ result = Client.post create_endpoint, attributes
29
33
  end
30
34
  if result
31
35
  self.attributes = result
@@ -33,12 +37,8 @@ module Siteleaf
33
37
  end
34
38
  end
35
39
 
36
- def self.delete(id)
37
- Client.delete "#{self.endpoint}/#{id}"
38
- end
39
-
40
40
  def delete
41
- Client.delete "#{self.class.endpoint}/#{self.id}"
41
+ Client.delete entity_endpoint
42
42
  end
43
43
 
44
44
  def attributes
@@ -60,6 +60,14 @@ module Siteleaf
60
60
  def create_endpoint
61
61
  self.class.endpoint
62
62
  end
63
+
64
+ def entity_endpoint
65
+ "#{self.class.endpoint}/#{identifier}"
66
+ end
67
+
68
+ def identifier
69
+ id
70
+ end
63
71
 
64
72
  end
65
73
  end
@@ -1,8 +1,27 @@
1
1
  module Siteleaf
2
- class File < Asset
3
-
2
+ class File < Entity
3
+
4
+ attr_accessor :file, :filename, :path, :collection_path, :site_id, :user_id
5
+ attr_reader :id, :basename, :directory, :url, :download_url, :thumbnail_url, :content_type, :filesize, :sha, :created_at, :updated_at
6
+
4
7
  def create_endpoint
5
- "sites/#{self.site_id}/files"
8
+ ::File.join("sites", site_id, "collections", collection_identifier, "files")
9
+ end
10
+
11
+ def site
12
+ Site.find(site_id) if site_id
13
+ end
14
+
15
+ def collection
16
+ Collection.find(collection_identifier)
17
+ end
18
+
19
+ def collection_identifier
20
+ collection_path || (directory && directory.match(/_(.*)/).try(:last))
21
+ end
22
+
23
+ def to_file
24
+ SourceFile.new(site_id: site_id, name: filename).to_file
6
25
  end
7
26
 
8
27
  end
@@ -0,0 +1,14 @@
1
+ module Siteleaf
2
+ module GitHash
3
+ # equivalent of `git hash-object file.txt`
4
+ def self.file(filename)
5
+ ::File.open(filename, 'r') do |f|
6
+ Digest::SHA1.hexdigest("blob #{f.size}\0#{f.read}")
7
+ end
8
+ end
9
+
10
+ def self.string(str)
11
+ Digest::SHA1.hexdigest("blob #{str.bytesize}\0#{str}")
12
+ end
13
+ end
14
+ end
@@ -2,7 +2,7 @@ module Siteleaf
2
2
  class Page < Content
3
3
 
4
4
  def create_endpoint
5
- "sites/#{self.site_id}/pages"
5
+ "sites/#{site_id}/pages"
6
6
  end
7
7
 
8
8
  end
@@ -15,33 +15,31 @@ module Siteleaf
15
15
  Job.new(id: result["job_id"]) if result
16
16
  end
17
17
 
18
- def files
19
- result = Client.get "sites/#{self.id}/files"
20
- result.map { |r| File.new(r) } if result.is_a? Array
21
- end
22
-
23
- def uploads
24
- result = Client.get "sites/#{self.id}/uploads"
25
- result.map { |r| Upload.new(r) } if result.is_a? Array
18
+ def source_files(dir = '.')
19
+ result = Client.get ::File.join(entity_endpoint, "source", dir)
20
+ result.map { |r| SourceFile.new(r.merge('site_id' => id)) } if result.is_a? Array
26
21
  end
27
22
 
28
23
  def pages
29
- result = Client.get "sites/#{self.id}/pages"
24
+ result = Client.get "#{entity_endpoint}/pages"
30
25
  result.map { |r| Page.new(r) } if result.is_a? Array
26
+ end
27
+
28
+ def collections
29
+ result = Client.get "#{entity_endpoint}/collections"
30
+ result.map { |r| Collection.new(r) } if result.is_a? Array
31
31
  end
32
32
 
33
33
  def posts
34
- result = Client.get "sites/#{self.id}/posts"
35
- result.map { |r| Post.new(r) } if result.is_a? Array
34
+ Collection.new(path: 'posts', site_id: id).documents
36
35
  end
37
36
 
38
- def collections
39
- result = Client.get "sites/#{self.id}/collections"
40
- result.map { |r| Collection.new(r) } if result.is_a? Array
37
+ def uploads
38
+ Collection.new(path: 'uploads', site_id: id).files
41
39
  end
42
40
 
43
41
  def publish
44
- result = Client.post "sites/#{self.id}/publish", {}
42
+ result = Client.post "#{entity_endpoint}/publish", {}
45
43
  Job.new(id: result["job_id"]) if result
46
44
  end
47
45
 
@@ -54,46 +52,30 @@ module Siteleaf
54
52
  end
55
53
 
56
54
  def sha
57
- Digest::SHA1.hexdigest(to_file)
55
+ Siteleaf::GitHash.string(to_file)
58
56
  end
59
57
 
60
- def to_file
61
- config
58
+ def source_tree(dir = '.')
59
+ @tree_files = []
60
+ @tree_dirs = []
61
+ recursive_source_files(dir)
62
+ @tree_files
62
63
  end
63
64
 
64
65
  protected
65
66
 
66
- def uploads_collection
67
- Collection.new('title' => 'Uploads', 'path' => 'uploads', 'output' => true)
68
- end
69
-
70
- def defaults_config
71
- defaults.map do |d|
72
- { 'scope' => {}, 'values' => d['values'] }.tap do |default|
73
- default['scope']['path'] = d['path'] if d['path']
74
- default['scope']['type'] = d['type'] if d['type']
67
+ def recursive_source_files(dir = '.')
68
+ source_files(dir).each do |file|
69
+ if file.type == 'directory'
70
+ unless @tree_dirs.include?(file.name)
71
+ @tree_dirs << file.name
72
+ recursive_source_files(file.name)
73
+ end
74
+ else
75
+ @tree_files << file
75
76
  end
76
77
  end
77
78
  end
78
79
 
79
- def collections_config
80
- collections.unshift(uploads_collection).each_with_object({}) do |collection, hash|
81
- hash[collection.path] = collection.metadata || {}
82
- hash[collection.path]['title'] = collection.title
83
- hash[collection.path]['output'] = collection.output
84
- hash[collection.path]['permalink'] = collection.permalink unless collection.permalink.nil?
85
- end
86
- end
87
-
88
- def config
89
- attrs = metadata || {}
90
- attrs['title'] = title
91
- attrs['url'] = full_url
92
- attrs['timezone'] = timezone
93
- attrs['collections'] = collections_config
94
- attrs['defaults'] = defaults_config unless defaults.empty?
95
- attrs.to_yaml
96
- end
97
-
98
80
  end
99
81
  end
@@ -0,0 +1,26 @@
1
+ module Siteleaf
2
+ class SourceFile < Entity
3
+
4
+ attr_accessor :file, :name, :site_id
5
+ attr_reader :name, :url, :download_url, :type, :filesize, :sha, :created_at, :updated_at, :user_id
6
+
7
+ def create_endpoint
8
+ ::File.join("sites", site_id, "source", URI.escape(identifier))
9
+ end
10
+
11
+ def entity_endpoint
12
+ create_endpoint
13
+ end
14
+
15
+ def identifier
16
+ name
17
+ end
18
+
19
+ def to_file
20
+ response = Client.get(::File.join("sites", site_id, "source", "#{URI.escape(identifier)}?download"))
21
+ raise response['message'] if response['message'] # indicates API error
22
+ response.body
23
+ end
24
+
25
+ end
26
+ end
@@ -1,3 +1,3 @@
1
1
  module Siteleaf
2
- VERSION = "2.0.0.pre.beta7"
2
+ VERSION = "2.0.0.pre.beta9"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: siteleaf
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0.pre.beta7
4
+ version: 2.0.0.pre.beta9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Siteleaf
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-10-08 00:00:00.000000000 Z
11
+ date: 2016-01-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httparty
@@ -80,20 +80,18 @@ files:
80
80
  - README.md
81
81
  - Rakefile
82
82
  - bin/siteleaf
83
- - lib/patches/time_with_zone_encode_with.rb
84
83
  - lib/siteleaf.rb
85
- - lib/siteleaf/asset.rb
86
84
  - lib/siteleaf/client.rb
87
85
  - lib/siteleaf/collection.rb
88
86
  - lib/siteleaf/content.rb
89
87
  - lib/siteleaf/document.rb
90
88
  - lib/siteleaf/entity.rb
91
89
  - lib/siteleaf/file.rb
90
+ - lib/siteleaf/git_hash.rb
92
91
  - lib/siteleaf/job.rb
93
92
  - lib/siteleaf/page.rb
94
- - lib/siteleaf/post.rb
95
93
  - lib/siteleaf/site.rb
96
- - lib/siteleaf/upload.rb
94
+ - lib/siteleaf/source_file.rb
97
95
  - lib/siteleaf/user.rb
98
96
  - lib/siteleaf/version.rb
99
97
  - siteleaf.gemspec
@@ -1,12 +0,0 @@
1
- class Time
2
- def encode_with(coder)
3
- label =
4
- if utc?
5
- usec.zero? ? '%Y-%m-%d %H:%M:%S Z' : '%Y-%m-%d %H:%M:%S.%9N Z'
6
- else
7
- usec.zero? ? '%Y-%m-%d %H:%M:%S %:z' : '%Y-%m-%d %H:%M:%S.%9N %:z'
8
- end
9
-
10
- coder.represent_scalar(nil, strftime(label))
11
- end
12
- end
@@ -1,43 +0,0 @@
1
- module Siteleaf
2
- class Asset < Entity
3
-
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
19
- else
20
- [frontmatter, "---\n\n".freeze, body].join('')
21
- end
22
- end
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
32
- end
33
-
34
- def body
35
- open(file['url'], 'r:UTF-8') { |f| f.read }
36
- end
37
-
38
- def static?
39
- static == true
40
- end
41
-
42
- end
43
- end
@@ -1,11 +0,0 @@
1
- module Siteleaf
2
- class Post < Content
3
-
4
- attr_accessor :taxonomy
5
-
6
- def create_endpoint
7
- "sites/#{self.parent_id}/posts"
8
- end
9
-
10
- end
11
- end
@@ -1,9 +0,0 @@
1
- module Siteleaf
2
- class Upload < Asset
3
-
4
- def create_endpoint
5
- "sites/#{self.site_id}/uploads"
6
- end
7
-
8
- end
9
- end