Skip to content

Commit

Permalink
Merge pull request #28 from kingdragox99/dev-superbase-rework
Browse files Browse the repository at this point in the history
add crawler sync
  • Loading branch information
kingdragox99 authored Oct 5, 2024
2 parents 831aec8 + 4d8f917 commit d798cc7
Show file tree
Hide file tree
Showing 4 changed files with 194 additions and 330 deletions.
113 changes: 97 additions & 16 deletions crawler.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ const supabase = createClient(
// Ta clé d'API Steam
const steamApiKey = process.env.STEAM_API;

// Crawler ID
const crawlerId = "1";

// Ensemble pour garder une trace des profils déjà visités
const visitedProfiles = new Set();

Expand All @@ -30,11 +33,14 @@ async function convertToSteamId64(profileUrl) {
const steamId64 = data.response.steamid;
return `https://steamcommunity.com/profiles/${steamId64}/`;
} else {
console.error(`Erreur : ${data.response.message}`);
console.error(`\x1b[41m\x1b[1mERROR\x1b[0m: ${data.response.message}`);
return null;
}
} catch (error) {
console.error("Erreur lors de la requête vers l'API Steam :", error);
console.error(
"\x1b[41m\x1b[1mERROR\x1b[0m: when requesting the Steam API :",
error
);
return null;
}
} else {
Expand All @@ -43,6 +49,66 @@ async function convertToSteamId64(profileUrl) {
}
}

// Fonction pour obtenir le prochain profil à crawler
async function getNextProfile() {
// Sélectionner le prochain profil non traité
const { data: nextProfile, error } = await supabase
.from("profil")
.select("url")
.eq("status", "pending")
.limit(1);

if (error) {
console.error(
"\x1b[41m\x1b[1mERROR\x1b[0m: when retrieving the next profile : ",
error
);
return null;
}

if (nextProfile.length === 0) {
console.log("\x1b[43m\x1b[1mUSER\x1b[0m: No profiles awaiting crawling.");
return null;
}

const profileUrl = nextProfile[0].url;

// Mettre à jour le statut de ce profil à 'in_progress'
const { error: updateError } = await supabase
.from("profil")
.update({ status: "in_progress" })
.eq("url", profileUrl);

if (updateError) {
console.error(
"\x1b[41m\x1b[1mERROR\x1b[0m: when updating profile status : ",
updateError
);
return null;
}

return profileUrl;
}

// Fonction pour marquer un profil comme terminé
async function markProfileAsDone(profileUrl) {
const { error } = await supabase
.from("profil")
.update({ status: "done" })
.eq("url", profileUrl);

if (error) {
console.error(
"\x1b[41m\x1b[1mERROR\x1b[0m: when updating the profile status to 'done': ",
error
);
} else {
console.log(
`\x1b[43m\x1b[1mUSER\x1b[0m: \x1b[45m\x1b[1m${profileUrl}\x1b[0m marked as completed.`
);
}
}

// Fonction pour ajouter un contact à la base de données dans la table "profil"
async function addContact(contactUrl) {
// Vérifier si le contact existe déjà dans la table "profil"
Expand All @@ -53,32 +119,31 @@ async function addContact(contactUrl) {

if (existingContact.length > 0) {
console.log(
`
\x1b[45m\x1b[1mCRAWLER:\x1b[0m The contact \x1b[33m\x1b[1m${contactUrl}\x1b[0m is already in the database.`
`\x1b[43m\x1b[1mUSER\x1b[0m: \x1b[43m\x1b[1m${contactUrl}\x1b[0m is already in the database.`
);
return;
}

// Ajouter le contact dans la table "profil" s'il n'existe pas
const { data, error } = await supabase.from("profil").insert([
{
id_server: "crawler",
watcher_user: "crawler",
id_server: "crawler " + crawlerId,
watcher_user: "crawler " + crawlerId,
url: contactUrl, // Utilise l'URL avec steamID64
watch_user: await scapName(contactUrl),
ban: await scapBan(contactUrl),
status: "pending", // Le profil est en attente d'être crawlé
},
]);

if (error) {
console.error(
"\x1b[45m\x1b[1mCRAWLER:\x1b[0m \x1b[31m\x1b[1mError during database insertion :\x1b[0m",
"\x1b[41m\x1b[1mERROR\x1b[0m: \x1b[31m\x1b[1mError during database insertion :\x1b[0m",
error
);
} else {
console.log(
`
\x1b[45m\x1b[1mCRAWLER:\x1b[0m Contact \x1b[42m\x1b[1m${contactUrl}\x1b[0m successfully added.`
`\x1b[43m\x1b[1mUSER\x1b[0m: \x1b[42m\x1b[1m${contactUrl}\x1b[0m successfully added.`
);
}
}
Expand All @@ -103,20 +168,33 @@ async function fetchSteamFriends(profileUrl) {
return contacts;
} catch (error) {
console.error(
`
\x1b[45m\x1b[1mCRAWLER:\x1b[0m \x1b[31m\x1b[1mError retrieving Steam friends page :\x1b[31\x1b[0m ${error.message}`
`\x1b[41m\x1b[1mERROR\x1b[0m: \x1b[31m\x1b[1mretrieving Steam friends page :\x1b[31\x1b[0m ${error.message}`
);
return [];
}
}

