Class FileHandlers::FileHandler
In: lib/webgen/plugins/filehandlers/filehandler.rb
Parent: Webgen::Plugin
Webgen::Plugin DefaultHandler FileHandler CopyHandler ThumbnailWriter SipttraHandler VirtualFileHandler GalleryHandler TemplateHandler PageHandler DirectoryHandler Listener lib/webgen/plugins/filehandlers/filehandler.rb lib/webgen/plugins/filehandlers/copy.rb lib/webgen/plugins/filehandlers/directory.rb lib/webgen/plugins/filehandlers/page.rb lib/webgen/plugins/filehandlers/sipttra.rb lib/webgen/plugins/filehandlers/gallery.rb lib/webgen/plugins/filehandlers/template.rb FileHandlers dot/m_28_0.png

The main plugin for handling files.

The following message listening hooks (defined via symbols) are available for this plugin (see Listener):

before_node_created:called before a node is created
after_node_created:called after a node has been created
after_all_nodes_created:called after the plugin has finfished reading in all files and the output backing section of the meta information file has been processed
before_node_written:called before a node is written out
after_node_written:called after a node has been written out
before_all_nodes_written:called before the plugin starts writing out the files
after_all_nodes_written:called after the plugin has finfished writing out the files

Methods

Included Modules

Listener

Public Class methods

[Source]

    # File lib/webgen/plugins/filehandlers/filehandler.rb, line 63
63:     def initialize( manager )
64:       super
65:       add_msg_name( :before_node_created )
66:       add_msg_name( :after_node_created )
67:       add_msg_name( :after_all_nodes_created )
68:       add_msg_name( :before_node_written )
69:       add_msg_name( :after_node_written )
70:       add_msg_name( :before_all_nodes_written )
71:       add_msg_name( :after_all_nodes_written )
72:       load_meta_info_backing_file
73:     end

Public Instance methods

Creates a node for file (creating parent directories apropriately) under parent_node using the given handler. If a block is given, then the block is used to create the node which is useful if you want a custom node creation method.

[Source]

     # File lib/webgen/plugins/filehandlers/filehandler.rb, line 128
128:     def create_node( file, parent_node, handler ) # :yields: file, parent_node, handler, meta_info
129:       pathname, filename = File.split( file )
130:       parent_node = @plugin_manager['File/DirectoryHandler'].recursive_create_path( pathname, parent_node )
131: 
132:       meta_info = meta_info_for( handler, File.join( parent_node.absolute_path, filename ) )
133: 
134:       src_path = File.join( Node.root( parent_node ).node_info[:src], parent_node.absolute_path, filename )
135:       dispatch_msg( :before_node_created, src_path, parent_node, handler, meta_info )
136:       if block_given?
137:         node = yield( src_path, parent_node, handler, meta_info )
138:       else
139:         node = handler.create_node( src_path, parent_node, meta_info )
140:       end
141:       check_node( node ) unless node.nil?
142: 
143:       dispatch_msg( :after_node_created, node ) unless node.nil?
144: 
145: 
146:       node
147:     end

Returns true if the file src is newer than dest and therefore has been modified since the last execution of webgen. The mtime values for the source and destination files are used to find this out.

[Source]

     # File lib/webgen/plugins/filehandlers/filehandler.rb, line 100
100:     def file_modified?( src, dest )
101:       if File.exists?( dest ) && ( File.mtime( src ) <= File.mtime( dest ) )
102:         log(:info) { "File is up to date: <#{dest}>" }
103:         return false
104:       else
105:         return true
106:       end
107:     end

Returns the meta info for nodes for the given handler. If file is specified, meta information from the backing file is also used if available (using files specified in the source block of the backing file). The parameter file has to be an absolute path, ie. starting with a slash.

[Source]

     # File lib/webgen/plugins/filehandlers/filehandler.rb, line 113
113:     def meta_info_for( handler, file = nil )
114:       info = (handler.class.config.infos[:default_meta_info] || {}).dup
115:       info.update( param('defaultMetaInfo')[handler.class.plugin_name] || {} )
116:       if file
117:         file = normalize_path( file )
118:         if @source_backing.has_key?( file )
119:           info.update( @source_backing[file] )
120:         end
121:       end
122:       info
123:     end

Renders only the given files.

[Source]

    # File lib/webgen/plugins/filehandlers/filehandler.rb, line 85
85:     def render_files( files )
86:       tree = build_tree
87:       return if tree.nil?
88:       files.each do |file|
89:         node = tree.resolve_node( file )
90:         if !node.nil?
91:           write_node( node.parent ) if !node.parent.nil? && node.parent.is_directory?
92:           write_node( node )
93:         end
94:       end
95:     end

Renders the whole website.

[Source]

    # File lib/webgen/plugins/filehandlers/filehandler.rb, line 76
76:     def render_site
77:       tree = build_tree
78:       unless tree.nil?
79:         @plugin_manager['Misc/TreeWalker'].execute( tree )
80:         write_tree( tree )
81:       end
82:     end

Private Instance methods

Reads all files from the source directory and constructs the node tree which is returned.

[Source]

     # File lib/webgen/plugins/filehandlers/filehandler.rb, line 213
213:     def build_tree
214:       all_files = find_all_files()
215:       return if all_files.empty?
216: 
217:       files_for_handlers = find_files_for_handlers()
218: 
219:       root_node = create_root_node()
220: 
221:       used_files = Set.new
222:       files_for_handlers.sort {|a,b| a[0] <=> b[0]}.each do |rank, handler, files|
223:         log(:debug) { "Creating nodes for #{handler.class.plugin_name} with rank #{rank}" }
224:         common = all_files & files
225:         used_files += common
226:         diff = files - common
227:         log(:info) { "Not using these files for #{handler.class.plugin_name} as they do not exist or are excluded: #{diff.inspect}" } if diff.length > 0
228:         common.each  do |file|
229:           log(:info) { "Creating node(s) for file <#{file}>..." }
230:           create_node( file.sub( /^#{Regexp.escape(root_node.node_info[:src])}/, '' ), root_node, handler )
231:         end
232:       end
233: 
234:       unused_files = all_files - used_files
235:       log(:info) { "No handlers found for: #{unused_files.inspect}" } if unused_files.length > 0
236: 
237:       handle_output_backing( root_node )
238:       dispatch_msg( :after_all_nodes_created, root_node )
239: 
240:       root_node
241:     end

Used to check that certain meta/node information is available and correct.

[Source]

     # File lib/webgen/plugins/filehandlers/filehandler.rb, line 154
154:     def check_node( node )
155:       node['lang'] = Webgen::LanguageManager.language_for_code( node['lang'] ) unless node['lang'].kind_of?( Webgen::Language )
156:       node['title'] ||= node.path
157:     end

Creates the root node.

[Source]

     # File lib/webgen/plugins/filehandlers/filehandler.rb, line 299
299:     def create_root_node
300:       root_path = File.join( param( 'srcDir', 'Core/Configuration' ), '/' )
301:       root_handler = @plugin_manager['File/DirectoryHandler']
302:       if root_handler.nil?
303:         log(:error) { "No handler for root directory <#{root_path}> found" }
304:         return nil
305:       end
306: 
307:       root = root_handler.create_node( root_path, nil, meta_info_for( root_handler, '/' ) )
308:       root['title'] = ''
309:       root.path = File.join( param( 'outDir', 'Core/Configuration' ), '/' )
310:       root.node_info[:src] = root_path
311: 
312:       root
313:     end

Returns an array of files of the source directory matching pattern

[Source]

     # File lib/webgen/plugins/filehandlers/filehandler.rb, line 287
287:     def files_for_pattern( pattern )
288:       files = Dir.glob( File.join( param( 'srcDir', 'Core/Configuration' ), pattern ), (param('useHiddenFiles') ? File::FNM_DOTMATCH : 0) | File::FNM_CASEFOLD ).to_set
289:       files.delete( File.join( param( 'srcDir', 'Core/Configuration' ), '/' ) )
290:       files.collect!  do |f|
291:         f = f.sub( /([^.])\.{1,2}$/, '\1' ) # remove '.' and '..' from end of paths
292:         f += '/' if File.directory?( f ) && ( f[-1] != ?/ )
293:         f
294:       end
295:       files
296:     end

Creates a set of all files in the source directory, removing all files which should be ignored.

[Source]

     # File lib/webgen/plugins/filehandlers/filehandler.rb, line 262
262:     def find_all_files
263:       all_files = files_for_pattern( '**/{**,**/}' ).to_set
264:       param( 'ignorePaths' ).each {|pattern| all_files.subtract( files_for_pattern( pattern ) ) }
265:       log(:error) { "No files found in the source directory <#{param('srcDir', 'Core/Configuration')}>" } if all_files.empty?
266:       all_files
267:     end

Finds the files for each registered handler plugin and stores them in a Hash with the plugin as key.

[Source]

     # File lib/webgen/plugins/filehandlers/filehandler.rb, line 271
271:     def find_files_for_handlers
272:       files_for_handlers = []
273:       @plugin_manager.plugins.each do |name, plugin|
274:         files_for_plugin = Set.new
275:         if plugin.kind_of?( DefaultHandler )
276:           plugin.path_patterns.each do |rank, pattern|
277:             files = files_for_pattern( pattern ) - files_for_plugin
278:             files_for_handlers << [rank, plugin, files ] unless files.empty?
279:             files_for_plugin += files
280:           end
281:         end
282:       end
283:       files_for_handlers
284:     end

Uses the output backing section of the meta information file to assign meta information or, if no node for a path can be found, to create virtual nodes.

[Source]

     # File lib/webgen/plugins/filehandlers/filehandler.rb, line 197
197:     def handle_output_backing( root )
198:       @output_backing.each do |path, data|
199:         path = path[1..-1] if path =~ /^\//
200:         if node = root.resolve_node( path )
201:           node.meta_info.update( data )
202:         else
203:           node = create_node( path, root, @plugin_manager['File/VirtualFileHandler'] ) do |src, parent, handler, meta_info|
204:             meta_info = meta_info.merge( data )
205:             handler.create_node( src, parent, meta_info )
206:           end
207:         end
208:         check_node( node )
209:       end
210:     end

Loads the meta information backing file from the website directory.

[Source]

     # File lib/webgen/plugins/filehandlers/filehandler.rb, line 165
165:     def load_meta_info_backing_file
166:       file = File.join( param( 'websiteDir', 'Core/Configuration' ), 'metainfo.yaml' )
167:       if File.exists?( file )
168:         begin
169:           index = 1
170:           YAML::load_documents( File.read( file ) ) do |data|
171:             if data.nil? || (data.kind_of?( Hash ) && data.all? {|k,v| v.kind_of?( Hash ) })
172:               if index == 1
173:                 @source_backing = {}
174:                 data.each_pair {|path, metainfo| @source_backing[normalize_path(path)] = metainfo} unless data.nil?
175:               elsif index == 2
176:                 @output_backing = data
177:               else
178:                 log(:error) { "A backing file can only have two blocks: one for source and one for output backing!" }
179:               end
180:             else
181:               log(:error) { "Content of backing file (#{index == 1 ? 'source' : 'output'} block) not correctcly structured" }
182:             end
183:             index += 1
184:           end
185:         rescue
186:           log(:error) { "Backing file is not a valid YAML document: #{$!.message}" }
187:         end
188:       else
189:         log(:info) { 'No meta information backing file found!' }
190:       end
191:       @source_backing ||= {}
192:       @output_backing ||= {}
193:     end

Returns a normalized path, ie. a path starting with a slash and any trailing slashes removed.

[Source]

     # File lib/webgen/plugins/filehandlers/filehandler.rb, line 160
160:     def normalize_path( path )
161:       path = (path =~ /^\// ? '' : '/') + path.sub( /\/+$/, '' )
162:     end

Writes out the given node.

[Source]

     # File lib/webgen/plugins/filehandlers/filehandler.rb, line 254
254:     def write_node( node )
255:       log(:info) { "Writing <#{node.full_path}>" }
256:       dispatch_msg( :before_node_written, node )
257:       node.write_node
258:       dispatch_msg( :after_node_written, node )
259:     end

Recursively writes out the tree specified by node.

[Source]

     # File lib/webgen/plugins/filehandlers/filehandler.rb, line 244
244:     def write_tree( node )
245:       dispatch_msg( :before_all_nodes_written, node ) if node.parent.nil?
246: 
247:       write_node( node )
248:       node.each {|child| write_tree( child ) }
249: 
250:       dispatch_msg( :after_all_nodes_written, node ) if node.parent.nil?
251:     end

[Validate]