octodmin 0.2.1 → 0.3.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e6dccbff614863c901ad602335672cdcc78ce8c0
4
- data.tar.gz: 0a80dcc4385350ac55e396ed454a92013a587308
3
+ metadata.gz: 0bf286fc4c638a5552de1e48cae1442f6334202b
4
+ data.tar.gz: a7fcaa4243fb13481b1b7370efcdaafaff495882
5
5
  SHA512:
6
- metadata.gz: b15e6eabb46c8b065a9979e8ed03d78db4de6f39291d6f775d390a145524db1a361396aaf5fc32a44c431f22f82c4cc68328b384d8a50b04d4f8c6456cce0698
7
- data.tar.gz: a4174ef053834d5feb939e4a95131cb34275f48fac73eea2fbd57238977ce1ac85ddc1087c078d4ec92e75a72816d6dc4bfab3fb14de7517640ce6d66ec83e51
6
+ metadata.gz: 6afa97affb291815163e250291a0bc156d43d3bae6f7d8efcb9adba28a452c196a89a490e3314170791b0d40f532c84ce4d5842c7e835bdc7be8f737cbea6d11
7
+ data.tar.gz: a9edd643b252f7e11c7935e920a8c9923f59a4539ccd05ad621b2d295375177abce22bedbf77e8b7bc9792de4bbfc0233d9ecbc96320d1ad8bb0058c4ed1e2cc
@@ -1,3 +1,9 @@
1
+ v0.3.0
2
+ ------
3
+
4
+ * Improve preview
5
+ * Implement file uploads
6
+
1
7
  v0.2.1
2
8
  ------
3
9
 
@@ -4,6 +4,7 @@
4
4
  #= require bootstrap
5
5
  #= require bootstrap-markdown
6
6
  #= require bootstrap.growl/bootstrap-growl
7
+ #= require marked
7
8
  #= require spin.js/spin.js
8
9
  #= require react
9
10
  #= require react-loader
@@ -29,7 +29,7 @@
29
29
  $(document).trigger("fetchPosts")
30
30
 
31
31
  handleError: (error) ->
32
- $.growl(error.responseJSON?.errors.join("\n").replace(/\n/g, "<br>"), growlError)
32
+ $.growl(error.responseJSON?.errors.join("\n").replace(/\n/g, "<br>") || error.statusText, growlError)
33
33
 
34
34
  render: ->
35
35
  <div>
@@ -79,7 +79,7 @@
79
79
  @transitionTo("post_edit", post_id: response.posts.identifier)
80
80
 
81
81
  handleError: (error) ->
82
- $.growl(error.responseJSON?.errors.join(", "), growlError)
82
+ $.growl(error.responseJSON?.errors.join(", ") || error.statusText, growlError)
83
83
 
84
84
  render: ->
85
85
  <div className="panel panel-default">
@@ -211,6 +211,30 @@
211
211
  @setState(loading: true)
212
212
  $.getq("default", "/api/posts/#{@getParams().post_id}").always(@handleResponse).done(@handleSuccess).fail(@handleError)
213
213
 
214
+ handleUpload: (event)->
215
+ form = $("<form><input type='file' name='file' /></form>")
216
+ event.disableButtons("cmdUpload")
217
+
218
+ form.find("input").on("change", (->
219
+ data = new FormData(form[0])
220
+ $.ajaxq("default",
221
+ type: "POST"
222
+ url: "/api/posts/#{@state.post.identifier}/upload"
223
+ data: data
224
+ cache: false
225
+ contentType: false
226
+ processData: false
227
+ ).always(->
228
+ event.enableButtons("cmdUpload")
229
+ ).done(((result) ->
230
+ @handleUploadSuccess(event, result)
231
+ ).bind(this)).fail(@handleError)
232
+ ).bind(this))
233
+ form.find("input").click()
234
+
235
+ handleUploadSuccess: (event, response) ->
236
+ event.replaceSelection(response.uploads[0])
237
+
214
238
  handleBack: (event) ->
215
239
  event.preventDefault()
216
240
  @transitionTo("app")
@@ -237,7 +261,7 @@
237
261
  @transitionTo("post_edit", post_id: response.posts.identifier)
238
262
 
