ann_wrapper 1.1.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.
- 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: []
|