Files
WeatherTool/src/main/scala/fetch/FetchService.scala
T

72 lines
2.4 KiB
Scala
Raw Normal View History

package fetch
import cats.effect._
import cats.implicits._
import org.http4s._
import org.http4s.client.Client
import org.http4s.headers.Authorization
2023-05-17 01:20:01 +03:00
import org.http4s.ember.client.EmberClientBuilder
2023-05-16 14:54:02 +03:00
import pureconfig._
import pureconfig.generic.auto._
import java.time.{LocalDate, LocalDateTime}
import scala.concurrent.ExecutionContext.global
2023-05-16 14:54:02 +03:00
final case class WeatherServerConfig(
username: String,
password: String,
url: String,
)
object FetchService {
2023-05-16 14:54:02 +03:00
private val weatherServerConfig: WeatherServerConfig = ConfigSource.default.load[WeatherServerConfig] match {
case Right(config) => config
case Left(errors) => throw new RuntimeException(s"Unable to load config: $errors")
}
2023-05-01 16:43:21 +03:00
2023-05-16 14:54:02 +03:00
private val basicCredentials: BasicCredentials =
BasicCredentials(weatherServerConfig.username, weatherServerConfig.password)
2023-05-01 16:43:21 +03:00
2023-05-16 14:54:02 +03:00
private val baseUrl: IO[Uri] = IO(Uri.unsafeFromString(weatherServerConfig.url))
private def makeRequest(client: Client[IO], url: Uri): IO[Either[Throwable, (String, String)]] = {
val fileName = url.path.toString()
2023-05-16 14:54:02 +03:00
val request = Request[IO](Method.GET, url).withHeaders(Authorization(basicCredentials))
2023-05-01 16:43:21 +03:00
2023-05-16 14:54:02 +03:00
client.expect[String](request).redeemWith(
error => IO(Left(error))
2023-05-01 16:43:21 +03:00
// .flatTap(_ => IO.println(s"Request failed to url: $url with error: ${error.getMessage}")),
,
fileContent => IO(Right((fileName, fileContent)))
2023-05-01 16:43:21 +03:00
// .flatTap(_ => IO.println(s"Fetched: $fileName"))
)
}
private def fetchFiles(fileNames: List[String]): IO[List[Either[Throwable, (String, String)]]] = {
2023-05-16 14:54:02 +03:00
val IOUrls = baseUrl.map(baseUrl => fileNames.map(baseUrl / _))
2023-05-17 01:20:01 +03:00
EmberClientBuilder.default[IO].build.use { client =>
2023-05-01 16:43:21 +03:00
IOUrls.flatMap(_.traverse(url => makeRequest(client, url)))
}
}
def fetchSingleFile(fileName: String): IO[(String, String)] = {
fetchFiles(List(fileName)).flatMap { results =>
results.headOption match {
case Some(Right(result)) => IO.pure(result)
case Some(Left(err)) => IO.raiseError(err)
case None => IO.raiseError(new Exception("No file fetched"))
}
}
}
def fetchInRange(from: LocalDateTime, to: LocalDateTime): IO[List[Either[Throwable, (String, String)]]] = {
val fileNames = FileNameService.generate(from, to)
fetchFiles(fileNames)
}
def fetchFromDate(date: LocalDate): IO[List[Either[Throwable, (String, String)]]] = {
val fileNames = FileNameService.generateFromDate(date)
fetchFiles(fileNames)
}
}