239
263
  handleError: (error) ->
240
- $.growl(error.responseJSON?.errors.join(", "), growlError)
264
+ $.growl(error.responseJSON?.errors.join(", ") || error.statusText, growlError)
241
265
 
242
266
  componentWillMount: ->
243
267
  @fetchPost()
@@ -253,6 +277,17 @@
253
277
  resize: "vertical"
254
278
  fullscreen:
255
279
  enable: false
280
+ additionalButtons: [
281
+ [{
282
+ name: "customGroup"
283
+ data: [{
284
+ name: "cmdUpload"
285
+ title: "Upload"
286
+ icon: "fa fa-upload"
287
+ callback: @handleUpload
288
+ }]
289
+ }]
290
+ ]
256
291
  )
257
292
 
258
293
  render: ->
@@ -5,6 +5,7 @@ namespace "api" do
5
5
  member do
6
6
  patch :restore
7
7
  patch :revert
8
+ post :upload
8
9
  end
9
10
  end
10
11
  resources :syncs, only: [:create]
@@ -1,13 +1,13 @@
1
+ require_relative "manage"
2
+
1
3
  module Octodmin::Controllers::Posts
2
- class Destroy
4
+ class Destroy < Manage
3
5
  include Octodmin::Action
4
6
  expose :post
5
7
 
6
8
  def call(params)
7
- self.format = :json
9
+ super
8
10
 
9
- @post = Octodmin::Post.find(params[:id])
10
- halt 400, JSON.dump(errors: ["Could not find post"]) unless @post
11
11
  @post.delete
12
12
  end
13
13
  end
@@ -0,0 +1,9 @@
1
+ module Octodmin::Controllers::Posts
2
+ class Manage
3
+ def call(params)
4
+ self.format = :json
5
+ @post = Octodmin::Post.find(params[:id])
6
+ halt 400, JSON.dump(errors: ["Could not find post"]) unless @post
7
+ end
8
+ end
9
+ end
@@ -1,13 +1,13 @@
1
+ require_relative "manage"
2
+
1
3
  module Octodmin::Controllers::Posts
2
- class Restore
4
+ class Restore < Manage
3
5
  include Octodmin::Action
4
6
  expose :post
5
7
 
6
8
  def call(params)
7
- self.format = :json
9
+ super
8
10
 
9
- @post = Octodmin::Post.find(params[:id])
10
- halt 400, JSON.dump(errors: ["Could not find post"]) unless @post
11
11
  @post.restore
12
12
  end
13
13
  end
@@ -1,13 +1,13 @@
1
+ require_relative "manage"
2
+
1
3
  module Octodmin::Controllers::Posts
2
- class Revert
4
+ class Revert < Manage
3
5
  include Octodmin::Action
4
6
  expose :post
5
7
 
6
8
  def call(params)
7
- self.format = :json
9
+ super
8
10
 
9
- @post = Octodmin::Post.find(params[:id])
10
- halt 400, JSON.dump(errors: ["Could not find post"]) unless @post
11
11
  @post.revert
12
12
  end
13
13
  end
@@ -1,13 +1,12 @@
1
+ require_relative "manage"
2
+
1
3
  module Octodmin::Controllers::Posts
2
- class Show
4
+ class Show < Manage
3
5
  include Octodmin::Action
4
6
  expose :post
5
7
 
6
8
  def call(params)
7
- self.format = :json
8
-
9
- @post = Octodmin::Post.find(params[:id])
10
- halt 400, JSON.dump(errors: ["Could not find post"]) unless @post
9
+ super
11
10
  end
12
11
  end
13
12
  end
@@ -0,0 +1,22 @@
1
+ require_relative "manage"
2
+
3
+ module Octodmin::Controllers::Posts
4
+ class Upload < Manage
5
+ include Octodmin::Action
6
+ expose :upload
7
+
8
+ def call(params)
9
+ super
10
+
11
+ site = Octodmin::Site.new
12
+ file = params[:file]
13
+ dir = File.join(site.source, "octodmin", @post.identifier)
14
+ path = File.join(dir, file["filename"])
15
+
16
+ FileUtils.mkdir_p(dir)
17
+ FileUtils.cp(file["tempfile"].path, path)
18
+
19
+ @upload = path.sub(site.source, "")
20
+ end
21
+ end
22
+ end
@@ -9,25 +9,14 @@ module Octodmin::Controllers::Syncs
9
9
  site = Octodmin::Site.new
