05/31 Phase 1: initial codes
This commit is contained in:
+120
@@ -0,0 +1,120 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
First-run initialization script.
|
||||
Creates the admin user and seeds default categories.
|
||||
Run once after `flask db upgrade`.
|
||||
|
||||
Usage:
|
||||
cd /home/pfm/app
|
||||
source venv/bin/activate
|
||||
python scripts/init_db.py
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
# Add project root to path
|
||||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
|
||||
from app import create_app
|
||||
from app.extensions import db
|
||||
from app.models.user import User
|
||||
from app.models.category import Category
|
||||
import getpass
|
||||
|
||||
app = create_app()
|
||||
|
||||
DEFAULT_EXPENSE_CATEGORIES = [
|
||||
('Housing', 'bi-house', '#6366f1'),
|
||||
('Food & Dining', 'bi-cup-hot', '#f59e0b'),
|
||||
('Transport', 'bi-car-front', '#3b82f6'),
|
||||
('Utilities', 'bi-lightning-charge', '#8b5cf6'),
|
||||
('Health', 'bi-heart-pulse', '#ef4444'),
|
||||
('Entertainment', 'bi-controller', '#ec4899'),
|
||||
('Shopping', 'bi-bag', '#f97316'),
|
||||
('Education', 'bi-book', '#14b8a6'),
|
||||
('Insurance', 'bi-shield-check', '#64748b'),
|
||||
('Personal Care', 'bi-person-heart', '#a78bfa'),
|
||||
('Travel', 'bi-airplane', '#0ea5e9'),
|
||||
('Subscriptions', 'bi-repeat', '#84cc16'),
|
||||
('Gifts', 'bi-gift', '#f43f5e'),
|
||||
('Other', 'bi-three-dots', '#94a3b8'),
|
||||
]
|
||||
|
||||
DEFAULT_INCOME_CATEGORIES = [
|
||||
('Salary', 'bi-briefcase', '#10b981'),
|
||||
('Freelance', 'bi-laptop', '#06b6d4'),
|
||||
('Business', 'bi-building', '#8b5cf6'),
|
||||
('Investment', 'bi-graph-up-arrow', '#3b82f6'),
|
||||
('Rental', 'bi-house-door', '#f59e0b'),
|
||||
('Gift Received', 'bi-gift', '#ec4899'),
|
||||
('Other Income', 'bi-three-dots', '#94a3b8'),
|
||||
]
|
||||
|
||||
|
||||
def seed_categories():
|
||||
print("Seeding categories...")
|
||||
count = 0
|
||||
for name, icon, color in DEFAULT_EXPENSE_CATEGORIES:
|
||||
if not Category.query.filter_by(name=name, category_type='expense').first():
|
||||
db.session.add(Category(
|
||||
name=name, icon=icon, color=color,
|
||||
category_type='expense', is_system=True
|
||||
))
|
||||
count += 1
|
||||
|
||||
for name, icon, color in DEFAULT_INCOME_CATEGORIES:
|
||||
if not Category.query.filter_by(name=name, category_type='income').first():
|
||||
db.session.add(Category(
|
||||
name=name, icon=icon, color=color,
|
||||
category_type='income', is_system=True
|
||||
))
|
||||
count += 1
|
||||
|
||||
db.session.commit()
|
||||
print(f" → {count} categories added.")
|
||||
|
||||
|
||||
def create_admin():
|
||||
print("\nCreate admin user")
|
||||
print("-" * 30)
|
||||
|
||||
existing = User.query.first()
|
||||
if existing:
|
||||
print(f" User '{existing.username}' already exists. Skipping.")
|
||||
return
|
||||
|
||||
username = input("Username [admin]: ").strip() or 'admin'
|
||||
display_name = input("Display name (optional): ").strip() or None
|
||||
email = input("Email (optional): ").strip() or None
|
||||
|
||||
while True:
|
||||
password = getpass.getpass("Password: ")
|
||||
confirm = getpass.getpass("Confirm password: ")
|
||||
if password == confirm and len(password) >= 6:
|
||||
break
|
||||
if password != confirm:
|
||||
print(" Passwords do not match. Try again.")
|
||||
else:
|
||||
print(" Password must be at least 6 characters.")
|
||||
|
||||
from flask import current_app
|
||||
user = User(
|
||||
username=username,
|
||||
display_name=display_name,
|
||||
email=email,
|
||||
currency=current_app.config.get('APP_CURRENCY', 'USD'),
|
||||
currency_symbol=current_app.config.get('APP_CURRENCY_SYMBOL', '$'),
|
||||
timezone=current_app.config.get('APP_TIMEZONE', 'Asia/Ho_Chi_Minh'),
|
||||
)
|
||||
user.set_password(password)
|
||||
db.session.add(user)
|
||||
db.session.commit()
|
||||
print(f" → User '{username}' created successfully.")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
with app.app_context():
|
||||
seed_categories()
|
||||
create_admin()
|
||||
print("\nInit complete. Run the app with: gunicorn wsgi:app")
|
||||
Reference in New Issue
Block a user