Anilistrb 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.dockerfile +1 -0
- data/.gitignore +12 -0
- data/.gitlab-ci.yml +13 -0
- data/.rspec +2 -0
- data/.rubocop.yml +60 -0
- data/Anilistrb.gemspec +39 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +65 -0
- data/LICENSE.txt +21 -0
- data/README.md +60 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/dev/anilist-test.gql +87 -0
- data/dev/anilist-test.http +6 -0
- data/dev/anilist-test.json +233 -0
- data/dev/anilist-test.py +6 -0
- data/dev/animelist.json +15096 -0
- data/dev/run.bat +5 -0
- data/dev/test.bat +3 -0
- data/example/install.bat +3 -0
- data/example/myapp.bat +4 -0
- data/example/myapp.rb +5 -0
- data/lib/Anilistrb.rb +9 -0
- data/lib/Anilistrb/AnilistObj.rb +30 -0
- data/lib/Anilistrb/Client.rb +108 -0
- data/lib/Anilistrb/GqlClient.rb +27 -0
- data/lib/Anilistrb/GraphQL/media_by_id.gql +87 -0
- data/lib/Anilistrb/GraphQL/media_by_pages.gql +44 -0
- data/lib/Anilistrb/GraphQL/media_by_search.gql +87 -0
- data/lib/Anilistrb/GraphQL/medialist_by_user.gql +39 -0
- data/lib/Anilistrb/GraphQL/user_by_id.gql +17 -0
- data/lib/Anilistrb/GraphQL/user_by_search.gql +17 -0
- data/lib/Anilistrb/Media.rb +9 -0
- data/lib/Anilistrb/Medialist.rb +56 -0
- data/lib/Anilistrb/User.rb +10 -0
- data/lib/Anilistrb/version.rb +3 -0
- metadata +165 -0
data/dev/run.bat
ADDED
data/dev/test.bat
ADDED
data/example/install.bat
ADDED
data/example/myapp.bat
ADDED
data/example/myapp.rb
ADDED
data/lib/Anilistrb.rb
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
require 'httparty'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
require_relative 'Anilistrb/AnilistObj'
|
5
|
+
require_relative 'Anilistrb/GqlClient'
|
6
|
+
require_relative 'Anilistrb/Media'
|
7
|
+
require_relative 'Anilistrb/Medialist'
|
8
|
+
require_relative 'Anilistrb/User'
|
9
|
+
require_relative 'Anilistrb/Version'
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Anilistrb
|
2
|
+
class AnilistObj
|
3
|
+
attr_reader :data, :attributes
|
4
|
+
|
5
|
+
def initialize(json)
|
6
|
+
@data = json
|
7
|
+
@attributes = []
|
8
|
+
unless @data.nil?
|
9
|
+
@data.each do |var, val|
|
10
|
+
snaked = to_snakecase(var)
|
11
|
+
self.class.__send__(:attr_accessor, snaked)
|
12
|
+
self.__send__("#{snaked}=", val)
|
13
|
+
@attributes.push(snaked)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def to_snakecase(str)
|
19
|
+
str.gsub(/::/, '/')
|
20
|
+
.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
21
|
+
.gsub(/([a-z\d])([A-Z])/, '\1_\2')
|
22
|
+
.tr('-', '_').downcase
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_s
|
26
|
+
data
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
require_relative 'GqlClient'
|
2
|
+
require_relative 'Media'
|
3
|
+
require_relative 'Medialist'
|
4
|
+
require_relative 'User'
|
5
|
+
|
6
|
+
module Anilistrb
|
7
|
+
class Client
|
8
|
+
def initialize
|
9
|
+
@gql_client = Anilistrb::GqlClient.new('https://graphql.anilist.co')
|
10
|
+
@gql_dir = File.expand_path('./GraphQL', __dir__)
|
11
|
+
@gql_queries = {
|
12
|
+
'media_by_id' => File.read("#{@gql_dir}/media_by_id.gql"),
|
13
|
+
'media_by_pages' => File.read("#{@gql_dir}/media_by_pages.gql"),
|
14
|
+
'media_by_search' => File.read("#{@gql_dir}/media_by_search.gql"),
|
15
|
+
'medialist_by_user' => File.read("#{@gql_dir}/medialist_by_user.gql"),
|
16
|
+
'user_by_id' => File.read("#{@gql_dir}/user_by_id.gql"),
|
17
|
+
'user_by_search' => File.read("#{@gql_dir}/user_by_search.gql")
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
def get_anime(id)
|
22
|
+
begin
|
23
|
+
raise TypeError unless id.is_a? Integer
|
24
|
+
Anilistrb::Media.new(gql_request(
|
25
|
+
@gql_queries['media_by_id'], { id: id, type: 'ANIME' }
|
26
|
+
)['data']['Media'])
|
27
|
+
rescue StandardError
|
28
|
+
nil
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def get_manga(id)
|
33
|
+
begin
|
34
|
+
raise TypeError unless id.is_a? Integer
|
35
|
+
Anilistrb::Media.new(gql_request(
|
36
|
+
@gql_queries['media_by_id'], { id: id, type: 'MANGA' }
|
37
|
+
)['data']['Media'])
|
38
|
+
rescue StandardError then nil
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def get_animelist(userId)
|
43
|
+
begin
|
44
|
+
raise TypeError unless userId.is_a? Integer
|
45
|
+
Anilistrb::Medialist.new(gql_request(
|
46
|
+
@gql_queries['medialist_by_user'], { id: userId, type: 'ANIME' }
|
47
|
+
)['data']['MediaListCollection'], 'ANIME')
|
48
|
+
rescue StandardError then nil
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def get_mangalist(userId)
|
53
|
+
begin
|
54
|
+
raise TypeError unless userId.is_a? Integer
|
55
|
+
Anilistrb::Medialist.new(gql_request(
|
56
|
+
@gql_queries['medialist_by_user'], { id: userId, type: 'MANGA' }
|
57
|
+
)['data']['MediaListCollection'], 'MANGA')
|
58
|
+
rescue StandardError then nil
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def search_anime(search)
|
63
|
+
Anilistrb::Media.new(gql_request(
|
64
|
+
@gql_queries['media_by_search'], { search: search, type: 'ANIME' }
|
65
|
+
)['data']['Media'])
|
66
|
+
end
|
67
|
+
|
68
|
+
def search_manga(search)
|
69
|
+
Anilistrb::Media.new(gql_request(
|
70
|
+
@gql_queries['media_by_search'], { search: search, type: 'MANGA' }
|
71
|
+
)['data']['Media'])
|
72
|
+
end
|
73
|
+
|
74
|
+
def search_anime_paged(search:, perPage: 10, page: 1)
|
75
|
+
search_media_paged(search: search, type: 'ANIME', perPage: perPage, page: page)
|
76
|
+
end
|
77
|
+
|
78
|
+
def search_manga_paged(search:, perPage: 10, page: 1)
|
79
|
+
search_media_paged(search: search, type: 'MANGA', perPage: perPage, page: page)
|
80
|
+
end
|
81
|
+
|
82
|
+
def search_media_paged(search:, type:, perPage: 10, page: 1)
|
83
|
+
media = []
|
84
|
+
begin
|
85
|
+
raise TypeError unless perPage.is_a? Integer
|
86
|
+
raise TypeError unless page.is_a? Integer
|
87
|
+
gql_request(
|
88
|
+
@gql_queries['media_by_pages'],
|
89
|
+
{ search: search, type: type, perPage: perPage, page: page }
|
90
|
+
)['data']['Page']['media'].each { |x| media.push(Anilistrb::Media.new(x)) }
|
91
|
+
rescue StandardError then nil
|
92
|
+
end
|
93
|
+
media
|
94
|
+
end
|
95
|
+
|
96
|
+
def search_user(search)
|
97
|
+
Anilistrb::User.new(gql_request(
|
98
|
+
@gql_queries['user_by_search'],
|
99
|
+
{ search: search }
|
100
|
+
)['data']['User'])
|
101
|
+
end
|
102
|
+
|
103
|
+
def gql_request(query, variables)
|
104
|
+
@gql_client.request(method: 'POST', query: query, variables: variables)
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'httparty'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
module Anilistrb
|
5
|
+
class GqlClient
|
6
|
+
def initialize(url)
|
7
|
+
@url = url
|
8
|
+
end
|
9
|
+
|
10
|
+
def build_request(query:, variables: nil)
|
11
|
+
[ @url,
|
12
|
+
headers: { 'Content-Type' => 'application/json', 'Accept' => 'application/json' },
|
13
|
+
body: { query: query, variables: variables }.to_json ]
|
14
|
+
end
|
15
|
+
|
16
|
+
def request(method:, query:, variables: nil)
|
17
|
+
# TODO: check if status code not 200
|
18
|
+
if method == 'POST'
|
19
|
+
HTTParty.post(*build_request(query: query, variables: variables))
|
20
|
+
elsif method == 'GET'
|
21
|
+
HTTParty.get(*build_request(query: query, variables: variables))
|
22
|
+
else
|
23
|
+
puts "#{method} not supported."
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
query ($id: Int, $type: MediaType) {
|
2
|
+
Media (id: $id, type: $type) {
|
3
|
+
id
|
4
|
+
title {
|
5
|
+
romaji
|
6
|
+
english
|
7
|
+
native
|
8
|
+
}
|
9
|
+
type
|
10
|
+
format
|
11
|
+
status
|
12
|
+
description
|
13
|
+
startDate {
|
14
|
+
year
|
15
|
+
month
|
16
|
+
day
|
17
|
+
}
|
18
|
+
endDate {
|
19
|
+
year
|
20
|
+
month
|
21
|
+
day
|
22
|
+
}
|
23
|
+
season
|
24
|
+
episodes
|
25
|
+
duration
|
26
|
+
chapters
|
27
|
+
volumes
|
28
|
+
countryOfOrigin
|
29
|
+
isLicensed
|
30
|
+
source
|
31
|
+
hashtag
|
32
|
+
trailer {
|
33
|
+
id
|
34
|
+
site
|
35
|
+
}
|
36
|
+
updatedAt
|
37
|
+
coverImage {
|
38
|
+
large
|
39
|
+
medium
|
40
|
+
}
|
41
|
+
bannerImage
|
42
|
+
genres
|
43
|
+
synonyms
|
44
|
+
averageScore
|
45
|
+
meanScore
|
46
|
+
popularity
|
47
|
+
trending
|
48
|
+
tags {
|
49
|
+
id
|
50
|
+
name
|
51
|
+
description
|
52
|
+
category
|
53
|
+
rank
|
54
|
+
isGeneralSpoiler
|
55
|
+
isMediaSpoiler
|
56
|
+
isAdult
|
57
|
+
}
|
58
|
+
isAdult
|
59
|
+
nextAiringEpisode {
|
60
|
+
timeUntilAiring
|
61
|
+
episode
|
62
|
+
}
|
63
|
+
externalLinks {
|
64
|
+
id
|
65
|
+
url
|
66
|
+
site
|
67
|
+
}
|
68
|
+
streamingEpisodes {
|
69
|
+
title
|
70
|
+
thumbnail
|
71
|
+
url
|
72
|
+
site
|
73
|
+
}
|
74
|
+
rankings {
|
75
|
+
id
|
76
|
+
rank
|
77
|
+
type
|
78
|
+
format
|
79
|
+
year
|
80
|
+
season
|
81
|
+
allTime
|
82
|
+
context
|
83
|
+
}
|
84
|
+
siteUrl
|
85
|
+
modNotes
|
86
|
+
}
|
87
|
+
}
|
@@ -0,0 +1,44 @@
|
|
1
|
+
query (
|
2
|
+
$id: Int,
|
3
|
+
$page: Int,
|
4
|
+
$perPage: Int,
|
5
|
+
$search: String,
|
6
|
+
$type: MediaType,
|
7
|
+
$sort: [MediaSort] = [SCORE_DESC, POPULARITY_DESC]
|
8
|
+
) {
|
9
|
+
Page(page: $page, perPage: $perPage) {
|
10
|
+
media(id: $id, search: $search, type: $type, sort: $sort) {
|
11
|
+
id
|
12
|
+
type
|
13
|
+
format
|
14
|
+
title {
|
15
|
+
english
|
16
|
+
romaji
|
17
|
+
native
|
18
|
+
}
|
19
|
+
synonyms
|
20
|
+
status
|
21
|
+
description
|
22
|
+
startDate {
|
23
|
+
year
|
24
|
+
month
|
25
|
+
day
|
26
|
+
}
|
27
|
+
endDate {
|
28
|
+
year
|
29
|
+
month
|
30
|
+
day
|
31
|
+
}
|
32
|
+
episodes
|
33
|
+
chapters
|
34
|
+
volumes
|
35
|
+
coverImage {
|
36
|
+
large
|
37
|
+
}
|
38
|
+
genres
|
39
|
+
averageScore
|
40
|
+
siteUrl
|
41
|
+
popularity
|
42
|
+
}
|
43
|
+
}
|
44
|
+
}
|
@@ -0,0 +1,87 @@
|
|
1
|
+
query ($search: String, $type: MediaType) {
|
2
|
+
Media (search: $search, type: $type) {
|
3
|
+
id
|
4
|
+
title {
|
5
|
+
romaji
|
6
|
+
english
|
7
|
+
native
|
8
|
+
}
|
9
|
+
type
|
10
|
+
format
|
11
|
+
status
|
12
|
+
description
|
13
|
+
startDate {
|
14
|
+
year
|
15
|
+
month
|
16
|
+
day
|
17
|
+
}
|
18
|
+
endDate {
|
19
|
+
year
|
20
|
+
month
|
21
|
+
day
|
22
|
+
}
|
23
|
+
season
|
24
|
+
episodes
|
25
|
+
duration
|
26
|
+
chapters
|
27
|
+
volumes
|
28
|
+
countryOfOrigin
|
29
|
+
isLicensed
|
30
|
+
source
|
31
|
+
hashtag
|
32
|
+
trailer {
|
33
|
+
id
|
34
|
+
site
|
35
|
+
}
|
36
|
+
updatedAt
|
37
|
+
coverImage {
|
38
|
+
large
|
39
|
+
medium
|
40
|
+
}
|
41
|
+
bannerImage
|
42
|
+
genres
|
43
|
+
synonyms
|
44
|
+
averageScore
|
45
|
+
meanScore
|
46
|
+
popularity
|
47
|
+
trending
|
48
|
+
tags {
|
49
|
+
id
|
50
|
+
name
|
51
|
+
description
|
52
|
+
category
|
53
|
+
rank
|
54
|
+
isGeneralSpoiler
|
55
|
+
isMediaSpoiler
|
56
|
+
isAdult
|
57
|
+
}
|
58
|
+
isAdult
|
59
|
+
nextAiringEpisode {
|
60
|
+
timeUntilAiring
|
61
|
+
episode
|
62
|
+
}
|
63
|
+
externalLinks {
|
64
|
+
id
|
65
|
+
url
|
66
|
+
site
|
67
|
+
}
|
68
|
+
streamingEpisodes {
|
69
|
+
title
|
70
|
+
thumbnail
|
71
|
+
url
|
72
|
+
site
|
73
|
+
}
|
74
|
+
rankings {
|
75
|
+
id
|
76
|
+
rank
|
77
|
+
type
|
78
|
+
format
|
79
|
+
year
|
80
|
+
season
|
81
|
+
allTime
|
82
|
+
context
|
83
|
+
}
|
84
|
+
siteUrl
|
85
|
+
modNotes
|
86
|
+
}
|
87
|
+
}
|
@@ -0,0 +1,39 @@
|
|
1
|
+
query ($id: Int!, $type: MediaType) {
|
2
|
+
MediaListCollection (userId: $id, type: $type) {
|
3
|
+
lists {
|
4
|
+
name
|
5
|
+
entries {
|
6
|
+
id
|
7
|
+
mediaId
|
8
|
+
status
|
9
|
+
score
|
10
|
+
progress
|
11
|
+
progressVolumes
|
12
|
+
startedAt {
|
13
|
+
year
|
14
|
+
month
|
15
|
+
day
|
16
|
+
}
|
17
|
+
completedAt {
|
18
|
+
year
|
19
|
+
month
|
20
|
+
day
|
21
|
+
}
|
22
|
+
updatedAt
|
23
|
+
createdAt
|
24
|
+
media {
|
25
|
+
id
|
26
|
+
title {
|
27
|
+
romaji
|
28
|
+
english
|
29
|
+
native
|
30
|
+
}
|
31
|
+
}
|
32
|
+
}
|
33
|
+
}
|
34
|
+
user {
|
35
|
+
id
|
36
|
+
name
|
37
|
+
}
|
38
|
+
}
|
39
|
+
}
|