secret
anonymous / sriramvarahan.rb
Last active

  • Download Gist
sriramvarahan.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226
=begin
Ruby Challenge
Submitted By: Sriram Varahan
Script to shift the timings of subtitle by an amount specified by the user.
The main algorithm used here is as follows:
1. The time associated with the subtitle is converted to milliseconds.
2. The shift time is also converted to milliseconds.
3. Now the two times are either added or subtracted based on the requirement and converted back to the required format.
=end
 
require 'optparse'
 
class Shift
def parse(argv)
# This hash will hold all of the options
# parsed from the command-line by
# OptionParser.
@options = {}
 
optparse = OptionParser.new do|opts|
# Set a banner, displayed at the top
# of the help screen.
opts.banner = "Usage: ruby-challenge.rb [options] input_file output_file"
 
opts.on( "-o", "--operation TYPE", 'Perform the desired operation. Valid options being add or sub' ) do |operation|
if %w[add sub].include?operation
@options[:operation] = operation
else
puts "Enter a valid operation.To know more use -h"
exit
end
end
 
@options[:time] = nil
opts.on( '-t', '--time TIME', 'Specify Shift time. Format is seconds,milliseconds' ) do |time|
seconds,milliseconds = time.split(",")
# Check the format of the input time entered by the user.
# The accepted format is xx,xxx
if (/^\d+$/.match(seconds).nil? || /^\d+$/.match(milliseconds).nil?)
puts "Check the input time. For Example: 12,345"
exit
end
@options[:time] = time
end
 
# This displays the help screen, all programs are
# assumed to have this option.
opts.on( '-h', '--help', 'Show the help menu' ) do
puts opts
exit
end
end
 
# Parse the command-line. Remember there are two forms
# of the parse method. The 'parse' method simply parses
# ARGV, while the 'parse!' method parses ARGV and removes
# any options found there, as well as any parameters for
# the options. What's left is the list of files to resize.
begin
optparse.parse!
rescue OptionParser::MissingArgument => e
puts e.to_str.capitalize.gsub("argument:", "value for:")
puts "That option requires a value. Please try with -h or --help to know more."
puts "Exiting.."
exit
rescue OptionParser::InvalidOption => e
puts e.to_str.capitalize.gsub("argument:", "value for:")
puts "That is an invalid option. Please try with -h or --help to know more."
puts "Exiting.."
exit
end
# Store the input and output in the options hash
%w(input output).each_with_index do |key,index|
if ARGV[index].nil?
puts "Please specify an #{key} file. To know more use -h"
exit
end
@options.store(key.to_sym,ARGV[index])
end
# Check if the input file exists or not.
# Exit if the file does not exist.
unless File.exists?(@options[:input])
puts "#{@options[:input]} file does not exist. Please check for typing or spelling errors."
exit
end
puts "Performing #{@options[:option]} operation on the input frames." if @options[:option]
# Invoke the shift method
self.perform_shift
end
##
# Perform the shift based on the operation specified.
def perform_shift
case @options[:operation]
when "add"
puts "Performing add on each of the frames"
self.open_file_and_shift("add")
when "sub"
puts "Performing sub on each of the frames"
self.open_file_and_shift("sub")
else
puts "Valid options are add or sub"
end
end
 
 
##
# Perform the required operation on each time frame.
def open_file_and_shift(operator)
input_file = @options[:input]
output_file = File.open(@options[:output],"w+")
File.open(input_file, "r") do |i_f|
while line = i_f.gets
if line =~ /-->/
start_time,end_time = line.split("-->")
start_time_seconds,start_time_milliseconds = start_time.split(",")
end_time_seconds,end_time_milliseconds = end_time.split(",")
# The time by which the shifting needs to be done
input_seconds,input_milliseconds = @options[:time].split(",")
# Convert to milliseconds.
input_milliseconds = input_milliseconds.to_i + (input_seconds.to_i * 1000)
output_file.puts "#{carry_out_operation(start_time_seconds,start_time_milliseconds,input_milliseconds,operator)} --> #{carry_out_operation(end_time_seconds,end_time_milliseconds,input_milliseconds,operator)} "
else
output_file.puts(line)
end
end
end
end
##
# Performs the actual operation.
def carry_out_operation(time,milliseconds,sub_milliseconds,operator)
time = time.split(":")
input_time = {}
input_time.store(:hr, time[0])
input_time.store(:min, time[1])
input_time.store(:sec , time[2])
# Convert the time to milliseconds.
# Perform subtraction and convert to the required output
time_in_seconds = (input_time[:hr].to_i*3600) + (input_time[:min].to_i* 60) + (input_time[:sec].to_i)
time_in_milliseconds = milliseconds.to_i + time_in_seconds.to_i * 1000
# Call the add or subtract method dynamically.
if self.respond_to?(operator)
operator = self.method(operator)
result = operator.call(time_in_milliseconds.to_i, sub_milliseconds.to_i)
end
if result > 0
# Call the method which will convert the reuired output in milliseconds to the time format required.
hours,minutes,seconds,milliseconds = convert_milliseconds_to_required_time_format(result)
else
# Return 0 is the result is a negative value.
hours,seconds,minutes,milliseconds = 00,00,00,000
end
hours,minutes,seconds,milliseconds = foramt_output_time(hours,minutes,seconds,milliseconds)
return "#{hours}:#{minutes}:#{seconds},#{milliseconds}"
end
##
# Perform addition
def add(a,b)
return a + b
end
##
# Perform subtraction.
def sub(a,b)
return a - b
end
##
# Append zeros in case of single digits.
def foramt_output_time(hours,minutes,seconds,milliseconds)
seconds = "0#{seconds}" if seconds < 10
minutes = "0#{minutes}" if minutes < 10
hours = "0#{hours}" if hours < 10
# Format the output as required.
# For example: if 9 print as 009.
if milliseconds < 10
milliseconds = "00#{milliseconds}"
elsif milliseconds < 100
milliseconds = "0#{milliseconds}"
end
return [hours,minutes,seconds,milliseconds]
end
##
# Converts time in milliseconds to hours, mins, seconds and milliseconds format.
def convert_milliseconds_to_required_time_format(input)
milliseconds = input % 1000
difference = (input - milliseconds) / 1000
seconds = difference % 60
difference = (difference - seconds) / 60
minutes = difference % 60
difference = (difference - minutes) / 60
hours = difference
return [hours,minutes,seconds,milliseconds]
end
end
 
 
# Create an object and invoke the parse method.
shift = Shift.new
shift.parse(ARGV)

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.