talia_core 0.5.4 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (122) hide show
  1. data/VERSION.yml +2 -2
  2. data/config/talia_core.yml.example +37 -35
  3. data/generators/talia_admin/templates/app/models/fake_source.rb +93 -0
  4. data/generators/talia_admin/templates/app/models/talia_collection.rb +13 -37
  5. data/generators/talia_base/talia_base_generator.rb +0 -1
  6. data/generators/talia_base/templates/app/controllers/custom_templates_controller.rb +2 -1
  7. data/generators/talia_base/templates/app/controllers/sources_controller.rb +1 -1
  8. data/generators/talia_base/templates/script/configure_talia +56 -73
  9. data/generators/talia_swicky/talia_swicky_generator.rb +18 -0
  10. data/generators/talia_swicky/templates/app/controllers/swicky_notebooks_controller.rb +111 -0
  11. data/generators/talia_swicky/templates/app/helpers/swicky_notebooks_helper.rb +29 -0
  12. data/generators/talia_swicky/templates/app/views/swicky_notebooks/index.builder +6 -0
  13. data/generators/talia_swicky/templates/app/views/swicky_notebooks/index.html.erb +10 -0
  14. data/generators/talia_swicky/templates/app/views/swicky_notebooks/show.html.erb +11 -0
  15. data/generators/talia_swicky/templates/test/fixtures/notebook.rdf +862 -0
  16. data/generators/talia_swicky/templates/test/functional/swicky_notebooks_controller_test.rb +44 -0
  17. data/lib/core_ext/boolean.rb +23 -0
  18. data/lib/core_ext/jdbc_rake_monkeypatch.rb +22 -0
  19. data/lib/core_ext/nil_class.rb +11 -0
  20. data/lib/core_ext/object.rb +34 -0
  21. data/lib/core_ext/string.rb +15 -0
  22. data/lib/custom_template.rb +3 -1
  23. data/lib/loader_helper.rb +16 -3
  24. data/lib/mysql.rb +7 -7
  25. data/lib/progressbar.rb +2 -2
  26. data/lib/swicky/exhibit_json/item.rb +129 -0
  27. data/lib/swicky/exhibit_json/item_collection.rb +129 -0
  28. data/lib/swicky/fragment.rb +0 -0
  29. data/lib/swicky/note.rb +7 -0
  30. data/lib/swicky/notebook.rb +78 -12
  31. data/lib/talia_core/active_source.rb +45 -13
  32. data/lib/talia_core/active_source_parts/class_methods.rb +154 -26
  33. data/lib/talia_core/active_source_parts/finders.rb +49 -26
  34. data/lib/talia_core/active_source_parts/predicate_handler.rb +71 -23
  35. data/lib/talia_core/active_source_parts/rdf/ntriples_reader.rb +13 -0
  36. data/lib/talia_core/active_source_parts/rdf/rdf_reader.rb +99 -0
  37. data/lib/talia_core/active_source_parts/rdf/rdfxml_reader.rb +12 -0
  38. data/lib/talia_core/active_source_parts/{rdf.rb → rdf_handler.rb} +52 -19
  39. data/lib/talia_core/active_source_parts/xml/generic_reader.rb +151 -260
  40. data/lib/talia_core/active_source_parts/xml/generic_reader_add_statements.rb +97 -0
  41. data/lib/talia_core/active_source_parts/xml/generic_reader_helpers.rb +88 -0
  42. data/lib/talia_core/active_source_parts/xml/generic_reader_import_statements.rb +239 -0
  43. data/lib/talia_core/active_source_parts/xml/rdf_builder.rb +14 -7
  44. data/lib/talia_core/active_source_parts/xml/source_builder.rb +7 -3
  45. data/lib/talia_core/active_source_parts/xml/source_reader.rb +17 -2
  46. data/lib/talia_core/collection.rb +192 -1
  47. data/lib/talia_core/data_types/data_loader.rb +88 -18
  48. data/lib/talia_core/data_types/data_record.rb +24 -2
  49. data/lib/talia_core/data_types/delayed_copier.rb +13 -3
  50. data/lib/talia_core/data_types/file_record.rb +24 -13
  51. data/lib/talia_core/data_types/file_store.rb +111 -94
  52. data/lib/talia_core/data_types/iip_data.rb +104 -23
  53. data/lib/talia_core/data_types/iip_loader.rb +102 -56
  54. data/lib/talia_core/data_types/image_data.rb +3 -1
  55. data/lib/talia_core/data_types/media_link.rb +4 -1
  56. data/lib/talia_core/data_types/mime_mapping.rb +65 -38
  57. data/lib/talia_core/data_types/path_helpers.rb +23 -17
  58. data/lib/talia_core/data_types/pdf_data.rb +9 -6
  59. data/lib/talia_core/data_types/simple_text.rb +5 -4
  60. data/lib/talia_core/data_types/xml_data.rb +53 -25
  61. data/lib/talia_core/dummy_handler.rb +3 -2
  62. data/lib/talia_core/errors.rb +13 -27
  63. data/lib/talia_core/initializer.rb +44 -4
  64. data/lib/talia_core/oai/active_source_model.rb +13 -6
  65. data/lib/talia_core/oai/active_source_oai_adapter.rb +13 -12
  66. data/lib/talia_core/rdf_import.rb +1 -1
  67. data/lib/talia_core/rdf_resource.rb +2 -1
  68. data/lib/talia_core/semantic_collection_wrapper.rb +143 -151
  69. data/lib/talia_core/semantic_property.rb +4 -0
  70. data/lib/talia_core/semantic_relation.rb +84 -33
  71. data/lib/talia_core/source.rb +45 -25
  72. data/lib/talia_core/source_fragment.rb +7 -0
  73. data/lib/talia_core/source_transfer_object.rb +3 -1
  74. data/lib/talia_core/source_types/agent.rb +16 -0
  75. data/lib/talia_core/source_types/dc_resource.rb +3 -3
  76. data/lib/talia_core/source_types/marcont_resource.rb +15 -0
  77. data/lib/talia_core/source_types/skos_concept.rb +17 -0
  78. data/lib/talia_dependencies.rb +1 -1
  79. data/lib/talia_util.rb +1 -1
  80. data/lib/talia_util/bar_progressor.rb +1 -1
  81. data/lib/talia_util/image_conversions.rb +8 -2
  82. data/lib/talia_util/import_job_helper.rb +40 -3
  83. data/lib/talia_util/io_helper.rb +15 -4
  84. data/lib/talia_util/progressable.rb +50 -1
  85. data/lib/talia_util/rake_tasks.rb +3 -21
  86. data/lib/talia_util/test_helpers.rb +6 -1
  87. data/lib/talia_util/util.rb +108 -27
  88. data/lib/talia_util/xml/base_builder.rb +28 -1
  89. data/lib/talia_util/xml/rdf_builder.rb +81 -5
  90. data/lib/tasks/talia_core_tasks.rake +2 -0
  91. data/test/core_ext/boolean_test.rb +26 -0
  92. data/test/core_ext/nil_class_test.rb +14 -0
  93. data/test/core_ext/object_test.rb +26 -0
  94. data/test/core_ext/string_test.rb +11 -0
  95. data/test/swicky/json_encoder_test.rb +51 -42
  96. data/test/swicky/notebook_test.rb +13 -6
  97. data/test/talia_core/active_source_finder_interface_test.rb +30 -0
  98. data/test/talia_core/active_source_test.rb +445 -34
  99. data/test/talia_core/collection_test.rb +332 -0
  100. data/test/talia_core/data_types/file_record_test.rb +2 -23
  101. data/test/talia_core/ntriples_reader_test.rb +49 -0
  102. data/test/talia_core/rdfxml_reader_test.rb +51 -0
  103. data/test/talia_core/source_test.rb +12 -0
  104. data/test/talia_util/import_job_helper_test.rb +19 -12
  105. metadata +190 -90
  106. data/config/database.yml +0 -19
  107. data/config/rdfstore.yml +0 -13
  108. data/config/talia_core.yml +0 -24
  109. data/generators/talia_base/templates/migrations/bj_migration.rb +0 -10
  110. data/lib/JXslt/jxslt.rb +0 -60
  111. data/lib/swicky/json_encoder.rb +0 -179
  112. data/lib/talia_core/agent.rb +0 -14
  113. data/lib/talia_core/background_jobs/job.rb +0 -82
  114. data/lib/talia_core/background_jobs/progress_job.rb +0 -68
  115. data/lib/talia_core/data_types/temp_file_handling.rb +0 -85
  116. data/lib/talia_core/ordered_source.rb +0 -228
  117. data/lib/talia_core/semantic_collection_item.rb +0 -94
  118. data/lib/talia_core/source_types/collection.rb +0 -15
  119. data/lib/talia_util/progressbar.rb +0 -236
  120. data/tasks/talia_core_tasks.rake +0 -2
  121. data/test/talia_core/ordered_source_test.rb +0 -394
  122. data/test/talia_core/semantic_collection_item_test.rb +0 -125
