first commit
This commit is contained in:
115
metrics/views.py
Normal file
115
metrics/views.py
Normal file
@@ -0,0 +1,115 @@
|
||||
from django.shortcuts import render
|
||||
from django.http import JsonResponse
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
from django.views.decorators.http import require_http_methods
|
||||
from django.db.models import Count
|
||||
from django.db.models.functions import TruncDate
|
||||
from django.utils import timezone
|
||||
from datetime import timedelta
|
||||
import json
|
||||
|
||||
from .models import ClickEvent
|
||||
|
||||
|
||||
def get_client_ip(request):
|
||||
x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
|
||||
if x_forwarded_for:
|
||||
ip = x_forwarded_for.split(',')[0].strip()
|
||||
else:
|
||||
ip = request.META.get('REMOTE_ADDR')
|
||||
return ip
|
||||
|
||||
|
||||
@csrf_exempt
|
||||
@require_http_methods(["POST"])
|
||||
def track_bot_click(request):
|
||||
"""Трекинг перехода в бота"""
|
||||
ClickEvent.objects.create(
|
||||
event_type='bot',
|
||||
ip_address=get_client_ip(request),
|
||||
user_agent=request.META.get('HTTP_USER_AGENT', ''),
|
||||
referrer=request.META.get('HTTP_REFERER'),
|
||||
)
|
||||
return JsonResponse({'status': 'ok', 'event': 'bot'})
|
||||
|
||||
|
||||
@csrf_exempt
|
||||
@require_http_methods(["POST"])
|
||||
def track_channel_click(request):
|
||||
"""Трекинг перехода в TG канал"""
|
||||
ClickEvent.objects.create(
|
||||
event_type='channel',
|
||||
ip_address=get_client_ip(request),
|
||||
user_agent=request.META.get('HTTP_USER_AGENT', ''),
|
||||
referrer=request.META.get('HTTP_REFERER'),
|
||||
)
|
||||
return JsonResponse({'status': 'ok', 'event': 'channel'})
|
||||
|
||||
|
||||
def dashboard(request):
|
||||
"""Страница статистики"""
|
||||
today = timezone.now().date()
|
||||
week_ago = today - timedelta(days=7)
|
||||
month_ago = today - timedelta(days=30)
|
||||
|
||||
# Общая статистика
|
||||
total_bot = ClickEvent.objects.filter(event_type='bot').count()
|
||||
total_channel = ClickEvent.objects.filter(event_type='channel').count()
|
||||
|
||||
# Статистика за сегодня
|
||||
today_bot = ClickEvent.objects.filter(
|
||||
event_type='bot',
|
||||
created_at__date=today
|
||||
).count()
|
||||
today_channel = ClickEvent.objects.filter(
|
||||
event_type='channel',
|
||||
created_at__date=today
|
||||
).count()
|
||||
|
||||
# Статистика за неделю
|
||||
week_bot = ClickEvent.objects.filter(
|
||||
event_type='bot',
|
||||
created_at__date__gte=week_ago
|
||||
).count()
|
||||
week_channel = ClickEvent.objects.filter(
|
||||
event_type='channel',
|
||||
created_at__date__gte=week_ago
|
||||
).count()
|
||||
|
||||
# Данные для графика (последние 30 дней)
|
||||
bot_by_day = ClickEvent.objects.filter(
|
||||
event_type='bot',
|
||||
created_at__date__gte=month_ago
|
||||
).annotate(date=TruncDate('created_at')).values('date').annotate(
|
||||
count=Count('id')
|
||||
).order_by('date')
|
||||
|
||||
channel_by_day = ClickEvent.objects.filter(
|
||||
event_type='channel',
|
||||
created_at__date__gte=month_ago
|
||||
).annotate(date=TruncDate('created_at')).values('date').annotate(
|
||||
count=Count('id')
|
||||
).order_by('date')
|
||||
|
||||
# Последние события
|
||||
recent_events = ClickEvent.objects.all()[:20]
|
||||
|
||||
context = {
|
||||
'total_bot': total_bot,
|
||||
'total_channel': total_channel,
|
||||
'today_bot': today_bot,
|
||||
'today_channel': today_channel,
|
||||
'week_bot': week_bot,
|
||||
'week_channel': week_channel,
|
||||
'bot_by_day': json.dumps([
|
||||
{'date': item['date'].isoformat(), 'count': item['count']}
|
||||
for item in bot_by_day
|
||||
]),
|
||||
'channel_by_day': json.dumps([
|
||||
{'date': item['date'].isoformat(), 'count': item['count']}
|
||||
for item in channel_by_day
|
||||
]),
|
||||
'recent_events': recent_events,
|
||||
}
|
||||
|
||||
return render(request, 'metrics/dashboard.html', context)
|
||||
Reference in New Issue
Block a user