wax_tasks 1.0.0.pre.beta → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +3 -2
- data/lib/tasks/derivatives_iiif.rake +7 -4
- data/lib/tasks/derivatives_simple.rake +7 -4
- data/lib/tasks/pages.rake +22 -0
- data/lib/tasks/search.rake +22 -0
- data/lib/wax_tasks.rb +29 -36
- data/lib/wax_tasks/asset.rb +51 -0
- data/lib/wax_tasks/collection.rb +20 -83
- data/lib/wax_tasks/collection/images.rb +127 -0
- data/lib/wax_tasks/collection/metadata.rb +101 -0
- data/lib/wax_tasks/config.rb +75 -0
- data/lib/wax_tasks/error.rb +17 -31
- data/lib/wax_tasks/index.rb +45 -0
- data/lib/wax_tasks/item.rb +116 -0
- data/lib/wax_tasks/record.rb +65 -0
- data/lib/wax_tasks/site.rb +68 -0
- data/lib/wax_tasks/utils.rb +57 -106
- data/spec/setup.rb +1 -1
- data/spec/spec_helper.rb +14 -9
- metadata +38 -36
- data/lib/tasks/jspackage.rake +0 -17
- data/lib/tasks/lunr.rake +0 -9
- data/lib/tasks/pagemaster.rake +0 -11
- data/lib/tasks/push.rake +0 -12
- data/lib/tasks/test.rake +0 -18
- data/lib/wax_tasks/branch.rb +0 -70
- data/lib/wax_tasks/iiif/derivatives.rb +0 -86
- data/lib/wax_tasks/iiif/manifest.rb +0 -26
- data/lib/wax_tasks/image_collection.rb +0 -137
- data/lib/wax_tasks/local_branch.rb +0 -21
- data/lib/wax_tasks/lunr/index.rb +0 -82
- data/lib/wax_tasks/lunr/page_set.rb +0 -57
- data/lib/wax_tasks/pagemaster_collection.rb +0 -60
- data/lib/wax_tasks/task_runner.rb +0 -148
- data/lib/wax_tasks/travis_branch.rb +0 -28
@@ -0,0 +1,101 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
module WaxTasks
|
5
|
+
#
|
6
|
+
class Collection
|
7
|
+
#
|
8
|
+
module Metadata
|
9
|
+
#
|
10
|
+
#
|
11
|
+
def search_fields=(fields)
|
12
|
+
@search_fields.concat(fields).flatten.compact.uniq
|
13
|
+
end
|
14
|
+
|
15
|
+
#
|
16
|
+
#
|
17
|
+
def records_from_pages
|
18
|
+
paths = Dir.glob("#{@page_source}/*.{md, markdown}")
|
19
|
+
warn Rainbow("There are no pages in #{@page_source} to index.").orange if paths.empty?
|
20
|
+
|
21
|
+
paths.map do |path|
|
22
|
+
begin
|
23
|
+
content = WaxTasks::Utils.content_clean File.read(path)
|
24
|
+
Record.new(SafeYAML.load_file(path)).tap do |r|
|
25
|
+
r.set 'content', content
|
26
|
+
r.set 'permalink', "/#{@name}/#{r.pid}#{@ext}" unless r.permalink?
|
27
|
+
end
|
28
|
+
rescue StandardError => e
|
29
|
+
raise Error::PageLoad, "Cannot load page #{path}\n#{e}"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
#
|
35
|
+
#
|
36
|
+
def records_from_metadata
|
37
|
+
raise Error::MissingSource, "Cannot find metadata source '#{@metadata_source}'" unless File.exist? @metadata_source
|
38
|
+
|
39
|
+
metadata = Utils.ingest @metadata_source
|
40
|
+
metadata.each_with_index.map do |meta, i|
|
41
|
+
Record.new(meta).tap do |r|
|
42
|
+
r.set 'order', Utils.padded_int(i, metadata.length) unless r.order?
|
43
|
+
r.set 'layout', @config['layout'] if @config.key? 'layout'
|
44
|
+
r.set 'collection', @name
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
#
|
50
|
+
#
|
51
|
+
def update_metadata(update)
|
52
|
+
records = consolidate_records records_from_metadata, update
|
53
|
+
reformatted = case File.extname @metadata_source
|
54
|
+
when '.csv'
|
55
|
+
csv_string records
|
56
|
+
when '.json'
|
57
|
+
json_string records
|
58
|
+
when /\.ya?ml/
|
59
|
+
yaml_string records
|
60
|
+
end
|
61
|
+
File.open(@metadata_source, 'w') { |f| f.puts reformatted }
|
62
|
+
end
|
63
|
+
|
64
|
+
#
|
65
|
+
#
|
66
|
+
def consolidate_records(original, new)
|
67
|
+
lost_record_pids = original.map(&:pid) - new.map(&:pid)
|
68
|
+
lost_record_pids.each do |pid|
|
69
|
+
new << original.find { |r| r.pid == pid }
|
70
|
+
end
|
71
|
+
new.sort_by(&:order)
|
72
|
+
end
|
73
|
+
|
74
|
+
#
|
75
|
+
#
|
76
|
+
def csv_string(records)
|
77
|
+
keys = records.flat_map(&:keys).uniq
|
78
|
+
CSV.generate do |csv|
|
79
|
+
csv << keys
|
80
|
+
records.each do |r|
|
81
|
+
csv << keys.map { |k| r.hash.fetch(k, '') }
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
#
|
87
|
+
#
|
88
|
+
def json_string(records)
|
89
|
+
hashes = records.map(&:hash)
|
90
|
+
JSON.pretty_generate hashes
|
91
|
+
end
|
92
|
+
|
93
|
+
#
|
94
|
+
#
|
95
|
+
def yaml_string(records)
|
96
|
+
hashes = records.map(&:hash)
|
97
|
+
hashes.to_yaml
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,75 @@
|
|
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
|
+
#
|
14
|
+
#
|
15
|
+
def source
|
16
|
+
@config.dig 'source'
|
17
|
+
end
|
18
|
+
|
19
|
+
#
|
20
|
+
#
|
21
|
+
def collections_dir
|
22
|
+
@config.dig 'collections_dir'
|
23
|
+
end
|
24
|
+
|
25
|
+
#
|
26
|
+
# Contructs permalink extension from site `permalink` variable
|
27
|
+
#
|
28
|
+
# @return [String] the end of the permalink, either '/' or '.html'
|
29
|
+
def ext
|
30
|
+
case @config.dig 'permalink'
|
31
|
+
when 'pretty' || '/'
|
32
|
+
'/'
|
33
|
+
else
|
34
|
+
'.html'
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
#
|
39
|
+
#
|
40
|
+
def process_collections
|
41
|
+
if @config.key? 'collections'
|
42
|
+
@config['collections'].map do |k, v|
|
43
|
+
WaxTasks::Collection.new(k, v, source, collections_dir, ext)
|
44
|
+
end
|
45
|
+
else
|
46
|
+
[]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
#
|
51
|
+
#
|
52
|
+
def search(name)
|
53
|
+
search_config = @config.dig 'search', name
|
54
|
+
raise WaxTasks::Error::InvalidConfig if search_config.nil?
|
55
|
+
raise WaxTasks::Error::InvalidConfig unless search_config.dig('collections').is_a? Hash
|
56
|
+
|
57
|
+
search_config['collections'] = search_config['collections'].map do |k, v|
|
58
|
+
fields = v.fetch('fields', [])
|
59
|
+
fields << 'content' if v.fetch('content', false)
|
60
|
+
find_collection(k).tap { |c| c.search_fields = fields }
|
61
|
+
end
|
62
|
+
|
63
|
+
search_config
|
64
|
+
end
|
65
|
+
|
66
|
+
#
|
67
|
+
#
|
68
|
+
def find_collection(name)
|
69
|
+
collection = @collections.find { |c| c.name == name }
|
70
|
+
raise WaxTasks::Error::InvalidCollection, "Cannot find requested collection '#{name}'" if collection.nil?
|
71
|
+
|
72
|
+
collection
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
data/lib/wax_tasks/error.rb
CHANGED
@@ -1,10 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module WaxTasks
|
2
4
|
# Custom WaxTasks Errors module
|
3
5
|
module Error
|
4
6
|
# Custom WaxTasks Error class with magenta console output
|
5
7
|
class WaxTasksError < StandardError
|
6
8
|
def initialize(msg = '')
|
7
|
-
super(msg.magenta)
|
9
|
+
super(Rainbow(msg).magenta)
|
8
10
|
end
|
9
11
|
end
|
10
12
|
|
@@ -13,8 +15,8 @@ module WaxTasks
|
|
13
15
|
class MissingArguments < WaxTasksError; end
|
14
16
|
|
15
17
|
# Custom Error:
|
16
|
-
# Site config cannot be found / parsed
|
17
|
-
class
|
18
|
+
# Site config cannot be found / parsed for the task at hand
|
19
|
+
class InvalidConfig < WaxTasksError; end
|
18
20
|
|
19
21
|
# Custom Error:
|
20
22
|
# Collection specified cannot be found / parsed in site config
|
@@ -22,58 +24,42 @@ module WaxTasks
|
|
22
24
|
|
23
25
|
# Custom Error:
|
24
26
|
# Collection data source type is not allowed or is an invalid file
|
25
|
-
class InvalidSource
|
27
|
+
class InvalidSource < WaxTasksError; end
|
26
28
|
|
27
29
|
# Custom Error:
|
28
30
|
# Data source file could not be found
|
29
|
-
class MissingSource
|
30
|
-
|
31
|
-
# Custom Error:
|
32
|
-
# While loading markdown pages to index, one could not be read
|
33
|
-
class LunrPageLoad < WaxTasksError; end
|
34
|
-
|
35
|
-
# Custom Error:
|
36
|
-
# Lunr collection does not have fields specified to index
|
37
|
-
class MissingFields < WaxTasksError; end
|
31
|
+
class MissingSource < WaxTasksError; end
|
38
32
|
|
39
33
|
# Custom Error:
|
40
|
-
#
|
41
|
-
class
|
34
|
+
# Could not load collection page(s)
|
35
|
+
class PageLoad < WaxTasksError; end
|
42
36
|
|
43
37
|
# Custom Error:
|
44
38
|
# Collection item does not have a required pid value
|
45
|
-
class MissingPid
|
39
|
+
class MissingPid < WaxTasksError; end
|
46
40
|
|
47
41
|
# Custom Error:
|
48
42
|
# Collection item has a non-unique pud value
|
49
|
-
class NonUniquePid
|
43
|
+
class NonUniquePid < WaxTasksError; end
|
50
44
|
|
51
45
|
# Custom Error:
|
52
46
|
# Collection page item could not be generated
|
53
|
-
class PageFailure
|
47
|
+
class PageFailure < WaxTasksError; end
|
54
48
|
|
55
49
|
# Custom Error:
|
56
50
|
# CSV file failed to lint + could not be loaded
|
57
|
-
class InvalidCSV
|
51
|
+
class InvalidCSV < WaxTasksError; end
|
58
52
|
|
59
53
|
# Custom Error:
|
60
54
|
# JSON file failed to lint + could not be loaded
|
61
|
-
class InvalidJSON
|
55
|
+
class InvalidJSON < WaxTasksError; end
|
62
56
|
|
63
57
|
# Custom Error:
|
64
58
|
# YAML file failed to lint + could not be loaded
|
65
|
-
class InvalidYAML
|
66
|
-
|
67
|
-
# Custom Error:
|
68
|
-
# No collections in site config have lunr_index parameters
|
69
|
-
class NoLunrCollections < WaxTasksError; end
|
70
|
-
|
71
|
-
# Custom Error:
|
72
|
-
# Cannot find _site directory to push to GitHub
|
73
|
-
class MissingSite < WaxTasksError; end
|
59
|
+
class InvalidYAML < WaxTasksError; end
|
74
60
|
|
75
61
|
# Custom Error:
|
76
|
-
#
|
77
|
-
class
|
62
|
+
# Search index in site config has no valid collections to index
|
63
|
+
class NoSearchCollections < WaxTasksError; end
|
78
64
|
end
|
79
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.pwd, 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]
|
24
|
+
end
|
25
|
+
|
26
|
+
#
|
27
|
+
#
|
28
|
+
def type
|
29
|
+
Dir.exist?(@path) ? 'dir' : File.extname(@path)
|
30
|
+
end
|
31
|
+
|
32
|
+
#
|
33
|
+
#
|
34
|
+
def valid?
|
35
|
+
accepted_image_formats.include?(@type) || @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(',')}}")
|
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,65 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module WaxTasks
|
4
|
+
#
|
5
|
+
class Record
|
6
|
+
attr_reader :pid, :hash, :order
|
7
|
+
|
8
|
+
def initialize(hash)
|
9
|
+
@hash = hash
|
10
|
+
@pid = @hash.dig 'pid'
|
11
|
+
@order = @hash.dig 'order'
|
12
|
+
end
|
13
|
+
|
14
|
+
#
|
15
|
+
#
|
16
|
+
def lunr_normalize_values
|
17
|
+
@hash.transform_values { |v| Utils.lunr_normalize v }
|
18
|
+
end
|
19
|
+
|
20
|
+
#
|
21
|
+
#
|
22
|
+
def keys
|
23
|
+
@hash.keys
|
24
|
+
end
|
25
|
+
|
26
|
+
#
|
27
|
+
#
|
28
|
+
def set(key, value)
|
29
|
+
@hash[key] = value
|
30
|
+
end
|
31
|
+
|
32
|
+
#
|
33
|
+
#
|
34
|
+
def permalink?
|
35
|
+
@hash.key? 'permalink'
|
36
|
+
end
|
37
|
+
|
38
|
+
#
|
39
|
+
#
|
40
|
+
def order?
|
41
|
+
@order.is_a? String
|
42
|
+
end
|
43
|
+
|
44
|
+
#
|
45
|
+
#
|
46
|
+
def keep_only(fields)
|
47
|
+
@hash.select! { |k, _v| fields.include? k }
|
48
|
+
end
|
49
|
+
|
50
|
+
#
|
51
|
+
#
|
52
|
+
def write_to_page(dir)
|
53
|
+
raise Error::MissingPid if @pid.nil?
|
54
|
+
|
55
|
+
path = "#{dir}/#{Utils.slug(@pid)}.md"
|
56
|
+
if File.exist? path
|
57
|
+
0
|
58
|
+
else
|
59
|
+
FileUtils.mkdir_p File.dirname(path)
|
60
|
+
File.open(path, 'w') { |f| f.puts "#{@hash.to_yaml}---" }
|
61
|
+
1
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|