This repository has been archived on 2023-02-21. You can view files and clone it, but cannot push or open issues or pull requests.
mandaye/mandaye/filters/vincennes.py

269 lines
12 KiB
Python

import Cookie
import mandaye
import re
from urlparse import parse_qs
from BeautifulSoup import BeautifulSoup
import lxml.html
from mandaye.db import sql_session
from mandaye.log import logger
from mandaye.models import Site, ExtUser, LocalUser
from mandaye.response import serve_template
from mandaye.response import _302, _401
def get_associate_form(env, values):
""" Return association template content
"""
associate_type = None
error_msg = None
first = False
if env['QUERY_STRING']:
qs = parse_qs(env['QUERY_STRING'])
if qs.has_key('type'):
associate_type = qs['type'][0]
if associate_type == 'badlogin':
error_msg = values.get('badlogin_msg')
elif associate_type == 'failed':
error_msg = values.get('failed_msg')
elif associate_type == 'first':
first = True
form = serve_template(values.get('template'),
first_connection=first, error_msg=error_msg,
action_url=values.get('action') + "?%s" % env['QUERY_STRING'],**values)
return form.encode('utf-8')
def get_current_account(env, values):
""" Return the current Mandaye user """
site_name = values.get('site_name')
if env['beaker.session'].get(site_name):
return sql_session().query(ExtUser).\
get(env['beaker.session'].get(site_name))
else:
return None
def get_multi_template(env, values, current_account):
""" return the content of the multi account template
"""
login = env['beaker.session'].get('login')
if login:
ext_users = sql_session().query(ExtUser).\
join(LocalUser).\
join(Site).\
filter(LocalUser.login==login).\
filter(Site.name==values.get('site_name')).\
order_by(ExtUser.last_connection.desc()).\
all()
accounts = {}
for ext_user in ext_users:
accounts[ext_user.id] = ext_user.login
if current_account:
current_login = current_account.login
else:
current_login = None
template = serve_template(values.get('template'),
accounts=accounts, current_login=current_login, **values)
return template
return None
class Biblio:
def resp_html_login_page(self, env, values, request, response):
""" msg: response message body
env: Mandaye environment
"""
if '<div>Connexion utilisateur</div>' in response.msg:
login = serve_template(values.get('template'), **values)
sub = re.subn(r'<!-- /block.tpl.php -->\s*(<span class="clear"></span>)',
r'\1 %s' % login.encode('utf-8'),
response.msg)
response.msg = sub[0]
if sub[1] != 1:
logger.warning('Filter Biblio.resp_html_login_page failed !')
return response
def resp_html(self, env, values, request, response):
""" Global html filter the Vincenne library
This fix the fucking absolute url of the biblio site
"""
content_type = response.headers.getheader('content-type')
if content_type and response.msg and \
('application/x-javascript' in content_type or \
'text/html' in content_type or \
'text/css'in content_type):
response.msg = response.msg.replace(env["target"].geturl(),
'%s://%s' % (env["mandaye.scheme"], env["HTTP_HOST"]))
if env["mandaye.scheme"] == 'https':
response.msg = response.msg.replace('http://' + env["HTTP_HOST"],
'%s://%s' % (env["mandaye.scheme"], env["HTTP_HOST"]))
return response
def resp_associate_login(self, env, values, request, response):
""" Use default login page to associate an account on the SSO
"""
if response.msg and '<div class="inner">' in response.msg:
form = get_associate_form(env, values)
r = re.compile(r'<div class="inner">.*</div><!-- / inner -->',
re.MULTILINE|re.DOTALL)
sub = re.subn(r, form, response.msg)
response.msg = sub[0]
if sub[1] != 1:
logger.warning('Filter Biblio.resp_associate failed !')
return response
def resp_multicompte_html(self, env, values, request, response):
""" Modify response html to support multi accounts
"""
content_type = response.headers.getheader('content-type')
if content_type and response.msg and 'text/html' in content_type and \
'<h2><div>Mon compte</div></h2>' in response.msg:
if env['beaker.session'].get('login'):
current_account = get_current_account(env, values)
template = get_multi_template(env, values, current_account)
if current_account:
sub = re.subn(r'(<div class="content"><div id="opacaccount" class="summary"><div class="name">)<b>(.*)</b>',
r'\1<b>\2 (%s)</b>' % current_account.login.encode('utf-8'),
response.msg)
response.msg = sub[0]
if sub[1] != 1:
logger.warning('Filter Biblio.resp_multicompte_html: add card number in account information failed')
desassociate = serve_template('biblio/disassociate.html',
account=current_account, **values)
sub = re.subn(r'<div class="link">', '<div class="link" style="margin-bottom: 10px">%s'\
% desassociate.encode('utf-8'),
response.msg)
response.msg = sub[0]
if sub[1] != 1:
logger.warning('Filter Biblio.resp_multicompte_html: add disassociate link failed !')
else:
template = serve_template(values.get('nosso_template'), **values)
regexp = re.compile(r'(<div id="opacaccount" class="summary">.*connecter</a></div></div>)',
re.MULTILINE|re.DOTALL)
sub = re.subn(regexp, r"\1 %s" % template.encode('utf-8'), response.msg)
response.msg = sub[0]
if sub[1] != 1:
logger.warning('Filter Biblio.resp_multicompte_html: add multiaccount informations failed !')
return response
class EspaceFamille:
def resp_login_page(self, env, values, request, response):
""" Modify the login_page form
"""
content_type = response.headers.getheader('content-type')
if response.msg and content_type and 'text/html' in content_type \
and '<!-- Bloc central > Bloc droite > Acc' in response.msg:
login = serve_template(values.get('template'), **values)
regexp = re.compile(r'(<!-- Bloc central > Bloc droite > Demandes -->)')
sub = re.subn(regexp,
r"\1%s" % login.encode('utf-8'), response.msg)
response.msg = sub[0]
if sub[1] != 1:
logger.warning('Filter EspaceFamille.resp_login_page failed !')
return response
def resp_associate(self, env, values, request, response):
""" Modify associate page response """
if response.msg:
# TODO: remove BeautifulSoup
soup = BeautifulSoup(response.msg)
div = soup.find('div', {'class': 'bloc-model-1'})
if div:
form = get_associate_form(env, values)
div.replaceWith(form)
response.msg = str(soup)
else:
logger.warning('Filter EspaceFamille.resp_associate failed !')
return response
def resp_disassociate(self, env, values, resquest, response):
""" Add a disassociation link
"""
content_type = response.headers.getheader('content-type')
if content_type and response.msg and 'text/html' in content_type and \
'<!-- Navigation -->' in response.msg:
login = env['beaker.session'].get('login')
current_account = get_current_account(env, values)
if login and current_account:
disassociate = serve_template('famille/disassociate.html',
account=current_account, **values)
sub = re.subn(r'(connexion" /></p>)',
r"\1%s" % disassociate.encode('iso8859-15'), response.msg)
response.msg = sub[0]
if sub[1] > 1:
logger.warning('Filter EspaceFamille.disassociate failed !')
return response
class Duonet:
def resp_login_page(self, env, values, request, response):
""" Modify login page to add the 'compte citoyen' connection
"""
if response.msg and '<form name="form1"' in response.msg:
login = serve_template(values.get('template'), **values)
regexp = re.compile(
r'</table>.*<center>.*<span id="lblError".*</center>',
re.MULTILINE|re.DOTALL)
sub = re.subn(regexp,
"</table>%s" % login.encode('utf-8'), response.msg)
response.msg = sub[0]
if sub[1] > 1:
logger.warning('Filter Duonet.resp_login_page failed !')
return response
def resp_associate(self, env, values, request, response):
""" Add the associate form in the page
"""
if response.msg:
# TODO: remove BeautifulSoup
soup = BeautifulSoup(response.msg)
form = soup.find('form', {'name': 'form1'})
if form:
new_form = get_associate_form(env, values)
form.replaceWith(new_form)
response.msg = str(soup)
return response
def resp_global_html(self, env, values, request, response):
""" Modify response html to support disassociation and link to federate an account
"""
if response.msg \
and 'font-weight:bold;">Conservatoire de Vincennes' in response.msg:
login = env['beaker.session'].get('login')
site_name = values.get('site_name')
current_account = get_current_account(env, values)
if login and current_account:
disassociate = serve_template('duonet/disassociate.html',
account=current_account, **values)
document = lxml.html.fromstring(response.msg.decode('utf8'))
a = document.get_element_by_id('ctl00_lnkDisconnect')
a.rewrite_links(lambda link: '/mandaye/logout')
new_element = lxml.html.fromstring(disassociate)
a.addprevious(new_element)
response.msg = lxml.html.tostring(document, encoding='utf8')
else:
template = serve_template(values.get('nosso_template'), **values)
document = lxml.html.fromstring(response.msg.decode('utf8'))
div = document.get_element_by_id('ctl00_chpMain_newsfeed_pnlBorder')
new_element = lxml.html.fromstring(template)
div.addnext(new_element)
response.msg = lxml.html.tostring(document, encoding='utf8')
return response
def logout(self, env, values, request, response):
for cookie in request.cookies.itervalues():
cookie['expires'] = 'Tue, 02-Dec-2003 08:19:12 GMT'
cookie['Path'] = '/'
logger.debug('Logout from Mandaye')
env['beaker.session'].delete()
return _302(values.get('index_url'), request.cookies)