srt-shell 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 451374bce528e8072d296659b7b80776094761da
4
+ data.tar.gz: 05bc3f85cce7d283c7a04204f6ffb3e4db81054f
5
+ SHA512:
6
+ metadata.gz: 0508c7547e778cee210482dfd5e9d88afb0cebd7edff39fa77649e7710db1fde4ec32fef18bb5697987f5d14a90a03b18206e266d7f09b4f3f51f9e249d3a1d1
7
+ data.tar.gz: 4122c0f3beaa7f290f98692ac87c5acdd6656011c5ced75dacb94da6cd5f4168b78cf5dc364be8c388f20ab312ea44b0518a7270ac1d7a763a7baee7042eb970
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in srt-shell.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 skliew
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,69 @@
1
+ # SRT::Shell
2
+
3
+ An interactive shell to retime SRT files.
4
+
5
+ ## Installation
6
+
7
+ For now you can only install this by cloning the repo, and then run the following commands:
8
+
9
+ ```shell
10
+ bundle install
11
+ rake install
12
+ ```
13
+ ## Usage
14
+
15
+ Start the shell with the command:
16
+
17
+ ```shell
18
+ srt-shell
19
+ ```
20
+
21
+ You could also optionally pass in an SRT file's path as an argument:
22
+ ```shell
23
+ srt-shell file.srt
24
+ ```
25
+
26
+ ## Commands
27
+
28
+ In the shell, the commands available will be shown with the 'help' command:
29
+ ```shell
30
+ help
31
+ ```
32
+
33
+ #### load '[filename]'
34
+ Load an SRT file.
35
+
36
+ ### exit
37
+ Exit the shell
38
+
39
+ ###### The following commands can only be used when we already have an SRT file loaded.
40
+ ###### Do note that all indexes start from 1, not 0.
41
+
42
+ #### interval [time in ms]
43
+ This would scan the SRT file for time gaps larger than the given time in ms. This is useful to search for indexes to be used with the time-shifting commands.
44
+
45
+ #### upshift|u [index] [time in ms]
46
+ Rewind the given time in ms for lines from index onwards.
47
+
48
+ #### forward|f [index] [time in ms]
49
+ Forward the given time in ms for lines from index onwards.
50
+
51
+ #### remove [index]
52
+ Remove line with the given index
53
+
54
+ #### save
55
+ Save (overwrite) the SRT file. You can place an executable file in $HOME/.srt_shell_hook to be executed when 'save' is used.
56
+
57
+ #### search [word]
58
+ Search for the given word in the SRT file and print out the entries that contain the word.
59
+
60
+ ## Platform
61
+ I've only tested this on Linux because it's the only machine I have.
62
+
63
+ ## Contributing
64
+
65
+ 1. Fork it ( https://github.com/skliew/srt-shell/fork )
66
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
67
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
68
+ 4. Push to the branch (`git push origin my-new-feature`)
69
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ desc 'Run tests'
4
+ task :test do |t|
5
+ sh 'rspec -Ilib -I. test/spec_*.rb'
6
+ end
7
+
data/bin/srt-shell ADDED
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'srt/shell'
4
+ require 'readline'
5
+
6
+ WORDS = %w( load interval upshift u forward f remove save show s search help h exit )
7
+ DEFAULT_WORD_BREAK_CHARS = " \t\n\"\\'`@$><=;|&{("
8
+ FILENAME_WORD_BREAK_CHARS = "\t\n\"\\'`@$><=;|&{"
9
+
10
+ Readline.completion_proc = lambda do |word|
11
+ Readline.completer_word_break_characters = DEFAULT_WORD_BREAK_CHARS
12
+ buffer = Readline.line_buffer.chomp
13
+
14
+ if buffer.match(/^\s*load\s+/)
15
+ Readline.completer_word_break_characters = FILENAME_WORD_BREAK_CHARS
16
+ return Readline::FILENAME_COMPLETION_PROC.call(word)
17
+ end
18
+
19
+ return [] if WORDS.find { |w| buffer.match(/^\s*#{w}\s+/) }
20
+ WORDS.grep(/^#{Regexp.escape(word)}/)
21
+ end
22
+
23
+ Signal.trap('INT') do
24
+ puts "Caught SIGINT, exiting..."
25
+ exit 0
26
+ end
27
+ shell = SRT::Shell.new(ARGV[0])
28
+
29
+ loop do
30
+ line = Readline.readline('> ', true)
31
+ shell.eval_command(line.chomp)
32
+ end
33
+
@@ -0,0 +1,7 @@
1
+ module SRT
2
+ class Line
3
+ def to_s(time_str_function=:time_str)
4
+ [sequence, (display_coordinates ? send(time_str_function) + display_coordinates : send(time_str_function)), text, ''].flatten.join("\n")
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,5 @@
1
+ module SRT
2
+ class Shell
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
data/lib/srt/shell.rb ADDED
@@ -0,0 +1,181 @@
1
+ # encoding: utf-8
2
+ require 'srt/shell/version'
3
+ require 'srt'
4
+ require 'srt/patches'
5
+
6
+ module SRT
7
+ class Shell
8
+ SAVE_HOOK_FILE = ::File.expand_path('~/.srt_shell_hook')
9
+ BOM_STRING = "\xEF\xBB\xBF"
10
+ BOM_REGEX = /#{BOM_STRING}/
11
+ USAGE_MSG = <<USAGE
12
+ Usage: #{$0} [SRT_FILENAME]
13
+ Commands:
14
+ EX: load 'SRT_FILENAME'
15
+ EX: interval 90
16
+ EX: upshift|u 50 5000
17
+ EX: forward|f 50 5000
18
+ EX: remove 50
19
+ EX: save
20
+ EX: show|s 50
21
+ EX: search TERM
22
+ EX: help|h
23
+ EX: exit
24
+ USAGE
25
+
26
+ def initialize(path = nil, save_hook=SAVE_HOOK_FILE)
27
+ @file, @path = nil, nil
28
+ @bom = false
29
+ load_path(path) if path
30
+ @save_hook = ::File.exists?(save_hook) ? save_hook : nil
31
+ end
32
+
33
+ def load_path(path)
34
+ path = ::File.expand_path(path)
35
+ @path = path
36
+
37
+ # Test if file contains BOM
38
+ ::File.open(path) do |file|
39
+ lines = file.read.split("\n")
40
+ unless lines.empty?
41
+ if lines[0].match(BOM_REGEX)
42
+ lines[0].sub!(BOM_REGEX, '')
43
+ @bom = true
44
+ end
45
+ @file = SRT::File.parse(lines.join("\n"))
46
+ else
47
+ raise ArgumentError, 'Invalid SRT file'
48
+ end
49
+ end
50
+ self
51
+ end
52
+
53
+ def show(index)
54
+ check_index(index)
55
+ puts @file.lines[index - 1].to_s + "\n"
56
+ rescue IndexError => error
57
+ puts error.message
58
+ end
59
+
60
+ def timeshift(index, timecode)
61
+ check_index(index)
62
+ if time = Parser.timespan(timecode)
63
+ @file.lines[index-1..-1].each do |line|
64
+ line.start_time += time
65
+ line.end_time += time
66
+ end
67
+ else
68
+ puts "Invalid timeshift input (#{index}, #{timecode})"
69
+ end
70
+ rescue IndexError => error
71
+ puts error.message
72
+ end
73
+
74
+ def rewind(index, time)
75
+ timeshift(index, "-#{time}ms")
76
+ end
77
+
78
+ def forward(index, time)
79
+ timeshift(index, "+#{time}ms")
80
+ end
81
+
82
+ def scan_interval(input_time)
83
+ unless time = Parser.timespan("#{input_time}ms")
84
+ puts "Invalid time used #{input_time}"
85
+ return
86
+ end
87
+ end_time = 0
88
+ result = []
89
+ @file.lines.each do |line|
90
+ interval = line.start_time - end_time
91
+ if interval >= time
92
+ result << "index: #{line.sequence} time: #{line.time_str} gap: #{interval}"
93
+ end
94
+ end_time = line.end_time
95
+ end
96
+ puts result.join("\n")
97
+ end
98
+
99
+ def remove(index)
100
+ check_index(index)
101
+ index -= 1
102
+ @file.lines.delete_at(index)
103
+ @file.lines[index..-1].each do |line|
104
+ line.sequence -= 1
105
+ end
106
+ rescue IndexError => error
107
+ puts error.message
108
+ end
109
+
110
+ def search(term)
111
+ result = []
112
+ @file.lines.each do |line|
113
+ if line.text.find { |text| text[term] }
114
+ result << line.to_s
115
+ end
116
+ end
117
+ puts result.join("\n") + "\n"
118
+ end
119
+
120
+ def show_all
121
+ puts @file
122
+ end
123
+
124
+ def save(path=@path)
125
+ ::File.open(path, 'w') do |file|
126
+ file.print BOM_STRING if @bom
127
+ file.print @file.to_s.split("\n").join("\r\n"), "\r\n\r\n"
128
+ end
129
+ if @save_hook
130
+ output = `sh #{@save_hook}`
131
+ puts output unless output.empty?
132
+ end
133
+ end
134
+
135
+ def eval_command(cmd)
136
+ case cmd
137
+ when /^\s*(?:help|h)\s*$/
138
+ puts USAGE_MSG
139
+ return
140
+ when /^\s*exit\s*$/
141
+ exit 0
142
+ when /^\s*load\s+\'?([^']+)\'?\s*$/
143
+ load_path($1)
144
+ return
145
+ end
146
+
147
+ if @file
148
+ case cmd
149
+ when /^\s*(?:show|s)\s+(\d+)\s*$/
150
+ show($1.to_i)
151
+ when /^\s*(?:showall)\s*$/
152
+ show_all
153
+ when /^\s*interval\s+(\d+)\s*$/
154
+ scan_interval($1.to_i)
155
+ when /^\s*(?:u|rewind)\s+(\d+)\s+(\d+)\s*$/
156
+ rewind($1.to_i, $2.to_i)
157
+ when /^\s*(?:f|forward)\s+(\d+)\s+(\d+)\s*$/
158
+ forward($1.to_i, $2.to_i)
159
+ when /^\s*(?:remove)\s+(\d+)\s*$/
160
+ remove($1.to_i)
161
+ when /^\s*save\s*$/
162
+ save
163
+ when /^\s*search\s*(.*)$/
164
+ search($1)
165
+ else
166
+ puts "Invalid command"
167
+ end
168
+ else
169
+ puts "File is not loaded. Load a file using the 'load' command"
170
+ end
171
+ end
172
+
173
+ private
174
+
175
+ def check_index(index)
176
+ if index < 1
177
+ raise IndexError, "Invalid index given, index must be more than 0"
178
+ end
179
+ end
180
+ end
181
+ end
data/srt-shell.gemspec ADDED
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'srt/shell/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "srt-shell"
8
+ spec.version = SRT::Shell::VERSION
9
+ spec.authors = ["skliew"]
10
+ spec.email = ["skliew@gmail.com"]
11
+ spec.summary = %q{An interactive shell to retime SRT files.}
12
+ spec.description = %q{}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.6"
22
+ spec.add_development_dependency "rake", "~> 10.0"
23
+ spec.add_development_dependency "rspec", "~> 3.0"
24
+ spec.add_development_dependency "simplecov", "~> 0.9"
25
+
26
+ spec.add_runtime_dependency "srt", "~> 0.1"
27
+ end
@@ -0,0 +1,21 @@
1
+ 1
2
+ 00:03:55,339 --> 00:03:57,236
3
+ I had the craziest dream last night.
4
+
5
+ 2
6
+ 00:03:59,679 --> 00:04:01,586
7
+ I was dancing the White Swan.
8
+
9
+ 3
10
+ 00:04:03,346 --> 00:04:06,552
11
+ It was different choreography, though.
12
+ It was more like the Bolshoi's.
13
+
14
+ 4
15
+ 00:04:10,566 --> 00:04:12,193
16
+ It was the prologue,
17
+
18
+ 5
19
+ 00:04:12,228 --> 00:04:15,015
20
+ when Rothbart casts his spell.
21
+
@@ -0,0 +1 @@
1
+ echo "Saved"
data/test/helper.rb ADDED
@@ -0,0 +1,4 @@
1
+ require 'simplecov'
2
+ SimpleCov.start
3
+
4
+ require 'srt/shell'
@@ -0,0 +1,91 @@
1
+ require File.join(File.dirname(__FILE__), 'helper')
2
+
3
+ describe SRT::Shell do
4
+ before do
5
+ @app = SRT::Shell.new(
6
+ File.dirname(__FILE__) + '/fixtures/sample.srt',
7
+ File.dirname(__FILE__) + '/fixtures/save_hook'
8
+ )
9
+ end
10
+
11
+ it "should return a SRT::Shell" do
12
+ expect(@app.class).to eq(SRT::Shell)
13
+ end
14
+
15
+ it "should load a file" do
16
+ expect{ @app.load_path(File.dirname(__FILE__) + '/fixtures/sample.srt') }.to_not raise_error(Exception)
17
+
18
+ end
19
+
20
+ it 'should print out its USAGE' do
21
+ expect(STDOUT).to receive(:puts).with(SRT::Shell::USAGE_MSG)
22
+ @app.eval_command('help')
23
+ end
24
+
25
+ describe "With a loaded SRT file" do
26
+ it "should show a line" do
27
+ expect(STDOUT).to receive(:puts).with(
28
+ "1\n00:03:55,339 --> 00:03:57,236\nI had the craziest dream last night.\n\n"
29
+ )
30
+ @app.eval_command('show 1')
31
+ end
32
+
33
+ it "should forward SRT file's time" do
34
+ @app.eval_command('forward 1 1')
35
+ expect(STDOUT).to receive(:puts).with(
36
+ "1\n00:03:55,340 --> 00:03:57,237\nI had the craziest dream last night.\n\n"
37
+ )
38
+ @app.eval_command('show 1')
39
+ end
40
+
41
+ it "should rewind SRT file's time" do
42
+ @app.eval_command('rewind 1 1')
43
+ expect(STDOUT).to receive(:puts).with(
44
+ "1\n00:03:55,338 --> 00:03:57,235\nI had the craziest dream last night.\n\n"
45
+ )
46
+ @app.eval_command('show 1')
47
+ end
48
+
49
+ it "should show a message when an invalid index is used for rewind/forward" do
50
+ expect(STDOUT).to receive(:puts).with(/Invalid/)
51
+ @app.eval_command('rewind 0 1')
52
+ end
53
+
54
+ it "should scan for lines' interval" do
55
+ expect(STDOUT).to receive(:puts).with(
56
+ "index: 1 time: 00:03:55,339 --> 00:03:57,236 gap: 235.339\nindex: 4 time: 00:04:10,566 --> 00:04:12,193 gap: 4.01400000000001"
57
+ )
58
+ @app.eval_command('interval 3000')
59
+ end
60
+
61
+ it "should remove a line from SRT::File" do
62
+ @app.eval_command('remove 1')
63
+ expect(STDOUT).to receive(:puts).with(
64
+ <<OUT
65
+ 1
66
+ 00:03:59,679 --> 00:04:01,586
67
+ I was dancing the White Swan.
68
+
69
+ OUT
70
+ )
71
+ @app.eval_command('show 1')
72
+ end
73
+
74
+ it "should return the lines containing the searched term" do
75
+ expect(STDOUT).to receive(:puts).with(
76
+ <<OUT
77
+ 2
78
+ 00:03:59,679 --> 00:04:01,586
79
+ I was dancing the White Swan.
80
+
81
+ OUT
82
+ )
83
+ @app.eval_command('search dancing')
84
+ end
85
+
86
+ it "should save and trigger its hook" do
87
+ expect(STDOUT).to receive(:puts).with("Saved\n")
88
+ @app.save
89
+ end
90
+ end
91
+ end
metadata ADDED
@@ -0,0 +1,133 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: srt-shell
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - skliew
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-09-30 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: simplecov
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0.9'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.9'
69
+ - !ruby/object:Gem::Dependency
70
+ name: srt
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '0.1'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '0.1'
83
+ description: ''
84
+ email:
85
+ - skliew@gmail.com
86
+ executables:
87
+ - srt-shell
88
+ extensions: []
89
+ extra_rdoc_files: []
90
+ files:
91
+ - ".gitignore"
92
+ - Gemfile
93
+ - LICENSE.txt
94
+ - README.md
95
+ - Rakefile
96
+ - bin/srt-shell
97
+ - lib/srt/patches.rb
98
+ - lib/srt/shell.rb
99
+ - lib/srt/shell/version.rb
100
+ - srt-shell.gemspec
101
+ - test/fixtures/sample.srt
102
+ - test/fixtures/save_hook
103
+ - test/helper.rb
104
+ - test/spec_shell.rb
105
+ homepage: ''
106
+ licenses:
107
+ - MIT
108
+ metadata: {}
109
+ post_install_message:
110
+ rdoc_options: []
111
+ require_paths:
112
+ - lib
113
+ required_ruby_version: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ required_rubygems_version: !ruby/object:Gem::Requirement
119
+ requirements:
120
+ - - ">="
121
+ - !ruby/object:Gem::Version
122
+ version: '0'
123
+ requirements: []
124
+ rubyforge_project:
125
+ rubygems_version: 2.4.5.1
126
+ signing_key:
127
+ specification_version: 4
128
+ summary: An interactive shell to retime SRT files.
129
+ test_files:
130
+ - test/fixtures/sample.srt
131
+ - test/fixtures/save_hook
132
+ - test/helper.rb
133
+ - test/spec_shell.rb