diff --git a/cli-lanterna/src/main/groovy/com/muwire/clilanterna/ResultsModel.groovy b/cli-lanterna/src/main/groovy/com/muwire/clilanterna/ResultsModel.groovy index 2e8577f5..d47d7d7a 100644 --- a/cli-lanterna/src/main/groovy/com/muwire/clilanterna/ResultsModel.groovy +++ b/cli-lanterna/src/main/groovy/com/muwire/clilanterna/ResultsModel.groovy @@ -15,13 +15,13 @@ class ResultsModel { ResultsModel(UIResultBatchEvent results) { this.results = results - model = new TableModel("Name","Size","Hash","Sources","Comment") + model = new TableModel("Name","Size","Hash","Sources","Comment","Certificates") results.results.each { String size = DataHelper.formatSize2Decimal(it.size, false) + "B" String infoHash = Base64.encode(it.infohash.getRoot()) String sources = String.valueOf(it.sources.size()) String comment = String.valueOf(it.comment != null) - model.addRow(it.name, size, infoHash, sources, comment) + model.addRow(it.name, size, infoHash, sources, comment, it.certificates) rootToResult.put(infoHash, it) } } diff --git a/cli-lanterna/src/main/groovy/com/muwire/clilanterna/ResultsView.groovy b/cli-lanterna/src/main/groovy/com/muwire/clilanterna/ResultsView.groovy index 7e10f410..3803a911 100644 --- a/cli-lanterna/src/main/groovy/com/muwire/clilanterna/ResultsView.groovy +++ b/cli-lanterna/src/main/groovy/com/muwire/clilanterna/ResultsView.groovy @@ -37,7 +37,7 @@ class ResultsView extends BasicWindow { Panel contentPanel = new Panel() contentPanel.setLayoutManager(new GridLayout(1)) - table = new Table("Name","Size","Hash","Sources","Comment") + table = new Table("Name","Size","Hash","Sources","Comment","Certificates") table.setCellSelection(false) table.setSelectAction({rowSelected()}) table.setTableModel(model.model) @@ -55,18 +55,29 @@ class ResultsView extends BasicWindow { int selectedRow = table.getSelectedRow() def rows = model.model.getRow(selectedRow) boolean comment = Boolean.parseBoolean(rows[4]) - if (comment) { - Window prompt = new BasicWindow("Download Or View Comment") + boolean certificates = rows[5] > 0 + if (comment || certificates) { + LayoutData layoutData = GridLayout.createLayoutData(Alignment.CENTER, Alignment.CENTER) + + Window prompt = new BasicWindow("Download Or View Comment/Certificates") prompt.setHints([Window.Hint.CENTERED]) Panel contentPanel = new Panel() - contentPanel.setLayoutManager(new GridLayout(3)) + contentPanel.setLayoutManager(new GridLayout(4)) Button downloadButton = new Button("Download", {download(rows[2])}) - Button viewButton = new Button("View Comment", {viewComment(rows[2])}) + contentPanel.addComponent(downloadButton, layoutData) + + + if (comment) { + Button viewButton = new Button("View Comment", {viewComment(rows[2])}) + contentPanel.addComponent(viewButton, layoutData) + } + if (certificates) { + Button certsButton = new Button("View Certificates", {viewCertificates(rows[2])}) + contentPanel.addComponent(certsButton, layoutData) + } + Button closeButton = new Button("Cancel", {prompt.close()}) - LayoutData layoutData = GridLayout.createLayoutData(Alignment.CENTER, Alignment.CENTER) - contentPanel.addComponent(downloadButton, layoutData) - contentPanel.addComponent(viewButton, layoutData) contentPanel.addComponent(closeButton, layoutData) prompt.setComponent(contentPanel) downloadButton.takeFocus() @@ -91,4 +102,11 @@ class ResultsView extends BasicWindow { ViewCommentView view = new ViewCommentView(result, terminalSize) textGUI.addWindowAndWait(view) } + + private void viewCertificates(String infohash) { + UIResultEvent result = model.rootToResult[infohash] + ViewCertificatesModel model = new ViewCertificatesModel(result, core, textGUI.getGUIThread()) + ViewCertificatesView view = new ViewCertificatesView(model, textGUI, core, terminalSize) + textGUI.addWindowAndWait(view) + } } diff --git a/cli-lanterna/src/main/groovy/com/muwire/clilanterna/ViewCertificatesModel.groovy b/cli-lanterna/src/main/groovy/com/muwire/clilanterna/ViewCertificatesModel.groovy new file mode 100644 index 00000000..4c6da862 --- /dev/null +++ b/cli-lanterna/src/main/groovy/com/muwire/clilanterna/ViewCertificatesModel.groovy @@ -0,0 +1,81 @@ +package com.muwire.clilanterna + +import com.googlecode.lanterna.gui2.Label +import com.googlecode.lanterna.gui2.TextGUIThread +import com.googlecode.lanterna.gui2.table.TableModel +import com.muwire.core.Core +import com.muwire.core.Persona +import com.muwire.core.filecert.Certificate +import com.muwire.core.filecert.CertificateFetchEvent +import com.muwire.core.filecert.CertificateFetchStatus +import com.muwire.core.filecert.CertificateFetchedEvent +import com.muwire.core.filecert.UIFetchCertificatesEvent +import com.muwire.core.search.UIResultEvent + +class ViewCertificatesModel { + private final UIResultEvent result + private final Core core + private final TextGUIThread guiThread + + private final TableModel model = new TableModel("Issuer","File Name","Timestamp") + private final Map> byIssuer = new HashMap<>() + + private int totalCerts + + private Label status + private Label percentage + + ViewCertificatesModel(UIResultEvent result, Core core, TextGUIThread guiThread) { + this.result = result + this.core = core + this.guiThread = guiThread + + core.eventBus.with { + register(CertificateFetchEvent.class,this) + register(CertificateFetchedEvent.class, this) + publish(new UIFetchCertificatesEvent(host : result.sender, infoHash : result.infohash)) + } + } + + void unregister() { + core.eventBus.unregister(CertificateFetchEvent.class, this) + core.eventBus.unregister(CertificateFetchedEvent.class, this) + } + + void onCertificateFetchEvent(CertificateFetchEvent e) { + guiThread.invokeLater { + status.setText(e.status.toString()) + if (e.status == CertificateFetchStatus.FETCHING) + totalCerts = e.count + } + } + + void onCertificateFetchedEvent(CertificateFetchedEvent e) { + guiThread.invokeLater { + Date date = new Date(e.certificate.timestamp) + model.addRow(new PersonaWrapper(e.certificate.issuer), e.certificate.name.name, date) + + Set set = byIssuer.get(e.certificate.issuer) + if (set == null) { + set = new HashSet<>() + byIssuer.put(e.certificate.issuer, set) + } + set.add(e.certificate) + + String percentageString = "" + if (totalCerts > 0) { + double percentage = Math.round((model.getRowCount() * 100 / totalCerts).toDouble()) + percentageString = String.valueOf(percentage) + "%" + } + percentage.setText(percentageString) + } + } + + void setStatusLabel(Label status) { + this.status = status + } + + void setPercentageLabel(Label percentage) { + this.percentage = percentage + } +} diff --git a/cli-lanterna/src/main/groovy/com/muwire/clilanterna/ViewCertificatesView.groovy b/cli-lanterna/src/main/groovy/com/muwire/clilanterna/ViewCertificatesView.groovy new file mode 100644 index 00000000..e2ea441f --- /dev/null +++ b/cli-lanterna/src/main/groovy/com/muwire/clilanterna/ViewCertificatesView.groovy @@ -0,0 +1,96 @@ +package com.muwire.clilanterna + +import com.googlecode.lanterna.TerminalSize +import com.googlecode.lanterna.gui2.BasicWindow +import com.googlecode.lanterna.gui2.Button +import com.googlecode.lanterna.gui2.GridLayout +import com.googlecode.lanterna.gui2.LayoutData +import com.googlecode.lanterna.gui2.Panel +import com.googlecode.lanterna.gui2.TextGUI +import com.googlecode.lanterna.gui2.Window +import com.googlecode.lanterna.gui2.dialogs.MessageDialog +import com.googlecode.lanterna.gui2.dialogs.MessageDialogButton +import com.googlecode.lanterna.gui2.GridLayout.Alignment +import com.googlecode.lanterna.gui2.Label +import com.googlecode.lanterna.gui2.table.Table +import com.muwire.core.Core +import com.muwire.core.Persona +import com.muwire.core.filecert.Certificate +import com.muwire.core.filecert.UIImportCertificateEvent + +class ViewCertificatesView extends BasicWindow { + private final ViewCertificatesModel model + private final TextGUI textGUI + private final Core core + private final Table table + private final TerminalSize terminalSize + private final LayoutData layoutData = GridLayout.createLayoutData(Alignment.CENTER, Alignment.CENTER, true, false) + + ViewCertificatesView(ViewCertificatesModel model, TextGUI textGUI, Core core, TerminalSize terminalSize) { + super("Certificates") + this.model = model + this.core = core + this.textGUI = textGUI + this.terminalSize = terminalSize + + setHints([Window.Hint.EXPANDED]) + + Panel contentPanel = new Panel() + contentPanel.setLayoutManager(new GridLayout(1)) + + Label statusLabel = new Label("") + Label percentageLabel = new Label("") + model.setStatusLabel(statusLabel) + model.setPercentageLabel(percentageLabel) + + Panel topPanel = new Panel() + topPanel.setLayoutManager(new GridLayout(2)) + topPanel.addComponent(statusLabel, layoutData) + topPanel.addComponent(percentageLabel, layoutData) + contentPanel.addComponent(topPanel, layoutData) + + table = new Table("Issuer","File Name","Timestamp") + table.with { + setCellSelection(false) + setTableModel(model.model) + setVisibleRows(terminalSize.getRows()) + setSelectAction({rowSelected()}) + } + contentPanel.addComponent(table, layoutData) + + Button closeButton = new Button("Close",{ + model.unregister() + close() + }) + contentPanel.addComponent(closeButton, layoutData) + setComponent(contentPanel) + } + + private void rowSelected() { + int selectedRow = table.getSelectedRow() + def row = model.model.getRow(selectedRow) + Persona persona = row[0].persona + + Window prompt = new BasicWindow("Import Certificate?") + prompt.setHints([Window.Hint.CENTERED]) + + Panel contentPanel = new Panel() + contentPanel.setLayoutManager(new GridLayout(2)) + Button importButton = new Button("Import", {importCert(persona)}) + Button closeButton = new Button("Close", {prompt.close()}) + contentPanel.addComponent(importButton, layoutData) + contentPanel.addComponent(closeButton, layoutData) + + prompt.setComponent(contentPanel) + importButton.takeFocus() + textGUI.addWindowAndWait(prompt) + } + + private void importCert(Persona persona) { + Set certs = model.byIssuer.get(persona) + certs.each { + core.eventBus.publish(new UIImportCertificateEvent(certificate : it)) + } + MessageDialog.showMessageDialog(textGUI, "Certificate(s) Imported", "", MessageDialogButton.OK) + } +}