Skip to content

Commit cee7a15

Browse files
committed
Add variables that can be used in the save path (#265)
1 parent 43eaa99 commit cee7a15

File tree

2 files changed

+62
-17
lines changed

2 files changed

+62
-17
lines changed

src/main/java/airsquared/blobsaver/app/Controller.java

+6-3
Original file line numberDiff line numberDiff line change
@@ -319,9 +319,12 @@ public void checkBlobs() {
319319
public void locationHelp() {
320320
ButtonType openURL = new ButtonType("Open URL");
321321
Alert alert = new Alert(Alert.AlertType.INFORMATION,
322-
"Click \"Open URL\" to see how to automatically upload blobs you save to the cloud.", openURL, ButtonType.OK);
323-
alert.setTitle("Tip: Saving Blobs to the Cloud");
324-
alert.setHeaderText("Tip");
322+
"You can use the following variables which will be automatically replaced by their respective values: ${DeviceIdentifier}, ${BoardConfig}, ${APNonce}, ${Generator}, ${DeviceModel}, ${ECID}, ${FullVersionString}, ${BuildID}, and ${MajorVersion}." +
323+
"\n\nExamples: /Users/airsquared/Blobs/${DeviceModel}/${MajorVersion}" +
324+
"\n/Users/airsquared/Blobs/${DeviceIdentifier}/${MajorVersion}/${FullVersionString}\n\n" +
325+
"Click \"Open URL\" to see how to automatically upload blobs you save to the cloud.", openURL, ButtonType.OK);
326+
alert.setTitle("Tips: Blob File Directory");
327+
alert.setHeaderText("Tips");
325328
alert.showAndWait();
326329
if (openURL.equals(alert.getResult())) {
327330
Utils.openURL("https://github.com/airsquared/blobsaver/wiki/Automatically-saving-blobs-to-the-cloud");

src/main/java/airsquared/blobsaver/app/TSS.java

+56-14
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
import com.google.gson.Gson;
2222
import javafx.concurrent.Task;
2323

24-
import java.io.File;
2524
import java.io.FileNotFoundException;
2625
import java.io.IOException;
2726
import java.net.MalformedURLException;
@@ -74,7 +73,6 @@ public class TSS extends Task<String> {
7473
private TSS(String deviceIdentifier, String ecid, String savePath, String boardConfig, boolean includeBetas, String manualVersion, String manualIpswURL, String apnonce, String generator, boolean saveToTSSSaver, boolean saveToSHSHHost) {
7574
this.deviceIdentifier = deviceIdentifier;
7675
this.ecid = ecid;
77-
this.savePath = savePath;
7876
this.boardConfig = boardConfig;
7977
this.includeBetas = includeBetas;
8078
this.manualVersion = manualVersion;
@@ -83,6 +81,7 @@ private TSS(String deviceIdentifier, String ecid, String savePath, String boardC
8381
this.generator = generator;
8482
this.saveToTSSSaver = saveToTSSSaver;
8583
this.saveToSHSHHost = saveToSHSHHost;
84+
this.savePath = parsePath(savePath);
8685
}
8786

8887
/**
@@ -98,7 +97,7 @@ protected String call() throws TSSException {
9897
ArrayList<String> args = constructArgs();
9998

10099
var alreadySaved = new StringJoiner(", ");
101-
var savedFor = new StringJoiner(", ");
100+
var newlySaved = new StringJoiner(", ");
102101
for (Utils.IOSVersion iosVersion : iosVersions) {
103102
if (!Prefs.getAlwaysSaveNewBlobs() && checkAlreadySaved(iosVersion)) {
104103
alreadySaved.add(iosVersion.versionString());
@@ -116,14 +115,14 @@ protected String call() throws TSSException {
116115
}
117116

118117
if (iosVersion.versionString() != null) {
119-
savedFor.add(iosVersion.versionString());
118+
newlySaved.add(iosVersion.versionString());
120119
}
121120
}
122-
StringBuilder responseBuilder = new StringBuilder();
123-
if (manualIpswURL != null || savedFor.length() > 0) {
121+
var responseBuilder = new StringBuilder();
122+
if (manualIpswURL != null || newlySaved.length() > 0) {
124123
responseBuilder.append("Successfully saved blobs in\n").append(savePath);
125-
if (savedFor.length() > 0) {
126-
responseBuilder.append("\n\nFor version").append(iosVersions.size() == 1 ? " " : "s ").append(savedFor);
124+
if (newlySaved.length() > 0) {
125+
responseBuilder.append("\n\nFor version").append(iosVersions.size() == 1 ? " " : "s ").append(newlySaved);
127126
}
128127
if (alreadySaved.length() > 0) {
129128
responseBuilder.append("\n\n");
@@ -156,7 +155,7 @@ private boolean checkAlreadySaved(Utils.IOSVersion ios) {
156155
String fileName = "%s_%s_%s_%s-%s_%s.shsh2"
157156
.formatted(parseECID(), deviceIdentifier, getBoardConfig(), versionStringOnly, ios.buildid(), apnonce);
158157

159-
if (Files.exists(Path.of(savePath, fileName))) {
158+
if (Files.exists(Path.of(parsePathWithVersion(ios), fileName))) {
160159
System.out.println("Already Saved: " + fileName);
161160
return true;
162161
}
@@ -168,16 +167,59 @@ private long parseECID() {
168167
: Long.parseLong(ecid.startsWith("0x") ? ecid.substring(2) : ecid, 16);
169168
}
170169

170+
private String parsePath(String input) {
171+
if (!input.contains("${")) return input;
172+
String template = input;
173+
174+
var variables = Map.of("${DeviceIdentifier}", deviceIdentifier,
175+
"${BoardConfig}", getBoardConfig(),
176+
"${APNonce}", apnonce,
177+
"${Generator}", generator,
178+
"${DeviceModel}", Devices.identifierToModel(deviceIdentifier),
179+
"${ECID}", ecid);
180+
for (Map.Entry<String, String> entry : variables.entrySet()) {
181+
template = template.replace(entry.getKey(), entry.getValue());
182+
}
183+
return template;
184+
}
185+
186+
private String parsePathWithVersion(Utils.IOSVersion ios) {
187+
if (!savePath.contains("${")) return savePath;
188+
var template = savePath;
189+
190+
Map<String, String> variables;
191+
if (ios.versionString() != null) {
192+
variables = Map.of("${FullVersionString}", ios.versionString(),
193+
"${BuildID}", ios.buildid(),
194+
"${MajorVersion}", ios.versionString().replaceFirst("\\..*", ""));
195+
} else {
196+
variables = Map.of("${FullVersionString}", "UnknownVersion",
197+
"${BuildID}", "UnknownBuildID",
198+
"${MajorVersion}", "UnknownVersion");
199+
}
200+
for (Map.Entry<String, String> entry : variables.entrySet()) {
201+
template = template.replace(entry.getKey(), entry.getValue());
202+
}
203+
204+
return template;
205+
}
171206

172207
private void saveFor(Utils.IOSVersion iosVersion, ArrayList<String> args) throws TSSException {
173208
final int urlIndex = args.size() - 1;
209+
final int pathIndex = args.size() - 3;
174210
Path manifest;
175211
try {
176212
manifest = extractBuildManifest(iosVersion.ipswURL());
177213
args.set(urlIndex, manifest.toString());
178214
} catch (IOException e) {
179215
throw new TSSException("Unable to extract BuildManifest.", true, e);
180216
}
217+
try {
218+
args.set(pathIndex, parsePathWithVersion(iosVersion));
219+
Files.createDirectories(Path.of(args.get(pathIndex)));
220+
} catch (IOException e) {
221+
throw new TSSException("Unable to create save directory. Try with a different save path. If you are using variables, make sure they are spelled correctly.", false, e);
222+
}
181223
try {
182224
System.out.println("Running: " + args);
183225
String tssLog = executeProgram(args);
@@ -258,9 +300,7 @@ private List<Utils.IOSVersion> getIOSVersions() throws TSSException {
258300
private ArrayList<String> constructArgs() {
259301
ArrayList<String> args = new ArrayList<>(17);
260302
String tsscheckerPath = Utils.getTsschecker().getAbsolutePath();
261-
//noinspection ResultOfMethodCallIgnored
262-
new File(savePath).mkdirs();
263-
Collections.addAll(args, tsscheckerPath, "--nocache", "--save", "--device", deviceIdentifier, "--ecid", ecid, "--save-path", savePath);
303+
Collections.addAll(args, tsscheckerPath, "--nocache", "--save", "--device", deviceIdentifier, "--ecid", ecid);
264304
Collections.addAll(args, "--boardconfig", getBoardConfig());
265305
if (apnonce != null) {
266306
Collections.addAll(args, "--apnonce", apnonce);
@@ -270,7 +310,9 @@ private ArrayList<String> constructArgs() {
270310
} else {
271311
Collections.addAll(args, "--generator", "0x1111111111111111");
272312
}
273-
Collections.addAll(args, "--build-manifest", "will be replaced in loop");
313+
314+
Collections.addAll(args, "--save-path", "will be replaced in loop",
315+
"--build-manifest", "will be replaced in loop");
274316

275317
return args;
276318
}
@@ -294,7 +336,7 @@ && containsIgnoreCase(tsscheckerLog, "checking tss status failed")) {
294336
} else if (containsIgnoreCase(tsscheckerLog, "Could not resolve host")) {
295337
throw new TSSException("Saving blobs failed. Check your internet connection.", false, tsscheckerLog);
296338
} else if (containsIgnoreCase(tsscheckerLog, "can't save shsh at")) {
297-
throw new TSSException("'" + savePath + "' is not a valid path", false);
339+
throw new TSSException("'" + savePath + "' is not a valid path. If you are using variables, make sure they are spelled correctly.", false);
298340
} else if (containsIgnoreCase(tsscheckerLog, "IS NOT being signed")) {
299341
if (manualVersion == null) {
300342
throw new TSSException("The " + Devices.getOSNameForType(Devices.getDeviceType(deviceIdentifier)) + " version is not being signed for device " + deviceIdentifier, false);

0 commit comments

Comments
 (0)