Page MenuHomeGitPull.it

D122.1773923409.diff
No OneTemporary

Size
30 KB
Referenced Files
None
Subscribers
None

D122.1773923409.diff

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

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)

Event Timeline