pagoda-jekyll 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/Gemfile +4 -0
- data/Gemfile.lock +119 -0
- data/LICENSE +22 -0
- data/Rakefile +15 -0
- data/config.rb +8 -0
- data/config.ru +11 -0
- data/lib/pagoda/app.rb +145 -0
- data/lib/pagoda/config.rb +24 -0
- data/lib/pagoda/helper.rb +55 -0
- data/lib/pagoda/jekyll-mod.rb +36 -0
- data/lib/pagoda/public/css/pagoda.css +547 -0
- data/lib/pagoda/public/images/fullscreen.png +0 -0
- data/lib/pagoda/public/js/editor.js +41 -0
- data/lib/pagoda/public/js/jquery.autosize.js +7 -0
- data/lib/pagoda/public/js/jquery.hotkeys.js +100 -0
- data/lib/pagoda/public/js/jquery.js +6 -0
- data/lib/pagoda/public/js/screenfull.js +128 -0
- data/lib/pagoda/templates/edit.mustache +37 -0
- data/lib/pagoda/templates/editor_area.mustache +14 -0
- data/lib/pagoda/templates/home.mustache +47 -0
- data/lib/pagoda/templates/layout.mustache +25 -0
- data/lib/pagoda/templates/new_post.mustache +36 -0
- data/lib/pagoda/templates/settings.mustache +13 -0
- data/lib/pagoda/views/edit.rb +11 -0
- data/lib/pagoda/views/home.rb +10 -0
- data/lib/pagoda/views/layout.rb +21 -0
- data/lib/pagoda/views/new_post.rb +12 -0
- data/lib/pagoda/views/settings.rb +10 -0
- data/pagoda.gemspec +79 -0
- data/unicorn.rb +1 -0
- metadata +33 -4
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
ZjFkMjlkZmJiNzg2NDc3NTMxMWMzNmU1MDdlMGMzOTlkYTE5YjBmZg==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
MTUxMzRlYjc1YzE1NmU2NjJjOTYwNWQ2MjE0Y2UwZjdjNjBiOGEwMg==
|
7
7
|
!binary "U0hBNTEy":
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
YjU4MTVmNGE3NzU2NDk4YWFhYWUyMGY4OTkxOTVmNzExNTQzNGYzYTY1YWQ1
|
10
|
+
NWJiNmU3YjE5NmYxZjlkZTdiNWMzODNhY2ZmNDdiMDAzMWIzZDY0M2U0MDE4
|
11
|
+
MjNkMDY2ZjRjYjUxZTc0MzExMWIyOGRmMmU4Mjc0N2Y3OGI0OGE=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
MmE2MDBkOWQyOGY0MGFlMDliYTAxMDllM2MzYzlhZmIxOGYyNGE5MzM4Y2E3
|
14
|
+
ZTVjMWQ3M2YzMGJjZTRlMDc0YmRmNWQ1OTExYzU1NzU3NDNjYTQ3YmFjZDQ3
|
15
|
+
ZjA5MjM3ODAzYzU1Y2EzNjAyNmUyNTc2YjdkMzEzOWZiNjc1ODQ=
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,119 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
pagoda (0.0.1)
|
5
|
+
grit
|
6
|
+
jekyll
|
7
|
+
json
|
8
|
+
sinatra
|
9
|
+
sinatra-mustache
|
10
|
+
stringex
|
11
|
+
|
12
|
+
GEM
|
13
|
+
remote: https://rubygems.org/
|
14
|
+
specs:
|
15
|
+
activesupport (3.2.13)
|
16
|
+
i18n (= 0.6.1)
|
17
|
+
multi_json (~> 1.0)
|
18
|
+
ansi (1.4.3)
|
19
|
+
backports (3.1.1)
|
20
|
+
bourne (1.4.0)
|
21
|
+
mocha (~> 0.13.2)
|
22
|
+
builder (3.2.0)
|
23
|
+
chunky_png (1.2.7)
|
24
|
+
classifier (1.3.3)
|
25
|
+
fast-stemmer (>= 1.0.0)
|
26
|
+
compass (0.12.2)
|
27
|
+
chunky_png (~> 1.2)
|
28
|
+
fssm (>= 0.2.7)
|
29
|
+
sass (~> 3.1)
|
30
|
+
diff-lcs (1.2.2)
|
31
|
+
directory_watcher (1.5.1)
|
32
|
+
eventmachine (1.0.3)
|
33
|
+
fast-stemmer (1.0.2)
|
34
|
+
fssm (0.2.10)
|
35
|
+
grit (2.5.0)
|
36
|
+
diff-lcs (~> 1.1)
|
37
|
+
mime-types (~> 1.15)
|
38
|
+
posix-spawn (~> 0.3.6)
|
39
|
+
hashie (2.0.3)
|
40
|
+
i18n (0.6.1)
|
41
|
+
jekyll (0.12.1)
|
42
|
+
classifier (~> 1.3)
|
43
|
+
directory_watcher (~> 1.1)
|
44
|
+
kramdown (~> 0.14)
|
45
|
+
liquid (~> 2.3)
|
46
|
+
maruku (~> 0.5)
|
47
|
+
pygments.rb (~> 0.3.2)
|
48
|
+
json (1.7.7)
|
49
|
+
kramdown (0.14.2)
|
50
|
+
liquid (2.5.0)
|
51
|
+
maruku (0.6.1)
|
52
|
+
syntax (>= 1.0.0)
|
53
|
+
metaclass (0.0.1)
|
54
|
+
mime-types (1.22)
|
55
|
+
minitest (4.7.0)
|
56
|
+
minitest-reporters (0.14.16)
|
57
|
+
ansi
|
58
|
+
builder
|
59
|
+
minitest (>= 2.12, < 5.0)
|
60
|
+
powerbar
|
61
|
+
mocha (0.13.3)
|
62
|
+
metaclass (~> 0.0.1)
|
63
|
+
multi_json (1.7.2)
|
64
|
+
mustache (0.99.4)
|
65
|
+
posix-spawn (0.3.6)
|
66
|
+
powerbar (1.0.11)
|
67
|
+
ansi (~> 1.4.0)
|
68
|
+
hashie (>= 1.1.0)
|
69
|
+
pygments.rb (0.3.7)
|
70
|
+
posix-spawn (~> 0.3.6)
|
71
|
+
yajl-ruby (~> 1.1.0)
|
72
|
+
rack (1.5.2)
|
73
|
+
rack-protection (1.5.0)
|
74
|
+
rack
|
75
|
+
rack-test (0.6.2)
|
76
|
+
rack (>= 1.0)
|
77
|
+
rake (10.0.3)
|
78
|
+
sass (3.2.7)
|
79
|
+
shoulda (3.4.0)
|
80
|
+
shoulda-context (~> 1.0, >= 1.0.1)
|
81
|
+
shoulda-matchers (~> 1.0, >= 1.4.1)
|
82
|
+
shoulda-context (1.1.0)
|
83
|
+
shoulda-matchers (1.5.6)
|
84
|
+
activesupport (>= 3.0.0)
|
85
|
+
bourne (~> 1.3)
|
86
|
+
sinatra (1.3.6)
|
87
|
+
rack (~> 1.4)
|
88
|
+
rack-protection (~> 1.3)
|
89
|
+
tilt (~> 1.3, >= 1.3.3)
|
90
|
+
sinatra-contrib (1.3.2)
|
91
|
+
backports (>= 2.0)
|
92
|
+
eventmachine
|
93
|
+
rack-protection
|
94
|
+
rack-test
|
95
|
+
sinatra (~> 1.3.0)
|
96
|
+
tilt (~> 1.3)
|
97
|
+
sinatra-mustache (0.1.0)
|
98
|
+
mustache (~> 0.99)
|
99
|
+
sinatra (~> 1)
|
100
|
+
tilt (~> 1.3, ~> 1.2)
|
101
|
+
sinatra-reloader (1.0)
|
102
|
+
sinatra-contrib
|
103
|
+
stringex (1.5.1)
|
104
|
+
syntax (1.0.0)
|
105
|
+
tilt (1.3.6)
|
106
|
+
yajl-ruby (1.1.0)
|
107
|
+
|
108
|
+
PLATFORMS
|
109
|
+
ruby
|
110
|
+
|
111
|
+
DEPENDENCIES
|
112
|
+
compass
|
113
|
+
fssm
|
114
|
+
minitest-reporters
|
115
|
+
pagoda!
|
116
|
+
rack-test
|
117
|
+
rake (~> 10.0.3)
|
118
|
+
shoulda
|
119
|
+
sinatra-reloader
|
data/LICENSE
CHANGED
@@ -0,0 +1,22 @@
|
|
1
|
+
(The MIT License)
|
2
|
+
|
3
|
+
Copyright (c) 2007-2009 Tom Preston-Werner
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
'Software'), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
19
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
20
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
21
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
22
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
require 'rake'
|
4
|
+
Bundler.setup
|
5
|
+
|
6
|
+
Dir["tasks/*.rake"].sort.each { |ext| load ext }
|
7
|
+
|
8
|
+
require 'rake/testtask'
|
9
|
+
Rake::TestTask.new(:test) do |test|
|
10
|
+
test.libs << 'lib' << 'test'
|
11
|
+
test.pattern = 'test/**/test_*.rb'
|
12
|
+
test.verbose = true
|
13
|
+
end
|
14
|
+
|
15
|
+
task :default => :test
|
data/config.rb
ADDED
data/config.ru
ADDED
data/lib/pagoda/app.rb
ADDED
@@ -0,0 +1,145 @@
|
|
1
|
+
# ~*~ encoding: utf-8 ~*~
|
2
|
+
require 'cgi'
|
3
|
+
require 'sinatra'
|
4
|
+
require 'mustache/sinatra'
|
5
|
+
require "sinatra/reloader"
|
6
|
+
require 'jekyll'
|
7
|
+
require 'json'
|
8
|
+
require 'grit'
|
9
|
+
require 'stringex'
|
10
|
+
|
11
|
+
require 'pagoda/views/layout'
|
12
|
+
require 'pagoda/helper'
|
13
|
+
require 'pagoda/config'
|
14
|
+
require 'pagoda/jekyll-mod'
|
15
|
+
|
16
|
+
# Sinatra based frontend
|
17
|
+
module Shwedagon
|
18
|
+
class App < Sinatra::Base
|
19
|
+
|
20
|
+
# Create a new post from scratch. Return filename
|
21
|
+
# This would not commit the file.
|
22
|
+
def create_new_post(params)
|
23
|
+
post_title = params['post']['title']
|
24
|
+
post_date = (Time.now).strftime("%Y-%m-%d")
|
25
|
+
yaml_data = { 'title' => post_title,
|
26
|
+
'layout' => 'post',
|
27
|
+
'published' => false }
|
28
|
+
|
29
|
+
content = yaml_data.to_yaml + "---\n" + params[:post][:content]
|
30
|
+
post_file = (post_date + " " + post_title).to_url + '.md'
|
31
|
+
file = File.join(jekyll_site.source, *%w[_posts], post_file)
|
32
|
+
File.open(file, 'w') { |file| file.write(content)}
|
33
|
+
post_file
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
# Merge existing yaml with post params
|
38
|
+
def merge_config(yaml, params)
|
39
|
+
yaml['published'] = !(params[:post].has_key? 'draft')
|
40
|
+
yaml['title'] = params[:post][:title]
|
41
|
+
|
42
|
+
yaml
|
43
|
+
end
|
44
|
+
|
45
|
+
def write_post_contents(content, yaml, post_file)
|
46
|
+
writeable_content = yaml.to_yaml + "---\n" + content
|
47
|
+
file_path = post_path(post_file)
|
48
|
+
|
49
|
+
if File.exists? file_path
|
50
|
+
File.open(file_path, 'w') { |file| file.write(writeable_content)}
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# Update exiting post.
|
55
|
+
def update_post(params)
|
56
|
+
post_file = params[:post][:name]
|
57
|
+
post = jekyll_post(post_file)
|
58
|
+
yaml_config = merge_config(post.data, params)
|
59
|
+
write_post_contents(params[:post][:content], yaml_config, post_file)
|
60
|
+
|
61
|
+
post_file
|
62
|
+
end
|
63
|
+
|
64
|
+
# Index of drafts and published posts
|
65
|
+
get '/' do
|
66
|
+
@drafts = posts_template_data(jekyll_site.read_drafts)
|
67
|
+
@published = posts_template_data(jekyll_site.posts)
|
68
|
+
|
69
|
+
mustache :home
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
#Delete any post. Ideally should be post. For convenience, it is get.
|
74
|
+
get '/delete/*' do
|
75
|
+
post_file = params[:splat].first
|
76
|
+
full_path = post_path(post_file)
|
77
|
+
|
78
|
+
repo.remove([full_path])
|
79
|
+
data = repo.commit_index "Deleted #{post_file}"
|
80
|
+
|
81
|
+
redirect "/"
|
82
|
+
end
|
83
|
+
|
84
|
+
# Edit any post
|
85
|
+
get '/edit/*' do
|
86
|
+
post_file = params[:splat].first
|
87
|
+
|
88
|
+
if not post_exists?(post_file)
|
89
|
+
halt(404)
|
90
|
+
end
|
91
|
+
|
92
|
+
post = jekyll_post(post_file)
|
93
|
+
@title = post.data['title']
|
94
|
+
@content = post.content
|
95
|
+
@name = post.name
|
96
|
+
if post.data['published'] == false
|
97
|
+
@draft = true
|
98
|
+
end
|
99
|
+
|
100
|
+
|
101
|
+
mustache :edit
|
102
|
+
end
|
103
|
+
|
104
|
+
get '/new' do
|
105
|
+
@ptitle = params['ptitle']
|
106
|
+
mustache :new_post
|
107
|
+
end
|
108
|
+
|
109
|
+
get '/settings' do
|
110
|
+
mustache :settings
|
111
|
+
end
|
112
|
+
|
113
|
+
get '/settings/pull' do
|
114
|
+
|
115
|
+
data = repo.git.pull({}, "origin", "master")
|
116
|
+
return data + " done"
|
117
|
+
end
|
118
|
+
|
119
|
+
get '/settings/push' do
|
120
|
+
data = repo.git.push
|
121
|
+
return data + " done"
|
122
|
+
end
|
123
|
+
|
124
|
+
post '/save-post' do
|
125
|
+
config = Jekyll.configuration({'source' => settings.blog})
|
126
|
+
site = Jekyll::Site.new(config)
|
127
|
+
|
128
|
+
if params[:method] == 'put'
|
129
|
+
filename = create_new_post(params)
|
130
|
+
log_message = "Created #{filename}"
|
131
|
+
else
|
132
|
+
filename = update_post(params)
|
133
|
+
log_message = "Changed #{filename}"
|
134
|
+
end
|
135
|
+
|
136
|
+
# Stage the file for commit
|
137
|
+
repo.add File.join(jekyll_site.source, *%w[_posts], filename)
|
138
|
+
|
139
|
+
data = repo.commit_index log_message
|
140
|
+
|
141
|
+
redirect '/edit/' + filename
|
142
|
+
end
|
143
|
+
|
144
|
+
end
|
145
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# Configuration for the pagoda app
|
2
|
+
module Shwedagon
|
3
|
+
class App < Sinatra::Base
|
4
|
+
|
5
|
+
register Mustache::Sinatra
|
6
|
+
register Sinatra::Reloader
|
7
|
+
|
8
|
+
|
9
|
+
dir = File.dirname(File.expand_path(__FILE__))
|
10
|
+
set :public_folder, "#{dir}/public"
|
11
|
+
set :static, true
|
12
|
+
|
13
|
+
set :mustache, {
|
14
|
+
# Tell mustache where the Views constant lives
|
15
|
+
:namespace => Shwedagon,
|
16
|
+
|
17
|
+
# Mustache templates live here
|
18
|
+
:templates => "#{dir}/templates",
|
19
|
+
|
20
|
+
# Tell mustache where the views are
|
21
|
+
:views => "#{dir}/views"
|
22
|
+
}
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# Helper functions for pagoda app
|
2
|
+
module Shwedagon
|
3
|
+
class App < Sinatra::Base
|
4
|
+
|
5
|
+
# Jekyll site instance
|
6
|
+
def jekyll_site
|
7
|
+
if not @site
|
8
|
+
config = Jekyll.configuration({'source' => settings.blog})
|
9
|
+
@site = Jekyll::Site.new(config)
|
10
|
+
@site.read
|
11
|
+
end
|
12
|
+
|
13
|
+
@site
|
14
|
+
end
|
15
|
+
|
16
|
+
# Grit repo instance
|
17
|
+
def repo
|
18
|
+
@repo ||= Grit::Repo.new(settings.blog)
|
19
|
+
Dir.chdir(settings.blog)
|
20
|
+
|
21
|
+
@repo
|
22
|
+
end
|
23
|
+
|
24
|
+
# Shortcut for checking whether the post exists
|
25
|
+
def post_exists?(post_file)
|
26
|
+
File.exists? post_path(post_file)
|
27
|
+
end
|
28
|
+
|
29
|
+
# Expanded post path of the post file
|
30
|
+
def post_path(post_file)
|
31
|
+
File.join(jekyll_site.source, *%w[_posts], post_file)
|
32
|
+
end
|
33
|
+
|
34
|
+
# Jekyll instance of post file
|
35
|
+
def jekyll_post(post_file)
|
36
|
+
Jekyll::Post.new(jekyll_site, jekyll_site.source, '', post_file)
|
37
|
+
end
|
38
|
+
|
39
|
+
# Gives out a sorted list of post template data
|
40
|
+
# for a post or draft
|
41
|
+
def posts_template_data(post_items)
|
42
|
+
template_data = post_items.map do |post|
|
43
|
+
{
|
44
|
+
:title => post.data['title'],
|
45
|
+
:filename => post.name,
|
46
|
+
:date => post.date
|
47
|
+
}
|
48
|
+
end
|
49
|
+
|
50
|
+
template_data.sort! { |x,y| y[:date] <=> x[:date] }
|
51
|
+
|
52
|
+
template_data
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Jekyll
|
2
|
+
class Site
|
3
|
+
|
4
|
+
# Read all the files in <source>/<dir>/_posts and create a new Post
|
5
|
+
# object only for draft items
|
6
|
+
#
|
7
|
+
# dir - The String relative path of the directory to read.
|
8
|
+
#
|
9
|
+
# Returns nothing.
|
10
|
+
def read_drafts(dir = '')
|
11
|
+
if self.respond_to? 'get_entries'
|
12
|
+
entries = get_entries(dir, '_posts')
|
13
|
+
else
|
14
|
+
base = File.join(self.source, dir, '_posts')
|
15
|
+
return unless File.exists?(base)
|
16
|
+
entries = Dir.chdir(base) { filter_entries(Dir['**/*']) }
|
17
|
+
end
|
18
|
+
|
19
|
+
drafts = []
|
20
|
+
|
21
|
+
# first pass processes, but does not yet render post content
|
22
|
+
entries.each do |f|
|
23
|
+
if Post.valid?(f)
|
24
|
+
post = Post.new(self, self.source, dir, f)
|
25
|
+
|
26
|
+
if (not post.published )
|
27
|
+
drafts << post
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
drafts
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|