Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#276 Le 26/06/2012, à 06:04

souen

Re : Topic des lève-tôt… Faisons manger leurs caleçons aux couche-tard! [4]

salut!


...

Hors ligne

#277 Le 26/06/2012, à 06:20

raspouillas

Re : Topic des lève-tôt… Faisons manger leurs caleçons aux couche-tard! [4]

Encore moi !
Linux PureOS 3.3.6-pureos #1 SMP PREEMPT Thu Jun 14 19:49:16 UTC 2012 i686 GNU/Linux

#278 Le 26/06/2012, à 06:32

Ras'

Re : Topic des lève-tôt… Faisons manger leurs caleçons aux couche-tard! [4]

Tu fais des tests pour le compteur ?


Va t'faire shampouiner par le compteur_V2 en timezone[Canada/Eastern] !
 
Les types awesome n'ont rien à prouver. À personne.
'k bye là

Hors ligne

#279 Le 26/06/2012, à 06:38

ljere

Re : Topic des lève-tôt… Faisons manger leurs caleçons aux couche-tard! [4]

yop


ancien PC Toshiba satellite_c670d-11 / Linux Mint 21 Vanessa
Nouveau PC ASUS TUF GAMING A17 GPU RTX 4070 CPU AMD Ryzen 9 7940HS w/ Radeon 780M Graphics / Linux Mint 21.2 Victoria / Kernel: 6.4.8-1-liquorix / Desktop: Cinnamon

Hors ligne

#280 Le 26/06/2012, à 06:47

ljere

Re : Topic des lève-tôt… Faisons manger leurs caleçons aux couche-tard! [4]

merci pour ton aide j'ai donc testé ton script qui me retourne la même erreur que voici

 python script_mindiell.py 
lecture de la page http://forum.ubuntu-fr.org/viewtopic.php?id=9643511
page récupéré, travail en cours
Traceback (most recent call last):
  File "script_mindiell.py", line 628, in <module>
    main("url",["count","count10days"])
  File "script_mindiell.py", line 522, in main
    res = getPage(url, entries, stats, urlscore)
  File "script_mindiell.py", line 334, in getPage
    if str(page.find('p','pagelink conl')).split('conl">')[1].split('</p')[0].split(str(page.find('p','pagelink conl').find('strong'))) == ['', '']:
IndexError: list index out of range

ancien PC Toshiba satellite_c670d-11 / Linux Mint 21 Vanessa
Nouveau PC ASUS TUF GAMING A17 GPU RTX 4070 CPU AMD Ryzen 9 7940HS w/ Radeon 780M Graphics / Linux Mint 21.2 Victoria / Kernel: 6.4.8-1-liquorix / Desktop: Cinnamon

Hors ligne

#281 Le 26/06/2012, à 06:49

Mindiell

Re : Topic des lève-tôt… Faisons manger leurs caleçons aux couche-tard! [4]

'jour

@ljere: Attention hein, j'ai repris celui donné il y a quelque temps par toi et je l'ai surtout annoté smile
Je regarde ça au boulot wink

Hors ligne

#282 Le 26/06/2012, à 07:18

ljere

Re : Topic des lève-tôt… Faisons manger leurs caleçons aux couche-tard! [4]

Scores totaux, depuis le début :

1) 49    1    herewegoagain
1) 49    1    TheUploader
1) 49    1    Kyansaa
1) 49    1    Xiti29
5) 45    3    Phoenamandre
5) 45    3    gonzolero
5) 45    3    helly
5) 45    3    Le Rouge
9) 43    4    Morgiver
9) 43    4    :!pakman
11) 36    6    wiscot
11) 36    6    timsy
11) 36    6    Slystone
11) 36    6    Hibou57
11) 36    6    tshirtman
11) 36    6    marting
11) 36    6    c4nuser
18) 32    10    Phoenix
18) 32    10    FLOZz
18) 32    10    sakul
18) 32    10    SopolesRâ
22) 31    13    Le grand rohr sha
23) 30    18    Ju
24) 29    22    marinmarais
25) 28    38    Atem18
26) 27    39    Clem_ufo
27) 26    40    Biaise
28) 24    42    nakraïou
28) 24    42    DaveNull
30) 23    43    Crocoii
31) 21    52    1101011
31) 21    52    jeyenkil
33) 20    60    Niltugor
34) 19    61    agarwood
35) 18    77    ljere
36) 17    99    karameloneboudeplus
37) 16    101    nathéo
38) 15    117    edge_one
39) 14    176    pololasi
40) 13    219    Πυλάδης
41) 12    277    omc
42) 11    318    mindiell
43) 10    359    golgoth42
44) 9    428    peterp@n
45) 8    552    Arcans
46) 7    808    raspouillas
47) 6    1017    Ras&#039;
48) 5    1239    souen
49) 4    1247    Azurea
50) 3    1463    MdMax
50) 3    raspouillas
50) 3    souen
50) 3    Ras&amp;#039;
50) 3    ljere
50) 3    Mindiell
56) 2    1566    pierguiard
57) 1    1835    FloydPepper

RépartitionPosts/heure


ancien PC Toshiba satellite_c670d-11 / Linux Mint 21 Vanessa
Nouveau PC ASUS TUF GAMING A17 GPU RTX 4070 CPU AMD Ryzen 9 7940HS w/ Radeon 780M Graphics / Linux Mint 21.2 Victoria / Kernel: 6.4.8-1-liquorix / Desktop: Cinnamon

Hors ligne

#283 Le 26/06/2012, à 07:20

ljere

Re : Topic des lève-tôt… Faisons manger leurs caleçons aux couche-tard! [4]

