/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package robotindex; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.MalformedURLException; import java.net.URL; import java.sql.*; import java.util.ArrayList; import java.util.List; /** * * @author arthurdambrine */ public class RobotIndex implements Runnable { private static int PORT = 8080; // Port par défaut pour le HTTP notification server private static List urlList; private static Boolean isErrorMode = false; private static ArrayList urlListInternesParcourir = new ArrayList(); private static ArrayList urlListParcourus = new ArrayList(); private static ArrayList urlListIndexed = new ArrayList(); private static ArrayList compteurPointsIndexed = new ArrayList(); private static MessageListener messageListener; public void setMessageListener(MessageListener messageListener) { RobotIndex.messageListener = messageListener; } /** * @param args the command line arguments * @throws java.net.MalformedURLException */ public static void main(String[] args) throws IOException, InterruptedException { String urlDepart; // variable qui viendra acceuillr l'URL en entrée de notre programme int nbIterations; // nombre de pages à parcourir dans le site Web if (args.length < 2) { System.out.println("Pas assez d'argument en entrée, demande URL + Nb iterations"); // Par defaut notre programme va tester le site https://art-dambrine.ovh sur une base de 10 pages à tester. urlDepart = "https://art-dambrine.ovh"; nbIterations = 10; // Si on donne uniquement une URl en premier paramètre le programme l'accepte et fera le test sur une base de 10 pages à tester. if (args.length == 1) { urlDepart = args[0]; } } else { /* Si tous les arguments sont donnés en entrée on prepare le programme avec : - urlDepart - nbIterations */ urlDepart = args[0]; nbIterations = Integer.parseInt(args[1]); if (args.length == 3) { // Si le troisième argument est donné en entrée port de notification pour le HTTP notification server PORT = Integer.parseInt(args[2]); } // Verifications légères sur l'URL donnée en paramètre // NOTE: si le site n'accepte pas le robot ou n'est pas un site valide alors le robot va s'arrêter à la première itération if (!args[0].startsWith("http")) { System.out.println("N'est pas une url valide"); return; } if (!args[0].contains("//")) { System.out.println("N'est pas une url valide"); return; } if (!args[0].contains(".")) { System.out.println("N'est pas une url valide"); return; } } // Creation d'un thread dedié pour le server HTTP notificaton RobotIndex myServer = new RobotIndex(); Thread thread = new Thread(myServer); thread.start(); // Preparation du parcours de la première page du site Web URL siteUrl = new URL(nettoyerURL(urlDepart)); urlListParcourus.add(urlDepart); urlList = fullUrlList(siteUrl.toString()); messageListener.newMessage("{\"message\":\"" + "Analyse premiere page" + "\"}"); // on va ici parcourir la première page du site web if (!isErrorMode) { URL formatUrl = null; System.out.println(" === Sites à indexer dans notre base\n\n"); for (String url : urlList) { formatUrl = new URL(url); if (!formatUrl.getHost().equals(siteUrl.getHost())) { // Indexer dans la liste urlListIndexed if (!urlListIndexed.contains(formatUrl.getHost())) { System.out.println("Adding: " + formatUrl.getHost()); urlListIndexed.add(formatUrl.getHost()); compteurPointsIndexed.add(1); } else { int getIndex = urlListIndexed.indexOf(formatUrl.getHost()); compteurPointsIndexed.set(getIndex, compteurPointsIndexed.get(getIndex) + 1); } } } System.out.println("\n\n === Liens à parcourir \n\n"); for (String url : urlList) { // Préparation pour parcourir les URL internes if (url.endsWith("/")) { formatUrl = new URL(url.substring(0, url.length() - 1)); } else { formatUrl = new URL(url); } if (formatUrl.getHost().equals(siteUrl.getHost())) { if (siteUrl.getHost().equals(formatUrl.getHost())) { if (isValidInterne(formatUrl.toString())) { // Liens valides internes à parcourir: System.out.println(formatUrl); urlListInternesParcourir.add(formatUrl.toString()); } } } } } // fin de parcours de la promière page du site web int cpt = 0; String lienCourant; if (!urlListInternesParcourir.isEmpty()) { // On demarre ici la boucle principale de parcours while (cpt < nbIterations) { float progression = ((float) cpt / (float) nbIterations) * 100; messageListener.newMessage("{\"message\":\"" + "Iteration page numero " + cpt + "\", \"progression\" : \"" + (int) progression + "\"}"); System.out.println("\n\n\n ++++ Lien parcouru pour cette iteration :" + urlListInternesParcourir.get(0) + "\n"); System.out.println("• urlListInternesParcourir :"); for (int i = 0; i < urlListInternesParcourir.size(); i++) { System.out.println("-> " + urlListInternesParcourir.get(i)); } lienCourant = urlListInternesParcourir.get(0); urlListParcourus.add(urlListInternesParcourir.get(0)); siteUrl = new URL(urlListInternesParcourir.get(0)); urlListInternesParcourir.remove(0); urlList = fullUrlList(siteUrl.toString()); if (!isErrorMode) { URL formatUrl = null; System.out.println("\n === Sites à indexer dans notre base\n"); for (String url : urlList) { formatUrl = new URL(url); if (!formatUrl.getHost().equals(siteUrl.getHost())) { // Indexer dans la liste urlListIndexed if (!urlListIndexed.contains(formatUrl.getHost())) { System.out.println("Adding: " + formatUrl.getHost()); urlListIndexed.add(formatUrl.getHost()); compteurPointsIndexed.add(1); } else { int getIndex = urlListIndexed.indexOf(formatUrl.getHost()); compteurPointsIndexed.set(getIndex, compteurPointsIndexed.get(getIndex) + 1); } } } for (String url : urlList) { // Préparation pour parcourir les URL internes if (url.endsWith("/")) { formatUrl = new URL(url.substring(0, url.length() - 1)); } else { formatUrl = new URL(url); } if (formatUrl.getHost().equals(siteUrl.getHost())) { if (siteUrl.getHost().equals(formatUrl.getHost())) { if (isValidInterne(formatUrl.toString())) { // Liens valides internes à parcourir: if (!formatUrl.toString().equals(lienCourant)) { // NE PAS AJOUTER LIEN EN COURS if (!urlListInternesParcourir.contains(formatUrl.toString())) { // NON CONTENU DEDEANS if (!urlListParcourus.contains(formatUrl.toString())) { // Ajout d'un lien dans la liste à parcourir après verifications. urlListInternesParcourir.add(formatUrl.toString()); } } } } } } } } if (urlListInternesParcourir.isEmpty()) { // Si la liste des url à parcourir est vide on sort de la boucle principale break; } cpt++; } // fin de la boucle while principale } // Affichage de tous les scores messageListener.newMessage("{\"message\":\"" + "SQL insert" + "\", \"progression\" : \"" + 100 + "\"}"); System.out.println("\n\n == Printing all scores : =="); for (int i = 0; i < urlListIndexed.size(); i++) { System.out.println("N°" + i + " " + urlListIndexed.get(i) + " scored : " + compteurPointsIndexed.get(i)); } // Conexion à MYSQL et envoi des resultats try { Class.forName("com.mysql.cj.jdbc.Driver"); // Connexion à la base de donnée try ( Connection con = DriverManager.getConnection( "jdbc:mysql://DATABASE_URL:3306/DATABASE_NAME", "USERNAME", "PASSWORD")) { Statement stmt = con.createStatement(); // INSERTION de la donnée SITE stmt.execute("INSERT INTO SITE VALUES ('" + urlDepart + "', NOW()) ON DUPLICATE KEY UPDATE creation_date = NOW();"); for (int i = 0; i < urlListIndexed.size(); i++) { // Insertion des données LINK stmt.execute("INSERT INTO LINK VALUES('" + urlListIndexed.get(i) + "'," + compteurPointsIndexed.get(i) + ",'" + urlDepart + "')ON DUPLICATE KEY UPDATE score = " + compteurPointsIndexed.get(i) + ";"); } } } catch (ClassNotFoundException | SQLException e) { System.out.println(e); } // Ordonne au serveur HTTP de se preparer à se fermer à la prochaine requête messageListener.newMessage("{\"message\":\"" + "finish" + "\", \"progression\" : \"" + 100 + "\"}"); // Envoie un requête GET qui va fermer le serveur en le faisant sortir de sa boucle d'écoute siteUrl = new URL(nettoyerURL("http://localhost:" + PORT)); urlList = fullUrlList(siteUrl.toString()); } public static List fullUrlList(String siteUrl) throws MalformedURLException, IOException { // Cette methode retourne l'ensemble des Url de la page en appellant le parser URL url = new URL(siteUrl); UrlParser parser = new UrlParser(url); BufferedReader br = null; try { br = new BufferedReader(new InputStreamReader(url.openStream())); } catch (IOException iOException) { System.out.println("ERROR: " + iOException.getMessage() + "\n\n"); isErrorMode = true; } String line; if (br != null) { try { while ((line = br.readLine()) != null) { parser.parseLine(line); } } catch (IOException e) { // Affiche l'exception System.out.println(e); } finally { if (br != null) { br.close(); } } } return parser.getFullUrlList(); } public static String nettoyerURL(String URLentry) { // Retire le / à la fin de l'URL donnée if (URLentry.endsWith("/")) { URLentry = URLentry.substring(0, URLentry.length() - 1); } System.out.println("URL de départ: " + URLentry + "\n\n"); return URLentry; } public static Boolean isValidInterne(String formatUrl) { // Permet d'exclure les fichiers contenant les extensions suivantes exemple: https://art-dambrine.ovh/mon-image.png if (formatUrl.endsWith(".png") == false && formatUrl.endsWith(".js") == false && formatUrl.endsWith(".svg") == false && formatUrl.endsWith(".css") == false && formatUrl.endsWith(".ico") == false && formatUrl.endsWith(".jpg") == false && formatUrl.endsWith("#") == false) { return true; } else { return false; } } @Override public void run() { // Lancement du thread server JsonNotificationHTTPServer.startNotificationServer(PORT); } }