typingpool 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +23 -0
- data/bin/tp-assign +240 -0
- data/bin/tp-collect +50 -0
- data/bin/tp-config +114 -0
- data/bin/tp-finish +101 -0
- data/bin/tp-make +169 -0
- data/bin/tp-review +175 -0
- data/lib/typingpool/amazon.rb +732 -0
- data/lib/typingpool/app.rb +634 -0
- data/lib/typingpool/config.rb +344 -0
- data/lib/typingpool/error.rb +22 -0
- data/lib/typingpool/filer.rb +396 -0
- data/lib/typingpool/project.rb +593 -0
- data/lib/typingpool/template.rb +175 -0
- data/lib/typingpool/templates/assignment/amazon-init.js +38 -0
- data/lib/typingpool/templates/assignment/interview/nameless.html.erb +13 -0
- data/lib/typingpool/templates/assignment/interview/noisy.html.erb +12 -0
- data/lib/typingpool/templates/assignment/interview/partials/voices.html.erb +10 -0
- data/lib/typingpool/templates/assignment/interview/phone.html.erb +12 -0
- data/lib/typingpool/templates/assignment/interview.html.erb +11 -0
- data/lib/typingpool/templates/assignment/main.css +20 -0
- data/lib/typingpool/templates/assignment/partials/entry.html.erb +19 -0
- data/lib/typingpool/templates/assignment/partials/footer.html.erb +3 -0
- data/lib/typingpool/templates/assignment/partials/header.html.erb +11 -0
- data/lib/typingpool/templates/assignment/partials/labeling-example.html.erb +4 -0
- data/lib/typingpool/templates/assignment/partials/labeling.html.erb +5 -0
- data/lib/typingpool/templates/assignment/partials/length-description.html.erb +6 -0
- data/lib/typingpool/templates/assignment/partials/voices.html.erb +10 -0
- data/lib/typingpool/templates/assignment/speech.html.erb +11 -0
- data/lib/typingpool/templates/config.yml +21 -0
- data/lib/typingpool/templates/project/audio/chunks/.empty_directory +0 -0
- data/lib/typingpool/templates/project/audio/originals/.empty_directory +0 -0
- data/lib/typingpool/templates/project/data/.empty_directory +0 -0
- data/lib/typingpool/templates/project/etc/ About these files - read me.txt +8 -0
- data/lib/typingpool/templates/project/etc/audio-compat.js +25 -0
- data/lib/typingpool/templates/project/etc/player/audio-player.js +4 -0
- data/lib/typingpool/templates/project/etc/player/license.txt +19 -0
- data/lib/typingpool/templates/project/etc/player/player.swf +0 -0
- data/lib/typingpool/templates/project/etc/transcript.css +49 -0
- data/lib/typingpool/templates/transcript.html.erb +23 -0
- data/lib/typingpool/test/fixtures/amazon-question-html.html +95 -0
- data/lib/typingpool/test/fixtures/amazon-question-url.txt +1 -0
- data/lib/typingpool/test/fixtures/audio/mp3/interview.1.mp3 +0 -0
- data/lib/typingpool/test/fixtures/audio/mp3/interview.2.mp3 +0 -0
- data/lib/typingpool/test/fixtures/audio/wma/VN620007.WMA +0 -0
- data/lib/typingpool/test/fixtures/audio/wma/VN620052.WMA +0 -0
- data/lib/typingpool/test/fixtures/config-1 +20 -0
- data/lib/typingpool/test/fixtures/config-2 +25 -0
- data/lib/typingpool/test/fixtures/not_yaml.txt +4 -0
- data/lib/typingpool/test/fixtures/template-2.html.erb +10 -0
- data/lib/typingpool/test/fixtures/template-3.html.erb +22 -0
- data/lib/typingpool/test/fixtures/template.html.erb +10 -0
- data/lib/typingpool/test/fixtures/tp_collect_id.txt +1 -0
- data/lib/typingpool/test/fixtures/tp_collect_sandbox-assignment.csv +8 -0
- data/lib/typingpool/test/fixtures/tp_review_id.txt +1 -0
- data/lib/typingpool/test/fixtures/tp_review_sandbox-assignment.csv +8 -0
- data/lib/typingpool/test/fixtures/transcript-chunks.csv +226 -0
- data/lib/typingpool/test/fixtures/utf8_transcript.txt +7 -0
- data/lib/typingpool/test/fixtures/vcr/tp-collect-1.yml +2712 -0
- data/lib/typingpool/test/fixtures/vcr/tp-collect-2.yml +2718 -0
- data/lib/typingpool/test/fixtures/vcr/tp-collect-3.yml +2768 -0
- data/lib/typingpool/test/fixtures/vcr/tp-review-1.yml +570 -0
- data/lib/typingpool/test/fixtures/vcr/tp-review-2.yml +351 -0
- data/lib/typingpool/test.rb +418 -0
- data/lib/typingpool/transcript.rb +181 -0
- data/lib/typingpool/utility.rb +272 -0
- data/lib/typingpool.rb +500 -0
- data/test/make_amazon_question_fixture.rb +24 -0
- data/test/make_tp_collect_fixture_1.rb +26 -0
- data/test/make_tp_collect_fixture_2.rb +16 -0
- data/test/make_tp_collect_fixture_3.rb +15 -0
- data/test/make_tp_collect_fixture_4.rb +17 -0
- data/test/make_tp_review_fixture_1.rb +26 -0
- data/test/make_tp_review_fixture_2.rb +30 -0
- data/test/make_transcript_chunks_fixture.rb +53 -0
- data/test/test_integration_script_1_tp_config.rb +108 -0
- data/test/test_integration_script_2_tp_make.rb +119 -0
- data/test/test_integration_script_3_tp_assign.rb +152 -0
- data/test/test_integration_script_4_tp_review.rb +72 -0
- data/test/test_integration_script_5_tp_collect.rb +44 -0
- data/test/test_integration_script_6_tp_finish.rb +123 -0
- data/test/test_unit_amazon.rb +153 -0
- data/test/test_unit_config.rb +94 -0
- data/test/test_unit_filer.rb +202 -0
- data/test/test_unit_project.rb +168 -0
- data/test/test_unit_project_local.rb +68 -0
- data/test/test_unit_project_remote.rb +157 -0
- data/test/test_unit_template.rb +111 -0
- data/test/test_unit_transcript.rb +77 -0
- metadata +234 -0
@@ -0,0 +1,53 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
$:.unshift File.join(File.dirname(File.dirname($0)), 'lib')
|
4
|
+
|
5
|
+
require 'typingpool'
|
6
|
+
|
7
|
+
lines_each = 2
|
8
|
+
if ARGV.last.to_s.match(/^\d+$/)
|
9
|
+
lines_each = ARGV.pop.to_i
|
10
|
+
end
|
11
|
+
|
12
|
+
if ARGV.empty?
|
13
|
+
abort "USAGE: #{File.basename($PROGRAM_NAME)} PROJECT_DIR [PROJECT_DIR...] [LINES_EACH=2]"
|
14
|
+
end
|
15
|
+
|
16
|
+
data_files = ARGV.map do |path|
|
17
|
+
data_file = nil
|
18
|
+
expanded = File.expand_path(path)
|
19
|
+
if not(File.exists? expanded)
|
20
|
+
abort "No such dir #{path}"
|
21
|
+
end
|
22
|
+
if not(File.directory? expanded)
|
23
|
+
abort "Not a dir: #{path}"
|
24
|
+
end
|
25
|
+
%w(data csv).each do |data_dir_name|
|
26
|
+
possible_data_file = File.join(expanded, data_dir_name, 'assignment.csv')
|
27
|
+
if File.exists? possible_data_file
|
28
|
+
data_file = possible_data_file
|
29
|
+
end
|
30
|
+
end #%w().each do...
|
31
|
+
if not(data_file)
|
32
|
+
abort "Dir #{path} has no data/assignment.csv or csv/assignment.csv"
|
33
|
+
end
|
34
|
+
data_file
|
35
|
+
end #ARGV.map
|
36
|
+
|
37
|
+
assignments=[]
|
38
|
+
data_files.each do |path|
|
39
|
+
csv = Typingpool::Filer::CSV.new(path)
|
40
|
+
with_transcripts = csv.reject{|assignment| assignment['transcript'].to_s.empty? }
|
41
|
+
next if with_transcripts.empty?
|
42
|
+
seeking = with_transcripts.count
|
43
|
+
if seeking > lines_each
|
44
|
+
seeking = lines_each
|
45
|
+
end
|
46
|
+
assignments.push(*with_transcripts.sample(seeking))
|
47
|
+
end #data_files.each do...
|
48
|
+
|
49
|
+
if assignments.empty?
|
50
|
+
abort "No transcripts found"
|
51
|
+
end
|
52
|
+
fixtures_dir = File.join(Typingpool::Utility.lib_dir, 'test', 'fixtures')
|
53
|
+
Typingpool::Filer::CSV.new(File.join(fixtures_dir, 'transcript-chunks.csv')).write(assignments)
|
@@ -0,0 +1,108 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
$:.unshift File.join(File.dirname(File.dirname($0)), 'lib')
|
4
|
+
|
5
|
+
require 'typingpool'
|
6
|
+
require 'typingpool/test'
|
7
|
+
|
8
|
+
class TestTpConfig < Typingpool::Test::Script
|
9
|
+
|
10
|
+
def test_abort_with_invalid_file
|
11
|
+
exception = assert_raise(Typingpool::Error::Shell) do
|
12
|
+
tp_config(File.join(fixtures_dir, 'not_yaml.txt'))
|
13
|
+
end
|
14
|
+
assert_match(exception.message, /not valid yaml/i)
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_abort_with_directory_path
|
18
|
+
dir = File.join(fixtures_dir, 'vcr')
|
19
|
+
assert(File.exists? dir)
|
20
|
+
assert(File.directory? dir)
|
21
|
+
exception = assert_raise(Typingpool::Error::Shell) do
|
22
|
+
tp_config(dir)
|
23
|
+
end
|
24
|
+
assert_match(exception.message, /not a file/i)
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_abort_with_invalid_path
|
28
|
+
path = '/jksdljs/euwiroeuw'
|
29
|
+
refute(File.exists? path)
|
30
|
+
exception = assert_raise(Typingpool::Error::Shell) do
|
31
|
+
tp_config(path)
|
32
|
+
end
|
33
|
+
assert_match(exception.message, /valid path/i)
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_usage_message
|
37
|
+
assert(output = tp_config('--help'))
|
38
|
+
assert_match(output, /\bUSAGE:/)
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_new_config_creation
|
42
|
+
in_temp_dir do |dir|
|
43
|
+
path = {
|
44
|
+
:config => File.join(dir, 'config.yml'),
|
45
|
+
:transcript_dir => File.join(dir, 'transcriptionz')
|
46
|
+
}
|
47
|
+
path.values.each{|path| refute(File.exists? path) }
|
48
|
+
assert(output = tp_config_with_input([path[:config], '--test'], ['keykey', 'secretsecret', path[:transcript_dir]]))
|
49
|
+
assert_match(output[:err], /wrote config to/i)
|
50
|
+
path.values.each{|path| assert(File.exists? path) }
|
51
|
+
assert(File.file? path[:config] )
|
52
|
+
assert(File.directory? path[:transcript_dir] )
|
53
|
+
assert(config = Typingpool::Config.file(path[:config]))
|
54
|
+
assert_equal(path[:transcript_dir], config.transcripts)
|
55
|
+
assert_equal(File.join(path[:transcript_dir], 'templates').downcase, config.templates.downcase)
|
56
|
+
assert_equal('keykey', config.amazon.key)
|
57
|
+
assert_equal('secretsecret', config.amazon.secret)
|
58
|
+
refute_empty(config.amazon.bucket.to_s)
|
59
|
+
end #in_temp_dir do |dir|
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_config_editing
|
63
|
+
in_temp_dir do |dir|
|
64
|
+
path = {
|
65
|
+
:config => File.join(dir, 'config.yml'),
|
66
|
+
:fixture => File.join(fixtures_dir, 'config-1'),
|
67
|
+
:transcript_dir => File.join(dir, 'transcriptionz')
|
68
|
+
}
|
69
|
+
assert(File.exists? path[:fixture])
|
70
|
+
refute(File.exists? path[:config])
|
71
|
+
FileUtils.cp(path[:fixture], path[:config])
|
72
|
+
assert(File.exists? path[:config])
|
73
|
+
assert(original_config = Typingpool::Config.file(path[:config]))
|
74
|
+
[:key, :secret, :bucket].each{|param| refute_empty(original_config.amazon.send(param).to_s) }
|
75
|
+
[:transcripts, :templates, :cache].each{|param| refute_empty(original_config.send(param).to_s) }
|
76
|
+
assert(output = tp_config_with_input([path[:config], '--test'], ['keykey', 'secretsecret', path[:transcript_dir]]))
|
77
|
+
assert(edited_config = Typingpool::Config.file(path[:config]))
|
78
|
+
[:key, :secret].each{|param| refute_equal(original_config.amazon.send(param), edited_config.amazon.send(param)) }
|
79
|
+
assert_equal(original_config.amazon.bucket, edited_config.amazon.bucket)
|
80
|
+
[:templates, :cache].each{|param| assert_equal(original_config.send(param), edited_config.send(param)) }
|
81
|
+
refute_equal(original_config.transcripts, edited_config.transcripts)
|
82
|
+
assert_equal('keykey', edited_config.amazon.key)
|
83
|
+
assert_equal('secretsecret', edited_config.amazon.secret)
|
84
|
+
assert_equal(path[:transcript_dir], edited_config.transcripts)
|
85
|
+
end #in_temp_dir |dir| do
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_skips_bucket_when_sftp_params_exist
|
89
|
+
in_temp_dir do |dir|
|
90
|
+
path = {
|
91
|
+
:config => File.join(dir, 'config.yml'),
|
92
|
+
:fixture => File.join(fixtures_dir, 'config-2'),
|
93
|
+
:transcript_dir => File.join(dir, 'transcriptionz')
|
94
|
+
}
|
95
|
+
assert(File.exists? path[:fixture])
|
96
|
+
refute(File.exists? path[:config])
|
97
|
+
FileUtils.cp(path[:fixture], path[:config])
|
98
|
+
assert(File.exists? path[:config])
|
99
|
+
assert(original_config = Typingpool::Config.file(path[:config]))
|
100
|
+
assert_empty(original_config.amazon.bucket.to_s)
|
101
|
+
assert(output = tp_config_with_input([path[:config], '--test'], ['keykey', 'secretsecret', path[:transcript_dir]]))
|
102
|
+
assert_match(output[:err], /wrote config to/i)
|
103
|
+
assert(edited_config = Typingpool::Config.file(path[:config]))
|
104
|
+
assert_empty(edited_config.amazon.bucket.to_s)
|
105
|
+
end #in_temp_dir do |dir|
|
106
|
+
end
|
107
|
+
|
108
|
+
end #class TestTpConfig
|
@@ -0,0 +1,119 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
$:.unshift File.join(File.dirname(File.dirname($0)), 'lib')
|
4
|
+
|
5
|
+
require 'typingpool'
|
6
|
+
require 'typingpool/test'
|
7
|
+
require 'csv'
|
8
|
+
|
9
|
+
class TestTpMake < Typingpool::Test::Script
|
10
|
+
def test_abort_with_no_files
|
11
|
+
assert_tp_make_abort_match(['--title', 'Foo', '--chunks', '0:20'], /no files/i)
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_abort_with_no_title
|
15
|
+
assert_tp_make_abort_match(['--file', audio_files[0]], /no title/i)
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_abort_with_invalid_title
|
19
|
+
assert_tp_make_abort_match(['--file', audio_files[0], '--title', 'Foo/Bar'], /illegal character/i)
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_abort_with_no_args
|
23
|
+
assert_tp_make_abort_match([], /\bUSAGE:/)
|
24
|
+
end
|
25
|
+
|
26
|
+
def assert_tp_make_abort_match(args, regex)
|
27
|
+
assert_script_abort_match(args, regex) do |args|
|
28
|
+
call_tp_make(*args)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def tp_make_with(dir, config_path, subdir='mp3')
|
33
|
+
begin
|
34
|
+
tp_make(dir, config_path, subdir)
|
35
|
+
assert(project = temp_tp_dir_project(dir, Typingpool::Config.file(config_path)))
|
36
|
+
assert_not_nil(project.local)
|
37
|
+
assert_not_nil(project.local.id)
|
38
|
+
assert(project.local.subdir('audio','chunks').to_a.size <= 7)
|
39
|
+
assert(project.local.subdir('audio','chunks').to_a.size >= 6)
|
40
|
+
assert_equal(project_default[:subtitle], project.local.subtitle)
|
41
|
+
assignments = project.local.file('data', 'assignment.csv').as(:csv)
|
42
|
+
assert_equal(project.local.subdir('audio','chunks').to_a.size, assignments.count)
|
43
|
+
assert_all_assets_have_upload_status(assignments, ['audio'], 'yes')
|
44
|
+
assignments.each do |assignment|
|
45
|
+
assert_not_nil(assignment['audio_url'])
|
46
|
+
assert(working_url? assignment['audio_url'])
|
47
|
+
assert_equal(assignment['project_id'], project.local.id)
|
48
|
+
assert_equal(assignment['unusual'].split(/\s*,\s*/), project_default[:unusual])
|
49
|
+
project_default[:voice].each_with_index do |voice, i|
|
50
|
+
name, description = voice.split(/\s*,\s*/)
|
51
|
+
assert_equal(name, assignment["voice#{i+1}"])
|
52
|
+
if not(description.to_s.empty?)
|
53
|
+
assert_equal(description, assignment["voice#{i+1}title"])
|
54
|
+
end
|
55
|
+
end #project_default[:voice].each_with_index...
|
56
|
+
end #assignments.each d0....
|
57
|
+
ensure
|
58
|
+
tp_finish_outside_sandbox(dir, config_path)
|
59
|
+
end #begin
|
60
|
+
assert_all_assets_have_upload_status(assignments, ['audio'], 'no')
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_tp_make
|
64
|
+
Dir.entries(audio_dir).select{|entry| File.directory?(File.join(audio_dir, entry))}.reject{|entry| entry.match(/^\./) }.each do |subdir|
|
65
|
+
in_temp_tp_dir do |dir|
|
66
|
+
config_path = self.config_path(dir)
|
67
|
+
skip_if_no_upload_credentials('tp-make integration test', Typingpool::Config.file(config_path))
|
68
|
+
tp_make_with(dir, config_path, subdir)
|
69
|
+
end #in_temp_tp_dir
|
70
|
+
end #Dir.entries
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_tp_make_s3
|
74
|
+
in_temp_tp_dir do |dir|
|
75
|
+
skip_if_no_s3_credentials('tp-make S3 integration test', config)
|
76
|
+
config_path = setup_s3_config(dir)
|
77
|
+
tp_make_with(dir, config_path)
|
78
|
+
end #in_temp_tp_dir do...
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_fixing_failed_tp_make
|
82
|
+
in_temp_tp_dir do |dir|
|
83
|
+
config = config_from_dir(dir)
|
84
|
+
skip_if_no_s3_credentials('tp-make failed upload integration test', config)
|
85
|
+
good_config_path = setup_s3_config(dir)
|
86
|
+
bad_config_path = setup_s3_config_with_bad_password(dir)
|
87
|
+
assert_raises(Typingpool::Error::Shell) do
|
88
|
+
tp_make(dir, bad_config_path, 'mp3')
|
89
|
+
end
|
90
|
+
project_dir = temp_tp_dir_project_dir(dir)
|
91
|
+
assert(File.exists? project_dir)
|
92
|
+
assert(File.directory? project_dir)
|
93
|
+
assert(File.exists? File.join(project_dir, 'data', 'assignment.csv'))
|
94
|
+
originals_dir = File.join(project_dir, 'audio', 'originals')
|
95
|
+
refute_empty(Dir.entries(originals_dir).reject{|entry| entry.match(/^\./) }.map{|entry| File.join(originals_dir, entry) }.select{|path| File.file? path })
|
96
|
+
assert(project = temp_tp_dir_project(dir))
|
97
|
+
assert(assignment_csv = project.local.file('data', 'assignment.csv').as(:csv))
|
98
|
+
refute_empty(assignment_csv.to_a)
|
99
|
+
assert_all_assets_have_upload_status(assignment_csv, ['audio'], 'maybe')
|
100
|
+
assert(audio_urls = assignment_csv.map{|assignment| assignment['audio_url'] })
|
101
|
+
refute_empty(audio_urls)
|
102
|
+
assert_empty(audio_urls.select{|url| working_url? url })
|
103
|
+
begin
|
104
|
+
tp_make(dir, good_config_path, 'mp3')
|
105
|
+
refute_empty(assignment_csv.read)
|
106
|
+
assert_all_assets_have_upload_status(assignment_csv, ['audio'], 'yes')
|
107
|
+
refute_empty(audio_urls2 = assignment_csv.map{|assignment| assignment['audio_url'] })
|
108
|
+
audio_urls.each_with_index do |original_url, i|
|
109
|
+
assert_equal(original_url, audio_urls2[i])
|
110
|
+
end
|
111
|
+
assert_equal(audio_urls.count, audio_urls2.select{|url| working_url? url }.count)
|
112
|
+
ensure
|
113
|
+
tp_finish_outside_sandbox(dir, good_config_path)
|
114
|
+
end #begin
|
115
|
+
assert_all_assets_have_upload_status(assignment_csv, ['audio'], 'no')
|
116
|
+
end #in_temp_tp_dir do...
|
117
|
+
end
|
118
|
+
|
119
|
+
end #TestTpMake
|
@@ -0,0 +1,152 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
$:.unshift File.join(File.dirname(File.dirname($0)), 'lib')
|
4
|
+
|
5
|
+
require 'typingpool'
|
6
|
+
require 'typingpool/test'
|
7
|
+
|
8
|
+
class TestTpAssign < Typingpool::Test::Script
|
9
|
+
#TODO: test that qualifications are sent (will need heroic effort
|
10
|
+
#(or at least some xml parsing) since rturk doesn't provide an
|
11
|
+
#easy way to look at HIT qualifications)
|
12
|
+
def test_abort_with_no_input
|
13
|
+
assert_raise(Typingpool::Error::Shell){call_tp_assign}
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_abort_with_no_template
|
17
|
+
assert_tp_assign_abort_match([project_default[:title]], /Missing\b[^\n\r\f]*\btemplate/i)
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_abort_with_bad_timespec
|
21
|
+
assert_tp_assign_abort_match([project_default[:title], assign_default[:template], '--lifetime', '4u'], /can't convert/i)
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_abort_with_bad_qualification
|
25
|
+
assert_tp_assign_abort_match([project_default[:title], assign_default[:template], '--qualify', 'approval_rate &= 8'], /\bsense of --qualify.+\bunknown comparator\b/i)
|
26
|
+
assert_tp_assign_abort_match([project_default[:title], assign_default[:template], '--qualify', 'fake_rate > 8'], /\bsense of --qualify\b.+unknown\b[^\n\r\f]*\btype\b/i)
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_abort_with_bad_reward
|
30
|
+
assert_tp_assign_abort_match([project_default[:title], assign_default[:template], '--reward', 'foo'], /sense of --reward/i)
|
31
|
+
end
|
32
|
+
|
33
|
+
def assert_tp_assign_abort_match(args, regex)
|
34
|
+
assert_script_abort_match(args, regex) do |args|
|
35
|
+
call_tp_assign(*args)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_tp_assign
|
40
|
+
skip_if_no_amazon_credentials('tp-assign integration test')
|
41
|
+
skip_if_no_upload_credentials('tp-assign integration test')
|
42
|
+
in_temp_tp_dir do |dir|
|
43
|
+
tp_make(dir)
|
44
|
+
begin
|
45
|
+
tp_assign(dir)
|
46
|
+
assign_time = Time.now
|
47
|
+
config = config_from_dir(dir)
|
48
|
+
project = temp_tp_dir_project(dir)
|
49
|
+
setup_amazon(dir)
|
50
|
+
results = nil
|
51
|
+
refute_empty(results = Typingpool::Amazon::HIT.all_for_project(project.local.id))
|
52
|
+
assert_equal(project.local.subdir('audio','chunks').to_a.size, results.size)
|
53
|
+
assert_equal(Typingpool::Utility.timespec_to_seconds(assign_default[:deadline]), results[0].full.assignments_duration.to_i)
|
54
|
+
#These numbers will be apart due to clock differences and
|
55
|
+
#timing vagaries of the assignment.
|
56
|
+
assert_in_delta((assign_time + Typingpool::Utility.timespec_to_seconds(assign_default[:lifetime])).to_f, results[0].full.expires_at.to_f, 60)
|
57
|
+
keywords = results[0].at_amazon.keywords
|
58
|
+
assign_default[:keyword].each{|keyword| assert_includes(keywords, keyword)}
|
59
|
+
sandbox_csv = project.local.file('data', 'sandbox-assignment.csv').as(:csv)
|
60
|
+
refute_empty(assignment_urls = sandbox_csv.map{|assignment| assignment['assignment_url'] })
|
61
|
+
assert(assignment_html = fetch_url(assignment_urls.first).body)
|
62
|
+
assert_match(assignment_html, /\b20[\s-]+second\b/)
|
63
|
+
assert_all_assets_have_upload_status(sandbox_csv, ['assignment'], 'yes')
|
64
|
+
ensure
|
65
|
+
tp_finish(dir)
|
66
|
+
end #begin
|
67
|
+
assert_empty(Typingpool::Amazon::HIT.all_for_project(project.local.id))
|
68
|
+
end # in_temp_tp_dir
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_uploads_audio_when_needed
|
72
|
+
skip_if_no_amazon_credentials('tp-assign unuploaded audio integration test')
|
73
|
+
skip_if_no_s3_credentials('tp-assign unuploaded audio integration test')
|
74
|
+
in_temp_tp_dir do |dir|
|
75
|
+
good_config_path = setup_s3_config(dir)
|
76
|
+
bad_config_path = setup_s3_config_with_bad_password(dir)
|
77
|
+
assert_raises(Typingpool::Error::Shell) do
|
78
|
+
tp_make(dir, bad_config_path, 'mp3')
|
79
|
+
end
|
80
|
+
project_dir = temp_tp_dir_project_dir(dir)
|
81
|
+
assert(File.exists? project_dir)
|
82
|
+
assert(File.directory? project_dir)
|
83
|
+
assert(project = temp_tp_dir_project(dir, Typingpool::Config.file(bad_config_path)))
|
84
|
+
csv = project.local.file('data', 'assignment.csv').as(:csv)
|
85
|
+
assert_empty(csv.select{|assignment| working_url? assignment['audio_url']})
|
86
|
+
assert_all_assets_have_upload_status(csv, ['audio'], 'maybe')
|
87
|
+
begin
|
88
|
+
tp_assign(dir, good_config_path)
|
89
|
+
sandbox_csv = project.local.file('data', 'sandbox-assignment.csv').as(:csv)
|
90
|
+
assert_equal(csv.count, sandbox_csv.count)
|
91
|
+
assert_equal(sandbox_csv.count, sandbox_csv.select{|assignment| working_url? assignment['audio_url'] }.count)
|
92
|
+
assert_all_assets_have_upload_status(csv, ['audio'], 'yes')
|
93
|
+
ensure
|
94
|
+
tp_finish(dir, good_config_path)
|
95
|
+
end #begin
|
96
|
+
end # in_temp_tp_dir do...
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_fixing_failed_assignment_html_upload
|
100
|
+
skip_if_no_amazon_credentials('tp-assign failed assignment upload integration test')
|
101
|
+
skip_if_no_s3_credentials('tp-assign failed assignment upload integration test')
|
102
|
+
in_temp_tp_dir do |dir|
|
103
|
+
good_config_path = setup_s3_config(dir)
|
104
|
+
bad_config_path = setup_s3_config_with_bad_password(dir)
|
105
|
+
tp_make(dir, good_config_path, 'mp3')
|
106
|
+
begin
|
107
|
+
assert(project = temp_tp_dir_project(dir, Typingpool::Config.file(good_config_path)))
|
108
|
+
assert(project.local)
|
109
|
+
get_assignment_urls = lambda{|csv| csv.map{|assignment| assignment['assignment_url'] }.select{|url| url } }
|
110
|
+
assert_empty(get_assignment_urls.call(project.local.file('data', 'assignment.csv').as(:csv)))
|
111
|
+
exception = assert_raises(Typingpool::Error::Shell) do
|
112
|
+
tp_assign(dir, bad_config_path)
|
113
|
+
end #assert_raises...
|
114
|
+
assert_match(exception.message, /s3 operation fail/i)
|
115
|
+
sandbox_csv = project.local.file('data', 'sandbox-assignment.csv').as(:csv)
|
116
|
+
refute_empty(get_assignment_urls.call(sandbox_csv))
|
117
|
+
check_assignment_urls = lambda{ get_assignment_urls.call(sandbox_csv).map{|url| Typingpool::Utility.working_url? url } }
|
118
|
+
check_assignment_urls.call.each{|checked_out| refute(checked_out) }
|
119
|
+
assert_all_assets_have_upload_status(sandbox_csv, ['assignment'], 'maybe')
|
120
|
+
tp_assign(dir, good_config_path)
|
121
|
+
check_assignment_urls.call.each{|checked_out| assert(checked_out) }
|
122
|
+
assert_all_assets_have_upload_status(sandbox_csv, ['assignment'], 'yes')
|
123
|
+
ensure
|
124
|
+
tp_finish(dir, good_config_path)
|
125
|
+
end #begin
|
126
|
+
end #in_temp_tp_dir do...
|
127
|
+
end
|
128
|
+
|
129
|
+
def test_abort_on_config_mismatch
|
130
|
+
skip_if_no_s3_credentials('tp-assign abort on config mismatch test')
|
131
|
+
in_temp_tp_dir do |dir|
|
132
|
+
config = config_from_dir(dir)
|
133
|
+
good_config_path = setup_s3_config(dir, config, '.config_s3_good')
|
134
|
+
tp_make(dir, good_config_path)
|
135
|
+
begin
|
136
|
+
tp_finish_outside_sandbox(dir, good_config_path)
|
137
|
+
assert(config.amazon.bucket)
|
138
|
+
new_bucket = 'configmismatch-test'
|
139
|
+
refute_equal(new_bucket, config.amazon.bucket)
|
140
|
+
config.amazon.bucket = new_bucket
|
141
|
+
bad_config_path = setup_s3_config(dir, config, '.config_s3_bad')
|
142
|
+
exception = assert_raises(Typingpool::Error::Shell) do
|
143
|
+
tp_assign(dir, bad_config_path)
|
144
|
+
end #assert_raises...
|
145
|
+
assert_match(exception.message, /\burls don't look right\b/i)
|
146
|
+
ensure
|
147
|
+
tp_finish(dir, good_config_path)
|
148
|
+
end #begin
|
149
|
+
end #in_temp_tp_dir do...
|
150
|
+
end
|
151
|
+
|
152
|
+
end #TestTpAssign
|
@@ -0,0 +1,72 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
$:.unshift File.join(File.dirname(File.dirname($0)), 'lib')
|
4
|
+
|
5
|
+
require 'typingpool'
|
6
|
+
require 'typingpool/test'
|
7
|
+
|
8
|
+
class TestTpReview < Typingpool::Test::Script
|
9
|
+
|
10
|
+
def test_tp_review
|
11
|
+
in_temp_tp_dir do |dir|
|
12
|
+
skip_if_no_upload_credentials('tp-review integration test')
|
13
|
+
skip_if_no_amazon_credentials('tp-review integration test')
|
14
|
+
tp_make(dir)
|
15
|
+
copy_fixtures_to_temp_tp_dir(dir, 'tp_review_')
|
16
|
+
assert(File.exists? File.join(temp_tp_dir_project_dir(dir), 'data','sandbox-assignment.csv'))
|
17
|
+
project = temp_tp_dir_project(dir)
|
18
|
+
assert_equal(7, project.local.file('data','sandbox-assignment.csv').as(:csv).reject{|assignment| assignment['hit_id'].to_s.empty? }.count)
|
19
|
+
begin
|
20
|
+
output = nil
|
21
|
+
assert_nothing_raised do
|
22
|
+
output = tp_review_with_fixture(dir, File.join(fixtures_dir, 'vcr', 'tp-review-1'), %w(a r a r s q))
|
23
|
+
end
|
24
|
+
assert_equal(0, output[:status].to_i, "Bad exit code: #{output[:status]} err: #{output[:err]}")
|
25
|
+
assert_equal(5, project.local.file('data','sandbox-assignment.csv').as(:csv).reject{|assignment| assignment['hit_id'].to_s.empty? }.count)
|
26
|
+
reviews = split_reviews(output[:out])
|
27
|
+
assert_match(reviews[1], /Interview\.00\.00/)
|
28
|
+
#we can't specify leading \b boundaries because the ansi
|
29
|
+
#escape sequences mess that up
|
30
|
+
assert_match(reviews[1], /Approved\b/i)
|
31
|
+
assert_match(reviews[2], /Interview\.00\.20/)
|
32
|
+
assert_match(reviews[2], /reason\b/i)
|
33
|
+
assert_match(reviews[2], /Rejected\b/i)
|
34
|
+
assert_match(reviews[3], /Interview\.00\.40/)
|
35
|
+
assert_match(reviews[3], /Approved\b/i)
|
36
|
+
assert_match(reviews[4], /Interview\.01\.00/)
|
37
|
+
assert_match(reviews[4], /reason\b/i)
|
38
|
+
assert_match(reviews[4], /Rejected\b/i)
|
39
|
+
assert_match(reviews[5], /Interview\.01\.20/)
|
40
|
+
assert_match(reviews[5], /Skipping\b/i)
|
41
|
+
assert_match(reviews[6], /Interview\.02\.00/)
|
42
|
+
assert_match(reviews[6], /Quitting\b/i)
|
43
|
+
transcript = assert_has_partial_transcript(dir)
|
44
|
+
assert_html_has_audio_count(2, transcript)
|
45
|
+
assert_assignment_csv_has_transcription_count(2, project, 'sandbox-assignment.csv')
|
46
|
+
|
47
|
+
assert_nothing_raised do
|
48
|
+
output = tp_review_with_fixture(dir, File.join(fixtures_dir, 'vcr', 'tp-review-2'), %w(a r))
|
49
|
+
end
|
50
|
+
assert_equal(0, output[:status].to_i, "Bad exit code: #{output[:status]} err: #{output[:err]}")
|
51
|
+
assert_equal(4, project.local.file('data','sandbox-assignment.csv').as(:csv).reject{|assignment| assignment['hit_id'].to_s.empty? }.count)
|
52
|
+
reviews = split_reviews(output[:out])
|
53
|
+
assert_match(reviews[1], /Interview\.01\.20/)
|
54
|
+
assert_match(reviews[1], /Approved\b/i)
|
55
|
+
assert_match(reviews[2], /Interview\.02\.00/)
|
56
|
+
assert_match(reviews[2], /reason\b/i)
|
57
|
+
assert_match(reviews[2], /Rejected\b/i)
|
58
|
+
transcript = assert_has_partial_transcript(dir)
|
59
|
+
assert_html_has_audio_count(3, transcript)
|
60
|
+
assert_assignment_csv_has_transcription_count(3, project, 'sandbox-assignment.csv')
|
61
|
+
ensure
|
62
|
+
rm_fixtures_from_temp_tp_dir(dir, 'tp_review_')
|
63
|
+
tp_finish(dir)
|
64
|
+
end #begin
|
65
|
+
end #in_temp_tp_dir
|
66
|
+
end
|
67
|
+
|
68
|
+
def split_reviews(output)
|
69
|
+
output.split(/Transcript for\b/)
|
70
|
+
end
|
71
|
+
|
72
|
+
end #class TestTpReview
|
@@ -0,0 +1,44 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
$:.unshift File.join(File.dirname(File.dirname($0)), 'lib')
|
4
|
+
|
5
|
+
require 'typingpool'
|
6
|
+
require 'typingpool/test'
|
7
|
+
|
8
|
+
class TestTpCollect < Typingpool::Test::Script
|
9
|
+
require 'fileutils'
|
10
|
+
|
11
|
+
def test_tp_collect
|
12
|
+
in_temp_tp_dir do |dir|
|
13
|
+
skip_if_no_upload_credentials('tp-collect integration test')
|
14
|
+
skip_if_no_amazon_credentials('tp-collect integration test')
|
15
|
+
tp_make(dir)
|
16
|
+
copy_fixtures_to_temp_tp_dir(dir, 'tp_collect_')
|
17
|
+
begin
|
18
|
+
project = temp_tp_dir_project(dir)
|
19
|
+
assert_nothing_raised do
|
20
|
+
tp_collect_with_fixture(dir, File.join(vcr_dir, 'tp-collect-1'))
|
21
|
+
end
|
22
|
+
transcript = assert_has_partial_transcript(dir)
|
23
|
+
assert_html_has_audio_count(2, transcript)
|
24
|
+
assert_assignment_csv_has_transcription_count(2, project, 'sandbox-assignment.csv')
|
25
|
+
assert_nothing_raised do
|
26
|
+
tp_collect_with_fixture(dir, File.join(vcr_dir, 'tp-collect-2'))
|
27
|
+
end
|
28
|
+
transcript = assert_has_partial_transcript(dir)
|
29
|
+
assert_html_has_audio_count(4, transcript)
|
30
|
+
assert_assignment_csv_has_transcription_count(4, project, 'sandbox-assignment.csv')
|
31
|
+
assert_nothing_raised do
|
32
|
+
tp_collect_with_fixture(dir, File.join(vcr_dir, 'tp-collect-3'))
|
33
|
+
end
|
34
|
+
# transcript = assert_has_transcript(dir) || assert_has_partial_transcript(dir)
|
35
|
+
# assert_html_has_audio_count(7, transcript)
|
36
|
+
# assert_assignment_csv_has_transcription_count(7, project, 'sandbox-assignment.csv')
|
37
|
+
ensure
|
38
|
+
rm_fixtures_from_temp_tp_dir(dir, 'tp_collect_')
|
39
|
+
tp_finish(dir)
|
40
|
+
end #begin
|
41
|
+
end #in_temp_tp_dir
|
42
|
+
end
|
43
|
+
|
44
|
+
end #TestTpCollect
|
@@ -0,0 +1,123 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
$:.unshift File.join(File.dirname(File.dirname($0)), 'lib')
|
4
|
+
|
5
|
+
require 'typingpool'
|
6
|
+
require 'typingpool/test'
|
7
|
+
|
8
|
+
class TestTpFinish < Typingpool::Test::Script
|
9
|
+
def tp_finish_on_audio_files_with(dir, config_path)
|
10
|
+
skip_if_no_amazon_credentials('tp-finish audio test')
|
11
|
+
skip_if_no_upload_credentials('tp-finish audio test')
|
12
|
+
tp_make(dir, config_path)
|
13
|
+
project = temp_tp_dir_project(dir, Typingpool::Config.file(config_path))
|
14
|
+
csv = project.local.file('data', 'assignment.csv').as(:csv)
|
15
|
+
urls = csv.map{|assignment| assignment['audio_url'] }
|
16
|
+
refute_empty(urls)
|
17
|
+
assert_all_assets_have_upload_status(csv, ['audio'], 'yes')
|
18
|
+
assert_equal(urls.size, urls.select{|url| working_url? url}.size)
|
19
|
+
assert_nothing_raised do
|
20
|
+
tp_finish_outside_sandbox(dir, config_path)
|
21
|
+
end
|
22
|
+
assert_empty(urls.select{|url| working_url? url })
|
23
|
+
assert_all_assets_have_upload_status(csv, ['audio'], 'no')
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_tp_finish_on_audio_files
|
27
|
+
in_temp_tp_dir do |dir|
|
28
|
+
config_path = self.config_path(dir)
|
29
|
+
tp_finish_on_audio_files_with(dir, config_path)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_tp_finish_on_audio_files_with_s3
|
34
|
+
in_temp_tp_dir do |dir|
|
35
|
+
config = config_from_dir(dir)
|
36
|
+
config.to_hash.delete('sftp')
|
37
|
+
config_path = write_config(config, dir)
|
38
|
+
tp_finish_on_audio_files_with(dir, config_path)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_tp_finish_on_amazon_hits
|
43
|
+
skip_if_no_amazon_credentials('tp-finish Amazon test')
|
44
|
+
skip_if_no_upload_credentials('tp-finish Amazon test')
|
45
|
+
in_temp_tp_dir do |dir|
|
46
|
+
tp_make(dir)
|
47
|
+
tp_assign(dir)
|
48
|
+
project = temp_tp_dir_project(dir)
|
49
|
+
sandbox_csv = project.local.file('data', 'sandbox-assignment.csv').as(:csv)
|
50
|
+
assert_all_assets_have_upload_status(sandbox_csv, ['audio', 'assignment'], 'yes')
|
51
|
+
setup_amazon(dir)
|
52
|
+
results = Typingpool::Amazon::HIT.all_for_project(project.local.id)
|
53
|
+
refute_empty(results)
|
54
|
+
assert_nothing_raised do
|
55
|
+
tp_finish(dir)
|
56
|
+
end
|
57
|
+
assert_empty(Typingpool::Amazon::HIT.all_for_project(project.local.id))
|
58
|
+
results.each do |result|
|
59
|
+
#The original HIT might be gone, or there and marked
|
60
|
+
#'disposed', depending whether Amazon has swept the server for
|
61
|
+
#dead HITs yet
|
62
|
+
begin
|
63
|
+
hit = RTurk::Hit.find(result.id)
|
64
|
+
assert_match(hit.status, /^dispos/i)
|
65
|
+
rescue RTurk::InvalidRequest => exception
|
66
|
+
assert_match(exception.message, /HITDoesNotExist/i)
|
67
|
+
end #begin
|
68
|
+
end #results.each...
|
69
|
+
refute(File.exists? sandbox_csv)
|
70
|
+
assert_all_assets_have_upload_status(project.local.file('data', 'assignment.csv').as(:csv), ['audio'], 'no')
|
71
|
+
end #in_temp_tp_dir
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_tp_finish_with_missing_files
|
75
|
+
skip_if_no_amazon_credentials('tp-finish missing files test')
|
76
|
+
skip_if_no_upload_credentials('tp-finish missing files test')
|
77
|
+
in_temp_tp_dir do |dir|
|
78
|
+
project = nil
|
79
|
+
tp_make(dir)
|
80
|
+
begin
|
81
|
+
project = temp_tp_dir_project(dir)
|
82
|
+
assignments = project.local.file('data', 'assignment.csv').as(:csv).read
|
83
|
+
urls = assignments.map{|assignment| assignment['audio_url'] }
|
84
|
+
assert_empty(urls.reject{|url| working_url? url })
|
85
|
+
bogus_url = urls.first.sub(/\.mp3/, '.foo.mp3')
|
86
|
+
refute_equal(urls.first, bogus_url)
|
87
|
+
refute(working_url? bogus_url)
|
88
|
+
bogus_assignment = assignments.first.dup
|
89
|
+
bogus_assignment['audio_url'] = bogus_url
|
90
|
+
assignments.insert(1, bogus_assignment)
|
91
|
+
project.local.file('data', 'assignment.csv').as(:csv).write(assignments)
|
92
|
+
assert_equal(1, project.local.file('data', 'assignment.csv').as(:csv).reject{|assignment| working_url? assignment['audio_url'] }.count)
|
93
|
+
ensure
|
94
|
+
tp_finish_outside_sandbox(dir)
|
95
|
+
end #begin
|
96
|
+
assert_empty(project.local.file('data', 'assignment.csv').as(:csv).select{|assignment| working_url? assignment['audio_url'] })
|
97
|
+
end #in_temp_tp_dir...
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_abort_on_config_mismatch
|
101
|
+
skip_if_no_s3_credentials('tp-finish abort on config mismatch test')
|
102
|
+
in_temp_tp_dir do |dir|
|
103
|
+
config = config_from_dir(dir)
|
104
|
+
good_config_path = setup_s3_config(dir, config, '.config_s3_good')
|
105
|
+
tp_make(dir, good_config_path)
|
106
|
+
begin
|
107
|
+
assert(config.amazon.bucket)
|
108
|
+
new_bucket = 'configmismatch-test'
|
109
|
+
refute_equal(new_bucket, config.amazon.bucket)
|
110
|
+
config.amazon.bucket = new_bucket
|
111
|
+
bad_config_path = setup_s3_config(dir, config, '.config_s3_bad')
|
112
|
+
exception = assert_raises(Typingpool::Error::Shell) do
|
113
|
+
tp_finish_outside_sandbox(dir, bad_config_path)
|
114
|
+
end #assert_raises...
|
115
|
+
assert_match(exception.message, /\burls don't look right\b/i)
|
116
|
+
ensure
|
117
|
+
tp_finish_outside_sandbox(dir, good_config_path)
|
118
|
+
end #begin
|
119
|
+
end #in_temp_tp_dir do...
|
120
|
+
|
121
|
+
end
|
122
|
+
|
123
|
+
end #TestTpFinish
|