Class: BandcampDiscover::Scrapers::Music

Inherits:
Base
  • Object
show all
Defined in:
lib/bandcamp-discover/scrapers/music.rb

Constant Summary collapse

MAX_ALBUMS =
20

Instance Method Summary collapse

Constructor Details

#initialize(url:, browser:, max_tasks:) ⇒ Music

Returns a new instance of Music.



12
13
14
15
16
17
# File 'lib/bandcamp-discover/scrapers/music.rb', line 12

def initialize(url:, browser:, max_tasks:)
  super

  uri = URI.parse(url)
  @base_url = "#{uri.scheme}://#{uri.host}"
end

Instance Method Details

#albums(grid) ⇒ Object

Each album carries the credit its grid item showed: the artist's name, or nil when the release is credited to the page owner. The grid is the only place the credit appears without another page load.



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/bandcamp-discover/scrapers/music.rb', line 47

def albums(grid)
  guarded do
    semaphore = Async::Semaphore.new(@max_tasks)

    albums = grid.take(MAX_ALBUMS).map do |item|
      semaphore.async do
        puts "starting to scrape #{item[:url]}"

        album = Scrapers::Album.new(url: item[:url], browser: @browser).scrape

        puts "done scraping #{item[:url]}"

        [item, album]
      end
    end.map(&:wait)

    albums.map! do |item, (album_url, album_title, album_tags, album_player)|
      {url: album_url, title: album_title, tags: album_tags, player_url: album_player, artist: item[:credit]}
    end

    [albums, normalize_tally(albums.map { _1[:tags] }.flatten.tally)]
  end
end

#gridObject

The grid alone tells a label from an artist (see Roster), and it is one page load against the twenty behind albums, so callers can look at it before paying for the rest.



26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/bandcamp-discover/scrapers/music.rb', line 26

def grid
  guarded do
    @page.goto(@url)
    items = @page.wait_for_selector("#music-grid").query_selector_all("li.music-grid-item")

    items.map do |item|
      {
        url: absolute(item.query_selector("a")[:href]),
        credit: item.query_selector(".artist-override")&.inner_text&.strip
      }
    end
  end
end

#normalize_tally(tally) ⇒ Object



71
72
73
74
75
# File 'lib/bandcamp-discover/scrapers/music.rb', line 71

def normalize_tally(tally)
  total = tally.values.sum.to_f
  tally.transform_values! { |count| count / total }
  tally.sort_by { |k, v| v }.reverse.to_h
end

#roster(grid, band_name:) ⇒ Object



40
41
42
# File 'lib/bandcamp-discover/scrapers/music.rb', line 40

def roster(grid, band_name:)
  Roster.new(band_name: band_name, credits: grid.map { _1[:credit] }, releases: grid.size)
end

#scrape(force: false) ⇒ Object



19
20
21
# File 'lib/bandcamp-discover/scrapers/music.rb', line 19

def scrape(force: false)
  albums(grid)
end