# -*- coding: utf-8 -*-
import webapp2,cgi,re,cookielib,urllib2,urllib,json,datetime
from google.appengine.ext import db
from google.appengine.api import users
from google.appengine.api import memcache
ripe = 'https://apps.db.ripe.net/search/query.html?search%3AdoSearch=Search&searchtext='
class Options(db.Model):
admin_username= db.StringProperty()
admin_password= db.StringProperty()
charset= db.StringProperty(default='utf-8')
# modèle d'un message de log
class Log(db.Model):
id_to= db.IntegerProperty()
str_to= db.StringProperty()
id_from= db.IntegerProperty()
str_from= db.StringProperty()
num= db.IntegerProperty()
date= db.DateTimeProperty(auto_now_add=True)
raison= db.StringProperty()
ip= db.StringProperty()
# fonction pour prendre les options
def get_options(domain):
options= memcache.get(domain+'_options')
if options is None:
options= Options.get_by_key_name(domain+'_options')
if options and options.charset is None:
options.charset= 'utf-8'
return options
# page pour administration
class Change(webapp2.RequestHandler):
# retour d'un message
def rep(self, message, erreur=True):
if erreur:
erreur='1'
else:
erreur='0'
self.response.write('fa_money_callback('+erreur+','+json.dumps(message)+')')
# affichage
def get(self,domain):
scheme = self.request.scheme
# on déclare que le document renvoyé est du javascript
self.response.content_type= 'application/javascript'
# saisie des options du compte admin
options= get_options(domain)
if options is None:
self.rep("l'outil de transfert n'a pas été configuré")
return
# on récupère le &from=
id_from=self.request.get('from')
if id_from is None or re.match('^[1-9][0-9]*$',id_from) is None:
self.rep("probleme de requête")
return
# on récupère le &from_username
str_from=self.request.get('from_username')
if str_from is None:
self.rep("probleme de requête")
return
# on récupère le &to=
id_to=self.request.get('to')
if id_to is None or re.match('^[1-9][0-9]*$',id_to) is None:
self.rep("probleme de requête")
return
if id_to==id_from:
self.rep("vous ne pouvez vous envoyez vous-même des points")
return
# on récupère le &to_username
str_to=self.request.get('to_username')
if str_to is None:
self.rep("probleme de requête")
return
# on récupère le &num=
num=self.request.get('num')
if num is None or re.match('^[1-9][0-9]*$',num) is None:
self.rep("probleme de requête")
return
# on récupère le &raison=
raison=self.request.get('raison')
if raison is None:
raison = "";
# on conserve les cookies
cj = cookielib.CookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
# connexion au forum
opener.open(scheme+'://'+domain+'/login.forum','username='+urllib.quote_plus(options.admin_username.encode(options.charset))+'&password='+urllib.quote_plus(options.admin_password.encode(options.charset))+'&login=1&redirect=/admin/&admin=1')
# ouverture du panneau d'admin afin de reçevoir un tid qui permet de visiter le panneau
r = opener.open(scheme+'://'+domain+'/admin')
# on prend le tid de l'adresse vers laquelle on a été redirigé
charset_match = re.search('charset=([^"]*)', r.read())
if charset_match is None:
charset = "utf-8"
else:
charset = charset_match.group(1)
tids = re.findall('[&\?]tid=([a-f0-9]{32})', r.geturl())
if not tids:
self.rep("l'outil de transfert a été mal configuré")
return
tid = tids[0]
# on va rechercher la page avec le nombre de point du donateur
r= opener.open(scheme+'://'+domain+'/admin/index.forum?part=modules&sub=point&mode=don&extended_admin=1&tid='+tid, "action=add_points_for_user&search_user="+urllib.quote_plus(re.sub(r'([\\\*%_])',r'\\\1',str_from).encode(charset))+"&submit_search_user=1")
# on prend le nombre de point du donateur
from_match= re.search('',r.read())
if from_match is None:
memcache.delete('lock'+id_from)
memcache.delete('lock'+id_to)
self.rep("probleme pour prendre la valeur actuelle des points de %s" % str_from)
return
# on regarde si son nombre de point est plus petit que le nombre de point qu'il donne
if int(from_match.group(1)) < int(num):
memcache.delete('lock'+id_from)
memcache.delete('lock'+id_to)
self.rep("vous n'avez que %d points, ce n'est pas assez pour en donner %d" % (int(from_match.group(1)), int(num)))
return
# on va rechercher la page avec le nombre de point du reçeveur
r= opener.open(scheme+'://'+domain+'/admin/index.forum?part=modules&sub=point&mode=don&extended_admin=1&tid='+tid, "action=add_points_for_user&search_user="+urllib.quote_plus(re.sub(r'([\\\*%_])',r'\\\1',str_to).encode(charset))+"&submit_search_user=1")
# on prend le nombre de point du reçeveur
to_match= re.search('',r.read())
if to_match is None:
self.rep(u"probleme pour prendre la valeur actuelle des points de %s" % str_to)
return
# on envoit les nouveaux nombres de point
opener.open(scheme+'://'+domain+'/admin/index.forum?part=modules&sub=point&mode=don&extended_admin=1&tid='+tid, "action=add_points_for_user&points_new_value["+id_from+"]="+str(int(from_match.group(1))-int(num))+"&points_new_value["+id_to+"]="+str(int(to_match.group(1))+int(num))+"&submit=1")
# on enregistre la transmission
Log(parent=Options.get_by_key_name(domain+'_options'),id_to=int(id_to), str_to=str_to, id_from=int(id_from), str_from=str_from, num=int(num), raison=raison, ip=self.request.remote_addr).put()
# on envoie le nouveau nombre de point du reçeveur
self.rep(str(int(to_match.group(1))+int(num)), False)
# page pour l'affichage de l'historique d'un membre
class History(webapp2.RequestHandler):
# affichage de la page
def get(self, domain, user):
scheme = self.request.scheme
# on récupère les options pour le domaine
ancestor= get_options(domain)
# on va rechercher toutes les fois où le membre a été reçeveur
receiver= []
if ancestor:
for log in Log.all().ancestor(ancestor).filter('id_to =',int(user)).order('-date'):
if log.raison is None:
log_raison = ""
else:
log_raison = log.raison
if log.ip is None:
ip = ""
else:
ip = log.ip
log.date=log.date.replace(tzinfo=UTC()).astimezone(CET())
receiver.append('
' if users.is_current_user_admin() else ''))
if len(receiver)<1:
receiver= '
Jamais reçu de points
';
else:
receiver= '
Envoyeur
Nombre de point
Raison
Date
'+('
IP
' if users.is_current_user_admin() else '')+'
'+'
'.join(receiver)+'
'
# on va rechercher toutes les fois où le membre a été envoyeur
sender= []
if ancestor:
for log in Log.all().ancestor(ancestor).filter('id_from =',int(user)).order('-date'):
if log.raison is None:
log_raison = ""
else:
log_raison = log.raison
if log.ip is None:
ip = ""
else:
ip = log.ip
log.date=log.date.replace(tzinfo=UTC()).astimezone(CET())
sender.append('
' if users.is_current_user_admin() else ''))
if len(sender)<1:
sender= '
Jamais envoyé de points
';
else:
sender= '
Reçeveur
Nombre de point
Raison
Date
'+('
IP
' if users.is_current_user_admin() else '')+'
'+'
'.join(sender)+'
'
# affichage de la page
self.response.out.write('''
Administration
Réception de point
%s
Don de point
%s
Profil
Lien
''' % (
receiver,
sender,
scheme+'://'+domain+'/u'+user
)
)
# page pour administration
class Admin(webapp2.RequestHandler):
# affichage
def get(self, domain):
# saisie des options
options= get_options(domain)
if options is None:
options=Options(admin_username='',admin_password='')
# on va rechercher tout les 100 derniers logs
logs= []
ancestor= get_options(domain)
if ancestor:
for log in Log.all().ancestor(ancestor).order('-date').fetch(100):
if log.raison is None:
log_raison = ""
else:
log_raison = log.raison
if log.ip is None:
ip = ""
else:
ip = log.ip
log.date=log.date.replace(tzinfo=UTC()).astimezone(CET())
logs.append('