Cleanup, some READMEs, manage.py script
This commit is contained in:
parent
e81cd1d88e
commit
e3a1cf4c41
11 changed files with 91 additions and 135 deletions
16
README.md
Normal file
16
README.md
Normal file
|
@ -0,0 +1,16 @@
|
|||
Kasownik
|
||||
========
|
||||
Warsaw Hackerspace Membership Management System.
|
||||
|
||||
> „100 linii pythona!” - enki o skrypcie do składek
|
||||
|
||||
Summary
|
||||
-------
|
||||
|
||||
This project is divided into two separate modules:
|
||||
|
||||
* `web` - web frontend and basic logic, public-facing service
|
||||
* `fetch` - bank account data fetcher, to be run in some secure domain
|
||||
(at least separate UID) - supports "old" IdeaBank web interface
|
||||
|
||||
More info about these can be found in their respective `README.md` files.
|
24
web/README.md
Normal file
24
web/README.md
Normal file
|
@ -0,0 +1,24 @@
|
|||
Kasownik webapp
|
||||
===============
|
||||
|
||||
Setup
|
||||
-----
|
||||
|
||||
pip install -r requirements.txt
|
||||
# Copy example development environment config
|
||||
cp config.py.dist config.py
|
||||
|
||||
Database initialization
|
||||
-----------------------
|
||||
|
||||
./manage.py syncdb
|
||||
|
||||
Development server
|
||||
------------------
|
||||
|
||||
FLASK_DEBUG=1 ./manage.py run
|
||||
|
||||
WSGI deployment
|
||||
---------------
|
||||
|
||||
`webapp/wsgi.py` exports `app` object suitable for wsgi deployments.
|
|
@ -3,6 +3,22 @@ class Config(object):
|
|||
TESTING = False
|
||||
SQLALCHEMY_DATABASE_URI = "sqlite:///data.db"
|
||||
|
||||
SECRET_KEY = 'changeme'
|
||||
|
||||
LDAP_URI = 'ldap://ldap.hackerspace.pl'
|
||||
LDAP_BIND_DN = 'cn=fascist,ou=Services,dc=hackerspace,dc=pl'
|
||||
LDAP_BIND_PASSWORD = 'changeme'
|
||||
|
||||
LDAP_USER_FILTER = '(objectClass=hsMember)'
|
||||
LDAP_USER_BASE = 'ou=People,dc=hackerspace,dc=pl'
|
||||
LDAP_CA_PATH = '/etc/ssl/certs/ca-certificates.crt'
|
||||
|
||||
CACHE_TYPE = 'null'
|
||||
CACHE_NO_NULL_WARNING = True
|
||||
|
||||
class DevelopmentConfig(Config):
|
||||
DEBUG = True
|
||||
DISABLE_LDAP = True
|
||||
|
||||
class CurrentConfig(DevelopmentConfig):
|
||||
pass
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
# Copyright (c) 2015, Sergiusz Bazanski <q3k@q3k.org>
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import webapp
|
||||
|
||||
webapp.db.create_all()
|
|
@ -1,70 +0,0 @@
|
|||
import re
|
||||
import datetime
|
||||
|
||||
import webapp
|
||||
|
||||
# yes, I am in fact importing an old sqlite dump with regexp
|
||||
# deal with it
|
||||
f = open('olddata', 'r')
|
||||
d = f.read()
|
||||
f.close()
|
||||
|
||||
def fancysplit(s):
|
||||
parts = []
|
||||
part = ""
|
||||
pi = 0
|
||||
escaped = False
|
||||
for c in s:
|
||||
if pi == 0 and c == "'":
|
||||
escaped = True
|
||||
elif pi > 0 and c == "'":
|
||||
escaped = False
|
||||
elif not escaped and c == ",":
|
||||
parts.append(part)
|
||||
part = ""
|
||||
pi = -1
|
||||
escaped = False
|
||||
else:
|
||||
part += c
|
||||
pi += 1
|
||||
if part != "":
|
||||
parts.append(part)
|
||||
return parts
|
||||
|
||||
|
||||
records = {}
|
||||
for line in d.split("\n"):
|
||||
m = re.match(r'^INSERT INTO "([a-z_]+)" ', line)
|
||||
if m:
|
||||
table_name = m.group(1)
|
||||
if table_name not in records:
|
||||
records[table_name] = []
|
||||
m = re.search("VALUES\((.+)\);", line)
|
||||
values_s = m.group(1)
|
||||
values_r = [v.strip("'").decode("utf-8") for v in fancysplit(values_s)]
|
||||
values = []
|
||||
for v in values_r:
|
||||
try:
|
||||
vales.append(int(v))
|
||||
except:
|
||||
values.append(v)
|
||||
records[table_name].append(tuple(values))
|
||||
|
||||
for member_id, member_name, member_type, member_active in records["_members"]:
|
||||
m = webapp.models.Member(member_id, member_name, member_type, True if member_active == 1 else False)
|
||||
webapp.db.session.add(m)
|
||||
|
||||
for _id, uid, account_from, name_from, amount, title, date in records["_transfers"]:
|
||||
date = datetime.datetime.strptime(date, "20%y-%m-%d %H:%M:%S")
|
||||
t = webapp.models.Transfer(_id, uid, account_from, name_from, amount, title, date)
|
||||
webapp.db.session.add(t)
|
||||
|
||||
webapp.db.session.commit()
|
||||
|
||||
for _id, transfer_id, member_id, year, month in records["_member_transfer"]:
|
||||
member = webapp.models.Member.query.get(member_id)
|
||||
transfer = webapp.models.Transfer.query.get(transfer_id)
|
||||
mt = webapp.models.MemberTransfer(_id, year, month, transfer)
|
||||
member.transfers.append(mt)
|
||||
|
||||
webapp.db.session.commit()
|
|
@ -1,7 +0,0 @@
|
|||
# FIXME we need to upgrade Flask_SQLAlchemy to get rid of deprecation warnings
|
||||
import warnings
|
||||
from flask.exthook import ExtDeprecationWarning
|
||||
warnings.simplefilter("ignore", ExtDeprecationWarning)
|
||||
|
||||
import webapp
|
||||
app = webapp.create_app()
|
1
web/kasownik-uwsgi.py
Symbolic link
1
web/kasownik-uwsgi.py
Symbolic link
|
@ -0,0 +1 @@
|
|||
webapp/wsgi.py
|
|
@ -4,6 +4,6 @@ master = 1
|
|||
threads = 10
|
||||
chdir = /var/www/kasownik
|
||||
venv = /var/www/kasownik/.env
|
||||
module = kasownik-uwsgi
|
||||
module = webapp.wsgi
|
||||
callable = app
|
||||
debug = true
|
||||
|
|
18
web/manage.py
Executable file
18
web/manage.py
Executable file
|
@ -0,0 +1,18 @@
|
|||
#!/usr/bin/env python
|
||||
# FIXME we need to upgrade Flask_SQLAlchemy to get rid of deprecation warnings
|
||||
import warnings
|
||||
from flask.exthook import ExtDeprecationWarning
|
||||
warnings.simplefilter("ignore", ExtDeprecationWarning)
|
||||
|
||||
import os
|
||||
import click
|
||||
from flask.cli import FlaskGroup
|
||||
|
||||
from webapp.wsgi import app
|
||||
|
||||
@click.group(cls=FlaskGroup, create_app=lambda i: app)
|
||||
def cli():
|
||||
"""This is a management script for Kasownik."""
|
||||
|
||||
if __name__ == '__main__':
|
||||
cli()
|
|
@ -1,28 +0,0 @@
|
|||
# Copyright (c) 2015, Sergiusz Bazanski <q3k@q3k.org>
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import webapp
|
||||
|
||||
app = webapp.create_app()
|
||||
app.run()
|
|
@ -12,7 +12,7 @@ group = AppGroup(__name__)
|
|||
@group.command()
|
||||
@click.option('-n', '--dry-run', is_flag=True, help='Don\'t apply any changes.')
|
||||
def ldapsync(dry_run):
|
||||
"""Synchronize LDAP groups state."""
|
||||
"""Synchronizes LDAP groups state."""
|
||||
|
||||
members = [m.get_status() for m in models.Member.get_members(True)]
|
||||
|
||||
|
@ -47,7 +47,7 @@ def ldapsync(dry_run):
|
|||
@group.command()
|
||||
@click.option('-n', '--dry-run', is_flag=True, help='Don\'t commit changes.')
|
||||
def automatch(dry_run):
|
||||
"""Tries to automatically match transfers to proper membership months."""
|
||||
"""Matches transfers to membership months."""
|
||||
transfers_unmatched = logic.get_unmatched_transfers()
|
||||
matched, unmatched = logic.try_automatch(transfers_unmatched)
|
||||
|
||||
|
@ -70,3 +70,9 @@ def automatch(dry_run):
|
|||
|
||||
if matched:
|
||||
click.echo("Done, %d matched, %d left" % (len(matched), len(unmatched)))
|
||||
|
||||
@group.command()
|
||||
def syncdb():
|
||||
"""Initializes database."""
|
||||
db.create_all()
|
||||
click.echo('Done.')
|
||||
|
|
7
web/webapp/wsgi.py
Executable file
7
web/webapp/wsgi.py
Executable file
|
@ -0,0 +1,7 @@
|
|||
# FIXME we need to upgrade Flask_SQLAlchemy to get rid of deprecation warnings
|
||||
import warnings
|
||||
from flask.exthook import ExtDeprecationWarning
|
||||
warnings.simplefilter("ignore", ExtDeprecationWarning)
|
||||
|
||||
import webapp
|
||||
app = webapp.create_app()
|
Loading…
Add table
Reference in a new issue