notu 2.0.3 → 3.0.0
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/VERSION +1 -1
- data/lib/notu/html_document.rb +1 -1
- data/lib/notu/http_download.rb +4 -4
- data/lib/notu/library.rb +9 -6
- data/lib/notu/listing.rb +3 -3
- data/lib/notu/loved_tracks.rb +5 -5
- data/lib/notu/most_played_tracks.rb +7 -7
- data/lib/notu/played_tracks.rb +5 -5
- data/notu.gemspec +10 -7
- metadata +77 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1e13444a530e59b3049d159ff447ba19c9525be2a861563e47dbe2fed586d728
|
4
|
+
data.tar.gz: b982c666ad9eac6e8fe23be668f7e3270fe528c0f1511fb0db63ebb46ddd0028
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1864ecdf4fdccd1629f11c6f789bb354736512c026a55825544087474e4ef0b4c5e73aae863efbed1c8a9cfd84bb06cf9538388068049ed324d36ed4f753c834
|
7
|
+
data.tar.gz: 6c3f3c4041d49547898cad9ef090e2d54711cac2b304ad9e30d829917709302ab6b09aef9272fa4662a6edf7615189d88aca0cc4470bf5f10dd7d394a80e4f17
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
3.0.0
|
data/lib/notu/html_document.rb
CHANGED
@@ -9,7 +9,7 @@ module Notu
|
|
9
9
|
def self.parse(data)
|
10
10
|
data = data.gsub(/ /i, ' ').gsub(/\s+/, ' ')
|
11
11
|
document = Nokogiri::HTML.parse(data, nil, 'UTF-8')
|
12
|
-
raise ParseError.new('Invalid HTML document') if (document/'head').empty?
|
12
|
+
raise ParseError.new('Invalid HTML document') if (document / 'head').empty?
|
13
13
|
document
|
14
14
|
end
|
15
15
|
private_class_method :parse
|
data/lib/notu/http_download.rb
CHANGED
@@ -26,13 +26,13 @@ module Notu
|
|
26
26
|
return response.body
|
27
27
|
end
|
28
28
|
end
|
29
|
-
rescue
|
30
|
-
raise NetworkError.new(
|
29
|
+
rescue Timeout::Error, Zlib::BufError => e
|
30
|
+
raise NetworkError.new(e) if options[:max_retries] < 1
|
31
31
|
options[:max_retries] -= 1
|
32
32
|
sleep(options[:retry_sleep])
|
33
33
|
get(url, options)
|
34
|
-
rescue =>
|
35
|
-
raise NetworkError.new(
|
34
|
+
rescue => e
|
35
|
+
raise NetworkError.new(e)
|
36
36
|
end
|
37
37
|
|
38
38
|
end
|
data/lib/notu/library.rb
CHANGED
@@ -7,6 +7,7 @@ module Notu
|
|
7
7
|
attr_reader :username
|
8
8
|
|
9
9
|
def initialize(options = {})
|
10
|
+
@semaphore = Mutex.new
|
10
11
|
options = options.symbolize_keys
|
11
12
|
self.username = options[:username]
|
12
13
|
end
|
@@ -42,12 +43,14 @@ module Notu
|
|
42
43
|
private
|
43
44
|
|
44
45
|
def username=(value)
|
45
|
-
@
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
46
|
+
@semaphore.synchronize do
|
47
|
+
@username = value.to_s.strip.downcase
|
48
|
+
raise UnknownUsernameError.new(value) if username !~ /^[a-z0-9_]+$/
|
49
|
+
begin
|
50
|
+
HtmlDocument.get(url)
|
51
|
+
rescue
|
52
|
+
raise UnknownUsernameError.new(value)
|
53
|
+
end
|
51
54
|
end
|
52
55
|
end
|
53
56
|
|
data/lib/notu/listing.rb
CHANGED
@@ -13,13 +13,13 @@ module Notu
|
|
13
13
|
|
14
14
|
def page_urls
|
15
15
|
(1..pages_count).map do |index|
|
16
|
-
library.url(path
|
16
|
+
library.url(path:, query: params.merge('page' => index))
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
20
|
def pages_count
|
21
|
-
document = HtmlDocument.get(library.url(path
|
22
|
-
[1, (document/'ul.pagination-list li.pagination-page').text.split(/\s+/).map(&:to_i)].flatten.compact.max
|
21
|
+
document = HtmlDocument.get(library.url(path:, query: params))
|
22
|
+
[1, (document / 'ul.pagination-list li.pagination-page').text.split(/\s+/).map(&:to_i)].flatten.compact.max
|
23
23
|
end
|
24
24
|
|
25
25
|
def params
|
data/lib/notu/loved_tracks.rb
CHANGED
@@ -4,14 +4,14 @@ module Notu
|
|
4
4
|
|
5
5
|
include Listing
|
6
6
|
|
7
|
-
def each
|
7
|
+
def each
|
8
8
|
return unless block_given?
|
9
9
|
page_urls.each do |url|
|
10
10
|
document = HtmlDocument.get(url)
|
11
|
-
(document/'table.chartlist tbody tr').each do |element|
|
12
|
-
artist = (element/'td.chartlist-artist a').first.try(:text) || next
|
13
|
-
title = (element/'td.chartlist-name a').first.try(:text) || next
|
14
|
-
yield(Track.new(artist
|
11
|
+
(document / 'table.chartlist tbody tr').each do |element|
|
12
|
+
artist = (element / 'td.chartlist-artist a').first.try(:text) || next
|
13
|
+
title = (element / 'td.chartlist-name a').first.try(:text) || next
|
14
|
+
yield(Track.new(artist:, title:))
|
15
15
|
end
|
16
16
|
end
|
17
17
|
nil
|
@@ -10,7 +10,7 @@ module Notu
|
|
10
10
|
'90 days' => 'LAST_90_DAYS',
|
11
11
|
'365 days' => 'LAST_365_DAYS',
|
12
12
|
'Overall' => '',
|
13
|
-
}
|
13
|
+
}.freeze
|
14
14
|
|
15
15
|
attr_reader :period
|
16
16
|
|
@@ -20,15 +20,15 @@ module Notu
|
|
20
20
|
self.period = options['period']
|
21
21
|
end
|
22
22
|
|
23
|
-
def each
|
23
|
+
def each
|
24
24
|
return unless block_given?
|
25
25
|
page_urls.each do |url|
|
26
26
|
document = HtmlDocument.get(url)
|
27
|
-
(document/'table.chartlist tbody tr').each do |element|
|
28
|
-
artist = (element/'td.chartlist-artist a').first.try(:text) || next
|
29
|
-
title = (element/'td.chartlist-name a').first.try(:text) || next
|
30
|
-
plays_count = (element/'td.chartlist-bar .chartlist-count-bar-value').text.gsub(/[^\d]/, '').presence || next
|
31
|
-
yield(Track.new(artist
|
27
|
+
(document / 'table.chartlist tbody tr').each do |element|
|
28
|
+
artist = (element / 'td.chartlist-artist a').first.try(:text) || next
|
29
|
+
title = (element / 'td.chartlist-name a').first.try(:text) || next
|
30
|
+
plays_count = (element / 'td.chartlist-bar .chartlist-count-bar-value').text.gsub(/[^\d]/, '').presence || next
|
31
|
+
yield(Track.new(artist:, plays_count:, title:))
|
32
32
|
end
|
33
33
|
end
|
34
34
|
nil
|
data/lib/notu/played_tracks.rb
CHANGED
@@ -4,14 +4,14 @@ module Notu
|
|
4
4
|
|
5
5
|
include Listing
|
6
6
|
|
7
|
-
def each
|
7
|
+
def each
|
8
8
|
return unless block_given?
|
9
9
|
page_urls.each do |url|
|
10
10
|
document = HtmlDocument.get(url)
|
11
|
-
(document/'table.chartlist tbody tr').each do |element|
|
12
|
-
artist = (element/'td.chartlist-artist a').first.try(:text) || next
|
13
|
-
title = (element/'td.chartlist-name a').first.try(:text) || next
|
14
|
-
yield(Track.new(artist
|
11
|
+
(document / 'table.chartlist tbody tr').each do |element|
|
12
|
+
artist = (element / 'td.chartlist-artist a').first.try(:text) || next
|
13
|
+
title = (element / 'td.chartlist-name a').first.try(:text) || next
|
14
|
+
yield(Track.new(artist:, title:))
|
15
15
|
end
|
16
16
|
end
|
17
17
|
nil
|
data/notu.gemspec
CHANGED
@@ -9,18 +9,21 @@ Gem::Specification.new do |s|
|
|
9
9
|
s.description = 'API to get Last.fm tracks (most played, loved, etc.)'
|
10
10
|
s.license = 'MIT'
|
11
11
|
|
12
|
-
s.files =
|
13
|
-
s.executables =
|
12
|
+
s.files = %x(git ls-files | grep -vE '^(spec/|test/|\\.|Gemfile|Rakefile)').split("\n")
|
13
|
+
s.executables = %x(git ls-files -- bin/*).split("\n").map { |f| File.basename(f) }
|
14
14
|
s.require_paths = ['lib']
|
15
15
|
|
16
|
-
s.required_ruby_version = '>=
|
16
|
+
s.required_ruby_version = '>= 3.1.0'
|
17
17
|
|
18
|
-
s.add_dependency 'activesupport', '>=
|
19
|
-
s.add_dependency 'nokogiri', '>= 1.6.0', '< 1.
|
18
|
+
s.add_dependency 'activesupport', '>= 7.0.0', '< 8.0.0'
|
19
|
+
s.add_dependency 'nokogiri', '>= 1.6.0', '< 1.14.0'
|
20
20
|
|
21
21
|
s.add_development_dependency 'byebug', '>= 3.2.0', '< 12.0.0'
|
22
|
-
s.add_development_dependency 'rake', '>= 10.3.0', '<
|
22
|
+
s.add_development_dependency 'rake', '>= 10.3.0', '< 14.0.0'
|
23
23
|
s.add_development_dependency 'rspec', '>= 3.1.0', '< 4.0.0'
|
24
|
-
s.add_development_dependency '
|
24
|
+
s.add_development_dependency 'rubocop', '>= 1.25.0', '< 2.0.0'
|
25
|
+
s.add_development_dependency 'rubocop-rake', '>= 0.6.0', '< 1.0.0'
|
26
|
+
s.add_development_dependency 'rubocop-rspec', '>= 2.8.0', '< 3.0.0'
|
27
|
+
s.add_development_dependency 'vcr', '>= 4.0.0', '< 7.0.0'
|
25
28
|
s.add_development_dependency 'webmock', '>= 3.0.0', '< 4.0.0'
|
26
29
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: notu
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alexis Toulotte
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-02-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -16,20 +16,20 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 7.0.0
|
20
20
|
- - "<"
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version:
|
22
|
+
version: 8.0.0
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
requirements:
|
27
27
|
- - ">="
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version:
|
29
|
+
version: 7.0.0
|
30
30
|
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version:
|
32
|
+
version: 8.0.0
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: nokogiri
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -39,7 +39,7 @@ dependencies:
|
|
39
39
|
version: 1.6.0
|
40
40
|
- - "<"
|
41
41
|
- !ruby/object:Gem::Version
|
42
|
-
version: 1.
|
42
|
+
version: 1.14.0
|
43
43
|
type: :runtime
|
44
44
|
prerelease: false
|
45
45
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -49,7 +49,7 @@ dependencies:
|
|
49
49
|
version: 1.6.0
|
50
50
|
- - "<"
|
51
51
|
- !ruby/object:Gem::Version
|
52
|
-
version: 1.
|
52
|
+
version: 1.14.0
|
53
53
|
- !ruby/object:Gem::Dependency
|
54
54
|
name: byebug
|
55
55
|
requirement: !ruby/object:Gem::Requirement
|
@@ -79,7 +79,7 @@ dependencies:
|
|
79
79
|
version: 10.3.0
|
80
80
|
- - "<"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version:
|
82
|
+
version: 14.0.0
|
83
83
|
type: :development
|
84
84
|
prerelease: false
|
85
85
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -89,7 +89,7 @@ dependencies:
|
|
89
89
|
version: 10.3.0
|
90
90
|
- - "<"
|
91
91
|
- !ruby/object:Gem::Version
|
92
|
-
version:
|
92
|
+
version: 14.0.0
|
93
93
|
- !ruby/object:Gem::Dependency
|
94
94
|
name: rspec
|
95
95
|
requirement: !ruby/object:Gem::Requirement
|
@@ -110,6 +110,66 @@ dependencies:
|
|
110
110
|
- - "<"
|
111
111
|
- !ruby/object:Gem::Version
|
112
112
|
version: 4.0.0
|
113
|
+
- !ruby/object:Gem::Dependency
|
114
|
+
name: rubocop
|
115
|
+
requirement: !ruby/object:Gem::Requirement
|
116
|
+
requirements:
|
117
|
+
- - ">="
|
118
|
+
- !ruby/object:Gem::Version
|
119
|
+
version: 1.25.0
|
120
|
+
- - "<"
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: 2.0.0
|
123
|
+
type: :development
|
124
|
+
prerelease: false
|
125
|
+
version_requirements: !ruby/object:Gem::Requirement
|
126
|
+
requirements:
|
127
|
+
- - ">="
|
128
|
+
- !ruby/object:Gem::Version
|
129
|
+
version: 1.25.0
|
130
|
+
- - "<"
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: 2.0.0
|
133
|
+
- !ruby/object:Gem::Dependency
|
134
|
+
name: rubocop-rake
|
135
|
+
requirement: !ruby/object:Gem::Requirement
|
136
|
+
requirements:
|
137
|
+
- - ">="
|
138
|
+
- !ruby/object:Gem::Version
|
139
|
+
version: 0.6.0
|
140
|
+
- - "<"
|
141
|
+
- !ruby/object:Gem::Version
|
142
|
+
version: 1.0.0
|
143
|
+
type: :development
|
144
|
+
prerelease: false
|
145
|
+
version_requirements: !ruby/object:Gem::Requirement
|
146
|
+
requirements:
|
147
|
+
- - ">="
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: 0.6.0
|
150
|
+
- - "<"
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: 1.0.0
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: rubocop-rspec
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - ">="
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: 2.8.0
|
160
|
+
- - "<"
|
161
|
+
- !ruby/object:Gem::Version
|
162
|
+
version: 3.0.0
|
163
|
+
type: :development
|
164
|
+
prerelease: false
|
165
|
+
version_requirements: !ruby/object:Gem::Requirement
|
166
|
+
requirements:
|
167
|
+
- - ">="
|
168
|
+
- !ruby/object:Gem::Version
|
169
|
+
version: 2.8.0
|
170
|
+
- - "<"
|
171
|
+
- !ruby/object:Gem::Version
|
172
|
+
version: 3.0.0
|
113
173
|
- !ruby/object:Gem::Dependency
|
114
174
|
name: vcr
|
115
175
|
requirement: !ruby/object:Gem::Requirement
|
@@ -119,7 +179,7 @@ dependencies:
|
|
119
179
|
version: 4.0.0
|
120
180
|
- - "<"
|
121
181
|
- !ruby/object:Gem::Version
|
122
|
-
version:
|
182
|
+
version: 7.0.0
|
123
183
|
type: :development
|
124
184
|
prerelease: false
|
125
185
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -129,7 +189,7 @@ dependencies:
|
|
129
189
|
version: 4.0.0
|
130
190
|
- - "<"
|
131
191
|
- !ruby/object:Gem::Version
|
132
|
-
version:
|
192
|
+
version: 7.0.0
|
133
193
|
- !ruby/object:Gem::Dependency
|
134
194
|
name: webmock
|
135
195
|
requirement: !ruby/object:Gem::Requirement
|
@@ -177,7 +237,7 @@ homepage: https://github.com/alexistoulotte/notu
|
|
177
237
|
licenses:
|
178
238
|
- MIT
|
179
239
|
metadata: {}
|
180
|
-
post_install_message:
|
240
|
+
post_install_message:
|
181
241
|
rdoc_options: []
|
182
242
|
require_paths:
|
183
243
|
- lib
|
@@ -185,15 +245,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
185
245
|
requirements:
|
186
246
|
- - ">="
|
187
247
|
- !ruby/object:Gem::Version
|
188
|
-
version:
|
248
|
+
version: 3.1.0
|
189
249
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
190
250
|
requirements:
|
191
251
|
- - ">="
|
192
252
|
- !ruby/object:Gem::Version
|
193
253
|
version: '0'
|
194
254
|
requirements: []
|
195
|
-
rubygems_version: 3.
|
196
|
-
signing_key:
|
255
|
+
rubygems_version: 3.3.3
|
256
|
+
signing_key:
|
197
257
|
specification_version: 4
|
198
258
|
summary: API for Last.fm
|
199
259
|
test_files: []
|