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