ann_wrapper 1.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/bin/example +59 -0
- data/lib/ann_wrapper.rb +71 -0
- data/lib/ann_wrapper/ann_objects.rb +150 -0
- metadata +47 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 20fb6fdc088155e3d21d55bdd957fe895863f6ea
|
4
|
+
data.tar.gz: e7e94ec1418f697cdc0764495fdcd31a0ad962e7
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 32aac6ddb361a0dc399cc1cb3df6e28be891c42d08e5f5447bddec6ee27877641f1288205869073de2fbfdc4853c1cd81135b7928ad8fc40703c8142655f1b05
|
7
|
+
data.tar.gz: ba760c4c2e2e4c7ffd9c784c3fdca0cc3581aef517a4e99b2ce536736df3c53fdfe3ccb5948eede7d3c812ac8f7ea1ef210a44dcab317f5f46638902860045e2
|
data/bin/example
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
##########################################
|
4
|
+
#
|
5
|
+
# Example usage of ANN wrapper and methods
|
6
|
+
#
|
7
|
+
##########################################
|
8
|
+
|
9
|
+
require 'ann_wrapper'
|
10
|
+
|
11
|
+
if ARGV.size < 1
|
12
|
+
puts "Usage: example <ann anime id>"
|
13
|
+
exit
|
14
|
+
end
|
15
|
+
|
16
|
+
def show(obj, method)
|
17
|
+
puts "#{method}: #{obj.send(method).to_s}"
|
18
|
+
end
|
19
|
+
|
20
|
+
begin
|
21
|
+
# create ANN API Wrapper instance
|
22
|
+
anime = ANN_Wrapper.instance.fetch_ann_anime(ARGV[0])
|
23
|
+
|
24
|
+
if anime.is_a?(ANN_Error)
|
25
|
+
puts anime.message
|
26
|
+
exit(1)
|
27
|
+
end
|
28
|
+
|
29
|
+
#demo
|
30
|
+
show anime, :title
|
31
|
+
show anime, :alt_titles
|
32
|
+
show anime, :type
|
33
|
+
# show anime, :synopsis
|
34
|
+
show anime, :num_episodes
|
35
|
+
show anime, :genres
|
36
|
+
show anime, :themes
|
37
|
+
# show anime, :op_theme
|
38
|
+
# show anime, :ed_theme
|
39
|
+
# show anime, :episodes
|
40
|
+
# show anime, :staff
|
41
|
+
# show anime, :cast
|
42
|
+
# show anime, :images
|
43
|
+
|
44
|
+
#titles = ANN_Wrapper.instance.fetch_titles("anime", 0, 5)
|
45
|
+
#if titles.is_a?(ANN_Error)
|
46
|
+
# puts titles.message
|
47
|
+
# exit(1)
|
48
|
+
#end
|
49
|
+
#
|
50
|
+
#titles.each do |title|
|
51
|
+
# puts title.id
|
52
|
+
#end
|
53
|
+
#
|
54
|
+
rescue
|
55
|
+
puts "oops"
|
56
|
+
|
57
|
+
# print last exception and backtrace
|
58
|
+
puts $!.inspect, $@
|
59
|
+
end
|
data/lib/ann_wrapper.rb
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
##################################################
|
2
|
+
# ANN_Wrapper
|
3
|
+
##################################################
|
4
|
+
|
5
|
+
require "net/http"
|
6
|
+
require "nokogiri"
|
7
|
+
require 'ann_wrapper/ann_objects'
|
8
|
+
require 'singleton'
|
9
|
+
|
10
|
+
# wrapper class for ANN API
|
11
|
+
class ANN_Wrapper
|
12
|
+
include Singleton
|
13
|
+
# ANN API anime url
|
14
|
+
ANN_URL = "http://cdn.animenewsnetwork.com/encyclopedia"
|
15
|
+
ANN_API_URL = "#{ANN_URL}/api.xml"
|
16
|
+
ANN_REPORTS_URL = "#{ANN_URL}/reports.xml"
|
17
|
+
|
18
|
+
# fetch data from ANN API via http GET request
|
19
|
+
# returns Nokogiri or ANN_Error
|
20
|
+
def fetch(url)
|
21
|
+
begin
|
22
|
+
# send http GET request with uri parsed from url
|
23
|
+
resp = Net::HTTP.get_response(URI.parse(url))
|
24
|
+
|
25
|
+
# get the response body and try converting to Nokogiri object
|
26
|
+
Nokogiri.XML(resp.body)
|
27
|
+
rescue
|
28
|
+
ANN_Error.new("xml format error, API likely unavailable")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# attempt to grab error message from XMLObject
|
33
|
+
def get_xml_error(xobj)
|
34
|
+
begin
|
35
|
+
xobj.at_xpath('//ann/warning').content
|
36
|
+
rescue NameError
|
37
|
+
"bad response"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# fetch anime and convert to ANN_Anime
|
42
|
+
def fetch_ann_anime(id)
|
43
|
+
# append id to API url and send request
|
44
|
+
url = "#{ANN_API_URL}?anime=#{id.to_s}"
|
45
|
+
|
46
|
+
ann = fetch(url)
|
47
|
+
|
48
|
+
return ann if ann.is_a?(ANN_Error)
|
49
|
+
|
50
|
+
anime = ann.at_xpath('//ann/anime')
|
51
|
+
|
52
|
+
# initialize new ann_anime or error with ann object
|
53
|
+
anime.nil? ? ANN_Error.new(get_xml_error(ann)) : ANN_Anime.new(anime)
|
54
|
+
end
|
55
|
+
|
56
|
+
# fetch list of titles via reports
|
57
|
+
def fetch_titles(type="anime", nskip=0, nlist=50, name="")
|
58
|
+
url = "#{ANN_REPORTS_URL}?id=155&type=#{type}&nskip=#{nskip}&nlist=#{nlist}"
|
59
|
+
report = fetch(url)
|
60
|
+
|
61
|
+
return report if report.is_a?(ANN_Error)
|
62
|
+
|
63
|
+
reports = report.xpath('//report/item')
|
64
|
+
|
65
|
+
return ANN_Error.new(get_xml_error(report)) if reports.nil?
|
66
|
+
|
67
|
+
reports.map do |item|
|
68
|
+
ANN_Report.new(item)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,150 @@
|
|
1
|
+
##################################################
|
2
|
+
# ANN_Objects
|
3
|
+
##################################################
|
4
|
+
|
5
|
+
# parent with helper methods
|
6
|
+
class ANN
|
7
|
+
private
|
8
|
+
# define method with supplied name and block
|
9
|
+
def create_method(name, &block)
|
10
|
+
self.class.send(:define_method, name, &block)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# various ANN struct types
|
15
|
+
ANN_Error = Struct.new(:message)
|
16
|
+
ANN_Staff = Struct.new(:id, :task, :name)
|
17
|
+
ANN_Cast = Struct.new(:id, :role, :name, :lang)
|
18
|
+
ANN_Episode = Struct.new(:number, :title, :lang)
|
19
|
+
ANN_Image = Struct.new(:src, :width, :height)
|
20
|
+
|
21
|
+
class ANN_Anime < ANN
|
22
|
+
# ann_anime Nokogiri object
|
23
|
+
attr_writer :ann_anime
|
24
|
+
|
25
|
+
# initialize and create info methods
|
26
|
+
def initialize(ann_anime)
|
27
|
+
@ann_anime = ann_anime
|
28
|
+
|
29
|
+
# information available from detail
|
30
|
+
@info = Hash.new
|
31
|
+
@info[:title] = "Main title"
|
32
|
+
@info[:synopsis] = "Plot Summary"
|
33
|
+
@info[:num_episodes] = "Number of episodes"
|
34
|
+
@info[:genres] = "Genres"
|
35
|
+
@info[:themes] = "Themes"
|
36
|
+
@info[:vintage] = "Vintage"
|
37
|
+
@info[:op_theme] = "Opening Theme"
|
38
|
+
@info[:ed_theme] = "Ending Theme"
|
39
|
+
|
40
|
+
# create methods
|
41
|
+
@info.each do |name, key|
|
42
|
+
create_method(name) do
|
43
|
+
info = find_info(key)
|
44
|
+
return nil if info.nil?
|
45
|
+
info.map do |i|
|
46
|
+
i.content
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
# return all info with provided key
|
54
|
+
def find_info(key)
|
55
|
+
begin
|
56
|
+
@ann_anime.search("info[@type=\"#{key}\"]")
|
57
|
+
rescue
|
58
|
+
nil
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# returns array of titles grouped by language abbreviation
|
63
|
+
def alt_titles
|
64
|
+
begin
|
65
|
+
titles = find_info("Alternative title").group_by {|title| title['lang']}
|
66
|
+
|
67
|
+
titles.each do |key, value|
|
68
|
+
value.map! do |title|
|
69
|
+
title.content
|
70
|
+
end
|
71
|
+
end
|
72
|
+
rescue NameError
|
73
|
+
nil
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def type
|
78
|
+
@type ||= @ann_anime['type']
|
79
|
+
end
|
80
|
+
|
81
|
+
# returns array of ANN_Image
|
82
|
+
def images
|
83
|
+
begin
|
84
|
+
@images ||= find_info("Picture").map do |i|
|
85
|
+
ANN_Image.new(i['src'], i['width'], i['height'])
|
86
|
+
end
|
87
|
+
rescue NameError
|
88
|
+
nil
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
# returns array of ANN_Episode
|
93
|
+
def episodes
|
94
|
+
begin
|
95
|
+
@episodes ||= @ann_anime.xpath("//episode").map do |e|
|
96
|
+
title = e.at_xpath("title")
|
97
|
+
ANN_Episode.new(e['num'], title.content, title['lang'])
|
98
|
+
end
|
99
|
+
rescue NameError
|
100
|
+
nil
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# returns array of ANN_Staff
|
105
|
+
def staff
|
106
|
+
begin
|
107
|
+
@staff ||= @ann_anime.xpath("//staff").map do |s|
|
108
|
+
task = s.at_xpath("task")
|
109
|
+
person = s.at_xpath("person")
|
110
|
+
ANN_Staff.new(person['id'], task.content, person.content)
|
111
|
+
end
|
112
|
+
rescue NameError
|
113
|
+
nil
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
# returns array of ANN_Cast
|
118
|
+
def cast
|
119
|
+
begin
|
120
|
+
@cast ||= @ann_anime.xpath("//cast").map do |s|
|
121
|
+
role = s.at_xpath("role")
|
122
|
+
person = s.at_xpath("person")
|
123
|
+
ANN_Cast.new(person['id'], role.content, person.content, s['lang'])
|
124
|
+
end
|
125
|
+
rescue NameError
|
126
|
+
nil
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
class ANN_Report < ANN
|
132
|
+
# initialize and build access methods
|
133
|
+
def initialize(ann_report)
|
134
|
+
@id, @type, @name, @precision, @vintage = ""
|
135
|
+
|
136
|
+
self.instance_variables.each do |iv|
|
137
|
+
var_name = iv.to_s.partition("@").last
|
138
|
+
create_method(var_name) { get_info_on(ann_report, var_name) }
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
# get info from xml
|
143
|
+
def get_info_on(ann_report, var_name)
|
144
|
+
begin
|
145
|
+
ann_report.at_xpath(var_name).content
|
146
|
+
rescue NameError
|
147
|
+
nil
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
metadata
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ann_wrapper
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- getkura
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-01-07 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: A simple wrapper for the Anime News Network API
|
14
|
+
email: getkura+ann_wrapper@gmail.com
|
15
|
+
executables:
|
16
|
+
- example
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- lib/ann_wrapper.rb
|
21
|
+
- lib/ann_wrapper/ann_objects.rb
|
22
|
+
- bin/example
|
23
|
+
homepage: http://rubygems.org/gems/ann_wrapper
|
24
|
+
licenses:
|
25
|
+
- MIT
|
26
|
+
metadata: {}
|
27
|
+
post_install_message:
|
28
|
+
rdoc_options: []
|
29
|
+
require_paths:
|
30
|
+
- lib
|
31
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
32
|
+
requirements:
|
33
|
+
- - ">="
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: '0'
|
36
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
requirements: []
|
42
|
+
rubyforge_project:
|
43
|
+
rubygems_version: 2.0.3
|
44
|
+
signing_key:
|
45
|
+
specification_version: 4
|
46
|
+
summary: Anime News Network API wrapper
|
47
|
+
test_files: []
|