ortfodb 1.4.0 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dc6ebc43736b80ff35857853c3fb858297233420c6b8f9548aea5317d3b50364
4
- data.tar.gz: 43b6d2cdeed9aaffcc42dc57ab9281e9ebc52588d8f14ecbc49d07d78cbb16f2
3
+ metadata.gz: 1f25b4793b5193e4ad8009bd31b30932bd64e3495b0e04a81f85ef4c164e27e3
4
+ data.tar.gz: 4d91389ec40ec4840f93c4ffbf45475bad4ea3fd29660f788312bc42154b3821
5
5
  SHA512:
6
- metadata.gz: 14f12d539988d2f55750b36abebe1b0537c008a49694bff1d60bb7992209bc9a76d070925d70dd2caa076c2c89e6b0d6cfb34a9740ed6058be53e7b31241314c
7
- data.tar.gz: dae1808de2bb3601798217520edf564fe12468c92a08c42f292796891168f1dd3a9ca9514739d86aa1c2ae53720d1ab4b9901c4e740396b13ec78d5db29fc315
6
+ metadata.gz: 8d9025810554c0cbd45ada3bd97ed5559631fda3d19b0ca81efc4992e4f9006c3293362a6bb82c4c999baeb051238713c66041c77539babbc36c15bb86015a80
7
+ data.tar.gz: ea901b1e430836c366997b2729f003a3d463cae5535b671bdeab0b056a61e8bff8a8342c905b8aecdaafac515c63836da693f7be107326e2f15063287fb7bab3
@@ -4,7 +4,7 @@
4
4
  # To parse this JSON, add 'dry-struct' and 'dry-types' gems, then do:
5
5
  #
6
6
  # configuration = Configuration.from_json! "{…}"
7
- # puts configuration.technologies.repository
7
+ # puts configuration.technologies&.repository
8
8
  #
9
9
  # If from_json! succeeds, the value returned matches the schema.
10
10
 
@@ -22,7 +22,7 @@ module Ortfodb
22
22
  String = Strict::String
23
23
  end
24
24
 
25
- class ExtractColors < Dry::Struct
25
+ class ExtractColorsConfiguration < Dry::Struct
26
26
  attribute :default_files, Types.Array(Types::String)
27
27
  attribute :enabled, Types::Bool
28
28
  attribute :extract, Types.Array(Types::String)
@@ -53,7 +53,7 @@ module Ortfodb
53
53
  end
54
54
  end
55
55
 
56
- class MakeGifs < Dry::Struct
56
+ class MakeGIFSConfiguration < Dry::Struct
57
57
  attribute :enabled, Types::Bool
58
58
  attribute :file_name_template, Types::String
59
59
 
@@ -81,7 +81,7 @@ module Ortfodb
81
81
  end
82
82
  end
83
83
 
84
- class MakeThumbnails < Dry::Struct
84
+ class MakeThumbnailsConfiguration < Dry::Struct
85
85
  attribute :enabled, Types::Bool
86
86
  attribute :file_name_template, Types::String
87
87
  attribute :input_file, Types::String
@@ -115,7 +115,9 @@ module Ortfodb
115
115
  end
116
116
  end
117
117
 
118
- class Media < Dry::Struct
118
+ class MediaConfiguration < Dry::Struct
119
+
120
+ # Path to the media directory.
119
121
  attribute :at, Types::String
120
122
 
121
123
  def self.from_dynamic!(d)
@@ -140,7 +142,9 @@ module Ortfodb
140
142
  end
141
143
  end
142
144
 
143
- class Tags < Dry::Struct
145
+ class TagsConfiguration < Dry::Struct
146
+
147
+ # Path to file describing all tags.
144
148
  attribute :repository, Types::String
145
149
 
146
150
  def self.from_dynamic!(d)
@@ -165,7 +169,9 @@ module Ortfodb
165
169
  end
166
170
  end
167
171
 
168
- class Technologies < Dry::Struct
172
+ class TechnologiesConfiguration < Dry::Struct
173
+
174
+ # Path to file describing all technologies.
169
175
  attribute :repository, Types::String
170
176
 
171
177
  def self.from_dynamic!(d)
@@ -192,36 +198,36 @@ module Ortfodb
192
198
 
193
199
  # Configuration represents what the ortfodb.yaml configuration file describes.
194
200
  class Configuration < Dry::Struct
