Changeset 53bad7e for backend/GlobeGuru-backend/src/main/java
- Timestamp:
- 01/10/25 00:33:50 (6 days ago)
- Branches:
- master
- Children:
- 1c51912
- Parents:
- c164f8f
- Location:
- backend/GlobeGuru-backend/src/main/java
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
backend/GlobeGuru-backend/src/main/java/AccountHandler.java
rc164f8f r53bad7e 16 16 17 17 public class AccountHandler implements HttpHandler { 18 19 // Simple in-memory session management20 18 private static final Map<String, String> sessions = new ConcurrentHashMap<>(); 21 19 private static final String CLIENT_ID = "376204422797-s8f05nn6drmec1cko2h4kg1nk24abgc9.apps.googleusercontent.com"; -
backend/GlobeGuru-backend/src/main/java/DatabaseUtil.java
rc164f8f r53bad7e 31 31 "price REAL, " + 32 32 "dateRange TEXT, " + 33 "numberOfPeople INTEGER, " + 33 34 "isPriceChanged BOOLEAN DEFAULT 0, " + 34 35 "newPrice REAL DEFAULT 0)" … … 55 56 stmt.setString(1, username); 56 57 stmt.setString(2, email); 57 stmt.setString(3, password); // Store hashed58 stmt.setString(3, password); 58 59 return stmt.executeUpdate() > 0; 59 60 } … … 69 70 String storedPassword = rs.getString("password"); 70 71 if (password == null) { 71 // Assume this is aGoogle login72 // Google login 72 73 return storedPassword == null; 73 74 } 74 return password.equals(storedPassword); // Check hashed password75 return password.equals(storedPassword); 75 76 } 76 77 } … … 92 93 try (ResultSet rs = selectStmt.executeQuery()) { 93 94 if (rs.next()) { 94 // User exists, delete the user and their favourite options95 95 deleteStmt.setInt(1, userId); 96 96 int rowsAffected = deleteStmt.executeUpdate(); … … 101 101 return rowsAffected > 0; 102 102 } else { 103 // User does not exist104 103 return false; 105 104 } … … 135 134 } 136 135 137 public static List<Option> queryOptions(String destination, String dateQuery, boolean dateFlag) throws SQLException {136 public static List<Option> queryOptions(String destination, String dateQuery, int numPeople, boolean dateFlag) throws SQLException { 138 137 List<Option> options = new ArrayList<>(); 139 138 String sql = "SELECT * FROM options WHERE (country LIKE ? OR hotelName LIKE ?)"; … … 143 142 } //append date 144 143 if (dateFlag) { //search only from dates 145 sql += "AND dateRange LIKE ?"; 146 } 144 sql += " AND dateRange LIKE ?"; 145 } 146 if(numPeople != 0) { //with number of people 147 sql += " AND numberOfPeople = ?"; 148 } 149 147 150 System.out.println("Searching for dest:" + destination + "\n" + sql); 148 151 try (Connection conn = getConnection(); … … 156 159 stmt.setString(3, dateQuery + "%"); 157 160 } 158 // Execute query 161 if(numPeople != 0) { 162 stmt.setInt(4, numPeople); 163 } 159 164 try (ResultSet rs = stmt.executeQuery()) { 160 165 while (rs.next()) { … … 167 172 option.setPrice(rs.getFloat("price")); 168 173 option.setDateRange(rs.getString("dateRange")); 174 option.setNumPeople(rs.getInt("numberOfPeople")); 169 175 options.add(option); 170 176 } … … 185 191 } 186 192 187 //TODO add frontend 193 188 194 public static boolean removeFavoriteOption(int userId, int optionId) throws SQLException { 189 195 String sql = "DELETE FROM savedOptions WHERE userId = ? AND optionId = ?"; … … 269 275 270 276 public static void saveOptionToDatabase(Option option) { 271 String sql = "INSERT INTO options (link, imgSrc, hotelName, country, price, dateRange, isPriceChanged, newPrice) VALUES (?, ?, ?, ?, ?, ?, ?, ?)";277 String sql = "INSERT INTO options (link, imgSrc, hotelName, country, price, dateRange,numberOfPeople, isPriceChanged, newPrice) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"; 272 278 try (Connection conn = DriverManager.getConnection("jdbc:sqlite:globe_guru.db"); 273 279 PreparedStatement stmt = conn.prepareStatement(sql)) { … … 278 284 stmt.setFloat(5, option.getPrice()); 279 285 stmt.setString(6, option.getDateRange()); 280 stmt.setBoolean(7, option.isPriceChanged()); 281 stmt.setFloat(8, option.getNewPrice()); 286 stmt.setInt(7,option.getNumPeople()); 287 stmt.setBoolean(8, option.isPriceChanged()); 288 stmt.setFloat(9, option.getNewPrice()); 282 289 stmt.executeUpdate(); 283 290 } catch (SQLException e) { … … 293 300 PreparedStatement stmt = conn.prepareStatement(sql)){ 294 301 stmt.executeUpdate(); 295 //Remake the options DB296 302 initializeDatabase(); 297 303 … … 334 340 existingOption.setPriceChanged(rs.getBoolean("isPriceChanged")); 335 341 existingOption.setNewPrice(rs.getInt("newPrice")); 342 existingOption.setNumPeople(rs.getInt("numberOfPeople")); 336 343 return existingOption; 337 344 } -
backend/GlobeGuru-backend/src/main/java/FrontendHandler.java
rc164f8f r53bad7e 101 101 String departureDate = formData.get("departureDate"); 102 102 String nightsNumberStr = formData.get("nightsNumber"); 103 String numPeopleStr = formData.get("numberPeople"); 103 104 int numberOfNights = (nightsNumberStr != null && !nightsNumberStr.isEmpty()) ? Integer.parseInt(nightsNumberStr) : 0; 105 int numPeople = Integer.parseInt(numPeopleStr); 104 106 String queryDate = ""; 105 107 boolean dateFlag = false; … … 121 123 List<Option> options; 122 124 try { 123 options = DatabaseUtil.queryOptions(destination, queryDate, dateFlag);125 options = DatabaseUtil.queryOptions(destination, queryDate, numPeople, dateFlag); 124 126 } catch (SQLException e) { 125 127 e.printStackTrace(); -
backend/GlobeGuru-backend/src/main/java/Option.java
rc164f8f r53bad7e 8 8 private String link; 9 9 private String imgSrc; 10 10 private int numPeople; 11 11 //Price changing 12 12 private float newPrice = 0; … … 69 69 } 70 70 71 public int getNumPeople() { 72 return numPeople; 73 } 74 75 public void setNumPeople(int numPeople) { 76 this.numPeople = numPeople; 77 } 78 71 79 @Override 72 80 public boolean equals(Object obj) { -
backend/GlobeGuru-backend/src/main/java/ScraperThread.java
rc164f8f r53bad7e 58 58 } 59 59 60 private void connectToWeb(String queryUrl ) {60 private void connectToWeb(String queryUrl, int numPeople) { 61 61 driver.get(queryUrl); 62 62 … … 65 65 case "https://booking.escapetravel.mk/": 66 66 wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#hotels-container"))); 67 try { Thread.sleep( 5000);} catch (InterruptedException e) { e.printStackTrace(); }67 try { Thread.sleep(10000);} catch (InterruptedException e) { e.printStackTrace(); }//price fetch 68 68 break; 69 69 case "https://magelantravel.mk/": … … 82 82 83 83 switch (url) { 84 case "https://www.fibula.com.mk/":85 parentDiv = doc.selectFirst("div.flex.flex-col.gap-5");86 if (parentDiv != null) {87 childDivs = parentDiv.select("div");88 for (Element div : childDivs) {89 String data = div.html();90 Option option = optionParser(data);91 if (option != null && optionSet.add(option)) {92 uniqueOptions.add(option);93 System.out.println("Parsed " + option);94 }95 }96 } else {97 System.out.println("Parent div not found");98 }99 break;100 84 case "https://booking.escapetravel.mk/": 101 85 parentDiv = doc.selectFirst("#hotels-container"); … … 104 88 for (Element div : childDivs) { 105 89 String data = div.outerHtml(); 106 Option option = optionParser(data );90 Option option = optionParser(data,numPeople); 107 91 if (option != null) { 108 92 Option existingOption = DatabaseUtil.findOption(option); … … 133 117 for (Element div : childDivs) { 134 118 String data = div.outerHtml(); 135 Option newOption = optionParser(data );119 Option newOption = optionParser(data,numPeople); 136 120 if (newOption != null) { 137 121 Option existingOption = DatabaseUtil.findOption(newOption); … … 161 145 162 146 163 private Option optionParser(String data ) {147 private Option optionParser(String data, int numPeople) { 164 148 Document doc = Jsoup.parse(data); 165 149 Option created = new Option(); … … 167 151 case "https://magelantravel.mk/": 168 152 created = parseMagelan(doc); 153 created.setNumPeople(numPeople); 169 154 break; 170 155 case "https://booking.escapetravel.mk/": 171 156 created = parseEscapeTravel(doc); 157 created.setNumPeople(numPeople); 172 158 break; 173 159 default: … … 210 196 created.setHotelName(card.attr("data-title")); 211 197 Element countryP = doc.selectFirst("p.text-info"); 212 created.setCountry(countryP != null ? countryP.text() : null); 198 String country = countryP.text().replaceAll("leto hoteli", ""); 199 created.setCountry(country); 213 200 Element priceElem = doc.selectFirst("span.hotel-price"); 214 201 String priceText = priceElem.text(); … … 267 254 String country = countryNode.asText(); 268 255 for (int nokevanja = 2; nokevanja <= 10; nokevanja++) { 269 String queryUrl = url + "/destinacii?ah_tip=1&iframe=&affiliate_code=&carter_id=0&carter_region=&carter_dataod=&carter_datado=&destinacija=" + country + "&oddatum=" + date + "&nokevanja=" + nokevanja + "&dodatum=&broj_vozrasni=2&broj_deca=0&spdete1=0&spdete2=0&spdete3=0&spdete4=0"; 270 connectToWeb(queryUrl); 256 for(int lugje = 1; lugje <= 4; lugje++) { 257 String queryUrl = url + "/destinacii?ah_tip=1&iframe=&affiliate_code=&carter_id=0&carter_region=&carter_dataod=&carter_datado=&destinacija=" + country + "&oddatum=" + date + "&nokevanja=" + nokevanja + "&dodatum=&broj_vozrasni=" + lugje + "&broj_deca=0&spdete1=0&spdete2=0&spdete3=0&spdete4=0"; 258 connectToWeb(queryUrl,lugje); 259 } 271 260 } 272 261 } … … 282 271 ClassLoader classLoader = getClass().getClassLoader(); 283 272 JsonNode root = mapper.readTree(new File(classLoader.getResource("CountriesList.json").getFile())); 284 JsonNode countries = root.get("countries"); // Assuming "destinations" key in JSON273 JsonNode countries = root.get("countries"); 285 274 SimpleDateFormat dateFormat = new SimpleDateFormat("dd.MM.yyyy"); 286 275 Calendar calendar = Calendar.getInstance(); … … 292 281 String country = countryNode.asText(); 293 282 for(int nokevanja = 2; nokevanja <=10; nokevanja ++) { 294 String queryUrl = url + "/hotels?Search=" + country + "&Date=" + date + "&Nights=" + nokevanja + "&Rooms=1&Adults=2"; 295 connectToWeb(queryUrl); 283 for(int lugje = 1; lugje <= 4; lugje++) { 284 String queryUrl = url + "/hotels?Search=" + country + "&Date=" + date + "&Nights=" + nokevanja + "&Rooms=1&Adults=" + lugje; 285 connectToWeb(queryUrl,lugje); 286 } 296 287 } 297 288 } -
backend/GlobeGuru-backend/src/main/java/Server.java
rc164f8f r53bad7e 28 28 import java.time.LocalDateTime; 29 29 import java.time.format.DateTimeFormatter; 30 import java.time.temporal.ChronoUnit; 30 31 import java.util.*; 31 32 import java.util.concurrent.ExecutorService; … … 34 35 35 36 public class Server { 36 37 private static final ExecutorService executorService = Executors.newFixedThreadPool(1); 37 38 public static void main(String[] args) throws IOException, SQLException { 38 39 // Start HTTP server … … 57 58 58 59 server.start(); 59 60 60 System.out.println("Server started on port 8000"); 61 62 LocalDateTime lastUpdateTime = getLastUpdateTime(); 63 LocalDateTime now = LocalDateTime.now(); 64 if (ChronoUnit.MONTHS.between(lastUpdateTime, now) >= 3) { 65 System.out.println("Automatic Update"); 66 Future<Void> future = executorService.submit(new Scraper()); 67 Server.updateLastUpdateTime(); 68 executorService.submit(() -> { 69 try { 70 future.get(); 71 } catch (Exception e) { 72 e.printStackTrace(); 73 } 74 }); 75 76 } 77 61 78 } 62 79 static class RemoveFromSavedTripsHandler implements HttpHandler {
Note:
See TracChangeset
for help on using the changeset viewer.