sr / git-wiki

A quick & dirty git-powered Sinatra wiki

This URL has Read+Write access

commit  ea533a233e2c973f538c416bd28205c84624be1b
tree    399f26d02e0ad065656906d699313740f888fb79
parent  ce3a6ff8516088bbf37254603a525ec7aca4ce6d
git-wiki / git-wiki.rb
cd4545f4 » Alex Payne 2008-02-19 provide feedback amount mis... 1 #!/usr/bin/env ruby
a40f8d3d » Simon Rozet 2008-08-26 require grit 2 $:.unshift *Dir[File.dirname(__FILE__) + '/vendor/**/lib'].to_a
11f29a57 » Simon Rozet 2008-07-21 no need to warn for submodu... 3 %w(sinatra
a40f8d3d » Simon Rozet 2008-08-26 require grit 4 grit
11f29a57 » Simon Rozet 2008-07-21 no need to warn for submodu... 5 rubygems
6 haml
7 sass
2a23bc0a » Simon Rozet 2008-08-26 stop using rubypants 8 bluecloth).each { |dependency| require dependency }
3bdddd51 » Simon Rozet 2008-01-29 Initial import 9
e34a1f77 » Simon Rozet 2008-08-26 try to use thin 10 begin
11 require 'thin'
12 rescue LoadError
13 puts '# May I suggest you to use Thin?'
14 end
15
8e732dcc » Simon Rozet 2008-08-24 decamelize page title and t... 16 class String
17 def to_html
2a23bc0a » Simon Rozet 2008-08-26 stop using rubypants 18 BlueCloth.new(self).to_html.linkify
8e732dcc » Simon Rozet 2008-08-24 decamelize page title and t... 19 end
20
21 def linkify
22 self.gsub(/([A-Z][a-z]+[A-Z][A-Za-z0-9]+)/) do |page|
ea533a23 » Simon Rozet 2008-08-28 little refactoring: page ta... 23 %Q{<a class="#{Page.new(page).to_css_class}" href="/#{page}">#{page.titleize}</a>}
8e732dcc » Simon Rozet 2008-08-24 decamelize page title and t... 24 end
25 end
26
27 def titleize
28 self.gsub(/([A-Z]+)([A-Z][a-z])/,'\1 \2').gsub(/([a-z\d])([A-Z])/,'\1 \2')
29 end
44e73c3e » Simon Rozet 2008-08-26 cosmetics 30
31 def without_ext
32 self.sub(File.extname(self), '')
33 end
8e732dcc » Simon Rozet 2008-08-24 decamelize page title and t... 34 end
35
ea533a23 » Simon Rozet 2008-08-28 little refactoring: page ta... 36 class PageNotFound < Sinatra::NotFound
37 attr_reader :name
38
39 def initialize(name)
40 @name = name
41 end
42 end
43
3bdddd51 » Simon Rozet 2008-01-29 Initial import 44 class Page
91e11a63 » Simon Rozet 2008-03-08 $store is now Page.store 45 class << self
46 attr_accessor :repo
47
44e73c3e » Simon Rozet 2008-08-26 cosmetics 48 def find_all
ea533a23 » Simon Rozet 2008-08-28 little refactoring: page ta... 49 return [] if repo.tree.contents.empty?
50 repo.tree.contents.collect { |blob| new(blob) }
44e73c3e » Simon Rozet 2008-08-26 cosmetics 51 end
ea533a23 » Simon Rozet 2008-08-28 little refactoring: page ta... 52
53 def find(name)
54 page_blob = find_blob(name)
55 raise PageNotFound.new(name) unless page_blob
56 new(page_blob)
57 end
58
59 def find_or_create(name)
60 find(name)
61 rescue PageNotFound
62 new(create_blob_for(name))
63 end
64
65 private
66 def find_blob(page_name)
67 repo.tree/(page_name + PageExtension)
68 end
69
70 def create_blob_for(page_name)
71 Grit::Blob.create(repo, :name => page_name + PageExtension, :data => '')
72 end
c6d5d08a » Simon Rozet 2008-03-08 Move page listing's logic i... 73 end
74
ea533a23 » Simon Rozet 2008-08-28 little refactoring: page ta... 75 def initialize(blob)
76 @blob = blob
77 end
3bdddd51 » Simon Rozet 2008-01-29 Initial import 78
ea533a23 » Simon Rozet 2008-08-28 little refactoring: page ta... 79 def new?
80 body.nil?
3bdddd51 » Simon Rozet 2008-01-29 Initial import 81 end
82
ea533a23 » Simon Rozet 2008-08-28 little refactoring: page ta... 83 def name
84 @blob.name.without_ext
3bdddd51 » Simon Rozet 2008-01-29 Initial import 85 end
86
ea533a23 » Simon Rozet 2008-08-28 little refactoring: page ta... 87 def body
88 @blob.data
3bdddd51 » Simon Rozet 2008-01-29 Initial import 89 end
90
ea533a23 » Simon Rozet 2008-08-28 little refactoring: page ta... 91 def update_content(new_content)
92 return if new_content == content
93 File.open(file_name, 'w') { |f| f << new_content }
44e73c3e » Simon Rozet 2008-08-26 cosmetics 94 add_to_index_and_commit!
3bdddd51 » Simon Rozet 2008-01-29 Initial import 95 end
96
ea533a23 » Simon Rozet 2008-08-28 little refactoring: page ta... 97 def to_html
98 body.linkify.to_html
68eeb527 » Simon Rozet 2008-01-31 I can has list of pages? 99 end
100
101 def to_s
44e73c3e » Simon Rozet 2008-08-26 cosmetics 102 name
3bdddd51 » Simon Rozet 2008-01-29 Initial import 103 end
44e73c3e » Simon Rozet 2008-08-26 cosmetics 104
ea533a23 » Simon Rozet 2008-08-28 little refactoring: page ta... 105 def to_css_class
106 new? ? 'unknown' : 'exists'
107 end
44e73c3e » Simon Rozet 2008-08-26 cosmetics 108
ea533a23 » Simon Rozet 2008-08-28 little refactoring: page ta... 109 private
44e73c3e » Simon Rozet 2008-08-26 cosmetics 110 def add_to_index_and_commit!
ea533a23 » Simon Rozet 2008-08-28 little refactoring: page ta... 111 Dir.chdir(GitRepository) { Page.repo.add(@blob.name) }
44e73c3e » Simon Rozet 2008-08-26 cosmetics 112 Page.repo.commit_index(commit_message)
113 end
114
115 def file_name
116 File.join(GitRepository, name + PageExtension)
117 end
118
119 def commit_message
ea533a23 » Simon Rozet 2008-08-28 little refactoring: page ta... 120 new? ? "Edited #{name}" : "Created #{name}"
44e73c3e » Simon Rozet 2008-08-26 cosmetics 121 end
3bdddd51 » Simon Rozet 2008-01-29 Initial import 122 end
123
5b5675c7 » Simon Rozet 2008-03-28 output html4 with proper do... 124 use_in_file_templates!
125
e8ace3b0 » Simon Rozet 2008-03-28 take of advantage of edge s... 126 configure do
a8f960aa » Simon Rozet 2008-07-21 make the rakefile a little ... 127 GitRepository = ENV['GIT_WIKI_REPO'] || File.join(ENV['HOME'], 'wiki')
f9fb79a4 » Simon Rozet 2008-08-08 configurable file extension 128 PageExtension = '.markdown'
735d262b » Simon Rozet 2008-06-06 CamelCase constants 129 Homepage = 'Home'
c0b58955 » Simon Rozet 2008-08-26 use double-quote to wrap ht... 130 set_option :haml, :format => :html4,
131 :attr_wrapper => '"'
e8ace3b0 » Simon Rozet 2008-03-28 take of advantage of edge s... 132
889a63c8 » Simon Rozet 2008-08-26 rescue correctly (bad bad r... 133 begin
134 Page.repo = Grit::Repo.new(GitRepository)
135 rescue Grit::InvalidGitRepositoryError, Grit::NoSuchPathError
735d262b » Simon Rozet 2008-06-06 CamelCase constants 136 abort "#{GitRepository}: Not a git repository. Install your wiki with `rake bootstrap`"
e8ace3b0 » Simon Rozet 2008-03-28 take of advantage of edge s... 137 end
138 end
139
ea533a23 » Simon Rozet 2008-08-28 little refactoring: page ta... 140 error PageNotFound do
141 page = request.env['sinatra.error'].name
142 redirect "/e/#{page}"
143 end
144
16928c6a » Simon Rozet 2008-03-27 Take advantage of Sinatra's... 145 helpers do
146 def title(title=nil)
8e732dcc » Simon Rozet 2008-08-24 decamelize page title and t... 147 @title = title.to_s unless title.nil?
16928c6a » Simon Rozet 2008-03-27 Take advantage of Sinatra's... 148 @title
149 end
60dfcabc » Simon Rozet 2008-03-28 Page#to_s now return page's... 150
151 def list_item(page)
c0b58955 » Simon Rozet 2008-08-26 use double-quote to wrap ht... 152 '<a class="page_name" href="/%s">%s</a>' % [page, page.name.titleize]
60dfcabc » Simon Rozet 2008-03-28 Page#to_s now return page's... 153 end
16928c6a » Simon Rozet 2008-03-27 Take advantage of Sinatra's... 154 end
155
58912852 » Simon Rozet 2008-07-21 cosmetic 156 before { content_type 'text/html', :charset => 'utf-8' }
4a2e99ae » Simon Rozet 2008-03-27 Set proper Content-Type hea... 157
735d262b » Simon Rozet 2008-06-06 CamelCase constants 158 get('/') { redirect '/' + Homepage }
4a2e99ae » Simon Rozet 2008-03-27 Set proper Content-Type hea... 159
f9fb79a4 » Simon Rozet 2008-08-08 configurable file extension 160 get '/_stylesheet.css' do
ca42b9c3 » Simon Rozet 2008-04-20 Make use of Sinatra HEAD la... 161 content_type 'text/css', :charset => 'utf-8'
162 sass :stylesheet
4a2e99ae » Simon Rozet 2008-03-27 Set proper Content-Type hea... 163 end
3bdddd51 » Simon Rozet 2008-01-29 Initial import 164
68eeb527 » Simon Rozet 2008-01-31 I can has list of pages? 165 get '/_list' do
c6d5d08a » Simon Rozet 2008-03-08 Move page listing's logic i... 166 @pages = Page.find_all
16928c6a » Simon Rozet 2008-03-27 Take advantage of Sinatra's... 167 haml :list
68eeb527 » Simon Rozet 2008-01-31 I can has list of pages? 168 end
169
3bdddd51 » Simon Rozet 2008-01-29 Initial import 170 get '/:page' do
ea533a23 » Simon Rozet 2008-08-28 little refactoring: page ta... 171 @page = Page.find(params[:page])
172 haml :show
3bdddd51 » Simon Rozet 2008-01-29 Initial import 173 end
174
d47f5f25 » Simon Rozet 2008-03-27 Basic edit in place support 175 get '/:page.txt' do
ea533a23 » Simon Rozet 2008-08-28 little refactoring: page ta... 176 @page = Page.find(params[:page])
ca42b9c3 » Simon Rozet 2008-04-20 Make use of Sinatra HEAD la... 177 content_type 'text/plain', :charset => 'utf-8'
ea533a23 » Simon Rozet 2008-08-28 little refactoring: page ta... 178 @page.content
d47f5f25 » Simon Rozet 2008-03-27 Basic edit in place support 179 end
180
3bdddd51 » Simon Rozet 2008-01-29 Initial import 181 get '/e/:page' do
ea533a23 » Simon Rozet 2008-08-28 little refactoring: page ta... 182 @page = Page.find_or_create(params[:page])
16928c6a » Simon Rozet 2008-03-27 Take advantage of Sinatra's... 183 haml :edit
3bdddd51 » Simon Rozet 2008-01-29 Initial import 184 end
185
186 post '/e/:page' do
ea533a23 » Simon Rozet 2008-08-28 little refactoring: page ta... 187 @page = Page.find_or_create(params[:page])
188 @page.update_content(params[:body])
189 redirect "/#{@page}"
3bdddd51 » Simon Rozet 2008-01-29 Initial import 190 end
191
16928c6a » Simon Rozet 2008-03-27 Take advantage of Sinatra's... 192 __END__
5108abaf » Simon Rozet 2008-05-04 update sinatra 193 @@ layout
5b5675c7 » Simon Rozet 2008-03-28 output html4 with proper do... 194 !!! strict
3bdddd51 » Simon Rozet 2008-01-29 Initial import 195 %html
196 %head
16928c6a » Simon Rozet 2008-03-27 Take advantage of Sinatra's... 197 %title= title
198 %link{:rel => 'stylesheet', :href => '/_stylesheet.css', :type => 'text/css'}
4a043b7d » Simon Rozet 2008-08-24 dry javascript libs inclusion 199 - Dir[Sinatra.application.options.public + '/*.js'].reverse.each do |lib|
200 %script{:src => "/#{File.basename(lib)}", :type => 'text/javascript'}
38c0188d » Simon Rozet 2008-03-27 Various UI tweaks 201 :javascript
202 $(document).ready(function() {
735d262b » Simon Rozet 2008-06-06 CamelCase constants 203 $.hotkeys.add('Ctrl+h', function() { document.location = '/#{Homepage}' })
b9bc2fe9 » Simon Rozet 2008-03-28 Bind ctrl+h to homepage and... 204 $.hotkeys.add('Ctrl+l', function() { document.location = '/_list' })
8e732dcc » Simon Rozet 2008-08-24 decamelize page title and t... 205
206 /* title-case-ification */
207 document.title = document.title.toTitleCase();
208 $('h1:first').text($('h1:first').text().toTitleCase());
209 $('a').each(function(i) {
210 var e = $(this)
211 e.text(e.text().toTitleCase());
212 })
38c0188d » Simon Rozet 2008-03-27 Various UI tweaks 213 })
3bdddd51 » Simon Rozet 2008-01-29 Initial import 214 %body
16928c6a » Simon Rozet 2008-03-27 Take advantage of Sinatra's... 215 #content= yield
3bdddd51 » Simon Rozet 2008-01-29 Initial import 216
5108abaf » Simon Rozet 2008-05-04 update sinatra 217 @@ show
8e732dcc » Simon Rozet 2008-08-24 decamelize page title and t... 218 - title @page.name.titleize
d47f5f25 » Simon Rozet 2008-03-27 Basic edit in place support 219 :javascript
220 $(document).ready(function() {
221 $.editable.addInputType('autogrow', {
222 element : function(settings, original) {
223 var textarea = $('<textarea>');
224 if (settings.rows) {
225 textarea.attr('rows', settings.rows);
226 } else {
227 textarea.height(settings.height);
228 }
229 if (settings.cols) {
230 textarea.attr('cols', settings.cols);
231 } else {
232 textarea.width(settings.width);
233 }
234 $(this).append(textarea);
235 return(textarea);
236 },
237 plugin : function(settings, original) {
238 $('textarea', this).autogrow(settings.autogrow);
239 }
240 });
241
60dfcabc » Simon Rozet 2008-03-28 Page#to_s now return page's... 242 $('#page_content').editable('/e/#{@page}', {
243 loadurl: '/#{@page}.txt',
e03a40e8 » Simon Rozet 2008-03-28 fix save button in eip form 244 submit: '<button class="submit" type="submit">Save as the newest version</button>',
cc3f201f » Simon Rozet 2008-03-28 fix cancel button in eip form 245 cancel: '<a class="cancel" href="" style="margin-left: 5px;">cancel</a>',
38c0188d » Simon Rozet 2008-03-27 Various UI tweaks 246 event: 'dblclick',
d47f5f25 » Simon Rozet 2008-03-27 Basic edit in place support 247 type: 'autogrow',
6ebfaa3d » Simon Rozet 2008-03-28 fix autogrow on textarea 248 cols: 84,
249 rows: 20,
d47f5f25 » Simon Rozet 2008-03-27 Basic edit in place support 250 name: 'body',
251 onblur: 'ignore',
60dfcabc » Simon Rozet 2008-03-28 Page#to_s now return page's... 252 tooltip: ' ',
38c0188d » Simon Rozet 2008-03-27 Various UI tweaks 253 indicator: 'Saving...',
254 loadtext: '',
d47f5f25 » Simon Rozet 2008-03-27 Basic edit in place support 255 cssclass: 'edit_form',
256 })
257 })
16928c6a » Simon Rozet 2008-03-27 Take advantage of Sinatra's... 258 %h1= title
c266faa8 » Simon Rozet 2008-05-13 fix wrong indentation in <pre> Comment 259 #page_content
ea533a23 » Simon Rozet 2008-08-28 little refactoring: page ta... 260 ~"#{@page.to_html}"
3bdddd51 » Simon Rozet 2008-01-29 Initial import 261
5108abaf » Simon Rozet 2008-05-04 update sinatra 262 @@ edit
8e732dcc » Simon Rozet 2008-08-24 decamelize page title and t... 263 - title "Editing #{@page.name.titleize}"
16928c6a » Simon Rozet 2008-03-27 Take advantage of Sinatra's... 264 %h1= title
c47205a1 » Simon Rozet 2008-03-28 various typo fix 265 %form{:method => 'POST', :action => "/e/#{@page}"}
d47f5f25 » Simon Rozet 2008-03-27 Basic edit in place support 266 %p
ea533a23 » Simon Rozet 2008-08-28 little refactoring: page ta... 267 %textarea{:name => 'body', :rows => 20, :cols => 80}= @page.content
d47f5f25 » Simon Rozet 2008-03-27 Basic edit in place support 268 %p
38c0188d » Simon Rozet 2008-03-27 Various UI tweaks 269 %input.submit{:type => :submit, :value => 'Save as the newest version'}
bdd34406 » Simon Rozet 2008-03-28 Cleaner page listing and va... 270 or
c47205a1 » Simon Rozet 2008-03-28 various typo fix 271 %a.cancel{:href=>"/#{@page}"} cancel
16928c6a » Simon Rozet 2008-03-27 Take advantage of Sinatra's... 272
5108abaf » Simon Rozet 2008-05-04 update sinatra 273 @@ list
16928c6a » Simon Rozet 2008-03-27 Take advantage of Sinatra's... 274 - title "Listing pages"
275 %h1 All pages
276 - if @pages.empty?
88d664e0 » Bryan T. Richardson 2008-08-20 fixed haml problem with lis... 277 %p No pages found.
16928c6a » Simon Rozet 2008-03-27 Take advantage of Sinatra's... 278 - else
bdd34406 » Simon Rozet 2008-03-28 Cleaner page listing and va... 279 %ul#pages_list
f88d9eb3 » Simon Rozet 2008-08-26 layout, js & css simplifica... 280 - @pages.each_with_index do |page, index|
281 - if (index % 2) == 0
282 %li.odd= list_item(page)
283 - else
284 %li.even= list_item(page)
16928c6a » Simon Rozet 2008-03-27 Take advantage of Sinatra's... 285
5108abaf » Simon Rozet 2008-05-04 update sinatra 286 @@ stylesheet
1dfbc578 » Simon Rozet 2008-02-26 Convert plain ol' CSS to Sa... 287 body
288 :font
38c0188d » Simon Rozet 2008-03-27 Various UI tweaks 289 family: "Lucida Grande", Verdana, Arial, Bitstream Vera Sans, Helvetica, sans-serif
1dfbc578 » Simon Rozet 2008-02-26 Convert plain ol' CSS to Sa... 290 size: 14px
291 color: black
292 line-height: 160%
293 background-color: white
38c0188d » Simon Rozet 2008-03-27 Various UI tweaks 294 margin: 0
295 padding: 0
296 #content
297 padding: 2em
1dfbc578 » Simon Rozet 2008-02-26 Convert plain ol' CSS to Sa... 298 a
38c0188d » Simon Rozet 2008-03-27 Various UI tweaks 299 padding: 2px
300 color: blue
bdd34406 » Simon Rozet 2008-03-28 Cleaner page listing and va... 301 &.exists
302 &:hover
303 background-color: blue
304 text-decoration: none
305 color: white
306 &.unknown
307 color: gray
308 &:hover
309 background-color: gray
310 color: white
311 text-decoration: none
f88d9eb3 » Simon Rozet 2008-08-26 layout, js & css simplifica... 312 &.cancel
313 color: red
314 &:hover
315 text-decoration: none
316 background-color: red
317 color: white
38c0188d » Simon Rozet 2008-03-27 Various UI tweaks 318 textarea
319 font-family: courrier
320 font-size: 14px
321 line-height: 18px
f88d9eb3 » Simon Rozet 2008-08-26 layout, js & css simplifica... 322 padding: 5px
323 button.submit
38c0188d » Simon Rozet 2008-03-27 Various UI tweaks 324 font-weight: bold
bdd34406 » Simon Rozet 2008-03-28 Cleaner page listing and va... 325 ul#pages_list
326 list-style-type: none
327 margin: 0
328 padding: 0
329 li
330 padding: 5px
331 &.odd
332 background-color: #D3D3D3