WhatsOpenService.kt 2.46 KB
Newer Older
Dylan Jones's avatar
Dylan Jones committed
1 2
package srct.whatsopen.util

3
import android.content.Context
Dylan Jones's avatar
Dylan Jones committed
4
import io.reactivex.Observable
5 6 7 8 9 10 11
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import okhttp3.Cache
import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory
Dylan Jones's avatar
Dylan Jones committed
12
import retrofit2.http.GET
13
import retrofit2.http.Headers
Dylan Jones's avatar
Dylan Jones committed
14 15 16
import srct.whatsopen.model.Facility

interface WhatsOpenService {
17 18
    // cache for 12 hours by default, allow 1 month stale
    @Headers("Cache-Control: public, max-age=43200, max-stale=2628003")
Dylan Jones's avatar
Dylan Jones committed
19 20
    @GET("facilities")
    fun getData(): Observable<List<Facility>>
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77

    companion object {
        lateinit var cache: Cache

        val okHttpClient: OkHttpClient by lazy {
            OkHttpClient.Builder()
                .cache(cache)
                .build()
        }

        val service: WhatsOpenService by lazy {
            Retrofit.Builder()
                .client(okHttpClient)
                .baseUrl("https://api.srct.gmu.edu/whatsopen/v2/")
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .build().create(WhatsOpenService::class.java)
        }

        private const val cacheSize = (8 * 1024 * 1024).toLong() // 8 MB cache

        var data: List<Facility>? = null

        /**
         *  Prepare the retrofit service for initialization if it hasn't already been.
         */
        fun init(context: Context) {
            cache = Cache(context.cacheDir, cacheSize)
        }

        /**
         * Get a list of all facilities. Uses cached information to speed up the process.
         */
        fun getData(): Observable<List<Facility>> {
            if (data == null) {
                return service.getData()
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .map(fun(results): List<Facility> {
                        data = results
                        return results
                    })
            } else {
                return Observable.just(data!!)
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
            }
        }

        /**
         * Clear all of the caches.
         */
        fun resetCache() {
            cache.evictAll()
            data = null
        }
    }
Dylan Jones's avatar
Dylan Jones committed
78
}