Cleanup, some READMEs, manage.py script

banking-pekao
informatic 2018-03-15 10:39:58 +01:00
parent e81cd1d88e
commit e3a1cf4c41
11 changed files with 91 additions and 135 deletions

16
README.md Normal file
View 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
View 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.

View File

@ -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

View File

@ -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()

View File

@ -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()

View File

@ -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
View File

@ -0,0 +1 @@
webapp/wsgi.py

View File

@ -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
View 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()

View File

@ -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()

View File

@ -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
View 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()