fixing imports

This commit is contained in:
2025-09-29 05:52:16 -07:00
parent 4469a6d35d
commit fa524a90cf
3 changed files with 200 additions and 2 deletions

View File

@@ -35,6 +35,15 @@ jobs:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Cache Docker layers
uses: actions/cache@v3
with:
path: /tmp/.buildx-cache # Or a custom path for your cache
key: ${{ runner.os }}-docker-${{ hashFiles('Dockerfile') }}-${{ hashFiles('src/**') }} # Example key
restore-keys: |
${{ runner.os }}-docker-${{ hashFiles('Dockerfile') }}-
${{ runner.os }}-docker-
- name: Extract metadata for Docker
id: meta
uses: docker/metadata-action@v5

77
main.py
View File

@@ -1938,7 +1938,6 @@ async def tracker_save_template(request: Request, db: Session = Depends(get_db))
meal_time=tracked_meal.meal_time
)
db.add(template_meal)
db.commit()
logging.info(f"DEBUG: Successfully saved template with {len(tracked_meals)} meals")
@@ -2060,4 +2059,78 @@ async def tracker_reset_to_plan(request: Request, db: Session = Depends(get_db))
@app.get("/test")
async def test_route():
logging.info("DEBUG: Test route called")
return {"status": "success", "message": "Test route is working"}
return {"status": "success", "message": "Test route is working"}
@app.post("/templates/upload")
async def bulk_upload_templates(file: UploadFile = File(...), db: Session = Depends(get_db)):
"""Handle bulk template upload from CSV"""
try:
contents = await file.read()
decoded = contents.decode('utf-8').splitlines()
reader = csv.DictReader(decoded)
stats = {'created': 0, 'updated': 0, 'errors': []}
for row_num, row in enumerate(reader, 2): # Row numbers start at 2 (1-based + header)
try:
user = row.get('User', '').strip()
template_id = row.get('ID', '').strip()
if not user or not template_id:
stats['errors'].append(f"Row {row_num}: Missing User or ID")
continue
# Create template name in format <User>-<ID>
template_name = f"{user}-{template_id}"
# Check if template already exists
existing_template = db.query(Template).filter(Template.name == template_name).first()
if existing_template:
# Update existing template - remove existing meals
db.query(TemplateMeal).filter(TemplateMeal.template_id == existing_template.id).delete()
template = existing_template
stats['updated'] += 1
else:
# Create new template
template = Template(name=template_name)
db.add(template)
stats['created'] += 1
db.flush() # Get template ID
# Meal time mappings from CSV columns
meal_columns = {
'Beverage 1': 'Beverage 1',
'Breakfast': 'Breakfast',
'Lunch': 'Lunch',
'Dinner': 'Dinner',
'Snack 1': 'Snack 1',
'Snack 2': 'Snack 2'
}
# Process each meal column
for csv_column, meal_time in meal_columns.items():
meal_name = row.get(csv_column, '').strip()
if meal_name:
# Find meal by name
meal = db.query(Meal).filter(Meal.name.ilike(meal_name)).first()
if meal:
# Create template meal
template_meal = TemplateMeal(
template_id=template.id,
meal_id=meal.id,
meal_time=meal_time
)
db.add(template_meal)
else:
stats['errors'].append(f"Row {row_num}: Meal '{meal_name}' not found for {meal_time}")
except (KeyError, ValueError) as e:
stats['errors'].append(f"Row {row_num}: {str(e)}")
db.commit()
return stats
except Exception as e:
db.rollback()
return {"status": "error", "message": str(e)}

View File

@@ -32,4 +32,120 @@
</form>
</div>
</div>
<div class="row mt-4">
<div class="col-md-4">
<div class="card">
<div class="card-header">
<h5 class="mb-0">Food Import</h5>
</div>
<div class="card-body">
<form action="/foods/upload" method="post" enctype="multipart/form-data" class="csv-upload-form">
<div class="mb-3">
<label class="form-label">CSV File</label>
<input type="file" class="form-control" name="file" accept=".csv" required>
</div>
<button type="submit" class="btn btn-secondary">Upload Foods CSV</button>
</form>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card">
<div class="card-header">
<h5 class="mb-0">Meal Import</h5>
</div>
<div class="card-body">
<form action="/meals/upload" method="post" enctype="multipart/form-data" class="csv-upload-form">
<div class="mb-3">
<label class="form-label">CSV File</label>
<input type="file" class="form-control" name="file" accept=".csv" required>
</div>
<button type="submit" class="btn btn-secondary">Upload Meals CSV</button>
</form>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card">
<div class="card-header">
<h5 class="mb-0">Template Import</h5>
</div>
<div class="card-body">
<form action="/templates/upload" method="post" enctype="multipart/form-data" class="csv-upload-form">
<div class="mb-3">
<label class="form-label">CSV File</label>
<input type="file" class="form-control" name="file" accept=".csv" required>
</div>
<button type="submit" class="btn btn-secondary">Upload Templates CSV</button>
</form>
</div>
</div>
</div>
</div>
<div class="mt-4" id="upload-results" style="display: none;">
<div class="alert">
<strong>Upload Results:</strong>
<p>Created: <span id="created-count"></span></p>
<p>Updated: <span id="updated-count"></span></p>
<div id="error-list" class="mt-2 text-danger"></div>
</div>
</div>
<script>
document.querySelectorAll('.csv-upload-form').forEach(form => {
form.addEventListener('submit', async (e) => {
e.preventDefault();
const submitBtn = form.querySelector('button[type="submit"]');
const resultsDiv = document.getElementById('upload-results');
const alertDiv = resultsDiv.querySelector('.alert');
submitBtn.disabled = true;
submitBtn.innerHTML = '<span class="spinner-border spinner-border-sm" role="status"></span> Uploading...';
try {
const formData = new FormData(form);
const response = await fetch(form.action, {
method: 'POST',
body: formData
});
if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
const results = await response.json();
resultsDiv.style.display = 'block';
if (results.status === 'error') {
alertDiv.className = 'alert alert-danger';
document.getElementById('created-count').textContent = 'N/A';
document.getElementById('updated-count').textContent = 'N/A';
document.getElementById('error-list').innerHTML = `<strong>Error:</strong> ${results.message}`;
} else {
alertDiv.className = 'alert alert-success';
document.getElementById('created-count').textContent = results.created || 0;
document.getElementById('updated-count').textContent = results.updated || 0;
if (results.errors?.length > 0) {
document.getElementById('error-list').innerHTML =
`<strong>Errors (${results.errors.length}):</strong><br>` + results.errors.join('<br>');
} else {
document.getElementById('error-list').innerHTML = '';
}
}
} catch (error) {
resultsDiv.style.display = 'block';
alertDiv.className = 'alert alert-danger';
document.getElementById('created-count').textContent = 'N/A';
document.getElementById('updated-count').textContent = 'N/A';
document.getElementById('error-list').innerHTML =
`<strong>Upload Failed:</strong> ${error.message}`;
} finally {
submitBtn.disabled = false;
submitBtn.textContent = 'Upload CSV';
}
});
});
</script>
{% endblock %}