from wsgicollection import Collection from config import config, log from model import model from robaccia import render, http404, http304, http403, http405 import mcoll import os import cgi import sha import re import comment_tools import time import fcntl import urlparse from urllib import unquote tz = "%+03d:00" % (-time.altzone/3600,) DEFAULT_ENTRY = """ http://bitworking.org/foo/app/main/third %s """ def comment_key(entry_id, comment_id): return sha.sha(entry_id + comment_id + config.get('comments', 'secret')).hexdigest() def comfirm_comment_key(key, entry_id, comment_id): return key == sha.sha(entry_id + comment_id + config.get('comments', 'secret')).hexdigest() def atomfeed(environ, start_response): entry_list = [model.entry.get_by_updated_id(id) for id in model.entry.id_list_by_updated()[:config.getint("display", "entries_per_page")]] raw_etag = entry_list[0].updated return render(environ, start_response, "feed.atom", {"entry_list": entry_list, "tz":tz}, raw_etag=raw_etag) def comment_atomfeed(environ, start_response): ids = model.recent_comments('entry')[:config.getint("display", "entries_per_page")] comments = [] for (id, comment_id) in ids: member = model.comments('entry', id).get(comment_id) if member: member['entry'] = model.entry.get(id) member['parsed_author'] = comment_tools.safeparsename(member['author']) comments.append(member) raw_etag = comments[0].updated return render(environ, start_response, "comment_feed.atom", {'comments': comments, "tz": tz}, raw_etag=raw_etag) def archives(environ, start_response): entry_list = [model.entry.get_by_published_id(id) for id in model.entry.id_list_by_published()] def row(entries): last_year = -1 last_month = -1 for entry in entries: pub = time.strptime(entry['published'].rsplit(".",1)[0], "%Y-%m-%dT%H:%M:%S") year = pub.tm_year if year != last_year: last_year = year yield (year, None, None, None, None) month = pub.tm_mon if month != last_month: last_month = month yield (None, time.strftime("%b", pub), None, None, None) yield (None, None, time.strftime("%d", pub), entry['title'], entry['slug'] and entry['id'] + "/" + entry['slug'] or entry['id']) raw_etag = entry_list[0].published return render(environ, start_response, "archives.xhtml", {"row_list": row(entry_list)}, raw_etag=raw_etag) def list(environ, start_response): collection = model.collection(environ.get('1812.collection', 'entry')) entry_list = [collection.get_by_published_id(id) for id in collection.id_list_by_published()[:config.getint("display", "entries_per_page")]] raw_etag = [] for e in entry_list: raw_etag.append(e.updated) c = model.comments('entry', e['id']) e['comment_count'] = len(c.id_list()) raw_etag.append(str(e['comment_count'])) raw_etag = "-".join(raw_etag) return render(environ, start_response, "index.xhtml", {"entry_list": entry_list}, raw_etag=raw_etag) def log_comment_create(id, comment_id): f = open(os.path.join(config.get('entry', 'comments'), "recent"), "a") fcntl.flock(f, fcntl.LOCK_EX) f.write("%s %s\n" % (id, comment_id)) fcntl.flock(f, fcntl.LOCK_UN) f.close() def add_comment(environ, start_response): import feedparser # 'name' and 'comment' args = environ['wsgiorg.routing_args'][1] id = args['id'] f = cgi.parse_qs(environ['wsgi.input'].read()) edit = f.get('edit', [''])[0] name = f.get('name', [''])[0] comment = f.get('comment', [''])[0] example = f.get('example', [''])[0] log.info(str(f)) author = comment_tools.parsename(name) log.info(str(author)) if not author or not example or not comment: start_response("200 Ok", [('content-type', 'text/html')]) return ["""
        
           You appear to either be a robot or someone 
           that hasn't followed the directions. If you are the latter
           then press the 'back' button and try again.
