Utilisateur:Djobot/page.cpp

Un article de Wikipédia, l'encyclopédie libre.


// ********************************************************************************
//
//      djobot, bot pour wikipédia. Sous licence gpl au nom de djo0012.
//
//      l'utilisation de ce bot est sous la responsabilité de son utilisateur, 
//      en aucun cas je ne peut être tenu responsable des actions effectuer avec
//      ce bot par d'autre personne que moi-même.
//
//      je ne garantis en aucun cas le bon fonctionnement de ce code.
//
//      fichier page.cpp            version 1.0
//      
//      gère toute l'interaction avec la Wikipédia francophone.
//
// ********************************************************************************

#include"page.h"
#include"tempfile.h"

extern string cookies;
extern tempfile log;

page::page()
{

}

page::page(string wikiPageName)
{
    pageok(wikiPageName,true);
}

page::page(string wikiPageName,bool edit)
{
    pageok(wikiPageName,edit);
}

void page::pageok(string wikiPageName,bool edit)
{

    pageName=wikiPageName;
    if(edit)
        pageAdresse="/w/wiki.phtml?title="+wikiPageName+"&action=edit";
    else
        pageAdresse=wikiPageName;

    resume("");
    minoredit(true);
    watch(false);


    getPage();
}

page::~page()
{

}

void page::socketCrea()
{
    WSADATA WSAData;
    WSAStartup(MAKEWORD(2,2), &WSAData);
    struct sockaddr_in sin;

    sin.sin_addr                = resolve("fr.wikipedia.org");
    sin.sin_family        = AF_INET;
    sin.sin_port                = htons(80);
//    cout<<"\tcreation du socket";
    sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if(sock < 0)  // Au cas ou la création de la socket ne fonctionnerais pas
    {
        cerr<<"\nImpossible de creer la socket\n";
        exit(1);
    }

//    cout<<"\r[ok]\n\tconnection au serveur";
    if (connect(sock,(struct sockaddr *)&sin, sizeof sin) < 0)
    {
        cerr<<"\nImpossible de se connecter au serveur\n";
        exit(1);
    }
//    cout<<"\r[ok]\n\n";
}

void page::closesock()
{
    closesocket(sock);
    WSACleanup();
}

struct in_addr page::resolve (char *name)
{
    static struct in_addr in;
    unsigned long l;
    struct hostent *ent;

    if ((l = inet_addr(name)) != INADDR_NONE)
    {
        in.s_addr = l;
        return in;
    }
    if (!(ent = gethostbyname(name)))
    {
        in.s_addr = INADDR_NONE;
        return in;
    }

    return *(struct in_addr *)ent->h_addr;
}

void page::login()
{

    string requete, entete, corp,  cookieTemp, pageverif;
    char recept[32];
    string messchar;
    int bytesRecv = 0;

    socketCrea();

    requete="POST /w/wiki.phtml?title=Special:Userlogin&action=submitlogin HTTP/1.0\r\n"; //&type=login

    corp="wpName=USERNAME&wpPassword=PASSWORD&wpRemember=1&wpLoginattempt=Identification";

    entete="Host: fr.wikipedia.org\r\n"
        "User-Agent: djobot\r\n"
        "Content-type: application/x-www-form-urlencoded\r\n"
        "Content-Length: "+str(corp.length())+"\r\n";
    requete=requete+entete+"\r\n"+corp;
    cout<<"\n\tenvois de requete login ";
    send(sock, requete.c_str(), requete.length(),0);
    cout<<"\r[ok]\n";
    cout<<"\tattente reponse du serveur";
    while( bytesRecv != SOCKET_ERROR )
    {
        bytesRecv = recv( sock, recept, 31, 0 );
        if ( bytesRecv == 0 )
            break;

        messchar+=recept;
        for(int i=0;i<32;++i)
            recept[i]=0;
    }

    cout<<"\r[ok]\n\textraction des cookies";
    cookieTemp=messchar;
    cookies="cookie:";
    while((int)cookieTemp.find("Set-Cookie: ")>0)
    {
    cookieTemp=cookieTemp.substr(cookieTemp.find("Set-Cookie:")+11);
    cookies+=cookieTemp.substr(0,cookieTemp.find_first_of(';')+1);
    }
    cookies[cookies.length()-1]='\r';
    cookies+='\n';
    cout<<"\r[ok]\n";
    closesock();
}

void page::sendPage()
{
    sendPage(1);
}

