Class: Mill::Site

Inherits:
Object
  • Object
show all
Defined in:
lib/mill/site.rb

Constant Summary collapse

DefaultResourceClasses =
ObjectSpace.each_object(Class).select { |c| c < Resource }
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) },
}

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(input_dir: 'content', output_dir: 'public_html', site_rsync: nil, site_title: nil, site_uri: 'http://localhost', site_email: nil, site_control_date: Date.today.to_s, html_version: :html4_transitional, shorten_uris: true, make_feed: true, make_sitemap: true, make_robots: true, allow_robots: true, htpasswd_file: nil, navigator: nil, google_site_verification: nil, resource_classes: [], redirects: {}) ⇒ Site

Returns a new instance of Site.



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
# File 'lib/mill/site.rb', line 29

def initialize(input_dir: 'content',
               output_dir: 'public_html',
               site_rsync: nil,
               site_title: nil,
               site_uri: 'http://localhost',
               site_email: nil,
               site_control_date: Date.today.to_s,
               html_version: :html4_transitional,
               shorten_uris: true,
               make_feed: true,
               make_sitemap: true,
               make_robots: true,
               allow_robots: true,
               htpasswd_file: nil,
               navigator: nil,
               google_site_verification: nil,
               resource_classes: [],
               redirects: {})

  @input_dir = Path.new(input_dir)
  @output_dir = Path.new(output_dir)
  @site_rsync = site_rsync
  @site_title = site_title
  @site_uri = Addressable::URI.parse(site_uri)
  @site_email = Addressable::URI.parse(site_email) if site_email
  @site_control_date = Date.parse(site_control_date)
  @html_version = html_version
  @shorten_uris = shorten_uris
  @make_feed = make_feed
  @make_sitemap = make_sitemap
  @make_robots = make_robots
  @allow_robots = allow_robots
  @htpasswd_file = htpasswd_file ? Path.new(htpasswd_file) : nil
  @resource_classes = resource_classes
  @navigator = navigator
  @google_site_verification = google_site_verification
  @redirects = redirects

  @resources = {}
  @resources_tree = Tree::TreeNode.new('')
  build_file_types
end

Instance Attribute Details

#allow_robotsObject

Returns the value of attribute allow_robots.



20
21
22
# File 'lib/mill/site.rb', line 20

def allow_robots
  @allow_robots
end

#feed_resourceObject

Returns the value of attribute feed_resource.



13
14
15
# File 'lib/mill/site.rb', line 13

def feed_resource
  @feed_resource
end

#html_versionObject

Returns the value of attribute html_version.



12
13
14
# File 'lib/mill/site.rb', line 12

def html_version
  @html_version
end

#htpasswd_fileObject

Returns the value of attribute htpasswd_file.



21
22
23
# File 'lib/mill/site.rb', line 21

def htpasswd_file
  @htpasswd_file
end

#input_dirObject

Returns the value of attribute input_dir.



5
6
7
# File 'lib/mill/site.rb', line 5

def input_dir
  @input_dir
end

#make_feedObject

Returns the value of attribute make_feed.



17
18
19
# File 'lib/mill/site.rb', line 17

def make_feed
  @make_feed
end

#make_robotsObject

Returns the value of attribute make_robots.



19
20
21
# File 'lib/mill/site.rb', line 19

def make_robots
  @make_robots
end

#make_sitemapObject

Returns the value of attribute make_sitemap.



18
19
20
# File 'lib/mill/site.rb', line 18

def make_sitemap
  @make_sitemap
end

Returns the value of attribute navigator.



22
23
24
# File 'lib/mill/site.rb', line 22

def navigator
  @navigator
end

#output_dirObject

Returns the value of attribute output_dir.



6
7
8
# File 'lib/mill/site.rb', line 6

def output_dir
  @output_dir
end

#redirectsObject

Returns the value of attribute redirects.



24
25
26
# File 'lib/mill/site.rb', line 24

def redirects
  @redirects
end

#resource_classesObject

Returns the value of attribute resource_classes.



23
24
25
# File 'lib/mill/site.rb', line 23

def resource_classes
  @resource_classes
end

#resourcesObject

Returns the value of attribute resources.



25
26
27
# File 'lib/mill/site.rb', line 25

def resources
  @resources
end

#robots_resourceObject

Returns the value of attribute robots_resource.



15
16
17
# File 'lib/mill/site.rb', line 15

def robots_resource
  @robots_resource
end

#shorten_urisObject

Returns the value of attribute shorten_uris.



16
17
18
# File 'lib/mill/site.rb', line 16

def shorten_uris
  @shorten_uris
end

#site_control_dateObject

Returns the value of attribute site_control_date.



11
12
13
# File 'lib/mill/site.rb', line 11

def site_control_date
  @site_control_date
end

#site_emailObject

Returns the value of attribute site_email.



10
11
12
# File 'lib/mill/site.rb', line 10

def site_email
  @site_email
end

#site_rsyncObject

Returns the value of attribute site_rsync.



7
8
9
# File 'lib/mill/site.rb', line 7

def site_rsync
  @site_rsync
end

#site_titleObject

Returns the value of attribute site_title.



8
9
10
# File 'lib/mill/site.rb', line 8

def site_title
  @site_title
end

#site_uriObject

Returns the value of attribute site_uri.



9
10
11
# File 'lib/mill/site.rb', line 9

def site_uri
  @site_uri
end

#sitemap_resourceObject

Returns the value of attribute sitemap_resource.