il y a du mieux par contre il faut enlever count 10 le camembert et l'histogramme en baton
on a jamais été aussi prés la mise en page je dois pouvoir le regler


ancien PC Toshiba satellite_c670d-11 / Linux Mint 21 Vanessa
Nouveau PC ASUS TUF GAMING A17 GPU RTX 4070 CPU AMD Ryzen 9 7940HS w/ Radeon 780M Graphics / Linux Mint 21.2 Victoria / Kernel: 6.4.8-1-liquorix / Desktop: Cinnamon

Hors ligne

#284 Le 26/06/2012, à 07:55

souen

Re : Topic des lève-tôt… Faisons manger leurs caleçons aux couche-tard! [4]

Allez, histoire de vous donner du courage!
http://lesjoiesducode.tumblr.com/


...

Hors ligne

#285 Le 26/06/2012, à 08:28

Ras&#039;

Re : Topic des lève-tôt… Faisons manger leurs caleçons aux couche-tard! [4]

Euh, au delà du fait qu'il n'est pas trié dans le bon sens, il est super buggé le compteur, non ?


Va t'faire shampouiner par le compteur_V2 en timezone[Canada/Eastern] !
 
Les types awesome n'ont rien à prouver. À personne.
'k bye là

Hors ligne

#286 Le 26/06/2012, à 08:50

ljere

Re : Topic des lève-tôt… Faisons manger leurs caleçons aux couche-tard! [4]

c'est surement pour ça qu'on travail dessus wink


ancien PC Toshiba satellite_c670d-11 / Linux Mint 21 Vanessa
Nouveau PC ASUS TUF GAMING A17 GPU RTX 4070 CPU AMD Ryzen 9 7940HS w/ Radeon 780M Graphics / Linux Mint 21.2 Victoria / Kernel: 6.4.8-1-liquorix / Desktop: Cinnamon

Hors ligne

#287 Le 26/06/2012, à 09:13

ljere

Re : Topic des lève-tôt… Faisons manger leurs caleçons aux couche-tard! [4]

Scores totaux, depuis le début :

1) 1829    FloydPepper
2) 1560    pierguiard
3) 1463    MdMax
4) 1247    Azurea
5) 1236    souen
6) 1007    Ras&#039;
7) 811    raspouillas
8) 552    Arcans
9) 428    peterp@n
10) 359    golgoth42
11) 315    mindiell
12) 277    omc
13) 219    Πυλάδης
14) 176    pololasi
15) 117    edge_one
16) 101    nathéo
17) 99    karameloneboudeplus
18) 79    ljere
19) 61    agarwood
20) 60    Niltugor
21) 52    1101011
21) 52    jeyenkil
23) 43    Crocoii
24) 42    nakraïou
24) 42    DaveNull
26) 40    Biaise
27) 39    Clem_ufo
28) 38    Atem18
29) 22    marinmarais
30) 18    Ju
31) 13    Le grand rohr sha
32) 10    Phoenix
32) 10    FLOZz
32) 10    sakul
32) 10    SopolesRâ
36) 6    wiscot
36) 6    timsy
36) 6    Slystone
36) 6    Hibou57
36) 6    tshirtman
36) 6    marting
36) 6    c4nuser
36) 6    Ras&amp;#039;
36) 6    diahovez
36) 6    Floyd Pepper
46) 4    Morgiver
46) 4    :!pakman
48) 3    Phoenamandre
48) 3    gonzolero
48) 3    helly
48) 3    Le Rouge
52) 1    herewegoagain
52) 1    TheUploader
52) 1    Kyansaa
52) 1    Xiti29

ancien PC Toshiba satellite_c670d-11 / Linux Mint 21 Vanessa
Nouveau PC ASUS TUF GAMING A17 GPU RTX 4070 CPU AMD Ryzen 9 7940HS w/ Radeon 780M Graphics / Linux Mint 21.2 Victoria / Kernel: 6.4.8-1-liquorix / Desktop: Cinnamon

Hors ligne

#288 Le 26/06/2012, à 09:16

ljere

Re : Topic des lève-tôt… Faisons manger leurs caleçons aux couche-tard! [4]

voila grâce à Mindiell j'ai réussi à remettre en route ce script demain on testera donc le bot sur le serveur prévu pour 9h15


ancien PC Toshiba satellite_c670d-11 / Linux Mint 21 Vanessa
Nouveau PC ASUS TUF GAMING A17 GPU RTX 4070 CPU AMD Ryzen 9 7940HS w/ Radeon 780M Graphics / Linux Mint 21.2 Victoria / Kernel: 6.4.8-1-liquorix / Desktop: Cinnamon

Hors ligne

#289 Le 26/06/2012, à 09:27

Mindiell

Re : Topic des lève-tôt… Faisons manger leurs caleçons aux couche-tard! [4]

ljere a écrit :

merci pour ton aide j'ai donc testé ton script qui me retourne la même erreur que voici

if str(page.find('p','pagelink conl')).split('conl">')[1].split('</p')[0].split(str(page.find('p','pagelink conl').find('strong'))) == ['', '']:
IndexError: list index out of range

Oui, cette partie est problématique, je n'ai pas réussi à la faire dans ma tête, il manque un truc smile
En fait, apparemment, cela vérifie qu'on est sur une discussion à une seule page, mais ça ne fonctionne pas (plus ?).

Le if lui-même est assez complexe, ce que je n'aime pas trop, décomposons le :

