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.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/.github/ISSUE_TEMPLATE/bug_report.md +35 -0
  3. data/.github/ISSUE_TEMPLATE/feature_request.md +17 -0
  4. data/.gitignore +7 -0
  5. data/.rspec +3 -0
  6. data/.rubocop.yml +16 -0
  7. data/.travis.yml +27 -0
  8. data/CHANGELOG.md +42 -0
  9. data/CODE_OF_CONDUCT.md +74 -0
  10. data/Gemfile +5 -2
  11. data/LICENSE +21 -0
  12. data/README.md +171 -0
  13. data/lib/tasks/clobber.rake +16 -0
  14. data/lib/tasks/derivatives_iiif.rake +9 -4
  15. data/lib/tasks/derivatives_simple.rake +8 -4
  16. data/lib/tasks/pages.rake +23 -0
  17. data/lib/tasks/search.rake +23 -0
  18. data/lib/wax_tasks.rb +30 -36
  19. data/lib/wax_tasks/asset.rb +57 -0
  20. data/lib/wax_tasks/collection.rb +42 -73
  21. data/lib/wax_tasks/collection/images.rb +126 -0
  22. data/lib/wax_tasks/collection/metadata.rb +101 -0
  23. data/lib/wax_tasks/config.rb +79 -0
  24. data/lib/wax_tasks/error.rb +17 -31
  25. data/lib/wax_tasks/index.rb +45 -0
  26. data/lib/wax_tasks/item.rb +116 -0
  27. data/lib/wax_tasks/record.rb +69 -0
  28. data/lib/wax_tasks/site.rb +86 -0
  29. data/lib/wax_tasks/utils.rb +58 -107
  30. data/lib/wax_tasks/version.rb +5 -0
  31. data/spec/setup.rb +1 -1
  32. data/spec/spec_helper.rb +14 -9
  33. data/wax_tasks.gemspec +33 -0
  34. metadata +52 -44
  35. data/lib/tasks/jspackage.rake +0 -17
  36. data/lib/tasks/lunr.rake +0 -9
  37. data/lib/tasks/pagemaster.rake +0 -11
  38. data/lib/tasks/push.rake +0 -12
  39. data/lib/tasks/test.rake +0 -18
  40. data/lib/wax_tasks/branch.rb +0 -70
  41. data/lib/wax_tasks/iiif/derivatives.rb +0 -86
  42. data/lib/wax_tasks/iiif/manifest.rb +0 -26
  43. data/lib/wax_tasks/image_collection.rb +0 -137
  44. data/lib/wax_tasks/local_branch.rb +0 -21
  45. data/lib/wax_tasks/lunr/index.rb +0 -82
  46. data/lib/wax_tasks/lunr/page_set.rb +0 -57
  47. data/lib/wax_tasks/pagemaster_collection.rb +0 -60
  48. data/lib/wax_tasks/task_runner.rb +0 -148
  49. 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
@@ -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 InvalidSiteConfig < WaxTasksError; end
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 < WaxTasksError; end
27
+ class InvalidSource < WaxTasksError; end
26
28
 
27
29
  # Custom Error:
28
30
  # Data source file could not be found
29
- class MissingSource < WaxTasksError; end
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
- # Page layout was not specified for a pagemaster collection
41
- class MissingLayout < WaxTasksError; end
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 < WaxTasksError; end
39
+ class MissingPid < WaxTasksError; end
46
40
 
47
41
  # Custom Error:
48
42
  # Collection item has a non-unique pud value
49
- class NonUniquePid < WaxTasksError; end
43
+ class NonUniquePid < WaxTasksError; end
50
44
 
51
45
  # Custom Error:
52
46
  # Collection page item could not be generated
53
- class PageFailure < WaxTasksError; end
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 < WaxTasksError; end
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 < WaxTasksError; end
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 < WaxTasksError; end
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
- # Cannot find IIIF source image files
77
- class MissingIiifSrc < WaxTasksError; end
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