cocina-models 0.2.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,95 @@
1
+ :xn109qc9773_work a bf:Work , bf:Text ;
2
+ rdfs:label "From superteacher to 'bad teacher': goals 2000, comic book films, and changing depictions of educators in the movies" ;
3
+ bf:title [ a bf:Title ;
4
+ bf:mainTitle "From superteacher to 'bad teacher'" ;
5
+ bf:subTitle "goals 2000, comic book films, and changing depictions of educators in the movies"
6
+ ] ;
7
+ bf:contribution [ a bf:Contribution ;
8
+ bf:agent [ a bf:Agent , bf:Person ;
9
+ rdfs:label "Grant, Derisa"
10
+ ] ;
11
+ ] ;
12
+ bf:contribution [ a bf:Contribution ;
13
+ bf:agent [ a bf:Agent , bf:Person ;
14
+ rdfs:label "Labaree, David F., 1947-"
15
+ ] ;
16
+ bf:role [ a bf:Role ;
17
+ rdfs:label "primary advisor"
18
+ ] ;
19
+ bf:role <http://id.loc.gov/vocabulary/relators/ths>
20
+ ] ;
21
+ bf:contribution [ a bf:Contribution ;
22
+ bf:agent [ a bf:Agent , bf:Person ;
23
+ rdfs:label "McDermott, Ray"
24
+ ] ;
25
+ bf:role [ a bf:Role ;
26
+ rdfs:label "advisor"
27
+ ] ;
28
+ bf:role <http://id.loc.gov/vocabulary/relators/ths>
29
+ ] ;
30
+ bf:contribution [ a bf:Contribution ;
31
+ bf:agent [ a bf:Agent , bf:Person ;
32
+ rdfs:label "Willinsky, John, 1950-"
33
+ ] ;
34
+ bf:role [ a bf:Role ;
35
+ rdfs:label "advisor"
36
+ ] ;
37
+ bf:role <http://id.loc.gov/vocabulary/relators/ths>
38
+ ] ;
39
+ bf:contribution [ a bf:Contribution ;
40
+ bf:agent [ a bf:Agent , bf:Organization ;
41
+ rdfs:label "Stanford University. Graduate School of Education"
42
+ ]
43
+ ]
44
+ bf:genreForm [ a bf:GenreForm ;
45
+ rdfs:label "theses" ;
46
+ bf:source [ a bf:Source ;
47
+ bf:code "marcgt"
48
+ ]
49
+ ] ;
50
+ bf:language <http://id.loc.gov/vocabulary/iso639-2/eng> ;
51
+ bf:summary [ a bf:Summary ;
52
+ rdfs:label "Since 1939, 46 eddies, or fictional movies about primary or secondary schooling that foreground a teacher..."
53
+ ] ;
54
+ bf:dissertation [ a bf:Dissertation ;
55
+ rdfs:label "Thesis (Ph.D.)--Stanford University, 2015."
56
+ ]
57
+ ] .
58
+
59
+ :xn109qc9773_instance a bf:Instance ;
60
+ rdfs:label "From superteacher to 'bad teacher': goals 2000, comic book films, and changing depictions of educators in the movies" ;
61
+ bf:title [ a bf:Title ;
62
+ bf:mainTitle "From superteacher to 'bad teacher'" ;
63
+ bf:subTitle "goals 2000, comic book films, and changing depictions of educators in the movies"
64
+ ] ;
65
+ bf:provisionActivity [ a bf:ProvisionActivity , a bf:Publication ;
66
+ bf:date "2015" ;
67
+ bf:place [ a bf:Place ;
68
+ bf:code "xx" ;
69
+ bf:source [ a bf:Source ;
70
+ bf:code "marccountry"
71
+ ] ;
72
+ ] ;
73
+ bf:issuance <http://id.loc.gov/vocabulary/issuance/mono>
74
+ ] ;
75
+ bf:carrier [ a bf:Carrier ;
76
+ rdfs:label "digital"
77
+ ] ;
78
+ bf:extent [ a bf:Extent ;
79
+ rdfs:label "1 online resource"
80
+ ] ;
81
+ bf:note [ a bf:Note ;
82
+ rdfs:label "Submitted to the Graduate School of Education."
83
+ ] ;
84
+ bf:responsibilityStatement "Derisa Grant."
85
+ ] .
86
+
87
+ :xn109qc9773_item [ a bf:Item ;
88
+ bf:electronicLocator [ a rdf:Resource ;
89
+ rdf:value <http://purl.stanford.edu/xn109qc9773> ;
90
+ bf:note [ a bf:Note ;
91
+ rdfs:label "primary display" ;
92
+ bf:noteType "URL usage"
93
+ ]
94
+ ]
95
+ ] .
@@ -0,0 +1,158 @@
1
+ { "version": "1.0",
2
+ "lastUpdated": "2018-11-13",
3
+ "druid": "xn109qc9773",
4
+ "descriptiveMetadata": {
5
+ "title": [{
6
+ "primary": "TRUE",
7
+ "titleParts": [
8
+ {"mainTitle": "From superteacher to 'bad teacher'"},
9
+ {"subTitle": "goals 2000, comic book films, and changing depictions of educators in the movies"}
10
+ ],
11
+ "titleFull": "From superteacher to 'bad teacher': goals 2000, comic book films, and changing depictions of educators in the movies",
12
+ "titleBrief": "From superteacher to 'bad teacher'"
13
+ }],
14
+ "origin": [
15
+ {
16
+ "primary": "TRUE",
17
+ "event": "creation",
18
+ "agent": [{
19
+ "type": "personal",
20
+ "name": {
21
+ "nameFromSource": "Grant, Derisa",
22
+ "lastName": "Grant",
23
+ "firstName": "Derisa"
24
+ }
25
+ }]
26
+ },
27
+ {
28
+ "event": "creation",
29
+ "agent": [{
30
+ "type": "personal",
31
+ "name": {
32
+ "nameFromSource": "Labaree, David F.",
33
+ "lastName": "Labaree",
34
+ "firstName": "David F.",
35
+ "nameDate": {
36
+ "type": "life",
37
+ "startDate": "1947",
38
+ "endDate": "open"
39
+ }
40
+ }
41
+ }],
42
+ "role": [
43
+ {"roleTerm": "primary advisor"},
44
+ {
45
+ "roleTerm": "thesis advisor",
46
+ "roleAuthority": "marcrelator",
47
+ "roleValueURI": "http://id.loc.gov/vocabulary/relators/ths"
48
+ }
49
+ ]
50
+ },
51
+ {
52
+ "event": "creation",
53
+ "agent": [{
54
+ "type": "personal",
55
+ "name": {
56
+ "nameFromSource": "McDermott, Ray",
57
+ "lastName": "McDermott",
58
+ "firstName": "Ray"
59
+ }
60
+ }],
61
+ "role": [
62
+ {"roleTerm": "advisor"},
63
+ {
64
+ "roleTerm": "thesis advisor",
65
+ "roleAuthority": "marcrelator",
66
+ "roleValueURI": "http://id.loc.gov/vocabulary/relators/ths"
67
+ }
68
+ ]
69
+ },
70
+ {
71
+ "event": "creation",
72
+ "agent": [{
73
+ "type": "personal",
74
+ "name": {
75
+ "nameFromSource": "Willinsky, John",
76
+ "lastName": "Willinsky",
77
+ "firstName": "John",
78
+ "nameDate": {
79
+ "type": "life",
80
+ "startDate": "1950",
81
+ "endDate": "open"
82
+ }
83
+ }
84
+ }],
85
+ "role": [
86
+ {"roleTerm": "advisor"},
87
+ {
88
+ "roleTerm": "thesis advisor",
89
+ "roleAuthority": "marcrelator",
90
+ "roleValueURI": "http://id.loc.gov/vocabulary/relators/ths"
91
+ }
92
+ ]
93
+ },
94
+ {
95
+ "event": "creation",
96
+ "agent": [{
97
+ "type": "corporate",
98
+ "name": {"nameParts": [
99
+ "Stanford University",
100
+ "Graduate School of Education"
101
+ ]}
102
+ }]
103
+ },
104
+ {
105
+ "event": "publication",
106
+ "place": [{
107
+ "code": "xx",
108
+ "authority": "marccountry"
109
+ }],
110
+ "date": {"singleDate": "2015"},
111
+ "periodicity": [{
112
+ "value": "monographic",
113
+ "vocabulary": "MODS issuance"
114
+ }]
115
+ }
116
+ ],
117
+ "typeOfResource": [{
118
+ "typeOfResourceTerm": "text",
119
+ "authority": "MODS typeOfResource"
120
+ }],
121
+ "genre": [{
122
+ "genreTerm": "theses",
123
+ "authority": "marcgt"
124
+ }],
125
+ "language": [{
126
+ "languageTerm": "English",
127
+ "languageAuthority": "iso639-2b",
128
+ "languageValueURI": "http://id.loc.gov/vocabulary/iso639-2/eng"
129
+ }],
130
+ "form": {
131
+ "appliesTo": "resource",
132
+ "medium": "digital",
133
+ "extent": {
134
+ "extentStatement": "1 online resource",
135
+ "extentNumber": 1,
136
+ "extentUnit": "online resource"
137
+ }
138
+ },
139
+ "access": ["online"],
140
+ "abstract": "Since 1939, 46 eddies, or fictional movies about primary or secondary schooling that foreground a teacher, have been released in the United States. From the 1950s through the 1990s, eddies often featured two interconnected and dominant tropes: the separation of home and school, and a superteacher, or a dedicated educator who uses unconventional teaching methods. However, many of the eddies made after 2000 blur or wholly erase the boundary between home and school, and nearly half of the 15 eddies made after 2000 feature unsavory or morally ambiguous teacher protagonists. This dissertation explores the contexts surrounding the genre's shift in tropes, and asserts that changes in eddies coincide with broader changes within the film industry, as well as with changes in educational policy and rhetoric. Specifically, generic changes in eddies coincide with the rise of the comic book film in the early 2000s, and President Bill Clinton's 1994 Goals 2000: Educate America Act, through which the Clinton administration framed education reform as a systemic problem requiring federal interventions and gained the public's support for federally led reforms. By the early 2000s, caped crusaders had begun proving lucrative at the box office, and the federal government had gained unprecedented traction in schools. Concurrently, the cinematic teacher--with no mask, no cape, and no federal authority&#x2014;was increasingly depicted as a drug addict, a coward, or a cheater who brought the dysfunction of her home life into the classroom.",
141
+ "note": [
142
+ {"value": "Submitted to the Graduate School of Education."},
143
+ {
144
+ "type": "thesis",
145
+ "value": "Thesis (Ph.D.)--Stanford University, 2015."
146
+ },
147
+ {
148
+ "type": "statementOfResponsibility",
149
+ "value": "Derisa Grant."
150
+ }
151
+ ],
152
+ "accessURL": [{
153
+ "type": "purl",
154
+ "url": "http://purl.stanford.edu/xn109qc9773",
155
+ "primary": "TRUE"
156
+ }]
157
+ }
158
+ }
data/lib/cocina/models.rb CHANGED
@@ -5,6 +5,7 @@ require 'zeitwerk'
5
5
  require 'dry-struct'
