rivendell-import 0.0.1

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.
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