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

/*
* 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);
}
}