diff options
Diffstat (limited to 'ruwiki/tags/release-0.9.0/lib')
29 files changed, 0 insertions, 6399 deletions
diff --git a/ruwiki/tags/release-0.9.0/lib/ruwiki.rb b/ruwiki/tags/release-0.9.0/lib/ruwiki.rb deleted file mode 100644 index ff4d76f..0000000 --- a/ruwiki/tags/release-0.9.0/lib/ruwiki.rb +++ /dev/null @@ -1,622 +0,0 @@ -#-- -# Ruwiki -# Copyright © 2002 - 2004, Digikata and HaloStatue -# Alan Chen (alan@digikata.com) -# Austin Ziegler (austin@halostatue.ca) -# -# Licensed under the same terms as Ruby. -# -# $Id$ -#++ - -class Ruwiki - VERSION = '0.9.0' - CONTENT_VERSION = 2 -end - -require 'cgi' -require 'ruwiki/handler' -require 'ruwiki/auth' -require 'ruwiki/template' -require 'ruwiki/lang/en' # Default to the English language. -require 'ruwiki/config' -require 'ruwiki/backend' -require 'ruwiki/wiki' -require 'ruwiki/page' - - # = Ruwiki - # Ruwiki is a simple, extensible Wiki written in Ruby. It supports both - # CGI and WEBrick interfaces, templates, and CSS formatting. Additionally, - # it supports project namespaces, so that two pages can be named the same - # for differing projects without colliding or having to resort to odd - # naming conventions. Please see the ::Ruwiki project in the running Wiki - # for more information. Ruwiki 0.9.0 has German and Spanish translations - # available. - # - # == Quick Start (CGI) - # 1. Place the Ruwiki directory in a place that your webserver can execute - # CGI programs and ensure that ruwiki.cgi is executable on your webserver. - # 2. Point your web browser to the appropriate URL. - # - # == Quick Start (WEBrick) - # 1. Run ruwiki_servlet (ruwiki_servlet.bat under Windows). - # 2. Point your web browser to <http://localhost:8808/>. - # - # == Configuration - # There are extensive configuration options available. The Ruwiki WEBrick - # servlet offers command-line options that simplify the configuration of - # Ruwiki without editing the servlet; use ruwiki_servlet --help for more - # information. - # - # == Copyright - # Copyright:: Copyright © 2002 - 2004, Digikata and HaloStatue, Ltd. - # Authors:: Alan Chen (alan@digikata.com) - # Austin Ziegler (ruwiki@halostatue.ca) - # Licence:: Ruby's -class Ruwiki - ALLOWED_ACTIONS = %w(edit create) - EDIT_ACTIONS = %w(save cancel) - EDIT_VARS = %w(newpage version edcomment q) - RESERVED = ['save', 'preview', 'cancel', EDIT_VARS].flatten - - # Returns the current configuration object. - attr_reader :config - # Returns the current Response object. - attr_reader :response - # Returns the current Request object. - attr_reader :request - # Returns the current Markup object. - attr_reader :markup - # Returns the current Backend object. - attr_reader :backend - # Sets the configuration object to a new configuration object. - def config=(cc) - raise self.message[:config_not_ruwiki_config] unless cc.kind_of?(Ruwiki::Config) - @config = cc - self.config! - end - - def config! - @markup.default_project = @config.default_project - @markup.message = self.message - end - - def load_config(filename) - @config = Ruwiki::Config.read(filename) - self.config! - end - - # The message hash. - def message - @config.message - end - - # Initializes Ruwiki. - def initialize(handler) - @request = handler.request - @response = handler.response - - @config = Ruwiki::Config.new - - @path_info = @request.determine_request_path || '' - - @type = nil - @error = {} - - @markup = Ruwiki::Wiki.new(@config.default_project, - @request.script_url, - @config.title) - end - - # Initializes the backend for Ruwiki. - def set_backend - @backend = BackendDelegator.new(self, @config.storage_type) - @markup.backend = @backend - # Load the blacklists here because I don't as of yet know where else - # to put them. :( - @banned_agents = load_blacklist('agents.banned') - @banned_hostip = load_blacklist('hostip.banned') - @readonly_agents = load_blacklist('agents.readonly') - @readonly_hostip = load_blacklist('hostip.readonly') - end - - def load_blacklist(filename) - data = [] - filename = File.join(@config.storage_options[@config.storage_type]['data-path'], filename) - ii = '^' - jj = /^#{ii}/o - File.open(filename, 'rb') do |f| - f.each do |line| - line.gsub!(%r{^\s*#.*$}, '') - line.strip! - if line.empty? - data << nil - else - if line =~ jj - data << "(?:#{line}\n)" - else - data << line - end - end - end - end - data.compact! - if data.empty? - nil - else - Regexp.new(data.join("|"), Regexp::EXTENDED) - end - end - - def check_useragent - addr = @request.environment['REMOTE_ADDR'] - user = @request.environment['HTTP_USER_AGENT'] - - if user.nil? or user.empty? - :forbidden - elsif @banned_hostip and addr and addr =~ @banned_hostip - :forbidden - elsif @banned_agents and user =~ @banned_agents - :forbidden - elsif @readonly_hostip and addr and addr =~ @readonly_hostip - :read_only - elsif @readonly_agents and user =~ @readonly_agents - :read_only - else - :clean - end - end - - # Runs the steps to process the wiki. - def run - @config.verify - set_backend - set_page - process_page - render - rescue Exception => ee - render(:error, ee) - ensure - output - end - - # Initializes current page for Ruwiki. - def set_page - path_info = @path_info.split(%r{/}, -1).map { |ee| ee.empty? ? nil : ee } - - if path_info.size == 1 or (path_info.size > 1 and path_info[0]) - raise self.message[:invalid_path_info_value] % [@path_info] unless path_info[0].nil? - end - - # path_info[0] will ALWAYS be nil. - path_info.shift - - case path_info.size - when 0 # Safety check. - nil - when 1 # /PageTopic OR /_edit - set_page_name_or_action(path_info[0]) - when 2 # /Project/ OR /Project/PageTopic OR /Project/_edit OR /Project/create - @project = path_info.shift - set_page_name_or_action(path_info[0]) - else # /Project/PageTopic/_edit OR /Project/diff/3,4 OR something else. - @project = path_info.shift - item = path_info.shift - action = RE_ACTION.match(item) - if action - @action = action.captures[0] - @params = path_info - else - @topic = item - item = path_info.shift - action = RE_ACTION.match(item) - if action - @action = action.captures[0] - @params = path_info - end - end - end - -# @request.each_parameter { |key, val| puts "#{key} :: #{val.class}" } - - @project ||= @config.default_project - @topic ||= @config.default_page - end - - PROJECT_LIST_ITEM = %[%1$s (a href='\\%2$s/%1$s/_topics' class='rw_minilink')%3$s\\</a\\>] - - # Processes the page through the necessary steps. This is where the edit, - # save, cancel, and display actions are present. - def process_page - content = nil - formatted = false - - @page = Ruwiki::Page.new(@backend.retrieve(@topic, @project)) - @type = :content - - agent_ok = check_useragent - case agent_ok - when :read_only - @page.editable = false - case @action - when 'edit', 'save', 'preview', 'cancel', 'search' - @page.indexable = false - end - when :forbidden - forbidden - return - else - unless @config.auth_mechanism.nil? - @auth_token = Ruwiki::Auth[@config.auth_mechanism].authenticate(@request, @response, @config.auth_options) - @page.editable = @auth_token.permissions['edit'] - end - end - - # TODO Detect if @action has already been set. - @action ||= @request.parameters['action'].downcase if @request.parameters['action'] - @action ||= 'save' if @request.parameters['save'] - @action ||= 'cancel' if @request.parameters['cancel'] - @action ||= 'preview' if @request.parameters['preview'] - - unless @page.editable - case @action - when 'edit', 'save', 'preview', 'cancel' - @action = 'show' - end - end - - case @action - when 'search' - # get, validate, and cleanse the search string - # TODO: add empty string rejection. - srchstr = validate_search_string(@request.parameters['q']) - if not srchstr.nil? - srchall = @request.parameters['a'] - - @page.editable = false - @page.indexable = false - - @page.content = self.message[:search_results_for] % [srchstr] - @page.topic = srchstr || "" - - unless srchall.nil? - hits = @backend.search_all_projects(srchstr) - else - hits = @backend.search_project(@page.project, srchstr) - end - - # turn hit hash into content - hitarr = [] - # organize by number of hits - hits.each { |key, val| (hitarr[val] ||= []) << key } - - rhitarr = hitarr.reverse - maxhits = hitarr.size - rhitarr.each_with_index do |tarray, rnhits| - next if tarray.nil? or tarray.empty? - nhits = maxhits - rnhits - 1 - - if nhits > 0 - @page.content << "\n== #{self.message[:number_of_hits] % [nhits]}\n* " - @page.content << tarray.join("\n* ") - end - end - - @type = :search - else - @sysmessage = self.message[:no_empty_search_string] % [ @page.project, @page.topic ] - @type = :content - end - when 'topics' - if @backend.project_exists?(@page.project) - topic_list = @backend.list_topics(@page.project) - else - topic_list = [] - end - - @page.editable = false - - # todo: make this localized - if topic_list.empty? - @page.content = self.message[:no_topics] % [@page.project] - else - topic_list.map! do |tt| - uu = CGI.unescape(tt) - if (uu != tt) or (tt =~ /^[A-Z][a-z]+$/) - "[[#{CGI.unescape(tt)}]]" - else - tt - end - end - @page.content = <<EPAGE -= #{self.message[:topics_for_project] % [@page.project]} -* #{topic_list.join("\n* ")} -EPAGE - end - - @type = :content - when 'projects' - proj_list = @backend.list_projects - - @page.editable = false - - if proj_list.empty? - @page.content = self.message[:no_projects] - else - # TODO make this localized - proj_list.map! { |proj| PROJECT_LIST_ITEM % [ proj, @request.script_url, self.message[:project_topics_link] ] } - @page.content = <<EPAGE -= #{self.message[:wiki_projects] % [@config.title]} -* ::#{proj_list.join("\n* ::")} -EPAGE - end - - content = @page.to_html(@markup) - content.gsub!(%r{\(a href='([^']+)/_topics' class='rw_minilink'\)}, '<a href="\1/_topics" class="rw_minilink">') #' - content.gsub!(%r{\\<}, '<') - content.gsub!(%r{\\>}, '>') - formatted = true - @type = :content - when 'edit', 'create' - # Automatically create the project if it doesn't exist or if the - # action is 'create'. - @backend.create_project(@page.project) if @action == 'create' - @backend.create_project(@page.project) unless @backend.project_exists?(@page.project) - @page.creator = @auth_token.name if @action == 'create' and @auth_token - @page.indexable = false - @lock = @backend.obtain_lock(@page, @request.environment['REMOTE_ADDR']) rescue nil - - if @lock.nil? - @type = :content - @sysmessage = self.message[:page_is_locked] - else - content = nil - formatted = true - @type = :edit - end - when 'save', 'preview' - np = @request.parameters['newpage'].gsub(/\r/, '').chomp - @page.topic = @request.parameters['topic'] - @page.project = @request.parameters['project'] - @page.editor_ip = @request.environment['REMOTE_ADDR'] - @page.indexable = false - - save_ver = @backend.retrieve(@page.topic, @page.project)['properties']['version'].to_i - sent_ver = @request.parameters['version'].to_i - - if sent_ver < save_ver - @type = :edit - - np = np.split($/) - content_diff = Diff::LCS.sdiff(np, @page.content.split($/), Diff::LCS::ContextDiffCallbacks) - content_diff.reverse_each do |hunk| - case hunk - when Array - hunk.reverse_each do |diff| - case diff.action - when '+' -# np.insert(diff.old_position, "+#{diff.new_element}") - np.insert(diff.old_position, "#{diff.new_element}") - when '-' - np.delete_at(diff.old_position) -# np[diff.old_position] = "-#{diff.old_element}" - when '!' - np[diff.old_position] = "-#{diff.old_element}" - np.insert(diff.old_position + 1, "+#{diff.new_element}") - end - end - when Diff::LCS::ContextChange - case hunk.action - when '+' - np.insert(hunk.old_position, "#{hunk.new_element}") -# np.insert(hunk.old_position, "+#{hunk.new_element}") - when '-' - np.delete_at(hunk.old_position) -# np[diff.old_position] = "-#{hunk.old_element}" - when '!' - np[hunk.old_position] = "-#{hunk.old_element}" - np.insert(hunk.old_position + 1, "+#{hunk.new_element}") - end - end - end - @page.content = np.join("\n") - - edc = @request.parameters['edcomment'] - unless (edc.nil? or edc.empty? or edc == "*") - @page.edit_comment = edc - end - - @sysmessage = self.message[:not_editing_current_version] % [ @page.project, @page.topic ] - else - if @action == 'save' - @page.editor = @auth_token.name if @auth_token - op = @page.content - else - op = nil - end - - if (np == op) and (@action == 'save') - @type = :content - else - @page.content = np - edc = @request.parameters['edcomment'] - unless (edc.nil? or edc.empty? or edc == "*") - @page.edit_comment = edc - end - - if @action == 'save' - @type = :save - @page.version = @request.parameters['version'].to_i + 1 - @backend.store(@page) - - # hack to ensure that Recent Changes are updated correctly - if @page.topic == 'RecentChanges' - recent = Ruwiki::Page.new(@backend.retrieve(@page.topic, @page.project)) - @page.content = recent.content - end - - @backend.release_lock(@page, @request.environment['REMOTE_ADDR']) - else - @type = :preview - @lock = @backend.obtain_lock(@page, @request.environment['REMOTE_ADDR']) - content = nil - formatted = true - end - end - end - when 'cancel' -# @page.topic = @request.parameters['topic'] -# @page.project = @request.parameters['project'] -# @page.version = @request.parameters['version'].to_i - - @backend.release_lock(@page, @request.environment['REMOTE_ADDR']) - @type = :content - else - # TODO AZ: This should probably return a 501 Not Implemented or some - # other error unless @action.nil? - nil - end - content = @page.to_html(@markup) if not formatted - rescue Exception => ee # rescue for def process_page - @type = :error - if ee.kind_of?(Ruwiki::Backend::BackendError) - name = "#{self.message[:error]}: #{ee.to_s}" - else - name = "#{self.message[:complete_utter_failure]}: #{ee.to_s}" - end - @error[:name] = CGI.escapeHTML(name) - @error[:backtrace] = ee.backtrace.map { |el| CGI.escapeHTML(el) }.join("<br />\n") - content = nil - ensure - @content = content - end # def process_page - - # Renders the page. - def render(*args) - if args.empty? - type = @type - error = @error - else - raise ArgumentError, self.message[:render_arguments] unless args.size == 2 - type = args[0] - error = { - :name => Ruwiki.clean_entities(args[1].inspect), - :backtrace => args[1].backtrace.join("<br />\n") - } - @page = Ruwiki::Page.new(Ruwiki::Page::NULL_PAGE) - end - - @rendered_page = "" - values = { - "css_link" => @config.css_link, - "home_link" => %Q(<a href="#{@request.script_url}">#{@config.title}</a>), - "cgi_url" => @request.script_url, - "content" => @content, - } - - if @page.nil? - values["page_project"] = "" - values["page_raw_topic"] = "" - values["page_topic"] = "" - values["editable"] = false - values["indexable"] = false - else - values["page_project"] = @page.project - values["page_raw_topic"] = @page.topic - values["page_topic"] = CGI.unescape(@page.topic) - values["editable"] = @page.editable - values["indexable"] = @page.indexable - end - - values["url_project"] = %Q(#{values["cgi_url"]}/#{values["page_project"]}) - values["url_topic_search"] = %Q(#{values["url_project"]}/_search?q=#{values["page_topic"]}) - values["link_topic_search"] = %Q(<a href='#{values["url_topic_search"]}'><strong>#{values["page_topic"]}</strong></a>) - values["message"] = @sysmessage unless @sysmessage.nil? - - case type - when :content, :save, :search - values["wiki_title"] = "#{self.message[:error]} - #{@config.title}" if @page.nil? - values["wiki_title"] ||= "#{@page.project}::#{CGI.unescape(@page.topic)} - #{@config.title}" - values["label_topic_or_search"] = self.message[:label_topic] - values["page_topic_name"] = values["page_topic"] - if type == :content or type == :search - template = TemplatePage.new(@config.template(:body), @config.template(:content), @config.template(:controls), @config.template(:footer)) - if type == :search - values["label_topic_or_search"] = self.message[:label_search] - else - values["page_topic"] = values["link_topic_search"] - end - else - # action type was save - values["page_topic"] = values["link_topic_search"] - template = TemplatePage.new(@config.template(:body), @config.template(:save), @config.template(:controls), @config.template(:footer)) - end - when :edit, :preview - template = TemplatePage.new(@config.template(:body), @config.template(:edit)) - values["wiki_title"] = "#{self.message[:editing]}: #{@page.project}::#{CGI.unescape(@page.topic)} - #{@config.title}" - values["page_content"] = @page.content - values["page_version"] = @page.version.to_s - values["unedited_page_content"] = @page.to_html(@markup) - values["pre_page_content"] = CGI.escapeHTML(@page.content) - if @request.parameters["edcomment"].nil? or @request.parameters["edcomment"].empty? - values["edit_comment"] = "*" - else - values["edit_comment"] = @request.parameters["edcomment"] - end - when :error - template = TemplatePage.new(@config.template(:body), @config.template(:error)) - values["wiki_title"] = "#{self.message[:error]} - #{@config.title}" - values["name"] = error[:name] - values["backtrace"] = error[:backtrace] - values["backtrace_email"] = error[:backtrace].gsub(/<br \/>/, '') - values["webmaster"] = @config.webmaster - end - - template.to_html(values, :messages => @config.message, - :output => @rendered_page) - end - - # Outputs the page. - def output - return if @response.written? -# if @request.environment["HTTP_ACCEPT"] =~ %r{application/xhtml\+xml} -# @response.add_header("Content-type", "application/xhtml+xml") -# else - @response.add_header("Content-type", "text/html") -# end - @response.add_header("Cache-Control", "max_age=0") - @response.write_headers - @response << @rendered_page - end - - def forbidden - protocol = @request.environment["SERVER_PROTOCOL"] || "HTTP/1.0" - @response.write_status "#{protocol} 403 FORBIDDEN\nDate: #{CGI::rfc1123_date(Time.now)}\n\n" - end - - # nil if string is invalid - def validate_search_string(instr) - return nil if instr.empty? - - modstr = instr.dup - - #TODO: add validation of modstr - return modstr - end - - def self.clean_entities(data) - data.gsub(/&/, '&').gsub(/</, '<').gsub(/>/, '>') - end - -private - RE_ACTION = %r{^_([[:lower:]]+)$} - - def set_page_name_or_action(item) - action = RE_ACTION.match(item) - if action - @action = action.captures[0] - else - @topic = item - end - end -end diff --git a/ruwiki/tags/release-0.9.0/lib/ruwiki/auth.rb b/ruwiki/tags/release-0.9.0/lib/ruwiki/auth.rb deleted file mode 100644 index ab4c923..0000000 --- a/ruwiki/tags/release-0.9.0/lib/ruwiki/auth.rb +++ /dev/null @@ -1,56 +0,0 @@ -#-- -# Ruwiki -# Copyright © 2002 - 2004, Digikata and HaloStatue -# Alan Chen (alan@digikata.com) -# Austin Ziegler (ruwiki@halostatue.ca) -# -# Licensed under the same terms as Ruby. -# -# $Id$ -#++ -class Ruwiki::Auth - class << self - def [](name) - @delegate ||= {} - - if @delegate.has_key?(name) - @delegate[name] - else - require "ruwiki/auth/#{name}" - @delegate[name] = Ruwiki::Auth.const_get(name.capitalize) - end - end - end - - class Token - def initialize(name = nil, groups = [], permissions = {}) - @user_name = name - @groups = groups - @permissions = permissions - end - - def found? - not @user_name.nil? - end - - def name - @user_name - end - - def member?(unix_group_name) - @groups.include?(unix_group_name) - end - - def groups - @groups - end - - def allowed?(action) - @permission[action] - end - - def permissions - @permissions - end - end -end diff --git a/ruwiki/tags/release-0.9.0/lib/ruwiki/auth/gforge.rb b/ruwiki/tags/release-0.9.0/lib/ruwiki/auth/gforge.rb deleted file mode 100644 index 70895a1..0000000 --- a/ruwiki/tags/release-0.9.0/lib/ruwiki/auth/gforge.rb +++ /dev/null @@ -1,73 +0,0 @@ -#-- -# Ruwiki -# Copyright © 2002 - 2004, Digikata and HaloStatue -# Alan Chen (alan@digikata.com) -# Austin Ziegler (ruwiki@halostatue.ca) -# -# Licensed under the same terms as Ruby. -# -# $Id$ -#++ - -begin - require 'gforge_auth' -rescue LoadError - class GForgeAuthenticator - class AuthenticationResult - def initialize(name = nil, groups = []) - @user_name = name - @groups = groups - end - - def found? - not @user_name.nil? - end - - def user_name - raise "No session associated with the given key was found" unless found? - @user_name - end - - def member?(unix_group_name) - raise "No session associated with the given key was found" unless found? - @groups.include?(unix_group_name) - end - - def groups - raise "No session associated with the given key was found" unless found? - @groups - end - end - - def self.authenticate(sessionkey, options = {}) - sql = %Q(SELECT user_name FROM users u, user_session us WHERE us.session_hash = '#{sessionkey}' AND us.user_id = u.user_id;) - res = %x{psql -q -t -U #{options['user']} #{options['pass']} -c \"#{sql}\"} - rows = res.split(/\n/) - return AuthenticationResult.new if rows.size != 1 - - user_name = rows[0].strip - sql = %Q(SELECT unix_group_name FROM groups g, users u, user_group ug WHERE u.user_name = '#{user_name}' AND ug.user_id = u.user_id AND g.group_id = ug.group_id) - - res = %x(psql -q -t -U #{options['user']} #{options['pass']} -c \"#{sql}\") - groups = [] - res.split(/\n/).each {|row| groups << row.strip } - AuthenticationResult.new(user_name, groups) - end - end -end - -class Ruwiki::Auth::Gforge < Ruwiki::Auth - def self.authenticate(request, response, options = {}) - options['user'] = options['user'].gsub!(%r{^(\w+)}, '\1') - options['pass'] = options['pass'].gsub!(%r{^(\w+)}, '\1') - session_key = request.cookies['session_ser'].value[0].split(%r{-\*-})[-1] - token = GForgeAuthenticator.authenticate(session_key, options) - token = Ruwiki::Auth::Token.new(token.user_name, token.groups) - token.permissions.default = true if token.found? - rescue - token = Ruwiki::Auth::Token.new - token.permissions.default = false - ensure - return token - end -end diff --git a/ruwiki/tags/release-0.9.0/lib/ruwiki/backend.rb b/ruwiki/tags/release-0.9.0/lib/ruwiki/backend.rb deleted file mode 100644 index 59947f8..0000000 --- a/ruwiki/tags/release-0.9.0/lib/ruwiki/backend.rb +++ /dev/null @@ -1,318 +0,0 @@ -#-- -# Ruwiki -# Copyright © 2002 - 2004, Digikata and HaloStatue -# Alan Chen (alan@digikata.com) -# Austin Ziegler (ruwiki@halostatue.ca) -# -# Licensed under the same terms as Ruby. -# -# $Id$ -#++ - -begin - if defined?(Gem::Cache) - require_gem 'diff-lcs', '~> 1.1.2' - else - require 'diff/lcs' - end -rescue LoadError => ex - $stderr.puts ex.message - raise -end - -class Ruwiki - # The list of known backends. - KNOWN_BACKENDS = %w(flatfiles) - - # The Ruwiki backend delegator. Ruwiki will always instantiate a version - # of this class which delegates the actual method execution to the Backend - # class. Error handling is handled by capturing (and possibly forwarding) - # exceptions raised by the delegate class. - class BackendDelegator - def initialize(ruwiki, backend) - @message = ruwiki.config.message - @time_format = ruwiki.config.time_format || "%H:%M:%S" - @date_format = ruwiki.config.date_format || "%Y.%m.%d" - @datetime_format = ruwiki.config.datetime_format || "#{@date_format} #{@time_format}" - options = ruwiki.config.storage_options - options['default-page'] = ruwiki.config.default_page - - unless Ruwiki::KNOWN_BACKENDS.include?(backend) - raise RuntimeError, @message[:backend_unknown] % [backend] - end - - beconst = backend.capitalize - - require "ruwiki/backend/#{backend}" - - beoptions = options[backend] - @delegate = Ruwiki::Backend.const_get(beconst).new(beoptions) - rescue Ruwiki::Backend::BackendError => ex - if ex.kind_of?(Array) - raise Ruwiki::Backend::BackendError.new(nil), @message[ex.reason[0]] % ex.reason[1] - else - raise - end - end - - # Retrieve the specified topic and project page. Calls Backend#load - # after verifying that the project exists. - def retrieve(topic, project = 'Default') - unless page_exists?(topic, project) - exported = Ruwiki::Page::NULL_PAGE.dup - exported['properties'] = { - 'title' => topic, - 'topic' => topic, - 'project' => project, - 'create-date' => Time.now, - 'edit-date' => Time.now, - 'editable' => true, - 'indexable' => true, - 'entropy' => 0.0, - 'html-headers' => [], - 'version' => 0 - } - exported['page'] = { - 'header' => nil, - 'footer' => nil - } - - if project_exists?(project) - exported['page']['content'] = "" - else - exported['page']['content'] = @message[:project_does_not_exist] % [project] - end - return exported - end - - return @delegate.load(topic, project) - rescue Ruwiki::Backend::InvalidFormatError => ex - raise Ruwiki::Backend::BackendError.new(nil), @message[:page_not_in_backend_format] % [project, topic, @delegate.class] - rescue Errno::EACCES => ex - raise Ruwiki::Backend::BackendError.new(ex), @message[:no_access_to_read_topic] % [project, topic] - rescue Exception => ex - mm = [project, topic, %Q~#{ex}<br />\n#{ex.backtrace.join('<br />\n')}~] - raise Ruwiki::Backend::BackendError.new(ex), @message[:cannot_retrieve_topic] % mm - end - - # Stores the specified topic and project page. - def store(page) - @delegate.store(page) - - # update change page - begin - recent_changes = nil - if (page.topic == 'RecentChanges') - recent_changes = page.dup - else - recent_changes = Page.new(retrieve('RecentChanges', page.project)) - end - - changeline = "\n; #{page.editor_ip} (#{Time.now.strftime(@datetime_format)}), #{page.topic} : #{page.edit_comment}" - - # add changeline to top of page - recent_changes.content = changeline + (recent_changes.content || "") - @delegate.store(recent_changes) - rescue Exception => ex - raise "Couldn't save RecentChanges\n#{ex.backtrace}" - end - rescue Errno::EACCES => ex - raise Ruwiki::Backend::BackendError.new(ex), @message[:no_access_to_store_topic] % [page.project, page.topic] - rescue Exception => ex - mm = [page.project, page.topic, %Q~#{ex}<br />\n#{ex.backtrace.join('<br />\n')}~] - raise Ruwiki::Backend::BackendError.new(ex), @message[:cannot_store_topic] % mm - end - - # Destroys the specified topic and project page. - def destroy(page) - @delegate.destroy(page) - rescue Errno::EACCES => ex - raise Ruwiki::Backend::BackendError.new(ex), @message[:no_access_to_destroy_topic] % [page.project, page.topic] - rescue Exception => ex - mm = [page.project, page.topic, %Q~#{ex}<br />\n#{ex.backtrace.join('<br />\n')}~] - raise Ruwiki::Backend::BackendError.new(ex), @message[:cannot_destroy_topic] % mm - end - - # Releases the lock on the page. - def release_lock(page, address = 'UNKNOWN') - time = Time.now.to_i - @delegate.release_lock(page, time, address) - rescue Ruwiki::Backend::BackendError - raise Ruwiki::Backend::BackendError.new(nil), @message[:cannot_release_lock] % [page.project, page.topic] - rescue Errno::EACCES, Exception => ex - mm = [page.project, page.topic, %Q~#{ex}<br />\n#{ex.backtrace.join('<br />\n')}~] - raise Ruwiki::Backend::BackendError.new(ex), @message[:error_releasing_lock] % mm - end - - # Attempts to obtain a lock on the page. The lock - def obtain_lock(page, address = 'UNKNOWN', timeout = 600) - time = Time.now.to_i - expire = time + timeout - @delegate.obtain_lock(page, time, expire, address) - rescue Ruwiki::Backend::BackendError - raise Ruwiki::Backend::BackendError.new(nil), @message[:cannot_obtain_lock] % [page.project, page.topic] - rescue Errno::EACCES, Exception => ex - mm = [page.project, page.topic, %Q~#{ex}<br />\n#{ex.backtrace.join('<br />\n')}~] - raise Ruwiki::Backend::BackendError.new(ex), @message[:error_creating_lock] % mm - end - - # Checks to see if the project exists. - def project_exists?(project) - @delegate.project_exists?(project) - end - - # Checks to see if the page exists. - def page_exists?(topic, project = 'Default') - @delegate.page_exists?(topic, project) - end - - # Attempts to create the project. - def create_project(project) - @delegate.create_project(project) - rescue Ruwiki::Backend::ProjectExists => ex - raise Ruwiki::Backend::BackendError.new(ex), @message[:project_already_exists] % [project] - rescue Errno::EACCES => ex - raise Ruwiki::Backend::BackendError.new(ex), @message[:no_access_to_create_project] % [project] - rescue Exception => ex - mm = [project, %Q~#{ex}<br />\n#{ex.backtrace.join('<br />\n')}~] - raise Ruwiki::Backend::BackendError.new(ex), @message[:cannot_create_project] % mm - end - - # Attempts to destroy the project. - def destroy_project(project) - @delegate.destroy_project(project) - rescue Errno::EACCES => ex - raise Ruwiki::Backend::BackendError.new(ex), @message[:no_access_to_destroy_project] % [project] - rescue Exception => ex - mm = [project, %Q~#{ex}<br />\n#{ex.backtrace.join('<br />\n')}~] - raise Ruwiki::Backend::BackendError.new(ex), @message[:cannot_destroy_project] % mm - end - - def search_all_projects(searchstr) - if @delegate.respond_to?(:search_all_projects) - @delegate.search_all_projects(searchstr) - else - search_all_projects_default(searchstr) - end - end - - # Attempts to search all projects. This is the default - # search_all_projects used unless the delegate implements - # a specialized search_all_projects. - def search_all_projects_default(searchstr) - hits = {} - list_projects.each do |project| - lhits = search_project(project, searchstr) - # Transform the keys from project local to global links. - lhits.each { |key, val| hits["#{project}::#{key}"] = val } - end - hits - end - - # Attempts to search a project - def search_project(project, searchstr) - #TODO: Validate searchstr is a safe regexp? - @delegate.search_project(project, searchstr) - rescue Exception => ex - mm = [project, searchstr, ex.class, %Q~#{ex}<br />\n#{ex.backtrace.join('<br />\n')}~] - raise Ruwiki::Backend::BackendError.new(ex), @message[:search_project_fail] % mm - end - - # Return an array of projects - def list_projects - @delegate.list_projects - rescue Errno::EACCES => ex - raise Ruwiki::Backend::BackendError.new(ex), @message[:no_access_list_projects] - rescue Exception => ex - mm = ['', %Q~#{ex}<br />\n#{ex.backtrace.join('<br />\n')}~] - raise Ruwiki::Backend::BackendError.new(ex), @message[:cannot_list_projects] % mm - end - - # Return an array of projects - def list_topics(projname) - @delegate.list_topics(projname) - rescue Errno::EACCES => ex - raise Ruwiki::Backend::BackendError.new(ex), @message[:no_access_list_topics] % [projname] - rescue Exception => ex - mm = [projname, ex.message] - raise Ruwiki::Backend::BackendError.new(ex), @message[:cannot_list_topics] % mm - end - end - - # The Ruwiki backend abstract class and factory. - class Backend - class ProjectExists < RuntimeError #:nodoc: - end - class InvalidFormatError < RuntimeError #:nodoc: - end - class BackendError < RuntimeError #:nodoc: - attr_reader :reason - - def initialize(reason, *args) - if @reason.respond_to?(:message) - @reason = reason.message - else - @reason = reason - end - end - end - def initialize(storage_options) - end - - private - NL_RE = %r{\n} #:nodoc: - - def map_diffset(diffset) - diffset.map do |hunk| - if hunk.kind_of?(Array) - hunk.map { |change| change.to_a } - else - hunk.to_a - end - end - end - - # Creates the current diff object. This is made from two - # Ruwiki::Page#export hashes. - def make_diff(oldpage, newpage) - oldpage = oldpage.export if oldpage.kind_of?(Ruwiki::Page) - newpage = newpage.export if newpage.kind_of?(Ruwiki::Page) - - diff = Hash.new - - newpage.keys.sort.each do |sect| - newpage[sect].keys.sort.each do |item| - oldval = oldpage[sect][item] - newval = newpage[sect][item] - - case [sect, item] - when ['properties', 'html-headers'] - # Protect against NoMethodError. - oldval ||= [] - newval ||= [] - val = Diff::LCS.sdiff(oldval, newval, Diff::LCS::ContextDiffCallbacks) - when ['ruwiki', 'content-version'], ['properties', 'version'], - ['properties', 'entropy'] - val = Diff::LCS.sdiff([oldval], [newval], Diff::LCS::ContextDiffCallbacks) - when ['properties', 'create-date'], ['properties', 'edit-date'] - val = Diff::LCS.sdiff([oldval.to_i], [newval.to_i], Diff::LCS::ContextDiffCallbacks) - else - # Protect against NoMethodError. - val = Diff::LCS.sdiff(oldval.to_s.split(NL_RE), newval.to_s.split(NL_RE), Diff::LCS::ContextDiffCallbacks) - end - - (diff[sect] ||= {})[item] = map_diffset(val) unless val.nil? or val.empty? - end - end - - diff_hash = { - 'old_version' => oldpage['properties']['version'], - 'new_version' => newpage['properties']['version'], - 'edit-date' => newpage['properties']['edit-date'].to_i, - 'editor-ip' => newpage['properties']['editor-ip'], - 'editor' => newpage['properties']['editor'], - 'diff' => diff - } - end - end -end diff --git a/ruwiki/tags/release-0.9.0/lib/ruwiki/backend/flatfiles.rb b/ruwiki/tags/release-0.9.0/lib/ruwiki/backend/flatfiles.rb deleted file mode 100644 index 7194095..0000000 --- a/ruwiki/tags/release-0.9.0/lib/ruwiki/backend/flatfiles.rb +++ /dev/null @@ -1,217 +0,0 @@ -#-- -# Ruwiki -# Copyright © 2002 - 2004, Digikata and HaloStatue -# Alan Chen (alan@digikata.com) -# Austin Ziegler (ruwiki@halostatue.ca) -# -# Licensed under the same terms as Ruby. -# -# $Id$ -#++ -require 'ruwiki/exportable' - - # Stores Ruwiki pages as flatfiles. -class Ruwiki::Backend::Flatfiles < Ruwiki::Backend - # Initializes the Flatfiles backend. The known options for the Flatfiles - # backend are documented below. - # - # data-path:: The directory in which the wiki files will be found. By - # default, this is "./data/" - # extension:: The extension of the wiki files. By default, this is - # +nil+ in the backend. - # format:: The format of the files in the backend. By default, - # this is 'exportable', a tagged data format produced by - # Ruwiki::Exportable; alternative formats are 'yaml' - # (::YAML.dump) and 'marshal' (::Marshal.dump). - # default-page:: The default page for a project. By default, this is - # ProjectIndex. This is provided only so that the backend - # can make reasonable guesses. - def initialize(options) - @data_path = options['data-path'] || File.join(".", "data") - @extension = options['extension'] - @format = case options['format'] - when 'exportable', nil - Ruwiki::Exportable - when 'yaml' - ::YAML - when 'marshal' - ::Marshal - end - - if @extension.nil? - @extension_re = /$/ - else - @extension_re = /\.#{@extension}$/ - end - - @default_page = options['default-page'] || "ProjectIndex" - if not (File.exists?(@data_path) and File.directory?(@data_path)) - raise Ruwiki::Backend::BackendError.new([:flatfiles_no_data_directory, [@data_path]]) - end - - super - end - - # Destroys the topic page. - def destroy(page) - pf = page_file(page.topic, page.project) - File.unlink(pf) if File.exists?(pf) - end - - # Checks to see if the project exists. - def project_exists?(project) - pd = project_directory(project) - File.exists?(pd) and File.directory?(pd) - end - - # Checks to see if the page exists. - def page_exists?(topic, project = 'Default') - pf = page_file(topic, project) - project_exists?(project) and File.exists?(pf) - end - - # Tries to create the project. - def create_project(project) - pd = project_directory(project) - raise Ruwiki::Backend::ProjectExists if File.exists?(pd) - Dir.mkdir(pd) - end - - # Tries to destroy the project. - def destroy_project(project) - pd = project_directory(project) - Dir.rmdir(pd) if File.exists?(pd) and File.directory?(pd) - end - - # String search all topic names and content in a project and - # return a hash of topic hits. - def search_project(project, searchstr) - re_search = Regexp.new(searchstr, Regexp::IGNORECASE) - - hits = Hash.new { |hh, kk| hh[kk] = 0 } - topic_list = list_topics(project) - - return hits if topic_list.empty? - - # search topic content - topic_list.each do |topic| - # search name - hits[topic] += topic.scan(re_search).size - - # check content - page = load(topic, project) rescue Ruwiki::Page::NULL_PAGE - page['page'].each_value do |item| - item = item.join("") if item.kind_of?(Array) - item ||= "" - hits[topic] += item.scan(re_search).size - end - end - - hits - end - - def lock_okay?(page, time, address = 'UNKNOWN') - lockokay = false - lockfile = "#{page_file(page.topic, page.project)}.lock" - - if File.exists?(lockfile) - data = File.read(lockfile).split(%r{!}) - # If the lock belongs to this address, we don't care how old it is. - # Thus, release it. - lock_okay ||= (data[0].chomp == address) - # If the lock is older than 10 minutes, release it. - lock_okay ||= (data[1].to_i < time) - else - lockokay = true - end - end - - # Attempts to obtain a lock on the topic page. This must return the lock - def obtain_lock(page, time, expire, address = 'UNKNOWN') - lock = "#{address}!#{expire}" - - if lock_okay?(page, time, address) - File.open("#{page_file(page.topic, page.project)}.lock", 'wb') { |lfh| lfh.puts lock } - else - raise Ruwiki::Backend::BackendError.new(nil) - end - lock - end - - # Releases the lock on the topic page. - def release_lock(page, time, address = 'UNKNOWN') - time = Time.now.to_i - lockfile = "#{page_file(page.topic, page.project)}.lock" - - if lock_okay?(page, time, address) - File.unlink(lockfile) if File.exists?(lockfile) - else - raise Ruwiki::Backend::BackendError.new(nil) - end - true - end - - # list projects found in data path - def list_projects - Dir[File.join(@data_path, "*")].select do |dd| - File.directory?(dd) and File.exist?(page_file(@default_page, File.basename(dd))) - end.map { |dd| File.basename(dd) } - end - - # list topics found in data path - def list_topics(project) - pd = project_directory(project) - raise Ruwiki::Backend::BackendError.new(:no_project) unless File.exist?(pd) - - Dir[File.join(pd, "*")].select do |ff| - ff !~ /\.rdiff$/ and ff !~ /\.lock$/ and File.file?(ff) and ff =~ @extension_re - end.map { |ff| File.basename(ff).sub(@extension_re, "") } - end - - def project_directory(project) # :nodoc: - File.join(@data_path, project) - end - - def page_file(topic, project = 'Default') # :nodoc: - if @extension.nil? - File.join(project_directory(project), topic) - else - File.join(project_directory(project), "#{topic}.#{@extension}") - end - end - - def make_rdiff(page_file, new_page) - diff_file = "#{page_file}.rdiff" - - old_page = self.class.load(pf) rescue Ruwiki::Page::NULL_PAGE - - diffs = [] - File.open(diff_file, 'rb') { |ff| diffs = Marshal.load(ff) } if File.exists?(diff_file) - diffs << make_diff(old_page, new_page) - changes = Marshal.dump(diffs) - - File.open(diff_file, 'wb') { |ff| ff << changes } - end - - # Provides a HEADER marker. - # Loads the topic page from disk. - def load(topic, project) - data = nil - File.open(page_file(topic, project), 'rb') { |ff| data = ff.read } - - Ruwiki::Page::NULL_PAGE.merge(@format.load(data)) - rescue Ruwiki::Exportable::InvalidFormatError, TypeError, ArgumentError - raise Ruwiki::Backend::InvalidFormatError - end - - # Saves the topic page -- and its difference with the previous version - # -- to disk. - def store(page) - pagefile = page_file(page.topic, page.project) - export = page.export - newpage = @format.dump(export) - make_rdiff(pagefile, export) - - File.open(pagefile, 'wb') { |ff| ff.puts newpage } - end -end diff --git a/ruwiki/tags/release-0.9.0/lib/ruwiki/config.rb b/ruwiki/tags/release-0.9.0/lib/ruwiki/config.rb deleted file mode 100644 index d01dca1..0000000 --- a/ruwiki/tags/release-0.9.0/lib/ruwiki/config.rb +++ /dev/null @@ -1,244 +0,0 @@ -#-- -# Ruwiki -# Copyright © 2002 - 2004, Digikata and HaloStatue -# Alan Chen (alan@digikata.com) -# Austin Ziegler (ruwiki@halostatue.ca) -# -# Licensed under the same terms as Ruby. -# -# $Id$ -#++ -require 'ruwiki/exportable' - - # Ruwiki configuration. -class Ruwiki::Config - include Ruwiki::Exportable - - CONFIG_NAME = 'ruwiki.conf' - - exportable_group 'ruwiki-config' - # Sets or returns the logger. The logger, if set, must respond to the same - # methods as WEBrick::Logger. - attr_accessor :logger - # Sets or returns the time format whenever time is outputted in Ruwiki. - # Default is <tt>%H:%M:%S</tt> (23:59:59). - attr_accessor :time_format - exportable :time_format - # Sets or returns the date format whenever time is outputted in Ruwiki. - # Default is <tt>%Y.%m.%d</tt> (2004.08.04). - attr_accessor :date_format - exportable :date_format - # Sets or returns the date-time format whenever time is outputted in - # Ruwiki. Default is <tt>%Y.%m.%d %H:%M:%S</tt> (2004.08.04 23:59:59). - attr_accessor :datetime_format - exportable :datetime_format - # Adds additional information to the (rare) error reports. Defaults to - # +false+. - attr_accessor :debug - exportable :debug - # The default page for display when Ruwiki is called without any arguments. - # Defaults to +ProjectIndex+ - attr_accessor :default_page - exportable :default_page - # The default project for display when Ruwiki is called without any - # arguments or a project specification. Defaults to +Default+ - attr_accessor :default_project - exportable :default_project - # The authentication mechanism name as a String. Corresponds to - # a filename that will be found in ruwiki/auth. The authenticator must - # have a single class method, +authenticate+, which accepts the - # +request+, the +response+, and the +#auth_options+. This API is - # a draft API and is likely to change in future versions of Ruwiki. In - # this version of Ruwiki, only one authentication mechanism will be - # found -- for dealing with authenticating users already logged into - # RubyForge. - attr_accessor :auth_mechanism - exportable :auth_mechanism - # Options for the authentication mechanism as a Hash. This will be - # passed to the authenticator defined in +#auth_mechanism+. - attr_accessor :auth_options - exportable :auth_options - # The storage type as a String. Corresponds to a filename that will be - # found in ruwiki/backend. NOTE: The yaml and marshal storage types have - # been removed from Ruwiki 0.9.0, to be replaced with a single storage - # type of Flatfiles. Now, the YAML and Marshal formats can be enabled by - # setting options in the @storage_options field. - attr_accessor :storage_type - exportable :storage_type - # The options for the specified storage type. This is a hash of hashes with - # auto-vifification. See the storage type for available options. - attr_reader :storage_options - exportable :storage_options - # The path for templates. Defaults to <tt>./templates/</tt>. - attr_accessor :template_path - exportable :template_path - # The name of the Wiki. Defaults to <tt>ruwiki</tt> - attr_accessor :title - exportable :title - # The email address of the webmaster for the Wiki. Defaults to +nil+. - attr_accessor :webmaster - exportable :webmaster - # The name of the Ruwiki CSS file. Defaults to <tt>ruwiki.css</tt>. - attr_accessor :css - exportable :css - # The template set. Templates are always named as - # <template_path>/<template_set>/<template_name>. Template filename. Must - # be reachable by File#read. - attr_accessor :template_set - exportable :template_set - # Ruwiki is internationalized. This method sets the Ruwiki error - # messages (and a few other messages) to the specified language Module. - # The language Module must have a constant Hash called +Message+ - # containing a set of symbols and localized versions of the messages - # associated with them. - # - # If the file 'ruwiki/lang/es.rb' contains the module - # <tt>Ruwiki::Lang::ES</tt>, the error messages for RSS could be - # localized to Español thus: - # - # require 'ruwiki/lang/es' - # ... - # wiki.config.language = Ruwiki::Lang::ES - # - # Localization is per wiki instance. In a servlet environment, this may - # mean that only a single language is recognised. - # - # See Ruwiki::Lang::EN for more information. - attr_accessor :language - exportable :language - # The message hash. - attr_reader :message - - def language=(ll) #:nodoc: - if ll.kind_of?(String) - @language = Ruwiki::Lang::const_get(ll.upcase) - else - @language = ll - end - @message = @language::Message - end - - # Returns the specified template as a string. - def template(name) - File.read(File.join(@template_path, @template_set, "#{name.to_s}.tmpl")) - rescue Errno::ENOENT - raise ConfigError, message[:no_template_found] % [name.inspect, @template_set] - end - - # Returns the CSS stylesheet content for the Wiki. This previously - # returned the <link> to the stylesheet, but instead returns a <style> - # block in the head so that the CSS is kept with the template set, which - # may be kept outside of the HTML area. - def css_link - %Q[<style type="text/css" media="screen,print">#{File.read(File.join(@template_path, @template_set, @css))}</style>] - end - - # Creates a new configuration object. - def initialize(exportable = {}) - rc = exportable['ruwiki-config'] || {} - @debug = (rc['debug'] == "false") ? false : true - @default_project = rc['default-project'] || "Default" - @default_page = rc['default-page'] || "ProjectIndex" - @auth_mechanism = rc['auth-mechanism'] || nil - - case rc['auth-options'] - when nil, "" - @auth_options = {} - else - @auth_options = Ruwiki::Exportable.load(rc['auth-options'])['default'] - end - - case rc['storage-type'] - when nil, "" - @storage_type = 'flatfiles' - else - @storage_type = rc['storage-type'] - end - - # in 'type!name:<Tab>value\n' format. - if rc['storage-options'].nil? or rc['storage-options'].empty? - @storage_options = Hash.new { |hh, kk| hh[kk] = {} } - else - @storage_options = Ruwiki::Exportable.load(rc['storage-options']) - @storage_options.keys.each do |key| - @storage_options[key] = @storage_options.delete(key) - end - end - if @storage_options.empty? - @storage_options[@storage_type]['extension'] = "ruwiki" - @storage_options[@storage_type]['data-path'] = "./data" - @storage_options[@storage_type]['format'] = "exportable" - end - - @storage_options.each_value do |vv| - if vv['extension'].nil? or vv['extension'].empty? - vv['extension'] = "ruwiki" - end - if vv['data-path'].nil? or vv['data-path'].empty? - vv['data-path'] = "./data" - end - end - - @template_path = rc['template-path'] || "./templates/" - @template_set = rc['template-set'] || "default" - @css = rc['css'] || "ruwiki.css" - @webmaster = rc['webmaster'] - @title = rc['title'] || "Ruwiki" - @time_format = rc['time-format'] || "%H:%M:%S" - @date_format = rc['date-format'] || "%Y.%m.%d" - @datetime_format = rc['datetime-format'] || "#{@date_format} #{@time_format}" - case rc['language'] - when nil, "" - self.language = Ruwiki::Lang::EN - else - self.language = Ruwiki::Lang::const_get(rc['language'].upcase) - end - end - - # Verifies that required configuration options are actually set. Right - # now, it only checks the values that are defaulted to +nil+. - def verify - raise ConfigError, message[:no_webmaster_defined] if @webmaster.nil? or @webmaster.empty? - raise ConfigError, message[:invalid_template_dir] % [@template_path] unless File.exists?(@template_path) and File.directory?(@template_path) - tt = File.join(@template_path, @template_set) - raise ConfigError, message[:no_template_set] % [@template_set] unless File.exists?(tt) and File.directory?(tt) - end - - # Provides the canonical export hash. - def export - exportable = super - - rc = exportable['ruwiki-config'] - - rc['auth-options'] = Ruwiki::Exportable.dump({ 'default' => rc['auth-options']}) - - rc['storage-options'] = Ruwiki::Exportable.dump(rc['storage-options']) - rc['storage-type'] = rc['storage-type'].to_s - rc['language'] = "#{rc['language']}".sub(/^.*?::([A-Z]+)$/, '\1').downcase - exportable - end - - class << self - def write(file, config) - if file.respond_to?(:write) - file.puts(config.dump) - else - File.open(file, 'wb') { |ff| ff.puts(config.dump) } - end - end - - def read(file) - data = nil - if file.respond_to?(:read) - data = file.read - else - File.open(file, 'rb') { |ff| data = ff.read } - end - hash = Ruwiki::Exportable.load(data) - - Ruwiki::Config.new(hash) - end - end - - class ConfigError < StandardError; end -end diff --git a/ruwiki/tags/release-0.9.0/lib/ruwiki/exportable.rb b/ruwiki/tags/release-0.9.0/lib/ruwiki/exportable.rb deleted file mode 100644 index c18290f..0000000 --- a/ruwiki/tags/release-0.9.0/lib/ruwiki/exportable.rb +++ /dev/null @@ -1,192 +0,0 @@ -#-- -# Ruwiki -# Copyright © 2002 - 2004, Digikata and HaloStatue -# Alan Chen (alan@digikata.com) -# Austin Ziegler (ruwiki@halostatue.ca) -# -# Licensed under the same terms as Ruby. -# -# $Id$ -#++ - - # == Synopsis - # Generalises a marshaling format that is easily read and edited by humans - # and is relatively easy to manage by software. When an attribute is marked - # #exportable, the name of the attribute is transformed and stored in - # a two-level hash, e.g.: - # - # exportable_group 'group1' - # exportable :var_1 - # exportable :var_2 - # exportable_group 'group2' - # exportable :var_3 - # exportable :var_4 - # - # Results in an exportable hash of: - # - # { 'group1' => - # { 'var-1' => @var1, - # 'var-2' => @var2, }, - # 'group2' => - # { 'var-3' => @var3, - # 'var-4' => @var4, }, } - # -module Ruwiki::Exportable - class InvalidFormatError < RuntimeError; end - - class << self - # Adds two methods and an attribute to the class that is including Exportable - # - # <tt>__exportables</tt>:: Contains the list of exportable symbols by group. - # <tt>exportable_group</tt>:: Defines the current group for exportable - # symbols. Default is 'default'. - # <tt>exportable</tt>:: Accepts two arguments, the attribute being - # exported and an option hash, containing the - # values :name and :group, where :name - # indicates the name of the attribute (so - # that the default name transformation is - # not applied) and :group overrides the - # current #exportable_group. By default, the - # name of the attribute is transformed such - # that underscores are converted to dashes - # (<tt>var_1</tt> becomes 'var-1'). - def append_features(mod) - super - - class << mod - attr_reader :__exportables - - define_method(:exportable_group) do |name| - @__exportable_group = name || 'default' - end - - define_method(:exportable) do |*symset| - symbol = symset.shift - options = symset.shift || {} - - @__exportables ||= {} - - options[:name] ||= symbol.to_s.gsub(/_/, '-') - options[:group] ||= @__exportable_group || 'default' - - @__exportables[options[:group]] ||= {} - @__exportables[options[:group]][options[:name]] = "@#{symbol.to_s}".intern - end - end - end - - # Looks for comments. Comments may ONLY be on single lines. - COMMENT_RE = %r{^#} - # Looks for newlines - NL_RE = %r{\n} - # Looks for a line that indicates an exportable value. See #dump. - HEADER_RE = %r{^([a-z][-a-z]+)!([a-z][-a-z]+):[ \t](.*)$} - # Looks for an indented group indicating that the last group is - # a multiline value. - FIRST_TAB = %r{^[ \t]} - - # Dumps the provided exportable hash in the form: - # - # section!name:<Tab>Value - # section!name:<Space>Value - # - # Multiline values are indented either one space or one tab: - # - # section!name:<Tab>Value Line 1 - # <Tab>Value Line 2 - # <Tab>Value Line 3 - # <Tab>Value Line 4 - # - # All values in the exportable hash are converted to string - # representations, so only values that can meaningfully be reinstantiated - # from string representations should be stored in the exportable hash. It - # is the responsibility of the class preparing the exportable hash - # through Exportable#export to make the necessary transformations. - def dump(export_hash) - dumpstr = "" - - export_hash.keys.sort.each do |sect| - export_hash[sect].keys.sort.each do |item| - val = export_hash[sect][item].to_s.split(NL_RE).join("\n\t") - dumpstr << "#{sect}!#{item}:\t#{val}\n" - end - end - - dumpstr - end - - # Loads a buffer in the form provided by #dump into an exportable hash. - # Skips comment lines. - def load(buffer) - hash = {} - return hash if buffer.nil? or buffer.empty? - - # Split the buffer and eliminate comments. - buffer = buffer.split(NL_RE).delete_if { |line| line =~ COMMENT_RE } - - if HEADER_RE.match(buffer[0]).nil? - raise Ruwiki::Exportable::InvalidFormatError - end - - sect = item = nil - - buffer.each do |line| - line.chomp! - match = HEADER_RE.match(line) - - # If there is no match, add the current line to the previous match. - # Remove the leading \t, though. - if match.nil? - raise Ruwiki::Exportable::InvalidFormatError if FIRST_TAB.match(line).nil? - hash[sect][item] << "\n#{line.gsub(FIRST_TAB, '')}" - else - sect = match.captures[0] - item = match.captures[1] - hash[sect] ||= {} - hash[sect][item] = match.captures[2] - end - end - - hash - end - end - - # Converts #exportable attributes to an exportable hash, in the form: - # { 'group1' => - # { 'var-1' => @var1, - # 'var-2' => @var2, }, - # 'group2' => - # { 'var-3' => @var3, - # 'var-4' => @var4, }, } - # - # Classes that #include Exportable are encouraged to override export to - # ensure safe transformations of values. An example use might be: - # - # class TimeClass - # include Ruwiki::Exportable - # - # def export - # sym = super - # - # sym['default']['time'] = sym['default']['time'].to_i - # sym - # end - # - # In this way, the 'time' value is converted to an integer rather than the - # default string representation. - def export - sym = {} - - self.class.__exportables.each do |group, gval| - gname = group || @__exportable_group || 'default' - gsym = {} - gval.each do |name, nval| - val = self.instance_variable_get(nval) - gsym[name] = val unless val.nil? - end - sym[gname] = gsym - end - - sym - end -end diff --git a/ruwiki/tags/release-0.9.0/lib/ruwiki/handler.rb b/ruwiki/tags/release-0.9.0/lib/ruwiki/handler.rb deleted file mode 100644 index c6a9375..0000000 --- a/ruwiki/tags/release-0.9.0/lib/ruwiki/handler.rb +++ /dev/null @@ -1,342 +0,0 @@ -#-- -# Ruwiki -# Copyright © 2002 - 2004, Digikata and HaloStatue -# Alan Chen (alan@digikata.com) -# Austin Ziegler (ruwiki@halostatue.ca) -# -# Licensed under the same terms as Ruby. -# -# $Id$ -#++ -class Ruwiki::Handler - class << self - # Generate a new Handler pair from a CGI request. - def from_cgi(cgi, output_stream = $stdout) - Ruwiki::Handler.new do |o| - o.request = Ruwiki::Handler::CGIRequest.new(cgi) - o.response = Ruwiki::Handler::CGIResponse.new(cgi, output_stream) - end - end - - # Generate a new Handler pair from a WEBrick request. - def from_webrick(req, res) - Ruwiki::Handler.new do |o| - o.request = Ruwiki::Handler::WEBrickRequest.new(req) - o.response = Ruwiki::Handler::WEBrickResponse.new(res) - end - end - end - - # Returns the handler's request object. - attr_accessor :request - # Returns the handler's response object. - attr_accessor :response - - # Creates the handler pair. - def initialize(&block) #:yields: self - @request = nil - @response = nil - yield self if block_given? - end - - # Essentially a clone of WEBrick::Cookie for use with Ruwiki. - class Cookie - attr_reader :name - attr_accessor :value - attr_accessor :version - - FIELDS = %w(domain path secure comment max_age expires) - - FIELDS.each { |field| attr_accessor field.intern } - - def initialize(name, value) - @name = name - @value = value - @version = 0 # Netscape Cookie - - FIELDS.each { |field| instance_variable_set("@#{field}", nil) } - - yield self if block_given? - end - - def expires=(t) #:nodoc: - @expires = if t.nil? or t.kind_of?(Time) - t - else - Time.parse(t.to_s) - end - end - - def to_s - ret = "#{@name}=#{@value}" - ret << "; Version=#{@version.to_s}" if @version > 0 - ret << "; Domain=#{@domain}" if @domain - ret << "; Expires=#{CGI::rfc1123_date(@expires)}" if @expires - ret << "; Max-Age=#{CGI::rfc1123_date(@max_age)}" if @max_age - ret << "; Comment=#{@comment}" if @comment - ret << "; Path=#{@path}" if @path - ret << "; Secure" if @secure - ret - end - end - - # Represents an abstract incoming request. This insulates the rest of - # the code from knowing whether parameters are passed as part of the - # path, as parameters in the URL, or in some other fashion. - class AbstractRequest - def initialize(*args) - end - end - - # Handles all requests from web applications. - # - # Subclasses should provide: - # @parameters:: Hash-like object that responds to #[] and #hash_key?] - # @environment:: Hash-like object that responds to #[] - class AbstractWebRequest < AbstractRequest - # The parameters provided via the web request. - attr_reader :parameters - # The environment provided to the web request. - attr_reader :environment - # The request path. - attr_reader :path - - # The list of cookies. - attr_reader :cookies - - def each_parameter #:yields parameter, value: - @parameters.each { |kk, vv| yield kk, vv } - end - - def each_environment #:yields variable, value - @environment.each { |kk, vv| yield kk, vv } - end - - def each_cookie #:yields name, value: - @cookies.each { |kk, vv| yield kk, vv } - end - - # Return the URL of our server. - def server_url - res = "http://" # should detect whether we're in secure server mode. - if @environment['HTTP_HOST'] - res << @environment['HTTP_HOST'] - else - res << "#{@environment['SERVER_NAME']}:#{@environment['SERVER_PORT']}" - end - end - - # Return the URL of this script. - def script_url - server_url << @environment['SCRIPT_NAME'].to_s - end - - # Return the URL of this request. - def request_url - res = script_url - res << @environment['PATH_INFO'] if @environment['PATH_INFO'] - query = @environment['QUERY_STRING'] - res << "?#{@environment['QUERY_STRING']}" if query && !query.empty? - res - end - - # Convert a file path into a URL - def make_url(project, path) - "#{server_url}/#{project}/#{path}" - end - - def determine_request_path - @path = "" - return @path if @environment['PATH_INFO'].nil? - @path = @environment['PATH_INFO'].dup - end - end - - # Request for CGI-based activity to ruwiki. - class CGIRequest < AbstractWebRequest - def initialize(cgi, output_stream = $stdout) - @environment = ENV - @cgi = cgi - @parameters = {} - cgi.params.each { |kk, vv| @parameters[kk] = vv[0] } - @cookies = {} - cgi.cookies.each do |name, cookie| - @cookies[name] = Ruwiki::Handler::Cookie.new(name, cookie.value) do |oc| - oc.version = cookie.version if cookie.respond_to?(:version) - oc.domain = cookie.domain - oc.path = cookie.path - oc.secure = cookie.secure - oc.comment = cookie.comment if cookie.respond_to?(:comment) - oc.expires = cookie.expires - end - end - super - end - end - - # Request for WEBrick based servlet activity to ruwiki. - class WEBrickRequest < AbstractWebRequest - def initialize(req) - @environment = req.meta_vars - @parameters = req.query - @cookies = {} - req.cookies.each do |rqc| - @cookies[rqc.name] = Ruwiki::Handler::Cookie.new(rqc.name, rqc.value) do |oc| - oc.version = rqc.version - oc.domain = rqc.domain - oc.path = rqc.path - oc.secure = rqc.secure - oc.comment = rqc.comment - oc.expires = rqc.expires - oc.max_age = rqc.max_age - end - end - super - end - end - - # Used to write responses in different execution environments such as - # CGI and Webrick. - # - # If you want to create a new response object, you'll need to implement - # #add_header, #write_headers, #write_cookies, and #<<. - # - # The Response object is instantiated with an output stream which must - # supply +<<+ and +puts+ methods. - class AbstractResponse - # Add to the list of headers to be sent back to the client. - def add_header(key, value) - raise "Not implemented" - end - - # Write the accumulated headers back to the client. - def write_headers - raise "Not implemented" - end - - # Write the string to the client. - def <<(string) - raise "Not implemented" - end - - def add_cookies(*cookies) - cookies.each do |cookie| - @cookies << cookie - end - end - - def write_cookies - raise "Not implemented" - end - - # output_stream must respond to #<< and #puts. - def initialize(output_stream = $stdout) - @headers = {} - @cookies = [] - @written = false - @status = nil - @output_stream = output_stream - end - - def written? - @written - end - end - - # CGIResponse is the response object for CGI mode. - class CGIResponse < AbstractResponse - # output_stream must respond to #<< and #puts. - def initialize(cgi, output_stream = $stdout) - @cgi = cgi - @done = { - :headers => false, - :cookies => false, - :body => false - } - super(output_stream) - end - - # Add the header pair for later output as a CGI header. - def add_header(key, value) - @headers[key] = value - end - - # Write the headers to the stream. The headers can only be written - # once. - def write_headers - return if @done[:headers] - @headers.each { |key, value| @output_stream.puts "#{key}: #{value}\r\n" } - write_cookies - @output_stream.puts - @done[:headers] = true - end - - # Write the cookies to the stream. The cookies can only be written - # once. - def write_cookies - return if @done[:cookies] - @cookies.each do |cookie| - @output_stream.puts "Set-Cookie: #{cookie.to_s}" - end - @done[:cookes] = true - end - - # Output the string to the stream provided. - def <<(string) - @output_stream << string - @written = true - end - - def write_status(status) - unless status.nil? - @output_stream << status - @written = true - end - end - end - - # WEBrickResponse is the response object for WEBrick servlet mode. - class WEBrickResponse < AbstractResponse - def initialize(webrick_response) - @response = webrick_response - @cookies = [] - @done = { - :headers => false, - :cookies => false, - :body => false - } - end - - def add_header(key, value) - @response[key] = value - end - - # Copy the cookies into the WEBrick::HTTPResponse cookies array. - def write_cookies - return if @done[:cookies] - @cookies.each do |cookie| - @response.cookies << cookie.to_s - end - @done[:cookes] = true - end - - def write_headers - write_cookies - # Webrick will take care of this on its own. - end - - def <<(string) - @response.body << string.to_s - @written = true - end - - def write_status(status) - unless status.nil? - match = %r{^HTTP/(?:\d|\.)+ (\d+) .*}.match(status) - @response.status = match.captures[0] - @response.body << status - @written = true - end - end - end -end diff --git a/ruwiki/tags/release-0.9.0/lib/ruwiki/lang/de.rb b/ruwiki/tags/release-0.9.0/lib/ruwiki/lang/de.rb deleted file mode 100644 index b9db0ef..0000000 --- a/ruwiki/tags/release-0.9.0/lib/ruwiki/lang/de.rb +++ /dev/null @@ -1,339 +0,0 @@ -#-- -# Ruwiki -# Copyright © 2002 - 2004, Digikata and HaloStatue -# Alan Chen (alan@digikata.com) -# Austin Ziegler (austin@halostatue.ca) -# Translation by Christian Neukirchen (chneukirchen@yahoo.de) on 22oct2003 -# Updated by Christian Neukirchen (purl.org/net/chneukirchen) on 27aug2004 -# Updated by Christian Neukirchen (purl.org/net/chneukirchen) on 09nov2004 -# -# Licensed under the same terms as Ruby. -# -# $Id$ -#++ -module Ruwiki::Lang - # Ruwiki::Lang::DE is the German-language output module. It contains a - # hash, *Message*, that contains the messages that may be reported by - # any method in the Ruwiki library. The messages are identified by a - # Symbol. - module DE - Message = Hash.new { |hh, kk| hh[kk] = "Sprachdatei-FEHLER: Unbekannter Nachrichten-Typ #{k.inspect}."; hh[kk] } - message = { - # The encoding for the webpages. This should match the encoding used - # to create these messages. - :charset_encoding => "iso-8859-15", - # Backend-related messages. - :backend_unknown => "Unbekanntes Backend %1$s.", - :cannot_create_project => "Kann %1$s nicht erstellen: %2$s", - :cannot_destroy_project => "Kann %1$s nicht zerstören: %2$s", - :cannot_destroy_topic => "Kann %1$s::%2$s nicht zerstören: %3$s", - :cannot_obtain_lock => "Kann keine Sperre für %1$s::%2$s erhalten. Bitte in Kürze nochmal versuchen.", - :cannot_release_lock => "Kann die Sperre für %1$s::%2$s nicht lösen. Bitte später nochmal versuchen.", - :cannot_retrieve_topic => "Kann auf %1$s::%2$s nicht zugreifen: %3$s", - :cannot_store_topic => "Kann %1$s::%2$s nicht speichern: %3$s", - :cannot_list_topics => "Kann Themen für Projekt %1$s nicht auflisten: %2$s", - :error_creating_lock => "Fehler beim Erzeugen der Sperre von %1$s::%2$s: %3$s", - :error_releasing_lock => "Fehler beim Lösen der Sperre von %1$s::%2$s: %3$s", - :flatfiles_no_data_directory => "Das Daten-Verzeichnis (%1$s) existiert nicht.", - :no_access_list_projects => "Keine Berechtigung zum Auflisten der Projekte.", - :no_access_list_topics => "Keine Berechtigung zum Auflisten der Themen von Projekt %1$s.", - :no_access_to_create_project => "Keine Berechtigung um Projekt %1$s zu erzeugen.", - :no_access_to_destroy_project => "Keine Berechtigung um Projekt %1$s zu zerstören.", - :no_access_to_destroy_topic => "Keine Berechtigung um Thema %1$s::%2$s zu zerstören.", - :no_access_to_read_topic => "Keine Berechtigung um Thema %1$s::%2$s zu lesen.", - :no_access_to_store_topic => "Keine Berechtigung um Thema %1$s::%2$s zu speichern.", - :page_not_in_backend_format => "%1$s::%2$s ist in einem von Backend %3$s nicht unterstütztem Format.", - :project_already_exists => "Project %1$s existiert bereits.", - :project_does_not_exist => "Project %1$s existiert nicht.", - :search_project_fail => "Suche in Projekt %1$s nach Zeichenkette %2$s gescheitert.", - :yaml_requires_182_or_higher => "YAML-Flatfile-Support existiert nur für Ruby 1.8.2 oder höher.", - :not_editing_current_version => <<EOM , -Sie haben eine alte Version von %1$s::%2$s abgeschickt. Die Unterschiede -zwischen ihrer und der jetzigen Version wurden kombiniert. Konfliktierende -Zeilen zeigen beide Zeilen. Bitte gehen sie sicher, dass sie die gesammte -Seite bearbeitet haben bevor sie nochmals speichern. -EOM - :no_empty_search_string => <<EOM , -Das Suchfeld darf nicht leer sein. Bitte etwas eingeben bevor der Suchknopf -gedrückt wird. -EOM - :page_is_locked => "Die Seite ist bereits zur Bearbeitung gesperrt. Bitte warte ein paar Minuten und versuche es dann noch ein mal.", - - # Config-related messages. - :config_not_ruwiki_config => "Die Konfiguration muss von Typ der Klasse Ruwiki::Config sein.", - :invalid_template_dir => "Der angegebene Pfad für Schablonen (%1$s) existiert nicht oder ist kein Verzeichnis.", - :no_template_found => "Keine Schablone %1$s im Schablonen-Set '%2$s' gefunden.", - :no_template_set => "Es gibt kein Schablonen-Set '%1$s' im Schablonen-Pfad.", - :no_webmaster_defined => "Konfigurations-Fehler: Kein Webmaster definiert.", - # Miscellaneous messages. - :complete_utter_failure => "Fataler Fehler", - :editing => "Editieren", - :error => "Fehler", - :invalid_path_info_value => "Fataler Fehler in der Web-Umgebung. PATH_INFO = %1$s", - # Should this really get translated? --chris - :render_arguments => "Ruwiki#render muss mit zwei oder mehr Argumenten aufgerufen werden.", - :unknown_feature => "Unbekanntes Feature %1$s.", - :topics_for_project => "Themen for Projekt ::%1$s", - :project_topics_link => "(Themen)", - :wiki_projects => "Projekte in %1$s", - :no_projects => "Keine Projekte bekannt.", - :no_topics => "Keine Themen in Projekt %1$s.", - :search_results_for => "= Suchergebnisse für: %1$s", - :number_of_hits => "%d Treffer", - - # Labels - :label_search_project => "Durchsuche Projekt", - :label_search_all => "Alles", - :label_search => "Suche: ", - :label_project => "Projekt: ", - :label_topic => "Thema: ", - :label_edit => "Editieren", - :label_recent_changes => "Aktuelle Änderungen", - :label_topics => "Themen", - :label_projects => "Projekte", - :label_editing => "Editieren", - :label_text => "Text:", - :label_text_accelerator => "T", - :label_edit_comment => "Anmerkung: ", - :label_comment_accelerator => "R", - :label_save => "Speichern", - :label_save_accelerator => "S", - :label_cancel => "Abbrechen", - :label_cancel_accelerator => "A", - :label_preview => "Vorschau", - :label_preview_accelerator => "V", - :label_original_text => "Ursprüngliche Version", - :label_raw => "Formatfrei", - :label_formatted => "Formatiert", - :label_send_report_by => "Schicken Sie dem Webmaster einen Report via Email.", - :label_send_report => "Report schicken.", - :label_saved_page => "Gespeicherte Seite: ", - - # Note to translators: certain words should be left alone. These - # will be marked in comments. Description lines are restricted to 40 - # characters and should be an array. Use this as a ruler. - # => [ "----------------------------------------" ] - :converter_usage => "Benutzung: %1$s [Optionen] <Verzeichnis>+", - :converter_format_desc => [ "Konvertiert gefundene Dateien (Jetziges", - "Format egal) in das angegebene Format", - "Standard ist flatfiles. Erlaubte", - "Formate sind: yaml marshal flatfiles" ], - :converter_backup_desc => [ "Erzeugt Backups der aktualisierten", - "Dateien. Standard ist --backup." ], - :converter_backupext_desc => [ 'Gibt die Backup-Erweiterung an. Standard', - 'ist "~", das dem Datendateinamen', - 'angehängt wird.' ], - :converter_backupext_error => "Die Backup-Erweiterung darf nicht leer sein.", - :converter_extension_desc => [ "Gibt die Erweiterung der Ruwiki-", - "Datendateien an. Standard ist .ruwiki" ], - :converter_extension_error => "Die Erweiterung darf nicht leer sein.", - :converter_noextension_desc => [ "Gibt an, dass Ruwiki-Datendateien", - "keine Dateierweiterung haben." ], - :converter_quiet_desc => [ "Still sein. Standard sind normale", - "Mitteilungen." ], - :converter_language_desc => [ "Sprache auf LANG setzen. Standard ist", - "en (Englisch). Bekannte Sprachen sind:", - "en es de" ], - :converter_verbose_desc => [ "Gesprächig sein. Standard sind normale", - "Mitteilungen." ], - :converter_help_desc => [ "Diesen Text zeigen." ], - :converter_num_arguments => "Fehler: Nicht genug Parameter.", - :converter_directory => "Verzeichnis", - :converter_converting_from => "Wandle von %1$s nach %2$s um... ", - :converter_done => "fertig.", - :converter_not_ruwiki => "Keine Ruwiki-Datei; übersprungen.", - :converter_nosave_modified => "Kann veränderte Datei %1$s nicht speichern.", - :converter_page_format_error => "Fehler: Kann Seitenformat nicht erkennen.", - - # Messages from Ruwiki::Utils::Manager - :manager_unknown_command => "Unbekannter Befehl: %1$s", - :manager_help_commands => <<EOH , -Es gibt diese 'ruwiki'-Befehle: - - ruwiki install Standard-Entwicklungspaket installieren. - ruwiki package Ruwiki-Installation einpacken. - ruwiki unpackage Ruwiki-Installation auspacken. - ruwiki service Win32::Service für Ruwiki verwalten. - -EOH - :manager_help_help => <<-EOH , -Diese Hilfsnachricht zeigt, wie man mehr Informationen zu diesem -Kommandozeilenwerkzeug erhalten kann: - - ruwiki help commands Alle 'ruwiki' Befehle anzeigen. - ruwiki help <BEFEHL> Hilfe zu <BEFEHL> zeigen. - (e.g., 'ruwiki help install') - -EOH - :manager_missing_parameter => "Fehlender Parameter für Option: %1$s", - :manager_dest_not_directory => "Das Ziel (%1$s) ist kein Verzeichnis.", - :manager_install_help => <<-EOH , - ruwiki install [OPTIONEN] [--to ZIEL] - -Erzeugt eine neue Ruwiki-Instanz. Standardmäßig installiert dies die Daten, -Schablonen und eine Standard-Konfigurationsdatei im derzeitigen Verzeichnis. -Das Ziel kann mit --to geändert werden, und was installiert werden soll mit -der OPTIONEN-Liste. Die Elemente der OPTIONEN-Liste dürfen durch Leerzeichen, -Komma oder Semikola getrennt werden. Daher haben - - ruwiki install data;servlet - ruwiki install data,servlet - ruwiki install data servlet - -alle die gleiche Wirkung. Die Groß-/Kleinschreibung spielt keine Rolle. -Die OPTIONEN sind: - - servlet # Den Ruwiki servlet stub installieren - service # Den Ruwiki Win32::Service stub installieren - CGI # Das Ruwiki CGI-Skript installieren - data # Ruwiki-Daten, Schablonen, und Konfiguration installieren - -Optionen können durch voranstellen von '-' oder 'no' abgeschaltet werden: - - ruwiki install cgi -data - ruwiki install cgi nodata - -Dies würde das CGI-Skript, nicht aber die Daten installieren. -EOH - :manager_package_help => <<-EOH , - ruwiki package [QUELL] [--output PAKET] [--replace] - ruwiki package [QUELL] [-o PAKET] [--replace] - -Packt die Ruwiki-Dateien (Daten, Schablonen und Programme) vom angegebenen -QUELL-Verzeichnis oder dem derzeitigen Verzeichnis in das angegebene Paket -(oder "./%1$s"). Sollte QUELL eine Ruwuki-Konfigurationsdatei sein (z.B. -"%2$s"), dann wird sie verwendet, um Ort und Name der Daten- und Schablonen- -Verzeichnisse zu erfahren. - - MERKE: Der Einpack-Prozess normalisiert die Daten- und Schablonen- - Verzeichnisnamen relativ zum Einpackverzeichnis. Es werden - niemals absolute Pfade sein. -EOH - :manager_unpackage_help => <<-EOH , - ruwiki unpackage [QUELL] [--output VERZEICHNIS] - ruwiki unpackage [QUELL] [-o VERZEICHNIS] - -Entpackt das gegebene Rukwiki-Paket (Standard: "./%1$s") in das angebene -Verzeichnis (oder "."). -EOH - :manager_service_broken => "Kann keinen Win32-Service verwalten, wenn Win32::Service nicht installiert ist.", - :manager_service_lo_argcount => "Ungenügene Parameteranzahl: %1$s", - :manager_service_hi_argcount => "Zu viele Parameter: %1$s", - :manager_service_help => <<-EOH , - ruwiki service install NAME [BESCHREIBUNG] [Optionen] - ruwiki service start NAME - ruwiki service stop NAME - ruwiki service delete NAME - -Verwaltet das Ruwiki WEBrick servlet als Windows-Service. Der Service muss -benannt (NAME) sein. install unterstützt folgende zusätzliche Optionen: - - --rubybin RUBYPFAD Der Pfad zum Ruby-Binärverzeichnis. - --exec SERVICEPFAD Der Pfad zum Service-Programm. - --home PFADNACHAHAUSE Der Pfad zum Heimverzeichnis. -EOH - :manager_package_exists => "Das Paket %1$s existiert bereits.", - :manager_service_installed => "Service %1$s installiert.", - :manager_one_moment => "Moment, %1$s ...", - :manager_service_started => "Service %1$s gestartet.", - :manager_service_stopped => "Service %1$s gestoppt.", - :manager_service_deleted => "Service %1$s gelöscht.", - - # Messages from Ruwiki::Utils::Converter - # Note to translators: certain words should be left alone. These - # will be marked in comments. Description lines are restricted to 40 - # characters and should be an array. Use this as a ruler. - # => [ "----------------------------------------" ] - :runner_usage => "Verwendung: %1$s [Optionen]", - :runner_general_options => "Allgemeine Optionen:", - :runner_saveconfig_desc => [ "Sichert die Konfiguration nach FILENAME", - "und beendet. Falls FILENAME nicht", - "gegben ist, wird die Standardkonfig-", - "urationsdatei verwendet. Alle Optionen", - "werden von der bestehenen Konfiguration", - "und der Kommandozeile und gesichert.", - "Das Servlet wird nicht gestartet.", - "Der Standardname ist:" ], - :runner_config_desc => [ "Standardkonfiguration von FILENAME", - "statt der Standardkonfigurationsdatei", - "lesen. Optionen die bislang gesetzt", - "wurden werden zu den Werten, die in der", - "Konfigurationsdatei stehen,", - " zurückgesetzt." ], - :runner_webrick_options => "WEBrick-Optionen:", - :runner_port_desc => [ "Lässt das Ruwiki-Servlet auf dem gegebenen", - "Port laufen. Standard: 8808." ], - :runner_address_desc => [ "Schränkt das Ruwiki-Servlet so ein, dass", - "es nur die (Komma-separierten) Adressen", - "akzepiert. Kann mehrfach angegeben werden", - "Standardmäßig wird nicht eingeschränkt." ], - :runner_local_desc => [ "Lässt das Ruwiki-Servlet nur lokale", - "Verbindungen akzeptieren (127.0.0.1).", - "Hebt vorige -A Adressen auf." ], - :runner_mountpoint_desc => [ "Die relative URI unter der Ruwiki", - 'zugreifbar wird. Standard: "/".' ], - :runner_log_desc => [ "Protokolliere WEBrick. Standard ist --log." ], - :runner_logfile_desc => [ "Die Datei, in die das WEBrick-Protokoll", - "geschrieben wird. Standard: Standard-", - "fehlerausgabe." ], - :runner_threads_desc => [ "Setzt den WEBrick-Threadcount." ], - :runner_ruwiki_options => "Ruwiki-Optionen:", - :runner_language_desc => [ 'Wählt die Oberflächensprache für Ruwiki.', - 'Standard: "en". Kann "en", "de", oder', - '"es" sein.' ], - :runner_webmaster_desc => [ 'Die Ruwiki-Wwebmaster Email-Adresse.', - 'Standard: "webmaster@domain.tld".' ], - :runner_debug_desc => [ 'Aktiviert Ruwuki-Debugging. Standard:', - '--no-debug.' ], - :runner_title_desc => [ 'Gibt den Ruwiki-Titel an. Standard ist', - '"Ruwiki".' ], - :runner_defaultpage_desc => [ 'Eine andere Standardseite. Standard ist', - '"ProjectIndex".' ], - :runner_defaultproject_desc => [ 'Eine andere Standardprojektseite.', - 'Standard ist "Default".' ], - :runner_templatepath_desc => [ 'Ort, an dem Ruwiki-Schablonen sind.', - 'Standard ist "./templates".' ], - :runner_templatename_desc => [ 'Name der Ruwiki-Schablonen. Default', - 'Standard ist "default".' ], - :runner_cssname_desc => [ 'Name der CSS-Datei im Schablonenpfad', - 'Standard ist "ruwiki.css".' ], - :runner_storage_desc => [ 'Wähle den Speichertyp:' ], - :runner_datapath_desc => [ 'Ort, an dem Datendateien gespeichert sind.', - 'Standard ist "./data".' ], - :runner_extension_desc => [ 'Dateierweiterung für Datendateien.', - 'Standard ist "ruwiki".' ], - :runner_central_desc => [ 'Lässt Ruwiki mit den Daten des Standard-', - 'RubyGem-Orts laufen .' ], - :runner_general_info => "Allgemeine Information:", - :runner_help_desc => [ "Zeigt diesen Text an." ], - :runner_version_desc => [ "Zeigt die Ruwuki-Version." ], - :runner_rejected_address => "Adresse %1$s abgewiesen. Nur Verbindungen von %2$s werden akzeptiert.", - :runner_banner => <<-BANNER , -%1$s - -WEBrick-Optionen: - Port %2$d - Erlaubte Adressen %3$s - Mount Point %4$s - Protokollieren? %5$s - Protokollpfad %6$s - Threads %7$s - -Ruwiki-Options: - Webmaster %8$s - Debugging? %9$s - Titel %10$s - Standardprojekt %11$s - Standardseite %12$s - Schablonenpfad %13$s - Schablone %14$s - CSS-Datei %15$s - - Speichertyp %16$s - Datenpfad %17$s - Dateierweiterung %18$s -BANNER - } - message.each { |kk, vv| Message[kk] = vv } - end -end diff --git a/ruwiki/tags/release-0.9.0/lib/ruwiki/lang/en.rb b/ruwiki/tags/release-0.9.0/lib/ruwiki/lang/en.rb deleted file mode 100644 index de0771a..0000000 --- a/ruwiki/tags/release-0.9.0/lib/ruwiki/lang/en.rb +++ /dev/null @@ -1,334 +0,0 @@ -#-- -# Ruwiki -# Copyright © 2002 - 2004, Digikata and HaloStatue -# Alan Chen (alan@digikata.com) -# Austin Ziegler (austin@halostatue.ca) -# -# Licensed under the same terms as Ruby. -# -# $Id$ -#++ -module Ruwiki::Lang - # Ruwiki::Lang::EN is the English-language output module. It contains a - # hash, *Message*, that contains the messages that may be reported by - # any method in the Ruwiki library. The messages are identified by a - # Symbol. - module EN - Message = Hash.new { |hh, kk| hh[kk] = "Language ERROR: Unknown message key #{kk.inspect}."; hh[kk] } - message = { - # The encoding for the webpages. This should match the encoding used - # to create these messages. - :charset_encoding => "iso-8859-15", - # Backend-related messages. - :backend_unknown => "Backend %1$s is unknown.", - :cannot_create_project => "Cannot create project %1$s: %2$s", - :cannot_destroy_project => "Cannot destroy project %1$s: %2$s", - :cannot_destroy_topic => "Cannot destroy %1$s::%2$s: %3$s", - :cannot_obtain_lock => "Unable to obtain a lock on %1$s::%2$s. Try again shortly.", - :cannot_release_lock => "Unable to release the lock on %1$s::%2$s. Try again shortly.", - :cannot_retrieve_topic => "Cannot retrieve %1$s::%2$s: %3$s", - :cannot_store_topic => "Cannot store %1$s::%2$s: %3$s", - :cannot_list_topics => "Cannot list topics for project %1$s: %2$s", - :error_creating_lock => "Error creating lock on %1$s::%2$s: %3$s", - :error_releasing_lock => "Error releasing lock on %1$s::%2$s: %3$s", - :flatfiles_no_data_directory => "The data directory (%1$s) does not exist.", - :no_access_list_projects => "No permission to list projects.", - :no_access_list_topics => "No permission to list topics in project %1$s.", - :no_access_to_create_project => "No permission to create project %1$s.", - :no_access_to_destroy_project => "No permission to destroy project %1$s::%2$s.", - :no_access_to_destroy_topic => "No permission to destroy topic %1$s::%2$s.", - :no_access_to_read_topic => "No permission to retrieve the %1$s::%2$s.", - :no_access_to_store_topic => "No permission to store the %1$s::%2$s.", - :page_not_in_backend_format => "%1$s::%2$s is not in the format supported by the backend %3$s.", - :project_already_exists => "Project %1$s already exists.", - :project_does_not_exist => "Project %1$s does not exist.", - :search_project_fail => "Failure searching project %1$s with string %2$s.", - :yaml_requires_182_or_higher => "YAML flatfile support exists only for Ruby version 1.8.2 or higher.", - :not_editing_current_version => <<EOM , -You have submitted an old version of %1$s::%2$s. The differences between -your version and the current version of this page have been merged. -Conflicting lines have both lines shown. Please ensure that you have edited -the entire page before saving again. -EOM - :no_empty_search_string => <<EOM , -The search field may not be empty. Please enter something in the search box -before pressing the search button. -EOM - :page_is_locked => "The page is locked for editing. Please wait a few minutes and try again.", - - # Config-related messages. - :config_not_ruwiki_config => "Configuration must be of class Ruwiki::Config.", - :invalid_template_dir => "The specified path for templates (%1$s) does not exist or is not a directory.", - :no_template_found => "No template of %1$s found in template set %2$s.", - :no_template_set => "There is no template set '%1$s' in the template path.", - :no_webmaster_defined => "Configuration error: Webmaster is unset.", - # Miscellaneous messages. - :complete_utter_failure => "Complete and Utter Failure", - :editing => "Editing", - :error => "Error", - :invalid_path_info_value => "Something has gone seriously wrong with the web environment. PATH_INFO = %1$s", - :render_arguments => "Ruwiki#render must be called with zero or two arguments.", - :unknown_feature => "Unknown feature %1$s.", - :topics_for_project => "Topics for Project ::%1$s", - :project_topics_link => "(topics)", - :wiki_projects => "Projects in %1$s", - :no_projects => "No known projects.", - :no_topics => "No topics in project %1$s.", - :search_results_for => "= Search results for: %1$s", - :number_of_hits => "%1$d Hits", - - # Labels - :label_search_project => "Search Project", - :label_search_all => "All", - :label_search => "Search: ", - :label_project => "Project: ", - :label_topic => "Topic: ", - :label_edit => "Edit", - :label_recent_changes => "Recent Changes", - :label_topics => "Topics", - :label_projects => "Projects", - :label_editing => "Editing", - :label_text => "Text:", - :label_text_accelerator => "T", - :label_edit_comment => "Edit Comment: ", - :label_comment_accelerator => "O", - :label_save => "Save", - :label_save_accelerator => "S", - :label_cancel => "Cancel", - :label_cancel_accelerator => "C", - :label_preview => "Preview", - :label_preview_accelerator => "P", - :label_original_text => "Original Text", - :label_raw => "Raw", - :label_formatted => "Formatted", - :label_send_report_by => "Send the Wiki maintainer a report by email.", - :label_send_report => "Send report.", - :label_saved_page => "Saved page: ", - - # Messages from Ruwiki::Utils::Converter - # Note to translators: certain words should be left alone. These - # will be marked in comments. Description lines are restricted to 40 - # characters and should be an array. Use this as a ruler. - # => [ "----------------------------------------" ] - :converter_usage => "Usage: %1$s [options] <directory>+", - :converter_format_desc => [ "Converts encountered files (regardless", - "of the current format), to the specified", - "format. Default is flatfiles. Allowed", - "formats are: yaml marshal flatfiles" ], - :converter_backup_desc => [ "Create backups of upgraded files.", - "Default is --backup." ], - :converter_backupext_desc => [ 'Specify the backup extension. Default', - 'is "~", which is appended to the data', - 'filename.' ], - :converter_backupext_error => "The backup extension must not be empty.", - :converter_extension_desc => [ "Specifies the extension of Ruwiki data", - "files. The default is .ruwiki" ], - :converter_extension_error => "The extension must not be empty.", - :converter_noextension_desc => [ "Indicates that the Ruwiki data files", - "have no extension." ], - :converter_quiet_desc => [ "Runs quietly. Default is to run with", - "normal messages." ], - :converter_language_desc => [ "Sets the language to LANG. Defaults", - "to en (English). Known languages", - "are: en es de" ], - :converter_verbose_desc => [ "Runs with full message. Default is to", - "run with normal messages." ], - :converter_help_desc => [ "Shows this text." ], - :converter_num_arguments => "Error: not enough arguments.", - :converter_directory => "directory", - :converter_converting_from => "converting from %1$s to %2$s ... ", - :converter_done => "done.", - :converter_not_ruwiki => "not a Ruwiki file; skipping.", - :converter_nosave_modified => "cannot save modified %1$s.", - :converter_page_format_error => "Error: Cannot detect the page format.", - - # Messages from Ruwiki::Utils::Manager - :manager_unknown_command => "Unknown command: %1$s", - :manager_help_commands => <<EOH , -The commands known to 'ruwiki' are: - - ruwiki install Installs the default deployment package. - ruwiki package Packages a Ruwiki installation. - ruwiki unpackage Unpackages a Ruwiki installation. - ruwiki service Manages a Win32::Service for Ruwiki. - -EOH - :manager_help_help => <<-EOH , -This is a basic help message containing pointers to more information on how -to use this command-line tool. Try: - - ruwiki help commands list all 'ruwiki' commands - ruwiki help <COMMAND> show help on <COMMAND> - (e.g., 'ruwiki help install') - -EOH - :manager_missing_parameter => "Missing parameter for option: %1$s", - :manager_dest_not_directory => "The destination (%1$s) is not a directory.", - :manager_install_help => <<-EOH , - ruwiki install [OPTIONS] [--to DEST] - -Creates a new Ruwiki instance. By default this installs the data, templates, -and a default configuration file to the current directory. The destination -can be changed with the --to option, and what is installed can be specified -with the OPTIONS list. The OPTIONS list may be space, comma, or semi-colon -separated. Thus, - - ruwiki install data;servlet - ruwiki install data,servlet - ruwiki install data servlet - -are all equivalent. The options may be specified in any case. The -installation OPTIONS are: - - servlet # Installs the Ruwiki servlet stub - service # Installs the Ruwiki Win32::Service stub - CGI # Installs the Ruwiki CGI script - data # Installs the Ruwiki data, templates, and configuration - -Options may be disabled with by prepending a dash or 'no': - - ruwiki install cgi -data - ruwiki install cgi nodata - -These will install the CGI script but not the data. -EOH - :manager_package_help => <<-EOH , - ruwiki package [SOURCE] [--output PACKAGE] [--replace] - ruwiki package [SOURCE] [-o PACKAGE] [--replace] - -Packages the Ruwiki files (data, templates, and executables) from the -specified SOURCE or the current directory into the specified output package -(or "./%1$s"). If the SOURCE is a ruwiki configuration file (e.g., -"%2$s"), then that will be used to determine the location and name of -the data and template directories. - - NOTE: The packaging process will normalize the data and templates - directory names to be relative to the unpacking directory. They - will NEVER be absolute paths. -EOH - :manager_unpackage_help => <<-EOH , - ruwiki unpackage [SOURCE] [--output DIRECTORY] - ruwiki unpackage [SOURCE] [-o DIRECTORY] - -Unpackages the provided Ruwiki package (default "./%1$s") into the -specified directory (default "."). -EOH - :manager_service_broken => "Cannot manage a Win32 service if Win32::Service is not installed.", - :manager_service_lo_argcount => "Insufficient arguments: %1$s", - :manager_service_hi_argcount => "Too many arguments: %1$s", - :manager_service_help => <<-EOH , - ruwiki service install NAME [DESCRIPTION] [options] - ruwiki service start NAME - ruwiki service stop NAME - ruwiki service delete NAME - -Manages the Ruwiki WEBrick servlet as a Windows service. The service must be -NAMEd. install supports the following additional options: - - --rubybin RUBYPATH The path to the Ruby binary. - --exec SERVICEPATH The path to the service executable. - --home PATHTOHOME The path to the home directory. -EOH - :manager_package_exists => "Package %1$s already exists.", - :manager_service_installed => "%1$s service installed.", - :manager_one_moment => "One moment, %1$s ...", - :manager_service_started => "%1$s service started.", - :manager_service_stopped => "%1$s service stopped.", - :manager_service_deleted => "%1$s service deleted.", - - # Messages from Ruwiki::Utils::Converter - # Note to translators: certain words should be left alone. These - # will be marked in comments. Description lines are restricted to 40 - # characters and should be an array. Use this as a ruler. - # => [ "----------------------------------------" ] - :runner_usage => "Usage: %1$s [options]", - :runner_general_options => "General options:", - :runner_saveconfig_desc => [ "Saves the configuration to FILENAME and", - "exit. If FILENAME is not used, then the", - "default configuration file will be", - "used. All options will be read from the", - "existing configuration file and the", - "command-line and saved. The servlet", - "will not start. The default name is:" ], - :runner_config_desc => [ "Read the default configuration from", - "FILENAME instead of the default config", - "file. Options set until this point will", - "be reset to the values from those read", - "configuration file." ], - :runner_webrick_options => "WEBrick options:", - :runner_port_desc => [ "Runs the Ruwiki servlet on the specified", - "port. Default 8808." ], - :runner_address_desc => [ "Restricts the Ruwiki servlet to accepting", - "connections from the specified address or", - "(comma-separated) addresses. May be", - "specified multiple times. Defaults to all", - "addresses." ], - :runner_local_desc => [ "Restricts the Ruwiki servlet to accepting", - "only local connections (127.0.0.1).", - "Overrides any previous -A addresses." ], - :runner_mountpoint_desc => [ "The relative URI from which Ruwiki will", - 'be accessible. Defaults to "/".' ], - :runner_log_desc => [ "Log WEBrick activity. Default is --log." ], - :runner_logfile_desc => [ "The file to which WEBrick logs are", - "written. Default is standard error." ], - :runner_threads_desc => [ "Sets the WEBrick threadcount." ], - :runner_ruwiki_options => "Ruwiki options:", - :runner_language_desc => [ 'The interface language for Ruwiki.', - 'Defaults to "en". May be "en", "de", or', - '"es".' ], - :runner_webmaster_desc => [ 'The Ruwiki webmaster email address.', - 'Defaults to "webmaster@domain.tld".' ], - :runner_debug_desc => [ 'Turns on Ruwiki debugging. Defaults', - 'to --no-debug.' ], - :runner_title_desc => [ 'Provides the Ruwiki title. Default is', - '"Ruwiki".' ], - :runner_defaultpage_desc => [ 'An alternate default page. Default is', - '"ProjectIndex".' ], - :runner_defaultproject_desc => [ 'An alternate default project. Default is', - '"Default".' ], - :runner_templatepath_desc => [ 'The location of Ruwiki templates. Default', - 'is "./templates".' ], - :runner_templatename_desc => [ 'The name of the Ruwiki templates. Default', - 'is "default".' ], - :runner_cssname_desc => [ 'The name of the CSS file in the template', - 'path. Default is "ruwiki.css".' ], - :runner_storage_desc => [ 'Select the storage type:' ], - :runner_datapath_desc => [ 'The path where data files are stored.', - 'Default is "./data".' ], - :runner_extension_desc => [ 'The extension for data files.', - 'Default is "ruwiki".' ], - :runner_central_desc => [ 'Runs Ruwiki with the data in the default', - 'RubyGem location.' ], - :runner_general_info => "General info:", - :runner_help_desc => [ "Shows this text." ], - :runner_version_desc => [ "Shows the version of Ruwiki." ], - :runner_rejected_address => "Rejected peer address %1$s. Connections are only accepted from %2$s.", - :runner_banner => <<-BANNER , -%1$s - -WEBrick options: - Port %2$d - Accepted Addresses %3$s - Mount Point %4$s - Logging? %5$s - Log Destination %6$s - Threads %7$s - -Ruwiki options: - Webmaster %8$s - Debugging? %9$s - Title %10$s - Default Project %11$s - Default Page %12$s - Template Path %13$s - Template Set %14$s - CSS Source %15$s - - Storage Type %16$s - Data Path %17$s - Extension %18$s -BANNER - } - message.each { |kk, vv| Message[kk] = vv } - end -end diff --git a/ruwiki/tags/release-0.9.0/lib/ruwiki/lang/es.rb b/ruwiki/tags/release-0.9.0/lib/ruwiki/lang/es.rb deleted file mode 100644 index 4a9ee2a..0000000 --- a/ruwiki/tags/release-0.9.0/lib/ruwiki/lang/es.rb +++ /dev/null @@ -1,339 +0,0 @@ -#-- -# Ruwiki -# Copyright © 2002 - 2004, Digikata and HaloStatue -# Alan Chen (alan@digikata.com) -# Austin Ziegler (austin@halostatue.ca) -# Mauricio Julio Fernández Pradier (batsman.geo@yahoo.com) -# -# Licensed under the same terms as Ruby. -# -# $Id$ -#++ -module Ruwiki::Lang - # Ruwiki::Lang::ES is the English-language output module. It contains a - # hash, *Message*, that contains the messages that may be reported by - # any method in the Ruwiki library. The messages are identified by a - # Symbol. - module ES - Message = Hash.new { |hh, kk| hh[kk] = "ERROR: Identificador de mensaje desconocido: #{kk.inspect}."; hh[kk] } - message = { - # The encoding for the webpages. This should match the encoding used - # to create these messages. - :charset_encoding => "iso-8859-15", - # Backend-related messages. - :backend_unknown => "Backend %1$s desconocido.", - :cannot_create_project => "No pudo crearse el proyecto %1$s: %2$s", - :cannot_destroy_project => "No pudo borrarse el proyecto %1$s: %2$s", - :cannot_destroy_topic => "No pudo borrarse %1$s::%2$s: %3$s", - :cannot_obtain_lock => "No pudo obtenerse el cerrojo para %1$s::%2$s. Reinténtelo de nuevo en breve.", - :cannot_release_lock => "No pudo liberarse el cerrojo para %1$s::%2$s. Reinténtelo de nuevo en breve.", - :cannot_retrieve_topic => "No pudo obtenerse %1$s::%2$s: %3$s", - :cannot_store_topic => "No pudo almacenarse %1$s::%2$s: %3$s", - :cannot_list_topics => "No se pudo listar los temas del proyecto %1$s: %2$s", - :error_creating_lock => "Error al crear el cerrojo para %1$s::%2$s: %3$s", - :error_releasing_lock => "Error al liberar el cerrojo para %1s::%2$s: %3$s", - :flatfiles_no_data_directory => "El directorio de datos (%1$s) no existe.", - :no_access_list_projects => "Permiso denegado al listar los proyectos.", - :no_access_list_topics => "Permiso denegado al listar los temas del proyecto %1$s.", - :no_access_to_create_project => "Permiso denegado al crear el proyecto %1$s.", - :no_access_to_destroy_project => "Permiso denegado al borrar el proyecto %1$s::%2$s.", - :no_access_to_destroy_topic => "Permiso denegado al borrar el borrar el tema %1$s::%2$s.", - :no_access_to_read_topic => "Permiso denegado al acceder a %1$s::%2$s.", - :no_access_to_store_topic => "Permiso denegado al almacenar %1$s::%2$s.", - :page_not_in_backend_format => "%1$s::%2$s no está en un formato soportado por el backend %3$s.", - :project_already_exists => "El proyecto %1$s ya existe.", - :project_does_not_exist => "El proyecto %1$s no existe.", - :search_project_fail => "Error al buscar la cadena %2$s en el proyecto %1$s.", - :yaml_requires_182_or_higher => "El soporte para archivos YAML sólo está disponible en Ruby versión 1.8.2 o superior.", - :not_editing_current_version => <<EOM , -Ha enviado una versión antigua de %1$s::%2$s. Las diferencias entre su versión -y la actual han sido fusionadas. En caso de conflicto, las líneas de ambas -versiones serán mostradas. Asegúrese de editar la página en su totalidad -antes de salvar de nuevo. -EOM - :no_empty_search_string => <<EOM , -El campo de búsqueda no puede estar vacío. Por favor introduzca el texto -a buscar antes de pulsar sobre el botón de búsqueda. -EOM - :page_is_locked => "La pagina no puede ser editada al estar bloqueada en este momento. Por favor espere unos minutos y vuelva a intentar.", - - # Config-related messages. - :config_not_ruwiki_config => "La configuración debe ser de clase Ruwiki::Config.", - :invalid_template_dir => "El path para plantillas (%1$s) no existe o no es un directorio.", - :no_template_found => "No pudo encontrarse la plantilla para %1$s en el conjunto %2$s.", - :no_template_set => "No pudo encontrarse el conjunto de plantillas '%1$s' en el path.", - :no_webmaster_defined => "Error de configuración: Webmaster no está definido.", - # Miscellaneous messages. - :complete_utter_failure => "Error catastrófico", - :editing => "Edición", - :error => "Error", - :invalid_path_info_value => "Algo huele a podrido en su entorno Web. PATH_INFO = %1$s", - :render_arguments => "Ruwiki#render debe ser llamado con cero o dos argumentos.", - :unknown_feature => "Característica desconocida: %1$s.", - :topics_for_project => "Temas del Proyecto ::%1$s", - :project_topics_link => "(temas)", - :wiki_projects => "Proyectos en %1$s", - :no_projects => "Ningún proyecto.", - :no_topics => "El proyecto %1$s no tiene nigún tema.", - :search_results_for => "= Resultados de la búsqueda de: %1$s", - :number_of_hits => "%1$d Resultados", - - # Labels - :label_search_project => "Buscar en projecto", - :label_search_all => "Todo", - :label_search => "Buscar: ", - :label_project => "Proyecto: ", - :label_topic => "Tema: ", - :label_edit => "Editar", - :label_recent_changes => "Cambios recientes", - :label_topics => "Temas", - :label_projects => "Proyectos", - :label_editing => "Edición", - :label_text => "Texto:", - :label_text_accelerator => "T", - :label_edit_comment => "Editar Comentario: ", - :label_comment_accelerator => "O", - :label_save => "Salvar", - :label_save_accelerator => "S", - :label_cancel => "Cancelar", - :label_cancel_accelerator => "C", - :label_preview => "Previsualizar", - :label_preview_accelerator => "P", - :label_original_text => "Text Original", - :label_raw => "Crudo", - :label_formatted => "Formateado", - :label_send_report_by => "Enviar notificación al administrador del Wiki por email.", - :label_send_report => "Enviar notificación.", - :label_saved_page => "Página salvada: ", - - # Messages from Ruwiki::Utils::Converter - # Note to translators: certain words should be left alone. These - # will be marked in comments. Description lines are restricted to 40 - # characters and should be an array. Use this as a ruler. - # => [ "----------------------------------------" ] - :converter_usage => "Modo de empleo: %1$s [opciones] <dir.>", - :converter_format_desc => [ "Convertir los ficheros encontrados", - "(independientemente de su formato), al", - "formato especificado; por defecto ", - "archivos planos. Formatos permitidos:", - " yaml marshal flatfiles" ], - :converter_backup_desc => [ "Crear copias de seguridad de ficheros ", - "actualizados. La opción por defecto es ", - "--backup." ], - :converter_backupext_desc => [ 'Especificar la extensión para las copias', - 'de seguridad (por defecto "~") que se', - 'añade al nombre del fichero de datos' ], - :converter_backupext_error => [ "La extensión para copias de seguridad", - "no debe estar vacía." ], - :converter_extension_desc => [ "Especifica la extensión de los ficheros", - "de datos de Ruwiki (por defecto .ruwiki)" ], - :converter_extension_error => "La extensión no debe estar vacía.", - :converter_noextension_desc => [ "Indica que los ficheros de datos de", - "Ruwiki no tienen ninguna extensión." ], - :converter_quiet_desc => [ "Ejecución silenciosa. Por defecto se ", - "ejecuta con mensajes normales." ], - :converter_language_desc => [ "Especifica el idioma a emplear con LANG.", - "Por defecto 'en' (inglés).", - "Idiomas disponibles: en es de" ], - :converter_verbose_desc => [ "Información detallada de ejecución.", - "Por defecto se ejecuta con un nivel de ", - "detalle inferior." ], - :converter_help_desc => [ "Mostrar este texto." ], - :converter_num_arguments => "Error: número de argumentos insuficiente.", - :converter_directory => "directorio", - :converter_converting_from => "convertiendo de %1$s a %2$s ... ", - :converter_done => "hecho.", - :converter_not_ruwiki => "no es un fichero de Ruwiki; ignorando.", - :converter_nosave_modified => "no pudo salvarse %1$s.", - :converter_page_format_error => "Error: No pudo detectarse el formato de la página.", - - # Messages from Ruwiki::Utils::Manager - :manager_unknown_command => "Comando desconocido: %1$s", - :manager_help_commands => <<EOH , -Los comandos reconocidos por 'ruwiki' son: - - ruwiki install Instala el entorno por defecto. - ruwiki package Empaqueta una instalación de Ruwiki. - ruwiki unpackage Desempaqueta una instalación de Ruwiki. - ruwiki service Gestiona un Win32::Service para Ruwiki. - -EOH - :manager_help_help => <<-EOH , -Este es un mensaje de ayuda básico con referencias a información suplementaria -relativa a esta herramienta de la línea de comandos. Intente: - - ruwiki help commands mostrar todos los comandos de ruwiki - ruwiki help <COMANDO> mostrar ayuda sobre <COMANDO> - (p.ej., 'ruwiki help install') - -EOH - :manager_missing_parameter => "Falta parámetro para la opción: %1$s", - :manager_dest_not_directory => "El destino (%1$s) no es un directorio.", - :manager_service_broken => "No pudo crearse un servicio de Win32 al no estar instalado Win32::Service.", - :manager_install_help => <<-EOH , - ruwiki install [OPCIONES] [--to DEST] - -Crea una instancia de Ruwiki. Por defecto, se instala los ficheros de datos, -plantillas y la configuración por defecto en el directorio actual. El destino -puede ser cambiado con la opción --to, y los elementos a instalar con la lista -de OPCIONES, que puede ser delimitada por espacios, comas o puntos y comas. -Así pues, - - ruwiki install data;servlet - ruwiki install data,servlet - ruwiki install data servlet - -son equivalentes. Las opciones pueden especificarse en mayúsculas/minúsculas. -Las opciones de instalación son: - - servlet # Instala el stub para el servlet Ruwiki - service # Instala el stub para el Win32::Service Ruwiki - CGI # Instala el script CGI Ruwiki - data # Instala los datos, plantillas y configuración de Ruwiki - -Las opciones pueden deshabilitarse precediéndolas de un guión o 'no': - - ruwiki install cgi -data - ruwiki install cgi nodata - -instalarán el script CGI pero no los datos. -EOH - :manager_package_help => <<-EOH , - ruwiki package [FUENTE] [--output PAQUETE] [--replace] - ruwiki package [FUENTE] [-o PAQUETE] [--replace] - -Empaqueta los ficheros de Ruwiki (datos, plantillas y ejecutables) de la -FUENTE especificada o el directorio actual en el archivo de salida -especificado (o "../%1$s"). Si la FUENTE es un fichero de configuración -de rukiwi (p.ej. "%2$s"), será empleado para determinar la localización -y el nombre de los directorios de datos y plantillas. - - NOTA: El proceso de empaquetado normaliza los nombres de los - ficheros de datos y plantillas para que sean relativos al - directorio de desempaquetado. NUNCA serán paths absolutos. - -EOH - :manager_unpackage_help => <<-EOH , - ruwiki unpackage [FUENTE] [--output DIRECTORIO] - ruwiki unpackage [FUENTE] [-o DIRECTORIO] - -Desempaqueta el paquete de Ruwiki provisto (por defecto "./%1$s") -en el directorio indicado (por defecto "."). -EOH - :manager_service_lo_argcount => "Argumentos insuficientes: %1$s", - :manager_service_hi_argcount => "Demasiados argumentos: %1$s", - :manager_service_help => <<-EOH , - ruwiki service install NOMBRE [DESCRIPCION] [opciones] - ruwiki service start NOMBRE - ruwiki service stop NOMBRE - ruwiki service delete NOMBRE - -Gestiona el servlet Ruwiki para WEBrick como un servicio de Windows, bajo el -NOMBRE indicado. install soporta además las opciones siguientes: - - --rubybin RUBYPATH Path del ejecutable Ruby. - --exec SERVICEPATH Path del ejecutable del servicio. - --home PATHTOHOME Path del directorio home. -EOH - :manager_package_exists => "El paquete %1$s ya existe.", - :manager_service_installed => "Servicio %1$s instalado.", - :manager_one_moment => "Un momento, %1$s ...", - :manager_service_started => "Servicio %1$s iniciado.", - :manager_service_stopped => "Servicio %1$s parado.", - :manager_service_deleted => "Servicio %1$s borrado.", - - # Messages from Ruwiki::Utils::Converter - # Note to translators: certain words should be left alone. These - # will be marked in comments. Description lines are restricted to 40 - # characters and should be an array. Use this as a ruler. - # => [ "----------------------------------------" ] - :runner_usage => "Modo de empleo: %1$s [opciones]", - :runner_general_options => "Opciones generales:", - :runner_saveconfig_desc => [ "Salvar la configuración en FILENAME y", - "salir. Si no se emplea FILENAME, la", - "configuración por defecto será usada.", - "Todas las opciones serán leídas del", - "fichero existente y de la línea de", - "comandos y salvadas. El servlet no se", - "arrancará. El nombre por defecto es:" ], - :runner_config_desc => [ "Leer la configuración por defecto de", - "FILENAME en vez del fichero por defecto", - "Las opciones especificadas anteriormente", - "serán sobrescritas" ], - :runner_webrick_options => "Opciones de WEBrick:", - :runner_port_desc => [ "Ejecutar el servlet Ruwiki en el puerto", - "especificado; por defecto 8808." ], - :runner_address_desc => [ "Aceptar únicamente conexiones desde las", - "direcciones especificadas (separadas por", - "comas). Puede usarse repetidamente. Por", - "defecto todas las direcciones serán", - "aceptadas" ], - :runner_local_desc => [ "Aceptar únicamente conexiones locales", - "(127.0.0.1). Anula las direcciones", - "indicadas previamente en -A" ], - :runner_mountpoint_desc => [ "URI relativo en el que Ruwiki estará", - 'accesible. Por defecto "/".' ], - :runner_log_desc => [ "Realizar log de la actividad de WEBrick.", - "Por defecto se usa --log." ], - :runner_logfile_desc => [ "Fichero en el que escribir los logs de", - "WEBrick. Por defecto, el standard error." ], - :runner_threads_desc => [ "Asigna al threadcount de WEBrick." ], - :runner_ruwiki_options => "Opciones de Ruwiki:", - :runner_language_desc => [ 'Idioma de la inferfaz de Ruwiki.', - 'Por defecto "en". Puede ser "en", ', - '"de", o "es".' ], - :runner_webmaster_desc => [ 'Email del webmaster de Ruwiki.', - 'Por defecto "webmaster@domain.tld".' ], - :runner_debug_desc => [ 'Activa debugging de Ruwiki. Por defecto', - 'inhabilitado.' ], - :runner_title_desc => 'Título del Ruwiki. Por defecto "Ruwiki".', - :runner_defaultpage_desc => [ 'Página por defecto alternativa; por', - 'defecto "ProjectIndex".' ], - :runner_defaultproject_desc => [ 'Proyecto por defecto. Por defecto', - '"Default".' ], - :runner_templatepath_desc => [ 'Localización de las plantillas.', - 'Por defecto "./templates".' ], - :runner_templatename_desc => [ 'Nombre de las plantillas. Por defecto', - '"default".' ], - :runner_cssname_desc => [ 'Nombre del fichero CSS en el directorio', - 'de plantillas. Por defecto "ruwiki.css".' ], - :runner_storage_desc => [ 'Tipo de almacenamiento:' ], - :runner_datapath_desc => [ 'Path donde salvar los ficheros de datos.', - 'Por defecto; "./data".' ], - :runner_extension_desc => [ 'Extensión para ficheros de datos.', - 'Por defecto "ruwiki".' ], - :runner_central_desc => [ 'Ejecuta Ruwiki con los datos del', - 'directorio RubyGem.' ], - :runner_general_info => "Información general:", - :runner_help_desc => [ "Muestra este texto." ], - :runner_version_desc => [ "Muestra la versión de Ruwiki." ], - :runner_rejected_address => "Dirección remota %1$s rechazada. Sólo se admiten conexiones desde %2$s.", - :runner_banner => <<-BANNER , -%1$s - -Opciones de WEBrick: - Puerto %2$d - Direcciones admitidas %3$s - Punto de montaje %4$s - Logging? %5$s - Destino del log %6$s - Hebras %7$s - -Opciones de Ruwiki: - Webmaster %8$s - Debugging? %9$s - Título %10$s - Proyecto por defecto %11$s - Página por defecto %12$s - Path para plantillas %13$s - Conjunto de plantillas %14$s - Fuente CSS %15$s - - Tipo de almacenamiento %16$s - Path de datos %17$s - Extensión %18$s -BANNER - } - message.each { |kk, vv| Message[kk] = vv } - end -end diff --git a/ruwiki/tags/release-0.9.0/lib/ruwiki/page.rb b/ruwiki/tags/release-0.9.0/lib/ruwiki/page.rb deleted file mode 100644 index b246b3a..0000000 --- a/ruwiki/tags/release-0.9.0/lib/ruwiki/page.rb +++ /dev/null @@ -1,262 +0,0 @@ -#-- -# Ruwiki -# Copyright © 2002 - 2004, Digikata and HaloStatue -# Alan Chen (alan@digikata.com) -# Austin Ziegler (ruwiki@halostatue.ca) -# -# Licensed under the same terms as Ruby. -# -# $Id$ -#++ -require 'ruwiki/exportable' - - # The page class for Ruwiki. The page defines the data and meta-data for a - # page. -class Ruwiki::Page - include Ruwiki::Exportable - - exportable_group 'ruwiki' - # Returns the content version of the page. If the page has a greater - # content version than this version of Ruwiki does, we should probably - # throw an exception, because attempting to save such a page will cause - # a loss of data. Immutable. - # - # Class:: +ruwiki+ - # ID:: +content-version+ - attr_reader :content_version - exportable :content_version - # Returns the version of Ruwiki from which this page was generated. - # Informational only. Immutable. - # - # Class:: +ruwiki+ - # ID:: +version+ - attr_reader :ruwiki_version - exportable :ruwiki_version, :name => 'version' - - exportable_group 'properties' - # Returns or sets the displayed title of the page, which may differ from - # the topic of the page. As of Ruwiki 0.8.0, this is not currently used - # and it may disappear. - # - # Class:: +properties+ - # ID:: +title+ - attr_accessor :title - exportable :title - # Returns or sets the topic of the page, which may differ from the - # title. This is used to set the topic on a page being saved. - # - # Class:: +properties+ - # ID:: +topic+ - attr_accessor :topic - exportable :topic - # Returns or sets the project of the page, which may differ from the - # title. This is used to set the project on a page being saved. - # - # Class:: +properties+ - # ID:: +project+ - attr_accessor :project - exportable :project - # Returns or sets the creator of the page. Unless we know the user - # (through the authentication mechanism, only partially implemented for - # Ruwiki 0.9.0), this will be +nil+. - # - # Class:: +properties+ - # ID:: +creator+ - attr_accessor :creator - exportable :creator - # Returns or sets the creator's IP address. This should always be set. - # It will have a value of "UNKNOWN" on the off-chance that something - # prevents this from working. - # - # Class:: +properties+ - # ID:: +creator-ip+ - attr_accessor :creator_ip - exportable :creator_ip - # Returns or sets the date of creation. - # - # Class:: +properties+ - # ID:: +create-date+ - attr_accessor :create_date - exportable :create_date - # Returns or sets the last editor of the page. Unless we know the user - # (through the authentication mechanism, only partially implemented for - # Ruwiki 0.9.0), this will be +nil+. - # - # Class:: +properties+ - # ID:: +editor+ - attr_accessor :editor - exportable :editor - # Returns or sets the last editor's IP address. This should always be - # set. It will have a value of "UNKNOWN" on the off-chance that - # something prevents this from working. - # - # Class:: +properties+ - # ID:: +editor-ip+ - attr_accessor :editor_ip - exportable :editor_ip - # Returns or sets the date of the last edit. - # - # Class:: +properties+ - # ID:: +edit-date+ - attr_accessor :edit_date - exportable :edit_date - # Indicates whether the page is editable. Non-editable pages are - # effectively static pages. - # - # Class:: +properties+ - # ID:: +editable+ - attr_accessor :editable - exportable :editable - # Indicates whether the page is indexable. Non-indexable pages are - # invisible to compliant web robots, and their links may not be - # followed. - # - # Class:: +properties+ - # ID:: +indexable+ - attr_accessor :indexable - exportable :indexable - # The current version of the page. The old version is always (#version - # - 1). - # - # Class:: +properties+ - # ID:: +version+ - attr_accessor :version - exportable :version - # An array of complete tags that will appear in the HTML <HEAD> section. - # Can be used to specify additional CSS, <META> tags, or even JavaScript - # on a per-page basis. Currently unused. - # - # Class:: +properties+ - # ID:: +html-headers+ - attr_accessor :html_headers - exportable :html_headers - # The entropy of the page. This is a ratio of the number of lines - # changed in the file vs. the total number of lines in the file. This - # value is currently unused. (And, sad to say, I don't remember why - # I included it. However, it's an interesting value that may be useful - # in spam fighting techniques. It is currently stored in the meta-data, - # but that may change moving forward.) - # - # Class:: +properties+ - # ID:: +entropy+ - attr_reader :entropy - exportable :entropy - # The edit comment for the current revision of the page. - # - # Class:: +properties+ - # ID:: +edit-comment+ - attr_accessor :edit_comment - exportable :edit_comment - - exportable_group 'page' - # The header content of the page. This is static content (in either Wiki - # or HTML formats) that appears before the editable contents of the - # page. If both this and Wiki-level header content are specified, this - # will appear *after* the Wiki-level header content. - # - # Class:: +page+ - # ID:: +header+ - attr_accessor :header - exportable :header - # The footer content of the page. This is static content (in either Wiki - # or HTML formats) that appears before the editable contents of the - # page. If both this and Wiki-level footer content are specified, this - # will appear *before* the Wiki-level footer content. - # - # Class:: +page+ - # ID:: +footer+ - attr_accessor :footer - exportable :footer - # The editable unformatted Wiki content of the page. - # - # Class:: +page+ - # ID:: +content+ - attr_accessor :content - exportable :content - - # Creates a Ruwiki page. This must be created from the canonical export - # hash. - def initialize(exported = {}) - ruwiki = exported['ruwiki'] - @content_version = (ruwiki['content-version'] || Ruwiki::CONTENT_VERSION).to_i - @ruwiki_version = ruwiki['version'] || Ruwiki::VERSION - - props = exported['properties'] - @title = props['title'] - @topic = props['topic'] || "NewTopic" - @project = props['project'] || "Default" - @creator = props['creator'] || "" - @creator_ip = props['creator-ip'] || "UNKNOWN" - @create_date = Time.at((props['create-date'] || Time.now).to_i) - @editor = props['editor'] || "" - @editor_ip = props['editor-ip'] || "UNKNOWN" - @edit_date = Time.at((props['edit-date'] || Time.now).to_i) - @edit_comment = props['edit-comment'] || "" - case props['editable'] - when "false" - @editable = false - else - @editable = true - end - case props['indexable'] - when "false" - @indexable = false - else - @indexable = true - end - @entropy = (props['entropy'] || 0).to_f - @html_headers = props['html-headers'] || [] - @version = (props['version'] || 0).to_i - - page = exported['page'] - @header = page['header'] || "" - @content = page['content'] || "" - @footer = page['footer'] || "" - - # Fix the possibility that the content might be an array of chunks. - @content = @content.join("") if @content.kind_of?(Array) - - @content.gsub!(/\r/, "") - end - - # Outputs the HTML version of the page. - def to_html(markup) - # Normalise the content, first - @content.gsub!(/\r/, "") - markup.parse(@content, @project) - end - - # Provides the canonical export hash. - def export - sym = super - - sym.each_key do |sect| - if sect == 'ruwiki' - sym[sect]['content-version'] = Ruwiki::CONTENT_VERSION - sym[sect]['version'] = Ruwiki::VERSION - else - sym[sect].each_key do |item| - case [sect, item] - when ['properties', 'create-date'], ['properties', 'edit-date'] - sym[sect][item] = sym[sect][item].to_i - when ['properties', 'editable'], ['properties', 'indexable'] - sym[sect][item] = (sym[sect][item] ? 'true' : 'false') - else - sym[sect][item] = sym[sect][item].to_s - end - end - end - end - - sym - end - - NULL_PAGE = { - 'ruwiki' => { - 'content-version' => Ruwiki::CONTENT_VERSION, - 'version' => Ruwiki::VERSION - }, - 'properties' => { }, - 'page' => { }, - } -end diff --git a/ruwiki/tags/release-0.9.0/lib/ruwiki/servlet.rb b/ruwiki/tags/release-0.9.0/lib/ruwiki/servlet.rb deleted file mode 100644 index 373482e..0000000 --- a/ruwiki/tags/release-0.9.0/lib/ruwiki/servlet.rb +++ /dev/null @@ -1,38 +0,0 @@ -#-- -# Ruwiki -# Copyright © 2002 - 2004, Digikata and HaloStatue -# Alan Chen (alan@digikata.com) -# Austin Ziegler (ruwiki@halostatue.ca) -# -# Licensed under the same terms as Ruby. -# -# $Id$ -#++ -require 'webrick' - -class Ruwiki::Servlet < WEBrick::HTTPServlet::AbstractServlet - class << self - attr_accessor :config - end - - def initialize(config) - @config = config - end - - # Converts a POST into a GET. - def do_POST(req, res) - do_GET(req, res) - end - - def do_GET(req, res) - # Generate the reponse handlers for Ruwiki from the request and response - # objects provided. - wiki = Ruwiki.new(Ruwiki::Handler.from_webrick(req, res)) - - # Configuration defaults to certain values. This overrides the defaults. - wiki.config = Ruwiki::Servlet.config unless Ruwiki::Servlet.config.nil? - wiki.config! - wiki.config.logger = @config.logger - wiki.run - end -end diff --git a/ruwiki/tags/release-0.9.0/lib/ruwiki/template.rb b/ruwiki/tags/release-0.9.0/lib/ruwiki/template.rb deleted file mode 100644 index af26151..0000000 --- a/ruwiki/tags/release-0.9.0/lib/ruwiki/template.rb +++ /dev/null @@ -1,553 +0,0 @@ -#-- -# Ruwiki -# Copyright © 2002 - 2004, Digikata and HaloStatue -# Alan Chen (alan@digikata.com) -# Austin Ziegler (ruwiki@halostatue.ca) -# -# Licensed under the same terms as Ruby. -# -# This file is originally from rdoc by Dave Thomas (dave@pragprog.com). -# -# $Id$ -#++ -require 'cgi' - - # Ruwiki templating, based originally on RDoc's "cheap-n-cheerful" HTML - # page template system, which is a line-oriented, text-based templating - # system. - # - # Templates can contain: - # - # * The directive !INCLUDE!, which will include the next template from the - # provided list. This is processed before any template substitution, so - # repeating and optional blocks work on the values within the template - # substitution. - # * Substitutable variable values between percent signs (<tt>%key%</tt>). - # Optional variable values can be preceded by a question mark - # (<tt>%?key%</tt>). - # * Label values between hash marks (<tt>#key#</tt>). Optional label - # values can be preceded by a question mark (<tt>#?key#</tt>). - # * Links (<tt>HREF:ref:name:</tt>). - # * Repeating substitution values (<tt>[:key| stuff :]</tt>). The value of - # +key+ may be an integer value or a range (in which case key will be - # used as an iterator, providing the current value of key on successive - # values), an array of scalar values (substituting each value), or an - # array of hashes (in which case it works like repeating blocks, see - # below). These must NOT be nested. Note that integer value counting is - # one-based. - # * Optional substitution values (<tt>[?key| stuff ?]</tt> or <tt>[!key| - # stuff ?]</tt>. These must NOT be nested. - # * Repeating blocks: - # START:key - # ... stuff - # END:key - # * Optional blocks: - # IF:key - # ... stuff - # ENDIF:key - # or: - # IFNOT:key - # ... stuff - # ENDIF:key - # - # When generating the output, a hash of values is provided and an optional - # hash of labels is provided. Simple variables are resolved directly from - # the hash; labels are resolved as Symbols from the label hash or are - # otherwise treated as variables. Labels are always resolved from a single - # message hash. - # - # The +key+ for repeating blocks (one-line or multi-line) must be an array - # of hashes. The repeating block will be generated once for each entry. - # Blocks can be nested arbitrarily deeply. - # - # Optional blocks will only be generated if the test is true. IF blocks - # test for the presence of +key+ or that +key+ is non-+nil+; IFNOT blocks - # look for the absence or +nil+ value of +key+. IFBLANK blocks test for - # the absence, +nil+ value, or emptiness of +key+; IFNOTBLANK blocks test - # for the presence of +key+ and that it is neither +nil+ nor empty. - # - # Usage: Given a set of templates <tt>T1</tt>, <tt>T2</tt>, etc. - # - # values = { "name" => "Dave", "state" => "TX" } - # fr = { :name => "Nom", :state => "Etat" } - # en = { :name => "Name", :state => "State" } - # tt = TemplatePage.new(T1, T2, T3) - # - # res = "" - # tt.process(res, values, fr) - # tt.process(res, values, en) - # -class Ruwiki::TemplatePage - BLOCK_RE = %r{^\s*(IF|IFNOT|IFBLANK|IFNOTBLANK|ENDIF|START|END):(\w+)?} - HREF_RE = %r{HREF:(\w+?):(\w+?):} - LABEL_RE = %r{#(\??)(-?)(\w+?)#} - VARIABLE_RE = %r{%(\??)(-?)(\w+?)%} - IFLINE_RE = %r{\[([?!])(\w+?)\|(.*?)\?\]} - BLOCKLINE_RE = %r{\[:(\w+?)\|(.*?):\]} - INCLUDE_RE = %r{!INCLUDE!} - - DDLB_RES = [ - [ :check, %r{%check:(\w+?)%} ], - [ :date, %r{%date:(\w+?)%} ], - [ :popup, %r{%popup:(\w+?):(\w+?)%} ], - [ :ddlb, %r{%ddlb:(\w+?):(\w+?)%} ], - [ :vsortddlb, %r{%vsortddlb:(\w+?):(\w+?)%} ], - [ :radio, %r{%radio:(\w+?):(\w+?)%} ], - [ :radioone, %r{%radioone:(\w+?):(\w+?)%} ], - [ :input, %r{%input:(\w+?):(\d+?):(\d+?)%} ], - [ :text, %r{%text:(\w+?):(\d+?):(\d+?)%} ], - [ :pwinput, %r{%pwinput:(\w+?):(\d+?):(\d+?)%} ], - [ :pair, %r{%pair(\d)?:([^:]+)(\w+?)%} ] - ] - - # Nasty hack to allow folks to insert tags if they really, really want to - OPEN_TAG = "\001" - CLOSE_TAG = "\002" - BR = "#{OPEN_TAG}br#{CLOSE_TAG}" - - # A Context holds a stack of key/value pairs (like a symbol table). When - # asked to resolve a key, it first searches the top of the stack, then the - # next level, and so on until it finds a match (or runs out of entries). - class Context - def initialize - @stack = [] - end - - def push(hash) - @stack.push(hash) - end - - def pop - @stack.pop - end - - # Find a scalar value, throwing an exception if not found. This method is - # used when substituting the %xxx% constructs - def find_scalar_raw(key) - @stack.reverse_each do |level| - if level.has_key?(key) - val = level[key] - return val unless val.kind_of?(Array) - end - end - raise "Template error: can't find variable '#{key}'." - end - - def find_scalar(key) - find_scalar_raw(key) || '' - end - - # Lookup any key in the stack of hashes - def lookup(key) - @stack.reverse_each do |level| - return level[key] if level.has_key?(key) - end - nil - end - end - - # Simple class to read lines out of a string - class LineReader - attr_reader :lines - def initialize(lines) - @lines = lines - end - - # read the next line - def read - @lines.shift - end - - # Return a list of lines up to the line that matches a pattern. That last - # line is discarded. - def read_up_to(pattern) - res = [] - while line = read - if pattern.match(line) - return LineReader.new(res) - else - res << line - end - end - raise "Missing end tag in template: #{pattern.source}" - end - - # Return a copy of ourselves that can be modified without affecting us - def dup - LineReader.new(@lines.dup) - end - end - - # +templates+ is an array of strings containing the templates. We start at - # the first, and substitute in subsequent ones where the string - # <tt>!INCLUDE!</tt> occurs. For example, we could have the overall page - # template containing - # - # <html><body> - # <h1>Master</h1> - # !INCLUDE! - # </body></html> - # - # and substitute subpages in to it by passing [master, sub_page]. This - # gives us a cheap way of framing pages - def initialize(*templates) - result = templates.shift.dup - templates.each { |content| result.sub!(INCLUDE_RE, content) } - @lines = LineReader.new(result.split(/\r?\n/)) - end - - attr_reader :lines - - def set_options(opts = {}) - @message = opts[:messages] || {} - @output = opts[:output] || $stdout - end - - # Render templates as HTML. Compatibility method for Rublog and - # Rdoc. - def write_html_on(op, value_hash, message_hash = {}) - to_html(value_hash, { :output => op, :messages => message_hash }) - end - - # Render templates as HTML - def to_html(value_hash, options = {}) - set_options(options) - esc = proc { |str| CGI.escapeHTML(str) } - @output << process(value_hash, esc) - end - - # Render templates as TeX. Compatibility method for Rublog and - # Rdoc. - def write_tex_on(op, value_hash, message_hash = {}) - to_tex(value_hash, { :output => op, :messages => message_hash }) - end - - # Render templates as TeX - def to_tex(value_hash, options = {}) - set_options(options) - - esc = proc do |str| - str. - gsub(/</, '<'). - gsub(/>/, '>'). - gsub(/&/) { '\\&' }. - gsub(/([$&%\#{}_])/) { "\\#$1" }. - gsub(/>/, '$>$'). - gsub(/</, '$<$') - end - str = "" - - str << process(value_hash, esc) - @output << str - end - - # Render templates as plain text. Compatibility method for Rublog and - # Rdoc. - def write_plain_on(op, value_hash, message_hash = {}) - to_plain(value_hash, { :output => op, :messages => message_hash }) - end - - # Render templates as plain text. - def to_plain(value_hash, options = {}) - set_options(options) - esc = proc {|str| str} - @output << process(value_hash, esc) - end - - # Render the templates. The The <tt>value_hash</tt> contains key/value - # pairs used to drive the substitution (as described above). The - # +escaper+ is a proc which will be used to sanitise the contents of the - # template. - def process(value_hash, escaper) - @context = Context.new - sub(@lines.dup, value_hash, escaper). - tr("\000", '\\'). - tr(OPEN_TAG, '<'). - tr(CLOSE_TAG, '>') - end - - # Substitute a set of key/value pairs into the given template. Keys with - # scalar values have them substituted directly into the page. Those with - # array values invoke <tt>substitute_array</tt> (below), which examples a - # block of the template once for each row in the array. - # - # This routine also copes with the <tt>IF:</tt>_key_ directive, removing - # chunks of the template if the corresponding key does not appear in the - # hash, and the START: directive, which loops its contents for each value - # in an array - def sub(lines, values, escaper) - @context.push(values) - skip_to = nil - result = [] - - while line = lines.read - mv = line.match(BLOCK_RE) - - if mv.nil? - result << expand(line.dup, escaper) - next - else - cmd = mv.captures[0] - tag = mv.captures[1] - end - - case cmd - when "IF", "IFNOT", "IFNOTBLANK", "IFBLANK" - raise "#{cmd}: must have a key to test." if tag.nil? - - val = @context.lookup(tag) - case cmd # Skip lines if the value is... - when "IF" # false or +nil+ (not false => true) - test = (not val) - when "IFBLANK" # +nil+ or empty - test = (not (val.nil? or val.empty?)) - when "IFNOT" - test = val - when "IFNOTBLANK" # - test = (val.nil? or val.empty?) - end - lines.read_up_to(/^\s*ENDIF:#{tag}/) if test - when "ENDIF" - nil - when "START" - raise "#{cmd}: must have a key." if tag.nil? - - body = lines.read_up_to(/^\s*END:#{tag}/) - inner = @context.lookup(tag) - raise "unknown tag: #{tag}" unless inner - raise "not array: #{tag}" unless inner.kind_of?(Array) - inner.each { |vals| result << sub(body.dup, vals, escaper) } - result << "" # Append the missing \n - else - result << expand(line.dup, escaper) - end - end - - @context.pop - - result.join("\n") - end - - # Given an individual line, we look for %xxx%, %?xxx%, #xxx#, #?xxx#, - # [:key| xxx :], [?key| stuff ?], [!key| stuff ?] and HREF:ref:name: - # constructs, substituting as appropriate. - def expand(line, escaper) - # Generate a cross-reference if a reference is given. Otherwise, just - # fill in the name part. - line = line.gsub(HREF_RE) do - ref = @context.lookup($1) - name = @context.find_scalar($2) - - if ref and not ref.kind_of?(Array) - %Q(<a href="#{ref}">#{name}</a>) - else - name - end - end - - # Look for optional content. - line = line.gsub(IFLINE_RE) do - type = $1 - name = $2 - stuff = $3 - - case type - when '?' - test = @context.lookup(name) - when '!' - test = (not @context.lookup(name)) - end - - if test - stuff - else - "" - end - end - - # Look for repeating content. - line = line.gsub(BLOCKLINE_RE) do |match| - name = $1 - stuff = $2 - - val = @context.lookup(name) - ss = "" - case val - when nil - nil - when Fixnum - val.times { |ii| ss << stuff.sub(/%#{name}%/, "#{ii + 1}") } - when Range - val.each { |ii| ss << stuff.sub(/%#{name}%/, "#{ii}") } - when Array - if not val.empty? and val[0].kind_of?(Hash) - val.each do |vv| - @context.push(vv) - ss << expand(stuff, escaper) - @context.pop - end - else - val.each { |ee| ss << stuff.sub(/%#{name}%/, "#{ee}") } - end - end - ss - end - - # Substitute in values for #xxx# constructs. - line = line.gsub(LABEL_RE) do - mandatory = $1.nil? - escaped = $2.nil? - key = $3.intern - val = @message[key] - - if val.nil? - raise "Template error: can't find label '#{key}'." if mandatory - "" - else - val = val.to_s - val = escaper.call(val) if escaped - val.tr('\\', "\000") - end - end - - # Substitute in values for %xxx% constructs. This is made complex - # because the replacement string may contain characters that are - # meaningful to the regexp (like \1) - line = line.gsub(VARIABLE_RE) do - mandatory = $1.nil? - escaped = $2.nil? - key = $3 - val = @context.lookup(key) - - if val.nil? - raise "Template error: can't find variable '#{key}'." if mandatory - "" - else - val = val.to_s - val = escaper.call(val) if escaped - val.tr('\\', "\000") - end - end - - # Substitute DDLB controls: - DDLB_RES.each do |ddlb| - line = line.gsub(ddlb[1]) do - self.send(ddlb[0], Regexp.last_match.captures) - end - end - - line - rescue Exception => ex - raise "Error in template: #{ex}\nOriginal line: #{line}\n#{ex.backtrace[0]}" - end - - def check(*args) - value = @context.find_scalar_raw(args[0]) - checked = value ? " checked" : "" - "<input type=\"checkbox\" name=\"#{name}\"#{checked}>" - end - - def vsortddlb(*args) - ddlb(*(args.dup << true)) - end - - def ddlb(*args) - value = @context.find_scalar(args[0]).to_s - options = @context.lookup(args[1]) - sort_on = args[2] || 0 - - unless options and options.kind_of?(Hash) - raise "Missing options #{args[1]} for ddlb #{args[0]}." - end - - res = %Q(<select name="#{args[0]}">) - - sorted = options.to_a.sort do |aa, bb| - if aa[0] == -1 - -1 - elsif bb[0] == -1 - 1 - else - aa[sort_on] <=> bb[sort_on] - end - end - - sorted.each do |key, val| - selected = (key.to_s == value) ? " selected" : "" - res << %Q(<option value="#{key}"#{selected}>#{val}</option>) - end - res << "</select>" - end - - def date(*args) - yy = "#{argv[0]}_y" - mm = "#{argv[0]}_m" - dd = "#{argv[0]}_d" - %Q<#{input(yy, 4, 4)} . #{input(mm, 2, 2)} . #{input(dd, 2, 2)}> - end - - def radioone(*args) - radio(*(args.dup << "")) - end - - def radio(*args) - value = @context.find_scalar(argv[0]).to_s - options = @context.lookup(argv[1]) - br = argv[2] || "<br />" - - unless options and options.kind_of?(Hash) - raise "Missing options #{args[1]} for radio #{args[0]}." - end - - res = "" - options.keys.sort.each do |key| - val = options[key] - checked = (key.to_s == value) ? " checked" : "" - res << %Q(<label> - <input type="radio" name="#{args[0]}" - value="#{key}"#{checked}">#{val}</label>#{br}) - end - res - end - - def text(*args) - value = @context.find_scalar(args[0]).to_s - %Q(<textarea name="#{args[0]}" cols="#{args[1]}" rows="#{args[2]}"> -#{CGI.escapeHTML(value)} -</textarea>) - end - - def pwinput(*args) - input(*(args.dup << "password")) - end - - def input(*args) - name = args[0] - value = @context.find_scalar(name).to_s - width = args[1] - max = args[2] - iptype = args[3] || "text" - %Q(<input type="#{iptype}" name="#{name}" value="#{value}" size="#{width}" maxsize="#{max}">) - end - - def popup(*args) - url = CGI.escapeHTML(@context.find_scalar(args[0]).to_s) - text = @context.find_scalar(args[1]).to_s - %Q|<a href="#{url}" target="Popup" class="methodtitle" onClick="popup('#{url}'); return false;">#{text}</a>| - end - - def pair(*args) - label = args[0] - name = args[1] - colsp = args[2] - - value = @context.find_scalar(name).to_s - value = case value - when "true" then "Yes" - when "false" then "No" - else value - end - td = (colsp.nil? or colsp.empty?) ? "<td>" : %Q{<td colspan="#{colsp}">} - "#{Html.tag(label)}#{td}#{value}</td>" - end -end diff --git a/ruwiki/tags/release-0.9.0/lib/ruwiki/utils.rb b/ruwiki/tags/release-0.9.0/lib/ruwiki/utils.rb deleted file mode 100644 index 26317b1..0000000 --- a/ruwiki/tags/release-0.9.0/lib/ruwiki/utils.rb +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env ruby -#-- -# Ruwiki -# Copyright © 2002 - 2004, Digikata and HaloStatue -# Alan Chen (alan@digikata.com) -# Austin Ziegler (ruwiki@halostatue.ca) -# -# Licensed under the same terms as Ruby. -# -# This file may be renamed to change the URI for the wiki. -# -# $Id$ -#++ - - # So that Ruwiki doesn't have to be loaded in full to use the bloody thing. -unless defined?(Ruwiki) - class Ruwiki - VERSION = "0.9.0" - end -end - -module Ruwiki::Utils - RUN_PATH = Dir.pwd -end diff --git a/ruwiki/tags/release-0.9.0/lib/ruwiki/utils/command.rb b/ruwiki/tags/release-0.9.0/lib/ruwiki/utils/command.rb deleted file mode 100644 index ba7c060..0000000 --- a/ruwiki/tags/release-0.9.0/lib/ruwiki/utils/command.rb +++ /dev/null @@ -1,102 +0,0 @@ -#!/usr/bin/env ruby -#-- -# Ruwiki -# Copyright © 2002 - 2004, Digikata and HaloStatue -# Alan Chen (alan@digikata.com) -# Austin Ziegler (ruwiki@halostatue.ca) -# -# Licensed under the same terms as Ruby. -# -# This file may be renamed to change the URI for the wiki. -# -# $Id$ -#++ - - # Implements the command pattern. Commands are used by the command-line -class Ruwiki::Utils::CommandPattern - class AbstractCommandError < Exception; end - class UnknownCommandError < RuntimeError; end - class CommandAlreadyExists < RuntimeError; end - class MissingParameterError < ArgumentError - def initialize(argument) - @argument = argument - end - - attr_reader :argument - end - - class << self - def add(command) - command = command.new if command.kind_of?(Class) - - @commands ||= {} - if @commands.has_key?(command.name) - raise CommandAlreadyExists - else - @commands[command.name] = command - end - - if command.respond_to?(:altname) - unless @commands.has_key?(command.altname) - @commands[command.altname] = command - end - end - end - - def <<(command) - add(command) - end - - attr_accessor :default - def default=(command) #:nodoc: - if command.kind_of?(Ruwiki::Utils::CommandPattern) - @default = command - elsif command.kind_of?(Class) - @default = command.new - elsif @commands.has_key?(command) - @default = @commands[command] - else - raise UnknownCommandError - end - end - - def command?(command) - @commands.has_key?(command) - end - - def command(command) - if command?(command) - @commands[command] - else - @default - end - end - - def [](cmd) - self.command(cmd) - end - - def default_ioe(ioe = {}) - ioe[:input] ||= $stdin - ioe[:output] ||= $stdout - ioe[:error] ||= $stderr - ioe - end - end - - def [](args, opts = {}, ioe = {}) - call(args, opts, ioe) - end - - def name - raise AbstractCommandError - end - - def call(args, opts = {}, ioe = {}) - raise AbstractCommandError - end - - def help - raise AbstractCommandError - end -end diff --git a/ruwiki/tags/release-0.9.0/lib/ruwiki/utils/converter.rb b/ruwiki/tags/release-0.9.0/lib/ruwiki/utils/converter.rb deleted file mode 100644 index 0261af8..0000000 --- a/ruwiki/tags/release-0.9.0/lib/ruwiki/utils/converter.rb +++ /dev/null @@ -1,297 +0,0 @@ -#!/usr/bin/env ruby -#-- -# Ruwiki -# Copyright © 2002 - 2004, Digikata and HaloStatue -# Alan Chen (alan@digikata.com) -# Austin Ziegler (ruwiki@halostatue.ca) -# -# Licensed under the same terms as Ruby. -# -# This file may be renamed to change the URI for the wiki. -# -# $Id$ -#++ - -require 'optparse' -require 'ostruct' -require 'fileutils' - -module Ruwiki::Utils::Converter - class << self - TARGETS = %w(flatfiles yaml marshal) - - # Create the regular expressions that are used in Ruwiki 0.6.2 - OLD_HEADER_RE = /^\s*([a-z]+)\s*:\s*(.*)$/ - OLD_HEADER_END_RE = /^#EHDR$/ - DATA_HEADER_END_RE = /\A#EHDR\z/ - NL_RE = /\n/ - - def with(obj) - yield obj if block_given? - end - - # Only allow this to be run once. Silently fail otherwise. - def set_defaults - return unless @options.nil? - @options = OpenStruct.new - - with @options do |oo| - oo.traverse_directories = true - oo.backup_old_files = true - oo.backup_extension = "~" - oo.quiet = false - oo.verbose = false - oo.extension = 'ruwiki' - oo.target_format = 'flatfiles' - end - end - - def message=(lang) - if lang.kind_of?(Hash) - @message = lang - elsif "constant" == defined?(lang::Message) - @message = lang::Message - else - raise ArgumentError - end - end - def message(id) - if @message[id].nil? - [] - else - @message[id] - end - end - - def display_options - end - - def summary - end - - def run(argv, input = $stdin, output = $stdout, error = $stderr) - set_defaults - - @input = input - @output = output - @error = error - - language = 'en' - find_lang = argv.grep(%r{^--lang}) - find_lang.each do |ee| - if ee =~ %r{^--lang=} - language = ee.sub(%r{^--lang=}, '') - else - language = argv[argv.index(ee).succ] - end - end - - require "ruwiki/lang/#{language.downcase}" - self.message = Ruwiki::Lang.const_get(language.upcase) - - argv.options do |opts| - opts.banner = message(:converter_usage) % File.basename($0) - opts.separator '' - opts.on('--format=FORMAT', *message(:converter_format_desc)) do |ff| - @options.target_format = ff - end - opts.on('--[no-]backup', *message(:converter_backup_desc)) do |bb| - @options.backup_old_files = bb - end - opts.on('--backup-extension=EXTENSION', *message(:converter_backupext_desc)) do |ee| - if ee.nil? or ee.empty? - @error << message(:converter_backupext_error) << "\n" if ee.nil? or ee.empty? - @error << "#{opts}\n" - return 0 - end - @options.backup_extension = ee - end - opts.on('--extension=EXTENSION', *message(:converter_extension_desc)) do |ee| - if ee.nil? or ee.empty? - @error << message(:converter_extension_error) << "\n" if ee.nil? or ee.empty? - @error << "#{opts}\n" - return 0 - end - @options.extension = ee - end - opts.on('--no-extension', *message(:converter_noextension_desc)) do - @options.extension = nil - end - opts.on('--lang=LANG', *message(:converter_language_desc)) do |lang| - self.message = Ruwiki::Lang.const_get(lang.upcase) - end - opts.on('--quiet', *message(:converter_quiet_desc)) do |qq| - @options.quiet = qq - @options.verbose = (not qq) - end - opts.on('--verbose', *message(:converter_verbose_desc)) do |vv| - @options.quiet = (not vv) - @options.verbose = vv - end - opts.separator '' - opts.on_tail('--help', *message(:converter_help_desc)) do - @error << "#{opts}\n" - return 0 - end - - opts.parse! - end - - if argv.empty? - @error << message(:converter_num_arguments) << "\n#{argv.options}\n" unless @options.quiet - return 127 - end - - display_options if @options.verbose - - @options.target_format.capitalize! - @options.target_format_class = Ruwiki::Backend.const_get(@options.target_format) - - argv.each { |file| process_file(file) } - - summary if not @options.quiet - end - - # Process a single file. - def process_file(file) - if @options.backup_old_files - return if file =~ /#{@options.backup_extension}/ - end - @out << "#{file}: " unless @options.quiet - - if File.directory?(file) and @options.traverse_directories - @out << message(:converter_directory) << "\n" unless @options.quiet - Dir.chdir(file) { Dir['*'].each { |entry| process_file(entry) } } - else - begin - page, page_format = load_page(file) - @out << message(:converter_converting_from) % [ page_format, @options.target_format ] if @options.verbose - save_page(file, page) - @out << message(:converter_done) << "\n" unless @options.quiet - rescue PageLoadException - @out << message(:converter_not_ruwiki) << "\n" unless @options.quiet - rescue PageSaveException - @out << message(:cannot_nosave_modified) << "\n" % [ file ] unless @options.quiet - end - end - end - - def load_page(file) - data = File.read(file) - page_format = nil - - if data =~ OLD_HEADER_END_RE - page_format = 'OldFlatfiles' - - page = Ruwiki::Page::NULL_PAGE.dup - - unless data.empty? - rawbuf = data.split(NL_RE).map { |ee| ee.chomp } - - loop do - if rawbuf[0] =~ OLD_HEADER_END_RE - rawbuf.shift - break - end - - match = OLD_HEADER_RE.match(rawbuf[0]) - - unless match.nil? - case match.captures[0] - when 'topic' - page['properties']['topic'] = match.captures[1] - page['properties']['title'] = match.captures[1] - when 'version' - page['properties']['version'] = match.captures[1].to_i - else - nil - end - end - rawbuf.shift - end - - page['page']['content'] = rawbuf.join("\n") - - with page['properties'] do |pp| - pp['project'] = File.basename(File.dirname(File.expand_path(file))) - pp['editable'] = true - pp['indexable'] = true - pp['entropy'] = 0.0 - end - end - end - - # Try Marshal - if page_format.nil? - begin - page = ::Marshal.load(data) - page_format = 'Marshal' - rescue Exception - nil - end - end - - # Try YAML - if page_format.nil? - begin - page = ::YAML.load(data) - page_format = 'YAML' - rescue Exception - nil - end - end - - # Try the Flatfiles format - if page_format.nil? - begin - page = Ruwiki::Backend::Flatfiles.load(data) - page_format = 'Exportable' - rescue Exception => ex - nil - end - end - - if page_format.nil? # Cannot detect page type. - @error << @message[:converter_page_format_error] << "\n" - raise PageLoadException - end - [page, page_format] - rescue PageLoadException - raise - rescue Exception => ex - @error << %Q|#{ex.message}\n#{ex.backtrace.join("\n")}\n| if @options.verbose - raise PageLoadException - end - - def save_page(file, page) - if @options.backup_extension != '~' - backup = "#{file}.#{@options.backup_extension}" - else - backup = "#{file}#{@options.backup_extension}" - end - - # Always backup the file -- we are transactional. - FileUtils.cp(file, backup) - - if @options.target_format == 'Marshal' - method = :print - else - method = :puts - end - File.open(file, 'wb') { |ff| ff.__send__(method, @options.target_format_class.dump(page)) } - rescue Exception => ex - FileUtils.mv(backup, file) if File.exists?(backup) - @error << %Q|#{ex.message}\n#{ex.backtrace.join("\n")}\n| if @options.verbose - raise PageSaveException - ensure - # If we aren't *supposed* to back up the file, then get rid of the - # backup. - if File.exists?(backup) and (not @options.backup_old_files) - FileUtils.rm(backup) - end - end - - class PageLoadException < RuntimeError; end - class PageSaveException < RuntimeError; end - end -end diff --git a/ruwiki/tags/release-0.9.0/lib/ruwiki/utils/manager.rb b/ruwiki/tags/release-0.9.0/lib/ruwiki/utils/manager.rb deleted file mode 100644 index aa8f2a1..0000000 --- a/ruwiki/tags/release-0.9.0/lib/ruwiki/utils/manager.rb +++ /dev/null @@ -1,639 +0,0 @@ -#!/usr/bin/env ruby -#-- -# Ruwiki -# Copyright © 2002 - 2004, Digikata and HaloStatue -# Alan Chen (alan@digikata.com) -# Austin Ziegler (ruwiki@halostatue.ca) -# -# Licensed under the same terms as Ruby. -# -# This file may be renamed to change the URI for the wiki. -# -# $Id$ -#++ - -require 'optparse' -require 'ostruct' -require 'fileutils' -require 'stringio' -require 'zlib' -require 'ruwiki/exportable' -require 'ruwiki/utils/command' -require 'ruwiki/config' - -begin - if defined?(Gem::Cache) - require_gem 'archive-tar-minitar', '~> 0.5.1' - else - require 'archive/tar/minitar' - end -rescue LoadError => ex - $stderr.puts ex.message - raise -end - -module Ruwiki::Utils::Manager - DEFAULT_PACKAGE_NAME = 'ruwiki.pkg' - - def self.message=(lang) - if lang.kind_of?(Hash) - @message = lang - elsif "constant" == defined?(lang::Message) - @message = lang::Message - else - raise ArgumentError - end - end - def self.message(id) - @message[id] - end - - class ManagerError < RuntimeError; end - - EXECUTABLES = %w(ruwiki.cgi ruwiki_servlet ruwiki_servlet.bat \ - ruwiki_servlet.cmd ruwiki_service.rb) - - class ManagerHelp < Ruwiki::Utils::CommandPattern - def name - "help" - end - - def call(args, opts = {}, ioe = {}) - ioe = Ruwiki::Utils::CommandPattern.default_ioe(ioe) - help_on = args.shift - output = "" - - if Ruwiki::Utils::CommandPattern.command?(help_on) - ioe[:output] << Ruwiki::Utils::CommandPattern[help_on].help - elsif help_on == "commands" - ioe[:output] << Ruwiki::Utils::Manager.message(:manager_help_commands) - else - ioe[:output] << Ruwiki::Utils::Manager.message(:manager_unknown_command) % [ help_on ] << "\n" % [ help_on ] unless help_on.nil? or help_on.empty? - ioe[:output] << self.help - end - - 0 - end - - def help - Ruwiki::Utils::Manager.message(:manager_help_help) - end - end - - class ManagerInstall < Ruwiki::Utils::CommandPattern - def name - "install" - end - - def call(args, opts = {}, ioe = {}) - argv = [] - - replace = false - dest = "." - name = nil - - while (arg = args.shift) - case arg - when '--to' - dir = args.shift - raise Ruwiki::Utils::CommandPattern::MissingParameterError.new(arg) if dir.nil? - if File.exist?(dir) - if not File.directory?(dir) - raise ArgumentError, Ruwiki::Utils::Manager.message(:manager_dest_not_directory) - end - else - FileUtils.mkdir_p(dir) - end - dest = dir - when /;/o - argv.push(*(arg.split(/;/o))) - when /,/o - argv.push(*(arg.split(/,/o))) - else - argv << arg - end - end - - options = { 'data' => true } - - while (arg = argv.shift) - case arg - when /^(?:-|no)(.*$)/ - options.delete($1) - else - options[arg] = true - end - end - - Ruwiki::Utils::Manager.install(dest, options) - - 0 - end - - def help - Ruwiki::Utils::Manager.message(:manager_install_help) - end - end - - class ManagerPackage < Ruwiki::Utils::CommandPattern - def name - "package" - end - - def call(args, opts = {}, ioe = {}) - ioe = Ruwiki::Utils::CommandPattern.default_ioe(ioe) - argv = [] - replace = false - dest = "." - name = nil - - while (arg = args.shift) - case arg - when '--replace' - replace = true - when '-o', '--output' - name = args.shift - raise Ruwiki::Utils::CommandPattern::MissingParameterError.new(arg) if name.nil? - dest = File.dirname(name) - name = File.basename(name) - else - argv << arg - end - end - - if argv.size > 1 - ioe[:output] << Ruwiki::Utils::Manager.message(:manager_service_hi_argcount) % [ args.join(" ") ] << "\n" - ioe[:output] << self.help - return 1 - end - source = argv.shift || "." - - Ruwiki::Utils::Manager.package(source, dest, name, replace) - 0 - end - - def help - Ruwiki::Utils::Manager.message(:manager_package_help) % [ "./#{Ruwiki::Utils::Manager::DEFAULT_PACKAGE_NAME}", - Ruwiki::Config::CONFIG_NAME ] - end - end - - class ManagerUnpackage < Ruwiki::Utils::CommandPattern - def name - "unpackage" - end - - def call(args, opts = {}, ioe = {}) - ioe = Ruwiki::Utils::CommandPattern.default_ioe(ioe) - argv = [] - dir = "." - - while (arg = args.shift) - case arg - when '-o', '--output' - dir = args.shift - raise Ruwiki::Utils::CommandPatter::MissingParameterError.new(arg) if dir.nil? or not File.directory?(dir) - else - argv << arg - end - end - - if argv.size > 1 - ioe[:output] << Ruwiki::Utils::Manager.message(:manager_service_hi_argcount) % [ args.join(" ") ] << "\n" - ioe[:output] << self.help - return 1 - end - source = argv.shift || Ruwiki::Utils::Manager::DEFAULT_PACKAGE_NAME - - Ruwiki::Utils::Manager.unpackage(source, dir) - - 0 - end - - def help - Ruwiki::Utils::Manager.message(:manager_unpackage_help) % [ "./#{Ruwiki::Utils::Manager::DEFAULT_PACKAGE_NAME}" ] - end - end - - if RUBY_PLATFORM =~ /win32/ - class ManagerService < Ruwiki::Utils::CommandPattern - def name - "service" - end - - def call(args, opts = {}, ioe = {}) - ioe = Ruwiki::Utils::CommandPattern.default_ioe(ioe) - - if args.size < 2 - ioe[:output] << Ruwiki::Utils::Manager.message(:manager_service_lo_argcount) % [ args.join(" ") ] << "\n" - ioe[:output] << self.help - return 0 - end - - command = args.shift - service = args.shift - - options ||= {} - options[:service_name] = service - options[:service_home] = File.expand_path(".") - - argv = [] - while (arg = args.shift) - case arg - when "--rubybin" - options[:ruby_bin] = args.shift - raise Ruwiki::Utils::CommandPattern::MissingParameterError.new(arg) if options[:ruby_bin].nil? - when "--exec" - options[:service_bin] = args.shift - raise Ruwiki::Utils::CommandPattern::MissingParameterError.new(arg) if options[:service_bin].nil? - when "--home" - options[:service_home] = args.shift - raise Ruwiki::Utils::CommandPattern::MissingParameterError.new(arg) if options[:service_home].nil? - else - argv << arg - end - end - - options[:service_desc] = args.join(" ") if args.size > 0 - - case command - when "install" - options[:service_install] = true - when "start" - options[:service_start] = true - when "stop" - options[:service_stop] = true - when "delete" - options[:service_delete] = true - else - raise ArgumentError, Ruwiki::Utils::Manager.message(:manager_unknown_command) % [ command ] - end - - Ruwiki::Utils::Manager.manage_windows_service(options, ioe) - - 0 - end - - def help - Ruwiki::Utils::Manager.message(:manager_service_help) - end - end - Ruwiki::Utils::CommandPattern << ManagerService - end - - Ruwiki::Utils::CommandPattern << ManagerHelp - Ruwiki::Utils::CommandPattern << ManagerInstall - Ruwiki::Utils::CommandPattern << ManagerPackage - Ruwiki::Utils::CommandPattern << ManagerUnpackage - Ruwiki::Utils::CommandPattern.default = Ruwiki::Utils::CommandPattern["help"] - - class << self - attr_accessor :shared - attr_reader :ruwiki_servlet - attr_reader :ruwiki_servlet_bat - attr_reader :ruwiki_servlet_cmd - attr_reader :ruwiki_service - attr_reader :ruwiki_cgi - attr_reader :ruwiki_pkg - def shared=(shared) - @shared = shared - @ruwiki_servlet = File.join(@shared, "bin", "ruwiki_servlet") - @ruwiki_servlet_bat = File.join(@shared, "bin", "ruwiki_servlet.bat") - @ruwiki_servlet_cmd = File.join(@shared, "bin", "ruwiki_servlet.cmd") - @ruwiki_service = File.join(@shared, "bin", "ruwiki_service.rb") - @ruwiki_cgi = File.join(@shared, "bin", "ruwiki.cgi") - @ruwiki_pkg = File.join(@shared, Ruwiki::Utils::Manager::DEFAULT_PACKAGE_NAME) - end - - def with(obj) - yield obj if block_given? - end - - def tar_files(list, name) - ff = StringIO.new - gz = Zlib::GzipWriter.new(ff) - to = Archive::Tar::Minitar::Output.new(gz) - list.each { |item| Archive::Tar::Minitar.pack_file(item, to) } - data = ff.string - group = { - :name => name, - :data => data, - :mode => 0644, - } - return group - rescue Exception => ex - puts ex.message, ex.backtrace.join("\n") - ensure - to.close - group[:size] = group[:data].size - end - - def package(source, dest, name = nil, replace = false) - # If the package name is nil, use the default name. If replace is - # false, then append a number on the end if the file already exists. - # Increment the number until we have a unique filename. - if name.nil? - pkg = File.join(dest, DEFAULT_PACKAGE_NAME) - if File.exists?(pkg) and (not replace) - pbn = "#{File.basename(DEFAULT_PACKAGE_NAME, '.pkg')}-%02d.pkg" - ii = 1 - while File.exists?(pkg) - pkg = File.join(dest, pbn % ii) - ii += 1 - end - end - else - pkg = File.join(dest, name) - if File.exists?(pkg) and (not replace) - raise ManagerError, Ruwiki::Utils::Manager.message(:manager_package_exists) - end - end - - files = [] - - if File.directory?(source) - Dir.chdir(source) do - if File.exists?(Ruwiki::Config::CONFIG_NAME) - cs = File.stat(Ruwiki::Config::CONFIG_NAME) - files << { - :name => Ruwiki::Config::CONFIG_NAME, - :data => File.read(Ruwiki::Config::CONFIG_NAME), - :mtime => cs.mtime, - :mode => 0644, - :size => cs.size - } - end - - EXECUTABLES.each do |ff| - if File.exists?(ff) - cs = File.stat(ff) - files << { - :name => ff, - :data => File.read(ff), - :mtime => cs.mtime, - :mode => 0755, - :size => cs.size - } - end - end - - f_data = Dir["data/**/**"].select { |dd| dd !~ /CVS\// } - f_data.unshift("data") - f_data.map! do |dd| - res = { :name => dd, :mode => 0644 } - if File.directory?(dd) - res[:mode] = 0755 - res[:dir] = true - end - res - end - - f_tmpl = Dir["templates/**/**"].select { |tt| tt !~ /CVS\// } - f_tmpl.unshift("templates") - f_tmpl.map! do |tt| - res = { :name => tt, :mode => 0644 } - if File.directory?(tt) - res[:mode] = 0755 - res[:dir] = true - end - res - end - - files << tar_files(f_data, "data.pkg") - files << tar_files(f_tmpl, "tmpl.pkg") - end - else - stat = File.stat(source) - files << { - :name => File.basename(source), - :data => File.read(source), - :mtime => stat.mtime, - :mode => 0644, - :size => stat.size - } - - EXECUTABLES.each do |ff| - ff = File.join(File.dirname(source), ff) - if File.exists?(ff) - cs = File.stat(ff) - files << { - :name => ff, - :data => File.read(ff), - :mtime => cs.mtime, - :mode => 0755, - :size => cs.size - } - end - end - - cc = Ruwiki::Exportable.load(files[0][:data]) - tp = cc['ruwiki-config']['template-path'] - tp = "./templates" if tp.nil? or tp.empty? - so = cc['ruwiki-config']['storage-options'] - - if so.nil? or so.empty? - dp = "./data" - else - so = Ruwiki::Exportable.load(so) - key = 'flatfiles' - dp = so[key]['data-path'] - end - - dp = "./data" if dp.nil? or dp.empty? - bndp = File.basename(dp) - bntp = File.basename(tp) - - so[key]['data-path'] = bndp - cc['ruwiki-config']['storage-options'] = Ruwiki::Exportable.dump(so) - cc['ruwiki-config']['template-path'] = bntp - files[0][:data] = Ruwiki::Exportable.dump(cc) - files[0][:size] = files[0][:data].size - - Dir.chdir(File.dirname(dp)) do - f_data = Dir["#{bndp}/**/**"].select { |dd| dd !~ /CVS\// } - f_data.map! { |dd| { :name => dd, :mode => 0644 } } - files << tar_files(f_data, "data.pkg") - end - - Dir.chdir(File.dirname(tp)) do - f_tmpl = Dir["#{bntp}/**/**"].select { |tt| tt !~ /CVS\// } - f_tmpl.map! { |tt| { :name => tt, :mode => 0644 } } - files << tar_files(f_tmpl, "tmpl.pkg") - end - end - - ff = File.open(pkg, "wb") - gz = Zlib::GzipWriter.new(ff) - tw = Archive::Tar::Minitar::Writer.new(gz) - - files.each do |entry| - tw.add_file_simple(entry[:name], entry) { |os| os.write(entry[:data]) } - end - - nil - rescue Exception => ex - puts ex, ex.backtrace.join("\n") - ensure - tw.close if tw - gz.close if gz - end - - def unpackage(source, dest) - ff = File.open(source, "rb") - gz = Zlib::GzipReader.new(ff) - Archive::Tar::Minitar::Input.open(gz) do |it| - it.each do |entry| - case entry.full_name - when "data.pkg", "tmpl.pkg" - pkg = StringIO.new(entry.read) - pkgz = Zlib::GzipReader.new(pkg) - Archive::Tar::Minitar::Input.open(pkgz) do |inner| - inner.each { |item| inner.extract_entry(dest, item) } - end - else - it.extract_entry(dest, entry) - end - end - end - - nil - end - - def install(dest, options = {}) - if options['servlet'] - FileUtils.install(Ruwiki::Utils::Manager.ruwiki_servlet, dest, :mode => 0755) - if RUBY_PLATFORM =~ /win32/ - if File.exists?(Ruwiki::Utils::Manager.ruwiki_servlet_bat) - FileUtils.install(Ruwiki::Utils::Manager.ruwiki_servlet_bat, dest, :mode => 0755) - end - if File.exists?(Ruwiki::Utils::Manager.ruwiki_servlet_cmd) - FileUtils.install(Ruwiki::Utils::Manager.ruwiki_servlet_cmd, dest, :mode => 0755) - end - end - end - - if RUBY_PLATFORM =~ /win32/ and options['service'] - FileUtils.install(Ruwiki::Utils::Manager.ruwiki_service, dest, :mode => 0755) - end - - if options['cgi'] - FileUtils.install(Ruwiki::Utils::Manager.ruwiki_cgi, dest, :mode => 0755) - end - - if options['data'] - unpackage(Ruwiki::Utils::Manager.ruwiki_pkg, dest) - end - end - - if RUBY_PLATFORM =~ /win32/ - begin - require 'win32/service' - require 'rbconfig' - HasWin32Service = true - rescue LoadError - HasWin32Service = false - end - - # The work here is based on Daniel Berger's Instiki Service Tutorial. - # http://rubyforge.org/docman/view.php/85/107/instiki_service_tutorial.txt - def manage_windows_service(options, ioe) - raise Ruwiki::Utils::Manager.message(:manager_service_broken) unless HasWin32Service - - service_name = options[:service_name] || 'RuwikiSvc' - - if options[:service_install] - service_home = options[:service_home] - - program = options[:service_bin] - if program.nil? or program.empty? - program = File.join(service_home, "ruwiki_service.rb") - elsif program !~ %r{[/\\]} - program = File.join(service_home, program) - end - program = %<"#{program}"> - - ruby = options[:ruby_bin] || %<"#{File.join(Config::CONFIG['bindir'], 'ruby.exe')}"> - - service_desc = options[:service_desc] || 'Ruwiki' - - binpath = "#{ruby} #{program}".tr('/', '\\') - - service = Win32::Service.new - service.create_service do |svc| - svc.service_name = service_name - svc.display_name = service_desc - svc.binary_path_name = binpath - svc.dependencies = [] # Required because of a bug in Win32::Service - end - service.close - ioe[:output] << Manager.manager(:manager_service_installed) % [ service_name ] << "\n" - end - - if options[:service_start] - Win32::Service.start(service_name) - started = false - while (not started) - status = Win32::Service.status(service_name) - started = (status.current_state == "running") - break if started - ioe[:output] << Ruwiki::Utils::Manager.message(:manager_one_moment) % [ status.current_state ] << "\n" - sleep 1 - end - ioe[:output] << Ruwiki::Utils::Manager.message(:manager_service_started) % [ service_name ] << "\n" - end - - if options[:service_stop] - Win32::Service.stop(service_name) - stopped = false - while (not stopped) - status = Win32::Service.status(service_name) - stopped = (status.current_state == "stopped") - break if stopped - ioe[:output] << Ruwiki::Utils::Manager.message(:manager_one_moment) % [ status.current_state ] << "\n" - sleep 1 - end - ioe[:output] << Ruwiki::Utils::Manager.message(:manager_service_stopped) % [ service_name ] << "\n" - end - - if options[:service_delete] - Win32::Service.stop(service_name) rescue nil - Win32::Service.delete(service_name) - ioe[:output] << Ruwiki::Utils::Manager.message(:manager_service_deleted) % [ service_name ] << "\n" - end - end - end - - def run(argv, input = $stdin, output = $stdout, error = $stderr) - ioe = { - :input => input, - :output => output, - :error => error - } - - language = 'en' - find_lang = argv.grep(%r{^--lang}) - find_lang.each do |ee| - eepos = argv.index(ee) - if ee =~ %r{^--lang=} - language = ee.sub(%r{^--lang=}, '') - else - language = argv[eepos.succ] - argv.delete_at(eepos.succ) - end - argv.delete_at(eepos) - end - - require "ruwiki/lang/#{language.downcase}" - Ruwiki::Utils::Manager.message = Ruwiki::Lang.const_get(language.upcase) - - command = Ruwiki::Utils::CommandPattern[(argv.shift or "").downcase] - return command[argv, {}, ioe] - rescue Ruwiki::Utils::CommandPattern::MissingParameterError => ee - ioe[:error] << Ruwiki::Utils::Manager.message(:manager_missing_parameter) % [ ee.argument ] << "\n" - return 1 - rescue ArgumentError, ManagerError => ee - ioe[:error] << ee.message << "\n" - return 1 - end - end -end diff --git a/ruwiki/tags/release-0.9.0/lib/ruwiki/utils/servletrunner.rb b/ruwiki/tags/release-0.9.0/lib/ruwiki/utils/servletrunner.rb deleted file mode 100644 index db6bcfa..0000000 --- a/ruwiki/tags/release-0.9.0/lib/ruwiki/utils/servletrunner.rb +++ /dev/null @@ -1,295 +0,0 @@ -#!/usr/bin/env ruby -#-- -# Ruwiki -# Copyright © 2002 - 2004, Digikata and HaloStatue -# Alan Chen (alan@digikata.com) -# Austin Ziegler (ruwiki@halostatue.ca) -# -# Licensed under the same terms as Ruby. -# -# This file may be renamed to change the URI for the wiki. -# -# $Id$ -#++ - - # Customize this if you put the RuWiki files in a different location. -require 'webrick' - -require 'ruwiki/utils' -require 'ruwiki/exportable' -require 'ruwiki/servlet' -require 'ruwiki/lang/en' -require 'ruwiki/lang/de' -require 'ruwiki/lang/es' - -require 'optparse' -require 'ostruct' - -module Ruwiki::Utils::ServletRunner - COPYRIGHT = <<-"COPYRIGHT" -Ruwiki #{Ruwiki::VERSION} - Copyright © 2002 - 2004, Digikata and HaloStatue - - http://rubyforge.org/projects/ruwiki/ - - Alan Chen (alan@digikata.com) - Austin Ziegler (ruwiki@halostatue.ca) - -Licensed under the same terms as Ruby. - -$Id$ -COPYRIGHT - - class WEBrickConfig - include Ruwiki::Exportable - - exportable_group 'webrick-config' - attr_accessor :port - exportable :port - attr_accessor :addresses - exportable :addresses - attr_accessor :mount - exportable :mount - attr_accessor :do_log - exportable :do_log - attr_accessor :log_dest - exportable :log_dest - attr_accessor :threads - exportable :threads - - def export - hash = super - sc = hash['webrick-config'] - sc['addresses'] = sc['addresses'].join(";") - sc['do-log'] = (sc['do-log'] ? 'true' : 'false') - hash - end - - # Because the servlet can be started from the command-line, provide - # defaults for all possible configuration options. - def initialize(exported = {}) - sc = exported['webrick-config'] || {} - @port = sc['port'] || 8808 - @mount = sc['mount'] || '/' - @addresses = sc['addresses'] - @do_log = ((sc['do-log'] == 'false') ? false : true) - @log_dest = sc['log-dest'] - @threads = sc['threads'] || 1 - - if @addresses.nil? or @addresses.empty? - @addresses = [] - else - @addresses = @addresses.split(/;/) - end - - if @log_dest.nil? or @log_dest.empty? - @log_dest = "<STDERR>" - end - end - end - - def self.message=(lang) - if lang.kind_of?(Hash) - @message = lang - elsif "constant" == defined?(lang::Message) - @message = lang::Message - else - raise ArgumentError - end - end - def self.message(id) - @message[id] - end - - class << self - # This is for the WEBrick version of Ruwiki. This has been abstracted to - # accept a Config global variable to reconfigure Ruwiki after initial - # creation. - def read_config(filename) - ch = {} - if File.exists?(filename) - File.open(filename, 'rb') { |ff| ch = Ruwiki::Exportable.load(ff.read) } - end - - @sc = WEBrickConfig.new(ch) - @rc = Ruwiki::Config.new(ch) - - if @rc.webmaster.nil? or @rc.webmaster.empty? - @rc.webmaster = "webmaster@domain.tld" - end - end - - def run(argv, input = $stdin, output = $stdout, error = $stderr) - read_config(Ruwiki::Config::CONFIG_NAME) - - save_config = nil - - language = 'en' - find_lang = argv.grep(%r{^--language}) - find_lang.each do |ee| - if ee =~ %r{^--language=} - language = ee.sub(%r{^--language=}, '') - else - language = argv[argv.index(ee).succ] - end - end - - require "ruwiki/lang/#{language.downcase}" - @rc.language = Ruwiki::Lang.const_get(language.upcase) - self.message = @rc.language - - argv.options do |oo| - oo.banner = self.message(:runner_usage) % [ File.basename($0) ] - oo.separator self.message(:runner_general_options) - oo.on('--save-config [FILENAME]', *([ self.message(:runner_saveconfig_desc), Ruwiki::Config::CONFIG_NAME ].flatten)) { |fname| - save_config = fname || Ruwiki::Config::CONFIG_NAME - } - oo.on('--config FILENAME', *self.message(:runner_config_desc)) { |fn| - read_config(fn) - } - oo.separator "" - oo.separator self.message(:runner_webrick_options) - oo.on('-P', '--port PORT', Numeric, *self.message(:runner_port_desc)) { |port| - @sc.port = port - } - oo.on('-A', '--accept ADDRESS,ADDRESS,ADDRESS', Array, *self.message(:runner_address_desc)) { |address| - @sc.addresses += address - } - oo.on('-L', '--local', *self.message(:runner_local_desc)) { - @sc.addresses = ["127.0.0.1"] - } - oo.on('-M', '--mount MOUNT-POINT', *self.message(:runner_mountpoint_desc)) { |mp| - @sc.mount = mp - } - oo.on('--[no-]log', *self.message(:runner_log_desc)) { |log| - @sc.do_log = log - } - oo.on('--logfile LOGFILE', *self.message(:runner_logfile_desc)) { |lf| - @sc.log_dest = lf - } - oo.on('-T', '--threads THREADS', Integer, *self.message(:runner_threads_desc)) { |tc| - @sc.threads = tc - } - oo.separator "" - oo.separator self.message(:runner_ruwiki_options) - oo.on('--language=LANGUAGE', *self.message(:runner_language_desc)) { |lang| - nil - } - oo.on('--webmaster WEBMASTER', *self.message(:runner_webmaster_desc)) { |wm| - @rc.webmaster = wm - } - oo.on('--[no-]debug', *self.message(:runner_debug_desc)) { |dd| - @rc.debug = dd - } - oo.on('--title TITLE', *self.message(:runner_title_desc)) { |tt| - @rc.title = tt - } - oo.on('--default-page PAGENAME', *self.message(:runner_defaultpage_desc)) { |dp| - @rc.default_page = dp - } - oo.on('--default-project PAGENAME', *self.message(:runner_defaultproject_desc)) { |dp| - @rc.default_project = dp - } - oo.on('--template-path TEMPLATE_PATH', *self.message(:runner_templatepath_desc)) { |tp| - @rc.template_path = tp - } - oo.on('--templates TEMPLATES', *self.message(:runner_templatename_desc)) { |tp| - @rc.template_set = tp - } - oo.on('--css CSS_NAME', *self.message(:runner_cssname_desc)) { |css| - @rc.css = css - } - oo.on('--storage-type TYPE', Ruwiki::KNOWN_BACKENDS, *([self.message(:runner_storage_desc), Ruwiki::KNOWN_BACKENDS.join(", ")].flatten)) { |st| - @rc.storage_type = st - @rc.storage_options[@rc.storage_type]['data-path'] ||= "./data/" - @rc.storage_options[@rc.storage_type]['extension'] ||= "ruwiki" - } - oo.on('--data-path PATH', *self.message(:runner_datapath_desc)) { |fdp| - @rc.storage_options['flatfiles']['data-path'] = fdp - } - oo.on('--extension EXT', *self.message(:runner_extension_desc)) { |ext| - @rc.storage_options['flatfiles']['data-path'] = fdp - } - if defined?(Gem::Cache) - oo.separator "" - oo.on('--central', *self.message(:runner_central_desc)) { - gempath = Gem::Cache.from_installed_gems.search("ruwiki", "=#{Ruwiki::VERSION}").last.full_gem_path - @rc.storage_type = 'flatfiles' - @rc.storage_options['flatfiles']['data-path'] = "#{gempath}/data" - @rc.storage_options['flatfiles']['extension'] = "ruwiki" - @rc.storage_options['flatfiles']['format'] = "exportable" - @rc.template_path = "#{gempath}/templates" - @rc.template_set = "sidebar" - } - end - - # TODO: Add options for time, date, and datetime formats. - oo.separator "" - oo.separator self.message(:runner_general_info) - oo.on_tail('--help', *self.message(:runner_help_desc)) { - error << oo << "\n" - return 0 - } - oo.on_tail('--version', *self.message(:runner_version_desc)) { - error << COPYRIGHT << "\n" - return 0 - } - oo.parse! - end - - if save_config - sc = @sc.export - rc = @rc.export - cf = sc.merge(rc) - - File.open(save_config, 'wb') { |ff| ff.puts Ruwiki::Exportable.dump(cf) } - return 0 - end - - # If the list of accepted addresses is not empty, provide IP-based - # restrictions. - if not @sc.addresses.empty? - localonly = lambda do |sock| - if not @sc.addresses.include?(sock.peeraddr[3]) - raise WEBrick::ServerError, self.message(:runner_rejected_address) % [ sock.peeraddr[3], @sc.addresses.join(", ") ] - end - end - else - localonly = nil - end - - if @sc.do_log - if "<STDERR>" == @sc.log_dest - dest = $stderr - else - dest = File.open(@sc.log_dest, "wb+") - end - logger = WEBrick::Log.new(dest, WEBrick::Log::DEBUG) - else - logger = nil - end - - banner = self.message(:runner_banner) % - [ Ruwiki::Utils::ServletRunner::COPYRIGHT, @sc.port, - @sc.addresses.join(", "), @sc.mount, @sc.do_log, @sc.log_dest, - @sc.threads, @rc.webmaster, @rc.debug, @rc.title, - @rc.default_project, @rc.default_page, @rc.template_path, - @rc.template_set, @rc.css, @rc.storage_type, - @rc.storage_options[@rc.storage_type]['data-path'], - @rc.storage_options[@rc.storage_type]['extension'] ] - - banner.each { |bb| logger.info(bb) } unless logger.nil? - - server = WEBrick::HTTPServer.new(:Port => @sc.port.to_i, - :StartThreads => @sc.threads.to_i, - :AcceptCallback => localonly, - :Logger => logger) - @rc.logger = logger - Ruwiki::Servlet.config = @rc - - server.mount(@sc.mount, Ruwiki::Servlet) - trap("INT") { server.shutdown; return } - server.start - end - end -end diff --git a/ruwiki/tags/release-0.9.0/lib/ruwiki/wiki.rb b/ruwiki/tags/release-0.9.0/lib/ruwiki/wiki.rb deleted file mode 100644 index 85f2c51..0000000 --- a/ruwiki/tags/release-0.9.0/lib/ruwiki/wiki.rb +++ /dev/null @@ -1,147 +0,0 @@ -#-- -# Ruwiki -# Copyright © 2002 - 2004, Digikata and HaloStatue -# Alan Chen (alan@digikata.com) -# Austin Ziegler (ruwiki@halostatue.ca) -# -# Licensed under the same terms as Ruby. -# -# $Id$ -#++ - # Ruwiki's Wiki markup class. This will convert the Wiki markup known by - # Ruwiki (defined by Token classes). The algorithm is as follows: - # - # 1. For each known Token class, match each instance of it in the content - # stream. Replace each instance in the content stream with a Token - # marker: TOKEN_x or \TOKEN_x, where x is a digit representing the Token. - # (\TOKEN_x is a special case of token matching. See - # Ruwiki::Markup::Token for more information.) Store the Token for later - # processing. - # 2. Go back through the content, replacing each instance of \TOKEN_x with - # the Token's defined restore value (which should be the same value as was - # originally matched). - # 3. Go through the content, replacing each instance of TOKEN_x with the - # Token's defined replacement value. - # 4. Go through the tokens, in reverse, and execute the post replacement - # routine defined by the Token. (This may be necessary to collapse - # consecutive HTML structures.) - # 5. Return the parsed content and the collected metadata. - # - # == Tokens - # Look at Ruwiki::Markup::Token describes how to create Token objects. -class Ruwiki::Wiki - def parse(content, project) - content = clean(content) - tokens = [] - project ||= @default_project - - Token.tokenlist.each do |token| - content.gsub!(token.regexp) do |mm| - match = Regexp.last_match - tc = token.new(match, project, @backend, @script, @message, @title) - tokens << tc - if mm[0, 1] == '\\' - "\\TOKEN_#{tokens.size - 1}" - else - "TOKEN_#{tokens.size - 1}" - end - end - end - - replaced = [] - ss = true - loop do - break if replaced.size >= tokens.size - break if ss.nil? - ss = content.gsub!(/\\TOKEN_(\d+)/) { |mm| - match = Regexp.last_match - itoken = match[1].to_i - replaced << itoken - tokens[itoken].restore - } - - ss = content.gsub!(/TOKEN_(\d+)/) { |mm| - match = Regexp.last_match - itoken = match[1].to_i - replaced << itoken - tokens[itoken].replace - } - end - - token_classes = tokens.map { |token| token.class }.sort_by { |token| token.rank } - token_classes.uniq.each { |tc| tc.post_replace(content) } - - content - end - - attr_accessor :default_project - attr_accessor :script - attr_accessor :backend - attr_accessor :message - - # Creates the markup class. - def initialize(default_project, script, title) - @default_project = default_project - @script = script - @title = title - end - -private - # Find HTML tags - SIMPLE_TAG_RE = %r{<[^<>]+?>} # Ensure that only the tag is grabbed. - HTML_TAG_RE = %r{\A< # Tag must be at start of match. - (/)? # Closing tag? - ([\w:]+) # Tag name - (?:\s+ # Space - ([^>]+) # Attributes - (/)? # Singleton tag? - )? # The above three are optional - >}x - ATTRIBUTES_RE = %r{([\w:]+)(=(?:\w+|"[^"]+?"|'[^']+?'))?}x - STYLE_NOVD_RE = %r{(?:\s?(visibility|display):[^'";]+;?)}x - ALLOWED_ATTR = %w(style title type lang dir class id cite datetime abbr) + - %w(colspan rowspan compact start media) - ALLOWED_HTML = %w(abbr acronym address b big blockquote br caption cite) + - %w(code col colgroup dd del dfn dir div dl dt em h1 h2 h3) + - %w(h4 h5 h6 hr i ins kbd li menu ol p pre q s samp small) + - %w(span strike strong style sub sup table tbody td tfoot) + - %w(th thead tr tt u ul var) - - # Clean the content of unsupported HTML and attributes. This includes - # XML namespaced HTML. Sorry, but there's too much possibility for - # abuse. - def clean(content) - content = content.gsub(SIMPLE_TAG_RE) do |tag| - tagset = HTML_TAG_RE.match(tag) - - if tagset.nil? - tag = Ruwiki.clean_entities(tag) - else - closer, name, attributes, single = tagset.captures - - if ALLOWED_HTML.include?(name.downcase) - unless closer or attributes.nil? - attributes = attributes.scan(ATTRIBUTES_RE).map do |set| - if ALLOWED_ATTR.include?(set[0].downcase) - if set[0] == 'style' - set[1].gsub!(STYLE_NOVD_RE, '') - end - set.join - else - nil - end - end.compact.join(" ") - tag = "<#{closer}#{name} #{attributes}#{single}>" - else - tag = "<#{closer}#{name}>" - end - else - tag = Ruwiki.clean_entities(tag) - end - end - tag.gsub(%r{((?:href|src)=["'])(#{Ruwiki::Wiki::RE_URI_SCHEME})}) { "#{$1}\\#{$2}" } - end - end -end - -require 'ruwiki/wiki/tokens' diff --git a/ruwiki/tags/release-0.9.0/lib/ruwiki/wiki/tokens.rb b/ruwiki/tags/release-0.9.0/lib/ruwiki/wiki/tokens.rb deleted file mode 100644 index 5ae48c1..0000000 --- a/ruwiki/tags/release-0.9.0/lib/ruwiki/wiki/tokens.rb +++ /dev/null @@ -1,136 +0,0 @@ -#-- -# Ruwiki -# Copyright © 2002 - 2004, Digikata and HaloStatue -# Alan Chen (alan@digikata.com) -# Austin Ziegler (ruwiki@halostatue.ca) -# -# Licensed under the same terms as Ruby. -# -# $Id$ -#++ -class Ruwiki - class Wiki - # The base Token class. All Token classes must inherit from Token and - # *must* implement the following methods: - # - # [self.regexp] The regular expression that the Token will be - # replacing. - # [replace] The mechanism for replacing the Token with the desired - # results. - # - # Token classes <i>should</i> implement the following method: - # [self.rank] Default: <tt>5000</tt>. Affects the sort order. - # Must return an integer. - # - # Token classes <i>may</i> implement the following methods: - # [restore] Restores the token without replacement. - # Implements the results of the escape character. - # NOTE: each Token class is responsible for its own - # restore. Tokens that are anchored to the - # beginning of a line are the most likely to need - # to reimplement this. - # [self.post_replace] Performs any necessary massaging of the data. See - # the implementation of Ruwiki::Wiki::Lists for - # more information. - class Token - @@tokenlist = [] - @@sorted = false - - class << self - # Tokens should define rank if they must be first or last in - # processing. Otherwise, they are sorted in the order defined. - def rank - 5000 - end - - # The Wiki parsing routine uses Token.tokenlist to determine the - # tokens that are processed, and the order in which they are - # processed. See Token.rank for more information. - def tokenlist - unless @@sorted - head = @@tokenlist.shift - @@tokenlist.sort! { |aa, bb| aa.rank <=> bb.rank } - @@tokenlist.unshift(head) - sorted = true - end - @@tokenlist - end - - def inherited(child_class) #:nodoc: - @@tokenlist << Token if @@tokenlist.empty? - - # Make the child class post_replace a blank function because we - # don't want to propogate the currently defined post_replace. - # The current post_replace is specific to Token_Base only. - class << child_class - def self.post_replace(content) - content - end - end - - @@tokenlist << child_class - @@sorted = false - end - - # The replacement regular expression. - def regexp - /TOKEN_(\d*)/ - end - end - - # All Token classes must match this header signature if they define - # #initialize. - # - # [match] The MatchData object for this Token. - # [project] The project being processed. - # [backend] The backend for the wiki. This is used to determine if - # the page or project exists. The object passed must - # respond to #project_exists?(project) and - # #page_exists?(page, project). - # [script] The URI to the script. - # [message] The message hash for localized messages. - # [title] The title of the Wiki. - def initialize(match, project, backend, script, message, title) - @match = match - @project = project - @backend = backend - @script = script - @message = message - @title = title - end - - # The replacement method. Uses @match to replace the token with the - # appropriate values. - def replace - "TOKEN_#{@match[1]}" - end - - # Restores the token without replacement. By default, replaces - # "dangerous" HTML characters. - def restore - Ruwiki.clean_entities(@match[0]) - end - - # The content may need massaging after processing. - def self.post_replace(content) - content - end - end - end -end - - # Load the tokens from the ruwiki/wiki/tokens directory. -tokens_dir = 'ruwiki/wiki/tokens' - -$LOAD_PATH.each do |path| - target = "#{path}/#{tokens_dir}" - if File.exists?(target) and File.directory?(target) - Dir::glob("#{target}/*.rb") do |token| - begin - require token - rescue LoadError - nil - end - end - end -end diff --git a/ruwiki/tags/release-0.9.0/lib/ruwiki/wiki/tokens/00default.rb b/ruwiki/tags/release-0.9.0/lib/ruwiki/wiki/tokens/00default.rb deleted file mode 100644 index b214758..0000000 --- a/ruwiki/tags/release-0.9.0/lib/ruwiki/wiki/tokens/00default.rb +++ /dev/null @@ -1,211 +0,0 @@ -#-- -# Ruwiki -# Copyright © 2002 - 2004, Digikata and HaloStatue -# Alan Chen (alan@digikata.com) -# Austin Ziegler (ruwiki@halostatue.ca) -# -# Licensed under the same terms as Ruby. -# -# $Id$ -#++ - -# $debug = File.open("output.txt", "wb") - -class Ruwiki::Wiki - # The Paragraph Token class changes blank lines to <p> tags. This class, - # under the current implementation, should be *first* in the Token list - # after Token. - class Paragraph < Ruwiki::Wiki::Token - # This Token is #rank 0, because it should be first in the Token list. - def self.rank - 0 - end - - # Matches blank lines. %r{^$} - def self.regexp - %r{(^$)} - end - - def replace - %Q(</p><p class="rwtk_Paragraph">) - end - - # Ensures that <p> won't be surrounded by <br> tags. - def self.post_replace(content) - content.gsub!(%r{\A}, '<p class="rwtk_Paragraph">') - content.gsub!(%r{\z}, '</p>') - content.gsub!(%r{\n(</p>)}, '\1') - content.gsub!(%r{(<p[^>]*>)\n}, '\1') - content.gsub!(%r{(</p>)(<p[^>]*>)}) { "#{$1}\n#{$2}" } - content.gsub!(%r{(<pre[^>]*>.*?)<p[^>]*></p>(.*?</pre>)}) { "#{$1}\n#{$2}" } - content.gsub!(%r{<p[^>]*></p>}, '') - content.gsub!(%r{^\n(<p[^>]*>)}, '\1') - content - end - end - - # The Code Token class converts indented text to "unformatted" (<pre>) - # text. This class should be *second* in the Token list. - class Code < Ruwiki::Wiki::Token - # This Token is #rank 1, because it should be second in the Token list. - def self.rank - 1 - end - - # Matches indented text. %r{^(\s+\S?.*)$} - def self.regexp - %r{^([ \t]+[^\n]*)\n} - end - - # Replaces the text to <pre>content</pre>. - def replace - content = Ruwiki.clean_entities(@match.captures[0]) - - %Q{</p><pre class="rwtk_Code">#{content}</pre>\n} - end - - # Converts cases of %r{</pre>(\n|<br ?/?>)<pre>} to \1. - def self.post_replace(content) - content.gsub!(%r{</pre>((\n)*</p>(\n)*)?<pre[^>]*>}, "\n") - content.gsub!(%r{</pre>(\n|<br ?/?>)?<pre[^>]*>}, '\1') - content.gsub!(%r{<p[^>]*>(<pre[^>]*>)}, '\1') - content.gsub!(%r{</pre></p>}, '</pre>') -# content.gsub!(%r{(<pre[^>]*>.*?)<p[^>]*></p>(.*?</pre>)}) { "#{$1}\n#{$2}" } - content - end - end - - RE_URI_SCHEME = %r{[-a-z0-9+.]{3,}?:} - RE_URI_PATH = %r{[^\s<>\]]} - RE_URI_TEXT = %r{[^\]]*} - - def self.redirect(uri) - "http://www.google.com/url?sa=D;q=#{CGI.escape(uri)}" - end - - # Converts URLs in the form of [url] to numbered links. - class NumberedLinks < Ruwiki::Wiki::Token - class << self - def increment - @count ||= 0 - @count += 1 - end - - def reset - @count = 0 - end - end - - def self.rank - 2 - end - - def self.regexp - %r{\[(#{RE_URI_SCHEME}(?:#{RE_URI_PATH})*?)\]} - end - - def replace - extlink = @match.captures[0] - - name = "[#{NumberedLinks.increment}]" - - %Q{<a class="rwtk_NumberedLinks" href="#{Ruwiki::Wiki.redirect(extlink)}">#{name}</a>} - end - end - - class Image < Ruwiki::Wiki::Token - def self.rank - 1 - end - - RE_IMAGE_OPTIONS=%r{([^=]+)=("[^"]+"|[^ ]+)} - - def self.regexp - %r{\[image\s*:\s*(#{RE_URI_SCHEME}(?:#{RE_URI_PATH})*?)(\s+[^\]]+)?\]} - end - - def replace - options = { 'src' => %Q("#{@match.captures[0]}") } - groups = @match.captures[1] - unless groups.nil? - groups.scan(RE_IMAGE_OPTIONS).each { |gg| options[gg[0].strip] = gg[1].strip } - end - - unless options['numbered'].nil? or options['numbered'] == "false" - options['title'] = %Q("[#{NumberedLinks.increment}]") - options.delete('numbered') - end - - options['title'] ||= options['alt'] - options['title'] ||= options['src'] - options['alt'] ||= options['title'] - - ss = "" - options.keys.sort.map { |kk| ss << %Q( #{kk}=#{options[kk]}) } - - %Q{<img class="rwtk_Image"#{ss} />} - end - end - - # Converts URLs in the form of [url name] to named links. - class NamedLinks < Ruwiki::Wiki::Token - def self.rank - 3 - end - - def self.regexp - %r{\[(#{RE_URI_SCHEME}(?:#{RE_URI_PATH})*?)\s+(#{RE_URI_TEXT})\]} - end - - def replace - extlink = @match.captures[0] - name = @match.captures[1] - - %Q{<a class="rwtk_NamedLinks" href="#{Ruwiki::Wiki.redirect(extlink)}">#{name}</a>} - end - end - - # Converts URLs to links where the "name" of the link is the URL itself. - class ExternalLinks < Ruwiki::Wiki::Token - def self.rank - 501 - end - - def self.regexp - %r{\b(#{RE_URI_SCHEME}#{RE_URI_PATH}+)} - end - - def restore - @match[0] - end - - def replace - extlink = @match.captures[0] - - %Q{<a class="rwtk_ExternalLinks" href="#{Ruwiki::Wiki.redirect(extlink)}">#{extlink}</a>} - end - end - - # Creates a horizontal rule. - class HRule < Ruwiki::Wiki::Token - def self.regexp - %r|^\\?-{4,}| - end - - def replace - %Q(<hr class="rwtk_HRule" />) - end - - def restore - @match[0][1 .. -1] - end - - def self.post_replace(content) - content.gsub!(%r{(<p[^>]*>)*(<hr[^ />]* ?/?>)(</p>)*}, '\1') - content.gsub!(%r{\n<hr />}, "</p>\n<hr />") - content.gsub!(%r{<hr ?/?>\n<br ?/?>}, "<hr />") - content.gsub!(%r{(\n|<br ?/?>)?<hr>(\n|<br ?/?>)?}, "<hr />") - content - end - end -end diff --git a/ruwiki/tags/release-0.9.0/lib/ruwiki/wiki/tokens/01wikilinks.rb b/ruwiki/tags/release-0.9.0/lib/ruwiki/wiki/tokens/01wikilinks.rb deleted file mode 100644 index 442a201..0000000 --- a/ruwiki/tags/release-0.9.0/lib/ruwiki/wiki/tokens/01wikilinks.rb +++ /dev/null @@ -1,166 +0,0 @@ -#-- -# Ruwiki -# Copyright © 2002 - 2004, Digikata and HaloStatue -# Alan Chen (alan@digikata.com) -# Austin Ziegler (ruwiki@halostatue.ca) -# -# Licensed under the same terms as Ruby. -# -# $Id$ -#++ -require 'cgi' - -class Ruwiki::Wiki - # This provides the basic WikiWord match. This supports WikiWord, - # CPlusPlus, ThisIsALink, and C_Plus_Plus. - RE_WIKI_WORDS = %r{[[:upper:]][\w_]*(?:[[:lower:]]+[[:upper:]_]|[[:upper:]_]+[[:lower:]])[\w_]*} - # This provides wikipedia format matches, e.g., [[wikipedia links]]. The - # only restriction on words in this format is that they must NOT begin - # with an underscore ('_'). - RE_WIKIPEDIA_WORDS = %r{\[\[([^_].*?)\]\]} - # This provides the basic Wiki Project match. - RE_PROJECT_WORD = %r{[[:upper:]][[:lower:]]+} - - # This provides the Wiki view link format: - VIEW_LINK = %Q[<a class="rwtk_WikiLink" href="%s">%s</a>] - EDIT_LINK = %Q[<span class="rwtk_EditWikiLink">%s</span><a class="rwtk_WikiLink" href="%s">?</a>] - - # Creates a crosslink for a Project::WikiPage. - class ProjectCrossLink < Ruwiki::Wiki::Token - def self.rank - 500 - end - - def self.regexp - %r{(#{RE_PROJECT_WORD})::(#{RE_WIKI_WORDS})} - end - - def replace - project = @match.captures[0] - topic = @match.captures[1] - link = CGI.escape(topic.dup) - - if @backend.page_exists?(topic, project) or @backend.page_exists?(link, project) - VIEW_LINK % ["#{@script}/#{project}/#{link}", "#{project}::#{topic.gsub(/_/, ' ')}"] - else - EDIT_LINK % ["#{project}::#{topic.gsub(/_/, ' ')}", "#{@script}/#{project}/#{link}/_edit"] - end - end - end - - # Creates a crosslink for a Project::WikiPage using a Wikipedia link - # format. - class ProjectCrossLinkWikipedia < Ruwiki::Wiki::Token - def self.rank - 500 - end - - def self.regexp - %r{(#{RE_PROJECT_WORD})::#{RE_WIKIPEDIA_WORDS}} - end - - def replace - project = @match.captures[0] - topic = @match.captures[1] - link = CGI.escape(topic) - - if @backend.page_exists?(topic, project) or @backend.page_exists?(link, project) - VIEW_LINK % ["#{@script}/#{project}/#{link}", "#{project}::#{topic}"] - else - EDIT_LINK % ["#{project}::#{topic}", "#{@script}/#{project}/#{link}/_edit"] - end - end - end - - # Creates a link to the project index from ::Project. - class ProjectIndex < Ruwiki::Wiki::Token - def self.rank - 501 - end - - def self.regexp - %r{(\B|\\)::(#{RE_PROJECT_WORD})\b} - end - - def restore - @match[0][1..-1] - end - - def replace - project = @match.captures[1] - - if @backend.page_exists?('ProjectIndex', project) - VIEW_LINK % ["#{@script}/#{project}/ProjectIndex", project] - else - if @backend.project_exists?(project) - EDIT_LINK % [project, "#{@script}/#{project}/ProjectIndex/_edit"] - else - EDIT_LINK % [project, "#{@script}/#{project}/_create"] - end - end - end - end - - # Creates a link to a WikiPage in the current project. - class WikiLinks < Ruwiki::Wiki::Token - def self.rank - 503 - end - - def self.regexp - %r{(\b|\\)(#{RE_WIKI_WORDS})\b} - end - - def restore - @match[0][1..-1] - end - - def replace - topic = @match.captures[1] - link = CGI.escape(topic.dup) - - if @backend.page_exists?(topic, @project) or @backend.page_exists?(link, @project) - VIEW_LINK % ["#{@script}/#{@project}/#{link}", topic.gsub(/_/, ' ')] - else - EDIT_LINK % [topic.gsub(/_/, ' '), "#{@script}/#{@project}/#{link}/_edit"] - end - end - end - - # Creates a link to a WikiPage in the current project using a Wikipedia - # link format. - class WikipediaLinks < Ruwiki::Wiki::Token - def self.rank - 502 - end - - def self.regexp - %r{(\B|\\)#{RE_WIKIPEDIA_WORDS}\B} - end - - def restore - @match[0][1..-1] - end - - ALT_TEXT = %r{(.+)\|(.+)}o - - def replace - captures = @match.captures - topic = @match.captures[1] - link = CGI.escape(topic) - - at = ALT_TEXT.match(topic) - - if not at.nil? - topic = at.captures[1] - link = CGI.escape(at.captures[0]) - end - - if @backend.page_exists?(link, @project) or @backend.page_exists?(link, @project) - VIEW_LINK % ["#{@script}/#{@project}/#{link}", topic] - else - EDIT_LINK % [topic, "#{@script}/#{@project}/#{link}/_edit"] - end - end - end -end diff --git a/ruwiki/tags/release-0.9.0/lib/ruwiki/wiki/tokens/02actions.rb b/ruwiki/tags/release-0.9.0/lib/ruwiki/wiki/tokens/02actions.rb deleted file mode 100644 index 8ad0950..0000000 --- a/ruwiki/tags/release-0.9.0/lib/ruwiki/wiki/tokens/02actions.rb +++ /dev/null @@ -1,63 +0,0 @@ -#-- -# Ruwiki -# Copyright © 2002 - 2004, Digikata and HaloStatue -# Alan Chen (alan@digikata.com) -# Austin Ziegler (ruwiki@halostatue.ca) -# -# Licensed under the same terms as Ruby. -# -# $Id$ -#++ -require 'cgi' - -class Ruwiki::Wiki - # Produces a list of topics. - class TopicList < Ruwiki::Wiki::Token - def self.regexp - %r{^%topics\((#{Ruwiki::Wiki::RE_PROJECT_WORD})?\)$} - end - - def replace - project = @match.captures[0] || @project - - if @backend.project_exists?(project) - topic_list = @backend.list_topics(project) - else - topic_list = [] - end - - if topic_list.empty? - ss = @message[:no_topics] % [project] - else - ss = %Q(<h4 class="rwtk_Headings">#{@message[:topics_for_project] % [project]}</h4>\n<ul class="rwtk_Lists">\n) - topic_list.each do |tt| - ss << %Q(<li class="rwtk_Lists">) - ss << VIEW_LINK % ["#{@script}/#{project}/#{tt}", "#{CGI::unescape(tt.gsub(/_/, ' '))}"] - ss << "</li>\n" - end - ss << "</ul>\n" - end - - ss - end - end - - class ProjectList < Ruwiki::Wiki::Token - def self.regexp - %r{^%projects\(\)$} - end - - def replace - proj_list = @backend.list_projects - - ss = %Q(<h4 class="rwtk_Headings">#{@message[:wiki_projects] % [@title]}</h4>\n<ul class="rwtk_Lists">\n) - proj_list.each do |pp| - ss << %Q(<li class="rwtk_Lists">) - ss << VIEW_LINK % ["#{@script}/#{pp}/ProjectIndex", pp] - ss << %Q! <a href='#{@script}/#{pp}/_topics' class='rw_minilink'>#{@message[:project_topics_link]}</a>! - ss << "</li>\n" - end - ss << "</ul>\n" - end - end -end diff --git a/ruwiki/tags/release-0.9.0/lib/ruwiki/wiki/tokens/abbreviations.rb b/ruwiki/tags/release-0.9.0/lib/ruwiki/wiki/tokens/abbreviations.rb deleted file mode 100644 index b928085..0000000 --- a/ruwiki/tags/release-0.9.0/lib/ruwiki/wiki/tokens/abbreviations.rb +++ /dev/null @@ -1,40 +0,0 @@ -#-- -# Ruwiki -# Copyright © 2002 - 2004, Digikata and HaloStatue -# Alan Chen (alan@digikata.com) -# Austin Ziegler (ruwiki@halostatue.ca) -# -# Licensed under the same terms as Ruby. -# -# $Id$ -#++ -class Ruwiki::Wiki - # Converts abbreviations. - class Abbreviations < Ruwiki::Wiki::Token - ABBREVIATIONS = { - "matz" => "Yukihiro Matsumoto", - } - - def self.regexp - %r!@\{([^\}]*)\}! - end - - def replace - kk = @match.captures[0] - if kk.nil? or kk.empty? - data = %Q(<dl class="rwtk_Abbreviations">) - ABBREVIATIONS.each do |kk, vv| - data << %Q(<dt class="rwtk_Abbreviations">#{kk}</dt><dd class="rwtk_Abbreviations">#{vv}</dd>) - end - data << %Q(</dl>) - else - if ABBREVIATIONS.has_key?(kk) - data = ABBREVIATIONS[kk] - else - data = @match[0] - end - end - data - end - end -end diff --git a/ruwiki/tags/release-0.9.0/lib/ruwiki/wiki/tokens/calendar.rb b/ruwiki/tags/release-0.9.0/lib/ruwiki/wiki/tokens/calendar.rb deleted file mode 100644 index c78dc45..0000000 --- a/ruwiki/tags/release-0.9.0/lib/ruwiki/wiki/tokens/calendar.rb +++ /dev/null @@ -1,147 +0,0 @@ -#-- -# Ruwiki -# Copyright © 2002 - 2004, Digikata and HaloStatue -# Alan Chen (alan@digikata.com) -# Austin Ziegler (ruwiki@halostatue.ca) -# -# Licensed under the same terms as Ruby. -# -# $Id$ -#++ -class Ruwiki - class Wiki - # Produces a mini-calendar with dates as WikiWords. - class Calendar < Ruwiki::Wiki::Token - def self.regexp - %r{^\\?%calendar\((?:(today)|(\d+),\s*(\d+))(?:,\s*(#{RE_PROJECT_WORD}))?\)} - end - - def self.make(year, month) - result = [] - tt = Time.local(year, month, 1) - rr = Array.new(tt.wday, nil) - rr << 1 - - 2.upto(31) do |ii| - break if Time.local(year, month, ii).month != month - rr << ii - end - - rr += Array.new((- rr.size) % 7, nil) - - 0.step(rr.size - 1, 7) do |ii| - result << rr[ii, 7] - end - result - end - - def make_month_link(project, year, month, state = nil) - ym = "%04d%02d" % [year, month] - case state - when :prev - title = "« #{year}.#{month}" - when :next - title = "#{year}.#{month} »" - else - title = "#{project}::#{year}.#{month}" - end - url = "#{@script}/#{project}/#{ym}" - - if @backend.page_exists?(ym, project) - VIEW_LINK % [url, title] - else - EDIT_LINK % [title, "#{url}/_edit"] - end - end - - def replace - today = @match.captures[0] - project = @match.captures[3] || @project - now = Time.now - - if today.nil? - year = @match.captures[1].to_i - month = @match.captures[2].to_i - else - year = now.year - month = now.month - end - - if (year == now.year) and (month == now.month) - show_today = now.day - else - show_today = nil - end - - result = <<-"CALENDAR_HEAD" -</p> -<div class="rwtk_Calendar"> -<table class="rwtk_Calendar" summary="calendar for ::#{project}: #{year}.#{month}"> -<thead> - CALENDAR_HEAD - - result << %Q{ <tr>\n<th colspan="7" class="rwtk_Calendar_current_month">} - result << make_month_link(project, year, month) - result << %Q{</th>\n </tr>\n <tr>\n<th colspan="2" class="rwtk_Calendar_prev_month">} - result << make_month_link(project, year, month - 1, :prev) - result << %Q{</th>\n<th colspan="3"></th>\n<th colspan="2" class="rwtk_Calendar_next_month">} - result << make_month_link(project, year, month + 1, :next) - result << "</th>\n" - - result << <<-"CALENDAR_HEAD2" - </tr> - <tr> - <th class="rwtk_Calendar_weekend">Su</th> - <th class="rwtk_Calendar_weekday">Mo</th> - <th class="rwtk_Calendar_weekday">Tu</th> - <th class="rwtk_Calendar_weekday">We</th> - <th class="rwtk_Calendar_weekday">Th</th> - <th class="rwtk_Calendar_weekday">Fr</th> - <th class="rwtk_Calendar_weekend">Sa</th> - </tr> -</thead> -<tbody> - CALENDAR_HEAD2 - - Calendar.make(year, month).each do |week| - result << " <tr>\n" - week.each do |day| - if day.nil? - result << %Q{ <td class="rwtk_Calendar_day"></td>\n} - else - date = "%04d%02d%02d" % [year, month, day] - # Add the ability to create pages based on date here. - if show_today == day - result << %Q{ <td class="rwtk_Calendar_today">} - else - result << %Q{ <td class="rwtk_Calendar_day">} - end - if @backend.page_exists?(date, project) - result << VIEW_LINK % ["#{@script}/#{project}/#{date}", day] - else - result << EDIT_LINK % [day, "#{@script}/#{project}/#{date}/_edit"] - end - result << %Q{</td>\n} - end - end - result << " </tr>\n" - end - - result << %Q(</tbody>\n</table>\n</div>\n<p class="rwtk_Paragraph">) - result - end - - def restore - @match[0][1 .. -1] - end - - def self.post_replace(content) - content.gsub!(%r{<p[^>]*>(\s*</?div(?: [^>]+)?>\s*)</p>}, '\1') - content.gsub!(%r{<p[^>]*>(\s*</?table(?: [^>]+)?>\s*)</p>}, '\1') - content.gsub!(%r{<p[^>]*>(\s*</?t(?:head|body|r)(?: [^>]+)?>\s*)</p>}, '\1') - content.gsub!(%r{<p[^>]*>(\s*<t[hd].+?</t[hd]>\s*)</p>}, '\1') - content - end - end - end -end diff --git a/ruwiki/tags/release-0.9.0/lib/ruwiki/wiki/tokens/headings.rb b/ruwiki/tags/release-0.9.0/lib/ruwiki/wiki/tokens/headings.rb deleted file mode 100644 index cfc3001..0000000 --- a/ruwiki/tags/release-0.9.0/lib/ruwiki/wiki/tokens/headings.rb +++ /dev/null @@ -1,43 +0,0 @@ -#-- -# Ruwiki -# Copyright © 2002 - 2004, Digikata and HaloStatue -# Alan Chen (alan@digikata.com) -# Austin Ziegler (ruwiki@halostatue.ca) -# -# Licensed under the same terms as Ruby. -# -# $Id$ -#++ -class Ruwiki - class Wiki - # Converts headings. - class Headings < Ruwiki::Wiki::Token -# def self.rank -# 5 -# end - - def self.regexp - %r{^\\?(=+)\s+(.*)} - end - - def restore - @match[0][1 .. -1] - end - - def replace - level = @match.captures[0].count("=") - content = @match.captures[1] - level = 6 if level > 6 - %Q(<h#{level} class="rwtk_Headings">#{content}</h#{level}>) - end - - def self.post_replace(content) - content.gsub!(%r{(</h\d>)\n}) { |m| %Q(#{$1}\n<p class="rwtk_Paragraph">) } - content.gsub!(%r{(</h\d>)</p>\n<p>}) { |m| %Q(#{$1}\n<p class="rwtk_Paragraph">) } - content.gsub!(%r{<p[^>]*>(<h\d[^>]*>)}, '\1') - content.gsub!(%r{(</h\d>)</p>}, '\1') - content - end - end - end -end diff --git a/ruwiki/tags/release-0.9.0/lib/ruwiki/wiki/tokens/lists.rb b/ruwiki/tags/release-0.9.0/lib/ruwiki/wiki/tokens/lists.rb deleted file mode 100644 index 1615c2c..0000000 --- a/ruwiki/tags/release-0.9.0/lib/ruwiki/wiki/tokens/lists.rb +++ /dev/null @@ -1,112 +0,0 @@ -#-- -# Ruwiki -# Copyright © 2002 - 2004, Digikata and HaloStatue -# Alan Chen (alan@digikata.com) -# Austin Ziegler (ruwiki@halostatue.ca) -# -# Licensed under the same terms as Ruby. -# -# $Id$ -#++ -class Ruwiki::Wiki - # Produces Lists - class Lists < Ruwiki::Wiki::Token - def self.regexp - %r{^\\?([*#]+)\s+(.*)$} - end - - def replace - indent = @match.captures[0].scan(/./).map { |ee| ee == "*" ? 'ul' : 'ol' } - content = @match.captures[1] - - pre = '' - post = '' - indent.each { |elem| pre << %Q(<#{elem} class="rwtk_Lists">) } - indent.reverse_each { |elem| post << %Q(</#{elem}>) } - %Q(#{pre}<li class="rwtk_Lists">#{content}</li>#{post}) - end - - def restore - @match[0][1 .. -1] - end - - RE_NESTED_LISTS = %r{</[uo]l>\s*<[uo]l[^>]*>} - - def self.post_replace(content) - content.gsub!(%r{<p[^>]*><([uo]l[^>]*)>}, '<\1>') - content.gsub!(%r{</([uo]l)></p>}, '</\1>') - content.gsub!(RE_NESTED_LISTS, '') while content =~ RE_NESTED_LISTS - content - end - end - - # Produces block quotes. - class Blockquotes < Ruwiki::Wiki::Token - def self.regexp - %r{^\\?((:+)|(>+))(\s+.*)$} - end - - def replace - content = @match.captures[3] - - if @match.captures[2].nil? - char = ':' - cite = '' - else - char = '>' - cite = ' type="cite"' - end - indent = @match.captures[0].count(char) - - pre = '' - post = '' - indent.times do - pre << %Q(<blockquote#{cite} class="rwtk_Blockquotes">) - post << %Q(</blockquote>) - end - "#{pre}#{content}#{post}" - end - - def restore - @match[0][1 .. -1].gsub(/^>/, '>') - end - - def self.post_replace(content) - content.gsub!(%r{</blockquote>(\n|<br ?/?>)?<blockquote[^>]*>}, '') - content.gsub!(%r{(</?blockquote[^>]*>\n?)\s*}, '\1') - content.gsub!(%r{</blockquote>(<blockquote[^>]*>)+}, '\1') - content - end - end - - # Produces definition lists. Does not completely work correctly. - class Definitions < Ruwiki::Wiki::Token - def self.regexp - %r{^\\?(;+)\s+(.+?)\s+:\s+(.*)} - end - - def replace - definition = @match.captures[2] - term = @match.captures[1] - indent = @match.captures[0].count(';') - - pre = '' - post = '' - indent.times do - pre << %Q(<dl class="rwtk_Definitions">) - post << %Q(</dl>) - end - %Q(#{pre}<dt class="rwtk_Definitions">#{term}</dt><dd class="rwtk_Definitions">#{definition}</dd>#{post}) - end - - def restore - @match[0][1 .. -1] - end - - def self.post_replace(content) - content.gsub!(%r{</dl>(\n|<br ?/?>)?<dl[^>]*>}, '') - content.gsub!(%r{</dl>(<dl[^>]*>)+}, '\1') - content - end - end -end diff --git a/ruwiki/tags/release-0.9.0/lib/ruwiki/wiki/tokens/rubylists.rb b/ruwiki/tags/release-0.9.0/lib/ruwiki/wiki/tokens/rubylists.rb deleted file mode 100644 index b765ad1..0000000 --- a/ruwiki/tags/release-0.9.0/lib/ruwiki/wiki/tokens/rubylists.rb +++ /dev/null @@ -1,48 +0,0 @@ -#-- -# Ruwiki -# Copyright © 2002 - 2004, Digikata and HaloStatue -# Alan Chen (alan@digikata.com) -# Austin Ziegler (ruwiki@halostatue.ca) -# -# Licensed under the same terms as Ruby. -# -# $Id$ -#++ -class Ruwiki - class Wiki - # Convert ruby-talk mailing list references (e.g., [ruby-talk:12345]) - # into named links. - class RubyTalkLinks < Ruwiki::Wiki::Token - def self.rank - 1 - end - - def self.regexp - %r{\[ruby-talk:(\d+)\]} - end - - def replace - lm = @match.captures[0] -# %Q(<a class="rwtk_RubyTalkLinks" href="http://www.ruby-talk.org/#{lm}">#{@match[0]}</a>) - %Q(<a class="rwtk_RubyTalkLinks" href="http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/#{lm}">#{@match[0]}</a>) - end - end - - # Convert ruby-core/ext/dev/list/math mailing list references (e.g., - # [ruby-core:12345]) into named links. - class OtherRubyLinks < Ruwiki::Wiki::Token - def self.rank - 1 - end - - def self.regexp - %r{\[ruby-(list|doc|core|dev|ext|math):(\d+)\]} - end - - def replace - ln, lm = @match.captures[0..1] - %Q(<a class="rwtk_OtherRubyLinks" href="http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-#{ln}/#{lm}">#{@match[0]}</a>) - end - end - end -end |