6
6
  require 'dry-types'
7
7
 
8
+ # Help Zeitwerk find some of our classes
8
9
  class CocinaModelsInflector < Zeitwerk::Inflector
9
10
  def camelize(basename, _abspath)
10
11
  case basename
@@ -24,8 +25,27 @@ loader.push_dir(File.absolute_path("#{__FILE__}/../.."))
24
25
  loader.setup
25
26
 
26
27
  module Cocina
28
+ # Provides Ruby objects for the repository and serializing them to/from JSON.
27
29
  module Models
28
30
  class Error < StandardError; end
29
- # Your code goes here...
31
+ # Raised when the type attribute is not valid.
32
+ class UnknownTypeError < Error; end
33
+
34
+ # @param [Hash] dyn a ruby hash representation of the JSON serialization of a collection or DRO
35
+ # @return [DRO,Collection]
36
+ # @raises [UnknownTypeError] if a valid type is not found in the data
37
+ # @raises [KeyError] if a type field cannot be found in the data
38
+ def self.build(dyn)
39
+ case dyn.fetch('type')
40
+ when *DRO::TYPES
41
+ DRO.from_dynamic(dyn)
42
+ when *Collection::TYPES
43
+ Collection.from_dynamic(dyn)
44
+ when *AdminPolicy::TYPES
45
+ AdminPolicy.from_dynamic(dyn)
46
+ else
47
+ raise UnknownTypeError, "Unknown type: '#{dyn.fetch('type')}'"
48
+ end
49
+ end
30
50
  end
