FossilRepo

fossilrepo / core / views.py
Source Blame History 76 lines
4ce269c… ragelink 1 import json
4ce269c… ragelink 2
4ce269c… ragelink 3 from django.contrib.auth.decorators import login_required
4ce269c… ragelink 4 from django.shortcuts import render
4ce269c… ragelink 5
4ce269c… ragelink 6
4ce269c… ragelink 7 @login_required
4ce269c… ragelink 8 def dashboard(request):
4ce269c… ragelink 9 from fossil.models import FossilRepository
4ce269c… ragelink 10 from fossil.reader import FossilReader
4ce269c… ragelink 11 from projects.models import Project
4ce269c… ragelink 12
4ce269c… ragelink 13 # Aggregate stats across all projects
4ce269c… ragelink 14 total_projects = Project.objects.count()
4ce269c… ragelink 15 total_checkins = 0
4ce269c… ragelink 16 total_tickets = 0
4ce269c… ragelink 17 total_wiki = 0
4ce269c… ragelink 18 system_activity = [] # weekly commit counts across all repos
c588255… ragelink 19 heatmap_data = {} # {date_string: count} -- daily commit counts across all repos
4ce269c… ragelink 20 recent_across_all = []
4ce269c… ragelink 21
c588255… ragelink 22 # NOTE: For large installations with many repos, this per-request aggregation
c588255… ragelink 23 # could become slow. Consider caching heatmap_data with a short TTL (e.g. 5 min)
c588255… ragelink 24 # via Django's cache framework if this becomes a bottleneck.
4ce269c… ragelink 25 repos = FossilRepository.objects.filter(deleted_at__isnull=True)
4ce269c… ragelink 26 for repo in repos:
4ce269c… ragelink 27 if not repo.exists_on_disk:
4ce269c… ragelink 28 continue
4ce269c… ragelink 29 try:
4ce269c… ragelink 30 with FossilReader(repo.full_path) as reader:
4ce269c… ragelink 31 meta = reader.get_metadata()
4ce269c… ragelink 32 total_checkins += meta.checkin_count
4ce269c… ragelink 33 total_tickets += meta.ticket_count
4ce269c… ragelink 34 total_wiki += meta.wiki_page_count
4ce269c… ragelink 35
4ce269c… ragelink 36 activity = reader.get_commit_activity(weeks=26)
4ce269c… ragelink 37 if not system_activity:
4ce269c… ragelink 38 system_activity = [c["count"] for c in activity]
4ce269c… ragelink 39 else:
4ce269c… ragelink 40 for i, c in enumerate(activity):
4ce269c… ragelink 41 if i < len(system_activity):
4ce269c… ragelink 42 system_activity[i] += c["count"]
4ce269c… ragelink 43
c588255… ragelink 44 # Aggregate daily activity for heatmap (single pass per repo)
c588255… ragelink 45 daily = reader.get_daily_commit_activity(days=365)
c588255… ragelink 46 for entry in daily:
c588255… ragelink 47 date = entry["date"]
c588255… ragelink 48 heatmap_data[date] = heatmap_data.get(date, 0) + entry["count"]
c588255… ragelink 49
4ce269c… ragelink 50 commits = reader.get_timeline(limit=3, event_type="ci")
4ce269c… ragelink 51 for c in commits:
4ce269c… ragelink 52 recent_across_all.append({"project": repo.project, "entry": c})
4ce269c… ragelink 53 except Exception:
4ce269c… ragelink 54 continue
4ce269c… ragelink 55
4ce269c… ragelink 56 # Sort recent across all by timestamp, take top 10
4ce269c… ragelink 57 recent_across_all.sort(key=lambda x: x["entry"].timestamp, reverse=True)
4ce269c… ragelink 58 recent_across_all = recent_across_all[:10]
c588255… ragelink 59
c588255… ragelink 60 # Convert heatmap to sorted list for the template
c588255… ragelink 61 heatmap_json = json.dumps(sorted([{"date": d, "count": c} for d, c in heatmap_data.items()], key=lambda x: x["date"]))
4ce269c… ragelink 62
4ce269c… ragelink 63 return render(
4ce269c… ragelink 64 request,
4ce269c… ragelink 65 "dashboard.html",
4ce269c… ragelink 66 {
4ce269c… ragelink 67 "total_projects": total_projects,
4ce269c… ragelink 68 "total_checkins": total_checkins,
4ce269c… ragelink 69 "total_tickets": total_tickets,
4ce269c… ragelink 70 "total_wiki": total_wiki,
4ce269c… ragelink 71 "total_repos": repos.count(),
4ce269c… ragelink 72 "system_activity_json": json.dumps(system_activity),
c588255… ragelink 73 "heatmap_json": heatmap_json,
4ce269c… ragelink 74 "recent_across_all": recent_across_all,
4ce269c… ragelink 75 },
4ce269c… ragelink 76 )

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button