diff --git a/blog.java b/blog.java new file mode 100644 index 0000000..151609d --- /dev/null +++ b/blog.java @@ -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 lines = Files.lines(new File(file.toString()).toPath())) { + List 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, "<- Back to home\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.get(i).replace("#", "") + "" + "\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, "

" + lineList.get(i).replace("^", "") + " | " + dtf.format(now) + "

" + "
", true); + } + AUTHOR.set(lineList.get(i).replace("^", "")); + + } + + else if (lineList.get(i).startsWith("|")) { + if (!setValuesOnly) { + FileUtils.writeStringToFile(newHtmlFile, "

" + lineList.get(i).replace("|", "") + "

" + "\n", true); + } + + } + + else if (lineList.get(i).startsWith(">") && lineList.get(i).endsWith("<") ) { + if (!setValuesOnly) { + FileUtils.writeStringToFile(newHtmlFile, "

" + lineList.get(i).replace("<", "").replace(">", "") + "

" + "\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, "" + "\n", true); + } + + } + } + + if (!setValuesOnly) { + FileUtils.writeStringToFile(newHtmlFile, "\n
\n \n" + + " \n" + + "", 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 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 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
\n" + + "
\n" + + " " + + "
\n" + + "

" + TITLE.toString() + "

\n" + + "
\n" + + "

" + RT + " minute read

\n" + + "

" + AUTHOR.toString() + "

\n" + + "
\n" + + Tag1Var + "\n" + Tag2Var + "\n" + Tag3Var + "\n" + Tag4Var + "\n" + Tag5Var + "\n" + Tag6Var + "\n" + Tag7Var + + "
\n" + + "

" + POST_CONTENT.toString() + "

\n" + + " " + "... See more\n" + + "
\n" + + "
\n" + + "
"; + + 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(); + } + + } \ No newline at end of file diff --git a/values.java b/values.java new file mode 100644 index 0000000..0a273a4 --- /dev/null +++ b/values.java @@ -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 AUTHOR = new AtomicReference<>(""); // The author for the post in blogPosts.php + AtomicReference TITLE = new AtomicReference<>(""); // The post title in blogPosts.php + AtomicReference 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 file = new AtomicReference<>(); // Select the blog txt file + AtomicReference publishFile = new AtomicReference<>(); // The .HTML file to be published to the site + AtomicReference 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 Tag1Var = new AtomicReference<>(""); // Remains empty if user doesn't select + AtomicReference Tag2Var = new AtomicReference<>(""); // Remains empty if user doesn't select + AtomicReference Tag3Var = new AtomicReference<>(""); // Remains empty if user doesn't select + AtomicReference Tag4Var = new AtomicReference<>(""); // Remains empty if user doesn't select + AtomicReference Tag5Var = new AtomicReference<>(""); // Remains empty if user doesn't select + AtomicReference Tag6Var = new AtomicReference<>(""); // Remains empty if user doesn't select + AtomicReference Tag7Var = new AtomicReference<>(""); // Remains empty if user doesn't select + String Tag1String = "How-To"; // The first blog post tag + String Tag2String = "Politics"; // The second blog post tag + String Tag3String = "Tech"; // The third blog post tag + String Tag4String = "Ethics"; // The fourth blog post tag + String Tag5String = "VPA/SEG"; // The fourth blog post tag + String Tag6String = "Personal"; // The fourth blog post tag + String Tag7String = "Other"; // 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 + + + +}