wax_tasks 1.0.0.pre.beta → 1.1.2
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/.gitignore +7 -0
- data/.rspec +3 -0
- data/.rubocop.yml +16 -0
- data/.travis.yml +27 -0
- data/CHANGELOG.md +42 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +5 -2
- data/LICENSE +21 -0
- data/README.md +171 -0
- data/lib/tasks/clobber.rake +16 -0
- data/lib/tasks/derivatives_iiif.rake +9 -4
- data/lib/tasks/derivatives_simple.rake +8 -4
- data/lib/tasks/pages.rake +23 -0
- data/lib/tasks/search.rake +23 -0
- data/lib/wax_tasks.rb +30 -36
- data/lib/wax_tasks/asset.rb +57 -0
- data/lib/wax_tasks/collection.rb +42 -73
- 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 +17 -31
- data/lib/wax_tasks/index.rb +45 -0
- data/lib/wax_tasks/item.rb +116 -0
- data/lib/wax_tasks/record.rb +69 -0
- data/lib/wax_tasks/site.rb +86 -0
- data/lib/wax_tasks/utils.rb +58 -107
- data/lib/wax_tasks/version.rb +5 -0
- data/spec/setup.rb +1 -1
- data/spec/spec_helper.rb +14 -9
- data/wax_tasks.gemspec +33 -0
- metadata +52 -44
- 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,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
|
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, @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,69 @@
|
|
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
|
+
# PATCH :: rename 'fullwidth' to 'full' to
|
27
|
+
# (1) avoid breaking wax_iiif with special 'full' variant label
|
28
|
+
# (2) avoid breaking wax_theme which still expects 'full' to provide an image path
|
29
|
+
# this can be deprecated when a new version of wax_theme looks for another fullsize key
|
30
|
+
#
|
31
|
+
def set(key, value)
|
32
|
+
key = 'full' if key == 'fullwidth'
|
33
|
+
@hash[key] = value
|
34
|
+
end
|
35
|
+
|
36
|
+
#
|
37
|
+
#
|
38
|
+
def permalink?
|
39
|
+
@hash.key? 'permalink'
|
40
|
+
end
|
41
|
+
|
42
|
+
#
|
43
|
+
#
|
44
|
+
def order?
|
45
|
+
@order.is_a? String
|
46
|
+
end
|
47
|
+
|
48
|
+
#
|
49
|
+
#
|
50
|
+
def keep_only(fields)
|
51
|
+
@hash.select! { |k, _v| fields.include? k }
|
52
|
+
end
|
53
|
+
|
54
|
+
#
|
55
|
+
#
|
56
|
+
def write_to_page(dir)
|
57
|
+
raise Error::MissingPid if @pid.nil?
|
58
|
+
|
59
|
+
path = "#{dir}/#{Utils.slug(@pid)}.md"
|
60
|
+
if File.exist? path
|
61
|
+
0
|
62
|
+
else
|
63
|
+
FileUtils.mkdir_p File.dirname(path)
|
64
|
+
File.open(path, 'w') { |f| f.puts "#{@hash.to_yaml}---" }
|
65
|
+
1
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|