void page::sendPage(int type)
{
    if(strcmp(article.c_str(),articleOriginal.c_str()))
    {
        string requete, entete, corp;
        char recept[32];
        int bytesRecv = 0;
        reponse="";

        log.put("[["+pageName+"]]",true);
        wait();     //fonction d'attente pour un certain temp
        socketCrea();
        cout<<"\n\t\t***requete***\n\t**POST page: "<<pageName;
        requete="POST /w/index.php?title="+pageName+"&action=submit HTTP/1.1\r\n";

        corp="--ABCDEF\r\nContent-Disposition: form-data; name=\"wpEdittime\"\r\n\r\n"+Edittime+"\r\n"
            "--ABCDEF\r\nContent-Disposition: form-data; name=\"wpTextbox1\"\r\n\r\n"+article+"\r\n"
            "--ABCDEF\r\nContent-Disposition: form-data; name=\"wpSummary\"\r\n\r\n"+Summary+"\r\n"
            "--ABCDEF\r\nContent-Disposition: form-data; name=\"wpMinoredit\"\r\n\r\n"+Minoredit+"\r\n"
            "--ABCDEF\r\nContent-Disposition: form-data; name=\"wpWatchthis\"\r\n\r\n"+Watch+"\r\n";

        if(type==1)
            corp+="--ABCDEF\r\nContent-Disposition: form-data; name=\"wpSave\"\r\n\r\nSauvegarder\r\n";
        if(type==2)
            corp+="--ABCDEF\r\nContent-Disposition: form-data; name=\"wpPreview\"\r\n\r\nPr%C3visualisation\r\n";
        if(type==3)
            corp+="--ABCDEF\r\nContent-Disposition: form-data; name=\"wpDiff\"\r\n\r\nChangements en cours\r\n";

        corp+="--ABCDEF\r\nContent-Disposition: form-data; name=\"wpEditToken\"\r\n\r\n"+EditToken+"\r\n"
            "--ABCDEF\r\nContent-Disposition: form-data; name=\"wpAutoSummary\"\r\n\r\n"+AutoSummary+"\r\n"
            "--ABCDEF--\r\n";
        entete="Host: fr.wikipedia.org\r\n"
            "User-Agent: djobot\r\n"+cookies+
            "Content-type: multipart/form-data; boundary=ABCDEF\r\n"
            "Content-Length: "+str(corp.length())+"\r\n";

        requete=requete+entete+"\r\n"+corp+"\r\n\r\n";  //assemblage de la requette finale
        cout<<"\n\tenvois de la page ";
        send(sock, requete.c_str(), requete.length(),0);
        cout<<"\r[ok]\n";
        cout<<"\tattente reponse du serveur";

        while( bytesRecv != SOCKET_ERROR )  //fonction de la MSDN
        {
            bytesRecv = recv( sock, recept, 31, 0 );
            if ( bytesRecv == 0 )
                break;

            reponse+=recept;
            for(int i=0;i<32;++i)
                recept[i]=0;
        }                                   //fin de la fonction de la MSDN
        closesock();
        cout<<"\r[ok]\n\n";
    }
}

void page::getPage()
{

    string requete, entete;
    char messchar[32]="";
    int bytesRecv = 0;

    wait();
    socketCrea();
    cout<<"\n\t\t***requete***\n\t**GET page: "<<pageName<<"\n a l'adresse: "<<pageAdresse;
    requete="GET "+pageAdresse+" HTTP/1.0\r\n";
    entete="Host: fr.wikipedia.org\r\n"
        "User-Agent: djobot\r\n";
    requete=requete+entete+cookies+"\r\n";  //
    cout<<"\n\n\tenvois de la requete";
    send(sock, requete.c_str(), requete.length(),0);
    cout<<"\r[ok]\n";
    cout<<"\tattente reponse du serveur";

    while( bytesRecv != SOCKET_ERROR )
    {
        bytesRecv = recv( sock, messchar, 31, 0 );

        if ( bytesRecv == 0 )
            break;

        fullPage+=messchar;
        for(int i=0;i<32;++i)
            messchar[i]=0;
    }

    cout<<"\r[ok]\n";
    closesock();
}

void page::resume(string resum)
{
    Summary=resum;
}

void page::minoredit(bool minor)
{
    if(minor)
        Minoredit='1';
    else
        Minoredit='0';
}

void page::watch(bool watch)
{
    if(watch)
        Watch='1';
    else
        Watch='0';
}

void page::recupArt()
{
    cout<<"\trecuperation de l'article";
    articleOriginal=article=fullPage.substr(fullPage.find("<textarea")+92,fullPage.find("</textarea>")
        -(fullPage.find("<textarea")+92));
    Edittime=fullPage.substr(fullPage.find(" name=\"wpEdittime")-15,14);
    EditToken=fullPage.substr(fullPage.find(" name=\"wpEditToken")-33,32);
    AutoSummary=fullPage.substr(fullPage.find(" name=\"wpAutoSummary")+43,32);

    cout<<"\r[ok]\n";
}

void page::recupHTML()
{
    cout<<"\trecuperation du code HTML";
    arcticleHTML=fullPage.substr(fullPage.find("<h1"),(fullPage.find("end content")-fullPage.find("<h1")));
    cout<<"\r[ok]\n";
}


void page::open(string val)
{
    ofstream rep("toop.html");
    rep<<val;
    rep.close();
    system("toop.html");
}

template<typename T>
std::string str( const T & Value )
{
    // utiliser un flux de sortie pour créer la chaîne
    std::ostringstream oss;
    // écrire la valeur dans le flux
    oss << Value;
    // renvoyer une string
    return oss.str();
}

void wait()
{
    static clock_t endwait=clock();     //temp d'attente avant de rapelle le serveur
    while (clock() < endwait)
    {
        cout<<(endwait-clock())/CLK_TCK<<" secondes avant rapelle du serveur               \r";
        Sleep(1000);
    }
    cout<<"                                                                  \r";
    endwait = clock()+30*CLK_TCK ;
}