openstax_content 0.3.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/openstax/content/abl.rb +74 -6
- data/lib/openstax/content/archive.rb +22 -11
- data/lib/openstax/content/book.rb +16 -31
- data/lib/openstax/content/book_part.rb +6 -0
- data/lib/openstax/content/page.rb +3 -2
- data/lib/openstax/content/s3.rb +3 -2
- data/lib/openstax/content/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 606de08c8e8a83ca196e43eef4d8159f4bddd9d94bf5a357af6e5e8109ed57ad
|
4
|
+
data.tar.gz: 4ef85c1b6bba83ef5a2605d76a8fc76fd3ce63dc80d84a3030a2f1943a56251d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6f994e45ad7f63e9d2ac8e2e143ef6b23a2688fee58c7de54a230cda84723bfa43eb1febeade0687e007d3453d1c970f7c4c6dad04cd75cee5ff0b9bc01003b2
|
7
|
+
data.tar.gz: 345ec56a1b9aecf201612f67ee3b283f22928afba02ec1ddeb2ad9f6e4243ab95f33049bb1f7892b570515538588c3a97859e4aa009f5f24038bf57fcf6aff0b
|
data/lib/openstax/content/abl.rb
CHANGED
@@ -1,13 +1,81 @@
|
|
1
|
+
require_relative 'archive'
|
2
|
+
require_relative 'book'
|
3
|
+
|
1
4
|
class OpenStax::Content::Abl
|
2
|
-
def
|
3
|
-
@
|
5
|
+
def initialize(url: nil)
|
6
|
+
@url = url
|
7
|
+
end
|
8
|
+
|
9
|
+
def url
|
10
|
+
@url ||= OpenStax::Content.abl_url
|
11
|
+
end
|
12
|
+
|
13
|
+
def body_string
|
14
|
+
@body_string ||= Faraday.get(url).body
|
4
15
|
end
|
5
16
|
|
6
|
-
def
|
7
|
-
|
17
|
+
def body_hash
|
18
|
+
@body_hash ||= JSON.parse(body_string, symbolize_names: true)
|
8
19
|
end
|
9
20
|
|
10
|
-
def
|
11
|
-
|
21
|
+
def digest
|
22
|
+
Digest::SHA256.hexdigest body_string
|
23
|
+
end
|
24
|
+
|
25
|
+
def latest_approved_version_by_collection_id(archive: OpenStax::Content::Archive.new)
|
26
|
+
{}.tap do |hash|
|
27
|
+
body_hash[:approved_versions].each do |version|
|
28
|
+
next if version[:min_code_version] > archive.version
|
29
|
+
|
30
|
+
existing_version = hash[version[:collection_id]]
|
31
|
+
|
32
|
+
next if !existing_version.nil? &&
|
33
|
+
(existing_version[:content_version].split('.').map(&:to_i) <=>
|
34
|
+
version[:content_version].split('.').map(&:to_i)) >= 0
|
35
|
+
|
36
|
+
hash[version[:collection_id]] = version
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def approved_books(archive: OpenStax::Content::Archive.new)
|
42
|
+
# Can be removed once we have no more CNX books
|
43
|
+
version_by_collection_id = latest_approved_version_by_collection_id(archive: archive)
|
44
|
+
|
45
|
+
body_hash[:approved_books].flat_map do |approved_book|
|
46
|
+
if approved_book[:versions].nil?
|
47
|
+
# CNX-hosted book
|
48
|
+
version = version_by_collection_id[approved_book[:collection_id]]
|
49
|
+
|
50
|
+
next [] if version.nil?
|
51
|
+
|
52
|
+
approved_book[:books].map do |book|
|
53
|
+
OpenStax::Content::Book.new(
|
54
|
+
archive: archive,
|
55
|
+
uuid: book[:uuid],
|
56
|
+
version: version[:content_version].sub('1.', ''),
|
57
|
+
slug: book[:slug],
|
58
|
+
style: approved_book[:style]
|
59
|
+
)
|
60
|
+
end
|
61
|
+
else
|
62
|
+
# Git-hosted book
|
63
|
+
approved_book[:versions].flat_map do |version|
|
64
|
+
next [] if version[:min_code_version] > archive.version
|
65
|
+
|
66
|
+
commit_metadata = version[:commit_metadata]
|
67
|
+
|
68
|
+
commit_metadata[:books].map do |book|
|
69
|
+
OpenStax::Content::Book.new(
|
70
|
+
archive: archive,
|
71
|
+
uuid: book[:uuid],
|
72
|
+
version: version[:commit_sha][0..6],
|
73
|
+
slug: book[:slug],
|
74
|
+
style: book[:style]
|
75
|
+
)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
12
80
|
end
|
13
81
|
end
|
@@ -2,14 +2,29 @@ require 'addressable/uri'
|
|
2
2
|
require 'faraday'
|
3
3
|
|
4
4
|
class OpenStax::Content::Archive
|
5
|
-
def initialize(version)
|
5
|
+
def initialize(version: nil)
|
6
6
|
@version = version
|
7
7
|
@slugs = {}
|
8
8
|
end
|
9
9
|
|
10
|
+
def s3
|
11
|
+
@s3 ||= OpenStax::Content::S3.new
|
12
|
+
end
|
13
|
+
|
14
|
+
def versions
|
15
|
+
@versions ||= s3.ls.reverse
|
16
|
+
end
|
17
|
+
|
18
|
+
def version
|
19
|
+
@version || versions.first
|
20
|
+
end
|
21
|
+
|
22
|
+
def previous_version
|
23
|
+
versions[versions.index(version) + 1]
|
24
|
+
end
|
25
|
+
|
10
26
|
def base_url
|
11
|
-
@base_url ||= "https://#{OpenStax::Content.domain}/#{
|
12
|
-
OpenStax::Content.archive_path}/#{@version}"
|
27
|
+
@base_url ||= "https://#{OpenStax::Content.domain}/#{OpenStax::Content.archive_path}/#{version}"
|
13
28
|
end
|
14
29
|
|
15
30
|
def url_for(object)
|
@@ -72,20 +87,16 @@ class OpenStax::Content::Archive
|
|
72
87
|
end
|
73
88
|
end
|
74
89
|
|
75
|
-
def s3
|
76
|
-
@s3 ||= OpenStax::Content::S3.new
|
77
|
-
end
|
78
|
-
|
79
90
|
def add_latest_book_version_if_missing(object)
|
80
91
|
book_id, page_id = object.split(':', 2)
|
81
92
|
book_uuid, book_version = book_id.split('@', 2)
|
82
93
|
return object unless book_version.nil? && s3.bucket_configured?
|
83
94
|
|
84
|
-
s3.ls(
|
85
|
-
|
86
|
-
next unless
|
95
|
+
s3.ls(version).each do |book|
|
96
|
+
s3_uuid, s3_version = book.split('@')
|
97
|
+
next unless s3_uuid == book_uuid
|
87
98
|
|
88
|
-
book_version =
|
99
|
+
book_version = s3_version
|
89
100
|
break
|
90
101
|
end
|
91
102
|
|
@@ -1,27 +1,18 @@
|
|
1
|
-
require_relative 'archive'
|
2
1
|
require_relative 'book_part'
|
3
2
|
|
4
3
|
class OpenStax::Content::Book
|
5
|
-
|
6
|
-
archive_version:, uuid: nil, version: nil, hash: nil, title: nil, tree: nil, root_book_part: nil
|
7
|
-
)
|
8
|
-
@uuid = uuid || (hash || {})['id']
|
9
|
-
raise ArgumentError, 'Either uuid or hash with id key is required' if @uuid.nil?
|
4
|
+
extend Forwardable
|
10
5
|
|
11
|
-
|
12
|
-
raise ArgumentError, 'Either version or hash with version key is required' if @version.nil?
|
6
|
+
attr_reader :archive, :uuid, :version, :slug, :style
|
13
7
|
|
14
|
-
|
15
|
-
@
|
16
|
-
@
|
17
|
-
@
|
18
|
-
@
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
def archive
|
24
|
-
@archive ||= OpenStax::Content::Archive.new archive_version
|
8
|
+
def initialize(archive:, uuid:, version:, url: nil, hash: nil, slug: nil, style: nil)
|
9
|
+
@archive = archive
|
10
|
+
@uuid = uuid
|
11
|
+
@version = version
|
12
|
+
@url = url
|
13
|
+
@hash = hash
|
14
|
+
@slug = slug
|
15
|
+
@style = style
|
25
16
|
end
|
26
17
|
|
27
18
|
def url
|
@@ -32,6 +23,10 @@ class OpenStax::Content::Book
|
|
32
23
|
@url_fragment ||= url.chomp('.json')
|
33
24
|
end
|
34
25
|
|
26
|
+
def hash
|
27
|
+
@hash ||= archive.json url
|
28
|
+
end
|
29
|
+
|
35
30
|
def baked
|
36
31
|
@baked ||= hash['baked']
|
37
32
|
end
|
@@ -40,22 +35,10 @@ class OpenStax::Content::Book
|
|
40
35
|
@collated ||= hash.fetch('collated', false)
|
41
36
|
end
|
42
37
|
|
43
|
-
def hash
|
44
|
-
@hash ||= archive.json url
|
45
|
-
end
|
46
|
-
|
47
|
-
def uuid
|
48
|
-
@uuid ||= hash.fetch('id')
|
49
|
-
end
|
50
|
-
|
51
38
|
def short_id
|
52
39
|
@short_id ||= hash['shortId']
|
53
40
|
end
|
54
41
|
|
55
|
-
def version
|
56
|
-
@version ||= hash.fetch('version')
|
57
|
-
end
|
58
|
-
|
59
42
|
def title
|
60
43
|
@title ||= hash.fetch('title')
|
61
44
|
end
|
@@ -67,4 +50,6 @@ class OpenStax::Content::Book
|
|
67
50
|
def root_book_part
|
68
51
|
@root_book_part ||= OpenStax::Content::BookPart.new(hash: tree, is_root: true, book: self)
|
69
52
|
end
|
53
|
+
|
54
|
+
def_delegator :root_book_part, :all_pages
|
70
55
|
end
|
@@ -32,7 +32,7 @@ class OpenStax::Content::Page
|
|
32
32
|
node.at_css(feature_id_css)
|
33
33
|
end
|
34
34
|
|
35
|
-
def initialize(book: nil, hash: {}, uuid: nil, url: nil, title: nil, content: nil)
|
35
|
+
def initialize(book: nil, hash: {}, uuid: nil, url: nil, title: nil, slug: nil, content: nil)
|
36
36
|
@uuid = uuid || hash['id']&.split('@', 2)&.first
|
37
37
|
raise ArgumentError, 'Either uuid or hash with id key is required' if @uuid.nil?
|
38
38
|
|
@@ -40,11 +40,12 @@ class OpenStax::Content::Page
|
|
40
40
|
@hash = hash
|
41
41
|
@url = url
|
42
42
|
@title = title || hash['title']
|
43
|
+
@slug = slug || hash['slug']
|
43
44
|
@content = content
|
44
45
|
end
|
45
46
|
|
46
47
|
attr_accessor :chapter_section
|
47
|
-
attr_reader :uuid, :hash
|
48
|
+
attr_reader :uuid, :hash, :slug
|
48
49
|
|
49
50
|
def book
|
50
51
|
raise ArgumentError, 'Book was not specified' if @book.nil?
|
data/lib/openstax/content/s3.rb
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
require 'aws-sdk-s3'
|
2
2
|
|
3
3
|
class OpenStax::Content::S3
|
4
|
-
def initialize
|
4
|
+
def initialize(bucket_name: nil)
|
5
|
+
@bucket_name = bucket_name
|
5
6
|
@ls = Hash.new { |hash, key| hash[key] = Hash.new { |hash, key| hash[key] = {} } }
|
6
7
|
end
|
7
8
|
|
8
9
|
def bucket_name
|
9
|
-
OpenStax::Content.bucket_name
|
10
|
+
@bucket_name ||= OpenStax::Content.bucket_name
|
10
11
|
end
|
11
12
|
|
12
13
|
def bucket_configured?
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: openstax_content
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dante Soares
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-04-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aws-sdk-s3
|
@@ -183,7 +183,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
183
183
|
- !ruby/object:Gem::Version
|
184
184
|
version: '0'
|
185
185
|
requirements: []
|
186
|
-
rubygems_version: 3.
|
186
|
+
rubygems_version: 3.1.4
|
187
187
|
signing_key:
|
188
188
|
specification_version: 4
|
189
189
|
summary: Ruby bindings to read and parse the OpenStax ABL and the content archive
|