Improve table rendering and uer details display
| | |
| | | IPublicKeyManager keyManager = getContext().getGitblit().getPublicKeyManager(); |
| | | String username = getContext().getClient().getUsername(); |
| | | List<SshKey> keys = keyManager.getKeys(username); |
| | | if (keys == null || keys.isEmpty()) { |
| | | stdout.println("You have not registered any public keys for ssh authentication."); |
| | | return; |
| | | } |
| | | |
| | | if (showRaw) { |
| | | asRaw(keys); |
| | |
| | | |
| | | /* output in the same format as authorized_keys */ |
| | | protected void asRaw(List<SshKey> keys) { |
| | | if (keys == null) { |
| | | return; |
| | | } |
| | | for (SshKey key : keys) { |
| | | stdout.println(key.getRawData()); |
| | | } |
| | |
| | | |
| | | protected void asTable(List<SshKey> keys) { |
| | | String[] headers = { "#", "Fingerprint", "Comment", "Type" }; |
| | | String[][] data = new String[keys.size()][]; |
| | | for (int i = 0; i < keys.size(); i++) { |
| | | int len = keys == null ? 0 : keys.size(); |
| | | String[][] data = new String[len][]; |
| | | for (int i = 0; i < len; i++) { |
| | | // show 1-based index numbers with the fingerprint |
| | | // this is useful for comparing with "ssh-add -l" |
| | | SshKey k = keys.get(i); |
| | | data[i] = new String[] { "" + (i + 1), k.getFingerprint(), k.getComment(), k.getAlgorithm() }; |
| | | } |
| | | |
| | | stdout.println(FlipTable.of(headers, data, Borders.BODY_COLS)); |
| | | stdout.println(FlipTable.of(headers, data, Borders.BODY_HCOLS)); |
| | | } |
| | | } |
| | | } |
| | |
| | | String[] h = { "Name", "Description", "Last Modified", "# Repos" }; |
| | | headers = h; |
| | | } else { |
| | | String[] h = { "Name", "Description" }; |
| | | String[] h = { "Name", "Last Modified", "# Repos" }; |
| | | headers = h; |
| | | } |
| | | |
| | |
| | | if (verbose) { |
| | | data[i] = new String[] { p.name, p.description, df.format(p.lastChange), "" + p.repositories.size() }; |
| | | } else { |
| | | data[i] = new String[] { p.name, p.description }; |
| | | data[i] = new String[] { p.name, df.format(p.lastChange), "" + p.repositories.size() }; |
| | | } |
| | | } |
| | | stdout.println(FlipTable.of(headers, data, Borders.BODY_COLS)); |
| | | stdout.println(FlipTable.of(headers, data, Borders.BODY_HCOLS)); |
| | | } |
| | | |
| | | protected void asTabbed(List<ProjectModel> list) { |
| | |
| | | String[] h = { "Name", "Description", "Owners", "Last Modified", "Size" }; |
| | | headers = h; |
| | | } else { |
| | | String[] h = { "Name", "Description" }; |
| | | String[] h = { "Name", "Last Modified", "Size" }; |
| | | headers = h; |
| | | } |
| | | |
| | |
| | | for (int i = 0; i < list.size(); i++) { |
| | | RepositoryModel r = list.get(i); |
| | | |
| | | String lm = df.format(r.lastChange); |
| | | String size = r.size; |
| | | if (!r.hasCommits) { |
| | | lm = ""; |
| | | size = "(empty)"; |
| | | } |
| | | if (verbose) { |
| | | String lm = df.format(r.lastChange); |
| | | String owners = ""; |
| | | if (!ArrayUtils.isEmpty(r.owners)) { |
| | | owners = Joiner.on(",").join(r.owners); |
| | | } |
| | | String size = r.size; |
| | | if (!r.hasCommits) { |
| | | size = "(empty)"; |
| | | } |
| | | data[i] = new String[] { r.name, r.description, owners, lm, size }; |
| | | } else { |
| | | data[i] = new String[] { r.name, r.description }; |
| | | data[i] = new String[] { r.name, lm, size }; |
| | | } |
| | | } |
| | | stdout.println(FlipTable.of(headers, data, Borders.BODY_COLS)); |
| | | stdout.println(FlipTable.of(headers, data, Borders.BODY_HCOLS)); |
| | | } |
| | | |
| | | protected void asTabbed(List<RepositoryModel> list) { |
| | |
| | | } |
| | | String size = r.size; |
| | | if (!r.hasCommits) { |
| | | lm = ""; |
| | | size = "(empty)"; |
| | | } |
| | | |
| | |
| | | |
| | | import com.gitblit.manager.IGitblit; |
| | | import com.gitblit.models.RegistrantAccessPermission; |
| | | import com.gitblit.models.TeamModel; |
| | | import com.gitblit.models.UserModel; |
| | | import com.gitblit.transport.ssh.commands.CommandMetaData; |
| | | import com.gitblit.transport.ssh.commands.DispatchCommand; |
| | |
| | | |
| | | @CommandMetaData(name = "users", description = "User management commands", admin = true) |
| | | public class UsersDispatcher extends DispatchCommand { |
| | | |
| | | private static final String banner1 = "==========================================================="; |
| | | |
| | | private static final String banner2 = "-----------------------------------------------------------"; |
| | | |
| | | @Override |
| | | protected void setup(UserModel user) { |
| | |
| | | @Override |
| | | public void run() throws UnloggedFailure { |
| | | IGitblit gitblit = getContext().getGitblit(); |
| | | UserModel user = gitblit.getUserModel(username); |
| | | if (user == null) { |
| | | UserModel u = gitblit.getUserModel(username); |
| | | if (u == null) { |
| | | throw new UnloggedFailure(1, String.format("Unknown user \"%s\"", username)); |
| | | } |
| | | stdout.println(); |
| | | stdout.println(user.username); |
| | | stdout.println(); |
| | | for (RegistrantAccessPermission ap : user.getRepositoryPermissions()) { |
| | | stdout.println(String.format("%s %s", ap.registrant, ap.permission)); |
| | | |
| | | // fields |
| | | String [] fheaders = new String [] { "Field", "Value" }; |
| | | String [][] fdata = new String[5][]; |
| | | fdata[0] = new String [] { "Email", u.emailAddress }; |
| | | fdata[1] = new String [] { "Type", u.accountType.toString() }; |
| | | fdata[2] = new String [] { "Can Admin", u.canAdmin() ? "Y":"N" }; |
| | | fdata[3] = new String [] { "Can Fork", u.canFork() ? "Y":"N" }; |
| | | fdata[4] = new String [] { "Can Create", u.canCreate() ? "Y":"N" }; |
| | | String fields = FlipTable.of(fheaders, fdata, Borders.COLS); |
| | | |
| | | // teams |
| | | String [] theaders = new String [] { "Team", "Type" }; |
| | | String [][] tdata = new String[u.teams.size()][]; |
| | | int i = 0; |
| | | for (TeamModel t : u.teams) { |
| | | tdata[i] = new String [] { t.name, t.accountType.toString() }; |
| | | i++; |
| | | } |
| | | String teams = FlipTable.of(theaders, tdata, Borders.COLS); |
| | | |
| | | // permissions |
| | | List<RegistrantAccessPermission> perms = u.getRepositoryPermissions(); |
| | | String[] pheaders = { "Repository", "Permission", "Type", "Source", "Mutable" }; |
| | | String [][] pdata = new String[perms.size()][]; |
| | | for (i = 0; i < perms.size(); i++) { |
| | | RegistrantAccessPermission ap = perms.get(i); |
| | | pdata[i] = new String[] { ap.registrant, ap.permission.toString(), ap.permissionType.toString(), ap.source, ap.mutable ? "Y":"N" }; |
| | | } |
| | | String permissions = FlipTable.of(pheaders, pdata, Borders.COLS); |
| | | |
| | | // assemble user table |
| | | String [] headers = new String[] { u.getDisplayName() + (u.username.equals(u.getDisplayName()) ? "" : (" (" + u.username + ")")) }; |
| | | String[][] data = new String[6][]; |
| | | data[0] = new String [] { "FIELDS" }; |
| | | data[1] = new String [] { fields }; |
| | | data[2] = new String [] { "TEAMS" }; |
| | | data[3] = new String [] { teams }; |
| | | data[4] = new String [] { "PERMISSIONS" }; |
| | | data[5] = new String [] { permissions }; |
| | | stdout.println(FlipTable.of(headers, data)); |
| | | } |
| | | } |
| | | |
| | |
| | | protected void asTable(List<UserModel> list) { |
| | | String[] headers; |
| | | if (verbose) { |
| | | String[] h = { "Name", "Display name", "Type", "E-mail", "Create?", "Fork?"}; |
| | | String[] h = { "Name", "Display name", "Type", "Email", "Create?", "Fork?"}; |
| | | headers = h; |
| | | } else { |
| | | String[] h = { "Name", "Display name", "Type", "E-mail"}; |
| | | String[] h = { "Name", "Display name", "Type", "Email"}; |
| | | headers = h; |
| | | } |
| | | |
| | |
| | | |
| | | String name = u.disabled ? "-" : ((u.canAdmin() ? "*" : " ")) + u.username; |
| | | if (verbose) { |
| | | data[i] = new String[] { name, u.displayName == null ? "" : u.displayName, |
| | | u.accountType.name(), u.emailAddress == null ? "" : u.emailAddress , |
| | | u.canCreate() ? "Y":"", u.canFork() ? "Y" : ""}; |
| | | data[i] = new String[] { name, u.displayName, u.accountType.name(), |
| | | u.emailAddress, u.canCreate() ? "Y":"", u.canFork() ? "Y" : ""}; |
| | | } else { |
| | | data[i] = new String[] { name, u.displayName == null ? "" : u.displayName, |
| | | u.accountType.name(), u.emailAddress == null ? "" : u.emailAddress }; |
| | | data[i] = new String[] { name, u.displayName, u.accountType.name(), |
| | | u.emailAddress }; |
| | | } |
| | | } |
| | | stdout.print(FlipTable.of(headers, data, Borders.BODY_COLS)); |
| | | stdout.println("* = admin account, - = disabled account"); |
| | | stdout.print(FlipTable.of(headers, data, Borders.BODY_HCOLS)); |
| | | stdout.println(" * = admin account, - = disabled account"); |
| | | stdout.println(); |
| | | } |
| | | |
| | |
| | | |
| | | /** |
| | | * This is a forked version of FlipTables which supports controlling the |
| | | * displayed borders. |
| | | * displayed borders and gracefully handles null cell values. |
| | | * |
| | | * FULL = all borders |
| | | * BODY_COLS = header + perimeter + column separators |
| | |
| | | private static final String EMPTY = "(empty)"; |
| | | |
| | | public static enum Borders { |
| | | FULL(7), BODY_COLS(5), COLS(4), BODY(1), HEADER(0); |
| | | FULL(15), BODY_HCOLS(13), HCOLS(12), BODY(9), HEADER(8), COLS(4); |
| | | |
| | | final int bitmask; |
| | | |
| | | private Borders(int bitmask) { |
| | | this.bitmask = bitmask; |
| | | } |
| | | |
| | | boolean header() { |
| | | return isset(0x8); |
| | | } |
| | | |
| | | boolean body() { |
| | |
| | | rowData.length, columns)); |
| | | } |
| | | for (int column = 0; column < columns; column++) { |
| | | for (String rowDataLine : rowData[column].split("\\n")) { |
| | | String cell = rowData[column]; |
| | | if (cell == null) { |
| | | continue; |
| | | } |
| | | for (String rowDataLine : cell.split("\\n")) { |
| | | columnWidths[column] = Math.max(columnWidths[column], rowDataLine.length()); |
| | | } |
| | | } |
| | |
| | | @Override |
| | | public String toString() { |
| | | StringBuilder builder = new StringBuilder(); |
| | | printDivider(builder, "╔═╤═╗"); |
| | | if (borders.header()) { |
| | | printDivider(builder, "╔═╤═╗"); |
| | | } |
| | | printData(builder, headers, true); |
| | | if (data.length == 0) { |
| | | if (borders.body()) { |
| | | printDivider(builder, "╠═╧═╣"); |
| | | builder.append('║').append(pad(emptyWidth, EMPTY)).append("║\n"); |
| | | printDivider(builder, "╚═══╝"); |
| | | } else { |
| | | } else if (borders.header()) { |
| | | printDivider(builder, "╚═╧═╝"); |
| | | builder.append(' ').append(pad(emptyWidth, EMPTY)).append(" \n"); |
| | | } |
| | | } else { |
| | | for (int row = 0; row < data.length; row++) { |
| | | if (row == 0) { |
| | | if (row == 0 && borders.header()) { |
| | | if (borders.body()) { |
| | | if (borders.columns()) { |
| | | printDivider(builder, "╠═╪═╣"); |
| | |
| | | } else { |
| | | printDivider(builder, "╚═╧═╝"); |
| | | } |
| | | } |
| | | } else if (row == 0 && !borders.header()) { |
| | | if (borders.columns()) { |
| | | printDivider(builder, " ─┼─ "); |
| | | } else { |
| | | printDivider(builder, " ─┼─ "); |
| | | } |
| | | } else if (borders.rows()) { |
| | | if (borders.columns()) { |
| | |
| | | for (int line = 0, lines = 1; line < lines; line++) { |
| | | for (int column = 0; column < columns; column++) { |
| | | if (column == 0) { |
| | | if (isHeader || borders.body()) { |
| | | if ((isHeader && borders.header()) || borders.body()) { |
| | | out.append('║'); |
| | | } else { |
| | | out.append(' '); |
| | |
| | | } else { |
| | | out.append(' '); |
| | | } |
| | | String[] cellLines = data[column].split("\\n"); |
| | | String cell = data[column]; |
| | | if (cell == null) { |
| | | cell = ""; |
| | | } |
| | | String[] cellLines = cell.split("\\n"); |
| | | lines = Math.max(lines, cellLines.length); |
| | | String cellLine = line < cellLines.length ? cellLines[line] : ""; |
| | | out.append(pad(columnWidths[column], cellLine)); |
| | | } |
| | | if (isHeader || borders.body()) { |
| | | if ((isHeader && borders.header()) || borders.body()) { |
| | | out.append("║\n"); |
| | | } else { |
| | | out.append('\n'); |