#!/usr/bin/python2.5
import cgi, re, os, sys, pickle, ConfigParser
from xml.sax.saxutils import escape, quoteattr
from glob import glob
import config, nonce
from get import resize
for path in glob(config.openid.code): sys.path.insert(0,path)
from openid.consumer import consumer
from openid.store import filestore
try:
store = filestore.FileOpenIDStore(config.openid.filestore)
# initialize
warn = ''
session = None
subs = []
sub_all = sub_cmt = sub_new = ''
user_name = user_jid = ''
# fetch id from post form
fs = cgi.FieldStorage()
env = os.environ
id=fs.getvalue('url','')
args = dict([(field.name,field.value) for field in fs.list])
test = fs.has_key('test')
# if not found, try cookie
if not id:
import Cookie, urllib
cookie = Cookie.SimpleCookie()
if(env.has_key('HTTP_COOKIE')): cookie.load(env['HTTP_COOKIE'])
if cookie.has_key('xmpp_id'):
id = urllib.unquote(cookie['xmpp_id'].value)
elif cookie.has_key('cmt_url'):
id = urllib.unquote(cookie['cmt_url'].value)
# if xid can be authenticated, restore the session
if fs.has_key('xid'):
xid = nonce.retrieve(fs.getvalue('xid'))
if xid:
session = pickle.loads(xid)
server = consumer.Consumer(session, store)
response = server.complete(args)
if response.status != consumer.SUCCESS:
session = None
warn = '
OpenID login failed
'
else:
extension = response.extensionResponse('sreg',True)
if extension.has_key('nickname'): user_name = extension['nickname']
if extension.has_key('fullname'): user_name = extension['fullname']
# if a session hasn't been established yet, establish one
if id and not session and not test:
import identity
args['REQUEST_METHOD'] = env.get('REQUEST_METHOD','')
redirect = identity.lookup(id, args, config.channel.registry)
if redirect:
print 'Status: 302 Found\r\nLocation: %s\r\n\r\nRedirecting' % redirect
sys.exit()
else:
warn = '
URI not OpenID enabled
'
# retrieve session values
if session:
if env.get('REQUEST_METHOD','')=='POST':
session['REQUEST_METHOD'] = 'POST'
else:
id = session.get('url',id)
user_name = session.get('name',user_name)
user_jid = session.get('email',user_jid)
subs = [name[4:] for name,value in session.items()
if name.startswith('sub_')]
if session.has_key('xall'): sub_all = ' checked="on"'
if session.has_key('xcmt'): sub_cmt = ' checked="on"'
if session.has_key('xnew'): sub_new = ' checked="on"'
# retrieve POST values
if env.get('REQUEST_METHOD','')=='POST':
user_name = fs.getvalue('name',user_name)
user_jid = fs.getvalue('email',user_jid)
subs = [field.name[4:] for field in fs.list
if field.name.startswith('sub_')]
if fs.has_key('xall'): sub_all = ' checked="on"'
if fs.has_key('xcmt'): sub_cmt = ' checked="on"'
if fs.has_key('xnew'): sub_new = ' checked="on"'
# send a test message
if test and user_jid:
import xnotify
plain_text = "This is a plaintext message. " + \
"If you see this, your client does NOT support XHTML-IM."
xhtml = "This is an %s message. " % \
'XHTML-IM' + \
"If you see this, your client does support XHTML-IM."
xnotify.send_message([user_jid], plain_text, xhtml, register=True)
# map id to a filename
if id:
filename = id
if id.startswith('http://') or id.startswith('https://'):
filename = filename.split('/',2)[-1].strip('/')
filename = re.sub(r'[?/:|]+', ',', filename)
# if this is an authenticated POST, write out the forms values
if id and session and session.get('REQUEST_METHOD','')=='POST' and not test:
parser = ConfigParser.ConfigParser()
parser.add_section('owner')
parser.set('owner','name',user_name)
parser.set('owner','jid',user_jid)
parser.set('owner','id',id)
parser.add_section('subscriptions')
parser.set('subscriptions','entries',' '.join(subs))
parser.set('subscriptions','sub_all',bool(sub_all))
parser.set('subscriptions','sub_cmt',bool(sub_cmt))
parser.set('subscriptions','sub_new',bool(sub_new))
parser.write(open(config.directory.registry + filename,'w'))
# read registration
if id and session and not test:
parser = ConfigParser.ConfigParser()
parser.read(config.directory.registry + filename)
if parser.has_option('owner','name'):
user_name = parser.get('owner', 'name') or user_name
if parser.has_option('owner','jid'):
user_jid = parser.get('owner', 'jid')
if parser.has_option('subscriptions','entries'):
subs = parser.get('subscriptions','entries').split(' ')
if parser.has_option('subscriptions','sub_all'):
if parser.getboolean('subscriptions','sub_all'): sub_all = ' checked="on"'
if parser.has_option('subscriptions','sub_new'):
if parser.getboolean('subscriptions','sub_new'): sub_new = ' checked="on"'
if parser.has_option('subscriptions','sub_cmt'):
if parser.getboolean('subscriptions','sub_cmt'): sub_cmt = ' checked="on"'
# get the ten most recent posts that have recent comments
cmt_re = re.compile('\d+-(\d+)\.cmt$')
os.chdir(config.directory.data)
blogdir = os.listdir('.')
blogdir = [(cmt_re.findall(name) or [str(os.stat(name).st_mtime)],name)
for name in blogdir]
blogdir.sort()
blogdir.reverse()
latest = []
for mtime, file in blogdir:
if file.startswith('.'): continue
if file.endswith('.html'): continue
post = file.split('-')[0].split('.')[0]
if post not in latest:
latest.append(post)
if len(latest) >= 10: break
# ensure all active subscriptions are on the 'latest' list
for sub in subs:
if sub not in latest: latest.append(sub)
# read routes
routes = ConfigParser.ConfigParser()
routes.read('/home/rubys/.xnotify')
xmpp_server = {}
for name in routes.sections() + ['DEFAULT']:
if routes.has_option(name,'class') and \
routes.get(name,'class') == 'private': continue
xmpp_server[name] = routes.get(name,'user').split('@')
# save xmpp id as a cookie
if id and session:
import Cookie, time
cookie = Cookie.SimpleCookie()
cookie['xmpp_id'] = id
expire = time.gmtime(time.time() + 365 * 24 * 60 * 60)
expire_date = time.strftime('%a %d-%b-%Y %H:%M:%S GMT', expire)
cookie['xmpp_id']['expires'] = expire_date
cookie['xmpp_id']['path'] = '/'
cookie['xmpp_id']['domain'] = config.channel.link.split('/')[2]
print str(cookie) + '\r'
except SystemExit:
raise
except:
#######################################################################
# Format tracebacks for display #
#######################################################################
import traceback
tb = ''.join(apply(traceback.format_exception, sys.exc_info()))
import nonce,time
nonce.generate(time.time()+86400, tb)
print 'Status: 500 Internal Error\r\nContent-type: text/html\r\n'
from xml.sax.saxutils import escape
print ''
print 'CGI Failure'
print ''
print '