[scrobbles] Add overlap map
All checks were successful
build & deploy / test (push) Successful in 1m55s
build & deploy / deploy (push) Successful in 30s

This commit is contained in:
2026-04-03 11:59:39 -04:00
parent decaba82f2
commit 523ed3a499

View File

@ -331,10 +331,67 @@ class ScrobbleListView(LoginRequiredMixin, ListView):
self.tag_list = tag_list
return qs
def _compute_overlap_groups(self, scrobbles):
parent = {}
def find(x):
while parent[x] != x:
parent[x] = parent[parent[x]]
x = parent[x]
return x
def union(x, y):
rx, ry = find(x), find(y)
if rx != ry:
parent[rx] = ry
for s in scrobbles:
parent[s.pk] = s.pk
def range_for(s):
start = s.timestamp
end = s.stop_timestamp
if end is None:
end = start + datetime.timedelta(hours=12)
return start, end
for i, a in enumerate(scrobbles):
a_start, a_end = range_for(a)
for b in scrobbles[i + 1 :]:
b_start, b_end = range_for(b)
if a_start <= b_end and b_start <= a_end:
union(a.pk, b.pk)
groups = {}
for s in scrobbles:
root = find(s.pk)
groups.setdefault(root, []).append(s.pk)
overlap_map = {}
color_idx = 0
COLORS = [
"border-start border-3 border-info",
"border-start border-3 border-success",
"border-start border-3 border-warning",
"border-start border-3 border-primary",
"border-start border-3 border-danger",
"border-start border-3 border-secondary",
]
for root, members in groups.items():
if len(members) >= 2:
color = COLORS[color_idx % len(COLORS)]
for pk in members:
overlap_map[pk] = color
color_idx += 1
return overlap_map
def get_context_data(self, **kwargs):
ctx = super().get_context_data(**kwargs)
ctx["tags_param"] = self.request.GET.get("tags", "")
ctx["tag_list"] = getattr(self, "tag_list", [])
scrobbles = list(ctx.get("object_list", []))
ctx["overlap_map"] = self._compute_overlap_groups(scrobbles)
return ctx