spreadskos 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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: