File: webgen.rb

package info (click to toggle)
webgen 0.3.8-3
  • links: PTS
  • area: main
  • in suites: lenny, squeeze
  • size: 1,912 kB
  • ctags: 586
  • sloc: ruby: 4,789; makefile: 9
file content (277 lines) | stat: -rw-r--r-- 10,388 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
#
#--
#
# $Id: webgen.rb 369 2005-12-24 11:37:40Z thomas $
#
# webgen: template based static website generator
# Copyright (C) 2004 Thomas Leitner
#
# This program is free software; you can redistribute it and/or modify it under the terms of the GNU
# General Public License as published by the Free Software Foundation; either version 2 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with this program; if not,
# write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
#++
#

require 'rbconfig'
require 'fileutils'
require 'cmdparse2'
require 'webgen/plugin'
require 'webgen/gui/common'


module Webgen

  class Color

    @@colors = {:bold => [0, 1], :green => [0, 32], :lblue => [1, 34], :lred => [1, 31], :reset => [0, 0]}

    def self.colorify
      @@colors.each do |color, values|
        module_eval <<-EOF
        def Color.#{color.to_s}
        "\e[#{values[0]};#{values[1]}m"
        end
        EOF
      end
    end

    def self.method_missing( id )
      ''
    end

  end

  class CreateCommand < CmdParse::Command

    def initialize
      super( 'create', false )
      self.short_desc = "Creates the basic directories and files for webgen"
      self.description = "You can optionally specify a template and/or a style which should be used. " \
      "This allows you to create a good starting template for your website."
      self.options = CmdParse::OptionParserWrapper.new do |opts|
        opts.separator "Options:"
        opts.on( '-t', '--template TEMPLATE', 'Specify the template which should be used' ) {|@template|}
        opts.on( '-s', '--style STYLE', 'Specify the style which should be used' ) {|@style|}
        opts.separator ""
        opts.separator "Available templates and styles:"
        opts.separator opts.summary_indent + "Templates: " + Webgen::Website.templates.join(', ')
        opts.separator opts.summary_indent + "Styles: " + Webgen::Website.styles.join(', ')
      end
      @template = 'default'
      @style = 'default'
    end

    def usage
      "Usage: #{commandparser.program_name} [global options] create [options] DIR"
    end

    def execute( args )
      if args.length == 0
        raise OptionParser::MissingArgument.new( 'DIR' )
      else
        Webgen.create_website( args[0], @template, @style )
      end
    end

  end

  class CleanCommand < CmdParse::Command

    module ::FileUtils

      def fu_output_message( msg )
        logger.info { msg }
      end

      def ask_before_delete( ask, func, list, options = {} )
        newlist = [*list].collect {|e| "'" + e + "'"}.join(', ')
        if ask
          print "Really delete #{newlist}? "
          return unless /y|Y/ =~ gets.strip
        end
        self.send( func, list, options.merge( :verbose => true ) )
      end

      module_function :ask_before_delete

    end

    class CleanWalker < Webgen::Plugin

      summary "Deletes the output file for each node."
      depends_on 'TreeWalker'

      attr_writer :ask

      def handle_node( node, level )
        file = node.recursive_value( 'dest' )
        return if !File.exists?( file ) || node['int:virtualNode']
        if File.directory?( file )
          begin
            FileUtils.ask_before_delete( @ask, :rmdir, file )
          rescue Errno::ENOTEMPTY => e
            logger.info "Cannot delete directory #{file}, as it is not empty!"
          end
        else
          FileUtils.ask_before_delete( @ask, :rm, file, :force => true )
        end
      end

    end

    def initialize;
      super( 'clean', false )
      self.short_desc = "Removes the generated or all files from the output directory"
      self.options = CmdParse::OptionParserWrapper.new do |opts|
        opts.separator( "Options" )
        opts.on( '--all', '-a', "Removes ALL files from the output directory" ) { @all = true }
        opts.on( '--interactive', '-i', "Ask for each file" ) { @ask = true }
      end
      @all = false
      @ask = false
    end

    def execute( args )
      if @all
        logger.info( "Deleting all files from output directory..." )
        outDir = Plugin['Configuration']['outDirectory']
        FileUtils.ask_before_delete( @ask, :rm_rf, outDir ) if File.exists?( outDir )
      else
        tree = Plugin['FileHandler'].build_tree
        logger.info( "Deleting generated files from output directory..." )
        Plugin['CleanWalker'].ask = @ask
        Plugin['TreeWalker'].execute( tree, Plugin['CleanWalker'], :backward )
      end
      logger.info( "Webgen finished 'clean' command" )
    end

  end

  class WebgenCommandParser < CmdParse::CommandParser

    def initialize
      super( true )
      self.program_name = "webgen"
      self.program_version = Webgen::VERSION
      self.options = CmdParse::OptionParserWrapper.new do |opts|
        opts.separator "Global options:"
        opts.on( "--verbosity LEVEL", "-V", Integer, "The verbosity level" ) { |verbosity| Plugin.set_param( 'Logging', 'verbosityLevel', verbosity ) }
        opts.on( "--[no-]logfile", "-L", "Log to file" ) { |logfile| Plugin.set_param( 'Logging', 'logToFile', logfile ) }
      end

      # Run command
      run = CmdParse::Command.new( 'run', false )
      run.short_desc = "Runs webgen"
      run.set_execution_block {|args| Webgen.run_webgen }
      self.add_command( run, true )

      # Show command
      show = CmdParse::Command.new( 'show', true )
      show.short_desc = "Show various information"
      self.add_command( show )

      # Show plugins command
      showPlugins = CmdParse::Command.new( 'plugins', false )
      showPlugins.short_desc = "Show the available plugins"
      showPlugins.set_execution_block do |args|
        print "List of loaded plugins:\n"

        headers = Hash.new {|h,k| h[k] = (k.nil? ? "Other Plugins" : k.gsub(/([A-Z][a-z])/, ' \1').strip) }

        ljustlength = 30 + Color.green.length + Color.reset.length
        header = ''
        Plugin.config.sort { |a, b| a[0].name <=> b[0].name }.each do |klass, data|
          newHeader = headers[klass.name[/^.*?(?=::)/]]
          unless newHeader == header
            print "\n  #{Color.bold}#{newHeader}#{Color.reset}:\n";
            header = newHeader
          end
          print "    - #{Color.green}#{data.plugin}#{Color.reset}:".ljust(ljustlength) +"#{data.summary}\n"
        end
      end
      show.add_command( showPlugins )

      # Show params command
      showConfig = CmdParse::Command.new( 'config', false )
      showConfig.short_desc = "Show the parameters of all plugins or of the specified one"
      showConfig.set_execution_block do |args|
        puts "List of plugin parameters:"
        puts
        ljustlength = 25 + Color.green.length + Color.reset.length
        Plugin.config.sort { |a, b| a[0].name[/\w*$/] <=> b[0].name[/\w*$/] }.each do |klass, data|
          next if args.length > 0 && args[0] != data.plugin
          puts "  #{Color.bold}#{data.plugin}#{Color.reset}:"
          puts "    #{Color.green}Summary:#{Color.reset}".ljust(ljustlength) + data.summary if data.summary
          puts "    #{Color.green}Description:#{Color.reset}".ljust(ljustlength) + data.description if data.description
          puts "    #{Color.green}Tag name:#{Color.reset}".ljust(ljustlength) + (data.tag == :default ? "Default tag" : data.tag) if data.tag
          puts "    #{Color.green}Handled paths:#{Color.reset}".ljust(ljustlength) + data.path.inspect if data.path

          data.table.keys.find_all {|k| /^registered_/ =~ k.to_s }.each do |k|
            name = k.to_s.sub( /^registered_/, '' ).tr('_', ' ').capitalize + " name"
            puts "    #{Color.green}#{name}:#{Color.reset}".ljust(ljustlength) + data.send( k )
          end

          if data.params
            puts "\n    #{Color.green}Parameters:#{Color.reset}"
            data.params.sort.each do |key, item|
              print "      #{Color.green}Parameter:#{Color.reset}".ljust(ljustlength)
              puts Color.lred + item.name + Color.reset + " = " + Color.lblue +  item.value.inspect + Color.reset + " (" + item.default.inspect + ")"
              puts "      #{Color.green}Description:#{Color.reset}".ljust(ljustlength) + item.description
              puts
            end
          end
          puts
        end
      end
      show.add_command( showConfig )

      self.add_command( CreateCommand.new )
      self.add_command( CleanCommand.new )
      self.add_command( CmdParse::HelpCommand.new )
      self.add_command( CmdParse::VersionCommand.new )
    end

  end

  # Run webgen
  def self.run_webgen( directory = Dir.pwd )
    Dir.chdir( directory )

    logger.info "Starting Webgen..."
    tree = Plugin['FileHandler'].build_tree
    Plugin['TreeWalker'].execute( tree ) unless tree.nil?
    Plugin['FileHandler'].write_tree( tree ) unless tree.nil?
    logger.info "Webgen finished"
  end

  # Create a website in the +directory+, using the +template+ and the +style+.
  def self.create_website( directory, template = 'default', style = 'default' )
    templateDir = File.join( CorePlugins::Configuration.data_dir, 'website_templates', template )
    styleDir = File.join( CorePlugins::Configuration.data_dir, 'website_styles', style )
    raise ArgumentError.new( "Invalid template <#{template}>" ) if !File.directory?( templateDir )
    raise ArgumentError.new( "Invalid style <#{style}>" ) if !File.directory?( styleDir )

    raise ArgumentError.new( "Website directory <#{directory}> does already exist!") if File.exists?( directory )
    FileUtils.mkdir( directory )
    FileUtils.cp_r( Dir[File.join( templateDir, '*' )], directory )
    FileUtils.cp_r( Dir[File.join( styleDir, '*' )], File.join( directory, 'src' ) )
  end

  # Main program for the webgen CLI command.
  def self.cli_main
    Color.colorify if $stdout.isatty && !Config::CONFIG['arch'].include?( 'mswin32' )
    Plugin['Configuration'].cmdparser = WebgenCommandParser.new
    Plugin['Configuration'].cmdparser.parse do |level, cmdName|
      Plugin['Configuration'].init_all if level == 0
    end
  end

end