@@ -44,14 +44,25 @@ module TaliaUtil
44
44
  #
45
45
  # [*trace*] Enable tracing output for errors. (By default, this takes the rake task's setting
46
46
  # if possible)
47
+ #
48
+ # The import itself consists in calling #initialize and the do_import
47
49
  class ImportJobHelper
48
50
 
49
51
  include IoHelper
50
52
 
51
53
  attr_reader :importer, :credentials, :index_data, :xml_data, :reset, :callback, :base_url, :message_stream, :progressor, :duplicates, :trace
52
54
 
53
- # The message_stream will be used for printing progress messages
54
- def initialize(message_stream = STDOUT, progressor = TaliaCore::BackgroundJobs::Job)
55
+ # The message_stream will be used for printing progress messages.
56
+ #
57
+ # The procedure of the import is the following:
58
+ #
59
+ # * Set up all the attributes of this class from the respective environment variables (from the
60
+ # rake task)
61
+ # * Initialize the data: If an index file is given, read the index file. Otherwise read the
62
+ # file given by the 'xml' environment variable, or from STDIN if 'xml' isn't set. See init_data
63
+ # * Create the callback class, if given
64
+ # * Set up the progressor for the import, if any
65
+ def initialize(message_stream = STDOUT, progressor = TaliaUtil::BarProgressor)
55
66
  @trace = (defined?(Rake) ? Rake.application.options.trace : false) || ENV['trace']
