Skip to content

Commit

Permalink
feat: added methods to get organization logos from API
Browse files Browse the repository at this point in the history
  • Loading branch information
MatheaGjerde committed Mar 24, 2026
1 parent f148875 commit 632bdcb
Showing 1 changed file with 91 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -1,15 +1,28 @@
package edu.group5.app.model.organization;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

/**
* Service class for managing organization-related operations.
* It interacts with the OrganizationRepository to retrieve organization information
* and contains business logic associated with organization management.
*
* <P>It provides fetching logo URLs by web scraping each organization's page on
* Innsamlingskontrollen.</P>
*
* Fetched logo URLs are cached to avoid redundant network requests.
*/
public class OrganizationService {
private OrganizationRepository organizationRepository;

private final Map<String, String> logoCache = new HashMap<>();

/**
* Constructs an OrganizationService with the given OrganizationRepository.
* @param organizationRepository the OrganizationRepository to use for managing organization data; must not be null
Expand Down Expand Up @@ -55,4 +68,82 @@ public Organization findByOrgNumber(int orgNumber) {
public Organization findByOrgName(String name) {
return organizationRepository.findByOrgName(name);
}

/**
* Fetches the logo URL for the given page by scraping the {@code div.logo img}
* element. Results are cached so each URL is only fetched once.
*
* <P>
* Using Jsoup to web scrape through the URLs in the API.
* </P>
* @param pageUrl the URL for the organization's page; may be null or blank
* @return the absolute logo URL, or null if not found or pageUrl is invalid
*/

public String fetchLogoUrl(String pageUrl) {
if (pageUrl == null || pageUrl.isBlank()) {
return null;
}

if (logoCache.containsKey(pageUrl)) {
return logoCache.get(pageUrl);
}

try {
Document doc = Jsoup.connect(pageUrl).get();
Element img = doc.selectFirst("div.logo img");

if (img != null) {
String logoUrl = img.absUrl("src");
logoCache.put(pageUrl, logoUrl);
return logoUrl;
}
} catch (Exception e) {
System.out.println("Could not get logo for: " + pageUrl);
}
return null;
}

/**
* Fetches all trusted organizations with their logo URLs.
*
* <p>
* For each trusted organization, attempts to get its logo using
* {@link #fetchLogoUrl(String)}. Creates a new Organization
* object including the logo URL.
* </p>
* @return a map of trusted organizations keyed by organization number, with logos included
*/
public Map<Integer, Organization> getTrustedOrganizationsWithLogos() {
Map<Integer, Organization> original = getTrustedOrganizations();
Map<Integer, Organization> trustedOrgsWithLogos = new HashMap<>();

for (Organization org : original.values()) {
String logoUrl = fetchLogoUrl(org.websiteUrl());

Organization newOrg = new Organization(
org.orgNumber(),
org.name(),
org.trusted(),
org.websiteUrl(),
org.isPreApproved(),
org.description(),
logoUrl
);
trustedOrgsWithLogos.put(newOrg.orgNumber(), newOrg);
}
return trustedOrgsWithLogos;
}

/**
* Asynchronously fetches trusted organizations with logos.
*
* <p>Runs in the background so the UI thread is no blocked.
* Returns a CompletableFuture that completes when all logos are loaded.</p>
*
* @return a CompletableFuture containing a map of organizations with logos
*/
public CompletableFuture<Map<Integer, Organization>> getTrustedOrganizationsWithLogosAsync() {
return CompletableFuture.supplyAsync(this::getTrustedOrganizationsWithLogos);
}
}

0 comments on commit 632bdcb

Please sign in to comment.