tiny_wiki 0.2.0 → 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 +4 -4
- data/exe/tiny_wiki_server +7 -0
- data/lib/tiny_wiki/app.rb +89 -35
- data/lib/tiny_wiki/templates/edit.erb +1 -1
- data/lib/tiny_wiki/templates/list.erb +1 -1
- data/lib/tiny_wiki/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 903269ded1ae9f2bb397a82fc2fbb9ffba908bbfd201c3e24f95663dd2e6f604
|
4
|
+
data.tar.gz: b8a0d910250d1862c1438127e9a3e19c3e0a6dbfeb255ed8486e62754d8539cd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2c7dddd80cad267b123557bde677c44d1e525f8001fb03938c89a03d8d8ee10bfda3f02182f9f29aae3aecdae06587f12b8637a64cf6a03ae129bb05b2c0df60
|
7
|
+
data.tar.gz: e26ccab0193a60426a29af24c1a65c06d587aae683d79f1584c481e448078518d4507e03d99d4d000cd6b6270c83eed29f045097a4f558d28e8f1497a33a2f5b
|
data/exe/tiny_wiki_server
CHANGED
@@ -17,6 +17,10 @@ OptionParser.new do |opts|
|
|
17
17
|
options[:bind] = b
|
18
18
|
end
|
19
19
|
|
20
|
+
opts.on("-d", "--debug", "Enable debug messages (verbose logging)") do |d|
|
21
|
+
options[:debug] = d
|
22
|
+
end
|
23
|
+
|
20
24
|
opts.on("-h", "--help", "Prints this help") do
|
21
25
|
puts opts
|
22
26
|
exit
|
@@ -45,6 +49,9 @@ TinyWiki::App.set :wiki_root, File.expand_path(wiki_directory)
|
|
45
49
|
TinyWiki::App.set :port, options[:port] if options[:port]
|
46
50
|
TinyWiki::App.set :bind, options[:bind] if options[:bind]
|
47
51
|
|
52
|
+
# Set the debug flag in the Sinatra application settings
|
53
|
+
TinyWiki::App.set :debug, options[:debug] if options[:debug]
|
54
|
+
|
48
55
|
puts "Starting TinyWiki server..."
|
49
56
|
puts "Wiki root: #{TinyWiki::App.settings.wiki_root}"
|
50
57
|
puts "Listening on #{TinyWiki::App.settings.bind}:#{TinyWiki::App.settings.port}"
|
data/lib/tiny_wiki/app.rb
CHANGED
@@ -19,16 +19,38 @@ module TinyWiki
|
|
19
19
|
# Enable sessions for flash messages (optional, but good for feedback)
|
20
20
|
enable :sessions
|
21
21
|
|
22
|
+
# Default debug setting
|
23
|
+
set :debug, false
|
24
|
+
|
25
|
+
# Helper for conditional debug logging
|
26
|
+
def debug_log(message)
|
27
|
+
puts "DEBUG: #{message}" if settings.debug
|
28
|
+
end
|
29
|
+
|
22
30
|
# Custom Redcarpet renderer to handle wiki links (e.g., [[Page Name]])
|
23
31
|
class WikiLinkRenderer < Redcarpet::Render::HTML
|
24
32
|
# The postprocess method is called after all other rendering is complete.
|
25
33
|
# We use it to find and replace our custom wiki link syntax.
|
26
34
|
def postprocess(full_document)
|
27
35
|
full_document.gsub(/\[\[(.*?)\]\]/) do
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
36
|
+
raw_page_path = $1.strip # e.g., "Folder/Page Name"
|
37
|
+
|
38
|
+
# Split the path into components
|
39
|
+
path_components = raw_page_path.split('/')
|
40
|
+
|
41
|
+
# Sanitize each component and convert spaces to underscores for the URL
|
42
|
+
# Then URI encode each component
|
43
|
+
url_safe_components = path_components.map do |comp|
|
44
|
+
# Replace spaces with underscores for URL segment
|
45
|
+
sanitized_comp = comp.gsub(' ', '_')
|
46
|
+
# URI encode the individual component
|
47
|
+
URI.encode_www_form_component(sanitized_comp)
|
48
|
+
end
|
49
|
+
|
50
|
+
# Rejoin with '/' to form the URL path
|
51
|
+
url_path = url_safe_components.join('/')
|
52
|
+
|
53
|
+
"<a href=\"/#{url_path}\">#{raw_page_path}</a>"
|
32
54
|
end
|
33
55
|
end
|
34
56
|
end
|
@@ -36,7 +58,7 @@ module TinyWiki
|
|
36
58
|
# Markdown renderer setup
|
37
59
|
# Create a Redcarpet renderer that uses HTML with code highlighting and auto-links.
|
38
60
|
# The `fenced_code_blocks` and `autolink` extensions are common and useful.
|
39
|
-
markdown_renderer = WikiLinkRenderer.new(
|
61
|
+
markdown_renderer = WikiLinkRenderer.new( # Use our custom renderer here
|
40
62
|
filter_html: true,
|
41
63
|
hard_wrap: true,
|
42
64
|
link_attributes: { rel: "nofollow", target: "_blank" },
|
@@ -57,12 +79,15 @@ module TinyWiki
|
|
57
79
|
)
|
58
80
|
|
59
81
|
# Helper method to get the full path to a markdown file
|
60
|
-
# `
|
61
|
-
def wiki_file_path(
|
62
|
-
#
|
63
|
-
#
|
64
|
-
|
65
|
-
|
82
|
+
# `page_path` is expected to be URL-decoded and can contain slashes.
|
83
|
+
def wiki_file_path(page_path)
|
84
|
+
# Normalize path to prevent directory traversal (e.g., /foo/../bar)
|
85
|
+
# Split by '/' and reject empty components, '.' and '..'.
|
86
|
+
# Then re-join to form a safe relative path.
|
87
|
+
safe_components = page_path.split('/').reject { |c| c.empty? || c == '.' || c == '..' }
|
88
|
+
|
89
|
+
# Reconstruct the path. File.join handles OS-specific separators.
|
90
|
+
File.join(settings.wiki_root, "#{safe_components.join('/')}.md")
|
66
91
|
end
|
67
92
|
|
68
93
|
# Helper method to read the content of a wiki page
|
@@ -84,10 +109,14 @@ module TinyWiki
|
|
84
109
|
@@markdown.render(markdown_content)
|
85
110
|
end
|
86
111
|
|
87
|
-
# Helper to get all wiki pages (filenames without extension)
|
112
|
+
# Helper to get all wiki pages (filenames without extension, including paths)
|
88
113
|
def all_wiki_pages
|
89
|
-
|
90
|
-
|
114
|
+
# Find all .md files recursively within the wiki_root
|
115
|
+
Dir.glob(File.join(settings.wiki_root, '**', '*.md')).map do |file_path|
|
116
|
+
# Get the path relative to wiki_root and remove the .md extension
|
117
|
+
# Example: /path/to/wiki_root/Folder/Page.md -> Folder/Page
|
118
|
+
relative_path_with_ext = file_path.sub("#{settings.wiki_root}/", '')
|
119
|
+
relative_path_with_ext.sub(/\.md$/, '')
|
91
120
|
end.sort
|
92
121
|
rescue Errno::ENOENT
|
93
122
|
# If the wiki_root directory doesn't exist yet, return an empty array
|
@@ -101,46 +130,71 @@ module TinyWiki
|
|
101
130
|
redirect to('/Home')
|
102
131
|
end
|
103
132
|
|
133
|
+
# Handle favicon.ico requests directly to avoid treating them as wiki pages
|
134
|
+
get '/favicon.ico' do
|
135
|
+
# You can serve an actual favicon.ico file here if you have one.
|
136
|
+
# For now, we'll just return a 404 to prevent redirection.
|
137
|
+
status 404
|
138
|
+
'' # Return empty body
|
139
|
+
end
|
140
|
+
|
141
|
+
# Handle Chrome DevTools specific requests
|
142
|
+
get '/.well-known/appspecific/com.chrome.devtools.json' do
|
143
|
+
status 404
|
144
|
+
'' # Return empty body
|
145
|
+
end
|
146
|
+
|
104
147
|
# List all wiki pages
|
105
148
|
get '/_list' do
|
106
149
|
@pages = all_wiki_pages
|
107
150
|
erb :list # Render a 'list.erb' template (you'll need to create this)
|
108
151
|
end
|
109
152
|
|
110
|
-
# Display a wiki page
|
111
|
-
get '/:page_name' do
|
112
|
-
@page_name = URI.decode_www_form_component(params[:page_name])
|
113
|
-
@markdown_content = read_page(@page_name)
|
114
|
-
|
115
|
-
if @markdown_content
|
116
|
-
@html_content = markdown_to_html(@markdown_content)
|
117
|
-
erb :show # Render 'show.erb'
|
118
|
-
else
|
119
|
-
# Page not found, redirect to edit page
|
120
|
-
session[:message] = "Page '#{@page_name}' does not exist. Create it!"
|
121
|
-
redirect to("/#{@page_name}/edit")
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
153
|
# Show the edit form for a wiki page
|
126
|
-
|
127
|
-
|
154
|
+
# The splat parameter `*page_path` will match multiple path segments, including slashes.
|
155
|
+
get '/*page_path/edit' do
|
156
|
+
@page_name = URI.decode_www_form_component(params[:page_path])
|
128
157
|
@markdown_content = read_page(@page_name) || "" # Empty string if new page
|
129
|
-
|
158
|
+
debug_log "Rendering edit form for page: #{@page_name}" # DEBUG
|
159
|
+
erb :edit
|
130
160
|
end
|
131
161
|
|
132
162
|
# Save the content of a wiki page
|
133
|
-
|
134
|
-
|
163
|
+
# The splat parameter `*page_path` will match multiple path segments, including slashes.
|
164
|
+
post '/*page_path' do
|
165
|
+
@page_name = URI.decode_www_form_component(params[:page_path])
|
135
166
|
new_content = params[:content]
|
167
|
+
debug_log "POST request to save page: #{@page_name}" # DEBUG
|
168
|
+
debug_log "Content received: #{new_content.inspect}" # DEBUG
|
136
169
|
|
137
170
|
if new_content && !new_content.strip.empty?
|
138
171
|
write_page(@page_name, new_content)
|
139
172
|
session[:message] = "Page '#{@page_name}' saved successfully!"
|
173
|
+
debug_log "Page saved, redirecting to /#{@page_name}" # DEBUG
|
140
174
|
redirect to("/#{@page_name}")
|
141
175
|
else
|
142
176
|
session[:message] = "Page content cannot be empty!"
|
143
|
-
|
177
|
+
debug_log "Empty content, redirecting to /#{@page_name}/edit" # DEBUG
|
178
|
+
redirect to("/#{@page_name}/edit")
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
# Display a wiki page
|
183
|
+
# The splat parameter `*page_path` will match multiple path segments, including slashes.
|
184
|
+
get '/*page_path' do
|
185
|
+
@page_name = URI.decode_www_form_component(params[:page_path])
|
186
|
+
@markdown_content = read_page(@page_name)
|
187
|
+
|
188
|
+
if @markdown_content
|
189
|
+
@html_content = markdown_to_html(@markdown_content)
|
190
|
+
erb :show
|
191
|
+
else
|
192
|
+
# Page not found, redirect to edit page
|
193
|
+
session[:message] = "Page '#{@page_name}' does not exist. Create it!"
|
194
|
+
# Ensure the page_name doesn't already end with '/edit' before redirecting
|
195
|
+
clean_page_name_for_redirect = @page_name.sub(/\/edit$/, '')
|
196
|
+
debug_log "Redirecting to edit for non-existent page: /#{clean_page_name_for_redirect}/edit" # DEBUG
|
197
|
+
redirect to("/#{clean_page_name_for_redirect}/edit")
|
144
198
|
end
|
145
199
|
end
|
146
200
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
<h1>Editing <%= @page_name.empty? ? 'New Page' : @page_name %></h1>
|
2
2
|
|
3
|
-
<form action="
|
3
|
+
<form action="<%= to(@page_name) %>" method="post">
|
4
4
|
<textarea name="content"><%= @markdown_content %></textarea><br>
|
5
5
|
<input type="submit" value="Save Page">
|
6
6
|
</form>
|
data/lib/tiny_wiki/version.rb
CHANGED