diff --git a/src/main/scala/db/DBService.scala b/src/main/scala/db/DBService.scala index 56cf8f3..4c5f0c4 100644 --- a/src/main/scala/db/DBService.scala +++ b/src/main/scala/db/DBService.scala @@ -2,6 +2,8 @@ package db import cats.effect.{IO, Resource} import cats.implicits.toTraverseOps +import org.typelevel.log4cats.Logger +import org.typelevel.log4cats.slf4j.Slf4jLogger import java.io.File import java.nio.file.{Files, Paths} @@ -11,6 +13,12 @@ import scala.io.Source import scala.util.Try object DBService { + def of: IO[DBService] = { + Slf4jLogger.create[IO].map(logger => new DBService(logger)) + } +} + +class DBService(log: Logger[IO]) { private val dateFormatter = DateTimeFormatter.ofPattern("yyyyMMdd_HHmm") private val dataPath = "./data" diff --git a/src/main/scala/db/Main.scala b/src/main/scala/db/Main.scala index 6a3b36e..8a7096b 100644 --- a/src/main/scala/db/Main.scala +++ b/src/main/scala/db/Main.scala @@ -3,7 +3,6 @@ package db import cats.effect.IO import cats.effect.unsafe.implicits.global import cats.implicits.toTraverseOps -import db.DBService import java.time.{LocalDate, LocalDateTime} import java.time.format.DateTimeFormatter @@ -16,21 +15,24 @@ object Main { val to = LocalDateTime.parse("20230501_1230", dateFormatter) for { - lines <- DBService.getInRange(from, to) + dbService <- DBService.of + lines <- dbService.getInRange(from, to) _ <- lines.traverse(IO.println) } yield () } private def testGetDates: IO[Unit] = { for { - dates <- DBService.getDates() + dbService <- DBService.of + dates <- dbService.getDates() _ <- IO.println(dates) } yield () } private def testGetDate: IO[Unit] = { for { - dates <- DBService.getDateFileNames(LocalDate.of(2023, 4, 23)) + dbService <- DBService.of + dates <- dbService.getDateFileNames(LocalDate.of(2023, 4, 23)) _ <- IO.println(dates) } yield () } diff --git a/src/main/scala/fetch/Main.scala b/src/main/scala/fetch/Main.scala index e7aeb0f..a98a767 100644 --- a/src/main/scala/fetch/Main.scala +++ b/src/main/scala/fetch/Main.scala @@ -5,7 +5,7 @@ import cats.effect.unsafe.implicits.global import cats.implicits.toTraverseOps import db.DBService -import java.time.{LocalDate, LocalDateTime} +import java.time.LocalDateTime object Main { def run: IO[Unit] = { @@ -17,7 +17,8 @@ object Main { fetchServiceError = fetchResultEither.left.toOption.map(e => s"FetchServiceError: ${e.getMessage}").toList fetchResult = fetchResultEither.getOrElse(List.empty) (fetchErrors, successDownloads) = fetchResult.partitionMap(identity) - saveResults <- successDownloads.traverse { case (name, content) => DBService.save(name, content) } + dbService <- DBService.of + saveResults <- successDownloads.traverse { case (name, content) => dbService.save(name, content) } (saveErrors, successSaves) = saveResults.partitionMap(identity) successes = successDownloads.map(s => s"fetched: ${s._1}") ++ successSaves.map(s => s"saved: $s") errors = fetchServiceError ++ fetchErrors.map(e => s"FetchError: ${e.getMessage}") ++ saveErrors.map(e => s"SaveError: ${e.getMessage}") diff --git a/src/main/scala/parse/Main.scala b/src/main/scala/parse/Main.scala index 69cfbc4..a4f7d06 100644 --- a/src/main/scala/parse/Main.scala +++ b/src/main/scala/parse/Main.scala @@ -2,6 +2,7 @@ package parse import cats.effect.IO import cats.effect.unsafe.implicits.global +import db.DBService import io.circe.syntax.EncoderOps import parse.Aggregate.AggregateValueImplicits.aggregateValueEncoder import parse.Aggregate.{AggregateKey, UserQuery} @@ -19,7 +20,8 @@ object Main { val userQuery = UserQuery(List("Rīga"), "tempAvg", AggregateKey.List) for { - lines <- db.DBService.getInRange(from, to) + dbService <- DBService.of + lines <- dbService.getInRange(from, to) parsed <- IO.pure(Parser.queryData(userQuery, lines)) _ <- IO.println(parsed.asJson) } yield () diff --git a/src/main/scala/server/Main.scala b/src/main/scala/server/Main.scala index b5ef801..c06e682 100644 --- a/src/main/scala/server/Main.scala +++ b/src/main/scala/server/Main.scala @@ -6,19 +6,21 @@ import fetch.{FetchService, FileNameService} object Main extends IOApp { def run(args: List[String]): IO[ExitCode] = { - // TODO looks like fetchTask fails server if no csv on meteo server - val fetchTask = FileNameService.generateCurrentHour.flatMap(FetchService.fetchSingleFile) - val scheduler = Scheduler.scheduleTask(fetchTask) - .evalMap { case (name, content) => - IO(println(s"fetched: $name")) *> - DBService.save(name, content).attempt.flatMap { - case Right(savedName) => IO(println(s"File saved: $savedName")) - case Left(err) => IO(println(s"Error: $err")) - } - }.compile.drain // Convert Stream[IO, Unit] to IO[Unit] + for { + dbService <- DBService.of + fetchTask = FileNameService.generateCurrentHour.flatMap(FetchService.fetchSingleFile) + scheduler = Scheduler.scheduleTask(fetchTask) + .evalMap { case (name, content) => + IO(println(s"fetched: $name")) *> + dbService.save(name, content).attempt.flatMap { + case Right(savedName) => IO(println(s"File saved: $savedName")) + case Left(err) => IO(println(s"Error: $err")) + } + }.compile.drain // Convert Stream[IO, Unit] to IO[Unit] - val server = Server.run // This is an IO[Server] + server = Server.run // This is an IO[Server] - (server, scheduler).parMapN((_, _) => ExitCode.Success) + exitCode <- (server, scheduler).parMapN((_, _) => ExitCode.Success) + } yield exitCode } } \ No newline at end of file diff --git a/src/main/scala/server/Server.scala b/src/main/scala/server/Server.scala index 7b862ba..fc6fb6e 100644 --- a/src/main/scala/server/Server.scala +++ b/src/main/scala/server/Server.scala @@ -38,9 +38,9 @@ object Server { // http://0.0.0.0:8080/api/query/20230414_2200-20230501_1230/Liepāja,Rēzekne/tempMax/max case GET -> Root / "query" / DateTimeRange(from, to) / CityList(cities) / field / AggKey(key) => - DBService.getInRange(from, to) + DBService.of.flatMap(_.getInRange(from, to) .map(Parser.queryData(UserQuery(cities, field, key), _)) - .flatMap(result => Ok(result.asJson.pretty)) + .flatMap(result => Ok(result.asJson.pretty))) // http://0.0.0.0:8080/api/fetch/date/20230514 case GET -> Root / "fetch" / "date" / ValidDate(date) => @@ -49,7 +49,8 @@ object Server { fetchServiceError = fetchResultEither.left.toOption.map(e => s"FetchServiceError: ${e.getMessage}").toList fetchResult = fetchResultEither.getOrElse(List.empty) (fetchErrors, successDownloads) = fetchResult.partitionMap(identity) - saveResults <- successDownloads.traverse { case (name, content) => DBService.save(name, content) } + dbService <- DBService.of + saveResults <- successDownloads.traverse { case (name, content) => dbService.save(name, content) } (saveErrors, successSaves) = saveResults.partitionMap(identity) // successes = successDownloads.map(s => s"fetched: ${s._1}") ++ successSaves.map(s => s"saved: $s") successes = successSaves @@ -67,19 +68,19 @@ object Server { // http://0.0.0.0:8080/api/show/all_dates case GET -> Root / "show" / "all_dates" => - DBService.getDates().flatMap(dates => + DBService.of.flatMap(_.getDates().flatMap(dates => Ok(dates.asJson.pretty) - ) + )) // http://0.0.0.0:8080/api/show/date/20230423 case GET -> Root / "show" / "date" / ValidDate(date) => - DBService.getDateFileNames(date).flatMap(fileNames => + DBService.of.flatMap(_.getDateFileNames(date).flatMap(fileNames => Ok(fileNames.asJson.pretty) - ) + )) // http://0.0.0.0:8080/api/show/file/20230423_12:30.csv case GET -> Root / "show" / "file" / (fileName: String) => - DBService.getFileContent(fileName).flatMap(Ok(_)) + DBService.of.flatMap(_.getFileContent(fileName).flatMap(Ok(_))) // http://0.0.0.0:8080/api/help case GET -> Root / "help" => {