From fa3e9761bb19aa871850945aa4111588a1a3db10 Mon Sep 17 00:00:00 2001 From: Roar Date: Thu, 16 Apr 2026 17:36:47 +0200 Subject: [PATCH 01/26] Updated DatabaseSetup Added UNIQUE Constraint to CharityVantiy UUID, as CharityVanity got a new entry (with the same UUID), everytime the scraper was run. --- .../java/ntnu/systemutvikling/team6/database/DatabaseSetup.java | 1 + 1 file changed, 1 insertion(+) diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/database/DatabaseSetup.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/database/DatabaseSetup.java index 6da6f1c..4f70f4b 100644 --- a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/database/DatabaseSetup.java +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/database/DatabaseSetup.java @@ -259,6 +259,7 @@ FOREIGN KEY (`User_UUID_User`) `logoURL` TEXT NULL, `key_values` TEXT NULL, `logoBLOB` MEDIUMBLOB NULL, + CONSTRAINT `unique_UUID_charity` UNIQUE (`UUID_charity`), INDEX `fk_CharityVanity_Charities1_idx` (`UUID_charity` ASC) VISIBLE, CONSTRAINT `fk_CharityVanity_Charities1` FOREIGN KEY (`UUID_charity`) From ef2b567b07ad9ebac17a24ca3fb52fe1c486af8f Mon Sep 17 00:00:00 2001 From: Roar Date: Thu, 16 Apr 2026 17:38:34 +0200 Subject: [PATCH 02/26] Updated APIToDatabaseService Fixed bug where CharityVanity would get multiple duplicate entries each run of the code. --- .../team6/service/APIToDatabaseService.java | 97 +++++++++---------- 1 file changed, 48 insertions(+), 49 deletions(-) diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/service/APIToDatabaseService.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/service/APIToDatabaseService.java index 9c50ad9..e62db7a 100644 --- a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/service/APIToDatabaseService.java +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/service/APIToDatabaseService.java @@ -36,31 +36,32 @@ public APIToDatabaseService(DatabaseConnection connection) { */ public void addAPIDataToTable(List charities) { Connection conn = null; - // Everything charity related except categories try { conn = connection.getMySqlConnection(); - conn.setAutoCommit(false); + conn.setAutoCommit( + false); + String sql1 = """ - INSERT INTO Charities (UUID_charities, org_number, pre_approved, status) - VALUES (?, ?, ?, ?) - ON DUPLICATE KEY UPDATE - pre_approved = VALUES(pre_approved), - status = VALUES(status); - """; + INSERT INTO Charities (UUID_charities, org_number, pre_approved, status) + VALUES (?, ?, ?, ?) + ON DUPLICATE KEY UPDATE + pre_approved = VALUES(pre_approved), + status = VALUES(status); + """; String sql2 = """ - INSERT INTO CharityVanity (UUID_charity, charity_name, charity_link, description, logoURL, key_values, logoBlob) - VALUES (?, ?, ?, ?, ?, ?, ?) - ON DUPLICATE KEY UPDATE - charity_name = VALUES(charity_name), - charity_link = VALUES(charity_link), - description = VALUES(description), - logoURL = VALUES(logoURL), - key_values = VALUES(key_values), - logoBlob = VALUES(logoBlob); - """; + INSERT INTO CharityVanity (UUID_charity, charity_name, charity_link, description, logoURL, key_values, logoBlob) + VALUES (?, ?, ?, ?, ?, ?, ?) + ON DUPLICATE KEY UPDATE + charity_name = VALUES(charity_name), + charity_link = VALUES(charity_link), + description = VALUES(description), + logoURL = VALUES(logoURL), + key_values = VALUES(key_values), + logoBlob = VALUES(logoBlob); + """; try (PreparedStatement ps1 = conn.prepareStatement(sql1); PreparedStatement ps2 = conn.prepareStatement(sql2)) { @@ -68,9 +69,13 @@ INSERT INTO CharityVanity (UUID_charity, charity_name, charity_link, description for (Charity charity : charities) { String uuid; if (charity.getUUID() == null) { - uuid = UUID.randomUUID().toString(); + + uuid = + UUID.nameUUIDFromBytes( + (charity.getOrg_number() + charity.getURL() + charity.getName()).getBytes()) + .toString(); charity.setUUIDFromString(uuid); - System.out.println("API object doesnt have UUID, assigning"); + System.out.println("API object doesn't have UUID, assigning stable UUID"); } else { uuid = charity.getUUID().toString(); } @@ -90,56 +95,51 @@ INSERT INTO CharityVanity (UUID_charity, charity_name, charity_link, description ps2.setBytes(7, charity.getLogoBlob()); ps2.executeUpdate(); } - } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(e); } - // -- Intergerty Check: + // Integrity Check String createTemp = """ - CREATE TEMPORARY TABLE temp_api_charities ( - org_number VARCHAR(255) PRIMARY KEY - ) - """; - + CREATE TEMPORARY TABLE temp_api_charities ( + org_number VARCHAR(255) PRIMARY KEY + ) + """; try (PreparedStatement ps = conn.prepareStatement(createTemp)) { ps.execute(); } String insertTemp = "INSERT IGNORE INTO temp_api_charities (org_number) VALUES (?)"; - try (PreparedStatement ps = conn.prepareStatement(insertTemp)) { - for (Charity charity : charities) { ps.setString(1, charity.getOrg_number().replaceAll("\\s", "")); ps.addBatch(); } - ps.executeBatch(); } String deleteSql = """ - DELETE FROM Charities c - WHERE NOT EXISTS ( - SELECT 1 FROM temp_api_charities t - WHERE t.org_number = c.org_number - ) - AND NOT EXISTS ( - SELECT 1 FROM Donations d WHERE d.charity_id = c.UUID_charities - ) - AND NOT EXISTS ( - SELECT 1 FROM Feedback f WHERE f.charity_id = c.UUID_charities - ) - AND NOT EXISTS ( - SELECT 1 FROM CharityVanity cv WHERE cv.UUID_charity = c.UUID_charities - ) - AND NOT EXISTS ( - SELECT 1 FROM CharityUsers cu WHERE cu.Charities_UUID_charities = c.UUID_charities - ); - """; + DELETE FROM Charities c + WHERE NOT EXISTS ( + SELECT 1 FROM temp_api_charities t + WHERE t.org_number = c.org_number + ) + AND NOT EXISTS ( + SELECT 1 FROM Donations d WHERE d.charity_id = c.UUID_charities + ) + AND NOT EXISTS ( + SELECT 1 FROM Feedback f WHERE f.charity_id = c.UUID_charities + ) + AND NOT EXISTS ( + SELECT 1 FROM CharityVanity cv WHERE cv.UUID_charity = c.UUID_charities + ) + AND NOT EXISTS ( + SELECT 1 FROM CharityUsers cu WHERE cu.Charities_UUID_charities = c.UUID_charities + ); + """; try (PreparedStatement ps = conn.prepareStatement(deleteSql)) { ps.executeUpdate(); @@ -156,7 +156,6 @@ AND NOT EXISTS ( } } e.printStackTrace(); - throw new RuntimeException("ERROR: Something went wrong during updating charities table."); } finally { if (conn != null) { From daef70aaf8efc2f470cc58db116b78300eee7740 Mon Sep 17 00:00:00 2001 From: Roar Date: Thu, 16 Apr 2026 18:18:56 +0200 Subject: [PATCH 03/26] Updated charityPage.fxml Description is showing correctly and name of Charity is only truncated for very, very long names. --- .../src/main/resources/fxml/charityPage.fxml | 903 +++++++++--------- 1 file changed, 452 insertions(+), 451 deletions(-) diff --git a/helpmehelpapplication/src/main/resources/fxml/charityPage.fxml b/helpmehelpapplication/src/main/resources/fxml/charityPage.fxml index e0b20e5..c9f5b00 100644 --- a/helpmehelpapplication/src/main/resources/fxml/charityPage.fxml +++ b/helpmehelpapplication/src/main/resources/fxml/charityPage.fxml @@ -25,484 +25,485 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - + + - - + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + + - - - + - + - + + + - - - - - - - - - + + - + + - - - - - - - - - + + + + - - + + + - - + - + + - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + - + - - + + + + - - - - + + + + + + + + + + + + + + + + + + + From 92aaac54087eedb93af86d851d7ad6b3a73c3961 Mon Sep 17 00:00:00 2001 From: Roar Date: Fri, 17 Apr 2026 00:56:53 +0200 Subject: [PATCH 04/26] Updated charityPage.fxml Added fx:id to charity logo for controller. --- .../src/main/resources/fxml/charityPage.fxml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/helpmehelpapplication/src/main/resources/fxml/charityPage.fxml b/helpmehelpapplication/src/main/resources/fxml/charityPage.fxml index c9f5b00..680dedd 100644 --- a/helpmehelpapplication/src/main/resources/fxml/charityPage.fxml +++ b/helpmehelpapplication/src/main/resources/fxml/charityPage.fxml @@ -219,11 +219,7 @@ - - - - - + From 068b189000f22d1dd4227ce354db3f55d25449b1 Mon Sep 17 00:00:00 2001 From: Roar Date: Fri, 17 Apr 2026 00:58:09 +0200 Subject: [PATCH 05/26] Updated CharityPageController Added reference to CharityLogo fx:id and dynamically sets the image to the logoBlob of the charity, or a placeholder image if the logoBlob is null. --- .../controller/CharityPageController.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/CharityPageController.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/CharityPageController.java index 81d6f4b..c5669e1 100644 --- a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/CharityPageController.java +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/CharityPageController.java @@ -1,9 +1,14 @@ package ntnu.systemutvikling.team6.controller; +import java.io.ByteArrayInputStream; +import java.util.Objects; + import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.scene.control.Label; import javafx.scene.control.TextField; +import javafx.scene.image.Image; +import javafx.scene.image.ImageView; import ntnu.systemutvikling.team6.controller.components.LoaderScene; import ntnu.systemutvikling.team6.models.Charity; @@ -18,6 +23,8 @@ public class CharityPageController { @FXML private Label CharityName; + @FXML private ImageView CharityLogo; + @FXML public void initialize() {} @@ -39,6 +46,17 @@ public void setCharity(Charity charity) { CharityDescription.setText(charity.getDescription()); CharityName.setText(charity.getName()); + + if (this.charity.getLogoBlob() != null) { + ByteArrayInputStream logoByteStream = new ByteArrayInputStream(this.charity.getLogoBlob()); + Image CharityLogoImage = new Image(logoByteStream); + this.CharityLogo.setImage(CharityLogoImage); + } else { + String placeholderImagePath = + Objects.requireNonNull(getClass().getResource("/images/leggTilBilde.jpg")).toExternalForm(); + Image placeholderImage = new Image(placeholderImagePath); + this.CharityLogo.setImage(placeholderImage); + } } /** From 57fdb668f20bd779116401ba21ae71baaf2ceccb Mon Sep 17 00:00:00 2001 From: Roar Date: Fri, 17 Apr 2026 01:06:13 +0200 Subject: [PATCH 06/26] Updated charityPage.fxml Added fx:id and method reference to Homepage Hyperlink. --- helpmehelpapplication/src/main/resources/fxml/charityPage.fxml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helpmehelpapplication/src/main/resources/fxml/charityPage.fxml b/helpmehelpapplication/src/main/resources/fxml/charityPage.fxml index 680dedd..cbc9670 100644 --- a/helpmehelpapplication/src/main/resources/fxml/charityPage.fxml +++ b/helpmehelpapplication/src/main/resources/fxml/charityPage.fxml @@ -169,7 +169,7 @@ - + From 7ba02775558d980a44375fc4f67572437494151c Mon Sep 17 00:00:00 2001 From: Roar Date: Fri, 17 Apr 2026 01:07:12 +0200 Subject: [PATCH 07/26] Updated CharityPageController Added method for opening browser and navigating to the url of the charity on IK. --- .../controller/CharityPageController.java | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/CharityPageController.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/CharityPageController.java index c5669e1..bf51b00 100644 --- a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/CharityPageController.java +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/controller/CharityPageController.java @@ -2,9 +2,9 @@ import java.io.ByteArrayInputStream; import java.util.Objects; - import javafx.event.ActionEvent; import javafx.fxml.FXML; +import javafx.scene.control.Hyperlink; import javafx.scene.control.Label; import javafx.scene.control.TextField; import javafx.scene.image.Image; @@ -25,6 +25,8 @@ public class CharityPageController { @FXML private ImageView CharityLogo; + @FXML private Hyperlink CharityURL; + @FXML public void initialize() {} @@ -53,7 +55,8 @@ public void setCharity(Charity charity) { this.CharityLogo.setImage(CharityLogoImage); } else { String placeholderImagePath = - Objects.requireNonNull(getClass().getResource("/images/leggTilBilde.jpg")).toExternalForm(); + Objects.requireNonNull(getClass().getResource("/images/leggTilBilde.jpg")) + .toExternalForm(); Image placeholderImage = new Image(placeholderImagePath); this.CharityLogo.setImage(placeholderImage); } @@ -91,4 +94,15 @@ public void handleSearch(ActionEvent event) { LoaderScene.LoadScene("availableOrganization", event, null, query); } + + @FXML + public void handleHomepageClick(ActionEvent event) { + try { + String url = this.charity.getURL(); + java.awt.Desktop.getDesktop().browse(java.net.URI.create(url)); + } catch (Exception e) { + System.out.println("Something went wrong when opening URL."); + e.printStackTrace(); + } + } } From 6410ed8e58ac323ad45de3148332f1d1388ef282 Mon Sep 17 00:00:00 2001 From: Roar Date: Fri, 17 Apr 2026 01:11:46 +0200 Subject: [PATCH 08/26] Updated URLCharityScraper Time for scraping went down from approx 2 hours to around 20-30 mins, and is still reliable. Thread.sleep() seems to not be required after all. --- .../scraperComponents/URLCharityScraper.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/scraperComponents/URLCharityScraper.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/scraperComponents/URLCharityScraper.java index f9e98b3..33b3c52 100644 --- a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/scraperComponents/URLCharityScraper.java +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/scraperComponents/URLCharityScraper.java @@ -70,7 +70,7 @@ public URLCharityScraper(String url, WebDriver driver) { * @return the {@code WebDriverWait} object to be used in the methods */ protected WebDriverWait createWait() { - return new WebDriverWait(driver, Duration.ofSeconds(30)); + return new WebDriverWait(driver, Duration.ofSeconds(10)); } /** @@ -118,7 +118,7 @@ protected void updateDescription() { wait.until( ExpectedConditions.numberOfElementsToBeMoreThan(By.cssSelector(".information"), 0)); - Thread.sleep(5000); + // Thread.sleep(5000); List firstDescription = findElements(By.cssSelector(".information")); for (WebElement element : firstDescription) { @@ -139,7 +139,7 @@ void updateLogo() { try { WebDriverWait wait = createWait(); wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".logo > img"))); - Thread.sleep(5000); + // Thread.sleep(5000); WebElement logo = findElement(By.cssSelector(".logo > img")); this.logoURL = logo.getAttribute("src"); @@ -155,7 +155,7 @@ void updateCategories() { WebDriverWait wait = createWait(); wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector(".tag-label"))); - Thread.sleep(5000); + // Thread.sleep(5000); List elements = findElements(By.cssSelector(".tag-label")); @@ -183,7 +183,7 @@ void updateKeyValues() { ExpectedConditions.visibilityOfElementLocated( By.xpath( "//li[.//h2[normalize-space()='Innsamlingsprosent']]//div[@class='graph']"))); - Thread.sleep(5000); + // Thread.sleep(5000); element = findElement( By.xpath("//li[.//h2[normalize-space()='Innsamlingsprosent']]//div[@class='graph']")); @@ -224,9 +224,9 @@ public void scrapeCharityPage() { updateLogo(); updateCategories(); updateKeyValues(); - Thread.sleep(1000); + // Thread.sleep(1000); - } catch (InterruptedException e) { + } catch (Exception e) { throw new RuntimeException(e); } finally { closeDriver(); From bed9fe4686640ca87ee12156f002707e48840ffd Mon Sep 17 00:00:00 2001 From: Roar Date: Fri, 17 Apr 2026 12:08:36 +0200 Subject: [PATCH 09/26] Updated charityPage.fxml Added fx:id to arc and label for key values. --- .../src/main/resources/fxml/charityPage.fxml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/helpmehelpapplication/src/main/resources/fxml/charityPage.fxml b/helpmehelpapplication/src/main/resources/fxml/charityPage.fxml index cbc9670..130f321 100644 --- a/helpmehelpapplication/src/main/resources/fxml/charityPage.fxml +++ b/helpmehelpapplication/src/main/resources/fxml/charityPage.fxml @@ -294,11 +294,11 @@ - + - - - + + - - - + + + - - + + + - - - + - - + + + + + + -