talia_core 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (119) hide show
  1. data/README.rdoc +41 -0
  2. data/bin/talia +33 -0
  3. data/lib/JXslt/jxslt.rb +60 -0
  4. data/lib/acts_as_roled.rb +11 -0
  5. data/lib/core_ext/platform.rb +9 -0
  6. data/lib/core_ext/string.rb +6 -0
  7. data/lib/core_ext.rb +1 -0
  8. data/lib/custom_template.rb +4 -0
  9. data/lib/loader_helper.rb +62 -0
  10. data/lib/mysql.rb +1214 -0
  11. data/lib/progressbar.rb +236 -0
  12. data/lib/role.rb +12 -0
  13. data/lib/talia_cl/command_line.rb +39 -0
  14. data/lib/talia_cl/commands/standalone/cl_options.rb +9 -0
  15. data/lib/talia_cl/commands/standalone/standalone_generate.rb +75 -0
  16. data/lib/talia_cl/commands/standalone.rb +25 -0
  17. data/lib/talia_cl/commands/talia_console/cl_options.rb +55 -0
  18. data/lib/talia_cl/commands/talia_console/console_commands.rb +37 -0
  19. data/lib/talia_cl/commands/talia_console/talia_commands.rb +131 -0
  20. data/lib/talia_cl/commands/talia_console.rb +47 -0
  21. data/lib/talia_cl/core_commands.rb +11 -0
  22. data/lib/talia_cl.rb +47 -0
  23. data/lib/talia_core/active_source.rb +372 -0
  24. data/lib/talia_core/active_source_parts/class_methods.rb +378 -0
  25. data/lib/talia_core/active_source_parts/predicate_handler.rb +89 -0
  26. data/lib/talia_core/active_source_parts/rdf.rb +131 -0
  27. data/lib/talia_core/active_source_parts/sql_helper.rb +36 -0
  28. data/lib/talia_core/active_source_parts/xml/base_builder.rb +47 -0
  29. data/lib/talia_core/active_source_parts/xml/generic_reader.rb +363 -0
  30. data/lib/talia_core/active_source_parts/xml/rdf_builder.rb +88 -0
  31. data/lib/talia_core/active_source_parts/xml/source_builder.rb +73 -0
  32. data/lib/talia_core/active_source_parts/xml/source_reader.rb +20 -0
  33. data/lib/talia_core/agent.rb +14 -0
  34. data/lib/talia_core/background_jobs/job.rb +82 -0
  35. data/lib/talia_core/background_jobs/progress_job.rb +68 -0
  36. data/lib/talia_core/collection.rb +13 -0
  37. data/lib/talia_core/data_types/data_loader.rb +92 -0
  38. data/lib/talia_core/data_types/data_record.rb +105 -0
  39. data/lib/talia_core/data_types/delayed_copier.rb +76 -0
  40. data/lib/talia_core/data_types/file_record.rb +59 -0
  41. data/lib/talia_core/data_types/file_store.rb +306 -0
  42. data/lib/talia_core/data_types/iip_data.rb +153 -0
  43. data/lib/talia_core/data_types/iip_loader.rb +127 -0
  44. data/lib/talia_core/data_types/image_data.rb +32 -0
  45. data/lib/talia_core/data_types/media_link.rb +19 -0
  46. data/lib/talia_core/data_types/mime_mapping.rb +45 -0
  47. data/lib/talia_core/data_types/path_helpers.rb +77 -0
  48. data/lib/talia_core/data_types/pdf_data.rb +42 -0
  49. data/lib/talia_core/data_types/simple_text.rb +36 -0
  50. data/lib/talia_core/data_types/temp_file_handling.rb +85 -0
  51. data/lib/talia_core/data_types/xml_data.rb +169 -0
  52. data/lib/talia_core/dc_resource.rb +20 -0
  53. data/lib/talia_core/dummy_handler.rb +34 -0
  54. data/lib/talia_core/dummy_source.rb +20 -0
  55. data/lib/talia_core/errors.rb +25 -0
  56. data/lib/talia_core/initializer.rb +427 -0
  57. data/lib/talia_core/ordered_source.rb +228 -0
  58. data/lib/talia_core/rails_ext/actionpack/action_controller/record_identifier.rb +13 -0
  59. data/lib/talia_core/rails_ext/actionpack/action_controller.rb +1 -0
  60. data/lib/talia_core/rails_ext/actionpack.rb +1 -0
  61. data/lib/talia_core/rails_ext.rb +1 -0
  62. data/lib/talia_core/rdf_import.rb +90 -0
  63. data/lib/talia_core/rdf_resource.rb +159 -0
  64. data/lib/talia_core/semantic_collection_item.rb +93 -0
  65. data/lib/talia_core/semantic_collection_wrapper.rb +324 -0
  66. data/lib/talia_core/semantic_property.rb +7 -0
  67. data/lib/talia_core/semantic_relation.rb +67 -0
  68. data/lib/talia_core/source.rb +323 -0
  69. data/lib/talia_core/source_transfer_object.rb +38 -0
  70. data/lib/talia_core/workflow/base.rb +15 -0
  71. data/lib/talia_core/workflow/publication_workflow.rb +62 -0
  72. data/lib/talia_core/workflow.rb +300 -0
  73. data/lib/talia_core.rb +9 -0
  74. data/lib/talia_dependencies.rb +12 -0
  75. data/lib/talia_util/bar_progressor.rb +15 -0
  76. data/lib/talia_util/configuration/config_file.rb +48 -0
  77. data/lib/talia_util/configuration/database_config.rb +40 -0
  78. data/lib/talia_util/configuration/mysql_database_setup.rb +104 -0
  79. data/lib/talia_util/data_import.rb +91 -0
  80. data/lib/talia_util/image_conversions.rb +82 -0
  81. data/lib/talia_util/import_job_helper.rb +132 -0
  82. data/lib/talia_util/io_helper.rb +54 -0
  83. data/lib/talia_util/progressable.rb +38 -0
  84. data/lib/talia_util/progressbar.rb +236 -0
  85. data/lib/talia_util/rdf_update.rb +80 -0
  86. data/lib/talia_util/some_sigla.xml +1960 -0
  87. data/lib/talia_util/test_helpers.rb +151 -0
  88. data/lib/talia_util/util.rb +226 -0
  89. data/lib/talia_util/yaml_import.rb +80 -0
  90. data/lib/talia_util.rb +13 -0
  91. data/lib/user.rb +116 -0
  92. data/lib/version.rb +15 -0
  93. data/test/core_ext/string_test.rb +11 -0
  94. data/test/custom_template_test.rb +8 -0
  95. data/test/talia_core/active_source_predicate_test.rb +54 -0
  96. data/test/talia_core/active_source_rdf_test.rb +89 -0
  97. data/test/talia_core/active_source_test.rb +631 -0
  98. data/test/talia_core/data_types/data_loader_test.rb +123 -0
  99. data/test/talia_core/data_types/data_record_test.rb +40 -0
  100. data/test/talia_core/data_types/file_record_test.rb +171 -0
  101. data/test/talia_core/data_types/iip_data_test.rb +130 -0
  102. data/test/talia_core/data_types/image_data_test.rb +88 -0
  103. data/test/talia_core/data_types/pdf_data_test.rb +68 -0
  104. data/test/talia_core/data_types/xml_data_test.rb +134 -0
  105. data/test/talia_core/generic_xml_test.rb +83 -0
  106. data/test/talia_core/initializer_test.rb +36 -0
  107. data/test/talia_core/ordered_source_test.rb +398 -0
  108. data/test/talia_core/rdf_resource_test.rb +115 -0
  109. data/test/talia_core/semantic_collection_item_test.rb +129 -0
  110. data/test/talia_core/source_reader_test.rb +33 -0
  111. data/test/talia_core/source_test.rb +484 -0
  112. data/test/talia_core/source_transfer_object_test.rb +24 -0
  113. data/test/talia_core/workflow/publication_workflow_test.rb +242 -0
  114. data/test/talia_core/workflow/user_class_for_workflow.rb +35 -0
  115. data/test/talia_core/workflow/workflow_base_test.rb +21 -0
  116. data/test/talia_core/workflow_test.rb +19 -0
  117. data/test/talia_util/import_job_helper_test.rb +46 -0
  118. data/test/test_helper.rb +68 -0
  119. metadata +262 -0
