From d777153cbbe36bda738bc375866425fe5831ad40 Mon Sep 17 00:00:00 2001 From: lantzelot-swe <75668734+lantzelot-swe@users.noreply.github.com> Date: Tue, 5 Oct 2021 22:06:38 +0200 Subject: [PATCH] feat: menu option to check all descriptions for CR characters --- src/main/java/se/lantz/db/DbConnector.java | 75 ++++++++++-- src/main/java/se/lantz/gui/MenuManager.java | 32 ++++- .../CheckDescrProgressDialog.java | 43 +++++++ .../CheckDescrProgressPanel.java | 114 ++++++++++++++++++ .../checkdescriptions/CheckDescrWorker.java | 55 +++++++++ .../gui/convertscreens/ConvertWorker.java | 3 +- 6 files changed, 307 insertions(+), 15 deletions(-) create mode 100644 src/main/java/se/lantz/gui/checkdescriptions/CheckDescrProgressDialog.java create mode 100644 src/main/java/se/lantz/gui/checkdescriptions/CheckDescrProgressPanel.java create mode 100644 src/main/java/se/lantz/gui/checkdescriptions/CheckDescrWorker.java diff --git a/src/main/java/se/lantz/db/DbConnector.java b/src/main/java/se/lantz/db/DbConnector.java index 364933b..e525af0 100644 --- a/src/main/java/se/lantz/db/DbConnector.java +++ b/src/main/java/se/lantz/db/DbConnector.java @@ -121,7 +121,7 @@ public class DbConnector ExceptionHandler.handleException(e, "Could not cretate db tables"); } } - + public void validateMissingColumnsAfterRestore() { addLanguageAndDuplicateColumnsIfMissing(); @@ -140,7 +140,8 @@ public class DbConnector try (Connection conn = this.connect(); PreparedStatement stmnt = conn.prepareStatement(tableInfoSql); ResultSet rs = stmnt.executeQuery(); Statement addDestmnt = conn.createStatement(); Statement addFrstmnt = conn.createStatement(); Statement addEsstmnt = conn.createStatement(); - Statement addItstmnt = conn.createStatement(); Statement addDuplicatestmnt = conn.createStatement(); Statement addViewtagstmnt = conn.createStatement()) + Statement addItstmnt = conn.createStatement(); Statement addDuplicatestmnt = conn.createStatement(); + Statement addViewtagstmnt = conn.createStatement()) { boolean columnsAvailable = false; boolean duplicateAvailable = false; @@ -479,7 +480,7 @@ public class DbConnector //Check which are already available and sort them out of rowValues for (String rowValue : rowValues) { - String[] splittedRowValue = rowValue.split(COMMA); + String[] splittedRowValue = rowValue.split(COMMA); String title = splittedRowValue[0]; StringBuilder sqlBuilder = new StringBuilder(); sqlBuilder.append("SELECT COUNT(*) FROM gameinfo WHERE title = "); @@ -539,7 +540,10 @@ public class DbConnector rowValues.addAll(newRowValues); } - private void insertAllIntoGameInfoTable(List rowValues, StringBuilder infoBuilder, int addAsFavorite, String viewTag) + private void insertAllIntoGameInfoTable(List rowValues, + StringBuilder infoBuilder, + int addAsFavorite, + String viewTag) { infoBuilder.append("Adding "); infoBuilder.append(rowValues.size()); @@ -549,7 +553,7 @@ public class DbConnector { return; } - + StringBuilder st = new StringBuilder(); st.append("INSERT INTO gameinfo ("); for (String column : columnList) @@ -566,7 +570,7 @@ public class DbConnector String oldGameName = getOldGameName(rowData); //Strip rowData from new filenames String strippedRowData = stripRowDataFromOldFileNames(rowData); - String duplicateIndex = rowData.substring(rowData.lastIndexOf(",")+1); + String duplicateIndex = rowData.substring(rowData.lastIndexOf(",") + 1); st.append(strippedRowData); if (addAsFavorite > 0) { @@ -577,7 +581,7 @@ public class DbConnector st.append(",0"); } st.append(","); - + if (oldGameName.isEmpty()) { st.append("\"missing"); @@ -625,7 +629,7 @@ public class DbConnector } return String.join("\",\"", strippedDataList) + "\""; } - + private String getOldGameName(String rowData) { String[] splittedRowData = rowData.split(COMMA); @@ -675,7 +679,7 @@ public class DbConnector { sqlBuilder.append(",Viewtag = \"" + viewTag + "\""); } - + sqlBuilder.append(" WHERE title = "); sqlBuilder.append(title); sqlBuilder.append("\" AND Duplicate = "); @@ -1020,7 +1024,7 @@ public class DbConnector public void toggleFavorite(String gameId, int currentFavoriteValue, int newFavorite) { - int newValue = currentFavoriteValue == newFavorite ? 0: newFavorite; + int newValue = currentFavoriteValue == newFavorite ? 0 : newFavorite; String sql = "UPDATE gameinfo SET Favorite = " + newValue + " WHERE rowId = " + gameId + ";"; try (Connection conn = this.connect(); PreparedStatement favoritestmt = conn.prepareStatement(sql)) { @@ -1046,10 +1050,59 @@ public class DbConnector ExceptionHandler.handleException(e, "Could not clear favorite values in db."); } } - + public void cleanupAfterImport() { addedRowsList.clear(); duplicateMap.clear(); } + + public List fixDescriptions() + { + List fixedGames = new ArrayList<>(); + String sql = + "SELECT title FROM gameinfo where description LIKE '%\n%' OR description_de LIKE '%\n%' OR description_es LIKE '%\n%' OR description_fr LIKE '%\n%' OR description_it LIKE '%\n%'"; + logger.debug("Generated SELECT String:\n{}", sql); + + String replaceDescSql = + "UPDATE gameinfo SET " + DbConstants.DESC + " = REPLACE(" + DbConstants.DESC + ", '\n', ' ');"; + String replaceDescDESql = + "UPDATE gameinfo SET " + DbConstants.DESC_DE + " = REPLACE(" + DbConstants.DESC_DE + ", '\n', ' ');"; + String replaceDescESSql = + "UPDATE gameinfo SET " + DbConstants.DESC_ES + " = REPLACE(" + DbConstants.DESC_ES + ", '\n', ' ');"; + String replaceDescFRSql = + "UPDATE gameinfo SET " + DbConstants.DESC_FR + " = REPLACE(" + DbConstants.DESC_FR + ", '\n', ' ');"; + String replaceDescITSql = + "UPDATE gameinfo SET " + DbConstants.DESC_IT + " = REPLACE(" + DbConstants.DESC_IT + ", '\n', ' ');"; + + try (Connection conn = this.connect(); PreparedStatement pstmt = conn.prepareStatement(sql); + PreparedStatement replaceDescPstmt = conn.prepareStatement(replaceDescSql); + PreparedStatement replaceDescDEPstmt = conn.prepareStatement(replaceDescDESql); + PreparedStatement replaceDescESPstmt = conn.prepareStatement(replaceDescESSql); + PreparedStatement replaceDescFRPstmt = conn.prepareStatement(replaceDescFRSql); + PreparedStatement replaceDescITPstmt = conn.prepareStatement(replaceDescITSql);) + { + ResultSet rs = pstmt.executeQuery(); + while (rs.next()) + { + String title = rs.getString("Title"); + fixedGames.add(title); + } + int value = replaceDescPstmt.executeUpdate(); + logger.debug("Fix description Executed successfully, value = {}", value); + value = replaceDescDEPstmt.executeUpdate(); + logger.debug("Fix description_de Executed successfully, value = {}", value); + value = replaceDescESPstmt.executeUpdate(); + logger.debug("Fix description_es Executed successfully, value = {}", value); + value = replaceDescFRPstmt.executeUpdate(); + logger.debug("Fix description_fr Executed successfully, value = {}", value); + value = replaceDescITPstmt.executeUpdate(); + logger.debug("Fix description_it Executed successfully, value = {}", value); + } + catch (SQLException e) + { + ExceptionHandler.handleException(e, "Could not fix descriptions in db."); + } + return fixedGames; + } } diff --git a/src/main/java/se/lantz/gui/MenuManager.java b/src/main/java/se/lantz/gui/MenuManager.java index ebaba9e..5590e71 100644 --- a/src/main/java/se/lantz/gui/MenuManager.java +++ b/src/main/java/se/lantz/gui/MenuManager.java @@ -17,6 +17,8 @@ import javax.swing.JOptionPane; import javax.swing.KeyStroke; import se.lantz.gamebase.GamebaseImporter; +import se.lantz.gui.checkdescriptions.CheckDescrProgressDialog; +import se.lantz.gui.checkdescriptions.CheckDescrWorker; import se.lantz.gui.convertscreens.ConvertProgressDialog; import se.lantz.gui.convertscreens.ConvertWorker; import se.lantz.gui.dbbackup.BackupProgressDialog; @@ -89,6 +91,7 @@ public class MenuManager private JMenuItem deleteGamesForViewItem; private JMenuItem convertScreensItem; + private JMenuItem checkDescrItem; private JMenuItem helpItem; private JMenuItem aboutItem; @@ -175,6 +178,7 @@ public class MenuManager toolsMenu.add(getDeleteGamesForViewMenuItem()); toolsMenu.addSeparator(); toolsMenu.add(getConvertScreensItem()); + toolsMenu.add(getCheckDescriptionsItem()); helpMenu = new JMenu("Help"); helpMenu.setMnemonic('H'); helpMenu.add(getHelpItem()); @@ -276,7 +280,7 @@ public class MenuManager exportItem.addActionListener(e -> exportGames()); return exportItem; } - + private JMenuItem getExportFileLoaderItem() { exportFLItem = new JMenuItem("Export to File loader..."); @@ -616,6 +620,14 @@ public class MenuManager return convertScreensItem; } + private JMenuItem getCheckDescriptionsItem() + { + checkDescrItem = new JMenuItem("Check descriptions..."); + checkDescrItem.setMnemonic('e'); + checkDescrItem.addActionListener(e -> fixInvalidCharsInDescriptions()); + return checkDescrItem; + } + private JMenuItem getHelpItem() { helpItem = new JMenuItem("Help"); @@ -753,7 +765,7 @@ public class MenuManager } } } - + private void exportGamesToFileLoader() { final ExportGamesDialog exportSelectionDialog = new ExportGamesDialog(MainWindow.getInstance(), false); @@ -886,6 +898,22 @@ public class MenuManager } } + private void fixInvalidCharsInDescriptions() + { + String message = + "Do you want to check all description texts in the database and remove all carrage return (CR) characters?\nEarlier versions of the game manager allowed for CR characters, the Carousel " + + "does not handle that properly.\nCR characters will be replaced by a space character."; + int option = JOptionPane.showConfirmDialog(MainWindow.getInstance() + .getMainPanel(), message, "Check description texts", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE); + if (option == JOptionPane.YES_OPTION) + { + CheckDescrProgressDialog dialog = new CheckDescrProgressDialog(this.mainWindow); + CheckDescrWorker worker = new CheckDescrWorker(dialog, this.uiModel.getDbConnector()); + worker.execute(); + dialog.setVisible(true); + } + } + private void clearFavorites(int number) { String message = "Are you sure you want to clear all games marked as favorites " + number + "?"; diff --git a/src/main/java/se/lantz/gui/checkdescriptions/CheckDescrProgressDialog.java b/src/main/java/se/lantz/gui/checkdescriptions/CheckDescrProgressDialog.java new file mode 100644 index 0000000..ed9cc0d --- /dev/null +++ b/src/main/java/se/lantz/gui/checkdescriptions/CheckDescrProgressDialog.java @@ -0,0 +1,43 @@ +package se.lantz.gui.checkdescriptions; + +import java.awt.Frame; + +import javax.swing.JDialog; +import javax.swing.WindowConstants; + +public class CheckDescrProgressDialog extends JDialog +{ + private static final long serialVersionUID = 1L; + + private CheckDescrProgressPanel panel; + + public CheckDescrProgressDialog(Frame frame) + { + super(frame, "Check descriptions", true); + this.add(getConvertProgressPanel()); + setSize(900, 600); + setLocationRelativeTo(frame); + setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); + } + + public void updateProgress(String infoText) + { + getConvertProgressPanel().updateProgress(infoText); + this.repaint(); + } + + public void finish(int count, Exception e) + { + getConvertProgressPanel().finish(count, e); + } + + public CheckDescrProgressPanel getConvertProgressPanel() + { + if (panel == null) + { + panel = new CheckDescrProgressPanel(); + panel.getCloseButton().addActionListener(e -> setVisible(false)); + } + return panel; + } +} diff --git a/src/main/java/se/lantz/gui/checkdescriptions/CheckDescrProgressPanel.java b/src/main/java/se/lantz/gui/checkdescriptions/CheckDescrProgressPanel.java new file mode 100644 index 0000000..ce5108e --- /dev/null +++ b/src/main/java/se/lantz/gui/checkdescriptions/CheckDescrProgressPanel.java @@ -0,0 +1,114 @@ +package se.lantz.gui.checkdescriptions; + +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; + +import javax.swing.JButton; +import javax.swing.JPanel; +import javax.swing.JProgressBar; +import javax.swing.JScrollPane; +import javax.swing.JTextArea; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class CheckDescrProgressPanel extends JPanel +{ + private static final Logger logger = LoggerFactory.getLogger(CheckDescrProgressPanel.class); + private JProgressBar progressBar; + private JTextArea textArea; + private JScrollPane textScrollPane; + private JButton closeButton; + + public CheckDescrProgressPanel() + { + GridBagLayout gridBagLayout = new GridBagLayout(); + setLayout(gridBagLayout); + GridBagConstraints gbc_progressBar = new GridBagConstraints(); + gbc_progressBar.weightx = 1.0; + gbc_progressBar.fill = GridBagConstraints.HORIZONTAL; + gbc_progressBar.insets = new Insets(10, 5, 5, 5); + gbc_progressBar.gridx = 0; + gbc_progressBar.gridy = 0; + add(getProgressBar(), gbc_progressBar); + GridBagConstraints gbc_textScrollPane = new GridBagConstraints(); + gbc_textScrollPane.insets = new Insets(0, 5, 5, 5); + gbc_textScrollPane.weighty = 1.0; + gbc_textScrollPane.weightx = 1.0; + gbc_textScrollPane.fill = GridBagConstraints.BOTH; + gbc_textScrollPane.gridx = 0; + gbc_textScrollPane.gridy = 1; + add(getTextScrollPane(), gbc_textScrollPane); + GridBagConstraints gbc_closeButton = new GridBagConstraints(); + gbc_closeButton.insets = new Insets(0, 5, 5, 5); + gbc_closeButton.gridx = 0; + gbc_closeButton.gridy = 2; + add(getCloseButton(), gbc_closeButton); + } + + private JProgressBar getProgressBar() + { + if (progressBar == null) + { + progressBar = new JProgressBar(); + progressBar.setIndeterminate(true); + } + return progressBar; + } + + private JTextArea getTextArea() + { + if (textArea == null) + { + textArea = new JTextArea(); + textArea.setEditable(false); + } + return textArea; + } + + private JScrollPane getTextScrollPane() + { + if (textScrollPane == null) + { + textScrollPane = new JScrollPane(); + textScrollPane.setViewportView(getTextArea()); + } + return textScrollPane; + } + + JButton getCloseButton() + { + if (closeButton == null) + { + closeButton = new JButton("Close"); + closeButton.setEnabled(false); + } + return closeButton; + } + + void updateProgress(String infoText) + { + getTextArea().append(infoText); + } + + public void finish(int count, Exception e) + { + getCloseButton().setEnabled(true); + getProgressBar().setIndeterminate(false); + getProgressBar().setValue(getProgressBar().getMaximum()); + if (e != null) + { + logger.error("description check failed", e); + getTextArea().append("\nDescription check failed: " + e.getMessage()); + } + else if (count == 0) + { + getTextArea().append("\nNothing to fix, all up to date."); + } + else + { + getTextArea().append("\nFixed descriptions for " + count + " games successfully."); + } + } +} diff --git a/src/main/java/se/lantz/gui/checkdescriptions/CheckDescrWorker.java b/src/main/java/se/lantz/gui/checkdescriptions/CheckDescrWorker.java new file mode 100644 index 0000000..97982a0 --- /dev/null +++ b/src/main/java/se/lantz/gui/checkdescriptions/CheckDescrWorker.java @@ -0,0 +1,55 @@ +package se.lantz.gui.checkdescriptions; + +import java.util.List; +import java.util.concurrent.ExecutionException; + +import javax.swing.SwingWorker; + +import se.lantz.db.DbConnector; +import se.lantz.util.FileManager; + +public class CheckDescrWorker extends SwingWorker +{ + private CheckDescrProgressDialog dialog; + private DbConnector dbConnector; + + public CheckDescrWorker(CheckDescrProgressDialog dialog, DbConnector dbConnector) + { + this.dialog = dialog; + this.dbConnector = dbConnector; + } + + @Override + protected Integer doInBackground() throws Exception + { + publish("Reading descriptions..."); + List fixedEntriesList = dbConnector.fixDescriptions(); + for (String game : fixedEntriesList) + { + publish("Fixed " + game); + } + return fixedEntriesList.size(); + } + + @Override + protected void process(List chunks) + { + for (String value : chunks) + { + dialog.updateProgress(value + "\n"); + } + } + + @Override + protected void done() + { + try + { + dialog.finish(this.get(), null); + } + catch (InterruptedException | ExecutionException e) + { + dialog.finish(0, e); + } + } +} diff --git a/src/main/java/se/lantz/gui/convertscreens/ConvertWorker.java b/src/main/java/se/lantz/gui/convertscreens/ConvertWorker.java index 02a00be..6d6203e 100644 --- a/src/main/java/se/lantz/gui/convertscreens/ConvertWorker.java +++ b/src/main/java/se/lantz/gui/convertscreens/ConvertWorker.java @@ -5,7 +5,6 @@ import java.util.concurrent.ExecutionException; import javax.swing.SwingWorker; -import se.lantz.util.ExceptionHandler; import se.lantz.util.FileManager; public class ConvertWorker extends SwingWorker @@ -20,7 +19,7 @@ public class ConvertWorker extends SwingWorker @Override protected Integer doInBackground() throws Exception { - publish("Reading screnshots..."); + publish("Reading screenshots..."); List convertionList = FileManager.convertAllScreenshotsTo32Bit(); for (String screenshot : convertionList) {