ttvdb 0.0.2 → 0.0.3
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.
- checksums.yaml +4 -4
- data/.travis.yml +5 -0
- data/README.md +22 -10
- data/Rakefile +7 -0
- data/bin/ttvdb +3 -0
- data/lib/ttvdb.rb +15 -2
- data/lib/ttvdb/cli.rb +7 -0
- data/lib/ttvdb/client.rb +25 -33
- data/lib/ttvdb/episode.rb +12 -15
- data/lib/ttvdb/match.rb +76 -0
- data/lib/ttvdb/parser.rb +99 -0
- data/lib/ttvdb/series.rb +11 -35
- data/lib/ttvdb/version.rb +1 -1
- data/spec/lib/ttvdb/client_spec.rb +40 -0
- data/spec/lib/ttvdb/episode_spec.rb +54 -0
- data/spec/lib/ttvdb/match_spec.rb +21 -0
- data/spec/lib/ttvdb/series_spec.rb +78 -0
- data/spec/lib/ttvdb_spec.rb +8 -0
- data/spec/res/episode_5_en.xml +33 -0
- data/spec/res/series_all_de.xml +2044 -0
- data/spec/res/series_all_en.xml +2044 -0
- data/spec/spec_helper.rb +2 -0
- data/ttvdb.gemspec +4 -1
- metadata +71 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 64f19e256a1cc6ee78fb68e18b8058f9cc452f8a
|
4
|
+
data.tar.gz: 002b47931f2199e77320ed238e997a68126b60fa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1abc5a4db7d907c1b1cc84827c1da232121d594001a742ade3519a8fafc9cb1b71d5dc707fd30b782d16e0bb6826d8377fc0b8442625be76852441fc2f7886af
|
7
|
+
data.tar.gz: e3a4ead1586d3e21ede28cc75aedeb99f8f8dadf612e31847d9e9d664e2b7998283e5cc017deb261df85f21a698297d8497ee8ce0379e7c9c2c58e1fc6dd7e64
|
data/.travis.yml
ADDED
data/README.md
CHANGED
@@ -1,7 +1,14 @@
|
|
1
|
+
[](https://travis-ci.org/lotherk/ttvdb)
|
2
|
+
|
1
3
|
# TTVDB
|
2
4
|
|
3
5
|
This is another [TheTVDB.com](http://www.thetvdb.com) API library. The others out there didn't fit my needs (if they even worked).
|
4
6
|
|
7
|
+
Source code is available at [github](httsp://github.com/lotherk/ttvdb)
|
8
|
+
|
9
|
+
Documentation is available at [rubydoc.info](http://rubydoc.info/github/lotherk/ttvdb)
|
10
|
+
|
11
|
+
Gem is available at [rubygems.org](https://rubygems.org/gems/ttvdb)
|
5
12
|
|
6
13
|
## Installation
|
7
14
|
|
@@ -17,8 +24,19 @@ Or install it yourself as:
|
|
17
24
|
|
18
25
|
$ gem install ttvdb
|
19
26
|
|
27
|
+
From source:
|
28
|
+
|
29
|
+
$ git clone https://github.com/lotherk/ttvdb
|
30
|
+
$ cd ttvdb
|
31
|
+
$ rake build
|
32
|
+
$ gem install pkg/ttvdb-VERSION.gem
|
33
|
+
|
20
34
|
## Usage
|
21
35
|
|
36
|
+
### Using the CLI tools
|
37
|
+
|
38
|
+
|
39
|
+
### Writing Code
|
22
40
|
Require the gem
|
23
41
|
|
24
42
|
```ruby
|
@@ -31,23 +49,17 @@ Create a ```TTVDB::Client``` instance
|
|
31
49
|
client = TTVDB::Client.new(options={})
|
32
50
|
```
|
33
51
|
|
52
|
+
Where ```options``` can be:
|
53
|
+
|
34
54
|
| key | value | description
|
35
55
|
| --- | :---: | --- |
|
36
56
|
| ```:api_key``` | api key | Your TheTVDB API Key, *optional* |
|
37
57
|
| ```:api_url``` | http://www.thetvdb.com/api/ | API Url, *optional* |
|
38
58
|
| ```:language```|```en```,```de```,```fr```,... | The language code to use. Fallback is ```en```, *optional* |
|
39
59
|
|
40
|
-
Fetch series by name. Returns an array of series if result count is more than 1.
|
41
|
-
|
42
|
-
```ruby
|
43
|
-
series = client.get_series "Saber Rider"
|
44
|
-
```
|
45
|
-
|
46
|
-
Results to an array of 3 ```TTVDB::Series``` instances.
|
47
|
-
|
48
60
|
# Example
|
49
61
|
|
50
|
-
This is an example script that fetches a series by ARGV. if ARGV is an integer, it
|
62
|
+
This is an example script that fetches a series by ARGV. if ARGV is an integer, it will fetch it by its id otherwise by its name. It will then print a little overview about the series.
|
51
63
|
|
52
64
|
## Usage
|
53
65
|
```bash
|
@@ -93,7 +105,7 @@ See the ```examples/``` folder for a complete list of examples. I try to make th
|
|
93
105
|
|
94
106
|
## Contributing
|
95
107
|
|
96
|
-
1. Fork it ( http://github.com
|
108
|
+
1. Fork it ( http://github.com/lotherk/ttvdb/fork )
|
97
109
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
98
110
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
99
111
|
4. Push to the branch (`git push origin my-new-feature`)
|
data/Rakefile
CHANGED
data/bin/ttvdb
ADDED
data/lib/ttvdb.rb
CHANGED
@@ -2,11 +2,24 @@ require "rest-client"
|
|
2
2
|
require "logger"
|
3
3
|
require "xmlsimple"
|
4
4
|
require "ttvdb/version"
|
5
|
+
require "ttvdb/match"
|
5
6
|
require "ttvdb/client"
|
6
7
|
|
7
8
|
|
8
9
|
module TTVDB
|
9
|
-
def self.logger
|
10
|
-
@logger
|
10
|
+
def self.logger(output=STDOUT)
|
11
|
+
unless @logger
|
12
|
+
@logger = Logger.new(output)
|
13
|
+
@logger.formatter = proc { |severity, datetime, progname, msg|
|
14
|
+
kaller = caller[4]
|
15
|
+
file, ln, func = kaller.split(":")
|
16
|
+
_nil, func = func.split("`")
|
17
|
+
func.gsub!(/[<>']/, "")
|
18
|
+
file = File.basename(file)
|
19
|
+
"#{datetime} #{severity} #{file}:#{func}:#{ln}: #{msg}\n"
|
20
|
+
}
|
21
|
+
@logger.level = Logger::WARN
|
22
|
+
end
|
23
|
+
@logger
|
11
24
|
end
|
12
25
|
end
|
data/lib/ttvdb/cli.rb
ADDED
data/lib/ttvdb/client.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
|
+
require 'ttvdb/parser'
|
1
2
|
require 'ttvdb/series'
|
2
3
|
require 'ttvdb/episode'
|
3
4
|
|
4
5
|
class TTVDB::Client
|
5
|
-
|
6
|
+
attr_accessor :language
|
6
7
|
|
7
8
|
def initialize(opts = {})
|
8
9
|
@opts = {
|
@@ -15,47 +16,38 @@ class TTVDB::Client
|
|
15
16
|
end
|
16
17
|
|
17
18
|
def get_series_by_id id
|
18
|
-
lookup = "series/#{id}/#{@
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
raise
|
24
|
-
end
|
19
|
+
lookup = "series/#{id}/#{@language}.xml"
|
20
|
+
hsh = XmlSimple.xml_in(client[lookup].get)
|
21
|
+
serie = TTVDB::Series.new(hsh["Series"][0])
|
22
|
+
serie.client = self
|
23
|
+
return serie
|
25
24
|
end
|
26
25
|
|
27
26
|
def get_series name
|
28
27
|
_client = RestClient::Resource.new("#{@opts[:api_url]}/GetSeries.php", :headers => { :params => { 'seriesname' => name, 'language' => @language }})
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
end
|
38
|
-
return series
|
39
|
-
rescue Exception => e
|
40
|
-
TTVDB.logger.error { "Error while fetching series: #{e.message}" }
|
41
|
-
raise
|
28
|
+
hsh = XmlSimple.xml_in(_client.get)
|
29
|
+
return [] unless hsh["Series"]
|
30
|
+
series = []
|
31
|
+
hsh["Series"].each do |s|
|
32
|
+
serie = TTVDB::Series.new(s)
|
33
|
+
next if serie.language != @language
|
34
|
+
serie.client = self
|
35
|
+
series << serie
|
42
36
|
end
|
37
|
+
return series
|
43
38
|
end
|
44
39
|
|
45
40
|
def get_episodes_by_series_id id
|
46
|
-
lookup = "series/#{id}/all/#{@
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
return episodes
|
55
|
-
rescue Exception => e
|
56
|
-
TTVDB.logger.error("get_episodes_by_series_id") { "Could not create hash from result: #{e.message}" }
|
57
|
-
raise
|
41
|
+
lookup = "series/#{id}/all/#{@language}.xml"
|
42
|
+
hsh = XmlSimple.xml_in(client[lookup].get)
|
43
|
+
return [] unless hsh["Episode"]
|
44
|
+
episodes = []
|
45
|
+
hsh["Episode"].each do |e|
|
46
|
+
episode = TTVDB::Episode.new(e)
|
47
|
+
episode.client = self
|
48
|
+
episodes << episode
|
58
49
|
end
|
50
|
+
episodes
|
59
51
|
end
|
60
52
|
|
61
53
|
private
|
data/lib/ttvdb/episode.rb
CHANGED
@@ -1,21 +1,18 @@
|
|
1
1
|
class TTVDB::Episode
|
2
|
-
|
3
|
-
:combined_number, :combined_season
|
2
|
+
include TTVDB::Parser
|
4
3
|
|
5
|
-
|
4
|
+
attr_reader :id, :combined_episodenumber, :combined_season,
|
5
|
+
:dvd_chapter, :dvd_discid, :dvd_episodenumber, :dvd_season,
|
6
|
+
:director, :ep_img_flag, :episode_name, :name, :episode_number,
|
7
|
+
:number, :first_aired, :guest_stars, :imdb_id, :overview,
|
8
|
+
:last_updated, :rating, :absolute_number, :season_number,
|
9
|
+
:season_id, :series_id
|
6
10
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
@
|
11
|
-
|
12
|
-
@overview = options["Overview"][0] rescue nil
|
13
|
-
@season_id = options["seasonid"][0].to_i rescue nil
|
14
|
-
@series_id = options["seriesid"][0].to_i rescue nil
|
15
|
-
@combined_number = options["Combined_episodenumber"][0].to_i rescue nil
|
16
|
-
@combined_season = options["Combined_season"][0].to_i rescue nil
|
17
|
-
@client = options[:client] rescue nil
|
18
|
-
@series = options[:series] rescue nil
|
11
|
+
attr_accessor :client, :series
|
12
|
+
|
13
|
+
def initialize(data)
|
14
|
+
@data = Hash[data.map { |k, v| [k.downcase, v] }]
|
15
|
+
parse
|
19
16
|
end
|
20
17
|
|
21
18
|
end
|
data/lib/ttvdb/match.rb
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'similar_text'
|
2
|
+
module TTVDB::Match
|
3
|
+
def match_episode filename, opts = {}
|
4
|
+
episode = nil
|
5
|
+
case opts[:filter]
|
6
|
+
when :sorted
|
7
|
+
episode = match_episode_sorted filename, opts
|
8
|
+
when :name
|
9
|
+
episode = match_episode_name filename, opts
|
10
|
+
when :regex
|
11
|
+
episode = match_episode_regex filename, opts
|
12
|
+
else
|
13
|
+
# try all
|
14
|
+
episode = match_episode_regex filename, opts rescue nil
|
15
|
+
episode ||= match_episode_name(filename, opts) rescue nil
|
16
|
+
episode ||= match_episode_regex(filename, opts) rescue nil
|
17
|
+
end
|
18
|
+
episode
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
def match_episode_sorted filename, opts = {}
|
23
|
+
enum = get_episode filename
|
24
|
+
return episodes[enum-1] rescue nil
|
25
|
+
end
|
26
|
+
|
27
|
+
def match_episode_name filename, opts = {}
|
28
|
+
results = []
|
29
|
+
episodes.each do |episode|
|
30
|
+
min = opts[:min]
|
31
|
+
min ||= 45
|
32
|
+
results << episode if episode.name.similar(filename) >= min
|
33
|
+
end
|
34
|
+
if results.count == 0
|
35
|
+
results = nil
|
36
|
+
elsif results.count == 1
|
37
|
+
results = results[0]
|
38
|
+
end
|
39
|
+
return results
|
40
|
+
end
|
41
|
+
|
42
|
+
def match_episode_regex filename, opts = {}
|
43
|
+
snum = get_season filename
|
44
|
+
enum = get_episode filename
|
45
|
+
seasons[snum][enum] rescue nil
|
46
|
+
end
|
47
|
+
|
48
|
+
def get_episode filename
|
49
|
+
filter_episode = [
|
50
|
+
/e(\d+)/i,
|
51
|
+
/(\d+)/i
|
52
|
+
]
|
53
|
+
filter_episode.each do |r|
|
54
|
+
m = filename.match(r)
|
55
|
+
if m
|
56
|
+
return m[1].to_i rescue nil
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def get_season filename
|
62
|
+
filter_season = [
|
63
|
+
/s(\d+)/i,
|
64
|
+
/season.*(\d+)/i,
|
65
|
+
/staffel.*(\d+)/i,
|
66
|
+
/(\d+)x/i,
|
67
|
+
/(\d+)-/i
|
68
|
+
]
|
69
|
+
filter_season.each do |r|
|
70
|
+
m = filename.match(r)
|
71
|
+
if m
|
72
|
+
return m[1].to_i rescue nil
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
data/lib/ttvdb/parser.rb
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
module TTVDB::Parser
|
2
|
+
attr_reader :id
|
3
|
+
|
4
|
+
MAP = {
|
5
|
+
"id" => { :map => true, :cast => :integer },
|
6
|
+
"combined_episodenumber" => { :map => true, :cast => :float },
|
7
|
+
"combined_season" => { :map => true, :cast => :integer },
|
8
|
+
"dvd_chapter" => { :map => true, :cast => :integer },
|
9
|
+
"dvd_discid" => { :map => true, :cast => :integer },
|
10
|
+
"dvd_episodenumber" => { :map => true, :cast => :float },
|
11
|
+
"dvd_season" => { :map => true, :cast => :integer },
|
12
|
+
"director" => { :map => true },
|
13
|
+
"epimgflag" => { :map => true, :cast => :integer },
|
14
|
+
"episodename" => { :map => :name },
|
15
|
+
"episodenumber" => { :map => :number, :cast => :integer },
|
16
|
+
"firstaired" => { :map => :first_aired, :cast => :time },
|
17
|
+
"gueststars" => { :map => :guest_stars, :cast => :array },
|
18
|
+
"imdb_id" => { :map => true },
|
19
|
+
"language" => { :map => true },
|
20
|
+
"overview" => { :map => true },
|
21
|
+
"productioncode" => { :map => :production_code },
|
22
|
+
"rating" => { :map => true, :cast => :float },
|
23
|
+
"ratingcount" => { :map => :rating_count, :cast => :integer },
|
24
|
+
"seasonnumber" => { :map => :season_number, :cast => :integer },
|
25
|
+
"writer" => { :map => true },
|
26
|
+
"absolute_number" => { :map => true, :cast => :integer },
|
27
|
+
"filename" => { :map => true },
|
28
|
+
"lastupdated" => { :map => :last_updated, :cast => :time_at },
|
29
|
+
"seasonid" => { :map => :season_id, :cast => :integer },
|
30
|
+
"seriesid" => { :map => :series_id, :cast => :integer },
|
31
|
+
"thumb_added" => { :map => true },
|
32
|
+
"thumb_height" => { :map => true, :cast => :integer },
|
33
|
+
"thumb_width" => { :map => true, :cast => :integer },
|
34
|
+
"actors" => { :map => true, :cast => :array },
|
35
|
+
"airs_dayofweek" => { :map => true },
|
36
|
+
"airs_time" => { :map => true },
|
37
|
+
"contentrating" => { :map => :content_rating, :cast => :float },
|
38
|
+
"genre" => { :map => true, :cast => :array },
|
39
|
+
"network" => { :map => true },
|
40
|
+
"networkid" => { :map => :network_id },
|
41
|
+
"runtime" => { :map => true, :cast => :integer },
|
42
|
+
"seriesname" => { :map => :name },
|
43
|
+
"status" => { :map => true },
|
44
|
+
"added" => { :map => true },
|
45
|
+
"added_by" => { :map => true },
|
46
|
+
"banner" => { :map => true },
|
47
|
+
"fanart" => { :map => true },
|
48
|
+
"poster" => { :map => true },
|
49
|
+
"zap2it_id" => { :map => true }
|
50
|
+
}
|
51
|
+
|
52
|
+
def parse
|
53
|
+
raise "no data to parse" unless @data
|
54
|
+
@data.each do |k, v|
|
55
|
+
k = k.downcase
|
56
|
+
v = v[0]
|
57
|
+
unless MAP.include? k
|
58
|
+
next
|
59
|
+
end
|
60
|
+
var = nil
|
61
|
+
if MAP[k][:map].is_a? TrueClass
|
62
|
+
var = k.to_sym
|
63
|
+
else
|
64
|
+
var = MAP[k][:map].to_sym
|
65
|
+
end
|
66
|
+
|
67
|
+
unless respond_to? var
|
68
|
+
next
|
69
|
+
end
|
70
|
+
k, v = map k, v
|
71
|
+
instance_variable_set("@#{k}", v)
|
72
|
+
end
|
73
|
+
@data = nil
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
def map k, v
|
78
|
+
case MAP[k][:cast]
|
79
|
+
when :integer
|
80
|
+
v = v.to_i rescue v
|
81
|
+
when :float
|
82
|
+
v = v.to_f rescue v
|
83
|
+
when :array
|
84
|
+
v = v.split("|").compact rescue v
|
85
|
+
when :time_at
|
86
|
+
v = Time.at(v.to_i) rescue v
|
87
|
+
when :time
|
88
|
+
v = Time.parse(v) rescue v
|
89
|
+
else
|
90
|
+
v = v
|
91
|
+
end
|
92
|
+
if MAP[k][:map].is_a? TrueClass
|
93
|
+
k = k.to_sym
|
94
|
+
else
|
95
|
+
k = MAP[k][:map].to_sym
|
96
|
+
end
|
97
|
+
[k, v]
|
98
|
+
end
|
99
|
+
end
|
data/lib/ttvdb/series.rb
CHANGED
@@ -1,49 +1,25 @@
|
|
1
1
|
class TTVDB::Series
|
2
|
+
include TTVDB::Parser
|
3
|
+
include TTVDB::Match
|
4
|
+
|
2
5
|
attr_reader :id, :actors, :airs_dayofweek, :airs_time,
|
3
6
|
:content_rating, :first_aired, :genre, :imdb_id, :language,
|
4
7
|
:network, :network_id, :overview, :rating, :rating_count,
|
5
8
|
:runtime, :series_id, :series_name, :status, :added, :added_by,
|
6
|
-
:banner, :fanart, :last_updated, :poster, :zap2it_id, :
|
9
|
+
:banner, :fanart, :last_updated, :poster, :zap2it_id, :seasons,
|
7
10
|
:name
|
8
11
|
|
9
|
-
|
12
|
+
attr_accessor :client
|
10
13
|
|
11
|
-
def initialize(data
|
12
|
-
|
13
|
-
|
14
|
-
@actors = options["Actors"][0].split("|").compact rescue []
|
15
|
-
@airs_dayofweek = options["Airs_DayOfWeek"][0] rescue nil
|
16
|
-
@airs_time = options["Airs_Time"][0] rescue nil
|
17
|
-
@content_rating = options["ContentRating"][0].to_f rescue 0
|
18
|
-
@first_aired = Time.parse(options["FirstAired"][0]) rescue nil
|
19
|
-
@genre = options["Genre"][0].split("|").compact rescue []
|
20
|
-
@imdb_id = options["IMDB_ID"][0].to_i rescue nil
|
21
|
-
@language = options["language"][0] rescue nil
|
22
|
-
@language ||= options["Language"][0] rescue "en"
|
23
|
-
@network = options["Network"][0] rescue nil
|
24
|
-
@network_id = options["NetworkID"][0] rescue nil
|
25
|
-
@overview = options["Overview"][0] rescue nil
|
26
|
-
@rating = options["Rating"][0].to_f rescue 0
|
27
|
-
@rating_count = options["RatingCount"][0] rescue 0
|
28
|
-
@runtime = options["Runtime"][0].to_i rescue nil
|
29
|
-
@runtime ||= options["runtime"][0].to_i rescue 0
|
30
|
-
@series_id = options["SeriesID"][0].to_i rescue nil
|
31
|
-
@series_name = options["SeriesName"][0] rescue nil
|
32
|
-
@name = @series_name
|
33
|
-
@status = options["Status"][0].downcase rescue nil
|
34
|
-
@added = options["added"][0] rescue nil
|
35
|
-
@added_by = options["addedBy"][0] rescue nil
|
36
|
-
@banner = options["banner"][0] rescue nil
|
37
|
-
@fanart = options["fanart"][0] rescue nil
|
38
|
-
@last_updated = Time.at(options["lastupdated"][0].to_i) rescue nil
|
39
|
-
@poster = options["poster"][0] rescue nil
|
40
|
-
@zap2it_id = options["zap2it_id"][0] rescue nil
|
41
|
-
@client = options[:client] rescue nil
|
14
|
+
def initialize(data)
|
15
|
+
@data = Hash[data.map { |k, v| [k.downcase, v] }]
|
16
|
+
parse
|
42
17
|
@seasons = {}
|
43
|
-
TTVDB.logger.debug { "Series language: #{@language}" }
|
44
|
-
fetch_episodes
|
45
18
|
end
|
46
19
|
|
20
|
+
def episodes
|
21
|
+
@episodes ||= fetch_episodes
|
22
|
+
end
|
47
23
|
|
48
24
|
private
|
49
25
|
def fetch_episodes
|