|
@@ -0,0 +1,172 @@
|
|
|
|
|
+package Parsers;
|
|
|
|
|
+
|
|
|
|
|
+import java.sql.Connection;
|
|
|
|
|
+import java.sql.DriverManager;
|
|
|
|
|
+import java.sql.PreparedStatement;
|
|
|
|
|
+import java.sql.ResultSet;
|
|
|
|
|
+import java.sql.SQLException;
|
|
|
|
|
+import java.util.Collections;
|
|
|
|
|
+import java.util.Properties;
|
|
|
|
|
+
|
|
|
|
|
+import javax.mail.Message;
|
|
|
|
|
+import javax.mail.MessagingException;
|
|
|
|
|
+import javax.mail.PasswordAuthentication;
|
|
|
|
|
+import javax.mail.Session;
|
|
|
|
|
+import javax.mail.Transport;
|
|
|
|
|
+import javax.mail.internet.InternetAddress;
|
|
|
|
|
+import javax.mail.internet.MimeMessage;
|
|
|
|
|
+
|
|
|
|
|
+import org.openqa.selenium.WebDriver;
|
|
|
|
|
+import org.openqa.selenium.chrome.ChromeDriver;
|
|
|
|
|
+import org.openqa.selenium.chrome.ChromeOptions;
|
|
|
|
|
+
|
|
|
|
|
+import Objects.Product;
|
|
|
|
|
+
|
|
|
|
|
+public class ParserBase {
|
|
|
|
|
+ private static final String USERNAME = "storeParser";
|
|
|
|
|
+ private static final String PASSWORD = "Rd0.mw4YVY6LLosq";
|
|
|
|
|
+ private static final String DATABASE = "StoreParser";
|
|
|
|
|
+ private static final String URL = "jdbc:mysql://nordh.xyz:3306/";
|
|
|
|
|
+
|
|
|
|
|
+ Connection conn;
|
|
|
|
|
+
|
|
|
|
|
+ private void openDbConnection() {
|
|
|
|
|
+ if (conn == null) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ conn = DriverManager.getConnection(URL + DATABASE, USERNAME, PASSWORD);
|
|
|
|
|
+ } catch (final SQLException e) {
|
|
|
|
|
+ throw new RuntimeException(e.getMessage(), e);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private void closeDbConnection() {
|
|
|
|
|
+ try {
|
|
|
|
|
+ conn.close();
|
|
|
|
|
+ } catch (SQLException e) {
|
|
|
|
|
+ // TODO Auto-generated catch block
|
|
|
|
|
+ e.printStackTrace();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public void insertProduct(Product product) {
|
|
|
|
|
+ openDbConnection();
|
|
|
|
|
+ String sql = "INSERT INTO Product (storeName, productName, price, updated) VALUE (?,?,?,?) ON DUPLICATE KEY UPDATE price = ?, updated = ?";
|
|
|
|
|
+ try (PreparedStatement stat = conn.prepareStatement(sql)) {
|
|
|
|
|
+ stat.setString(1, product.getStore());
|
|
|
|
|
+ stat.setString(2, product.getName());
|
|
|
|
|
+ stat.setFloat(3, product.getPrice());
|
|
|
|
|
+ stat.setString(4, product.getUpdatedDate());
|
|
|
|
|
+ stat.setFloat(5, product.getPrice());
|
|
|
|
|
+ stat.setString(6, product.getUpdatedDate());
|
|
|
|
|
+
|
|
|
|
|
+ stat.execute();
|
|
|
|
|
+
|
|
|
|
|
+ sendUpdatedPriceMail(product);
|
|
|
|
|
+
|
|
|
|
|
+ } catch (SQLException e) {
|
|
|
|
|
+ e.printStackTrace();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public void sendUpdatedPriceMail(Product product) {
|
|
|
|
|
+ String to = "axelnordh@gmail.com";
|
|
|
|
|
+ String from = "axelnordh@gmail.com";
|
|
|
|
|
+ String host = "smtp.gmail.com";
|
|
|
|
|
+ Properties properties = System.getProperties();
|
|
|
|
|
+
|
|
|
|
|
+ properties.put("mail.smtp.host", host);
|
|
|
|
|
+ String port = "465";
|
|
|
|
|
+ properties.put("mail.smtp.port", port);
|
|
|
|
|
+ properties.put("mail.smtp.ssl.enable", "true");
|
|
|
|
|
+ properties.put("mail.smtp.auth", "true");
|
|
|
|
|
+
|
|
|
|
|
+ properties.put("mail.smtp.starttls.enable", "true");
|
|
|
|
|
+ properties.put("mail.smtp.socketFactory.port", port);
|
|
|
|
|
+ properties.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
|
|
|
|
|
+ properties.put("mail.smtp.ssl.checkserveridentity", "true");
|
|
|
|
|
+ properties.put("mail.smtp.socketFactory.fallback", "false");
|
|
|
|
|
+
|
|
|
|
|
+ Session session = Session.getInstance(properties, new javax.mail.Authenticator() {
|
|
|
|
|
+ @Override protected PasswordAuthentication getPasswordAuthentication() {
|
|
|
|
|
+ return new PasswordAuthentication(from, "fprgcnbbhbwiwdmi");
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ session.setDebug(true);
|
|
|
|
|
+ try {
|
|
|
|
|
+ MimeMessage message = new MimeMessage(session);
|
|
|
|
|
+
|
|
|
|
|
+ message.setFrom(from);
|
|
|
|
|
+ message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
|
|
|
|
|
+ message.setSubject("Nytt bättre pris från " + product.getStore());
|
|
|
|
|
+ message.setText(String.format("%s fick ett bättre pris från %s, nya priset är %s (%s)", product.getName(),
|
|
|
|
|
+ product.getStore(), product.getPrice(), product.getUpdatedDate()));
|
|
|
|
|
+
|
|
|
|
|
+ Transport transport = session.getTransport("smtps");
|
|
|
|
|
+ transport.connect(host, Integer.valueOf(port), from, "fprgcnbbhbwiwdmi");
|
|
|
|
|
+ transport.sendMessage(message, message.getAllRecipients());
|
|
|
|
|
+ transport.close();
|
|
|
|
|
+ } catch (MessagingException e) {
|
|
|
|
|
+ e.printStackTrace();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public float getStoredProductPrice(Product product) {
|
|
|
|
|
+ openDbConnection();
|
|
|
|
|
+ String sql = "SELECT price FROM Product WHERE productName = ? AND storeName = ?";
|
|
|
|
|
+
|
|
|
|
|
+ float result = -1;
|
|
|
|
|
+
|
|
|
|
|
+ try (PreparedStatement stat = conn.prepareStatement(sql)) {
|
|
|
|
|
+ stat.setString(1, product.getName());
|
|
|
|
|
+ stat.setString(2, product.getStore());
|
|
|
|
|
+
|
|
|
|
|
+ ResultSet rs = stat.executeQuery();
|
|
|
|
|
+
|
|
|
|
|
+ while (rs.next()) {
|
|
|
|
|
+ result = rs.getFloat("price");
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (SQLException e) {
|
|
|
|
|
+ e.printStackTrace();
|
|
|
|
|
+ }
|
|
|
|
|
+ return result;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ protected ChromeDriver getSeleniumDriver() {
|
|
|
|
|
+ ChromeOptions options = new ChromeOptions();
|
|
|
|
|
+
|
|
|
|
|
+ System.setProperty("webdriver.chrome.driver", System.getProperty("user.dir") + "/src/main/resources/chromedriver.exe");
|
|
|
|
|
+ System.setProperty("webdriver.chrome.silentOutput", "true");
|
|
|
|
|
+ // Fixing 255 Error crashes
|
|
|
|
|
+ options.addArguments("--no-sandbox");
|
|
|
|
|
+ options.addArguments("--disable-dev-shm-usage");
|
|
|
|
|
+
|
|
|
|
|
+ // Options to trick bot detection
|
|
|
|
|
+ // Removing webdriver property
|
|
|
|
|
+ options.addArguments("--disable-blink-features=AutomationControlled");
|
|
|
|
|
+ options.setExperimentalOption("excludeSwitches", Collections.singletonList("enable-automation"));
|
|
|
|
|
+ options.setExperimentalOption("useAutomationExtension", null);
|
|
|
|
|
+
|
|
|
|
|
+ // Changing the user agent / browser fingerprint
|
|
|
|
|
+ options.addArguments("window-size=1920,1080");
|
|
|
|
|
+ options.addArguments(
|
|
|
|
|
+ "user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36");
|
|
|
|
|
+
|
|
|
|
|
+ // Other
|
|
|
|
|
+ options.addArguments("disable-infobars");
|
|
|
|
|
+
|
|
|
|
|
+ ChromeDriver driver = new ChromeDriver(options);
|
|
|
|
|
+ driver.executeScript("Object.defineProperty(navigator, 'webdriver', {get: () => undefined})");
|
|
|
|
|
+ return driver;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ protected void closeDriver(WebDriver driver) {
|
|
|
|
|
+ driver.close();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public float formatPrice(String priceValueString) {
|
|
|
|
|
+ return Float.valueOf(priceValueString.replaceAll("[^\\d.]", ""));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+}
|