Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GTFS: Add file storage for gtfs static data downloads #449

Merged
merged 1 commit into from
Dec 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions composeApp/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ kotlin {
implementation(projects.feature.tripPlanner.network)
implementation(projects.feature.tripPlanner.ui)
implementation(projects.feature.tripPlanner.state)
implementation(projects.gtfsStatic)

implementation(libs.navigation.compose)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import org.koin.dsl.includes
import org.koin.dsl.koinConfiguration
import org.koin.dsl.module
import xyz.ksharma.krail.core.appinfo.di.appInfoModule
import xyz.ksharma.krail.gtfs_static.di.fileStorageModule
import xyz.ksharma.krail.gtfs_static.di.gtfsModule
import xyz.ksharma.krail.sandook.di.sandookModule
import xyz.ksharma.krail.splash.SplashViewModel
import xyz.ksharma.krail.trip.planner.network.api.di.networkModule
Expand All @@ -19,6 +21,8 @@ val koinConfig = koinConfiguration {
sandookModule,
splashModule,
appInfoModule,
gtfsModule,
fileStorageModule,
)
}

Expand Down
1 change: 1 addition & 0 deletions feature/trip-planner/ui/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ kotlin {
implementation(projects.feature.tripPlanner.state)
implementation(projects.sandook)
implementation(projects.taj)
implementation(projects.gtfsStatic)

implementation(compose.foundation)
implementation(compose.animation)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ package xyz.ksharma.krail.trip.planner.ui.savedtrips

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.IO
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import xyz.ksharma.krail.gtfs_static.NswGtfsService
import xyz.ksharma.krail.sandook.Sandook
import xyz.ksharma.krail.sandook.SavedTrip
import xyz.ksharma.krail.trip.planner.ui.state.savedtrip.SavedTripUiEvent
Expand All @@ -18,13 +18,17 @@ import xyz.ksharma.krail.trip.planner.ui.state.timetable.Trip

class SavedTripsViewModel(
private val sandook: Sandook,
private val nswGtfsService: NswGtfsService,
) : ViewModel() {

private val _uiState: MutableStateFlow<SavedTripsState> = MutableStateFlow(SavedTripsState())
val uiState: StateFlow<SavedTripsState> = _uiState

private fun loadSavedTrips() {

viewModelScope.launch(context = Dispatchers.IO) {
nswGtfsService.getSydneyTrains()

updateUiState { copy(isLoading = true) }
val trips = mutableSetOf<Trip>()

Expand Down
23 changes: 0 additions & 23 deletions gtfs-static/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
import com.android.build.gradle.internal.cxx.configure.gradleLocalProperties
import com.codingfeline.buildkonfig.compiler.FieldSpec

android {
namespace = "xyz.ksharma.krail.gtfs_static"

Expand All @@ -18,7 +15,6 @@ plugins {
alias(libs.plugins.compose.compiler)
alias(libs.plugins.kotlin.serialization)
alias(libs.plugins.ksp)
alias(libs.plugins.buildkonfig)
}

kotlin {
Expand Down Expand Up @@ -73,22 +69,3 @@ kotlin {
}
}
}

// READ API KEY
val localProperties = gradleLocalProperties(rootProject.rootDir, providers)
val nswTransportApiKey: String = localProperties.getProperty("NSW_TRANSPORT_API_KEY")
?: System.getenv("NSW_TRANSPORT_API_KEY")
require(nswTransportApiKey.isNotEmpty()) {
"Register API key and put in local.properties as `NSW_TRANSPORT_API_KEY`"
}
buildkonfig {
packageName = "xyz.ksharma.krail.trip.planner.network"

require(nswTransportApiKey.isNotEmpty()) {
"Register API key and put in local.properties as `NSW_TRANSPORT_API_KEY`"
}

defaultConfigs {
buildConfigField(FieldSpec.Type.STRING, "NSW_TRANSPORT_API_KEY", nswTransportApiKey)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package xyz.ksharma.krail.gtfs_static

import android.content.Context
import java.io.File

class AndroidFileStorage(private val context: Context) : FileStorage {
override suspend fun saveFile(fileName: String, data: ByteArray) {
val file = File(context.filesDir, fileName)
file.writeBytes(data)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package xyz.ksharma.krail.gtfs_static.di

import org.koin.android.ext.koin.androidContext
import org.koin.dsl.module
import xyz.ksharma.krail.gtfs_static.AndroidFileStorage
import xyz.ksharma.krail.gtfs_static.FileStorage

actual val fileStorageModule = module {
single<FileStorage> {
AndroidFileStorage(context = androidContext())
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package xyz.ksharma.krail.gtfs_static

interface FileStorage {
suspend fun saveFile(fileName: String, data: ByteArray)
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package xyz.ksharma.krail.gtfs_static.di
package xyz.ksharma.krail.gtfs_static

/**
* All other transport modes:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,30 @@
package xyz.ksharma.krail.gtfs_static.di
package xyz.ksharma.krail.gtfs_static

import io.ktor.client.HttpClient
import io.ktor.client.request.get
import io.ktor.client.statement.HttpResponse
import io.ktor.client.statement.readRawBytes
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.IO
import kotlinx.coroutines.withContext

class RealNswGtfsService(private val httpClient: HttpClient) : NswGtfsService {
class RealNswGtfsService(
private val httpClient: HttpClient,
private val fileStorage: FileStorage,
) : NswGtfsService {

override suspend fun getSydneyTrains() = withContext(Dispatchers.IO) {
val response: HttpResponse =
httpClient.get("$NSW_TRANSPORT_BASE_URL/$GTFS_SCHEDULE_V1/sydneytrains")

if (response.status.value == 200) {
println("Downloading file: ")
val data = response.readRawBytes()
fileStorage.saveFile("sydneytrains.zip", data)
println("File downloaded")
} else {
throw Exception("Failed to download file: ${response.status}")
}
}

override suspend fun getSydneyMetro() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
package xyz.ksharma.krail.gtfs_static.di

import org.koin.core.module.Module
import org.koin.core.module.dsl.bind
import org.koin.core.module.dsl.singleOf
import org.koin.dsl.module
import xyz.ksharma.krail.gtfs_static.NswGtfsService
import xyz.ksharma.krail.gtfs_static.RealNswGtfsService

val gtfsModule = module {

singleOf(::RealNswGtfsService) { bind<NswGtfsService>() }
}

expect val fileStorageModule: Module
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package xyz.ksharma.krail.gtfs_static

import kotlinx.cinterop.ExperimentalForeignApi
import kotlinx.cinterop.addressOf
import kotlinx.cinterop.usePinned
import platform.Foundation.NSData
import platform.Foundation.NSDocumentDirectory
import platform.Foundation.NSFileManager
import platform.Foundation.NSUserDomainMask
import platform.Foundation.dataWithBytes
import platform.Foundation.writeToFile

class IosFileStorage : FileStorage {
@OptIn(ExperimentalForeignApi::class)
override suspend fun saveFile(fileName: String, data: ByteArray) {
println("Saving file: $fileName")
val fileManager = NSFileManager.defaultManager
val directory = fileManager.URLForDirectory(
directory = NSDocumentDirectory,
inDomain = NSUserDomainMask,
appropriateForURL = null,
create = true,
error = null,
)?.path

val filePath = "$directory/$fileName"
data.usePinned { pinned ->
NSData.dataWithBytes(pinned.addressOf(0), data.size.toULong())
.writeToFile(filePath, true)
}
println("File saved: $filePath")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package xyz.ksharma.krail.gtfs_static.di

import org.koin.dsl.module
import xyz.ksharma.krail.gtfs_static.FileStorage
import xyz.ksharma.krail.gtfs_static.IosFileStorage

actual val fileStorageModule = module {
single<FileStorage> {
IosFileStorage()
}
}
Loading