spreadskos 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. data/lib/spreadskos.rb +269 -0
  2. metadata +78 -0
data/lib/spreadskos.rb ADDED
@@ -0,0 +1,269 @@
1
+ # encoding: UTF-8
2
+ require 'linkeddata'
3
+ require 'roo'
4
+ require 'logger'
5
+
6
+ # Creates SKOS files from vocabulary data in a spreadsheet template.
7
+ class Spreadskos
8
+
9
+ def initialize(filepath=nil)
10
+
11
+ @log = defined?(Rails) ? Rails.logger : Logger.new(STDOUT)
12
+ @log.info("init")
13
+
14
+ @filepath = filepath
15
+ @default_lang = :en
16
+
17
+ @skos_objs = []
18
+ setup_skos
19
+
20
+ # start new SKOS doc output
21
+ @graph = RDF::Graph.new
22
+
23
+ # Load spreadsheet data
24
+ @spreadsheet = nil
25
+ load_spreadsheet(filepath)
26
+
27
+ # set up vocab basic info
28
+ @namespace = "http://example.com/your_namespace/"
29
+
30
+ setup_vocab_info
31
+
32
+ # Add concepts and related information
33
+ @concepts = []
34
+ add_concepts
35
+
36
+ end
37
+
38
+
39
+
40
+ # Load SKOS itself to be able to render labels etc later.
41
+ def setup_skos
42
+
43
+ skosfile = File.dirname(__FILE__) + ::File::SEPARATOR + "skos.rdf"
44
+ @log.info("Load SKOS itself to be able to render labels etc later. File: " + skosfile)
45
+
46
+ RDF::Reader.open(skosfile) do |reader|
47
+ reader.each_statement do |statement|
48
+ if statement.predicate == "http://www.w3.org/2000/01/rdf-schema#label" then
49
+ @skos_objs << {:obj => statement.subject.to_s.sub("http://www.w3.org/2004/02/skos/core#",""), :label => statement.object.to_s.downcase.strip}
50
+
51
+ @log.info("Adding #{statement.object.to_s.downcase.strip}, #{statement.subject.to_s}")
52
+ end
53
+ end
54
+ end
55
+
56
+ end
57
+
58
+
59
+
60
+ def load_spreadsheet(filepath)
61
+
62
+ @log.info("Loading #{filepath}")
63
+
64
+ if filepath then
65
+ @spreadsheet = Roo::Spreadsheet.open(filepath)
66
+ else
67
+ raise "Spreadsheet not found."
68
+ end
69
+ end
70
+
71
+
72
+
73
+ def setup_vocab_info
74
+
75
+ # Build concept scheme info from first sheet
76
+ info_sheet = @spreadsheet.sheet(0)
77
+
78
+ title = ""
79
+ description = ""
80
+ version = ""
81
+ creators = ""
82
+ contributors = ""
83
+
84
+ 1.upto(info_sheet.last_row) do |row_no|
85
+ case info_sheet.cell(row_no, 1)
86
+ when "Title:"
87
+ title = info_sheet.cell(row_no, 2)
88
+ when "Description:"
89
+ description = info_sheet.cell(row_no, 2)
90
+ when "Version:"
91
+ version = info_sheet.cell(row_no, 2)
92
+ when "Vocabulary identifier:"
93
+ @namespace = info_sheet.cell(row_no, 2)
94
+ when "Default language:"
95
+ @default_lang = info_sheet.cell(row_no, 2).strip
96
+ when "Creators:"
97
+ creators = info_sheet.cell(row_no, 2).strip.split(",")
98
+ when "Contributors:"
99
+ contributors = info_sheet.cell(row_no, 2).strip.split(",")
100
+ else
101
+ puts "Unknown property: " + info_sheet.cell(row_no, 1)
102
+ end
103
+ end
104
+
105
+ # Write it
106
+ @graph << [RDF::URI.new(@namespace), RDF.type, RDF::SKOS.ConceptScheme]
107
+ @graph << [RDF::URI.new(@namespace), RDF::RDFS.label, RDF::Literal.new(title, :language => @default_lang)]
108
+ @graph << [RDF::URI.new(@namespace), RDF::DC.description, RDF::Literal.new(description, :language => @default_lang)]
109
+
110
+ add_creators(creators)
111
+
112
+ add_contributors(contributors)
113
+
114
+ end
115
+
116
+
117
+
118
+ def add_creators(creators)
119
+ @log.info("adding creators")
120
+
121
+ creators.each do |creator|
122
+ @graph << [RDF::URI.new(@namespace), RDF::DC.creator, RDF::Literal.new(creator.strip)]
123
+ end
124
+ end
125
+
126
+
127
+
128
+ def add_contributors(contributors)
129
+ @log.info("adding contributors")
130
+
131
+ contributors.each do |contributor|
132
+ @graph << [RDF::URI.new(@namespace), RDF::DC.contributor, RDF::Literal.new(contributor.strip)]
133
+ end
134
+ end
135
+
136
+
137
+ def add_concepts
138
+
139
+ @log.info("adding concepts")
140
+
141
+ # Add concepts and labels from second worksheet
142
+ concept_sheet = @spreadsheet.sheet(1)
143
+
144
+ columns = []
145
+
146
+ # Build column model
147
+ 1.upto(concept_sheet.last_column) do |col_no|
148
+ @log.info("\tcol: " + concept_sheet.cell(1, col_no))
149
+ columns << concept_sheet.cell(1, col_no)
150
+ end
151
+
152
+
153
+ # Iterate rows
154
+ 2.upto(concept_sheet.last_row) do |row_no|
155
+
156
+ # Concepts fragments are in the first column
157
+ concept_fragment_id = concept_sheet.cell(row_no, 1)
158
+
159
+ if concept_fragment_id.size > 0 then
160
+
161
+ concept = uri_for_concept_fragment(concept_fragment_id)
162
+ @log.info("concept: " + concept)
163
+
164
+ # Add concept to graph
165
+ @graph << [concept, RDF.type, RDF::SKOS.Concept]
166
+
167
+ # Connect it to the concept scheme
168
+ add_concept_to_scheme(concept)
169
+
170
+ #loop columns for concept
171
+ 2.upto(concept_sheet.last_column) do |col_no|
172
+
173
+ # What property is this?
174
+ property, lang = skosname_and_lang_from_column_head(columns[col_no - 1])
175
+ @log.info("Prop+lang: #{property}, #{lang}")
176
+
177
+ #Value
178
+ value = concept_sheet.cell(row_no, col_no)
179
+ @log.info("Val: #{value}")
180
+
181
+ # literal?
182
+ if value and value.strip.size > 0
183
+ if value.start_with?("#") or value.start_with?("http")
184
+ # Add this property to the graph
185
+ add_property_to_graph(concept, property, value)
186
+ else
187
+ value = RDF::Literal.new(value, :language => lang)
188
+ add_property_to_graph(concept, property, value)
189
+ end
190
+ end
191
+
192
+ end
193
+ end
194
+
195
+ end
196
+
197
+ end
198
+
199
+
200
+
201
+ def add_property_to_graph(concept, property, value)
202
+ @graph << [concept, property, value]
203
+ end
204
+
205
+
206
+
207
+ def add_concept_to_scheme(concept)
208
+ @graph << [concept, RDF::SKOS.inScheme, @namespace]
209
+ end
210
+
211
+
212
+
213
+
214
+ def uri_for_concept_fragment(fragment)
215
+ if fragment.downcase.start_with?("http") then
216
+ # user edited their own concept identifier
217
+ return RDF::URI.new(fragment)
218
+ else
219
+ # make local identifier
220
+ return RDF::URI.new(@namespace + fragment)
221
+ end
222
+ end
223
+
224
+
225
+
226
+ def skosname_and_lang_from_column_head(column)
227
+
228
+ @log.info("\t Mapping column #{column}")
229
+
230
+ # find skos property from column header text (e.g. "Preferred label (en)")
231
+ label, lang = column.split("(")
232
+ if lang then
233
+ lang = lang.sub(")","").to_sym
234
+ else
235
+ # Default lang
236
+ lang = @default_lang
237
+ end
238
+
239
+ skosprop = skos_from_label(label)
240
+
241
+ @log.info("skosprop: #{skosprop}")
242
+
243
+ return skosprop, lang
244
+ end
245
+
246
+
247
+
248
+ def skos_from_label(label)
249
+ @log.info("Looking up >#{label.downcase.strip}<")
250
+
251
+ prop = @skos_objs.select {|o| o[:label] == label.downcase.strip }
252
+
253
+ @log.info(prop)
254
+
255
+ return eval("RDF::SKOS." + prop[0][:obj])
256
+ end
257
+
258
+
259
+ def write_graph(filename="result.rdf", format=:rdfxml)
260
+
261
+ puts @graph.dump(:rdfxml)
262
+
263
+ File.open(filename, 'w') { |file|
264
+ file.write(@graph.dump(format))
265
+ }
266
+
267
+ end
268
+
269
+ end
metadata ADDED
@@ -0,0 +1,78 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: spreadskos
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Peter Krantz
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-07-11 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rake
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rspec
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ description: Convert vocabularies created in a spreadsheet template to SKOS.
47
+ email: peter@peterkrantz.se
48
+ executables: []
49
+ extensions: []
50
+ extra_rdoc_files: []
51
+ files:
52
+ - lib/spreadskos.rb
53
+ homepage: http://rubygems.org/gems/spreadskos
54
+ licenses: []
55
+ post_install_message:
56
+ rdoc_options: []
57
+ require_paths:
58
+ - lib
59
+ required_ruby_version: !ruby/object:Gem::Requirement
60
+ none: false
61
+ requirements:
62
+ - - ! '>='
63
+ - !ruby/object:Gem::Version
64
+ version: '0'
65
+ required_rubygems_version: !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ! '>='
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ requirements: []
72
+ rubyforge_project:
73
+ rubygems_version: 1.8.24
74
+ signing_key:
75
+ specification_version: 3
76
+ summary: Spreadskos
77
+ test_files: []
78
+ has_rdoc: