Code style improvements (thanks to codebeat.co)

This commit is contained in:
Christian Basler 2017-11-22 21:07:09 +01:00
parent 49d87c3c75
commit dd22caaa50
3 changed files with 174 additions and 141 deletions

View File

@ -20,7 +20,6 @@ import android.app.Activity
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.SharedPreferences import android.content.SharedPreferences
import android.net.Uri
import android.os.Bundle import android.os.Bundle
import android.preference.PreferenceManager import android.preference.PreferenceManager
import android.support.v4.content.FileProvider.getUriForFile import android.support.v4.content.FileProvider.getUriForFile
@ -31,24 +30,14 @@ import ch.dissem.apps.abit.service.Singleton
import ch.dissem.apps.abit.synchronization.SyncAdapter import ch.dissem.apps.abit.synchronization.SyncAdapter
import ch.dissem.apps.abit.util.Constants.PREFERENCE_SERVER_POW import ch.dissem.apps.abit.util.Constants.PREFERENCE_SERVER_POW
import ch.dissem.apps.abit.util.Constants.PREFERENCE_TRUSTED_NODE import ch.dissem.apps.abit.util.Constants.PREFERENCE_TRUSTED_NODE
import ch.dissem.apps.abit.util.Exports
import ch.dissem.apps.abit.util.Preferences import ch.dissem.apps.abit.util.Preferences
import ch.dissem.bitmessage.entity.valueobject.Label
import ch.dissem.bitmessage.exports.ContactExport
import ch.dissem.bitmessage.exports.MessageExport
import ch.dissem.bitmessage.utils.UnixTime
import com.beust.klaxon.JsonArray
import com.beust.klaxon.Parser
import com.mikepenz.aboutlibraries.Libs import com.mikepenz.aboutlibraries.Libs
import com.mikepenz.aboutlibraries.LibsBuilder import com.mikepenz.aboutlibraries.LibsBuilder
import org.jetbrains.anko.doAsync import org.jetbrains.anko.doAsync
import org.jetbrains.anko.support.v4.indeterminateProgressDialog import org.jetbrains.anko.support.v4.indeterminateProgressDialog
import org.jetbrains.anko.support.v4.startActivity import org.jetbrains.anko.support.v4.startActivity
import org.jetbrains.anko.uiThread import org.jetbrains.anko.uiThread
import java.io.File
import java.io.FileOutputStream
import java.util.zip.ZipEntry
import java.util.zip.ZipInputStream
import java.util.zip.ZipOutputStream
/** /**
* @author Christian Basler * @author Christian Basler
@ -101,43 +90,20 @@ class SettingsFragment : PreferenceFragmentCompat(), SharedPreferences.OnSharedP
findPreference("export")?.onPreferenceClickListener = Preference.OnPreferenceClickListener { findPreference("export")?.onPreferenceClickListener = Preference.OnPreferenceClickListener {
val ctx = context ?: throw IllegalStateException("No context available") val ctx = context ?: throw IllegalStateException("No context available")
val dialog = indeterminateProgressDialog(R.string.export_data_summary, R.string.export_data) indeterminateProgressDialog(R.string.export_data_summary, R.string.export_data).apply {
doAsync { doAsync {
val exportDirectory = Preferences.getExportDirectory(ctx) val exportDirectory = Preferences.getExportDirectory(ctx)
exportDirectory.mkdirs() exportDirectory.mkdirs()
val temp = File(exportDirectory, "export-${UnixTime.now}.zip") val file = Exports.exportData(exportDirectory, ctx)
ZipOutputStream(FileOutputStream(temp)).use { zip -> val contentUri = getUriForFile(ctx, "ch.dissem.apps.abit.fileprovider", file)
zip.putNextEntry(ZipEntry("contacts.json"))
val addressRepo = Singleton.getAddressRepository(ctx)
val exportContacts = ContactExport.exportContacts(addressRepo.getContacts())
zip.write(
exportContacts.toJsonString(true).toByteArray()
)
zip.closeEntry()
val messageRepo = Singleton.getMessageRepository(ctx)
zip.putNextEntry(ZipEntry("labels.json"))
val exportLabels = MessageExport.exportLabels(messageRepo.getLabels())
zip.write(
exportLabels.toJsonString(true).toByteArray()
)
zip.closeEntry()
zip.putNextEntry(ZipEntry("messages.json"))
val exportMessages = MessageExport.exportMessages(messageRepo.getAllMessages())
zip.write(
exportMessages.toJsonString(true).toByteArray()
)
zip.closeEntry()
}
val contentUri = getUriForFile(ctx, "ch.dissem.apps.abit.fileprovider", temp)
val intent = Intent(android.content.Intent.ACTION_SEND) val intent = Intent(android.content.Intent.ACTION_SEND)
intent.type = "application/zip" intent.type = "application/zip"
intent.putExtra(Intent.EXTRA_SUBJECT, "abit-export.zip") intent.putExtra(Intent.EXTRA_SUBJECT, "abit-export.zip")
intent.putExtra(Intent.EXTRA_STREAM, contentUri) intent.putExtra(Intent.EXTRA_STREAM, contentUri)
startActivityForResult(Intent.createChooser(intent, ""), WRITE_EXPORT_REQUEST_CODE) startActivityForResult(Intent.createChooser(intent, ""), WRITE_EXPORT_REQUEST_CODE)
uiThread { uiThread {
dialog.dismiss() dismiss()
}
} }
} }
return@OnPreferenceClickListener true return@OnPreferenceClickListener true
@ -163,52 +129,18 @@ class SettingsFragment : PreferenceFragmentCompat(), SharedPreferences.OnSharedP
} }
} }
private fun processEntry(ctx: Context, zipFile: Uri, entry: String, processor: (JsonArray<*>) -> Unit) =
ZipInputStream(ctx.contentResolver.openInputStream(zipFile)).use { zip ->
var nextEntry = zip.nextEntry
while (nextEntry != null) {
if (nextEntry.name == entry) {
processor(Parser().parse(zip) as JsonArray<*>)
}
nextEntry = zip.nextEntry
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
val ctx = context ?: throw IllegalStateException("No context available") val ctx = context ?: throw IllegalStateException("No context available")
when (requestCode) { when (requestCode) {
WRITE_EXPORT_REQUEST_CODE -> Preferences.cleanupExportDirectory(ctx) WRITE_EXPORT_REQUEST_CODE -> Preferences.cleanupExportDirectory(ctx)
READ_IMPORT_REQUEST_CODE -> { READ_IMPORT_REQUEST_CODE -> {
if (resultCode == Activity.RESULT_OK && data?.data != null) { if (resultCode == Activity.RESULT_OK && data?.data != null) {
val dialog = indeterminateProgressDialog(R.string.import_data_summary, R.string.import_data) indeterminateProgressDialog(R.string.import_data_summary, R.string.import_data).apply {
doAsync { doAsync {
val bmc = Singleton.getBitmessageContext(ctx) Exports.importData(data.data, ctx)
val labels = mutableMapOf<String, Label>()
val zipFile = data.data
processEntry(ctx, zipFile, "contacts.json") { json ->
ContactExport.importContacts(json).forEach { contact ->
bmc.addresses.save(contact)
}
}
bmc.messages.getLabels().forEach { label ->
labels[label.toString()] = label
}
processEntry(ctx, zipFile, "labels.json") { json ->
MessageExport.importLabels(json).forEach { label ->
if (!labels.contains(label.toString())) {
bmc.messages.save(label)
labels[label.toString()] = label
}
}
}
processEntry(ctx, zipFile, "messages.json") { json ->
MessageExport.importMessages(json, labels).forEach { message ->
bmc.messages.save(message)
}
}
uiThread { uiThread {
dialog.dismiss() dismiss()
}
} }
} }
} }
@ -227,7 +159,12 @@ class SettingsFragment : PreferenceFragmentCompat(), SharedPreferences.OnSharedP
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) { override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) {
when (key) { when (key) {
PREFERENCE_TRUSTED_NODE -> { PREFERENCE_TRUSTED_NODE -> toggleSyncTrustedNode(sharedPreferences)
PREFERENCE_SERVER_POW -> toggleSyncServerPOW(sharedPreferences)
}
}
private fun toggleSyncTrustedNode(sharedPreferences: SharedPreferences) {
val node = sharedPreferences.getString(PREFERENCE_TRUSTED_NODE, null) val node = sharedPreferences.getString(PREFERENCE_TRUSTED_NODE, null)
val ctx = context ?: throw IllegalStateException("No context available") val ctx = context ?: throw IllegalStateException("No context available")
if (node != null) { if (node != null) {
@ -236,7 +173,8 @@ class SettingsFragment : PreferenceFragmentCompat(), SharedPreferences.OnSharedP
SyncAdapter.stopSync(ctx) SyncAdapter.stopSync(ctx)
} }
} }
PREFERENCE_SERVER_POW -> {
private fun toggleSyncServerPOW(sharedPreferences: SharedPreferences) {
val node = sharedPreferences.getString(PREFERENCE_TRUSTED_NODE, null) val node = sharedPreferences.getString(PREFERENCE_TRUSTED_NODE, null)
if (node != null) { if (node != null) {
val ctx = context ?: throw IllegalStateException("No context available") val ctx = context ?: throw IllegalStateException("No context available")
@ -247,8 +185,6 @@ class SettingsFragment : PreferenceFragmentCompat(), SharedPreferences.OnSharedP
} }
} }
} }
}
}
companion object { companion object {
const val WRITE_EXPORT_REQUEST_CODE = 1 const val WRITE_EXPORT_REQUEST_CODE = 1

View File

@ -17,6 +17,7 @@
package ch.dissem.apps.abit.repository package ch.dissem.apps.abit.repository
import android.content.ContentValues import android.content.ContentValues
import android.database.Cursor
import ch.dissem.bitmessage.entity.BitmessageAddress import ch.dissem.bitmessage.entity.BitmessageAddress
import ch.dissem.bitmessage.entity.payload.V3Pubkey import ch.dissem.bitmessage.entity.payload.V3Pubkey
import ch.dissem.bitmessage.entity.payload.V4Pubkey import ch.dissem.bitmessage.entity.payload.V4Pubkey
@ -118,34 +119,36 @@ class AndroidAddressRepository(private val sql: SqlHelper) : AddressRepository {
where, null, null, null, null where, null, null, null, null
).use { c -> ).use { c ->
while (c.moveToNext()) { while (c.moveToNext()) {
result.add(getAddress(c))
}
}
return result
}
private fun getAddress(c: Cursor): BitmessageAddress {
val address: BitmessageAddress val address: BitmessageAddress
val privateKeyBytes = c.getBlob(c.getColumnIndex(COLUMN_PRIVATE_KEY)) val privateKeyBytes = c.getBlob(c.getColumnIndex(COLUMN_PRIVATE_KEY))
if (privateKeyBytes != null) { if (privateKeyBytes != null) {
val privateKey = PrivateKey.read(ByteArrayInputStream(privateKeyBytes)) address = BitmessageAddress(PrivateKey.read(ByteArrayInputStream(privateKeyBytes)))
address = BitmessageAddress(privateKey)
} else { } else {
address = BitmessageAddress(c.getString(c.getColumnIndex(COLUMN_ADDRESS))) address = BitmessageAddress(c.getString(c.getColumnIndex(COLUMN_ADDRESS)))
val publicKeyBytes = c.getBlob(c.getColumnIndex(COLUMN_PUBLIC_KEY)) c.getBlob(c.getColumnIndex(COLUMN_PUBLIC_KEY))?.let { publicKeyBytes ->
if (publicKeyBytes != null) { val pubkey = Factory.readPubkey(address.version, address.stream,
var pubkey = Factory.readPubkey(address.version, address
.stream,
ByteArrayInputStream(publicKeyBytes), publicKeyBytes.size, ByteArrayInputStream(publicKeyBytes), publicKeyBytes.size,
false) false)
if (address.version == 4L && pubkey is V3Pubkey) { address.pubkey = if (address.version == 4L && pubkey is V3Pubkey) {
pubkey = V4Pubkey(pubkey) V4Pubkey(pubkey)
} else {
pubkey
} }
address.pubkey = pubkey
} }
} }
address.alias = c.getString(c.getColumnIndex(COLUMN_ALIAS)) address.alias = c.getString(c.getColumnIndex(COLUMN_ALIAS))
address.isChan = c.getInt(c.getColumnIndex(COLUMN_CHAN)) == 1 address.isChan = c.getInt(c.getColumnIndex(COLUMN_CHAN)) == 1
address.isSubscribed = c.getInt(c.getColumnIndex(COLUMN_SUBSCRIBED)) == 1 address.isSubscribed = c.getInt(c.getColumnIndex(COLUMN_SUBSCRIBED)) == 1
result.add(address) return address
}
}
return result
} }
override fun save(address: BitmessageAddress) = if (exists(address)) { override fun save(address: BitmessageAddress) = if (exists(address)) {

View File

@ -0,0 +1,94 @@
package ch.dissem.apps.abit.util
import android.content.Context
import android.net.Uri
import ch.dissem.apps.abit.service.Singleton
import ch.dissem.bitmessage.entity.valueobject.Label
import ch.dissem.bitmessage.exports.ContactExport
import ch.dissem.bitmessage.exports.MessageExport
import ch.dissem.bitmessage.utils.UnixTime
import com.beust.klaxon.JsonArray
import com.beust.klaxon.Parser
import java.io.File
import java.io.FileOutputStream
import java.util.zip.ZipEntry
import java.util.zip.ZipInputStream
import java.util.zip.ZipOutputStream
/**
* Helper object for data export and import.
*/
object Exports {
fun exportData(target: File, ctx: Context): File {
val temp = if (target.isDirectory) {
File(target, "export-${UnixTime.now}.zip")
} else {
target
}
ZipOutputStream(FileOutputStream(temp)).use { zip ->
zip.putNextEntry(ZipEntry("contacts.json"))
val addressRepo = Singleton.getAddressRepository(ctx)
val exportContacts = ContactExport.exportContacts(addressRepo.getContacts())
zip.write(
exportContacts.toJsonString(true).toByteArray()
)
zip.closeEntry()
val messageRepo = Singleton.getMessageRepository(ctx)
zip.putNextEntry(ZipEntry("labels.json"))
val exportLabels = MessageExport.exportLabels(messageRepo.getLabels())
zip.write(
exportLabels.toJsonString(true).toByteArray()
)
zip.closeEntry()
zip.putNextEntry(ZipEntry("messages.json"))
val exportMessages = MessageExport.exportMessages(messageRepo.getAllMessages())
zip.write(
exportMessages.toJsonString(true).toByteArray()
)
zip.closeEntry()
}
return temp
}
fun importData(zipFile: Uri, ctx: Context) {
val bmc = Singleton.getBitmessageContext(ctx)
val labels = mutableMapOf<String, Label>()
processEntry(ctx, zipFile, "contacts.json") { json ->
ContactExport.importContacts(json).forEach { contact ->
bmc.addresses.save(contact)
}
}
bmc.messages.getLabels().forEach { label ->
labels[label.toString()] = label
}
processEntry(ctx, zipFile, "labels.json") { json ->
MessageExport.importLabels(json).forEach { label ->
if (!labels.contains(label.toString())) {
bmc.messages.save(label)
labels[label.toString()] = label
}
}
}
processEntry(ctx, zipFile, "messages.json") { json ->
MessageExport.importMessages(json, labels).forEach { message ->
bmc.messages.save(message)
}
}
}
private fun processEntry(ctx: Context, zipFile: Uri, entry: String, processor: (JsonArray<*>) -> Unit) =
ZipInputStream(ctx.contentResolver.openInputStream(zipFile)).use { zip ->
var nextEntry = zip.nextEntry
while (nextEntry != null) {
if (nextEntry.name == entry) {
processor(Parser().parse(zip) as JsonArray<*>)
}
nextEntry = zip.nextEntry
}
}
}