sick-beard 1.0.0.pre
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.gitignore +33 -0
- data/.rspec +2 -0
- data/.travis.yml +5 -0
- data/Changelog.md +19 -0
- data/Gemfile +4 -0
- data/Guardfile +9 -0
- data/LICENSE +22 -0
- data/README.md +54 -0
- data/Rakefile +7 -0
- data/lib/sickbeard.rb +53 -0
- data/lib/sickbeard/api.rb +64 -0
- data/lib/sickbeard/show.rb +152 -0
- data/lib/sickbeard/version.rb +3 -0
- data/sick-beard.gemspec +33 -0
- data/spec/.rspec +2 -0
- data/spec/cassettes/sickbeard.yml +6911 -0
- data/spec/client_spec.rb +106 -0
- data/spec/show_spec.rb +142 -0
- data/spec/spec_helper.rb +59 -0
- metadata +267 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
ODhhNDM5YzU4YjBjNTQ4NWQ0MTEyOTllNjgwNzc0Zjc1ZGM5MGNhYw==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
NDdjZmQwYzgzMWNlY2MyY2VlYWE5NWFjODkwNzJjODNjM2U4OGQxZQ==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
NGJmNWE0MzYwZjAxZTliZmQ4MDZhNjZkMGM0NDYwZDQwNTI4M2M1YmE5YmJl
|
10
|
+
Nzk3MjZjYjZiMDMwZjY3NGJiNjczMGQyNzdjYWQ0NTNmYWJkMTJhYTllZTcz
|
11
|
+
YWUxZTcyODNjYWQzYzAyYjllNThiOGYyNjQ4ZTM4MDhlMWQ0Y2E=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
YzFlY2M0NzZmYWI5MmI1MzYzOGRmMGY3OTBiYjAyMTk3YjRjNjAzZGU4MWZh
|
14
|
+
NTU3YjI1N2NkZTU2YmYxY2FkMzM4MDAyODcyMmY5Yjg2NDc2MzllM2ZkNGVl
|
15
|
+
ZjEyYTIwOGE0ZjgwMTA2MTA5NjhkYjQzODIwOWFiYjk1ZGQzYzg=
|
data/.gitignore
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
18
|
+
|
19
|
+
# RVM
|
20
|
+
.rvmrc
|
21
|
+
.ruby-gemset
|
22
|
+
.ruby-version
|
23
|
+
|
24
|
+
# YARD artifacts
|
25
|
+
.yardoc
|
26
|
+
_yardoc
|
27
|
+
doc/
|
28
|
+
|
29
|
+
# OSX artifacts
|
30
|
+
.DS_Store
|
31
|
+
|
32
|
+
# RubyMine
|
33
|
+
.idea/
|
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Changelog.md
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# SickBeard Gem Changelog
|
2
|
+
|
3
|
+
## 0.0.6 - 2012/09/18
|
4
|
+
|
5
|
+
* Add #addnew and #delete methods to Show from work by nickmeessen.
|
6
|
+
|
7
|
+
## 0.0.5 - 2012/09/15
|
8
|
+
|
9
|
+
* Fix for issue #1
|
10
|
+
|
11
|
+
## 0.0.4 - 2012/08/14
|
12
|
+
|
13
|
+
* Ensure that if we load all shows, we get the season_list from the server if
|
14
|
+
necessary.
|
15
|
+
* Implement sb.searchtvdb API call simply.
|
16
|
+
* Implement show.refresh.
|
17
|
+
|
18
|
+
## 0.0.3 - 2012/08/13
|
19
|
+
* Add further YARD documentation for the Show class.
|
data/Gemfile
ADDED
data/Guardfile
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
|
4
|
+
guard 'rspec', all_after_pass: true, keep_failed: false do
|
5
|
+
watch(%r{^spec/.+_spec\.rb$})
|
6
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
7
|
+
watch('spec/spec_helper.rb') { "spec" }
|
8
|
+
end
|
9
|
+
|
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Kevin McDermott
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
# Sick Beard [![Build Status](https://travis-ci.org/RLovelett/sick-beard.png?branch=master)](https://travis-ci.org/RLovelett/sick-beard) [![Coverage Status](https://coveralls.io/repos/RLovelett/sick-beard/badge.png?branch=master)](https://coveralls.io/r/RLovelett/sick-beard?branch=master)
|
2
|
+
|
3
|
+
The `sick-beard` gem provides a Ruby interface for interacting with the [Sick Beard PRV API](http://sickbeard.com/api/). Pull requests are always welcome.
|
4
|
+
|
5
|
+
## Author
|
6
|
+
|
7
|
+
[Ryan Lovelett](http://ryan.lovelett.me/) ( [@rlovelett](http://twitter.com/#!/rlovelett) )
|
8
|
+
|
9
|
+
Drop me a message for any questions, suggestions, requests, bugs or
|
10
|
+
submit them to the [issue
|
11
|
+
log](https://github.com/rlovelett/sports_data_api/issues).
|
12
|
+
|
13
|
+
## Installation
|
14
|
+
|
15
|
+
Add this line to your application's Gemfile:
|
16
|
+
|
17
|
+
gem 'sick-beard'
|
18
|
+
|
19
|
+
And then execute:
|
20
|
+
|
21
|
+
$ bundle
|
22
|
+
|
23
|
+
Or install it yourself as:
|
24
|
+
|
25
|
+
$ gem install sick-beard
|
26
|
+
|
27
|
+
## Usage
|
28
|
+
|
29
|
+
The specs for this Gem should give you some idea of how to make use of
|
30
|
+
the API. For now they will be the usage information. As always Pull
|
31
|
+
Requests for better documentation are welcome.
|
32
|
+
|
33
|
+
## Testing
|
34
|
+
|
35
|
+
The tests for the API have been mocked using [VCR](https://github.com/vcr/vcr) and [WebMock](https://github.com/bblimke/webmock).
|
36
|
+
|
37
|
+
Actual calls to a Sick Beard have been mocked out to prevent storage of valid API credentials and making
|
38
|
+
superflous API calls while testing. As such, in order to generically run the tests (without actually hitting)
|
39
|
+
the server the only thing that needs to be done is to run the specs (e.g., `bundle exec rake spec` or
|
40
|
+
`bundle exec guard start`).
|
41
|
+
|
42
|
+
However, if you want to refresh the actual server API responses you will need to re-record all of the VCR cassettes.
|
43
|
+
This can be achieved simply by performing the following two steps:
|
44
|
+
|
45
|
+
1. Delete all the cassettes (`rm spec/cassettes/*.yml`)
|
46
|
+
2. Run specs passing the API key as environment variable (`SPORTS_DATA_<NBA|NFL>_API_KEY=realapikey bundle exec rake spec`)
|
47
|
+
|
48
|
+
## Contributing
|
49
|
+
|
50
|
+
1. Fork it
|
51
|
+
2. Create a topic branch (`git checkout -b topic`)
|
52
|
+
3. Make your changes
|
53
|
+
4. Squash your changes into one commit
|
54
|
+
5. Create new Pull Request against this squashed commit
|
data/Rakefile
ADDED
data/lib/sickbeard.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'uri'
|
3
|
+
require 'json'
|
4
|
+
require 'cgi'
|
5
|
+
|
6
|
+
module SickBeard
|
7
|
+
# This class provides all the methods for using the SickBeard API.
|
8
|
+
class Base
|
9
|
+
|
10
|
+
# @option options [String] :api_key ("") The SickBeard username for access.
|
11
|
+
# @option options [String] :server ("") The server API endpoint.
|
12
|
+
# @return [Object] the object.
|
13
|
+
def initialize(options = {})
|
14
|
+
|
15
|
+
options = { api_key: '',
|
16
|
+
server: '',
|
17
|
+
}.merge(options)
|
18
|
+
|
19
|
+
@server = options[:server]
|
20
|
+
@api_key = options[:api_key]
|
21
|
+
raise ArgumentError, 'No :api_key provided' if options[:api_key].nil? || options[:api_key].empty?
|
22
|
+
raise ArgumentError, 'No :server provided' if options[:server].nil? || options[:server].empty?
|
23
|
+
end
|
24
|
+
|
25
|
+
# Makes an API call to a SickBeard server
|
26
|
+
#
|
27
|
+
# @param [String] cmd SickBeard API call to request
|
28
|
+
# @param [Hash] options the options to make the API call with, these are
|
29
|
+
# passed as GET parameters to the SickBeard server.
|
30
|
+
# @return [String] the HTTP response
|
31
|
+
def make_request(cmd, options = {})
|
32
|
+
options = { cmd: cmd }.merge(options)
|
33
|
+
path = "/api/#{@api_key}/"
|
34
|
+
uri = URI::join(URI.parse(@server), path)
|
35
|
+
uri.query = URI.encode_www_form( options )
|
36
|
+
Net::HTTP.get(uri)
|
37
|
+
end
|
38
|
+
|
39
|
+
# Makes an API call to a SickBeard server returns JSON parsed result
|
40
|
+
# @see make_request
|
41
|
+
# @return [Hash] JSON parsed result from the remote server
|
42
|
+
def make_json_request(cmd, options = {})
|
43
|
+
response = JSON.parse(make_request(cmd, options))
|
44
|
+
raise Error.new(response['message']) if response['result'] != 'success'
|
45
|
+
response
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# Raised when the remote server returns a non-success response
|
50
|
+
class Error < RuntimeError; end
|
51
|
+
end
|
52
|
+
|
53
|
+
Dir[File.join(File.dirname(__FILE__), 'sickbeard/**/*.rb')].sort.each { |lib| require lib }
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module SickBeard
|
2
|
+
|
3
|
+
class Client < Base
|
4
|
+
|
5
|
+
# Returns misc SickBeard related information.
|
6
|
+
def sb
|
7
|
+
make_json_request('sb')
|
8
|
+
end
|
9
|
+
|
10
|
+
# Returns the upcoming episodes for the shows currently added in the
|
11
|
+
# users' database.
|
12
|
+
|
13
|
+
# @param [Hash] options optional parameters for the SickBeard API call
|
14
|
+
# @option options [String] :sort (nil) Option to sort the results:
|
15
|
+
# * date
|
16
|
+
# * network
|
17
|
+
# * name
|
18
|
+
#
|
19
|
+
# @option options [Array<String>] :filter (nil) Option to filter the results:
|
20
|
+
# * missed - show's date is older than today
|
21
|
+
# * today - show's date is today
|
22
|
+
# * soon - show's date greater than today but less than a week
|
23
|
+
# * later - show's date greater than a week
|
24
|
+
# @return [Object] the object.
|
25
|
+
def future(options = {})
|
26
|
+
filter = (options[:type] || []).join('|')
|
27
|
+
make_json_request('future', type: filter, sort: options[:sort])['data']
|
28
|
+
end
|
29
|
+
|
30
|
+
# Returns global episode and show statistics.
|
31
|
+
def shows_stats
|
32
|
+
make_json_request('shows.stats')['data']
|
33
|
+
end
|
34
|
+
|
35
|
+
# Returns a list of all shows in SickBeard.
|
36
|
+
def shows(options = {})
|
37
|
+
make_json_request('shows', sort: options[:sort])['data'].collect do |key, response|
|
38
|
+
# SickBeard API returns different things based on your sort.
|
39
|
+
if options[:sort] == 'name'
|
40
|
+
response['show_name'] = key
|
41
|
+
show_id = response['tvdbid']
|
42
|
+
else
|
43
|
+
show_id = key
|
44
|
+
end
|
45
|
+
Show.from_response(self, show_id, response)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# Returns information for a given show.
|
50
|
+
# @param [String] show_id the tvdbid for the show to fetch
|
51
|
+
# @return [SickBeard::Show]
|
52
|
+
def show(show_id)
|
53
|
+
Show.from_response(self, show_id, make_json_request('show', tvdbid: show_id)['data'])
|
54
|
+
end
|
55
|
+
|
56
|
+
# Search for Shows by name
|
57
|
+
# @param [String] name the show to match on.
|
58
|
+
def searchtvdb(name)
|
59
|
+
make_json_request('sb.searchtvdb', name: name)['data']['results'].collect do |result|
|
60
|
+
Show.from_response(self, result['tvdbid'], result)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,152 @@
|
|
1
|
+
module SickBeard
|
2
|
+
|
3
|
+
class Show
|
4
|
+
# @!attribute [r] name
|
5
|
+
# @return [String] the name of the Show
|
6
|
+
# @!attribute [r] genres
|
7
|
+
# @return [Array(String)] genres for this Show
|
8
|
+
# @!attribute [r] status
|
9
|
+
# @return [String] the status for this Show
|
10
|
+
# * Continuing
|
11
|
+
# * Ended
|
12
|
+
# @!attribute [r] season_list
|
13
|
+
# @return [Array(String)] list of known Series for this Show
|
14
|
+
# @!attribute [r] server
|
15
|
+
# @return [SickBeard::Client] the server this Show was loaded from
|
16
|
+
# @!attribute [r] tvdbid
|
17
|
+
# @return [Integer] the tvdbid for this Show
|
18
|
+
# @!attribute [r] quality
|
19
|
+
# @return [String] The download quality for this Show e.g. SD
|
20
|
+
attr_reader :name, :genres, :status, :server, :tvdbid, :quality
|
21
|
+
|
22
|
+
def self.from_response(server, tvdbid, response)
|
23
|
+
options = {
|
24
|
+
name: response['show_name'] || response['name'],
|
25
|
+
genres: response['genre'],
|
26
|
+
status: response['status'],
|
27
|
+
season_list: response['season_list'],
|
28
|
+
quality: response['quality'],
|
29
|
+
server: server,
|
30
|
+
tvdbid: tvdbid
|
31
|
+
}
|
32
|
+
Show.new(options)
|
33
|
+
end
|
34
|
+
|
35
|
+
# Create a new Show
|
36
|
+
# @option options [String] :name ("") The name for this show
|
37
|
+
# @option options [Array(String)] :genres ("") array of genres applicable to this show.
|
38
|
+
# @return [Object] the object.
|
39
|
+
def initialize(options = {})
|
40
|
+
|
41
|
+
options = { name: '',
|
42
|
+
genres: '',
|
43
|
+
status: '',
|
44
|
+
season_list: [],
|
45
|
+
}.merge(options)
|
46
|
+
@name = options[:name]
|
47
|
+
@genres = options[:genres]
|
48
|
+
@status = options[:status]
|
49
|
+
@season_list = (options[:season_list] || []).sort
|
50
|
+
@server = options[:server]
|
51
|
+
@tvdbid = options[:tvdbid]
|
52
|
+
@quality = options[:quality]
|
53
|
+
end
|
54
|
+
|
55
|
+
# Add this show to SickBeard to be tracked.
|
56
|
+
# @param [Hash] Options to be passed (location, lang, season_folder, status, initial, archive)
|
57
|
+
def addnew(options = {})
|
58
|
+
|
59
|
+
options[:initial] = [*(options[:initial] || [])].join('|') if options[:initial]
|
60
|
+
options[:archive] = [*(options[:archive] || [])].join('|') if options[:archive]
|
61
|
+
|
62
|
+
options = { tvdbid: @tvdbid }.merge(options)
|
63
|
+
|
64
|
+
@server.make_json_request('show.addnew', options)['message']
|
65
|
+
end
|
66
|
+
|
67
|
+
# Remove this show from SickBeard.
|
68
|
+
def delete
|
69
|
+
@server.make_json_request('show.delete', tvdbid: @tvdbid)['message']
|
70
|
+
end
|
71
|
+
|
72
|
+
# Retrieve a listing of episodes for all or a given season.
|
73
|
+
# @param [Integer] season optional if provided, fetch only episodes for
|
74
|
+
# the provided season otherwise pulls details down for every season of the how.
|
75
|
+
# @return [Array(Hash)] of season details
|
76
|
+
def seasons(season = nil)
|
77
|
+
@server.make_json_request('show.seasons', tvdbid: @tvdbid, season: season)['data']
|
78
|
+
end
|
79
|
+
|
80
|
+
# Retrieve the stored banner image from SickBeard's cache for this show.
|
81
|
+
# @return image data (JPEG format)
|
82
|
+
def get_banner
|
83
|
+
@server.make_request('show.getbanner', tvdbid: @tvdbid)
|
84
|
+
end
|
85
|
+
|
86
|
+
# Retrieve the stored poster image from SickBeard's cache for this show.
|
87
|
+
# @return image data (JPEG format)
|
88
|
+
def get_poster
|
89
|
+
@server.make_request('show.getposter', tvdbid: @tvdbid)
|
90
|
+
end
|
91
|
+
|
92
|
+
# Set a show's paused state in SickBeard.
|
93
|
+
def pause
|
94
|
+
@server.make_json_request('show.pause', tvdbid: @tvdbid, pause: 1)['message']
|
95
|
+
end
|
96
|
+
|
97
|
+
# Set a show's paused state in SickBeard.
|
98
|
+
def unpause
|
99
|
+
@server.make_json_request('show.pause', tvdbid: @tvdbid)['message']
|
100
|
+
end
|
101
|
+
|
102
|
+
# Retrieve a show's paused state in SickBeard.
|
103
|
+
# @return [Boolean] indicating whether or not this Show is paused
|
104
|
+
def paused?
|
105
|
+
@server.make_json_request('show', tvdbid: @tvdbid)['data']['paused'] == 1
|
106
|
+
end
|
107
|
+
|
108
|
+
# Set desired quality of a show in SickBeard.
|
109
|
+
# @option options [String, Array] :initial ([]) either a single quality SD
|
110
|
+
# or HD, or an array of allowable video quality definitions for downloading.
|
111
|
+
# @option options [String, Array] :archive ([]) either a single quality SD
|
112
|
+
# or HD, or an array of allowable video quality definitions for archiving.
|
113
|
+
def set_quality(options)
|
114
|
+
initial = [*(options[:initial] || [])].join('|')
|
115
|
+
archive = [*(options[:archive] || [])].join('|')
|
116
|
+
@server.make_json_request('show.setquality', tvdbid: @tvdbid, initial: initial, archive: archive)['message']
|
117
|
+
end
|
118
|
+
|
119
|
+
def season_list
|
120
|
+
if @season_list.empty?
|
121
|
+
@season_list = @server.make_json_request('show.seasonlist', tvdbid: @tvdbid)['data'].sort
|
122
|
+
end
|
123
|
+
@season_list
|
124
|
+
end
|
125
|
+
|
126
|
+
# Returns episode statistics for this show.
|
127
|
+
def stats
|
128
|
+
@server.make_json_request('show.stats', tvdbid: @tvdbid)['data']
|
129
|
+
end
|
130
|
+
|
131
|
+
# Returns true if SickBeard's poster image cache is valid
|
132
|
+
def has_cached_poster?
|
133
|
+
@server.make_json_request('show.cache', tvdbid: @tvdbid)['data']['poster'] == 1
|
134
|
+
end
|
135
|
+
|
136
|
+
# Returns true if SickBeard's banner image cache is valid
|
137
|
+
def has_cached_banner?
|
138
|
+
@server.make_json_request('show.cache', tvdbid: @tvdbid)['data']['banner'] == 1
|
139
|
+
end
|
140
|
+
|
141
|
+
# Update a show in SickBeard by pulling down information from TVDB and rescan
|
142
|
+
# local files.
|
143
|
+
def update
|
144
|
+
@server.make_json_request('show.update', tvdbid: @tvdbid)['message']
|
145
|
+
end
|
146
|
+
|
147
|
+
# Refresh a show in SickBeard by rescanning local files.
|
148
|
+
def refresh
|
149
|
+
@server.make_json_request('show.refresh', tvdbid: @tvdbid)['message']
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|