vodstamp 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/bin/vodstamp +28 -0
  2. data/lib/vodstamp.rb +207 -0
  3. metadata +48 -0
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+ require 'vodstamp'
5
+
6
+ if ARGV.length > 0
7
+ vodstamp = Vodstamp.new;
8
+ actual_command = ARGV.shift
9
+ command = actual_command.gsub ':', '_'
10
+ if vodstamp.respond_to? command
11
+ vodstamp.send command, ARGV
12
+ else # ! vodstamp.respond_to? command
13
+ puts " err: unknown command #{actual_command}"
14
+ end#if
15
+ else # ARGV.length == 0
16
+
17
+ puts
18
+ puts <<eos
19
+ Commands
20
+ ------------------------------------------------------------------------------
21
+ vodstamp version - current version
22
+ vodstamp all <input> <output> - filter timestamp messages based only on marker
23
+ vodstamp filter <input> <output> <source> - filter timestamp messages from a chat log
24
+ vodstamp build <input> <output> <splits> <offset> - build timestamps
25
+
26
+ eos
27
+
28
+ end#if
@@ -0,0 +1,207 @@
1
+ class Vodstamp
2
+
3
+ VERSION = '0.1.0'
4
+
5
+ #### Commands ##################################################################
6
+
7
+ def version(args)
8
+ puts " #{Vodstamp::VERSION}"
9
+ end#def
10
+
11
+ def all(args)
12
+ msg "filtering all from [#{args[0]}] to [#{args[1]}]"
13
+
14
+ inputfile = File.expand_path(args[0]);
15
+ outputfile = File.expand_path(args[1]);
16
+
17
+ if ! File.exist? inputfile
18
+ err "The file [#{inputfile}] does not exist."
19
+ end
20
+
21
+ rawlog = File.read inputfile
22
+ rawlog = rawlog.split "\n"
23
+
24
+ log = filter_chatlog true, rawlog, arg[2]
25
+
26
+ File.write(outputfile, log.join("\n"))
27
+ msg "fin"
28
+ end#def
29
+
30
+ def filter(args)
31
+ msg "filtering [#{args[0]}] to [#{args[1]}] using source [#{args[2]}]"
32
+
33
+ inputfile = File.expand_path(args[0]);
34
+ outputfile = File.expand_path(args[1]);
35
+
36
+ if ! File.exist? inputfile
37
+ err "The file [#{inputfile}] does not exist."
38
+ end
39
+
40
+ rawlog = File.read inputfile
41
+ rawlog = rawlog.split "\n"
42
+
43
+ filter_chatlog false, rawlog, args[2]
44
+
45
+ File.write(outputfile, log.join("\n"))
46
+ msg "fin"
47
+ end#def
48
+
49
+ def build(args)
50
+ msg "building from [#{args[0]}] to [#{args[1]}] with splits [#{args[2]}] and offset of #{args[3]} seconds"
51
+
52
+ inputfile = File.expand_path(args[0]);
53
+ outputfile = File.expand_path(args[1]);
54
+ splitsfile = File.expand_path(args[2]);
55
+
56
+ if ! File.exist? inputfile
57
+ err "The file [#{inputfile}] does not exist."
58
+ end
59
+
60
+ if ! File.exist? splitsfile
61
+ err "The file [#{splitsfile}] does not exist."
62
+ end
63
+
64
+ rawlog = File.read inputfile
65
+ rawlog = rawlog.split "\n"
66
+
67
+ rawsplits = File.read splitsfile
68
+ rawsplits = rawsplits.split "\n"
69
+
70
+ timestamps = build_timestamps rawlog, rawsplits, args[3].to_i
71
+
72
+ File.write(outputfile, timestamps.join("\n"))
73
+ msg "fin"
74
+ end#def
75
+
76
+ #### Working Methods ###########################################################
77
+
78
+ def build_timestamps(rawlog, rawsplits, offset)
79
+ # parse timestamps
80
+ logpattern = /[a-zA-Z]+ [0-9]+ ([0-9]{2}):([0-9]{2}):([0-9]{2}) <([a-zA-Z0-9_-]+)> \[timestamp\] (T-([0-9]{2}):([0-9]{2}) (.*)|ignore last|todo|realign)/
81
+ log = [];
82
+ diff = nil
83
+ rawlog.each do |line|
84
+ match = logpattern.match(line)
85
+ next if match[6] == nil
86
+ # get data
87
+ h = match[1].to_i
88
+ m = match[2].to_i
89
+ s = match[3].to_i
90
+ om = match[6].to_i
91
+ os = match[7].to_i
92
+ message = match[8]
93
+ # convert to seconds
94
+ time_s = s + m * 60 + h * 60 * 60
95
+ offset_s = os + om * 60
96
+
97
+ if diff === nil
98
+ diff = time_s - offset_s
99
+ end
100
+
101
+ time_s = time_s - offset_s - diff
102
+ log.push({ time: time_s, msg: message })
103
+ end#each
104
+
105
+ # parse splits
106
+ splitpattern = /([a-zA-Z0-9 ]+)\. ([0-9]{2}):([0-9]{2}):([0-9]{2})/
107
+ splits = []
108
+ rawsplits.each do |line|
109
+ match = splitpattern.match(line)
110
+ h = match[2].to_i
111
+ m = match[3].to_i
112
+ s = match[4].to_i
113
+ # convert to seconds
114
+ time_s = s + m * 60 + h * 60 * 60
115
+ splits.push({ time: time_s, name: match[1] })
116
+ end#each
117
+
118
+ # generate timestamps
119
+ times = []
120
+ splitidx = 0
121
+ this_split = splits[splitidx]
122
+ split_max_time = this_split[:time]
123
+ split_diff = -offset
124
+ times.push([]);
125
+ log.each do |entry|
126
+ if offset + entry[:time] > split_max_time
127
+ split_diff += this_split[:time]
128
+ splitidx += 1
129
+ this_split = splits[splitidx]
130
+ split_max_time += this_split[:time]
131
+ times.push([])
132
+ end
133
+ times[splitidx].push({ time: entry[:time] - split_diff, msg: entry[:msg] })
134
+ end#each
135
+
136
+ timestamps = []
137
+ idx = 0
138
+
139
+ print " " # progress prefix
140
+ times.each do |stamps|
141
+ timestamps.push " -- #{splits[idx][:name]} -- "
142
+ stamps.each do |time|
143
+ minutes = (time[:time] / 60).to_i
144
+ seconds = time[:time] - minutes * 60
145
+ timestamps.push readable_time(time[:time]) + " #{time[:msg]}"
146
+ print '.' # progress indicator
147
+ end#each
148
+ idx += 1
149
+ end#each
150
+ puts
151
+
152
+ return timestamps;
153
+ end#def
154
+
155
+ def filter_chatlog(all_messages, rawlog, source = nil)
156
+ log = []
157
+
158
+ if all_messages
159
+ logpattern = /.* \[timestamp\] .*/
160
+ else # only correct ones
161
+ logpattern = /[a-zA-Z]+ [0-9]+ ([0-9]{2}):([0-9]{2}):([0-9]{2}) <([a-zA-Z0-9_-]+)> \[timestamp\] (T-([0-9]{2}):([0-9]{2}) .*|ignore last|todo|realign)/
162
+ end
163
+
164
+ ignorepattern = /\[timestamp\] ignore last/
165
+
166
+ print " " # progress prefix
167
+ rawlog.each do |line|
168
+ if (match = logpattern.match(line)) != nil
169
+ if all_messages || match[4] == source
170
+ if ! all_messages && ignorepattern.match(line) != nil
171
+ log.pop
172
+ print ',' # indicate backtracking
173
+ else # normal line
174
+ log.push line
175
+ print '.' # indicate progress
176
+ end
177
+ end
178
+ end
179
+ end#each
180
+ puts # new line at end of progress
181
+
182
+ return log
183
+ end#def
184
+
185
+ #### Helpers ###################################################################
186
+
187
+ def readable_time(time)
188
+ hours = (time / 3600).to_i
189
+ minutes = ((time - hours) / 60).to_i
190
+ seconds = time - hours * 3600 - minutes * 60
191
+ if hours != 0
192
+ return ('%02d' % hours) + ':' + ('%02d' % minutes) + ':' + ('%02d' % seconds)
193
+ else
194
+ return ('%02d' % minutes) + ':' + ('%02d' % seconds)
195
+ end
196
+ end#def
197
+
198
+ def err(msg)
199
+ puts " Err: #{msg}"
200
+ exit
201
+ end#def
202
+
203
+ def msg(msg)
204
+ puts " #{msg}"
205
+ end#def
206
+
207
+ end#class
metadata ADDED
@@ -0,0 +1,48 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: vodstamp
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - srcspider
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-03-18 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: Video timestamping tool
15
+ email: source.spider@gmail.com
16
+ executables:
17
+ - vodstamp
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - lib/vodstamp.rb
22
+ - bin/vodstamp
23
+ homepage: http://rubygems.org/gems/vodstamp
24
+ licenses:
25
+ - MIT
26
+ post_install_message:
27
+ rdoc_options: []
28
+ require_paths:
29
+ - lib
30
+ required_ruby_version: !ruby/object:Gem::Requirement
31
+ none: false
32
+ requirements:
33
+ - - ! '>='
34
+ - !ruby/object:Gem::Version
35
+ version: '0'
36
+ required_rubygems_version: !ruby/object:Gem::Requirement
37
+ none: false
38
+ requirements:
39
+ - - ! '>='
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ requirements: []
43
+ rubyforge_project:
44
+ rubygems_version: 1.8.28
45
+ signing_key:
46
+ specification_version: 3
47
+ summary: video timestamping tool
48
+ test_files: []