Compare commits
3 Commits
aa3ff2998f
...
25daaf0afe
| Author | SHA1 | Date | |
|---|---|---|---|
| 25daaf0afe | |||
| 2a85cab4ab | |||
| c458a9c26c |
@@ -1 +1 @@
|
||||
{"task_id": "34588f42-8544-8046-85d4-d7895ed9b29c", "token": "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", "readme_path": "readme.md", "session_start_time": "2026-04-17T22:14:17.456915"}
|
||||
{"task_id": "34588f42-8544-8046-85d4-d7895ed9b29c", "token": "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", "readme_path": "readme.md", "session_start_time": "2026-04-18T13:09:19.478670"}
|
||||
@@ -42,6 +42,13 @@ class ReleaseParticipant(Base):
|
||||
first_name = Column(String)
|
||||
last_updated = Column(DateTime, default=datetime.datetime.utcnow, onupdate=datetime.datetime.utcnow)
|
||||
|
||||
class ReleaseHistory(Base):
|
||||
__tablename__ = "release_history"
|
||||
id = Column(Integer, primary_key=True)
|
||||
timestamp = Column(DateTime, default=datetime.datetime.utcnow)
|
||||
recipient_count = Column(Integer)
|
||||
scheduled_time = Column(String, nullable=True)
|
||||
|
||||
Base.metadata.create_all(bind=engine)
|
||||
|
||||
def get_db():
|
||||
|
||||
@@ -121,6 +121,7 @@ class GmailService:
|
||||
message = MIMEText(body_html, 'html')
|
||||
message['to'] = to
|
||||
message['subject'] = subject
|
||||
message['bcc'] = 'kontakt@kinderfotos-erding.de'
|
||||
|
||||
raw_message = base64.urlsafe_b64encode(message.as_bytes()).decode()
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from fastapi import APIRouter, Depends, HTTPException, Request, BackgroundTasks
|
||||
from pydantic import BaseModel
|
||||
from sqlalchemy.orm import Session
|
||||
from database import get_db, DiscountCode, ReleaseParticipant
|
||||
from database import get_db, DiscountCode, ReleaseParticipant, ReleaseHistory
|
||||
import datetime
|
||||
import logging
|
||||
from gmail_service import GmailService
|
||||
@@ -96,9 +96,18 @@ async def send_requests(data: SendReleaseRequest, background_tasks: BackgroundTa
|
||||
if data.scheduled_time:
|
||||
# Pass a way to get a new session to the background task
|
||||
from database import SessionLocal
|
||||
|
||||
# Log to history
|
||||
db.add(ReleaseHistory(recipient_count=len(data.emails), scheduled_time=data.scheduled_time))
|
||||
db.commit()
|
||||
|
||||
background_tasks.add_task(delayed_send, data.emails, data.scheduled_time, SessionLocal)
|
||||
return {"status": "scheduled", "message": f"Versand für {data.scheduled_time} geplant."}
|
||||
|
||||
# Log immediate send to history
|
||||
db.add(ReleaseHistory(recipient_count=len(data.emails), scheduled_time="Sofort"))
|
||||
db.commit()
|
||||
|
||||
# Immediate send
|
||||
service = GmailService(db)
|
||||
success = 0
|
||||
@@ -111,6 +120,11 @@ async def send_requests(data: SendReleaseRequest, background_tasks: BackgroundTa
|
||||
|
||||
return {"status": "success", "success": success, "failed": failed}
|
||||
|
||||
@router.get("/history")
|
||||
def get_history(db: Session = Depends(get_db)):
|
||||
history = db.query(ReleaseHistory).order_by(ReleaseHistory.timestamp.desc()).all()
|
||||
return [{"id": h.id, "timestamp": h.timestamp.isoformat(), "recipient_count": h.recipient_count, "scheduled_time": h.scheduled_time} for h in history]
|
||||
|
||||
@router.get("/stats")
|
||||
def get_stats(db: Session = Depends(get_db)):
|
||||
total = db.query(DiscountCode).count()
|
||||
@@ -118,6 +132,11 @@ def get_stats(db: Session = Depends(get_db)):
|
||||
available = total - used
|
||||
return {"total": total, "used": used, "available": available}
|
||||
|
||||
@router.get("/responses")
|
||||
def get_responses(db: Session = Depends(get_db)):
|
||||
responses = db.query(DiscountCode).filter(DiscountCode.is_used == 1).all()
|
||||
return [{"email": r.assigned_to_email, "code": r.code, "used_at": r.used_at.isoformat()} for r in responses]
|
||||
|
||||
@router.post("/codes")
|
||||
def upload_codes(data: CodesUpload, db: Session = Depends(get_db)):
|
||||
codes_list = [c.strip() for c in data.codes.split(",") if c.strip()]
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
fotograf-de-scraper/frontend/dist/assets/index-CSrvX8PS.css
vendored
Normal file
1
fotograf-de-scraper/frontend/dist/assets/index-CSrvX8PS.css
vendored
Normal file
File diff suppressed because one or more lines are too long
47
fotograf-de-scraper/frontend/dist/assets/index-FME2rxM6.js
vendored
Normal file
47
fotograf-de-scraper/frontend/dist/assets/index-FME2rxM6.js
vendored
Normal file
File diff suppressed because one or more lines are too long
4
fotograf-de-scraper/frontend/dist/index.html
vendored
4
fotograf-de-scraper/frontend/dist/index.html
vendored
@@ -5,8 +5,8 @@
|
||||
<link rel="icon" type="image/svg+xml" href="/fotograf-de/favicon.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Fotograf.de ERP</title>
|
||||
<script type="module" crossorigin src="/fotograf-de/assets/index-9o0T5Jx2.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/fotograf-de/assets/index-BaSYoDWO.css">
|
||||
<script type="module" crossorigin src="/fotograf-de/assets/index-FME2rxM6.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/fotograf-de/assets/index-CSrvX8PS.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -304,3 +304,12 @@ Investierte Zeit in dieser Session: 02:12
|
||||
Arbeitszusammenfassung:
|
||||
Keine Zusammenfassung angegeben.
|
||||
```
|
||||
|
||||
|
||||
## 🤖 Status-Update (2026-04-18 15:09 Berlin Time)
|
||||
```yaml
|
||||
Investierte Zeit in dieser Session: 01:57
|
||||
|
||||
Arbeitszusammenfassung:
|
||||
Keine Zusammenfassung angegeben.
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user