app/controllers/wiki.rb in Pimki-1.3.092 vs app/controllers/wiki.rb in Pimki-1.4.092
- old
+ new
@@ -1,8 +1,10 @@
require "cgi"
require "redcloth_for_tex"
+RenderedTodo = Struct.new( :text, :context, :due_date )
+
class WikiController < ActionControllerServlet
EXPORT_DIRECTORY = WikiService.storage_path unless const_defined?("EXPORT_DIRECTORY")
def index
if web_address
@@ -110,21 +112,26 @@
parse_category
set_menu_pages
@pages_by_name = @pages_in_category.by_name
@page_names_that_are_wanted = @pages_in_category.wanted_pages
@pages_that_are_orphaned = @pages_in_category.orphaned_pages
- case @req.query['Action']
- when 'Delete' # Handle page deletion
- wiki.delete_page(web_address, @req.query['sel_page_name'])
- redirect_action "list/"
-
- when 'Create' # Handle page creation
- redirect_show @req.query['newpage']
- when 'Rename' # Handle page rename
- wiki.rename_page(web_address, @req.query['sel_page_name'], @req.query['newpage'])
- redirect_action "list/"
+ if @req.query['Action']
+ redirect_action 'list/' if web.check_pass_on_edit and not authenticate
+
+ case @req.query['Action']
+ when 'Delete' # Handle page deletion
+ wiki.delete_page(web_address, @req.query['sel_page_name'])
+ redirect_action "list/"
+
+ when 'Create' # Handle page creation
+ redirect_show @req.query['newpage']
+
+ when 'Rename' # Handle page rename
+ wiki.rename_page(web_address, @req.query['sel_page_name'], @req.query['newpage'])
+ redirect_action "list/"
+ end
end
end
def export_html
@@ -158,13 +165,20 @@
export_web_to_tex(file_path) unless FileTest.exists?(file_path)
send_export(file_name, file_path)
end
+ def edit_web #{{{
+ parse_category
+ set_mm_options
+ end #}}}
+
def update_web
redirect_show("HomePage") unless wiki.authenticate(@params["system_password"])
+ set_mm_options
+
wiki.update_web(
web.address, @params["address"], @params["name"],
@params["markup"].intern,
@params["color"], @params["additional_style"],
@params["safe_mode"] ? true : false,
@@ -172,11 +186,14 @@
@params["published"] ? true : false,
@params["brackets_only"] ? true : false,
@params["count_pages"] ? true : false,
@params['mind_map_size'],
@params['symbols_map'],
- @params['links_map']
+ @params['links_map'],
+ @params['enable_dclick_edit'],
+ @params['check_pass_on_edit'] == 'each_edit',
+ @prog, @graph_type, @missing, @show_authors, @show_leaves, @selected_categories
)
redirect_show("HomePage", @params["address"])
end
@@ -187,43 +204,99 @@
else
redirect_show "HomePage"
end
end
+ FAR_FUTURE = Date.new(4000,1,1).freeze
+ TODO_RE = %r{<todo-tag context='(.*?)' due_date='(.*?)'><span class="todo"><strong>TODO(?:.*)?:</strong> (.*?)</span></todo-tag>}
+
def todo #{{{
parse_category
set_menu_pages
- @pages_by_name = @pages_in_category.by_name
- @todo_items = Hash.new { Array.new }
- @bliki_todo_items = Hash.new { Array.new }
- @pages_by_name.each do |page|
- if page.content =~ Todo.pattern
+
+ @context = @params['context']
+ @sort_order = @params['sort_order']
+
+ clear_render_cache # hack to make sure we don't have old-style rendered todos.
+ @todo_items = analyse_rendered_todo_items @pages_in_category.by_name
+ @bliki_todo_items = analyse_rendered_todo_items web.bliki.values
+
+ @context_links = @todo_items.clone.update(@bliki_todo_items).map { |page, items|
+ # 'items' contain the full 'todo' info
+ items.map { |item| item.context }
+ }.flatten.compact.uniq.reject { |c| c.nil? || c.empty? }.map { |context|
+ @context == context ?
+ "[<span class='selected'>#{context}</span>]" :
+ "<a href='?context=#{context}#{"&sort_order=#{@sort_order}" if @sort_order}'>#{context}</a>"
+ }
+
+ @todo_items = sort_and_filter_todo_items @todo_items, @sort_order, @context
+ @bliki_todo_items = sort_and_filter_todo_items @bliki_todo_items, @sort_order, @context
+
+ end #}}}
+
+ def analyse_rendered_todo_items pages
+ items = Hash.new { Array.new }
+ pages.each do |page|
+ if page.has_todos?
# Page has todo items. Get the rendered version (marked-up and with links):
+ # I specifically don't use the todo chunkss because I want the fully marked-up
+ # text of the item.
content = page.revisions.last.display_content
- @todo_items[page] = content.scan /<span class="todo"><strong>TODO:<\/strong> (.*?)<\/span>/
+ items[page] = content.scan(TODO_RE).map { |match|
+ RenderedTodo.new match[2], (match[0].empty? ? [] : match[0].split(',') ), (Date.parse(match[1]) rescue FAR_FUTURE)
+ }
end
end
- @todo_items = @todo_items.sort_by { |page, items| page.name }
- web.bliki.each do |pname, entry|
- if entry.content =~ Todo.pattern
- # Entry has todo items. Get the rendered version (marked-up and with links):
- content = entry.revisions.last.display_content
- @bliki_todo_items[entry] = content.scan /<span class="todo"><strong>TODO:<\/strong> (.*?)<\/span>/
- end
+ items
+ end
+
+ def sort_and_filter_todo_items items, sort_order, context
+ case sort_order
+ when 'due_date'
+ result = items.map { |page, todos|
+ # sort the to items themselves
+ [page, todos.sort_by { |i| i.due_date } ]
+ }.sort_by { |page, todos|
+ # sort the pages by the one with the most urgent todo
+ todos.map{ |i| i.due_date }.min
+ }
+
+ else # default = sort by page name
+ result = items.sort_by { |page, items| page.name }
+
end
- @bliki_todo_items = @bliki_todo_items.sort_by { |entry, items| entry.name }
- end #}}}
+
+ if context
+ # filter the items to those that are in context
+ result = result.map { |page, items|
+ [ page, items.select { |item| item.context.include? context } ]
+ }.select { |page, items| not items.empty? }
+ end
+ result
+ end
+
+ def get_todo_display_style due_date
+ # default is the muted 'darkred', to prevent to many bright red
+ # items on one page: (See also chunks/todo.rb)
+ (due_date <=> Date.today) > -1 ? "todoFuture" : "todo"
+ end
+
+ def clear_render_cache do_redirect=false
+ web.refresh_revisions
+ redirect_show 'HomePage' if do_redirect
+ end
def set_menu_pages #{{{
parse_category
@all_pages = web.select { true }
@menu_pages = case web.menu_type
when 'all' then @all_pages.by_name
when 'recent' then @all_pages.by_last_visited
when 'viewed' then @all_pages.by_most_viewed
when 'revised' then @all_pages.by_revision
- when 'user' then @menu_content = web.rendered_menu; nil
+ when 'user' then @menu_content = web.menu_content.revisions.last.display_content; nil
when 'category' then web.select { |page| page.in_category?(web.menu_category) }
when 'linkers'
web.select { |page|
page.wiki_words.size > 0
}.sort_by { |page| page.name }
@@ -248,39 +321,54 @@
end
@color = web.color
@authors = web.authors
end #}}}
-require 'pp'
def mind #{{{
parse_category
set_menu_pages
+ set_mm_options
- @prog = @req.query['draw_type'] || 'neato'
- @graph_type = @req.query['graph_type'] || 'normal'
- missing = @pages_in_category.wanted_pages if @req.query['missing']
- show_authors = !@req.query.empty? && @req.query['show_authors'] == 'on'
- show_leaves = @req.query.empty? || @req.query['show_leaves'] == 'on'
-
- # TODO: fix handling of multiple-select for whole application
- @selected_categories = @req.body.split('&').map { |pair|
- pair.split('=') }.select { |k,v|
- k == 'selected_categs' }.map { |k,v| v } if @req.body
- @selected_categories ||= []
- @selected_categories = [] if @selected_categories.include? 'all'
-
@pngFile = @mapFile = nil
case @graph_type
- when 'normal' then @pngFile, @mapFile = web.create_mind_map(@prog, missing,
- show_authors, show_leaves, @selected_categories)
- when 'author' then @pngFile, @mapFile = web.create_author_graph(@prog,
- @selected_categories)
- when 'category' then @pngFile, @mapFile = web.create_category_graph(@prog,
- show_authors, @selected_categories)
+ when 'normal'
+ @pngFile, @mapFile = web.create_mind_map(@prog, @missing,
+ @show_authors, @show_leaves, @selected_categories)
+
+ when 'author'
+ @pngFile, @mapFile = web.create_author_graph(@prog, @selected_categories)
+
+ when 'category'
+ @pngFile, @mapFile = web.create_category_graph(@prog,
+ @show_authors, @selected_categories)
end
end #}}}
+ def set_mm_options #{{{
+ if @req.query.empty?
+ @prog = web.mm_prog
+ @graph_type = web.mm_graph_type
+ @missing = @pages_in_category.wanted_pages if web.mm_show_missing
+ @show_authors = web.mm_show_authors
+ @show_leaves = web.mm_show_leaves
+ @selected_categories = web.mm_selected_categories
+ else
+ @prog = @req.query['draw_type'] || 'neato'
+ @graph_type = @req.query['graph_type'] || 'normal'
+ @missing = @pages_in_category.wanted_pages if @req.query['missing']
+ @show_authors = @req.query['show_authors'] == 'on'
+ @show_leaves = @req.query.empty? || @req.query['show_leaves'] == 'on'
+
+ # TODO: fix handling of multiple-select for whole application
+ @selected_categories = @req.body.split('&').map { |pair|
+ pair.split('=') }.select { |k,v|
+ k == 'selected_categs' }.map { |k,v| v } if @req.body
+ @selected_categories ||= []
+ @selected_categories = [] if @selected_categories.include? 'all'
+ end
+ end #}}}
+
def edit_menu #{{{
@menu_type = web.menu_type
@menu_content = web.menu_content
@list_limit = web.menu_limit
@list_limit += 1 if @list_limit >= -1
@@ -291,21 +379,22 @@
unless @req.query['action'] == 'Cancel Update'
type = @req.query['type']
content = @req.query['content']
category = @req.query['category']
+ author = @req.query['author']
limit = @req.query['limit'].to_i rescue nil
limit = 20 unless limit
limit -= 1 if limit >= 0
# need to go through the WikiService to persist the command:
- wiki.save_menu_pref web_address, type, limit, content, category
+ wiki.save_menu_pref(web_address, type, limit, content, category, Author.new(author, remote_ip))
end
+ # redirect to the most recently viewed page, or the home page.
if web_address
- # redirect to the most recently viewed page, or the home page.
pname = begin
web.select{ true }.by_last_visited.first.name
rescue
"HomePage"
end
@@ -372,10 +461,11 @@
convert_tex_to_pdf(file_path + ".tex")
send_export(file_name + ".pdf", file_path + ".pdf")
end
def new
+ redirect_show("HomePage") if web.check_pass_on_edit and not authenticate
@page_name, @author = page_name, default_author
end
def edit
@page = wiki.read_page(web_address, page_name)
@@ -394,14 +484,19 @@
@page.unlock
redirect_show
end
def save
+ if web.check_pass_on_edit and not authenticate
+ wiki.read_page(web_address, page_name).unlock if web.pages[page_name]
+ redirect_show("HomePage")
+ end
+
if web.pages[page_name]
page = wiki.revise_page(
web_address, page_name, @params["content"], Time.now,
- Author.new(@params["author"], remote_ip)
+ Author.new(@params["author"], remote_ip), @params['edit_type']
)
page.unlock
else
page = wiki.write_page(
@@ -418,23 +513,28 @@
@page = wiki.read_page(web_address, page_name)
@revision = @page.revisions[@params["rev"].to_i]
end
def rollback
+ redirect_show("HomePage") if web.check_pass_on_edit and not authenticate
+
@page = wiki.read_page(web_address, page_name)
- wiki.rollback_page(web_address, page_name, @params["rev"].to_i, Time.now, remote_ip)
- redirect_show
+ @revision = @page.revisions[@params["rev"].to_i]
end
# Bliki ----------------------------------------------------------------------
def bliki_delete
+ redirect_bliki if web.check_pass_on_edit and not authenticate
+
wiki.delete_bliki_entry(web_address, page_name)
redirect_bliki
end
def bliki_edit
+ redirect_bliki if web.check_pass_on_edit and not authenticate
+
@page = wiki.read_bliki_entry(web_address, page_name)
if !@page.locked?(Time.now) || @params["break_lock"]
@page.lock(Time.now, default_author)
@author = default_author
@@ -449,10 +549,12 @@
@page.unlock if @page
redirect_bliki
end
def bliki_save
+ redirect_bliki if web.check_pass_on_edit and not authenticate
+
pname = page_name || @params["pagename"]
if web.bliki[pname]
page = wiki.revise_bliki_entry(web_address, pname, @params["content"], Time.now, @params["author"])
page.unlock
else
@@ -462,15 +564,19 @@
write_cookie("author", @params["author"])
redirect_bliki
end
def bliki_revision
+ parse_category
+ set_menu_pages
@page = wiki.read_bliki_entry(web_address, page_name || @params['pagename'])
@revision = @page.revisions[@params["rev"].to_i] || @page.revisions.last
end
def rollback_bliki
+ redirect_bliki if web.check_pass_on_edit and not authenticate
+
@page = wiki.read_bliki_entry(web_address, page_name)
wiki.rollback_bliki_entry(web_address, page_name, @params["rev"].to_i, Time.now)
redirect_bliki
end
@@ -533,11 +639,12 @@
def page_name
CGI.unescape(request_path[2]) if request_path[2]
end
def authorized?(web_address)
- (web && web.password.nil?) ||
+ web.nil? ||
+ web.password.nil? ||
(read_cookie(web_address) && read_cookie(web_address) == web.password) ||
password_check(@params["password"])
end
def default_author
@@ -594,10 +701,16 @@
def truncate(text, length = 30, truncate_string = "...")
if text.length > length then text[0..(length - 3)] + truncate_string else text end
end
def render_markup_help
- sub_template "#{web.markup}_help"
+ if web
+ markup = web.markup
+ markup = 'markdown' if markup.to_s =~ /markdown/
+ sub_template("#{markup}_help")
+ else
+ ''
+ end
end
def send_export(file_name, file_path, content_type = "application/zip")
@res["Content-Type"] = content_type
@res["Content-Disposition"] = "attachment; filename=#{file_name}"
\ No newline at end of file