195
- attribute :build_metadata_file, Types::String
201
+ attribute :build_metadata_file, Types::String.optional
196
202
 
197
203
  # Exporter-specific configuration. Maps exporter names to their configuration.
198
204
  attribute :exporters, Types::Hash.meta(of: Types::Hash.meta(of: Types::Any)).optional
199
205
 
200
- attribute :extract_colors, ExtractColors
201
- attribute :make_gifs, MakeGifs
202
- attribute :make_thumbnails, MakeThumbnails
203
- attribute :media, Media
206
+ attribute :extract_colors, ExtractColorsConfiguration.optional
207
+ attribute :make_gifs, MakeGIFSConfiguration.optional
208
+ attribute :make_thumbnails, MakeThumbnailsConfiguration.optional
209
+ attribute :media, MediaConfiguration.optional
204
210
 
205
211
  # Path to the directory containing all projects. Must be absolute.
206
212
  attribute :projects_at, Types::String
207
213
 
208
214
  attribute :scattered_mode_folder, Types::String
209
- attribute :tags, Tags
210
- attribute :technologies, Technologies
215
+ attribute :tags, TagsConfiguration.optional
216
+ attribute :technologies, TechnologiesConfiguration.optional
211
217
 
212
218
  def self.from_dynamic!(d)
213
219
  d = Types::Hash[d]
214
220
  new(
215
- build_metadata_file: d.fetch("build metadata file"),
221
+ build_metadata_file: d["build metadata file"],
216
222
  exporters: Types::Hash.optional[d["exporters"]]&.map { |k, v| [k, Types::Hash[v].map { |k, v| [k, Types::Any[v]] }.to_h] }&.to_h,
217
- extract_colors: ExtractColors.from_dynamic!(d.fetch("extract colors")),
218
- make_gifs: MakeGifs.from_dynamic!(d.fetch("make gifs")),
219
- make_thumbnails: MakeThumbnails.from_dynamic!(d.fetch("make thumbnails")),
220
- media: Media.from_dynamic!(d.fetch("media")),
223
+ extract_colors: d["extract colors"] ? ExtractColorsConfiguration.from_dynamic!(d["extract colors"]) : nil,
224
+ make_gifs: d["make gifs"] ? MakeGIFSConfiguration.from_dynamic!(d["make gifs"]) : nil,
225
+ make_thumbnails: d["make thumbnails"] ? MakeThumbnailsConfiguration.from_dynamic!(d["make thumbnails"]) : nil,
226
+ media: d["media"] ? MediaConfiguration.from_dynamic!(d["media"]) : nil,
221
227
  projects_at: d.fetch("projects at"),
222
228
  scattered_mode_folder: d.fetch("scattered mode folder"),
223
- tags: Tags.from_dynamic!(d.fetch("tags")),
224
- technologies: Technologies.from_dynamic!(d.fetch("technologies")),
229
+ tags: d["tags"] ? TagsConfiguration.from_dynamic!(d["tags"]) : nil,
230
+ technologies: d["technologies"] ? TechnologiesConfiguration.from_dynamic!(d["technologies"]) : nil,
225
231
  )
226
232
  end
227
233
 
@@ -233,14 +239,14 @@ module Ortfodb
233
239
  {
234
240
  "build metadata file" => build_metadata_file,
235
241
  "exporters" => exporters,
236
- "extract colors" => extract_colors.to_dynamic,
237
- "make gifs" => make_gifs.to_dynamic,
238
- "make thumbnails" => make_thumbnails.to_dynamic,
239
- "media" => media.to_dynamic,
242
+ "extract colors" => extract_colors&.to_dynamic,
243
+ "make gifs" => make_gifs&.to_dynamic,
244
+ "make thumbnails" => make_thumbnails&.to_dynamic,
245
+ "media" => media&.to_dynamic,
240
246
  "projects at" => projects_at,
241
247
  "scattered mode folder" => scattered_mode_folder,
242
- "tags" => tags.to_dynamic,
243
- "technologies" => technologies.to_dynamic,
248
+ "tags" => tags&.to_dynamic,
249
+ "technologies" => technologies&.to_dynamic,
244
250
  }
245
251
  end
246
252
 
@@ -24,7 +24,7 @@ module Ortfodb
24
24
  end
25
25
 
26
26
  # MediaAttributes stores which HTML attributes should be added to the media.
27
- class Attributes < Dry::Struct
27
+ class MediaAttributes < Dry::Struct
28
28
 