"""] feed = feedparser.parse(DEFAULT_ENTRY % comment) message = {} message['author'] = "%(name)s (%(uri)s)" % author message['content'] = feed.entries[0].content[0].value entry = model.entry.get(id) updated = time.mktime(time.strptime(entry['updated'].rsplit(".",1)[0], "%Y-%m-%dT%H:%M:%S")) if (time.time() - updated) > 5*24*60*60: return http403(environ, start_response) comment_id = model.comments('entry', id).create(message) log_comment_create(id, comment_id) start_response("303 See Other", [('location', environ['REQUEST_URI'] + (";edit_comment_form?key=%s&comment_id=%s#X%s" % (comment_key(id, comment_id), comment_id, comment_id)))]) return [] def retrieve(environ, start_response): collection = model.collection(environ.get('1812.collection', 'entry')) args = environ['wsgiorg.routing_args'][1] id = args['id'] slug = args.get('slug', '') or '' if not id in collection: return http404(environ, start_response) entry = collection.get(id) if slug != entry['slug']: return http404(environ, start_response) raw_etag = [entry.updated] comment_coll = model.comments('entry', id) comments = [comment_coll.get_by_published_id(id) for id in sorted(comment_coll.id_list_by_published())] updated = time.mktime(time.strptime(entry['updated'].rsplit(".",1)[0], "%Y-%m-%dT%H:%M:%S")) allow_comments = (time.time() - updated) < 5*24*60*60 for c in comments: raw_etag.append(c.id) raw_etag.append(c.updated) c['parsed_author'] = comment_tools.safeparsename(c['author']) raw_etag = "-".join(raw_etag) return render(environ, start_response, "entry_comment_form.xhtml", {"entry": entry, "comments": comments, "allow_comments": allow_comments}, raw_etag=raw_etag) def edit_retrieve(environ, start_response): collection = model.collection(environ.get('1812.collection', 'entry')) args = environ['wsgiorg.routing_args'][1] id = args['id'] fieldstorage = cgi.parse_qs(environ.get('QUERY_STRING', '')) comment_id = fieldstorage.get('comment_id', [''])[0] slug = args.get('slug', '') or '' if not id in collection: return http404(environ, start_response) entry = collection.get(id) if slug != entry['slug']: return http404(environ, start_response) comment_coll = model.comments('entry', id) if not comment_id in comment_coll: return http404(environ, start_response) comments = [comment_coll.get_by_published_id(id) for id in sorted(comment_coll.id_list_by_published())] for c in comments: c['parsed_author'] = comment_tools.safeparsename(c['author']) log.warning("comment id == %s" % comment_id) comment = comment_coll.get(comment_id) return render(environ, start_response, "entry_preview_form.xhtml", {"entry": entry, "comments": comments, "edited_comment": comment}) def edit_update(environ, start_response): import feedparser # 'name' and 'comment' args = environ['wsgiorg.routing_args'][1] id = args['id'] fieldstorage = cgi.parse_qs(environ.get('QUERY_STRING', '')) comment_id = fieldstorage.get('comment_id', [''])[0] key = fieldstorage.get('key', [''])[0] log.info(key) if not comfirm_comment_key(key, id, comment_id): return http403(environ, start_response) old_message = model.comments('entry', id).get(comment_id) old_time = time.mktime(time.strptime(old_message['updated'].rsplit(".",1)[0], "%Y-%m-%dT%H:%M:%S")) if (time.time() - old_time) > 300: return http403(environ, start_response) f = cgi.parse(environ['wsgi.input']) name = f.get('name', [''])[0] comment = f.get('comment', [''])[0] example = f.get('example', [''])[0] log.info(str(f)) author = comment_tools.parsename(name) log.info(str(author)) if not author or not example or not comment: start_response("200 Ok", [('content-type', 'text/html')]) return ["""
        
           You appear to either be a robot or someone 
           that hasn't followed the directions. If you are the latter
           then press the 'back' button and try again.
"""] feed = feedparser.parse(DEFAULT_ENTRY % comment) message = {} message['author'] = "%(name)s (%(uri)s)" % author message['content'] = feed.entries[0].content[0].value fieldstorage = cgi.parse_qs(environ.get('QUERY_STRING', '')) comment_id = fieldstorage.get('comment_id', [''])[0] model.comments('entry', id).put(comment_id, message) start_response("303 See Other", [('Location', environ['REQUEST_URI'])]) return []