Mercurial > cgi-bin > hgweb.cgi > PassMan
comparison src/main/kotlin/name/blackcap/passman/ListSubcommand.kt @ 21:ea65ab890f66
More work to support interactive feature.
author | David Barts <n5jrn@me.com> |
---|---|
date | Tue, 02 Jul 2024 11:27:39 -0700 |
parents | 72619175004e |
children | 07406c4af4a5 |
comparison
equal
deleted
inserted
replaced
20:4391afcf6bd0 | 21:ea65ab890f66 |
---|---|
1 package name.blackcap.passman | 1 package name.blackcap.passman |
2 | 2 |
3 import org.apache.commons.cli.* | 3 import org.apache.commons.cli.* |
4 import java.util.regex.PatternSyntaxException | 4 import java.util.regex.PatternSyntaxException |
5 import kotlin.system.exitProcess | |
6 | 5 |
7 class ListSubcommand(): Subcommand() { | 6 class ListSubcommand(): Subcommand() { |
8 private companion object { | 7 private companion object { |
9 const val CASE = "case" | 8 const val CASE = "case" |
10 const val FIXED = "fixed" | 9 const val FIXED = "fixed" |
55 } | 54 } |
56 } | 55 } |
57 try { | 56 try { |
58 commandLine = DefaultParser().parse(options, args) | 57 commandLine = DefaultParser().parse(options, args) |
59 } catch (e: ParseException) { | 58 } catch (e: ParseException) { |
60 die(e.message ?: "syntax error", 2) | 59 throw SubcommandException(message = e.message ?: "syntax error", cause = e, status = 2) |
61 } | 60 } |
62 if (commandLine.hasOption(HELP)) { | 61 if (commandLine.hasOption(HELP)) { |
63 HelpFormatter().printHelp("$SHORTNAME list [options]", options) | 62 HelpFormatter().printHelp("$SHORTNAME list [options]", options) |
64 exitProcess(0) | 63 return |
65 } | 64 } |
66 if (commandLine.args.isNotEmpty()) { | 65 if (commandLine.args.isNotEmpty()) { |
67 die("unexpected trailing arguments", 2) | 66 throw SubcommandException(message = "unexpected trailing arguments", status = 2) |
68 } | 67 } |
69 | 68 |
70 STRING_OPTIONS.forEach { | 69 STRING_OPTIONS.forEach { |
71 commandLine.getOptionValues(it.name)?.forEach { value -> | 70 commandLine.getOptionValues(it.name)?.forEach { value -> |
72 val regexOptions = mutableSetOf<RegexOption>() | 71 val regexOptions = mutableSetOf<RegexOption>() |
80 if (it.name !in matchers) { | 79 if (it.name !in matchers) { |
81 matchers[it.name] = mutableListOf<(Any?) -> Boolean>() | 80 matchers[it.name] = mutableListOf<(Any?) -> Boolean>() |
82 } | 81 } |
83 matchers[it.name]!! += { x -> x is String && x.contains(Regex(value, regexOptions)) } | 82 matchers[it.name]!! += { x -> x is String && x.contains(Regex(value, regexOptions)) } |
84 } catch (e: PatternSyntaxException) { | 83 } catch (e: PatternSyntaxException) { |
85 die("${see(value)} - invalid regular expression") | 84 throw SubcommandException(message = "${see(value)} - invalid regular expression", cause = e, status = 2) |
86 } | 85 } |
87 } | 86 } |
88 } | 87 } |
89 | 88 |
90 TIME_OPTIONS.forEach { | 89 TIME_OPTIONS.forEach { |
91 commandLine.getOptionValues(it.name)?.forEach { rawValue -> | 90 commandLine.getOptionValues(it.name)?.forEach { rawValue -> |
92 if (rawValue.isEmpty()) { | 91 if (rawValue.isEmpty()) { |
93 die("empty string is not a valid time expression") | 92 throw SubcommandException(message = "empty string is not a valid time expression") |
94 } | 93 } |
95 val (op, exp) = when(rawValue.first()) { | 94 val (op, exp) = when(rawValue.first()) { |
96 '+', '>' -> Pair<Char, String>('>', rawValue.substring(1)) | 95 '+', '>' -> Pair<Char, String>('>', rawValue.substring(1)) |
97 '=' -> Pair<Char, String>('=', rawValue.substring(1)) | 96 '=' -> Pair<Char, String>('=', rawValue.substring(1)) |
98 '-', '<' -> Pair<Char, String>('<', rawValue.substring(1)) | 97 '-', '<' -> Pair<Char, String>('<', rawValue.substring(1)) |
99 else -> Pair<Char, String>('=', rawValue) | 98 else -> Pair<Char, String>('=', rawValue) |
100 } | 99 } |
101 val value = parseDateTime(exp) | 100 val value = parseDateTime(exp) |
102 if (value == null) { | 101 if (value == null) { |
103 die("${see(rawValue)} - invalid time expression") | 102 throw SubcommandException(message = "${see(rawValue)} - invalid time expression") |
104 throw RuntimeException("will never happen") | |
105 } | 103 } |
106 if (it.name !in matchers) { | 104 if (it.name !in matchers) { |
107 matchers[it.name] = mutableListOf<(Any?) -> Boolean>() | 105 matchers[it.name] = mutableListOf<(Any?) -> Boolean>() |
108 } | 106 } |
109 when(op) { | 107 when(op) { |
115 } | 113 } |
116 } | 114 } |
117 } | 115 } |
118 | 116 |
119 private fun runQuery(): Unit { | 117 private fun runQuery(): Unit { |
120 val db = Database.open() | 118 val db = Database.default |
121 | 119 |
122 db.connection.prepareStatement("select $NAME, $USERNAME, $NOTES, $CREATED, $MODIFIED, $ACCESSED from passwords").use { | 120 db.connection.prepareStatement("select $NAME, $USERNAME, $NOTES, $CREATED, $MODIFIED, $ACCESSED from passwords").use { |
123 val results = it.executeQuery() | 121 val results = it.executeQuery() |
124 val printer = if (commandLine.hasOption(LONG)) Entry::printLong else Entry::print | 122 val printer = if (commandLine.hasOption(LONG)) Entry::printLong else Entry::print |
125 var count = 0; | 123 var count = 0; |