diff --git a/twidere/src/androidTest/kotlin/org/mariotaku/twidere/util/IOFunctionsKtTest.kt b/twidere/src/androidTest/kotlin/org/mariotaku/twidere/util/IOFunctionsKtTest.kt new file mode 100644 index 000000000..9a555440d --- /dev/null +++ b/twidere/src/androidTest/kotlin/org/mariotaku/twidere/util/IOFunctionsKtTest.kt @@ -0,0 +1,27 @@ +package org.mariotaku.twidere.util + +import android.support.test.InstrumentationRegistry +import android.support.test.runner.AndroidJUnit4 +import org.junit.Assert +import org.junit.Test +import org.junit.runner.RunWith +import java.util.* + +/** + * Created by mariotaku on 2017/1/24. + */ +@RunWith(AndroidJUnit4::class) +class IOFunctionsKtTest { + @Test + fun testTempFileInputStream() { + val context = InstrumentationRegistry.getTargetContext() + val random = Random() + val testData = ByteArray(1024) + random.nextBytes(testData) + val compareData = tempFileInputStream(context) { os -> + os.write(testData) + }.readBytes(1024) + Assert.assertArrayEquals(testData, compareData) + } + +} \ No newline at end of file diff --git a/twidere/src/google/kotlin/org/mariotaku/twidere/util/sync/google/GoogleDriveDraftsSyncAction.kt b/twidere/src/google/kotlin/org/mariotaku/twidere/util/sync/google/GoogleDriveDraftsSyncAction.kt index 8c20f6ba8..45c9001a7 100644 --- a/twidere/src/google/kotlin/org/mariotaku/twidere/util/sync/google/GoogleDriveDraftsSyncAction.kt +++ b/twidere/src/google/kotlin/org/mariotaku/twidere/util/sync/google/GoogleDriveDraftsSyncAction.kt @@ -8,8 +8,8 @@ import org.mariotaku.twidere.extension.model.filename import org.mariotaku.twidere.extension.model.readMimeMessageFrom import org.mariotaku.twidere.extension.model.writeMimeMessageTo import org.mariotaku.twidere.model.Draft -import org.mariotaku.twidere.util.io.DirectByteArrayOutputStream import org.mariotaku.twidere.util.sync.FileBasedDraftsSyncAction +import org.mariotaku.twidere.util.tempFileInputStream import java.io.IOException import java.util.* @@ -27,20 +27,21 @@ internal class GoogleDriveDraftsSyncAction( @Throws(IOException::class) override fun Draft.saveToRemote(): DriveFileInfo { - val os = DirectByteArrayOutputStream() - this.writeMimeMessageTo(context, os) - val driveId = this.remote_extras - val `is` = os.inputStream(true) - val fileConfig: (File) -> Unit = { - it.modifiedTime = DateTime(timestamp) + tempFileInputStream(context) { os -> + this.writeMimeMessageTo(context, os) + }.use { + val driveId = this.remote_extras + val fileConfig: (File) -> Unit = { + it.modifiedTime = DateTime(timestamp) + } + val file = if (driveId != null) { + drive.files().performUpdate(driveId, filename, draftMimeType, stream = it, fileConfig = fileConfig) + } else { + drive.updateOrCreate(name = filename, mimeType = draftMimeType, parent = folderId, + spaces = appDataFolderSpace, stream = it, fileConfig = fileConfig) + } + return DriveFileInfo(file.id, file.name, Date(file.modifiedTime.value)) } - val file = if (driveId != null) { - drive.files().performUpdate(driveId, filename, draftMimeType, stream = `is`, fileConfig = fileConfig) - } else { - drive.updateOrCreate(name = filename, mimeType = draftMimeType, parent = folderId, - spaces = appDataFolderSpace, stream = `is`, fileConfig = fileConfig) - } - return DriveFileInfo(file.id, file.name, Date(file.modifiedTime.value)) } @Throws(IOException::class) diff --git a/twidere/src/google/kotlin/org/mariotaku/twidere/util/sync/google/GoogleDriveFiltersDataSyncAction.kt b/twidere/src/google/kotlin/org/mariotaku/twidere/util/sync/google/GoogleDriveFiltersDataSyncAction.kt index 587fd55ea..97f7075f0 100644 --- a/twidere/src/google/kotlin/org/mariotaku/twidere/util/sync/google/GoogleDriveFiltersDataSyncAction.kt +++ b/twidere/src/google/kotlin/org/mariotaku/twidere/util/sync/google/GoogleDriveFiltersDataSyncAction.kt @@ -9,8 +9,8 @@ import org.mariotaku.twidere.extension.model.serialize import org.mariotaku.twidere.extension.newPullParser import org.mariotaku.twidere.extension.newSerializer import org.mariotaku.twidere.model.FiltersData -import org.mariotaku.twidere.util.io.DirectByteArrayOutputStream import org.mariotaku.twidere.util.sync.FileBasedFiltersDataSyncAction +import org.mariotaku.twidere.util.tempFileInputStream import java.io.FileNotFoundException import java.io.IOException import java.io.InputStream @@ -56,9 +56,9 @@ internal class GoogleDriveFiltersDataSyncAction( override fun newSaveToRemoteSession(): GoogleDriveUploadSession { return object : GoogleDriveUploadSession(fileName, commonFolderId, xmlMimeType, drive) { override fun FiltersData.toInputStream(): InputStream { - val os = DirectByteArrayOutputStream() - this.serialize(os.newSerializer(charset = Charsets.UTF_8, indent = true)) - return os.inputStream(true) + return tempFileInputStream(context) { + this.serialize(it.newSerializer(charset = Charsets.UTF_8, indent = true)) + } } } } diff --git a/twidere/src/google/kotlin/org/mariotaku/twidere/util/sync/google/GoogleDrivePreferencesValuesSyncAction.kt b/twidere/src/google/kotlin/org/mariotaku/twidere/util/sync/google/GoogleDrivePreferencesValuesSyncAction.kt index ddf020464..ada9bac45 100644 --- a/twidere/src/google/kotlin/org/mariotaku/twidere/util/sync/google/GoogleDrivePreferencesValuesSyncAction.kt +++ b/twidere/src/google/kotlin/org/mariotaku/twidere/util/sync/google/GoogleDrivePreferencesValuesSyncAction.kt @@ -6,8 +6,8 @@ import com.google.api.services.drive.Drive import com.google.api.services.drive.model.File import org.mariotaku.twidere.extension.newPullParser import org.mariotaku.twidere.extension.newSerializer -import org.mariotaku.twidere.util.io.DirectByteArrayOutputStream import org.mariotaku.twidere.util.sync.FileBasedPreferencesValuesSyncAction +import org.mariotaku.twidere.util.tempFileInputStream import java.io.FileNotFoundException import java.io.IOException import java.io.InputStream @@ -48,9 +48,9 @@ internal class GoogleDrivePreferencesValuesSyncAction( override fun newSaveToRemoteSession(): GoogleDriveUploadSession> { return object : GoogleDriveUploadSession>(fileName, commonFolderId, xmlMimeType, drive) { override fun Map.toInputStream(): InputStream { - val os = DirectByteArrayOutputStream() - this.serialize(os.newSerializer(charset = Charsets.UTF_8, indent = true)) - return os.inputStream(true) + return tempFileInputStream(context) { + this.serialize(it.newSerializer(charset = Charsets.UTF_8, indent = true)) + } } } } diff --git a/twidere/src/google/kotlin/org/mariotaku/twidere/util/sync/google/GoogleDriveUploadSession.kt b/twidere/src/google/kotlin/org/mariotaku/twidere/util/sync/google/GoogleDriveUploadSession.kt index 02d212094..5ffb204d2 100644 --- a/twidere/src/google/kotlin/org/mariotaku/twidere/util/sync/google/GoogleDriveUploadSession.kt +++ b/twidere/src/google/kotlin/org/mariotaku/twidere/util/sync/google/GoogleDriveUploadSession.kt @@ -25,10 +25,12 @@ abstract internal class GoogleDriveUploadSession( abstract fun Data.toInputStream(): InputStream fun uploadData(data: Data): Boolean { - drive.updateOrCreate(name = name, mimeType = mimeType, parent = parentId, - spaces = appDataFolderSpace, stream = data.toInputStream(), fileConfig = { - it.modifiedTime = DateTime(localModifiedTime) - }) + data.toInputStream().use { + drive.updateOrCreate(name = name, mimeType = mimeType, parent = parentId, + spaces = appDataFolderSpace, stream = it, fileConfig = { + it.modifiedTime = DateTime(localModifiedTime) + }) + } return true } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/loader/MicroBlogAPIStatusesLoader.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/loader/MicroBlogAPIStatusesLoader.kt index 738205f33..cba7eca39 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/loader/MicroBlogAPIStatusesLoader.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/loader/MicroBlogAPIStatusesLoader.kt @@ -43,12 +43,8 @@ import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.util.AccountUtils import org.mariotaku.twidere.model.util.ParcelableStatusUtils import org.mariotaku.twidere.task.twitter.GetStatusesTask -import org.mariotaku.twidere.util.JsonSerializer -import org.mariotaku.twidere.util.SharedPreferencesWrapper -import org.mariotaku.twidere.util.TwidereArrayUtils -import org.mariotaku.twidere.util.UserColorNameManager +import org.mariotaku.twidere.util.* import org.mariotaku.twidere.util.dagger.GeneralComponentHelper -import java.io.ByteArrayInputStream import java.io.IOException import java.util.* import java.util.concurrent.CopyOnWriteArrayList @@ -237,10 +233,9 @@ abstract class MicroBlogAPIStatusesLoader( val databaseItemLimit = preferences[loadItemLimitKey] try { val statuses = data.subList(0, Math.min(databaseItemLimit, data.size)) - fileCache.save(key, ByteArrayInputStream(byteArrayOf())) { current, total -> true } - fileCache.get(key)?.outputStream()?.use { - LoganSquare.serialize(statuses, it, ParcelableStatus::class.java) - } + fileCache.save(key, tempFileInputStream(context) { os -> + LoganSquare.serialize(statuses, os, ParcelableStatus::class.java) + }) { current, total -> true } } catch (e: Exception) { // Ignore if (BuildConfig.DEBUG && e !is IOException) { diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/service/LengthyOperationsService.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/service/LengthyOperationsService.kt index 2f9943c34..6d5b8f1b9 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/service/LengthyOperationsService.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/service/LengthyOperationsService.kt @@ -259,7 +259,13 @@ class LengthyOperationsService : BaseIntentService("lengthy_operations") { val exception = result.exception val exceptions = result.exceptions if (exception != null) { - Toast.makeText(context, exception.message, Toast.LENGTH_SHORT).show() + val cause = exception.cause + if (cause is MicroBlogException) { + Toast.makeText(context, cause.errors?.firstOrNull()?.message ?: cause.message, + Toast.LENGTH_SHORT).show() + } else { + Toast.makeText(context, exception.message, Toast.LENGTH_SHORT).show() + } failed = true Log.w(LOGTAG, exception) } else for (e in exceptions) { diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/util/IOFunctions.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/util/IOFunctions.kt new file mode 100644 index 000000000..ebdbcecbd --- /dev/null +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/util/IOFunctions.kt @@ -0,0 +1,27 @@ +package org.mariotaku.twidere.util + +import android.content.Context +import java.io.File +import java.io.FileInputStream +import java.io.InputStream +import java.io.OutputStream + +/** + * Created by mariotaku on 2017/1/24. + */ + +fun tempFileInputStream(context: Context, write: (OutputStream) -> Unit): InputStream { + val file = File.createTempFile("twidere__temp_is_file", "tmp", context.cacheDir) + file.outputStream().use { write(it) } + return TempFileInputStream(file) +} + +internal class TempFileInputStream(val file: File) : FileInputStream(file) { + override fun close() { + try { + super.close() + } finally { + file.delete() + } + } +} \ No newline at end of file diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/util/io/DirectByteArrayOutputStream.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/util/io/DirectByteArrayOutputStream.kt deleted file mode 100644 index d41fd9b14..000000000 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/util/io/DirectByteArrayOutputStream.kt +++ /dev/null @@ -1,24 +0,0 @@ -package org.mariotaku.twidere.util.io - -import java.io.ByteArrayInputStream -import java.io.ByteArrayOutputStream -import java.io.InputStream - -class DirectByteArrayOutputStream : ByteArrayOutputStream() { - - fun inputStream(close: Boolean): InputStream { - return DirectInputStream(this, close) - } - - internal class DirectInputStream( - val os: DirectByteArrayOutputStream, - val close: Boolean - ) : ByteArrayInputStream(os.buf, 0, os.count) { - override fun close() { - if (close) { - os.close() - } - super.close() - } - } -} \ No newline at end of file