olelo 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +10 -0
- data/.gitmodules +3 -0
- data/Gemfile +3 -0
- data/README.markdown +104 -0
- data/Rakefile +92 -0
- data/bin/olelo +5 -0
- data/config.ru +86 -0
- data/config/aspects.rb +256 -0
- data/config/config.yml.default +154 -0
- data/config/initializers/00-mime_types.rb +29 -0
- data/config/initializers/01-slim.rb +2 -0
- data/config/interwiki.yml +11 -0
- data/doc/AUTHORS +7 -0
- data/doc/LICENSE +22 -0
- data/lib/olelo.rb +39 -0
- data/lib/olelo/application.rb +294 -0
- data/lib/olelo/attributes.rb +285 -0
- data/lib/olelo/config.rb +88 -0
- data/lib/olelo/extensions.rb +252 -0
- data/lib/olelo/helper.rb +290 -0
- data/lib/olelo/hooks.rb +142 -0
- data/lib/olelo/html_safe.rb +29 -0
- data/lib/olelo/initializer.rb +76 -0
- data/lib/olelo/locale.rb +63 -0
- data/lib/olelo/locale.yml +284 -0
- data/lib/olelo/menu.rb +101 -0
- data/lib/olelo/middleware/blacklist.rb +25 -0
- data/lib/olelo/middleware/degrade_mime_type.rb +19 -0
- data/lib/olelo/middleware/flash.rb +97 -0
- data/lib/olelo/middleware/force_encoding.rb +41 -0
- data/lib/olelo/page.rb +266 -0
- data/lib/olelo/patch.rb +311 -0
- data/lib/olelo/plugin.rb +188 -0
- data/lib/olelo/repository.rb +225 -0
- data/lib/olelo/routing.rb +223 -0
- data/lib/olelo/templates.rb +30 -0
- data/lib/olelo/user.rb +132 -0
- data/lib/olelo/util.rb +233 -0
- data/lib/olelo/version.rb +3 -0
- data/lib/olelo/virtualfs.rb +161 -0
- data/lib/rack/olelo_patches.rb +33 -0
- data/lib/rack/relative_redirect.rb +44 -0
- data/lib/rack/static_cache.rb +93 -0
- data/lib/yard/addons.rb +1 -0
- data/lib/yard/addons/hook_handler.rb +25 -0
- data/lib/yard/addons/override_tag.rb +14 -0
- data/lib/yard/addons/route_handler.rb +33 -0
- data/lib/yard/addons/sanitize_anchor.rb +16 -0
- data/olelo.gemspec +31 -0
- data/plugins/aspects/changelog.rb +45 -0
- data/plugins/aspects/documentbrowser.rb +57 -0
- data/plugins/aspects/download.rb +11 -0
- data/plugins/aspects/highlight.rb +8 -0
- data/plugins/aspects/image.rb +41 -0
- data/plugins/aspects/imageinfo.rb +64 -0
- data/plugins/aspects/locale.yml +60 -0
- data/plugins/aspects/main.rb +199 -0
- data/plugins/aspects/pageinfo.rb +37 -0
- data/plugins/aspects/source.rb +6 -0
- data/plugins/aspects/subpages.rb +44 -0
- data/plugins/aspects/text.rb +9 -0
- data/plugins/blog/blog.css +1 -0
- data/plugins/blog/blog.scss +37 -0
- data/plugins/blog/locale.yml +12 -0
- data/plugins/blog/main.rb +85 -0
- data/plugins/editor/locale.yml +18 -0
- data/plugins/editor/markup/main.rb +3 -0
- data/plugins/editor/markup/script.js +10 -0
- data/plugins/editor/markup/script/00-jquery.textselection.js +267 -0
- data/plugins/editor/markup/script/01-olelo.markupeditor.js +116 -0
- data/plugins/editor/markup/script/init.js +10 -0
- data/plugins/editor/preview.rb +52 -0
- data/plugins/editor/recaptcha.rb +56 -0
- data/plugins/filters/creole.rb +37 -0
- data/plugins/filters/disposition.rb +9 -0
- data/plugins/filters/editsection.rb +67 -0
- data/plugins/filters/fix_img_tag.rb +16 -0
- data/plugins/filters/html_wrapper.rb +12 -0
- data/plugins/filters/interwiki.rb +19 -0
- data/plugins/filters/link_classifier.rb +26 -0
- data/plugins/filters/locale.yml +15 -0
- data/plugins/filters/main.rb +202 -0
- data/plugins/filters/markdown_nowiki.rb +15 -0
- data/plugins/filters/numbering.xsl +93 -0
- data/plugins/filters/orgmode.rb +6 -0
- data/plugins/filters/rubypants.rb +6 -0
- data/plugins/filters/s5/main.rb +32 -0
- data/plugins/filters/s5/s5.xsl +118 -0
- data/plugins/filters/tilt.rb +17 -0
- data/plugins/filters/toc.rb +50 -0
- data/plugins/filters/xhtml2latex.xsl +232 -0
- data/plugins/filters/xslt.rb +22 -0
- data/plugins/gallery/gallery.css +1 -0
- data/plugins/gallery/gallery.scss +28 -0
- data/plugins/gallery/main.rb +34 -0
- data/plugins/misc/fancybox/images/blank.gif +0 -0
- data/plugins/misc/fancybox/images/fancy_close.png +0 -0
- data/plugins/misc/fancybox/images/fancy_loading.png +0 -0
- data/plugins/misc/fancybox/images/fancy_nav_left.png +0 -0
- data/plugins/misc/fancybox/images/fancy_nav_right.png +0 -0
- data/plugins/misc/fancybox/images/fancy_shadow_e.png +0 -0
- data/plugins/misc/fancybox/images/fancy_shadow_n.png +0 -0
- data/plugins/misc/fancybox/images/fancy_shadow_ne.png +0 -0
- data/plugins/misc/fancybox/images/fancy_shadow_nw.png +0 -0
- data/plugins/misc/fancybox/images/fancy_shadow_s.png +0 -0
- data/plugins/misc/fancybox/images/fancy_shadow_se.png +0 -0
- data/plugins/misc/fancybox/images/fancy_shadow_sw.png +0 -0
- data/plugins/misc/fancybox/images/fancy_shadow_w.png +0 -0
- data/plugins/misc/fancybox/images/fancy_title_left.png +0 -0
- data/plugins/misc/fancybox/images/fancy_title_main.png +0 -0
- data/plugins/misc/fancybox/images/fancy_title_over.png +0 -0
- data/plugins/misc/fancybox/images/fancy_title_right.png +0 -0
- data/plugins/misc/fancybox/images/fancybox-x.png +0 -0
- data/plugins/misc/fancybox/images/fancybox-y.png +0 -0
- data/plugins/misc/fancybox/images/fancybox.png +0 -0
- data/plugins/misc/fancybox/jquery.fancybox.css +1 -0
- data/plugins/misc/fancybox/jquery.fancybox.scss +323 -0
- data/plugins/misc/fancybox/main.rb +4 -0
- data/plugins/misc/fancybox/script.js +37 -0
- data/plugins/misc/fancybox/script/00-jquery.mousewheel.js +84 -0
- data/plugins/misc/fancybox/script/01-jquery.easing.js +205 -0
- data/plugins/misc/fancybox/script/02-jquery.fancybox.js +1156 -0
- data/plugins/misc/fancybox/script/init.js +18 -0
- data/plugins/misc/system.rb +192 -0
- data/plugins/misc/variables.rb +29 -0
- data/plugins/misc/webdav.rb +45 -0
- data/plugins/repositories/git_grep.rb +69 -0
- data/plugins/repositories/gitrb_repository.rb +204 -0
- data/plugins/repositories/locale.yml +12 -0
- data/plugins/repositories/rugged_repository.rb +454 -0
- data/plugins/security/acl.rb +57 -0
- data/plugins/security/basic_auth.rb +21 -0
- data/plugins/security/locale.yml +21 -0
- data/plugins/security/persistent_login.rb +32 -0
- data/plugins/security/portal.rb +28 -0
- data/plugins/security/private_wiki.rb +24 -0
- data/plugins/security/readonly_wiki.rb +25 -0
- data/plugins/security/stack.rb +20 -0
- data/plugins/security/yamlfile.rb +66 -0
- data/plugins/tags/code.rb +6 -0
- data/plugins/tags/footnotes.rb +35 -0
- data/plugins/tags/gist-embed.css +123 -0
- data/plugins/tags/gist.rb +13 -0
- data/plugins/tags/html.rb +57 -0
- data/plugins/tags/include.rb +20 -0
- data/plugins/tags/main.rb +353 -0
- data/plugins/tags/math.rb +117 -0
- data/plugins/tags/scripting.rb +64 -0
- data/plugins/tags/sort.rb +7 -0
- data/plugins/tags/tabs.rb +20 -0
- data/plugins/treeview/images/collapsed.png +0 -0
- data/plugins/treeview/images/expanded.png +0 -0
- data/plugins/treeview/images/menu.png +0 -0
- data/plugins/treeview/images/tree.png +0 -0
- data/plugins/treeview/images/wait.gif +0 -0
- data/plugins/treeview/main.rb +16 -0
- data/plugins/treeview/script.js +5 -0
- data/plugins/treeview/script/00-jquery.treeview.js +164 -0
- data/plugins/treeview/script/init.js +25 -0
- data/plugins/treeview/treeview.css +1 -0
- data/plugins/treeview/treeview.scss +113 -0
- data/plugins/utils/assets.rb +74 -0
- data/plugins/utils/cache.rb +53 -0
- data/plugins/utils/image_magick.rb +34 -0
- data/plugins/utils/pygments.css +1 -0
- data/plugins/utils/pygments.rb +50 -0
- data/plugins/utils/pygments.scss +83 -0
- data/plugins/utils/semaphore.rb +50 -0
- data/plugins/utils/shell.rb +45 -0
- data/plugins/utils/store.rb +315 -0
- data/plugins/utils/worker.rb +36 -0
- data/plugins/utils/xml.rb +29 -0
- data/static/images/favicon.png +0 -0
- data/static/script.js +267 -0
- data/static/script/00-json2.js +486 -0
- data/static/script/01-jstorage.js +217 -0
- data/static/script/02-jquery.js +9440 -0
- data/static/script/03-jquery.ui.core.js +337 -0
- data/static/script/04-jquery.ui.widget.js +502 -0
- data/static/script/05-jquery.ui.position.js +517 -0
- data/static/script/06-jquery.ui.menu.js +609 -0
- data/static/script/07-jquery.ui.autocomplete.js +601 -0
- data/static/script/08-olelo.i18n.js +37 -0
- data/static/script/09-olelo.unsaved.js +68 -0
- data/static/script/10-olelo.historytable.js +40 -0
- data/static/script/11-olelo.pagination.js +18 -0
- data/static/script/13-olelo.tabwidget.js +57 -0
- data/static/script/14-olelo.timeago.js +70 -0
- data/static/script/15-olelo.underliner.js +31 -0
- data/static/script/16-olelo.ui.combobox.js +32 -0
- data/static/script/init.js +48 -0
- data/static/themes/atlantis/constants.scss +15 -0
- data/static/themes/atlantis/iehacks.scss +38 -0
- data/static/themes/atlantis/images/actions/delete.png +0 -0
- data/static/themes/atlantis/images/actions/edit.png +0 -0
- data/static/themes/atlantis/images/actions/history.png +0 -0
- data/static/themes/atlantis/images/actions/home.png +0 -0
- data/static/themes/atlantis/images/actions/move.png +0 -0
- data/static/themes/atlantis/images/actions/new.png +0 -0
- data/static/themes/atlantis/images/actions/page.png +0 -0
- data/static/themes/atlantis/images/bg/button.png +0 -0
- data/static/themes/atlantis/images/bg/container.png +0 -0
- data/static/themes/atlantis/images/bg/content.png +0 -0
- data/static/themes/atlantis/images/bg/footer.png +0 -0
- data/static/themes/atlantis/images/bg/header.jpg +0 -0
- data/static/themes/atlantis/images/bg/header.orig.jpg +0 -0
- data/static/themes/atlantis/images/bg/header_gray.jpg +0 -0
- data/static/themes/atlantis/images/bug.png +0 -0
- data/static/themes/atlantis/images/filetypes/7z.png +0 -0
- data/static/themes/atlantis/images/filetypes/_archive.png +0 -0
- data/static/themes/atlantis/images/filetypes/_audio.png +0 -0
- data/static/themes/atlantis/images/filetypes/_code.png +0 -0
- data/static/themes/atlantis/images/filetypes/_linux.png +0 -0
- data/static/themes/atlantis/images/filetypes/_picture.png +0 -0
- data/static/themes/atlantis/images/filetypes/_video.png +0 -0
- data/static/themes/atlantis/images/filetypes/bz2.png +0 -0
- data/static/themes/atlantis/images/filetypes/doc.png +0 -0
- data/static/themes/atlantis/images/filetypes/flac.png +0 -0
- data/static/themes/atlantis/images/filetypes/gz.png +0 -0
- data/static/themes/atlantis/images/filetypes/html.png +0 -0
- data/static/themes/atlantis/images/filetypes/java.png +0 -0
- data/static/themes/atlantis/images/filetypes/jpg.png +0 -0
- data/static/themes/atlantis/images/filetypes/midi.png +0 -0
- data/static/themes/atlantis/images/filetypes/mp3.png +0 -0
- data/static/themes/atlantis/images/filetypes/ogg.png +0 -0
- data/static/themes/atlantis/images/filetypes/pdf.png +0 -0
- data/static/themes/atlantis/images/filetypes/php.png +0 -0
- data/static/themes/atlantis/images/filetypes/png.png +0 -0
- data/static/themes/atlantis/images/filetypes/ppt.png +0 -0
- data/static/themes/atlantis/images/filetypes/psd.png +0 -0
- data/static/themes/atlantis/images/filetypes/rar.png +0 -0
- data/static/themes/atlantis/images/filetypes/rb.png +0 -0
- data/static/themes/atlantis/images/filetypes/sh.png +0 -0
- data/static/themes/atlantis/images/filetypes/tar.png +0 -0
- data/static/themes/atlantis/images/filetypes/txt.png +0 -0
- data/static/themes/atlantis/images/filetypes/wma.png +0 -0
- data/static/themes/atlantis/images/filetypes/xls.png +0 -0
- data/static/themes/atlantis/images/filetypes/zip.png +0 -0
- data/static/themes/atlantis/images/folder.png +0 -0
- data/static/themes/atlantis/images/folder_open.png +0 -0
- data/static/themes/atlantis/images/loading.gif +0 -0
- data/static/themes/atlantis/images/loading.xcf +0 -0
- data/static/themes/atlantis/images/not_found.png +0 -0
- data/static/themes/atlantis/images/page.png +0 -0
- data/static/themes/atlantis/images/search.png +0 -0
- data/static/themes/atlantis/layout.scss +115 -0
- data/static/themes/atlantis/menu.scss +99 -0
- data/static/themes/atlantis/print.scss +129 -0
- data/static/themes/atlantis/screen.scss +495 -0
- data/static/themes/atlantis/style.css +3 -0
- data/static/themes/lib/autocomplete.scss +39 -0
- data/static/themes/lib/headlines.scss +10 -0
- data/static/themes/lib/horizontal-list.scss +31 -0
- data/static/themes/lib/patch.scss +88 -0
- data/static/themes/lib/reset.scss +114 -0
- data/static/themes/lib/rounded.scss +46 -0
- data/static/themes/lib/shadow.scss +14 -0
- data/test/config_test.rb +28 -0
- data/test/factory_test.rb +29 -0
- data/test/hash_extensions_test.rb +16 -0
- data/test/helper.rb +38 -0
- data/test/hooks_test.rb +85 -0
- data/test/object_extensions_test.rb +20 -0
- data/test/page_test.rb +168 -0
- data/test/request_test.rb +166 -0
- data/test/string_extensions_test.rb +32 -0
- data/test/templates_test.rb +39 -0
- data/test/util_test.rb +71 -0
- data/views/changes.slim +22 -0
- data/views/compare.slim +8 -0
- data/views/delete.slim +9 -0
- data/views/deleted.slim +2 -0
- data/views/edit.slim +65 -0
- data/views/error.slim +6 -0
- data/views/history.slim +20 -0
- data/views/layout.slim +38 -0
- data/views/login.slim +37 -0
- data/views/move.slim +10 -0
- data/views/not_found.slim +6 -0
- data/views/profile.slim +26 -0
- data/views/show.slim +9 -0
- metadata +488 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
require 'rack'
|
|
2
|
+
require 'socket'
|
|
3
|
+
|
|
4
|
+
class Rack::Request
|
|
5
|
+
# Remote host name
|
|
6
|
+
def remote_host
|
|
7
|
+
@remote_host ||= Socket.gethostbyaddr(ip.split('.').map(&:to_i).pack('C*')).first rescue nil
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# No caching for this request?
|
|
11
|
+
def no_cache?
|
|
12
|
+
env['HTTP_PRAGMA'] == 'no-cache' || env['HTTP_CACHE_CONTROL'].to_s.include?('no-cache')
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Rack::Lint injector
|
|
17
|
+
class Rack::Builder
|
|
18
|
+
module UseLint
|
|
19
|
+
def use(middleware, *args, &block)
|
|
20
|
+
super Rack::Lint if middleware != Rack::Lint
|
|
21
|
+
super
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def run(app)
|
|
25
|
+
use Rack::Lint
|
|
26
|
+
super
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def use_lint
|
|
31
|
+
class << self; include UseLint; end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
require 'rack'
|
|
2
|
+
|
|
3
|
+
# Rack::RelativeRedirect is a simple middleware that converts relative paths in
|
|
4
|
+
# redirects in absolute urls, so they conform to RFC2616. It allows the user to
|
|
5
|
+
# specify the absolute path to use (with a sensible default), and handles
|
|
6
|
+
# relative paths (those that don't start with a slash) as well.
|
|
7
|
+
class Rack::RelativeRedirect
|
|
8
|
+
SCHEME_MAP = {'http'=>'80', 'https'=>'443'}
|
|
9
|
+
# The default proc used if a block is not provided to .new
|
|
10
|
+
# Just uses the url scheme of the request and the server name.
|
|
11
|
+
DEFAULT_ABSOLUTE_PROC = proc do |env, res|
|
|
12
|
+
port = env['SERVER_PORT']
|
|
13
|
+
scheme = env['rack.url_scheme']
|
|
14
|
+
"#{scheme}://#{env['SERVER_NAME']}#{":#{port}" unless SCHEME_MAP[scheme] == port}"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Initialize a new RelativeRedirect object with the given arguments. Arguments:
|
|
18
|
+
# * app : The next middleware in the chain. This is always called.
|
|
19
|
+
# * &block : If provided, it is called with the environment and the response
|
|
20
|
+
# from the next middleware. It should return a string representing the scheme
|
|
21
|
+
# and server name (such as 'http://example.org').
|
|
22
|
+
def initialize(app, &block)
|
|
23
|
+
@app = app
|
|
24
|
+
@absolute_proc = block || DEFAULT_ABSOLUTE_PROC
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Call the next middleware with the environment. If the request was a
|
|
28
|
+
# redirect (response status 301, 302, or 303), and the location header does
|
|
29
|
+
# not start with an http or https url scheme, call the block provided by new
|
|
30
|
+
# and use that to make the Location header an absolute url. If the Location
|
|
31
|
+
# does not start with a slash, make location relative to the path requested.
|
|
32
|
+
def call(env)
|
|
33
|
+
res = @app.call(env)
|
|
34
|
+
if [301,302,303].include?(res[0]) and loc = res[1]['Location'] and !%r{\Ahttps?://}o.match(loc)
|
|
35
|
+
absolute = @absolute_proc.call(env, res)
|
|
36
|
+
res[1]['Location'] = if %r{\A/}.match(loc)
|
|
37
|
+
"#{absolute}#{loc}"
|
|
38
|
+
else
|
|
39
|
+
"#{absolute}#{File.dirname(Rack::Utils.unescape(env['PATH_INFO']))}/#{loc}"
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
res
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
module Rack
|
|
2
|
+
|
|
3
|
+
#
|
|
4
|
+
# The Rack::StaticCache middleware automatically adds, removes and modifies
|
|
5
|
+
# stuffs in response headers to facilitiate client and proxy caching for static files
|
|
6
|
+
# that minimizes http requests and improves overall load times for second time visitors.
|
|
7
|
+
#
|
|
8
|
+
# Once a static content is stored in a client/proxy the only way to enforce the browser
|
|
9
|
+
# to fetch the latest content and ignore the cache is to rename the static file.
|
|
10
|
+
#
|
|
11
|
+
# Alternatively, we can add a version number into the URL to the content to bypass
|
|
12
|
+
# the caches. Rack::StaticCache by default handles version numbers in the filename.
|
|
13
|
+
# As an example,
|
|
14
|
+
# http://yoursite.com/images/test-1.0.0.png and http://yoursite.com/images/test-2.0.0.png
|
|
15
|
+
# both reffers to the same image file http://yoursite.com/images/test.png
|
|
16
|
+
#
|
|
17
|
+
# Another way to bypass the cache is adding the version number in a field-value pair in the
|
|
18
|
+
# URL query string. As an example, http://yoursite.com/images/test.png?v=1.0.0
|
|
19
|
+
# In that case, set the option :versioning to false to avoid unneccessary regexp calculations.
|
|
20
|
+
#
|
|
21
|
+
# It's better to keep the current version number in some config file and use it in every static
|
|
22
|
+
# content's URL. So each time we modify our static contents, we just have to change the version
|
|
23
|
+
# number to enforce the browser to fetch the latest content.
|
|
24
|
+
#
|
|
25
|
+
# You can use Rack::Deflater along with Rack::StaticCache for further improvements in page loading time.
|
|
26
|
+
#
|
|
27
|
+
# Examples:
|
|
28
|
+
# use Rack::StaticCache, :urls => ["/images", "/css", "/js", "/documents*"], :root => "statics"
|
|
29
|
+
# will serve all requests beginning with /images, /csss or /js from the
|
|
30
|
+
# directory "statics/images", "statics/css", "statics/js".
|
|
31
|
+
# All the files from these directories will have modified headers to enable client/proxy caching,
|
|
32
|
+
# except the files from the directory "documents". Append a * (star) at the end of the pattern
|
|
33
|
+
# if you want to disable caching for any pattern . In that case, plain static contents will be served with
|
|
34
|
+
# default headers.
|
|
35
|
+
#
|
|
36
|
+
# use Rack::StaticCache, :urls => ["/images"], :duration => 2, :versioning => false
|
|
37
|
+
# will serve all requests begining with /images under the current directory (default for the option :root
|
|
38
|
+
# is current directory). All the contents served will have cache expiration duration set to 2 years in headers
|
|
39
|
+
# (default for :duration is 1 year), and StaticCache will not compute any versioning logics (default for
|
|
40
|
+
# :versioning is true)
|
|
41
|
+
#
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class StaticCache
|
|
45
|
+
|
|
46
|
+
def initialize(app, options={})
|
|
47
|
+
@app = app
|
|
48
|
+
@urls = options[:urls]
|
|
49
|
+
@no_cache = {}
|
|
50
|
+
@urls.collect! do |url|
|
|
51
|
+
if url =~ /\*$/
|
|
52
|
+
url.sub!(/\*$/, '')
|
|
53
|
+
@no_cache[url] = 1
|
|
54
|
+
end
|
|
55
|
+
url
|
|
56
|
+
end
|
|
57
|
+
root = options[:root] || Dir.pwd
|
|
58
|
+
@file_server = Rack::File.new(root)
|
|
59
|
+
@cache_duration = options[:duration] || 1
|
|
60
|
+
@versioning_enabled = true
|
|
61
|
+
@versioning_enabled = options[:versioning] unless options[:versioning].nil?
|
|
62
|
+
@duration_in_seconds = self.duration_in_seconds
|
|
63
|
+
@duration_in_words = self.duration_in_words
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def call(env)
|
|
67
|
+
path = env["PATH_INFO"]
|
|
68
|
+
url = @urls.detect{ |u| path.index(u) == 0 }
|
|
69
|
+
unless url.nil?
|
|
70
|
+
path.sub!(/-[\d.]+([.][a-zA-Z][\w]+)?$/, '\1') if @versioning_enabled
|
|
71
|
+
status, headers, body = @file_server.call(env)
|
|
72
|
+
if @no_cache[url].nil?
|
|
73
|
+
headers['Cache-Control'] ="max-age=#{@duration_in_seconds}, public"
|
|
74
|
+
headers['Expires'] = @duration_in_words
|
|
75
|
+
headers.delete 'Etag'
|
|
76
|
+
headers.delete 'Pragma'
|
|
77
|
+
headers.delete 'Last-Modified'
|
|
78
|
+
end
|
|
79
|
+
[status, headers, body]
|
|
80
|
+
else
|
|
81
|
+
@app.call(env)
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def duration_in_words
|
|
86
|
+
(Time.now + self.duration_in_seconds).strftime '%a, %d %b %Y %H:%M:%S GMT'
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def duration_in_seconds
|
|
90
|
+
60 * 60 * 24 * 365 * @cache_duration
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
data/lib/yard/addons.rb
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Dir[File.dirname(__FILE__) + '/addons/*.rb'].each {|file| require file }
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module YARD
|
|
2
|
+
module Handlers
|
|
3
|
+
class HookHandler < Ruby::Base
|
|
4
|
+
handles method_call(:hook)
|
|
5
|
+
handles method_call(:before)
|
|
6
|
+
handles method_call(:after)
|
|
7
|
+
|
|
8
|
+
def process
|
|
9
|
+
hook = statement.parameters.first.source
|
|
10
|
+
return if hook =~ /^"(BEFORE|AFTER)/
|
|
11
|
+
name = "#{statement.method_name(true).to_s.upcase} #{hook}"
|
|
12
|
+
route = register CodeObjects::MethodObject.new(namespace, name, :instance) do |o|
|
|
13
|
+
o.visibility = "public"
|
|
14
|
+
o.source = statement.source
|
|
15
|
+
o.signature = name
|
|
16
|
+
o.explicit = true
|
|
17
|
+
o.scope = scope
|
|
18
|
+
o.docstring = statement.comments
|
|
19
|
+
o.sanitize_anchor = true
|
|
20
|
+
o.add_file(parser.file, statement.line)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module YARD::Tags
|
|
2
|
+
class OverrideTag < Tag
|
|
3
|
+
def initialize(tag_name, text)
|
|
4
|
+
super(tag_name, text)
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def text
|
|
8
|
+
"{#{object.namespace.superclass}##{object.name(false)}}"
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
Library.define_tag "Override", :override, OverrideTag
|
|
13
|
+
Library.visible_tags.place(:override).before(:return)
|
|
14
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
module YARD
|
|
2
|
+
module Handlers
|
|
3
|
+
class RouteHandler < Ruby::Base
|
|
4
|
+
handles method_call(:get)
|
|
5
|
+
handles method_call(:post)
|
|
6
|
+
handles method_call(:put)
|
|
7
|
+
handles method_call(:delete)
|
|
8
|
+
handles method_call(:head)
|
|
9
|
+
|
|
10
|
+
def register_route(name, explicit)
|
|
11
|
+
register CodeObjects::MethodObject.new(namespace, name, :instance) do |o|
|
|
12
|
+
o.visibility = "public"
|
|
13
|
+
o.source = statement.source
|
|
14
|
+
o.signature = name
|
|
15
|
+
o.explicit = explicit
|
|
16
|
+
o.scope = scope
|
|
17
|
+
o.docstring = statement.comments
|
|
18
|
+
o.sanitize_anchor = true
|
|
19
|
+
o.add_file(parser.file, statement.line)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def process
|
|
24
|
+
path = statement.parameters.first.source
|
|
25
|
+
if path =~ /'(.*)'/
|
|
26
|
+
verb = statement.method_name(true).to_s.upcase
|
|
27
|
+
register_route("HEAD #{$1}", false) if verb == 'GET'
|
|
28
|
+
register_route("#{verb} #{$1}", true)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module YARD
|
|
2
|
+
class CodeObjects::Base
|
|
3
|
+
attr_accessor :sanitize_anchor
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
module Templates::Helpers::HtmlHelper
|
|
7
|
+
alias anchor_for_without_sanitize anchor_for
|
|
8
|
+
def anchor_for(object)
|
|
9
|
+
if CodeObjects::Base === object && object.sanitize_anchor
|
|
10
|
+
anchor_for_without_sanitize(object).gsub(/[^\w_\-]/, '_')
|
|
11
|
+
else
|
|
12
|
+
anchor_for_without_sanitize(object)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
data/olelo.gemspec
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
require File.dirname(__FILE__) + '/lib/olelo/version'
|
|
3
|
+
require 'date'
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |s|
|
|
6
|
+
s.name = 'olelo'
|
|
7
|
+
s.version = Olelo::VERSION
|
|
8
|
+
s.date = Date.today.to_s
|
|
9
|
+
s.authors = ['Daniel Mendler']
|
|
10
|
+
s.email = ['mail@daniel-mendler.de']
|
|
11
|
+
s.summary = 'Olelo is a git-based wiki.'
|
|
12
|
+
s.summary = 'Olelo is a git-based wiki which supports many markup languages, tags, embedded TeX and much more. It can be extended through plugins.'
|
|
13
|
+
s.homepage = 'http://gitwiki.org/'
|
|
14
|
+
s.rubyforge_project = s.name
|
|
15
|
+
|
|
16
|
+
s.files = `git ls-files | grep -P -v '^tools/'`.split("\n")
|
|
17
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
|
18
|
+
s.require_paths = %w(lib)
|
|
19
|
+
|
|
20
|
+
s.add_runtime_dependency('tilt', ['~> 1.3.3'])
|
|
21
|
+
s.add_runtime_dependency('slim', ['~> 1.3.3'])
|
|
22
|
+
s.add_runtime_dependency('creole', ['~> 0.4.2'])
|
|
23
|
+
s.add_runtime_dependency('nokogiri', ['~> 1.5.5'])
|
|
24
|
+
s.add_runtime_dependency('mimemagic', ['~> 0.1.9'])
|
|
25
|
+
s.add_runtime_dependency('rack', ['~> 1.4.1'])
|
|
26
|
+
s.add_runtime_dependency('redcarpet', ['~> 2.1.1'])
|
|
27
|
+
s.add_runtime_dependency('rugged', ['~> 0.17.0b6'])
|
|
28
|
+
|
|
29
|
+
s.add_development_dependency('rake', ['>= 0.8.7'])
|
|
30
|
+
s.add_development_dependency('sass', ['>= 3.1.0'])
|
|
31
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
description 'Changelog Aspect'
|
|
3
|
+
require 'rss/maker'
|
|
4
|
+
|
|
5
|
+
Aspect.create(:changelog, :cacheable => true, :hidden => true) do
|
|
6
|
+
def call(context, page)
|
|
7
|
+
format = context.params[:format]
|
|
8
|
+
|
|
9
|
+
url = context.request.base_url
|
|
10
|
+
context.header['Content-Type'] = "application/#{format == 'rss' ? 'rss' : 'atom'}+xml; charset=utf-8"
|
|
11
|
+
|
|
12
|
+
content = RSS::Maker.make(format == 'rss' ? '2.0' : 'atom') do |feed|
|
|
13
|
+
feed.channel.generator = 'Ōlelo'
|
|
14
|
+
feed.channel.title = Config['title']
|
|
15
|
+
feed.channel.link = url + '/' + page.path
|
|
16
|
+
feed.channel.description = Config['title'] + ' Changelog'
|
|
17
|
+
feed.channel.id = url + page.path
|
|
18
|
+
feed.channel.updated = Time.now
|
|
19
|
+
feed.channel.author = Config['title']
|
|
20
|
+
feed.items.do_sort = true
|
|
21
|
+
page.history.each do |version|
|
|
22
|
+
i = feed.items.new_item
|
|
23
|
+
i.title = version.comment
|
|
24
|
+
i.link = url + '/changes'/version
|
|
25
|
+
i.date = version.date
|
|
26
|
+
i.dc_creator = version.author.name
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
content.to_s
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
Application.hook :head do
|
|
34
|
+
%{<link rel="alternate" type="application/atom+xml" title="Sitewide Atom Changelog"
|
|
35
|
+
href="#{escape_html build_path('/', :aspect => 'changelog', :format => 'atom')}"/>
|
|
36
|
+
<link rel="alternate" type="application/rss+xml" title="Sitewide RSS Changelog"
|
|
37
|
+
href="#{escape_html build_path('/', :aspect => 'changelog', :format => 'rss')}"/>}
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
Application.hook :head do
|
|
41
|
+
%{<link rel="alternate" type="application/atom+xml" title="#{escape_html page.path} Atom Changelog"
|
|
42
|
+
href="#{escape_html(build_path(page.path, :aspect => 'changelog', :format => 'atom'))}"/>
|
|
43
|
+
<link rel="alternate" type="application/rss+xml" title="#{escape_html page.path} RSS Changelog"
|
|
44
|
+
href="#{escape_html(build_path(page.path, :aspect => 'changelog', :format => 'rss'))}"/>} if page && !page.new? && !page.root?
|
|
45
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
description 'Document browser aspect'
|
|
2
|
+
dependencies 'utils/shell'
|
|
3
|
+
|
|
4
|
+
Aspect.create(:documentbrowser, :priority => 1, :layout => true, :cacheable => true, :accepts => %r{^application/pdf$|postscript$}) do
|
|
5
|
+
def count_pages
|
|
6
|
+
content = @page.content
|
|
7
|
+
page_count = 0
|
|
8
|
+
if @page.mime == 'application/pdf'
|
|
9
|
+
page_count = $1.to_i if Shell.pdfinfo('-').run(content) =~ /Pages:\s+(\d+)/
|
|
10
|
+
else
|
|
11
|
+
content = Shell.cmd($1 == 'gz' ? 'gunzip' : 'bunzip2').run(content) if @page.mime.to_s =~ /(gz|bz)/
|
|
12
|
+
page_count = $1.to_i if content =~ /^%%Pages:\s+(\d+)$/
|
|
13
|
+
end
|
|
14
|
+
page_count
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def call(context, page)
|
|
18
|
+
@page = page
|
|
19
|
+
@page_nr = [context.params[:page].to_i, 1].max
|
|
20
|
+
@page_count = count_pages
|
|
21
|
+
render :browser
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
__END__
|
|
26
|
+
|
|
27
|
+
@@ browser.slim
|
|
28
|
+
= pagination(@page, @page_count, @page_nr, :aspect => 'documentbrowser')
|
|
29
|
+
p
|
|
30
|
+
img src=build_path(@page, :aspect => 'image', :geometry => '480x>', :trim => 1, :page => @page_nr)
|
|
31
|
+
= pagination(@page, @page_count, @page_nr, :aspect => 'documentbrowser')
|
|
32
|
+
h3= :information.t
|
|
33
|
+
table
|
|
34
|
+
tbody
|
|
35
|
+
tr
|
|
36
|
+
td= :name.t
|
|
37
|
+
td= @page.name
|
|
38
|
+
tr
|
|
39
|
+
td= :title.t
|
|
40
|
+
td= @page.title
|
|
41
|
+
tr
|
|
42
|
+
td= :description.t
|
|
43
|
+
td= @page.attributes['description']
|
|
44
|
+
- if @page.version
|
|
45
|
+
tr
|
|
46
|
+
td= :last_modified.t
|
|
47
|
+
td= date @page.version.date
|
|
48
|
+
tr
|
|
49
|
+
td= :version.t
|
|
50
|
+
td.version= @page.version
|
|
51
|
+
tr
|
|
52
|
+
td= :type.t
|
|
53
|
+
td= @page.mime.comment.blank? ? @page.mime : "#{@page.mime.comment} (#{@page.mime})"
|
|
54
|
+
tr
|
|
55
|
+
td= :download.t
|
|
56
|
+
td
|
|
57
|
+
a href=build_path(@page, :aspect => 'download') = :download.t
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
description 'Download aspect'
|
|
2
|
+
|
|
3
|
+
Aspect.create(:download) do
|
|
4
|
+
def accepts?(page); !page.content.empty?; end
|
|
5
|
+
def call(context, page)
|
|
6
|
+
name = page.root? ? :root.t : page.name.gsub(/[^\w.\-_]/, '_')
|
|
7
|
+
context.header['Content-Disposition'] = %{attachment; filename="#{name}"}
|
|
8
|
+
context.header['Content-Length'] = page.content.bytesize.to_s
|
|
9
|
+
page.content
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
description 'Source code highlighting aspect'
|
|
2
|
+
dependencies 'utils/pygments'
|
|
3
|
+
|
|
4
|
+
Aspect.create(:highlight, :priority => 2, :layout => true, :cacheable => true) do
|
|
5
|
+
def accepts?(page); !page.content.empty? && Pygments.file_format(page.name); end
|
|
6
|
+
def call(context, page); Pygments.pygmentize(page.content, Pygments.file_format(page.name)); end
|
|
7
|
+
end
|
|
8
|
+
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
description 'Image aspect'
|
|
2
|
+
dependencies 'utils/image_magick'
|
|
3
|
+
|
|
4
|
+
Aspect.create(:image, :priority => 5, :accepts => %r{^application/pdf$|postscript$|^image/}, :cacheable => true) do
|
|
5
|
+
def call(context, page)
|
|
6
|
+
geometry = context.params[:geometry]
|
|
7
|
+
trim = context.params[:trim]
|
|
8
|
+
ps = page.mime.to_s =~ /postscript/
|
|
9
|
+
if ps || page.mime == 'application/pdf'
|
|
10
|
+
page_nr = [context.params[:page].to_i, 1].max
|
|
11
|
+
cmd = ImageMagick.new
|
|
12
|
+
if ps
|
|
13
|
+
cmd.cmd($1 == 'gz' ? 'gunzip' : 'bunzip2') if page.mime.to_s =~ /(bz|gz)/
|
|
14
|
+
cmd.psselect "-p#{page_nr}"
|
|
15
|
+
cmd.gs('-sDEVICE=jpeg', '-sOutputFile=-', '-r144', '-dBATCH', '-dNOPAUSE', '-q', '-')
|
|
16
|
+
end
|
|
17
|
+
cmd.convert('-depth', 8, '-quality', 50) do |args|
|
|
18
|
+
args << '-trim' if trim
|
|
19
|
+
args << '-thumbnail' << geometry if geometry =~ /^(\d+)?x?(\d+)?[%!<>]*$/
|
|
20
|
+
if ps
|
|
21
|
+
args << '-'
|
|
22
|
+
else
|
|
23
|
+
args << '-density' << 144 << "-[#{page_nr - 1}]"
|
|
24
|
+
end
|
|
25
|
+
args << 'JPEG:-'
|
|
26
|
+
end
|
|
27
|
+
context.header['Content-Type'] = 'image/jpeg'
|
|
28
|
+
cmd.run(page.content)
|
|
29
|
+
elsif page.mime.to_s =~ /svg/ || geometry || trim
|
|
30
|
+
cmd = ImageMagick.convert do |args|
|
|
31
|
+
args << '-trim' if trim
|
|
32
|
+
args << '-thumbnail' << geometry if geometry =~ /^(\d+)?x?(\d+)?[%!<>]*$/
|
|
33
|
+
args << '-' << (page.mime.to_s == 'image/jpeg' ? 'JPEG:-' : 'PNG:-')
|
|
34
|
+
end
|
|
35
|
+
context.header['Content-Type'] = 'image/png'
|
|
36
|
+
cmd.run(page.content)
|
|
37
|
+
else
|
|
38
|
+
page.content
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|