29
29
  # Controlled with attribute character > (adds)
30
30
  attribute :autoplay, Types::Bool
@@ -33,7 +33,7 @@ module Ortfodb
33
33
  attribute :controls, Types::Bool
34
34
 
35
35
  # Controlled with attribute character ~ (adds)
36
- attribute :attributes_loop, Types::Bool
36
+ attribute :media_attributes_loop, Types::Bool
37
37
 
38
38
  # Controlled with attribute character > (adds)
39
39
  attribute :muted, Types::Bool
@@ -44,11 +44,11 @@ module Ortfodb
44
44
  def self.from_dynamic!(d)
45
45
  d = Types::Hash[d]
46
46
  new(
47
- autoplay: d.fetch("autoplay"),
48
- controls: d.fetch("controls"),
49
- attributes_loop: d.fetch("loop"),
50
- muted: d.fetch("muted"),
51
- playsinline: d.fetch("playsinline"),
47
+ autoplay: d.fetch("autoplay"),
48
+ controls: d.fetch("controls"),
49
+ media_attributes_loop: d.fetch("loop"),
50
+ muted: d.fetch("muted"),
51
+ playsinline: d.fetch("playsinline"),
52
52
  )
53
53
  end
54
54
 
@@ -60,7 +60,7 @@ module Ortfodb
60
60
  {
61
61
  "autoplay" => autoplay,
62
62
  "controls" => controls,
63
- "loop" => attributes_loop,
63
+ "loop" => media_attributes_loop,
64
64
  "muted" => muted,
65
65
  "playsinline" => playsinline,
66
66
  }
@@ -72,7 +72,7 @@ module Ortfodb
72
72
  end
73
73
 
74
74
  # ColorPalette reprensents the object in a Work's metadata.colors.
75
- class Colors < Dry::Struct
75
+ class ColorPalette < Dry::Struct
76
76
  attribute :primary, Types::String
77
77
  attribute :secondary, Types::String
78
78
  attribute :tertiary, Types::String
@@ -104,7 +104,7 @@ module Ortfodb
104
104
  end
105
105
 
106
106
  # ImageDimensions represents metadata about a media as it's extracted from its file.
107
- class Dimensions < Dry::Struct
107
+ class ImageDimensions < Dry::Struct
108
108
 
109
109
  # width / height
110
110
  attribute :aspect_ratio, Types::Double
@@ -141,7 +141,7 @@ module Ortfodb
141
141
  end
142
142
  end
143
143
 
144
- class Thumbnails < Dry::Struct
144
+ class ThumbnailsMap < Dry::Struct
145
145
 
146
146
  def self.from_dynamic!(d)
147
147
  d = Types::Hash[d]
@@ -163,22 +163,22 @@ module Ortfodb
163
163
  end
164
164
  end
165
165
 
166
- class BlockElement < Dry::Struct
166
+ class ContentBlock < Dry::Struct
167
167
  attribute :alt, Types::String
168
168
 
169
169
  # whether the media has been analyzed
170
170
  attribute :analyzed, Types::Bool
171
171
 
172
172
  attribute :anchor, Types::String
173
- attribute :attributes, Attributes
173
+ attribute :attributes, MediaAttributes
174
174
  attribute :caption, Types::String
175
- attribute :colors, Colors
175
+ attribute :colors, ColorPalette
176
176
 
177
177
  # html
178
178
  attribute :content, Types::String
179
179
 
180
180
  attribute :content_type, Types::String
181
- attribute :dimensions, Dimensions
181
+ attribute :dimensions, ImageDimensions
182
182
  attribute :dist_source, Types::String
183
183
 
184
184
  # in seconds
@@ -193,39 +193,39 @@ module Ortfodb
193
193
  # in bytes
194
194
  attribute :size, Types::Integer
195
195
 
196
- attribute :text, Types::String
197
- attribute :thumbnails, Thumbnails
198
- attribute :thumbnails_built_at, Types::String
199
- attribute :title, Types::String
200
- attribute :database_schema_type, Types::String
201
- attribute :url, Types::String
196
+ attribute :text, Types::String
197
+ attribute :thumbnails, ThumbnailsMap
198
+ attribute :thumbnails_built_at, Types::String
199
+ attribute :title, Types::String
200
+ attribute :content_block_type, Types::String
201
+ attribute :url, Types::String
202
202
 
203
203
  def self.from_dynamic!(d)