@@ -0,0 +1,300 @@
1
+ module TaliaCore #:nodoc:
2
+ module Workflow #:nodoc:
3
+ class InvalidState < Exception #:nodoc:
4
+ end
5
+ class NoInitialState < Exception #:nodoc:
6
+ end
7
+ class NoAuthorizedException < Exception #:nodoc:
8
+ end
9
+
10
+
11
+ def self.included(base) #:nodoc:
12
+ base.extend WorkflowMacro
13
+ end
14
+
15
+ module SupportingClasses
16
+ class State
17
+ attr_reader :name
18
+
19
+ def initialize(name, opts)
20
+ @name, @opts = name, opts
21
+ end
22
+
23
+ def entering(record)
24
+ enteract = @opts[:enter]
25
+ record.send(:run_transition_action, enteract) if enteract
26
+ end
27
+
28
+ def entered(record)
29
+ afteractions = @opts[:after]
30
+ return unless afteractions
31
+ Array(afteractions).each do |afteract|
32
+ record.send(:run_transition_action, afteract)
33
+ end
34
+ end
35
+
36
+ def exited(record)
37
+ exitact = @opts[:exit]
38
+ record.send(:run_transition_action, exitact) if exitact
39
+ end
40
+ end
41
+
42
+ class StateTransition
43
+ attr_reader :from, :to, :opts
44
+
45
+ def initialize(opts)
46
+ @from, @to, @guard = opts[:from], opts[:to], opts[:guard]
47
+ @opts = opts
48
+ end
49
+
50
+ def guard(obj, args)
51
+ @guard ? obj.send(:run_transition_action, @guard, args) : true
52
+ end
53
+
54
+ def on_transition(obj, args = nil)
55
+ action = @opts[:on_transition]
56
+ obj.send(:run_transition_action, action, args) if action
57
+ end
58
+
59
+ def perform(record, args = nil)
60
+ return false unless guard(record, args)
61
+ loopback = record.current_state == to
62
+ states = record.class.read_inheritable_attribute(:states)
63
+ next_state = states[to]
64
+ old_state = states[record.current_state]
65
+
66
+ # permform action
67
+ on_transition(record, args)
68
+
69
+ next_state.entering(record) unless loopback
70
+
71
+ record.update_attribute(record.class.state_column, to.to_s)
72
+
73
+ next_state.entered(record) unless loopback
74
+ old_state.exited(record) unless loopback
75
+ true
76
+ end
77
+
78
+ def ==(obj)
79
+ @from == obj.from && @to == obj.to
80
+ end
81
+ end
82
+
83
+ class Event
84
+ attr_reader :name
85
+ attr_reader :transitions
86
+ attr_reader :opts
87
+
88
+ def initialize(name, opts, transition_table, &block)
89
+ @name = name.to_sym
90
+ @transitions = transition_table[@name] = []
91
+ instance_eval(&block) if block
92
+ @opts = opts
93
+ @opts.freeze
94
+ @transitions.freeze
95
+ freeze
96
+ end
97
+
98
+ def next_states(record)
99
+ @transitions.select { |t| t.from == record.current_state }
100
+ end
101
+
102
+ def fire(record, user, args = nil)
103
+ # check user role
104
+ unless @opts[:require_role].nil?
105
+ raise NoAuthorizedException unless user.authorized_as?(@opts[:require_role])
106
+ end
107
+
108
+ # perform transition
109
+ next_states(record).each do |transition|
110
+ break true if transition.perform(record, args)
111
+ end
112
+ end
113
+
114
+ def transitions(trans_opts)
115
+ Array(trans_opts[:from]).each do |s|
116
+ @transitions << SupportingClasses::StateTransition.new(trans_opts.merge({:from => s.to_sym}))
117
+ end
118
+ end
119
+ end
120
+ end
121
+
122
+ module WorkflowMacro
123
+ # Configuration options are
124
+ #
125
+ # * +column+ - specifies the column name to use for keeping the state (default: state)
126
+ # * +property+ - specifies the column name to use for keeping the property of current state (default: state_properties)
127
+ # * +initial+ - specifies an initial state for newly created objects (required)
128
+ def workflow_machine(opts)
129
+ self.extend(ClassMethods)
130
+ raise NoInitialState unless opts[:initial]
131
+
132
+ write_inheritable_attribute :states, {}
133
+ write_inheritable_attribute :initial_state, opts[:initial]
134
+ write_inheritable_attribute :initial_state_properties, opts[:initial_properties] || {}
135
+ write_inheritable_attribute :transition_table, {}
136
+ write_inheritable_attribute :event_table, {}
137
+ write_inheritable_attribute :state_column, opts[:column] || 'state'
138
+ write_inheritable_attribute :state_properties_column, opts[:properties] || 'state_properties'
139
+
140
+ class_inheritable_reader :initial_state
141
+ class_inheritable_reader :initial_state_properties
142
+ class_inheritable_reader :state_column
143
+ class_inheritable_reader :state_properties_column
144
+ class_inheritable_reader :transition_table
145
+ class_inheritable_reader :event_table
146
+
147
+ self.send(:include, TaliaCore::Workflow::InstanceMethods)
148
+
149
+ before_create :set_initial_state, :set_initial_state_properties
150
+ after_create :run_initial_state_actions
151
+ end
152
+ end
153
+
154
+ module InstanceMethods
155
+ def state_properties
156
+ Marshal.load(self.send(self.class.state_properties_column))
157
+ end
158
+
159
+ def state_properties=(value)
160
+ write_attribute self.class.state_properties_column, Marshal.dump(value)
161
+ end
162
+
163
+ def set_initial_state #:nodoc:
164
+ write_attribute self.class.state_column, self.class.initial_state.to_s
165
+ end
166
+
167
+ def set_initial_state_properties #:nodoc:
168
+ write_attribute self.class.state_properties_column, Marshal.dump(self.class.initial_state_properties)
169
+ end
170
+
171
+ def run_initial_state_actions
172
+ initial = self.class.read_inheritable_attribute(:states)[self.class.initial_state.to_sym]
173
+ initial.entering(self)
174
+ initial.entered(self)
175
+ end
176
+
177
+ # Returns the current state the object is in, as a Ruby symbol.
178
+ def current_state
179
+ self.send(self.class.state_column).to_sym
180
+ end
181
+
182
+ # Returns what the next state for a given event would be, as a Ruby symbol.
183
+ def next_state_for_event(event)
184
+ ns = next_states_for_event(event)
185
+ ns.empty? ? nil : ns.first.to
186
+ end
187
+
188
+ def next_states_for_event(event)
189
+ self.class.read_inheritable_attribute(:transition_table)[event.to_sym].select do |s|
190
+ s.from == current_state
191
+ end
192
+ end
193
+
194
+ def run_transition_action(action, args = nil)
195
+ Symbol === action ? self.method(action).call(args) : action.call(self)
196
+ end
197
+ private :run_transition_action
198
+ end
199
+
200
+ module ClassMethods
201
+ # Returns an array of all known states.
202
+ def states
203
+ read_inheritable_attribute(:states).keys
204
+ end
205
+
206
+ # Define an event. This takes a block which describes all valid transitions
207
+ # for this event.
208
+ #
209
+ # Example:
210
+ #
211
+ # class Order < ActiveRecord::Base
212
+ # acts_as_state_machine :initial => :open
213
+ #
214
+ # state :open
215
+ # state :closed
216
+ #
217
+ # event :close_order do
218
+ # transitions :to => :closed, :from => :open
219
+ # end
220
+ # end
221
+ #
222
+ # +transitions+ takes a hash where <tt>:to</tt> is the state to transition
223
+ # to and <tt>:from</tt> is a state (or Array of states) from which this
224
+ # event can be fired.
225
+ #
226
+ # This creates an instance method used for firing the event. The method
227
+ # created is the name of the event followed by an exclamation point (!).
228
+ # Example: <tt>order.close_order!</tt>.
229
+ def event(event, opts={}, &block)
230
+ tt = read_inheritable_attribute(:transition_table)
231
+
232
+ et = read_inheritable_attribute(:event_table)
233
+ e = et[event.to_sym] = SupportingClasses::Event.new(event, opts, tt, &block)
234
+ define_method("#{event.to_s}!") { |user, *args| e.fire(self, user, args) }
235
+ end
236
+
237
+ # Define a state of the system. +state+ can take an optional Proc object
238
+ # which will be executed every time the system transitions into that
239
+ # state. The proc will be passed the current object.
240
+ #
241
+ # Example:
242
+ #
243
+ # class Order < ActiveRecord::Base
244
+ # acts_as_state_machine :initial => :open
245
+ #
246
+ # state :open
247
+ # state :closed, Proc.new { |o| Mailer.send_notice(o) }
248
+ # end
249
+ def state(name, opts={})
250
+ state = SupportingClasses::State.new(name.to_sym, opts)
251
+ read_inheritable_attribute(:states)[name.to_sym] = state
252
+
253
+ define_method("#{state.name}?") { current_state == state.name }
254
+ end
255
+
256
+ # Wraps ActiveRecord::Base.find to conveniently find all records in
257
+ # a given state. Options:
258
+ #
259
+ # * +number+ - This is just :first or :all from ActiveRecord +find+
260
+ # * +state+ - The state to find
261
+ # * +args+ - The rest of the args are passed down to ActiveRecord +find+
262
+ def find_in_state(number, state, *args)
263
+ with_state_scope state do
264
+ find(number, *args)
265
+ end
266
+ end
267
+
268
+ # Wraps ActiveRecord::Base.count to conveniently count all records in
269
+ # a given state. Options:
270
+ #
271
+ # * +state+ - The state to find
272
+ # * +args+ - The rest of the args are passed down to ActiveRecord +find+
273
+ def count_in_state(state, *args)
274
+ with_state_scope state do
275
+ count(*args)
276
+ end
277
+ end
278
+
279
+ # Wraps ActiveRecord::Base.calculate to conveniently calculate all records in
280
+ # a given state. Options:
281
+ #
282
+ # * +state+ - The state to find
283
+ # * +args+ - The rest of the args are passed down to ActiveRecord +calculate+
284
+ def calculate_in_state(state, *args)
285
+ with_state_scope state do
286
+ calculate(*args)
287
+ end
288
+ end
289
+
290
+ protected
291
+ def with_state_scope(state)
292
+ raise InvalidState unless states.include?(state)
293
+
294
+ with_scope :find => {:conditions => ["#{table_name}.#{state_column} = ?", state.to_s]} do
295
+ yield if block_given?
296
+ end
297
+ end
298
+ end
299
+ end
300
+ end
data/lib/talia_core.rb ADDED
@@ -0,0 +1,9 @@
1
+ # TaliaCore loader
2
+ require File.dirname(__FILE__) + '/talia_dependencies'
3
+
4
+ TLoad::force_rails_parts unless(defined?(ActiveRecord))
5
+
6
+ # Load local things
7
+ require 'talia_core/errors'
8
+ require 'talia_core/rails_ext'
9
+ require 'talia_core/initializer'
@@ -0,0 +1,12 @@
1
+ # TaliaCore loader
2
+ require File.dirname(__FILE__) + '/loader_helper'
3
+
4
+ # This is also needed for local loading
5
+ RAILS_GEM_VERSION = '2.3.4' unless defined? RAILS_GEM_VERSION
6
+
7
+ # Stuff we may need to load from sources/uninstalled versions
8
+ TLoad::require_module("assit", "assit", "/../../assit") unless(defined?(assit))
9
+ TLoad::require_module("activerdf", "active_rdf", "/../../ActiveRDF")
10
+ TLoad::require_module("semantic_naming", "semantic_naming", "/../../semantic_naming")
11
+
12
+ require 'version'
@@ -0,0 +1,15 @@
1
+ require File.join(File.dirname(__FILE__), 'progressbar')
2
+
3
+ module TaliaUtil
4
+
5
+ # Helper class for command-line progress bars as progressor objects
6
+ class BarProgressor
7
+
8
+ def self.run_with_progress(message, size)
9
+ progress = ProgressBar.new(message, size)
10
+ yield(progress)
11
+ progress.finish
12
+ end
13
+
14
+ end
15
+ end
@@ -0,0 +1,48 @@
1
+ require 'yaml'
2
+
3
+ module TaliaUtil
4
+ module Configuration
5
+
6
+ # This is an object representation of a configuration file, the elements
7
+ # of the file can be directly accessed using dynamic getters/setters on the
8
+ # the class.
9
+ class ConfigFile
10
+
11
+ # Initialize from the given template
12
+ def initialize(template)
13
+ @config_doc = YAML::load_file(template)
14
+ end
15
+
16
+ # Write the configuration to the given file
17
+ def write(file)
18
+ open(file, 'w') { |io| io.puts(@config_doc.to_yaml) }
19
+ end
20
+
21
+ def [](id)
22
+ @config_doc[id]
23
+ end
24
+
25
+ # Automatically creates "accessors" for the config properties.
26
+ def method_missing(method, *params)
27
+ method = method.to_s
28
+ assign = method[-1..-1] == '=' # True if last char is a =
29
+
30
+ result = nil
31
+
32
+ if(assign)
33
+ return super if(params.size != 1)
34
+ result = @config_doc[method[0..-2]] = params[0]
35
+ else
36
+ return super if(params.size != 0)
37
+ result = @config_doc[method]
38
+ end
39
+
40
+ result
41
+ end
42
+
43
+
44
+
45
+ end
46
+
47
+ end
48
+ end
@@ -0,0 +1,40 @@
1
+ require File.dirname(__FILE__) + '/config_file'
2
+
3
+ module TaliaUtil
4
+ module Configuration
5
+
6
+ # This contains some special methods for database config files
7
+ class DatabaseConfig < ConfigFile
8
+
9
+ def initialize(template)
10
+ @environments = ['test', 'development', 'production']
11
+ super
12
+ end
13
+
14
+ # Set the credentials for all environments
15
+ def set_credentials(db_user, db_pass)
16
+ @environments.each do |env|
17
+ @config_doc[env]['username'] = db_user
18
+ @config_doc[env]['password'] = db_pass
19
+ end
20
+ end
21
+
22
+ # Sets the database adapter for all environments
23
+ def set_adapter(db_adapter)
24
+ @environments.each { |env| @config_doc[env]['adapter'] = db_adapter }
25
+ end
26
+
27
+ # Sets the database names based on the given application name
28
+ def set_database_names(app_name)
29
+ @environments.each { |env| @config_doc[env]['database'] = "#{app_name}_#{env}" }
30
+ end
31
+
32
+ # Sets the socket file for the db
33
+ def set_socket(socket)
34
+ @environments.each { |env| @config_doc[env]['socket'] = socket }
35
+ end
36
+
37
+ end
38
+
39
+ end
40
+ end
@@ -0,0 +1,104 @@
1
+ require 'active_record'
2
+
3
+ module TaliaUtil
4
+ module Configuration
5
+
6
+ # This contains some methods to set mysql databases on a production system
7
+ # from scratch. Setting the root password will apply immediately, the SQL
8
+ # operations will be cached and applied in one go.
9
+ class MysqlDatabaseSetup
10
+
11
+ def initialize
12
+ @sql_statements = []
13
+ end
14
+
15
+ attr_accessor :host
16
+ attr_accessor :app_name
17
+ attr_accessor :sock
18
+ attr_accessor :db_prefix # Prefix for having multiple databases on one install
19
+
20
+ # Set the root user/pw
21
+ def root_credentials(root_user = 'root', root_pw = nil)
22
+ @root_user = root_user
23
+ @root_pw = root_pw
24
+ end
25
+
26
+ # Set the normal user/pw
27
+ def rails_credentials(rails_user, rails_pw)
28
+ @rails_user = rails_user
29
+ @rails_pw = rails_pw
30
+ end
31
+
32
+
33
+ # Assign a new root password
34
+ def assign_root_pw(new_root_pw)
35
+ success = mysqladmin("password #{new_root_pw}")
36
+ @root_pw = new_root_pw if(success)
37
+ success
38
+ end
39
+
40
+ # Create the given database and set the permssions on it
41
+ def create_database(database)
42
+ raise(ArgumentError, "Credentials incomplete") unless(@rails_user && @rails_pw)
43
+ @sql_statements << "CREATE DATABASE #{database};"
44
+ @sql_statements << "GRANT ALL ON #{database}.* TO '#{@rails_user}'@'#{@host || 'localhost'}' IDENTIFIED BY '#{@rails_pw}'"
45
+ end
46
+
47
+ # Creates the default databases for the application. You can call back a
48
+ # block for each db to do something depending on the success of the
49
+ # operation
50
+ def create_default_databases
51
+ raise(ArgumentError, "App name not set") unless(@app_name)
52
+ %w(production test development).each do |db_suffix|
53
+ db_name = "#{db_prefix}#{@app_name}_#{db_suffix}"
54
+ create_database(db_name)
55
+ end
56
+ end
57
+
58
+ # Executes all stored statements
59
+ def execute
60
+ execute_as_root do |connection|
61
+ connection.transaction do
62
+ @sql_statements.each do |statement|
63
+ connection.execute(statement)
64
+ end
65
+ end
66
+ end
67
+ end
68
+
69
+ private
70
+
71
+ # Call the mysqladmin command (as root)
72
+ def mysqladmin(command)
73
+ if(@root_pw)
74
+ system("mysqladmin -u #{@root_user} #{command}")
75
+ else
76
+ system("mysqladmin -u #{@root_user} -p#{@root_pw} #{command}")
77
+ end
78
+ end
79
+
80
+ # Calls sql commands on the database using root credentials. The open
81
+ # database (ActiveRecord) connection will be passed. This will open
82
+ # the given database.
83
+ def execute_as_root(database = nil)
84
+ ActiveRecord::Base.establish_connection(root_con_opts(database))
85
+ yield(ActiveRecord::Base.connection)
86
+ ActiveRecord::Base.remove_connection
87
+ end
88
+
89
+ # options for root connection
90
+ def root_con_opts(database)
91
+ {
92
+ :adapter => "mysql",
93
+ :host => @host || "localhost",
94
+ :username => @root_user,
95
+ :password => @root_pw,
96
+ :database => database,
97
+ :socket => @sock || '/tmp/mysql.sock'
98
+ }
99
+ end
100
+
101
+ end
102
+
103
+ end
104
+ end
@@ -0,0 +1,91 @@
1
+ require 'fileutils'
2
+
3
+ module TaliaUtil
4
+
5
+ # Import data files into the Talia store. This can be used to bootstrap
6
+ # simple installations
7
+ class DataImport
8
+
9
+ class << self
10
+
11
+ # Import files with the given type. This is a simple import feature,
12
+ # it's assumed that the file (without extension is named like the
13
+ # Source it should be assigned to.
14
+ def import(files, type)
15
+
16
+ # First get the class for the data type and the directory
17
+ data_klass = get_data_class(type)
18
+ replace = ENV['replace_files'] && (ENV['replace_files'] == "yes")
19
+
20
+ progress = ProgressBar.new("Importing #{data_klass}", files.size)
21
+ not_found = []
22
+ created = 0
23
+
24
+ files.each do |file|
25
+ # Get the basename without extension and additions. This strips off
26
+ # everything after the first point or - character. Examples:
27
+ # book.html
28
+ # book-picture.jpg
29
+ # => Will all be assigned to "book"
30
+ name = File.basename(file).gsub(/[-|\.].+$/, '')
31
+ if(TaliaCore::Source.exists?(name))
32
+ src = TaliaCore::Source.find(name)
33
+
34
+ # Get the filename with extension
35
+ file_name = File.basename(file)
36
+
37
+ # Create the record if necessary
38
+ unless(data = src.data_records.find_by_location(file_name))
39
+ data = data_klass.new
40
+ File.open(file) do |io|
41
+ data.create_from_data(file_name, io)
42
+ end
43
+ src.data_records << data
44
+ src.save!
45
+ data.save!
46
+ created += 1
47
+ end
48
+ else
49
+ not_found << file
50
+ end
51
+ progress.inc
52
+ end
53
+
54
+ progress.finish
55
+ puts "Done, #{not_found.size} of #{files.size} files had no record associated."
56
+ puts "#{created} new records created."
57
+ puts "\nNot found:" unless(not_found.size == 0)
58
+ not_found.each { |file| puts file}
59
+ end
60
+
61
+
62
+ # Get the data class for the type. That does some sanity checks
63
+ def get_data_class(type)
64
+ data_klass = nil
65
+ begin
66
+ data_klass = TaliaCore::DataTypes.const_get(type)
67
+ rescue Exception => e
68
+ puts("Could get the data type #{type}: #{e}")
69
+ Util.print_options
70
+ exit(1)
71
+ end
72
+
73
+ # Do the basic check
74
+ unless(data_klass && data_klass.kind_of?(Class) && data_klass.method_defined?('data_directory'))
75
+ puts("Cannot create data class from #{type}")
76
+ exit(1)
77
+ end
78
+
79
+ # Now check if we are a subclass of the data class
80
+ my_instance = data_klass.new
81
+
82
+ unless(my_instance.kind_of?(TaliaCore::DataTypes::DataRecord))
83
+ puts("The class #{data_klass} is not a DataRecord, can't create data for it.")
84
+ exit(1)
85
+ end
86
+
87
+ data_klass
88
+ end
89
+ end
90
+ end
91
+ end