<commit_before>class Spotbot::Playlist
  include Singleton

  URI_KEY = "playlist:uri"
  TRACKS_KEY = "playlist:tracks"
  SHUFFLE_KEY = "playlist:shuffle"

  attr_reader :uri, :queue

  def initialize
    reset_state
  end

  def from_uri(uri)
    return false unless valid_uri?(uri)
    reset_state
    @uri = uri
    self.shuffle = false
    redis.set URI_KEY, uri
    fetch_tracks
    populate_queue
    Spotbot::Firebase.playlist(as_json)
    self
  end

  def next
    populate_queue if queue.size == 0
    track = queue.pop
    Spotbot::Firebase.playlist(as_json)
    track
  end

  def tracks
    redis.lrange(TRACKS_KEY, 0, -1).map do |uri|
      Spotbot::Track.new uri
    end
  end

  def uri
    @uri ||= redis.get URI_KEY
  end

  def name
    if album?
      "#{album.artists.map(&:name).join(", ")}  – #{album.name}"
    else
      Spotify.playlist_name playlist
    end
  end

  def shuffle?
    redis.get(SHUFFLE_KEY) == "true"
  end

  def shuffle=(state)
    @queue = [] if shuffle? != state
    redis.set SHUFFLE_KEY, state
    Spotbot::Firebase.playlist(as_json)
  end

  def album?
    uri.match(/:album:/)
  end

  private

  def as_json
    {
      name: name,
      uri: uri,
      shuffle: shuffle?,
      tracks: tracks.map(&:as_json),
    }
  end

  def valid_uri?(uri)
    !!uri.match(/spotify:(album:|(user:\S*:playlist:))\S+/)
  end

  def populate_queue
    return unless uri
    fetch_tracks if redis.llen(TRACKS_KEY) == 0
    @queue = redis.lrange(TRACKS_KEY, 0, -1).reverse
    @queue.shuffle! if shuffle?
  end

  def fetch_tracks
    if album?
      redis.rpush TRACKS_KEY, album.tracks.map(&:uri)
    else
      redis.rpush TRACKS_KEY, playlist_tracks
    end
  end

  def playlist
    playlist = Spotify.playlist_create support.session, link
    support.poll { Spotify.playlist_is_loaded(playlist) }
    playlist
  end

  def playlist_tracks
    tracks = []
    while track = Spotify.playlist_track(playlist, tracks.size) do
      link = Spotify.link_create_from_track track, 0
      tracks << Spotify.link_as_string(link)
    end
    tracks
  end

  def album
    @album ||= RSpotify::Album.find(uri_id)
  end

  def uri_id
    uri.gsub("spotify:album:", "")
  end

  def reset_state
    redis.del TRACKS_KEY
    @queue = []
    @album = nil
    Spotbot::Firebase.playlist(as_json)
  end<commit_msg>Tweak firebase posting from playlist<commit_after>class Spotbot::Playlist
  include Singleton

  URI_KEY = "playlist:uri"
  TRACKS_KEY = "playlist:tracks"
  SHUFFLE_KEY = "playlist:shuffle"

  attr_reader :uri, :queue

  def initialize
    reset_state
    Spotbot::Firebase.playlist(as_json)
  end

  def from_uri(uri)
    return false unless valid_uri?(uri)
    reset_state
    @uri = uri
    self.shuffle = false
    redis.set URI_KEY, uri
    fetch_tracks
    populate_queue
    Spotbot::Firebase.playlist(as_json)
    self
  end

  def next
    populate_queue if queue.size == 0
    track = queue.pop
    Spotbot::Firebase.playlist(as_json)
    track
  end

  def tracks
    redis.lrange(TRACKS_KEY, 0, -1).map do |uri|
      Spotbot::Track.new uri
    end
  end

  def uri
    @uri ||= redis.get URI_KEY
  end

  def name
    if album?
      "#{album.artists.map(&:name).join(", ")}  – #{album.name}"
    else
      Spotify.playlist_name playlist
    end
  end

  def shuffle?
    redis.get(SHUFFLE_KEY) == "true"
  end

  def shuffle=(state)
    @queue = [] if shuffle? != state
    redis.set SHUFFLE_KEY, state
    Spotbot::Firebase.playlist(as_json)
  end

  def album?
    uri.match(/:album:/)
  end

  private

  def as_json
    {
      name: name,
      uri: uri,
      shuffle: shuffle?,
      tracks: tracks.map(&:as_json),
    }
  end

  def valid_uri?(uri)
    !!uri.match(/spotify:(album:|(user:\S*:playlist:))\S+/)
  end

  def populate_queue
    return unless uri
    fetch_tracks if redis.llen(TRACKS_KEY) == 0
    @queue = redis.lrange(TRACKS_KEY, 0, -1).reverse
    @queue.shuffle! if shuffle?
  end

  def fetch_tracks
    if album?
      redis.rpush TRACKS_KEY, album.tracks.map(&:uri)
    else
      redis.rpush TRACKS_KEY, playlist_tracks
    end
  end

  def playlist
    playlist = Spotify.playlist_create support.session, link
    support.poll { Spotify.playlist_is_loaded(playlist) }
    playlist
  end

  def playlist_tracks
    tracks = []
    while track = Spotify.playlist_track(playlist, tracks.size) do
      link = Spotify.link_create_from_track track, 0
      tracks << Spotify.link_as_string(link)
    end
    tracks
  end

  def album
    @album ||= RSpotify::Album.find(uri_id)
  end

  def uri_id
    uri.gsub("spotify:album:", "")
  end

  def reset_state
    redis.del TRACKS_KEY
    @queue = []
    @album = nil
  end
{'fraction_non_alphanumeric': 0.10512875079804214, 'fraction_numerical': 0.0029793573100659713, 'mean_word_length': 2.721298495645289, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '297473', 'n_tokens_mistral': 1796, 'n_tokens_neox': 1717, 'n_words': 377}