Skip to content

Commit 25907b0

Browse files
authored
Merge branch 'main' into optimized-images-clean
2 parents 38eddb3 + 385df26 commit 25907b0

File tree

2 files changed

+66
-0
lines changed

2 files changed

+66
-0
lines changed

website/management/commands/run_weekly.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,10 @@ def handle(self, *args, **options):
2626
logger.info("Completed sample invites cleanup")
2727
except Exception:
2828
logger.exception("Error cleaning up sample invites")
29+
30+
# Send weekly Slack report
31+
try:
32+
management.call_command("slack_weekly_report")
33+
logger.info("Completed weekly Slack report")
34+
except Exception:
35+
logger.exception("Error sending weekly Slack report")
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import logging
2+
from datetime import timedelta
3+
4+
from django.core.management.base import BaseCommand
5+
from django.utils import timezone
6+
from slack_bolt import App
7+
8+
from website.models import Issue, Project, SlackIntegration, User
9+
10+
logger = logging.getLogger(__name__)
11+
12+
13+
class Command(BaseCommand):
14+
help = "Generate and send weekly project statistics to configured Slack integrations"
15+
16+
def handle(self, *args, **kwargs):
17+
now = timezone.now()
18+
last_week = now - timedelta(days=7)
19+
20+
# Weekly Stats
21+
new_issues = Issue.objects.filter(created__gte=last_week).count()
22+
closed_issues = Issue.objects.filter(
23+
status="closed", closed_date__isnull=False, closed_date__gte=last_week
24+
).count()
25+
new_users = User.objects.filter(date_joined__gte=last_week).count()
26+
total_projects = Project.objects.count()
27+
28+
summary = (
29+
"* Weekly OWASP BLT Report*\n\n"
30+
f"*New Issues:* {new_issues}\n"
31+
f"*Closed Issues:* {closed_issues}\n"
32+
f"*New Users:* {new_users}\n"
33+
f"*Total Projects:* {total_projects}\n\n"
34+
"_Report generated automatically._"
35+
)
36+
37+
success = 0
38+
fail = 0
39+
40+
for integration in SlackIntegration.objects.all():
41+
if not integration.default_channel_id or not integration.bot_access_token:
42+
continue
43+
44+
if self.send_message(integration.default_channel_id, integration.bot_access_token, summary):
45+
success += 1
46+
else:
47+
fail += 1
48+
49+
logger.info(f"Weekly Slack report: {success} sent, {fail} failed.")
50+
51+
def send_message(self, channel_id, bot_token, message):
52+
try:
53+
app = App(token=bot_token)
54+
app.client.conversations_join(channel=channel_id)
55+
app.client.chat_postMessage(channel=channel_id, text=message)
56+
return True
57+
except Exception as e:
58+
logger.error(f"Failed to send weekly report: {e}")
59+
return False

0 commit comments

Comments
 (0)