1
0
Fork 0
mirror of https://github.com/Findus23/RPGnotes.git synced 2024-09-19 15:43:45 +02:00
RPGnotes/graph/views.py

120 lines
3.3 KiB
Python

from typing import Union
from django.db import connection
from django.http import JsonResponse, HttpRequest, HttpResponse
from django.views.generic import TemplateView
from characters.models import Character
from factions.models import Faction
from locations.models import Location
from loot.models import Loot, LootType
from notes.models import Note
from users.models import TenantUser
GraphModelEl = Union[Location, Note, Character, Faction]
class Graph:
def __init__(self):
self.nodes = []
self.edges = set()
def add_node(self, el: GraphModelEl, label: str = None):
if label is None:
label = el.name
self.nodes.append({
"key": el.graphkey,
"attributes": {
"label": label,
"size": 10,
"url": el.get_absolute_url() if hasattr(el, "get_absolute_url") else "/"
}
})
def add_edge(self, source: GraphModelEl, target: GraphModelEl):
if source == target:
return
self.edges.add((source.graphkey, target.graphkey))
def add_edge_str(self, source: str, target: str):
if source == target:
return
self.edges.add((source, target))
def prune(self) -> None:
connected_nodes = set()
for e in self.edges:
connected_nodes.add(e[0])
connected_nodes.add(e[1])
self.nodes = [n for n in self.nodes if n["key"] in connected_nodes]
def export(self):
edges = []
for source, target in self.edges:
edges.append({
"source": source,
"target": target
})
return {
"attributes": {},
"nodes": list(self.nodes),
"edges": edges
}
#
#
# class Graph:
# def __init__(self):
# self.nodes=
class GraphView(TemplateView):
template_name = "graph/graph.jinja"
def get_description_links(el: GraphModelEl, g: Graph):
if el.linked_objects:
for lo in el.linked_objects.split(","):
g.add_edge_str(el.graphkey, lo)
def get_graph(request: HttpRequest) -> HttpResponse:
g = Graph()
for loc in list(Location.objects.all()) + list(Note.objects.all()):
g.add_node(loc)
if loc.parent:
g.add_edge(loc, loc.parent)
get_description_links(loc, g)
for faction in Faction.objects.all():
g.add_node(faction, faction.name)
get_description_links(faction, g)
for user in TenantUser.objects \
.filter(tenants=connection.get_tenant()) \
.exclude(pk__in=[1, 2]):
g.add_node(user, user.name)
for char in Character.objects.all():
g.add_node(char)
if char.location:
g.add_edge(char, char.location)
if char.faction:
g.add_edge(char, char.faction)
if char.player:
g.add_edge(char, char.player)
get_description_links(char, g)
for loottype in LootType.objects.all():
g.add_node(loottype)
for loot in Loot.objects.all():
g.add_node(loot)
if loot.location:
g.add_edge(loot, loot.location)
if loot.owner:
g.add_edge(loot, loot.owner)
if loot.type:
g.add_edge(loot, loot.type)
get_description_links(loot, g)
g.prune()
return JsonResponse(g.export())