diff --git a/.gitignore b/.gitignore index afcc81a..8c3bc09 100644 --- a/.gitignore +++ b/.gitignore @@ -6,10 +6,13 @@ # Virtualenv bin -data include lib lib64 __pycache__ share pyvenv.cfg + +# App specific +data +config diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..b389f6c --- /dev/null +++ b/Makefile @@ -0,0 +1,15 @@ +.PHONY: run debug clean + +bin/activate: requirements.txt + test -f bin/activate || $(shell which python3) -m venv . + bin/pip install -Ur requirements.txt + touch bin/activate + +run: bin/activate + . bin/activate; FLASK_SETTINGS_FILE=../config/prod.cfg FLASK_ENV=production FLASK_APP=start.py flask run --host=0.0.0.0 + +debug: bin/activate + . bin/activate; FLASK_SETTINGS_FILE=../config/dev.cfg FLASK_ENV=development FLASK_APP=start.py flask run --host=0.0.0.0 + +clean: + rm -rf bin/ include/ lib/ lib64/ __pycache__/ share/; rm pyvenv.cfg diff --git a/acks/__init__.py b/acks/__init__.py index 67bc997..dceea86 100644 --- a/acks/__init__.py +++ b/acks/__init__.py @@ -1,7 +1,11 @@ from flask import Flask +from flask_admin import Admin +from flask_admin.contrib.sqla import ModelView def create_app(): app = Flask(__name__) + app.config.from_object('acks.default_settings') + app.config.from_envvar('FLASK_SETTINGS_FILE') # Prep the database from acks.models import db @@ -23,4 +27,11 @@ def create_app(): from acks.npc.commands import npc_cli app.cli.add_command(npc_cli) + # Load the Admin views + admin = Admin(app, name='acks', template_mode='bootstrap3') + + from acks.npc.models import admin_models as npc_admin_models + for mdl in npc_admin_models: + admin.add_view(ModelView(mdl, db.session)) + return app diff --git a/acks/default_settings.py b/acks/default_settings.py new file mode 100644 index 0000000..8b17298 --- /dev/null +++ b/acks/default_settings.py @@ -0,0 +1,5 @@ +# Default Configuration +SECRET_KEY = "" + +# Flask-SQLAlchemy +SQLALCHEMY_TRACK_MODIFICATIONS = False diff --git a/acks/models.py b/acks/models.py index 878f0a3..1afc8e1 100644 --- a/acks/models.py +++ b/acks/models.py @@ -1,3 +1,5 @@ +from datetime import datetime + from flask_sqlalchemy import SQLAlchemy @@ -7,4 +9,4 @@ class BaseModel(db.Model): __abstract__ = True id = db.Column(db.Integer, primary_key=True) - created_at = db.Column(db.DateTime) + created_at = db.Column(db.DateTime, default=datetime.utcnow) diff --git a/acks/npc/commands.py b/acks/npc/commands.py index e2f0007..03cb3ed 100644 --- a/acks/npc/commands.py +++ b/acks/npc/commands.py @@ -7,178 +7,15 @@ from ..models import db npc_cli = AppGroup('npc') @npc_cli.command('create classes') -def create_classes(): +def create_class(): + import csv from .models import CharacterClass classes = [] - classes.append(CharacterClass( - name = 'Elven Nightblade', - bucket = 'Demi-Human', - prime_requisite = 'D+I', - hit_die_size = 6, - maximum_level = 11, - armour_modifier = -4, - melee_light = 1, - melee_medium = 2, - melee_heavy = 0, - ranged_light = 0, - ranged_heavy = 0 - )) - - classes.append(CharacterClass( - name = 'Elven Spellsword', - bucket = 'Demi-Human', - prime_requisite = 'S+I', - hit_die_size = 6, - maximum_level = 10, - armour_modifier = -4, - melee_light = 0, - melee_medium = 1, - melee_heavy = 0, - ranged_light = 0, - ranged_heavy = 0 - )) - - classes.append(CharacterClass( - name = 'Explorer', - bucket = 'Campaign', - prime_requisite = 'S+D', - hit_die_size = 6, - maximum_level = 14, - armour_modifier = -3, - melee_light = 1, - melee_medium = 1, - melee_heavy = 0, - ranged_light = 0, - ranged_heavy = 1 - )) - - classes.append(CharacterClass( - name = 'Bladedancer', - bucket = 'Campaign', - prime_requisite = 'W+D', - hit_die_size = 6, - maximum_level = 14, - armour_modifier = -2, - melee_light = 0, - melee_medium = 1, - melee_heavy = 0, - ranged_light = 0, - ranged_heavy = 0 - )) - - classes.append(CharacterClass( - name = 'Cleric', - bucket = 'Core', - prime_requisite = 'WIS', - hit_die_size = 6, - maximum_level = 14, - armour_modifier = 0, - melee_light = 1, - melee_medium = 3, - melee_heavy = 1, - ranged_light = 1, - ranged_heavy = 3 - )) - - classes.append(CharacterClass( - name = 'Fighter', - bucket = 'Core', - prime_requisite = 'STR', - hit_die_size = 8, - maximum_level = 14, - armour_modifier = 1, - melee_light = 1, - melee_medium = 4, - melee_heavy = 1, - ranged_light = 1, - ranged_heavy = 1 - )) - - classes.append(CharacterClass( - name = 'Thief', - bucket = 'Core', - prime_requisite = 'DEX', - hit_die_size = 4, - maximum_level = 14, - armour_modifier = -6, - melee_light = 1, - melee_medium = 1, - melee_heavy = 0, - ranged_light = 1, - ranged_heavy = 0 - )) - - classes.append(CharacterClass( - name = 'Mage', - bucket = 'Core', - prime_requisite = 'INT', - hit_die_size = 4, - maximum_level = 14, - armour_modifier = -8, - melee_light = 1, - melee_medium = 0, - melee_heavy = 0, - ranged_light = 0, - ranged_heavy = 0 - )) - - classes.append(CharacterClass( - name = 'Assassin', - bucket = 'Campaign', - prime_requisite = 'S+D', - hit_die_size = 6, - maximum_level = 14, - armour_modifier = -6, - melee_light = 1, - melee_medium = 2, - melee_heavy = 0, - ranged_light = 1, - ranged_heavy = 0 - )) - - classes.append(CharacterClass( - name = 'Bard', - bucket = 'Campaign', - prime_requisite = 'D+H', - hit_die_size = 6, - maximum_level = 14, - armour_modifier = -3, - melee_light = 1, - melee_medium = 2, - melee_heavy = 0, - ranged_light = 1, - ranged_heavy = 0 - )) - - classes.append(CharacterClass( - name = 'Dwarven Vaultguard', - bucket = 'Demi-Human', - prime_requisite = 'STR', - hit_die_size = 8, - maximum_level = 13, - armour_modifier = -1, - melee_light = 0, - melee_medium = 3, - melee_heavy = 1, - ranged_light = 1, - ranged_heavy = 1 - )) - - classes.append(CharacterClass( - name = 'Dwarven Craftpriest', - bucket = 'Demi-Human', - prime_requisite = 'WIS', - hit_die_size = 6, - maximum_level = 10, - armour_modifier = -2, - melee_light = 0, - melee_medium = 1, - melee_heavy = 0, - ranged_light = 1, - ranged_heavy = 0 - )) - + with open('acks/npc/default_classes.csv', newline='') as data: + reader = csv.DictReader(data) + for row in reader: + classes.append(CharacterClass(**row)) db.session.bulk_save_objects(classes) db.session.commit() diff --git a/acks/npc/default_classes.csv b/acks/npc/default_classes.csv new file mode 100644 index 0000000..2a10347 --- /dev/null +++ b/acks/npc/default_classes.csv @@ -0,0 +1,12 @@ +name,bucket,prime_requisite,hit_die_size,maximum_level,armour_modifier,melee_light,melee_medium,melee_heavy,ranged_light,ranged_heavy +Elven Nightblade,Demi-Human,D+I,6,11,-4,1,2,0,0,0 +Elven Spellsword,Demi-Human,S+I,6,10,-4,0,1,0,0,0 +Explorer,Campaign,S+D,6,14,-3,1,1,0,0,1 +Bladedancer,Campaign,W+D,6,14,-2,0,1,0,0,0 +Cleric,Core,WIS,6,14,0,1,3,1,1,3 +Fighter,Core,STR,8,14,1,1,4,1,1,1 +Thief,Core,DEX,4,14,-6,1,1,0,1,0 +Mage,Core,INT,4,14,-8,1,0,0,0,0 +Assassin,Campaign,S+D,6,14,-6,1,2,0,1,0 +Bard,Campaign,D+H,6,14,-3,1,2,0,1,0 +Dwarven Vaultguard,Demi-Human,STR,8,13,-1,0,3,1,1,1 diff --git a/acks/npc/models.py b/acks/npc/models.py index 6052e0f..fac9689 100644 --- a/acks/npc/models.py +++ b/acks/npc/models.py @@ -21,3 +21,6 @@ class CharacterClass(BaseModel): def __repr__(self): return ''.format(self.name) + + +admin_models = [CharacterClass] diff --git a/acks/npc/templates/generate_npc_party.html b/acks/npc/templates/generate_npc_party.html index fea902c..63c866c 100644 --- a/acks/npc/templates/generate_npc_party.html +++ b/acks/npc/templates/generate_npc_party.html @@ -116,7 +116,7 @@ div.acks-npc-card { {% endblock %}