Remove page file dir from frontend. Resolves #1052 #1241 (#1369)

* Remove all references to page_file_dir. Use new method signature for Wiki#page. Refactor helpers.
* Use write_file for uploads
* Refactor /pages route
This commit is contained in:
Dawa Ometto
2019-05-04 01:19:59 +02:00
committed by GitHub
parent e0a2b183ad
commit b40a344c49
9 changed files with 154 additions and 197 deletions
+56 -83
View File
@@ -9,6 +9,7 @@ require 'json'
require 'sprockets'
require 'sprockets-helpers'
require 'sass'
require 'pathname'
require 'gollum'
require 'gollum/assets'
@@ -88,8 +89,10 @@ module Precious
forbid unless @allow_editing || request.request_method == "GET"
Precious::App.set(:mustache, {:templates => settings.wiki_options[:template_dir]}) if settings.wiki_options[:template_dir]
@base_url = url('/', false).chomp('/').force_encoding('utf-8')
@page_dir = settings.wiki_options[:page_file_dir].to_s
# above will detect base_path when it's used with map in a config.ru
settings.wiki_options.merge!({ :base_path => @base_url })
@css = settings.wiki_options[:css]
@@ -112,7 +115,7 @@ module Precious
end
get '/' do
redirect clean_url(::File.join(@base_url, @page_dir, wiki_new.index_page))
redirect clean_url(::File.join(@base_url, wiki_new.index_page))
end
namespace '/gollum' do
@@ -166,8 +169,9 @@ module Precious
get '/edit/*' do
forbid unless @allow_editing
wikip = wiki_page(params[:splat].first)
@name = join_page_name(wikip.name, wikip.ext)
@name = wikip.fullname
@path = wikip.path
@upload_dest = find_upload_dest(wikip.fullpath)
wiki = wikip.wiki
@allow_uploads = wiki.allow_uploads
@@ -194,28 +198,12 @@ module Precious
end
halt 500 unless tempfile.is_a? Tempfile
if wiki.per_page_uploads
# remove base_url and gollum/* subpath if necessary
dir = request.referer.
sub(request.base_url, '').
sub(/.*gollum\/[-\w]+\//, '')
# remove file extension
dir = dir.sub(::File.extname(dir), '')
dir = ::File.join("uploads", dir)
else
# Remove page file dir prefix from upload path if necessary -- committer handles this itself
dir = ::File.join([wiki.page_file_dir, 'uploads'].compact)
end
halt 500 if dir.include?('..')
halt 500 unless Pathname(dir).relative?
dir = wiki.per_page_uploads ? params[:upload_dest] : 'uploads'
ext = ::File.extname(fullname)
format = ext.split('.').last || 'txt'
filename = ::File.basename(fullname, ext)
contents = ::File.read(tempfile)
reponame = "#{filename}.#{format}"
head = wiki.repo.head
reponame = "#{dir}/#{filename}.#{format}"
options = {
:message => "Uploaded file to #{dir}/#{reponame}",
@@ -229,16 +217,11 @@ module Precious
normalize = Gollum::Page.valid_extension?(fullname)
begin
committer = Gollum::Committer.new(wiki, options)
committer.add_to_index(dir, filename, format, contents, {normalize: normalize})
committer.after_commit do |committer, sha|
wiki.clear_cache
committer.update_working_dir(dir, filename, format)
end
committer.commit
wiki.write_file(reponame, contents, options)
redirect to(request.referer)
rescue Gollum::DuplicatePageError => e
halt 409 # Signal conflict
rescue Gollum::DuplicatePageError, Gollum::IllegalDirectoryPath => e
@message = e.message
mustache :error
end
end
@@ -247,7 +230,7 @@ module Precious
wikip = wiki_page(params[:splat].first)
halt 500 if wikip.nil?
wiki = wikip.wiki
page = wiki.paged(join_page_name(wikip.name, wikip.ext), wikip.path, exact = true)
page = wikip.page
rename = params[:rename]
halt 500 if page.nil?
halt 500 if rename.nil? or rename.empty?
@@ -274,7 +257,7 @@ module Precious
committer.commit
wikip = wiki_page(rename)
page = wiki.paged(join_page_name(wikip.name, wikip.ext), wikip.path, exact = true)
page = wikip.page
return if page.nil?
redirect to("/#{page.escaped_url_path}")
end
@@ -284,8 +267,8 @@ module Precious
path = "/#{clean_url(sanitize_empty_params(params[:path]))}"
page_name = CGI.unescape(params[:page])
wiki = wiki_new
page = wiki.paged(page_name, path, exact = true)
page = wiki.page(::File.join(path, page_name))
return if page.nil?
if etag != page.sha
# Signal edit collision and return the page's most recent version
@@ -303,7 +286,6 @@ module Precious
end
post '/delete/*' do
forbid unless @allow_editing
wiki = wiki_new
@@ -313,8 +295,7 @@ module Precious
commit[:message] = "Deleted #{filepath}"
wiki.delete_file(filepath, commit)
end
end
end
get '/create/*' do
forbid unless @allow_editing
@@ -327,20 +308,11 @@ module Precious
@ext = wikip.ext
@path = wikip.path
@allow_uploads = wikip.wiki.allow_uploads
page_dir = settings.wiki_options[:page_file_dir].to_s
unless page_dir.empty?
# --page-file-dir docs
# /docs/Home should be created in /Home
# not /docs/Home because write_page will append /docs
@path = @path.sub(page_dir, '/') if @path.start_with? page_dir
end
@path = clean_path(@path)
@upload_dest = find_upload_dest(wikip.fullpath)
page = wikip.page
if page
page_dir = settings.wiki_options[:page_file_dir].to_s
redirect to("/#{clean_url(::File.join(page_dir, page.escaped_url_path))}")
redirect to("/#{clean_url(page.escaped_url_path)}")
else
unless Gollum::Page.format_for("#{@name}#{@ext}")
@name = "#{@name}#{@ext}"
@@ -359,12 +331,11 @@ module Precious
path.gsub!(/^\//, '')
begin
wiki.write_page(name, format, params[:content], commit_message, path)
wiki.write_page(::File.join(path, name), format, params[:content], commit_message)
page_dir = settings.wiki_options[:page_file_dir].to_s
redirect to("/#{clean_url(::File.join(encodeURIComponent(page_dir), encodeURIComponent(path), encodeURIComponent(wiki.page_file_name(name, format))))}")
rescue Gollum::DuplicatePageError => e
@message = "Duplicate page: #{e.message}"
redirect to("/#{clean_url(::File.join(encodeURIComponent(path), encodeURIComponent(wiki.page_file_name(name, format))))}")
rescue Gollum::DuplicatePageError, Gollum::IllegalDirectoryPath => e
@message = e.message
mustache :error
end
end
@@ -372,9 +343,9 @@ module Precious
post '/revert/*/:sha1/:sha2' do
wikip = wiki_page(params[:splat].first)
@path = wikip.path
@name = join_page_name(wikip.name, wikip.ext)
@name = wiki.fullname
wiki = wikip.wiki
@page = wiki.paged(@name, @path)
@page = wikip.page
sha1 = params[:sha1]
sha2 = params[:sha2]
@@ -448,7 +419,7 @@ module Precious
}x do |path, start_version, end_version|
wikip = wiki_page(path)
@path = wikip.path
@name = join_page_name(wikip.name, wikip.ext)
@name = wikip.fullname
@versions = [start_version, end_version]
wiki = wikip.wiki
@page = wikip.page
@@ -472,12 +443,17 @@ module Precious
/(.+) # capture any path after the "/pages" excluding the leading slash
)? # end the optional non-capturing group
}x do |path|
@path = extract_path(path) if path
wiki_options = settings.wiki_options.merge({ :page_file_dir => @path })
wiki = Gollum::Wiki.new(settings.gollum_path, wiki_options)
@results = wiki.pages
@results += wiki.files
@results = @results.sort_by { |p| p.name.downcase } # Sort Results alphabetically, fixes 922
wiki = wiki_new
@results = wiki.tree_list
if path
@path = Pathname.new(path).cleanpath.to_s
check_path = wiki.page_file_dir ? ::File.join(wiki.page_file_dir, @path, '/') : "#{@path}/"
@results.select! {|result| result.path.start_with?(check_path) }
end
@results.sort_by! {|result| result.name.downcase}
@ref = wiki.ref
mustache :pages
end
@@ -486,8 +462,8 @@ module Precious
get %r{/(.+?)/([0-9a-f]{40})} do
file_path = params[:captures][0]
version = params[:captures][1]
wikip = wiki_page(file_path, file_path, version)
name = join_page_name(wikip.name, wikip.ext)
wikip = wiki_page(file_path, version)
name = wikip.fullname
path = wikip.path
if page = wikip.page
@page = page
@@ -496,7 +472,7 @@ module Precious
@version = version
@bar_side = wikip.wiki.bar_side
mustache :page
elsif file = wikip.wiki.file("#{file_path}", version, true)
elsif file = wikip.wiki.file(file_path, version, true)
show_file(file)
else
halt 404
@@ -511,13 +487,11 @@ module Precious
def show_page_or_file(fullpath)
wiki = wiki_new
name, ext = extract_name(fullpath) || wiki.index_page
path = extract_path(fullpath) || '/'
if page = wiki.paged(join_page_name(name, ext), path, exact = true)
if page = wiki.page(fullpath)
@page = page
@name = name
@name = page.filename_stripped
@content = page.formatted_data
@upload_dest = find_upload_dest(Pathname.new(fullpath).cleanpath.to_s)
# Extensions and layout data
@editable = true
@@ -532,8 +506,8 @@ module Precious
show_file(file)
else
if @allow_editing
page_path = [path, join_page_name(name, ext)].compact.join('/')
redirect to("/gollum/create/#{clean_url(encodeURIComponent(page_path))}")
path = fullpath[-1] == '/' ? "#{fullpath}#{wiki.index_page}" : fullpath # Append default index page if no page name is supplied
redirect to("/gollum/create/#{clean_url(encodeURIComponent(path))}")
else
@message = "The requested page does not exist."
status 404
@@ -561,19 +535,11 @@ module Precious
wiki.update_page(page, name, format, content.to_s, commit)
end
# path is set to name if path is nil.
# if path is 'a/b' and a and b are dirs, then
# path must have a trailing slash 'a/b/' or
# extract_path will trim path to 'a'
def wiki_page(name, path = nil, version = nil, exact = true)
def wiki_page(path, version = nil)
pathname = (Pathname.new('/') + path).cleanpath
wiki = wiki_new
path = name if path.nil?
name, ext = extract_name(name) || wiki.index_page
path = extract_path(path)
path = '/' if exact && path.nil?
OpenStruct.new(:wiki => wiki, :page => wiki.paged(join_page_name(name, ext), path, exact, version),
:name => name, :path => path, :ext => ext)
OpenStruct.new(:wiki => wiki, :page => wiki.page(pathname.to_s, version = version),
:name => pathname.basename.sub_ext('').to_s, :path => pathname.dirname.to_s, :ext => pathname.extname, :fullname => pathname.basename.to_s, :fullpath => pathname.to_s)
end
def wiki_new
@@ -594,5 +560,12 @@ module Precious
commit_message
end
def find_upload_dest(path)
settings.wiki_options[:allow_uploads] ?
(settings.wiki_options[:per_page_uploads] ?
path : 'uploads'
) : ''
end
end
end
-32
View File
@@ -6,42 +6,10 @@ module Precious
EMOJI_PATHNAME = Pathname.new(Gemojione.images_path).freeze
def join_page_name(name, ext)
"#{name}#{ext}"
end
# Extract the path string that Gollum::Wiki expects
def extract_path(file_path)
return nil if file_path.nil?
last_slash = file_path.rindex("/")
if last_slash
file_path[0, last_slash]
end
end
# Extract the 'page' name from the file_path
def extract_name(file_path)
if file_path[-1, 1] == "/"
return nil
end
# File.basename is too eager to please and will return the last
# component of the path even if it ends with a directory separator.
ext = ::File.extname(file_path)
return ::File.basename(file_path, ext), ext
end
def sanitize_empty_params(param)
[nil, ''].include?(param) ? nil : CGI.unescape(param)
end
# Ensure path begins with a single leading slash
def clean_path(path)
if path
(path[0] != '/' ? path.insert(0, '/') : path).gsub(/\/{2,}/, '/')
end
end
# Remove all slashes from the start of string.
# Remove all double slashes
def clean_url url
+1 -1
View File
@@ -28,7 +28,7 @@
{{#no_results}}
<p id="no-results">
There are no pages in <strong>{{ref}}</strong>.
There are no pages in <strong>{{current_path}}</strong> on <strong>{{ref}}</strong>.
</p>
{{/no_results}}
+1 -5
View File
@@ -24,16 +24,12 @@ module Precious
!@path.nil?
end
def page_dir
@page_dir
end
def base_url
@base_url
end
def custom_path
"#{@base_url}#{@page_dir.empty? ? '' : '/'}#{@page_dir}"
"#{@base_url}"
end
def css # custom css
+15 -12
View File
@@ -6,7 +6,11 @@ module Precious
attr_reader :results, :ref, :allow_editing
def title
"All pages in #{@ref}"
"Overview of #{@ref}"
end
def current_path
@path ? @path : '/'
end
def breadcrumb
@@ -23,15 +27,15 @@ module Precious
end
end
breadcrumb.join(" / ")
breadcrumb.join(' / ')
else
"Home"
'Home'
end
end
def delete_file(url)
%Q(<div class="delete-file" data-file-path="#{url}" data-confirm="Are you sure you want to delete #{URI.decode(url)}?"><span><button type="submit" name="delete">Delete</button></span></div>)
def delete_file(path)
%Q(<div class="delete-file" data-file-path="#{path}" data-confirm="Are you sure you want to delete #{path}?"><span><button type="submit" name="delete">Delete</button></span></div>)
end
def files_folders
@@ -41,9 +45,8 @@ module Precious
# 1012: Folders and Pages need to be separated
@results.each do |result|
result_path = result.path
result_path = result_path.sub(/^#{Regexp.escape(@path)}\//, '') unless @path.nil?
result_path = result.url_path
result_path = result_path.sub(/^#{Regexp.escape(@path)}\//, '') unless @path.nil?
if result_path.include?('/')
# result contains a folder
@@ -52,12 +55,12 @@ module Precious
folder_link = %{<li><a href="#{pages_path}/#{folder_path}/" class="folder">#{folder}</a></li>}
folders[folder] = folder_link unless folders.key?(folder)
elsif result_path != ".gitkeep"
elsif result_path != '.gitkeep'
# result is either a valid gollum page or another type of file
klass = (defined? result.format) ? "page" : "file"
klass = (defined? result.format) ? 'page' : 'file'
url = "#{@base_url}/#{result.escaped_url_path}"
file_link = %{<li><a href="#{url}" class="#{klass}">#{result.filename}</a>#{delete_file(result.escaped_url_path) if @allow_editing}</li>}
file_link = %{<li><a href="#{url}" class="#{klass}">#{result.filename}</a>#{delete_file(result.url_path) if @allow_editing}</li>}
files[result.name] = file_link
end
end
@@ -68,7 +71,7 @@ module Precious
result
else
""
''
end
end