commit
72f422f4c2
10 changed files with 798 additions and 0 deletions
Binary file not shown.
@ -0,0 +1,207 @@ |
|||||
|
/* |
||||
|
* 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.BufferedOutputStream; |
||||
|
import java.io.BufferedReader; |
||||
|
import java.io.FileNotFoundException; |
||||
|
import java.io.IOException; |
||||
|
import java.io.InputStreamReader; |
||||
|
import java.io.OutputStream; |
||||
|
import java.io.PrintWriter; |
||||
|
import java.net.ServerSocket; |
||||
|
import java.net.Socket; |
||||
|
import java.util.Date; |
||||
|
import java.util.StringTokenizer; |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @author arthurdambrine |
||||
|
*/ |
||||
|
public class JsonNotificationHTTPServer implements Runnable { |
||||
|
|
||||
|
// keepRunning
|
||||
|
static boolean keepRunning = true; // nous permettra de signaliser au serveur que c'est sa dernière itération d'écoute
|
||||
|
static String messageToJson = ""; // message qui sera communiqué en JSON à travers HTTP
|
||||
|
|
||||
|
// mode verbose - pour debug
|
||||
|
static final boolean verbose = true; |
||||
|
|
||||
|
// Connexion client via la classe de Socket
|
||||
|
private Socket connect; |
||||
|
|
||||
|
public JsonNotificationHTTPServer(Socket c) { |
||||
|
connect = c; |
||||
|
} |
||||
|
|
||||
|
public static void startNotificationServer(int PORT) { |
||||
|
|
||||
|
RobotIndex robotIndex = new RobotIndex(); |
||||
|
robotIndex.setMessageListener(new MessageListener() { |
||||
|
@Override |
||||
|
public void newMessage(String message) { |
||||
|
messageToJson = message; |
||||
|
System.out.println("De HTTPServer - message reçu du robot : " + message); |
||||
|
if (message.contains("\"message\":\"finish\"")) { |
||||
|
System.out.println("Dernière iteration d'écoute - envoyer une req HTTP pour terminer le thread"); |
||||
|
keepRunning = false; |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
try { |
||||
|
ServerSocket serverConnect = new ServerSocket(PORT); |
||||
|
System.out.println("Server lancé.\nEn ecoute sur le port : " + PORT + " ...\n"); |
||||
|
|
||||
|
// On écoute jusqu'à ce que la demande de fermetture soit envoyée
|
||||
|
while (keepRunning) { |
||||
|
JsonNotificationHTTPServer myServer = new JsonNotificationHTTPServer(serverConnect.accept()); |
||||
|
|
||||
|
if (verbose) { |
||||
|
System.out.println("Connexion ouverte. (" + new Date() + ")"); |
||||
|
} |
||||
|
|
||||
|
// Creation d'un thread dedié pour les connexions client
|
||||
|
Thread thread = new Thread(myServer); |
||||
|
thread.start(); |
||||
|
} |
||||
|
|
||||
|
} catch (IOException e) { |
||||
|
System.err.println("Erreur connexion server : " + e.getMessage()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void run() { |
||||
|
|
||||
|
// nous gérons notre connexion client
|
||||
|
BufferedReader in = null; |
||||
|
PrintWriter out = null; |
||||
|
BufferedOutputStream dataOut = null; |
||||
|
String fileRequested = null; |
||||
|
|
||||
|
try { |
||||
|
// nous lisons les caractères du client via le flux d'entrée sur le socket
|
||||
|
in = new BufferedReader(new InputStreamReader(connect.getInputStream())); |
||||
|
// nous obtenons le flux de sortie des caractères vers le client (pour les en-têtes)
|
||||
|
out = new PrintWriter(connect.getOutputStream()); |
||||
|
// obtenir le flux de sortie binaire vers le client (pour les données demandées)
|
||||
|
dataOut = new BufferedOutputStream(connect.getOutputStream()); |
||||
|
|
||||
|
// obtenir la première ligne de la request client
|
||||
|
String input = in.readLine(); |
||||
|
// on parse la requête HTTP avec un StringTokenizer
|
||||
|
StringTokenizer parse = new StringTokenizer(input); |
||||
|
String method = parse.nextToken().toUpperCase(); // on obtient la méthode HTTP du client (GET, POST ..)
|
||||
|
// on obtient la requete - fichier demandé
|
||||
|
fileRequested = parse.nextToken().toLowerCase(); |
||||
|
|
||||
|
// on ne prend en charge que les méthodes GET et HEAD, vérification
|
||||
|
if (!method.equals("GET") && !method.equals("HEAD")) { |
||||
|
if (verbose) { |
||||
|
System.out.println("501 Not Implemented : " + method + " method."); |
||||
|
} |
||||
|
|
||||
|
// fichier non pris en charge - on renvoie une erreur 501
|
||||
|
String file = "{\"message\":\"501\"}"; |
||||
|
int fileLength = (int) file.length(); |
||||
|
String contentMimeType = "application/json"; |
||||
|
//lecture des données à retourner au client
|
||||
|
byte[] fileData = file.getBytes(); |
||||
|
|
||||
|
// on envoie le HTTP header avec données au client
|
||||
|
out.println("HTTP/1.1 501 Not Implemented"); |
||||
|
out.println("Server: Java HTTP Server from robot : 1.0"); |
||||
|
out.println("Date: " + new Date()); |
||||
|
out.println("Content-type: " + contentMimeType); |
||||
|
out.println("Content-length: " + fileLength); |
||||
|
out.println(); // ligne d'espace entre le header et le contenu, très important
|
||||
|
out.flush(); // vidage du tampon de flux de sortie des caractères
|
||||
|
// file
|
||||
|
dataOut.write(fileData, 0, fileLength); |
||||
|
dataOut.flush(); |
||||
|
|
||||
|
} else { |
||||
|
// GET or HEAD method
|
||||
|
|
||||
|
String file = messageToJson; |
||||
|
int fileLength = (int) file.length(); |
||||
|
String content = "application/json"; |
||||
|
|
||||
|
if (method.equals("GET")) { // GET method on envoie le contenu
|
||||
|
byte[] fileData = file.getBytes(); |
||||
|
|
||||
|
// send HTTP Headers
|
||||
|
out.println("HTTP/1.1 200 OK"); |
||||
|
out.println("Server: Java HTTP Server from robot : 1.0"); |
||||
|
out.println("Date: " + new Date()); |
||||
|
out.println("Content-type: " + content); |
||||
|
out.println("Content-length: " + fileLength); |
||||
|
out.println(); // ligne d'espace entre le header et le contenu, très important
|
||||
|
out.flush(); // vidage du tampon de flux de sortie des caractères
|
||||
|
|
||||
|
dataOut.write(fileData, 0, fileLength); |
||||
|
dataOut.flush(); |
||||
|
} |
||||
|
|
||||
|
if (verbose) { |
||||
|
System.out.println("File " + fileRequested + " of type " + content + " returned"); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
} catch (FileNotFoundException fnfe) { |
||||
|
try { |
||||
|
fileNotFound(out, dataOut, fileRequested); |
||||
|
} catch (IOException ioe) { |
||||
|
System.err.println("Error with file not found exception : " + ioe.getMessage()); |
||||
|
} |
||||
|
|
||||
|
} catch (IOException ioe) { |
||||
|
System.err.println("Server error : " + ioe); |
||||
|
} finally { |
||||
|
try { |
||||
|
in.close(); |
||||
|
out.close(); |
||||
|
dataOut.close(); |
||||
|
connect.close(); // Fermeture de la connexion socket avec le client
|
||||
|
} catch (Exception e) { |
||||
|
System.err.println("Error closing stream : " + e.getMessage()); |
||||
|
} |
||||
|
|
||||
|
if (verbose) { |
||||
|
System.out.println("Connection closed.\n"); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
private void fileNotFound(PrintWriter out, OutputStream dataOut, String fileRequested) throws IOException { |
||||
|
|
||||
|
// En renvoie une erreur 404 au client
|
||||
|
String file = "{\"message\":\"404\"}"; |
||||
|
int fileLength = (int) file.length(); |
||||
|
String content = "application/json"; |
||||
|
//lecture des données à retourner au client
|
||||
|
byte[] fileData = file.getBytes(); |
||||
|
|
||||
|
out.println("HTTP/1.1 404 File Not Found"); |
||||
|
out.println("Server: Java HTTP Server from robot : 1.0"); |
||||
|
out.println("Date: " + new Date()); |
||||
|
out.println("Content-type: " + content); |
||||
|
out.println("Content-length: " + fileLength); |
||||
|
out.println(); // ligne d'espace entre le header et le contenu, très important
|
||||
|
out.flush(); // vidage du tampon de flux de sortie des caractères
|
||||
|
|
||||
|
dataOut.write(fileData, 0, fileLength); |
||||
|
dataOut.flush(); |
||||
|
|
||||
|
if (verbose) { |
||||
|
System.out.println("File " + fileRequested + " not found"); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,14 @@ |
|||||
|
/* |
||||
|
* 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; |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @author arthurdambrine |
||||
|
*/ |
||||
|
public interface MessageListener { |
||||
|
public void newMessage(String message); |
||||
|
} |
@ -0,0 +1,33 @@ |
|||||
|
# Voici comment installer/utiliser le programme JAVA : |
||||
|
|
||||
|
NOTE : Vous trouverez dans le dossier dist une version compilée sans les accès à la base de donnée, |
||||
|
cepedant vous pouvez recompiler le projet chez vous pour y ajouter les accès à votre base. |
||||
|
|
||||
|
## 1/ Recuperer le .jar dans le dossier dist et le connecteur mysql .jar dans lib_to_add |
||||
|
|
||||
|
## 2/ Les placer sur le serveur dans un dossier (necessite JRE 11 pour être lancés) |
||||
|
|
||||
|
## 3/ Depuis le dossier lancer la commande : |
||||
|
|
||||
|
NOTE : Vous pouvez tester le programme rapidement en lançant ./run.sh dans le dossier dist (necessite JRE 11) |
||||
|
|
||||
|
----- |
||||
|
$ java -cp mysql-connector-java.jar:RobotIndex.jar robotindex.RobotIndex 'param1:URL' 'param2:nbIterations' 'param3:portSrvWebNotification' |
||||
|
----- |
||||
|
|
||||
|
3 Arguments au lancement du programme JAVA : |
||||
|
|
||||
|
1 - URL du site à tester |
||||
|
2 - Nb d'itérations, nombre de liens parcourus par le programme (default 15) |
||||
|
3 - Numero du port pour le serveur web de notif (default 8080) |
||||
|
|
||||
|
Utilisation de la notification d'avancement : |
||||
|
|
||||
|
Le developeur du site web pourra ainsi tester avec une requête GET l'etat d'avancement de l'algo : |
||||
|
|
||||
|
( Exemple : boîte de dialogue javascript test toutes les 1 sec l'avancement ). |
||||
|
|
||||
|
-> Requette GET : http://urlprogrammejava.dev:port (format application/json) |
||||
|
|
||||
|
NOTE: Le developpeur utilisant ce programme doit s'assurer avant de le lancer que le PORT utilisé pour le WebNotification est LIBRE. (e.g. avoir une fonction de test côté serveur avant de lancer le programme JAVA) |
||||
|
|
@ -0,0 +1,362 @@ |
|||||
|
/* |
||||
|
* 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); |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,180 @@ |
|||||
|
/* |
||||
|
* 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.net.MalformedURLException; |
||||
|
import java.net.URL; |
||||
|
import java.util.ArrayList; |
||||
|
import java.util.List; |
||||
|
import java.util.regex.Matcher; |
||||
|
import java.util.regex.Pattern; |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @author arthurdambrine |
||||
|
*/ |
||||
|
public class UrlParser { |
||||
|
|
||||
|
private static URL Monsite; |
||||
|
private URL aURL; |
||||
|
private static List urlList, fullUrlList; |
||||
|
|
||||
|
// regex pour les liens de type https://monsite.ovh
|
||||
|
private static final Pattern ptn |
||||
|
= Pattern.compile("(https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]"); |
||||
|
|
||||
|
// regex pour les liens internes de type href="/chemin"
|
||||
|
private static final Pattern ptn2 |
||||
|
= Pattern.compile("<a\\s+(?:[^>]*?\\s+)?href=([\"'])(.*?)\\1"); |
||||
|
|
||||
|
// constructeur
|
||||
|
public UrlParser() { |
||||
|
urlList = new ArrayList(); |
||||
|
fullUrlList = new ArrayList(); |
||||
|
} |
||||
|
|
||||
|
public UrlParser(URL MonSite) { |
||||
|
this(); |
||||
|
this.Monsite = MonSite; |
||||
|
} |
||||
|
|
||||
|
// methodes
|
||||
|
public void parseLine(String line) { |
||||
|
|
||||
|
urlList = captureValues(line); |
||||
|
for (Object item : urlList) { |
||||
|
if (!fullUrlList.contains(item)) { |
||||
|
fullUrlList.add(item); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public void displayUrl() throws MalformedURLException { |
||||
|
|
||||
|
String lURL; // Tampon pour l'URL en cours de traitement
|
||||
|
|
||||
|
for (int i = 0; i < urlList.size(); i++) { |
||||
|
// Chaque URL est affichée indépendemment
|
||||
|
lURL = urlList.get(i).toString(); |
||||
|
//System.out.println(lUrl); // affiche l'URL complète
|
||||
|
|
||||
|
aURL = new URL(lURL); |
||||
|
|
||||
|
// Préparation pour parcourir les URL internes
|
||||
|
if (Monsite.getHost().equals(aURL.getHost())) { |
||||
|
if (aURL.getPath().endsWith("/")) { |
||||
|
System.out.println(aURL); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
//System.out.println(aURL.getPath());
|
||||
|
//System.out.println("Site = " + aURL.getHost()); // Affiche le nom de domaine example.com
|
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
// Cette methode permet d'extraire le pattern et retourne au format liste
|
||||
|
public static List<String> captureValues(String largeText) { |
||||
|
Matcher mtch = ptn.matcher(largeText); |
||||
|
|
||||
|
Matcher m = ptn2.matcher(largeText); |
||||
|
|
||||
|
List<String> ips = new ArrayList<String>(); |
||||
|
|
||||
|
// Première regex sur url http(s)://...
|
||||
|
while (mtch.find()) { |
||||
|
if (IsMatch(mtch.group())) { |
||||
|
|
||||
|
ips.add(mtch.group()); |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
|
||||
|
while (m.find()) { // Deuxième regex (prendre en compte les href)
|
||||
|
|
||||
|
if (m.group(2).endsWith(".html")) { |
||||
|
|
||||
|
//System.out.println("TEST: " + m.group(2));
|
||||
|
if (!m.group(2).startsWith("htt")) { |
||||
|
// Si on a un lien comme href="docs/blabla.html"
|
||||
|
if (!m.group(2).startsWith("/")) { |
||||
|
//System.out.println("TEST: " + m.group()) ;
|
||||
|
// Ajouter un / à la fin est une astuce de différenciation, il faudra le retirer ensuite pour parcourir
|
||||
|
if (Monsite.toString().charAt(4) == 's') { |
||||
|
ips.add("https://" + Monsite.getHost().toString() + Monsite.getPath().toString() + "/" + m.group(2) + "/"); |
||||
|
} else { |
||||
|
ips.add("http://" + Monsite.getHost().toString() + Monsite.getPath().toString() + "/" + m.group(2) + "/"); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (m.group(2).startsWith("htt")) { // Si on a un lien href="http://monsite.fr/blabla.html"
|
||||
|
if (!m.group(2).startsWith("/")) { |
||||
|
//System.out.println("MATCH de http href: " + m.group(2)) ;
|
||||
|
ips.add(m.group(2)); |
||||
|
} |
||||
|
} |
||||
|
} else if (m.group(2).length() > 2) // securisation pour eviter de planter le m.group(2).charAt(1) == '/'
|
||||
|
{ |
||||
|
if (m.group(2).charAt(1) == '/') // si on a un lien de type : href:"//en.wikipedia.org"
|
||||
|
{ |
||||
|
if (Monsite.toString().charAt(4) == 's') { |
||||
|
//System.out.println("https:"+m.group(2));
|
||||
|
ips.add("https:" + m.group(2)); |
||||
|
} else { |
||||
|
//System.out.println("http:"+m.group(2));
|
||||
|
ips.add("http:" + m.group(2)); |
||||
|
} |
||||
|
} else // si lien interne commenaçant par /
|
||||
|
{ |
||||
|
if (m.group(2).startsWith("/")) { |
||||
|
//System.out.println("TEST: " + m.group()) ;
|
||||
|
// Ajouter un / à la fin est une astuce de différenciation, il faudra le retirer ensuite pour parcourir
|
||||
|
if (Monsite.toString().charAt(4) == 's') { |
||||
|
ips.add("https://" + Monsite.getHost().toString() + m.group(2) + "/"); |
||||
|
} else { |
||||
|
ips.add("http://" + Monsite.getHost().toString() + m.group(2) + "/"); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
return ips; |
||||
|
} |
||||
|
|
||||
|
// Cette methode verifie si oui ou non la chaîne correspond à mon pattern
|
||||
|
private static boolean IsMatch(String s) { |
||||
|
try { |
||||
|
Matcher matcher = ptn.matcher(s); |
||||
|
return matcher.matches(); |
||||
|
} catch (RuntimeException e) { |
||||
|
return false; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public static void displayFullUrlList() { |
||||
|
|
||||
|
for (int i = 0; i < fullUrlList.size(); i++) { |
||||
|
// Chaque URL est affichée indépendemment
|
||||
|
System.out.println(fullUrlList.get(i)); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public static List<String> getFullUrlList() { |
||||
|
|
||||
|
return fullUrlList; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
} |
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,2 @@ |
|||||
|
#!/bin/sh |
||||
|
java -cp mysql-connector-java.jar:RobotIndex.jar robotindex.RobotIndex |
Loading…
Reference in new issue