drum 0.2.1 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0515ca290089497d8667ed64575eb60dc604ba793812b77437ced8d27f70e6bb
4
- data.tar.gz: 1da960b8dc5e79ce85328e918c43d214898824e51d544b613b58ede726666f97
3
+ metadata.gz: e1cf895018608f7c8ecbf68a5f243228d1569af86b9015c0f178b13f6614cd7c
4
+ data.tar.gz: f52ba7d7d00e81cd8f3f3a1793d637def247beb9c88a58d167d64e9c890ab841
5
5
  SHA512:
6
- metadata.gz: db118818875e8c9d0d5281697e033bcaeebb3bc204355e41ab4436ed2da1738297c703ed8aa813f32456f968851729794f3e209c0510ca1ddbf218b93af75ab0
7
- data.tar.gz: 24ce2b4be59b259617cc50ba66fc35c48aeeeb89faa716a5ad457a959364ccb39cb37b7fa86c4e4f4da6593b7c753bc9eebcde02226d24a6a65402f5d2e7eca8
6
+ metadata.gz: 5c24724da7a46dc623202cef18dc779f9c5fa98d0f34491da5a4445927ee47cf7b0dda2f0372c9ed0d26a6a3a4ec13cfb9f515227009ffb0239d6bb751908038
7
+ data.tar.gz: 806e30e6353f897cd3f163f663769913ccb33f9f5df7b1f629cf97b5258cf3f682b9bbc185906785b570d8f97e9930b74fa837d5fd1a5cc019336e42d5708528
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- drum (0.2.1)
4
+ drum (0.2.3)
5
5
  highline (~> 2.0)
6
6
  jwt (~> 2.2)
7
7
  launchy (~> 2.4)
