thewoolleyman-webgen 0.5.8.20090419
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/AUTHORS +8 -0
- data/COPYING +10 -0
- data/GPL +340 -0
- data/Rakefile +334 -0
- data/THANKS +18 -0
- data/bin/webgen +12 -0
- data/data/webgen/resources.yaml +3 -0
- data/data/webgen/webgui/controller/main.rb +135 -0
- data/data/webgen/webgui/overrides/win32console.rb +0 -0
- data/data/webgen/webgui/public/css/jquery.autocomplete.css +50 -0
- data/data/webgen/webgui/public/css/ramaze_error.css +90 -0
- data/data/webgen/webgui/public/css/style.css +55 -0
- data/data/webgen/webgui/public/img/headerbg.jpg +0 -0
- data/data/webgen/webgui/public/img/webgen_logo.png +0 -0
- data/data/webgen/webgui/public/js/jquery.autocomplete.js +15 -0
- data/data/webgen/webgui/public/js/jquery.js +32 -0
- data/data/webgen/webgui/view/create_website.xhtml +22 -0
- data/data/webgen/webgui/view/error.xhtml +64 -0
- data/data/webgen/webgui/view/index.xhtml +22 -0
- data/data/webgen/webgui/view/manage_website.xhtml +18 -0
- data/data/webgen/webgui/view/page.xhtml +40 -0
- data/data/webgen/website_skeleton/README +10 -0
- data/data/webgen/website_skeleton/Rakefile +40 -0
- data/data/webgen/website_skeleton/config.yaml +17 -0
- data/data/webgen/website_skeleton/ext/init.rb +10 -0
- data/data/webgen/website_styles/1024px/README +13 -0
- data/data/webgen/website_styles/1024px/src/default.css +188 -0
- data/data/webgen/website_styles/1024px/src/default.template +60 -0
- data/data/webgen/website_styles/1024px/src/images/background.gif +0 -0
- data/data/webgen/website_styles/andreas00/README +13 -0
- data/data/webgen/website_styles/andreas00/src/default.css +290 -0
- data/data/webgen/website_styles/andreas00/src/default.template +60 -0
- data/data/webgen/website_styles/andreas00/src/images/bg.gif +0 -0
- data/data/webgen/website_styles/andreas00/src/images/front.jpg +0 -0
- data/data/webgen/website_styles/andreas00/src/images/menubg.gif +0 -0
- data/data/webgen/website_styles/andreas00/src/images/menubg2.gif +0 -0
- data/data/webgen/website_styles/andreas01/README +14 -0
- data/data/webgen/website_styles/andreas01/src/default.css +310 -0
- data/data/webgen/website_styles/andreas01/src/default.template +62 -0
- data/data/webgen/website_styles/andreas01/src/images/bg.gif +0 -0
- data/data/webgen/website_styles/andreas01/src/images/front.jpg +0 -0
- data/data/webgen/website_styles/andreas01/src/print.css +35 -0
- data/data/webgen/website_styles/andreas03/README +14 -0
- data/data/webgen/website_styles/andreas03/src/default.css +223 -0
- data/data/webgen/website_styles/andreas03/src/default.template +58 -0
- data/data/webgen/website_styles/andreas03/src/images/bodybg.png +0 -0
- data/data/webgen/website_styles/andreas03/src/images/contbg.png +0 -0
- data/data/webgen/website_styles/andreas03/src/images/footerbg.png +0 -0
- data/data/webgen/website_styles/andreas03/src/images/gradient1.png +0 -0
- data/data/webgen/website_styles/andreas03/src/images/gradient2.png +0 -0
- data/data/webgen/website_styles/andreas04/README +15 -0
- data/data/webgen/website_styles/andreas04/src/default.css +290 -0
- data/data/webgen/website_styles/andreas04/src/default.template +81 -0
- data/data/webgen/website_styles/andreas04/src/images/blinkarrow.gif +0 -0
- data/data/webgen/website_styles/andreas04/src/images/bodybg.png +0 -0
- data/data/webgen/website_styles/andreas04/src/images/contentbg.png +0 -0
- data/data/webgen/website_styles/andreas04/src/images/entrybg.png +0 -0
- data/data/webgen/website_styles/andreas04/src/images/flash.gif +0 -0
- data/data/webgen/website_styles/andreas04/src/images/flash2.gif +0 -0
- data/data/webgen/website_styles/andreas04/src/images/globe.gif +0 -0
- data/data/webgen/website_styles/andreas04/src/images/globebottom.gif +0 -0
- data/data/webgen/website_styles/andreas04/src/images/linkarrow.gif +0 -0
- data/data/webgen/website_styles/andreas04/src/images/menuhover.png +0 -0
- data/data/webgen/website_styles/andreas05/README +14 -0
- data/data/webgen/website_styles/andreas05/src/default.css +33 -0
- data/data/webgen/website_styles/andreas05/src/default.template +40 -0
- data/data/webgen/website_styles/andreas05/src/images/bodybg.gif +0 -0
- data/data/webgen/website_styles/andreas05/src/images/front.png +0 -0
- data/data/webgen/website_styles/andreas06/README +14 -0
- data/data/webgen/website_styles/andreas06/src/default.css +354 -0
- data/data/webgen/website_styles/andreas06/src/default.template +70 -0
- data/data/webgen/website_styles/andreas06/src/images/bodybg.gif +0 -0
- data/data/webgen/website_styles/andreas06/src/images/boxbg.gif +0 -0
- data/data/webgen/website_styles/andreas06/src/images/greypx.gif +0 -0
- data/data/webgen/website_styles/andreas06/src/images/header.jpg +0 -0
- data/data/webgen/website_styles/andreas06/src/images/innerbg.gif +0 -0
- data/data/webgen/website_styles/andreas06/src/images/leaves.jpg +0 -0
- data/data/webgen/website_styles/andreas06/src/images/tabs.gif +0 -0
- data/data/webgen/website_styles/andreas07/README +15 -0
- data/data/webgen/website_styles/andreas07/src/browserfix.css +7 -0
- data/data/webgen/website_styles/andreas07/src/default.css +92 -0
- data/data/webgen/website_styles/andreas07/src/default.template +42 -0
- data/data/webgen/website_styles/andreas07/src/images/bodybg.gif +0 -0
- data/data/webgen/website_styles/andreas07/src/images/sidebarbg.gif +0 -0
- data/data/webgen/website_styles/andreas08/README +14 -0
- data/data/webgen/website_styles/andreas08/src/default.css +224 -0
- data/data/webgen/website_styles/andreas08/src/default.template +51 -0
- data/data/webgen/website_styles/andreas09/README +14 -0
- data/data/webgen/website_styles/andreas09/src/default.css +308 -0
- data/data/webgen/website_styles/andreas09/src/default.template +68 -0
- data/data/webgen/website_styles/andreas09/src/images/bodybg-black.jpg +0 -0
- data/data/webgen/website_styles/andreas09/src/images/bodybg-green.jpg +0 -0
- data/data/webgen/website_styles/andreas09/src/images/bodybg-orange.jpg +0 -0
- data/data/webgen/website_styles/andreas09/src/images/bodybg-purple.jpg +0 -0
- data/data/webgen/website_styles/andreas09/src/images/bodybg-red.jpg +0 -0
- data/data/webgen/website_styles/andreas09/src/images/bodybg.jpg +0 -0
- data/data/webgen/website_styles/andreas09/src/images/footerbg.jpg +0 -0
- data/data/webgen/website_styles/andreas09/src/images/menuhover-black.jpg +0 -0
- data/data/webgen/website_styles/andreas09/src/images/menuhover-green.jpg +0 -0
- data/data/webgen/website_styles/andreas09/src/images/menuhover-orange.jpg +0 -0
- data/data/webgen/website_styles/andreas09/src/images/menuhover-purple.jpg +0 -0
- data/data/webgen/website_styles/andreas09/src/images/menuhover-red.jpg +0 -0
- data/data/webgen/website_styles/andreas09/src/images/menuhover.jpg +0 -0
- data/data/webgen/website_styles/simple/README +6 -0
- data/data/webgen/website_styles/simple/src/default.css +84 -0
- data/data/webgen/website_styles/simple/src/default.template +36 -0
- data/data/webgen/website_templates/default/README +6 -0
- data/data/webgen/website_templates/default/src/index.page +8 -0
- data/data/webgen/website_templates/project/README +5 -0
- data/data/webgen/website_templates/project/src/about.page +12 -0
- data/data/webgen/website_templates/project/src/download.page +15 -0
- data/data/webgen/website_templates/project/src/features.page +8 -0
- data/data/webgen/website_templates/project/src/index.page +9 -0
- data/data/webgen/website_templates/project/src/screenshots.page +18 -0
- data/doc/contentprocessor.template +11 -0
- data/doc/contentprocessor/blocks.page +129 -0
- data/doc/contentprocessor/builder.page +80 -0
- data/doc/contentprocessor/erb.page +59 -0
- data/doc/contentprocessor/erubis.page +46 -0
- data/doc/contentprocessor/fragments.page +25 -0
- data/doc/contentprocessor/haml.page +47 -0
- data/doc/contentprocessor/maruku.page +41 -0
- data/doc/contentprocessor/rdiscount.page +37 -0
- data/doc/contentprocessor/rdoc.page +36 -0
- data/doc/contentprocessor/redcloth.page +39 -0
- data/doc/contentprocessor/sass.page +31 -0
- data/doc/contentprocessor/tags.page +73 -0
- data/doc/extensions.metainfo +29 -0
- data/doc/extensions.page +16 -0
- data/doc/extensions.template +17 -0
- data/doc/faq.page +219 -0
- data/doc/getting_started.page +135 -0
- data/doc/index.page +65 -0
- data/doc/manual.page +589 -0
- data/doc/reference_configuration.page +959 -0
- data/doc/reference_metainfo.page +222 -0
- data/doc/source/filesystem.page +39 -0
- data/doc/source/tararchive.page +40 -0
- data/doc/sourcehandler.template +21 -0
- data/doc/sourcehandler/copy.page +19 -0
- data/doc/sourcehandler/directory.page +27 -0
- data/doc/sourcehandler/feed.page +105 -0
- data/doc/sourcehandler/metainfo.page +41 -0
- data/doc/sourcehandler/page.page +14 -0
- data/doc/sourcehandler/sitemap.page +46 -0
- data/doc/sourcehandler/template.page +45 -0
- data/doc/sourcehandler/virtual.page +49 -0
- data/doc/tag.template +25 -0
- data/doc/tag/breadcrumbtrail.page +40 -0
- data/doc/tag/coderay.page +49 -0
- data/doc/tag/date.page +31 -0
- data/doc/tag/executecommand.page +26 -0
- data/doc/tag/includefile.page +32 -0
- data/doc/tag/langbar.page +44 -0
- data/doc/tag/link.page +44 -0
- data/doc/tag/menu.page +106 -0
- data/doc/tag/metainfo.page +29 -0
- data/doc/tag/relocatable.page +38 -0
- data/doc/tag/sitemap.page +31 -0
- data/doc/tag/tikz.page +158 -0
- data/doc/upgrading.page +139 -0
- data/doc/webgen_page_format.page +129 -0
- data/lib/webgen/blackboard.rb +78 -0
- data/lib/webgen/cache.rb +87 -0
- data/lib/webgen/cli.rb +124 -0
- data/lib/webgen/cli/apply_command.rb +64 -0
- data/lib/webgen/cli/create_command.rb +66 -0
- data/lib/webgen/cli/run_command.rb +22 -0
- data/lib/webgen/cli/utils.rb +88 -0
- data/lib/webgen/cli/webgui_command.rb +72 -0
- data/lib/webgen/common.rb +21 -0
- data/lib/webgen/common/sitemap.rb +83 -0
- data/lib/webgen/configuration.rb +153 -0
- data/lib/webgen/contentprocessor.rb +99 -0
- data/lib/webgen/contentprocessor/blocks.rb +60 -0
- data/lib/webgen/contentprocessor/builder.rb +30 -0
- data/lib/webgen/contentprocessor/context.rb +89 -0
- data/lib/webgen/contentprocessor/erb.rb +28 -0
- data/lib/webgen/contentprocessor/erubis.rb +40 -0
- data/lib/webgen/contentprocessor/fragments.rb +25 -0
- data/lib/webgen/contentprocessor/haml.rb +30 -0
- data/lib/webgen/contentprocessor/maruku.rb +20 -0
- data/lib/webgen/contentprocessor/rdiscount.rb +17 -0
- data/lib/webgen/contentprocessor/rdoc.rb +19 -0
- data/lib/webgen/contentprocessor/redcloth.rb +17 -0
- data/lib/webgen/contentprocessor/sass.rb +20 -0
- data/lib/webgen/contentprocessor/tags.rb +136 -0
- data/lib/webgen/coreext.rb +13 -0
- data/lib/webgen/default_config.rb +215 -0
- data/lib/webgen/languages.rb +589 -0
- data/lib/webgen/loggable.rb +25 -0
- data/lib/webgen/logger.rb +97 -0
- data/lib/webgen/node.rb +391 -0
- data/lib/webgen/output.rb +82 -0
- data/lib/webgen/output/filesystem.rb +69 -0
- data/lib/webgen/page.rb +153 -0
- data/lib/webgen/path.rb +194 -0
- data/lib/webgen/source.rb +54 -0
- data/lib/webgen/source/filesystem.rb +61 -0
- data/lib/webgen/source/resource.rb +44 -0
- data/lib/webgen/source/stacked.rb +55 -0
- data/lib/webgen/source/tararchive.rb +73 -0
- data/lib/webgen/sourcehandler.rb +226 -0
- data/lib/webgen/sourcehandler/base.rb +248 -0
- data/lib/webgen/sourcehandler/copy.rb +43 -0
- data/lib/webgen/sourcehandler/directory.rb +36 -0
- data/lib/webgen/sourcehandler/feed.rb +117 -0
- data/lib/webgen/sourcehandler/fragment.rb +68 -0
- data/lib/webgen/sourcehandler/memory.rb +43 -0
- data/lib/webgen/sourcehandler/metainfo.rb +128 -0
- data/lib/webgen/sourcehandler/page.rb +59 -0
- data/lib/webgen/sourcehandler/sitemap.rb +60 -0
- data/lib/webgen/sourcehandler/template.rb +66 -0
- data/lib/webgen/sourcehandler/virtual.rb +110 -0
- data/lib/webgen/tag.rb +27 -0
- data/lib/webgen/tag/base.rb +170 -0
- data/lib/webgen/tag/breadcrumbtrail.rb +70 -0
- data/lib/webgen/tag/coderay.rb +31 -0
- data/lib/webgen/tag/date.rb +18 -0
- data/lib/webgen/tag/executecommand.rb +30 -0
- data/lib/webgen/tag/includefile.rb +42 -0
- data/lib/webgen/tag/langbar.rb +52 -0
- data/lib/webgen/tag/link.rb +26 -0
- data/lib/webgen/tag/menu.rb +207 -0
- data/lib/webgen/tag/metainfo.rb +25 -0
- data/lib/webgen/tag/relocatable.rb +54 -0
- data/lib/webgen/tag/sitemap.rb +41 -0
- data/lib/webgen/tag/tikz.rb +119 -0
- data/lib/webgen/tree.rb +90 -0
- data/lib/webgen/version.rb +8 -0
- data/lib/webgen/webgentask.rb +152 -0
- data/lib/webgen/website.rb +342 -0
- data/lib/webgen/websiteaccess.rb +31 -0
- data/lib/webgen/websitemanager.rb +127 -0
- data/man/man1/webgen.1 +73 -0
- data/misc/default.css +384 -0
- data/misc/default.template +75 -0
- data/misc/htmldoc.metainfo +25 -0
- data/misc/htmldoc.virtual +5 -0
- data/misc/images/arrow.gif +0 -0
- data/misc/images/error.png +0 -0
- data/misc/images/headerbg.jpg +0 -0
- data/misc/images/important.png +0 -0
- data/misc/images/information.png +0 -0
- data/misc/images/quote.gif +0 -0
- data/misc/images/warning.png +0 -0
- data/setup.rb +1585 -0
- data/test/helper.rb +45 -0
- data/test/test_blackboard.rb +60 -0
- data/test/test_cache.rb +59 -0
- data/test/test_cli.rb +21 -0
- data/test/test_common.rb +18 -0
- data/test/test_common_sitemap.rb +58 -0
- data/test/test_configuration.rb +68 -0
- data/test/test_contentprocessor.rb +33 -0
- data/test/test_contentprocessor_blocks.rb +68 -0
- data/test/test_contentprocessor_builder.rb +23 -0
- data/test/test_contentprocessor_context.rb +40 -0
- data/test/test_contentprocessor_erb.rb +23 -0
- data/test/test_contentprocessor_erubis.rb +49 -0
- data/test/test_contentprocessor_fragments.rb +42 -0
- data/test/test_contentprocessor_haml.rb +23 -0
- data/test/test_contentprocessor_maruku.rb +29 -0
- data/test/test_contentprocessor_rdiscount.rb +17 -0
- data/test/test_contentprocessor_rdoc.rb +18 -0
- data/test/test_contentprocessor_redcloth.rb +15 -0
- data/test/test_contentprocessor_sass.rb +22 -0
- data/test/test_contentprocessor_tags.rb +99 -0
- data/test/test_languages.rb +67 -0
- data/test/test_loggable.rb +32 -0
- data/test/test_logger.rb +94 -0
- data/test/test_node.rb +367 -0
- data/test/test_output_filesystem.rb +60 -0
- data/test/test_page.rb +214 -0
- data/test/test_path.rb +165 -0
- data/test/test_source_filesystem.rb +76 -0
- data/test/test_source_resource.rb +28 -0
- data/test/test_source_stacked.rb +36 -0
- data/test/test_source_tararchive.rb +65 -0
- data/test/test_sourcehandler_base.rb +123 -0
- data/test/test_sourcehandler_copy.rb +47 -0
- data/test/test_sourcehandler_directory.rb +42 -0
- data/test/test_sourcehandler_feed.rb +77 -0
- data/test/test_sourcehandler_fragment.rb +69 -0
- data/test/test_sourcehandler_memory.rb +44 -0
- data/test/test_sourcehandler_metainfo.rb +118 -0
- data/test/test_sourcehandler_page.rb +65 -0
- data/test/test_sourcehandler_sitemap.rb +49 -0
- data/test/test_sourcehandler_template.rb +65 -0
- data/test/test_sourcehandler_virtual.rb +87 -0
- data/test/test_tag_base.rb +85 -0
- data/test/test_tag_breadcrumbtrail.rb +91 -0
- data/test/test_tag_coderay.rb +32 -0
- data/test/test_tag_date.rb +18 -0
- data/test/test_tag_executecommand.rb +41 -0
- data/test/test_tag_includefile.rb +50 -0
- data/test/test_tag_langbar.rb +72 -0
- data/test/test_tag_link.rb +69 -0
- data/test/test_tag_menu.rb +207 -0
- data/test/test_tag_metainfo.rb +19 -0
- data/test/test_tag_relocatable.rb +59 -0
- data/test/test_tag_sitemap.rb +47 -0
- data/test/test_tag_tikz.rb +69 -0
- data/test/test_tree.rb +70 -0
- data/test/test_webgentask.rb +23 -0
- data/test/test_website.rb +98 -0
- data/test/test_websiteaccess.rb +25 -0
- data/test/test_websitemanager.rb +70 -0
- metadata +613 -0
@@ -0,0 +1,54 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
module Webgen
|
4
|
+
|
5
|
+
# Namespace for all classes that provide source paths.
|
6
|
+
#
|
7
|
+
# == Implementing a source class
|
8
|
+
#
|
9
|
+
# Source classes provide access to the source paths on which the source handlers act.
|
10
|
+
#
|
11
|
+
# A source class only needs to respond to the method +paths+ which needs to return a set of paths
|
12
|
+
# for the source. The returned paths must respond to the method <tt>changed?</tt> (has to return
|
13
|
+
# +true+ if the paths has changed since the last webgen run). The default implementation in the
|
14
|
+
# Path class just returns +true+. One can either derive a specialized path class or define
|
15
|
+
# singleton methods on each path object.
|
16
|
+
#
|
17
|
+
# == Sample Source Class
|
18
|
+
#
|
19
|
+
# Following is a simple source class which has stored the paths and their contents in a hash:
|
20
|
+
#
|
21
|
+
# require 'stringio'
|
22
|
+
#
|
23
|
+
# class MemorySource
|
24
|
+
#
|
25
|
+
# CONTENT = {
|
26
|
+
# '/directory/' => nil,
|
27
|
+
# '/directory/file.page' => "This is the content of the file"
|
28
|
+
# }
|
29
|
+
#
|
30
|
+
# def paths
|
31
|
+
# CONTENT.collect do |path, content|
|
32
|
+
# Webgen::Path.new(path) { StringIO.new(content.to_s) }
|
33
|
+
# end.to_set
|
34
|
+
# end
|
35
|
+
#
|
36
|
+
# end
|
37
|
+
#
|
38
|
+
# You can use this source class in your website (after placing the code in, for example,
|
39
|
+
# <tt>ext/init.rb</tt>) by updating the <tt>sources</tt> configuration option (the following code
|
40
|
+
# has to be placed after the definition of the +MemorySource+ class):
|
41
|
+
#
|
42
|
+
# WebsiteAccess.website.config['sources'] << ['/', MemorySource]
|
43
|
+
#
|
44
|
+
module Source
|
45
|
+
|
46
|
+
autoload :Base, 'webgen/source/base'
|
47
|
+
autoload :FileSystem, 'webgen/source/filesystem'
|
48
|
+
autoload :Stacked, 'webgen/source/stacked'
|
49
|
+
autoload :Resource, 'webgen/source/resource'
|
50
|
+
autoload :TarArchive, 'webgen/source/tararchive'
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'pathname'
|
4
|
+
require 'webgen/websiteaccess'
|
5
|
+
require 'webgen/path'
|
6
|
+
|
7
|
+
module Webgen
|
8
|
+
|
9
|
+
# This class is used to read source paths from a directory in the file system.
|
10
|
+
class Source::FileSystem
|
11
|
+
|
12
|
+
# A special Webgen::Path class for handling with file system paths.
|
13
|
+
class Path < Webgen::Path
|
14
|
+
|
15
|
+
# Create a new object with absolute path +path+ for the file system path +fs_path+.
|
16
|
+
def initialize(path, fs_path)
|
17
|
+
super(path) { File.open(fs_path, 'rb') }
|
18
|
+
@fs_path = fs_path
|
19
|
+
WebsiteAccess.website.cache[[:fs_path, @fs_path]] = File.mtime(@fs_path)
|
20
|
+
@meta_info['modified_at'] = File.mtime(@fs_path)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Return +true+ if the file system path used by the object has been modified.
|
24
|
+
def changed?
|
25
|
+
data = WebsiteAccess.website.cache[[:fs_path, @fs_path]]
|
26
|
+
File.mtime(@fs_path) > data
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
# The root path from which paths read.
|
32
|
+
attr_reader :root
|
33
|
+
|
34
|
+
# The glob (see Dir.glob for details) that is used to specify which paths under the root path
|
35
|
+
# should be returned by #paths.
|
36
|
+
attr_reader :glob
|
37
|
+
|
38
|
+
# Create a new file system source for the root path +root+ using the provided +glob+.
|
39
|
+
def initialize(root, glob = '**/*')
|
40
|
+
if root =~ /^([a-zA-Z]:|\/)/
|
41
|
+
@root = root
|
42
|
+
else
|
43
|
+
@root = File.join(WebsiteAccess.website.directory, root)
|
44
|
+
end
|
45
|
+
@glob = glob
|
46
|
+
end
|
47
|
+
|
48
|
+
# Return all paths under #root which match #glob.
|
49
|
+
def paths
|
50
|
+
@paths ||= Dir.glob(File.join(@root, @glob), File::FNM_DOTMATCH|File::FNM_CASEFOLD).to_set.collect do |f|
|
51
|
+
next unless File.exists?(f) # handle invalid links
|
52
|
+
temp = Pathname.new(f.sub(/^#{Regexp.escape(@root)}\/?/, '/')).cleanpath.to_s
|
53
|
+
temp += '/' if File.directory?(f) && temp[-1] != ?/
|
54
|
+
path = Path.new(temp, f)
|
55
|
+
path
|
56
|
+
end.compact
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'webgen/websiteaccess'
|
4
|
+
require 'webgen/source'
|
5
|
+
|
6
|
+
module Webgen::Source
|
7
|
+
|
8
|
+
# This class is used to provide access to sources provided by resources.
|
9
|
+
class Resource
|
10
|
+
|
11
|
+
include Webgen::WebsiteAccess
|
12
|
+
|
13
|
+
# The glob (see File.fnmatch) specifying the resources.
|
14
|
+
attr_reader :glob
|
15
|
+
|
16
|
+
# The glob (see File.fnmatch) specifying the paths that should be used from the resources.
|
17
|
+
attr_reader :paths_glob
|
18
|
+
|
19
|
+
# The prefix that should optionally be stripped from the paths.
|
20
|
+
attr_reader :strip_prefix
|
21
|
+
|
22
|
+
# Create a new resource source for the the +glob+ and use only those paths matching +paths_glob+
|
23
|
+
# while stripping +strip_prefix+ off the path.
|
24
|
+
def initialize(glob, paths_glob = nil, strip_prefix = nil)
|
25
|
+
@glob, @paths_glob, @strip_prefix = glob, paths_glob, strip_prefix
|
26
|
+
end
|
27
|
+
|
28
|
+
# Return all paths associated with the resources identified by #glob.
|
29
|
+
def paths
|
30
|
+
if !defined?(@paths)
|
31
|
+
stack = Stacked.new
|
32
|
+
website.config['resources'].select {|name, infos| File.fnmatch(@glob, name)}.sort.each do |name, infos|
|
33
|
+
stack.add([['/', constant(infos.first).new(*infos[1..-1])]])
|
34
|
+
end
|
35
|
+
@paths = stack.paths
|
36
|
+
@paths = @paths.select {|p| File.fnmatch(@paths_glob, p)} if @paths_glob
|
37
|
+
@paths.collect! {|p| p.mount_at('/', @strip_prefix)} if @strip_prefix
|
38
|
+
end
|
39
|
+
@paths
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
module Webgen::Source
|
4
|
+
|
5
|
+
# This source class is used to stack several sources together.
|
6
|
+
#
|
7
|
+
# It serves two purposes:
|
8
|
+
#
|
9
|
+
# * First, it can be used to access more than one source. This is useful when your website
|
10
|
+
# consists of more than one source directory and you want to use all of them.
|
11
|
+
#
|
12
|
+
# * Second, sources can be mounted on specific directories. For example, a folder with images that
|
13
|
+
# you don't want to copy to the website source directory can be mounted under <tt>/images</tt>
|
14
|
+
# sothat they are available nonetheless.
|
15
|
+
#
|
16
|
+
# Also be aware that when a path is returned by a source that has already be returned by a prior
|
17
|
+
# source, it is discarded and not used.
|
18
|
+
class Stacked
|
19
|
+
|
20
|
+
# Return the stack of Webgen::Source objects.
|
21
|
+
attr_reader :stack
|
22
|
+
|
23
|
+
# Create a new stack. The optional +map+ parameter can be used to provide initial mappings of
|
24
|
+
# mount points to source objects (see #add for details).
|
25
|
+
def initialize(map = {})
|
26
|
+
@stack = []
|
27
|
+
add(map)
|
28
|
+
end
|
29
|
+
|
30
|
+
# Add all mappings found in +maps+ to the stack. The parameter +maps+ should be an array of
|
31
|
+
# two-element arrays which contain an absolute directoriy (ie. starting with a slash) and a
|
32
|
+
# source object.
|
33
|
+
def add(maps)
|
34
|
+
maps.each do |mp, source|
|
35
|
+
raise "Invalid mount point specified: #{mp}" unless mp =~ /^\//
|
36
|
+
@stack << [mp, source]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# Return all paths returned by the sources in the stack. Since the stack is ordered, paths
|
41
|
+
# returned by later source objects are not used if a prior source object has returned the same
|
42
|
+
# path.
|
43
|
+
def paths
|
44
|
+
@paths = Set.new
|
45
|
+
@stack.each do |mp, source|
|
46
|
+
source.paths.each do |path|
|
47
|
+
@paths.add?(path.mount_at(mp))
|
48
|
+
end
|
49
|
+
end
|
50
|
+
@paths
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'pathname'
|
4
|
+
require 'webgen/websiteaccess'
|
5
|
+
require 'webgen/path'
|
6
|
+
require 'open-uri'
|
7
|
+
require 'zlib'
|
8
|
+
require 'archive/tar/minitar'
|
9
|
+
|
10
|
+
module Webgen
|
11
|
+
|
12
|
+
# This class is used to read source paths from a (gzipped) tar archive. The archive can be remote
|
13
|
+
# (http(s) or ftp) or local.
|
14
|
+
#
|
15
|
+
# For example, the following are all valid URIs:
|
16
|
+
# http://example.com/directory/file.tgz
|
17
|
+
# /home/test/my.tar.gz
|
18
|
+
# ftp://ftp.example.com/archives/archive.tar
|
19
|
+
#
|
20
|
+
class Source::TarArchive
|
21
|
+
|
22
|
+
# A special Webgen::Path class for handling paths from a tar archive.
|
23
|
+
class Path < Webgen::Path
|
24
|
+
|
25
|
+
# Create a new tar archive path object for the entry +entry+.
|
26
|
+
def initialize(path, data, mtime, uri)
|
27
|
+
super(path) { StringIO.new(data.to_s) }
|
28
|
+
@uri = uri
|
29
|
+
@mtime = mtime
|
30
|
+
WebsiteAccess.website.cache[[:tararchive_path, @uri, path]] = @mtime if WebsiteAccess.website
|
31
|
+
@meta_info['modified_at'] = @mtime
|
32
|
+
end
|
33
|
+
|
34
|
+
# Return +true+ if the tar archive path used by the object has been modified.
|
35
|
+
def changed?
|
36
|
+
!WebsiteAccess.website || @mtime > WebsiteAccess.website.cache[[:tararchive_path, @uri, path]]
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
# The URI of the tar archive.
|
42
|
+
attr_reader :uri
|
43
|
+
|
44
|
+
# The glob (see File.fnmatch for details) that is used to specify which paths in the archive should
|
45
|
+
# be returned by #paths.
|
46
|
+
attr_reader :glob
|
47
|
+
|
48
|
+
# Create a new tar archive source for the URI string +uri+.
|
49
|
+
def initialize(uri, glob = '**/*')
|
50
|
+
@uri = uri
|
51
|
+
@glob = glob
|
52
|
+
end
|
53
|
+
|
54
|
+
# Return all paths in the tar archive available at #uri.
|
55
|
+
def paths
|
56
|
+
if !defined?(@paths)
|
57
|
+
stream = open(@uri)
|
58
|
+
stream = Zlib::GzipReader.new(stream) if @uri =~ /(\.tar\.gz|\.tgz)$/
|
59
|
+
Archive::Tar::Minitar::Input.open(stream) do |input|
|
60
|
+
@paths = input.collect do |entry|
|
61
|
+
path = entry.full_name
|
62
|
+
next unless File.fnmatch(@glob, path, File::FNM_DOTMATCH|File::FNM_CASEFOLD|File::FNM_PATHNAME)
|
63
|
+
path += '/' if entry.directory? && path[-1] != ?/
|
64
|
+
Path.new(path, entry.read, Time.at(entry.mtime), @uri)
|
65
|
+
end.compact.to_set
|
66
|
+
end
|
67
|
+
end
|
68
|
+
@paths
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
@@ -0,0 +1,226 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'webgen/loggable'
|
4
|
+
require 'benchmark'
|
5
|
+
|
6
|
+
module Webgen
|
7
|
+
|
8
|
+
# Namespace for all classes that handle source paths.
|
9
|
+
#
|
10
|
+
# Have a look at Webgen::SourceHandler::Base for details on how to implement a source handler
|
11
|
+
# class.
|
12
|
+
module SourceHandler
|
13
|
+
|
14
|
+
autoload :Base, 'webgen/sourcehandler/base'
|
15
|
+
autoload :Copy, 'webgen/sourcehandler/copy'
|
16
|
+
autoload :Directory, 'webgen/sourcehandler/directory'
|
17
|
+
autoload :Metainfo, 'webgen/sourcehandler/metainfo'
|
18
|
+
autoload :Template, 'webgen/sourcehandler/template'
|
19
|
+
autoload :Page, 'webgen/sourcehandler/page'
|
20
|
+
autoload :Fragment, 'webgen/sourcehandler/fragment'
|
21
|
+
autoload :Virtual, 'webgen/sourcehandler/virtual'
|
22
|
+
autoload :Feed, 'webgen/sourcehandler/feed'
|
23
|
+
autoload :Sitemap, 'webgen/sourcehandler/sitemap'
|
24
|
+
autoload :Memory, 'webgen/sourcehandler/memory'
|
25
|
+
|
26
|
+
# This class is used by Website to do the actual rendering of the website. It
|
27
|
+
#
|
28
|
+
# * collects all source paths using the source classes
|
29
|
+
# * creates nodes using the source handler classes
|
30
|
+
# * writes changed nodes out using an output class
|
31
|
+
class Main
|
32
|
+
|
33
|
+
include WebsiteAccess
|
34
|
+
include Loggable
|
35
|
+
|
36
|
+
def initialize #:nodoc:
|
37
|
+
website.blackboard.add_service(:create_nodes, method(:create_nodes))
|
38
|
+
website.blackboard.add_service(:source_paths, method(:find_all_source_paths))
|
39
|
+
website.blackboard.add_listener(:node_meta_info_changed?, method(:meta_info_changed?))
|
40
|
+
end
|
41
|
+
|
42
|
+
# Render the nodes provided in the +tree+. Before the actual rendering is done, the sources
|
43
|
+
# are checked (nodes for deleted sources are deleted, nodes for new and changed sources).
|
44
|
+
def render(tree)
|
45
|
+
begin
|
46
|
+
website.logger.mark_new_cycle if website.logger
|
47
|
+
|
48
|
+
puts "Updating tree..."
|
49
|
+
time = Benchmark.measure do
|
50
|
+
website.cache.reset_volatile_cache
|
51
|
+
update_tree(tree)
|
52
|
+
end
|
53
|
+
puts "...done in " + ('%2.4f' % time.real) + ' seconds'
|
54
|
+
|
55
|
+
if !tree.root
|
56
|
+
puts 'No source files found - maybe not a webgen website?'
|
57
|
+
return nil
|
58
|
+
end
|
59
|
+
|
60
|
+
puts "Writing changed nodes..."
|
61
|
+
time = Benchmark.measure do
|
62
|
+
write_tree(tree)
|
63
|
+
end
|
64
|
+
puts "...done in " + ('%2.4f' % time.real) + ' seconds'
|
65
|
+
end while tree.node_access[:alcn].any? {|name,node| node.flagged(:created) || node.flagged(:reinit)}
|
66
|
+
:success
|
67
|
+
end
|
68
|
+
|
69
|
+
#######
|
70
|
+
private
|
71
|
+
#######
|
72
|
+
|
73
|
+
# Update the +tree+ by creating/reinitializing all needed nodes.
|
74
|
+
def update_tree(tree)
|
75
|
+
unused_paths = Set.new
|
76
|
+
begin
|
77
|
+
used_paths = Set.new(find_all_source_paths.keys) - unused_paths
|
78
|
+
paths_to_use = Set.new
|
79
|
+
nodes_to_delete = Set.new
|
80
|
+
|
81
|
+
tree.node_access[:alcn].each do |alcn, node|
|
82
|
+
next if node == tree.dummy_root
|
83
|
+
used_paths.delete(node.node_info[:src])
|
84
|
+
|
85
|
+
deleted = !find_all_source_paths.include?(node.node_info[:src])
|
86
|
+
if deleted
|
87
|
+
nodes_to_delete << node
|
88
|
+
#TODO: delete output path
|
89
|
+
elsif (!node.flagged(:created) && find_all_source_paths[node.node_info[:src]].changed?) || node.meta_info_changed?
|
90
|
+
node.flag(:reinit)
|
91
|
+
paths_to_use << node.node_info[:src]
|
92
|
+
elsif node.changed?
|
93
|
+
# nothing to be done here
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
nodes_to_delete.each {|node| tree.delete_node(node)}
|
98
|
+
used_paths.merge(paths_to_use)
|
99
|
+
paths = create_nodes_from_paths(tree, used_paths.to_a.sort)
|
100
|
+
unused_paths.merge(used_paths - paths)
|
101
|
+
tree.node_access[:alcn].each {|name, node| tree.delete_node(node) if node.flagged(:reinit)}
|
102
|
+
website.cache.reset_volatile_cache
|
103
|
+
end until used_paths.empty?
|
104
|
+
end
|
105
|
+
|
106
|
+
# Write out all changed nodes of the +tree+.
|
107
|
+
def write_tree(tree)
|
108
|
+
output = website.blackboard.invoke(:output_instance)
|
109
|
+
|
110
|
+
tree.node_access[:alcn].select do |name, node|
|
111
|
+
use_node = (node != tree.dummy_root && node.flagged(:dirty))
|
112
|
+
node.unflag(:dirty_meta_info)
|
113
|
+
node.unflag(:created)
|
114
|
+
node.unflag(:dirty)
|
115
|
+
use_node
|
116
|
+
end.sort.each do |name, node|
|
117
|
+
next if node['no_output'] || !(content = node.content)
|
118
|
+
|
119
|
+
begin
|
120
|
+
puts " "*4 + name, :verbose
|
121
|
+
type = if node.is_directory?
|
122
|
+
:directory
|
123
|
+
elsif node.is_fragment?
|
124
|
+
:fragment
|
125
|
+
else
|
126
|
+
:file
|
127
|
+
end
|
128
|
+
output.write(node.path, content, type)
|
129
|
+
rescue
|
130
|
+
raise RuntimeError, "Error while processing <#{node.absolute_lcn}>: #{$!.message}", $!.backtrace
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
# Return a hash with all source paths.
|
136
|
+
def find_all_source_paths
|
137
|
+
if !defined?(@paths)
|
138
|
+
source = Webgen::Source::Stacked.new(website.config['sources'].collect do |mp, name, *args|
|
139
|
+
[mp, constant(name).new(*args)]
|
140
|
+
end)
|
141
|
+
@paths = {}
|
142
|
+
source.paths.each do |path|
|
143
|
+
if !(website.config['sourcehandler.ignore'].any? {|pat| File.fnmatch(pat, path, File::FNM_CASEFOLD|File::FNM_DOTMATCH)})
|
144
|
+
@paths[path.source_path] = path
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
@paths
|
149
|
+
end
|
150
|
+
|
151
|
+
# Return only the subset of +paths+ which are handled by the source handler +name+.
|
152
|
+
def paths_for_handler(name, paths)
|
153
|
+
patterns = website.config['sourcehandler.patterns'][name]
|
154
|
+
return [] if patterns.nil?
|
155
|
+
|
156
|
+
options = (website.config['sourcehandler.casefold'] ? File::FNM_CASEFOLD : 0) |
|
157
|
+
(website.config['sourcehandler.use_hidden_files'] ? File::FNM_DOTMATCH : 0)
|
158
|
+
find_all_source_paths.values_at(*paths).select do |path|
|
159
|
+
patterns.any? {|pat| File.fnmatch(pat, path, options)}
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
# Use the source handlers to create nodes for the +paths+ in the +tree+.
|
164
|
+
def create_nodes_from_paths(tree, paths)
|
165
|
+
used_paths = Set.new
|
166
|
+
website.config['sourcehandler.invoke'].sort.each do |priority, shns|
|
167
|
+
shns.each do |shn|
|
168
|
+
sh = website.cache.instance(shn)
|
169
|
+
handler_paths = paths_for_handler(shn, paths)
|
170
|
+
used_paths.merge(handler_paths)
|
171
|
+
handler_paths.sort {|a,b| a.path.length <=> b.path.length}.each do |path|
|
172
|
+
parent_dir = path.directory.split('/').collect {|p| Path.new(p).cn}.join('/')
|
173
|
+
parent_dir += '/' if path != '/' && parent_dir == ''
|
174
|
+
create_nodes(tree, parent_dir, path, sh)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
used_paths
|
179
|
+
end
|
180
|
+
|
181
|
+
# Prepare everything to create nodes under the absolute lcn path +parent_path_name+ in the
|
182
|
+
# +tree from the +path+ using the +source_handler+. If a block is given, the actual creation
|
183
|
+
# of the nodes is deferred to it. After the nodes are created, it is also checked if they have
|
184
|
+
# all needed properties.
|
185
|
+
def create_nodes(tree, parent_path_name, path, source_handler) #:yields: parent, path
|
186
|
+
if !(parent = tree[parent_path_name])
|
187
|
+
raise "The specified parent path <#{parent_path_name}> does not exist"
|
188
|
+
end
|
189
|
+
path = path.dup
|
190
|
+
path.meta_info = default_meta_info(path, source_handler.class.name)
|
191
|
+
(website.cache[:sourcehandler_path_mi] ||= {})[[path.path, source_handler.class.name]] = path.meta_info.dup
|
192
|
+
website.blackboard.dispatch_msg(:before_node_created, parent, path)
|
193
|
+
*nodes = if block_given?
|
194
|
+
yield(parent, path)
|
195
|
+
else
|
196
|
+
source_handler.create_node(parent, path)
|
197
|
+
end
|
198
|
+
nodes.flatten.compact.each do |node|
|
199
|
+
website.blackboard.dispatch_msg(:after_node_created, node)
|
200
|
+
end
|
201
|
+
nodes
|
202
|
+
end
|
203
|
+
|
204
|
+
# Return the default meta info for the pair of +path+ and +sh_name+.
|
205
|
+
def default_meta_info(path, sh_name)
|
206
|
+
path.meta_info.merge(website.config['sourcehandler.default_meta_info'][:all]).
|
207
|
+
merge(website.config['sourcehandler.default_meta_info'][sh_name] || {})
|
208
|
+
end
|
209
|
+
|
210
|
+
# Check if the default meta information for +node+ has changed since the last run. But don't
|
211
|
+
# take the node's path's +modified_at+ meta information into account since that changes on
|
212
|
+
# every path change.
|
213
|
+
def meta_info_changed?(node)
|
214
|
+
path = node.node_info[:creation_path]
|
215
|
+
old_mi = website.cache[:sourcehandler_path_mi][[path, node.node_info[:processor]]]
|
216
|
+
old_mi.delete('modified_at')
|
217
|
+
new_mi = default_meta_info(@paths[path] || Webgen::Path.new(path), node.node_info[:processor])
|
218
|
+
new_mi.delete('modified_at')
|
219
|
+
node.flag(:dirty_meta_info) if !old_mi || old_mi != new_mi
|
220
|
+
end
|
221
|
+
|
222
|
+
end
|
223
|
+
|
224
|
+
end
|
225
|
+
|
226
|
+
end
|