Nathan McRae 3aea6f1281 Factor out argument parsing
and encapsulate the result in a class
2025-02-16 23:10:35 -08:00

184 lines
7.0 KiB
Java

package name.nathanmcrae.numbersstation;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.SftpException;
import com.leakyabstractions.result.api.Result;
import com.leakyabstractions.result.core.Results;
import com.tearsofaunicorn.wordpress.api.model.Post;
import com.tearsofaunicorn.wordpress.api.WordpressClient;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.FileHandler;
import java.util.logging.Logger;
import java.util.logging.Level;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import org.apache.commons.cli.*;
public class Main extends Application {
private static final Logger logger = Logger.getLogger(Main.class.getName());
// TODO: get git info
private static final String VERSION = "0.0.1";
private static Path statePath = null;
public static Path getStatePath() {
if (statePath == null) {
String stateHome = System.getenv("XDG_STATE_HOME");
if (stateHome == null || stateHome.isEmpty() || !Paths.get(stateHome).isAbsolute()) {
String userHome = System.getProperty("user.home");
statePath = Paths.get(userHome, ".local", "state", "numbers-station");
} else {
statePath = Paths.get(stateHome, "numbers-station");
}
}
return statePath;
}
@Override
public void start(Stage primaryStage) throws Exception {
try {
Parent root = FXMLLoader.load(getClass().getResource("MainView.fxml"));
primaryStage.setTitle("Numbers Station");
primaryStage.setScene(new Scene(root));
primaryStage.show();
logger.info("Application started");
} catch (IOException e) {
logger.log(Level.SEVERE, "Failed to load main view", e);
}
}
private static void setupLogger() {
try {
Path logFile = getStatePath().resolve("main.log");
if (!Files.exists(logFile.getParent())) {
Files.createDirectories(logFile.getParent());
}
FileHandler fileHandler = new FileHandler(logFile.toString(), true);
fileHandler.setFormatter(new CustomFormatter());
logger.addHandler(fileHandler);
} catch (IOException e) {
System.out.println("Failed to set up logger: " + e.getMessage());
}
}
public static void main(String[] args) {
MainParsedArguments parsedArgs = new MainParsedArguments(args);
if (parsedArgs.getHelpFlag()) {
parsedArgs.printHelp();
System.exit(0);
}
if (parsedArgs.getVersionFlag()) {
System.out.println("Numbers Station version " + VERSION);
System.exit(0);
}
Thread.setDefaultUncaughtExceptionHandler((thread, throwable) -> {
logger.log(Level.SEVERE, "Unhandled exception caught", throwable);
});
Platform.setImplicitExit(false);
Thread.currentThread().setUncaughtExceptionHandler((thread, throwable) -> {
logger.log(Level.SEVERE, "Unhandled exception in JavaFX application thread", throwable);
});
setupLogger();
if (parsedArgs.getStationName() != null) {
// TODO: errors in runStation should trigger a notification
runStation(parsedArgs);
} else {
launch(args);
}
}
public static void runStation(MainParsedArguments parsedArgs) {
if (parsedArgs.getStationName() == null || parsedArgs.getStationName() == "") {
logger.log(Level.SEVERE, "Station name must be provided and not empty");
// TODO: Notification
System.exit(1);
}
Result<MainSettings, Exception> result = MainSettings.load();
if (!result.hasSuccess()) {
logger.log(Level.SEVERE, "Unable to load settings");
// TODO: Notification
System.exit(1);
}
MainSettings settings = result.getSuccess().get();
StationSettings loadedStation = settings.getStations().stream()
.filter(station -> station.getName().equals(parsedArgs.getStationName()))
.findFirst()
.orElse(null);
if (loadedStation == null) {
logger.log(Level.SEVERE, "Unable to find station " + parsedArgs.getStationName());
// TODO: Notification
System.exit(1);
}
logger.info("Loaded station " + parsedArgs.getStationName());
Path stationDirPath = loadedStation.stationPath();
try {
boolean generateMessage = false;
if (!Files.exists(stationDirPath)) {
Files.createDirectories(stationDirPath);
}
Path nextMessagePath = stationDirPath.resolve("next-message.txt");
String messageText;
if (!Files.exists(nextMessagePath)) {
messageText = loadedStation.generateMessage(settings.getMessageGenerationAttempts());
} else {
messageText = new String(Files.readAllBytes(nextMessagePath));
}
// Send message using appropriate method
switch (loadedStation.getMessageMethod()) {
case StationSettings.MessageMethod.SFTP:
//loadedStation.uploadNextMessageToSFTP();
break;
case StationSettings.MessageMethod.WORDPRESS:
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
String dateStr = dateFormat.format(new Date());
System.setProperty("wordpress.username", loadedStation.getUsername());
System.setProperty("wordpress.password", loadedStation.getPassword());
System.setProperty("wordpress.url", loadedStation.getAddress());
Post post = new Post(dateStr, messageText);
WordpressClient client = new WordpressClient();
String newPostId = client.newPost(post);
break;
default:
logger.log(Level.SEVERE, "Message method " + loadedStation.getMessageMethod() + " not supported");
// TODO: Notification
System.exit(1);
}
String newMessageText = loadedStation.generateMessage(settings.getMessageGenerationAttempts());
Files.write(nextMessagePath, newMessageText.getBytes(StandardCharsets.UTF_8));
} catch (IOException | StationSettings.MessageGenerationException e) {
logger.log(Level.SEVERE, "Exception while posting message to station " + parsedArgs.getStationName(), e);
// TODO: Notification
System.exit(1);
}
System.exit(0);
}
}