data/README.md CHANGED
@@ -29,7 +29,8 @@ The basic usage pattern is always `drum cp [source] [destination]` where `source
29
29
  * `@stdout`
30
30
  * A dash `-`, synonymous with `@stdin` and `@stdout`, depending on usage
31
31
 
32
- > Note that if the source is folder-like, i.e. includes multiple playlists, the destination has to be folder-like too. (The reverse is not true though.)
32
+ > [!NOTE]
33
+ > If the source is folder-like, i.e. includes multiple playlists, the destination has to be folder-like too. (The reverse is not true though.)
33
34
 
34
35
  ### Examples
35
36
 
@@ -59,7 +60,8 @@ Currently, the following music services are supported:
59
60
  * Apple Music
60
61
  * Local, YAML-based playlists (via stdio or files)
61
62
 
62
- > Note that the tool only processes metadata, not the actual audio files.
63
+ > [!NOTE]
64
+ > The tool only processes metadata, not the actual audio files.
63
65
 
64
66
  ## Development
65
67
 
@@ -67,11 +69,13 @@ After checking out the repo, run `bin/setup` (or `bundle install`) to install de
67
69
 
68
70
  To run the application, run `bundle exec bin/drum`. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
69
71
 
70
- > Note that you may need to run `bundle exec ruby bin/drum` on Windows
72
+ > [!IMPORTANT]
73
+ > You may need to run `bundle exec ruby bin/drum` on Windows
71
74
 
72
75
  To package the application into a gem, run `bundle exec rake build`. The built gem should then be located in `pkg`.
73
76
 
74
- > Note: If you wish to install `drum` using `gem install`, you may need to install additional gems such as `rb-scpt` on macOS to use platform-specific integrations. See [the `Gemfile`](Gemfile) for more information.
77
+ > [!IMPORTANT]
78
+ > If you wish to install `drum` using `gem install`, you may need to install additional gems such as `rb-scpt` on macOS to use platform-specific integrations. See [the `Gemfile`](Gemfile) for more information.
75
79
 
76
80
  To install the gem, run `bundle exec rake install`.
77
81
 
@@ -79,6 +83,9 @@ To generate the documentation, run `bundle exec rake yard`.
79
83
 
80
84
  To run tests, run `bundle exec rake spec`.
81
85
 
86
+ > [!TIP]
87
+ > If you wish to use a language server such as Solargraph and code completion isn't working for required gems, you may have to run `yard gems`: https://solargraph.org/guides/troubleshooting
88
+
82
89
  ### Spotify
83
90
 
84
91
  To use the service integration with Spotify, set the following environment variables:
@@ -31,6 +31,8 @@ module Drum
31
31
  TO_SPOTIFY_TRACKS_CHUNK_SIZE = 50
32
32
  UPLOAD_PLAYLIST_TRACKS_CHUNK_SIZE = 100
33
33
 
34
+ MAX_PLAYLIST_TRACKS = 10_000
35
+
34
36
  CLIENT_ID_VAR = 'SPOTIFY_CLIENT_ID'
35
37
  CLIENT_SECRET_VAR = 'SPOTIFY_CLIENT_SECRET'
36
38
 
@@ -241,30 +243,37 @@ module Drum
241
243
  # Download helpers
242
244
 
243
245
  def all_sp_library_playlists(offset: 0)
244
- sp_playlists = @me.playlists(limit: PLAYLISTS_CHUNK_SIZE, offset: offset)
245
- unless sp_playlists.empty?
246
- sp_playlists + self.all_sp_library_playlists(offset: offset + PLAYLISTS_CHUNK_SIZE)
247
- else
248
- []
246
+ all_sp_playlists = []
247
+ while !(sp_playlists = @me.playlists(limit: PLAYLISTS_CHUNK_SIZE, offset: offset)).empty?
248
+ offset += PLAYLISTS_CHUNK_SIZE
249
+ all_sp_playlists += sp_playlists
249
250
  end
251
+ all_sp_playlists
250
252
  end
251
253
 
252
254
  def all_sp_playlist_tracks(sp_playlist, offset: 0)
253
- sp_tracks = sp_playlist.tracks(limit: TRACKS_CHUNK_SIZE, offset: offset)
254
- unless sp_tracks.empty?
255
- sp_tracks + self.all_sp_playlist_tracks(sp_playlist, offset: offset + TRACKS_CHUNK_SIZE)
256
- else
257
- []
255
+ all_sp_tracks = []
256
+ while !(sp_tracks = sp_playlist.tracks(limit: TRACKS_CHUNK_SIZE, offset: offset)).empty?
257
+ offset += TRACKS_CHUNK_SIZE
258
+ all_sp_tracks += sp_tracks
259
+ if offset > sp_playlist.total + TRACKS_CHUNK_SIZE
260
+ log.warn "Truncating playlist '#{sp_playlist.name}' at #{offset}, which strangely seems to yield more tracks than its length of #{sp_playlist.total} would suggest."
261
+ break
262
+ elsif offset > MAX_PLAYLIST_TRACKS
263
+ log.warn "Truncating playlist '#{sp_playlist.name}' at #{offset}, since it exceeds the maximum of #{MAX_PLAYLIST_TRACKS} tracks."
264
+ break
265
+ end
258
266
  end
267
+ all_sp_tracks
259
268
  end
260
269
 
261
270
  def all_sp_library_tracks(offset: 0)
262
- sp_tracks = @me.saved_tracks(limit: SAVED_TRACKS_CHUNKS_SIZE, offset: offset)
263
- unless sp_tracks.empty?
264
- sp_tracks + self.all_sp_library_tracks(offset: offset + SAVED_TRACKS_CHUNKS_SIZE)
265
- else
266
- []
271
+ all_sp_tracks = []
272
+ while !(sp_tracks = @me.saved_tracks(limit: SAVED_TRACKS_CHUNKS_SIZE, offset: offset)).empty?
273
+ offset += SAVED_TRACKS_CHUNKS_SIZE
274
+ all_sp_tracks += sp_tracks
267
275
  end
276
+ all_sp_tracks
268
277
  end
269
278
 
270
279
  def extract_sp_features(sp_track)
@@ -555,11 +564,35 @@ module Drum
555
564
  log.info 'Fetching playlists...'
556
565
  Enumerator.new(sp_playlists.length) do |enum|
557
566
  sp_playlists.each do |sp_playlist|
558
- begin
559
- new_playlist = self.from_sp_playlist(sp_playlist)
560
- enum.yield new_playlist
561
- rescue StandardError => e
562
- log.info "Could not download playlist '#{sp_playlist.name}': #{e}"
567
+ # These playlists seem to cause trouble for some reason, by either
568
+ # 404ing or by returning seemingly endless amounts of tracks, so
569
+ # we'll ignore them for now...
570
+ if sp_playlist.name.start_with?('Your Top Songs')
571
+ log.info "Skipping '#{sp_playlist.name}'"
572
+ next
573
+ end
574
+
575
+ 3.times do |attempt|
576
+ begin
577
+ if attempt > 0
578
+ log.info "Attempt \##{attempt + 1} to download '#{sp_playlist.name}'..."
579
+ end
580
+ new_playlist = self.from_sp_playlist(sp_playlist)
581
+ enum.yield new_playlist
582
+ break
583
+ rescue RestClient::TooManyRequests => e
584
+ seconds = e.response.headers[:retry_after]&.to_f || 0.5
585
+ if seconds <= 300
586
+ log.warn "Got 429 Too Many Requests while downloading '#{sp_playlist.name}', retrying in #{seconds} seconds..."
587
+ sleep seconds
588
+ else
589
+ log.error "Got 429 Too Many Requests while downloading '#{sp_playlist.name}' with a too large retry time of #{seconds} seconds"
590
+ raise
591
+ end
592
+ rescue StandardError => e
593
+ log.warn "Could not download playlist '#{sp_playlist.name}': #{e}"
594
+ break
595
+ end
563
596
  end
564
597
  end
565
598
  end
data/lib/drum/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Drum
2
- VERSION = '0.2.1'
2
+ VERSION = '0.2.3'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: drum
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - fwcd
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-01-19 00:00:00.000000000 Z
11
+ date: 2024-02-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor