-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcheck_bsto_series.rb
executable file
·177 lines (145 loc) · 4.09 KB
/
check_bsto_series.rb
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
#!/usr/bin/env ruby
# Coypright (C) 2018 Christian Mayer <christian@fox21.at>
require 'net/http'
require 'json'
require 'optparse'
require 'cgi'
API_BASE_URL = 'https://bs.to/serie/%s/%d'
STATES = ['OK', 'WARNING', 'CRITICAL', 'UNKNOWN']
@options = {
:series_name => nil,
:series_season => nil,
:warning_episode => nil,
:critical_episode => nil,
:lang => 'en',
:unknown_state => 3,
}
opts = OptionParser.new do |o|
o.banner = 'Usage: --series <name> --season <number> -w <episode> -c <episode> --lang en|de'
o.separator('')
o.on('-n', '--series <name>', 'Series Name') do |series_name|
@options[:series_name] = series_name
end
o.on('-s', '--season <number>', 'Season Number') do |season|
@options[:series_season] = season.to_i
end
o.on('-w', '--warning <episode>', 'Warning Episode') do |episode|
@options[:warning_episode] = episode.to_i
end
o.on('-c', '--critical <episode>', 'Critical Episode') do |episode|
@options[:critical_episode] = episode.to_i
end
o.on('-l', '--lang <string>', 'Language: English or German') do |lang|
@options[:lang] = lang.downcase
end
o.on('-u', '--unknown <int>', 'Treat UNKNOWN state with different status code. Default: 3') do |state|
@options[:unknown_state] = state.to_i
end
o.on_tail('-h', '--help', 'Show this message.') do
puts o
puts
exit 3
end
end
ARGV << '-h' if ARGV.count == 0
commands = opts.parse(ARGV)
# Build URL.
url = API_BASE_URL % [@options[:series_name], @options[:series_season]]
uri = URI(url)
# Make response to API.
response = Net::HTTP.get(uri)
# This happens when you enter a season that does not exist (yet).
not_found_pos = response.index('Staffel nicht gefunden')
if not not_found_pos.nil?
state_name = STATES[@options[:unknown_state]]
perf_data = [
state_name, @options[:series_season],
@options[:series_name].downcase,
@options[:series_season], @options[:warning_episode],
@options[:series_season], @options[:critical_episode],
]
puts "%s: Season %d not found | '%s'=U;%d%03d;%d%03d" % perf_data
exit @options[:unknown_state]
end
# Search the beginning position of the episodes table.
table_beginning_pos = response.index('<table class="episodes">')
# Cut everything above the table beginning to get the table end.
table = response[table_beginning_pos..-1]
# Search the end position of the table.
# Hopefully there is no other table inside the table.
table_end_pos = table.index('</table>')
# Cut everything below the table.
table = table[0...table_end_pos]
regex_s = [
'<tr>',
'<td>',
'<a href="[^"]{6,}" title="([^"]{1,})">(\d{1,3})<.a>', # Title, Episode Number
'<.td>',
'<td>',
'<a [^>]{20,}>[^<]{1,}<s([tp]).{10}', # Language based on the HTML tag.
].join('\s{0,20}') # Whitespace between HTML tags.
regex = Regexp.new(regex_s)
episodes = table.scan(regex)
state = 0 # OK
title = 'N/A'
etitle = nil
id = 0
eid = nil
lang = 'N/A'
elang = nil
episodes.each do |episode|
etitle, eid, etag = episode
etitle = CGI.unescapeHTML(etitle)
.strip
.gsub(/[^ \-A-Za-z0-9']/, '')
eid = eid.to_i
elang = etag == 't' ? 'de' : 'en'
case @options[:lang]
when 'en'
# puts "episode: #%d %s (%s) '%s'" % [eid, etag, elang, etitle]
if eid >= @options[:critical_episode]
state = 2
title = etitle
id = eid
lang = elang
break
elsif eid >= @options[:warning_episode]
state = 1
title = etitle
id = eid
lang = elang
# contine loop
end
when 'de'
if elang == 'de'
# puts "episode: #%d %s (%s) '%s'" % [eid, etag, elang, etitle]
if eid >= @options[:critical_episode]
state = 2
title = etitle
id = eid
lang = elang
break
elsif eid >= @options[:warning_episode]
state = 1
title = etitle
id = eid
lang = elang
# contine loop
end
end
end
end
if state == 0
title = etitle
id = eid
lang = elang
end
state_name = STATES[state]
perf_data = [
state_name, id, title, @options[:series_season], lang, # Normal Output
@options[:series_name].downcase, id,
@options[:series_season], @options[:warning_episode],
@options[:series_season], @options[:critical_episode],
]
puts "%s: #%d %s (s=%d,l=%s) | '%s'=%d;%d%03d;%d%03d" % perf_data
exit state