Skip to content

Commit 0a0d00f

Browse files
committed
re-add the lj as it will stand at the end of class today.
1 parent c3c5349 commit 0a0d00f

30 files changed

+1043
-0
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
*.pyc
2+
.DS_Store
3+
*.egg-info
4+
*.sqlite
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
0.0
2+
---
3+
4+
- Initial version
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
include *.txt *.ini *.cfg *.rst
2+
recursive-include learning_journal *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
web: ./run
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
learning_journal README
2+
==================
3+
4+
Getting Started
5+
---------------
6+
7+
- cd <directory containing this file>
8+
9+
- $VENV/bin/python setup.py develop
10+
11+
- $VENV/bin/initialize_learning_journal_db development.ini
12+
13+
- $VENV/bin/pserve development.ini
14+
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#!/bin/bash
2+
python setup.py develop
3+
initialize_learning_journal_db production.ini
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
###
2+
# app configuration
3+
# http://docs.pylonsproject.org/projects/pyramid/en/1.5-branch/narr/environment.html
4+
###
5+
6+
[app:main]
7+
use = egg:learning_journal
8+
9+
pyramid.reload_templates = true
10+
pyramid.debug_authorization = false
11+
pyramid.debug_notfound = false
12+
pyramid.debug_routematch = false
13+
pyramid.default_locale_name = en
14+
pyramid.includes =
15+
pyramid_debugtoolbar
16+
pyramid_tm
17+
18+
sqlalchemy.url = sqlite:///%(here)s/learning_journal.sqlite
19+
20+
jinja2.filters =
21+
markdown = learning_journal.views.render_markdown
22+
23+
# By default, the toolbar only appears for clients from IP addresses
24+
# '127.0.0.1' and '::1'.
25+
# debugtoolbar.hosts = 127.0.0.1 ::1
26+
27+
###
28+
# wsgi server configuration
29+
###
30+
31+
[server:main]
32+
use = egg:waitress#main
33+
host = 0.0.0.0
34+
port = 6543
35+
36+
###
37+
# logging configuration
38+
# http://docs.pylonsproject.org/projects/pyramid/en/1.5-branch/narr/logging.html
39+
###
40+
41+
[loggers]
42+
keys = root, learning_journal, sqlalchemy
43+
44+
[handlers]
45+
keys = console
46+
47+
[formatters]
48+
keys = generic
49+
50+
[logger_root]
51+
level = INFO
52+
handlers = console
53+
54+
[logger_learning_journal]
55+
level = DEBUG
56+
handlers =
57+
qualname = learning_journal
58+
59+
[logger_sqlalchemy]
60+
level = INFO
61+
handlers =
62+
qualname = sqlalchemy.engine
63+
# "level = INFO" logs SQL queries.
64+
# "level = DEBUG" logs SQL queries and results.
65+
# "level = WARN" logs neither. (Recommended for production systems.)
66+
67+
[handler_console]
68+
class = StreamHandler
69+
args = (sys.stderr,)
70+
level = NOTSET
71+
formatter = generic
72+
73+
[formatter_generic]
74+
format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import os
2+
from pyramid.authentication import AuthTktAuthenticationPolicy
3+
from pyramid.authorization import ACLAuthorizationPolicy
4+
from pyramid.config import Configurator
5+
from sqlalchemy import engine_from_config
6+
7+
from .models import (
8+
DBSession,
9+
Base,
10+
)
11+
from .security import EntryFactory
12+
13+
14+
def main(global_config, **settings):
15+
""" This function returns a Pyramid WSGI application.
16+
"""
17+
if 'DATABASE_URL' in os.environ:
18+
settings['sqlalchemy.url'] = os.environ['DATABASE_URL']
19+
engine = engine_from_config(settings, 'sqlalchemy.')
20+
engine = engine_from_config(settings, 'sqlalchemy.')
21+
DBSession.configure(bind=engine)
22+
Base.metadata.bind = engine
23+
secret = os.environ.get('AUTH_SECRET', 'somesecret')
24+
config = Configurator(
25+
settings=settings,
26+
authentication_policy=AuthTktAuthenticationPolicy(secret),
27+
authorization_policy=ACLAuthorizationPolicy(),
28+
default_permission='view'
29+
)
30+
config.include('pyramid_jinja2')
31+
config.add_static_view('static', 'static', cache_max_age=3600)
32+
config.add_route('home', '/', factory=EntryFactory)
33+
config.add_route('detail', '/journal/{id:\d+}', factory=EntryFactory)
34+
config.add_route('action', '/journal/{action}', factory=EntryFactory)
35+
config.add_route('auth', '/sign/{action}', factory=EntryFactory)
36+
config.scan()
37+
return config.make_wsgi_app()
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
from wtforms import (
2+
Form,
3+
HiddenField,
4+
PasswordField,
5+
TextField,
6+
TextAreaField,
7+
validators,
8+
)
9+
10+
strip_filter = lambda x: x.strip() if x else None
11+
12+
13+
class EntryCreateForm(Form):
14+
title = TextField(
15+
'Entry title',
16+
[validators.Length(min=1, max=255)],
17+
filters=[strip_filter]
18+
)
19+
body = TextAreaField(
20+
'Entry body',
21+
[validators.Length(min=1)],
22+
filters=[strip_filter]
23+
)
24+
25+
26+
class EntryEditForm(EntryCreateForm):
27+
id = HiddenField()
28+
29+
class LoginForm(Form):
30+
username = TextField('Username', [validators.Length(min=1, max=255)])
31+
password = PasswordField('Password', [validators.Length(min=1, max=255)])
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import datetime
2+
from sqlalchemy import (
3+
Column,
4+
DateTime,
5+
Index,
6+
Integer,
7+
Text,
8+
Unicode,
9+
UnicodeText,
10+
)
11+
12+
# from cryptacular.pbkdf2 import PBKDF2PassordManager as Manager
13+
from cryptacular.bcrypt import BCRYPTPasswordManager as Manager
14+
15+
import sqlalchemy as sa
16+
from sqlalchemy.ext.declarative import declarative_base
17+
18+
from sqlalchemy.orm import (
19+
scoped_session,
20+
sessionmaker,
21+
)
22+
23+
from zope.sqlalchemy import ZopeTransactionExtension
24+
25+
DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension()))
26+
Base = declarative_base()
27+
28+
29+
class MyModel(Base):
30+
__tablename__ = 'models'
31+
id = Column(Integer, primary_key=True)
32+
name = Column(Text)
33+
value = Column(Integer)
34+
35+
Index('my_index', MyModel.name, unique=True, mysql_length=255)
36+
37+
38+
class Entry(Base):
39+
__tablename__ = 'entries'
40+
id = Column(Integer, primary_key=True)
41+
title = Column(Unicode(255), unique=True, nullable=False)
42+
body = Column(UnicodeText, default=u'')
43+
created = Column(DateTime, default=datetime.datetime.utcnow)
44+
edited = Column(DateTime, default=datetime.datetime.utcnow)
45+
46+
@classmethod
47+
def all(cls, session=None):
48+
"""return a query with all entries, ordered by creation date reversed
49+
"""
50+
if session is None:
51+
session = DBSession
52+
return session.query(cls).order_by(sa.desc(cls.created)).all()
53+
54+
@classmethod
55+
def by_id(cls, id, session=None):
56+
"""return a single entry identified by id
57+
58+
If no entry exists with the provided id, return None
59+
"""
60+
if session is None:
61+
session = DBSession
62+
return session.query(cls).get(id)
63+
64+
65+
class User(Base):
66+
__tablename__ = 'users'
67+
id = Column(Integer, primary_key=True, autoincrement=True)
68+
name = Column(Unicode(255), unique=True, nullable=False)
69+
password = Column(Unicode(255), nullable=False)
70+
71+
@classmethod
72+
def by_name(cls, name, session=None):
73+
if session is None:
74+
session = DBSession
75+
return DBSession.query(User).filter(User.name == name).first()
76+
77+
def verify_password(self, password):
78+
manager = Manager()
79+
return manager.check(self.password, password)

0 commit comments

Comments
 (0)