hlspider 0.1.0 → 0.1.2
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.
- data/README.md +5 -2
- data/lib/hlspider/playlist.rb +6 -24
- data/lib/hlspider/spider.rb +58 -26
- data/lib/hlspider/version.rb +1 -1
- data/lib/hlspider.rb +1 -1
- metadata +50 -56
data/README.md
CHANGED
@@ -3,7 +3,10 @@ HLSpider
|
|
3
3
|
ASYNC .m3u8 downloader. Downloads .m3u8 playlist files and confirms their segments are properly aligned.
|
4
4
|
|
5
5
|
Usage
|
6
|
-
-----
|
6
|
+
-----
|
7
|
+
hlspider crawl --playlists=http://site.tld/playlist1.m3u8 http://site.tld/playlist2.m3u8 http://site.tld/playlist3.m3u8
|
8
|
+
|
9
|
+
|
7
10
|
hlspider
|
8
11
|
|
9
12
|
Tasks:
|
@@ -17,7 +20,7 @@ Usage
|
|
17
20
|
Options:
|
18
21
|
--playlists=one two three
|
19
22
|
[--sleep=N] # Default: 5
|
20
|
-
[--log=LOG] #
|
23
|
+
[--log=LOG] # Disabled by default - Log provides some extra debug information
|
21
24
|
|
22
25
|
|
23
26
|
|
data/lib/hlspider/playlist.rb
CHANGED
@@ -1,27 +1,12 @@
|
|
1
1
|
module HLSpider
|
2
2
|
class Playlist
|
3
|
-
attr_accessor :file
|
3
|
+
attr_accessor :file, :source
|
4
4
|
attr_reader :playlists, :segments
|
5
5
|
|
6
|
-
def
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
playlists << {:title => f[:title], :playlist => playlist} if playlist.valid?
|
11
|
-
end
|
12
|
-
|
13
|
-
segments = []
|
14
|
-
playlists.each do |p|
|
15
|
-
segment = /(\d*.ts)/.match(p[:playlist].segments.first)[0].gsub(".ts", "")
|
16
|
-
segments << segment
|
17
|
-
end
|
18
|
-
|
19
|
-
return segments
|
20
|
-
end
|
21
|
-
|
22
|
-
def initialize(file)
|
23
|
-
@file = file
|
24
|
-
|
6
|
+
def initialize(file, source = '')
|
7
|
+
@file = file
|
8
|
+
@source = source
|
9
|
+
|
25
10
|
@valid = false
|
26
11
|
@variable_playlist = false
|
27
12
|
@segment_playlist = false
|
@@ -49,11 +34,8 @@ module HLSpider
|
|
49
34
|
end
|
50
35
|
|
51
36
|
private
|
52
|
-
include Line
|
53
|
-
|
54
37
|
def parse
|
55
38
|
@valid = true if /#EXTM3U/.match(@file)
|
56
|
-
|
57
39
|
if has_playlist?(@file) && !has_segment?(@file)
|
58
40
|
@variable_playlist = true
|
59
41
|
@file.each_line do |line|
|
@@ -70,7 +52,7 @@ module HLSpider
|
|
70
52
|
end
|
71
53
|
|
72
54
|
def has_segment?(str)
|
73
|
-
true if /.
|
55
|
+
true if /#EXT-X-MEDIA-SEQUENCE/.match(str)
|
74
56
|
end
|
75
57
|
|
76
58
|
def has_playlist?(str)
|
data/lib/hlspider/spider.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
+
require 'rubygems'
|
1
2
|
require 'em-synchrony'
|
2
3
|
require 'em-synchrony/em-http'
|
3
4
|
require 'logger'
|
5
|
+
require_relative 'playlist'
|
4
6
|
|
5
7
|
module HLSpider
|
6
8
|
class Spider
|
@@ -10,43 +12,73 @@ module HLSpider
|
|
10
12
|
end
|
11
13
|
|
12
14
|
def crawl
|
15
|
+
playlists = dive(@playlists)
|
16
|
+
|
17
|
+
segments = []
|
18
|
+
playlists.each { |p| segments << p.segments.first }
|
19
|
+
|
20
|
+
puts Time.now
|
21
|
+
put_and_log "--- #{segments.inspect} ---"
|
22
|
+
segments.uniq!
|
23
|
+
|
24
|
+
if segments.size > 1 && ((segments[0].to_i - segments[1].to_i).abs > 1)
|
25
|
+
p "Segments are off - #{@time}"
|
26
|
+
log "**********"
|
27
|
+
log segments.inspect
|
28
|
+
log "**********"
|
29
|
+
elsif segments.size == 1
|
30
|
+
p "All Good. at #{segments[0]}"
|
31
|
+
log "^^^^^^^^^^^"
|
32
|
+
log segments.inspect
|
33
|
+
log "^^^^^^^^^^^"
|
34
|
+
else
|
35
|
+
p "No segements found - #{@time}"
|
36
|
+
log "~~~~~~~~~~~"
|
37
|
+
log "No segments!"
|
38
|
+
log "~~~~~~~~~~~"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def async_download(urls = [])
|
45
|
+
res = nil
|
46
|
+
|
13
47
|
EM.synchrony do
|
14
48
|
multi = EventMachine::Synchrony::Multi.new
|
15
|
-
|
49
|
+
|
50
|
+
urls.each_with_index do |p,i|
|
16
51
|
log p
|
17
|
-
puts "Downloading: #{p}"
|
18
52
|
multi.add :"#{i}", EventMachine::HttpRequest.new(p).aget
|
19
53
|
@time = Time.now
|
20
54
|
end
|
21
|
-
|
55
|
+
|
22
56
|
res = multi.perform
|
57
|
+
|
58
|
+
EventMachine.stop
|
59
|
+
end
|
23
60
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
61
|
+
return res
|
62
|
+
end
|
63
|
+
|
64
|
+
def dive(urls = [])
|
65
|
+
playlists = []
|
66
|
+
|
67
|
+
res = async_download(urls)
|
68
|
+
res.requests.each do |req|
|
69
|
+
p = Playlist.new(req.response, req.req.uri.to_s)
|
32
70
|
|
33
|
-
if
|
34
|
-
p
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
p "All Good. at #{segments[0]}"
|
40
|
-
log "^^^^^^^^^^^"
|
41
|
-
log segments.inspect
|
42
|
-
log "^^^^^^^^^^^"
|
71
|
+
if p.valid?
|
72
|
+
if p.variable_playlist?
|
73
|
+
playlists = dive(p.playlists)
|
74
|
+
else
|
75
|
+
playlists << p
|
76
|
+
end
|
43
77
|
end
|
44
|
-
|
45
|
-
EventMachine.stop
|
46
78
|
end
|
47
|
-
|
48
|
-
|
49
|
-
|
79
|
+
|
80
|
+
return playlists
|
81
|
+
end
|
50
82
|
|
51
83
|
def log(str)
|
52
84
|
#eval "@log.#{type} \"#{str}\"" if @log
|
data/lib/hlspider/version.rb
CHANGED
data/lib/hlspider.rb
CHANGED
metadata
CHANGED
@@ -1,72 +1,70 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: hlspider
|
3
|
-
version: !ruby/object:Gem::Version
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.2
|
4
5
|
prerelease:
|
5
|
-
version: 0.1.0
|
6
6
|
platform: ruby
|
7
|
-
authors:
|
7
|
+
authors:
|
8
8
|
- Brooke McKim
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
|
13
|
-
date: 2011-05-27 00:00:00 -04:00
|
12
|
+
date: 2011-08-18 00:00:00.000000000 -04:00
|
14
13
|
default_executable:
|
15
|
-
dependencies:
|
16
|
-
- !ruby/object:Gem::Dependency
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
17
16
|
name: thor
|
18
|
-
|
19
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
17
|
+
requirement: &2152994560 !ruby/object:Gem::Requirement
|
20
18
|
none: false
|
21
|
-
requirements:
|
22
|
-
- -
|
23
|
-
- !ruby/object:Gem::Version
|
19
|
+
requirements:
|
20
|
+
- - ! '>='
|
21
|
+
- !ruby/object:Gem::Version
|
24
22
|
version: 0.14.0
|
25
23
|
type: :runtime
|
26
|
-
version_requirements: *id001
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: em-synchrony
|
29
24
|
prerelease: false
|
30
|
-
|
25
|
+
version_requirements: *2152994560
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: em-synchrony
|
28
|
+
requirement: &2152993020 !ruby/object:Gem::Requirement
|
31
29
|
none: false
|
32
|
-
requirements:
|
33
|
-
- -
|
34
|
-
- !ruby/object:Gem::Version
|
30
|
+
requirements:
|
31
|
+
- - ! '>='
|
32
|
+
- !ruby/object:Gem::Version
|
35
33
|
version: 0.3.0.beta.1
|
36
34
|
type: :runtime
|
37
|
-
version_requirements: *id002
|
38
|
-
- !ruby/object:Gem::Dependency
|
39
|
-
name: eventmachine
|
40
35
|
prerelease: false
|
41
|
-
|
36
|
+
version_requirements: *2152993020
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: eventmachine
|
39
|
+
requirement: &2152983760 !ruby/object:Gem::Requirement
|
42
40
|
none: false
|
43
|
-
requirements:
|
44
|
-
- -
|
45
|
-
- !ruby/object:Gem::Version
|
41
|
+
requirements:
|
42
|
+
- - ! '>='
|
43
|
+
- !ruby/object:Gem::Version
|
46
44
|
version: 1.0.0.beta.3
|
47
45
|
type: :runtime
|
48
|
-
version_requirements: *id003
|
49
|
-
- !ruby/object:Gem::Dependency
|
50
|
-
name: em-http-request
|
51
46
|
prerelease: false
|
52
|
-
|
47
|
+
version_requirements: *2152983760
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: em-http-request
|
50
|
+
requirement: &2152981200 !ruby/object:Gem::Requirement
|
53
51
|
none: false
|
54
|
-
requirements:
|
55
|
-
- -
|
56
|
-
- !ruby/object:Gem::Version
|
52
|
+
requirements:
|
53
|
+
- - ! '>='
|
54
|
+
- !ruby/object:Gem::Version
|
57
55
|
version: 1.0.0.beta.3
|
58
56
|
type: :runtime
|
59
|
-
|
60
|
-
|
61
|
-
|
57
|
+
prerelease: false
|
58
|
+
version_requirements: *2152981200
|
59
|
+
description: Downloads .m3u8 playlist files and confirms their segments are properly
|
60
|
+
aligned.
|
61
|
+
email:
|
62
62
|
- bmckim@telvue.com
|
63
|
-
executables:
|
63
|
+
executables:
|
64
64
|
- hlspider
|
65
65
|
extensions: []
|
66
|
-
|
67
66
|
extra_rdoc_files: []
|
68
|
-
|
69
|
-
files:
|
67
|
+
files:
|
70
68
|
- .gitignore
|
71
69
|
- Gemfile
|
72
70
|
- README.md
|
@@ -81,30 +79,26 @@ files:
|
|
81
79
|
has_rdoc: true
|
82
80
|
homepage: http://github.com/telvue/hlspider
|
83
81
|
licenses: []
|
84
|
-
|
85
82
|
post_install_message:
|
86
83
|
rdoc_options: []
|
87
|
-
|
88
|
-
require_paths:
|
84
|
+
require_paths:
|
89
85
|
- lib
|
90
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
86
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
91
87
|
none: false
|
92
|
-
requirements:
|
93
|
-
- -
|
94
|
-
- !ruby/object:Gem::Version
|
95
|
-
version:
|
96
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
88
|
+
requirements:
|
89
|
+
- - ! '>='
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: '0'
|
92
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
97
93
|
none: false
|
98
|
-
requirements:
|
99
|
-
- -
|
100
|
-
- !ruby/object:Gem::Version
|
101
|
-
version:
|
94
|
+
requirements:
|
95
|
+
- - ! '>='
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
102
98
|
requirements: []
|
103
|
-
|
104
99
|
rubyforge_project: hlspider
|
105
100
|
rubygems_version: 1.6.2
|
106
101
|
signing_key:
|
107
102
|
specification_version: 3
|
108
103
|
summary: ASYNC .m3u8 downloader
|
109
104
|
test_files: []
|
110
|
-
|