import 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +7 -0
- data/.rspec +1 -0
- data/Gemfile +14 -0
- data/Gemfile.lock +160 -0
- data/Guardfile +21 -0
- data/README.rdoc +18 -2
- data/Rakefile +7 -10
- data/import.gemspec +33 -0
- data/lib/generators/import/install/install_generator.rb +32 -0
- data/lib/generators/import/install/templates/migrations/1_create_imports.rb +27 -0
- data/lib/import.rb +4 -0
- data/lib/import/no_relation.rb +42 -0
- data/lib/import/resource.rb +195 -0
- data/lib/import/version.rb +1 -1
- data/script/rails +4 -0
- data/spec/dummy/Gemfile +17 -0
- data/spec/dummy/Gemfile.lock +163 -0
- data/{test → spec}/dummy/Rakefile +0 -0
- data/{test → spec}/dummy/app/assets/javascripts/application.js +0 -2
- data/{test → spec}/dummy/app/assets/stylesheets/application.css +0 -0
- data/{test → spec}/dummy/app/controllers/application_controller.rb +0 -0
- data/{test → spec}/dummy/app/helpers/application_helper.rb +0 -0
- data/{test/dummy/public/favicon.ico → spec/dummy/app/mailers/.gitkeep} +0 -0
- data/spec/dummy/app/models/.gitkeep +0 -0
- data/spec/dummy/app/models/importer/music/artist.rb +2 -0
- data/spec/dummy/app/models/music/artist.rb +20 -0
- data/{test → spec}/dummy/app/views/layouts/application.html.erb +0 -0
- data/{test → spec}/dummy/config.ru +0 -0
- data/{test → spec}/dummy/config/application.rb +10 -1
- data/{test → spec}/dummy/config/boot.rb +0 -0
- data/spec/dummy/config/database.example.yml +42 -0
- data/spec/dummy/config/database.yml +42 -0
- data/{test → spec}/dummy/config/environment.rb +0 -0
- data/{test → spec}/dummy/config/environments/development.rb +0 -0
- data/{test → spec}/dummy/config/environments/production.rb +0 -0
- data/{test → spec}/dummy/config/environments/test.rb +0 -0
- data/{test → spec}/dummy/config/initializers/backtrace_silencers.rb +0 -0
- data/{test → spec}/dummy/config/initializers/inflections.rb +0 -0
- data/{test → spec}/dummy/config/initializers/mime_types.rb +0 -0
- data/{test → spec}/dummy/config/initializers/secret_token.rb +1 -1
- data/{test → spec}/dummy/config/initializers/session_store.rb +0 -0
- data/{test → spec}/dummy/config/initializers/wrap_parameters.rb +0 -0
- data/{test → spec}/dummy/config/locales/en.yml +0 -0
- data/spec/dummy/config/routes.rb +2 -0
- data/spec/dummy/db/migrate/20110925192802_create_imports.rb +27 -0
- data/spec/dummy/db/migrate/20110925204213_create_music_artists.rb +15 -0
- data/spec/dummy/db/schema.rb +44 -0
- data/spec/dummy/db/schema.txt +20 -0
- data/spec/dummy/lib/assets/.gitkeep +0 -0
- data/spec/dummy/log/.gitkeep +0 -0
- data/spec/dummy/log/development.log +263 -0
- data/spec/dummy/log/test.log +38 -0
- data/{test → spec}/dummy/public/404.html +0 -0
- data/{test → spec}/dummy/public/422.html +0 -0
- data/{test → spec}/dummy/public/500.html +0 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/{test → spec}/dummy/script/rails +0 -0
- data/spec/dummy/tmp/pids/server.pid +1 -0
- data/spec/models/no_relation_spec.rb +13 -0
- data/spec/spec_helper.rb +31 -0
- metadata +170 -72
- data/test/dummy/config/database.yml +0 -25
- data/test/dummy/config/routes.rb +0 -58
- data/test/import_test.rb +0 -7
- data/test/test_helper.rb +0 -10
data/.gitignore
ADDED
data/.rspec
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
--colour
|
data/Gemfile
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
source "http://rubygems.org"
|
|
2
|
+
|
|
3
|
+
# Declare your gem's dependencies in import.gemspec.
|
|
4
|
+
# Bundler will treat runtime dependencies like base dependencies, and
|
|
5
|
+
# development dependencies will be added by default to the :development group.
|
|
6
|
+
gemspec
|
|
7
|
+
|
|
8
|
+
# Declare any dependencies that are still in development here instead of in
|
|
9
|
+
# your gemspec. These might include edge Rails or gems from your path or
|
|
10
|
+
# Git. Remember to move these dependencies to your gemspec before releasing
|
|
11
|
+
# your gem to rubygems.org.
|
|
12
|
+
|
|
13
|
+
# To use debugger
|
|
14
|
+
# gem 'ruby-debug19', :require => 'ruby-debug'
|
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: .
|
|
3
|
+
specs:
|
|
4
|
+
import (0.0.2)
|
|
5
|
+
activerecord-import
|
|
6
|
+
rails (~> 3.1.0)
|
|
7
|
+
state_machine
|
|
8
|
+
valium
|
|
9
|
+
|
|
10
|
+
GEM
|
|
11
|
+
remote: http://rubygems.org/
|
|
12
|
+
specs:
|
|
13
|
+
actionmailer (3.1.0)
|
|
14
|
+
actionpack (= 3.1.0)
|
|
15
|
+
mail (~> 2.3.0)
|
|
16
|
+
actionpack (3.1.0)
|
|
17
|
+
activemodel (= 3.1.0)
|
|
18
|
+
activesupport (= 3.1.0)
|
|
19
|
+
builder (~> 3.0.0)
|
|
20
|
+
erubis (~> 2.7.0)
|
|
21
|
+
i18n (~> 0.6)
|
|
22
|
+
rack (~> 1.3.2)
|
|
23
|
+
rack-cache (~> 1.0.3)
|
|
24
|
+
rack-mount (~> 0.8.2)
|
|
25
|
+
rack-test (~> 0.6.1)
|
|
26
|
+
sprockets (~> 2.0.0)
|
|
27
|
+
activemodel (3.1.0)
|
|
28
|
+
activesupport (= 3.1.0)
|
|
29
|
+
bcrypt-ruby (~> 3.0.0)
|
|
30
|
+
builder (~> 3.0.0)
|
|
31
|
+
i18n (~> 0.6)
|
|
32
|
+
activerecord (3.1.0)
|
|
33
|
+
activemodel (= 3.1.0)
|
|
34
|
+
activesupport (= 3.1.0)
|
|
35
|
+
arel (~> 2.2.1)
|
|
36
|
+
tzinfo (~> 0.3.29)
|
|
37
|
+
activerecord-import (0.2.8)
|
|
38
|
+
activerecord (~> 3.0pre)
|
|
39
|
+
activerecord (~> 3.0pre)
|
|
40
|
+
activeresource (3.1.0)
|
|
41
|
+
activemodel (= 3.1.0)
|
|
42
|
+
activesupport (= 3.1.0)
|
|
43
|
+
activesupport (3.1.0)
|
|
44
|
+
multi_json (~> 1.0)
|
|
45
|
+
arel (2.2.1)
|
|
46
|
+
bcrypt-ruby (3.0.1)
|
|
47
|
+
builder (3.0.0)
|
|
48
|
+
capybara (1.1.1)
|
|
49
|
+
mime-types (>= 1.16)
|
|
50
|
+
nokogiri (>= 1.3.3)
|
|
51
|
+
rack (>= 1.0.0)
|
|
52
|
+
rack-test (>= 0.5.4)
|
|
53
|
+
selenium-webdriver (~> 2.0)
|
|
54
|
+
xpath (~> 0.1.4)
|
|
55
|
+
childprocess (0.2.2)
|
|
56
|
+
ffi (~> 1.0.6)
|
|
57
|
+
diff-lcs (1.1.3)
|
|
58
|
+
erubis (2.7.0)
|
|
59
|
+
factory_girl (2.1.2)
|
|
60
|
+
activesupport
|
|
61
|
+
factory_girl_rails (1.2.0)
|
|
62
|
+
factory_girl (~> 2.1.0)
|
|
63
|
+
railties (>= 3.0.0)
|
|
64
|
+
ffi (1.0.9)
|
|
65
|
+
guard (0.7.0)
|
|
66
|
+
thor (~> 0.14.6)
|
|
67
|
+
guard-rspec (0.4.5)
|
|
68
|
+
guard (>= 0.4.0)
|
|
69
|
+
hike (1.2.1)
|
|
70
|
+
i18n (0.6.0)
|
|
71
|
+
json (1.6.1)
|
|
72
|
+
json_pure (1.6.1)
|
|
73
|
+
mail (2.3.0)
|
|
74
|
+
i18n (>= 0.4.0)
|
|
75
|
+
mime-types (~> 1.16)
|
|
76
|
+
treetop (~> 1.4.8)
|
|
77
|
+
mime-types (1.16)
|
|
78
|
+
multi_json (1.0.3)
|
|
79
|
+
mysql2 (0.3.7)
|
|
80
|
+
nokogiri (1.5.0)
|
|
81
|
+
polyglot (0.3.2)
|
|
82
|
+
rack (1.3.3)
|
|
83
|
+
rack-cache (1.0.3)
|
|
84
|
+
rack (>= 0.4)
|
|
85
|
+
rack-mount (0.8.3)
|
|
86
|
+
rack (>= 1.0.0)
|
|
87
|
+
rack-ssl (1.3.2)
|
|
88
|
+
rack
|
|
89
|
+
rack-test (0.6.1)
|
|
90
|
+
rack (>= 1.0)
|
|
91
|
+
rails (3.1.0)
|
|
92
|
+
actionmailer (= 3.1.0)
|
|
93
|
+
actionpack (= 3.1.0)
|
|
94
|
+
activerecord (= 3.1.0)
|
|
95
|
+
activeresource (= 3.1.0)
|
|
96
|
+
activesupport (= 3.1.0)
|
|
97
|
+
bundler (~> 1.0)
|
|
98
|
+
railties (= 3.1.0)
|
|
99
|
+
railties (3.1.0)
|
|
100
|
+
actionpack (= 3.1.0)
|
|
101
|
+
activesupport (= 3.1.0)
|
|
102
|
+
rack-ssl (~> 1.3.2)
|
|
103
|
+
rake (>= 0.8.7)
|
|
104
|
+
rdoc (~> 3.4)
|
|
105
|
+
thor (~> 0.14.6)
|
|
106
|
+
rake (0.9.2)
|
|
107
|
+
rdoc (3.9.4)
|
|
108
|
+
rspec (2.6.0)
|
|
109
|
+
rspec-core (~> 2.6.0)
|
|
110
|
+
rspec-expectations (~> 2.6.0)
|
|
111
|
+
rspec-mocks (~> 2.6.0)
|
|
112
|
+
rspec-core (2.6.4)
|
|
113
|
+
rspec-expectations (2.6.0)
|
|
114
|
+
diff-lcs (~> 1.1.2)
|
|
115
|
+
rspec-mocks (2.6.0)
|
|
116
|
+
rspec-rails (2.6.1)
|
|
117
|
+
actionpack (~> 3.0)
|
|
118
|
+
activesupport (~> 3.0)
|
|
119
|
+
railties (~> 3.0)
|
|
120
|
+
rspec (~> 2.6.0)
|
|
121
|
+
rubyzip (0.9.4)
|
|
122
|
+
sanitize (2.0.3)
|
|
123
|
+
nokogiri (>= 1.4.4, < 1.6)
|
|
124
|
+
sdoc (0.3.11)
|
|
125
|
+
json (>= 1.1.3)
|
|
126
|
+
rdoc (~> 3)
|
|
127
|
+
sanitize (~> 2)
|
|
128
|
+
selenium-webdriver (2.7.0)
|
|
129
|
+
childprocess (>= 0.2.1)
|
|
130
|
+
ffi (>= 1.0.7)
|
|
131
|
+
json_pure
|
|
132
|
+
rubyzip
|
|
133
|
+
sprockets (2.0.0)
|
|
134
|
+
hike (~> 1.2)
|
|
135
|
+
rack (~> 1.0)
|
|
136
|
+
tilt (!= 1.3.0, ~> 1.1)
|
|
137
|
+
state_machine (1.0.2)
|
|
138
|
+
thor (0.14.6)
|
|
139
|
+
tilt (1.3.3)
|
|
140
|
+
treetop (1.4.10)
|
|
141
|
+
polyglot
|
|
142
|
+
polyglot (>= 0.3.1)
|
|
143
|
+
tzinfo (0.3.29)
|
|
144
|
+
valium (0.4.0)
|
|
145
|
+
activerecord (>= 3.0.2)
|
|
146
|
+
xpath (0.1.4)
|
|
147
|
+
nokogiri (~> 1.3)
|
|
148
|
+
|
|
149
|
+
PLATFORMS
|
|
150
|
+
ruby
|
|
151
|
+
|
|
152
|
+
DEPENDENCIES
|
|
153
|
+
capybara
|
|
154
|
+
factory_girl_rails
|
|
155
|
+
guard-rspec
|
|
156
|
+
import!
|
|
157
|
+
mysql2
|
|
158
|
+
rspec (~> 2.6.0)
|
|
159
|
+
rspec-rails
|
|
160
|
+
sdoc
|
data/Guardfile
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# A sample Guardfile
|
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
|
3
|
+
|
|
4
|
+
guard 'rspec', :version => 2 do
|
|
5
|
+
watch(%r{^spec/.+_spec\.rb$})
|
|
6
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
|
7
|
+
watch('spec/spec_helper.rb') { "spec" }
|
|
8
|
+
|
|
9
|
+
# Rails example
|
|
10
|
+
watch(%r{^spec/.+_spec\.rb$})
|
|
11
|
+
watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
|
12
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
|
13
|
+
watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
|
|
14
|
+
watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
|
|
15
|
+
watch('spec/spec_helper.rb') { "spec" }
|
|
16
|
+
watch('config/routes.rb') { "spec/routing" }
|
|
17
|
+
watch('app/controllers/application_controller.rb') { "spec/controllers" }
|
|
18
|
+
# Capybara request specs
|
|
19
|
+
watch(%r{^app/views/(.+)/.*\.(erb|haml)$}) { |m| "spec/requests/#{m[1]}_spec.rb" }
|
|
20
|
+
end
|
|
21
|
+
|
data/README.rdoc
CHANGED
|
@@ -1,3 +1,19 @@
|
|
|
1
|
-
|
|
1
|
+
# Import
|
|
2
2
|
|
|
3
|
-
Data entity importer for Ruby and asynchronous handling.
|
|
3
|
+
Data entity importer for Ruby and asynchronous handling wrapped around activerecord-import and featured by valium and state_machine.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
Perform the installation as follows
|
|
8
|
+
|
|
9
|
+
rails g import:install
|
|
10
|
+
|
|
11
|
+
Run the installed migration
|
|
12
|
+
|
|
13
|
+
rake db:migrate
|
|
14
|
+
|
|
15
|
+
## Changelog
|
|
16
|
+
|
|
17
|
+
## License
|
|
18
|
+
|
|
19
|
+
Import is Copyright (c) 2010-2011 [Mathias Gawlista] (http://Applic.at) and is released under MIT-LICENSE.
|
data/Rakefile
CHANGED
|
@@ -20,18 +20,15 @@ RDoc::Task.new(:rdoc) do |rdoc|
|
|
|
20
20
|
rdoc.rdoc_files.include('lib/**/*.rb')
|
|
21
21
|
end
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
25
23
|
Bundler::GemHelper.install_tasks
|
|
26
24
|
|
|
27
|
-
require 'rake
|
|
25
|
+
require 'rake'
|
|
26
|
+
require 'rspec/core'
|
|
27
|
+
require 'rspec/core/rake_task'
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
t.libs << 'test'
|
|
32
|
-
t.pattern = 'test/**/*_test.rb'
|
|
33
|
-
t.verbose = false
|
|
29
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
|
30
|
+
spec.pattern = FileList['spec/**/*_spec.rb']
|
|
34
31
|
end
|
|
35
32
|
|
|
36
|
-
|
|
37
|
-
task :default => :
|
|
33
|
+
desc 'Default: Run all specs.'
|
|
34
|
+
task :default => :spec
|
data/import.gemspec
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
$:.push File.expand_path("../lib", __FILE__)
|
|
2
|
+
|
|
3
|
+
# Maintain your gem's version:
|
|
4
|
+
require "import/version"
|
|
5
|
+
|
|
6
|
+
# Describe your gem and declare its dependencies:
|
|
7
|
+
Gem::Specification.new do |s|
|
|
8
|
+
s.name = "import"
|
|
9
|
+
s.version = Import::VERSION
|
|
10
|
+
s.authors = ["Mathias Gawlista"]
|
|
11
|
+
s.email = ["gawlista@googlemail.com"]
|
|
12
|
+
s.homepage = "http://applic.at"
|
|
13
|
+
s.summary = "Data entity importer for Ruby and asynchronous handling"
|
|
14
|
+
s.description = "Data entity importer for Ruby and asynchronous handling wrapped around activerecord-import and featured by valium and state_machine."
|
|
15
|
+
|
|
16
|
+
#s.files = Dir["{app,config,db,lib}/**/*"] + ["MIT-LICENSE", "Rakefile", "README.rdoc"]
|
|
17
|
+
s.files = `git ls-files`.split("\n")
|
|
18
|
+
s.test_files = `git ls-files -- {spec}/*`.split("\n")
|
|
19
|
+
|
|
20
|
+
s.add_dependency "rails", "~> 3.1.0"
|
|
21
|
+
#s.add_dependency "activerecord", ">= 3.0.2"
|
|
22
|
+
s.add_dependency "valium"
|
|
23
|
+
s.add_dependency "state_machine"
|
|
24
|
+
s.add_dependency "activerecord-import"
|
|
25
|
+
|
|
26
|
+
s.add_development_dependency "mysql2"
|
|
27
|
+
s.add_development_dependency "rspec", "~> 2.6.0"
|
|
28
|
+
s.add_development_dependency "rspec-rails"
|
|
29
|
+
s.add_development_dependency "capybara"
|
|
30
|
+
s.add_development_dependency "factory_girl_rails"
|
|
31
|
+
s.add_development_dependency "guard-rspec"
|
|
32
|
+
s.add_development_dependency "sdoc"
|
|
33
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
require 'rails/generators'
|
|
2
|
+
require 'rails/generators/migration'
|
|
3
|
+
|
|
4
|
+
module Import
|
|
5
|
+
module Generators
|
|
6
|
+
class InstallGenerator < Rails::Generators::Base
|
|
7
|
+
include Rails::Generators::Migration
|
|
8
|
+
|
|
9
|
+
def self.source_root
|
|
10
|
+
File.join(File.dirname(__FILE__), 'templates')
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Implement the required interface for Rails::Generators::Migration.
|
|
14
|
+
# taken from http://github.com/rails/rails/blob/master/activerecord/lib/generators/active_record.rb
|
|
15
|
+
def self.next_migration_number(dirname) #:nodoc:
|
|
16
|
+
if ActiveRecord::Base.timestamped_migrations
|
|
17
|
+
Time.now.utc.strftime("%Y%m%d%H%M%S")
|
|
18
|
+
else
|
|
19
|
+
"%.3d" % (current_migration_number(dirname) + 1)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def create_migrations
|
|
24
|
+
Dir["#{self.class.source_root}/migrations/*.rb"].sort.each do |filepath|
|
|
25
|
+
name = File.basename(filepath)
|
|
26
|
+
migration_template "migrations/#{name}", "db/migrate/#{name.gsub(/^\d+_/,'')}"
|
|
27
|
+
sleep 1
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
class CreateImports < ActiveRecord::Migration
|
|
2
|
+
def self.up
|
|
3
|
+
create_table :imports do |t|
|
|
4
|
+
t.string :type
|
|
5
|
+
t.text :input
|
|
6
|
+
t.text :parameters
|
|
7
|
+
t.string :email
|
|
8
|
+
t.integer :author_id
|
|
9
|
+
t.string :parent_type
|
|
10
|
+
t.integer :parent_id
|
|
11
|
+
t.text :exception
|
|
12
|
+
t.string :state
|
|
13
|
+
t.timestamps
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
change_table :imports do |t|
|
|
17
|
+
t.index :type
|
|
18
|
+
t.index :author_id
|
|
19
|
+
t.index [:parent_type, :parent_id]
|
|
20
|
+
t.index :state
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def self.down
|
|
25
|
+
drop_table :imports
|
|
26
|
+
end
|
|
27
|
+
end
|
data/lib/import.rb
CHANGED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
module Import
|
|
2
|
+
class NoRelation < Resource
|
|
3
|
+
protected
|
|
4
|
+
|
|
5
|
+
def parse_resource(resource)
|
|
6
|
+
resource.gsub('*', '').strip
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def append_existing_resources_criteria(resource)
|
|
10
|
+
@existing_resources_criteria << "(#{table_name}.name = ?)"
|
|
11
|
+
@existing_resources_criteria_values << resource
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def import_resources
|
|
15
|
+
log "#{parsed_resources_missing.length} of #{@parsed_resources.length} new #{resource_class.name.humanize.pluralize}."
|
|
16
|
+
|
|
17
|
+
new_resources_data = []
|
|
18
|
+
|
|
19
|
+
parsed_resources_missing.each do |resource|
|
|
20
|
+
new_resources_data << new_record(resource)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
log "Creating #{new_resources_data.length} new #{resource_class.name.humanize.pluralize}."
|
|
24
|
+
|
|
25
|
+
unless new_resources_data.empty?
|
|
26
|
+
resource_class.import(columns, new_resources_data, :validate => false)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def parsed_resources_missing
|
|
31
|
+
@parsed_resources_missing ||= @parsed_resources.select{|r| !collection(false).map(&:second).include?(r) }
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def new_record(resource)
|
|
35
|
+
[resource]
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def columns
|
|
39
|
+
[:name]
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
module Import
|
|
2
|
+
class Resource < ActiveRecord::Base
|
|
3
|
+
set_table_name 'imports'
|
|
4
|
+
|
|
5
|
+
belongs_to :author, :class_name => 'User'
|
|
6
|
+
belongs_to :parent, :polymorphic => true
|
|
7
|
+
|
|
8
|
+
TYPES = [
|
|
9
|
+
[I18n.t('imports.types.user_import'), 'Importer::User'],
|
|
10
|
+
[I18n.t('imports.types.group_affiliation_import'), 'Importer::GroupAffiliation'],
|
|
11
|
+
[I18n.t('imports.types.music_group_label_affiliation_import'), 'Importer::Music::GroupLabelAffiliation'],
|
|
12
|
+
[I18n.t('imports.types.music_group_artist_affiliation_import'), 'Importer::Music::GroupArtistAffiliation'],
|
|
13
|
+
[I18n.t('imports.types.music_group_release_affiliation_import'), 'Importer::Music::GroupReleaseAffiliation'],
|
|
14
|
+
[I18n.t('imports.types.music_group_video_affiliation_import'), 'Importer::Music::GroupVideoAffiliation'],
|
|
15
|
+
[I18n.t('imports.types.music_artist_import'), 'Importer::Music::Artist'],
|
|
16
|
+
[I18n.t('imports.types.music_release_import'), 'Import::Music::Release']
|
|
17
|
+
]
|
|
18
|
+
INDEX_COLUMNS = ['id', 'type', 'author_id', 'parent_type', 'parent_id']
|
|
19
|
+
|
|
20
|
+
validates :type, :inclusion => { :in => TYPES.map(&:last) }
|
|
21
|
+
validates :input, :presence => true
|
|
22
|
+
validates_format_of :email, :with => /\A[^@]+@([^@\.]+\.)+[^@\.]+\z/, :allow_blank => true
|
|
23
|
+
|
|
24
|
+
serialize :parameters, Hash
|
|
25
|
+
|
|
26
|
+
attr_accessible :logger, :input, :email
|
|
27
|
+
attr_accessor :logger, :parent_import_id
|
|
28
|
+
|
|
29
|
+
state_machine :state, :initial => :draft do
|
|
30
|
+
event :confirm do
|
|
31
|
+
transition :draft => :confirmed
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
event :process do
|
|
35
|
+
#transition :confirmed => :processed
|
|
36
|
+
transition :draft => :processed, :if => :process_successful?
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
event :my_fail do
|
|
40
|
+
transition :draft => :failed
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
event :complete do
|
|
44
|
+
transition :processed => :completed
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
after_initialize :initialize_variables
|
|
49
|
+
|
|
50
|
+
def initialize_variables
|
|
51
|
+
@raw_resources, @parsed_resources, @existing_resources_criteria, @existing_resources_criteria_values = [], [], [], []
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def add_resource(resource)
|
|
55
|
+
resource = resource.gsub('*', '').strip
|
|
56
|
+
|
|
57
|
+
return if resource.blank? || @raw_resources.include?(resource)
|
|
58
|
+
|
|
59
|
+
@raw_resources << resource
|
|
60
|
+
resource = parse_resource(resource.strip)
|
|
61
|
+
@parsed_resources << resource
|
|
62
|
+
|
|
63
|
+
append_existing_resources_criteria(resource)
|
|
64
|
+
|
|
65
|
+
resource
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def values
|
|
69
|
+
@raw_resources
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def collection(force = true)
|
|
73
|
+
unless resource_class.respond_to?(:find_existing_entries)
|
|
74
|
+
raise I18n.t('imports.errors.derive_from_resource', :class_name => resource_class.class_name)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
if force
|
|
78
|
+
@existing_collection = find_existing_resources
|
|
79
|
+
else
|
|
80
|
+
@existing_collection ||= find_existing_resources
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
protected
|
|
85
|
+
|
|
86
|
+
def parse_resource(resource)
|
|
87
|
+
raise I18n.t('imports.errors.override_parse_resource', :class_name => self.class_name)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def append_existing_resources_criteria(resource)
|
|
91
|
+
raise I18n.t('imports.errors.override_append_existing_resources_criteria', :class_name => self.class_name)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def all_dependencies_loaded?
|
|
95
|
+
true
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def import_dependencies
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def import_resources
|
|
102
|
+
raise I18n.t('imports.errors.override_import_resources', :class_name => self.class_name)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def find_existing_resources
|
|
106
|
+
unless @existing_resources_criteria.empty?
|
|
107
|
+
resource_class.find_existing_entries(
|
|
108
|
+
@existing_resources_criteria.join(' OR '),
|
|
109
|
+
@existing_resources_criteria_values
|
|
110
|
+
)
|
|
111
|
+
else
|
|
112
|
+
[]
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def parsed_resources_missing
|
|
117
|
+
raise I18n.t('imports.errors.override_parsed_resources_missing', :class_name => self.class_name)
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def resource_class
|
|
121
|
+
class_name = self.class.name.split('::')
|
|
122
|
+
class_name.shift
|
|
123
|
+
class_name.join('::').constantize
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def table_name
|
|
127
|
+
class_name = self.class.name.split('::')
|
|
128
|
+
class_name.shift
|
|
129
|
+
class_name.join('::').tableize.gsub('/', '_')
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def log(message)
|
|
133
|
+
logger.debug message unless logger == nil
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
private
|
|
137
|
+
|
|
138
|
+
def process_successful?
|
|
139
|
+
loadInput
|
|
140
|
+
|
|
141
|
+
raise I18n.t('imports.errors.not_all_dependencies_loaded') unless all_dependencies_loaded?
|
|
142
|
+
|
|
143
|
+
ActiveRecord::Base.transaction(:requires_new => true) do
|
|
144
|
+
begin
|
|
145
|
+
import_dependencies_wrapper
|
|
146
|
+
rescue Exception => my_e
|
|
147
|
+
self.exception = my_e.message + ":" + my_e.backtrace.join('\n')
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
if self.exception.blank?
|
|
151
|
+
begin
|
|
152
|
+
import_resources_transaction
|
|
153
|
+
rescue Exception => my_e
|
|
154
|
+
log "import exception:" + my_e.message
|
|
155
|
+
self.exception = my_e.message + ":" + my_e.backtrace.join('\n')
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
if self.exception.blank?
|
|
161
|
+
return true
|
|
162
|
+
elsif self.parent_import_id.blank?
|
|
163
|
+
self.my_fail!
|
|
164
|
+
return false
|
|
165
|
+
else
|
|
166
|
+
raise ActiveRecord::Rollback.new(self.exception)
|
|
167
|
+
return false
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def import_dependencies_wrapper
|
|
172
|
+
begin
|
|
173
|
+
import_dependencies
|
|
174
|
+
rescue StateMachine::InvalidTransition
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
def loadInput
|
|
179
|
+
unless self.input.blank?
|
|
180
|
+
self.input.split("\r\n").map(&:strip).select{|r| !r.blank? }.each do |resource|
|
|
181
|
+
self.add_resource(resource)
|
|
182
|
+
break
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def import_resources_transaction
|
|
188
|
+
begin
|
|
189
|
+
import_resources
|
|
190
|
+
rescue Exception => e
|
|
191
|
+
raise ActiveRecord::Rollback.new("#{e.class.name}: #{e.message} (#{self.class.name}):#{e.backtrace.join('\n')}")
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
end
|