drum 0.2.1 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
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