JVbackup

pour backup le saint sanctuaire

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name         JVbackup
// @namespace    http://tampermonkey.net/
// @version      0.8.1
// @description  pour backup le saint sanctuaire
// @author       flolep2607
// @match        https://www.jeuxvideo.com/forums/0-51-*.htm
// @match        https://www.jeuxvideo.com/forums/42-51-*.htm
// @icon         https://www.google.com/s2/favicons?domain=jeuxvideo.com
// @run-at       document-idle
// @grant        GM_xmlhttpRequest
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';
    const TIMER_SLEEP=5000;
    const DEBUG=false;
    const sleep = ms => {
        return new Promise(resolve => setTimeout(resolve, ms));
    }
    const months=['janvier','février','mars','avril','mai','juin','juillet','août','septembre','octobre','novembre','décembre'];
    const regex_code = /[0-9]+\-[0-9]+\-([0-9]+)\-[0-9]+\-[0-9]+\-[0-9]+\-[0-9]+/;
    const SUPPORT = (function () {
        if (!window.DOMParser) return false;
        var parser = new DOMParser();
        try {
            parser.parseFromString('x', 'text/html');
        } catch(err) {
            return false;
        }
        return true;
    })();
    const parser = SUPPORT?new DOMParser():null;

    const textToHTML=(html) => {
        // check for DOMParser support
        if (SUPPORT) {
            //let p =parser.parseFromString(html, 'text/html');
            //console.log(p.querySelectorAll("ul.topic-list > li[class='']"));
            return parser.parseFromString(html, 'text/html');
        }else{
            document.write(html)
            return document;
        }
    };
    const aa_fetch=(url_u)=>{
        return fetch(url_u).then(async u=>[await u.text(),u.url]).then((b)=>{
            //console.log("aa",b[0])
            return scrape(textToHTML(b[0]),b[1]);
        }).catch(r=>console.log(`!!req error:${r} url:${url_u}`));
    }
    const makeGetRequest=url=>{
        return new Promise((resolve, reject) => {
            GM_xmlhttpRequest({
                method: "GET",
                url: url,
                onload: function(response) {
                    resolve(response.responseText);
                },
                onerror: function(error) {
                    reject(error);
                }
            });
        });
    }
    let RUNNING=false;
    const farmer= async _=>{
        const checkbox=document.querySelector('#check_scrape');
        checkbox.addEventListener(
            "click",async _=>{
                let interval;
                while(checkbox.checked && !RUNNING){
                    RUNNING=true;
                    let TODO=[];
                    interval=setInterval(_=>{
                        aa_fetch("https://www.jeuxvideo.com/forums/0-51-0-1-0-1-0-blabla-18-25-ans.htm");
                    },5000)
                    await makeGetRequest(DEBUG?'http://localhost:3000/api/thread2scrape':'http://jvc.flolep.fr/api/thread2scrape')
                        .then(async json=>{
                        let result=[];
                        json=JSON.parse(json);
                        result.push(...json.data.map(r=>[1,r,1]).filter(u=>!result.map(i=>i[1]).includes(u[1]) && !TODO.map(i=>i[1]).includes(u[1])));
                        while(TODO.length<10&&result.length>0){TODO.push(result.pop())}
                        while(checkbox.checked && TODO.length>=10){
                            console.log(checkbox.checked);
                            TODO = await Promise.allSettled(
                                TODO.map((infos)=>{
                                    const url=`https://www.jeuxvideo.com/forums/42-51-${infos[1]}-${infos[0]}-0-1-0-u.htm`;
                                    //let final_url;
                                    return fetch(url).then(u=>u.text()).then((b)=>{
                                        const tmp=scrape(textToHTML(b),url);
                                        return [tmp[0],infos[1],infos[2]];
                                    }).catch(r=>console.log(`req error:${r} url:${url}`));
                                })).then(r=>{console.log('bunch scraped');return r})
                            TODO=TODO.filter(b=>b).map(r=>r.value);
                            console.log(">>",TODO);
                            TODO=TODO.filter(b=>b&&b[0]>b[2]);
                            while(TODO.length<10&&result.length>0){TODO.push(result.pop())}
                        }
                    });
                    RUNNING=false;
                }
                clearInterval(interval);
            }
        )
    }
    const actualiseur=a=>{
        while(document.querySelector('.bloc-pre-right')){
            const bloc=document.querySelector('.bloc-pre-right');
            //return
            if(bloc){
                bloc.classList.remove('bloc-pre-right');bloc.style='float: right;'
                if(a){
                    bloc.style='position: relative;right: unset;left: unset;top: unset;bottom: unset;overflow: hidden;display: flex;flex-wrap: wrap;justify-content: flex-end;margin-top: auto;flex: 1;'
                }
                bloc.innerHTML=`<div class="btn btn-actu-new-list-forum btn-actualiser-forum" style="float: right;border-color: var(--jv-text-secondary);background: transparent;color: var(--jv-text-secondary);text-transform: uppercase;font-weight: 700;padding: 0;font-size: .625rem;height: 1.75rem;min-width: 6.375rem;line-height: 1.6875rem;border-radius: 0.25rem;">Actualiser</button>`;
                const child=bloc.querySelector('div')
                child.classList.remove('btn-actu-new-list-forum')
                child.classList.remove('btn-actualiser-forum')
                //console.log(child)
                child.addEventListener(
                    "click",_=>{
                        fetch(document.URL).then(r=>r.text())
                            .then(u=>{
                            const data=textToHTML(u);
                            document.body.innerHTML=data.body.innerHTML;
                            scrape(document,document.URL);
                            actualiseur(a);
                        })
                    }
                )
            }
        }
    }
    const uniq_fast = a=> {
        var seen = {};
        var out = [];
        var len = a.length;
        var j = 0;
        for(var i = 0; i < len; i++) {
            var item = a[i];
            if(seen[item] !== 1) {
                seen[item] = 1;
                out[j++] = item;
            }
        }
        return out;
    }
    // `https://www.jeuxvideo.com/forums/42-51-${code}-1-0-1-0-ma-tante-est-morte.htm`
    //fetch('https://www.jeuxvideo.com/forums/42-51-49703882-21-0-1-0-qui-n-a-toujours-pas-eu-son-alloc-garantie-jeunes.htm').then(u=>u.text()).then(u=>document.write(u))
    const range = (u, l) => {
        var list = [];
        for (var i = u; i <= l; i++) {
            list.push(i);
        }
        return list;
    }
    if(document.URL.includes('forums/0-51-')){
        actualiseur();
        document.querySelector('div.header__nav.header__nav--primary').innerHTML=""
        document.querySelector('.header__globalWeb').innerHTML='<input id="check_scrape" type="checkbox" ><input id="addon_backup_start" class="xXx" style="width:64px" value="5"><input id="addon_backup_end" class="xXx" style="width:64px" value="20"><input id="addon_backup" class="xXx" style="width:64px" type="button">';
        document.getElementById("addon_backup").addEventListener(
            "click", async _=>{
                //let url="";
                let start=parseInt(document.getElementById("addon_backup_start").value);
                const end=parseInt(document.getElementById("addon_backup_end").value);
                while(start<end){
                    await Promise.allSettled(
                        range(start,(start+10-end)<0?start+10:end).map(i=>{
                            return aa_fetch(`https://www.jeuxvideo.com/forums/0-51-0-1-0-${1+i*25}-0-blabla-18-25-ans.htm`);
                        })
                    );
                    start=(start+10-end)<0?start+10:end;
                    console.log(`part done: ${start}`);
                }
                console.log("alldone");
                //for(let i=parseInt(document.getElementById("addon_backup_start").value);i<parseInt(document.getElementById("addon_backup_end").value);i++){
                //    url=`https://www.jeuxvideo.com/forums/0-51-0-1-0-${1+i*25}-0-blabla-18-25-ans.htm`
                //    aa_fetch(url);
                //}
            }
        );
        farmer();
    }else if(document.URL.includes('forums/42-51-')){
        actualiseur(1);
        document.querySelector('.header__globalWeb').innerHTML='<input id="check_scrape" type="checkbox" ><input id="addon_backup" class="xXx" style="width:64px" type="button">';
        document.getElementById("addon_backup").addEventListener(
            "click", async _=>{

                const DONES=[];
                let last = Date.now();
                let last_tmp;
                const thread_code=regex_code.exec(document.URL)[1];
                var url=`https://www.jeuxvideo.com/forums/42-51-${thread_code}-1-0-1-0-u.htm`;
                var resp=await fetch(url).then(r=>r.text())
                var data=textToHTML(resp);
                var tmp=scrape(data,url,DONES);
                DONES.push(...tmp[1]);
                let end=[...data.querySelectorAll("div.bloc-liste-num-page > span")].map(r=>parseInt(r.innerText)).filter(r=>r).reduce((before,now)=>now>before?now:before);
                console.log(end)
                //let end=parseInt(tmppppp[tmppppp.length-1].innerText);
                if(end>1){
                    var PAGED=2;
                    for(;PAGED<end;PAGED++){
                        await Promise.allSettled(
                            range(PAGED,PAGED+10>end?end:PAGED+10).map(PAGE=>{
                                const zurl=`https://www.jeuxvideo.com/forums/42-51-${thread_code}-${PAGE}-0-1-0-u.htm`
                                return fetch(zurl).then(r=>r.text()).then(resp=>{
                                    let _data=textToHTML(resp);
                                    [..._data.querySelectorAll('div.risibank-image-enhancer-buttons')].forEach(r=>r.remove())
                                    let _tmp=scrape(_data,zurl,DONES);
                                    DONES.push(..._tmp[1]);
                                    return 1
                                }).catch(e=>console.log("pd",e))
                            })
                        ).catch(e=>console.log("pd",e));
                        PAGED+=10
                    }
                }
                document.getElementById("addon_backup").style="width:64px;background-color:green"
                //setTimeout(_=>{
                //    document.getElementById("addon_backup").style="width:64px";
                //},5000)
                while(true){
                    const url=`https://www.jeuxvideo.com/forums/42-51-${thread_code}-${end}-0-1-0-u.htm`;
                    console.log(url)
                    resp=await fetch(url).then(r=>r.text())
                    data=textToHTML(resp);
                    end=[...data.querySelectorAll("div.bloc-liste-num-page > span")].map(r=>parseInt(r.innerText)).filter(r=>r).reduce((before,now)=>now>before?now:before);
                    //tmppppp=data.querySelectorAll("div.bloc-liste-num-page > span");
                    console.log("AAAAAA",end);
                    //end=parseInt(tmppppp[tmppppp.length-1].innerText);
                    [...data.querySelectorAll('div.risibank-image-enhancer-buttons')].forEach(r=>r.remove())
                    tmp=scrape(data,url,DONES);
                    if(tmp && tmp.length>=2){DONES.push(...tmp[1])}
                    last_tmp=Date.now();
                    console.log(`wait: ${last-last_tmp+TIMER_SLEEP} | ${end}`);
                    if(last-last_tmp+TIMER_SLEEP>0){await sleep(last-last_tmp+TIMER_SLEEP);}
                    last = Date.now();
                }
            }
        )
    }
    farmer();
    const scrape=(DOC,URL,banned=[])=>{
        let PAGE=1;
        if(URL.includes('forums/42-51-')){
            //console.log("DOC",DOC.body.innerText);
            const thread_code=parseInt(regex_code.exec(URL)[1]);
            const thread={
                code:thread_code,
                title:DOC.querySelector("#bloc-title-forum").innerText.trim(),
                url:URL
            };
            let USERS=[];
            PAGE=(DOC.querySelector('span.page-active') && DOC.querySelector('span.page-active').nextSibling)?DOC.querySelector('span.page-active').nextSibling.innerText:1;
            const posts=[...DOC.querySelectorAll('div.bloc-message-forum')]
            .map(post=>{
                //console.log(post);
                const date=post.querySelector('div.bloc-date-msg').innerText.trim().split(' ');
                const day=parseInt(date[0]);
                const month=months.indexOf(date[1]);
                const year=parseInt(date[2]);
                const time=date[4].trim().split(':')
                const hours=parseInt(time[0]);
                const minutes=parseInt(time[1]);
                const seconds=parseInt(time[2]);
                //console.log(year,month,day,hours,minutes,seconds);
                let avatar_url=null
                if(post.querySelector('div.bloc-avatar-msg img.user-avatar-msg')) {
                    const img=post.querySelector('div.bloc-avatar-msg img.user-avatar-msg').getAttribute("data-src")||post.querySelector('div.bloc-avatar-msg img.user-avatar-msg').src
                    if(![
                        "https://image.jeuxvideo.com/avatar-sm/default.jpg",
                        'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7',
                        null
                    ].includes(img)){
                        avatar_url=img
                    }
                }
                const pseudo=post.querySelector('.bloc-pseudo-msg')?post.querySelector('.bloc-pseudo-msg').innerText.trim():null;
                //console.log(pseudo,post.querySelector('.bloc-pseudo-msg'));
                [...post.querySelectorAll('div.risibank-image-enhancer-buttons')].forEach(r=>r.remove())
                USERS.push({
                    pseudo:pseudo,
                    image:avatar_url
                })
                //console.log(date,year,month,day,time,hours,minutes,seconds,new Date(year,month,day,hours,minutes,seconds).toISOString());
                return {
                    date:new Date(year,month,day,hours,minutes,seconds).toISOString(),//~~((new Date(year,month,day,hours,minutes,seconds)).getTime()/1000),
                    html:post.querySelector('div.bloc-contenu > div.txt-msg').innerHTML.trim(),
                    thread_code:thread_code,
                    id:post.getAttribute("data-id"),
                    pseudo:pseudo,
                }
            }).filter(r=>!banned.includes(r.id))
            USERS=uniq_fast(USERS);
            if(posts.length){
                //console.log(posts);
                GM_xmlhttpRequest({
                    method: "POST",
                    headers:    {
                        "Content-Type": "application/json"
                    },
                    data:JSON.stringify({thread:thread,posts:posts,users:USERS}),
                    url: DEBUG?'http://localhost:3000/api/newposts':"http://jvc.flolep.fr/api/newposts"
                });
                return [PAGE,posts.map(r=>r.id)];
            }else if(DOC.querySelector('div.col-md-12:nth-child(2) > strong:nth-child(1)')){
                const ban=DOC.querySelector('div.col-md-12:nth-child(2) > strong:nth-child(1)').innerHTML.includes('modération')?2:1;
                GM_xmlhttpRequest({
                    method: "POST",
                    headers:    {
                        "Content-Type": "application/json"
                    },
                    data:JSON.stringify({type:ban,code:thread_code}),
                    url: DEBUG?'http://localhost:3000/api/banthread':"http://jvc.flolep.fr/api/banthread"
                });
                return [PAGE,null];
            }
        }else if(URL.includes('forums/0-51-')){
            //console.log(">>>>",URL,DOC.querySelectorAll("li[data-id]"))
            const data=[...DOC.querySelectorAll("li[data-id][class='']")]
            .filter(r=>r && r.getAttribute("data-id")!="63346087")
            .map(thread=>{
                const date_string=thread.querySelector('span.topic-date').innerText.trim();
                //console.log(date_string,thread.querySelector('span.topic-date').innerText.trim())
                let datee;
                if(date_string.includes('/')){
                    datee=(new Date(date_string))/1000
                }else{
                    const now=new Date();
                    datee=~~((now.setHours(...date_string.split(":")))/1000)
                }
                //console.log(">>",thread);
                //console.log("datee",datee)
                return {
                    title:thread.querySelector('a.topic-title').getAttribute('title'),
                    date:datee,
                    responses:parseInt(thread.querySelector('span.topic-count').innerText),
                    code:thread.getAttribute("data-id"),
                    link:`https://api.jeuxvideo.com/forums/42-51-${thread.getAttribute("data-id")}-1-0-1-0-u.htm`
                }});
            //console.log(JSON.stringify(data));
            if(data.length>0){
                GM_xmlhttpRequest({
                    method: "POST",
                    headers:    {
                        "Content-Type": "application/json"
                    },
                    data:JSON.stringify(data),
                    url: DEBUG?'http://localhost:3000/api/newfeed':"http://jvc.flolep.fr/api/newfeed"
                });
            }
            return [PAGE,data.map(r=>r.code)];
        }
    }
    scrape(document,document.URL);
})();