wax_tasks 1.1.4 → 1.1.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/ISSUE_TEMPLATE/bug_report.md +35 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +17 -0
- data/.github/workflows/ci.yml +30 -0
- data/.gitignore +7 -0
- data/.rspec +3 -0
- data/.rubocop.yml +16 -0
- data/.ruby-version +1 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +11 -0
- data/LICENSE +21 -0
- data/README.md +171 -0
- data/lib/tasks/clobber.rake +16 -0
- data/lib/tasks/derivatives_iiif.rake +26 -0
- data/lib/tasks/derivatives_simple.rake +17 -0
- data/lib/tasks/pages.rake +23 -0
- data/lib/tasks/search.rake +23 -0
- data/lib/wax_tasks.rb +37 -0
- data/lib/wax_tasks/asset.rb +57 -0
- data/lib/wax_tasks/collection.rb +61 -0
- data/lib/wax_tasks/collection/images.rb +126 -0
- data/lib/wax_tasks/collection/metadata.rb +101 -0
- data/lib/wax_tasks/config.rb +79 -0
- data/lib/wax_tasks/error.rb +65 -0
- data/lib/wax_tasks/index.rb +45 -0
- data/lib/wax_tasks/item.rb +116 -0
- data/lib/wax_tasks/record.rb +72 -0
- data/lib/wax_tasks/site.rb +86 -0
- data/lib/wax_tasks/utils.rb +151 -0
- data/lib/wax_tasks/version.rb +5 -0
- data/spec/setup.rb +0 -0
- data/spec/spec_helper.rb +0 -0
- data/wax_tasks.gemspec +33 -0
- metadata +32 -2
@@ -0,0 +1,79 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module WaxTasks
|
4
|
+
#
|
5
|
+
class Config
|
6
|
+
attr_reader :collections
|
7
|
+
|
8
|
+
def initialize(config)
|
9
|
+
@config = config
|
10
|
+
@collections = process_collections
|
11
|
+
end
|
12
|
+
|
13
|
+
def self
|
14
|
+
@config
|
15
|
+
end
|
16
|
+
|
17
|
+
#
|
18
|
+
#
|
19
|
+
def source
|
20
|
+
@config.dig 'source'
|
21
|
+
end
|
22
|
+
|
23
|
+
#
|
24
|
+
#
|
25
|
+
def collections_dir
|
26
|
+
@config.dig 'collections_dir'
|
27
|
+
end
|
28
|
+
|
29
|
+
#
|
30
|
+
# Contructs permalink extension from site `permalink` variable
|
31
|
+
#
|
32
|
+
# @return [String] the end of the permalink, either '/' or '.html'
|
33
|
+
def ext
|
34
|
+
case @config.dig 'permalink'
|
35
|
+
when 'pretty' || '/'
|
36
|
+
'/'
|
37
|
+
else
|
38
|
+
'.html'
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
#
|
43
|
+
#
|
44
|
+
def process_collections
|
45
|
+
if @config.key? 'collections'
|
46
|
+
@config['collections'].map do |k, v|
|
47
|
+
WaxTasks::Collection.new(k, v, source, collections_dir, ext)
|
48
|
+
end
|
49
|
+
else
|
50
|
+
[]
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
#
|
55
|
+
#
|
56
|
+
def search(name)
|
57
|
+
search_config = @config.dig 'search', name
|
58
|
+
raise WaxTasks::Error::InvalidConfig if search_config.nil?
|
59
|
+
raise WaxTasks::Error::InvalidConfig unless search_config.dig('collections').is_a? Hash
|
60
|
+
|
61
|
+
search_config['collections'] = search_config['collections'].map do |k, v|
|
62
|
+
fields = v.fetch('fields', [])
|
63
|
+
fields << 'content' if v.fetch('content', false)
|
64
|
+
find_collection(k).tap { |c| c.search_fields = fields }
|
65
|
+
end
|
66
|
+
|
67
|
+
search_config
|
68
|
+
end
|
69
|
+
|
70
|
+
#
|
71
|
+
#
|
72
|
+
def find_collection(name)
|
73
|
+
collection = @collections.find { |c| c.name == name }
|
74
|
+
raise WaxTasks::Error::InvalidCollection, "Cannot find requested collection '#{name}'" if collection.nil?
|
75
|
+
|
76
|
+
collection
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module WaxTasks
|
4
|
+
# Custom WaxTasks Errors module
|
5
|
+
module Error
|
6
|
+
# Custom WaxTasks Error class with magenta console output
|
7
|
+
class WaxTasksError < StandardError
|
8
|
+
def initialize(msg = '')
|
9
|
+
super(Rainbow(msg).magenta)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
# Custom Error:
|
14
|
+
# Rake task expects arguments, found none
|
15
|
+
class MissingArguments < WaxTasksError; end
|
16
|
+
|
17
|
+
# Custom Error:
|
18
|
+
# Site config cannot be found / parsed for the task at hand
|
19
|
+
class InvalidConfig < WaxTasksError; end
|
20
|
+
|
21
|
+
# Custom Error:
|
22
|
+
# Collection specified cannot be found / parsed in site config
|
23
|
+
class InvalidCollection < WaxTasksError; end
|
24
|
+
|
25
|
+
# Custom Error:
|
26
|
+
# Collection data source type is not allowed or is an invalid file
|
27
|
+
class InvalidSource < WaxTasksError; end
|
28
|
+
|
29
|
+
# Custom Error:
|
30
|
+
# Data source file could not be found
|
31
|
+
class MissingSource < WaxTasksError; end
|
32
|
+
|
33
|
+
# Custom Error:
|
34
|
+
# Could not load collection page(s)
|
35
|
+
class PageLoad < WaxTasksError; end
|
36
|
+
|
37
|
+
# Custom Error:
|
38
|
+
# Collection item does not have a required pid value
|
39
|
+
class MissingPid < WaxTasksError; end
|
40
|
+
|
41
|
+
# Custom Error:
|
42
|
+
# Collection item has a non-unique pud value
|
43
|
+
class NonUniquePid < WaxTasksError; end
|
44
|
+
|
45
|
+
# Custom Error:
|
46
|
+
# Collection page item could not be generated
|
47
|
+
class PageFailure < WaxTasksError; end
|
48
|
+
|
49
|
+
# Custom Error:
|
50
|
+
# CSV file failed to lint + could not be loaded
|
51
|
+
class InvalidCSV < WaxTasksError; end
|
52
|
+
|
53
|
+
# Custom Error:
|
54
|
+
# JSON file failed to lint + could not be loaded
|
55
|
+
class InvalidJSON < WaxTasksError; end
|
56
|
+
|
57
|
+
# Custom Error:
|
58
|
+
# YAML file failed to lint + could not be loaded
|
59
|
+
class InvalidYAML < WaxTasksError; end
|
60
|
+
|
61
|
+
# Custom Error:
|
62
|
+
# Search index in site config has no valid collections to index
|
63
|
+
class NoSearchCollections < WaxTasksError; end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module WaxTasks
|
4
|
+
#
|
5
|
+
class Index
|
6
|
+
attr_reader :path, :collections
|
7
|
+
|
8
|
+
def initialize(config)
|
9
|
+
@config = config
|
10
|
+
@collections = config.dig 'collections'
|
11
|
+
@path = config.dig 'index'
|
12
|
+
|
13
|
+
raise WaxTasks::Error::NoSearchCollections if @collections.nil?
|
14
|
+
raise WaxTasks::Error::InvalidConfig if @path.nil?
|
15
|
+
|
16
|
+
@records = records
|
17
|
+
end
|
18
|
+
|
19
|
+
#
|
20
|
+
#
|
21
|
+
def records
|
22
|
+
lunr_id = 0
|
23
|
+
@collections.flat_map do |collection|
|
24
|
+
collection.records_from_pages.each.flat_map do |r|
|
25
|
+
r.keep_only collection.search_fields
|
26
|
+
r.set 'lunr_id', lunr_id
|
27
|
+
r.lunr_normalize_values
|
28
|
+
lunr_id += 1
|
29
|
+
r
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
#
|
35
|
+
#
|
36
|
+
def write_to(dir)
|
37
|
+
file_path = WaxTasks::Utils.safe_join dir, @path
|
38
|
+
FileUtils.mkdir_p File.dirname(file_path)
|
39
|
+
File.open(file_path, 'w') do |f|
|
40
|
+
f.puts "---\nlayout: none\n---\n"
|
41
|
+
f.puts JSON.pretty_generate(@records.map(&:hash))
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module WaxTasks
|
4
|
+
#
|
5
|
+
class Item
|
6
|
+
attr_accessor :record, :iiif_config
|
7
|
+
attr_reader :pid
|
8
|
+
|
9
|
+
#
|
10
|
+
#
|
11
|
+
#
|
12
|
+
def initialize(path, variants)
|
13
|
+
@path = path
|
14
|
+
@variants = variants
|
15
|
+
@type = type
|
16
|
+
@pid = File.basename @path, '.*'
|
17
|
+
@assets = assets
|
18
|
+
end
|
19
|
+
|
20
|
+
#
|
21
|
+
#
|
22
|
+
def accepted_image_formats
|
23
|
+
%w[.png .jpg .jpeg .tiff .tif]
|
24
|
+
end
|
25
|
+
|
26
|
+
#
|
27
|
+
#
|
28
|
+
def type
|
29
|
+
Dir.exist?(@path) ? 'dir' : File.extname(@path).downcase
|
30
|
+
end
|
31
|
+
|
32
|
+
#
|
33
|
+
#
|
34
|
+
def valid?
|
35
|
+
accepted_image_formats.include? @type or @type == 'dir'
|
36
|
+
end
|
37
|
+
|
38
|
+
#
|
39
|
+
#
|
40
|
+
def record?
|
41
|
+
@record.is_a? Record
|
42
|
+
end
|
43
|
+
|
44
|
+
#
|
45
|
+
#
|
46
|
+
def assets
|
47
|
+
if accepted_image_formats.include? @type
|
48
|
+
[Asset.new(@path, @pid, @variants)]
|
49
|
+
elsif @type == 'dir'
|
50
|
+
paths = Dir.glob("#{@path}/*{#{accepted_image_formats.join(',')}}").sort
|
51
|
+
paths.map { |p| Asset.new(p, @pid, @variants) }
|
52
|
+
else
|
53
|
+
[]
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
#
|
58
|
+
#
|
59
|
+
def simple_derivatives
|
60
|
+
@assets.map(&:simple_derivatives).flatten
|
61
|
+
end
|
62
|
+
|
63
|
+
#
|
64
|
+
#
|
65
|
+
def logo
|
66
|
+
logo_uri = @iiif_config&.dig 'logo'
|
67
|
+
"{{ '#{logo_uri}' | absolute_url }}" if logo_uri
|
68
|
+
end
|
69
|
+
|
70
|
+
def label
|
71
|
+
label_key = @iiif_config&.dig 'label'
|
72
|
+
if @record && label_key
|
73
|
+
@record.hash.dig label_key
|
74
|
+
else
|
75
|
+
@pid
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
#
|
80
|
+
#
|
81
|
+
def description
|
82
|
+
description_key = @iiif_config&.dig 'description'
|
83
|
+
@record.hash.dig description_key if description_key && @record
|
84
|
+
end
|
85
|
+
|
86
|
+
#
|
87
|
+
#
|
88
|
+
def attribution
|
89
|
+
attribution_key = @iiif_config.dig 'attribution'
|
90
|
+
@record.hash.dig attribution_key if attribution_key && @record
|
91
|
+
end
|
92
|
+
|
93
|
+
#
|
94
|
+
#
|
95
|
+
def iiif_image_records
|
96
|
+
opts = base_opts.clone
|
97
|
+
is_only = @assets.length == 1
|
98
|
+
|
99
|
+
@assets.map.with_index do |asset, i|
|
100
|
+
asset.to_iiif_image_record(is_only, i, opts)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
#
|
105
|
+
#
|
106
|
+
def base_opts
|
107
|
+
opts = { label: label }
|
108
|
+
return opts unless @iiif_config
|
109
|
+
|
110
|
+
opts[:logo] = logo if logo
|
111
|
+
opts[:description] = description.to_s if description
|
112
|
+
opts[:attribution] = attribution.to_s if attribution
|
113
|
+
opts
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module WaxTasks
|
4
|
+
#
|
5
|
+
class Record
|
6
|
+
attr_reader :pid, :hash
|
7
|
+
|
8
|
+
def initialize(hash)
|
9
|
+
@hash = hash
|
10
|
+
@pid = @hash.dig 'pid'
|
11
|
+
end
|
12
|
+
|
13
|
+
def order
|
14
|
+
@hash.dig 'order'
|
15
|
+
end
|
16
|
+
|
17
|
+
#
|
18
|
+
#
|
19
|
+
def lunr_normalize_values
|
20
|
+
@hash.transform_values { |v| Utils.lunr_normalize v }
|
21
|
+
end
|
22
|
+
|
23
|
+
#
|
24
|
+
#
|
25
|
+
def keys
|
26
|
+
@hash.keys
|
27
|
+
end
|
28
|
+
|
29
|
+
# PATCH :: rename 'fullwidth' to 'full' to
|
30
|
+
# (1) avoid breaking wax_iiif with special 'full' variant label
|
31
|
+
# (2) avoid breaking wax_theme which still expects 'full' to provide an image path
|
32
|
+
# this can be deprecated when a new version of wax_theme looks for another fullsize key
|
33
|
+
#
|
34
|
+
def set(key, value)
|
35
|
+
key = 'full' if key == 'fullwidth'
|
36
|
+
@hash[key] = value
|
37
|
+
end
|
38
|
+
|
39
|
+
#
|
40
|
+
#
|
41
|
+
def permalink?
|
42
|
+
@hash.key? 'permalink'
|
43
|
+
end
|
44
|
+
|
45
|
+
#
|
46
|
+
#
|
47
|
+
def order?
|
48
|
+
!order.to_s.empty?
|
49
|
+
end
|
50
|
+
|
51
|
+
#
|
52
|
+
#
|
53
|
+
def keep_only(fields)
|
54
|
+
@hash.select! { |k, _v| fields.include? k }
|
55
|
+
end
|
56
|
+
|
57
|
+
#
|
58
|
+
#
|
59
|
+
def write_to_page(dir)
|
60
|
+
raise Error::MissingPid if @pid.nil?
|
61
|
+
|
62
|
+
path = "#{dir}/#{Utils.slug(@pid)}.md"
|
63
|
+
if File.exist? path
|
64
|
+
0
|
65
|
+
else
|
66
|
+
FileUtils.mkdir_p File.dirname(path)
|
67
|
+
File.open(path, 'w') { |f| f.puts "#{@hash.to_yaml}---" }
|
68
|
+
1
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
module WaxTasks
|
5
|
+
#
|
6
|
+
class Site
|
7
|
+
attr_reader :config
|
8
|
+
|
9
|
+
#
|
10
|
+
#
|
11
|
+
def initialize(config = nil)
|
12
|
+
@config = WaxTasks::Config.new(config || WaxTasks.config_from_file)
|
13
|
+
end
|
14
|
+
|
15
|
+
#
|
16
|
+
#
|
17
|
+
def collections
|
18
|
+
@config.collections
|
19
|
+
end
|
20
|
+
|
21
|
+
#
|
22
|
+
#
|
23
|
+
def clobber(name)
|
24
|
+
collection = @config.find_collection name
|
25
|
+
raise WaxTasks::Error::InvalidCollection if collection.nil?
|
26
|
+
|
27
|
+
collection.clobber_pages
|
28
|
+
collection.clobber_derivatives
|
29
|
+
|
30
|
+
@config.self.fetch('search', {}).each do |_name, search|
|
31
|
+
next unless search.key? 'index'
|
32
|
+
index = Utils.safe_join @config.source, search['index']
|
33
|
+
next unless File.exist? index
|
34
|
+
puts Rainbow("Removing search index #{index}").cyan
|
35
|
+
FileUtils.rm index
|
36
|
+
end
|
37
|
+
|
38
|
+
puts Rainbow("\nDone ✔").green
|
39
|
+
end
|
40
|
+
|
41
|
+
#
|
42
|
+
#
|
43
|
+
def generate_pages(name)
|
44
|
+
result = 0
|
45
|
+
collection = @config.find_collection name
|
46
|
+
raise WaxTasks::Error::InvalidCollection if collection.nil?
|
47
|
+
|
48
|
+
collection.records_from_metadata.each do |record|
|
49
|
+
result += record.write_to_page(collection.page_source)
|
50
|
+
end
|
51
|
+
|
52
|
+
puts Rainbow("#{result} pages were generated to #{collection.page_source}.").cyan
|
53
|
+
puts Rainbow("\nDone ✔").green
|
54
|
+
end
|
55
|
+
|
56
|
+
#
|
57
|
+
#
|
58
|
+
def generate_static_search(name)
|
59
|
+
search_config = @config.search name
|
60
|
+
index = WaxTasks::Index.new(search_config)
|
61
|
+
|
62
|
+
puts Rainbow("Generating #{name} search index to #{index.path}").cyan
|
63
|
+
index.write_to @config.source
|
64
|
+
|
65
|
+
puts Rainbow("\nDone ✔").green
|
66
|
+
end
|
67
|
+
|
68
|
+
#
|
69
|
+
#
|
70
|
+
def generate_derivatives(name, type)
|
71
|
+
collection = @config.find_collection name
|
72
|
+
raise WaxTasks::Error::InvalidCollection if collection.nil?
|
73
|
+
raise WaxTasks::Error::InvalidConfig unless %w[iiif simple].include? type
|
74
|
+
|
75
|
+
records = case type
|
76
|
+
when 'iiif'
|
77
|
+
collection.write_iiif_derivatives
|
78
|
+
when 'simple'
|
79
|
+
collection.write_simple_derivatives
|
80
|
+
end
|
81
|
+
|
82
|
+
collection.update_metadata records
|
83
|
+
puts Rainbow("\nDone ✔").green
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|