lib/mill/site.rb in mill-0.11 vs lib/mill/site.rb in mill-0.16

- old
+ new

@@ -62,12 +62,12 @@ @resource_classes = resource_classes @navigator = navigator @google_site_verification = google_site_verification @redirects = redirects - @resources = [] - @resources_by_uri = {} + @resources = {} + @resources_tree = Tree::TreeNode.new('') build_file_types end def build_file_types @file_types = {} @@ -77,39 +77,24 @@ end end end def add_resource(resource) - resource.site = self - @resources << resource - @resources_by_uri[resource.uri] = resource - # ;;warn "added #{resource} as #{resource.uri}" - end - - def delete_resource(resource) - @resources.delete(resource) - @resources_by_uri.delete(resource.uri) - end - - def find_resource(uri) - uri = Addressable::URI.parse(uri.to_s) unless uri.kind_of?(Addressable::URI) - resource = @resources_by_uri[uri] - if resource.nil? && @shorten_uris - uri.path = uri.path.sub(%r{\.html$}, '') - resource = @resources_by_uri[uri] + raise "Must assign resource to site" unless resource.site + @resources[resource.path] = resource + node = @resources_tree + resource.path.split('/').reject(&:empty?).each do |component| + node = node[component] || (node << Tree::TreeNode.new(component)) end - resource + resource.node = node + node.content = resource + # ;;warn "added #{resource} as #{resource.path}" end - def resource_for_file(path) - find_resource( - URI.parse( - '/' + URI.encode( - path.relative_to(@output_dir).to_s - ) - ) - ) + def find_resource(path) + path = path.path if path.kind_of?(Addressable::URI) + @resources[path] || @resources[path + '/'] end def home_resource find_resource('/') end @@ -133,60 +118,102 @@ def feed_author_email @site_email end + def select_resources(selector=nil, &block) + if block_given? + @resources.values.select(&block) + elsif selector.kind_of?(Class) + @resources.values.select { |r| r.kind_of?(selector) } + else + @resources.values.select(selector) + end + end + def feed_resources public_resources.sort_by(&:date) end def public_resources - @resources.select(&:public) + select_resources(&:public?) end - def private_resources - @resources.select { |r| r.kind_of?(Resource::Text) && !r.public } + def redirect_resources + select_resources(&:redirect?) end - def redirect_resources - @resources.select { |r| r.kind_of?(Resource::Redirect) } + def text_resources + select_resources(&:text?) end def make build save end - def list + def print_tree(node=nil, level=0) + node ||= @resources_tree + if node.is_root? + print '*' + else + print "\t" * level + end + print " #{node.name.inspect}" + print " <#{node.content&.path}>" + print " (#{node.children.length} children)" if node.has_children? + puts + node.children { |child| print_tree(child, level + 1) } + end - list_keys = { - class: proc { |v| v.to_s.sub(/::Resource::/, '::') }, - input_file: proc { |v| v.relative_to(@input_dir) }, - output_file: proc { |v| v.relative_to(@output_dir) }, - public: proc { |v| v }, - content: proc { |v| '%dKB' % (v.to_s.length / 1024.0).ceil }, - } + ListKeys = { + path: :to_s, + input_file: :to_s, + output_file: :to_s, + date: :to_s, + public: :to_s, + class: :to_s, + content: proc { |r| r.content ? ('%s (%dKB)' % [r.content.class, (r.content.to_s.length / 1024.0).ceil]) : nil }, + parent: proc { |r| r.parent&.path }, + siblings: proc { |r| r.siblings.map(&:path) }, + children: proc { |r| r.children.map(&:path) }, + } + def list build - list = @resources.map do |resource| - Hash[ - list_keys.map do |k, p| - v = resource.send(k) - [ - k, - v ? p.call(v).to_s : '-' - ] + width = ListKeys.keys.map(&:length).max + select_resources.each do |resource| + ListKeys.each do |key, converter| + value = resource.send(key) + value = case converter + when nil + value + when Symbol + value.send(converter) + when Proc + converter.call(resource) + else + raise end - ] + print '%*s: ' % [width, key] + case value + when Array + if value.empty? + puts '-' + else + value.each_with_index do |v, i| + print '%*s ' % [width, ''] if i > 0 + puts (v.nil? ? '-' : v) + end + end + else + puts (value.nil? ? '-' : value) + end + end + puts end - format = list_keys.keys.map do |key| - '%%-%ds' % list.map { |item| item[key].length }.max - end.join(' ') - puts format % list_keys.keys - list.each do |item| - puts format % item.values - end + puts end def build import_resources load_resources @@ -203,27 +230,27 @@ add_htpasswd if @htpasswd_file end def load_resources on_each_resource do |resource| - # ;;warn "#{resource.uri}: loading" + # ;;warn "#{resource.path}: loading" resource.load end end def build_resources on_each_resource do |resource| - # ;;warn "#{resource.uri}: building" + # ;;warn "#{resource.path}: building" resource.build end end def save clean @output_dir.mkpath on_each_resource do |resource| - # ;;warn "#{resource.uri}: saving" + # ;;warn "#{resource.path}: saving" resource.save end end def clean @@ -240,10 +267,12 @@ end def snapshot @output_dir.chdir do system('git', + 'init') unless Path.new('.git').exist? + system('git', 'add', '.') system('git', 'commit', '-a', @@ -263,29 +292,24 @@ raise "site_rsync not defined" unless @site_rsync system('rsync', '--progress', '--verbose', '--archive', + # '--append-verify', '--exclude=.git', '--delete-after', @output_dir.to_s, @site_rsync) end def on_each_resource(&block) - @resources.each do |resource| - old_uri = resource.uri.dup + @resources.values.each do |resource| begin yield(resource) rescue Error => e - raise e, "#{resource.input_file || '-'} (#{old_uri}): #{e}" + raise e, "#{resource.input_file || '-'} (#{resource.path}): #{e}" end - if resource.uri != old_uri - # ;;warn "URI changed: #{old_uri} => #{resource.uri}" - @resources_by_uri.delete(old_uri) - @resources_by_uri[resource.uri] = resource - end end end private @@ -297,65 +321,72 @@ raise Error, "Unknown file type: #{file.to_s.inspect} (#{MIME::Types.of(file.to_s).join(', ')})" end end def add_files - raise Error, "Input path not found: #{@input_dir}" unless @input_dir.exist? + raise Error, "Input directory not found: #{@input_dir}" unless @input_dir.exist? @input_dir.find do |input_file| if input_file.basename.to_s[0] == '.' Find.prune elsif input_file.directory? # skip else (klass = resource_class_for_file(input_file)) resource = klass.new( input_file: input_file, - output_file: @output_dir / input_file.relative_to(@input_dir)) + output_file: @output_dir / input_file.relative_to(@input_dir), + site: self) add_resource(resource) end end end def add_feed @feed_resource = Resource::Feed.new( - output_file: @output_dir / 'feed.xml') + output_file: @output_dir / 'feed.xml', + site: self) add_resource(@feed_resource) end def add_sitemap @sitemap_resource = Resource::Sitemap.new( - output_file: @output_dir / 'sitemap.xml') + output_file: @output_dir / 'sitemap.xml', + site: self) add_resource(@sitemap_resource) end def add_robots @robots_resource = Resource::Robots.new( - output_file: @output_dir / 'robots.txt') + output_file: @output_dir / 'robots.txt', + site: self) add_resource(@robots_resource) end def add_redirects if @redirects @redirects.each do |from, to| output_file = @output_dir / Path.new(from).relative_to('/') resource = Resource::Redirect.new( output_file: output_file, - redirect_uri: to) + redirect_uri: to, + site: self) add_resource(resource) end end end def add_google_site_verification resource = Resource::GoogleSiteVerification.new( output_file: (@output_dir / @google_site_verification).add_extension('.html'), - key: @google_site_verification) + key: @google_site_verification, + site: self) add_resource(resource) end def add_htpasswd resource = Resource.new( input_file: @htpasswd_file, - output_file: @output_dir / '.htpasswd') + output_file: @output_dir / '.htpasswd', + site: self) add_resource(resource) end end \ No newline at end of file