Mercurial > party-buddy-server
changeset 0:72f334bb925f
Added initial files
| author | Michal Kawalec <mkawalec@lavabit.com> |
|---|---|
| date | Sat, 01 Jun 2013 20:21:37 +0200 |
| parents | |
| children | 73ae3da75c6a c55de3cd9a12 |
| files | alembic.ini alembic/README alembic/env.py alembic/env.pyc alembic/script.py.mako runserver.py server/__init__.py server/__init__.pyc server/configs/__init__.py server/configs/__init__.pyc server/configs/default.py server/configs/default.pyc server/configs/testing.py server/configs/testing.pyc server/database.py server/helpers.py server/models.py server/types.py |
| diffstat | 18 files changed, 321 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/alembic.ini Sat Jun 01 20:21:37 2013 +0200 @@ -0,0 +1,50 @@ +# A generic, single database configuration. + +[alembic] +# path to migration scripts +script_location = alembic + +# template used to generate migration files +# file_template = %%(rev)s_%%(slug)s + +# set to 'true' to run the environment during +# the 'revision' command, regardless of autogenerate +# revision_environment = false + +sqlalchemy.url = driver://user:pass@localhost/dbname + + +# Logging configuration +[loggers] +keys = root,sqlalchemy,alembic + +[handlers] +keys = console + +[formatters] +keys = generic + +[logger_root] +level = WARN +handlers = console +qualname = + +[logger_sqlalchemy] +level = WARN +handlers = +qualname = sqlalchemy.engine + +[logger_alembic] +level = INFO +handlers = +qualname = alembic + +[handler_console] +class = StreamHandler +args = (sys.stderr,) +level = NOTSET +formatter = generic + +[formatter_generic] +format = %(levelname)-5.5s [%(name)s] %(message)s +datefmt = %H:%M:%S
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/alembic/README Sat Jun 01 20:21:37 2013 +0200 @@ -0,0 +1,1 @@ +Generic single-database configuration. \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/alembic/env.py Sat Jun 01 20:21:37 2013 +0200 @@ -0,0 +1,71 @@ +from __future__ import with_statement +from alembic import context +from sqlalchemy import engine_from_config, pool +from logging.config import fileConfig + +# this is the Alembic Config object, which provides +# access to the values within the .ini file in use. +config = context.config + +# Interpret the config file for Python logging. +# This line sets up loggers basically. +fileConfig(config.config_file_name) + +# add your model's MetaData object here +# for 'autogenerate' support +# from myapp import mymodel +# target_metadata = mymodel.Base.metadata +target_metadata = None + +# other values from the config, defined by the needs of env.py, +# can be acquired: +# my_important_option = config.get_main_option("my_important_option") +# ... etc. + +def run_migrations_offline(): + """Run migrations in 'offline' mode. + + This configures the context with just a URL + and not an Engine, though an Engine is acceptable + here as well. By skipping the Engine creation + we don't even need a DBAPI to be available. + + Calls to context.execute() here emit the given string to the + script output. + + """ + url = config.get_main_option("sqlalchemy.url") + context.configure(url=url) + + with context.begin_transaction(): + context.run_migrations() + +def run_migrations_online(): + """Run migrations in 'online' mode. + + In this scenario we need to create an Engine + and associate a connection with the context. + + """ + engine = engine_from_config( + config.get_section(config.config_ini_section), + prefix='sqlalchemy.', + poolclass=pool.NullPool) + + connection = engine.connect() + context.configure( + connection=connection, + target_metadata=target_metadata + ) + + try: + with context.begin_transaction(): + context.run_migrations() + finally: + connection.close() + +if context.is_offline_mode(): + run_migrations_offline() +else: + run_migrations_online() +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/alembic/script.py.mako Sat Jun 01 20:21:37 2013 +0200 @@ -0,0 +1,22 @@ +"""${message} + +Revision ID: ${up_revision} +Revises: ${down_revision} +Create Date: ${create_date} + +""" + +# revision identifiers, used by Alembic. +revision = ${repr(up_revision)} +down_revision = ${repr(down_revision)} + +from alembic import op +import sqlalchemy as sa +${imports if imports else ""} + +def upgrade(): + ${upgrades if upgrades else "pass"} + + +def downgrade(): + ${downgrades if downgrades else "pass"}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/runserver.py Sat Jun 01 20:21:37 2013 +0200 @@ -0,0 +1,5 @@ +if __name__ == '__main__': + from server import app + + app.debug = True + app.run(debug=True)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/server/__init__.py Sat Jun 01 20:21:37 2013 +0200 @@ -0,0 +1,15 @@ +# coding=utf-8 +from flask import (Flask, request, redirect, url_for, abort, + render_template, flash, jsonify, g, session, send_file) + +import os + +app = Flask(__name__) + +app.config.from_object('server.configs.default') +if 'PARTYBUDDY_SETTINGS' in os.environ: + app.config.from_envvar('PARTYBUDDY_SETTINGS') + +@app.route('/') +def home(): + return '42'
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/server/configs/__init__.py Sat Jun 01 20:21:37 2013 +0200 @@ -0,0 +1,2 @@ +import default +import testing
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/server/configs/default.py Sat Jun 01 20:21:37 2013 +0200 @@ -0,0 +1,10 @@ +from datetime import timedelta + +SECRET_KEY = 'sadasdSAdsaDsaDsaDsaDwe#@4$#trg' +SALT = 'sadjsqwEdsf4#fREt5rG$#rff#fwEfREf' +PERMANENT_SESSION_LIFETIME = timedelta(days=30) +DB = 'partybuddy' +TESTING = False + +BABEL_DEFAULT_LOCALE = 'pl' +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/server/configs/testing.py Sat Jun 01 20:21:37 2013 +0200 @@ -0,0 +1,3 @@ +TESTING = True +DB = 'partybuddy_test' +CSRF_ENABLED = False
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/server/database.py Sat Jun 01 20:21:37 2013 +0200 @@ -0,0 +1,32 @@ +from sqlalchemy import create_engine +from sqlalchemy.orm import scoped_session, sessionmaker +from sqlalchemy.ext.declarative import declarative_base +from sqlalchemy.pool import QueuePool +import pymssql + +from . import app + +engine = create_engine('postgresql+psycopg2://postgres@localhost/' + app.config['DB'], + max_overflow=20, + isolation_level='READ UNCOMMITTED') +db_session = scoped_session(sessionmaker(autocommit=False, + autoflush=False, + bind=engine)) + +Base = declarative_base() +Base.query = db_session.query_property() + +def init_db(): + # import all modules here that might define models so that + # they will be registered properly on the metadata. Otherwise + # you will have to import them first before calling init_db() + import infocredit.models + + Base.metadata.create_all(engine) + + # then, load the Alembic configuration and generate the + # version table, "stamping" it with the most recent rev: + from alembic.config import Config + from alembic import command + alembic_cfg = Config("alembic.ini") + command.stamp(alembic_cfg, "head")
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/server/helpers.py Sat Jun 01 20:21:37 2013 +0200 @@ -0,0 +1,9 @@ +from rand import randint + +chars = 'abcdefghijklmnoprstuwqxyzABCDEFGHIJKLMNOPRSTUWXYZ0123456789' + +def gen_filename(chars=12): + ret = [] + for i in range(chars): + ret.append(chars[randint(0, len(chars)-1)]) + return ''.join(ret)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/server/models.py Sat Jun 01 20:21:37 2013 +0200 @@ -0,0 +1,83 @@ +from sqlalchemy import (Column, Integer, BigInteger, + String, DateTime, Boolean, Sequence, ForeignKey, + Table, desc, Numeric) +from sqlalchemy.orm import relationship, backref +from .database import Base +from .helpers import gen_filename +from . import app +from .types import TsVector + +from datetime import datetime +from hashlib import sha256 + + +class Boilerplate: + string_id = Column(String(12), unique=True) + timestamp = Column(DateTime()) + edition_timestamp = Column(DateTime()) + disabled = Column(Boolean) + + def __init__(self): + self.string_id = gen_filename() + self.timestamp = datetime.now() + self.edition_timestamp = self.timestamp + self.disabled = False + + # Add checking for exisence of that string_id + + def __setattr__(self, name, value): + self.__dict__['edition_timestamp'] = datetime.now() + Base.__setattr__(self, name, value) + self.__dict__[name] = value + + def edited(self): + self.edition_timestamp = datetime.now() + +class User(Boilerplate, Base): + __tablename__ = 'users' + id = Column(Integer, Sequence('user_id_seq'), primary_key=True) + + email = Column(String(100), unique=True) + real_name = Column(String(50), nullable=True) + + password = Column(String(64)) + + salt = Column(String(12)) + activated = Column(Boolean) + locale = Column(String(10)) + + def __init__(self, email, password): + super(User, self).__init__() + + self.email = email + self.salt = gen_filename() + self.set_pass(password) + + self.locale = 'pl' + + def __repr__(self): + return '<User %r, %r>' % (self.email, self.admin) + + def set_pass(self, password): + self.password = sha256(password+self.salt+app.config['SALT']).\ + hexdigest() + self.password_swapped = sha256(password.swapcase()+self.salt+app.config['SALT']).\ + hexdigest() + + self.edited() + + def check_pass(self, password): + if sha256(password+self.salt+app.config['SALT']).hexdigest()\ + == self.password or\ + sha256(password.swapcase()+self.salt+app.config['SALT']).hexdigest()\ + == self.password_swapped: + return True + return False + + def update_pass(self, old_pass, new_pass): + if old_pass == new_pass: + return -1 + if self.check_pass(old_pass): + self.set_pass(new_pass) + return True + return False
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/server/types.py Sat Jun 01 20:21:37 2013 +0200 @@ -0,0 +1,18 @@ +import sqlalchemy.types as types + +class TsVector(types.UserDefinedType): + def __init__(self): + pass + + def get_col_spec(self): + return "TSVECTOR" + + def bind_processor(self, dialect): + def process(value): + return value + return process + + def result_processor(self, dialect, coltype): + def process(value): + return value + return process
