talia_core 0.4.3 → 0.4.4
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +6 -27
- data/VERSION.yml +3 -2
- data/config/database.yml +11 -11
- data/config/talia_core.yml +11 -6
- data/config/talia_core.yml.example +11 -6
- data/generators/talia_base/talia_base_generator.rb +3 -0
- data/generators/talia_base/templates/README +1 -1
- data/generators/talia_base/templates/app/controllers/source_data_controller.rb +1 -1
- data/generators/talia_base/templates/app/controllers/sources_controller.rb +31 -12
- data/generators/talia_base/templates/app/helpers/sources_helper.rb +77 -1
- data/generators/talia_base/templates/app/views/layouts/sources.html.erb +22 -0
- data/generators/talia_base/templates/app/views/sources/_data_list.html.erb +17 -0
- data/generators/talia_base/templates/app/views/sources/_property_item.html.erb +10 -0
- data/generators/talia_base/templates/app/views/sources/_property_list.html.erb +13 -0
- data/generators/talia_base/templates/app/views/sources/index.html.erb +16 -11
- data/generators/talia_base/templates/app/views/sources/semantic_templates/default/default.html.erb +8 -19
- data/generators/talia_base/templates/config/routes.rb +11 -0
- data/generators/talia_base/templates/migrations/create_semantic_relations.rb +2 -1
- data/generators/talia_base/templates/public/images/core/arrow.png +0 -0
- data/generators/talia_base/templates/public/images/core/building.png +0 -0
- data/generators/talia_base/templates/public/images/core/contents_top_left.gif +0 -0
- data/generators/talia_base/templates/public/images/core/document-horizontal-text.png +0 -0
- data/generators/talia_base/templates/public/images/core/document.png +0 -0
- data/generators/talia_base/templates/public/images/core/gear.png +0 -0
- data/generators/talia_base/templates/public/images/core/group.png +0 -0
- data/generators/talia_base/templates/public/images/core/header_bg.gif +0 -0
- data/generators/talia_base/templates/public/images/core/image.png +0 -0
- data/generators/talia_base/templates/public/images/core/imagebig.png +0 -0
- data/generators/talia_base/templates/public/images/core/left_edge.gif +0 -0
- data/generators/talia_base/templates/public/images/core/letter.png +0 -0
- data/generators/talia_base/templates/public/images/core/line.png +0 -0
- data/generators/talia_base/templates/public/images/core/logo.gif +0 -0
- data/generators/talia_base/templates/public/images/core/map.png +0 -0
- data/generators/talia_base/templates/public/images/core/period.png +0 -0
- data/generators/talia_base/templates/public/images/core/person.png +0 -0
- data/generators/talia_base/templates/public/images/core/person_default.png +0 -0
- data/generators/talia_base/templates/public/images/core/place.png +0 -0
- data/generators/talia_base/templates/public/images/core/source.png +0 -0
- data/generators/talia_base/templates/public/images/core/television.png +0 -0
- data/generators/talia_base/templates/public/images/core/text.png +0 -0
- data/generators/talia_base/templates/public/images/core/type.png +0 -0
- data/generators/talia_base/templates/public/images/core/video.png +0 -0
- data/generators/talia_base/templates/public/stylesheets/img/arrow.png +0 -0
- data/generators/talia_base/templates/public/stylesheets/main.css +276 -0
- data/generators/talia_base/templates/script/configure_talia +1 -1
- data/generators/talia_base/templates/script/setup_talia_backend +2 -0
- data/lib/core_ext/platform.rb +1 -0
- data/lib/core_ext/string.rb +6 -0
- data/lib/talia_core/active_source.rb +62 -3
- data/lib/talia_core/active_source_parts/class_methods.rb +36 -122
- data/lib/talia_core/active_source_parts/finders.rb +158 -0
- data/lib/talia_core/active_source_parts/predicate_handler.rb +7 -8
- data/lib/talia_core/active_source_parts/xml/generic_reader.rb +95 -11
- data/lib/talia_core/active_source_parts/xml/rdf_builder.rb +6 -13
- data/lib/talia_core/active_source_parts/xml/source_reader.rb +8 -3
- data/lib/talia_core/data_types/data_loader.rb +14 -6
- data/lib/talia_core/data_types/data_record.rb +5 -1
- data/lib/talia_core/data_types/iip_data.rb +1 -1
- data/lib/talia_core/data_types/mime_mapping.rb +8 -3
- data/lib/talia_core/errors.rb +4 -0
- data/lib/talia_core/initializer.rb +1 -8
- data/lib/talia_core/property_string.rb +58 -0
- data/lib/talia_core/semantic_collection_item.rb +3 -2
- data/lib/talia_core/semantic_collection_wrapper.rb +236 -198
- data/lib/talia_core/source.rb +130 -178
- data/lib/talia_core/source_types/collection.rb +15 -0
- data/lib/talia_core/source_types/dc_resource.rb +22 -0
- data/lib/talia_core/source_types/dummy_source.rb +22 -0
- data/lib/talia_core.rb +0 -1
- data/lib/talia_util/import_job_helper.rb +44 -16
- data/lib/talia_util/io_helper.rb +21 -1
- data/lib/talia_util/rake_tasks.rb +48 -72
- data/lib/talia_util/rdf_update.rb +22 -13
- data/lib/talia_util/test_helpers.rb +1 -1
- data/lib/talia_util.rb +0 -2
- data/test/core_ext/string_test.rb +5 -0
- data/test/talia_core/active_source_test.rb +151 -14
- data/test/talia_core/generic_xml_test.rb +46 -2
- data/test/talia_core/initializer_test.rb +0 -1
- data/test/talia_core/property_string_test.rb +78 -0
- data/test/talia_core/source_reader_test.rb +5 -1
- data/test/talia_core/source_test.rb +23 -32
- data/test/talia_util/import_job_helper_test.rb +1 -1
- data/test/talia_util/io_helper_test.rb +44 -0
- metadata +399 -373
- data/generators/talia_base/templates/app/views/sources/semantic_templates/default/province.html.erb +0 -19
- data/lib/acts_as_roled.rb +0 -11
- data/lib/talia_core/collection.rb +0 -13
- data/lib/talia_core/dc_resource.rb +0 -20
- data/lib/talia_core/dummy_source.rb +0 -20
- data/lib/talia_core/rails_ext/actionpack/action_controller/record_identifier.rb +0 -13
- data/lib/talia_core/rails_ext/actionpack/action_controller.rb +0 -1
- data/lib/talia_core/rails_ext/actionpack.rb +0 -1
- data/lib/talia_core/rails_ext.rb +0 -1
- data/lib/talia_util/data_import.rb +0 -91
- data/lib/talia_util/yaml_import.rb +0 -80
@@ -0,0 +1,276 @@
|
|
1
|
+
/* CSS Document */
|
2
|
+
|
3
|
+
|
4
|
+
/* ***************** ************** ************** */
|
5
|
+
/* ***************** TAG GENERICI ************** */
|
6
|
+
/* ***************** ************** ************** */
|
7
|
+
* {margin: 0; padding: 0;}
|
8
|
+
|
9
|
+
|
10
|
+
body {
|
11
|
+
text-align:left;
|
12
|
+
color:#333;
|
13
|
+
margin: 0;
|
14
|
+
padding: 0;
|
15
|
+
border: 0;
|
16
|
+
font-family: Avenir, "Lucida Grande", Verdana, "Bitstream Vera Sans", Arial, Helvetica, sans-serif;
|
17
|
+
font-size:0.8125em;
|
18
|
+
background: #FFF url(/images/core/left_edge.gif) top left repeat-y;
|
19
|
+
}
|
20
|
+
|
21
|
+
|
22
|
+
/* DEFINIZIONE TAG */
|
23
|
+
a{
|
24
|
+
color: #355a8e;
|
25
|
+
text-decoration: none;
|
26
|
+
outline: none;
|
27
|
+
}
|
28
|
+
a:hover{
|
29
|
+
color: #355a8e;
|
30
|
+
text-decoration: underline;
|
31
|
+
background-color: transparent;
|
32
|
+
}
|
33
|
+
h1{
|
34
|
+
font-size:1.3em;
|
35
|
+
margin-bottom: 5px;
|
36
|
+
}
|
37
|
+
h2{
|
38
|
+
font-size:1.2em;
|
39
|
+
margin-bottom: 5px;
|
40
|
+
}
|
41
|
+
h3{
|
42
|
+
font-size:1.1em;
|
43
|
+
margin-bottom: 5px;
|
44
|
+
}
|
45
|
+
p{
|
46
|
+
color:#333333;
|
47
|
+
line-height:1.7em;
|
48
|
+
font-size:0.9em;
|
49
|
+
margin-bottom: 5px;
|
50
|
+
}
|
51
|
+
|
52
|
+
td {
|
53
|
+
padding-right: 3ex;
|
54
|
+
}
|
55
|
+
/* DEFINIZIONE TAG */
|
56
|
+
|
57
|
+
|
58
|
+
/* Taglist */
|
59
|
+
div.tags {
|
60
|
+
margin-bottom: 0.5em;
|
61
|
+
margin-top: 0.5em;
|
62
|
+
padding: 0.3em;
|
63
|
+
background-color: #F1F1F1;
|
64
|
+
line-height: 1.5em;
|
65
|
+
}
|
66
|
+
|
67
|
+
span.tag {
|
68
|
+
background-color: #C0C0C0;
|
69
|
+
margin: 5px;
|
70
|
+
}
|
71
|
+
|
72
|
+
span.tag_selected {
|
73
|
+
background-color: #A0A0E0;
|
74
|
+
margin: 5px;
|
75
|
+
}
|
76
|
+
|
77
|
+
/* ***************** ************** ************** */
|
78
|
+
/* ***************** CLASSI RICORRENTI ************** */
|
79
|
+
/* ***************** ************** ************** */
|
80
|
+
.hidden{
|
81
|
+
display:none;
|
82
|
+
}
|
83
|
+
|
84
|
+
.floatClear{
|
85
|
+
clear:both;
|
86
|
+
}
|
87
|
+
|
88
|
+
/* ***************** ************** ************** */
|
89
|
+
/* ***************** HEADER ************** */
|
90
|
+
/* ***************** ************** ************** */
|
91
|
+
|
92
|
+
|
93
|
+
#title_bar h1{
|
94
|
+
padding: 13px 0 0 13px;
|
95
|
+
}
|
96
|
+
#title_bar h1 a{
|
97
|
+
font-size:1.7em;
|
98
|
+
color:#FFFFFF;
|
99
|
+
display: block;
|
100
|
+
width: 235px;
|
101
|
+
height: 97px;
|
102
|
+
background: transparent url(/images/core/logo.gif) top left no-repeat;
|
103
|
+
text-indent: -9999px;
|
104
|
+
}
|
105
|
+
|
106
|
+
#title_bar p.header_subtitle{
|
107
|
+
display: none;
|
108
|
+
}
|
109
|
+
|
110
|
+
div#title_bar{
|
111
|
+
height: 122px;
|
112
|
+
margin:0;
|
113
|
+
padding:0;
|
114
|
+
border:0;
|
115
|
+
width:100%;
|
116
|
+
background:#666 url(/images/core/header_bg.gif) top left repeat;
|
117
|
+
}
|
118
|
+
|
119
|
+
/* ***************** ************** ************** */
|
120
|
+
/* ***************** CONTENTS ************** */
|
121
|
+
/* ***************** ************** ************** */
|
122
|
+
#contents {
|
123
|
+
padding: 25px;
|
124
|
+
background:transparent url(/images/core/contents_top_left.gif) top left repeat-x;
|
125
|
+
}
|
126
|
+
|
127
|
+
/* ***************** ************** ************** */
|
128
|
+
/* ***************** FOOTER ************** */
|
129
|
+
/* ***************** ************** ************** */
|
130
|
+
/* tree: #footer h1, #footer p */
|
131
|
+
#footer.open{
|
132
|
+
margin: 0 0 0 300px;
|
133
|
+
}
|
134
|
+
|
135
|
+
/* !!!! SIDE BAR CHIUSO !!!! */
|
136
|
+
#footer.closed{
|
137
|
+
margin-left:73px;
|
138
|
+
}
|
139
|
+
|
140
|
+
#select-container {
|
141
|
+
margin-bottom: 3ex;
|
142
|
+
}
|
143
|
+
|
144
|
+
|
145
|
+
/* ***************** ************** ************** */
|
146
|
+
/* ***************** Barbz demo stuff ************** */
|
147
|
+
/* ***************** ************** ************** */
|
148
|
+
.sources_list ul {
|
149
|
+
width: 100%;
|
150
|
+
list-style: none;
|
151
|
+
}
|
152
|
+
|
153
|
+
.sources_list ul li {
|
154
|
+
border-bottom: 1px solid #d8d8d8;
|
155
|
+
width: 100%;
|
156
|
+
padding-bottom: 0;
|
157
|
+
float: left;
|
158
|
+
}
|
159
|
+
|
160
|
+
.sources_list ul li p {
|
161
|
+
float: left;
|
162
|
+
width: 100%;
|
163
|
+
background: #f9f9f9;
|
164
|
+
margin: 0;
|
165
|
+
padding:0 }
|
166
|
+
|
167
|
+
.sources_list ul li p .source_type {
|
168
|
+
display: block;
|
169
|
+
float: left;
|
170
|
+
width: 10%;
|
171
|
+
padding:6px 1%;
|
172
|
+
/*background:#f8f8f8 url(img/type.png) repeat-x bottom;*/
|
173
|
+
/*border-bottom: 1px solid #ccc;*/
|
174
|
+
voice-family: "\"}\"";
|
175
|
+
voice-family:inherit;
|
176
|
+
width:8%
|
177
|
+
}
|
178
|
+
|
179
|
+
.sources_list ul li p .source_title {
|
180
|
+
display: block;
|
181
|
+
float: left;
|
182
|
+
width: 45%;
|
183
|
+
font-size:12px ;
|
184
|
+
background: #f2f2f2;
|
185
|
+
font-weight: bold;
|
186
|
+
padding:6px 1% ;
|
187
|
+
voice-family: "\"}\"";
|
188
|
+
voice-family:inherit;
|
189
|
+
width:43%
|
190
|
+
}
|
191
|
+
|
192
|
+
|
193
|
+
|
194
|
+
.sources_list ul li p .source-data {
|
195
|
+
display: block;
|
196
|
+
float: left;
|
197
|
+
width: 35%;
|
198
|
+
padding: 7px 1% 7px 1%;
|
199
|
+
voice-family: "\"}\"";
|
200
|
+
voice-family:inherit;
|
201
|
+
width:33%
|
202
|
+
}
|
203
|
+
|
204
|
+
.sources_list ul li p .more {
|
205
|
+
width: 10%;
|
206
|
+
float: left;
|
207
|
+
padding: 6px 0; font-size:12px ;
|
208
|
+
background: url(img/arrow.png) no-repeat right;
|
209
|
+
display: block;
|
210
|
+
}
|
211
|
+
|
212
|
+
|
213
|
+
|
214
|
+
.sources_list ul li p .more a{
|
215
|
+
color: #999;
|
216
|
+
}
|
217
|
+
|
218
|
+
a img {
|
219
|
+
border: 0px none;
|
220
|
+
}
|
221
|
+
|
222
|
+
/* Styles for the Person template*/
|
223
|
+
|
224
|
+
div#tl {
|
225
|
+
margin-bottom: 30px;
|
226
|
+
margin-top: 30px;
|
227
|
+
}
|
228
|
+
|
229
|
+
|
230
|
+
.properties_list ul {
|
231
|
+
width: 100%;
|
232
|
+
list-style: none;
|
233
|
+
}
|
234
|
+
|
235
|
+
.properties_list ul li {
|
236
|
+
border-bottom: 1px solid #d8d8d8;
|
237
|
+
width: 100%;
|
238
|
+
padding-bottom: 0;
|
239
|
+
float: left;
|
240
|
+
}
|
241
|
+
|
242
|
+
.properties_list ul li p {
|
243
|
+
float: left;
|
244
|
+
width: 100%;
|
245
|
+
background: #f9f9f9;
|
246
|
+
margin: 0;
|
247
|
+
padding:0 }
|
248
|
+
|
249
|
+
.properties_list ul li p .predicate {
|
250
|
+
display: block;
|
251
|
+
float: left;
|
252
|
+
width: 10%;
|
253
|
+
padding:6px 1%;
|
254
|
+
/*background:#f8f8f8 url(img/type.png) repeat-x bottom;*/
|
255
|
+
/*border-bottom: 1px solid #ccc;*/
|
256
|
+
voice-family: "\"}\"";
|
257
|
+
voice-family:inherit;
|
258
|
+
width:8%
|
259
|
+
}
|
260
|
+
|
261
|
+
.properties_list ul li p .value {
|
262
|
+
display: block;
|
263
|
+
float: left;
|
264
|
+
width: 45%;
|
265
|
+
font-size:12px ;
|
266
|
+
background: #f2f2f2;
|
267
|
+
font-weight: bold;
|
268
|
+
padding:6px 1% ;
|
269
|
+
voice-family: "\"}\"";
|
270
|
+
voice-family:inherit;
|
271
|
+
width:43%
|
272
|
+
}
|
273
|
+
.person hr
|
274
|
+
{
|
275
|
+
margin-top:30px;
|
276
|
+
}
|
@@ -24,6 +24,8 @@ if(Rails::VERSION::MAJOR > 2 ||(Rails::VERSION::MAJOR == 2 && Rails::VERSION::MI
|
|
24
24
|
Commands::Plugin.parse!(['install', 'git://github.com/lackac/render_component.git', '-r', 'rails-edge'])
|
25
25
|
end
|
26
26
|
|
27
|
+
puts "Install the auto completion plugin"
|
28
|
+
Commands::Plugin.parse!(['install', 'auto_complete'])
|
27
29
|
|
28
30
|
puts "Install the adminstration backend"
|
29
31
|
Rails::Generator::Scripts::Generate.new.run(%w(talia_admin))
|
data/lib/core_ext/platform.rb
CHANGED
data/lib/core_ext/string.rb
CHANGED
@@ -24,6 +24,7 @@ module TaliaCore
|
|
24
24
|
include RDFS::ResourceLike
|
25
25
|
|
26
26
|
extend ActiveSourceParts::ClassMethods
|
27
|
+
extend ActiveSourceParts::Finders
|
27
28
|
extend ActiveSourceParts::SqlHelper
|
28
29
|
include ActiveSourceParts::PredicateHandler
|
29
30
|
extend ActiveSourceParts::PredicateHandler::ClassMethods
|
@@ -49,7 +50,7 @@ module TaliaCore
|
|
49
50
|
:class_name => 'TaliaCore::SemanticRelation'
|
50
51
|
has_many :subjects, :through => :related_subjects
|
51
52
|
|
52
|
-
validates_format_of :uri, :with => /\A\S*:.*\Z
|
53
|
+
validates_format_of :uri, :with => /\A\S*:.*\Z/, :message => '<{{value}}> does not look like an uri.'
|
53
54
|
validates_uniqueness_of :uri
|
54
55
|
|
55
56
|
before_destroy :remove_inverse_properties # Remove inverse properties when destroying an element
|
@@ -67,6 +68,11 @@ module TaliaCore
|
|
67
68
|
|
68
69
|
validate :check_uri
|
69
70
|
|
71
|
+
# Uri in short notation
|
72
|
+
def short_uri
|
73
|
+
N::URI.new(self.uri).to_name_s
|
74
|
+
end
|
75
|
+
|
70
76
|
# Helper
|
71
77
|
def value_for(thing)
|
72
78
|
self.class.value_for(thing)
|
@@ -77,6 +83,11 @@ module TaliaCore
|
|
77
83
|
def to_s
|
78
84
|
self[:uri]
|
79
85
|
end
|
86
|
+
|
87
|
+
# Create a new uri object
|
88
|
+
def to_uri
|
89
|
+
self[:uri].to_uri
|
90
|
+
end
|
80
91
|
|
81
92
|
# Works in the normal way for database attributes. If the value
|
82
93
|
# is not an attribute, it tries to find objects related to this source
|
@@ -107,6 +118,53 @@ module TaliaCore
|
|
107
118
|
alias :update_attributes_orig :update_attributes
|
108
119
|
alias :update_attributes_orig! :update_attributes!
|
109
120
|
|
121
|
+
|
122
|
+
# Updates the source with the given properties. The 'mode' field indicates if
|
123
|
+
# and how the update will be performed. See the ImportJobHelper class for
|
124
|
+
# the different modes.
|
125
|
+
#
|
126
|
+
# As opposed to the *_attributes method, this will also handle file elements.
|
127
|
+
# The default mode is :skip (do nothing)
|
128
|
+
def update_source(properties, mode)
|
129
|
+
properties.to_options!
|
130
|
+
mode = :update if(self.is_a?(SourceTypes::DummySource)) # Dummy sources are always updated
|
131
|
+
mode ||= :skip
|
132
|
+
mode = mode.to_sym
|
133
|
+
return self if(mode == :skip) # If we're told to ignore updates
|
134
|
+
|
135
|
+
# Deal with already existing sources
|
136
|
+
files = properties.delete(:files)
|
137
|
+
|
138
|
+
if(mode == :overwrite)
|
139
|
+
# If we are to overwrite, delete all relations and update normally
|
140
|
+
self.semantic_relations.destroy_all
|
141
|
+
self.data_records.destroy_all
|
142
|
+
mode = :update
|
143
|
+
elsif(mode == :update && files && self.data_records.size > 0)
|
144
|
+
# On updating we should only remove the files if there are new ones
|
145
|
+
self.data_records.destroy_all
|
146
|
+
end
|
147
|
+
|
148
|
+
# Add any files
|
149
|
+
attach_files(files) if(files)
|
150
|
+
|
151
|
+
# Rewrite the type, if neccessary
|
152
|
+
type = properties[:type]
|
153
|
+
switch_type = type && (self.type != type)
|
154
|
+
# Warn to the log if we have a problematic type change
|
155
|
+
TaliaCore.logger.warn("WARNING: Type change from #{self.type} to #{type}") if(switch_type && !self.is_a?(SourceTypes::DummySource))
|
156
|
+
self.type = type if(switch_type)
|
157
|
+
|
158
|
+
# Now we should either be adding or updating
|
159
|
+
assit(mode == :update || mode == :add)
|
160
|
+
update = (mode == :update)
|
161
|
+
|
162
|
+
# Overwrite with or add the imported attributes
|
163
|
+
update ? rewrite_attributes(properties) : update_attributes(properties)
|
164
|
+
|
165
|
+
self
|
166
|
+
end
|
167
|
+
|
110
168
|
# Updates *all* attributes of this source. For the database attributes, this works
|
111
169
|
# exactly like ActiveRecord::Base#update_attributes
|
112
170
|
#
|
@@ -304,6 +362,7 @@ module TaliaCore
|
|
304
362
|
# given, it will retrieve only the specified data element
|
305
363
|
def data(type = nil, location= nil)
|
306
364
|
find_type = location ? :first : :all # Find just one element if a location is given
|
365
|
+
type = type.name if(type.is_a?(Class))
|
307
366
|
options = {}
|
308
367
|
options[:conditions] = [ "type = ?", type ] if(type && !location)
|
309
368
|
options[:conditions] = [ "type = ? AND location = ?", type, location ] if(type && location)
|
@@ -331,13 +390,13 @@ module TaliaCore
|
|
331
390
|
# string it will be returned as a string.
|
332
391
|
def target_for(value)
|
333
392
|
return value if(value.kind_of?(N::URI) || value.kind_of?(ActiveSource))
|
334
|
-
|
393
|
+
assit_block { |msg| msg << "Expected #{value.inspect} to be a String" unless(value.is_a?(String)) ; value.is_a?(String) }
|
335
394
|
value.strip!
|
336
395
|
if((value[0..0] == '<') && (value[-1..-1] == '>'))
|
337
396
|
value = ActiveSource.expand_uri(value [1..-2])
|
338
397
|
val_src = ActiveSource.find(:first, :conditions => { :uri => value })
|
339
398
|
if(!val_src)
|
340
|
-
value = DummySource.new(value)
|
399
|
+
value = SourceTypes::DummySource.new(value)
|
341
400
|
value.save!
|
342
401
|
else
|
343
402
|
value = val_src
|
@@ -19,9 +19,13 @@ module TaliaCore
|
|
19
19
|
# on creation. This will call the attach_files method on the object.
|
20
20
|
def new(*args)
|
21
21
|
the_source = if((args.size == 1) && (args.first.is_a?(Hash)))
|
22
|
+
options = args.first
|
23
|
+
options.to_options!
|
24
|
+
|
22
25
|
# We have an option hash to init the source
|
23
|
-
files =
|
24
|
-
|
26
|
+
files = options.delete(:files)
|
27
|
+
options[:uri] = uri_string_for(options[:uri])
|
28
|
+
attributes = split_attribute_hash(options)
|
25
29
|
the_source = super(attributes[:db_attributes])
|
26
30
|
the_source.add_semantic_attributes(false, attributes[:semantic_attributes])
|
27
31
|
the_source.attach_files(files) if(files)
|
@@ -41,7 +45,8 @@ module TaliaCore
|
|
41
45
|
# like #new, but it will correctly initialize a source of the type given
|
42
46
|
# in the hash. If no type is given, this will create a plain ActiveSource.
|
43
47
|
def create_source(args)
|
44
|
-
|
48
|
+
args.to_options!
|
49
|
+
type = args.delete(:type) || 'TaliaCore::ActiveSource'
|
45
50
|
klass = type.constantize
|
46
51
|
klass.new(args)
|
47
52
|
end
|
@@ -58,12 +63,17 @@ module TaliaCore
|
|
58
63
|
# [*reader*] The reader class that the import should use
|
59
64
|
# [*progressor*] The progress reporting object, which must respond to run_with_progress(message, size, &block)
|
60
65
|
# [*errors*] If given, all erors will be looged to this array instead of raising
|
61
|
-
# an exception
|
66
|
+
# an exception. See the create_multi_from method for more.
|
67
|
+
# [*duplicates*] How to treat alredy existing sources. See ImportJobHelper for more
|
68
|
+
# documentation
|
69
|
+
# [*base_file_uri*] The base uri to import file from
|
62
70
|
def create_from_xml(xml, options = {})
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
71
|
+
options.to_options!
|
72
|
+
options.assert_valid_keys(:reader, :progressor, :errors, :duplicates, :base_file_uri)
|
73
|
+
reader = options[:reader] ? options.delete(:reader).to_s.classify.constantize : TaliaCore::ActiveSourceParts::Xml::SourceReader
|
74
|
+
source_properties = reader.sources_from(xml, options[:progressor], options.delete(:base_file_uri))
|
75
|
+
self.progressor = options.delete(:progressor)
|
76
|
+
sources = create_multi_from(source_properties, options)
|
67
77
|
(sources.size > 1) ? sources : sources.first
|
68
78
|
end
|
69
79
|
|
@@ -72,32 +82,35 @@ module TaliaCore
|
|
72
82
|
# correctly.
|
73
83
|
#
|
74
84
|
# Options:
|
75
|
-
# [*errors*] If given, all erors will be
|
76
|
-
# an exception
|
85
|
+
# [*errors*] If given, all erors will be logged to this array instead of raising
|
86
|
+
# an exception. Each "entry" in the error array will be an Error object
|
87
|
+
# containing the origianl stack trace of the error
|
88
|
+
# [*duplicates*] Indicates how to deal with sources that already exist in the
|
89
|
+
# datastore. See the ImportJobHelper class for a documentation of
|
90
|
+
# this option. Default is :skip
|
77
91
|
def create_multi_from(sources, options = {})
|
92
|
+
options.to_options!
|
93
|
+
options.assert_valid_keys(:errors, :duplicates)
|
78
94
|
source_objects = []
|
79
95
|
run_with_progress('Writing imported', sources.size) do |progress|
|
80
96
|
source_objects = sources.collect do |props|
|
97
|
+
props.to_options!
|
81
98
|
src = nil
|
82
99
|
begin
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
type = props[:type] || props['type']
|
88
|
-
switch_type = type && (src.type != type)
|
89
|
-
# Warn to the log if we have a problematic type change
|
90
|
-
TaliaCore.logger.warn("WARNING: Type change from #{src.type} to #{type}") if(switch_type && !src.is_a?(DummySource))
|
91
|
-
src.type = type if(switch_type)
|
92
|
-
src
|
100
|
+
props[:uri] = uri_string_for(props[:uri])
|
101
|
+
assit(props[:uri], "Must have a valid uri at this step")
|
102
|
+
if(src = ActiveSource.find(:first, :conditions => { :uri => props[:uri] }))
|
103
|
+
src.update_source(props, options[:duplicates])
|
93
104
|
else
|
94
105
|
src = ActiveSource.create_source(props)
|
95
106
|
end
|
96
107
|
src.save!
|
97
108
|
rescue Exception => e
|
98
109
|
if(options[:errors])
|
99
|
-
|
100
|
-
|
110
|
+
err = ImportError.new("ERROR during import of #{props[:uri]}: #{e.message}")
|
111
|
+
err.set_backtrace(e.backtrace)
|
112
|
+
options[:errors] << err
|
113
|
+
TaliaCore.logger.warn("Problems importing #{props[:uri]} (logged): #{e.message}")
|
101
114
|
else
|
102
115
|
raise
|
103
116
|
end
|
@@ -119,41 +132,6 @@ module TaliaCore
|
|
119
132
|
end
|
120
133
|
end
|
121
134
|
|
122
|
-
|
123
|
-
# Finder also accepts uris as "ids". There are also some additional options
|
124
|
-
# that are accepted:
|
125
|
-
#
|
126
|
-
# [*:find_through*] accepts and array with an predicate name and an object
|
127
|
-
# value/uri, to search for predicates that match the given predicate/value
|
128
|
-
# combination
|
129
|
-
# [*:type*] specifically looks for sources with the given type.
|
130
|
-
# [*:find_through_inv*] like :find_through, but for the "inverse" lookup
|
131
|
-
# [*:prefetch_relations*] if set to "true", this will pre-load all semantic
|
132
|
-
# relations for the sources (experimental, not fully implemented yet)
|
133
|
-
def find(*args)
|
134
|
-
prefetching = false
|
135
|
-
if(args.last.is_a?(Hash))
|
136
|
-
options = args.last
|
137
|
-
prefetching = options.delete(:prefetch_relations)
|
138
|
-
if(options.empty?) # If empty we remove the args hash, so that the 1-param uri search works
|
139
|
-
args.pop
|
140
|
-
else
|
141
|
-
prepare_options!(args.last)
|
142
|
-
end
|
143
|
-
end
|
144
|
-
result = if(args.size == 1 && (uri_s = uri_string_for(args[0])))
|
145
|
-
src = super(:first, :conditions => { :uri => uri_s })
|
146
|
-
raise(ActiveRecord::RecordNotFound, "Not found: #{uri_s}") unless(src)
|
147
|
-
src
|
148
|
-
else
|
149
|
-
super
|
150
|
-
end
|
151
|
-
|
152
|
-
prefetch_relations_for(result) if(prefetching)
|
153
|
-
|
154
|
-
result
|
155
|
-
end
|
156
|
-
|
157
135
|
# Semantic version of ActiveRecord::Base#update - the id may be a record id or an URL,
|
158
136
|
# and the attributes may contain semantic attributes. See the update_attributes method
|
159
137
|
# for details on how the semantic attributes behave.
|
@@ -233,7 +211,7 @@ module TaliaCore
|
|
233
211
|
|
234
212
|
# The attributes stored in the database
|
235
213
|
def db_attributes
|
236
|
-
@db_attributes ||= ActiveSource.new.attribute_names
|
214
|
+
@db_attributes ||= (ActiveSource.new.attribute_names << 'id')
|
237
215
|
end
|
238
216
|
|
239
217
|
# Helper to define a "additional type" in subclasses which will
|
@@ -310,70 +288,6 @@ module TaliaCore
|
|
310
288
|
result
|
311
289
|
end
|
312
290
|
|
313
|
-
|
314
|
-
# Takes the "advanced" options that can be passed to the find method and
|
315
|
-
# converts them into "standard" find options.
|
316
|
-
def prepare_options!(options)
|
317
|
-
check_for_find_through!(options)
|
318
|
-
check_for_type_find!(options)
|
319
|
-
check_for_find_through_inv!(options)
|
320
|
-
end
|
321
|
-
|
322
|
-
# Checks if the :find_through option is set. If so, this expects the
|
323
|
-
# option to have 2 values: The first representing the URL of the predicate
|
324
|
-
# and the second the URL or value that should be matched.
|
325
|
-
#
|
326
|
-
# An optional third parameter can be used to force an object search on the
|
327
|
-
# semantic_properties table (instead of active_sources) - if not present
|
328
|
-
# this will be auto-guessed from the "object value", checking if it appears
|
329
|
-
# to be an URL or not.
|
330
|
-
#
|
331
|
-
# ...find(:find_through => [N::RDF::something, 'value', true]
|
332
|
-
def check_for_find_through!(options)
|
333
|
-
if(f_through = options.delete(:find_through))
|
334
|
-
assit_kind_of(Array, f_through)
|
335
|
-
raise(ArgumentError, "Passed non-hash conditions with :find_through") if(options.has_key?(:conditions) && !options[:conditions].is_a?(Hash))
|
336
|
-
raise(ArgumentError, "Cannot pass custom join conditions with :find_through") if(options.has_key?(:joins))
|
337
|
-
predicate = f_through[0]
|
338
|
-
obj_val = f_through[1]
|
339
|
-
search_prop = (f_through.size > 2) ? f_through[2] : !(obj_val.to_s =~ /:/)
|
340
|
-
options[:joins] = default_joins(!search_prop, search_prop)
|
341
|
-
options[:conditions] ||= {}
|
342
|
-
options[:conditions]['semantic_relations.predicate_uri'] = predicate.to_s
|
343
|
-
if(search_prop)
|
344
|
-
options[:conditions]['obj_props.value'] = obj_val.to_s
|
345
|
-
else
|
346
|
-
options[:conditions]['obj_sources.uri'] = obj_val.to_s
|
347
|
-
end
|
348
|
-
end
|
349
|
-
end
|
350
|
-
|
351
|
-
# Check for the :find_through_inv option. This expects the 2 basic values
|
352
|
-
# in the same way as :find_through.
|
353
|
-
#
|
354
|
-
# find(:find_through_inv => [N::RDF::to_me, my_uri]
|
355
|
-
def check_for_find_through_inv!(options)
|
356
|
-
if(f_through = options.delete(:find_through_inv))
|
357
|
-
assit_kind_of(Array, f_through)
|
358
|
-
raise(ArgumentError, "Passed non-hash conditions with :find_through") if(options.has_key?(:conditions) && !options[:conditions].is_a?(Hash))
|
359
|
-
raise(ArgumentError, "Cannot pass custom join conditions with :find_through") if(options.has_key?(:joins))
|
360
|
-
options[:joins] = default_inv_joins
|
361
|
-
options[:conditions] ||= {}
|
362
|
-
options[:conditions]['semantic_relations.predicate_uri'] = f_through[0].to_s
|
363
|
-
options[:conditions]['sub_sources.uri'] = f_through[1].to_s
|
364
|
-
end
|
365
|
-
end
|
366
|
-
|
367
|
-
|
368
|
-
# Checks for the :type option in the find options. This is the same as
|
369
|
-
# doing a :find_through on the rdf type
|
370
|
-
def check_for_type_find!(options)
|
371
|
-
if(f_type = options.delete(:type))
|
372
|
-
options[:find_through] = [N::RDF::type, f_type.to_s, false]
|
373
|
-
check_for_find_through!(options)
|
374
|
-
end
|
375
|
-
end
|
376
|
-
|
377
291
|
end
|
378
292
|
end
|
379
293
|
end
|