wax_tasks 0.3.2 → 1.1.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.

Potentially problematic release.


This version of wax_tasks might be problematic. Click here for more details.

@@ -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
@@ -1,16 +1,22 @@
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
 
11
13
  # Custom Error:
12
- # Site config cannot be found / parsed
13
- class InvalidSiteConfig < WaxTasksError; end
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
14
20
 
15
21
  # Custom Error:
16
22
  # Collection specified cannot be found / parsed in site config
@@ -18,54 +24,42 @@ module WaxTasks
18
24
 
19
25
  # Custom Error:
20
26
  # Collection data source type is not allowed or is an invalid file
21
- class InvalidSource < WaxTasksError; end
27
+ class InvalidSource < WaxTasksError; end
22
28
 
23
29
  # Custom Error:
24
30
  # Data source file could not be found
25
- class MissingSource < WaxTasksError; end
26
-
27
- # Custom Error:
28
- # While loading markdown pages to index, one could not be read
29
- class LunrPageLoad < WaxTasksError; end
31
+ class MissingSource < WaxTasksError; end
30
32
 
31
33
  # Custom Error:
32
- # Lunr collection does not have fields specified to index
33
- class MissingFields < WaxTasksError; end
34
-
35
- # Custom Error:
36
- # Page layout was not specified for a pagemaster collection
37
- class MissingLayout < WaxTasksError; end
34
+ # Could not load collection page(s)
35
+ class PageLoad < WaxTasksError; end
38
36
 
39
37
  # Custom Error:
40
38
  # Collection item does not have a required pid value
41
- class MissingPid < WaxTasksError; end
39
+ class MissingPid < WaxTasksError; end
42
40
 
43
41
  # Custom Error:
44
42
  # Collection item has a non-unique pud value
45
- class NonUniquePid < WaxTasksError; end
43
+ class NonUniquePid < WaxTasksError; end
46
44
 
47
45
  # Custom Error:
48
46
  # Collection page item could not be generated
49
- class PageFailure < WaxTasksError; end
47
+ class PageFailure < WaxTasksError; end
50
48
 
51
49
  # Custom Error:
52
50
  # CSV file failed to lint + could not be loaded
53
- class InvalidCSV < WaxTasksError; end
51
+ class InvalidCSV < WaxTasksError; end
54
52
 
55
53
  # Custom Error:
56
54
  # JSON file failed to lint + could not be loaded
57
- class InvalidJSON < WaxTasksError; end
55
+ class InvalidJSON < WaxTasksError; end
58
56
 
59
57
  # Custom Error:
60
58
  # YAML file failed to lint + could not be loaded
61
- class InvalidYAML < WaxTasksError; end
62
-
63
- # Custom Error:
64
- # No collections in site config have lunr_index parameters
65
- class NoLunrCollections < WaxTasksError; end
59
+ class InvalidYAML < WaxTasksError; end
66
60
 
67
61
  # Custom Error:
68
- # Cannot find _site directory to push to GitHub
69
- class MissingSite < WaxTasksError; end
62
+ # Search index in site config has no valid collections to index
63
+ class NoSearchCollections < WaxTasksError; end
70
64
  end
71
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) || @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,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