diff --git a/app.py b/app.py
index c95cd47..9615406 100644
--- a/app.py
+++ b/app.py
@@ -848,7 +848,7 @@ def easter_y(y=None):
#### EXTENSIONS ####
-active_extensions = []
+active_extensions = ['circles']
for ext in active_extensions:
try:
diff --git a/extensions/__init__.py b/extensions/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/extensions/circles.py b/extensions/circles.py
index 5b2993e..9ddbc05 100644
--- a/extensions/circles.py
+++ b/extensions/circles.py
@@ -6,7 +6,13 @@ Circles (people) extension for Salvi.
'''
from peewee import *
-from ..app import _getconf
+import datetime
+from app import _getconf
+from flask import Blueprint, request, redirect, render_template
+from werkzeug.routing import BaseConverter
+import csv
+import io
+import itertools
#### HELPERS ####
@@ -25,7 +31,7 @@ def _getmbt(s):
def _putmbt(s):
if s & 16 == 0:
- return "1x38b"
+ return "1x38B"
return ''.join((
'IE'[(s & 8) >> 3],
'NS'[(s & 4) >> 2],
@@ -34,6 +40,7 @@ def _putmbt(s):
))
+
#### DATABASE SCHEMA ####
database = SqliteDatabase(_getconf("config", "database_dir") + '/circles.sqlite')
@@ -46,10 +53,12 @@ class MbTypeField(Field):
field_type = 'integer'
def db_value(self, value):
+ if isinstance(value, int):
+ return value
return _getmbt(value)
def python_value(self, value):
return _putmbt(value)
-
+
ST_ORANGE = 0
ST_YELLOW = 1
ST_GREEN = 2
@@ -63,6 +72,8 @@ class Person(BaseModel):
circle = IntegerField(default=7, index=True)
status = IntegerField(default=ST_ORANGE, index=True)
type = MbTypeField(default=0, index=True)
+ area = IntegerField(default=0, index=True)
+ touched = DateTimeField(default=datetime.datetime.now)
class Meta:
indexes = (
(('last_name', 'first_name'), False),
@@ -71,16 +82,145 @@ class Person(BaseModel):
def init_db():
database.create_tables([Person])
+def add_from_csv(s):
+ f = io.StringIO()
+ f.write(s)
+ f.seek(0)
+ rd = csv.reader(f)
+ for line in rd:
+ code = line[0]
+ if not code.isdigit():
+ continue
+ names = line[1:4]
+ while len(names) < 3:
+ names.append('')
+ if not names[2]:
+ names[2] = names[0] + " " + names[1]
+ type_ = line[4] if len(line) > 4 else 0
+ try:
+ p = Person[code]
+ except Person.DoesNotExist:
+ p = Person.create(
+ code = code,
+ display_name = names[2],
+ first_name = names[0],
+ last_name = names[1],
+ type = type_
+ )
+ else:
+ p.touched = datetime.datetime.now()
+ p.first_name, p.last_name, p.display_name = names
+ p.type = type_ or p.type
+ p.save()
+
#### ROUTING ####
+class MbTypeConverter(BaseConverter):
+ regex = '[IE][NS][TF][JP]|[ie][ns][tf][jp]'
+ def to_python(self, value):
+ return value.upper()
+ def to_url(self, value):
+ return value.lower()
+
+class StatusColorConverter(BaseConverter):
+ regex = 'red|yellow|green|orange'
+ def to_python(self, value):
+ if value == 'red':
+ return -1
+ return ['orange', 'yellow', 'green'].index(value)
+ def to_url(self, value):
+ return ['orange', 'yellow', 'green', ..., 'red'][value]
+
+def _register_converters(state):
+ state.app.url_map.converters['mbtype'] = MbTypeConverter
+ state.app.url_map.converters['statuscolor'] = StatusColorConverter
+
bp = Blueprint('circles', __name__,
url_prefix='/circles')
+bp.record_once(_register_converters)
@bp.route('/init-config')
def _init_config():
init_db()
return redirect('/circles')
+@bp.route('/new', methods=['GET', 'POST'])
+def add_new():
+ if request.method == 'POST':
+ p = Person.create(
+ code = request.form["code"],
+ display_name = request.form["display_name"],
+ first_name = request.form["first_name"],
+ last_name = request.form["last_name"],
+ type = request.form["type"],
+ status = int(request.form.get('status', 0))
+ )
+ return redirect("/circles")
+ return render_template("circles/add.html")
+
+@bp.route('/edit/ Looking for mass addition? Try CSV adding form instead. Showing: {{ cat }} Show by: Type:
+ {% set typ_list = [
+ 'INTJ', 'INTP', 'INFJ', 'INFP', 'ENTJ', 'ENTP',
+ 'ENFJ', 'ENFP', 'ISTJ', 'ISTP', 'ISFJ', 'ISFP',
+ 'ESTJ', 'ESTP', 'ESFJ', 'ESFP'] %}
+ {% for t in typ_list %}
+ {{ t }} ·
+ {% endfor %}
+ Status:
+ {% set typ_list = ['Green', 'Yellow', 'Orange', 'Red'] %}
+ {% for t in typ_list %}
+ {{ t }} ·
+ {% endfor %}
+ Area:
+ {% for t in range(1, 13) %}
+ {{ t }} ·
+ {% endfor %}
+ Showing {{ people.count() }} people of {{ count }} total. Next page{% if pageno > 1 %} · Prev page{% endif %}
{{ count }} people.
+{% endif %} + +Showing {{ people.count() }} people of {{ count }} total.
+{% if count > pageno * 50 %} +Next page{% if pageno > 1 %} · Prev page{% endif %}
+{% elif pageno > 1 %} +Prev page +{% endif %} +{% else %} +{{ count }} people.
+{% endif %} + +{% endblock %} diff --git a/templates/circles/stats.html b/templates/circles/stats.html new file mode 100644 index 0000000..43cfa2e --- /dev/null +++ b/templates/circles/stats.html @@ -0,0 +1,23 @@ +{% extends "base.html" %} + +{% block title %}Circles – {{ app_name }}{% endblock %} + +{% block content %} +