56
67
  @progressor = progressor
57
68
  @message_stream = message_stream
@@ -59,7 +70,7 @@ module TaliaUtil
59
70
  @importer = ENV['importer'] || 'TaliaCore::ActiveSourceParts::Xml::SourceReader'
60
71
  @credentials = { :http_basic_authentication => [ENV['user'], ENV['pass']] } unless(ENV['user'].blank?)
61
72
  assit(!(ENV['xml'] && ENV['index']), 'Not both xml and index parameters allowed')
62
- @reset = ['yes', 'true'].include?(ENV['reset_store'].downcase) if(ENV['reset_store'])
73
+ @reset = ENV['reset_store'].yes?
63
74
 
64
75
  @base_url = ENV['base_url'].blank? ? '' : ENV['base_url']
65
76
  if(base_url && File.directory?(base_url))
@@ -76,6 +87,10 @@ module TaliaUtil
76
87
  callback.progressor = progressor if(callback && callback.respond_to?(:'progressor='))
77
88
  end
78
89
 
90
+ # Reads the data for the coming import. If the 'index' parameter is found in the
91
+ # environment, this will be used as the file name for the index file, which will be
92
+ # read into the object. Otherwise, if the 'xml' environment variable is set, this will
93
+ # will be read and used as the XML data for the import
79
94
  def init_data
80
95
  if(ENV['index'].blank?)
81
96
  @xml_data = if(ENV['xml'].blank?)
@@ -92,6 +107,14 @@ module TaliaUtil
92
107
  end
93
108
  end
94
109
 
110
+ # Does the actual importing:
111
+ #
112
+ # * If required, reset the data store
113
+ # * Run the "before_import" callback
114
+ # * In case there is plain xml data, TaliaCore::ActiveSource.create_from_xml
115
+ # will handle all the import
116
+ # * If an index is given, the import will be done by import_from_index
117
+ # * Run the "after_import" callback
95
118
  def do_import
96
119
  if(reset)
97
120
  TaliaUtil::Util.full_reset
@@ -112,11 +135,25 @@ module TaliaUtil
112
135
  run_callback(:after_import)
113
136
  end
114
137
 
