38188-vm/core/views.py
Flatlogic Bot 16066e4ba4 Mock 5
2026-02-06 20:41:24 +00:00

260 lines
10 KiB
Python

import os
import platform
import random
from datetime import date, timedelta
from django.shortcuts import render, get_object_or_404, redirect
from django.utils import timezone
from django.db.models import Count, Q
from django.http import JsonResponse
from django.contrib.auth.decorators import login_required
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth import login as auth_login
from .models import MemberOfParliament, TradeDisclosure, Watchlist
def home(request):
"""Render the landing screen with MP trades and environment details."""
# Seed data if empty
if not MemberOfParliament.objects.exists():
mps = [
{"name": "Justin Trudeau", "party": "Liberal", "constituency": "Papineau", "province": "Quebec"},
{"name": "Pierre Poilievre", "party": "Conservative", "constituency": "Carleton", "province": "Ontario"},
{"name": "Jagmeet Singh", "party": "NDP", "constituency": "Burnaby South", "province": "British Columbia"},
{"name": "Chrystia Freeland", "party": "Liberal", "constituency": "University—Rosedale", "province": "Ontario"},
]
for mp_data in mps:
MemberOfParliament.objects.get_or_create(**mp_data)
mp_jt = MemberOfParliament.objects.get(name="Justin Trudeau")
mp_pp = MemberOfParliament.objects.get(name="Pierre Poilievre")
TradeDisclosure.objects.get_or_create(
mp=mp_jt, ticker="AAPL", company_name="Apple Inc.",
trade_type="BUY", amount_range="$15,001 - $50,000",
disclosure_date=date.today() - timedelta(days=2)
)
TradeDisclosure.objects.get_or_create(
mp=mp_pp, ticker="SHOP", company_name="Shopify Inc.",
trade_type="SELL", amount_range="$50,001 - $100,000",
disclosure_date=date.today() - timedelta(days=5)
)
TradeDisclosure.objects.get_or_create(
mp=mp_jt, ticker="TSLA", company_name="Tesla, Inc.",
trade_type="BUY", amount_range="$1,000 - $15,000",
disclosure_date=date.today() - timedelta(days=10)
)
party_filter = request.GET.get('party')
trades_qs = TradeDisclosure.objects.select_related('mp').order_by('-disclosure_date')
if party_filter:
trades_qs = trades_qs.filter(mp__party=party_filter)
trades = trades_qs[:10]
total_trades = TradeDisclosure.objects.count()
total_mps = MemberOfParliament.objects.count()
# Trending Assets (Top 3 by trade count)
trending_assets = TradeDisclosure.objects.values('ticker', 'company_name').annotate(
trade_count=Count('id')
).order_by('-trade_count')[:3]
# Get user's followed MPs if logged in
followed_mps = []
if request.user.is_authenticated:
followed_mps = Watchlist.objects.filter(user=request.user, mp__isnull=False).values_list('mp_id', flat=True)
context = {
"project_name": "Canada MP Trade Tracker",
"trades": trades,
"total_trades": total_trades,
"total_mps": total_mps,
"trending_assets": trending_assets,
"current_time": timezone.now(),
"selected_party": party_filter,
"followed_mps": followed_mps,
}
if request.headers.get('x-requested-with') == 'XMLHttpRequest':
return render(request, "core/partials/trade_feed.html", context)
return render(request, "core/index.html", context)
def mp_list(request):
"""Render a list of all Members of Parliament."""
mps = MemberOfParliament.objects.all().order_by('name')
context = {
"project_name": "Canada MP Trade Tracker",
"mps": mps,
}
return render(request, "core/mp_list.html", context)
def mp_detail(request, pk):
"""Detailed view for a specific MP."""
mp = get_object_or_404(MemberOfParliament, pk=pk)
trades = mp.trades.all().order_by('-disclosure_date')
is_followed = False
if request.user.is_authenticated:
is_followed = Watchlist.objects.filter(user=request.user, mp=mp).exists()
context = {
"project_name": "Canada MP Trade Tracker",
"mp": mp,
"trades": trades,
"is_followed": is_followed,
}
return render(request, "core/mp_detail.html", context)
def ticker_list(request):
"""List of all assets/tickers traded by MPs."""
search_query = request.GET.get('q', '')
tickers_qs = TradeDisclosure.objects.values('ticker', 'company_name').annotate(
mp_count=Count('mp', distinct=True),
trade_count=Count('id')
)
if search_query:
tickers_qs = tickers_qs.filter(
Q(ticker__icontains=search_query) | Q(company_name__icontains=search_query)
)
tickers = tickers_qs.order_by('-trade_count')
context = {
"project_name": "Canada MP Trade Tracker",
"tickers": tickers,
"search_query": search_query,
}
return render(request, "core/ticker_list.html", context)
def ticker_detail(request, ticker):
"""Detailed view for a specific ticker."""
trades = TradeDisclosure.objects.filter(ticker=ticker).select_related('mp').order_by('-disclosure_date')
company_name = trades.first().company_name if trades.exists() else ticker
is_followed = False
if request.user.is_authenticated:
is_followed = Watchlist.objects.filter(user=request.user, ticker=ticker).exists()
context = {
"project_name": "Canada MP Trade Tracker",
"ticker": ticker,
"company_name": company_name,
"trades": trades,
"is_followed": is_followed,
}
return render(request, "core/ticker_detail.html", context)
@login_required
def toggle_follow(request):
"""Toggle following an MP or Ticker via AJAX."""
if request.method == 'POST':
mp_id = request.POST.get('mp_id')
ticker = request.POST.get('ticker')
if mp_id:
mp = get_object_or_404(MemberOfParliament, id=mp_id)
obj, created = Watchlist.objects.get_or_create(user=request.user, mp=mp)
if not created:
obj.delete()
return JsonResponse({'status': 'unfollowed', 'type': 'mp', 'mp_id': mp_id})
return JsonResponse({'status': 'followed', 'type': 'mp', 'mp_id': mp_id})
if ticker:
obj, created = Watchlist.objects.get_or_create(user=request.user, ticker=ticker)
if not created:
obj.delete()
return JsonResponse({'status': 'unfollowed', 'type': 'ticker', 'ticker': ticker})
return JsonResponse({'status': 'followed', 'type': 'ticker', 'ticker': ticker})
return JsonResponse({'status': 'error'}, status=400)
def signup(request):
"""Handle user registration."""
if request.method == 'POST':
form = UserCreationForm(request.POST)
if form.is_valid():
user = form.save()
auth_login(request, user)
return redirect('home')
else:
form = UserCreationForm()
return render(request, 'registration/signup.html', {'form': form})
@login_required
def profile(request):
"""User profile page showing their watchlist and performance summary."""
followed_mps_objs = Watchlist.objects.filter(user=request.user, mp__isnull=False).select_related('mp')
followed_tickers_objs = Watchlist.objects.filter(user=request.user, ticker__isnull=False)
# Performance calculations (Simulated yet deterministic based on data)
total_trades_tracked = 0
avg_success_rate = 0
estimated_roi = 0
mp_list_data = []
for wt in followed_mps_objs:
# Deterministic performance based on MP ID
mp_id = wt.mp.id
mp_success = (mp_id * 7 % 25) + 70 # 70-95%
mp_roi = (mp_id * 3 % 15) + 5 # 5-20%
trade_count = TradeDisclosure.objects.filter(mp=wt.mp).count()
total_trades_tracked += trade_count
mp_list_data.append({
'mp': wt.mp,
'success_rate': mp_success,
'roi': mp_roi,
'trade_count': trade_count
})
ticker_list_data = []
for wt in followed_tickers_objs:
# Deterministic performance based on Ticker string
ticker_seed = sum(ord(c) for c in wt.ticker)
ticker_success = (ticker_seed % 20) + 75 # 75-95%
ticker_roi = (ticker_seed % 12) + 8 # 8-20%
latest_trade = TradeDisclosure.objects.filter(ticker=wt.ticker).first()
trade_count = TradeDisclosure.objects.filter(ticker=wt.ticker).count()
ticker_list_data.append({
'ticker': wt.ticker,
'company_name': latest_trade.company_name if latest_trade else wt.ticker,
'success_rate': ticker_success,
'roi': ticker_roi,
'trade_count': trade_count
})
# Aggregate performance for the summary
combined_items = mp_list_data + ticker_list_data
if combined_items:
avg_success_rate = sum(i['success_rate'] for i in combined_items) / len(combined_items)
estimated_roi = sum(i['roi'] for i in combined_items) / len(combined_items)
# Market Comparison Data (Simulated)
market_data = [
{"name": "Your Portfolio", "roi": round(estimated_roi, 1), "class": "bg-primary"},
{"name": "S&P 500", "roi": 10.2, "class": "bg-secondary"},
{"name": "TSX Composite", "roi": 6.8, "class": "bg-info"},
{"name": "Bitcoin (BTC)", "roi": 42.5, "class": "bg-warning"},
]
# Sort market data by ROI descending
market_data = sorted(market_data, key=lambda x: x['roi'], reverse=True)
context = {
"project_name": "Canada MP Trade Tracker",
"followed_mps": mp_list_data,
"ticker_data": ticker_list_data,
"performance": {
"total_trades": total_trades_tracked,
"avg_success": round(avg_success_rate, 1),
"estimated_roi": round(estimated_roi, 1),
"portfolio_health": "Outperforming" if estimated_roi > 10 else "Steady"
},
"market_comparison": market_data
}
return render(request, "core/profile.html", context)