This is the entire pyramid program, weblogin.py. It will need heavy site-specific customization if you want to use it yourself.
The imports, first the pyramid imports, and then system imports. memcache was chosen for persistence for this project for three reasons: it is fast; there will never be many visitors logged in, so an in-memory solution is appropriate; and it takes care of removing stale data itself, which makes this program much easier. Since syslog is used, rather than logger, you have to be on a POSIX system.:
from paste.httpserver import serve
from pyramid.config import Configurator
from pyramid.response import Response
from pyramid.httpexceptions import HTTPFound
import memcache
import syslog
import email
import smtplib
Only one memcache connection is used, this will not be a bottleneck.:
# Note, global.
mc = memcache.Client(['127.0.0.1:11211'], debug=0)
Send an email to someone when a visitor logs in. You have to customize this heavily. MYLOCATION, mydomain.com, myname@mydomain.com, and mailhost.maildomain.com should all be edited per your site.:
def send_email(name, ip, location, email_addr):
txt = """A user having a dynamic address (which should be a visitor),
is using the web from MYLOCATION.
Name: %(name)s
Location: %(location)s
IP NUmber: %(ip)s
Email Addr: %(email)s""" % dict(name=name, ip=ip,
location=location, email=email_addr)
msg = email.message_from_string(txt)
msg['Subject'] = 'Visitor Signin To Web'
msg['From'] = 'web_signin@mydomain.com'
msg['To'] = 'myname@mydomain.com'
msg['Date'] = email.utils.formatdate()
smtp = smtplib.SMTP( 'mailhost.maildomain.com')
smtp.sendmail( msg['From'], msg['To'].split(','), msg.as_string() )
In permit(), the user is persisted in the memcache for 8 hours. If you are testing, simply restart memcache any time you want to force a new round of logins. A email is sent, and a line is written to syslog. Then the user is redirected to the originally requested URL.:
def permit(request):
"""The user has given a non-empty user name, location and email_addr,
and clicked the accept button. Store an entry for him in the
memcache, and redirect him out to the original url"""
name = request.params['myname'].strip().encode('UTF-8')
location = request.params['location'].strip().encode('UTF-8')
email_addr = request.params['email'].strip().encode('UTF-8')
ip = request.params['ip'].strip().encode('UTF-8')
url = request.params['url']
# time is measured in seconds, give 8 hours.
syslog.syslog(
'VISITOR WEB SIGNIN: name %s, ip %s, location %s,email %s' %
(name, ip, location, email_addr) )
try:
send_email(name, ip, location, email_addr)
except Exception as excpt:
syslog.syslog('VISITOR WEB SIGNIN: ' + str(excpt) )
# here we are remembering that the user has registered, and
# setting the term to be 8 hours (8 * 60 * 60 seconds).
mc.set(ip, name + ':' + location + ':' + email_addr, time= 8 * 60 * 60)
# and now redirect to original request
return HTTPFound(location=url)
signin() takes care of displaying the information screen, which is generated by signin.pt (see below). The squid redirector process gives us the IP of the machine requesting a web resource, and the requested URL. We will store these as hidden fields for use by permit():
def signin(request):
"""Just return a form, IP and URL come from the squid redirector, and
are encoded as query string parameters."""
return dict(ip=request.params['ip'], url=request.params['url'] )
And this is the configuration. permit is registered as a view, signin is registered as the default view with renderer sigin.pt, a static directory is configured to put jquery in. A app is contructed and the run. You need to fix the 127.0.0.1 per your squid proxy. It should listen to the internal arm of your proxy (only):
if __name__ == '__main__':
config = Configurator()
config.add_view(permit, name='permit')
# __main__ is a special asset specification
config.add_view(signin, renderer='__main__:signin.pt')
config.add_static_view(name='static', path='__main__:static')
app = config.make_wsgi_app()
serve(app, host='127.0.0.1', port=8081)