31
51
  end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+
5
+ module Cocina
6
+ module Models
7
+ # An admin policy object.
8
+ class AdminPolicy < Dry::Struct
9
+ TYPES = %w[http://cocina.sul.stanford.edu/models/admin_policy.jsonld].freeze
10
+
11
+ # Subschema for access concerns
12
+ class Access < Dry::Struct
13
+ def self.from_dynamic(_dyn)
14
+ params = {}
15
+ Access.new(params)
16
+ end
17
+ end
18
+
19
+ # Subschema for administrative concerns
20
+ class Administrative < Dry::Struct
21
+ def self.from_dynamic(_dyn)
22
+ params = {}
23
+ Administrative.new(params)
24
+ end
25
+ end
26
+
27
+ class Identification < Dry::Struct
28
+ end
29
+
30
+ class Structural < Dry::Struct
31
+ end
32
+
33
+ attribute :externalIdentifier, Types::Strict::String
34
+ attribute :type, Types::String.enum(*TYPES)
35
+ attribute :label, Types::Strict::String
36
+ attribute :version, Types::Coercible::Integer
37
+ attribute(:access, Access.default { Access.new })
38
+ attribute(:administrative, Administrative.default { Administrative.new })
39
+ attribute(:identification, Identification.default { Identification.new })
40
+ attribute(:structural, Structural.default { Structural.new })
41
+
42
+ def self.from_dynamic(dyn)
43
+ params = {
44
+ externalIdentifier: dyn['externalIdentifier'],
45
+ type: dyn['type'],
46
+ label: dyn['label'],
47
+ version: dyn['version']
48
+ }
49
+
50
+ # params[:access] = Access.from_dynamic(dyn['access']) if dyn['access']
51
+ # params[:administrative] = Administrative.from_dynamic(dyn['administrative']) if dyn['administrative']
52
+
53
+ AdminPolicy.new(params)
54
+ end
55
+
56
+ def self.from_json(json)
57
+ from_dynamic(JSON.parse(json))
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+
5
+ module Cocina
6
+ module Models
7
+ # A digital repository collection. See http://sul-dlss.github.io/cocina-models/maps/Collection.json
8
+ class Collection < Dry::Struct
9
+ TYPES = %w[http://cocina.sul.stanford.edu/models/collection.jsonld
10
+ http://cocina.sul.stanford.edu/models/curated-collection.jsonld
11
+ http://cocina.sul.stanford.edu/models/user-collection.jsonld
12
+ http://cocina.sul.stanford.edu/models/exhibit.jsonld
13
+ http://cocina.sul.stanford.edu/models/series.jsonld].freeze
14
+
15
+ # Subschema for access concerns
16
+ class Access < Dry::Struct
17
+ def self.from_dynamic(_dyn)
18
+ params = {}
19
+ Access.new(params)
20
+ end
21
+ end
22
+
23
+ # Subschema for administrative concerns
24
+ class Administrative < Dry::Struct
25
+ def self.from_dynamic(_dyn)
26
+ params = {}
27
+ Administrative.new(params)
28
+ end
29
+ end
30
+
31
+ class Identification < Dry::Struct
32
+ end
33
+
34
+ class Structural < Dry::Struct
35
+ end
36
+
37
+ attribute :externalIdentifier, Types::Strict::String
38
+ attribute :type, Types::String.enum(*TYPES)
39
+ attribute :label, Types::Strict::String
40
+ attribute :version, Types::Coercible::Integer
41
+ attribute(:access, Access.default { Access.new })
42
+ attribute(:administrative, Administrative.default { Administrative.new })
43
+ attribute(:identification, Identification.default { Identification.new })
44
+ attribute(:structural, Structural.default { Structural.new })
45
+
46
+ def self.from_dynamic(dyn)
47
+ params = {
48
+ externalIdentifier: dyn['externalIdentifier'],
49
+ type: dyn['type'],
50
+ label: dyn['label'],
51
+ version: dyn['version']
52
+ }
53
+
54
+ # params[:access] = Access.from_dynamic(dyn['access']) if dyn['access']
55
+ # params[:administrative] = Administrative.from_dynamic(dyn['administrative']) if dyn['administrative']
56
+
57
+ Collection.new(params)
58
+ end
59
+
60
+ def self.from_json(json)
61
+ from_dynamic(JSON.parse(json))
62
+ end
63
+ end
64
+ end
65
+ end
@@ -4,27 +4,90 @@ require 'json'
4
4
 
5
5
  module Cocina
6
6
  module Models
7
- # A digital repository object. See https://github.com/sul-dlss-labs/taco/blob/master/maps/DRO.json
7
+ # A digital repository object. See http://sul-dlss.github.io/cocina-models/maps/DRO.json
8
8
  class DRO < Dry::Struct
9
+ TYPES = %w[
10
+ http://cocina.sul.stanford.edu/models/object.jsonld
11
+ http://cocina.sul.stanford.edu/models/3d.jsonld
12
+ http://cocina.sul.stanford.edu/models/agreement.jsonl
13
+ http://cocina.sul.stanford.edu/models/book.jsonld
14
+ http://cocina.sul.stanford.edu/models/document.jsonld
15
+ http://cocina.sul.stanford.edu/models/geo.jsonld
16
+ http://cocina.sul.stanford.edu/models/image.jsonld
17
+ http://cocina.sul.stanford.edu/models/page.jsonld
18
+ http://cocina.sul.stanford.edu/models/photograph.jsonld
19
+ http://cocina.sul.stanford.edu/models/manuscript.jsonld
20
+ http://cocina.sul.stanford.edu/models/map.jsonld
21
+ http://cocina.sul.stanford.edu/models/media.jsonld
22
+ http://cocina.sul.stanford.edu/models/track.jsonld
23
+ http://cocina.sul.stanford.edu/models/webarchive-binary.jsonld
24
+ http://cocina.sul.stanford.edu/models/webarchive-seed.jsonld
25
+ ].freeze
26
+ # Subschema for release tags
27
+ class ReleaseTag < Dry::Struct
28
+ attribute :to, Types::Strict::String
29
+ attribute :what, Types::Strict::String.enum('self', 'collection')
30
+ # we use 'when' other places, but that's reserved word, so 'date' it is!
31
+ attribute :date, Types::Params::DateTime
32
+ attribute :who, Types::Strict::String
33
+ attribute :release, Types::Params::Bool
34
+
35
+ def self.from_dynamic(dyn)
36
+ ReleaseTag.new(to: dyn['to'],
37
+ what: dyn['what'],
38
+ date: dyn['date'],
39
+ who: dyn['who'],
40
+ release: dyn['release'])
41
+ end
42
+ end
43
+
44
+ # Subschema for access concerns
45
+ class Access < Dry::Struct
46
+ attribute :embargoReleaseDate, Types::Params::DateTime.meta(omittable: true)
47
+
48
+ def self.from_dynamic(dyn)
49
+ params = {}
50
+ params[:embargoReleaseDate] = dyn['embargoReleaseDate'] if dyn['embargoReleaseDate']
51
+ Access.new(params)
52
+ end
53
+ end
54
+
55
+ # Subschema for administrative concerns
56
+ class Administrative < Dry::Struct
57
+ attribute :releaseTags, Types::Strict::Array.of(ReleaseTag).meta(omittable: true)
58
+
59
+ def self.from_dynamic(dyn)
60
+ params = {}
61
+ params[:releaseTags] = dyn['releaseTags'].map { |rt| ReleaseTag.from_dynamic(rt) } if dyn['releaseTags']
62
+ Administrative.new(params)
63
+ end
64
+ end
65
+
66
+ class Identification < Dry::Struct
67
+ end
68
+
69
+ class Structural < Dry::Struct
70
+ end
71
+
9
72
  attribute :externalIdentifier, Types::Strict::String
10
- attribute :type, Types::Strict::String
73
+ attribute :type, Types::String.enum(*TYPES)
11
74
  attribute :label, Types::Strict::String
12
- attribute :access, Dry::Struct.meta(omittable: true) do
13
- attribute :embargoReleaseDate, Types::Params::Date
14
- end
75
+ attribute :version, Types::Coercible::Integer
76
+ attribute(:access, Access.default { Access.new })
77
+ attribute(:administrative, Administrative.default { Administrative.new })
78
+ attribute(:identification, Identification.default { Identification.new })
79
+ attribute(:structural, Structural.default { Structural.new })
15
80
 
16
- def self.from_dynamic(d)
81
+ def self.from_dynamic(dyn)
17
82
  params = {
18
- externalIdentifier: d['externalIdentifier'],
19
- type: d['type'],
20
- label: d['label']
83
+ externalIdentifier: dyn['externalIdentifier'],
84
+ type: dyn['type'],
85
+ label: dyn['label'],
86
+ version: dyn['version']
21
87
  }
22
- if d['access']
23
- access = {
24
- embargoReleaseDate: d['access']['embargoReleaseDate']
25
- }
26
- params[:access] = access
27
- end
88
+
89
+ params[:access] = Access.from_dynamic(dyn['access']) if dyn['access']
90
+ params[:administrative] = Administrative.from_dynamic(dyn['administrative']) if dyn['administrative']
28
91
 
29
92
  DRO.new(params)
30
93
  end