rivendell-import 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. data/.gitignore +21 -0
  2. data/Gemfile +11 -0
  3. data/Guardfile +14 -0
  4. data/LICENSE +22 -0
  5. data/README.md +29 -0
  6. data/Rakefile +4 -0
  7. data/bin/rivendell-import +6 -0
  8. data/db/migrate/20120920712200_create_tasks.rb +21 -0
  9. data/db/migrate/20120927194300_create_notifiers.rb +14 -0
  10. data/db/migrate/20120927203600_create_notifications.rb +14 -0
  11. data/examples/.gitignore +2 -0
  12. data/examples/config.rb +31 -0
  13. data/features/manage_cart_attributes.feature +20 -0
  14. data/features/manage_file_matching.feature +44 -0
  15. data/features/step_definitions/import_steps.rb +38 -0
  16. data/features/support/env.rb +19 -0
  17. data/features/support/mock_xport.rb +34 -0
  18. data/lib/rivendell/import.rb +48 -0
  19. data/lib/rivendell/import/base.rb +57 -0
  20. data/lib/rivendell/import/cart.rb +67 -0
  21. data/lib/rivendell/import/carts_cache.rb +58 -0
  22. data/lib/rivendell/import/cli.rb +90 -0
  23. data/lib/rivendell/import/config.rb +13 -0
  24. data/lib/rivendell/import/context.rb +28 -0
  25. data/lib/rivendell/import/cut.rb +33 -0
  26. data/lib/rivendell/import/file.rb +57 -0
  27. data/lib/rivendell/import/notification.rb +16 -0
  28. data/lib/rivendell/import/notifier/base.rb +89 -0
  29. data/lib/rivendell/import/notifier/mail-body.erb +8 -0
  30. data/lib/rivendell/import/notifier/mail-subject.erb +11 -0
  31. data/lib/rivendell/import/notifier/mail.rb +104 -0
  32. data/lib/rivendell/import/notifiers.rb +24 -0
  33. data/lib/rivendell/import/task.rb +80 -0
  34. data/lib/rivendell/import/tasking/cart.rb +25 -0
  35. data/lib/rivendell/import/tasking/destination.rb +28 -0
  36. data/lib/rivendell/import/tasking/file.rb +20 -0
  37. data/lib/rivendell/import/tasking/status.rb +29 -0
  38. data/lib/rivendell/import/tasking/tags.rb +27 -0
  39. data/lib/rivendell/import/tasks.rb +23 -0
  40. data/lib/rivendell/import/version.rb +5 -0
  41. data/lib/rivendell/import/worker.rb +34 -0
  42. data/rivendell-import.gemspec +37 -0
  43. data/spec/fixtures/mail-body.erb +5 -0
  44. data/spec/rivendell/import/base_spec.rb +125 -0
  45. data/spec/rivendell/import/cart_spec.rb +132 -0
  46. data/spec/rivendell/import/carts_cache_spec.rb +110 -0
  47. data/spec/rivendell/import/cli_spec.rb +149 -0
  48. data/spec/rivendell/import/config_spec.rb +16 -0
  49. data/spec/rivendell/import/context_spec.rb +19 -0
  50. data/spec/rivendell/import/file_spec.rb +63 -0
  51. data/spec/rivendell/import/notifier/base_spec.rb +63 -0
  52. data/spec/rivendell/import/notifier/mail_spec.rb +110 -0
  53. data/spec/rivendell/import/task_spec.rb +217 -0
  54. data/spec/rivendell/import/tasks_spec.rb +30 -0
  55. data/spec/rivendell/import/worker_spec.rb +25 -0
  56. data/spec/rivendell/import_spec.rb +32 -0
  57. data/spec/spec_helper.rb +15 -0
  58. data/spec/support/database_cleaner.rb +17 -0
  59. data/spec/support/fixtures.rb +3 -0
  60. data/spec/support/mail.rb +3 -0
  61. data/spec/support/test_notifier.rb +15 -0
  62. data/tasks/ci.rake +2 -0
  63. data/tasks/cucumber.rake +4 -0
  64. data/tasks/database.rake +11 -0
  65. data/tasks/rdoc.rake +16 -0
  66. data/tasks/rspec.rake +2 -0
  67. metadata +399 -0
