memo_rage 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|