We want to make sure the message doesn't match any of the station's listed prefixes. Also, we give a finite number of tries to generate a valid message just in case prefixes somehow cover all messages. Make it a setting so it can be increased if needed.
216 lines
7.9 KiB
Java
216 lines
7.9 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());
|
|
}
|
|
}
|
|
|
|
private static String parseArguments(String[] args) {
|
|
Options options = new Options();
|
|
|
|
Option help = new Option("h", "help", false, "Show help");
|
|
options.addOption(help);
|
|
|
|
Option version = new Option("v", "version", false, "Show version");
|
|
options.addOption(version);
|
|
|
|
Option station = new Option("s", "station", true, "Specify station name");
|
|
station.setArgName("station-name");
|
|
options.addOption(station);
|
|
|
|
CommandLineParser parser = new DefaultParser();
|
|
HelpFormatter formatter = new HelpFormatter();
|
|
String stationName = null;
|
|
|
|
try {
|
|
CommandLine cmd = parser.parse(options, args);
|
|
|
|
if (cmd.hasOption("help")) {
|
|
formatter.printHelp("numbers-station", options);
|
|
System.exit(0);
|
|
}
|
|
|
|
if (cmd.hasOption("version")) {
|
|
System.out.println("Numbers Station version " + VERSION);
|
|
System.exit(0);
|
|
}
|
|
|
|
if (cmd.hasOption("station")) {
|
|
stationName = cmd.getOptionValue("station");
|
|
}
|
|
} catch (ParseException e) {
|
|
System.out.println(e.getMessage());
|
|
formatter.printHelp("numbers-station", options);
|
|
System.exit(1);
|
|
}
|
|
|
|
return stationName;
|
|
}
|
|
|
|
public static void main(String[] args) {
|
|
String stationName = parseArguments(args);
|
|
|
|
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 (stationName != null) {
|
|
// TODO: errors in runStation should trigger a notification
|
|
runStation(stationName);
|
|
} else {
|
|
launch(args);
|
|
}
|
|
}
|
|
|
|
public static void runStation(String stationName) {
|
|
if (stationName == null || stationName == "") {
|
|
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(stationName))
|
|
.findFirst()
|
|
.orElse(null);
|
|
|
|
if (loadedStation == null) {
|
|
logger.log(Level.SEVERE, "Unable to find station " + stationName);
|
|
// TODO: Notification
|
|
System.exit(1);
|
|
}
|
|
|
|
logger.info("Loaded station " + stationName);
|
|
|
|
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 " + stationName, e);
|
|
// TODO: Notification
|
|
System.exit(1);
|
|
}
|
|
|
|
System.exit(0);
|
|
}
|
|
}
|