Add .java files

This commit is contained in:
Evan Niederwerfer 2025-01-19 18:44:00 -05:00
parent 1a8d5f5d38
commit b8f42e2f99
2 changed files with 431 additions and 0 deletions

379
blog.java Normal file
View File

@ -0,0 +1,379 @@
package evanniederwerfer.blogapp.blogappv2;
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.GridPane;
import javafx.scene.text.Font;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import java.io.*;
import java.net.SocketException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Stream;
import java.time.format.DateTimeFormatter;
import java.time.LocalDateTime;
import org.apache.commons.io.FileUtils;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
public class blog extends Application implements values {
// Post Creation Values
// Create HTML from TXT syntax
public void createHtml(Stage stage, boolean setValuesOnly, Path path) {
File file = new File(path.toString());
File newHtmlFile = null;
try (Stream<String> lines = Files.lines(new File(file.toString()).toPath())) {
List<String> lineList = lines.toList(); // Store the individual lines of files in a list
if (!setValuesOnly) {
FileChooser save = new FileChooser();
FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter("HTML files (*.html)", "*.html");
save.getExtensionFilters().add(extFilter);
File selectedFile = save.showSaveDialog(stage);
newHtmlFile = new File(selectedFile.toString());
FileUtils.writeStringToFile(newHtmlFile, "<a class=\"backbtn\" href=\"https://www.blog.evanniederwerfer.com\"><- Back to home</a>\n", true);
}
else if (setValuesOnly) {
System.out.println(lineList);
}
// Traverse through lineList and write to newly created HTML file
for (int i=0; i<lineList.toArray().length; i++) {
if (lineList.get(i).startsWith("#")) {
if (!setValuesOnly) {
FileUtils.writeStringToFile(newHtmlFile, "<h1 class=\"title\">" + lineList.get(i).replace("#", "") + "</h1>" + "\n", true);
}
TITLE.set(lineList.get(i).replace("#", ""));
}
else if (lineList.get(i).startsWith("^") && lineList.get(i).endsWith("^")) {
if (!setValuesOnly) {
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy/MM/dd");
LocalDateTime now = LocalDateTime.now();
FileUtils.writeStringToFile(newHtmlFile, "<h3 class='author'>" + lineList.get(i).replace("^", "") + " | " + dtf.format(now) + "</h3>" + "<div class=\"content\">", true);
}
AUTHOR.set(lineList.get(i).replace("^", ""));
}
else if (lineList.get(i).startsWith("|")) {
if (!setValuesOnly) {
FileUtils.writeStringToFile(newHtmlFile, "<h3 class='subheading'>" + lineList.get(i).replace("|", "") + "</h3>" + "\n", true);
}
}
else if (lineList.get(i).startsWith(">") && lineList.get(i).endsWith("<") ) {
if (!setValuesOnly) {
FileUtils.writeStringToFile(newHtmlFile, "<p>" + lineList.get(i).replace("<", "").replace(">", "") + "</p>" + "\n", true);
}
POST_CONTENT.set(POST_CONTENT.get() + " " + lineList.get(i).replace("<", "").replace(">", ""));
}
else if (lineList.get(i).startsWith("{") && lineList.get(i).endsWith("}")) {
if (!setValuesOnly) {
FileUtils.writeStringToFile(newHtmlFile, "<img src=\"" + lineList.get(i).replace("{", "").replace("}", "") + "\">" + "\n", true);
}
}
}
if (!setValuesOnly) {
FileUtils.writeStringToFile(newHtmlFile, "\n </div> \n <head>\n" +
" <link rel=\"stylesheet\" href=\"./stylesheets/blog.css\">\n" +
"</head>", true);
}
}
catch (IOException er) {
try {
throw new IOException(er);
} catch (IOException ex) {
throw new RuntimeException(ex);
}
}
}
public void start(Stage stage) {
// Java FX control styling
GridPane grid = new GridPane();
grid.setHgap(5);
grid.setAlignment(Pos.CENTER);
FileChooser md = new FileChooser();
Label filepath = new Label();
grid.add(filepath, 2, 1);
Label heading = new Label(headingLabel);
heading.setFont(new Font(30));
heading.setAlignment(Pos.CENTER);
Label fileLabel = new Label(fileLabelTxt);
Button button = new Button(selectFileBtn);
AtomicReference<File> selectedTxtFile = new AtomicReference<>();
// Store user selected txt file path
button.setOnAction(e -> {
selectedTxtFile.set(md.showOpenDialog(stage));
filepath.setText(selectedTxtFile.toString());
});
// Create new HTML file based on users selection
Button confirm = new Button("Confirm");
confirm.setOnAction(e -> {
Path fileTxtPath = selectedTxtFile.get().toPath();
createHtml(stage, false, fileTxtPath);
});
// Java FX control styling
Label heading2 = new Label("Publish Blog");
heading2.setFont(new Font(30));
heading2.setAlignment(Pos.CENTER);
Label blogNameLabel = new Label("Blog name for URL (evanniederwerfer.com/text-here):");
TextArea blogName = new TextArea();
blogName.setMaxHeight(20);
Label blogImageLabel = new Label("Blog image:");
Button blogImgBtn = new Button("Select Image");
blogImgBtn.setOnAction(e -> {
File selectedFile = md.showOpenDialog(stage);
imageFile.set(selectedFile.toPath());
blogImageLabel.setText(selectedFile.toPath().toString());
});
Label blogTagsLabel = new Label("Select Tags:");
RadioButton Tags1 = new RadioButton("How-To");
RadioButton Tags2 = new RadioButton("Politics");
RadioButton Tags3 = new RadioButton("Tech");
RadioButton Tags4 = new RadioButton("Ethics");
RadioButton Tags5 = new RadioButton("VPA/SEG");
RadioButton Tags6 = new RadioButton("Personal");
RadioButton Tags7 = new RadioButton("Other");
Label blogFileLabel = new Label("Blog HTML File:");
Button blogFileBtn = new Button("Select HTML File");
Label selectedFilePath = new Label();
// User selected .HTML file to publish
blogFileBtn.setOnAction(e -> {
File selectedFile = md.showOpenDialog(stage);
publishFile.set(selectedFile.toPath());
selectedFilePath.setText(publishFile.toString());
});
Button publishBtn = new Button("Publish");
// Connect to the FTP server & publish the new page and write changes
publishBtn.setOnAction(e -> {
if (AUTHOR.toString().isEmpty() || TITLE.toString().isEmpty() || POST_CONTENT.toString().isEmpty()) { // check to see if first step was skipped, ask user to select txt
Alert emptyVars = new Alert(Alert.AlertType.CONFIRMATION, "Warning - no values set for post. Select the txt file associated with the generated HTML file to proceed");
Optional<ButtonType> result = emptyVars.showAndWait();
if (blogName.getText().isEmpty()) {
Alert emptyName = new Alert(Alert.AlertType.ERROR, "No blog name was specified");
emptyName.show();
try {
throw new Exception("blog name empty");
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
if (publishFile.toString().isEmpty()) {
Alert emptyFile = new Alert(Alert.AlertType.ERROR, "No publish HTML file was selected");
emptyFile.show();
try {
throw new Exception("publish file empty");
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
if(result.get() == ButtonType.OK) {
File selectedFile = md.showOpenDialog(stage);
Path filep = selectedFile.toPath();
filepath.setText(file.toString());
createHtml(stage, true, filep);
}
else if(result.get() == ButtonType.CANCEL) {
emptyVars.close();
}
// cancel button is pressed
}
FTPClient ftpClient = new FTPClient();
try {
ftpClient.connect(host, port);
ftpClient.login(user, password);
ftpClient.enterLocalPassiveMode();
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
InputStream inputStream = new FileInputStream(publishFile.toString());
boolean stored = ftpClient.storeFile("./blogs/" + blogName.getText().replace(" ", "-") + ".html", inputStream);
if (stored) {
if(Tags1.isSelected()){
Tag1Var.set(Tag1String);
}
if(Tags2.isSelected()){
Tag2Var.set(Tag2String);
}
if(Tags3.isSelected()){
Tag3Var.set(Tag3String);
}
if(Tags4.isSelected()){
Tag4Var.set(Tag4String);
}
if(Tags5.isSelected()){
Tag5Var.set(Tag5String);
}
if(Tags6.isSelected()){
Tag6Var.set(Tag6String);
}
if(Tags7.isSelected()){
Tag7Var.set(Tag7String);
}
try (FileOutputStream fos = new FileOutputStream(tempFile)) {
ftpClient.retrieveFile("blogPosts.php", fos);
}
InputStream inputStream2 = new FileInputStream(imageFile.toString());
boolean image_stored = ftpClient.storeFile("./images/" + blogName.getText().replace(" ", "-"), inputStream2);
if (!image_stored) {
Alert imgStoreEx = new Alert(Alert.AlertType.ERROR, "Image was unable to be stored");
imgStoreEx.show();
throw new Exception("Image not transmitted");
}
}
String genText = // Generate the post div and content to write to the replacement blogPosts.php
"\n<div class=\"posts-container\">\n" +
" <div class=\"post\">\n" +
" <img src=\"./images/" + blogName.getText().replace(" ", "-") + "\">" +
" <div>\n" +
" <h1 class=\"post-heading\">" + TITLE.toString() + "</h1>\n" +
" <div class=\"post-info\">\n" +
" <p class=\"post-read-time\">" + RT + " minute read</p>\n" +
" <p class=\"post-author\">" + AUTHOR.toString() + "</p>\n" +
" <br>\n" +
Tag1Var + "\n" + Tag2Var + "\n" + Tag3Var + "\n" + Tag4Var + "\n" + Tag5Var + "\n" + Tag6Var + "\n" + Tag7Var +
" <br>\n" +
" <p class=\"post-content\">" + POST_CONTENT.toString() + "</p>\n" +
" <a class=\"post-more\" href=\"https://www.blog.evanniederwerfer.com/blogs/" + blogName.getText().replace(" ", "-") + "\">" + "... See more</a>\n" +
" </div>\n" +
" </div>\n" +
" </div>";
String existingContent = FileUtils.readFileToString(tempFile, "UTF-8");
String updatedContent = genText + existingContent;
FileUtils.writeStringToFile(tempFile, updatedContent, "UTF-8");
try (FileInputStream fis = new FileInputStream(tempFile)) {
ftpClient.storeFile("blogPosts.php", fis);
}
boolean isDeleted = tempFile.delete();
if (!isDeleted) {
System.out.println("Warning: temp PHP file cannot be deleted, check the directory permissions and try again");
}
} catch (SocketException ex) {
throw new RuntimeException(ex);
} catch (FileNotFoundException ex) {
Alert nullImg = new Alert(Alert.AlertType.ERROR, "Image not specified");
nullImg.show();
throw new RuntimeException(ex);
} catch (IOException ex) {
throw new RuntimeException(ex);
} catch (Exception ex) {
throw new RuntimeException(ex);
}
// Set all values to empty or 0
AUTHOR.set("");
TITLE.set("");
POST_CONTENT.set("");
RT.set(0);
Alert success = new Alert(Alert.AlertType.INFORMATION, "Your blog was published! https://www.blog.evanniederwerfer.com/" + blogName.getText().replace(" ", "-"));
success.show();
});
// JavaFX add items and show window
grid.add(heading, 0,0);
grid.add(fileLabel, 0, 1);
grid.add(button, 1, 1);
grid.add(confirm, 0, 2);
grid.add(heading2, 0, 3);
grid.add(blogNameLabel, 0, 4);
grid.add(blogName, 1, 4);
grid.add(blogImageLabel, 0, 5);
grid.add(blogImgBtn, 1, 5);
grid.add(blogTagsLabel, 0, 6);
grid.add(Tags1, 0, 7);
grid.add(Tags2, 0, 8);
grid.add(Tags3, 0, 9);
grid.add(Tags4, 0, 10);
grid.add(Tags5, 0, 11);
grid.add(Tags6, 0, 12);
grid.add(Tags7, 0, 13);
grid.add(blogFileLabel, 0, 14);
grid.add(blogFileBtn, 1, 14);
grid.add(selectedFilePath, 2, 14);
grid.add(publishBtn, 0, 15);
Scene scene = new Scene(grid, 800, 400);
stage.setScene(scene);
stage.show();
}
}

52
values.java Normal file
View File

@ -0,0 +1,52 @@
package evanniederwerfer.blogapp.blogappv2;
import java.io.File;
import java.nio.file.Path;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
public interface values {
AtomicReference<String> AUTHOR = new AtomicReference<>(""); // The author for the post in blogPosts.php
AtomicReference<String> TITLE = new AtomicReference<>(""); // The post title in blogPosts.php
AtomicReference<String> POST_CONTENT = new AtomicReference<>(""); // The post content for blogPosts.php
AtomicInteger RT = new AtomicInteger(); // Read time (approx time it takes to read article) for blogPosts.php
// Files
AtomicReference<Path> file = new AtomicReference<>(); // Select the blog txt file
AtomicReference<Path> publishFile = new AtomicReference<>(); // The .HTML file to be published to the site
AtomicReference<Path> imageFile = new AtomicReference<>(); // The image to be displayed on published div
File tempFile = new File("tempFile.php"); // Temp .PHP file downloaded to update blogPosts.php
// HTML Strings
AtomicReference<String> Tag1Var = new AtomicReference<>(""); // Remains empty if user doesn't select
AtomicReference<String> Tag2Var = new AtomicReference<>(""); // Remains empty if user doesn't select
AtomicReference<String> Tag3Var = new AtomicReference<>(""); // Remains empty if user doesn't select
AtomicReference<String> Tag4Var = new AtomicReference<>(""); // Remains empty if user doesn't select
AtomicReference<String> Tag5Var = new AtomicReference<>(""); // Remains empty if user doesn't select
AtomicReference<String> Tag6Var = new AtomicReference<>(""); // Remains empty if user doesn't select
AtomicReference<String> Tag7Var = new AtomicReference<>(""); // Remains empty if user doesn't select
String Tag1String = "<a class=\"i1\">How-To</a>"; // The first blog post tag
String Tag2String = "<a class=\"i2\">Politics</a>"; // The second blog post tag
String Tag3String = "<a class=\"i3\">Tech</a>"; // The third blog post tag
String Tag4String = "<a class=\"i4\">Ethics</a>"; // The fourth blog post tag
String Tag5String = "<a class=\"i5\">VPA/SEG</a>"; // The fourth blog post tag
String Tag6String = "<a class=\"i6\">Personal</a>"; // The fourth blog post tag
String Tag7String = "<a class=\"i7\">Other</a>"; // The fourth blog post tag
// FTP Credentials
String host = "";
String user = "";
String password = "";
int port = 21;
// JavaFX Node Text
String headingLabel = "Create Blog"; // First heading label
String fileLabelTxt = "Blog File:"; // The blog file label text located by "Select File" button
String selectFileBtn = "Select File"; // The button to select a txt file with syntax to create blog
}