#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é
Je regarde ça au boulot
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'
48) 5 1239 souen
49) 4 1247 Azurea
50) 3 1463 MdMax
50) 3 raspouillas
50) 3 souen
50) 3 Ras&#039;
50) 3 ljere
50) 3 Mindiell
56) 2 1566 pierguiard
57) 1 1835 FloydPepper
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'
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
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'
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&#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]
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
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é !
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
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!!
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'
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]
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
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 !
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.
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
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'
Re : Topic des lève-tôt… Faisons manger leurs caleçons aux couche-tard! [4]
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