Page Menu
Home
GitPull.it
Search
Configure Global Search
Log In
Files
F11477671
D122.1773923409.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Size
30 KB
Referenced Files
None
Subscribers
None
D122.1773923409.diff
View Options
diff --git a/app/src/main/java/it/reyboz/bustorino/backend/Notifications.java b/app/src/main/java/it/reyboz/bustorino/backend/Notifications.java
--- a/app/src/main/java/it/reyboz/bustorino/backend/Notifications.java
+++ b/app/src/main/java/it/reyboz/bustorino/backend/Notifications.java
@@ -1,9 +1,11 @@
package it.reyboz.bustorino.backend;
+import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.os.Build;
+import androidx.core.app.NotificationCompat;
import it.reyboz.bustorino.R;
public class Notifications {
@@ -44,4 +46,35 @@
notificationManager.createNotificationChannel(channel);
}
}
+
+
+ public static Notification makeMatoDownloadNotification(Context context,String title){
+ return new NotificationCompat.Builder(context, Notifications.DB_UPDATE_CHANNELS_ID)
+ //.setContentIntent(PendingIntent.getActivity(context, 0, Intent(context, MainActivity::class.java), Constants.PENDING_INTENT_FLAG_IMMUTABLE))
+ .setSmallIcon(R.drawable.bus)
+ .setOngoing(true)
+ .setAutoCancel(true)
+ .setOnlyAlertOnce(true)
+ .setPriority(NotificationCompat.PRIORITY_MIN)
+ .setContentTitle(context.getString(R.string.app_name))
+ .setLocalOnly(true)
+ .setVisibility(NotificationCompat.VISIBILITY_SECRET)
+ .setContentText(title)
+ .build();
+ }
+ public static Notification makeMatoDownloadNotification(Context context){
+ return makeMatoDownloadNotification(context, "Downloading data from MaTO");
+ }
+
+ public static void createDBNotificationChannel(Context context){
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ NotificationChannel channel = new NotificationChannel(
+ Notifications.DB_UPDATE_CHANNELS_ID,
+ context.getString(R.string.database_notification_channel),
+ NotificationManager.IMPORTANCE_MIN
+ );
+ NotificationManager notificationManager = context.getSystemService(NotificationManager.class);
+ notificationManager.createNotificationChannel(channel);
+ }
+ }
}
diff --git a/app/src/main/java/it/reyboz/bustorino/backend/mato/MatoAPIFetcher.kt b/app/src/main/java/it/reyboz/bustorino/backend/mato/MatoAPIFetcher.kt
--- a/app/src/main/java/it/reyboz/bustorino/backend/mato/MatoAPIFetcher.kt
+++ b/app/src/main/java/it/reyboz/bustorino/backend/mato/MatoAPIFetcher.kt
@@ -408,22 +408,7 @@
res?.set(Fetcher.Result.PARSER_ERROR)
//Log.e(DEBUG_TAG, "Downloading feeds: $outObj")
}
- /*
- var numRequests = 0
- for(routeName in routesGTFSIds){
- if (!routeName.isEmpty()) numRequests++
- }
- val countDownForRequests = CountDownLatch(numRequests)
- val lockSave = ReentrantLock()
- //val countDownFor
- for (routeName in routesGTFSIds){
- val pars = JSONObject()
- pars.put("")
- }
- val goodResponseListener = Response.Listener<JSONObject> { }
- val errorResponseListener = Response.ErrorListener { }
- */
return patterns
}
diff --git a/app/src/main/java/it/reyboz/bustorino/backend/mato/MatoQueries.kt b/app/src/main/java/it/reyboz/bustorino/backend/mato/MatoQueries.kt
--- a/app/src/main/java/it/reyboz/bustorino/backend/mato/MatoQueries.kt
+++ b/app/src/main/java/it/reyboz/bustorino/backend/mato/MatoQueries.kt
@@ -118,7 +118,7 @@
}
}
"""
-
+ //Query for the patterns, with the associated route
const val ROUTES_WITH_PATTERNS="""
query RoutesWithPatterns(${'$'}routes: [String]) {
routes(ids: ${'$'}routes) {
diff --git a/app/src/main/java/it/reyboz/bustorino/data/DatabaseUpdate.java b/app/src/main/java/it/reyboz/bustorino/data/DatabaseUpdate.java
--- a/app/src/main/java/it/reyboz/bustorino/data/DatabaseUpdate.java
+++ b/app/src/main/java/it/reyboz/bustorino/data/DatabaseUpdate.java
@@ -31,7 +31,6 @@
import it.reyboz.bustorino.backend.Fetcher;
import it.reyboz.bustorino.backend.FiveTAPIFetcher;
import it.reyboz.bustorino.backend.Palina;
-import it.reyboz.bustorino.backend.Route;
import it.reyboz.bustorino.backend.mato.MatoAPIFetcher;
import it.reyboz.bustorino.data.gtfs.GtfsAgency;
import it.reyboz.bustorino.data.gtfs.GtfsDatabase;
@@ -126,7 +125,9 @@
}
//match patterns with routes
- final ArrayList<PatternStop> patternStops = new ArrayList<>(patterns.size());
+ final ArrayList<PatternStop> patternStops = makeStopsForPatterns(patterns);
+ final List<String> allPatternsCodeInDB = dao.getPatternsCodes();
+ final HashSet<String> patternsCodesToDelete = new HashSet<>(allPatternsCodeInDB);
for(MatoPattern p: patterns){
//scan patterns
@@ -135,25 +136,47 @@
if (mRoute == null) {
Log.e(DEBUG_TAG, "Error in parsing the route: " + p.getRouteGtfsId() + " , cannot find the IDs in the map");
}
- for (int i=0; i<stopsIDs.size(); i++){
- final String ID = stopsIDs.get(i);
- patternStops.add(new PatternStop(p.getCode(),ID, i));
+ for (final String sID : stopsIDs) {
+ //add stops to pattern stops
// save routes stopping in the stop
-
- if (!routesStoppingInStop.containsKey(ID)){
- routesStoppingInStop.put(ID, new HashSet<>());
+ if (!routesStoppingInStop.containsKey(sID)) {
+ routesStoppingInStop.put(sID, new HashSet<>());
}
- Set<String> mset= routesStoppingInStop.get(ID);
+ Set<String> mset = routesStoppingInStop.get(sID);
assert mset != null;
mset.add(mRoute.getShortName());
}
+ //finally, remove from deletion list
+ patternsCodesToDelete.remove(p.getCode());
}
+ // final time for insert
dao.insertPatterns(patterns);
+ // clear patterns that are unused
+ Log.d(DEBUG_TAG, "Have to remove "+patternsCodesToDelete.size()+ " patterns from the DB");
+ dao.deletePatternsWithCodes(new ArrayList<>(patternsCodesToDelete));
dao.insertPatternStops(patternStops);
return routesStoppingInStop;
}
+ /**
+ * Make the list of stops that each pattern does, to be inserted into the DB
+ * @param patterns the MatoPattern
+ * @return a list of PatternStop
+ */
+ public static ArrayList<PatternStop> makeStopsForPatterns(List<MatoPattern> patterns){
+ final ArrayList<PatternStop> patternStops = new ArrayList<>(patterns.size());
+ for (MatoPattern p: patterns){
+ final ArrayList<String> stopsIDs = p.getStopsGtfsIDs();
+ for (int i=0; i<stopsIDs.size(); i++) {
+ //add stops to pattern stops
+ final String ID = stopsIDs.get(i);
+ patternStops.add(new PatternStop(p.getCode(), ID, i));
+ }
+ }
+ return patternStops;
+ }
+
/**
* Run the DB Update
diff --git a/app/src/main/java/it/reyboz/bustorino/data/MatoPatternsDownloadWorker.kt b/app/src/main/java/it/reyboz/bustorino/data/MatoPatternsDownloadWorker.kt
new file mode 100644
--- /dev/null
+++ b/app/src/main/java/it/reyboz/bustorino/data/MatoPatternsDownloadWorker.kt
@@ -0,0 +1,101 @@
+/*
+ BusTO - Data components
+ Copyright (C) 2023 Fabio Mazza
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package it.reyboz.bustorino.data
+
+import android.app.NotificationManager
+import android.content.Context
+import android.util.Log
+import androidx.work.*
+import it.reyboz.bustorino.backend.Fetcher
+import it.reyboz.bustorino.backend.Notifications
+import it.reyboz.bustorino.backend.mato.MatoAPIFetcher
+import java.util.concurrent.atomic.AtomicReference
+
+class MatoPatternsDownloadWorker(appContext: Context, workerParams: WorkerParameters)
+ : CoroutineWorker(appContext, workerParams) {
+
+
+ override suspend fun doWork(): Result {
+ val routesList = inputData.getStringArray(ROUTES_KEYS)
+
+ if (routesList== null){
+ Log.e(DEBUG_TAG,"routes list given is null")
+ return Result.failure()
+ }
+
+ val res = AtomicReference<Fetcher.Result>(Fetcher.Result.OK)
+
+ val gtfsRepository = GtfsRepository(applicationContext)
+ val patterns = MatoAPIFetcher.getPatternsWithStops(applicationContext, routesList.asList().toMutableList(), res)
+ if (res.get() != Fetcher.Result.OK) {
+ Log.e(DatabaseUpdate.DEBUG_TAG, "Something went wrong downloading patterns")
+ return Result.failure()
+ }
+
+ gtfsRepository.gtfsDao.insertPatterns(patterns)
+ //Insert the PatternStops
+ gtfsRepository.gtfsDao.insertPatternStops(DatabaseUpdate.makeStopsForPatterns(patterns))
+ return Result.success()
+ }
+
+
+ override suspend fun getForegroundInfo(): ForegroundInfo {
+ val notificationManager =
+ applicationContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
+ val context = applicationContext
+ Notifications.createDBNotificationChannel(context)
+
+ return ForegroundInfo(NOTIFICATION_ID, Notifications.makeMatoDownloadNotification(context))
+ }
+
+
+ companion object{
+ const val ROUTES_KEYS = "routesToDownload"
+ const val DEBUG_TAG="BusTO:MatoPattrnDownWRK"
+ const val NOTIFICATION_ID=21983102
+
+ const val TAG_PATTERNS ="matoPatternsDownload"
+
+
+
+ fun downloadPatternsForRoutes(routesIds: List<String>, context: Context): Boolean{
+ if(routesIds.isEmpty()) return false;
+
+ val workManager = WorkManager.getInstance(context);
+ val info = workManager.getWorkInfosForUniqueWork(TAG_PATTERNS).get()
+
+ val runNewWork = if(info.isEmpty()) true
+ else info[0].state!= WorkInfo.State.RUNNING && info[0].state!= WorkInfo.State.ENQUEUED
+ val addDat = if(info.isEmpty())
+ null else info[0].state
+
+ Log.d(DEBUG_TAG, "Request to download and insert patterns for ${routesIds.size} routes, proceed: $runNewWork, workstate: $addDat")
+ if(runNewWork){
+ val routeIdsArray = routesIds.toTypedArray()
+ val dataBuilder = Data.Builder().putStringArray(ROUTES_KEYS,routeIdsArray)
+
+ val requ = OneTimeWorkRequest.Builder(MatoPatternsDownloadWorker::class.java)
+ .setInputData(dataBuilder.build()).setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)
+ .addTag(TAG_PATTERNS)
+ .build()
+ workManager.enqueueUniqueWork(TAG_PATTERNS, ExistingWorkPolicy.KEEP, requ)
+ }
+ return true
+ }
+ }
+}
diff --git a/app/src/main/java/it/reyboz/bustorino/data/MatoDownloadTripsWorker.kt b/app/src/main/java/it/reyboz/bustorino/data/MatoTripsDownloadWorker.kt
rename from app/src/main/java/it/reyboz/bustorino/data/MatoDownloadTripsWorker.kt
rename to app/src/main/java/it/reyboz/bustorino/data/MatoTripsDownloadWorker.kt
--- a/app/src/main/java/it/reyboz/bustorino/data/MatoDownloadTripsWorker.kt
+++ b/app/src/main/java/it/reyboz/bustorino/data/MatoTripsDownloadWorker.kt
@@ -17,32 +17,26 @@
*/
package it.reyboz.bustorino.data
-import android.app.NotificationChannel
import android.app.NotificationManager
-import android.app.PendingIntent
import android.content.Context
-import android.content.Intent
-import android.os.Build
import android.util.Log
-import androidx.core.app.NotificationCompat
-import androidx.lifecycle.viewModelScope
-import androidx.work.CoroutineWorker
-import androidx.work.ForegroundInfo
-import androidx.work.Worker
-import androidx.work.WorkerParameters
-import com.android.volley.Response
-import it.reyboz.bustorino.R
+import androidx.work.*
import it.reyboz.bustorino.backend.Notifications
import it.reyboz.bustorino.data.gtfs.GtfsTrip
-import kotlinx.coroutines.launch
import java.util.concurrent.CountDownLatch
-class MatoDownloadTripsWorker(appContext: Context, workerParams: WorkerParameters)
+class MatoTripsDownloadWorker(appContext: Context, workerParams: WorkerParameters)
: CoroutineWorker(appContext, workerParams) {
+
override suspend fun doWork(): Result {
- //val imageUriInput =
- // inputData.("IMAGE_URI") ?: return Result.failure()
+ return downloadGtfsTrips()
+ }
+
+ /**
+ * Download GTFS Trips from Mato
+ */
+ private fun downloadGtfsTrips():Result{
val tripsList = inputData.getStringArray(TRIPS_KEYS)
if (tripsList== null){
@@ -80,7 +74,7 @@
}
Log.i(
DEBUG_TAG,"Result download, so far, trips: ${queriedMatoTrips.size}, failed: ${failedMatoTripsDownload.size}," +
- " succeded: ${downloadedMatoTrips.size}")
+ " succeded: ${downloadedMatoTrips.size}")
//check if we can insert the trips
requestCountDown.countDown()
}
@@ -102,35 +96,40 @@
val notificationManager =
applicationContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val context = applicationContext
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
- val channel = NotificationChannel(
- Notifications.DB_UPDATE_CHANNELS_ID,
- context.getString(R.string.database_notification_channel),
- NotificationManager.IMPORTANCE_MIN
- )
- notificationManager.createNotificationChannel(channel)
- }
+ Notifications.createDBNotificationChannel(context)
- val notification = NotificationCompat.Builder(context, Notifications.DB_UPDATE_CHANNELS_ID)
- //.setContentIntent(PendingIntent.getActivity(context, 0, Intent(context, MainActivity::class.java), Constants.PENDING_INTENT_FLAG_IMMUTABLE))
- .setSmallIcon(R.drawable.bus)
- .setOngoing(true)
- .setAutoCancel(true)
- .setOnlyAlertOnce(true)
- .setPriority(NotificationCompat.PRIORITY_MIN)
- .setContentTitle(context.getString(R.string.app_name))
- .setLocalOnly(true)
- .setVisibility(NotificationCompat.VISIBILITY_SECRET)
- .setContentText("Downloading data")
- .build()
- return ForegroundInfo(NOTIFICATION_ID, notification)
+ return ForegroundInfo(NOTIFICATION_ID, Notifications.makeMatoDownloadNotification(context))
}
companion object{
const val TRIPS_KEYS = "tripsToDownload"
- const val WORK_TAG = "tripsDownloaderAndInserter"
const val DEBUG_TAG="BusTO:MatoTripDownWRK"
- const val NOTIFICATION_ID=424242
+ const val NOTIFICATION_ID=42424221
+
+ const val TAG_TRIPS ="gtfsTripsDownload"
+
+ fun downloadTripsFromMato(trips: List<String>, context: Context, debugTag: String): Boolean{
+ if (trips.isEmpty()) return false
+ val workManager = WorkManager.getInstance(context)
+ val info = workManager.getWorkInfosForUniqueWork(TAG_TRIPS).get()
+
+ val runNewWork = if(info.isEmpty()) true
+ else info[0].state!= WorkInfo.State.RUNNING && info[0].state!= WorkInfo.State.ENQUEUED
+ val addDat = if(info.isEmpty())
+ null else info[0].state
+ Log.d(debugTag, "Request to download and insert ${trips.size} trips, proceed: $runNewWork, workstate: $addDat")
+ if(runNewWork) {
+ val tripsArr = trips.toTypedArray()
+ val dataBuilder = Data.Builder().putStringArray(TRIPS_KEYS, tripsArr)
+ //build()
+ val requ = OneTimeWorkRequest.Builder(MatoTripsDownloadWorker::class.java)
+ .setInputData(dataBuilder.build()).setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)
+ .addTag(TAG_TRIPS)
+ .build()
+ workManager.enqueueUniqueWork(TAG_TRIPS, ExistingWorkPolicy.KEEP, requ)
+ }
+ return true
+ }
}
}
diff --git a/app/src/main/java/it/reyboz/bustorino/data/gtfs/GtfsDBDao.kt b/app/src/main/java/it/reyboz/bustorino/data/gtfs/GtfsDBDao.kt
--- a/app/src/main/java/it/reyboz/bustorino/data/gtfs/GtfsDBDao.kt
+++ b/app/src/main/java/it/reyboz/bustorino/data/gtfs/GtfsDBDao.kt
@@ -48,6 +48,8 @@
@Query("SELECT * FROM ${GtfsRoute.DB_TABLE} WHERE ${GtfsRoute.COL_AGENCY_ID} LIKE :agencyID")
fun getRoutesByAgency(agencyID:String) : LiveData<List<GtfsRoute>>
+ @Query("SELECT ${MatoPattern.COL_CODE} FROM ${MatoPattern.TABLE_NAME} ")
+ fun getPatternsCodes(): List<String>
@Query("SELECT * FROM ${MatoPattern.TABLE_NAME} WHERE ${MatoPattern.COL_ROUTE_ID} LIKE :routeID")
fun getPatternsLiveDataByRouteID(routeID: String): LiveData<List<MatoPattern>>
@@ -65,6 +67,9 @@
@Query("SELECT * FROM ${MatoPattern.TABLE_NAME} WHERE ${MatoPattern.COL_CODE} IN (:patternGtfsIDs)")
fun getPatternsWithStopsFromIDs(patternGtfsIDs: List<String>) : LiveData<List<MatoPatternWithStops>>
+ @Query("SELECT ${MatoPattern.COL_CODE} FROM ${MatoPattern.TABLE_NAME} WHERE ${MatoPattern.COL_CODE} IN (:codes)")
+ fun getPatternsCodesInTheDB(codes: List<String>): List<String>
+
@Transaction
@Query("SELECT * FROM ${GtfsTrip.DB_TABLE} WHERE ${GtfsTrip.COL_TRIP_ID} IN (:tripsIds)")
fun getTripsFromIDs(tripsIds: List<String>) : List<GtfsTrip>
@@ -73,10 +78,14 @@
@Query("SELECT * FROM ${GtfsTrip.DB_TABLE} WHERE ${GtfsTrip.COL_TRIP_ID} IN (:trips)")
fun getTripPatternStops(trips: List<String>): LiveData<List<TripAndPatternWithStops>>
+
+
fun getRoutesForFeed(feed:String): LiveData<List<GtfsRoute>>{
val agencyID = "${feed}:%"
return getRoutesByAgency(agencyID)
}
+
+
@Transaction
fun clearAndInsertRoutes(routes: List<GtfsRoute>){
deleteAllRoutes()
@@ -111,6 +120,9 @@
fun deleteAllStops()
@Query("DELETE FROM "+GtfsTrip.DB_TABLE)
fun deleteAllTrips()
+
+ @Query("DELETE FROM ${MatoPattern.TABLE_NAME} WHERE ${MatoPattern.COL_CODE} IN (:codes)")
+ fun deletePatternsWithCodes(codes: List<String>): Int
@Update(onConflict = OnConflictStrategy.REPLACE)
fun updateShapes(shapes: List<GtfsShape>) : Int
diff --git a/app/src/main/java/it/reyboz/bustorino/data/gtfs/GtfsTrip.kt b/app/src/main/java/it/reyboz/bustorino/data/gtfs/GtfsTrip.kt
--- a/app/src/main/java/it/reyboz/bustorino/data/gtfs/GtfsTrip.kt
+++ b/app/src/main/java/it/reyboz/bustorino/data/gtfs/GtfsTrip.kt
@@ -120,7 +120,7 @@
parentColumn = GtfsTrip.COL_PATTERN_ID,
entityColumn = MatoPattern.COL_CODE
)
- val pattern: MatoPattern,
+ val pattern: MatoPattern?,
@Relation(
parentColumn = MatoPattern.COL_CODE,
entityColumn = PatternStop.COL_PATTERN_ID,
diff --git a/app/src/main/java/it/reyboz/bustorino/fragments/MapFragment.java b/app/src/main/java/it/reyboz/bustorino/fragments/MapFragment.java
--- a/app/src/main/java/it/reyboz/bustorino/fragments/MapFragment.java
+++ b/app/src/main/java/it/reyboz/bustorino/fragments/MapFragment.java
@@ -47,6 +47,7 @@
import it.reyboz.bustorino.backend.gtfs.GtfsPositionUpdate;
import it.reyboz.bustorino.backend.gtfs.GtfsUtils;
import it.reyboz.bustorino.backend.utils;
+import it.reyboz.bustorino.data.gtfs.MatoPattern;
import it.reyboz.bustorino.data.gtfs.TripAndPatternWithStops;
import it.reyboz.bustorino.map.*;
import org.osmdroid.api.IGeoPoint;
@@ -346,7 +347,7 @@
//mapViewModel.testCascade();
mapViewModel.getTripsGtfsIDsToQuery().observe(this, dat -> {
Log.i(DEBUG_TAG, "Have these trips IDs missing from the DB, to be queried: "+dat);
- mapViewModel.downloadandInsertTripsInDB(dat);
+ mapViewModel.downloadTripsFromMato(dat);
});
}
}
@@ -637,11 +638,11 @@
if(tripWithPatternStops == null){
noPatternsTrips.add(tripID);
}
- marker.setInfoWindow(new BusInfoWindow(map, update, tripWithPatternStops != null ? tripWithPatternStops.getPattern() : null, new BusInfoWindow.onTouchUp() {
- @Override
- public void onActionUp() {
+ MatoPattern markerPattern = null;
+ if(tripWithPatternStops != null && tripWithPatternStops.getPattern()!=null)
+ markerPattern = tripWithPatternStops.getPattern();
+ marker.setInfoWindow(new BusInfoWindow(map, update, markerPattern , () -> {
- }
}));
updateBusMarker(marker, update, true);
diff --git a/app/src/main/java/it/reyboz/bustorino/fragments/MapViewModel.kt b/app/src/main/java/it/reyboz/bustorino/fragments/MapViewModel.kt
--- a/app/src/main/java/it/reyboz/bustorino/fragments/MapViewModel.kt
+++ b/app/src/main/java/it/reyboz/bustorino/fragments/MapViewModel.kt
@@ -20,15 +20,11 @@
import android.app.Application
import android.util.Log
import androidx.lifecycle.*
-import androidx.work.*
import com.android.volley.Response
-import com.google.transit.realtime.GtfsRealtime.VehiclePosition
import it.reyboz.bustorino.backend.NetworkVolleyManager
-import it.reyboz.bustorino.backend.Result
import it.reyboz.bustorino.backend.gtfs.GtfsPositionUpdate
import it.reyboz.bustorino.backend.gtfs.GtfsRtPositionsRequest
import it.reyboz.bustorino.data.*
-import it.reyboz.bustorino.data.gtfs.GtfsTrip
import it.reyboz.bustorino.data.gtfs.TripAndPatternWithStops
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
@@ -39,10 +35,7 @@
*/
class MapViewModel(application: Application): AndroidViewModel(application) {
private val gtfsRepo = GtfsRepository(application)
- private val executor = Executors.newFixedThreadPool(2)
- private val oldRepo= OldDataRepository(executor, NextGenDB.getInstance(application))
- private val matoRepository = MatoRepository(application)
private val netVolleyManager = NetworkVolleyManager.getInstance(application)
@@ -107,13 +100,23 @@
//add "gtt:" prefix because it's implicit in GTFS Realtime API
return@map it.map { pos -> "gtt:"+pos.tripID }
}
- // trips that are in the DB
- val gtfsTripsInDB = tripsIDsInUpdates.switchMap {
+ //this holds the trips that have been downloaded but for which we have no pattern
+ /*private val gtfsTripsInDBMissingPattern = tripsIDsInUpdates.map { tripsIDs ->
+ val tripsInDB = gtfsRepo.gtfsDao.getTripsFromIDs(tripsIDs)
+ val tripsPatternCodes = tripsInDB.map { tr -> tr.patternId }
+ val codesInDB = gtfsRepo.gtfsDao.getPatternsCodesInTheDB(tripsPatternCodes)
+
+ tripsInDB.filter { !(codesInDB.contains(it.patternId)) }
+ }*/
+ //private val patternsCodesInDB = tripsDBPatterns.map { gtfsRepo.gtfsDao.getPatternsCodesInTheDB(it) }
+
+ // trips that are in the DB, together with the pattern. If the pattern is not present in the DB, it's null
+ val gtfsTripsPatternsInDB = tripsIDsInUpdates.switchMap {
//Log.i(DEBUG_TI, "tripsIds in updates changed: ${it.size}")
gtfsRepo.gtfsDao.getTripPatternStops(it)
}
//trip IDs to query, which are not present in the DB
- val tripsGtfsIDsToQuery: LiveData<List<String>> = gtfsTripsInDB.map { tripswithPatterns ->
+ val tripsGtfsIDsToQuery: LiveData<List<String>> = gtfsTripsPatternsInDB.map { tripswithPatterns ->
val tripNames=tripswithPatterns.map { twp-> twp.trip.tripID }
Log.i(DEBUG_TI, "Have ${tripswithPatterns.size} trips in the DB")
if (tripsIDsInUpdates.value!=null)
@@ -124,14 +127,21 @@
}
}
- val updatesWithTripAndPatterns = gtfsTripsInDB.map { tripPatterns->
+ val updatesWithTripAndPatterns = gtfsTripsPatternsInDB.map { tripPatterns->
Log.i(DEBUG_TI, "Mapping trips and patterns")
val mdict = HashMap<String,Pair<GtfsPositionUpdate, TripAndPatternWithStops?>>()
+ //missing patterns
+ val routesToDownload = HashSet<String>()
if(positionsLiveData.value!=null)
for(update in positionsLiveData.value!!){
val trID = update.tripID
var found = false
for(trip in tripPatterns){
+ if (trip.pattern == null){
+ //pattern is null, which means we have to download
+ // the pattern data from MaTO
+ routesToDownload.add(trip.trip.routeID)
+ }
if (trip.trip.tripID == "gtt:$trID"){
found = true
//insert directly
@@ -140,10 +150,17 @@
}
}
if (!found){
+ //Log.d(DEBUG_TI, "Cannot find pattern ${tr}")
//give the update anyway
mdict[trID] = Pair(update,null)
}
}
+ //have to request download of missing Patterns
+ if (routesToDownload.size > 0){
+ Log.d(DEBUG_TI, "Have ${routesToDownload.size} missing patterns from the DB: $routesToDownload")
+ downloadMissingPatterns(ArrayList(routesToDownload))
+ }
+
return@map mdict
}
/*
@@ -152,38 +169,17 @@
1 -> wait until they are all queried to insert in the DB
2 -> after each request finishes, insert it into the DB
- Keep in mind that trips do not change very often, so they might only need to be inserted once every two months
- TODO: find a way to avoid trips getting scrubbed (check if they are really scrubbed)
+ Keep in mind that trips DO CHANGE often, and so do the Patterns
*/
+ fun downloadTripsFromMato(trips: List<String>): Boolean{
+ return MatoTripsDownloadWorker.downloadTripsFromMato(trips,getApplication(), DEBUG_TI)
+ }
+ fun downloadMissingPatterns(routeIds: List<String>): Boolean{
+ return MatoPatternsDownloadWorker.downloadPatternsForRoutes(routeIds, getApplication())
+ }
init {
- /*
- //what happens when the trips to query with Mato are determined
- tripsIDsQueried.addSource(tripsGtfsIDsToQuery) { tripList ->
- // avoid infinite loop of querying to Mato, insert in DB and
- // triggering another query update
-
- val tripsToQuery =
- Log.d(DEBUG_TI, "Querying trips IDs to Mato: $tripsToQuery")
- for (t in tripsToQuery){
- matoRepository.requestTripUpdate(t,matoTripReqErrorList, matoTripCallback)
- }
- tripsIDsQueried.value = tripsToQuery
- }
- tripsToInsert.addSource(tripsFromMato) { matoTrips ->
- if (tripsIDsQueried.value == null) return@addSource
- val tripsIdsToInsert = matoTrips.map { trip -> trip.tripID }
-
- //val setTripsToInsert = HashSet(tripsIdsToInsert)
- val tripsRequested = HashSet(tripsIDsQueried.value!!)
- val insertInDB = tripsRequested.containsAll(tripsIdsToInsert)
- if(insertInDB){
- gtfsRepo.gtfsDao.insertTrips(matoTrips)
- }
- Log.d(DEBUG_TI, "MatoTrips: ${matoTrips.size}, total trips req: ${tripsRequested.size}, inserting: $insertInDB")
- }
- */
Log.d(DEBUG_TI, "MapViewModel created")
Log.d(DEBUG_TI, "Observers of positionsLiveData ${positionsLiveData.hasActiveObservers()}")
@@ -198,36 +194,12 @@
))
positionsLiveData.value = n
}
- private val queriedMatoTrips = HashSet<String>()
- private val downloadedMatoTrips = ArrayList<GtfsTrip>()
- private val failedMatoTripsDownload = HashSet<String>()
/**
* Start downloading missing GtfsTrips and Insert them in the DB
*/
- fun downloadandInsertTripsInDB(trips: List<String>): Boolean{
- if (trips.isEmpty()) return false
- val workManager = WorkManager.getInstance(getApplication())
- val info = workManager.getWorkInfosForUniqueWork(MatoDownloadTripsWorker.WORK_TAG).get()
-
- val runNewWork = if(info.isEmpty()){
- true
- } else info[0].state!=WorkInfo.State.RUNNING && info[0].state!=WorkInfo.State.ENQUEUED
- val addDat = if(info.isEmpty())
- null else info[0].state
- Log.d(DEBUG_TI, "Request to download and insert ${trips.size} trips, proceed: $runNewWork, workstate: $addDat")
- if(runNewWork) {
- val tripsArr = trips.toTypedArray()
- val data = Data.Builder().putStringArray(MatoDownloadTripsWorker.TRIPS_KEYS, tripsArr).build()
- val requ = OneTimeWorkRequest.Builder(MatoDownloadTripsWorker::class.java)
- .setInputData(data).setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)
- .addTag(MatoDownloadTripsWorker.WORK_TAG)
- .build()
- workManager.enqueueUniqueWork(MatoDownloadTripsWorker.WORK_TAG, ExistingWorkPolicy.KEEP, requ)
- }
- return true
- }
+
companion object{
const val DEBUG_TI="BusTO-MapViewModel"
diff --git a/app/src/main/java/it/reyboz/bustorino/fragments/SettingsFragment.java b/app/src/main/java/it/reyboz/bustorino/fragments/SettingsFragment.java
--- a/app/src/main/java/it/reyboz/bustorino/fragments/SettingsFragment.java
+++ b/app/src/main/java/it/reyboz/bustorino/fragments/SettingsFragment.java
@@ -31,13 +31,11 @@
import androidx.lifecycle.Observer;
import androidx.preference.*;
import androidx.work.OneTimeWorkRequest;
-import androidx.work.OutOfQuotaPolicy;
import androidx.work.WorkInfo;
import androidx.work.WorkManager;
import it.reyboz.bustorino.R;
import it.reyboz.bustorino.data.DatabaseUpdate;
import it.reyboz.bustorino.data.GtfsMaintenanceWorker;
-import it.reyboz.bustorino.data.MatoDownloadTripsWorker;
import org.jetbrains.annotations.NotNull;
import java.lang.ref.WeakReference;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Mar 19, 13:30 (22 h, 19 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1757669
Default Alt Text
D122.1773923409.diff (30 KB)
Attached To
Mode
D122: Download missing patterns when downloading trips
Attached
Detach File
Event Timeline
Log In to Comment