Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
galaxyproject
GitHub Repository: galaxyproject/training-material
Path: blob/main/_plugins/gtn/shortlinks.rb
1677 views
1
# frozen_string_literal: true
2
3
module Gtn
4
# This module is responsible for generating shortlinks for tutorials and FAQs and any other pages we add.
5
#
6
# Every category gets its own prefix letter.
7
module Shortlinks
8
CATEGORY_TUTORIAL = 'T'
9
CATEGORY_SLIDES = 'S'
10
CATEGORY_FAQ = 'F'
11
CATEGORY_NEWS = 'N'
12
CATEGORY_PATHWAYS = 'P'
13
CATEGORY_EVENTS = 'E'
14
CATEGORY_WORKFLOW = 'W'
15
16
REDIRECT_TEMPLATE = <<~REDIR
17
<!DOCTYPE html>
18
<html lang="en-US">
19
<meta charset="utf-8">
20
<title>Redirecting&hellip;</title>
21
<link rel="canonical" href="REDIRECT_URL">
22
<script>location="REDIRECT_URL"</script>
23
<meta http-equiv="refresh" content="0; url=REDIRECT_URL">
24
<meta name="robots" content="noindex">
25
<h1>Redirecting&hellip;</h1>
26
<a href="REDIRECT_URL">Click here if you are not redirected.</a>
27
</html>
28
REDIR
29
30
def self.mapped?(tutorial, current_mapping)
31
current_mapping['id'].values.include? tutorial
32
end
33
34
##
35
# Duplicate of the jekyll-redirect-from plugin template.
36
# We can't use that for, reasons.
37
def self.html_redirect(target)
38
REDIRECT_TEMPLATE.gsub('REDIRECT_URL', target)
39
end
40
41
##
42
# Fix missing symlinks (usually exist because the target file has been
43
# renamed and doesn't exist anymore.) However, a redirect *will* be present
44
# for the original filename so we just fix the missing symlink.
45
#
46
# Params:
47
# +site+:: The Jekyll site object
48
def self.fix_missing_redirs(site)
49
missing_redirs = site.data['shortlinks']['id'].select do |id, target|
50
short_link = "short/#{id}.html"
51
! File.exist?(site.in_dest_dir(short_link))
52
end
53
54
missing_redirs.each do |id, target|
55
short_link = "short/#{id}.html"
56
Jekyll.logger.warn "[GTN/Shortlink]" "Shortlink target #{target} does not exist for shortlink #{short_link}, fixing."
57
File.write(site.in_dest_dir(short_link), Gtn::Shortlinks.html_redirect(target))
58
end
59
end
60
61
def self.update(current_mapping)
62
current_mapping['id'] = {} if !current_mapping.key? 'id'
63
64
current_mapping['name'] = {} if !current_mapping.key? 'name'
65
66
# Discover tutorials
67
num_tutorials = current_mapping['id'].select { |x| x[0] == CATEGORY_TUTORIAL }.length
68
Dir.glob('topics/*/tutorials/*/tutorial.md').each do |tutorial|
69
html_path = "/#{tutorial.gsub(/md$/, 'html')}"
70
# If it's not already mapped by a key, add it.
71
if !mapped?(html_path, current_mapping)
72
# Generate a short code
73
short_code_number = num_tutorials.to_s.rjust(5, '0')
74
short_code = CATEGORY_TUTORIAL + short_code_number
75
puts "Discovered tutorial #{short_code} (#{html_path})"
76
# If the target of this flavour of short code isn't already in here, then add it
77
current_mapping['id'][short_code] = html_path
78
num_tutorials += 1
79
end
80
81
# Also generate one from topic/tutorial name
82
# These are idempotent and safe
83
short_code2 = tutorial.split('/')[1..3].join('/').gsub(%r{/tutorials}, '')
84
current_mapping['name'][short_code2] = "/#{tutorial.gsub(/md$/, 'html')}"
85
end
86
87
# Discover slides
88
num_slides = current_mapping['id'].select { |x| x[0] == CATEGORY_SLIDES }.length
89
Dir.glob('topics/*/tutorials/*/slides.html').each do |tutorial|
90
html_path = "/#{tutorial}"
91
# If it's not already mapped by a key, add it.
92
if !mapped?(html_path, current_mapping)
93
# Generate a short code
94
short_code_number = num_slides.to_s.rjust(5, '0')
95
short_code = CATEGORY_SLIDES + short_code_number
96
puts "Discovered slides #{short_code}"
97
# If the target of this flavour of short code isn't already in here, then add it
98
current_mapping['id'][short_code] = html_path
99
num_slides += 1
100
end
101
102
# Also generate one from topic/tutorial name
103
# These are idempotent and safe
104
short_code2 = "#{tutorial.split('/')[1..3].join('/').gsub(%r{/tutorials}, '')}/slides"
105
current_mapping['name'][short_code2] = "/#{tutorial.gsub(/md$/, 'html')}"
106
end
107
108
# Discover FAQs
109
all_faqs = Dir.glob('faqs/**/*.md') + Dir.glob('topics/*/faqs/**/*.md') + \
110
Dir.glob('topics/*/tutorials/*/faqs/*.md')
111
# Remove symlinked files
112
all_faqs = all_faqs.reject { |x| File.symlink?(x) }
113
# Reject indexes, readme, etc.
114
all_faqs = all_faqs.grep_v(/index.md$/)
115
all_faqs = all_faqs.grep_v(/README.md$/)
116
117
num_faqs = current_mapping['id'].select { |x| x[0] == CATEGORY_FAQ }.length
118
all_faqs.each do |tutorial|
119
html_path = "/#{tutorial.gsub(/md$/, 'html')}"
120
# If it's not already mapped by a key, add it.
121
if !mapped?(html_path, current_mapping)
122
# Generate a short code
123
short_code_number = num_faqs.to_s.rjust(5, '0')
124
short_code = CATEGORY_FAQ + short_code_number
125
puts "Discovered FAQ #{short_code}"
126
# If the target of this flavour of short code isn't already in here, then add it
127
current_mapping['id'][short_code] = html_path
128
num_faqs += 1
129
end
130
end
131
132
# Discover news
133
num_news = current_mapping['id'].select { |x| x[0] == CATEGORY_NEWS }.length
134
Dir.glob('news/_posts/*.md').each do |material|
135
m = material.match(%r{news/_posts/(?<year>\d\d\d\d)-(?<month>\d\d)-(?<day>\d\d)-(?<title>.*)\.md})
136
html_path = "/news/#{m[:year]}/#{m[:month]}/#{m[:day]}/#{m[:title]}.html"
137
# If it's not already mapped by a key, add it.
138
if !mapped?(html_path, current_mapping)
139
# Generate a short code
140
short_code_number = num_news.to_s.rjust(5, '0')
141
short_code = CATEGORY_NEWS + short_code_number
142
puts "Discovered news #{short_code}"
143
# If the target of this flavour of short code isn't already in here, then add it
144
current_mapping['id'][short_code] = html_path
145
num_news += 1
146
end
147
end
148
149
# Discover learning pathways
150
lps = Dir.glob('learning-pathways/*.md')
151
lps.reject! { |t| t =~ /index.md/ }
152
lps.reject! { |t| t =~ /pathway-example.md/ }
153
154
num_lps = current_mapping['id'].select { |x| x[0] == CATEGORY_PATHWAYS }.length
155
lps.each do |tutorial|
156
html_path = "/#{tutorial.gsub(/md$/, 'html')}"
157
# If it's not already mapped by a key, add it.
158
if !mapped?(html_path, current_mapping)
159
# Generate a short code
160
short_code_number = num_lps.to_s.rjust(5, '0')
161
short_code = CATEGORY_PATHWAYS + short_code_number
162
puts "Discovered learning pathway #{short_code}"
163
# If the target of this flavour of short code isn't already in here, then add it
164
current_mapping['id'][short_code] = html_path
165
num_lps += 1
166
end
167
end
168
169
# Discover events
170
events = Dir.glob('events/*.md')
171
events.reject! { |t| t =~ /index.md/ }
172
events.reject! { |t| t =~ /pathway-example.md/ }
173
174
num_events = current_mapping['id'].select { |x| x[0] == CATEGORY_EVENTS }.length
175
events.each do |event|
176
html_path = "/#{event.gsub(/md$/, 'html')}"
177
# If it's not already mapped by a key, add it.
178
if !mapped?(html_path, current_mapping)
179
# Generate a short code
180
short_code_number = num_events.to_s.rjust(5, '0')
181
short_code = CATEGORY_EVENTS + short_code_number
182
puts "Discovered event #{short_code}"
183
# If the target of this flavour of short code isn't already in here, then add it
184
current_mapping['id'][short_code] = html_path
185
num_events += 1
186
end
187
end
188
189
# Discover workflows
190
workflows = Dir.glob('topics/**/workflows/*.ga')
191
192
num_workflows = current_mapping['id'].select { |x| x[0] == CATEGORY_WORKFLOW }.length
193
workflows.each do |workflow|
194
html_path = "/#{workflow.gsub(/ga$/, 'html')}"
195
# If it's not already mapped by a key, add it.
196
if !mapped?(html_path, current_mapping)
197
# Generate a short code
198
short_code_number = num_workflows.to_s.rjust(5, '0')
199
short_code = CATEGORY_WORKFLOW + short_code_number
200
puts "Discovered workflow #{short_code}"
201
# If the target of this flavour of short code isn't already in here, then add it
202
current_mapping['id'][short_code] = html_path
203
num_workflows += 1
204
end
205
end
206
207
current_mapping
208
end
209
end
210
end
211
212
if $PROGRAM_NAME == __FILE__
213
require 'yaml'
214
current_mapping = YAML.load_file('metadata/shortlinks.yaml')
215
Gtn::Shortlinks.update(current_mapping)
216
File.write('metadata/shortlinks.yaml', current_mapping.to_yaml)
217
end
218
219