204
204
  d = Types::Hash[d]
205
205
  new(
206
- alt: d.fetch("alt"),
207
- analyzed: d.fetch("analyzed"),
208
- anchor: d.fetch("anchor"),
209
- attributes: Attributes.from_dynamic!(d.fetch("attributes")),
210
- caption: d.fetch("caption"),
211
- colors: Colors.from_dynamic!(d.fetch("colors")),
212
- content: d.fetch("content"),
213
- content_type: d.fetch("contentType"),
214
- dimensions: Dimensions.from_dynamic!(d.fetch("dimensions")),
215
- dist_source: d.fetch("distSource"),
216
- duration: d.fetch("duration"),
217
- has_sound: d.fetch("hasSound"),
218
- id: d.fetch("id"),
219
- index: d.fetch("index"),
220
- online: d.fetch("online"),
221
- relative_source: d.fetch("relativeSource"),
222
- size: d.fetch("size"),
223
- text: d.fetch("text"),
224
- thumbnails: Thumbnails.from_dynamic!(d.fetch("thumbnails")),
225
- thumbnails_built_at: d.fetch("thumbnailsBuiltAt"),
226
- title: d.fetch("title"),
227
- database_schema_type: d.fetch("type"),
228
- url: d.fetch("url"),
206
+ alt: d.fetch("alt"),
207
+ analyzed: d.fetch("analyzed"),
208
+ anchor: d.fetch("anchor"),
209
+ attributes: MediaAttributes.from_dynamic!(d.fetch("attributes")),
210
+ caption: d.fetch("caption"),
211
+ colors: ColorPalette.from_dynamic!(d.fetch("colors")),
212
+ content: d.fetch("content"),
213
+ content_type: d.fetch("contentType"),
214
+ dimensions: ImageDimensions.from_dynamic!(d.fetch("dimensions")),
215
+ dist_source: d.fetch("distSource"),
216
+ duration: d.fetch("duration"),
217
+ has_sound: d.fetch("hasSound"),
218
+ id: d.fetch("id"),
219
+ index: d.fetch("index"),
220
+ online: d.fetch("online"),
221
+ relative_source: d.fetch("relativeSource"),
222
+ size: d.fetch("size"),
223
+ text: d.fetch("text"),
224
+ thumbnails: ThumbnailsMap.from_dynamic!(d.fetch("thumbnails")),
225
+ thumbnails_built_at: d.fetch("thumbnailsBuiltAt"),
226
+ title: d.fetch("title"),
227
+ content_block_type: d.fetch("type"),
228
+ url: d.fetch("url"),
229
229
  )
230
230
  end
231
231
 
@@ -256,7 +256,7 @@ module Ortfodb
256
256
  "thumbnails" => thumbnails.to_dynamic,
257
257
  "thumbnailsBuiltAt" => thumbnails_built_at,
258
258
  "title" => title,
259
- "type" => database_schema_type,
259
+ "type" => content_block_type,
260
260
  "url" => url,
261
261
  }
262
262
  end
@@ -266,8 +266,8 @@ module Ortfodb
266
266
  end
267
267
  end
268
268
 
269
- class ContentValue < Dry::Struct
270
- attribute :blocks, Types.Array(BlockElement)
269
+ class LocalizedContent < Dry::Struct
270
+ attribute :blocks, Types.Array(ContentBlock)
271
271
  attribute :footnotes, Types::Hash.meta(of: Types::String)
272
272
  attribute :layout, Types.Array(Types.Array(Types::String))
273
273
  attribute :title, Types::String
@@ -275,7 +275,7 @@ module Ortfodb
275
275
  def self.from_dynamic!(d)
276
276
  d = Types::Hash[d]
