|
1 |
| -require "sinatra/base" |
2 |
| -require "haml" |
3 |
| -require "grit" |
4 |
| -require "rdiscount" |
| 1 | +#!/usr/bin/env ruby |
| 2 | + |
| 3 | +require 'sinatra' |
| 4 | +require 'haml' |
| 5 | +require 'grit' |
| 6 | +require 'rdiscount' |
5 | 7 |
|
6 | 8 | module GitWiki
|
7 | 9 | class << self
|
8 | 10 | attr_accessor :homepage, :extension, :repository
|
9 | 11 | end
|
| 12 | + @repository = Grit::Repo.new(ARGV[0] || File.expand_path('~/wiki')) |
| 13 | + @extension = ARGV[1] || '.markdown' |
| 14 | + @homepage = ARGV[2] || 'Home' |
| 15 | +end |
| 16 | + |
| 17 | +class PageNotFound < Sinatra::NotFound |
| 18 | + attr_reader :name |
| 19 | + |
| 20 | + def initialize(name) |
| 21 | + @name = name |
| 22 | + end |
| 23 | +end |
| 24 | + |
| 25 | +class Page |
| 26 | + def self.find_all |
| 27 | + return [] if repository.tree.contents.empty? |
| 28 | + GitWiki.repository.tree.contents.collect { |blob| new(blob) } |
| 29 | + end |
| 30 | + |
| 31 | + def self.find(name) |
| 32 | + page_blob = find_blob(name) |
| 33 | + raise PageNotFound.new(name) unless page_blob |
| 34 | + new(page_blob) |
| 35 | + end |
| 36 | + |
| 37 | + def self.find_or_create(name) |
| 38 | + find(name) |
| 39 | + rescue PageNotFound |
| 40 | + new(create_blob_for(name)) |
| 41 | + end |
| 42 | + |
| 43 | + def self.css_class_for(name) |
| 44 | + find(name) |
| 45 | + "exists" |
| 46 | + rescue PageNotFound |
| 47 | + "unknown" |
| 48 | + end |
| 49 | + |
| 50 | + def self.repository |
| 51 | + GitWiki.repository || raise |
| 52 | + end |
| 53 | + |
| 54 | + def self.extension |
| 55 | + GitWiki.extension || raise |
| 56 | + end |
| 57 | + |
| 58 | + def self.find_blob(page_name) |
| 59 | + repository.tree/(page_name + extension) |
| 60 | + end |
| 61 | + private_class_method :find_blob |
| 62 | + |
| 63 | + def self.create_blob_for(page_name) |
| 64 | + Grit::Blob.create(repository, { |
| 65 | + :name => page_name + extension, |
| 66 | + :data => "" |
| 67 | + }) |
| 68 | + end |
| 69 | + private_class_method :create_blob_for |
| 70 | + |
| 71 | + def initialize(blob) |
| 72 | + @blob = blob |
| 73 | + end |
| 74 | + |
| 75 | + def to_html |
| 76 | + RDiscount.new(wiki_link(content)).to_html |
| 77 | + end |
| 78 | + |
| 79 | + def to_s |
| 80 | + name |
| 81 | + end |
| 82 | + |
| 83 | + def new? |
| 84 | + @blob.id.nil? |
| 85 | + end |
| 86 | + |
| 87 | + def name |
| 88 | + @blob.name.gsub(/#{File.extname(@blob.name)}$/, '') |
| 89 | + end |
| 90 | + |
| 91 | + def content |
| 92 | + @blob.data |
| 93 | + end |
| 94 | + |
| 95 | + def update_content(new_content) |
| 96 | + return if new_content == content |
| 97 | + File.open(file_name, "w") { |f| f << new_content } |
| 98 | + add_to_index_and_commit! |
| 99 | + end |
| 100 | + |
| 101 | + private |
| 102 | + def add_to_index_and_commit! |
| 103 | + Dir.chdir(self.class.repository.working_dir) { |
| 104 | + self.class.repository.add(@blob.name) |
| 105 | + } |
| 106 | + self.class.repository.commit_index(commit_message) |
| 107 | + end |
| 108 | + |
| 109 | + def file_name |
| 110 | + File.join(self.class.repository.working_dir, name + self.class.extension) |
| 111 | + end |
| 112 | + |
| 113 | + def commit_message |
| 114 | + new? ? "Created #{name}" : "Updated #{name}" |
| 115 | + end |
10 | 116 |
|
11 |
| - def self.new(repository, extension, homepage) |
12 |
| - self.homepage = homepage |
13 |
| - self.extension = extension |
14 |
| - self.repository = Grit::Repo.new(repository) |
15 |
| - |
16 |
| - App |
17 |
| - end |
18 |
| - |
19 |
| - class PageNotFound < Sinatra::NotFound |
20 |
| - attr_reader :name |
21 |
| - |
22 |
| - def initialize(name) |
23 |
| - @name = name |
24 |
| - end |
25 |
| - end |
26 |
| - |
27 |
| - class Page |
28 |
| - def self.find_all |
29 |
| - return [] if repository.tree.contents.empty? |
30 |
| - repository.tree.contents.collect { |blob| new(blob) } |
31 |
| - end |
32 |
| - |
33 |
| - def self.find(name) |
34 |
| - page_blob = find_blob(name) |
35 |
| - raise PageNotFound.new(name) unless page_blob |
36 |
| - new(page_blob) |
37 |
| - end |
38 |
| - |
39 |
| - def self.find_or_create(name) |
40 |
| - find(name) |
41 |
| - rescue PageNotFound |
42 |
| - new(create_blob_for(name)) |
43 |
| - end |
44 |
| - |
45 |
| - def self.css_class_for(name) |
46 |
| - find(name) |
47 |
| - "exists" |
48 |
| - rescue PageNotFound |
49 |
| - "unknown" |
50 |
| - end |
51 |
| - |
52 |
| - def self.repository |
53 |
| - GitWiki.repository || raise |
54 |
| - end |
55 |
| - |
56 |
| - def self.extension |
57 |
| - GitWiki.extension || raise |
58 |
| - end |
59 |
| - |
60 |
| - def self.find_blob(page_name) |
61 |
| - repository.tree/(page_name + extension) |
62 |
| - end |
63 |
| - private_class_method :find_blob |
64 |
| - |
65 |
| - def self.create_blob_for(page_name) |
66 |
| - Grit::Blob.create(repository, { |
67 |
| - :name => page_name + extension, |
68 |
| - :data => "" |
69 |
| - }) |
70 |
| - end |
71 |
| - private_class_method :create_blob_for |
72 |
| - |
73 |
| - def initialize(blob) |
74 |
| - @blob = blob |
75 |
| - end |
76 |
| - |
77 |
| - def to_html |
78 |
| - RDiscount.new(wiki_link(content)).to_html |
79 |
| - end |
80 |
| - |
81 |
| - def to_s |
82 |
| - name |
83 |
| - end |
84 |
| - |
85 |
| - def new? |
86 |
| - @blob.id.nil? |
87 |
| - end |
88 |
| - |
89 |
| - def name |
90 |
| - @blob.name.gsub(/#{File.extname(@blob.name)}$/, '') |
91 |
| - end |
92 |
| - |
93 |
| - def content |
94 |
| - @blob.data |
95 |
| - end |
96 |
| - |
97 |
| - def update_content(new_content) |
98 |
| - return if new_content == content |
99 |
| - File.open(file_name, "w") { |f| f << new_content } |
100 |
| - add_to_index_and_commit! |
101 |
| - end |
102 |
| - |
103 |
| - private |
104 |
| - def add_to_index_and_commit! |
105 |
| - Dir.chdir(self.class.repository.working_dir) { |
106 |
| - self.class.repository.add(@blob.name) |
107 |
| - } |
108 |
| - self.class.repository.commit_index(commit_message) |
109 |
| - end |
110 |
| - |
111 |
| - def file_name |
112 |
| - File.join(self.class.repository.working_dir, name + self.class.extension) |
113 |
| - end |
114 |
| - |
115 |
| - def commit_message |
116 |
| - new? ? "Created #{name}" : "Updated #{name}" |
117 |
| - end |
118 |
| - |
119 |
| - def wiki_link(str) |
120 |
| - str.gsub(/([A-Z][a-z]+[A-Z][A-Za-z0-9]+)/) { |page| |
121 |
| - %Q{<a class="#{self.class.css_class_for(page)}"} + |
122 |
| - %Q{href="/#{page}">#{page}</a>} |
123 |
| - } |
124 |
| - end |
125 |
| - end |
126 |
| - |
127 |
| - class App < Sinatra::Base |
128 |
| - set :app_file, __FILE__ |
129 |
| - set :haml, { :format => :html5, |
130 |
| - :attr_wrapper => '"' } |
131 |
| - enable :inline_templates |
132 |
| - |
133 |
| - error PageNotFound do |
134 |
| - page = request.env["sinatra.error"].name |
135 |
| - redirect "/#{page}/edit" |
136 |
| - end |
137 |
| - |
138 |
| - before do |
139 |
| - content_type "text/html", :charset => "utf-8" |
140 |
| - end |
141 |
| - |
142 |
| - get "/" do |
143 |
| - redirect "/" + GitWiki.homepage |
144 |
| - end |
145 |
| - |
146 |
| - get "/pages" do |
147 |
| - @pages = Page.find_all |
148 |
| - haml :list |
149 |
| - end |
150 |
| - |
151 |
| - get "/:page/edit" do |
152 |
| - @page = Page.find_or_create(params[:page]) |
153 |
| - haml :edit |
154 |
| - end |
155 |
| - |
156 |
| - get "/:page" do |
157 |
| - @page = Page.find(params[:page]) |
158 |
| - haml :show |
159 |
| - end |
160 |
| - |
161 |
| - post "/:page" do |
162 |
| - @page = Page.find_or_create(params[:page]) |
163 |
| - @page.update_content(params[:body]) |
164 |
| - redirect "/#{@page}" |
165 |
| - end |
166 |
| - |
167 |
| - private |
168 |
| - def title(title=nil) |
169 |
| - @title = title.to_s unless title.nil? |
170 |
| - @title |
171 |
| - end |
172 |
| - |
173 |
| - def list_item(page) |
174 |
| - %Q{<a class="page_name" href="/#{page}">#{page.name}</a>} |
175 |
| - end |
| 117 | + def wiki_link(str) |
| 118 | + str.gsub(/([A-Z][a-z]+[A-Z][A-Za-z0-9]+)/) { |page| |
| 119 | + %Q{<a class="#{self.class.css_class_for(page)}"} + |
| 120 | + %Q{href="/#{page}">#{page}</a>} |
| 121 | + } |
176 | 122 | end
|
177 | 123 | end
|
178 | 124 |
|
| 125 | +set :haml, :format => :html5, :attr_wrapper => '"' |
| 126 | +enable :inline_templates |
| 127 | + |
| 128 | +error PageNotFound do |
| 129 | + page = request.env["sinatra.error"].name |
| 130 | + redirect "/#{page}/edit" |
| 131 | +end |
| 132 | + |
| 133 | +before do |
| 134 | + content_type "text/html", :charset => "utf-8" |
| 135 | +end |
| 136 | + |
| 137 | +helpers do |
| 138 | + def title(title=nil) |
| 139 | + @title = title.to_s unless title.nil? |
| 140 | + @title |
| 141 | + end |
| 142 | + |
| 143 | + def list_item(page) |
| 144 | + %Q{<a class="page_name" href="/#{page}">#{page.name}</a>} |
| 145 | + end |
| 146 | +end |
| 147 | + |
| 148 | +get "/" do |
| 149 | + redirect "/" + GitWiki.homepage |
| 150 | +end |
| 151 | + |
| 152 | +get "/pages" do |
| 153 | + @pages = Page.find_all |
| 154 | + haml :list |
| 155 | +end |
| 156 | + |
| 157 | +get "/:page/edit" do |
| 158 | + @page = Page.find_or_create(params[:page]) |
| 159 | + haml :edit |
| 160 | +end |
| 161 | + |
| 162 | +get "/:page" do |
| 163 | + @page = Page.find(params[:page]) |
| 164 | + haml :show |
| 165 | +end |
| 166 | + |
| 167 | +post "/:page" do |
| 168 | + @page = Page.find_or_create(params[:page]) |
| 169 | + @page.update_content(params[:body]) |
| 170 | + redirect "/#{@page}" |
| 171 | +end |
| 172 | + |
179 | 173 | __END__
|
180 | 174 | @@ layout
|
181 | 175 | !!!
|
|
0 commit comments