python: Start Django project.

This is enough code to load Ledger data into Django models.
This commit is contained in:
Brett Smith 2017-01-24 11:28:06 -05:00
parent 02e80b8d08
commit b32e72b1e8
6 changed files with 193 additions and 0 deletions

2
.gitignore vendored
View file

@ -1,3 +1,5 @@
python/db.sqlite3
python/**/__pycache__/
Supporters/MYMETA.json
Supporters/MYMETA.yml
Supporters/Makefile

87
python/load_ledger.py Executable file
View file

@ -0,0 +1,87 @@
#!/usr/bin/env python3
import argparse
import collections
import csv
import os
import subprocess
import django
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'supporters.settings')
django.setup()
from supporters.models import Payment
COLUMNS = collections.OrderedDict([
('date', '%(format_date(date, "%Y-%m-%d"))'),
('entity', '%(quoted(meta("Entity")))'),
('payee', '%(quoted(payee))'),
('program', '%(quoted(meta("Program")))'),
('amount', '%(quoted(display_amount))'),
])
def parse_arguments(arglist):
parser = argparse.ArgumentParser(prog='load_ledger')
parser.add_argument(
'--ledger-from-scratch', default=False, action='store_true',
help="""By default, this script imports all Supporter payments,
and you can narrow the set of payments it imports by providing
additional search criteria as arguments. If you set this flag,
the script will not use any default criteria, and only use the criteria
you specify.""")
parser.add_argument(
'--ledger-command', default='ledger', metavar='COMMAND',
help="Name or path of ledger executable")
parser.add_argument(
'ledger_arguments', default=[], nargs=argparse.REMAINDER,
help="Additional Ledger search criteria for payments to import")
args = parser.parse_args(arglist)
if args.ledger_arguments and (args.ledger_arguments[0] == '--'):
del args.ledger_arguments[0]
base_cmdline = [
args.ledger_command, 'csv',
'--csv-format', ','.join(COLUMNS.values()) + '\n',
'--sort', 'date',
]
if args.ledger_from_scratch:
args.ledger_cmdline = base_cmdline + args.ledger_arguments
else:
args.ledger_cmdline = (base_cmdline
+ ['--limit', 'tag("Program") =~ /:Supporters:/']
+ args.ledger_arguments
+ ['/^Income:/'])
return args
def load_ledger(ledger_cmdline):
ledger_env = os.environ.copy()
for lang_envvar in ['LC_ALL', 'LC_CTYPE', 'LANG']:
try:
current_language = ledger_env[lang_envvar].split('.', 1)[0]
except KeyError:
pass
else:
break
else:
lang_envvar = 'LC_CTYPE'
current_language = 'en_US'
ledger_env[lang_envvar] = current_language + '.utf8'
ledger = subprocess.Popen(ledger_cmdline,
env=ledger_env,
stdin=subprocess.PIPE, stdout=subprocess.PIPE)
ledger.stdin.close()
with ledger, open(ledger.stdout.fileno(), encoding='utf-8', closefd=False) as stdout:
yield from csv.reader(stdout)
assert ledger.returncode == 0, "ledger subprocess failed"
def save_payments(row_source):
with django.db.transaction.atomic():
for row in row_source:
kwargs = {colname: row[index] for index, colname in enumerate(COLUMNS)}
Payment(**kwargs).save()
def main(arglist):
args = parse_arguments(arglist)
save_payments(load_ledger(args.ledger_cmdline))
if __name__ == '__main__':
main(None)

10
python/manage.py Executable file
View file

@ -0,0 +1,10 @@
#!/usr/bin/env python3
import os
import sys
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "supporters.settings")
from django.core.management import execute_from_command_line
execute_from_command_line(sys.argv)

View file

View file

@ -0,0 +1,10 @@
#!/usr/bin/env python3
from django.db import models
class Payment(models.Model):
date = models.DateField()
entity = models.TextField()
payee = models.TextField()
program = models.TextField()
amount = models.TextField()

View file

@ -0,0 +1,84 @@
"""
Django settings for supporters project.
For more information on this file, see
https://docs.djangoproject.com/en/1.7/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.7/ref/settings/
"""
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.7/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'c7%o*zll@260k&e98qutdm!0i7cbi9=ll3y1xh*4a!xk+bipnr'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
TEMPLATE_DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = (
'supporters',
# 'django.contrib.admin',
# 'django.contrib.auth',
# 'django.contrib.contenttypes',
# 'django.contrib.sessions',
# 'django.contrib.messages',
# 'django.contrib.staticfiles',
)
MIDDLEWARE_CLASSES = (
# 'django.contrib.sessions.middleware.SessionMiddleware',
# 'django.middleware.common.CommonMiddleware',
# 'django.middleware.csrf.CsrfViewMiddleware',
# 'django.contrib.auth.middleware.AuthenticationMiddleware',
# 'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
# 'django.contrib.messages.middleware.MessageMiddleware',
# 'django.middleware.clickjacking.XFrameOptionsMiddleware',
)
# ROOT_URLCONF = 'supporters.urls'
# WSGI_APPLICATION = 'supporters.wsgi.application'
# Database
# https://docs.djangoproject.com/en/1.7/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
# Internationalization
# https://docs.djangoproject.com/en/1.7/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.7/howto/static-files/
STATIC_URL = '/static/'