# Trouve le paragraphe contenant les liens vers les pages de la discussion
p = str(page.find('p','pagelink conl'))
# Récupère le contenu de l'élement p
p = p.split('conl">')[1].split('</p')[0]
# Trouve l'élément strong de la page sur laquelle on est dans le paragraphe des pages de la discussion
strong = str(page.find('p','pagelink conl').find('strong'))
# Récupère l'ensemble des éléments coupés au niveau du strong
p.split(strong)

Le problème est qu'ici, si le strong se trouve en dernière position, on obtient alors le contenu de p ("Pages : ...") et c'est tout.
Je pense qu'il serait plus judicieux de faire un findAll('a') et de vérifier que l'ensemble est vide : pas de lien => pas plusieurs pages dans la discussion.

EDIT: Bon, apparemment tu t'es débrouillé sans. Tu pourras me fournir le script final ? Tu as continué sur le tien ou tu es reparti sur ma bafouille ? Si c'est la première réponse, j'espère que tu l'as commenté ! tongue

Dernière modification par Mindiell (Le 26/06/2012, à 09:29)

Hors ligne

#290 Le 26/06/2012, à 10:21

ljere

Re : Topic des lève-tôt… Faisons manger leurs caleçons aux couche-tard! [4]

voici le script légèrement modifié

#!/usr/bin/env python
# -*- coding: utf-8 -*-

# ========================================================================================
#
# Script revu et modifié par Thomas Bouchet
# auteur originel Gabriel Pettier
# license GPL V3 or later
#
# Mise sur plusieurs lignes des commandes et ajout de commentaires
# Modification utilisée pour fonctionnement sur le Topic des Lève-Tôt
#
# Description :
# Ce script permet de comptabiliser les points engrangés par les utilisateurs sur un sujet
# d'un forum suivant l'heure à laquelle ils laissent un message.
# Les résultats sont affichés régulièrement sur le sujet par un compte spécifique appelé
# "bot" (qu'il faut donc inscrire à la main pour le bon fonctionnement du script).
# Les points des différents utilisateurs sont conservés dans un fichier nommé "count"
# et "count10days"
#
# ========================================================================================



# -----------------------------------------------
# Ajout de bibliothèques utiles
# -----------------------------------------------

# BeautifulSoup est une librairie permettant d'analyser un arbre (du HTML ici)
from BeautifulSoup import BeautifulSoup
# urllib2 est une librairie permettant d'ouvrir des URLs simplement (plutôt en HTTP ici)
import urllib2
# re est une librairie permettant d'utiliser les expressions rationnelles (regular expressions)
import re
# time est une librairie de fonctions liées à la manipulation des dates
import time
# sys est une librairie permettant d'utiliser les fonctionnalités de base du langage python
import sys
# mechanize est une librairie permettant de gérer des objets HTML comme les formulaires
import mechanize

# -----------------------------------------------
# Initialisations
# -----------------------------------------------

# Ceci est une liste des utilisateurs à ne pas prendre en compte. On y mettra notamment le nom de
# l'utilisateur utilisé par le "bot"
ignoreList = (
    'compteur des leve tot',
    )


# -----------------------------------------------
# Class Day
#
# Cette classe permet de manipuler les utilisateurs et leurs points par jour. La classe contient
# donc les points par joueur du jour actuel.
#
# Pour des raisons propres au sujet qui nous intéresse (compteur des lève-tôts), la comptabilisation
# des points se fait entre 5 heures et 9 heures du matin exclu ([5h;9h[). Le reste ne sera donc pas
# pris en compte.
#
# Attributs :
#     - entries : le tableau contenant les points de chaque joueur
#
# Méthodes spécifiques :
#     - addEntry : Fonction permettant l'ajout d'un enregistrement dans le tableau des joueurs
#                  Cette fonction permet aussi la mise à jour du nombre de points d'un joueur déjà existant
#
# -----------------------------------------------
class Day:
    # Description de la classe
    """Contient la derniere entrée (points) de ce jour pour chaque joueur"""

    # Cette fonction initialise le tableau des utilisateurs lors de l'instanciation de la classe
    def __init__(self):
        self.entries={}

    # Cette fonction permet d'ajouter un utilisateur et de le lier à son nombre de points
    # On utilise : entries['utilisateur'] = nb_points
    def addEntry(self, entry):
        # Si l'utilisateur existe déjà, on lui attribue le nouveau nombre de moins à condition
        # que celui-ci soit supérieur à l'ancien nombre de points.
        # Pour des raisons de légereté du code, il est plus simple de faire un try/except que de verifier
        # que l'entrée existe
        try:
            self.entries[entry.name] = max(self.entries[entry.name],entry.date.points())
        except:
            self.entries[entry.name] = entry.date.points()

    # Cette fonction permet d'afficher la classe sous forme de chaine de caractères.
    # Ici, on affiche la liste de chaque utilisateur suivi de son nombre de points
    def __str__(self):
        for entry in self.entries.items():
            print entry,'+',entries[entry]



# -----------------------------------------------
# Fonction utcFrance
#
# Cette fonction renvoie le décalage horaire a appliquer.
#
# Dans le cas spécifique qui nous préoccupe, le script est utilisé en France, un simple +1 suffit
# alors à déterminer le décalage horaire, sachant que le résultat renvoyé sera 1 ou 2 suivant si la machine hébergeant
# le script est en heures d'été ou pas.
#
# -----------------------------------------------
def utcFrance():
    #1 + 1 si on est a l'heure d'été
    return 1 + time.localtime(time.time())[-1]


# -----------------------------------------------
# Class Date
#
# Cette classe permet de calculer le nombre de points qu'un utilisateur devra recevoir suivant l'heure
# à laquelle il a écrit son message.
#
# Pour des raisons propres au sujet qui nous intéresse, un utilisateur écrivant entre :
# 5h00 et 5h59 recevra 10 points
# 6h00 et 6h59 recevra 6 points
# 7h00 et 7h59 recevra 3 points
# 8h00 et 8h59 recevra 1 point
#
# Attributs :
#     - h : entier représentant une heure
#     - m : entier représentant les minutes
#
# Méthodes spécifiques :
#     - points : qui renvoie le nombre de points à donner pour une heure spécifique
#
# -----------------------------------------------
class Date:
    # Description de la classe

    # Cette fonction initialise deux entiers de la classe : h et m (hu hu hu, quel jeu de mot !)
    # Si aucune donnée n'est fournie, h et m sont initialisés avec 20 et 0, et utc vaut utcFrance()
    def __init__(self,tuple=(20,0),utc=utcFrance()):
        # h est initialisé suivant l'heure donnée et le décalage horaire
        self.h = (int(tuple[0])-utcFrance()+24+utc)%24
        # m est initialisé suivant la minute donnée
        self.m = int(tuple[1])

    # Cette fonction permet de comparer l'objet à un autre objet équivalent
    # Ici, la comparaison se fait sur le nombre de points entre les deux classes
    def __cmp__(self, other):
        return cmp(self.points(),other.points())

    # Cette fonction permet de connaitre le nombre de points à donner à un utilisateur suivant une heure spécifiée
    # Si l'heure correspondante n'est pas trouvée, la fonction retourne 0
    def points(self):
        # Instanciation d'un dictionnaire (clé: valeur)
        pts =  {5: 10, 6: 6, 7: 3, 8: 1}
        # Si la clé n'est pas trouvée, retourne 0
        return pts.get(self.h, 0)


# -----------------------------------------------
# Class Entry
#
# Cette classe permet de lister les méta-données nécessaires de chaque message afin de calculer les points
# des utilisateurs.
#
# Pour des raisons propres au sujet qui nous intéresse
#
# Attributs :
#     - name : Nom de l'utilisateur ayant laissé un message sur le forum
#     - date : Date du message laissé par l'utilisateur
#
# Méthodes spécifiques :
#     - setName : permet de spécifier un nom d'utilisateur
#     - setDate : permet de spécifier une date
#
# -----------------------------------------------
class Entry:
    # Description de la classe

    # Cette fonction initialise les attributs de la classe suivant les données fournies
    def __init__(self,name='',date=Date(),edit=Date()):
        self.name = name
        #self.date = max(date,edit)
        # Contrairement au topic des couche-tard, l'édition d'un message n'est pas pris en compte pour le topic
        # des lève-tôt
        self.date = date

    # Cette fonction permet de spécifier un nom d'utilisateur après l'instanciation de la classe
    def setName(self, name):
        self.name = name

    # Cette fonction permet de spécifier une date après l'instanciation de la classe
    def setDate(self, date):
        if date.points()>self.date.points(): self.date = date


# -----------------------------------------------
# Class Score
#
# Cette classe permet de lister le classement des utilisateurs.
#
# Attributs :
#     - name : Nom de l'utilisateur ayant laissé un message sur le forum
#     - num : Score de l'utilisateur
#
# Méthodes spécifiques :
#
# -----------------------------------------------
class Score:
    # Description de la classe

    # Cette fonction initialise les attributs de la classe suivant les données fournies
    def __init__(self, tuple):
        self.name = tuple[1]
        self.num = int(tuple[0])

    # Cette fonction permet de vérifier si l'objet est plus grand qu'un autre objet équivalent
    # Ici, la comparaison se fait sur num (le score de l'utilisateur)
    def __gt__(self, other):
        return self.num>other.num

    # Cette fonction permet d'afficher la classe sous forme de chaine de caractères.
    # Ici, cela permet d'afficher le score de l'utilisateur suivi de son nom
    def __str__(self):
        return '%i    %s' %(self.num, self.name)


# -----------------------------------------------
# Fonction getPage
#
# Cette fonction récupère la page de la discussion spécifique du forum et comptabilise les points
# des utilisateurs qui ont écrits dessus
#
# Dans le cas spécifique qui nous préoccupe, tout le code de la fonction est très spécifique
# au forum et aux css utilisés (ici, ubuntu-fr.org)
#
# -----------------------------------------------
def getPage(url, entries, stat, urlscore):
    # Essaye jusqu'a 15 fois de récupérer la page
    for i in range(15):
        try:
            # page contiendra le contenu de l'url recherchée
            page = BeautifulSoup(urllib2.urlopen(url))
            break
        except:
            print 'essai: %s' % i
            # Lors de la dernière tentative, la main est rendue au gestionnaire d'erreur principal
            if i==14: raise
            # A chaque tentative non réussie, un délai de 60 secondes est attendu pour ne pas submerger le serveur
            time.sleep(60)

    # Le print permet de tracer le travail du script à condition de lancer le script à la main ou bien
    # de rediriger la sortie du script vers un fichier lorsqu'on utilise un cron pour l'exécuter
    print 'page récupéré, travail en cours'

    # ============ ATTENTION ==================
    # A partir de là, le code est très spécifique au contenu HTML des pages du forum

    # Parcours de chaque élément DIV de la page contenant un message
    for post in page.findAll("div","blockpost rowodd blockpost1")+page.findAll("div","blockpost roweven")+page.findAll("div","blockpost rowodd"):
    # post contient donc le contenu du DIV complet

        # Récupération du contenu du lien vers le message
        str_date = str(post.find("h2").find("span").find("a"))

        # Découpage du lien afin de supprimer le tag ancre

        # On conserve la partie située après le premier caractère ">"
        str_date = str_date.split('>')[1]
        # On conserve la partie située avant le premier caractère "<"
        str_date = str_date.split('<')[0]

        # str_date contient alors quelque chose comme l'un des trois exemples ci-dessous:
        # Le XX/XX/XXXX, à XX:XX
        # Hier à XX:XX
        # Aujourd'hui à XX:XX

        # hh_mm est un tableau qui contient l'heure et la minute du message
        hh_mm = str_date.split(' ')[2].split(':')

        # Si str_date contient Aujourd'hui et que l'heure du message est située entre 5 et 8
        if (str_date.split(' ')[0] in ["Aujourd\'hui"]
             and int(hh_mm[0]) in range(5,8)
           ):

            # On a trouvé au moins un message qui contient un score, on stocke donc l'url
            urlscore = url

            # Récupération du nom de l'utilisateur qui a écrit le message et création d'une
            # instance de la classe Entry avec le nom récupéré
            # Le nom de l'utilisateur est soit situé dans un lien (s'il a un profil), soit directement
            # dans le tag strong (s'il n'a pas de profil)
            try:
                entry = Entry(str(post.find("div","postleft").find("a")).split(">")[1].split("<")[0])
            except:
                entry = Entry(str(post.find("div","postleft").find("strong")).split(">")[1].split("<")[0])

            # Spécification du décalage horaire par défaut du message
            utc = utcFrance()

            # Si la chaine GMT est trouvée dans le message de l'utilisateur, on récupère le décalage horaire
            # et on l'applique à la variable utc
            if 'GMT' in str(post):
                try:
                    utc = int(str(post).split("GMT")[-1].split(" ")[0].split("<")[0])
                    print 'GMT found',utc
                except:
                    print "no good GMT!"

            # La date de l'instance de la classe Entry est alors spécifiée en donnant un tableau de 2 entiers
            # correspondant à l'heure et à la minute du message et le décalage horaire
            entry.setDate(Date(hh_mm,utc))

            # On note le nombre de messages ayant obtenu des points par heure pour effectuer des statistiques
            if hh_mm[0] not in stat:
                stat[hh_mm[0]] = 1
            else:
                stat[hh_mm[0]] += 1

            # L'entrée est alors ajoutée à la liste des entrées uniquement si l'utilisateur ne doit pas être ignoré
            # et si les points associés à l'entrée sont supérieurs à 0
            if entry.name not in ignoreList and (entry.date.points() is not 0): entries.addEntry(entry)

        # Fin du if
    # Fin du parcours des messages


    # Ici, on vérifie si l'on relance le script pour atteindre la page suivante, car les messages peuvent être dispersés sur plusieurs
    # pages. On le fera si result vaut True, ce qui arrive uniquement si on a plusieurs pages et que la page sur laquelle on se situe
    # n'est pas la dernière de la discussion

    # S'il n'y a qu'une seule page dans la discussion, result vaut False
    if str(page.find('p','pagelink conl')).split('conl">')[1].split('</p')[0].split(str(page.find('p','pagelink conl').find('strong'))) == ['', '']:
        result = False
    else:
        # Sinon, on renvoie True si le numéro de la dernière page est plus grand que la page surlaquelle on est
        try:
            result = int(url.split('p=')[1]) < int(str(page.find('p','pagelink conl').findAll('a')[-2]).split('p=')[1].split('"')[0])
        except IndexError:
            result = False

    # Si on est arrivé au bout de la discussion, il faut, en plus, vérifier que la discussion ne continue pas sur une autre discussion
    # Ce procédé est utilisé sur le forum quand une discussion atteint trop de pages pour éclaircir le forum
    if not result:

        # Si la page contient la chaine "Discussion fermée" dans un paragraphe spécifique
        if "Discussion fermée" in ''.join( (str( i) for i in page.findAll('p','postlink conr'))):

            # Récupération du lien vers la nouvelle discussion
            result = str(page.findAll('div','postmsg')[-1].findAll('a')[-1]).split('"')[1]

    # Finalement, la fonction renvoie result et urlscore
    return result, urlscore

# -----------------------------------------------
# Fonction renderstats
#
# Cette fonction crée deux graphiques permettant de représenter les répartitions de messages par heure pour la journée
#
# -----------------------------------------------
# def renderstats(stats):
    # Si le dictionnaire stats contient quelque chose
#     if stats != {}:

        # Création d'un dictionnaire pour la journée
#         DayStats = {'00': 0, '01': 0, '02': 0, '03': 0, '04': 0, '05': 0, '06': 0, '07': 0, '08': 0, '09': 0, '10': 0, '11': 0, '12': 0, '13': 0, '14': 0, '15': 0, '16': 0, # '17': 0, '18': 0, '19': 0, '20': 0, '21': 0, '22': 0, '23': 0}
        # Copie des valeurs des clés existantes ce qui permet d'avoir un tableau contenant toutes les heures
#         DayStats.update(stats)

        # ============ ATTENTION ==================
        # Le reste de cette fonction n'est pas commenté car elle ne sert qu'à des fins statistiques et que j'ai autre chose à faire ;oP
#         HoursBar = 'h|'.join(sorted(DayStats.keys()))+'h'
#         HoursBar = HoursBar[20:]+'|'+HoursBar[:19]
#         HoursBar = HoursBar[0:len(HoursBar)-1]
#         HoursPie = 'h|'.join(sorted(stats.keys()))+'h'
#         for k in stats.keys():
#             HoursPie = HoursPie.replace(k+'h', k+'h%20-%20'+k+'h59')

