wax_tasks 0.3.2 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,11 +0,0 @@
1
- require 'wax_tasks'
2
-
3
- namespace :wax do
4
- desc 'generate iiif derivatives from local image files'
5
- task :iiif do
6
- ARGS = ARGV.drop(1).each { |a| task a.to_sym }
7
- abort "You must specify a collection after 'wax:iiif'" if ARGS.empty?
8
- task_runner = WaxTasks::TaskRunner.new
9
- task_runner.iiif(ARGS)
10
- end
11
- end
@@ -1,14 +0,0 @@
1
- require 'wax_tasks'
2
-
3
- namespace :wax do
4
- desc 'write a simple package.json for monitoring js dependencies'
5
- task :jspackage do
6
- task_runner = WaxTasks::TaskRunner.new
7
- package = task_runner.js_package
8
- unless package.empty?
9
- path = WaxTasks::Utils.make_path(task_runner.site[:source_dir],
10
- 'package.json')
11
- File.open(path, 'w') { |f| f.write(package.to_json) }
12
- end
13
- end
14
- end
@@ -1,9 +0,0 @@
1
- require 'wax_tasks'
2
-
3
- namespace :wax do
4
- desc 'build lunr search index (with default UI if UI=true)'
5
- task :lunr do
6
- task_runner = WaxTasks::TaskRunner.new
7
- task_runner.lunr(generate_ui: !!ENV['UI'])
8
- end
9
- end
@@ -1,11 +0,0 @@
1
- require 'wax_tasks'
2
-
3
- namespace :wax do
4
- desc 'generate collection md pages from yaml or csv data source'
5
- task :pagemaster do
6
- ARGS = ARGV.drop(1).each { |a| task a.to_sym }
7
- raise 'You must specify a collection after wax:pagemaster' if ARGS.empty?
8
- task_runner = WaxTasks::TaskRunner.new
9
- task_runner.pagemaster(ARGS)
10
- end
11
- end
@@ -1,12 +0,0 @@
1
- require 'wax_tasks'
2
-
3
- namespace :wax do
4
- desc 'push compiled Jekyll site to git branch BRANCH'
5
- task :push do
6
- ARGS = ARGV.drop(1).each { |a| task a.to_sym }
7
- raise 'You must specify a branch after \'wax:push:branch\'' if ARGS.empty?
8
-
9
- task_runner = WaxTasks::TaskRunner.new
10
- task_runner.push_branch(ARGS.first)
11
- end
12
- end
@@ -1,18 +0,0 @@
1
- require 'html-proofer'
2
-
3
- namespace :wax do
4
- desc 'run htmlproofer, rspec if .rspec file exists'
5
- task :test do
6
- opts = {
7
- check_external_hash: true,
8
- allow_hash_href: true,
9
- check_html: true,
10
- disable_external: true,
11
- empty_alt_ignore: true,
12
- only_4xx: true,
13
- verbose: true
14
- }
15
- HTMLProofer.check_directory('./_site', opts).run
16
- system('bundle exec rspec') if File.exist?('.rspec')
17
- end
18
- end
@@ -1,67 +0,0 @@
1
- require 'jekyll'
2
- require 'logger'
3
- require 'tmpdir'
4
-
5
- module WaxTasks
6
- # Parent class representing a Git Branch
7
- # that cannot be created directly. Only child classes
8
- # (LocalBranch, TravisBranch) can be initialized.
9
- #
10
- # @attr target [String] the name of the Git branch to deploy to
11
- # @attr origin [String] the current repository remote
12
- # @attr commit_msg [String] the commit message to use on push
13
- # @attr baseurl [String] the site baseurl to build with (if on gh-pages)
14
- # @attr success_msg [String] informative message to be output to console
15
- class Branch
16
- attr_reader :target, :origin, :commit_msg, :baseurl, :success
17
- private_class_method :new
18
-
19
- # This method ensures child classes can be instantiated eventhough
20
- # Branch.new cannot be.
21
- def self.inherited(*)
22
- public_class_method :new
23
- end
24
-
25
- # @param site [Hash] the site config from (TaskRunner.site)
26
- # @param target [String] the name of the Git branch to deploy to
27
- def initialize(site, target)
28
- @site = site
29
- @target = target
30
- end
31
-
32
- # Rebuild the Jekyll site with branch @baseurl
33
- # @return [Nil]
34
- def rebuild
35
- if @baseurl.empty?
36
- msg = 'Building the gh-pages _site without a baseurl is not recommended'
37
- Logger.new($stdout).warn(msg.orange)
38
- end
39
- FileUtils.rm_r(SITE_DIR) if File.directory?(WaxTasks::SITE_DIR)
40
- opts = {
41
- source: @site[:source_dir] || '.',
42
- destination: WaxTasks::SITE_DIR,
43
- config: WaxTasks::DEFAULT_CONFIG,
44
- baseurl: @baseurl,
45
- verbose: true
46
- }
47
- Jekyll::Site.new(Jekyll.configuration(opts)).process
48
- end
49
-
50
- # Add, commmit, and push compiled Jekyll site to @target branch
51
- # @return [Nil]
52
- def push
53
- if @site[:env] == 'prod'
54
- rebuild if @target == 'gh-pages'
55
- raise Error::MissingSite, "Cannot find #{WaxTasks::SITE_DIR}" unless Dir.exist? WaxTasks::SITE_DIR
56
- Dir.chdir(SITE_DIR)
57
- system 'git init && git add .'
58
- system "git commit -m '#{@commit_msg}'"
59
- system "git remote add origin #{@origin}"
60
- puts @success_msg.cyan
61
- system "git push origin master:refs/heads/#{@target} --force"
62
- else
63
- puts "Skipping build for branch '#{@target}' on env='test'".orange
64
- end
65
- end
66
- end
67
- end
@@ -1,105 +0,0 @@
1
- require 'wax_iiif'
2
-
3
- module WaxTasks
4
- # A Jekyll collection with IIIF configuration + data
5
- #
6
- # @attr src_data [String] the path to the data source file
7
- # @attr iiif_config [Hash] the iiif configuration for the collection
8
- # @attr meta [Array] metadata k,v rules
9
- # @attr variants [Hash] image variants to generate e.g. { med: 650 }
10
- # @attr src_dir [String] path to existing iiif source images
11
- # @attr target_dir [String] target path for iiif derivatives
12
- class IiifCollection < Collection
13
- attr_reader :variants, :meta, :target_dir
14
-
15
- # Creates a new IiifCollection with name @name given site config @site
16
- def initialize(name, site)
17
- super(name, site)
18
-
19
- @src_data = @config.fetch('source', nil)
20
- @iiif_config = @config.fetch('iiif', {})
21
- @meta = @iiif_config.fetch('meta', nil)
22
- @variants = validated_variants
23
- @src_dir = Utils.make_path(@site[:source_dir],
24
- '_data/iiif',
25
- @name)
26
- @target_dir = Utils.make_path(@site[:source_dir],
27
- 'iiif',
28
- @name)
29
- end
30
-
31
- # Main method for generating iiif derivatives and json
32
- # @return [Nil]
33
- def process
34
- raise Error::MissingIiifSrc, "Cannot find IIIF source directory #{@src_dir}" unless Dir.exist?(@src_dir)
35
- FileUtils.mkdir_p(@target_dir, verbose: false)
36
- builder = iiif_builder
37
- builder.load(iiif_records)
38
- builder.process_data(true)
39
- end
40
-
41
- # Creates a IiifS3::Builder object from collection config
42
- # @return [Object]
43
- def iiif_builder
44
- build_opts = {
45
- base_url: "#{@site[:baseurl]}/iiif/#{@name}",
46
- output_dir: @target_dir,
47
- verbose: true,
48
- variants: @variants
49
- }
50
- IiifS3::Builder.new(build_opts)
51
- end
52
-
53
- # Gets custom image variants from collection config if available
54
- # Else returns default variants { med: 600, lg: 1140 } to Builder
55
- #
56
- # @return [Hash]
57
- def validated_variants
58
- vars = @iiif_config.fetch('variants', false)
59
- if vars.is_a?(Array) && vars.all? { |v| v.is_a?(Integer) }
60
- variants = {}
61
- vars.each_with_index do |v, i|
62
- variants["custom_variant_#{i}".to_sym] = v
63
- end
64
- else
65
- variants = { med: 600, lg: 1140 }
66
- end
67
- variants
68
- end
69
-
70
- # Creates an array of IIIfS3 ImageRecords from the collection config
71
- # for the IiifS3 Builder to process
72
- #
73
- # @return [Array]
74
- def iiif_records
75
- records = []
76
- source_images = Dir["#{@src_dir}/*"].sort!
77
- if @meta && @src_data
78
- src_path = Utils.make_path(@site[:source_dir], '_data', @src_data)
79
- metadata = ingest_file(src_path)
80
- else
81
- metadata = false
82
- end
83
- source_images.each { |src_img| records << iiif_record(src_img, metadata) }
84
- records
85
- end
86
-
87
- # Creates an individual IiifS3 ImageRecord
88
- # with metadata from source data file if available
89
- #
90
- # @param src_img [String] path to the original source image
91
- # @param metadata [Hash] metadata to add to the item if available
92
- # @return [Object]
93
- def iiif_record(src_img, metadata)
94
- basename = File.basename(src_img, '.*').to_s
95
- record_opts = { id: basename, path: src_img, label: basename }
96
- if metadata
97
- src_item = metadata.find { |i| i['pid'].to_s == basename }
98
- @meta.each do |i|
99
- record_opts[i.first[0].to_sym] = src_item.fetch(i.first[1], '')
100
- end
101
- end
102
- IiifS3::ImageRecord.new(record_opts)
103
- end
104
- end
105
- end
@@ -1,21 +0,0 @@
1
- require 'time'
2
-
3
- module WaxTasks
4
- # Branch object for `$ wax:push` task when run on local machine
5
- # using local credentials
6
- #
7
- # @attr origin [String] the current repository remote
8
- # @attr commit_msg [String] the commit message to use on push
9
- # @attr baseurl [String] the site baseurl to build with (if on gh-pages)
10
- # @attr success_msg [String] informative message to be output to console
11
- class LocalBranch < Branch
12
- def initialize(site, target)
13
- super(site, target)
14
-
15
- @origin = `git config --get remote.origin.url`.strip
16
- @commit_msg = "Updated via local task at #{Time.now.utc}"
17
- @baseurl = "/#{@origin.split('/').last.gsub('.git', '')}"
18
- @success_msg = "Deploying to #{@target} branch from local task."
19
- end
20
- end
21
- end
@@ -1,62 +0,0 @@
1
- module WaxTasks
2
- # A Jekyll collection to be Indexed in a Lunr Index / JSON file
3
- # for client-side search.
4
- #
5
- # @attr index_config [Hash] the collection's lunr_index config
6
- # @attr content [Boolean] whether/not page content should be indexed
7
- # @attr fields [Array] the fields (i.e., keys) that should be indexed
8
- # @attr data [Array] hash array of data from the ingested pages
9
- class LunrCollection < Collection
10
- attr_accessor :fields, :data
11
-
12
- # Creates a new LunrCollection with name @name given site config @site
13
- def initialize(name, site)
14
- super(name, site)
15
-
16
- @index_config = @config['lunr_index']
17
- @content = @index_config.fetch('content', false)
18
- @fields = @index_config.fetch('fields', [])
19
- @data = ingest_pages
20
-
21
- raise Error::MissingFields, "There are no fields for #{@name}.".magenta if @fields.empty?
22
- end
23
-
24
- # Finds the @page_dir of markdown pages for the collection and ingests
25
- # them as an array of hashes
26
- #
27
- # @return [Array] array of the loaded markdown pages loaded as hashes
28
- def ingest_pages
29
- data = []
30
- pages = Dir.glob("#{@page_dir}/*.md")
31
- puts "There are no pages in #{@page_dir} to index.".cyan if pages.empty?
32
- pages.each do |p|
33
- begin
34
- data << load_page(p)
35
- rescue StandardError => e
36
- raise Error::LunrPageLoad, "Cannot load page #{p}\n#{e}"
37
- end
38
- end
39
- data
40
- end
41
-
42
- # Reads in a markdown file and converts it to a hash
43
- # with the values from @fields.
44
- # Adds the content of the file (below the YAML) if @content == true
45
- #
46
- # @param page [String] the path to a markdown page to load
47
- def load_page(page)
48
- yaml = YAML.load_file(page)
49
- hash = {
50
- 'link' => "{{'#{yaml.fetch('permalink')}' | relative_url }}",
51
- 'collection' => @name
52
- }
53
- if @content
54
- content = WaxTasks::Utils.html_strip(File.read(page))
55
- hash['content'] = WaxTasks::Utils.remove_diacritics(content)
56
- end
57
- fields = @fields.push('pid').uniq
58
- fields.each { |f| hash[f] = yaml[f].lunr_normalize }
59
- hash
60
- end
61
- end
62
- end
@@ -1,67 +0,0 @@
1
- module WaxTasks
2
- # A LunrIndex document that combines data from all collections
3
- # in site config that have `lunr_index` parameters.
4
- #
5
- # @attr collections [Array] a list of LunrCollection objects
6
- # @attr fields [Array] shared list of fields to index among LunrCollections
7
- class LunrIndex
8
- attr_accessor :collections, :fields
9
-
10
- # Creates a new LunrIndex object
11
- def initialize(collections)
12
- @collections = collections
13
- @fields = total_fields
14
- end
15
-
16
- # @return [Array] shared list of fields to index among LunrCollections
17
- def total_fields
18
- total_fields = @collections.map(&:fields).reduce([], :concat)
19
- total_fields.uniq
20
- end
21
-
22
- # @return [String] writes index data as pretty JSON with YAML front-matter
23
- def to_s
24
- data = @collections.map(&:data).flatten
25
- data.each_with_index.map { |d, id| d['lunr_index'] = id }
26
- "---\nlayout: none\n---\n#{JSON.pretty_generate(data)}"
27
- end
28
-
29
- # Creates a default LunrUI / JS file for displaying the Index
30
- #
31
- # @return [String]
32
- def default_ui
33
- <<~HEREDOC
34
- ---
35
- layout: none
36
- ---
37
- $.getJSON({{ site.baseurl }}/js/lunr-index.json, function(index_json) {
38
- window.index = new elasticlunr.Index;
39
- window.store = index_json;
40
- index.saveDocument(false);
41
- index.setRef('lunr_id');
42
- #{@fields.map { |f| "index.addField('#{f}');" }.join("\n")}
43
- // add docs
44
- for (i in store){
45
- index.addDoc(store[i]);
46
- }
47
- $('input#search').on('keyup', function() {
48
- var results_div = $('#results');
49
- var query = $(this).val();
50
- var results = index.search(query, { boolean: 'AND', expand: true });
51
- results_div.empty();
52
- if (results.length > 10) {
53
- results_div.prepend("<p><small>Displaying 10 of " + results.length + " results.</small></p>");
54
- }
55
- for (var r in results.slice(0, 9)) {
56
- var ref = results[r].ref;
57
- var item = store[ref];
58
- #{@fields.map { |f| "var #{f} = item.#{f};" }.join("\n")}
59
- var result = '<div class="result"><b><a href="' + item.link + '">' + title + '</a></b></p></div>';
60
- results_div.append(result);
61
- }
62
- });
63
- });
64
- HEREDOC
65
- end
66
- end
67
- end
@@ -1,67 +0,0 @@
1
- module WaxTasks
2
- # A Jekyll collection with a data source file that
3
- # can generate markdown pages from that data.
4
- #
5
- # @attr source [String] the path to the data source file
6
- # @attr layout [String] the Jekyll layout to be used by the generated pages
7
- # @attr data [Array] array of hashes representing the ingested data file
8
- # @attr ordered [Boolean] whether/not the order of items should be preserved
9
- class PagemasterCollection < Collection
10
- attr_reader :source, :layout, :data, :ordered
11
-
12
- # Creates a new PagemasterCollection with name @name given site config @site
13
- def initialize(name, site)
14
- super(name, site)
15
-
16
- @source = source_path
17
- @layout = assert_layout
18
- @data = ingest_file(@source)
19
- @ordered = @config.fetch('keep_order', false)
20
- end
21
-
22
- # Constructs the path to the data source file
23
- #
24
- # @return [String] the path to the data source file
25
- def source_path
26
- raise WaxTasks::Error::MissingSource, "Missing collection source in _config.yml for #{@name}" unless @config.key? 'source'
27
- WaxTasks::Utils.make_path(@site[:source_dir], '_data', @config['source'])
28
- end
29
-
30
- # Confirms + requires `layout` value in the collection @config
31
- #
32
- # @return [String] the Jekyll layout to be used by the generated pages
33
- def assert_layout
34
- raise WaxTasks::Error::MissingLayout, "Missing collection layout in _config.yml for #{@name}" unless @config.key? 'layout'
35
- @config['layout']
36
- end
37
-
38
- # Writes markdown pages from the ingested data to @page_dir
39
- # with layout, permalink, and order info added (if applicable)
40
- #
41
- # @return [Array] a copy of the pages as hashes, for testing
42
- def generate_pages
43
- FileUtils.mkdir_p(@page_dir)
44
- pages = []
45
- @data.each_with_index do |item, idx|
46
- page_slug = Utils.slug(item.fetch('pid'))
47
- path = "#{@page_dir}/#{page_slug}.md"
48
- item['permalink'] = "/#{@name}/#{page_slug}#{@site[:permalink]}"
49
- item['layout'] = @layout
50
- item['order'] = padded_int(idx, @data.length) if @ordered
51
- pages << item
52
- next "#{page_slug}.md already exits. Skipping." if File.exist?(path)
53
- File.open(path, 'w') { |f| f.write("#{item.to_yaml}---") }
54
- end
55
- puts "#{@data.length} pages were generated to #{@page_dir} directory.".cyan
56
- pages
57
- end
58
-
59
- # Constructs the order variable for each page (if the collection
60
- # needs to preserve the order of items from the file)
61
- #
62
- # @return [Integer] the order if the item padded with '0's for sorting
63
- def padded_int(idx, max_idx)
64
- idx.to_s.rjust(Math.log10(max_idx).to_i + 1, '0')
65
- end
66
- end
67
- end