Skip to content

Commit

Permalink
Support any delimiter for bracketed game titles
Browse files Browse the repository at this point in the history
  • Loading branch information
Gemba committed Nov 26, 2024
1 parent a8805f5 commit 1daff19
Show file tree
Hide file tree
Showing 11 changed files with 163 additions and 84 deletions.
2 changes: 1 addition & 1 deletion aliasMap.csv
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
# This file is global and will be used when scraping ANY platform.
#
# Note 2:
# All bracket info in the search name alias is ignored.
# All bracket/parenthesis info in the search name alias is ignored.
# It merely provides a different base name for Skyscraper when it creates
# the search query. It is meant to help scrape files that have abstract file-
# names where the search-based scraping modules have a hard time finding good
Expand Down
2 changes: 2 additions & 0 deletions config.ini.example
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@
;scummIni="/full/path/to/scummvm.ini"
;tidyDesc="true"
;onlyMissing="false"
;innerBracketsReplace="] ["
;innerParenthesesReplace=") ("

; The following is an example of configs that only affect the 'snes' platform.
;[snes]
Expand Down
11 changes: 9 additions & 2 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,16 @@ humans](https://keepachangelog.com).

- Added: Support for [XDG Base Directories](XDG.md), thanks for the suggestion
@ASHGOLDOFFICIAL.
- Added: Option `--hint`, shows a random Tip of the Day
- Added: Option to allow any delimiter between consecutive brackets and
parentheses in gamelist title. See
[`innerBracketsReplace`](CONFIGINI.md#innerbracketsreplace) for examples.
Thanks for the suggestion, @retrobit.
- Added: [Platform 'Fujitsu
FM-Towns'](https://github.com/Gemba/skyscraper/pull/95/files). Manually update
your `peas.json` and `platformid_map.csv` to make use of it.
- Added: Option `--hint`, it shows a random Tip of the Day.
- Updated: Skyscraper's hardcoded `/home/<USER>` replaced with the actual user's
home directory screen messages, thanks for highlighting it on the Mac,
home directory screen messages. Thanks for highlighting it on the Mac,
@cdaters
- Updated: A downloaded `whdload.xml` file for platform Amiga will be not
downloaded again until the server indicates. Manually removing
Expand Down
33 changes: 32 additions & 1 deletion docs/CONFIGINI.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ This is an alphabetical index of all configuration options including the section
| [importFolder](CONFIGINI.md#importfolder) | Y | Y | | |
| [includeFrom](CONFIGINI.md#includefrom) | Y | Y | | |
| [includePattern](CONFIGINI.md#includepattern) | Y | Y | Y | |
| [innerBracketsReplace](CONFIGINI.md#innerbracketsreplace) | Y | | | |
| [innerParenthesesReplace](CONFIGINI.md#innerparenthesesreplace) | Y | | | |
| [inputFolder](CONFIGINI.md#inputfolder) | Y | Y | | |
| [interactive](CONFIGINI.md#interactive) | Y | Y | | Y |
| [jpgQuality](CONFIGINI.md#jpgquality) | Y | Y | | Y |
Expand Down Expand Up @@ -241,7 +243,7 @@ By default Skyscraper uses just the title as the game name when generating gamel

- `%t`: The game title as returned by the scraping sources without bracket information (see `%b` and `%B` below)
- `%f`: The game filename without extension and bracket information (see `%b` and `%B` below)
- `%b`: The game `()` bracket information. This information often comes from the filename, but can also come from the scraping source title (eg. `(USA)` or `(en,fr,de)`)
- `%b`: The game `()` parentheses information. This information often comes from the filename, but can also come from the scraping source title (eg. `(USA)` or `(en,fr,de)`)
- `%B`: The game `[]` bracket information. This information often comes from the filename, but can also come from the scraping source title (eg. `[disk 1 of 2]` or `[AGA]`)
- `%a`: The age restriction as returned by the scraping sources (eg. `16+`)
- `%d`: The game developer as returned by the scraping sources
Expand Down Expand Up @@ -517,6 +519,35 @@ Allowed in sections: `[main]`, `[<PLATFORM>]`, `[<FRONTEND>]`

---

#### innerBracketsReplace

Only in use when the option `brackets` is set to `true` for gamelist creation:
This replaces consecutive brackets `][` in the game title with whatever is
defined in this option. This setting has no effect, if there is only one bracket
present in the game filename.
Use the option `innerParenthesesReplace` for the same effect on round brackets
`)(` (aka. parentheses).

**Example(s)**

Filename: `Oddworld - Abe's Exoddus [NTSC-U] [SLUS-00710].m3u`

- `innerBracketsReplace=""` (unset), gamelist game title output: `Oddworld - Abe's Exoddus [NTSC-U][SLUS-00710]`
- `innerBracketsReplace="] ["`, gamelist game title output (_note the space._): `Oddworld - Abe's Exoddus [NTSC-U] [SLUS-00710]`
- `innerBracketsReplace=","`, gamelist game title output: `Oddworld - Abe's Exoddus [NTSC-U,SLUS-00710]`

Default value: unset
Allowed in sections: `[main]`

---

#### innerParenthesesReplace

Same as [innerBracketsReplace](#innerbracketsreplace) but for parentheses `)(`
(aka. round brackets).

---

#### maxLength

Sets the maximum length of returned game descriptions. This is a convenience option if you feel like game descriptions are too long. By default it is set to 2500.
Expand Down
21 changes: 14 additions & 7 deletions src/nametools.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include <QFileInfo>
#include <QRegularExpression>
#include <QSettings>
#include <QStringBuilder>

QString NameTools::getScummName(const QFileInfo &info, const QString baseName,
const QString scummIni) {
Expand Down Expand Up @@ -280,6 +281,7 @@ QString NameTools::notesByRegex(const QString &baseName, const QString &re) {
QString NameTools::getSqrNotes(QString baseName) {
// Get square notes: Pattern to match text in brackets
QString sqrNotes = notesByRegex(baseName, "\\[([^[\\]]+)\\]");
qDebug() << "sqrNotes pre:" << sqrNotes;

// Look for '_tag_' or '[tag]' with the last char optional
QMap<QString, QString> replacements = {
Expand All @@ -292,10 +294,13 @@ QString NameTools::getSqrNotes(QString baseName) {
QMapIterator<QString, QString> i(replacements);
while (i.hasNext()) {
i.next();
if (QRegularExpression(i.key()).match(baseName).hasMatch()) {
sqrNotes.append("[" + i.value() + "]");
if (QRegularExpression(i.key()).match(baseName).hasMatch() &&
/* avoid NTSC-U being replicated to NTSC on psx */
!sqrNotes.contains("[" + i.value(), Qt::CaseInsensitive)) {
sqrNotes.append("[" % i.value() % "]");
}
}
qDebug() << "sqrNotes post:" << sqrNotes;
return sqrNotes.simplified();
}

Expand Down Expand Up @@ -390,7 +395,9 @@ QString NameTools::getCacheId(const QFileInfo &info) {
}

QString NameTools::getNameFromTemplate(const GameEntry &game,
const QString &nameTemplate) {
const QString &nameTemplate,
const QString &parenthesesInfo,
const QString &bracketInfo) {
QList<QString> templateGroups = nameTemplate.split(";");
QString finalName;
for (auto &templateGroup : templateGroups) {
Expand All @@ -401,10 +408,10 @@ QString NameTools::getNameFromTemplate(const GameEntry &game,
if (templateGroup.contains("%f") && !game.baseName.isEmpty()) {
include = true;
}
if (templateGroup.contains("%b") && !game.parNotes.isEmpty()) {
if (templateGroup.contains("%b") && !parenthesesInfo.isEmpty()) {
include = true;
}
if (templateGroup.contains("%B") && !game.sqrNotes.isEmpty()) {
if (templateGroup.contains("%B") && !bracketInfo.isEmpty()) {
include = true;
}
if (templateGroup.contains("%a") && !game.ages.isEmpty()) {
Expand All @@ -425,8 +432,8 @@ QString NameTools::getNameFromTemplate(const GameEntry &game,
if (include) {
templateGroup.replace("%t", game.title);
templateGroup.replace("%f", StrTools::stripBrackets(game.baseName));
templateGroup.replace("%b", game.parNotes);
templateGroup.replace("%B", game.sqrNotes);
templateGroup.replace("%b", parenthesesInfo);
templateGroup.replace("%B", bracketInfo);
templateGroup.replace("%a", game.ages);
templateGroup.replace("%d", game.developer);
templateGroup.replace("%p", game.publisher);
Expand Down
4 changes: 3 additions & 1 deletion src/nametools.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ class NameTools : public QObject {
static QString getUniqueNotes(const QString &notes, QChar delim);
static QString getCacheId(const QFileInfo &info);
static QString getNameFromTemplate(const GameEntry &game,
const QString &nameTemplate);
const QString &nameTemplate,
const QString &parenthesesInfo,
const QString &bracketInfo);

private:
static QString notesByRegex(const QString &baseName, const QString &re);
Expand Down
1 change: 0 additions & 1 deletion src/netmanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ QNetworkReply *NetManager::getRequest(const QNetworkRequest &request) {
return get(request);
}


QNetworkReply *NetManager::headRequest(const QNetworkRequest &request) {
QMutexLocker locker(&requestMutex);
return head(request);
Expand Down
29 changes: 24 additions & 5 deletions src/scraperworker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -364,19 +364,38 @@ void ScraperWorker::run() {
output.append("Title: '\033[1;32m" + game.title +
"\033[0m' (" + game.titleSrc + ")\n");
}

QString bracketInfo = game.sqrNotes;
QString parenthesesInfo = game.parNotes;
if (config.brackets) {
if (!config.innerBracketsReplace.isEmpty()) {
bracketInfo =
bracketInfo.replace("][", config.innerBracketsReplace);
}
if (!bracketInfo.isEmpty()) {
bracketInfo = " " % bracketInfo;
}
if (!config.innerParenthesesReplace.isEmpty()) {
parenthesesInfo = parenthesesInfo.replace(
")(", config.innerParenthesesReplace);
}
if (!parenthesesInfo.isEmpty()) {
parenthesesInfo = " " % parenthesesInfo;
}
}

if (!config.nameTemplate.isEmpty()) {
game.title = StrTools::xmlUnescape(
NameTools::getNameFromTemplate(game, config.nameTemplate));
game.title = StrTools::xmlUnescape(NameTools::getNameFromTemplate(
game, config.nameTemplate, parenthesesInfo, bracketInfo));
} else {
game.title = StrTools::xmlUnescape(game.title);
if (config.forceFilename) {
game.title = StrTools::xmlUnescape(
StrTools::stripBrackets(info.completeBaseName()));
}
if (config.brackets) {
game.title.append(StrTools::xmlUnescape(
(game.parNotes != "" ? " " + game.parNotes : "") +
(game.sqrNotes != "" ? " " + game.sqrNotes : "")));
game.title.append(
StrTools::xmlUnescape(parenthesesInfo % bracketInfo));
}
}
output.append("Platform: '\033[1;32m" + game.platform +
Expand Down
8 changes: 8 additions & 0 deletions src/settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,14 @@ void RuntimeCfg::applyConfigIni(CfgType type, QSettings *settings,
config->includeFrom = v;
continue;
}
if (k == "innerBracketsReplace") {
config->innerBracketsReplace = v;
continue;
}
if (k == "innerParenthesesReplace") {
config->innerParenthesesReplace = v;
continue;
}
if (k == "inputFolder") {
config->inputFolder = (type == CfgType::MAIN)
? concatPath(v, config->platform)
Expand Down
Loading

0 comments on commit 1daff19

Please sign in to comment.