#         DataBar = ','.join([str(DayStats[x]) for x in sorted(DayStats.keys())])
#         DataBar = ','.join(DataBar.split(',')[5:24])+','+','.join(DataBar.split(',')[0:5])
#         Vmax10 = str(10*(int(max([DayStats[x] for x in DayStats.keys()]))/10+1))

#         urlimage='[img=Répartition]http://chart.apis.google.com/chart?chs=675x280&cht=p3&chco=d80020,d88000,ffd840,20d820,2080ff,101080,a020d8&chf=bg,s,00000000&chl='+HoursPie+'&chd=t:'+','.join([str(stats[x]) for x in sorted(stats.keys())])+'&chp=1.6&chtt=R%C3%A9partition%20des%20posts&chts=606060,16[/img]'

#         urlimage+='[img=Posts/heure]http://chart.apis.google.com/chart?chs=675x280&cht=bvs&chxt=x,y&chds=0,'+Vmax10+'&chxr=1,0,'+Vmax10+((Vmax10 == '30' and ',5') or '')+'&chf=b0,lg,0,803000,0,ffc080,1|bg,s,00000000&chxl=0:|'+HoursBar+'h'+'&chxp=0,0.7,4.9,9.1,13.2,17.3,21.5,25.6,29.8,33.9,38,42.2,46.3,50.5,54.6,58.8,62.9,67,71.2,75.3,79.4,83.6,87.7,91.8,96&chd=t:'+DataBar+'&chm=N,803000,0,-1,12&chtt=|Nombre%20de%20posts%20par%20heure&chts=606060,16[/img]'

#         return urlimage

#     return None



# -----------------------------------------------
# Fonction post
#
# Cette fonction permet au "bot" d'écrire un message qui récapitule les scores des utilisateurs
#
# Dans le cas spécifique qui nous préoccupe, le fichier '.compteur_logins' doit contenir le login du posteur sur la première ligne,
# et son mot de passe sur la deuxième (cela et seulement cela).
#
# -----------------------------------------------
def post(_file, stats):
    # Récupération de l'identifiant et du mot de passe du "bot" qui va lire, analyser, puis poster le résultat dans la discussion
    file = open(".compteur_logins","r")
    login = file.readline().split('\n')[0]
    password = file.readline().split('\n')[0]
    file.close()

    # Instsanciation d'un Cookie géré par la librairie mechanize
    cookieJar = mechanize.CookieJar()

    # Création d'un navigateur spécifique pour le "bot" et liaison avec le cooki
    # Désormais, les différents appels de pages webs se feront en appui des informations de session
    # conservées dans le Cookie
    opener = mechanize.build_opener(mechanize.HTTPCookieProcessor(cookieJar))
    opener.addheaders = [("User-agent","Mozilla/5.0 (compatible)")]
    mechanize.install_opener(opener)

    # Appel du formulaire de connexion
    fp = mechanize.urlopen("http://forum.ubuntu-fr.org/login.php")
    forms = mechanize.ParseResponse(fp)
    fp.close()

    # Remplissage du formulaire de connexion et validation de celui-ci
    form = forms[1]
    form["req_username"] = login
    form["req_password"] = password
    fp = mechanize.urlopen(form.click())
    fp.close()

    # ouverture du fichier url contenant l'adresse de la discussion à analyser
    file = open('url','r')
    tid = file.readline().split('=')[1][:-2] # la première ligne contenant l'addresse du topic.
    file.close()

    # Ouverture du formulaire permettant d'ajouter un message dans une discussion
    fp = mechanize.urlopen("http://forum.ubuntu-fr.org/post.php?tid="+tid)
    forms = mechanize.ParseResponse(fp)
    fp.close()

    # Trace des informations utilisées
    print "http://forum.ubuntu-fr.org/post.php?tid="+tid
    print forms[0]

    form = forms[1]

    # Préparation du message : Titre du message suivant l'action demandée à l'appel de la fonction
    # via son paramètre _file
    title = ((_file == "count") and "Scores totaux, depuis le début")

    # Préparation du message : Ajout de la balise [cade]
    # Les codes hexadécimaux utilisés à la suite de la balise code servent surement à quelque chose
    form["req_message"]  = title+" :[cade]"

    # Récupération des scores enregistrés dans le fichier correspondant
    file = open(_file, 'r')
    scores=file.readlines()

    # Création des images statistiques si demandées
#     urlimage = renderstats(stats)
#     stats = {}

    # Pour chaque score lu à partir du fichier
    for i in range(len(scores)):
        # La variable tmpRange contient le classement des utilisateurs par rapport à leur score
        # Pour la première ligne, on initialise donc tmpRange à 0
        if i == 0:
            tmpRange = 0
        # Si le score déjà lu est le même que celui qu'on vient de lire, la position du classement reste la même
        elif scores[i].split(" ")[0] == scores[i-1].split(" ")[0]:
            pass
        # Sinon, on augmente la place dans le classement
        else:
            tmpRange = i

        # Préparation du message : Ajout du classement, du score, et du nom de l'utilisateur
        # C'est ici que l'on peut gérer les noms spécifiques et/ou les annonces spécifiques pour un
        # utilisateur
        form["req_message"] += (str(tmpRange+1)+") "+scores[i])

    # Le message contient donc tous les scores, il est conclut en fermant la balise [cade]
    # Si les statistiques sont demandées, les images correspondantes sont rajoutées après
    form["req_message"] += "[/cade]" # +(urlimage or '')

    # Validation du formulaire
    fp = mechanize.urlopen(form.click())
    fp.close()