14
15
16
# File 'lib/mill/site.rb', line 14

def sitemap_resource
  @sitemap_resource
end

Instance Method Details

#add_resource(resource) ⇒ Object



81
82
83
84
85
86
87
88
89
90
91
# File 'lib/mill/site.rb', line 81

def add_resource(resource)
  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.node = node
  node.content = resource
  # ;;warn "added #{resource} as #{resource.path}"
end

#buildObject



217
218
219
220
221
# File 'lib/mill/site.rb', line 217

def build
  import_resources
  load_resources
  build_resources
end

#build_file_typesObject



72
73
74
75
76
77
78
79
# File 'lib/mill/site.rb', line 72

def build_file_types
  @file_types = {}
  (DefaultResourceClasses + @resource_classes).each do |resource_class|
    resource_class.const_get(:FileTypes).each do |type|
      @file_types[type] = resource_class
    end
  end
end

#build_resourcesObject



240
241
242
243
244
245
# File 'lib/mill/site.rb', line 240

def build_resources
  on_each_resource do |resource|
    # ;;warn "#{resource.path}: building"
    resource.build
  end
end

#checkObject



264
265
266
267
# File 'lib/mill/site.rb', line 264

def check
  build
  checker = WebChecker.new(site_uri: @site_uri, site_dir: @output_dir)
end

#cleanObject



256
257
258
259
260
261
262
# File 'lib/mill/site.rb', line 256

def clean
  if @output_dir.exist?
    @output_dir.children.reject { |p| p.basename.to_s == '.git' }.each do |path|
      path.rm_rf
    end
  end
end

#diffObject



284
285
286
287
288
289
# File 'lib/mill/site.rb', line 284

def diff
  @output_dir.chdir do
    system('git',
      'diff')
  end
end

#feed_author_emailObject



119
120
121
# File 'lib/mill/site.rb', line 119

def feed_author_email
  @site_email
end

#feed_author_nameObject



111
112
113
# File 'lib/mill/site.rb', line 111

def feed_author_name
  @site_title
end

#feed_author_uriObject



115
116
117
# File 'lib/mill/site.rb', line 115

def feed_author_uri
  @site_uri
end

#feed_resourcesObject



133
134
135
# File 'lib/mill/site.rb', line 133

def feed_resources
  public_resources.sort_by(&:date)
end

#find_resource(path) ⇒ Object



93
94
95
96
# File 'lib/mill/site.rb', line 93

def find_resource(path)
  path = path.path if path.kind_of?(Addressable::URI)
  @resources[path] || @resources[path + '/']
end

#home_resourceObject



98
99
100
# File 'lib/mill/site.rb', line 98

def home_resource
  find_resource('/')
end

#import_resourcesObject



223
224
225
226
227
228
229
230
231
# File 'lib/mill/site.rb', line 223

def import_resources
  add_files
  add_redirects
  add_google_site_verification if @google_site_verification
  add_feed if @make_feed
  add_sitemap if @make_sitemap
  add_robots if @make_robots
  add_htpasswd if @htpasswd_file
end

#listObject



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
# File 'lib/mill/site.rb', line 181

def list
  build
  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
  puts
end

#load_resourcesObject



233
234
235
236
237
238
# File 'lib/mill/site.rb', line 233

def load_resources
  on_each_resource do |resource|
    # ;;warn "#{resource.path}: loading"
    resource.load
  end
end

#makeObject



149
150
151
152
# File 'lib/mill/site.rb', line 149

def make
  build
  save
end

#on_each_resource(&block) ⇒ Object



304
305
306
307
308
309
310
311
312
# File 'lib/mill/site.rb', line 304

def on_each_resource(&block)
  @resources.values.each do |resource|
    begin
      yield(resource)
    rescue Error => e
      raise e, "#{resource.input_file || '-'} (#{resource.path}): #{e}"
    end
  end
end


154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/mill/site.rb', line 154

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

#public_resourcesObject



137
138
139
# File 'lib/mill/site.rb', line 137

def public_resources
  select_resources(&:public?)
end

#redirect_resourcesObject



141
142
143
# File 'lib/mill/site.rb', line 141

def redirect_resources
  select_resources(&:redirect?)
end

#saveObject



247
248
249
250
251
252
253
254
# File 'lib/mill/site.rb', line 247

def save
  clean
  @output_dir.mkpath
  on_each_resource do |resource|
    # ;;warn "#{resource.path}: saving"
    resource.save
  end
end

#select_resources(selector = nil, &block) ⇒ Object



123
124
125
126
127
128
129
130
131
# File 'lib/mill/site.rb', line 123

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

#snapshotObject



269
270
271
272
273
274
275
276
277
278
279
280
281
282
# File 'lib/mill/site.rb', line 269

def snapshot
  @output_dir.chdir do
    system('git',
      'init') unless Path.new('.git').exist?
    system('git',
      'add',
      '.')
    system('git',
      'commit',
      '-a',
      '-m',
      'Update.')
  end
end

#tag_uriObject



102
103
104
105
106
107
108
109
# File 'lib/mill/site.rb', line 102

def tag_uri
  'tag:%s:' % [
    [
      @site_uri.host.downcase,
      @site_control_date
    ].join(','),
  ]
end

#text_resourcesObject



145
146
147
# File 'lib/mill/site.rb', line 145

def text_resources
  select_resources(&:text?)
end

#uploadObject



291
292
293
294
295
296
297
298
299
300
301
302
# File 'lib/mill/site.rb', line 291

def upload
  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