python: Start Django project.
This is enough code to load Ledger data into Django models.
This commit is contained in:
parent
02e80b8d08
commit
b32e72b1e8
6 changed files with 193 additions and 0 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1,3 +1,5 @@
|
|||
python/db.sqlite3
|
||||
python/**/__pycache__/
|
||||
Supporters/MYMETA.json
|
||||
Supporters/MYMETA.yml
|
||||
Supporters/Makefile
|
||||
|
|
87
python/load_ledger.py
Executable file
87
python/load_ledger.py
Executable 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
10
python/manage.py
Executable 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)
|
0
python/supporters/__init__.py
Normal file
0
python/supporters/__init__.py
Normal file
10
python/supporters/models.py
Normal file
10
python/supporters/models.py
Normal 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()
|
84
python/supporters/settings.py
Normal file
84
python/supporters/settings.py
Normal 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/'
|
Loading…
Reference in a new issue