10
10
  git = Git.open(Octodmin::App.dir)
11
11
 
12
- # Add posts only to commit stage
12
+ # Add files to commit stage
13
13
  stage(site, git)
14
14
 
15
- # Compute staged paths
16
- staged = paths(site, git)
17
-
18
15
  # Pull changes
19
16
  git.pull
20
17
 
21
18
  # Commit and push changes if any
22
- if staged.any?
23
- @message = "Octodmin sync for #{staged.count} file#{"s" if staged.count > 1}"
24
- @message += "\n\n#{staged.join("\n")}"
25
-
26
- git.commit(@message)
27
- git.push
28
- else
29
- @message = "Everything is up-to-date"
30
- end
19
+ commit(site, git)
31
20
  rescue Git::GitExecuteError => e
32
21
  halt 400, JSON.dump(errors: [e.message])
33
22
  ensure
@@ -37,26 +26,38 @@ module Octodmin::Controllers::Syncs
37
26
  private
38
27
 
39
28
  def stage(site, git)
29
+ # Posts
40
30
  deleted = site.status.deleted.keys.map { |path| File.join(Octodmin::App.dir, path) }
41
-
42
31
  site.posts.each do |post|
43
32
  path = File.join(site.source, post.path)
44
33
  git.add(path) unless deleted.include?(path)
45
34
  end
35
+
36
+ # Uploads
37
+ git.add(File.join(site.source, "octodmin"))
46
38
  end
47
39
 
48
40
  def paths(site, git)
49
41
  status = site.reset.status
42
+ keys = status.changed.keys + status.added.keys + status.deleted.keys
50
43
 
51
- paths = (
52
- status.changed.keys +
53
- status.added.keys +
54
- status.deleted.keys
55
- ).map { |path| File.join(Octodmin::App.dir, path) }
44
+ keys.sort.reverse.map do |path|
45
+ File.join(Octodmin::App.dir, path).sub(File.join(site.source, ""), "")
46
+ end
47
+ end
48
+
49
+ def commit(site, git)
50
+ staged = paths(site, git)
56
51
 
57
- site.posts.select do |post|
58
- paths.any? { |path| path.end_with?(post.path) }
59
- end.map(&:path)
52
+ if staged.any?
53
+ @message = "Octodmin sync for #{staged.count} file#{"s" if staged.count > 1}"
54
+ @message += "\n\n#{staged.join("\n")}"
55
+
56
+ git.commit(@message)
57
+ git.push
58
+ else
59
+ @message = "Everything is up-to-date"
60
+ end
60
61
  end
61
62
  end
62
63
  end
@@ -31,7 +31,10 @@ module Octodmin
31
31
 
32
32
  # :nocov:
33
33
  configure :production do
34
- assets << ["public"]
34
+ assets << [
35
+ "public",
36
+ Octodmin::Site.new.source
37
+ ]
35
38
  serve_assets true
36
39
  handle_exceptions false
37
40
  end
@@ -0,0 +1,10 @@
1
+ module Octodmin::Views::Posts
2
+ class Upload
3
+ include Octodmin::View
4
+ format :json
5
+
6
+ def render
7
+ JSON.dump(uploads: [upload])
8
+ end
9
+ end
10
+ end
data/bower.json CHANGED
@@ -7,6 +7,7 @@
7
7
  "bootstrap-sass": "~3.3.2",
8
8
  "bootstrap-markdown": "~2.8.0",
9
9
  "bootstrap.growl": "~2.0.1",
10
+ "marked": "~0.3.3",
10
11
  "spin.js": "~2.0.2",
11
12
  "react": "~0.12.0",
12
13
  "react-loader": "~1.1.0",
@@ -1,3 +1,3 @@
1
1
  module Octodmin
2
- VERSION = "0.2.1"
2
+ VERSION = "0.3.0"
3
3
  end
@@ -408,4 +408,22 @@ describe "posts" do
408
408
  end
409
409
  end
410
410
  end
