Ignore:
Timestamp:
01/13/25 14:18:51 (2 days ago)
Author:
Kristijan <kristijanzafirovski26@…>
Branches:
master
Parents:
0a7426e
Message:

Added frontend functionality for changes and refactored code

Location:
backend/GlobeGuru-backend
Files:
2 added
9 edited

Legend:

Unmodified
Added
Removed
  • backend/GlobeGuru-backend/src/main/java/DatabaseUtil.java

    r0a7426e rdf7f390  
    5353                             "price REAL," +
    5454                             "FOREIGN KEY(optionId) REFERENCES options(id))"
     55             );
     56             PreparedStatement stmt5 = conn.prepareStatement(
     57                     "CREATE TABLE IF NOT EXISTS changeLog(" +
     58                             "id INTEGER PRIMARY KEY AUTOINCREMENT," +
     59                             "detail_id INTEGER NOT NULL," +
     60                             "attribute TEXT NOT NULL," +
     61                             "oldValue TEXT," +
     62                             "newValue TEXT," +
     63                             "FOREIGN KEY(detail_id) REFERENCES optionDetails(id))"
    5564             )) {
    5665
     
    5968            stmt3.executeUpdate();
    6069            stmt4.executeUpdate();
     70            stmt5.executeUpdate();
    6171        }
    6272    }
     
    201211        }
    202212    }
    203 
    204 
    205 
    206213    public static List<Option> poolOptionDetails(int id) throws SQLException{
    207214        String sql = "SELECT * FROM optionDetails WHERE optionId = ?";
     
    283290    }
    284291    public static int saveOptionToDatabase(Option option) {
    285         String sql = "INSERT INTO options (link, imgSrc, hotelName, country, dateRange,numberOfPeople, isPriceChanged, newPrice) VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
     292        String sql = "INSERT INTO options (link, imgSrc, hotelName, country, dateRange,numberOfPeople) VALUES (?, ?, ?, ?, ?, ?)";
    286293        int id = 0;
    287294        try (Connection conn = DriverManager.getConnection("jdbc:sqlite:globe_guru.db");
     
    293300            stmt.setString(5, option.getDateRange());
    294301            stmt.setInt(6,option.getNumPeople());
    295             stmt.setBoolean(7, option.isPriceChanged());
    296             stmt.setFloat(8, option.getNewPrice());
    297302            stmt.executeUpdate();
    298303            try(ResultSet genKey = stmt.getGeneratedKeys()){
     
    331336        }
    332337    }
    333 
    334338    public static void updateOptionDetails(int detail_id, String type, String board, String amenities, float price) {
    335         String sql = "UPDATE optionDetails SET ";
    336 
    337         List<String> updates = new ArrayList<>();
    338         if (type != null && !type.isEmpty()) updates.add("type = '" + type + "'");
    339         if (board != null && !board.isEmpty()) updates.add("board = '" + board + "'");
    340         if (amenities != null && !amenities.isEmpty()) updates.add("amenities = '" + amenities + "'");
    341         updates.add("price = " + price);
    342 
    343         sql += String.join(", ", updates);
    344         sql += " WHERE id = " + detail_id;
    345 
    346         try (Connection conn = getConnection();
    347              PreparedStatement stmt = conn.prepareStatement(sql)) {
    348             stmt.executeUpdate();
     339        try (Connection conn = getConnection()) {
     340            String selectSql = "SELECT * FROM optionDetails WHERE id = ?";
     341            PreparedStatement selectStmt = conn.prepareStatement(selectSql);
     342            selectStmt.setInt(1, detail_id);
     343            ResultSet rs = selectStmt.executeQuery();
     344
     345            if (rs.next()) {
     346                String oldType = rs.getString("type");
     347                String oldBoard = rs.getString("board");
     348                String oldAmenities = rs.getString("amenities");
     349                float oldPrice = rs.getFloat("price");
     350
     351                insertChangeLog(detail_id, "type", oldType, type);
     352                insertChangeLog(detail_id, "board", oldBoard, board);
     353                insertChangeLog(detail_id, "amenities", oldAmenities, amenities);
     354                insertChangeLog(detail_id, "price", String.valueOf(oldPrice), String.valueOf(price));
     355            }
     356
     357            String sql = "UPDATE optionDetails SET ";
     358            List<String> updates = new ArrayList<>();
     359            if (type != null && !type.isEmpty()) updates.add("type = '" + type + "'");
     360            if (board != null && !board.isEmpty()) updates.add("board = '" + board + "'");
     361            if (amenities != null && !amenities.isEmpty()) updates.add("amenities = '" + amenities + "'");
     362            if (price > 0) updates.add("price = " + price);
     363
     364            sql += String.join(", ", updates);
     365            sql += " WHERE id = " + detail_id;
     366
     367            try (PreparedStatement stmt = conn.prepareStatement(sql)) {
     368                stmt.executeUpdate();
     369            }
    349370        } catch (SQLException e) {
    350371            e.printStackTrace();
    351372        }
    352373    }
    353 
    354     public static void updateOptionInDatabase(Option option) {
    355         String sql = "UPDATE options SET link = ?, imgSrc = ?, hotelName = ?, country = ?, price = ?, dateRange = ?, isPriceChanged = ?, newPrice = ? WHERE id = ?";
    356         try (Connection conn = DriverManager.getConnection("jdbc:sqlite:globe_guru.db");
    357              PreparedStatement stmt = conn.prepareStatement(sql)) {
    358             stmt.setString(1, option.getLink());
    359             stmt.setString(2, option.getImgSrc());
    360             stmt.setString(3, option.getHotelName());
    361             stmt.setString(4, option.getCountry());
    362             stmt.setFloat(5, option.getPrice());
    363             stmt.setString(6, option.getDateRange());
    364             stmt.setBoolean(7, option.isPriceChanged());
    365             stmt.setFloat(8, option.getNewPrice());
    366             stmt.setInt(9, option.getId());
    367             stmt.executeUpdate();
    368         } catch (SQLException e) {
    369             e.printStackTrace();
    370         }
    371     }
    372     public static Option findOption(Option option) {
    373         String sql = "SELECT * FROM options WHERE id = ?";
    374         try (Connection conn = DriverManager.getConnection("jdbc:sqlite:globe_guru.db");
    375              PreparedStatement stmt = conn.prepareStatement(sql)) {
    376             stmt.setInt(1, option.getId());
    377             try (ResultSet rs = stmt.executeQuery()) {
    378                 if (rs.next()) {
    379                     Option existingOption = new Option();
    380                     existingOption.setId(rs.getInt("id"));
    381                     existingOption.setLink(rs.getString("link"));
    382                     existingOption.setImgSrc(rs.getString("imgSrc"));
    383                     existingOption.setHotelName(rs.getString("hotelName"));
    384                     existingOption.setCountry(rs.getString("country"));
    385                     existingOption.setPrice(rs.getFloat("price"));
    386                     existingOption.setDateRange(rs.getString("dateRange"));
    387                     existingOption.setPriceChanged(rs.getBoolean("isPriceChanged"));
    388                     existingOption.setNewPrice(rs.getInt("newPrice"));
    389                     existingOption.setNumPeople(rs.getInt("numberOfPeople"));
    390                     return existingOption;
    391                 }
    392             }
    393         } catch (SQLException e) {
    394             e.printStackTrace();
    395         }
    396         return null;
    397     }
    398 
    399 
     374    private static void insertChangeLog(int detail_id, String attribute, String oldValue, String newValue) {
     375        if (!oldValue.equals(newValue)) {
     376            String sql = "INSERT INTO changeLog (detail_id, attribute, oldValue, newValue) VALUES (?, ?, ?, ?)";
     377            try (Connection conn = getConnection();
     378                 PreparedStatement stmt = conn.prepareStatement(sql)) {
     379                stmt.setInt(1, detail_id);
     380                stmt.setString(2, attribute);
     381                stmt.setString(3, oldValue);
     382                stmt.setString(4, newValue);
     383                stmt.executeUpdate();
     384            } catch (SQLException e) {
     385                e.printStackTrace();
     386            }
     387        }
     388    }
    400389    public static int getCurrentOptionsCount() throws SQLException {
    401390        String sql = "SELECT COUNT(*) AS optionsCount FROM options";
  • backend/GlobeGuru-backend/src/main/java/Option.java

    r0a7426e rdf7f390  
     1import java.util.ArrayList;
     2import java.util.List;
    13import java.util.Objects;
    24
     
    1214    private String board;
    1315    private String amenities;
     16    private int numPeople;
     17    private String dateRange;
     18    private List<Change> changes = new ArrayList<>();
    1419
    15     private int numPeople;
    16     //Price changing
    17     private float newPrice = 0;
    18     private boolean isPriceChanged = false;
    19     private String dateRange;
    20     // Constructor
    21     public Option(){
    22         price = 0;
     20    public String getDateRange() {
     21        return dateRange;
    2322    }
    2423
     
    3130    }
    3231
     32    public int getId() {
     33        return id;
     34    }
     35
     36    public void setId(int id) {
     37        this.id = id;
     38    }
     39
    3340    public void setDetail_id(int detail_id) {
    3441        this.detail_id = detail_id;
    35     }
    36 
    37     public String getDateRange() {
    38         return dateRange;
    3942    }
    4043
     
    6366    }
    6467
    65     public boolean isEmpty(){
    66         return (hotelName == null || country == null || link == null || imgSrc == null);
     68    public int getNumPeople() {
     69        return numPeople;
    6770    }
     71
     72    public void setNumPeople(int numPeople) {
     73        this.numPeople = numPeople;
     74    }
     75
    6876    public String getHotelName() {
    6977        return hotelName;
     
    98106    }
    99107
     108    public String getImgSrc() {
     109        return imgSrc;
     110    }
     111
    100112    public void setImgSrc(String imgSrc) {
    101113        this.imgSrc = imgSrc;
    102114    }
    103115
    104     public String getImgSrc() {
    105         return imgSrc;
     116    public void addChange(String attribute, String oldValue, String newValue) {
     117        this.changes.add(new Change(attribute, oldValue, newValue));
    106118    }
    107119
    108     public int getNumPeople() {
    109         return numPeople;
    110     }
    111 
    112     public void setNumPeople(int numPeople) {
    113         this.numPeople = numPeople;
     120    public List<Change> getChanges() {
     121        return changes;
    114122    }
    115123
    116124    @Override
    117125    public boolean equals(Object obj) {
    118         if(this==obj) return true;
    119         if(obj == null || getClass() != obj.getClass()) return false;
     126        if (this == obj) return true;
     127        if (obj == null || getClass() != obj.getClass()) return false;
    120128        Option option = (Option) obj;
    121129        return Float.compare(option.price, price) == 0
     
    127135    @Override
    128136    public int hashCode() {
    129         return Objects.hash(hotelName,country,price,link);
     137        return Objects.hash(hotelName, country, price, link);
    130138    }
    131139
    132     public int getId() {
    133         return id;
    134     }
    135 
    136     public void setId(int id) {
    137         this.id = id;
    138     }
    139 
    140     //debug
    141140    @Override
    142141    public String toString() {
    143142        return "Option{" +
    144                 "id='" + id + '\'' +
    145                 "dateRange='" + dateRange + '\'' +
    146                 "hotelName='" + hotelName + '\'' +
     143                "id=" + id +
     144                ", dateRange='" + dateRange + '\'' +
     145                ", hotelName='" + hotelName + '\'' +
    147146                ", country='" + country + '\'' +
    148                 ", price='" + price + '\'' +
     147                ", price=" + price +
    149148                ", link='" + link + '\'' +
    150                 ", image='" + imgSrc +
     149                ", imgSrc='" + imgSrc + '\'' +
     150                ", type='" + type + '\'' +
     151                ", board='" + board + '\'' +
     152                ", amenities='" + amenities + '\'' +
     153                ", numPeople=" + numPeople +
     154                ", changes=" + changes +
    151155                '}';
    152156    }
    153157
    154     public void setPriceChanged(boolean a){
    155         isPriceChanged = a;
    156     }
    157     public void setNewPrice(float a){
    158         newPrice = a;
    159     }
    160 
    161     public boolean isPriceChanged() {
    162         return isPriceChanged;
    163     }
    164 
    165     public float getNewPrice() {
    166         return newPrice;
     158    public boolean isEmpty() {
     159        return (link.isEmpty() || country.isEmpty() || hotelName.isEmpty());
    167160    }
    168161}
     162
  • backend/GlobeGuru-backend/src/main/java/Scraper.java

    r0a7426e rdf7f390  
    1414
    1515    private List<String> urls;
    16     private ConcurrentLinkedQueue<Option> optionsQueue;
    1716    private CountDownLatch latch;
    1817
    1918    public Scraper() {
    2019        urls = new ArrayList<>();
    21         this.optionsQueue = new ConcurrentLinkedQueue<>();
    2220        ObjectMapper mapper = new ObjectMapper();
    2321        try {
     
    4442        System.out.println("Scraper has started ");
    4543        for (String url : urls) {
    46             new ScraperThread(url, optionsQueue, latch).start();
     44            new ScraperThread(url, latch).start();
    4745        }
    4846        return null;
  • backend/GlobeGuru-backend/src/main/java/ScraperThread.java

    r0a7426e rdf7f390  
    2929public class ScraperThread extends Thread {
    3030    private String url;
    31     private ConcurrentLinkedQueue<Option> uniqueOptions;
    3231    private CountDownLatch latch;
    33     private Set<Option> optionSet;
    34 
    35     public ScraperThread(String url, ConcurrentLinkedQueue<Option> optionsQueue, CountDownLatch latch) {
     32
     33    public ScraperThread(String url, CountDownLatch latch) {
    3634        this.url = url;
    37         this.uniqueOptions = optionsQueue;
    3835        this.latch = latch;
    39         this.optionSet = new HashSet<>();
    4036    }
    4137
     
    8682                    for (Element div : childDivs) {
    8783                        String data = div.outerHtml();
    88                         Option option = optionParser(data,numPeople);
     84                        Option option = optionParser(data, numPeople);
    8985                        if (option != null) {
    90                             Option existingOption = DatabaseUtil.findOption(option);
    91                             if (existingOption != null) {
    92                                 if (existingOption.equals(option)) {
    93                                     option.setPriceChanged(true);
    94                                     option.setNewPrice(option.getPrice());
    95                                 }
    96                                 DatabaseUtil.updateOptionInDatabase(option);
    97                             } else if (optionSet.add(option)) {
    98                                 uniqueOptions.add(option);
    99                                 option.setId(DatabaseUtil.saveOptionToDatabase(option));
    100                                 scrapeOptionInfo(option);
    101                                 System.out.println("Parsed " + option);
    102                             }
     86                            option.setId(DatabaseUtil.saveOptionToDatabase(option));
     87                            scrapeOptionInfo(option);
     88                            System.out.println("Parsed " + option);
    10389                        }
    10490                    }
     
    115101                    for (Element div : childDivs) {
    116102                        String data = div.outerHtml();
    117                         Option newOption = optionParser(data,numPeople);
     103                        Option newOption = optionParser(data, numPeople);
    118104                        if (newOption != null) {
    119                             if (optionSet.add(newOption)) {
    120                                 uniqueOptions.add(newOption);
    121 
    122                                 newOption.setId(DatabaseUtil.saveOptionToDatabase(newOption));
    123                                 scrapeOptionInfo(newOption);
    124                                 System.out.println("Parsed " + newOption);
    125                             }
    126                         }
    127                     }
    128 
    129         } else {
     105                            newOption.setId(DatabaseUtil.saveOptionToDatabase(newOption));
     106                            scrapeOptionInfo(newOption);
     107                            System.out.println("Parsed " + newOption);
     108                        }
     109                    }
     110                } else {
    130111                    System.out.println("Parent div not found");
    131112                }
     
    134115                System.out.println("URL not recognized for parsing.");
    135116        }
     117
    136118    }
    137119    private void scrapeOptionInfo(Option option) {
  • backend/GlobeGuru-backend/target/classes/lastUpdateTime.json

    r0a7426e rdf7f390  
    11{
    2   "lastUpdateTime" : "2025-01-11T00:07:21.694581100"
     2  "lastUpdateTime" : "2025-01-13T13:53:28.872595600"
    33}
Note: See TracChangeset for help on using the changeset viewer.