138
+ # Prints the message and, if the "trace" option is set,
139
+ # also the stack trace of the Exception e
115
140
  def print_error(e)
116
141
  puts e.message
117
142
  puts e.backtrace if(trace)
118
143
  end
119
144
 
145
+ # This is *only* used if an index file is given for the import. All "plain"
146
+ # imports go directly to #create_from_xml in the ActiveSource class
147
+ #
148
+ # * The index file is parsed as XML
149
+ # * If the root element is "sigla", the old hyper format is used
150
+ # * In case the hyper format is used, sigla (local names for URIs)
151
+ # are expected as "siglum" elements. Otherwise, the import URIs are expected
152
+ # in "url" tags.
153
+ # * For each import url, #sources_from_url is called on the selected importer,
154
+ # and the attributes added to the import data
155
+ # * The result is passed to TaliaCore::ActiveSource.create_multi from
156
+ # to create the sources
120
157
  def import_from_index(errors)
121
158
  doc = Hpricot.XML(index_data)
122
159
  hyper_format = (doc.root.name == 'sigla')
@@ -2,13 +2,18 @@ require 'open-uri'
2
2
 
3
3
  module TaliaUtil
4
4
 
5
- # Import data files into the Talia store. This can be used to bootstrap
6
- # simple installations
5
+ # Collection of IO methods than can be mixed into other classes
7
6
  module IoHelper
8
7
 
9
8
  # Generic "open" method for files and urls. This won't choke on file:// URLs and
10
9
  # will do some extra escaping on the URL.
11
10
  #
11
+ # *Usage*:
12
+ #
13
+ # open_generic('someurl.foo') do |io|
14
+ # ...
15
+ # end
16
+ #
12
17
  # See open_from_url for an explanation of the options
13
18
  def open_generic(url, options = {})
14
19
  url = file_url(url)
@@ -21,7 +26,7 @@ module TaliaUtil
21
26
  end
22
27
  end
23
28
 
24
- # Will try to figure out the "base" (that is the parent directory or path)
29
+ # Will try to figure out the "base", which is the parent directory or path.
25
30
  # If the base is a directory, this will return the directory name, but if
26
31
  # it is an URL, this will return an URI object.
27
32
  def base_for(url)
@@ -46,6 +51,12 @@ module TaliaUtil
46
51
  # the documentation for open-uri for more information. Example for options:
47
52
  #
48
53
  # :http_basic_authentication => [login, password]
54
+ #
55
+ # *Example*:
56
+ #
57
+ # open_from_url('http://foobar.com/', :http_basic_authentication => ['user', 'secret']) do |io|
58
+ # ...
59
+ # end
49
60
  def open_from_url(url, options = {})
50
61
  # Encode the URI (the inner decode will save already-encoded URI and should
51
62
  # do nothing to non-encoded URIs)
@@ -65,7 +76,7 @@ module TaliaUtil
65
76
  end
66
77
  end
67
78
 
68
- # Get the "file url" for the given url, stripping a possible file:// from the front
79
+ # Get the "file url" for the given uri, stripping a possible file:// from the front
69
80
  def file_url(uri)