277
277
  new(
278
- blocks: d.fetch("blocks").map { |x| BlockElement.from_dynamic!(x) },
278
+ blocks: d.fetch("blocks").map { |x| ContentBlock.from_dynamic!(x) },
279
279
  footnotes: Types::Hash[d.fetch("footnotes")].map { |k, v| [k, Types::String[v]] }.to_h,
280
280
  layout: d.fetch("layout"),
281
281
  title: d.fetch("title"),
@@ -300,7 +300,7 @@ module Ortfodb
300
300
  end
301
301
  end
302
302
 
303
- class DatabaseMetadataClass < Dry::Struct
303
+ class DatabaseMeta < Dry::Struct
304
304
 
305
305
  # Partial is true if the database was not fully built.
306
306
  attribute :partial, Types::Bool
@@ -327,11 +327,11 @@ module Ortfodb
327
327
  end
328
328
  end
329
329
 
330
- class Metadata < Dry::Struct
330
+ class WorkMetadata < Dry::Struct
331
331
  attribute :additional_metadata, Types::Hash.meta(of: Types::Any)
332
332
  attribute :aliases, Types.Array(Types::String)
333
- attribute :colors, Colors
334
- attribute :database_metadata, DatabaseMetadataClass
333
+ attribute :colors, ColorPalette
334
+ attribute :database_metadata, DatabaseMeta
335
335
  attribute :finished, Types::String
336
336
  attribute :made_with, Types.Array(Types::String)
337
337
  attribute :page_background, Types::String
@@ -347,8 +347,8 @@ module Ortfodb
347
347
  new(
348
348
  additional_metadata: Types::Hash[d.fetch("additionalMetadata")].map { |k, v| [k, Types::Any[v]] }.to_h,
349
349
  aliases: d.fetch("aliases"),
350
- colors: Colors.from_dynamic!(d.fetch("colors")),
351
- database_metadata: DatabaseMetadataClass.from_dynamic!(d.fetch("databaseMetadata")),
350
+ colors: ColorPalette.from_dynamic!(d.fetch("colors")),
351
+ database_metadata: DatabaseMeta.from_dynamic!(d.fetch("databaseMetadata")),
352
352
  finished: d.fetch("finished"),
353
353
  made_with: d.fetch("madeWith"),
354
354
  page_background: d.fetch("pageBackground"),
@@ -389,22 +389,22 @@ module Ortfodb
389
389
  end
390
390
 
391
391
  # AnalyzedWork represents a complete work, with analyzed mediae.
392
- class DatabaseValue < Dry::Struct
392
+ class AnalyzedWork < Dry::Struct
393
393
  attribute :built_at, Types::String
394
- attribute :content, Types::Hash.meta(of: ContentValue)
394
+ attribute :content, Types::Hash.meta(of: LocalizedContent)
395
395
  attribute :description_hash, Types::String
396
396
  attribute :id, Types::String
397
- attribute :metadata, Metadata
397
+ attribute :metadata, WorkMetadata
398
398
  attribute :partial, Types::Bool
399
399
 
400
400
  def self.from_dynamic!(d)
401
401
  d = Types::Hash[d]
402
402
  new(
403
403
  built_at: d.fetch("builtAt"),
404
- content: Types::Hash[d.fetch("content")].map { |k, v| [k, ContentValue.from_dynamic!(v)] }.to_h,
404
+ content: Types::Hash[d.fetch("content")].map { |k, v| [k, LocalizedContent.from_dynamic!(v)] }.to_h,
405
405
  description_hash: d.fetch("descriptionHash"),
406
406
  id: d.fetch("id"),
407
- metadata: Metadata.from_dynamic!(d.fetch("metadata")),
407
+ metadata: WorkMetadata.from_dynamic!(d.fetch("metadata")),
408
408
  partial: d.fetch("Partial"),
409
409
  )
410
410
  end
@@ -432,7 +432,7 @@ module Ortfodb
432
432
  module Ortfodb
433
433
  class Database
434
434
  def self.from_json!(json)
435
- Types::Hash[JSON.parse(json, quirks_mode: true)].map { |k, v| [k, DatabaseValue.from_dynamic!(v)] }.to_h
435
+ Types::Hash[JSON.parse(json, quirks_mode: true)].map { |k, v| [k, AnalyzedWork.from_dynamic!(v)] }.to_h
436
436
  end
437
437
  end
438
438
  end
@@ -21,7 +21,7 @@ module Ortfodb
21
21
  String = Strict::String
22
22
  end
23
23
 
24
- class ExporterSchema < Dry::Struct
24
+ class ExporterCommand < Dry::Struct
25
25
 
26
26
  # Log a message. The first argument is the verb, the second is the color, the third is the
27
27
  # message.
@@ -58,10 +58,10 @@ module Ortfodb
58
58
 
59
59
  # Commands to run after the build finishes. Go text template that receives .Data and
60
60
  # .Database, the built database.
61
- attribute :after, Types.Array(ExporterSchema).optional
61
+ attribute :after, Types.Array(ExporterCommand).optional
62
62
 
63
63
  # Commands to run before the build starts. Go text template that receives .Data
64
- attribute :before, Types.Array(ExporterSchema).optional
64
+ attribute :before, Types.Array(ExporterCommand).optional
65
65
 
66
66
  # Initial data
67
67
  attribute :data, Types::Hash.meta(of: Types::Any).optional
@@ -80,19 +80,19 @@ module Ortfodb
80
80
 
81
81
  # Commands to run during the build, for each work. Go text template that receives .Data and
82
82
  # .Work, the current work.
83
- attribute :work, Types.Array(ExporterSchema).optional
83
+ attribute :work, Types.Array(ExporterCommand).optional
84
84
 
85
85
  def self.from_dynamic!(d)
86
86
  d = Types::Hash[d]
87
87
  new(
88
- after: d["after"]&.map { |x| ExporterSchema.from_dynamic!(x) },
89
- before: d["before"]&.map { |x| ExporterSchema.from_dynamic!(x) },
88
+ after: d["after"]&.map { |x| ExporterCommand.from_dynamic!(x) },
89
+ before: d["before"]&.map { |x| ExporterCommand.from_dynamic!(x) },
90
90
  data: Types::Hash.optional[d["data"]]&.map { |k, v| [k, Types::Any[v]] }&.to_h,
91
91
  description: d.fetch("description"),
92
92
  exporter_name: d.fetch("name"),
93
93
  requires: d["requires"],
94
94
  verbose: d["verbose"],
95
- work: d["work"]&.map { |x| ExporterSchema.from_dynamic!(x) },
95
+ work: d["work"]&.map { |x| ExporterCommand.from_dynamic!(x) },
96
96
  )
97
97
  end
98
98
 
data/lib/ortfodb/tags.rb CHANGED
@@ -4,7 +4,7 @@
4
4
  # To parse this JSON, add 'dry-struct' and 'dry-types' gems, then do:
5
5
  #
6
6
  # tags = Tags.from_json! "[…]"
7
- # puts tags.first.detect.search.first
7
+ # puts tags.first.detect&.search&.first
8
8
  #
9
9
  # If from_json! succeeds, the value returned matches the schema.
10
10
 
@@ -20,17 +20,18 @@ module Ortfodb
20
20
  String = Strict::String
21
21
  end
22
22
 
23
+ # Various ways to automatically detect that a work is tagged with this tag.
23
24
  class Detect < Dry::Struct
24
- attribute :files, Types.Array(Types::String)
25
- attribute :made_with, Types.Array(Types::String)
26
- attribute :search, Types.Array(Types::String)
25
+ attribute :files, Types.Array(Types::String).optional
26
+ attribute :made_with, Types.Array(Types::String).optional
27
+ attribute :search, Types.Array(Types::String).optional
27
28
 
28
29
  def self.from_dynamic!(d)
29
30
  d = Types::Hash[d]
30
31
  new(
31
- files: d.fetch("files"),
32
- made_with: d.fetch("made with"),
33
- search: d.fetch("search"),
32
+ files: d["files"],
33
+ made_with: d["made with"],
34
+ search: d["search"],
34
35
  )
35
36
  end
36
37
 
@@ -51,21 +52,34 @@ module Ortfodb
51
52
  end
52
53
  end
53
54
 
55
+ # Tag represents a category that can be assigned to a work.
54
56
  class Tag < Dry::Struct
55
- attribute :aliases, Types.Array(Types::String)
56
- attribute :description, Types::String
57
- attribute :detect, Detect
58
- attribute :learn_more_at, Types::String
59
- attribute :plural, Types::String
60
- attribute :singular, Types::String
57
+
58
+ # Other singular-form names of tags that refer to this tag. The names mentionned here
59
+ # should not be used to define other tags.
60
+ attribute :aliases, Types.Array(Types::String).optional
61
+
62
+ attribute :description, Types::String.optional
63
+
64
+ # Various ways to automatically detect that a work is tagged with this tag.
65
+ attribute :detect, Detect.optional
66
+
67
+ # URL to a website where more information can be found about this tag.
68
+ attribute :learn_more_at, Types::String.optional
69
+
70
+ # Plural-form name of the tag. For example, "Books".
71
+ attribute :plural, Types::String
72
+
73
+ # Singular-form name of the tag. For example, "Book".
74
+ attribute :singular, Types::String
61
75
 
62
76
  def self.from_dynamic!(d)
63
77
  d = Types::Hash[d]
64
78
  new(
65
- aliases: d.fetch("aliases"),
66
- description: d.fetch("description"),
67
- detect: Detect.from_dynamic!(d.fetch("detect")),
68
- learn_more_at: d.fetch("learn more at"),
79
+ aliases: d["aliases"],
80
+ description: d["description"],
81
+ detect: d["detect"] ? Detect.from_dynamic!(d["detect"]) : nil,
82
+ learn_more_at: d["learn more at"],
69
83
  plural: d.fetch("plural"),
70
84
  singular: d.fetch("singular"),
71
85
  )
@@ -79,7 +93,7 @@ module Ortfodb
79
93
  {
80
94
  "aliases" => aliases,
81
95
  "description" => description,
82
- "detect" => detect.to_dynamic,
96
+ "detect" => detect&.to_dynamic,
83
97
  "learn more at" => learn_more_at,
84
98
  "plural" => plural,
85
99
  "singular" => singular,
@@ -4,7 +4,7 @@
4
4
  # To parse this JSON, add 'dry-struct' and 'dry-types' gems, then do:
5
5
  #
6
6
  # technologies = Technologies.from_json! "[…]"
7
- # puts technologies.first.files.first
7
+ # puts technologies.first.files&.first
8
8
  #
9
9
  # If from_json! succeeds, the value returned matches the schema.
10
10
 
@@ -20,34 +20,48 @@ module Ortfodb
20
20
  String = Strict::String
21
21
  end
22
22
 
23
+ # Technology represents a "technology" (in the very broad sense) that was used to create a
24
+ # work.
23
25
  class Technology < Dry::Struct
24
- attribute :aliases, Types.Array(Types::String)
26
+
27
+ # Other technology slugs that refer to this technology. The slugs mentionned here should
28
+ # not be used in the definition of other technologies.
29
+ attribute :aliases, Types.Array(Types::String).optional
25
30
 
26
31
  # Autodetect contains an expression of the form 'CONTENT in PATH' where CONTENT is a
27
32
  # free-form unquoted string and PATH is a filepath relative to the work folder.
28
33
  # If CONTENT is found in PATH, we consider that technology to be used in the work.
29
- attribute :autodetect, Types.Array(Types::String)
34
+ attribute :autodetect, Types.Array(Types::String).optional
35
+
36
+ # Name of the person or organization that created this technology.
37
+ attribute :by, Types::String.optional
30
38
 
31
- attribute :by, Types::String
32
- attribute :description, Types::String
39
+ attribute :description, Types::String.optional
33
40
 
34
41
  # Files contains a list of gitignore-style patterns. If the work contains any of the
35
42
  # patterns specified, we consider that technology to be used in the work.
36
- attribute :files, Types.Array(Types::String)
43
+ attribute :files, Types.Array(Types::String).optional
44
+
45
+ # URL to a website where more information can be found about this technology.
46
+ attribute :learn_more_at, Types::String.optional
37
47
 
38
- attribute :learn_more_at, Types::String
39
48
  attribute :technology_name, Types::String
40
- attribute :slug, Types::String
49
+
50
+ # The slug is a unique identifier for this technology, that's suitable for use in a
51
+ # website's URL.
52
+ # For example, the page that shows all works using a technology with slug "a" could be at
53
+ # https://example.org/technologies/a.
54
+ attribute :slug, Types::String
41
55
 
42
56
  def self.from_dynamic!(d)
43
57
  d = Types::Hash[d]
44
58
  new(
45
- aliases: d.fetch("aliases"),
46
- autodetect: d.fetch("autodetect"),
47
- by: d.fetch("by"),
48
- description: d.fetch("description"),
49
- files: d.fetch("files"),
50
- learn_more_at: d.fetch("learn more at"),
59
+ aliases: d["aliases"],
60
+ autodetect: d["autodetect"],
61
+ by: d["by"],
62
+ description: d["description"],
63
+ files: d["files"],
64
+ learn_more_at: d["learn more at"],
51
65
  technology_name: d.fetch("name"),
52
66
  slug: d.fetch("slug"),
53
67
  )
@@ -1,3 +1,3 @@
1
1
  module Ortfodb
2
- VERSION = "1.4.0"
2
+ VERSION = "1.5.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ortfodb
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.0
4
+ version: 1.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ewen Le Bihan
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-04-16 00:00:00.000000000 Z
11
+ date: 2024-04-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dry-struct