Commit 6d47619a authored by Vladislav Bogdashkin's avatar Vladislav Bogdashkin 🎣

downloadmanager massive fix and refactor

parent e93cc2e9
...@@ -61,6 +61,7 @@ class EstateRepository @Inject constructor( ...@@ -61,6 +61,7 @@ class EstateRepository @Inject constructor(
} }
} }
.doOnNext(db::blockingUpsert) .doOnNext(db::blockingUpsert)
.doOnNext{ db.refreshUser(user) }
} }
private val getFavoritesDb: Observable<List<EstateEntity>> = private val getFavoritesDb: Observable<List<EstateEntity>> =
......
...@@ -36,7 +36,7 @@ private const val TIMEOUT_SECONDS=120L ...@@ -36,7 +36,7 @@ private const val TIMEOUT_SECONDS=120L
private const val WRITE_SECONDS=120L private const val WRITE_SECONDS=120L
private const val READ_SECONDS=120L private const val READ_SECONDS=120L
val INTERCEPT_LOG_LEVEL = HttpLoggingInterceptor.Level.NONE val INTERCEPT_LOG_LEVEL = HttpLoggingInterceptor.Level.BODY
@Module @Module
class RetrofitModule{ class RetrofitModule{
......
...@@ -72,4 +72,5 @@ interface IDb { ...@@ -72,4 +72,5 @@ interface IDb {
fun dropFileTable(): Completable fun dropFileTable(): Completable
fun dropTourFileJuncTable(): Completable fun dropTourFileJuncTable(): Completable
fun dropTourTable(): Completable fun dropTourTable(): Completable
fun refreshUser(userEntity: UserEntity): Observable<UserEntity>
} }
\ No newline at end of file
...@@ -4,7 +4,6 @@ import android.app.Application ...@@ -4,7 +4,6 @@ import android.app.Application
import com.biganto.visual.roompark.Models import com.biganto.visual.roompark.Models
import com.biganto.visual.roompark.data.repository.db.IDb import com.biganto.visual.roompark.data.repository.db.IDb
import com.biganto.visual.roompark.data.repository.db.requrey.model.* import com.biganto.visual.roompark.data.repository.db.requrey.model.*
import com.biganto.visual.roompark.di.dagger.DATABASE_VERSION
import com.biganto.visual.roomparkvr.data.repository.db.requery.model.DownloadState import com.biganto.visual.roomparkvr.data.repository.db.requery.model.DownloadState
import com.biganto.visual.roomparkvr.data.repository.db.requery.model.TourPreview import com.biganto.visual.roomparkvr.data.repository.db.requery.model.TourPreview
import com.biganto.visual.roomparkvr.data.repository.db.requery.model.TourPreviewEntity import com.biganto.visual.roomparkvr.data.repository.db.requery.model.TourPreviewEntity
...@@ -30,6 +29,8 @@ import javax.inject.Inject ...@@ -30,6 +29,8 @@ import javax.inject.Inject
*/ */
private const val DATABASE_VERSION = 14
@Module @Module
class DbModule{ class DbModule{
...@@ -52,6 +53,9 @@ class RequeryRepository @Inject constructor( ...@@ -52,6 +53,9 @@ class RequeryRepository @Inject constructor(
) )
: IDb { : IDb {
override fun refreshUser(userEntity: UserEntity): Observable<UserEntity> =
store.refresh(userEntity).toObservable()
override fun dropTourTable() = store.delete(TourPreviewEntity::class).get().toCompletable() override fun dropTourTable() = store.delete(TourPreviewEntity::class).get().toCompletable()
override fun dropTourFileJuncTable() = store.delete(TourFileJunctionEntity::class).get().toCompletable() override fun dropTourFileJuncTable() = store.delete(TourFileJunctionEntity::class).get().toCompletable()
......
...@@ -78,6 +78,6 @@ interface Estate : Persistable { ...@@ -78,6 +78,6 @@ interface Estate : Persistable {
@get:Nullable @get:Nullable
@get:Column(name = "UserContainer") @get:Column(name = "UserContainer")
@get:ForeignKey(references = User::class ) @get:ForeignKey(references = User::class )
@get:OneToOne(mappedBy = "uuid",cascade = [CascadeAction.NONE]) @get:ManyToOne(cascade = [CascadeAction.NONE])
var user:User? var user:User?
} }
\ No newline at end of file
...@@ -25,6 +25,10 @@ interface User : Persistable { ...@@ -25,6 +25,10 @@ interface User : Persistable {
@get:OneToMany(cascade = [CascadeAction.DELETE]) @get:OneToMany(cascade = [CascadeAction.DELETE])
val deals:List<Deal>? val deals:List<Deal>?
@get:Nullable
@get:OneToMany(cascade = [CascadeAction.DELETE])
val estates:List<Estate>?
@get:Nullable @get:Nullable
@get:OneToMany(cascade = [CascadeAction.DELETE]) @get:OneToMany(cascade = [CascadeAction.DELETE])
val subscriptions:List<Subscription>? val subscriptions:List<Subscription>?
......
...@@ -41,10 +41,12 @@ import javax.inject.Singleton ...@@ -41,10 +41,12 @@ import javax.inject.Singleton
*/ */
private const val DB_ACCESS_CHUNK_SIZE = 256 private const val DB_ACCESS_CHUNK_SIZE = 256
private const val READ_SYNC_MILLS = 12L private const val READ_SYNC_MILLS = 120L
private const val DEQUE_REQUEST_TIMEOUT_MILLS=100L private const val DEQUE_REQUEST_TIMEOUT_MILLS=100L
private const val META_PREDICTION="/tourMeta_" private const val META_PREDICTION="/tourMeta_"
private const val META_FILE_TYPE=".json" private const val META_FILE_TYPE=".json"
const val DOWNLOAD_MANAGER_COMMAND_KEY = "TOURS_DOWNLOAD_MANAGER_COMMAND"
const val DOWNLOAD_MANAGER_ADD_IDS_TO_LOAD_COMMAND = "ADD_TOUR_IDS_TO_QUEUE"
@Singleton @Singleton
class DownloadManagerService @Inject constructor( class DownloadManagerService @Inject constructor(
...@@ -123,14 +125,16 @@ class DownloadManagerService @Inject constructor( ...@@ -123,14 +125,16 @@ class DownloadManagerService @Inject constructor(
// stopSelf() // stopSelf()
// } // }
val command = intent?.getStringExtra(DOWNLOAD_MANAGER_COMMAND_KEY)
if (command == DOWNLOAD_MANAGER_ADD_IDS_TO_LOAD_COMMAND){
intent.getStringArrayListExtra(TOUR_IDS_TO_DOWNLOAD_KEY)
?.forEach { toursToDownloadObserver.accept(it) }
}
Timber.d(" ON START COMMAND,${disposable.size()}") Timber.d(" ON START COMMAND,${disposable.size()}")
if (disposable.size() == 0) if (disposable.size() == 0)
attachDownloader() attachDownloader()
intent?.getStringArrayListExtra(TOUR_IDS_TO_DOWNLOAD_KEY)
?.forEach { toursToDownloadObserver.accept(it) }
return START_NOT_STICKY return START_NOT_STICKY
} }
...@@ -173,13 +177,15 @@ class DownloadManagerService @Inject constructor( ...@@ -173,13 +177,15 @@ class DownloadManagerService @Inject constructor(
var read = 0L var read = 0L
val step = 4096 val step = 4096
val source = response.source() val source = response.source()
val timer = System.currentTimeMillis() var timer = System.currentTimeMillis()
var stop: Boolean = false var stop: Boolean = false
sink.use { sink.use {
while (!stop && { read = source.read(buffer, step.toLong());read }() != -1L) { while (!stop && { read = source.read(buffer, step.toLong());read }() != -1L) {
model.tempDownloadedSize += read model.tempDownloadedSize += read
if (System.currentTimeMillis() - timer > READ_SYNC_MILLS || source.exhausted()) { if ((System.currentTimeMillis() - timer) > READ_SYNC_MILLS || source.exhausted()) {
model.fileDownloadedSize += read timer = System.currentTimeMillis()
model.fileDownloadedSize += model.tempDownloadedSize
if (model.tempOverallFileSize == 0L) if (model.tempOverallFileSize == 0L)
model.tempTourTotalDiff += model.tempDownloadedSize model.tempTourTotalDiff += model.tempDownloadedSize
...@@ -188,9 +194,9 @@ class DownloadManagerService @Inject constructor( ...@@ -188,9 +194,9 @@ class DownloadManagerService @Inject constructor(
&& (model.fileDownloadedSize == model.tempOverallFileSize && (model.fileDownloadedSize == model.tempOverallFileSize
|| model.tempOverallFileSize == 0L)) || model.tempOverallFileSize == 0L))
sub.onNext(model.copy())
model.tempTourTotalDiff = 0 model.tempTourTotalDiff = 0
model.tempDownloadedSize = 0 model.tempDownloadedSize = 0
} }
} }
} }
...@@ -256,7 +262,8 @@ class DownloadManagerService @Inject constructor( ...@@ -256,7 +262,8 @@ class DownloadManagerService @Inject constructor(
if (entity.downloadedFiles == entity.overallFiles) if (entity.downloadedFiles == entity.overallFiles)
entity.isDownloaded = DownloadState.Downloaded entity.isDownloaded = DownloadState.Downloaded
} }
}.flatMap { db.upsert(it).toObservable() } }
.flatMap { db.upsert(it).toObservable() }
private fun flowableFilesDownloading(tour: TourPreviewEntity) = private fun flowableFilesDownloading(tour: TourPreviewEntity) =
api.getTourFiles(tour.id, tour.targetResolution.toString()) api.getTourFiles(tour.id, tour.targetResolution.toString())
...@@ -267,32 +274,29 @@ class DownloadManagerService @Inject constructor( ...@@ -267,32 +274,29 @@ class DownloadManagerService @Inject constructor(
val fileEntities = raw.files.map(::fromRaw) val fileEntities = raw.files.map(::fromRaw)
mergeFiles(fileEntities) mergeFiles(fileEntities)
Timber.d("1")
val jlist = db.getTourFilesJunction(tour.id).toList() val jlist = db.getTourFilesJunction(tour.id).toList()
Timber.d("2")
val junctionList = fileEntities val junctionList = fileEntities
.map {file -> .map {file ->
val entity = jlist.firstOrNull{it.tour == tour.id && it.file == file.uri} val entity = jlist.firstOrNull{it.tour == tour.id && it.file == file.uri}
?: TourFileJunctionEntity() ?: TourFileJunctionEntity().apply {
entity.setTour(tour.id) setTour(tour.id)
entity.setFile(file.uri) setFile(file.uri)
}
downloadedSize += file.downloadedSize downloadedSize += file.downloadedSize
totalSize += file.totalSize totalSize += file.totalSize
entity entity
} }
Timber.d("3")
setDownloadInfo( setDownloadInfo(
raw.id.toString() raw.id.toString()
, tempLoadedFiles = 0
, downloadedSize = downloadedSize , downloadedSize = downloadedSize
, totalSize = totalSize , totalSize = totalSize
, resolution = raw.resolution , resolution = raw.resolution
, filesCount = raw.files.count() , filesCount = raw.files.count()
).map { junctionList } ).map { junctionList }
} }
.doOnNext{Timber.d("4")}
.flatMap{ db.upsertTourFileJunction(it) } .flatMap{ db.upsertTourFileJunction(it) }
.doOnNext{Timber.d("5 ${it.count()}")}
.flatMapIterable { it } .flatMapIterable { it }
.flatMap { junction -> .flatMap { junction ->
db.getFileEntity(junction.file) db.getFileEntity(junction.file)
...@@ -338,17 +342,20 @@ class DownloadManagerService @Inject constructor( ...@@ -338,17 +342,20 @@ class DownloadManagerService @Inject constructor(
.toObservable() .toObservable()
.observeOn(Schedulers.computation()) .observeOn(Schedulers.computation())
// .doOnNext{Timber.d("7 ${it}")} // .doOnNext{Timber.d("7 ${it}")}
.map { model -> .flatMap { model ->
setDownloadInfo( setDownloadInfo(
model.tourId model.tourId
, totalSizedDiffSize = model.tempTourTotalDiff , totalSizedDiffSize = model.tempTourTotalDiff
, downloadedDiffSize = model.tempDownloadedSize , downloadedDiffSize = model.tempDownloadedSize
, tempLoadedFiles = if (model.isDownloaded) 1 else null , tempLoadedFiles = if (model.isDownloaded) 1 else null
) )
model.tempDownloadedSize = 0 .map {
model.tourId model.tempDownloadedSize = 0
model.tourId
}
} }
.delay(12L, TimeUnit.MILLISECONDS) // .delay(12L, TimeUnit.MILLISECONDS)
...@@ -363,7 +370,6 @@ class DownloadManagerService @Inject constructor( ...@@ -363,7 +370,6 @@ class DownloadManagerService @Inject constructor(
deleteTourFromQueue() deleteTourFromQueue()
} }
downloadQueue.isNotEmpty() -> { downloadQueue.isNotEmpty() -> {
Timber.w(" 8 to donload: ${downloadQueue.size}")
notifyDownloading() notifyDownloading()
downloadTourFromQueue() downloadTourFromQueue()
} }
...@@ -376,12 +382,12 @@ class DownloadManagerService @Inject constructor( ...@@ -376,12 +382,12 @@ class DownloadManagerService @Inject constructor(
private fun downloadTourFromQueue(): Observable<String> = private fun downloadTourFromQueue(): Observable<String> =
Observable.fromCallable { activeDownloading.set(true);downloadQueue.poll() } Observable.fromCallable { activeDownloading.set(true);downloadQueue.poll() }
.doOnNext { Timber.w("loading tour $it") }
.flatMap { db.getTourPreview(it).observable() } .flatMap { db.getTourPreview(it).observable() }
.doOnNext { Timber.w("loading tour status ${it.isDownloaded}") }
.filter { .filter {
val forward = it.isDownloaded == DownloadState.Downloading val forward = it.isDownloaded != DownloadState.Downloaded
activeDownloading.set(forward) activeDownloading.set(forward)
if (!forward)
notifyDownloadProgress()
forward forward
} }
.flatMap { tour -> .flatMap { tour ->
......
...@@ -9,7 +9,6 @@ import dagger.Module ...@@ -9,7 +9,6 @@ import dagger.Module
* Created by Vladislav Bogdashkin on 13.06.2018. * Created by Vladislav Bogdashkin on 13.06.2018.
*/ */
const val DATABASE_VERSION = 13
@Module @Module
abstract class AppModule{ abstract class AppModule{
......
...@@ -4,6 +4,8 @@ import android.content.Intent ...@@ -4,6 +4,8 @@ import android.content.Intent
import android.os.Build import android.os.Build
import com.biganto.visual.roompark.R import com.biganto.visual.roompark.R
import com.biganto.visual.roompark.base.BaseRoomParkActivity import com.biganto.visual.roompark.base.BaseRoomParkActivity
import com.biganto.visual.roompark.data.service.download.DOWNLOAD_MANAGER_ADD_IDS_TO_LOAD_COMMAND
import com.biganto.visual.roompark.data.service.download.DOWNLOAD_MANAGER_COMMAND_KEY
import com.biganto.visual.roompark.data.service.download.DownloadManagerService import com.biganto.visual.roompark.data.service.download.DownloadManagerService
import com.biganto.visual.roompark.domain.model.CachedDataModel import com.biganto.visual.roompark.domain.model.CachedDataModel
import com.biganto.visual.roompark.domain.model.PushSwitchModel import com.biganto.visual.roompark.domain.model.PushSwitchModel
...@@ -14,6 +16,7 @@ import io.reactivex.Completable ...@@ -14,6 +16,7 @@ import io.reactivex.Completable
import io.reactivex.Observable import io.reactivex.Observable
import io.reactivex.schedulers.Schedulers import io.reactivex.schedulers.Schedulers
import timber.log.Timber import timber.log.Timber
import java.util.concurrent.TimeUnit
import javax.inject.Inject import javax.inject.Inject
/** /**
...@@ -28,12 +31,23 @@ class SettingsInteractor @Inject constructor( ...@@ -28,12 +31,23 @@ class SettingsInteractor @Inject constructor(
private val toursUc: TourPreviewsUseCase private val toursUc: TourPreviewsUseCase
){ ){
private fun startDownloadService() {
val i = Intent(activity, DownloadManagerService::class.java)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
activity.startForegroundService(i)
} else {
activity.startService(i)
}
}
private fun startDownloadService(ids:List<String>){ private fun startDownloadService(ids:List<String>){
Timber.d(" gonna startService ++") Timber.d(" gonna startService ++")
try { try {
val i = Intent(activity, DownloadManagerService::class.java) val i = Intent(activity, DownloadManagerService::class.java)
i.putExtra(DOWNLOAD_MANAGER_COMMAND_KEY, DOWNLOAD_MANAGER_ADD_IDS_TO_LOAD_COMMAND)
i.putStringArrayListExtra(TOUR_IDS_TO_DOWNLOAD_KEY, ArrayList(ids)) i.putStringArrayListExtra(TOUR_IDS_TO_DOWNLOAD_KEY, ArrayList(ids))
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
activity.startForegroundService(i) activity.startForegroundService(i)
} else { } else {
...@@ -45,9 +59,11 @@ class SettingsInteractor @Inject constructor( ...@@ -45,9 +59,11 @@ class SettingsInteractor @Inject constructor(
} }
} }
fun startToursDownloading() = fun startToursDownloading(): Completable =
toursUc.downloadAllDeelsAndEstates() toursUc.downloadAllDeelsAndEstates()
.doOnNext { Timber.d(" gonna startService") } .doOnNext { Timber.d(" gonna startService") }
.doOnNext { this.startDownloadService() }
.delay(100,TimeUnit.MILLISECONDS)
.doOnNext { tours -> .doOnNext { tours ->
startDownloadService(tours.map { tour -> tour.id }) startDownloadService(tours.map { tour -> tour.id })
}.ignoreElements() }.ignoreElements()
......
...@@ -23,6 +23,7 @@ import javax.inject.Inject ...@@ -23,6 +23,7 @@ import javax.inject.Inject
const val EMPTY_PARENT = -778 const val EMPTY_PARENT = -778
const val TOUR_IDS_TO_DOWNLOAD_KEY = "DOWNLOAD_MANAGER_IDS_TO LOAD" const val TOUR_IDS_TO_DOWNLOAD_KEY = "DOWNLOAD_MANAGER_IDS_TO LOAD"
class TourPreviewsUseCase @Inject constructor( class TourPreviewsUseCase @Inject constructor(
private val api:IBigantoApi private val api:IBigantoApi
,private val db: IDb ,private val db: IDb
...@@ -173,15 +174,20 @@ class TourPreviewsUseCase @Inject constructor( ...@@ -173,15 +174,20 @@ class TourPreviewsUseCase @Inject constructor(
fun downloadAllDeelsAndEstates(): Observable<Iterable<TourPreviewEntity>> = fun downloadAllDeelsAndEstates(): Observable<Iterable<TourPreviewEntity>> =
auth.currentUser() auth.currentUser()
.map { user -> .map { user ->
user.deals val estatesList =
user.deals?.map { it.estate }?.plus(
user.estates?.asIterable()?: arrayListOf()
)
estatesList
?.asSequence() ?.asSequence()
?.filter { it.estate.multitourId != null } ?.filter { it.multitourId != null }
?.toList() ?.toList()
?.map { ?.map {
Pair( Pair(
it.estate.multitourId!! it.multitourId!!
, TourRemoteRequestModel( , TourRemoteRequestModel(
estateId = it.estate.id estateId = it.id
, targetResolution = user.targetResolution , targetResolution = user.targetResolution
) )
) )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment