ann_wrapper 1.1.4 → 1.1.5
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 +1 -1
- data/Gemfile +3 -0
- data/README.md +81 -31
- data/ann_wrapper.gemspec +1 -1
- data/lib/ann_wrapper.rb +47 -14
- data/lib/ann_wrapper/ann.rb +44 -0
- data/lib/ann_wrapper/ann_anime.rb +85 -0
- data/lib/ann_wrapper/ann_manga.rb +63 -0
- data/lib/ann_wrapper/ann_media.rb +67 -0
- data/lib/ann_wrapper/ann_report.rb +26 -0
- data/lib/ann_wrapper/version.rb +1 -1
- data/spec/ann_anime_spec.rb +64 -94
- data/spec/ann_manga_spec.rb +109 -0
- data/spec/ann_report_spec.rb +62 -0
- data/spec/ann_wrapper_spec.rb +128 -14
- data/spec/spec_helper.rb +8 -1
- data/spec/support/fake_ann.rb +17 -1
- data/spec/support/fixtures/anime_batch.xml +884 -0
- data/spec/support/fixtures/anime_batch_with_invalid.xml +248 -0
- data/spec/support/fixtures/invalid_warning.xml +3 -0
- data/spec/support/fixtures/list_report.xml +47 -0
- data/spec/support/fixtures/manga_batch.xml +92 -0
- data/spec/support/fixtures/manga_batch_with_invalid.xml +55 -0
- data/spec/support/fixtures/steins_gate.xml +34 -12
- data/spec/support/fixtures/tokyo_ghoul.xml +60 -0
- metadata +27 -5
- data/lib/ann_wrapper/ann_objects.rb +0 -217
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3a9e7afef7ed3479ae7b65cd78990ac4ec590094
|
4
|
+
data.tar.gz: 9ac1f2658558da468d3c3bd36aa83827d989baf8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 033dc1f439ea2110322bd23366a51377fb550e691ea4f1adf00e327b0d2b26db677029dc37d1813fe621e908bb33747fc8a08203126d42d048e67c50cb72be61
|
7
|
+
data.tar.gz: 12606ade1ae66a7a131fb80eff2eeaab8f7ea90a4eeb7dccb5fafcc2f7981e222a160e458d89d620cb6effaba2bdfcdfba5da3c712ec6cb350310541c3c72ab7
|
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -4,8 +4,8 @@
|
|
4
4
|
[](http://badge.fury.io/rb/ann_wrapper)
|
5
5
|
[](https://travis-ci.org/Getkura/ann_wrapper)
|
6
6
|
[](https://gemnasium.com/Getkura/ann_wrapper)
|
7
|
-
[](https://codeclimate.com/github/Getkura/ann_wrapper)
|
8
|
+
[](https://coveralls.io/r/Getkura/ann_wrapper?branch=dev)
|
9
9
|
|
10
10
|
A simple ruby wrapper/abstraction for the [Anime News Network API](http://www.animenewsnetwork.com/encyclopedia/api.php)
|
11
11
|
|
@@ -25,82 +25,132 @@ Or install it yourself as:
|
|
25
25
|
|
26
26
|
## Usage
|
27
27
|
|
28
|
-
Fetch an anime:
|
28
|
+
###Fetch an anime:
|
29
|
+
|
30
|
+
anime = ANN_Wrapper.fetch_anime "id"
|
31
|
+
anime.title
|
32
|
+
anime.alt_titles
|
33
|
+
anime.synopsis
|
34
|
+
anime.num_episodes
|
35
|
+
anime.genres
|
36
|
+
anime.themes
|
37
|
+
anime.vintage
|
38
|
+
anime.op_theme
|
39
|
+
anime.ed_theme
|
40
|
+
anime.id
|
41
|
+
anime.type
|
42
|
+
anime.ratings
|
43
|
+
anime.episodes
|
44
|
+
anime.staff
|
45
|
+
anime.cast
|
46
|
+
anime.images
|
47
|
+
anime.to_h
|
48
|
+
|
49
|
+
####Example:
|
29
50
|
|
30
51
|
steins_gate = ANN_Wrapper.fetch_anime 11770
|
31
52
|
|
32
|
-
Info:
|
33
|
-
|
53
|
+
#####Info:
|
54
|
+
|
34
55
|
steins_gate.id
|
35
56
|
=> "11770"
|
36
|
-
|
57
|
+
|
37
58
|
steins_gate.title
|
38
59
|
=> ["Steins;Gate"]
|
39
|
-
|
60
|
+
|
40
61
|
steins_gate.alt_titles
|
41
62
|
=> {"PT"=>["Steins-Gate e a Teoria do Caos"], "JA"=>["シュタインズ・ゲート"], "ZH-TW"=>["命運石之門"], "KO"=>["슈타인즈 게이트"]}
|
42
63
|
|
43
64
|
steins_gate.synopsis
|
44
65
|
=> ["Rintaro Okabe is a self-proclaimed "mad scientist" ... "]
|
45
|
-
|
66
|
+
|
46
67
|
steins_gate.num_episodes
|
47
68
|
=> ["24"]
|
48
|
-
|
69
|
+
|
49
70
|
steins_gate.vintage
|
50
71
|
=> ["2011-04-03 (Advanced screening)", "2011-04-05 to 2011-09-13"]
|
51
|
-
|
72
|
+
|
52
73
|
steins_gate.genres
|
53
74
|
=> ["adventure", "comedy", "drama", "mystery", "psychological", "romance", "science fiction", "thriller"]
|
54
|
-
|
75
|
+
|
55
76
|
steins_gate.themes
|
56
77
|
=> ["butterfly effect", "conspiracy", "technology", "Time travel"]
|
57
|
-
|
78
|
+
|
58
79
|
steins_gate.op_theme
|
59
80
|
=> ["\"Hacking to the Gate\" by Kanako Ito"]
|
60
|
-
|
81
|
+
|
61
82
|
steins_gate.ed_theme
|
62
83
|
=> ["\"Tokitsukasadoru Jūni no Meiyaku\" (刻司ル十二ノ盟約) by Yui Sakakibara", "#2: \"Sukai Kuraddo no Kansokusha\" (スカイクラッドの観測者) by Kanako Ito (ep 23)", "#3: \"Another Heaven\" by Kanako Itou (ep 24)"]
|
63
84
|
|
64
85
|
|
65
|
-
Cast and Staff:
|
66
|
-
|
86
|
+
#####Cast and Staff:
|
87
|
+
|
67
88
|
steins_gate.cast.find_all {|c| c.name.include? "Hanazawa"}
|
68
89
|
=> [#<struct ANN_Cast id="53741", role="Mayuri Shiina", name="Kana Hanazawa", lang="JA">]
|
69
|
-
|
90
|
+
|
70
91
|
steins_gate.staff.find_all {|s| s.task.eql? "Director"}
|
71
92
|
=> [
|
72
|
-
#<struct ANN_Staff id="593", task="Director", name="Takuya Satō">,
|
73
|
-
#<struct ANN_Staff id="9693", task="Director", name="Hiroshi Hamasaki">,
|
93
|
+
#<struct ANN_Staff id="593", task="Director", name="Takuya Satō">,
|
94
|
+
#<struct ANN_Staff id="9693", task="Director", name="Hiroshi Hamasaki">,
|
74
95
|
#<struct ANN_Staff id="35713", task="Director", name="Tomoki Kobayashi">
|
75
96
|
]
|
76
97
|
|
77
98
|
|
78
|
-
Episodes:
|
99
|
+
#####Episodes:
|
79
100
|
|
80
101
|
steins_gate.episodes.find_all {|e| e.title.include? "Prologue"}
|
81
102
|
=> [
|
82
|
-
#<struct ANN_Episode number="1", title="Prologue of the Beginning and End", lang="EN">,
|
103
|
+
#<struct ANN_Episode number="1", title="Prologue of the Beginning and End", lang="EN">,
|
83
104
|
#<struct ANN_Episode number="24", title="The Prologue Begins With the End", lang="EN">
|
84
105
|
]
|
85
|
-
|
106
|
+
|
86
107
|
steins_gate.episodes.first.to_h
|
87
108
|
=> {:number=>"1", :title=>"Prologue of the Beginning and End", :lang=>"EN"}
|
88
|
-
|
89
|
-
Images:
|
109
|
+
|
110
|
+
#####Images:
|
90
111
|
|
91
112
|
steins_gate.images
|
92
113
|
=> [
|
93
|
-
#<struct ANN_Image src="http://cdn.animenewsnetwork.com/thumbnails/fit200x200/encyc/A11770-1864351140.1370764886.jpg", width="200", height="125">,
|
94
|
-
#<struct ANN_Image src="http://cdn.animenewsnetwork.com/thumbnails/max500x600/encyc/A11770-1864351140.1370764886.jpg", width="500", height="312">,
|
95
|
-
#<struct ANN_Image src="http://cdn.animenewsnetwork.com/images/encyc/A11770-1864351140.1370764886.jpg", width="900", height="562">,
|
96
|
-
#<struct ANN_Image src="http://cdn.animenewsnetwork.com/thumbnails/fit200x200/encyc/A11770-8.jpg", width="200", height="200">,
|
114
|
+
#<struct ANN_Image src="http://cdn.animenewsnetwork.com/thumbnails/fit200x200/encyc/A11770-1864351140.1370764886.jpg", width="200", height="125">,
|
115
|
+
#<struct ANN_Image src="http://cdn.animenewsnetwork.com/thumbnails/max500x600/encyc/A11770-1864351140.1370764886.jpg", width="500", height="312">,
|
116
|
+
#<struct ANN_Image src="http://cdn.animenewsnetwork.com/images/encyc/A11770-1864351140.1370764886.jpg", width="900", height="562">,
|
117
|
+
#<struct ANN_Image src="http://cdn.animenewsnetwork.com/thumbnails/fit200x200/encyc/A11770-8.jpg", width="200", height="200">,
|
97
118
|
#<struct ANN_Image src="http://cdn.animenewsnetwork.com/thumbnails/max500x600/encyc/A11770-8.jpg", width="317", height="317">
|
98
119
|
]
|
120
|
+
|
121
|
+
#####Ratings:
|
99
122
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
123
|
+
steings_gate.ratings
|
124
|
+
=> [
|
125
|
+
#<struct ANN_Rating votes="3788", weighted="9.1129", bayesian_score="9.1075">
|
126
|
+
]
|
127
|
+
|
128
|
+
###Fetch a manga:
|
129
|
+
|
130
|
+
Fetching a manga works exactly the same as an anime, but you should call the `fetch_manga` method.
|
131
|
+
|
132
|
+
manga = ANN_Wrapper.fetch_manga "id"
|
133
|
+
manga.title
|
134
|
+
manga.alt_titles
|
135
|
+
manga.synopsis
|
136
|
+
manga.genres
|
137
|
+
manga.vintage
|
138
|
+
manga.themes
|
139
|
+
manga.num_tankoubon
|
140
|
+
manga.num_pages
|
141
|
+
manga.id
|
142
|
+
manga.type
|
143
|
+
manga.staff
|
144
|
+
manga.ratings
|
145
|
+
manga.images
|
146
|
+
manga.to_h
|
147
|
+
|
148
|
+
###Batching:
|
149
|
+
Send any number of ids in an array for a batch request.
|
150
|
+
This will return an array of ANN_Anime or ANN_Manga objects.
|
151
|
+
|
152
|
+
anime = ANN_Wrapper.batch_anime(["id_1", "id_2", "id_3", ...])
|
153
|
+
manga = ANN_Wrapper.batch_manga(["id_1", "id_2", "id_3", ...])
|
104
154
|
|
105
155
|
## Contributing
|
106
156
|
|
data/ann_wrapper.gemspec
CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
|
|
10
10
|
spec.email = ["getkura+ann_wrapper@gmail.com"]
|
11
11
|
spec.description = 'A simple wrapper for the Anime News Network API'
|
12
12
|
spec.summary = 'Anime News Network API wrapper'
|
13
|
-
spec.homepage = "http://
|
13
|
+
spec.homepage = "http://getkura.github.io/ann_wrapper/"
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
16
16
|
spec.files = `git ls-files`.split($/)
|
data/lib/ann_wrapper.rb
CHANGED
@@ -4,35 +4,59 @@
|
|
4
4
|
|
5
5
|
require "net/http"
|
6
6
|
require "nokogiri"
|
7
|
-
require 'ann_wrapper/
|
7
|
+
require 'ann_wrapper/ann_anime'
|
8
|
+
require 'ann_wrapper/ann_manga'
|
9
|
+
require 'ann_wrapper/ann_report'
|
8
10
|
|
9
11
|
# wrapper class for ANN API
|
10
12
|
module ANN_Wrapper
|
11
13
|
extend ANN_Wrapper
|
12
14
|
|
15
|
+
@@type = "anime"
|
16
|
+
|
13
17
|
# ANN API anime url
|
14
18
|
ANN_URL = "http://cdn.animenewsnetwork.com/encyclopedia"
|
15
19
|
ANN_API_URL = "#{ANN_URL}/api.xml"
|
16
20
|
ANN_REPORTS_URL = "#{ANN_URL}/reports.xml"
|
17
21
|
|
18
|
-
# fetch
|
19
|
-
def
|
22
|
+
# fetch up to 50 items(Animes or Mangas) in one request
|
23
|
+
def batch_items(ids, api_url=ANN_API_URL)
|
20
24
|
# append id to API url and send request
|
21
|
-
url = "#{api_url}?
|
25
|
+
url = "#{api_url}?title=#{ids.first.to_s}"
|
26
|
+
ids[1..-1].each do |id|
|
27
|
+
url << "/#{id.to_s}"
|
28
|
+
end
|
22
29
|
|
23
30
|
ann = fetch(url)
|
24
31
|
|
25
|
-
return ann if ann.is_a?(ANN_Error)
|
32
|
+
return [ann] if ann.is_a?(ANN_Error)
|
33
|
+
|
34
|
+
all_items = ann.xpath("//ann/#{@@type}")
|
35
|
+
warnings = ann.xpath('//ann/warning')
|
36
|
+
|
37
|
+
return [ANN_Error.new(get_xml_error(ann))] if all_items.empty? and warnings.empty?
|
38
|
+
|
39
|
+
all_items = all_items.map { |item| Object.const_get("ANN_#{@@type.capitalize}").new(item) }
|
40
|
+
warnings = warnings.map { |warning| ANN_Error.new(get_xml_error(warning)) }
|
26
41
|
|
27
|
-
|
42
|
+
all_items.push(*warnings)
|
43
|
+
end
|
28
44
|
|
29
|
-
|
30
|
-
|
45
|
+
# fetch anime and convert to ANN_Anime
|
46
|
+
def fetch_item(id, api_url=ANN_API_URL)
|
47
|
+
batch_items([id], api_url).first
|
31
48
|
end
|
32
49
|
|
33
50
|
# fetch list of titles via reports
|
34
|
-
def fetch_titles(
|
35
|
-
|
51
|
+
def fetch_titles(options = {})
|
52
|
+
options[:type] ||= "anime"
|
53
|
+
options[:nskip] ||= 0
|
54
|
+
options[:nlist] ||= 50
|
55
|
+
options[:name] ||= ""
|
56
|
+
options[:api_url] ||= ANN_REPORTS_URL
|
57
|
+
|
58
|
+
url = "#{options[:api_url]}?id=155&type=#{options[:type]}&name=#{options[:name]}&nskip=#{options[:nskip]}&nlist=#{options[:nlist]}"
|
59
|
+
|
36
60
|
report = fetch(url)
|
37
61
|
|
38
62
|
return report if report.is_a?(ANN_Error)
|
@@ -44,6 +68,15 @@ extend ANN_Wrapper
|
|
44
68
|
reports.map { |item| ANN_Report.new(item) }
|
45
69
|
end
|
46
70
|
|
71
|
+
def method_missing(meth, *args, &block)
|
72
|
+
if meth.to_s =~ /^(fetch|batch)_(anime|manga)$/
|
73
|
+
@@type = $2
|
74
|
+
$1 == 'fetch' ? fetch_item(*args) : batch_items(*args)
|
75
|
+
else
|
76
|
+
super
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
47
80
|
private
|
48
81
|
# fetch data from ANN API via http GET request
|
49
82
|
# returns Nokogiri or ANN_Error
|
@@ -55,16 +88,16 @@ extend ANN_Wrapper
|
|
55
88
|
# get the response body and try converting to Nokogiri object
|
56
89
|
Nokogiri.XML(resp.body)
|
57
90
|
rescue
|
58
|
-
ANN_Error.new("
|
91
|
+
ANN_Error.new("Could not reach valid URL")
|
59
92
|
end
|
60
|
-
end
|
93
|
+
end
|
61
94
|
|
62
95
|
# attempt to grab error message from XMLObject
|
63
96
|
def get_xml_error(xobj)
|
64
97
|
begin
|
65
98
|
xobj.at_xpath('//ann/warning').content
|
66
|
-
rescue
|
67
|
-
"
|
99
|
+
rescue NoMethodError
|
100
|
+
"unrecognized response body"
|
68
101
|
end
|
69
102
|
end
|
70
103
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# parent with helper methods
|
2
|
+
class ANN
|
3
|
+
private
|
4
|
+
##
|
5
|
+
# define method with supplied name and block
|
6
|
+
def create_method(name, &block)
|
7
|
+
self.class.send(:define_method, name, &block)
|
8
|
+
end
|
9
|
+
|
10
|
+
|
11
|
+
# return hash of methods and returns excluding those in excludes
|
12
|
+
def to_hash(excludes)
|
13
|
+
# get list of methods excluding above
|
14
|
+
methods = self.class.instance_methods(false).reject {|m| excludes.include? m}
|
15
|
+
|
16
|
+
# map methods and results to hash
|
17
|
+
data = methods.map do |method |
|
18
|
+
result = self.send(method)
|
19
|
+
|
20
|
+
# convert Structs to hash
|
21
|
+
if (result.is_a? Array)
|
22
|
+
result.map! do |item|
|
23
|
+
item.is_a?(Struct) ? item.hash : item
|
24
|
+
end
|
25
|
+
else
|
26
|
+
result.hash! if result.is_a?(Struct)
|
27
|
+
end
|
28
|
+
|
29
|
+
# make hash with method name and result of call
|
30
|
+
[method.to_sym, result]
|
31
|
+
end
|
32
|
+
|
33
|
+
# return hash
|
34
|
+
Hash[data]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# various ANN struct types
|
39
|
+
ANN_Error = Struct.new(:message)
|
40
|
+
ANN_Staff = Struct.new(:id, :task, :name)
|
41
|
+
ANN_Cast = Struct.new(:id, :role, :name, :lang)
|
42
|
+
ANN_Episode = Struct.new(:number, :title, :lang)
|
43
|
+
ANN_Image = Struct.new(:src, :width, :height)
|
44
|
+
ANN_Rating = Struct.new(:votes, :weighted, :bayesian_score)
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require_relative 'ann_media'
|
2
|
+
|
3
|
+
class ANN_Anime < ANN_Media
|
4
|
+
# ann_anime Nokogiri object
|
5
|
+
attr_writer :ann_anime
|
6
|
+
|
7
|
+
|
8
|
+
# initialize and create info methods
|
9
|
+
def initialize(ann_anime)
|
10
|
+
@ann_anime = ann_anime
|
11
|
+
|
12
|
+
# information available from detail
|
13
|
+
@info = Hash.new
|
14
|
+
@info[:title] = "Main title"
|
15
|
+
@info[:synopsis] = "Plot Summary"
|
16
|
+
@info[:num_episodes] = "Number of episodes"
|
17
|
+
@info[:genres] = "Genres"
|
18
|
+
@info[:themes] = "Themes"
|
19
|
+
@info[:vintage] = "Vintage"
|
20
|
+
@info[:op_theme] = "Opening Theme"
|
21
|
+
@info[:ed_theme] = "Ending Theme"
|
22
|
+
|
23
|
+
# create methods
|
24
|
+
create_methods(@ann_anime, @info)
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
# @return [Nokogiri::XML::NodeSet] return all info with provided key
|
29
|
+
def find_info(key)
|
30
|
+
super(@ann_anime, key)
|
31
|
+
end
|
32
|
+
|
33
|
+
# @return [String] returns anime id
|
34
|
+
def id
|
35
|
+
@id ||= @ann_anime['id']
|
36
|
+
end
|
37
|
+
|
38
|
+
# @return [String] returns anime type
|
39
|
+
def type
|
40
|
+
@type ||= @ann_anime['type']
|
41
|
+
end
|
42
|
+
|
43
|
+
# @return [[ANN_Rating]] returns array of ANN_Episode
|
44
|
+
def ratings
|
45
|
+
super @ann_anime
|
46
|
+
end
|
47
|
+
|
48
|
+
# @return [[ANN_Episode]] returns array of ANN_Episode
|
49
|
+
def episodes
|
50
|
+
@episodes ||= @ann_anime.xpath("./episode").map do |e|
|
51
|
+
title = e.at_xpath("title")
|
52
|
+
ANN_Episode.new(e['num'], title.content, title['lang'])
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# @return [[ANN_Cast]] returns array of ANN_Cast
|
57
|
+
def cast
|
58
|
+
@cast ||= @ann_anime.xpath("./cast").map do |s|
|
59
|
+
role = s.at_xpath("role")
|
60
|
+
person = s.at_xpath("person")
|
61
|
+
ANN_Cast.new(person['id'], role.content, person.content, s['lang'])
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# @return [[ANN_Staff]] returns array of ANN_Staff
|
66
|
+
def staff
|
67
|
+
super @ann_anime
|
68
|
+
end
|
69
|
+
|
70
|
+
# @return [Hash] hash of self
|
71
|
+
def to_h
|
72
|
+
# create hash excluding some methods
|
73
|
+
to_hash([:to_h, :ann_anime=, :find_info])
|
74
|
+
end
|
75
|
+
|
76
|
+
##
|
77
|
+
# These methods are created via create_method in the constructor
|
78
|
+
|
79
|
+
# @return [[String]] returns number of episodes
|
80
|
+
def num_episodes; end
|
81
|
+
# @return [[String]] returns op theme(s)
|
82
|
+
def op_theme; end
|
83
|
+
# @return [[String]] returns ed theme(s)
|
84
|
+
def ed_theme; end
|
85
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require_relative 'ann_media'
|
2
|
+
|
3
|
+
class ANN_Manga < ANN_Media
|
4
|
+
# ann_anime Nokogiri object
|
5
|
+
attr_writer :ann_manga
|
6
|
+
|
7
|
+
def initialize(ann_manga)
|
8
|
+
@ann_manga = ann_manga
|
9
|
+
|
10
|
+
# information available from detail
|
11
|
+
@info = Hash.new
|
12
|
+
@info[:title] = "Main title"
|
13
|
+
@info[:synopsis] = "Plot Summary"
|
14
|
+
@info[:genres] = "Genres"
|
15
|
+
@info[:vintage] = "Vintage"
|
16
|
+
@info[:themes] = "Themes"
|
17
|
+
@info[:num_tankoubon] = "Number of tankoubon"
|
18
|
+
@info[:num_pages] = "Number of pages"
|
19
|
+
|
20
|
+
# create methods
|
21
|
+
create_methods(@ann_manga, @info)
|
22
|
+
end
|
23
|
+
|
24
|
+
# @return [Nokogiri::XML::NodeSet] return all info with provided key
|
25
|
+
def find_info(key)
|
26
|
+
super(@ann_manga, key)
|
27
|
+
end
|
28
|
+
|
29
|
+
# @return [String] returns manga id
|
30
|
+
def id
|
31
|
+
@id ||= @ann_manga['id']
|
32
|
+
end
|
33
|
+
|
34
|
+
# @return [String] returns manga type
|
35
|
+
def type
|
36
|
+
@type ||= @ann_manga['type']
|
37
|
+
end
|
38
|
+
|
39
|
+
# @return [[ANN_Staff]] returns array of ANN_Staff
|
40
|
+
def staff
|
41
|
+
super @ann_manga
|
42
|
+
end
|
43
|
+
|
44
|
+
# @return [[ANN_Rating]] returns array of ANN_Episode
|
45
|
+
def ratings
|
46
|
+
super @ann_manga
|
47
|
+
end
|
48
|
+
|
49
|
+
# @return [Hash] hash of self
|
50
|
+
def to_h
|
51
|
+
# create hash excluding some methods
|
52
|
+
to_hash([:to_h, :ann_manga=, :find_info])
|
53
|
+
end
|
54
|
+
|
55
|
+
##
|
56
|
+
# These methods are created via create_method in the constructor
|
57
|
+
|
58
|
+
# @return [[String]] returns the number of tankoubon
|
59
|
+
def num_tankoubon; end
|
60
|
+
|
61
|
+
# @return [[String]] returns the number of tankoubon
|
62
|
+
def num_pages; end
|
63
|
+
end
|