srt_subtitle_validator 0.1.7

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 76cc266523c735a5fb9a42a316b50100d589a02188590dff783924a4738abb1f
4
+ data.tar.gz: 351be1177c397d13ff9b6e5c26c4e61de2f25c227eb84824ebc1e25cd95b5d25
5
+ SHA512:
6
+ metadata.gz: 870c37daededdda8ebc614c8f2dcef8bf07b4253e3ff98f783eb452e366523e70e1994264b011994440b0376979b0dfbb801896ad46ecbdcfcc7c3f4de077d3d
7
+ data.tar.gz: b679b8d97f323a55cd95dc1e4374edd82ffe48e4bfa4ed350756a140e5a82b0be4b045edb863b8c5be90b553f4d3b605a8a1e48c2fcfe73455f54097c8e489f9
data/.gitignore ADDED
@@ -0,0 +1,10 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ .idea/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in srt_subtitle_validator.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Lukáš Pokorný
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,38 @@
1
+ # SRT subtitle validator & converter
2
+
3
+ Check SRT file and try to fix it.
4
+
5
+ * Convert to UTF-8
6
+ * Convert line-endings to UNIX/Linux
7
+ * Recreate number counter sequence
8
+
9
+ ## Why?
10
+ Because in my case Plex server & TV doesn't show subtitle correctly.
11
+
12
+ ## Installation
13
+ ```ruby
14
+ gem install 'srt_subtitle_validator'
15
+ ```
16
+
17
+ ## Usage
18
+
19
+ * Process files are overwritten with results.
20
+ * For all processed files are created backup.
21
+
22
+
23
+ ### For analyze
24
+ ```
25
+ srt_checker check <path to SRT file(s)>
26
+ ```
27
+
28
+ ### For direct convert
29
+ ```
30
+ srt_checker convert <path to SRT file(s)>
31
+ ```
32
+
33
+ ### General options
34
+ `--output, -o` : Specify output directory of file. By default its same as input
35
+
36
+ `--without_backup` : Skip creating backup files.
37
+
38
+ `--encoding, -e` : Encoding of input file. By default it's windows-1250
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
data/bin/srt_checker ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ lib = File.join(File.dirname(__FILE__), '..', 'lib')
4
+ $LOAD_PATH.unshift(lib) if !$LOAD_PATH.include?(lib)
5
+
6
+ require 'srt_subtitle_validator/cli'
@@ -0,0 +1,57 @@
1
+ require 'srt_subtitle_validator'
2
+ require 'thor'
3
+ require 'logger'
4
+
5
+ if %w(--version -v).include?(ARGV.first)
6
+ puts "Srt Subtitle Validator #{SrtSubtitleValidator::VERSION}"
7
+ exit(0)
8
+ end
9
+ module SrtSubtitleValidator
10
+ class Cli < Thor
11
+
12
+ class_option :version, type: :boolean, aliases: '-v', group: :main,
13
+ desc: 'Show version number and quit'
14
+
15
+ def self.srt_default_options
16
+ method_option :without_backup, :default => false, :type => :boolean, :desc => 'Skip backuping original SRT file'
17
+ method_option :output, :aliases => '-o', :default => nil, :type => :string, :desc => 'Output directory (file)'
18
+ method_option :encoding, :aliases => '-e', :default => Encoding::CP1250, :type => :string, :desc => 'Output directory (file)'
19
+ end
20
+
21
+ srt_default_options
22
+ desc 'check', 'Check SRT file. '
23
+
24
+ def check(*files)
25
+ files_to_convert = Array.new
26
+ Array(files).each do |file|
27
+ validator = SrtSubtitleValidator::Validator.new(file)
28
+ say("\n == #{validator.file_name} -> ")
29
+ if validator.valid?
30
+ say 'SRT file is valid', :green
31
+ else
32
+ say 'SRT file is invalid, with following errors: ', :red, true
33
+ validator.srt.errors.each { |e| say "* #{e}" }
34
+ files_to_convert << validator
35
+ end
36
+ end
37
+ if files_to_convert.any? && yes?("Try to convert #{files_to_convert.length} files ?")
38
+ files_to_convert.each{|f| f.convert_srt(options[:output], options[:without_backup])}
39
+ end
40
+
41
+ end
42
+
43
+ srt_default_options
44
+ desc 'convert', 'Check files and fix them if needed'
45
+
46
+ def convert(*files)
47
+ Array(files).each do |file|
48
+ validator = SrtSubtitleValidator::Validator.new(file)
49
+ unless validator.valid?
50
+ validator.convert_srt(options[:output], options[:without_backup])
51
+ end
52
+ end
53
+ end
54
+
55
+ end
56
+ end
57
+ SrtSubtitleValidator::Cli.start
@@ -0,0 +1,43 @@
1
+ module SrtSubtitleValidator
2
+ class SrtFile
3
+ attr_reader :blocks, :length
4
+ attr_accessor :errors
5
+ def initialize(source, logger = nil)
6
+ @logger = logger || Logger.new(STDOUT)
7
+ @errors = Array.new
8
+ x = source.dup.encode(Encoding::UTF_8).gsub(/\r/, '')
9
+ @srt_dialog_blocks = Hash.new
10
+ @blocks = x.split(/^\r?\n+/m).map { |n| i = SrtBlock.new(n); @srt_dialog_blocks[i.dialog_number] = i; i }
11
+ @length = !@blocks.empty? && @blocks.last.dialog_number || 0
12
+ @errors << 'File is zero size' if @length.zero?
13
+ end
14
+
15
+ def valid?
16
+ unless @blocks.count == @length
17
+ @errors << 'Numbers sequence is corrupted'
18
+ end
19
+ @errors.empty?
20
+ end
21
+
22
+ class SrtBlock
23
+ attr_accessor :dialog_number, :dialog_time, :dialog_text
24
+ def initialize(*args)
25
+ case args.count
26
+ when 1
27
+ blok = args[0].split("\n")
28
+ @dialog_number = blok.shift.to_i
29
+ @dialog_time = blok.shift
30
+ @dialog_text = blok.join("\n")
31
+ when 3
32
+ @dialog_number, @dialog_time, @dialog_text = args
33
+ else
34
+ raise ArgumentError
35
+ end
36
+ end
37
+
38
+ def to_s
39
+ [@dialog_number, @dialog_time, @dialog_text].join("\n") + "\n\n"
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,89 @@
1
+ require 'srt_subtitle_validator/srt_file'
2
+ class InvalidFile < ArgumentError; end
3
+ module SrtSubtitleValidator
4
+ class Validator
5
+
6
+ require 'logger'
7
+ require 'tempfile'
8
+
9
+ attr_reader :srt, :path, :file_name
10
+
11
+ def initialize(file_path, encoding = nil, logger = nil)
12
+ @logger = logger || Logger.new(STDOUT)
13
+ @path = File.absolute_path(file_path).strip
14
+ raise InvalidFile unless File.extname(@path) == '.srt'
15
+ @file_name = File.basename(@path)
16
+ parse_srt(File.read(@path, :encoding => (encoding || Encoding::UTF_8)))
17
+ end
18
+
19
+ def valid?
20
+ @srt.valid?
21
+ end
22
+
23
+ def convert_srt(output, skip_backup = false)
24
+ skip_backup ||= output_file(output) != @path
25
+ backup_original_file unless !!skip_backup
26
+ @new_srt = Tempfile.new([@file_name.gsub('.srt', ''), '.srt'])
27
+ recalculate_number_sequence
28
+
29
+ @logger.info ' > Save as UTF-8 encoded file...'
30
+ @new_srt.flush
31
+ FileUtils.copy(@new_srt.path, output_file(output))
32
+ @new_srt.close
33
+ @new_srt.unlink
34
+ end
35
+
36
+ def missing_numbers
37
+ @missing_numbers ||= (Array(1..@srt.length) - @srt.blocks.map(&:dialog_number))
38
+ end
39
+
40
+ private
41
+
42
+ def recalculate_number_sequence
43
+ @logger.info ' > Create new number sequence...'
44
+ @srt.blocks.each_with_index do |block, index|
45
+ number = index + 1
46
+ n = SrtSubtitleValidator::SrtFile::SrtBlock.new(number, block.dialog_time, block.dialog_text)
47
+ @new_srt.write(n.to_s)
48
+ end
49
+ end
50
+
51
+ def output_file(output = nil)
52
+ if output.to_s.empty?
53
+ @path
54
+ else
55
+ if File.directory?(output)
56
+ File.join(output, @file_name)
57
+ else
58
+ output
59
+ end
60
+ end
61
+ end
62
+
63
+
64
+ def backup_original_file
65
+ @logger.info ' > Create backup...'
66
+ backup_suffix = 1
67
+ possible_backup_file = @path + '.' + backup_suffix.to_s
68
+ while File.exist?(possible_backup_file)
69
+ possible_backup_file = @path + '.' + (backup_suffix += 1).to_s
70
+ raise StandardError if backup_suffix >= 66
71
+ end
72
+ FileUtils.cp(@path, possible_backup_file)
73
+ end
74
+
75
+ def parse_srt(raw, with_fallback = true)
76
+ begin
77
+ @srt = SrtSubtitleValidator::SrtFile.new(raw)
78
+ rescue ArgumentError => e
79
+ if e.to_s == 'invalid byte sequence in UTF-8' && with_fallback
80
+ parse_srt(raw.force_encoding(Encoding::CP1250), false)
81
+ @srt.errors << 'Invalid encoding'
82
+ end
83
+ end
84
+
85
+ end
86
+
87
+ end
88
+
89
+ end
@@ -0,0 +1,3 @@
1
+ module SrtSubtitleValidator
2
+ VERSION = '0.1.7'
3
+ end
@@ -0,0 +1,26 @@
1
+ require 'srt_subtitle_validator/version'
2
+ # require 'srt_subtitle_validator/srt_file'
3
+ require 'srt_subtitle_validator/validator'
4
+
5
+ module SrtSubtitleValidator
6
+ # Your code goes here...
7
+
8
+ end
9
+
10
+ class String
11
+ def blank?
12
+ to_s == ''
13
+ end
14
+ end
15
+
16
+ class NilClass
17
+ def blank?
18
+ true
19
+ end
20
+ end
21
+
22
+ class Array
23
+ def blank?
24
+ empty?
25
+ end
26
+ end
@@ -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_subtitle_validator/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'srt_subtitle_validator'
8
+ spec.version = SrtSubtitleValidator::VERSION
9
+ spec.authors = ['Lukáš Pokorný']
10
+ spec.email = ['luk4s.pokorny@gmail.com']
11
+
12
+ spec.summary = 'SRT subtitle file checker, validator'
13
+ spec.description = 'For check encoding and srt subtitle number sequence'
14
+ spec.homepage = 'https://github.com/luk4s/srt-subtitle-validator'
15
+ spec.license = 'MIT'
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.bindir = 'bin'
19
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
20
+ spec.require_paths = ['lib']
21
+
22
+ spec.add_development_dependency 'bundler', '~> 1.16'
23
+ spec.add_development_dependency 'rake', '~> 10.0'
24
+ spec.add_development_dependency 'pry', '~> 0.10'
25
+
26
+ spec.add_runtime_dependency 'thor', '~> 0.20'
27
+ end
metadata ADDED
@@ -0,0 +1,113 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: srt_subtitle_validator
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.7
5
+ platform: ruby
6
+ authors:
7
+ - Lukáš Pokorný
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-11-20 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.16'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.16'
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: pry
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.10'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.10'
55
+ - !ruby/object:Gem::Dependency
56
+ name: thor
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0.20'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.20'
69
+ description: For check encoding and srt subtitle number sequence
70
+ email:
71
+ - luk4s.pokorny@gmail.com
72
+ executables:
73
+ - srt_checker
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - ".gitignore"
78
+ - Gemfile
79
+ - LICENSE.txt
80
+ - README.md
81
+ - Rakefile
82
+ - bin/srt_checker
83
+ - lib/srt_subtitle_validator.rb
84
+ - lib/srt_subtitle_validator/cli.rb
85
+ - lib/srt_subtitle_validator/srt_file.rb
86
+ - lib/srt_subtitle_validator/validator.rb
87
+ - lib/srt_subtitle_validator/version.rb
88
+ - srt_subtitle_validator.gemspec
89
+ homepage: https://github.com/luk4s/srt-subtitle-validator
90
+ licenses:
91
+ - MIT
92
+ metadata: {}
93
+ post_install_message:
94
+ rdoc_options: []
95
+ require_paths:
96
+ - lib
97
+ required_ruby_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ required_rubygems_version: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ requirements: []
108
+ rubyforge_project:
109
+ rubygems_version: 2.7.7
110
+ signing_key:
111
+ specification_version: 4
112
+ summary: SRT subtitle file checker, validator
113
+ test_files: []