You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
362 lines
14 KiB
362 lines
14 KiB
/*
|
|
* 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<String> urlList;
|
|
private static Boolean isErrorMode = false;
|
|
|
|
private static ArrayList<String> urlListInternesParcourir = new ArrayList<String>();
|
|
private static ArrayList<String> urlListParcourus = new ArrayList<String>();
|
|
|
|
private static ArrayList<String> urlListIndexed = new ArrayList<String>();
|
|
private static ArrayList<Integer> compteurPointsIndexed = new ArrayList<Integer>();
|
|
|
|
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<String> 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);
|
|
}
|
|
|
|
}
|
|
|