70
81
  uri.gsub(/\Afile:\/\//, '')
71
82
  end
@@ -1,6 +1,55 @@
1
1
  module TaliaUtil
2
2
 
3
- # Mix-in for a class that wishes to use decoupled progress meters.
3
+ # Mix-in for a class that wishes to use decoupled progress meters.
4
+ # This creates an read/write accessor for a progressor, which is used
5
+ # to report progress to.
6
+ #
7
+ # Inside the object #run_with_progress may be used to run a
8
+ # progress-reporting operation. If no progressor has been assigned,
9
+ # run_with_progress will still work as expected, providing a progressor
10
+ # object that will do nothing.
11
+ #
12
+ # = Example
13
+ #
14
+ # class Foo
15
+ #
16
+ # include Progressable
17
+ #
18
+ # def long_thing
19
+ # run_with_progress("doing long thing", 100) { |prog| (1..100).each { prog.inc } }
20
+ # end
21
+ # end
22
+ #
23
+ # Foo.new.long_thing # Will do nothing
24
+ # foo_real = Foo.new
25
+ # foo_real.progressor = some_progressor
26
+ # foo_real.long_thing # reports progress to some_progressor
27
+ #
28
+ # = How a progressor must look like
29
+ #
30
+ # A progressor is simply required to provide a method called "run_with_progress(message, size)",
31
+ # with the first parameter being the progress message and the second the overall
32
+ # count of operations. The method *must* take a block, and call that block with an object
33
+ # which responds to a method calle "inc", which increases the current count/progress.
34
+ #
35
+ # = Example progressor
36
+ #
37
+ # class DummyProgress
38
+ # def inc
39
+ # print '.'
40
+ # end
41
+ # end
42
+ #
43
+ # class SimpleProgressor
44
+ # def self.run_with_progress(message, size)
45
+ # puts message
46
+ # yield(DummyProgress.new)
47
+ # puts "Done"
48
+ # end
49
+ # end
50
+ #
51
+ # This will print a dot for each thing that is processed. See also the BarProgressor for
52
+ # another example
4
53
  module Progressable
5
54
 
6
55
  # This is the object that will receive the progress messages
@@ -53,17 +53,10 @@ namespace :talia_core do
53
53
  t.libs << 'lib'
54
54
  # This will always take the files from the talia_core directory
55
55
  t.test_files = FileList["#{File.dirname(__FILE__)}/../../test/**/*_test.rb"]
56
- t.verbose = true
56
+ t.verbose = false
57
57
  end
58
58
 
59
- # Queue an import in the background
60
- desc "Xml Background import. Options: [index=<indexfile>] [xml=<datafile>] [importer=<importclass>] [reset_store=true] [...]"
61
- task :xml_background_import do
62
- background_job('xml_import', :tag => 'import')
63
- puts "Queued XML background import."
64
- end
65
-
66
- desc "Xml Import. Options: see xml_background_import"
59
+ desc "Xml import. Options: [index=<indexfile>] [xml=<datafile>] [importer=<importclass>] [reset_store=true] [...]"
67
60
  task :xml_import => :init do
68
61
  importer = TaliaUtil::ImportJobHelper.new(STDOUT, TaliaUtil::BarProgressor)
69
62
  importer.do_import
@@ -185,15 +178,4 @@ namespace :talia_core do
185
178
 
186
179
  # Helper methods
187
180
 
188
- # Queue the long-running task in the background processing queue.
189
- # This will simply queue the job, and doesn't start the runner
190
- # by itself
191
- def background_job(job, options)
192
- # Use the current environment for the job
193
- options[:env] = ENV.merge(options[:env] || {})
194
- # Avoid "tickling" to start the background job from here
195
- options[:no_tickle] = true
196
- TaliaCore::BackgroundJobs::Job.submit_with_progress(job, options)
197
- end
198
-
199
- end
181
+ end
@@ -21,8 +21,9 @@ module TaliaUtil
21
21
  def assert_property(property, *values)
22
22
  assert_kind_of(TaliaCore::SemanticCollectionWrapper, property) # Just to be sure
23
23
  assert_equal(values.size, property.size, "Expected #{values.size} values instead of #{property.size}.")
24
+ value_str = values.inject("Expected:\n") { |str, value| str << "#{value.inspect} (#{value.class.name})\n" }
24
25
  property.each do |value|
25
- assert(values.detect { |val| val.respond_to?(:uri) ? (val.uri.to_s == value.uri.to_s) : (value == val) }, "Found unexpected value #{value}. Value is a #{value.class}\nExpected:\n#{values.join("\n")}")
26
+ assert(values.detect { |val| val.respond_to?(:uri) ? (value.respond_to?(:uri) && (val.uri.to_s == value.uri.to_s)) : (value == val) }, "Found unexpected value #{value.inspect} (#{value.class.name})\n#{value_str}")
26
27
  end
27
28
  end
28
29
 
@@ -129,7 +130,11 @@ class Test::Unit::TestCase
129
130
 
130
131
  # Lets the class suppress the fixtures for the tests
131
132
  def self.suppress_fixtures
133
+ # Activates the suppress mechanism for older versions of rails
132
134
  @suppress_fixtures = true
135
+ # This overwrites the setup/teardown callbacks for Rails 2.3.*
136
+ define_method(:setup_fixtures) { }
137
+ define_method(:teardown_fixtures) { }
133
138
  end
134
139
 
135
140
  def self.suppress_fixtures?
@@ -5,7 +5,12 @@ module TaliaUtil
5
5
  class Util
6
6
  class << self
7
7
 
8
- # Get the list of files from the "files" option
8
+ # Rake task helper. Get the list of files the <tt>files</tt>
9
+ # environment variable (passed as <tt>file=[files]</tt>). Exits the
10
+ # runtime and prints an error message if the variable is not set.
11
+ #
12
+ # This returns a FileList object with all the files that match the
13
+ # pattern.
9
14
  def get_files
10
15
  puts "Files given: #{ENV['files']}"
11
16
  unless(ENV['files'])
@@ -17,12 +22,19 @@ module TaliaUtil
17
22
  FileList.new(ENV['files'])
18
23
  end
19
24
 
20
- # Get the configured folder for the ontologies
25
+ # Gets the <tt>ontology_folder</tt> environment variable, as passed
26
+ # to the rake task with <tt>ontology_folder=[folder]</tt>
27
+ #
28
+ # Defaults to <tt>RAILS_ROOT/ontologies</tt> if the variable is not
29
+ # set.
21
30
  def ontology_folder
22
31
  ENV['ontology_folder'] || File.join(RAILS_ROOT, 'ontologies')
23
32
  end
24
33
 
25
- # Set up the ontologies from the given folder
34
+ # Set up the ontologies from the ontology_folder. This clears
35
+ # the RDF context for the ontologies, if possible. Then it will
36
+ # load all ontologies in the ontology_folder into the store,
37
+ # and run the RdfUpdate::owl_to_rdfs update.
26
38
  def setup_ontologies
27
39
  # Clear the ontologies from RDF, if possible
28
40
  adapter = ActiveRDF::ConnectionPool.write_adapter
@@ -41,7 +53,13 @@ module TaliaUtil
41
53
  RdfUpdate::owl_to_rdfs
42
54
  end
43
55
 
44
- # Init the talia core system
56
+ # Init the talia core system. Use to initialize the system for the
57
+ # rake tasks. This will just exit if the system is already initialized,
58
+ # e.g. through Rails.
59
+ #
60
+ # See the rake:talia_core help task for options supported. Options
61
+ # include <tt>talia_root</tt>, <tt>environment</tt>, <tt>config</tt>,
62
+ # <tt>reset_db</tt> and <tt>reset_rdf</tt>
45
63
  def init_talia
46
64
  return if(TaliaCore::Initializer.initialized)
47
65
 
@@ -82,7 +100,8 @@ module TaliaUtil
82
100
  end
83
101
  end
84
102
 
85
- # Get info from the Talia configuraion
103
+ # Rake helper. Prints the talia configuration to the
104
+ # console.
86
105
  def talia_config
87
106
  puts "Talia configuration"
88
107
  puts ""
@@ -93,25 +112,32 @@ module TaliaUtil
93
112
  puts "Local Domain: #{N::LOCAL}"
94
113
  end
95
114
 
96
- # Put the title for Talia
115
+ # Rake/Startup helper. Prints out the talia version/header to the the console.
97
116
  def title
98
117
  puts "\nTalia Digital Library system. Version: #{TaliaCore::Version::STRING}"
99
118
  puts "http://www.muruca.org/\n\n"
100
119
  end
101
120
 
102
- # Flush the database. This only flushes the main data tables!
121
+ # Flush the SQL database. This deletes all entries *only* from the main Talia
122
+ # tables in the db. Additional tables for user-defined models (e.g. translations)
123
+ # will _not_ be touched.
103
124
  def flush_db
104
125
  [ 'active_sources', 'data_records', 'semantic_properties', 'semantic_relations', 'workflows'].reverse.each { |f| ActiveRecord::Base.connection.execute "DELETE FROM #{f}" }
105
126
  # Also remove the "unsaved cache" for the wrappers (may be important during testing)
106
127
  TaliaCore::SemanticCollectionWrapper.instance_variable_set(:'@unsaved_source_cache', {})
107
128
  end
108
129
 
109
- # Flush the RDF store
130
+ # Flush the RDF store. This clears the whole store, including triples that
131
+ # were added through other means than the Talia API.
110
132
  def flush_rdf
111
133
  ActiveRDF::ConnectionPool.write_adapter.clear
112
134
  end
113
135
 
114
- # Remove the data directories
136
+ # Remove the data directories. Removes the data directory (configured
137
+ # as <tt>data_directory_location</tt> in talia_core.yml) and the iip directory
138
+ # (configured as <tt>iip_root_location</tt> in talia_core.yml).
139
+ #
140
+ # This ignores non-existing directories without an error message.
115
141
  def clear_data
116
142
  data_dir = TaliaCore::CONFIG['data_directory_location']
117
143
  iip_dir = TaliaCore::CONFIG['iip_root_directory_location']
@@ -120,7 +146,9 @@ module TaliaUtil
120
146
  end
121
147
 
122
148
 
123
- # Do a full reset of the data store
149
+ # Do a full reset of the data store. Equivalent to clearing
150
+ # the Talia SQL tables, the RDF store and the data directories.
151
+ # This will re-initialize the ontologies afterwards.
124
152
  def full_reset
125
153
  flush_db
126
154
  flush_rdf
@@ -128,11 +156,29 @@ module TaliaUtil
128
156
  setup_ontologies
129
157
  end
130
158
 
131
- # Rewrite the RDF for the whole database. Will yield without parameters
132
- # for progress-reporting blocks.
133
- # FIXME: At the moment, this
134
- # looses all RDF data that is not in the database.
135
- def rewrite_rdf
159
+ # Rewrite the RDF for the whole database. Erases the RDF store
160
+ # completely and re-builds the graph from the data in the SQL
161
+ # tables.
162
+ #
163
+ # *Warning:* This will *loose* all information contained in the
164
+ # RDF that is not duplicated. This includes all SWICKY notebooks!
165
+ #
166
+ # Unless the turn_off_safety flag is set, or the environment variable
167
+ # <tt>i_know_what_i_am_doing</tt> is set to "yes", this method will
168
+ # print an error message and raise an exception.
169
+ #
170
+ # For each triple written, this will yield to the block (if one is given)
171
+ # without parameters. For progress reporting, the overall number of
172
+ # triples that will be rewritten can be acquired with #rewrite_count
173
+ def rewrite_rdf(turn_off_safety=false)
174
+ unless((ENV['i_know_what_i_am_doing'].yes?) || turn_off_safety)
175
+ puts "WARNING: Rewriting the RDF will ERASE all data that does not come from the Talia API"
176
+ puts "This includes ALL SWICKY notebooks"
177
+ puts
178
+ puts "To proceed run this task again, and give the following option:"
179
+ puts "i_know_what_i_am_doing=yes"
180
+ raise ArgumentError, "Can't proceed without confirmation."
181
+ end
136
182
  flush_rdf
137
183
  # We'll get all data from single query.
138
184
  fat_rels = TaliaCore::SemanticRelation.find(:all, :joins => fat_record_joins,
@@ -160,12 +206,14 @@ module TaliaUtil
160
206
  end
161
207
  end
162
208
 
163
- # This gives the number of triples that would be rewritten on #rewrite_rdf
209
+ # The number of triples that would be rewritten with #rewrite_rdf
164
210
  def rewrite_count
165
211
  TaliaCore::SemanticRelation.count + TaliaCore::ActiveSource.count
166
212
  end
167
213
 
168
- # Load the fixtures
214
+ # Load the database fixtures. This "manually" loads the database fixtures for
215
+ # the Talia tables for the core unit tests. The fixtures are those contained
216
+ # in the talia_core folder, _not_ the ones from the application's tests.
169
217
  def load_fixtures
170
218
  # fixtures = ENV['FIXTURES'] ? ENV['FIXTURES'].split(/,/) : Dir.glob(File.join(File.dirname(__FILE__), 'test', 'fixtures', '*.{yml,csv}'))
171
219
  fixtures = [ 'active_sources', 'semantic_relations', 'semantic_properties' 'data_records']
@@ -175,21 +223,23 @@ module TaliaUtil
175
223
  end
176
224
  end
177
225
 
178
- # Do migrations
226
+ # Runs the migrations for the main Talia tables. This will use the migrations from
227
+ # the "talia" generator, _not_ the ones from the Rails application.
179
228
  def do_migrations
180
229
  migration_path = File.join("generators", "talia", "templates", "migrations")
181
230
  ActiveRecord::Migrator.migrate(migration_path, ENV["VERSION"] ? ENV["VERSION"].to_i : nil )
182
231
  end
183
232
 
184
- # Check if the given flag is set on the command line
233
+ # Check if the given flag is set on the command line. This will assert that the flag
234
+ # is set, otherwise it's equivalent to String#yes? (from the core extensions) on
235
+ # the variable
185
236
  def flag?(the_flag)
186
237
  assit_not_nil(the_flag)
187
- ENV[the_flag] && (ENV[the_flag] == "yes" || ENV[the_flag] == "true")
238
+ ENV[the_flag].yes?
188
239
  end
189
240
 
190
- # For selecting "fat" records on the semantic properties, including the
191
- # objects. Used for rewriting the rdf. TODO: Review after merging
192
- # with optimized branch
241
+ # SQL select portion selecting "fat" records from the semantic_relatations table.
242
+ # This will select all data needed to create all triples. Used for rewriting the rdf.
193
243
  def fat_record_select
194
244
  select = 'semantic_relations.id AS id, semantic_relations.created_at AS created_at, '
195
245
  select << 'semantic_relations.updated_at AS updated_at, '
@@ -204,8 +254,7 @@ module TaliaUtil
204
254
  select
205
255
  end
206
256
 
207
- # Select semantic properties joined with all connected tables.
208
- # TODO: Review after merging with optimized branch
257
+ # SQL join snippet for selecting "fat" records. See fat_record_select
209
258
  def fat_record_joins
210
259
  joins = " LEFT JOIN active_sources AS obj_sources ON semantic_relations.object_id = obj_sources.id AND semantic_relations.object_type = 'TaliaCore::ActiveSource'"
211
260
  joins << " LEFT JOIN semantic_properties AS obj_props ON semantic_relations.object_id = obj_props.id AND semantic_relations.object_type = 'TaliaCore::SemanticProperty'"
@@ -213,7 +262,7 @@ module TaliaUtil
213
262
  joins
214
263
  end
215
264
 
216
- # print the common options for the tasks
265
+ # Print the options for the rake tasks to the console.
217
266
  def print_options
218
267
  puts "\nGeneral options (not all options are valid for all tasks):"
219
268
  puts "files=<pattern> - Files for the task (a pattern to match the files)"
@@ -228,6 +277,38 @@ module TaliaUtil
228
277
  puts ""
229
278
  end
230
279
 
280
+ # Force-loads all Talia related models. This will attempt to load all classes in
281
+ # RAILS_ROOT/app/models and in TALIA_CODE_ROOT/lib/talia_core/source_types.
282
+ #
283
+ # Use this to make sure the whole hierarchy of ActiveSource subclasses is in memory..
284
+ def load_all_models
285
+ return if @models_loaded
286
+ load_models_from File.join(RAILS_ROOT, 'app', 'models', '**', '*.rb') if(defined? RAILS_ROOT)
287
+ load_models_from File.join(TALIA_CODE_ROOT, 'lib', 'talia_core', 'source_types', '**', '*.rb'), 'TaliaCore::SourceTypes::'
288
+ TaliaCore::Source
289
+ TaliaCore::Collection
290
+
291
+ @models_loaded = true
292
+ end
293
+
294
+ # Helper to load all classes from a given directory. This will attempt to instanciate all
295
+ # classes found in the dir. The name of the class to be instantiated will be taken from the
296
+ # file name, prepending the prefix (e.g. 'ModuleName::') if set.
297
+ def load_models_from(dir, prefix='')
298
+ # Appends a file system directory separator to the directory if needed.
299
+ dir = File.join(dir, '')
300
+ Dir[File.join(dir, '**', '*.rb')].each do |f|
301
+ # For every rb file we try to gues and instantiate the contained class.
302
+ model_name = f.gsub(/#{dir}|\.rb/, '')
303
+ begin
304
+ (prefix + model_name).camelize.constantize
305
+ rescue Exception => e
306
+ # Errors at this point could be ignored, as there may be files that do not contain classes.
307
+ TaliaCore.logger.warn "Could not load class #{(prefix + model_name).camelize}: #{e.message}"
308
+ end
309
+ end
310
+ end
311
+
231
312
  end
232
313
  end
233
- end
314
+ end