natalia 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/natalia/services/j_lyric.rb +125 -0
- data/lib/natalia/services/joysound.rb +2 -1
- data/lib/natalia/services/utamap.rb +2 -2
- data/lib/natalia/version.rb +1 -1
- data/lib/natalia.rb +5 -0
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b2656442ac7d8e82de97e949248c5bef87b51faef371254f8f9800d488f8c813
|
4
|
+
data.tar.gz: 2966d8b5a3fd4b2f8e623bfd37b562c8682831391ffa17cdfd68b756b2265e6c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fb91352464023b97cfb10c280b3687467241162e2a518b52b7f4b7dd67543bcf1ef8e439be091fb98dfad89bf28c9a16a79d9badf106e60e33125d853bb807b4
|
7
|
+
data.tar.gz: 6d404e9fac70e8b5d5e15d9db794091d73e4c0751356ebab7350077d1e5e2f5bfacd590c43fecbd7ab88a9506131fef647b0a4e5528eb7b22fd92d71c8050dc8
|
@@ -0,0 +1,125 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'nokogiri'
|
4
|
+
require 'time'
|
5
|
+
require_relative '../utils'
|
6
|
+
|
7
|
+
module Natalia
|
8
|
+
module JLyric
|
9
|
+
# sort という概念はないっぽい
|
10
|
+
def self.search(keyword, type: :title, sort: :popularity_desc)
|
11
|
+
case type
|
12
|
+
when :title
|
13
|
+
search_by_title(keyword)
|
14
|
+
when :artist
|
15
|
+
search_by_artist(keyword, sort: sort)
|
16
|
+
else
|
17
|
+
raise ArgumentError, "unsupported search type `#{type}`"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.search_by_title(keyword)
|
22
|
+
entries = []
|
23
|
+
(1..).each do |page|
|
24
|
+
response =
|
25
|
+
Natalia::Utils.curl_get('https://search2.j-lyric.net/index.php', {
|
26
|
+
kt: keyword,
|
27
|
+
ct: '2', # kt 検索方法 (0: 前方, 1: 完全, 2: 中間, 3: 後方)
|
28
|
+
search: '検索', # 謎
|
29
|
+
ex: 'on', # 謎
|
30
|
+
ca: '2', # ka 検索方法
|
31
|
+
cl: '2', # kl 検索方法
|
32
|
+
p: page
|
33
|
+
})
|
34
|
+
response.value
|
35
|
+
|
36
|
+
doc = Nokogiri::HTML.parse(response.body)
|
37
|
+
table = doc.css('div#bas div#cnt div#mnb > div.bdy')
|
38
|
+
break if table.empty?
|
39
|
+
|
40
|
+
table.each do |body|
|
41
|
+
entries << {
|
42
|
+
source: self,
|
43
|
+
id: body.at_css('p.mid a')['href'].match(%r{/artist/(.+)\.html\z})[1],
|
44
|
+
title: body.at_css('p.mid a').content,
|
45
|
+
artist: body.css('p.sml')[0].at_css('a').content,
|
46
|
+
artist_id: body.css('p.sml')[0].at_css('a')['href'].match(%r{/artist/(.+)/\z})[1]
|
47
|
+
}
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
entries
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.search_by_artist(artist_id, sort: :popularity_desc)
|
55
|
+
response = Natalia::Utils.curl_get("https://j-lyric.net/artist/#{artist_id}/")
|
56
|
+
response.value
|
57
|
+
|
58
|
+
doc = Nokogiri::HTML.parse(response.body)
|
59
|
+
artist_name = doc.at_css('div#mnb div.cnt div.cap h2').content.match(/\A(.+)の歌詞リスト\z/)[1]
|
60
|
+
table = doc.css('div#bas div#cnt div#mnb div.bdy[id^=ly]')
|
61
|
+
|
62
|
+
entries = table.map do |row|
|
63
|
+
order, date, popularity = row.css('input[type=hidden]').map {|e| e['value']}
|
64
|
+
{
|
65
|
+
source: self,
|
66
|
+
id: row.at_css('p.ttl a')['href'].match(%r{/artist/(.+)\.html\z})[1],
|
67
|
+
title: row.at_css('p.ttl a').content,
|
68
|
+
artist: artist_name,
|
69
|
+
artist_id: artist_id,
|
70
|
+
order: order.to_i,
|
71
|
+
date: Time.parse("#{date} JST"),
|
72
|
+
popularity: -popularity.to_i
|
73
|
+
}
|
74
|
+
end.compact
|
75
|
+
|
76
|
+
case sort
|
77
|
+
when :title
|
78
|
+
entries.sort_by {|e| e[:order]}
|
79
|
+
when :title_desc
|
80
|
+
entries.sort_by {|e| -e[:order]}
|
81
|
+
when :popularity
|
82
|
+
entries.sort_by {|e| e[:popularity]}
|
83
|
+
when :popularity_desc
|
84
|
+
entries.sort_by {|e| -e[:popularity]}
|
85
|
+
when :date
|
86
|
+
entries.sort_by {|e| e[:date]}
|
87
|
+
when :date_desc
|
88
|
+
entries.sort_by {|e| -e[:date].to_i}
|
89
|
+
when :artist, :artist_desc
|
90
|
+
entries
|
91
|
+
else
|
92
|
+
raise ArgumentError, "unsupported sort type `#{sort}`"
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def self.get(id)
|
97
|
+
response = Natalia::Utils.curl_get("https://j-lyric.net/artist/#{id}.html")
|
98
|
+
response.value
|
99
|
+
|
100
|
+
doc = Nokogiri::HTML.parse(response.body)
|
101
|
+
|
102
|
+
smls = doc.css('div#mnb div.lbdy p.sml')
|
103
|
+
|
104
|
+
ret = {
|
105
|
+
source: self,
|
106
|
+
id: id,
|
107
|
+
title: doc.at_css('div#mnb div.cap h2').content.match(/\A「(.+)」歌詞\z/)[1],
|
108
|
+
artist: smls[0].at_css('a').content,
|
109
|
+
artist_id: smls[0].at_css('a')['href'].match(%r{/artist/(.+)/\z})[1]
|
110
|
+
}
|
111
|
+
|
112
|
+
smls[1..].each do |e|
|
113
|
+
content = e.content
|
114
|
+
ret[:lyricist] = content.match(/作詞:(.+)/)[1] if content.start_with?('作詞:')
|
115
|
+
ret[:composer] = content.match(/作曲:(.+)/)[1] if content.start_with?('作曲:')
|
116
|
+
end
|
117
|
+
|
118
|
+
ret[:lyrics] = doc.at_css('p#Lyric').children.map do |e|
|
119
|
+
e.name == 'br' ? "\n" : e.content
|
120
|
+
end.join.strip
|
121
|
+
|
122
|
+
ret
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
@@ -24,7 +24,8 @@ module Natalia
|
|
24
24
|
|
25
25
|
def self.search(keyword, type: :title, sort: :popularity_desc)
|
26
26
|
sort = SORT_MAP[sort]
|
27
|
-
raise ArgumentError,
|
27
|
+
raise ArgumentError, "unsupported sort type `#{sort}`" unless sort
|
28
|
+
raise ArgumentError, "unsupported search type `#{type}`" unless KIND_MAP.key?(type)
|
28
29
|
|
29
30
|
response = Natalia::Utils.curl_post('https://mspxy.joysound.com/Common/ContentsList') do |request|
|
30
31
|
request.content_type = 'application/x-www-form-urlencoded; charset=UTF-8'
|
@@ -19,8 +19,8 @@ module Natalia
|
|
19
19
|
# @param [String] keyword キーワード(タイトル検索)、ID(それ以外)
|
20
20
|
def self.search(keyword, type: :title, sort: :popularity_desc)
|
21
21
|
sort = SORT_MAP[sort]
|
22
|
-
raise ArgumentError,
|
23
|
-
raise ArgumentError,
|
22
|
+
raise ArgumentError, "unsupported sort type `#{sort}`" unless sort
|
23
|
+
raise ArgumentError, "unsupported search type `#{type}`" unless %i[title artist lyricist composer arranger].include?(type)
|
24
24
|
|
25
25
|
entries = []
|
26
26
|
(type == :title ? 1.. : [1]).each do |page|
|
data/lib/natalia/version.rb
CHANGED
data/lib/natalia.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative 'natalia/services/j_lyric'
|
3
4
|
require_relative 'natalia/services/joysound'
|
4
5
|
require_relative 'natalia/services/utamap'
|
5
6
|
require_relative 'natalia/version'
|
@@ -44,6 +45,7 @@ module Natalia
|
|
44
45
|
# 信頼できるソース順に並べる
|
45
46
|
SERVICES = [
|
46
47
|
Natalia::Utamap,
|
48
|
+
Natalia::JLyric,
|
47
49
|
Natalia::Joysound
|
48
50
|
].freeze
|
49
51
|
|
@@ -51,6 +53,9 @@ module Natalia
|
|
51
53
|
entries = []
|
52
54
|
SERVICES.each do |service|
|
53
55
|
entries += service.search(keyword, type: :title, sort: sort)
|
56
|
+
rescue StandardError
|
57
|
+
warn "Failed to search by #{service}"
|
58
|
+
warn $!.full_message
|
54
59
|
end
|
55
60
|
entries.map {|entry| Song.new(entry)}
|
56
61
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: natalia
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ishotihadus
|
@@ -37,6 +37,7 @@ files:
|
|
37
37
|
- README.md
|
38
38
|
- Rakefile
|
39
39
|
- lib/natalia.rb
|
40
|
+
- lib/natalia/services/j_lyric.rb
|
40
41
|
- lib/natalia/services/joysound.rb
|
41
42
|
- lib/natalia/services/utamap.rb
|
42
43
|
- lib/natalia/utils.rb
|