Create custom-collections from txt file [v1.3, final]
-
As we have the wonderfull cutom collections now and I dislike it to connect keyboards on my Pi I thought it would be nice to create custom collections from simple txtfiles.
As this method undergoes some character checks that were established by @pjft during his C++ coding in ES there is no support if the created files will be working (as it may not be recognized by ES). There is theoretical no chance to break something but expect the unexpected!
The script is so simple but it works nice
- Place a txtfile with name collections.txt to
/home/pi/RetroPie/roms/
this is usually reachable via samba share - Just write your collections name in there ... MegaMan, Turtels, Beatemups.... and end each line with enter (LF)
- Start the script with user PI (root will mess it up!)
#!/bin/bash # >> Create Custom Collection << # this creates custom-collections through collections.txt file # Content of created files will never be altered! # Now enter collections names, every single line will result in a new collection # # Remember you need ES 2.6.0 at least to use that features # v1.1, v1.2 Avoid empty entries and truncate CR char from windows files # v1.3 RegEx handling and code cleanup # As always ;) Thx @meleu and @pjft // cyperghost txtfile="$HOME/RetroPie/roms/collections.txt" colpath="/opt/retropie/configs/all/emulationstation/collections" mkdir -p "$colpath" while read line; do if [[ "$line" =~ ^[][()\ \'_A-Za-z0-9-]+$ ]]; then file="$colpath/custom-$line.cfg" echo "Creating \"$file\"." touch "$file" else echo "Ignoring \"$line\": invalid filename." >&2 fi done < <(tr -d '\r' < "$txtfile")
You won't break anything .... because the files will only be touched. That means that if a file already created the content will not be deleted, just the access-data will be changed. If the file does not exist then an empty file will be created.
Restart ES and activate the new created collections.
Hope it helps!example file
/home/pi/RetroPie/roms/collections.txt
col1 col2 col3 Beat 'em up
Contributions for this sniplet fly out to @meleu und @pjft // yours cyperghost
- Place a txtfile with name collections.txt to
-
Small update...
Established a check if filestring is empty
So your collections.txt can contain LF entries and no void-file will be createdfile 1 file 2 file 3 file 4 file 5
Will create only 5 files ;)
- custom-file 1.cfg
- custom-file 2.cfg
- custom-file 3.cfg
- custom-file 4.cfg
- custom-file 5.cfg
-
v1.2
TRIM CR from windows files
1.2 = Final version -
I don't know (yet) how the custom collections work, but I would like to make some suggestions on the script...
Suggestion 1
Use
$HOME
instead of hardcoded/home/pi
. It makes the script useful for those who install RetroPie on other platform (example: me).Suggestion 2
Considering the filenames can't have spaces (I'm not sure if it's valid for custom collections, but assuming that it's not), I would like to suggest the use of this regex to check valid filenames:
^[^\ /]+$
. This regex means "no spaces and no slashes".Suggestion 3
Create the
$colpath
directory if it doesn't exist.Suggestion 4
Trim the CR character in
done
redirection.result:
#!/bin/bash txtfile="$HOME/RetroPie/roms/collections.txt" colpath="/opt/retropie/configs/all/emulationstation/collections" mkdir -p "$colpath" while read line; do if [[ "$line" =~ ^[^\ /]+$ ]]; then file="$colpath/custom-$line.cfg" echo "Creating \"$file\"." touch "$file" else echo "Ignoring \"$line\": invalid filename." >&2 fi done < <(tr -d '\r' < "$txtfile")
-
@meleu Hi mate ;) Didn't know you are not using
custom-collections
;)
Maybe now? Btw: Do you know a good manual for RetroAchivments?@pjft Wonderfull work ;) One question: Are spaces in custom-collections allowed?
I think this tool can be quite usefull because you can create collections:
- No need of keyboard to Pie
- No need for
custom-.cfg
- I always forget this to add - You can create an "overview" of collections because file content will not be changed, so no need to "maintain" the list! Just add a new entry and run the script!
Suggestion 1: Thank you ;) That is usefull for multiuser mashines
Suggestion 2: I think @pjft removed empty characters vie ES keyboard input but filename with space work. So this can be well... explained as "expect the unexpected". Your solution is surly better but will remove spaces ;) So what to do?
Suggestion 3: No, it's already created by default if ES 2.6.0 is updated via RetroPie_setup
Suggestion 4: Seems to me just for ... speed reasons? Because I read file in variable and then rewrite it with trim command. You do this in one slash ;)
So everything is clear for me ... but:
Is the CAT command usefull here? Because it will extract single strings in file? -
@cyperghost said in Create custom-collections from txt file:
@meleu Hi mate ;) Didn't know you are not using
custom-collections
;)
Maybe now?Yes. I wanna use it!
Suggestion 3: No, it's already created by default if ES 2.6.0 is updated via RetroPie_setup
But if the user try the script without updating ES he/she will get a bunch of "no such file or directory" errors.
Is the CAT command usefull here? Because it will extract single strings in file?
Well, I used it because
tr
can't read from a file name. It reads only thestdin
. But we can avoid thecat
usingtr -d '\r' < "$txtfile"
.Btw: Do you know a good manual for RetroAchivments?
There's a FAQ on their site. I think it's simple, but I agree the info is a little scattered. I'll try to write two or three paragraphs about it and post here in the forum.
But just to let you start I suggest you to:
-
Cretate an account at RetroAchievements.org
-
Configure your RetroArch following the instructions on the docs.
-
Play something. :-)
-
-
This is the regular expression of things I allow/exclude:
[^A-Za-z0-9-[]()\s']
So, we should allow:
- letters (lower and upper case)
- numbers
- spaces
- '
I believe none of these would pose problems with any file system. That was the main criteria.
-
@meleu As whitespaces are working
(even if they are not allowed!)I would suggest followingif [[ "$line" =~ ^[^\/]+$ ]] && [[ -n "$line" ]]; then
remove the whitespace in the regex but check $line if empty or not.
Maybe pjft can tell more ;)
Goodnight mate
EDIT: Was to late
So we should allow whitespaces ;) -
@cyperghost I think in concept everything should work as long as it's accepted by the file system. I just wanted to play it safe and create a minimum common denominator set of characters.
-
@pjft I think so but as I'm not a C++ coder I can't exactly tell. Thank you for taking part!
The touch command is a smooth way to leave files unchanged so this script seems to be save even if we update with new collections. The exclusion that @meleu made ... the two slashes are correct. But I wan't avoid that LF entries create
custom-.cfg
files therefore a check of $line parameter is needed.I will update first post and it's codes as @meleu agrees to changes - maybe he gots a better idea ;)
-
@pjft said in Create custom-collections from txt file:
This is the regular expression of things I allow/exclude:
[^A-Za-z0-9-[]()\s']
So, we should allow:
- letters (lower and upper case)
- numbers
- spaces
- '
Are you saying that this is what currently works with your custom collections feature? Or is it your personal opinion?
-
@cyperghost said in Create custom-collections from txt file:
@meleu As whitespaces are working
(even if they are not allowed!)I would suggest followingif [[ "$line" =~ ^[^\/]+$ ]] && [[ -n "$line" ]]; then
remove the whitespace in the regex but check $line if empty or not.
looks like you didn't test that... :-) that regex don't match empty strings. Try it and see.
prompt$ [[ "" =~ ^[^\/]+$ ]] && echo valid || echo invalid invalid
Translating that regex:
^
- start of the line[^\ /]
- any character that is NOT a space'\ '
or a slash'/'
.+
- one or more occurences (here is the trick for not allowing empty strings)$
- end of the line
-
@meleu those are the checks I implemented for when the user can type a collection name.
-
-
@cyperghost just to match the same limits @pjft imposed to what the user can type for a collection name, I suggest this regex in the script:
^[][()\ \'A-Za-z0-9-]+$
.Then that
if
inside thewhile
becomes this:if [[ "$line" =~ ^[][()\ \'A-Za-z0-9-]+$ ]]; then
@pjft out of curiosity: is the underscore
_
invalid? -
@meleu I suppose it is, by omission, not deliberately. As I said, I tried to get a regular expression that would match the majority of names people would try to enter - it was not extensive, but had the main concern of not allowing people to enter characters that would fail miserably in some OSs ('/', '*', '?', etc).
Underscores could certainly be added. My recommendation is that if you manage to try it out and confirm it works via your script in ES, then by all means keep it. As I mentioned, these checks are only used at text entry time, so they shouldn't affect in any way how ES would work if you create them elsewhere. But if they fail, don't hold me against it :)
-
-
@meleu @pjft
I updated previous post to give tributes.
Well I think there are other characters that can be included. But I think space and "-" and () are good way.
The underscore works btw ;)
What do you both think.... Is v1.3 with RegEx^[][()\ \'A-Za-z0-9-]+$
final? or should it be extended. For my personal usage it's enoughWe can add
\_
and then the underscore works, what's next? #,&,!,?,~..... -
@cyperghost No, please stay away from most of the characters you just mentioned, as some of them are special characters in different file systems (~, ?, etc).
I'd rather keep the REGEXP exactly the same for compatibility purposes. I don't like to give people tools for them to easily shoot themselves in the foot :)
-
Okay... I update script (hopefully last time) and add the underscore.
Contributions to the project are always appreciated, so if you would like to support us with a donation you can do so here.
Hosting provided by Mythic-Beasts. See the Hosting Information page for more information.