-
Notifications
You must be signed in to change notification settings - Fork 2
/
schema.py
163 lines (126 loc) · 5.37 KB
/
schema.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
from django.contrib.gis.db.models.functions import Transform
import graphene
from graphene_django import DjangoObjectType
from django.db.models.fields import IntegerField
from django.urls import reverse
from wagtail.core.rich_text import expand_db_html
from mocaf.graphql_gis import PointScalar
from mocaf.graphql_types import DjangoNode
from utils.i18n import resolve_i18n_field
from .models import AreaType, Area, DailyTripSummary
from pages.models import VisualisationGuidePage
class AreaPropertyNode(graphene.ObjectType):
property_id = graphene.ID()
value = graphene.Float()
class AreaNode(graphene.ObjectType):
id = graphene.ID()
identifier = graphene.ID()
name = graphene.String()
centroid = PointScalar()
properties = graphene.List(AreaPropertyNode)
def resolve_properties(root: Area, info):
props = []
for prop in root.property_values.all():
props.append(dict(property_id=prop.property_id, value=prop.value))
return props
def resolve_centroid(root: Area, info):
return root.centroid_wsg84
class PropertyMeta(graphene.ObjectType):
id = graphene.ID()
identifier = graphene.ID()
description = graphene.String()
class AreaTypeNode(DjangoNode):
areas = graphene.List(AreaNode)
topojson_url = graphene.String(required=False)
geojson_url = graphene.String()
properties_meta = graphene.List(PropertyMeta)
# daily_trips_url = graphene.String()
# daily_lengths_url = graphene.String()
property_values_url = graphene.String(required=False)
daily_trips_date_range = graphene.List(graphene.Date)
daily_lengths_date_range = graphene.List(graphene.Date)
daily_poi_trips_date_range = graphene.List(graphene.Date)
is_poi = graphene.Boolean()
def resolve_areas(root, info):
return root.areas.all()\
.only('id', 'identifier', 'name', 'type')\
.prefetch_related('property_values')\
.annotate(centroid_wsg84=Transform('centroid', 4326))
def resolve_topojson_url(root: AreaType, info):
request = info.context
if root.is_poi:
return None
url = reverse('area-type-topojson', kwargs=dict(id=root.id))
return request.build_absolute_uri(url)
def resolve_geojson_url(root: AreaType, info):
request = info.context
if not root.is_poi:
return None
url = reverse('area-type-geojson', kwargs=dict(id=root.id))
return request.build_absolute_uri(url)
def resolve_daily_trips_url(root: AreaType, info):
request = info.context
url = reverse('area-type-stats', kwargs=dict(id=root.id, type='daily-trips'))
return request.build_absolute_uri(url)
def resolve_daily_lengths_url(root: AreaType, info):
request = info.context
url = reverse('area-type-stats', kwargs=dict(id=root.id, type='daily-lengths'))
return request.build_absolute_uri(url)
def resolve_property_values_url(root: AreaType, info):
if not root.properties_meta.exists():
return None
request = info.context
url = reverse('area-type-stats', kwargs=dict(id=root.id, type='properties'))
return request.build_absolute_uri(url)
def resolve_properties_meta(root: AreaType, info):
return root.properties_meta.all()
def resolve_name(root: AreaType, info):
return resolve_i18n_field(root, 'name', info)
class Meta:
model = AreaType
fields = ['id', 'identifier', 'name', 'areas']
class DailyTripSummaryNode(graphene.ObjectType):
date = graphene.Date()
origin_id = graphene.ID()
dest_id = graphene.ID()
mode_id = graphene.ID()
trips = IntegerField()
class VisualisationGuidePageNode(DjangoObjectType):
class Meta:
model = VisualisationGuidePage
fields = ['id', 'title', 'body']
body = graphene.String()
def resolve_body(root, info):
return expand_db_html(root.body)
class Analytics(graphene.ObjectType):
area_types = graphene.List(AreaTypeNode, id=graphene.ID(required=False))
visualisation_guide = graphene.Field(VisualisationGuidePageNode, id=graphene.ID(required=True))
visualisation_guides = graphene.List(VisualisationGuidePageNode)
def resolve_daily_trips(root, info, area_type):
area_type = AreaType.objects.get(identifier=area_type)
return list(DailyTripSummary.objects.filter(origin__type=area_type, dest__type=area_type).values(
'date', 'origin_id', 'dest_id', 'mode_id', 'trips',
))
def resolve_area_types(root, info, id=None):
types = AreaType.objects.all().prefetch_related('properties_meta')
if id is not None:
types = types.filter(id=id)
return types
def resolve_visualisation_guide(root, info, id, **kwargs):
return (VisualisationGuidePage.objects
.live()
.public()
.specific()
.get(id=id))
def resolve_visualisation_guides(root, info, **kwargs):
return (VisualisationGuidePage.objects
.live()
.public()
.filter(locale__language_code=info.context.language)
.specific()
.order_by('-first_published_at'))
class Query(graphene.ObjectType):
analytics = graphene.Field(Analytics)
def resolve_analytics(root, info):
# FIXME: Check API key?
return Analytics()