memo_rage 0.0.1
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/.gitignore +5 -0
- data/.rspec +1 -0
- data/Gemfile +4 -0
- data/README.md +26 -0
- data/Rakefile +1 -0
- data/lib/memo_rage/client.rb +40 -0
- data/lib/memo_rage/episode.rb +13 -0
- data/lib/memo_rage/node.rb +12 -0
- data/lib/memo_rage/parser/base.rb +21 -0
- data/lib/memo_rage/parser/episode_list.rb +44 -0
- data/lib/memo_rage/parser/show_info.rb +36 -0
- data/lib/memo_rage/parser/show_search.rb +26 -0
- data/lib/memo_rage/parser.rb +4 -0
- data/lib/memo_rage/show.rb +24 -0
- data/lib/memo_rage/version.rb +3 -0
- data/lib/memo_rage.rb +13 -0
- data/memo_rage.gemspec +26 -0
- data/spec/helpers/webmock_helper.rb +73 -0
- data/spec/memo_rage/client_spec.rb +20 -0
- data/spec/memo_rage/parser/episode_list_spec.rb +13 -0
- data/spec/memo_rage/parser/show_info_spec.rb +29 -0
- data/spec/memo_rage/parser/show_search_spec.rb +13 -0
- data/spec/mock_xml/episode_list.xml +1417 -0
- data/spec/mock_xml/show_info.xml +43 -0
- data/spec/mock_xml/show_search.xml +27 -0
- data/spec/spec_helper.rb +14 -0
- metadata +142 -0
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# Memo Rage #
|
2
|
+
|
3
|
+
Memo rage is an api wrapper for the http://services.tvrage.com/
|
4
|
+
The gem is created to fulfil the needs of the project http://watchmemo.com
|
5
|
+
|
6
|
+
## Installation ##
|
7
|
+
|
8
|
+
gem install memo_rage
|
9
|
+
|
10
|
+
## How to use it? ##
|
11
|
+
|
12
|
+
First you have to create a client with your api key
|
13
|
+
|
14
|
+
client = MemoRage::Client.new(:key => "abcd1234")
|
15
|
+
|
16
|
+
You can search tv shows with
|
17
|
+
|
18
|
+
client.search("NAME OF THE TV SHOW")
|
19
|
+
|
20
|
+
Get show info with
|
21
|
+
|
22
|
+
client.show_info("THE ID OF THE SHOW")
|
23
|
+
|
24
|
+
Get show episode list
|
25
|
+
|
26
|
+
client.episode_list("THE ID OF THE SHOW")
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module MemoRage
|
2
|
+
class Client
|
3
|
+
attr_reader :params
|
4
|
+
|
5
|
+
def initialize(options)
|
6
|
+
@params = { :key => options[:key] }
|
7
|
+
end
|
8
|
+
|
9
|
+
def search(query)
|
10
|
+
content = get("search", { :show => query })
|
11
|
+
parser = MemoRage::Parser::ShowSearch.new content
|
12
|
+
parser.parse
|
13
|
+
end
|
14
|
+
|
15
|
+
def show_info(id)
|
16
|
+
content = get("showinfo", { :sid => id })
|
17
|
+
parser = MemoRage::Parser::ShowInfo.new content
|
18
|
+
parser.parse
|
19
|
+
end
|
20
|
+
|
21
|
+
def episode_list(id)
|
22
|
+
content = get("episode_list", { :sid => id })
|
23
|
+
parser = MemoRage::Parser::EpisodeList.new content
|
24
|
+
parser.parse
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
def get(path, params = {})
|
29
|
+
HTTPClient.get build_endpoint(path), build_params(params)
|
30
|
+
end
|
31
|
+
|
32
|
+
def build_params(params = {})
|
33
|
+
@params.merge(params)
|
34
|
+
end
|
35
|
+
|
36
|
+
def build_endpoint(path)
|
37
|
+
File.join(MemoRage::ROOT_URL, "#{path}.php")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module MemoRage
|
2
|
+
module Parser
|
3
|
+
class Base
|
4
|
+
def initialize(content)
|
5
|
+
@content = content
|
6
|
+
end
|
7
|
+
|
8
|
+
def parse
|
9
|
+
parse_content @content
|
10
|
+
end
|
11
|
+
|
12
|
+
def form_array(entry)
|
13
|
+
output = []
|
14
|
+
entry.elements.each do |text|
|
15
|
+
output << text.text
|
16
|
+
end
|
17
|
+
output
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module MemoRage
|
2
|
+
module Parser
|
3
|
+
class EpisodeList < Base
|
4
|
+
def parse_content(content)
|
5
|
+
doc = REXML::Document.new(content.body)
|
6
|
+
list = doc.elements["Show"]
|
7
|
+
|
8
|
+
unless list == "0"
|
9
|
+
parse_entry(list)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def parse_entry(entry)
|
14
|
+
episodes = []
|
15
|
+
season_number = 0
|
16
|
+
entry.elements["Episodelist"].elements.each("Season") do |season|
|
17
|
+
season_number += 1
|
18
|
+
season.elements.each("episode") do |episode|
|
19
|
+
if episode.elements["screencap"] == nil
|
20
|
+
missing = episode.add_element "screencap"
|
21
|
+
missing.add_text ""
|
22
|
+
end
|
23
|
+
episodes << MemoRage::Episode.new(
|
24
|
+
:num => episode.elements["epnum"].text,
|
25
|
+
:season => season_number,
|
26
|
+
:season_num => episode.elements["seasonnum"].text,
|
27
|
+
:prod_num => episode.elements["prodnum"].text,
|
28
|
+
:airdate => episode.elements["airdate"].text,
|
29
|
+
:link => episode.elements["link"].text,
|
30
|
+
:title => episode.elements["title"].text,
|
31
|
+
:rating => episode.elements["rating"].text,
|
32
|
+
:image => episode.elements["screencap"].text
|
33
|
+
)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
MemoRage::Show.new(
|
37
|
+
:name => entry.elements["name"].text,
|
38
|
+
:seasons => entry.elements["totalseasons"].text.to_i,
|
39
|
+
:episodes => episodes
|
40
|
+
)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module MemoRage
|
2
|
+
module Parser
|
3
|
+
class ShowInfo < Base
|
4
|
+
def parse_content(content)
|
5
|
+
doc = REXML::Document.new(content.body)
|
6
|
+
showinfo = doc.elements["Showinfo"]
|
7
|
+
|
8
|
+
unless showinfo == "0"
|
9
|
+
parse_entry(showinfo)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def parse_entry(entry)
|
14
|
+
MemoRage::Show.new(
|
15
|
+
:id => entry.elements["showid"].text.to_i,
|
16
|
+
:name => entry.elements["showname"].text,
|
17
|
+
:link => entry.elements["showlink"].text,
|
18
|
+
:seasons => entry.elements["seasons"].text.to_i,
|
19
|
+
:image => entry.elements["image"].text,
|
20
|
+
:started => entry.elements["started"].text,
|
21
|
+
:ended => entry.elements["ended"].text,
|
22
|
+
:origin_country => entry.elements["origin_country"].text,
|
23
|
+
:status => entry.elements["status"].text,
|
24
|
+
:classification => entry.elements["classification"].text,
|
25
|
+
:genres => form_array(entry.elements["genres"]),
|
26
|
+
:runtime => entry.elements["runtime"].text.to_i,
|
27
|
+
:airtime => entry.elements["airtime"].text,
|
28
|
+
:airday => entry.elements["airday"].text,
|
29
|
+
:timezone => entry.elements["timezone"].text,
|
30
|
+
:akas => form_array(entry.elements["akas"])
|
31
|
+
)
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module MemoRage
|
2
|
+
module Parser
|
3
|
+
class ShowSearch < Base
|
4
|
+
def parse_content(content)
|
5
|
+
doc = REXML::Document.new(content.body)
|
6
|
+
results = doc.elements["Results"]
|
7
|
+
|
8
|
+
shows = []
|
9
|
+
unless results == "0"
|
10
|
+
results.elements.each("show") do |show|
|
11
|
+
shows << parse_entry(show)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
shows
|
16
|
+
end
|
17
|
+
|
18
|
+
def parse_entry(entry)
|
19
|
+
MemoRage::Show.new(
|
20
|
+
:id => entry.elements["showid"].text.to_i,
|
21
|
+
:name => entry.elements["name"].text
|
22
|
+
)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module MemoRage
|
2
|
+
class Show < Node
|
3
|
+
attr_reader :id
|
4
|
+
attr_reader :name
|
5
|
+
attr_reader :link
|
6
|
+
attr_reader :seasons
|
7
|
+
attr_reader :image
|
8
|
+
attr_reader :started
|
9
|
+
attr_reader :ended
|
10
|
+
attr_reader :startdate
|
11
|
+
attr_reader :origin_country
|
12
|
+
attr_reader :status
|
13
|
+
attr_reader :classification
|
14
|
+
attr_reader :runtime
|
15
|
+
attr_reader :airtime
|
16
|
+
attr_reader :airday
|
17
|
+
attr_reader :timezone
|
18
|
+
attr_reader :seasons
|
19
|
+
|
20
|
+
attr_reader :genres # Array
|
21
|
+
attr_reader :akas # Array
|
22
|
+
attr_reader :episodes # Array
|
23
|
+
end
|
24
|
+
end
|
data/lib/memo_rage.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require "httpclient"
|
2
|
+
require "rexml/document"
|
3
|
+
require "memo_rage/version"
|
4
|
+
|
5
|
+
module MemoRage
|
6
|
+
ROOT_URL = "http://services.tvrage.com/myfeeds"
|
7
|
+
end
|
8
|
+
|
9
|
+
require "memo_rage/node"
|
10
|
+
require "memo_rage/show"
|
11
|
+
require "memo_rage/episode"
|
12
|
+
require "memo_rage/client"
|
13
|
+
require "memo_rage/parser"
|
data/memo_rage.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "memo_rage/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "memo_rage"
|
7
|
+
s.version = MemoRage::VERSION
|
8
|
+
s.authors = ["Alex Ganov", "Todor Grudev"]
|
9
|
+
s.email = ["aganov@gmail.com", "tagrudev@gmail.com"]
|
10
|
+
s.homepage = ""
|
11
|
+
s.summary = %q{Memo rage is an api wrapper for the http://services.tvrage.com/ The gem is created to fulfil the needs of the project http://watchmemo.com}
|
12
|
+
s.description = %q{Find more information at https://github.com/appsbakery/memo_rage}
|
13
|
+
|
14
|
+
s.rubyforge_project = "memo_rage"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
s.add_runtime_dependency "httpclient", ">= 2.2.0.2"
|
21
|
+
s.add_runtime_dependency "hashie", ">= 1.1.0"
|
22
|
+
s.add_development_dependency "rake", ">= 0.8.7"
|
23
|
+
s.add_development_dependency "rspec", ">= 2"
|
24
|
+
s.add_development_dependency "webmock", ">= 1.6.2"
|
25
|
+
s.add_development_dependency "timecop", ">= 0.3.5"
|
26
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'webmock/rspec'
|
2
|
+
|
3
|
+
module WebMockHelper
|
4
|
+
|
5
|
+
# Mock http request with webmock
|
6
|
+
#
|
7
|
+
# @param [Symbol] method http method
|
8
|
+
# @param [String] path endpoint path
|
9
|
+
# @param [String] response_file json response file name/path
|
10
|
+
# @param [Hash] options optional options params
|
11
|
+
def mock_api(method, path, response_file, options = {})
|
12
|
+
stub_request(method, endpoint_for(path)).with(
|
13
|
+
request_for(method, options)
|
14
|
+
).to_return(
|
15
|
+
response_for(response_file, options)
|
16
|
+
)
|
17
|
+
|
18
|
+
yield
|
19
|
+
end
|
20
|
+
|
21
|
+
# Load json response file and return its content
|
22
|
+
#
|
23
|
+
# @param [String] response_file json response file name/path
|
24
|
+
# @return [String]
|
25
|
+
def load_json(response_file)
|
26
|
+
File.new(File.join(File.dirname(__FILE__), '../mock_xml', "#{response_file}.xml"))
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
# Get final url for specific endpoint
|
32
|
+
#
|
33
|
+
# @param [String] path is the endpoint path ex: `showinfo`
|
34
|
+
# @return [String] the formatted endpoint, if anonymize is enabled prefixed with anonymous
|
35
|
+
def endpoint_for(path)
|
36
|
+
File.join(MemoRage::ROOT_URL, "#{path}.php")
|
37
|
+
end
|
38
|
+
|
39
|
+
# Prepare request params for HTTPClient
|
40
|
+
#
|
41
|
+
# @param [Symbol] http method
|
42
|
+
# @param [Hash] options like params, etc
|
43
|
+
# @return [Hash] formatted http request hash
|
44
|
+
def request_for(method, options = {})
|
45
|
+
request = {}
|
46
|
+
if options[:params]
|
47
|
+
case method
|
48
|
+
when :post, :put
|
49
|
+
request[:body] = options[:params]
|
50
|
+
else
|
51
|
+
request[:query] = options[:params]
|
52
|
+
end
|
53
|
+
end
|
54
|
+
request
|
55
|
+
end
|
56
|
+
|
57
|
+
# Build response hash for HTTPClient
|
58
|
+
#
|
59
|
+
# @param [String] response_file json response file name/path
|
60
|
+
# @param [Hash] options like status, etc
|
61
|
+
# @return [Hash] formatted http response hash
|
62
|
+
def response_for(response_file, options = {})
|
63
|
+
response = {}
|
64
|
+
response[:body] = load_json(response_file)
|
65
|
+
if options[:status]
|
66
|
+
response[:status] = options[:status]
|
67
|
+
end
|
68
|
+
response
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
include WebMockHelper
|
73
|
+
WebMock.disable_net_connect!
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
|
2
|
+
|
3
|
+
describe MemoRage::Client do
|
4
|
+
let(:client) { MemoRage::Client.new(:key => 'abcd1234') }
|
5
|
+
|
6
|
+
describe '#build_params' do
|
7
|
+
it 'should merge provided params with api key' do
|
8
|
+
params = client.send :build_params, { :show => 'buffy' }
|
9
|
+
params[:key].should == 'abcd1234'
|
10
|
+
params[:show].should == 'buffy'
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe '#build_endpoint' do
|
15
|
+
it 'should merge path with root url' do
|
16
|
+
client.send(:build_endpoint, 'search').should == "http://services.tvrage.com/myfeeds/search.php"
|
17
|
+
client.send(:build_endpoint, 'showinfo').should == "http://services.tvrage.com/myfeeds/showinfo.php"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper")
|
2
|
+
|
3
|
+
describe MemoRage::Parser::EpisodeList do
|
4
|
+
let(:client) { MemoRage::Client.new(:key => "abcd1234") }
|
5
|
+
|
6
|
+
it 'should be awesome' do
|
7
|
+
mock_api :get, 'episode_list', 'episode_list', :params => client.params.merge(:sid => "2930") do
|
8
|
+
list = client.episode_list("2930")
|
9
|
+
list.name.should == "Buffy the Vampire Slayer"
|
10
|
+
list.seasons.should == 7
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper")
|
4
|
+
|
5
|
+
describe MemoRage::Parser::ShowInfo do
|
6
|
+
let(:client) { MemoRage::Client.new(:key => "abcd1234") }
|
7
|
+
|
8
|
+
it 'should be awesome' do
|
9
|
+
mock_api :get, 'showinfo', 'show_info', :params => client.params.merge(:sid => "2930") do
|
10
|
+
show = client.show_info("2930")
|
11
|
+
show.id.should == 2930
|
12
|
+
show.name.should == "Buffy the Vampire Slayer"
|
13
|
+
show.link.should == "http://www.tvrage.com/Buffy_The_Vampire_Slayer"
|
14
|
+
show.seasons.should == 7
|
15
|
+
show.image.should == "http://images.tvrage.com/shows/3/2930.jpg"
|
16
|
+
show.started.should == "1997"
|
17
|
+
show.origin_country.should == "US"
|
18
|
+
show.status.should == "Canceled/Ended"
|
19
|
+
show.classification.should == "Scripted"
|
20
|
+
show.genres.should =~ [ "Action", "Adventure", "Comedy", "Drama", "Mystery", "Sci-Fi" ]
|
21
|
+
show.runtime.should == 60
|
22
|
+
show.airtime.should == "20:00"
|
23
|
+
show.airday.should == "Tuesday"
|
24
|
+
show.timezone == "GMT-5 -DST"
|
25
|
+
show.akas =~ [ "Buffy & vampyrerna", "Buffy - Im Bann der Dämonen", "Buffy - Vampyrenes skrekk", "Buffy a vámpírok réme", "Buffy Contre les Vampires", "Buffy l'Ammazza Vampiri", "Buffy postrach wampirów", "Buffy, a Caça-Vampiros", "Buffy, a Caçadora de Vampiros", "Buffy, Cazavampiros", "Buffy, ubojica vampira", "Buffy, vampyyrintappaja", "Vampiiritapja Buffy", "Vampírubaninn Buffy" ]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper")
|
2
|
+
|
3
|
+
describe MemoRage::Parser::ShowSearch do
|
4
|
+
let(:client) { MemoRage::Client.new(:key => "abcd1234") }
|
5
|
+
|
6
|
+
it 'should be awesome' do
|
7
|
+
mock_api :get, 'search', 'show_search', :params => client.params.merge(:show => "buffy") do
|
8
|
+
show = client.search("buffy").first
|
9
|
+
show.id.should == 2930
|
10
|
+
show.name.should == "Buffy the Vampire Slayer"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|