2023-04-23 22:41:38 +03:00
|
|
|
package fetch
|
|
|
|
|
|
|
|
|
|
import cats.effect._
|
|
|
|
|
import cats.implicits._
|
|
|
|
|
import org.http4s._
|
|
|
|
|
import org.http4s.blaze.client.BlazeClientBuilder
|
|
|
|
|
import org.http4s.client.Client
|
|
|
|
|
import org.http4s.headers.Authorization
|
|
|
|
|
import com.typesafe.config.ConfigFactory
|
|
|
|
|
|
|
|
|
|
import java.time.{LocalDate, LocalDateTime}
|
|
|
|
|
import scala.concurrent.ExecutionContext.global
|
|
|
|
|
|
|
|
|
|
object FetchService {
|
|
|
|
|
private val config = ConfigFactory.load()
|
2023-05-01 16:43:21 +03:00
|
|
|
private def getIOString(path: String): IO[String] =
|
|
|
|
|
if (config.hasPath(path)) IO.pure(config.getString(path))
|
|
|
|
|
else IO.raiseError(new RuntimeException(s"Missing configuration: $path"))
|
|
|
|
|
|
|
|
|
|
private val basicCredentialsIO: IO[BasicCredentials] =
|
|
|
|
|
for {
|
|
|
|
|
username <- getIOString("username")
|
|
|
|
|
password <- getIOString("password")
|
|
|
|
|
} yield BasicCredentials(username, password)
|
|
|
|
|
|
|
|
|
|
private val baseUrlIO: IO[Uri] = getIOString("url").map(Uri.unsafeFromString) // 20220831_1330.csv
|
2023-04-23 22:41:38 +03:00
|
|
|
|
|
|
|
|
private def makeRequest(client: Client[IO], url: Uri): IO[Either[Throwable, (String, String)]] = {
|
|
|
|
|
val fileName = url.path.toString()
|
2023-05-01 16:43:21 +03:00
|
|
|
|
2023-04-23 22:41:38 +03:00
|
|
|
for {
|
2023-05-01 16:43:21 +03:00
|
|
|
basicCredentials <- basicCredentialsIO
|
|
|
|
|
request = Request[IO](Method.GET, url).withHeaders(Authorization(basicCredentials))
|
2023-04-23 22:41:38 +03:00
|
|
|
result <- 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}")),
|
2023-04-23 22:41:38 +03:00
|
|
|
,
|
|
|
|
|
fileContent => IO(Right((fileName, fileContent)))
|
2023-05-01 16:43:21 +03:00
|
|
|
// .flatTap(_ => IO.println(s"Fetched: $fileName"))
|
2023-04-23 22:41:38 +03:00
|
|
|
)
|
|
|
|
|
} yield result
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private def fetchFiles(fileNames: List[String]): IO[List[Either[Throwable, (String, String)]]] = {
|
2023-05-01 16:43:21 +03:00
|
|
|
val IOUrls = baseUrlIO.map(baseUrl => fileNames.map(baseUrl / _))
|
2023-04-23 22:41:38 +03:00
|
|
|
BlazeClientBuilder[IO](global).resource.use { client =>
|
2023-05-01 16:43:21 +03:00
|
|
|
IOUrls.flatMap(_.traverse(url => makeRequest(client, url)))
|
2023-04-23 22:41:38 +03:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-14 15:48:52 +03:00
|
|
|
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"))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-23 22:41:38 +03:00
|
|
|
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)
|
|
|
|
|
}
|
|
|
|
|
}
|