Permalink
Browse files

Added snippet database to the website.

  • Loading branch information...
1 parent a81cf3a commit 0ab7a9cb67bcb6cc916f4c7ba75100b55dbe675c @mitsuhiko mitsuhiko committed May 3, 2010
View
@@ -1,17 +1,25 @@
-from flask import Flask, render_template
+from flask import Flask, session, g, render_template
import websiteconfig as config
app = Flask(__name__)
app.debug = config.DEBUG
+app.secret_key = config.SECRET_KEY
@app.errorhandler(404)
def not_found(error):
return render_template('404.html'), 404
+@app.before_request
+def load_currrent_user():
+ g.user = User.query.filter_by(openid=session['openid']).first() \
+ if 'openid' in session else None
+
from flask_website.views.general import general
from flask_website.views.mailinglist import mailinglist
from flask_website.views.snippets import snippets
app.register_module(general)
app.register_module(mailinglist)
app.register_module(snippets)
+
+from flask_website.database import User
@@ -1,83 +0,0 @@
-from __future__ import with_statement
-
-from time import time
-from hashlib import sha1
-from contextlib import closing
-
-from openid.association import Association
-from openid.store.interface import OpenIDStore
-from openid.consumer.consumer import Consumer, SUCCESS, CANCEL
-from openid.consumer import discover
-from openid.store import nonce
-
-from sqlalchemy.orm import scoped_session
-from sqlalchemy.exceptions import SQLError
-
-from flask import request, redirect, abort, url_for, flash
-from flask_website.database import User, db_session
-
-
-class WebsiteOpenIDStore(OpenIDStore):
- """Implements the open store for the website using the database."""
-
- def storeAssociation(self, server_url, association):
- assoc = OpenIDAssociation(
- server_url=server_url,
- handle=association.handle,
- secret=association.secret.encode('base64'),
- issued=association.issued,
- lifetime=association.lifetime,
- assoc_type=association.assoc_type
- )
- db_session.add(assoc)
-
- def getAssociation(self, server_url, handle=None):
- q = OpenIDAssociation.query.filter_by(server_url=server_url)
- if handle is not None:
- q = q.filter_by(handle=handle)
- result_assoc = None
- for item in q.all():
- assoc = Association(item.handle, item.secret.decode('base64'),
- item.issued, item.lifetime, item.assoc_type)
- if assoc.getExpiresIn() <= 0:
- self.removeAssociation(server_url, assoc.handle)
- else:
- result_assoc = assoc
- return result_assoc
-
- def removeAssociation(self, server_url, handle):
- return OpenIDAssociation.filter(
- (OpenIDAssociation.server_url == server_url) &
- (OpenIDAssociation.handle == handle)
- ).delete()
-
- def useNonce(self, server_url, timestamp, salt):
- if abs(timestamp - time()) > nonce.SKEW:
- return False
- rv = OpenIDUserNonces.query.filter(
- (OpenIDUserNonces.server_url == server_url) &
- (OpenIDUserNonces.timestamp == timestamp) &
- (OpenIDUserNonces.salt == salt)
- ).first()
- if rv is not None:
- return False
- rv = OpenIDUserNonces(server_url=server_url, timestamp=timestamp,
- salt=salt)
- session.add(rv)
- return True
-
- def cleanupNonces(self):
- return OpenIDUserNonces.filter(
- OpenIDUserNonces.timestamp <= int(time() - nonce.SKEW)
- ).delete()
-
- def cleanupAssociations(self):
- return OpenIDAssociation.filter(
- OpenIDAssociation.lifetime < int(time())
- ).delete()
-
- def getAuthKey(self):
- return sha1(config.SECRET_KEY).hexdigest()[:self.AUTH_KEY_LEN]
-
- def isDump(self):
- return False
View
@@ -1,9 +1,12 @@
from datetime import datetime
from sqlalchemy import create_engine, MetaData, Table, Column, Integer, \
String, DateTime, ForeignKey
-from sqlalchemy.orm import scoped_session, sessionmaker, backref
+from sqlalchemy.orm import scoped_session, sessionmaker, backref, relation
from sqlalchemy.ext.declarative import declarative_base
+from werkzeug import cached_property
+
+from flask import url_for
from flask_website import config
engine = create_engine(config.DATABASE_URI)
@@ -15,20 +18,25 @@ def init_db():
Model.metadata.create_all(bind=engine)
-class Model(declarative_base()):
- query = db_session.query_property()
+Model = declarative_base(name='Model')
+Model.query = db_session.query_property()
class User(Model):
__tablename__ = 'users'
id = Column('user_id', Integer, primary_key=True)
openid = Column('openid', String(200))
- username = Column(String(40), unique=True)
- password = Column(String(80))
+ name = Column(String(200), unique=True)
+
+ def __init__(self, name, openid):
+ self.name = name
+ self.openid = openid
+
+ def __eq__(self, other):
+ return type(self) is type(other) and self.id == other.id
- def __init__(self, username, password):
- self.username = username
- self.password = password
+ def __ne__(self, other):
+ return not self.__eq__(other)
class Category(Model):
@@ -37,40 +45,73 @@ class Category(Model):
name = Column(String(50))
slug = Column(String(50))
+ def __init__(self, name):
+ self.name = name
+ self.slug = '-'.join(name.split()).lower()
+
+ @cached_property
+ def count(self):
+ return self.snippets.count()
+
+ @property
+ def url(self):
+ return url_for('snippets.category', slug=self.slug)
+
class Snippet(Model):
__tablename__ = 'snippets'
id = Column('snippet_id', Integer, primary_key=True)
- author = ForeignKey(User, backref=backref('snippets', lazy='dynamic'))
- category = ForeignKey(Category, backref=backref('snippets', lazy='dynamic'))
+ author_id = Column(Integer, ForeignKey('users.user_id'))
+ author = relation(User, backref=backref('snippets', lazy='dynamic'))
+ category_id = Column(Integer, ForeignKey('categories.category_id'))
+ category = relation(Category, backref=backref('snippets', lazy='dynamic'))
title = Column(String(200))
body = Column(String)
- pub_date = DateTime()
+ pub_date = Column(DateTime)
- def __init__(self, author, title, body):
+ def __init__(self, author, title, body, category):
self.author = author
self.title = title
self.body = body
+ self.category = category
self.pub_date = datetime.utcnow()
+ @property
+ def url(self):
+ return url_for('snippets.show', id=self.id)
+
+ @property
+ def rendered_body(self):
+ from flask_website.utils import format_creole
+ return format_creole(self.body)
+
class Comment(Model):
__tablename__ = 'comments'
id = Column('comment_id', Integer, primary_key=True)
- snippet = ForeignKey(Snippet, backref='lazy')
- author = ForeignKey(User, backref=backref('comments', lazy='dynamic'))
+ snippet_id = Column(Integer, ForeignKey('snippets.snippet_id'))
+ snippet = relation(Snippet, backref=backref('comments', lazy=True))
+ author_id = Column(Integer, ForeignKey('users.user_id'))
+ author = relation(User, backref=backref('comments', lazy='dynamic'))
title = Column(String(200))
text = Column(String)
- pub_date = DateTime()
+ pub_date = Column(DateTime)
- def __init__(self, author, title, text):
+ def __init__(self, snippet, author, title, text):
+ self.snippet = snippet
self.author = author
self.title = title
self.text = text
self.pub_date = datetime.utcnow()
+ @property
+ def rendered_text(self):
+ from flask_website.utils import format_creole
+ return format_creole(self.text)
+
class OpenIDAssociation(Model):
+ __tablename__ = 'openid_associations'
id = Column('association_id', Integer, primary_key=True)
server_url = Column(String(1024))
handle = Column(String(255))
@@ -80,7 +121,8 @@ class OpenIDAssociation(Model):
assoc_type = Column(String(64))
-class OpenIDUserNonces(Model):
+class OpenIDUserNonce(Model):
+ __tablename__ = 'openid_user_nonces'
id = Column('user_nonce_id', Integer, primary_key=True)
server_url = Column(String(1024))
timestamp = Column(Integer)
@@ -0,0 +1,86 @@
+# flasky extensions. flasky pygments style based on tango style
+from pygments.style import Style
+from pygments.token import Keyword, Name, Comment, String, Error, \
+ Number, Operator, Generic, Whitespace, Punctuation, Other, Literal
+
+
+class FlaskyStyle(Style):
+ background_color = "#f8f8f8"
+ default_style = ""
+
+ styles = {
+ # No corresponding class for the following:
+ #Text: "", # class: ''
+ Whitespace: "underline #f8f8f8", # class: 'w'
+ Error: "#a40000 border:#ef2929", # class: 'err'
+ Other: "#000000", # class 'x'
+
+ Comment: "italic #8f5902", # class: 'c'
+ Comment.Preproc: "noitalic", # class: 'cp'
+
+ Keyword: "bold #004461", # class: 'k'
+ Keyword.Constant: "bold #004461", # class: 'kc'
+ Keyword.Declaration: "bold #004461", # class: 'kd'
+ Keyword.Namespace: "bold #004461", # class: 'kn'
+ Keyword.Pseudo: "bold #004461", # class: 'kp'
+ Keyword.Reserved: "bold #004461", # class: 'kr'
+ Keyword.Type: "bold #004461", # class: 'kt'
+
+ Operator: "#582800", # class: 'o'
+ Operator.Word: "bold #004461", # class: 'ow' - like keywords
+
+ Punctuation: "bold #000000", # class: 'p'
+
+ # because special names such as Name.Class, Name.Function, etc.
+ # are not recognized as such later in the parsing, we choose them
+ # to look the same as ordinary variables.
+ Name: "#000000", # class: 'n'
+ Name.Attribute: "#c4a000", # class: 'na' - to be revised
+ Name.Builtin: "#004461", # class: 'nb'
+ Name.Builtin.Pseudo: "#3465a4", # class: 'bp'
+ Name.Class: "#000000", # class: 'nc' - to be revised
+ Name.Constant: "#000000", # class: 'no' - to be revised
+ Name.Decorator: "#888", # class: 'nd' - to be revised
+ Name.Entity: "#ce5c00", # class: 'ni'
+ Name.Exception: "bold #cc0000", # class: 'ne'
+ Name.Function: "#000000", # class: 'nf'
+ Name.Property: "#000000", # class: 'py'
+ Name.Label: "#f57900", # class: 'nl'
+ Name.Namespace: "#000000", # class: 'nn' - to be revised
+ Name.Other: "#000000", # class: 'nx'
+ Name.Tag: "bold #004461", # class: 'nt' - like a keyword
+ Name.Variable: "#000000", # class: 'nv' - to be revised
+ Name.Variable.Class: "#000000", # class: 'vc' - to be revised
+ Name.Variable.Global: "#000000", # class: 'vg' - to be revised
+ Name.Variable.Instance: "#000000", # class: 'vi' - to be revised
+
+ Number: "#990000", # class: 'm'
+
+ Literal: "#000000", # class: 'l'
+ Literal.Date: "#000000", # class: 'ld'
+
+ String: "#4e9a06", # class: 's'
+ String.Backtick: "#4e9a06", # class: 'sb'
+ String.Char: "#4e9a06", # class: 'sc'
+ String.Doc: "italic #8f5902", # class: 'sd' - like a comment
+ String.Double: "#4e9a06", # class: 's2'
+ String.Escape: "#4e9a06", # class: 'se'
+ String.Heredoc: "#4e9a06", # class: 'sh'
+ String.Interpol: "#4e9a06", # class: 'si'
+ String.Other: "#4e9a06", # class: 'sx'
+ String.Regex: "#4e9a06", # class: 'sr'
+ String.Single: "#4e9a06", # class: 's1'
+ String.Symbol: "#4e9a06", # class: 'ss'
+
+ Generic: "#000000", # class: 'g'
+ Generic.Deleted: "#a40000", # class: 'gd'
+ Generic.Emph: "italic #000000", # class: 'ge'
+ Generic.Error: "#ef2929", # class: 'gr'
+ Generic.Heading: "bold #000080", # class: 'gh'
+ Generic.Inserted: "#00A000", # class: 'gi'
+ Generic.Output: "#888", # class: 'go'
+ Generic.Prompt: "#745334", # class: 'gp'
+ Generic.Strong: "bold #000000", # class: 'gs'
+ Generic.Subheading: "bold #800080", # class: 'gu'
+ Generic.Traceback: "bold #a40000", # class: 'gt'
+ }
Oops, something went wrong.

0 comments on commit 0ab7a9c

Please sign in to comment.