data/.gitignore ADDED
@@ -0,0 +1,21 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *~
19
+ log/*
20
+ db/*.sqlite3
21
+ db.sqlite3
data/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ # gem "rivendell-api", :git => "git://projects.tryphon.priv/rivendell-api", :path => "~/Projects/RivendellApi"
6
+
7
+ if RUBY_PLATFORM =~ /linux/
8
+ gem 'libnotify'
9
+ gem 'rb-inotify', '~> 0.8.8'
10
+ end
11
+
data/Guardfile ADDED
@@ -0,0 +1,14 @@
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
+ end
9
+
10
+ guard 'cucumber' do
11
+ watch(%r{^features/.+\.feature$})
12
+ watch(%r{^features/support/.+$}) { 'features' }
13
+ watch(%r{^features/step_definitions/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'features' }
14
+ end
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Alban Peignier
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # Rivendell::Import
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'rivendell-import'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install rivendell-import
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+
4
+ FileList['tasks/**/*.rake'].each { |task| import task }
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "rivendell/import"
4
+ require "rivendell/import/cli"
5
+
6
+ Rivendell::Import::CLI.new(ARGV).run
@@ -0,0 +1,21 @@
1
+ class CreateTasks < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :tasks do |t|
4
+ t.string :status
5
+
6
+ t.string :file_name
7
+ t.string :file_path
8
+ t.string :destination
9
+ t.string :tags
10
+ t.text :cart
11
+
12
+ t.integer :priority
13
+
14
+ t.timestamps
15
+ end
16
+ end
17
+
18
+ def self.down
19
+ drop_table :tasks
20
+ end
21
+ end
@@ -0,0 +1,14 @@
1
+ class CreateNotifiers < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :notifiers do |t|
4
+ t.string :type
5
+ t.string :key
6
+ t.text :parameters
7
+ t.timestamps
8
+ end
9
+ end
10
+
11
+ def self.down
12
+ drop_table :notifiers
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ class CreateNotifications < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :notifications do |t|
4
+ t.belongs_to :task
5
+ t.belongs_to :notifier
6
+ t.time :sent_at
7
+ t.timestamps
8
+ end
9
+ end
10
+
11
+ def self.down
12
+ drop_table :notifications
13
+ end
14
+ end
@@ -0,0 +1,2 @@
1
+ music/
2
+ pad/
@@ -0,0 +1,31 @@
1
+ # Mail.defaults do
2
+ # delivery_method :smtp, { :address => "smtp.me.com",
3
+ # :port => 587,
4
+ # :domain => 'your.host.name',
5
+ # :user_name => '<username>',
6
+ # :password => '<password>',
7
+ # :authentication => 'plain',
8
+ # :enable_starttls_auto => true }
9
+ # end
10
+
11
+ Mail.defaults do
12
+ delivery_method :smtp, { :address => "smtp.free.fr" }
13
+ end
14
+
15
+ Rivendell::Import::Notifier::Mail.from = "root@tryphon.eu"
16
+
17
+ Rivendell::Import.config do |config|
18
+ config.to_prepare do |file|
19
+ file.in("music") do
20
+ cart.group = "MUSIC"
21
+ end
22
+
23
+ file.in("pad") do
24
+ cart.find_by_title file.basename
25
+ end
26
+
27
+ cart.group ||= "TEST"
28
+
29
+ notify 'alban@tryphon.eu', :by => :email
30
+ end
31
+ end
@@ -0,0 +1,20 @@
1
+ Feature: Manage Cart attributes
2
+ In order to make the correct import
3
+ An user
4
+ wants to manage carts attributes according importing file
5
+
6
+ Scenario: Seletec the cart group
7
+ Given a configuration with this prepare block
8
+ """
9
+ cart.group = 'MUSIC'
10
+ """
11
+ When a file "dummy.wav" is imported
12
+ Then the task should have destination "Cart in group MUSIC"
13
+
14
+ Scenario: Seletec a cart by number
15
+ Given a configuration with this prepare block
16
+ """
17
+ cart.number = 123
18
+ """
19
+ When a file "dummy.wav" is imported
20
+ Then the task should have destination "Cart 123"
@@ -0,0 +1,44 @@
1
+ Feature: Manage Cart attributes
2
+ In order to organize dropboxes
3
+ An user
4
+ wants to filter files by name
5
+
6
+ Scenario: Select a file by Ruby regexp
7
+ Given a configuration with this prepare block
8
+ """
9
+ if file.match /dummy/
10
+ task.tags << 'matched'
11
+ end
12
+ """
13
+ When a file "dummy.wav" is imported
14
+ Then the task should have tag "matched"
15
+
16
+ Scenario: Select a file with helper 'with'
17
+ Given a configuration with this prepare block
18
+ """
19
+ with /dummy/ do
20
+ task.tag 'matched'
21
+ end
22
+ """
23
+ When a file "dummy.wav" is imported
24
+ Then the task should have tag "matched"
25
+
26
+ Scenario: Select a cast by file name
27
+ Given a cart "123" exists with title:"A long Title"
28
+ And a configuration with this prepare block
29
+ """
30
+ cart.find_by_title file.basename
31
+ """
32
+ When a file "a-long-title.wav" is imported
33
+ Then the task should have destination "Cart 123"
34
+
35
+ Scenario: Select a cast by file name
36
+ Given a cart "123" exists with title:"A long Title", group:"PAD"
37
+ And a cart "666" exists with title:"A long Title", group:"MUSIC"
38
+ And a configuration with this prepare block
39
+ """
40
+ cart.find_by_title file.basename, :group => 'PAD'
41
+ """
42
+ When a file "a-long-title.wav" is imported
43
+ Then the task should have destination "Cart 123"
44
+
@@ -0,0 +1,38 @@
1
+ def import
2
+ @import ||= Rivendell::Import::Base.new.tap do |import|
3
+
4
+ end
5
+ end
6
+
7
+ class Array
8
+
9
+ def as_hash
10
+ Hash[self]
11
+ end
12
+
13
+ end
14
+
15
+ Given /^a cart "(.*?)" exists with (.*)$/ do |number, fields|
16
+ attributes = fields.scan(/\ *(([^:]+):"([^\"]+)",?)/).map do |part, name, value|
17
+ [name, value]
18
+ end.as_hash
19
+
20
+ cart = Rivendell::API::Cart.new(attributes.merge(:number => number))
21
+ Rivendell::Import::Task.mock_xport.carts << cart
22
+ end
23
+
24
+ Given /^a configuration with this prepare block$/ do |code|
25
+ import.to_prepare = eval "lambda { |file| " + code + " }"
26
+ end
27
+
28
+ When /^a file "([^"]*)" is imported$/ do |file|
29
+ import.file file
30
+ end
31
+
32
+ Then /^the task should have destination "([^"]*)"$/ do |destination|
33
+ import.tasks.pop.destination.should == destination
34
+ end
35
+
36
+ Then /^the task should have tag "([^"]*)"$/ do |tag|
37
+ import.tasks.pop.tags.should include(tag)
38
+ end
@@ -0,0 +1,19 @@
1
+ $: << File.dirname(__FILE__) + "/../../lib"
2
+
3
+ require "rivendell/import"
4
+
5
+ require "logger"
6
+ Rivendell::Import.logger = ActiveRecord::Base.logger = Logger.new("log/cucumber.log")
7
+
8
+ Rivendell::Import.establish_connection "db/test.sqlite3"
9
+
10
+ require 'database_cleaner'
11
+ DatabaseCleaner.strategy = :truncation
12
+
13
+ Before do
14
+ DatabaseCleaner.start
15
+ end
16
+
17
+ After do |scenario|
18
+ DatabaseCleaner.clean
19
+ end
@@ -0,0 +1,34 @@
1
+ class Rivendell::API::MockXport
2
+
3
+ def carts
4
+ @carts ||= []
5
+ end
6
+
7
+ def list_carts(options = {})
8
+ result = carts
9
+ if group = options[:group]
10
+ result = result.select { |cart| cart.group == group }
11
+ end
12
+ result
13
+ end
14
+
15
+ def reset!
16
+ @carts = nil
17
+ end
18
+
19
+ end
20
+
21
+ class Rivendell::Import::Task
22
+
23
+ @@mock_xport = Rivendell::API::MockXport.new
24
+ cattr_accessor :mock_xport
25
+
26
+ def xport
27
+ mock_xport
28
+ end
29
+
30
+ end
31
+
32
+ Before do
33
+ Rivendell::Import::Task.mock_xport.reset!
34
+ end
@@ -0,0 +1,48 @@
1
+ require "rivendell/import/version"
2
+
3
+ require "null_logger"
4
+ require "active_support/core_ext/module/attribute_accessors"
5
+ require "active_support/core_ext/module/delegation"
6
+ require "active_support/core_ext/enumerable"
7
+
8
+ require "rivendell/import/config"
9
+
10
+ module Rivendell
11
+ module Import
12
+
13
+ @@config = Config.new
14
+ def self.config(&block)
15
+ yield @@config if block_given?
16
+ @@config
17
+ end
18
+
19
+ @@logger = NullLogger.instance
20
+ mattr_accessor :logger
21
+
22
+ def self.establish_connection(file = "db.sqlite3")
23
+ ActiveRecord::Base.establish_connection :adapter => "sqlite3", :database => file
24
+ ActiveRecord::Migrator.migrate(::File.expand_path("../../../db/migrate/", __FILE__), nil)
25
+ end
26
+
27
+ end
28
+ end
29
+
30
+ require 'listen'
31
+
32
+ require 'active_record'
33
+ ActiveRecord::Base.include_root_in_json = false
34
+
35
+ require "rivendell/api"
36
+
37
+ require "rivendell/import/worker"
38
+ require "rivendell/import/task"
39
+ require "rivendell/import/tasks"
40
+ require "rivendell/import/base"
41
+ require "rivendell/import/carts_cache"
42
+ require "rivendell/import/cart"
43
+ require "rivendell/import/context"
44
+ require "rivendell/import/cut"
45
+ require "rivendell/import/file"
46
+ require "rivendell/import/notification"
47
+ require "rivendell/import/notifier/base"
48
+ require "rivendell/import/notifier/mail"
@@ -0,0 +1,57 @@
1
+ require 'thread'
2
+
3
+ module Rivendell::Import
4
+ class Base
5
+
6
+ attr_reader :tasks, :workers
7
+
8
+ def initialize
9
+ @tasks = Tasks.new
10
+ @workers = []
11
+ end
12
+
13
+ attr_accessor :to_prepare
14
+
15
+ def listen(directory, options = {})
16
+ workers << Worker.new(self).start unless options[:dry_run]
17
+
18
+ Rivendell::Import.logger.info "Listen files in #{directory}"
19
+ Listen.to(directory) do |modified, added, removed|
20
+ added.each do |file|
21
+ Rivendell::Import.logger.debug "Detected file '#{file}'"
22
+ file(file, directory)
23
+ end
24
+ end
25
+ end
26
+
27
+ def process(*paths)
28
+ paths.flatten.each do |path|
29
+ method = ::File.directory?(path) ? :directory : :file
30
+ send method, path
31
+ end
32
+ end
33
+
34
+ def file(path, base_directory = nil)
35
+ file = Rivendell::Import::File.new path, :base_directory => base_directory
36
+ create_task file
37
+ end
38
+
39
+ def directory(directory)
40
+ Dir[::File.join(directory, "**/*")].each do |file|
41
+ file(file, directory) if ::File.file?(file)
42
+ end
43
+ end
44
+
45
+ def create_task(file)
46
+ Rivendell::Import.logger.debug "Create task for #{file}"
47
+ tasks.create(file) do |task|
48
+ prepare_task task
49
+ end
50
+ end
51
+
52
+ def prepare_task(task)
53
+ task.prepare(&to_prepare) if to_prepare
54
+ end
55
+
56
+ end
57
+ end