#676 Le 03/02/2019, à 20:22
- Henry de Monfreid
Re : Topic des couche-tard (septante-quatre)
Que voudrais-tu que le code fiche ? Une brandade ?
(comprenne qui peut)
« Je te hais plus qu'aucun des dieux qui vivent sur l'Olympe
Car tu ne rêves que discordes, guerres et combats. »
Trouble obsessionnelcompulsif
Le TdCT est revenu (ils reviennent tous)
Hors ligne
#677 Le 03/02/2019, à 20:33
- UpsideDown
Re : Topic des couche-tard (septante-quatre)
UpsideDown a écrit :[edit)HdP proof, jdç, jdr... [/edit]
[edit2] qui est le petit coquin qui m' volé le Hdp? [/edit]Il te restait au moins 10 messages avant le h d'épée.
euh, j'ai pas viendu ici pendant longtemps, mais quand mon post apparait en hache d'épée, c'est qu'il l'était, je suis con, mais pas totalement abruti
je suis en mode par d"éfaut pour l'affichage des messages, si tu as mis du 50 par pages, forcément, on a pas la même vision
Hors ligne
#678 Le 03/02/2019, à 20:36
- PPdM
Re : Topic des couche-tard (septante-quatre)
Il y avait longtemps !!
Dernière modification par PPdM (Le 03/02/2019, à 20:37)
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
#679 Le 03/02/2019, à 20:38
- nany
Re : Topic des couche-tard (septante-quatre)
@UpsideDown : tu es sûrement victime d’un bug. Le post que tu prétends avoir vu en hdp porte le numéro 688.
En ligne
#680 Le 03/02/2019, à 21:02
- UpsideDown
Re : Topic des couche-tard (septante-quatre)
@UpsideDown : tu es sûrement victime d’un bug. Le post que tu prétends avoir vu en hdp porte le numéro 688.
je suis maudit ^^
même la bête se refuse à moi
ou le 88 veux dire quelque chose, mais non, je n'en suis pas
Hors ligne
#681 Le 03/02/2019, à 21:04
- UpsideDown
Re : Topic des couche-tard (septante-quatre)
juste parce que je content de reviendre
Hors ligne
#682 Le 03/02/2019, à 21:04
- UpsideDown
Re : Topic des couche-tard (septante-quatre)
je m'en vait le chopper ce HdP
Hors ligne
#683 Le 03/02/2019, à 21:05
- UpsideDown
Re : Topic des couche-tard (septante-quatre)
et si ça vous plait pas, c'est pareil, namého!!!
Hors ligne
#684 Le 03/02/2019, à 21:06
- nany
Re : Topic des couche-tard (septante-quatre)
En ligne
#685 Le 03/02/2019, à 21:07
- UpsideDown
Re : Topic des couche-tard (septante-quatre)
tavoir ta gueule à la récré ^^
Hors ligne
#686 Le 03/02/2019, à 21:19
- UpsideDown
Re : Topic des couche-tard (septante-quatre)
Madame, y'a la nounou elle fait rien que des bêtises...
Hors ligne
#687 Le 03/02/2019, à 21:19
- nany
Re : Topic des couche-tard (septante-quatre)
En ligne
#688 Le 03/02/2019, à 21:20
- UpsideDown
Re : Topic des couche-tard (septante-quatre)
plop
Hors ligne
#689 Le 03/02/2019, à 21:21
- UpsideDown
Re : Topic des couche-tard (septante-quatre)
rohh mais euh... le monsieur, elle fait rien qu'à m'énerver....
puisque c'est, boudes, nanère
Hors ligne
#690 Le 03/02/2019, à 21:52
- Mornagest
Re : Topic des couche-tard (septante-quatre)
*montre ses fesses à l'assemblée et s'en va dodo*
N'oubliez pas de consulter la documentation pour vous donner un coup de main !
Merci de modifier le premier message de votre sujet pour ajouter [Résolu] lorsque votre problème l'est :)
Xubuntu 20.04 sur deux ordinateurs, zéro souci. Passez à Xubuntu ;)
Hors ligne
#691 Le 03/02/2019, à 21:59
- jeange
Re : Topic des couche-tard (septante-quatre)
Mornagest montre ses fesses à l'assemblée et s'en va dodo
Pfff!!! ramasses les vû qu'elles sont en goutte d'huile.
CLEVO W670SZQ SSD 480Go i3 Ram 12Go Ubuntu 22.04.4 et 24.04.1 LTS 64bit
Thinkpad X270 nvme 128Go i5 Ram 8Go Ubuntu 24.04 LTS 64bit et W10
Merci de donner les retours avec les balises < > et les allers avec les valises, et toujours pas de raton laveur.
%NOINDEX%
Hors ligne
#692 Le 03/02/2019, à 22:54
- GR 34
Re : Topic des couche-tard (septante-quatre)
Night !
Karantez-vro... Breizhad on ha lorc'h ennon !
«Les animaux sont mes amis. Et je ne mange pas mes amis.» George Bernard Shaw
https://www.l214.com/
Hors ligne
#693 Le 03/02/2019, à 23:13
- Na K' en vadrouille
Re : Topic des couche-tard (septante-quatre)
https://twitter.com/XrayProblems/status … 90373?s=19
Bonne question, j'ai aussi un doute...
Je suis Na Kraïou et j’utilise ce compte pour des raisons de sécurité, quand je suis avec mon smartphone. J'échange trois sodium et deux potassium en scrapant de l'atp en adp.
Je suis un système quantique ondulatoire et très peu dispersé .
Hors ligne
#694 Le 04/02/2019, à 00:02
- moko138
Re : Topic des couche-tard (septante-quatre)
https://twitter.com/XrayProblems/status … 90373?s=19
Bonne question, j'ai aussi un doute...
Ça dépend : c'est posté par Docteur Na K' en vour ou par mister ailled ?
%NOINDEX%
Un utilitaire précieux : ncdu
Photo, mini-tutoriel : À la découverte de dcraw
Hors ligne
#695 Le 04/02/2019, à 00:36
- nany
Re : Topic des couche-tard (septante-quatre)
[Unblacklistme] pour pouvoir tester la remise à zéro demain.
En ligne
#696 Le 04/02/2019, à 00:41
- pierrecastor
Re : Topic des couche-tard (septante-quatre)
Le festival du court métrage à Clermont-Ferrand, ça s'annonce bien.
Oui c'est bien plus ouf et c'est bien bandant
Courir nu la bite à l'air, courir nue la fouffe au vent
Ludwig von 88 - Fracas
Hors ligne
#697 Le 04/02/2019, à 01:43
- Henry de Monfreid
Re : Topic des couche-tard (septante-quatre)
La salle de cinéma "La Jetée", c'est un hommage au chef-d'Œuvre de Chris Marker ?
Vous devez tous avoir vu La Jetée.
« Je te hais plus qu'aucun des dieux qui vivent sur l'Olympe
Car tu ne rêves que discordes, guerres et combats. »
Trouble obsessionnelcompulsif
Le TdCT est revenu (ils reviennent tous)
Hors ligne
#698 Le 04/02/2019, à 01:51
- Henry de Monfreid
Re : Topic des couche-tard (septante-quatre)
Le festival du court métrage à Clermont-Ferrand, ça s'annonce bien.
Le site internet est joli, mais où est le programme ?
(demande à la con de ma part, car le principal intérêt d'un festival, qui plus est de court-métrage, c'est la surprise)
« Je te hais plus qu'aucun des dieux qui vivent sur l'Olympe
Car tu ne rêves que discordes, guerres et combats. »
Trouble obsessionnelcompulsif
Le TdCT est revenu (ils reviennent tous)
Hors ligne
#699 Le 04/02/2019, à 02:44
- moko138
Re : Topic des couche-tard (septante-quatre)
La salle de cinéma "La Jetée", c'est un hommage au chef-d'Œuvre de Chris Marker ?
Vous devez tous avoir vu La Jetée.
Merci de l'info.
%NOINDEX%
Un utilitaire précieux : ncdu
Photo, mini-tutoriel : À la découverte de dcraw
Hors ligne
#700 Le 04/02/2019, à 03:00
- compteur-couche-tard_V2.0
Re : Topic des couche-tard (septante-quatre)
Mon code presque définitif :
$ tree -a | egrep -v "2019|pyc| log|3|└── a"
.
├── archives.sh
├── counter_classlib.py
├── counter_forum.py
├── counter_funclib.py
├── counter_path.py
├── counter_post.py
├── counter.py
├── counter_stat.py
├── files
│ ├── blacklist
│ ├── .counter_logins
│ ├── count_month_TdCT
│ ├── count_TdCT
│ ├── url_poststat
│ └── url_TdCT
$ for f in $(ls *.py *.sh); do echo -e "\n------------------------------\n$f :\n"; cat "$(pwd)/$f";done
------------------------------
archives.sh :
#!/bin/bash
# encoding: utf-8
LAST_MONTH=$(date --date="last month" +%Y-%m)
MY_PATH=$(dirname $0)
LOG_PATH="$MY_PATH/log"
ARC_PATH="$LOG_PATH/archives"
[[ ! -d $ARC_PATH ]] && mkdir $ARC_PATH
FILES=$(ls "$LOG_PATH")
ARCHIVE="$ARC_PATH/$LAST_MONTH.tar.gz"
FILES_TO_ARCHIVE=$(echo "$FILES" | grep "$LAST_MONTH\-")
cd $LOG_PATH
tar -zcf $ARCHIVE $FILES_TO_ARCHIVE
rm $FILES_TO_ARCHIVE
------------------------------
counter_classlib.py :
#!/usr/bin/env python
# encoding: utf-8
# auteur originel: Gabriel Pettier
# fork: nany
# license GPL V3 or later
# bibliothèque des classes du compteur
# nécessite python 2.4 minimum.
from counter_path import LOGFILE, LOGPATH, FILESPATH, FORUM_URL, TOPIC_URL
from counter_funclib import DateTimePost, HtmlToText, tzFrance, log
from dateutil.tz import *
DEBUG = True
class IgnoreList:
def __init__(self, blackfile):
self.black = FILESPATH + blackfile
f = open(self.black, 'r')
self.list = f.read().split('\n')[:-1]
f.close()
def Add(self, stridname):
if stridname not in self.list:
self.list.append(stridname)
log(stridname + ' ajouté')
self.Save()
def Del(self, stridname):
if stridname in self.list:
self.list.remove(stridname)
log(stridname + ' retiré')
self.Save()
def Save(self):
log('sauvegarde de la blacklist')
f = open(self.black, 'w')
for stridname in self.list:
f.write('%s\n' % stridname)
f.close()
class Day:
"""
un jour dure de 21h à 5h du matin exclu ([21h:5h[)
il contient la derniere entrée (points) de ce jour pour chaque joueur
"""
def __init__(self):
self.entries = {}
# plus simple de faire try/except que de verifier si l'entrée existe. :/
def addEntry(self, entry):
try:
self.entries[str(entry.id)] = (
entry.name,
max(self.entries[str(entry.id)][1], entry.points))
except KeyError:
self.entries[str(entry.id)] = (entry.name, entry.points)
def __str__(self):
for entry in self.entries.items():
print entry, '+', entries[entry][1]
class Score:
def __init__(self, tuple):
self.name = tuple[2]
self.id = tuple[1]
self.num = int(tuple[0])
def __gt__(self, other):
return self.num > other.num
def __str__(self):
rnum = str(self.num).rjust(10)
rid = str(self.id).rjust(10)
return rnum + rid + ' ' + self.name
class User:
def __init__(self, postleft):
if postleft.find('a'):
self.id = int(postleft.find('a')['href'].split('=')[1])
if self.id == 1205711:
self.name = '<2028><2029>'
elif self.id == 1205721:
self.name = '<2029><2028>'
else:
self.name = HtmlToText(str(postleft.find('a').renderContents()))
else:
self.id = 0
self.name = HtmlToText(str(postleft.strong.renderContents()))
self.posts = []
self.tz = tzFrance
self.points = 0
if postleft.find('img'):
self.avatar = postleft.find('img')['src'].split('?')[0]
else:
self.avatar = ''
def Points(self, hour):
if hour in range(21,24):
self.points = hour - 20
if hour in range(3):
self.points = hour + 4
if hour in [3,4]:
self.points = 10
def __str__(self):
return str(self.id) + ' ' + self.name + ' ' + str(self.points)
class Post:
def __init__(self, post):
self.url = post.find('h2').a['href']
self.left = post.find('div', 'postleft')
self.dt = DateTimePost(str(post.find('h2').a.renderContents()))
self.edit = post.find('p', 'postedit')
if self.edit:
self.edit = DateTimePost(
str(self.edit).split('(')[-1].split(')')[0])
# suppression des balises «quote»
if post.find('div', 'quotebox'):
for quote in post.findAll('div', 'quotebox'):
quote.extract()
# suppression des balises «code»
if post.find('div', 'codebox'):
for code in post.findAll('div', 'codebox'):
code.extract()
self.msg = post.find('div', 'postmsg').renderContents()
if post.find('div', 'postsignature postmsg'):
self.sign = post.find('div', 'postsignature postmsg'
).renderContents()
else:
self.sign = ''
def localize(self, tz):
self.dt = self.dt.astimezone(gettz(tz))
if self.edit:
self.edit = self.edit.astimezone(gettz(tz))
------------------------------
counter_forum.py :
#!/usr/bin/env python
# encoding: utf-8
# auteur originel: Gabriel Pettier
# fork: nany
# license GPL V3 or later
# bibliothèque de fonctions pour naviguer dans le forum
# nécessite python 2.4 minimum et python-mechanicalsoup.
from counter_path import LOGFILE, POSTFILE, FILESPATH, FORUM_URL, TOPIC_URL
from counter_funclib import log
from time import sleep
from sys import exit
from os import access, F_OK
from mechanicalsoup import *
def getBrowser():
return StatefulBrowser(raise_on_404=True,
user_agent='Mozilla/5.0 (compatible)')
def getPage(browser, url):
# essaye de récupérer la page tant qu’il y a des erreurs
while True:
try:
browser.open(url)
page = browser.get_current_page()
if 'Error / FluxBB' in page.title.renderContents():
log('Erreur FluxBB')
sleep(10)
continue
break
except Exception as error:
log(str(error))
sleep(10)
return page
def log_in(browser, forum_url):
lf = open(FILESPATH + '.counter_logins', 'r')
login = lf.readline().strip('\n')
password = lf.readline().strip('\n')
lf.close()
plog = forum_url + 'login.php'
pindex = forum_url + 'index.php'
browser.open(plog)
browser.select_form('form[id="login"]')
browser['req_username'] = login
browser['req_password'] = password
browser.submit_selected()
page = getPage(browser, pindex)
welcome = page.find('div', id='brdwelcome')
if welcome.findAll('a')[-1].renderContents() == 'Déconnexion':
log('connexion effectuée')
else:
log('erreur lors de la connexion')
def log_out(browser, forum_url):
pindex = forum_url + 'index.php'
browser.open(pindex)
disconnect = browser.find_link(title="Déconnexion")
try:
browser.follow_link(disconnect)
browser.open(pindex)
welcome = browser.get_current_page().findAll('fieldset')[-1]
if welcome.findAll('a')[-1].renderContents() == 'inscription':
log('déconnexion effectuée')
else:
log('erreur lors de la déconnexion')
except:
log('le compteur ne semble pas être connecté')
browser.close()
def search_TdCT(browser, f_url):
log('recherche du TdCT')
url = ''
eonpe = getPage(browser, f_url + 'viewforum.php?id=181')
st = eonpe.tbody
for td in st.findAll('td', 'tcl'):
if td.find('span', 'stickytext'):
t_url = td.findAll('a')[-1]['href']
str_p = td.findAll('a')[-1].renderContents()
int_p = int(str_p) - 10
if int_p < 1:
int_p = 1
t_url = t_url.replace(str_p, str(int_p))
log(t_url)
url = f_url + t_url
if check_url(url, f_url, t_url):
break
if url == '':
log('échec : arrêt du script')
print 'le script s’est arrêté suite à une erreur'
print 'détail des opérations dans', LOGFILE
exit()
return url
def check_url(browser, url, f_url, t_url):
if not url.split('?')[0] == f_url + TOPIC_URL:
log('mauvaise url')
return False
else:
page = getPage(browser, url)
if isfirstpage(page):
firstpage = page
else:
urlfirst = f_url + pagelinks(page)[1]['href']
firstpage = getPage(browser, urlfirst)
firstpost = firstpage.find('div',
'blockpost rowodd firstpost blockpost1')
firstpost = firstpost.find('div', 'postmsg')
firstlinks = firstpost.findAll('a')
if len(firstlinks) > 0:
for link in firstlinks:
if 'topic des couche-tard' in link.renderContents():
return True
else:
log('mauvaise url')
return False
def post(browser, postfile, urlfile):
if access(postfile, F_OK):
fp = open(postfile, 'r')
msg = fp.read()
log('message chargé')
fp.close
else:
msg = 'Oups!'
log('message = Oups!')
fu = open(urlfile, 'r')
url = fu.readline().strip('\n')
fu.close()
log(url)
browser.open(url)
browser.select_form('form[id="quickpostform"]')
browser['req_message'] = msg
browser.get_current_form().choose_submit('submit')
browser.submit_selected()
log('message posté')
def numpage(page):
return page.find('p', 'pagelink conl').strong.renderContents()
def pagelinks(page):
return page.find('p', 'pagelink conl').findAll('a')
def isfirstpage(page):
num = numpage(page)
return (int(num) == 1)
def islastpage(page):
num = numpage(page)
links = pagelinks(page)
if len(links) > 0:
if int(links[-1]['href'].split('p=')[-1]) > int(num):
return False
else:
return True
else:
return True
------------------------------
counter_funclib.py :
#!/usr/bin/env python
# encoding: utf-8
# auteur originel: Gabriel Pettier
# fork: nany
# license GPL V3 or later
# bibliothèque des fonctions du compteur
# nécessite python 2.4 minimum et python-dateutil.
from counter_path import LOGFILE, POSTFILE, LOGPATH, FILESPATH
from counter_path import FORUM_URL, TOPIC_URL
from datetime import *
from dateutil.tz import *
import re
tzFrance = 'Europe/Paris'
def DateTimePost(dt):
if ', ' in dt:
dt = dt.split('Le ')[1].split(', à ')
else:
dt = dt.split(' ')
if dt[0].lower() == 'hier':
d = date.today() + timedelta(days=-1)
elif dt[0].lower() == 'aujourd\'hui':
d = date.today()
else:
d = datetime.strptime(dt[0], '%d/%m/%Y').date()
t = time(int(dt[-1].split(':')[0]), int(dt[-1].split(':')[1]))
dyear = int(d.strftime('%Y'))
dmonth = int(d.strftime('%m'))
dday = int(d.strftime('%d'))
thour = int(dt[-1].split(':')[0])
tmin = int(dt[-1].split(':')[1])
return datetime(dyear, dmonth, dday, thour, tmin, tzinfo=gettz('UTC'))
def naive(dt):
return datetime.combine(dt.date(), dt.time())
def renderstats(stats): # pour faire le graphique
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}
DayStats.update(stats)
code = '[code]\n'
for k in sorted(DayStats.keys())[5:]:
code += '[' + k + 'h:' + ((int(k) < 9 and '0') or '')
code += ((int(k) == 23 and '00') or str(int(k)+1)) + 'h[ : '
code += '#' * DayStats[k]
code += ((DayStats[k] > 0 and ' ') or '')
code += str(DayStats[k]) + '\n'
for k in sorted(DayStats.keys())[:5]:
code += '[' + k + 'h:' + '0' + str(int(k)+1) + 'h[ : '
code += '#' * DayStats[k]
code += ((DayStats[k] > 0 and ' ') or '')
code += str(DayStats[k]) + '\n'
code += '[/code]'
return code
def renderpost(_file):
title = (((_file == FILESPATH + 'count_TdCT')
and 'Scores totaux de la seconde guerre')
or 'Scores du mois en cours')
msg = title + ' :\n[code]\n' + '\xe2\x80\xad'
fs = open(_file, 'r')
scores = fs.readlines()
for i in range(len(scores)): # on veut toutes les lignes restantes
score = re.compile('\s*').split(scores[i], 3)[1:]
precnum = re.compile('\s*').split(scores[i-1])[1]
num = score[0]
Id = score[1]
name = score[2]
line = scores[i].replace(Id.rjust(10), '')
if i == 0:
tmpRange = 0
elif num == precnum:
pass
else:
tmpRange = i
# et on ajoute la ligne avec le bon rang a l'entrée
if '\xe2\x80\xae' in scores[i-1]:
msg += '\xe2\x80\xac'
if Id == '7666':
msg += '*** Vétéran des couche-tard, héros de la première'
msg += ' guerre, invaincu avant retraite ***\n'
msg += str(tmpRange + 1).rjust(5) + ')' + line
if Id == '7666':
msg += '*' * 85 + '\n'
msg += '[/code]\n'
fp = open(POSTFILE, 'a')
fp.write(msg)
fp.close
def HtmlToText(txt):
data = (['<', '<'], ['>', '>'], [''', '\''], [' ', ' '],
['"', '\"'], ['&', '&'])
for rep in data:
txt = txt.replace(rep[0], rep[1])
return txt
def log(line):
time = datetime.now().strftime('[%H:%M:%S] ')
f = open(LOGFILE, 'a')
f.write(time + line + '\n')
f.close()
------------------------------
counter_path.py :
#!/usr/bin/env python
# encoding: utf-8
# auteur originel: Gabriel Pettier
# fork: nany
# license GPL V3 or later
# bibliothèque des chemins pour le compteur + url du forum
# nécessite python 2.4 minimum.
import os
import sys
from datetime import date, datetime
FORUM_URL = 'https://forum.ubuntu-fr.org/'
TOPIC_URL = 'viewtopic.php'
MYPATH = sys.path[0] + os.sep
LOGPATH = MYPATH + 'log'
if not os.path.exists(LOGPATH):
if os.access(MYPATH, os.W_OK):
os.mkdir(LOGPATH)
else:
LOGPATH = os.getenv('HOME') + os.sep + 'counter_files/log'
if not os.path.exists(LOGPATH):
os.makedirs(LOGPATH)
LOGPATH += os.sep
LOGFILE = LOGPATH + str(date.today())
POSTFILE = LOGFILE + '_post_TdCT'
STATFILE = LOGFILE + '_stat_TdCT'
FILESPATH = MYPATH + 'files'
if not os.path.exists(FILESPATH):
if os.access(MYPATH, os.W_OK):
os.mkdir(FILESPATH)
else:
LOGPATH = os.getenv('HOME') + os.sep + 'counter_files/files'
if not os.path.exists(FILESPATH):
os.makedirs(FILESPATH)
FILESPATH += os.sep
------------------------------
counter_post.py :
#!/usr/bin/env python
# encoding: utf-8
# auteur originel: Gabriel Pettier
# fork: nany
# license GPL V3 or later
# pour poster les messages sur le forum
# nécessite python 2.4 minimum.
from counter_path import FORUM_URL, POSTFILE, STATFILE, MYPATH , FILESPATH
from counter_funclib import log
from time import sleep
import counter_forum as forum
import sys
if len(sys.argv) > 1 and sys.argv[1] == 'stat':
pfile = STATFILE
urlfile = FILESPATH + 'url_poststat'
else:
pfile = POSTFILE
urlfile = FILESPATH + 'url_TdCT'
if pfile == STATFILE:
log('ENVOI DES STATISTIQUES' + '\n')
else:
log('ENVOI DES COMPTES DE POINTS' + '\n')
log('début\n ‾‾‾‾‾')
sleep(5)
browser = forum.getBrowser()
sleep(2)
forum.log_in(browser, FORUM_URL)
sleep(2)
forum.post(browser, pfile, urlfile)
sleep(2)
forum.log_out(browser, FORUM_URL)
log('fin\n ‾‾‾\n')
------------------------------
counter.py :
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# auteur originel: Gabriel Pettier
# license GPL V3 or later
# sert uniquement a compter les points sur ce topic:
# https://forum.ubuntu-fr.org/viewtopic.php?pid=22045004#p22045004
# et donc probablement inutile a quiquonque vu que le serveur
# se charge de le lancer tous les matins et tous les soirs
# publié a seul but de vérification par les interressés. ;),
# peut aussi servir si mon serveur n'est plus là
# pour assurer le service un jour.
# nécessite python 2.4 minimum et python-dateutil.
# le fichier './files/.counter_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).
# fork: nany
from counter_path import LOGFILE, POSTFILE, LOGPATH, FILESPATH
from counter_path import FORUM_URL, TOPIC_URL
from counter_classlib import IgnoreList, Day, Score, User, Post
from counter_funclib import DateTimePost, naive, renderpost
from counter_funclib import HtmlToText, tzFrance, log
import counter_forum as forum
import datetime
from dateutil.tz import *
import re
import os
DEBUG = False
TZPATH = '/usr/share/zoneinfo/'
def main(urlfile, files, blackfile):
TODAY = datetime.date.today()
#TODAY = datetime.date(2015, 8, 13)
YESTERDAY = TODAY + datetime.timedelta(days=-1)
log('POINTS DE LA NUIT DU ' + YESTERDAY.strftime('%d/%m/%Y') + ' AU '
+ TODAY.strftime('%d/%m/%Y') + '\n')
log('début\n ‾‾‾‾‾')
MIN = datetime.datetime.combine(YESTERDAY, datetime.time(21, 0))
MINSTAT = datetime.datetime.combine(YESTERDAY, datetime.time(5, 0))
MAX = MAXSTAT = datetime.datetime.combine(TODAY, datetime.time(5, 0))
logurl = LOGPATH + str(TODAY) + '_' + urlfile
urlfile = FILESPATH + urlfile
users = {}
f = open(urlfile, 'r')
url = f.readline().strip('\n')
t_url = url.split('/')[-1]
f.close()
save_url = ''
entries = Day()
black = IgnoreList(blackfile)
log('blacklist chargée')
browser = forum.getBrowser()
forum.log_in(browser, FORUM_URL)
log('parcours des pages')
while True:
log(url)
if not forum.check_url(browser, url, FORUM_URL, t_url):
url = forum.search_TdCT(browser, FORUM_URL)
page = forum.getPage(browser, url)
# parcourt les posts de la page
for p in page.findAll('div', id=re.compile('p+[0-9]')):
post = Post(p)
user = User(post.left)
post.localize(tzFrance)
if str(user.id) in users.keys():
user = users[str(user.id)]
user.posts.append(post)
users[str(user.id)] = user
# recherche de «timezone[» dans le message
# (sans citation ni code) et dans la signature
tpost = post.msg + post.sign
stpost = tpost.replace(' ', '')
stpost = stpost.replace(' ', '')
stpost = stpost.replace('', '')
stpost = stpost.replace(' ', '')
if 'timezone[' in stpost:
tzpost = stpost.split('timezone[')[1].split(']')[0]
# ne sera pas pris en compte s’il y a plus d’une occurence
if stpost.count('timezone[') > 1:
log('{0} {1} → trop de «timezone»!'.format(
user.name, post.url))
# ni si la désignation du fuseau horaire est incorrect
elif not os.path.exists(TZPATH + tzpost):
log('{0} {1} → mauvaise «timezone» : {2}'.format(
user.name, post.url, tzpost))
else:
user.tz = tzpost
# recherche de «[blacklistme]» dans le message
if '[blacklistme]' in post.msg.lower():
log('ajout éventuel de {0} à la blacklist'.format(user.name))
black.Add(str(user.id) + ';' + user.name)
# recherche de «[unblacklistme]» dans le message
if '[unblacklistme]' in post.msg.lower():
log('retrait éventuel de {0} de la blacklist'.format(
user.name, user.id))
black.Del(str(user.id) + ';' + user.name)
# recherche de «[razme]» dans le message
if '[razme]' in post.msg.lower():
log('retrait éventuel du score de {0}'.format(
user.name, user.id))
content = ''
for scorefile in files:
fscore = open(FILESPATH + scorefile, 'r+b')
s = fscore.read()
x = s.find(str(user.id))
x = s[0:x].rfind('\n') + 1
fscore.seek(x)
for line in fscore[x:]:
if not(str(user.id) in line):
content += line
else:
log('score de ' + user.name + ' effacé')
print content
fscore.seek(x)
fscore.write(content)
# ne sert qu’en cas de récup depuis une date antérieure
#TOMOROW = TODAY + datetime.timedelta(days=1)
#LIMIT = datetime.datetime.combine(TOMOROW, datetime.time(15, 0))
#if naive(post.dt) > LIMIT:
# break
# les 4 lignes précédentes peuvent être commentées
# s’il n’y a pas de récup depuis une date antérieure
# si la page n’est pas la dernière,
# le dernier lien pointe vers la page suivante
if not forum.islastpage(page):
t_url = forum.pagelinks(page)[-1]['href']
url = FORUM_URL + t_url
log('page suivante :')
else: # sinon, on est à la dernière page
# on vérifie alors si le sujet est fermé,
# auquel cas on renvoie le dernier lien fourni sur la page
resp = page.find('p', 'postlink conr').renderContents()
if resp == 'Discussion fermée':
for postmsg in page.findAll('div', 'postmsg'):
if postmsg.find('a'):
nextpage = postmsg.findAll('a')[-1]['href']
t_url = nextpage.split('/')[-1]
url = FORUM_URL + t_url
log('nouveau topic :')
else: # le sujet n’est pas fermé
break # on arrête donc le parcours des pages
forum.log_out(browser, FORUM_URL)
save_dt = naive(datetime.datetime.now())
for u in users:
user = users[u]
for post in user.posts:
# récupère l’url d’où repartir le lendemain
if save_dt > naive(post.dt) >= MAXSTAT:
save_dt = naive(post.dt)
save_url = FORUM_URL + post.url
# traitement du décalage horaire
post.localize(user.tz)
# comptage si post entre 21:00 la veille et 04:59 ce jour
if MIN < naive(post.dt) < MAX:
if post.edit and MIN < naive(post.edit) < MAX:
user.Points(naive(post.edit).hour)
else:
user.Points(naive(post.dt).hour)
# on ajoute l’entrée si le membre n’est pas blacklisté
if (str(user.id) + ';' + user.name) not in black.list:
entries.addEntry(user)
if not DEBUG:
log('sauvegarde de l\'url ' + save_url + '\n')
f = open(urlfile, 'w')
f.write(save_url)
f.close()
flog = open(logurl, 'w')
flog.write(save_url)
flog.close()
log('analyse des scores')
for scorefile in files:
if files.index(scorefile) == 0:
period = 'du mois en cours'
else:
period = 'de la seconde guerre'
log(period + '\n')
f = open(FILESPATH + scorefile, 'r')
lines = f.readlines()
f.close()
scores = []
for line in lines:
if line not in [' ', '']:
line_tuple = re.compile('\s*').split(line)[1:-1]
line_num = line_tuple[0]
line_id = line_tuple[1]
line_name = ' '.join(line_tuple[2:])
scores.append(Score([line_num, line_id, line_name]))
new_scores = []
night_scores = []
for entry, data in entries.entries.items():
name = data[0]
num = data[1]
night_scores.append(Score([num, entry, name]))
if files.index(scorefile) == 0 and TODAY.day == 2:
scores = []
log(' '.join(['nouvelle période', name, '→',
str(num), 'points']))
new_scores.append(Score([num, entry, name]))
elif scores == []:
log(' '.join(['nouveau membre :', name, '→', str(num),
'points']))
new_scores.append(Score([num, entry, name]))
else:
for score in scores:
if entry == score.id:
score.num += num
score.name = name
log(' '.join(['ajout :', score.name, '+', str(num),
'⇒', str(score.num)]))
break
if score is scores[-1]:
log(' '.join(['nouveau membre :', name, '→', str(num),
'points']))
new_scores.append(Score([num, entry, name]))
break
scores += new_scores
# vérification des doublons
for nScore in range(len(scores) - 2):
mScore = nScore + 1
for score in scores[mScore:]:
if scores[nScore].id == score.id:
log(' '.join(['doublon :', scores[nScore].name, '⇐⇒',
score.name]))
score.num += scores[nScore].num
del(scores[nScore])
scores.sort(reverse=True)
if not DEBUG:
log('sauvegarde des scores ' + period + '\n')
f = open(FILESPATH + scorefile, 'w')
flog = open(LOGPATH + str(TODAY) + '_' + scorefile, 'w')
for score in scores:
f.write('%s\n' % score)
flog.write('%s\n' % score)
f.close()
flog.close()
renderpost(FILESPATH + scorefile)
fp = open(POSTFILE, 'r')
msg = fp.read()
fp.close()
fp = open(POSTFILE, 'w')
fp.write('Points marqués la nuit passée:\n[code]\n')
night_scores.sort(reverse=True)
for score in night_scores:
fp.write(str(score.num).rjust(3) + ' ' + score.name + '\n')
fp.write('[/code]\n')
fp.write(msg)
fp.close()
log('fin\n ‾‾‾\n')
main('url_TdCT', ['count_month_TdCT', 'count_TdCT'], 'blacklist')
------------------------------
counter_stat.py :
#!/usr/bin/env python
# encoding: utf-8
# auteur originel: Gabriel Pettier
# fork: nany
# license GPL V3 or later
# pour faire les statistiques des posts de la journée passée sur le topic
# nécessite python 2.4 minimum.
from counter_path import LOGFILE, STATFILE, LOGPATH, FILESPATH
from counter_path import FORUM_URL, TOPIC_URL
from counter_classlib import Post
from counter_funclib import DateTimePost, naive, renderstats, tzFrance, log
import counter_forum as forum
import datetime
import re
def main(urlfile, statfile):
DEBUG = False
TODAY = datetime.date.today()
#TODAY = datetime.date(2015, 4, 30)
YESTERDAY = TODAY + datetime.timedelta(days=-1)
log('STATISTIQUES DE LA NUIT DU ' + YESTERDAY.strftime('%d/%m/%Y') + ' AU '
+ TODAY.strftime('%d/%m/%Y') + '\n')
log('début\n ‾‾‾‾‾')
MINSTAT = datetime.datetime.combine(YESTERDAY, datetime.time(5, 0))
MAXSTAT = datetime.datetime.combine(TODAY, datetime.time(5, 0))
urlfile = FILESPATH + urlfile
urlpost = FILESPATH + 'url_poststat'
logurl = LOGPATH + str(TODAY) + '_' + 'url_poststat'
stats = {}
f = open(urlfile, 'r')
url = f.readline().strip('\n')
t_url = url.split('/')[-1]
f.close()
browser = forum.getBrowser()
forum.log_in(browser, FORUM_URL)
log('parcours des pages')
while True:
log(url)
if not forum.check_url(browser, url, FORUM_URL, t_url):
url = forum.search_TdCT(FORUM_URL)
page = forum.getPage(browser, url)
# parcourt les posts de la page
for p in page.findAll('div', id=re.compile('p+[0-9]')):
post = Post(p)
post.localize(tzFrance)
# statistiques si post entre 05:00 la veille et 04:59 ce jour
if MINSTAT < naive(post.dt) < MAXSTAT:
# compte les posts par plage horaire
if post.dt.strftime('%H') not in stats:
stats[post.dt.strftime('%H')] = 1
else:
stats[post.dt.strftime('%H')] += 1
# si la page n’est pas la dernière,
# le dernier lien pointe vers la page suivante
if not forum.islastpage(page):
t_url = forum.pagelinks(page)[-1]['href']
url = FORUM_URL + t_url
log('page suivante :')
else: # sinon, on est à la dernière page
# on vérifie alors si le sujet est fermé,
# auquel cas on renvoie le dernier lien fourni sur la page
resp = page.find('p', 'postlink conr').renderContents()
if resp == 'Discussion fermée':
for postmsg in page.findAll('div', 'postmsg'):
if postmsg.find('a'):
nextpage = postmsg.findAll('a')[-1]['href']
t_url = nextpage.split('/')[-1]
url = FORUM_URL + t_url
log('nouveau topic :')
else: # le sujet n’est pas fermé
break # on arrête donc le parcours des pages
if not DEBUG:
log('sauvegarde de l\'url ' + url + '\n')
f = open(urlpost, 'w')
f.write(url)
f.close()
flog = open(logurl, 'w')
flog.write(url)
flog.close()
msg = renderstats(stats)
fs = open(statfile, 'w')
fs.write('Statistiques de la journée passée')
fs.write(' (entre 5:00 et 4:59, heure de Paris) :\n')
fs.write(msg)
fs.write('\nLe décompte des points sera donné ultérieurement')
fs.write(', lorsque la nuit aura fait le tour du monde.')
fs.close()
forum.log_out(browser, FORUM_URL)
log('fin\n ‾‾‾\n')
main('url_TdCT', STATFILE)
$ crontab -l | tail -5
42 5 * * * /path/to/counter_directory/counter_stat.py
42 6 * * * /path/to/counter_directory/counter_post.py stat
10 19 * * * /path/to/counter_directory/counter.py
42 19 * * * /path/to/counter_directory/counter_post.py
42 7 2 * * /path/to/counter_directory/archives.sh
Dernière modification par compteur-couche-tard_V2.0 (Le 14/02/2019, à 06:03)
Insomnies ? Je quantifie votre manque de sommeil. - timezone[Etc/UTC]
Si vous voulez que je vous souhaite votre anniversaire, envoyez moi la date de celui-ci en MP.
Mon code. Mon wiki.
Le cri du caillou
Hors ligne