// Fonction principale pour crawler les contacts récursivement
async function crawlSteamProfile(profileUrl) {
async function crawlSteamProfile(startUrl = null) {
// Si un profil de démarrage est fourni, ajouter ce profil dans la base de données s'il n'existe pas
if (startUrl) {
const normalizedProfileUrl = await convertToSteamId64(startUrl);
if (normalizedProfileUrl) {
await addContact(normalizedProfileUrl); // Ajouter le profil de départ à la base de données
}
}

const profileUrl = startUrl || (await getNextProfile());

if (!profileUrl) {
console.log("\x1b[41m\x1b[1mERROR\x1b[0m: No profile available to crawl.");
return;
}

// Vérifier si le profil a déjà été visité pour éviter les boucles infinies
if (visitedProfiles.has(profileUrl)) {
console.log(
`
\x1b[45m\x1b[1mCRAWLER:\x1b[0m profile \x1b[33m\x1b[1m${profileUrl}\x1b[0m has already been visited. `
`\x1b[43m\x1b[1mUSER\x1b[0m: \x1b[46m\x1b[1m${profileUrl}\x1b[0m has already been visited. `
);
return;
}
Expand All @@ -128,7 +206,7 @@ async function crawlSteamProfile(profileUrl) {
const normalizedProfileUrl = await convertToSteamId64(profileUrl);
if (!normalizedProfileUrl) {
console.error(
"\x1b[45m\x1b[1mCRAWLER:\x1b[0m \x1b[31m\x1b[1mUnable to convert URL to steamID64.\x1b[0m"
"\x1b[41m\x1b[1mERROR\x1b[0m: \x1b[31m\x1b[1mUnable to convert URL to steamID64.\x1b[0m"
);
return;
}
Expand All @@ -143,7 +221,10 @@ async function crawlSteamProfile(profileUrl) {
// Récursivement crawler les contacts des contacts sans limite de profondeur
await crawlSteamProfile(contactUrl);
}

// Marquer ce profil comme terminé
await markProfileAsDone(profileUrl);
}

// Lancer le crawler
// Lancer le crawler avec le profil de démarrage spécifié
crawlSteamProfile(process.env.CRAWLER_SEED);
113 changes: 97 additions & 16 deletions crawler2.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ const supabase = createClient(
// Ta clé d'API Steam
const steamApiKey = process.env.STEAM_API;

// Crawler ID
const crawlerId = "2";

// Ensemble pour garder une trace des profils déjà visités
const visitedProfiles = new Set();

Expand All @@ -30,11 +33,14 @@ async function convertToSteamId64(profileUrl) {
const steamId64 = data.response.steamid;
return `https://steamcommunity.com/profiles/${steamId64}/`;
} else {
console.error(`Erreur : ${data.response.message}`);
console.error(`\x1b[41m\x1b[1mERROR\x1b[0m: ${data.response.message}`);
return null;
}
} catch (error) {
console.error("Erreur lors de la requête vers l'API Steam :", error);
console.error(
"\x1b[41m\x1b[1mERROR\x1b[0m: when requesting the Steam API :",
error
);
return null;
}
} else {
Expand All @@ -43,6 +49,66 @@ async function convertToSteamId64(profileUrl) {
}
}

// Fonction pour obtenir le prochain profil à crawler
async function getNextProfile() {
// Sélectionner le prochain profil non traité
const { data: nextProfile, error } = await supabase
.from("profil")
.select("url")
.eq("status", "pending")
.limit(1);

if (error) {
console.error(
"\x1b[41m\x1b[1mERROR\x1b[0m: when retrieving the next profile : ",
error
);
return null;
}

if (nextProfile.length === 0) {
console.log("\x1b[43m\x1b[1mUSER\x1b[0m: No profiles awaiting crawling.");
return null;
}

const profileUrl = nextProfile[0].url;

// Mettre à jour le statut de ce profil à 'in_progress'
const { error: updateError } = await supabase
.from("profil")
.update({ status: "in_progress" })
.eq("url", profileUrl);

if (updateError) {
console.error(
"\x1b[41m\x1b[1mERROR\x1b[0m: when updating profile status : ",
updateError
);
return null;
}

return profileUrl;
}

// Fonction pour marquer un profil comme terminé
async function markProfileAsDone(profileUrl) {
const { error } = await supabase
.from("profil")
.update({ status: "done" })
.eq("url", profileUrl);

if (error) {
console.error(
"\x1b[41m\x1b[1mERROR\x1b[0m: when updating the profile status to 'done': ",
error
);
} else {
console.log(
`\x1b[43m\x1b[1mUSER\x1b[0m: \x1b[45m\x1b[1m${profileUrl}\x1b[0m marked as completed.`
);
}
}

// Fonction pour ajouter un contact à la base de données dans la table "profil"
async function addContact(contactUrl) {
// Vérifier si le contact existe déjà dans la table "profil"
Expand All @@ -53,32 +119,31 @@ async function addContact(contactUrl) {

if (existingContact.length > 0) {
console.log(
`
\x1b[45m\x1b[1mCRAWLER:\x1b[0m The contact \x1b[33m\x1b[1m${contactUrl}\x1b[0m is already in the database.`
`\x1b[43m\x1b[1mUSER\x1b[0m: \x1b[43m\x1b[1m${contactUrl}\x1b[0m is already in the database.`
);
return;
}

// Ajouter le contact dans la table "profil" s'il n'existe pas
const { data, error } = await supabase.from("profil").insert([
{
id_server: "crawler 2",
watcher_user: "crawler 2",
id_server: "crawler " + crawlerId,
watcher_user: "crawler " + crawlerId,
url: contactUrl, // Utilise l'URL avec steamID64
watch_user: await scapName(contactUrl),
ban: await scapBan(contactUrl),
status: "pending", // Le profil est en attente d'être crawlé
},
]);

if (error) {
console.error(
"\x1b[45m\x1b[1mCRAWLER:\x1b[0m \x1b[31m\x1b[1mError during database insertion :\x1b[0m",
"\x1b[41m\x1b[1mERROR\x1b[0m: \x1b[31m\x1b[1mError during database insertion :\x1b[0m",
error
);
} else {
console.log(
`
\x1b[45m\x1b[1mCRAWLER:\x1b[0m Contact \x1b[42m\x1b[1m${contactUrl}\x1b[0m successfully added.`
`\x1b[43m\x1b[1mUSER\x1b[0m: \x1b[42m\x1b[1m${contactUrl}\x1b[0m successfully added.`
);
}
}
Expand All @@ -103,20 +168,33 @@ async function fetchSteamFriends(profileUrl) {
return contacts;
} catch (error) {
console.error(
`
\x1b[45m\x1b[1mCRAWLER:\x1b[0m \x1b[31m\x1b[1mError retrieving Steam friends page :\x1b[31\x1b[0m ${error.message}`
`\x1b[41m\x1b[1mERROR\x1b[0m: \x1b[31m\x1b[1mretrieving Steam friends page :\x1b[31\x1b[0m ${error.message}`
);
return [];
}
}

// Fonction principale pour crawler les contacts récursivement
async function crawlSteamProfile(profileUrl) {
async function crawlSteamProfile(startUrl = null) {
// Si un profil de démarrage est fourni, ajouter ce profil dans la base de données s'il n'existe pas
if (startUrl) {
const normalizedProfileUrl = await convertToSteamId64(startUrl);
if (normalizedProfileUrl) {
await addContact(normalizedProfileUrl); // Ajouter le profil de départ à la base de données
}
}

const profileUrl = startUrl || (await getNextProfile());

if (!profileUrl) {
console.log("\x1b[41m\x1b[1mERROR\x1b[0m: No profile available to crawl.");
return;
}

// Vérifier si le profil a déjà été visité pour éviter les boucles infinies
if (visitedProfiles.has(profileUrl)) {
console.log(
`
\x1b[45m\x1b[1mCRAWLER:\x1b[0m profile \x1b[33m\x1b[1m${profileUrl}\x1b[0m has already been visited. `
`\x1b[43m\x1b[1mUSER\x1b[0m: \x1b[46m\x1b[1m${profileUrl}\x1b[0m has already been visited. `
);
return;
}
Expand All @@ -128,7 +206,7 @@ async function crawlSteamProfile(profileUrl) {
const normalizedProfileUrl = await convertToSteamId64(profileUrl);
if (!normalizedProfileUrl) {
console.error(
"\x1b[45m\x1b[1mCRAWLER:\x1b[0m \x1b[31m\x1b[1mUnable to convert URL to steamID64.\x1b[0m"
"\x1b[41m\x1b[1mERROR\x1b[0m: \x1b[31m\x1b[1mUnable to convert URL to steamID64.\x1b[0m"
);
return;
}
Expand All @@ -143,7 +221,10 @@ async function crawlSteamProfile(profileUrl) {
// Récursivement crawler les contacts des contacts sans limite de profondeur
await crawlSteamProfile(contactUrl);
}

// Marquer ce profil comme terminé
await markProfileAsDone(profileUrl);
}

// Lancer le crawler
// Lancer le crawler avec le profil de démarrage spécifié
crawlSteamProfile(process.env.CRAWLER_SEED_2);
Loading

0 comments on commit d798cc7

Please sign in to comment.