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