Mercurial > cgi-bin > hgweb.cgi > PassMan
diff src/main/kotlin/name/blackcap/passman/ExportSubcommand.kt @ 16:7a74ae668665
Add export subcommand.
author | David Barts <n5jrn@me.com> |
---|---|
date | Sun, 05 Feb 2023 10:50:39 -0800 |
parents | |
children | ea65ab890f66 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/kotlin/name/blackcap/passman/ExportSubcommand.kt Sun Feb 05 10:50:39 2023 -0800 @@ -0,0 +1,77 @@ +package name.blackcap.passman + +import com.opencsv.CSVWriterBuilder +import com.opencsv.ICSVWriter +import java.io.FileOutputStream +import java.io.IOException +import java.io.OutputStreamWriter +import java.sql.ResultSet +import java.text.SimpleDateFormat +import java.util.* + +class ExportSubcommand() : Subcommand() { + private companion object { + const val NULL = "null" + } + private lateinit var csvDateFormat: SimpleDateFormat + private lateinit var db: Database + private val options = ImportExportArguments() + private lateinit var csvFile: String + + override fun run(args: Array<String>) { + parseArguments(args) + db = Database.open() + try { + doExport() + } catch (e: IOException) { + die(e.message ?: "I/O error") + } + } + + private fun parseArguments(args: Array<String>) { + val params = parseInto("export", args, options) + when (params.size) { + 0 -> die("expecting CSV file name", 2) + 1 -> csvFile = params[0] + else -> die("unexpected trailing arguments", 2) + } + csvDateFormat = SimpleDateFormat(options.format).apply { + timeZone = TimeZone.getTimeZone(options.zone) + isLenient = false + } + } + + private fun doExport() { + val csvWriter = CSVWriterBuilder(OutputStreamWriter(FileOutputStream(csvFile), options.charset)) + .withEscapeChar(options.escape) + .withQuoteChar(options.quote) + .withSeparator(options.separator) + .withLineEnd(ICSVWriter.RFC4180_LINE_END) + .build() + + try { + db.connection.prepareStatement("select name, username, password, notes, created, modified, accessed from passwords").use { + val results = it.executeQuery() + while (results.next()) { + val entry = arrayOf<String>( + results.getDecryptedString(1, db.encryption)!!, + results.getDecryptedString(2, db.encryption)!!, + results.getDecryptedString(3, db.encryption)!!, + results.getDecryptedString(4, db.encryption) ?: NULL, + results.getTimeString(5), + results.getTimeString(6), + results.getTimeString(7) + ) + csvWriter.writeNext(entry) + } + } + } finally { + csvWriter.close() + } + } + + private fun ResultSet.getTimeString(columnIndex: Int): String { + val value = getDate(columnIndex) + return if (value == null) NULL else csvDateFormat.format(value) + } +} \ No newline at end of file