Improved file name generation and handling of duplicate titles

fix: generated file names for covers, screens and game files is improved to consider more characters to avoid that two games point to the same files.
fix: When adding a new game where the file names becomes equal to an existing game in the db an additional index is added to the file name as a suffix.
fix: file names are re-calculated when a game is saved and renamed if not matching the new rules.
This commit is contained in:
lantzelot-swe 2021-12-13 19:01:55 +01:00
parent fea8772a6e
commit 1772fab2f3
6 changed files with 82 additions and 75 deletions

View File

@ -24,6 +24,7 @@ import se.lantz.model.data.GameView;
import se.lantz.model.data.ViewFilter;
import se.lantz.util.DbConstants;
import se.lantz.util.ExceptionHandler;
import se.lantz.util.FileManager;
import se.lantz.util.GameListDataComparator;
public class DbConnector
@ -755,12 +756,19 @@ public class DbConnector
return returnValue;
}
public int getGameDuplicateIndexToUse(String title)
public int getGameDuplicateIndexToUse(String title, String gameId)
{
//This is only called when the title changes for an existing game or when adding a new game
//Use generated name, that is what decides if a duplicate index needs to be used.
//Look at the coverFile column since all covers have the same name ending.
String fileName = FileManager.generateFileNameFromTitle(title, 0);
StringBuilder sqlBuilder = new StringBuilder();
sqlBuilder.append("SELECT Duplicate FROM gameinfo WHERE title LIKE \"");
sqlBuilder.append(title);
sqlBuilder.append("\";");
sqlBuilder.append("SELECT rowId, Duplicate FROM gameinfo WHERE Coverfile GLOB \'");
sqlBuilder.append(fileName);
sqlBuilder.append("-cover*\' OR CoverFile GLOB \'");
sqlBuilder.append(fileName);
sqlBuilder.append("[0-9][0-9]-cover*\';");
String sql = sqlBuilder.toString();
logger.debug("Checking if game is in db already: {}", sql);
int returnIndex = 0;
@ -768,11 +776,16 @@ public class DbConnector
{
ResultSet rs = pstmt.executeQuery();
while (rs.next())
{
int rowId = rs.getInt("rowId");
//Ignore the current game if the query matches it
if (gameId.isEmpty() || rowId != Integer.parseInt(gameId))
{
//Increase one to the available index since it's the one supposed to be used.
returnIndex = Math.max(returnIndex, rs.getInt(DbConstants.DUPLICATE_INDEX) + 1);
}
}
}
catch (SQLException e)
{
ExceptionHandler.handleException(e, "Could not check for duplicate in db.");

View File

@ -468,7 +468,7 @@ public class ImportManager
int duplicateIndex = 0;
if (selectedOption == Options.ADD)
{
duplicateIndex = uiModel.getDbConnector().getGameDuplicateIndexToUse(title);
duplicateIndex = uiModel.getDbConnector().getGameDuplicateIndexToUse(title, "");
}
//Check any duplicates in added rows, always use this otherwise duplicates uses same names.
duplicateIndex = duplicateIndex + getDbRowDuplicate(title);

View File

@ -99,16 +99,14 @@ public class SavedStatesManager
}
//If the game has been renamed, make sure to rename the saves folder also
if (model.getInfoModel().isTitleChanged())
{
String oldFileName = model.getInfoModel().getOldGamesFile();
String newFileName = model.getInfoModel().getGamesFile();
File oldSaveFolder = new File(SAVES + oldFileName);
if (oldSaveFolder.exists())
if (!oldFileName.equals(newFileName) && oldSaveFolder.exists())
{
//Rename old folder to new name
oldSaveFolder.renameTo(new File(SAVES + model.getInfoModel().getGamesFile()));
}
}
String fileName = model.getInfoModel().getGamesFile();
Path saveFolder = new File(SAVES + fileName).toPath();

View File

@ -367,9 +367,7 @@ public class InfoModel extends AbstractModel
}
}
public boolean updateFileNames()
{
if (isNewGame() || isTitleChanged() || screenNamesNeedsUpdate())
public void updateFileNames()
{
//Keep track of the old names, used when renaming files when saving
oldCoverFile = getCoverFile();
@ -397,9 +395,6 @@ public class InfoModel extends AbstractModel
setGamesFile(fileName + fileEnding);
}
disableChangeNotification(false);
return true;
}
return false;
}
public void updateCoverAndScreensIfEmpty(boolean isC64)

View File

@ -8,7 +8,6 @@ import java.util.Collections;
import java.util.List;
import javax.swing.DefaultComboBoxModel;
import javax.swing.ListModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -492,7 +491,8 @@ public class MainViewModel extends AbstractModel
if (infoModel.isNewGame() || infoModel.isTitleChanged())
{
//Update duplicate index
infoModel.setDuplicateIndex(dbConnector.getGameDuplicateIndexToUse(infoModel.getTitle()));
infoModel.setDuplicateIndex(dbConnector.getGameDuplicateIndexToUse(infoModel.getTitle(),
this.selectedData.getGameId()));
}
if (!validateRequiredFields().isEmpty())

View File

@ -113,12 +113,8 @@ public class FileManager
public void saveFiles()
{
//Check if title is different that in db, then rename existing files!
if (infoModel.isTitleChanged() || infoModel.isAnyScreenRenamed())
{
//Rename existing covers and screens and game file
//Rename existing covers and screens and game file if needed
renameFiles();
}
//Fetch images that has been added
BufferedImage cover = infoModel.getCoverImage();
@ -352,14 +348,7 @@ public class FileManager
public static String generateFileNameFromTitle(String title, int duplicateIndex)
{
// All uppercase letters
// No spaces or special characters
//The maxi game tool seems to work like this: truncate to 23 characters and then remove all special characters.
if (title.length() > 23)
{
title = title.substring(0, 23);
logger.debug("FileName: truncating to : {}", title);
}
// Do the conversion
// No spaces or special characters, remove them first
List<Character> forbiddenCharsList =
" ,:'<27>-.!+*<>()/[]?|".chars().mapToObj(item -> (char) item).collect(Collectors.toList());
@ -367,11 +356,23 @@ public class FileManager
title.chars().mapToObj(item -> (char) item).filter(character -> !forbiddenCharsList.contains(character))
.map(Character::toUpperCase).collect(Collectors.toList());
String newNameString = newName.stream().map(String::valueOf).collect(Collectors.joining());
if (duplicateIndex > 0)
//The maxi game tool seems to truncate to a maximum length of 23 characters. Let's do the same here.
if (newNameString.length() > 23)
{
newNameString = newNameString.substring(0, 23);
logger.debug("FileName: truncating to : {}", title);
}
//Just add the duplicate index if there are several games with the same name
if (duplicateIndex > 0 && duplicateIndex < 10)
{
newNameString = newNameString + "0" + duplicateIndex;
}
else if (duplicateIndex > 9)
{
newNameString = newNameString + duplicateIndex;
}
logger.debug("Game title: \"{}\" ---- New fileName: \"{}\"", title, newNameString);
return newNameString;