Added spinners to visualize the ongoing download of bigger media files.

This commit is contained in:
Fabian Schlenz 2018-04-20 06:52:30 +02:00
parent c2b1c0625e
commit cf806da77d
8 changed files with 52 additions and 25 deletions

View File

@ -23,6 +23,8 @@ import de.fabianonline.telegram_backup.Utils
internal class CommandLineDownloadProgress : DownloadProgressInterface { internal class CommandLineDownloadProgress : DownloadProgressInterface {
private var mediaCount = 0 private var mediaCount = 0
private var i = 0 private var i = 0
private var step = 0
private val chars = arrayOf("|", "/", "-", "\\")
override fun onMessageDownloadStart(count: Int, source: String?) { override fun onMessageDownloadStart(count: Int, source: String?) {
i = 0 i = 0
@ -59,6 +61,21 @@ internal class CommandLineDownloadProgress : DownloadProgressInterface {
override fun onMediaDownloaded(file_manager: AbstractMediaFileManager) { override fun onMediaDownloaded(file_manager: AbstractMediaFileManager) {
show(file_manager.letter.toUpperCase()) show(file_manager.letter.toUpperCase())
} }
override fun onMediaFileDownloadStarted() {
step = 0
print(chars[step % chars.size])
}
override fun onMediaFileDownloadStep() {
step++
print("\b")
print(chars[step % chars.size])
}
override fun onMediaFileDownloadFinished() {
print("\b")
}
override fun onMediaDownloadedEmpty() { override fun onMediaDownloadedEmpty() {
show("e") show("e")

View File

@ -263,7 +263,7 @@ class DownloadManager(val client: TelegramClient, val prog: DownloadProgressInte
prog.onMediaSkipped() prog.onMediaSkipped()
} else { } else {
try { try {
val result = m.download() val result = m.download(prog)
if (result) { if (result) {
prog.onMediaDownloaded(m) prog.onMediaDownloaded(m)
} else { } else {
@ -361,19 +361,19 @@ class DownloadManager(val client: TelegramClient, val prog: DownloadProgressInte
internal val logger = LoggerFactory.getLogger(DownloadManager::class.java) internal val logger = LoggerFactory.getLogger(DownloadManager::class.java)
@Throws(RpcErrorException::class, IOException::class, TimeoutException::class) @Throws(RpcErrorException::class, IOException::class, TimeoutException::class)
fun downloadFile(targetFilename: String, size: Int, dcId: Int, volumeId: Long, localId: Int, secret: Long) { fun downloadFile(targetFilename: String, size: Int, dcId: Int, volumeId: Long, localId: Int, secret: Long, prog: DownloadProgressInterface?) {
val loc = TLInputFileLocation(volumeId, localId, secret) val loc = TLInputFileLocation(volumeId, localId, secret)
downloadFileFromDc(targetFilename, loc, dcId, size) downloadFileFromDc(targetFilename, loc, dcId, size, prog)
} }
@Throws(RpcErrorException::class, IOException::class, TimeoutException::class) @Throws(RpcErrorException::class, IOException::class, TimeoutException::class)
fun downloadFile(targetFilename: String, size: Int, dcId: Int, id: Long, accessHash: Long) { fun downloadFile(targetFilename: String, size: Int, dcId: Int, id: Long, accessHash: Long, prog: DownloadProgressInterface?) {
val loc = TLInputDocumentFileLocation(id, accessHash) val loc = TLInputDocumentFileLocation(id, accessHash)
downloadFileFromDc(targetFilename, loc, dcId, size) downloadFileFromDc(targetFilename, loc, dcId, size, prog)
} }
@Throws(RpcErrorException::class, IOException::class, TimeoutException::class) @Throws(RpcErrorException::class, IOException::class, TimeoutException::class)
private fun downloadFileFromDc(target: String, loc: TLAbsInputFileLocation, dcID: Int, size: Int): Boolean { private fun downloadFileFromDc(target: String, loc: TLAbsInputFileLocation, dcID: Int, size: Int, prog: DownloadProgressInterface?): Boolean {
var fos: FileOutputStream? = null var fos: FileOutputStream? = null
try { try {
val temp_filename = target + ".downloading" val temp_filename = target + ".downloading"
@ -392,6 +392,7 @@ class DownloadManager(val client: TelegramClient, val prog: DownloadProgressInte
} }
logger.trace("offset before the loop is {}", offset) logger.trace("offset before the loop is {}", offset)
fos = FileOutputStream(temp_filename, true) fos = FileOutputStream(temp_filename, true)
if (prog != null) prog.onMediaFileDownloadStarted()
do { do {
logger.trace("offset: {} block_size: {} size: {}", offset, size, size) logger.trace("offset: {} block_size: {} size: {}", offset, size, size)
val req = TLRequestUploadGetFile(loc, offset, size) val req = TLRequestUploadGetFile(loc, offset, size)
@ -409,7 +410,7 @@ class DownloadManager(val client: TelegramClient, val prog: DownloadProgressInte
} }
val response = resp!! val response = resp!!
if (prog!=null) prog.onMediaFileDownloadStep()
offset += response.getBytes().getData().size offset += response.getBytes().getData().size
logger.trace("response: {} total size: {}", response.getBytes().getData().size, offset) logger.trace("response: {} total size: {}", response.getBytes().getData().size, offset)
@ -418,6 +419,7 @@ class DownloadManager(val client: TelegramClient, val prog: DownloadProgressInte
try { TimeUnit.MILLISECONDS.sleep(Config.DELAY_AFTER_GET_FILE) } catch (e: InterruptedException) { } try { TimeUnit.MILLISECONDS.sleep(Config.DELAY_AFTER_GET_FILE) } catch (e: InterruptedException) { }
} while (offset < size && response.getBytes().getData().size > 0) } while (offset < size && response.getBytes().getData().size > 0)
if (prog != null) prog.onMediaFileDownloadFinished()
fos.close() fos.close()
if (offset < size) { if (offset < size) {
System.out.println("Requested file $target with $size bytes, but got only $offset bytes.") System.out.println("Requested file $target with $size bytes, but got only $offset bytes.")
@ -472,13 +474,18 @@ class DownloadManager(val client: TelegramClient, val prog: DownloadProgressInte
} }
@Throws(IOException::class) @Throws(IOException::class)
fun downloadExternalFile(target: String, url: String): Boolean { fun downloadExternalFile(target: String, url: String, prog: DownloadProgressInterface?): Boolean {
val (_, response, result) = Fuel.get(url).response() if (prog != null) prog.onMediaFileDownloadStarted()
if (result is Result.Success) { var success = true
File(target).writeBytes(response.data) Fuel.download(url).destination { _, _ ->
return true File(target)
}.progress { _, _ ->
if (prog != null) prog.onMediaFileDownloadStep()
}.response { _, _, result ->
success = (result is Result.Success)
} }
return false if (prog != null) prog.onMediaFileDownloadFinished()
return success
} }
} }
} }

View File

@ -30,4 +30,7 @@ interface DownloadProgressInterface {
fun onMediaAlreadyPresent(file_manager: AbstractMediaFileManager) fun onMediaAlreadyPresent(file_manager: AbstractMediaFileManager)
fun onMediaDownloadFinished() fun onMediaDownloadFinished()
fun onMediaFailed() fun onMediaFailed()
fun onMediaFileDownloadStarted()
fun onMediaFileDownloadStep()
fun onMediaFileDownloadFinished()
} }

View File

@ -65,7 +65,7 @@ abstract class AbstractMediaFileManager(private var json: JsonObject, val file_b
abstract val name: String abstract val name: String
abstract val description: String abstract val description: String
@Throws(RpcErrorException::class, IOException::class, TimeoutException::class) @Throws(RpcErrorException::class, IOException::class, TimeoutException::class)
abstract fun download(): Boolean abstract fun download(prog: DownloadProgressInterface? = null): Boolean
protected fun extensionFromMimetype(mime: String): String { protected fun extensionFromMimetype(mime: String): String {
when (mime) { when (mime) {

View File

@ -18,7 +18,7 @@ package de.fabianonline.telegram_backup.mediafilemanager
import de.fabianonline.telegram_backup.UserManager import de.fabianonline.telegram_backup.UserManager
import de.fabianonline.telegram_backup.DownloadManager import de.fabianonline.telegram_backup.DownloadManager
import de.fabianonline.telegram_backup.DownloadProgressInterface
import com.github.badoualy.telegram.tl.api.* import com.github.badoualy.telegram.tl.api.*
import com.github.badoualy.telegram.tl.exception.RpcErrorException import com.github.badoualy.telegram.tl.exception.RpcErrorException
@ -74,8 +74,8 @@ open class DocumentFileManager(message: JsonObject, file_base: String) : Abstrac
} }
@Throws(RpcErrorException::class, IOException::class, TimeoutException::class) @Throws(RpcErrorException::class, IOException::class, TimeoutException::class)
override fun download(): Boolean { override fun download(prog: DownloadProgressInterface?): Boolean {
DownloadManager.downloadFile(targetPathAndFilename, size, json["dcId"].int, json["id"].long, json["accessHash"].long) DownloadManager.downloadFile(targetPathAndFilename, size, json["dcId"].int, json["id"].long, json["accessHash"].long, prog)
return true return true
} }
} }

View File

@ -18,7 +18,7 @@ package de.fabianonline.telegram_backup.mediafilemanager
import de.fabianonline.telegram_backup.UserManager import de.fabianonline.telegram_backup.UserManager
import de.fabianonline.telegram_backup.DownloadManager import de.fabianonline.telegram_backup.DownloadManager
import de.fabianonline.telegram_backup.DownloadProgressInterface
import com.github.badoualy.telegram.tl.api.* import com.github.badoualy.telegram.tl.api.*
import de.fabianonline.telegram_backup.Config import de.fabianonline.telegram_backup.Config
import de.fabianonline.telegram_backup.Settings import de.fabianonline.telegram_backup.Settings
@ -61,12 +61,12 @@ class GeoFileManager(message: JsonObject, file_base: String, val settings: Setti
} }
@Throws(IOException::class) @Throws(IOException::class)
override fun download(): Boolean { override fun download(prog: DownloadProgressInterface?): Boolean {
val url = "https://maps.googleapis.com/maps/api/staticmap?" + val url = "https://maps.googleapis.com/maps/api/staticmap?" +
"center=${json["lat"].float},${json["_long"].float}&" + "center=${json["lat"].float},${json["_long"].float}&" +
"markers=color:red|${json["lat"].float},${json["_long"].float}&" + "markers=color:red|${json["lat"].float},${json["_long"].float}&" +
"zoom=14&size=300x150&scale=2&format=png&" + "zoom=14&size=300x150&scale=2&format=png&" +
"key=" + (settings?.gmaps_key) "key=" + (settings?.gmaps_key)
return DownloadManager.downloadExternalFile(targetPathAndFilename, url) return DownloadManager.downloadExternalFile(targetPathAndFilename, url, prog)
} }
} }

View File

@ -18,7 +18,7 @@ package de.fabianonline.telegram_backup.mediafilemanager
import de.fabianonline.telegram_backup.UserManager import de.fabianonline.telegram_backup.UserManager
import de.fabianonline.telegram_backup.DownloadManager import de.fabianonline.telegram_backup.DownloadManager
import de.fabianonline.telegram_backup.DownloadProgressInterface
import com.github.badoualy.telegram.tl.api.* import com.github.badoualy.telegram.tl.api.*
import com.github.badoualy.telegram.tl.exception.RpcErrorException import com.github.badoualy.telegram.tl.exception.RpcErrorException
@ -76,12 +76,12 @@ class PhotoFileManager(message: JsonObject, file_base: String) : AbstractMediaFi
} }
@Throws(RpcErrorException::class, IOException::class, TimeoutException::class) @Throws(RpcErrorException::class, IOException::class, TimeoutException::class)
override fun download(): Boolean { override fun download(prog: DownloadProgressInterface?): Boolean {
/*if (isEmpty) return true*/ /*if (isEmpty) return true*/
//val loc = photo_size.getLocation() as TLFileLocation //val loc = photo_size.getLocation() as TLFileLocation
val loc = biggestSize["location"].obj val loc = biggestSize["location"].obj
DownloadManager.downloadFile(targetPathAndFilename, size, loc["dcId"].int, loc["volumeId"].long, loc["localId"].int, loc["secret"].long) DownloadManager.downloadFile(targetPathAndFilename, size, loc["dcId"].int, loc["volumeId"].long, loc["localId"].int, loc["secret"].long, prog)
return true return true
} }
} }

View File

@ -17,7 +17,7 @@
package de.fabianonline.telegram_backup.mediafilemanager package de.fabianonline.telegram_backup.mediafilemanager
import de.fabianonline.telegram_backup.UserManager import de.fabianonline.telegram_backup.UserManager
import de.fabianonline.telegram_backup.DownloadProgressInterface
import com.github.badoualy.telegram.tl.api.* import com.github.badoualy.telegram.tl.api.*
import com.google.gson.JsonObject import com.google.gson.JsonObject
@ -32,5 +32,5 @@ class UnsupportedFileManager(json: JsonObject, file_base: String, type: String)
override val letter = " " override val letter = " "
override val description = "Unsupported / non-downloadable Media" override val description = "Unsupported / non-downloadable Media"
override fun download(): Boolean = true override fun download(prog: DownloadProgressInterface?): Boolean = true
} }