<commit_before>package lila.tv

import akka.actor._
import akka.pattern.{ ask, pipe }
import play.api.libs.json._
import play.api.libs.ws.WS
import play.api.Play.current

private final class Streaming(
    system: ActorSystem,
    renderer: ActorSelection,
    streamerList: StreamerList,
    keyword: String,
    googleApiKey: String,
    hitboxUrl: String,
    twitchClientId: String) {

  import Streaming._
  import Twitch.Reads._
  import Hitbox.Reads._
  import Youtube.Reads._

  def onAir: Fu[List[StreamOnAir]] = {
    import makeTimeout.short
    actor ? Get mapTo manifest[List[StreamOnAir]]
    // fuccess(List(StreamOnAir(
    //   service = "twitch",
    //   name = "Chess master streams at lichess.org",
    //   streamer = "ChessNetwork",
    //   url = "http://foo.com",
    //   streamId = "test")))
  }

  private[tv] val actor = system.actorOf(Props(new Actor {

    private var onAir = List[StreamOnAir]()

    def receive = {

      case Get => sender ! onAir

      case Search => streamerList.get.map(_.filter(_.featured)).foreach { streamers =>
        val max = 5
        val twitch = WS.url("https://api.twitch.tv/kraken/streams")
          .withQueryString("channel" -> streamers.filter(_.twitch).map(_.streamerName).mkString(","))
          .withHeaders(
            "Accept" -> "application/vnd.twitchtv.v3+json",
            "Client-ID" -> twitchClientId
          )
          .get() map { res =>
            res.json.validate[Twitch.Result] match {
              case JsSuccess(data, _) => data.streamsOnAir(streamers) filter (_.name.toLowerCase contains keyword) take max
              case JsError(err) =>
                logger.warn(s"twitch ${res.status} $err ${~res.body.lines.toList.headOption}")
                Nil
            }
          }
        val hitbox = hitboxUrl.nonEmpty ?? {
          WS.url(hitboxUrl + streamers.filter(_.hitbox).map(_.streamerName).mkString(",")).get() map { res =>
            res.json.validate[Hitbox.Result] match {
              case JsSuccess(data, _) => data.streamsOnAir(streamers) filter (_.name.toLowerCase contains keyword) take max
              case JsError(err) =>
                logger.warn(s"hitbox ${res.status} $err ${~res.body.lines.toList.headOption}")
                Nil
            }
          }
        }
        val youtube = googleApiKey.nonEmpty ?? {
          WS.url("https://www.googleapis.com/youtube/v3/search").withQueryString(
            "part" -> "snippet",
            "type" -> "video",
            "eventType" -> "live",
            "q" -> keyword,
            "key" -> googleApiKey
          ).get() map { res =>
              res.json.validate[Youtube.Result] match {
                case JsSuccess(data, _) => data.streamsOnAir(streamers) filter (_.name.toLowerCase contains keyword) take max
                case JsError(err) =>
                  logger.warn(s"youtube ${res.status} $err ${~res.body.lines.toList.headOption}")
                  Nil
              }
            }
        }
        (twitch |+| hitbox |+| youtube) map { ss =>
          StreamsOnAir {<commit_msg>skip twitch call if empty client ID<commit_after>package lila.tv

import akka.actor._
import akka.pattern.{ ask, pipe }
import play.api.libs.json._
import play.api.libs.ws.WS
import play.api.Play.current

private final class Streaming(
    system: ActorSystem,
    renderer: ActorSelection,
    streamerList: StreamerList,
    keyword: String,
    googleApiKey: String,
    hitboxUrl: String,
    twitchClientId: String) {

  import Streaming._
  import Twitch.Reads._
  import Hitbox.Reads._
  import Youtube.Reads._

  def onAir: Fu[List[StreamOnAir]] = {
    import makeTimeout.short
    actor ? Get mapTo manifest[List[StreamOnAir]]
    // fuccess(List(StreamOnAir(
    //   service = "twitch",
    //   name = "Chess master streams at lichess.org",
    //   streamer = "ChessNetwork",
    //   url = "http://foo.com",
    //   streamId = "test")))
  }

  private[tv] val actor = system.actorOf(Props(new Actor {

    private var onAir = List[StreamOnAir]()

    def receive = {

      case Get => sender ! onAir

      case Search => streamerList.get.map(_.filter(_.featured)).foreach { streamers =>
        val max = 5
        val twitch = hitboxUrl.nonEmpty ?? {
          WS.url("https://api.twitch.tv/kraken/streams")
            .withQueryString("channel" -> streamers.filter(_.twitch).map(_.streamerName).mkString(","))
            .withHeaders(
              "Accept" -> "application/vnd.twitchtv.v3+json",
              "Client-ID" -> twitchClientId
            )
            .get() map { res =>
              res.json.validate[Twitch.Result] match {
                case JsSuccess(data, _) => data.streamsOnAir(streamers) filter (_.name.toLowerCase contains keyword) take max
                case JsError(err) =>
                  logger.warn(s"twitch ${res.status} $err ${~res.body.lines.toList.headOption}")
                  Nil
              }
            }
        }
        val hitbox = hitboxUrl.nonEmpty ?? {
          WS.url(hitboxUrl + streamers.filter(_.hitbox).map(_.streamerName).mkString(",")).get() map { res =>
            res.json.validate[Hitbox.Result] match {
              case JsSuccess(data, _) => data.streamsOnAir(streamers) filter (_.name.toLowerCase contains keyword) take max
              case JsError(err) =>
                logger.warn(s"hitbox ${res.status} $err ${~res.body.lines.toList.headOption}")
                Nil
            }
          }
        }
        val youtube = googleApiKey.nonEmpty ?? {
          WS.url("https://www.googleapis.com/youtube/v3/search").withQueryString(
            "part" -> "snippet",
            "type" -> "video",
            "eventType" -> "live",
            "q" -> keyword,
            "key" -> googleApiKey
          ).get() map { res =>
              res.json.validate[Youtube.Result] match {
                case JsSuccess(data, _) => data.streamsOnAir(streamers) filter (_.name.toLowerCase contains keyword) take max
                case JsError(err) =>
                  logger.warn(s"youtube ${res.status} $err ${~res.body.lines.toList.headOption}")
                  Nil
              }
            }
        }
        (twitch |+| hitbox |+| youtube) map { ss =>
          StreamsOnAir {
{'fraction_non_alphanumeric': 0.13408801020408162, 'fraction_numerical': 0.0009566326530612245, 'mean_word_length': 2.0071907957814, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 45, 'https://': 4, 'lorem ipsum': 0, 'www.': 2, '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': '5090251', 'n_tokens_mistral': 1955, 'n_tokens_neox': 1896, 'n_words': 373}