foxit 0.1.1 → 0.1.3
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/.gitignore +2 -1
- data/README.md +20 -4
- data/foxit.gemspec +1 -1
- data/lib/foxit.rb +1 -0
- data/lib/foxit/api.rb +95 -64
- data/lib/foxit/url_builder.rb +43 -0
- data/tests/tc_get_anime_results.rb +44 -0
- data/tests/tc_get_library_results.rb +32 -0
- data/tests/ts_all.rb +4 -0
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4f2ddc5e34db607cabc25cd0df88a4a1830df59757d2021fd75ef414d6cfc9bd
|
4
|
+
data.tar.gz: 7689130ad6eea5df3f7f7b5a49df55e548890e4513223fa98cfc65b078718f3c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9912bb8e912a1b41ee8150c341e4cb75718466058a78193c48835d2cf8d3b2470941015a3820a501daaa5809d906537c36518917cb7d5383f2fafaf922090255
|
7
|
+
data.tar.gz: 11fe6338525040504c52537e7dfe565bcbb29a07ea8551687a3721deb5d88fb4f3078b7c6c822ff19dd85815eecc434f21828a6dcde1f40bb9aed3737c8a8f8d
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -13,22 +13,38 @@ gem install foxit
|
|
13
13
|
A few quick examples are detailed below:
|
14
14
|
|
15
15
|
### Retrieving Data
|
16
|
-
Get an anime item by id.
|
16
|
+
Get an anime item by id or slug.
|
17
17
|
```ruby
|
18
18
|
api = Foxit::API.new()
|
19
19
|
result = api.get_anime_by_id(1)
|
20
|
+
result = api.get_anime_by_slug('cowboy-bebop')
|
21
|
+
```
|
22
|
+
The slug is basically the hyphen separated version of the name with the special characters removed. When you click on a anime item in kitsu it will be at the end of the url. This returns the `Anime` object; however, the full json response can be obtained as per below:
|
23
|
+
```ruby
|
24
|
+
result = api.get_anime_by_id(1, :json)
|
20
25
|
```
|
21
26
|
|
22
|
-
|
27
|
+
Similarly, getting a users library. Returns a list of `LibraryItem` objects.
|
23
28
|
```ruby
|
24
|
-
|
29
|
+
result = api.get_user_library_by_id(1)
|
25
30
|
```
|
26
31
|
|
27
|
-
|
32
|
+
This returns a list of entries (hash format) from the `'data'` attribute of the json returned.
|
28
33
|
```ruby
|
29
34
|
result = api.get_library_by_id(1)
|
30
35
|
```
|
31
36
|
|
37
|
+
Examples of getting a batch of anime results:
|
38
|
+
```ruby
|
39
|
+
result = api.batch_get_anime([1, 4, 8, 25])
|
40
|
+
```
|
41
|
+
|
42
|
+
Similarly, user library examples below. Note: the library batch results are returned as a flat array (filter on user_id to split out).
|
43
|
+
```ruby
|
44
|
+
result = api.batch_get_libraries(1..10)
|
45
|
+
result = api.batch_get_libraries([1, 2, 3, 5])
|
46
|
+
```
|
47
|
+
|
32
48
|
|
33
49
|
### Storing Data with MongoDB
|
34
50
|
If you don't have mongodb installed you can download the free community version from [here][mongodb]. Once installed, you need to start the service via terminal:
|
data/foxit.gemspec
CHANGED
@@ -6,7 +6,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
7
|
spec.name = "foxit"
|
8
8
|
# spec.version = Foxit::VERSION
|
9
|
-
spec.version = "0.1.
|
9
|
+
spec.version = "0.1.3"
|
10
10
|
spec.authors = ["Lachlan Taylor"]
|
11
11
|
spec.email = ["lachlanbtaylor@gmail.com"]
|
12
12
|
|
data/lib/foxit.rb
CHANGED
data/lib/foxit/api.rb
CHANGED
@@ -1,37 +1,23 @@
|
|
1
1
|
require_relative 'objects'
|
2
|
+
require_relative 'helpers'
|
3
|
+
require_relative 'url_builder'
|
2
4
|
|
3
5
|
require 'net/http'
|
4
6
|
require 'json'
|
5
|
-
require 'addressable/uri'
|
6
7
|
|
7
8
|
|
8
9
|
|
9
10
|
module Foxit
|
10
11
|
|
11
|
-
|
12
|
+
# TODO: probably split out library and anime methods
|
13
|
+
class API < Helpers
|
12
14
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
uri = Addressable::URI.parse("#{@root}library-entries")
|
20
|
-
|
21
|
-
uri_query = {
|
22
|
-
"filter[user_id]" => id,
|
23
|
-
"filter[media_type]" => type,
|
24
|
-
"filter[status]" => status,
|
25
|
-
"page[limit]" => limit
|
26
|
-
}
|
27
|
-
uri.query_values = uri_query
|
28
|
-
|
29
|
-
uri.to_s
|
30
|
-
end
|
31
|
-
|
32
|
-
|
33
|
-
def build_media_url entry_id
|
34
|
-
"#{@root}/library-entries/#{entry_id}/relationships/media"
|
15
|
+
attr_reader :urlbuilder
|
16
|
+
attr_accessor :max_threads
|
17
|
+
|
18
|
+
def initialize max_threads=200
|
19
|
+
@max_threads = max_threads
|
20
|
+
@urlbuilder = URLBuilder.new()
|
35
21
|
end
|
36
22
|
|
37
23
|
|
@@ -41,14 +27,14 @@ module Foxit
|
|
41
27
|
end
|
42
28
|
|
43
29
|
|
44
|
-
def
|
30
|
+
def _get_library_by_url url, entries=[]
|
45
31
|
|
46
32
|
result = self.get_result(url)
|
47
33
|
entries += result['data']
|
48
34
|
|
49
35
|
if result['links'].key?('next')
|
50
36
|
# recursion to retrieve additional results that have ben paginated
|
51
|
-
result = self.
|
37
|
+
result = self._get_library_by_url(result['links']['next'], entries)
|
52
38
|
else
|
53
39
|
return entries
|
54
40
|
end
|
@@ -56,8 +42,8 @@ module Foxit
|
|
56
42
|
|
57
43
|
|
58
44
|
def get_library_by_id user_id
|
59
|
-
url =
|
60
|
-
self.
|
45
|
+
url = @urlbuilder.library(user_id)
|
46
|
+
self._get_library_by_url(url)
|
61
47
|
end
|
62
48
|
|
63
49
|
|
@@ -67,17 +53,16 @@ module Foxit
|
|
67
53
|
@get_media_relationship_by_id ||= {}
|
68
54
|
return @get_media_relationship_by_id[entry_id] if @get_media_relationship_by_id.key?(entry_id)
|
69
55
|
|
70
|
-
url =
|
56
|
+
url = @urlbuilder.media(entry_id)
|
71
57
|
self.get_result(url)
|
72
58
|
end
|
73
59
|
|
74
60
|
|
75
|
-
def batch_get_results ids, fn
|
61
|
+
def batch_get_results ids, fn
|
76
62
|
"""
|
77
63
|
ids: ids of results returned: user_id | library_entry_id in this case.
|
78
64
|
fn: function name to use to return results (need to use symbol method name)
|
79
65
|
e.g. :get_result
|
80
|
-
max_threads: maximum number of active threads.
|
81
66
|
"""
|
82
67
|
|
83
68
|
results = {}
|
@@ -85,7 +70,7 @@ module Foxit
|
|
85
70
|
|
86
71
|
ids.each do |id|
|
87
72
|
|
88
|
-
if Thread.list.count % max_threads != 0
|
73
|
+
if Thread.list.count % @max_threads != 0
|
89
74
|
thread = Thread.new do
|
90
75
|
# adding lock slows down considerably shouldn't matter as results are written to hash?
|
91
76
|
results[id] = send(fn, id)
|
@@ -108,56 +93,101 @@ module Foxit
|
|
108
93
|
results
|
109
94
|
end
|
110
95
|
|
111
|
-
|
112
|
-
def batch_get_libraries user_ids
|
96
|
+
|
97
|
+
def batch_get_libraries user_ids
|
113
98
|
|
114
99
|
all_library_entries = []
|
115
|
-
user_libraries = self.batch_get_results(user_ids, :get_library_by_id
|
100
|
+
user_libraries = self.batch_get_results(user_ids, :get_library_by_id)
|
116
101
|
|
117
102
|
user_libraries.each do |user_id, library|
|
118
|
-
|
119
|
-
media_ids = []
|
120
|
-
library.map { |entry| media_ids << entry['id'] }
|
121
|
-
media_results = self.batch_get_results(media_ids, :get_media_relationship_by_id, max_threads)
|
122
|
-
|
123
|
-
library.each do |entry|
|
124
|
-
all_library_entries << LibraryItem.new(user_id, entry, media_results[entry['id']])
|
125
|
-
end
|
126
|
-
|
103
|
+
all_library_entries += self._create_library_items(user_id, library)
|
127
104
|
end
|
128
105
|
|
129
106
|
all_library_entries
|
130
107
|
end
|
131
|
-
|
108
|
+
|
109
|
+
|
110
|
+
def _create_library_items user_id, library
|
111
|
+
|
112
|
+
# get media_ids from record_ids (not in same response, additional request required)
|
113
|
+
record_ids = []
|
114
|
+
library.map { |entry| record_ids << entry['id'] }
|
115
|
+
media_results = self.batch_get_results(record_ids, :get_media_relationship_by_id)
|
116
|
+
|
117
|
+
library_entries = []
|
118
|
+
library.each do |entry|
|
119
|
+
library_entries << LibraryItem.new(user_id, entry, media_results[entry['id']])
|
120
|
+
end
|
121
|
+
|
122
|
+
library_entries
|
123
|
+
end
|
124
|
+
|
132
125
|
|
133
|
-
def
|
134
|
-
|
126
|
+
def get_user_library_by_id user_id
|
127
|
+
library = self.get_library_by_id(user_id)
|
128
|
+
self._create_library_items(user_id, library)
|
135
129
|
end
|
136
130
|
|
137
131
|
|
138
|
-
def batch_get_libraries_docs user_ids
|
139
|
-
all_library_entries = self.batch_get_libraries(user_ids
|
132
|
+
def batch_get_libraries_docs user_ids
|
133
|
+
all_library_entries = self.batch_get_libraries(user_ids)
|
140
134
|
|
141
135
|
docs = []
|
142
136
|
all_library_entries.map { |entry| docs << entry.to_hash }
|
143
137
|
|
144
138
|
docs
|
145
139
|
end
|
146
|
-
|
147
|
-
|
148
|
-
def
|
149
|
-
|
140
|
+
|
141
|
+
|
142
|
+
def _get_anime_by_attr filter_attr, filter_value, rtype=:object
|
143
|
+
|
144
|
+
# TODO: this is a bit of a mess
|
145
|
+
|
146
|
+
case filter_attr
|
147
|
+
when :id
|
148
|
+
url = @urlbuilder.anime_by_id(filter_value)
|
149
|
+
when :slug
|
150
|
+
url = @urlbuilder.anime_by_slug(filter_value)
|
151
|
+
else
|
152
|
+
raise ArgumentError.new("filter_attr argument (1st) not in {:id, :slug}")
|
153
|
+
end
|
154
|
+
|
155
|
+
result = self.get_result(url)
|
156
|
+
|
157
|
+
case rtype
|
158
|
+
when :json
|
159
|
+
return result
|
160
|
+
when :object
|
161
|
+
case filter_attr
|
162
|
+
when :id
|
163
|
+
return Anime.new(result['data'])
|
164
|
+
when :slug
|
165
|
+
# filtering by slug results in the 'data' attribute to be an array
|
166
|
+
return Anime.new(result['data'][0])
|
167
|
+
end
|
168
|
+
else
|
169
|
+
raise ArgumentError.new("rtype not :object or :json")
|
170
|
+
end
|
150
171
|
end
|
151
|
-
|
152
|
-
|
153
|
-
def get_anime_by_id id
|
154
|
-
|
155
|
-
self.get_result(url)
|
172
|
+
|
173
|
+
|
174
|
+
def get_anime_by_id id, rtype=:object
|
175
|
+
self._get_anime_by_attr(:id, id, rtype)
|
156
176
|
end
|
157
|
-
|
158
|
-
|
159
|
-
def
|
160
|
-
|
177
|
+
|
178
|
+
|
179
|
+
def get_anime_by_slug slug, rtype=:object
|
180
|
+
self._get_anime_by_attr(:slug, slug, rtype)
|
181
|
+
end
|
182
|
+
|
183
|
+
|
184
|
+
def _get_anime_by_id_json id
|
185
|
+
self._get_anime_by_attr(:id, id, :json)
|
186
|
+
end
|
187
|
+
|
188
|
+
|
189
|
+
def batch_get_anime anime_ids
|
190
|
+
results = self.batch_get_results(anime_ids, :_get_anime_by_id_json)
|
161
191
|
|
162
192
|
anime_items = []
|
163
193
|
results.each do |id, result|
|
@@ -169,8 +199,9 @@ module Foxit
|
|
169
199
|
anime_items
|
170
200
|
end
|
171
201
|
|
172
|
-
|
173
|
-
|
202
|
+
|
203
|
+
def get_anime_documents anime_ids
|
204
|
+
anime_items = self.batch_get_anime(anime_ids)
|
174
205
|
self.objects_to_hash(anime_items)
|
175
206
|
end
|
176
207
|
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'addressable/uri'
|
2
|
+
|
3
|
+
|
4
|
+
|
5
|
+
class URLBuilder
|
6
|
+
|
7
|
+
attr_reader :root
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@root = "https://kitsu.io/api/edge/"
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
def media entry_id
|
15
|
+
"#{@root}/library-entries/#{entry_id}/relationships/media"
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
def library id, type='Anime', status='completed', limit=500
|
20
|
+
uri = Addressable::URI.parse("#{@root}library-entries")
|
21
|
+
|
22
|
+
uri_query = {
|
23
|
+
"filter[user_id]" => id,
|
24
|
+
"filter[media_type]" => type,
|
25
|
+
"filter[status]" => status,
|
26
|
+
"page[limit]" => limit
|
27
|
+
}
|
28
|
+
uri.query_values = uri_query
|
29
|
+
|
30
|
+
uri.to_s
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
def anime_by_id id
|
35
|
+
"#{@root}/anime/#{id}"
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
def anime_by_slug slug
|
40
|
+
"#{@root}/anime?filter[slug]=#{slug}"
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require "test/unit"
|
2
|
+
|
3
|
+
require_relative '../lib/foxit/api'
|
4
|
+
|
5
|
+
|
6
|
+
|
7
|
+
class TestGetAnimeResponses < Test::Unit::TestCase
|
8
|
+
|
9
|
+
def setup
|
10
|
+
@api = Foxit::API.new()
|
11
|
+
@slug = 'cowboy-bebop'
|
12
|
+
end
|
13
|
+
|
14
|
+
def test__get_anime_by_attr_id_json
|
15
|
+
result = @api._get_anime_by_attr(:id, 1, :json)
|
16
|
+
assert_equal(@slug, result['data']['attributes']['slug'])
|
17
|
+
end
|
18
|
+
|
19
|
+
def test__get_anime_by_attr_id_object
|
20
|
+
result = @api._get_anime_by_attr(:id, 1, :object)
|
21
|
+
assert_equal(@slug, result.slug)
|
22
|
+
end
|
23
|
+
|
24
|
+
def test__get_anime_by_attr_slug_json
|
25
|
+
result = @api._get_anime_by_attr(:slug, @slug, :json)
|
26
|
+
assert_equal(@slug, result['data'][0]['attributes']['slug'])
|
27
|
+
end
|
28
|
+
|
29
|
+
def test__get_anime_by_attr_slug_object
|
30
|
+
result = @api._get_anime_by_attr(:slug, @slug, :object)
|
31
|
+
assert_equal(@slug, result.slug)
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_get_anime_by_id_base
|
35
|
+
result = @api.get_anime_by_id(1)
|
36
|
+
assert_equal(@slug, result.slug)
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_get_anime_by_slug_base
|
40
|
+
result = @api.get_anime_by_slug(@slug)
|
41
|
+
assert_equal(@slug, result.slug)
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require "test/unit"
|
2
|
+
|
3
|
+
require_relative '../lib/foxit/api'
|
4
|
+
|
5
|
+
|
6
|
+
|
7
|
+
class TestGetLibraryResults < Test::Unit::TestCase
|
8
|
+
|
9
|
+
def setup
|
10
|
+
@api = Foxit::API.new()
|
11
|
+
@user_id = 1
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_get_library_by_id
|
15
|
+
result = @api.get_library_by_id(@user_id)
|
16
|
+
assert_kind_of(Hash, result[0], 'result should be an array of Hash objects')
|
17
|
+
assert(result.length > 10, 'user library should not be empty') # user 1 library is 35 'complete' items
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_get_user_library_by_id
|
21
|
+
result = @api.get_user_library_by_id(@user_id)
|
22
|
+
assert_kind_of(LibraryItem, result[0], 'result should be an array of LibraryItem objects')
|
23
|
+
assert(result.length > 10, 'user library should not be empty')
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_batch_get_libraries
|
27
|
+
result = @api.batch_get_libraries(1..2)
|
28
|
+
assert_kind_of(LibraryItem, result[0], 'result should be an array of LibraryItem objects')
|
29
|
+
assert(result.length > 40, 'user library should not be empty')
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
data/tests/ts_all.rb
ADDED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: foxit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lachlan Taylor
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-08-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: json
|
@@ -87,6 +87,10 @@ files:
|
|
87
87
|
- lib/foxit/etl.rb
|
88
88
|
- lib/foxit/helpers.rb
|
89
89
|
- lib/foxit/objects.rb
|
90
|
+
- lib/foxit/url_builder.rb
|
91
|
+
- tests/tc_get_anime_results.rb
|
92
|
+
- tests/tc_get_library_results.rb
|
93
|
+
- tests/ts_all.rb
|
90
94
|
homepage: https://github.com/rokkuran/foxit
|
91
95
|
licenses:
|
92
96
|
- MIT
|