# -----------------------------------------------
# Fonction main
#
# Cette fonction est la fonction principale qui gère tout le reste
#
# Dans le cas spécifique qui nous préoccupe,
#
# -----------------------------------------------
def main(urlfile, files):
    # Pour debugger le script ou pas
    debug = False
    # Initialisation du tableau des statistiques
    stats = {}

    # Ouverture du fichier contenant l'url de la discussion à analyser
    f=open(urlfile,"r")

    # Stockage du numéro de la discusion (topic id : tid)
    url=urlscore=f.readline().split('\n')[0]
    f.close()

    # Instanciation de la classe Day
    entries = Day()

    # Boucle infinie permettant de comptabiliser les scores des utilisateurs
    while True:

        # Trace
        print "lecture de la page "+url

        # Premier comptage des points sur la dernière page visitée (la dernière fois que le script a été lancé)
        res = getPage(url, entries, stats, urlscore)

        # Récupération de l'url à réutiliser la prochaine fois
        urlscore = res[1]

        # Si la fin de discussion a été trouvée (result de getPAge vaut False), sortie de la boucle
        if not res[0]: break

        # Sinon, on recherche l'url de la même discussion mais page suivante à analyser
        url=url.split('p=')[0]+'p='+str(1+int(url.split('p=')[1]))
        # Ou bien, on repart sur l'url donnée d'une nouvelle discussion
        if res[0] is not True:
            url = url.split('?')[0]+'?'+res[0].split('?')[1]+'&p=1'

    # Sauvegarde l'url utilisée en dernier (nouvelle page ou discussion) pour la prochaine fois
    if not debug:
        f=open(urlfile,"w")
        f.write(urlscore+'\n')
        f.close()

    # Pour chaque type de travail à faire
    for file in files:

        # Ouverture du fichier correspondant
        f=open(file,'r')

        # Lecture des lignes du fichier
        # Pour l'action 10days, le 2 du mois tout est remis à zéro (ce qui fait plus 1month que 10days d'ailleurs)
        lines=(file=="count10days" and ((time.localtime()[2]==2 and ["0    "+entries.entries.keys()[0]+"\n"]) or f.readlines()) or f.readlines())
        f.close()

        # Expression régulière permettant de récupérer le score, puis le nom séparés par un nombre quelconque d'espaces
        exp = re.compile("^[0-9]+\s*")

        # Initialisation de la liste des scores
        scores = []
        print "lecture scores courants"
        # Remplissage du tableau des scores ligne par ligne
        for line in lines:
            # Si la ligne n'est pas vide
            if line not in [' ','']:
               print line
               # Création d'une instance de la classe Score aussitôt stockée dans le tableau scores
               # et contenant le score, suivi du nom
               scores.append(Score([(line.split(' ')[0]),exp.split(line)[1].split('\n')[0]]))

        # Initialisation des nouveaux scores
        new_scores=[]
        # Remplissage du tableau des nouveaux scores et mise à jour des anciens scores suivant la liste des utilisateurs
        # ayant gagné des points
        for entry,num in entries.entries.items():
            # Sous-boucle permettant de chercher si un utilisateur existe déjà
            for score in scores:
                # Comparaison des noms d'utilisateurs en casse basse
                if entry.lower() == score.name.lower():
                    # L'utilisateur existant, on ajoute son ancien score au nouveau
                    score.num+=num
                    # Puis on quitte la sous-boucle
                    break
                if score is scores[-1]:
                    # L'utilisateur n'existe pas encore, on rajoute donc son score au tableau des nouveaux scores
                    new_scores.append(Score([num,entry]))
                    break

        # Les deux tableaux sont joints afin de contenir tous les scores
        scores+=new_scores

        # Vérification des doublons
        for nScore in range(len(scores)-1):
            for mScore in range(nScore+1,len(scores)-1):
                try:
                    # En cas de doublon
                    if scores[nScore].name.lower() == scores[mScore].name.lower():
                        # les scores sont sommés
                        scores[nScore].num+=scores[mScore].num
                        # puis le doublon est détruit
                        del(scores[mScore])
                except:
                    pass

        # Tri des scores du plus grand au plus petit
        scores.sort(reverse=True)

        # Sauvegarde des scores dans le fichier correspondant
        if not debug:
            # Trace
            for score in scores: print score

            # Ecriture des scores
            f=open(file, "w")
            for score in scores:
                f.write('%s\n'%score)
            f.close()

            # Essai 15 fois maximum d'écrire le message des scores
            for i in range(15):
                try:
                    post(file, stats)
                    stats = {}
                    break
                except:
                    if i == 14: raise
                    time.sleep(60)
        time.sleep(10)

# Lancement de la fonction principale
main("url",["count"])

# Action à lancer pour ne faire qu'une seule fonction à la main (en général pour le debug)
#post("count",{})
#post("count10days",{})

ancien PC Toshiba satellite_c670d-11 / Linux Mint 21 Vanessa
Nouveau PC ASUS TUF GAMING A17 GPU RTX 4070 CPU AMD Ryzen 9 7940HS w/ Radeon 780M Graphics / Linux Mint 21.2 Victoria / Kernel: 6.4.8-1-liquorix / Desktop: Cinnamon

Hors ligne

#291 Le 26/06/2012, à 11:38

Mindiell

Re : Topic des lève-tôt… Faisons manger leurs caleçons aux couche-tard! [4]

Bon, alors quelques petites choses :
- Stocke le quelque part,
- Mets le accessible dans la signature du bottillon
- Rajoute-toi dans les auteurs ! Non mais !
- Tu as mis des balises [cade][/cade] au lieu de [ code], c'est normal ?