411
+
412
+ describe "upload" do
413
+ context "valid" do
414
+ before do
415
+ post "/api/posts/2015-01-30-test/upload", {
416
+ file: Rack::Test::UploadedFile.new("spec/fixtures/ear.png")
417
+ }
418
+ end
419
+ after do
420
+ File.delete("sample/octodmin/2015-01-30-test/ear.png")
421
+ end
422
+ subject { parse_json(last_response.body)["posts"] }
423
+
424
+ specify do
425
+ expect(File.exists?("sample/octodmin/2015-01-30-test/ear.png")).to be_truthy
426
+ end
427
+ end
428
+ end
411
429
  end
@@ -62,6 +62,11 @@ end
62
62
  # Delete post
63
63
  delete "/api/posts/2015-01-29-welcome-to-jekyll"
64
64
 
65
+ # Upload file
66
+ post "/api/posts/2015-01-30-test/upload", {
67
+ file: Rack::Test::UploadedFile.new("spec/fixtures/ear.png")
68
+ }
69
+
65
70
  post "/api/syncs"
66
71
  end
67
72
  after do
@@ -69,11 +74,18 @@ end
69
74
  git = Git.open(Octodmin::App.dir)
70
75
  git.checkout("sample/_posts/2015-01-30-test.markdown")
71
76
  git.checkout("sample/_posts/2015-01-29-welcome-to-jekyll.markdown")
77
+ File.delete("sample/octodmin/2015-01-30-test/ear.png")
72
78
  end
73
79
  subject { parse_json(last_response.body)["syncs"] }
74
80
 
75
81
  it "returns syncs" do
76
- expect(subject).to eql(["Octodmin sync for 3 files\n\n_posts/#{date}-yo.markdown\n_posts/2015-01-30-test.markdown\n_posts/2015-01-29-welcome-to-jekyll.markdown"])
82
+ expect(subject).to eql([[
83
+ "Octodmin sync for 4 files\n",
84
+ "octodmin/2015-01-30-test/ear.png",
85
+ "_posts/#{date}-yo.markdown",
86
+ "_posts/2015-01-30-test.markdown",
87
+ "_posts/2015-01-29-welcome-to-jekyll.markdown",
88
+ ].join("\n")])
77
89
  end
78
90
  end
79
91
  end
Binary file
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: octodmin
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dmitry Krasnoukhov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-02-12 00:00:00.000000000 Z
11
+ date: 2015-02-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: octopress
@@ -101,10 +101,12 @@ files:
101
101
  - app/controllers/posts/create.rb
102
102
  - app/controllers/posts/destroy.rb
103
103
  - app/controllers/posts/index.rb
104
+ - app/controllers/posts/manage.rb
104
105
  - app/controllers/posts/restore.rb
105
106
  - app/controllers/posts/revert.rb
106
107
  - app/controllers/posts/show.rb
107
108
  - app/controllers/posts/update.rb
109
+ - app/controllers/posts/upload.rb
108
110
  - app/controllers/site/show.rb
109
111
  - app/controllers/syncs/create.rb
110
112
  - app/controllers/version/show.rb
@@ -185,6 +187,7 @@ files:
185
187
  - app/views/posts/revert.rb
186
188
  - app/views/posts/show.rb
187
189
  - app/views/posts/update.rb
190
+ - app/views/posts/upload.rb
188
191
  - app/views/site/show.rb
189
192
  - app/views/syncs/create.rb
190
193
  - app/views/version/show.rb
@@ -220,6 +223,7 @@ files:
220
223
  - spec/api/site_spec.rb
221
224
  - spec/api/syncs_spec.rb
222
225
  - spec/api/version_spec.rb
226
+ - spec/fixtures/ear.png
223
227
  - spec/frontend/assets_spec.rb
224
228
  - spec/frontend/home_spec.rb
225
229
  - spec/spec_helper.rb
@@ -254,6 +258,7 @@ test_files:
254
258
  - spec/api/site_spec.rb
255
259
  - spec/api/syncs_spec.rb
256
260
  - spec/api/version_spec.rb
261
+ - spec/fixtures/ear.png
257
262
  - spec/frontend/assets_spec.rb
258
263
  - spec/frontend/home_spec.rb
259
264
  - spec/spec_helper.rb