PS: en même temps, après réflexion, si tu veux poster le code source et qu'il contient lui-même une balise code fermante... Disons que j'ai rien dit, mais je le laisse pour pouvoir me rappeler combien je parle sans réfléchir wink

Dernière modification par Mindiell (Le 26/06/2012, à 11:39)

Hors ligne

#292 Le 26/06/2012, à 17:48

diahovez

Re : Topic des lève-tôt… Faisons manger leurs caleçons aux couche-tard! [4]

Maintenant,je suis le dernier !
Le script du Compteur à disparu ?

#293 Le 26/06/2012, à 18:24

PPdM

Re : Topic des lève-tôt… Faisons manger leurs caleçons aux couche-tard! [4]

Salut levé a la bourre j'ai pas pointé, a 6h30 j’étais sur la route!! yikes


La critique est facile, mais l'art est difficile !
L'humanité étant ce qu'elle est, la liberté ne sera jamais un acquit, mais toujours un droit à défendre !
Pour résoudre un problème commence par poser les bonnes questions, la bonne solution en découlera

Hors ligne

#294 Le 26/06/2012, à 19:04

Floyd Pepper

Re : Topic des lève-tôt… Faisons manger leurs caleçons aux couche-tard! [4]

1    1841    FloydPepper
2    1566    pierguiard
3    1463    MdMax
4    1247    Azurea
5    1242    souen
6    1023    Ras&#039;
7    814    raspouillas
8    552    Arcans
9    428    peterp@n
10    359    golgoth42
11    321    mindiell
12    277    omc
13    219    Πυλάδης
14    176    pololasi
15    117    edge_one
16    101    nathéo
17    99    karameloneboudeplus
18    80    ljere
19    61    agarwood
20    60    Niltugor
21    52    1101011
21    52    jeyenkil
23    43    Crocoii
24    42    nakraïou
24    42    DaveNull
26    40    Biaise
27    39    Clem_ufo
28    38    Atem18
29    22    marinmarais
30    18    Ju
31    13    Le grand rohr sha
32    10    Phoenix
32    10    FLOZz
32    10    sakul
32    10    SopolesRâ
36    6    wiscot
36    6    timsy
36    6    Slystone
36    6    Hibou57
36    6    tshirtman
36    6    marting
36    6    c4nuser
43    4    Morgiver
43    4    :!pakman
45    3    Phoenamandre
45    3    gonzolero
45    3    helly
45    3    Le Rouge
49    1    herewegoagain
49    1    TheUploader
49    1    Kyansaa
49    1    Xiti29

... J'aurais tendance à ne pas utiliser de smilleys.
Le plus tu t'fais chier, le plus t'es emmerdé.

Hors ligne

#295 Le 26/06/2012, à 23:03

Mindiell

Re : Topic des lève-tôt… Faisons manger leurs caleçons aux couche-tard! [4]

ljere a écrit :

voila grâce à Mindiell j'ai réussi à remettre en route ce script demain on testera donc le bot sur le serveur prévu pour 9h15

Bon, ben surtout merci à toi hein smile
Ca m'a fait découvrir le python et j'en ai profité pour faire un script pour nettoyer le Wiki de Framasoft des pages des spammers à la p'tite semaine... Faut encore le fignoler un poil mais c'est bien parti ! cool

PS: Ah ouais, faut qu'j'aille dormir si j'veux récupérer quelques points tout à l'heure ! Aller, à plus les marmottes !

Hors ligne

#296 Le 27/06/2012, à 04:02

Pylades

Re : Topic des lève-tôt… Faisons manger leurs caleçons aux couche-tard! [4]

Il paraît que le compteur tient debout ?

Pour fêter ça, j’prends les points. tongue

Dernière modification par Πυλάδης (Le 27/06/2012, à 04:02)


“Any if-statement is a goto. As are all structured loops.
“And sometimes structure is good. When it’s good, you should use it.
“And sometimes structure is _bad_, and gets into the way, and using a goto is just much clearer.”
                Linus Torvalds – 12 janvier 2003

Hors ligne

#297 Le 27/06/2012, à 04:45

diahovez

Re : Topic des lève-tôt… Faisons manger leurs caleçons aux couche-tard! [4]

Bonjours ...

#298 Le 27/06/2012, à 05:07

PPdM

Re : Topic des lève-tôt… Faisons manger leurs caleçons aux couche-tard! [4]

Salut

Voltaire a écrit :

L'amour-propre est un ballon gonflé de vent dont il sort des tempêtes quand on y fait une piqûre.


La critique est facile, mais l'art est difficile !
L'humanité étant ce qu'elle est, la liberté ne sera jamais un acquit, mais toujours un droit à défendre !
Pour résoudre un problème commence par poser les bonnes questions, la bonne solution en découlera

Hors ligne

#299 Le 27/06/2012, à 05:34

Ras&#039;

Re : Topic des lève-tôt… Faisons manger leurs caleçons aux couche-tard! [4]

neutral


Va t'faire shampouiner par le compteur_V2 en timezone[Canada/Eastern] !
 
Les types awesome n'ont rien à prouver. À personne.
'k bye là

Hors ligne

#300 Le 27/06/2012, à 06:00

Floyd Pepper

Re : Topic des lève-tôt… Faisons manger leurs caleçons aux couche-tard! [4]

'jour


... J'aurais tendance à ne pas utiliser de smilleys.
Le plus tu t'fais chier, le plus t'es emmerdé.

Hors ligne