Skip to content

Commit 65e7c5c

Browse files
committed
feat(permissions): add casbin
1 parent 7200aaf commit 65e7c5c

23 files changed

+3756
-0
lines changed

manatee/datatypes/bngcentrepoint.py

+114
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
from arches.app.datatypes.base import BaseDataType
2+
from arches.app.models.models import Widget
3+
from arches.app.models.system_settings import settings
4+
5+
bngpoint = Widget.objects.get(name="bngpoint")
6+
7+
details = {
8+
"datatype": "bngcentrepoint",
9+
"iconclass": "fa fa-location-arrow",
10+
"modulename": "bngcentrepoint.py",
11+
"classname": "BNGCentreDataType",
12+
"defaultwidget": bngpoint,
13+
"defaultconfig": None,
14+
"configcomponent": None,
15+
"configname": None,
16+
"isgeometric": False,
17+
"issearchable": False,
18+
}
19+
20+
21+
class BNGCentreDataType(BaseDataType):
22+
def validate(self, value, row_number=None, source=None, node=None, nodeid=None, strict=False, request=None):
23+
24+
errors = []
25+
gridSquareArray = [
26+
"NA",
27+
"NB",
28+
"NC",
29+
"ND",
30+
"NE",
31+
"NF",
32+
"NG",
33+
"NH",
34+
"NJ",
35+
"NK",
36+
"NL",
37+
"NM",
38+
"NN",
39+
"NO",
40+
"NP",
41+
"NR",
42+
"NS",
43+
"NT",
44+
"NU",
45+
"NV",
46+
"NW",
47+
"NX",
48+
"NY",
49+
"NZ",
50+
"OA",
51+
"OB",
52+
"OF",
53+
"OG",
54+
"OL",
55+
"OM",
56+
"OQ",
57+
"OR",
58+
"OV",
59+
"OW",
60+
"SA",
61+
"SB",
62+
"SC",
63+
"SD",
64+
"SE",
65+
"SF",
66+
"SG",
67+
"SH",
68+
"SJ",
69+
"SK",
70+
"SL",
71+
"SM",
72+
"SN",
73+
"SO",
74+
"SP",
75+
"SQ",
76+
"SR",
77+
"SS",
78+
"ST",
79+
"SU",
80+
"SV",
81+
"SW",
82+
"SX",
83+
"SY",
84+
"SZ",
85+
"TA",
86+
"TB",
87+
"TF",
88+
"TG",
89+
"TL",
90+
"TM",
91+
"TQ",
92+
"TR",
93+
"TV",
94+
"TW",
95+
]
96+
try:
97+
# CS - Validation for datatype. Replicates functionality in widget which will be removed once datatype validation is fixed.
98+
firstTwoCharacters = value[0:2]
99+
numberElement = value[2:]
100+
101+
firstTwoCharacters in gridSquareArray
102+
isinstance(int(numberElement), int)
103+
len(value) == 12
104+
except Exception:
105+
errors.append({"type": "ERROR", "message": "Issue with input data"})
106+
107+
return errors
108+
109+
def append_to_document(self, document, nodevalue, nodeid, tile, provisional=False):
110+
111+
document["strings"].append({"string": nodevalue, "nodegroup_id": tile.nodegroup_id})
112+
113+
def get_search_terms(self, nodevalue, nodeid=None):
114+
return [nodevalue]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
1+
import uuid
2+
from arches.app.functions.base import BaseFunction
3+
from arches.app.models.system_settings import settings
4+
from arches.app.models import models
5+
from arches.app.models.tile import Tile
6+
from arches.app.models.resource import Resource
7+
from django.contrib.gis.geos import GEOSGeometry
8+
from django.db import connection, transaction
9+
import json
10+
from datetime import datetime
11+
12+
13+
details = {
14+
"name": "BNG Point to GeoJSON",
15+
"type": "node",
16+
"description": "Pushes the geometry from a BNG Point node to a related GeoJSON node",
17+
"defaultconfig": {"bng_node": "", "geojson_node": "", "bng_nodegroup": "", "geojson_nodegroup": "", "triggering_nodegroups": []},
18+
"classname": "BNGPointToGeoJSON",
19+
"component": "views/components/functions/bngpoint-to-geojson-function",
20+
"functionid": "0434df8d-b98a-4b41-9a0a-68cd9214ad73",
21+
}
22+
23+
24+
class BNGPointToGeoJSON(BaseFunction):
25+
def get(self):
26+
raise NotImplementedError
27+
28+
def save_geojson(self, tile, request, is_function_save_method=True):
29+
"""Finds the equivalen GeoJSON for a BNG Alphanumeric value and saves that value to the
30+
geojson nodegroup of the tile.
31+
32+
Args:
33+
self : BNGPointToGeoJSON object.
34+
35+
tile : Tile to attach / amend geojson_nodegroup of.
36+
37+
request : WSGI Request used to varify call is result of user action. N.B. Function Returns if empty.
38+
39+
is_function_save_method : a bool stating whether the function calling it is the save function.
40+
"""
41+
42+
# First let's check if this call is as a result of an inbound request (user action) or
43+
# as a result of the complementary GeoJSONToBNGPoint function saving a new BngPoint.
44+
if request is None and is_function_save_method == True:
45+
return
46+
47+
bngValueReturned = ""
48+
gridSquare = {
49+
"NA": [0, 9],
50+
"NB": [1, 9],
51+
"NC": [2, 9],
52+
"ND": [3, 9],
53+
"NE": [4, 9],
54+
"OA": [5, 9],
55+
"OB": [6, 9],
56+
"NF": [0, 8],
57+
"NG": [1, 8],
58+
"NH": [2, 8],
59+
"NJ": [3, 8],
60+
"NK": [4, 8],
61+
"OF": [5, 8],
62+
"OG": [6, 8],
63+
"NL": [0, 7],
64+
"NM": [1, 7],
65+
"NN": [2, 7],
66+
"NO": [3, 7],
67+
"NP": [4, 7],
68+
"OL": [5, 7],
69+
"OM": [6, 7],
70+
"NQ": [0, 6],
71+
"NR": [1, 6],
72+
"NS": [2, 6],
73+
"NT": [3, 6],
74+
"NU": [4, 6],
75+
"OQ": [5, 6],
76+
"OR": [6, 6],
77+
"NV": [0, 5],
78+
"NW": [1, 5],
79+
"NX": [2, 5],
80+
"NY": [3, 5],
81+
"NZ": [4, 5],
82+
"OV": [5, 5],
83+
"OW": [6, 5],
84+
"SA": [0, 4],
85+
"SB": [1, 4],
86+
"SC": [2, 4],
87+
"SD": [3, 4],
88+
"SE": [4, 4],
89+
"TA": [5, 4],
90+
"TB": [6, 4],
91+
"SF": [0, 3],
92+
"SG": [1, 3],
93+
"SH": [2, 3],
94+
"SJ": [3, 3],
95+
"SK": [4, 3],
96+
"TF": [5, 3],
97+
"TG": [6, 3],
98+
"SL": [0, 2],
99+
"SM": [1, 2],
100+
"SN": [2, 2],
101+
"SO": [3, 2],
102+
"SP": [4, 2],
103+
"TL": [5, 2],
104+
"TM": [6, 2],
105+
"SQ": [0, 1],
106+
"SR": [1, 1],
107+
"SS": [2, 1],
108+
"ST": [3, 1],
109+
"SU": [4, 1],
110+
"TQ": [5, 1],
111+
"TR": [6, 1],
112+
"SV": [0, 0],
113+
"SW": [1, 0],
114+
"SX": [2, 0],
115+
"SY": [3, 0],
116+
"SZ": [4, 0],
117+
"TV": [5, 0],
118+
"TW": [6, 0],
119+
}
120+
121+
bngnode = self.config["bng_node"]
122+
geojsonNode = self.config["geojson_node"]
123+
bngValueReturned = tile.data[bngnode]
124+
125+
if bngValueReturned != None:
126+
"""
127+
The following section turns the alphanumberic BNG value in the tile into a point geometry object and then transforms that object
128+
into WGS 1984 long/lat projection system.
129+
"""
130+
131+
dt = datetime.now()
132+
gridSquareLetters = bngValueReturned[0:2]
133+
bngValueNumbers = bngValueReturned[2:]
134+
splitSection = int(len(bngValueNumbers) / 2)
135+
gridSquareNumbers = gridSquare[gridSquareLetters]
136+
eastingValue = str(gridSquareNumbers[0]) + str(bngValueNumbers[:splitSection])
137+
northingValue = str(gridSquareNumbers[1]) + str(bngValueNumbers[splitSection:])
138+
osgb36PointString = "POINT (" + eastingValue + " " + northingValue + ")"
139+
osgb36Point = GEOSGeometry(osgb36PointString, srid=27700)
140+
osgb36Point.transform(4326, False)
141+
pointGeoJSON = json.loads(osgb36Point.geojson)
142+
143+
"""
144+
This section creates a geojson object required in the format required by Arches. The date and time the object was
145+
created has also been added in the feature's properties.
146+
"""
147+
148+
uuidForRecord = uuid.uuid4().hex
149+
bngFeature = {
150+
"geometry": pointGeoJSON,
151+
"type": "Feature",
152+
"id": str(uuidForRecord),
153+
"properties": {"datetime": dt.strftime("%d/%m/%Y %H:%M:%S"), "bngref": str(bngValueReturned)},
154+
}
155+
156+
geometryValue = {"type": "FeatureCollection", "features": [bngFeature]}
157+
158+
geometryValueJson = geometryValue
159+
160+
"""
161+
The Tile.objects.filter function from tiles.py is called to return any tiles with the geojson_nodegroup value
162+
as the nodegroup_id and the current tile's resource instance ID as its resourceinstance_id value; any tiles returned
163+
are added to the previously_saved_tiles variable.
164+
165+
If there are tiles returned then the new geojson object overwrites the current value.
166+
167+
If there are no tiles returned, a new tile is created for the geojson nodegroup using tile.py's get_blank_tile
168+
function. If there is a key within the data object in the new node with the same id as the geojson_nodegroup value
169+
then that key/value pair are deleted. The geojson object is set at the value to the key which has the value of the geojson_node
170+
value.
171+
172+
The new tile is saved and then the mv_geojson_geoms materialised view is refreshed so the point geometry will be displayed
173+
on the Search map.
174+
"""
175+
if self.config["geojson_nodegroup"] == str(tile.nodegroup_id):
176+
tile.data[geojsonNode] = geometryValueJson
177+
else:
178+
previously_saved_tiles = Tile.objects.filter(
179+
nodegroup_id=self.config["geojson_nodegroup"], resourceinstance_id=tile.resourceinstance_id
180+
)
181+
182+
if len(previously_saved_tiles) > 0:
183+
for p in previously_saved_tiles:
184+
old_geojson = p.data[geojsonNode]
185+
p.data[geojsonNode] = geometryValueJson
186+
187+
for f in old_geojson["features"]:
188+
if "bngref" not in f["properties"]:
189+
p.data[geojsonNode]["features"].append(f)
190+
191+
p.save()
192+
else:
193+
new_geojson_tile = Tile().get_blank_tile_from_nodegroup_id(
194+
self.config["geojson_nodegroup"], resourceid=tile.resourceinstance_id, parenttile=tile.parenttile
195+
)
196+
new_geojson_tile.data[self.config["geojson_node"]] = geometryValueJson
197+
198+
if self.config["geojson_nodegroup"] in new_geojson_tile.data:
199+
del new_geojson_tile.data[self.config["geojson_nodegroup"]]
200+
201+
new_geojson_tile.save()
202+
203+
cursor = connection.cursor()
204+
sql = """
205+
SELECT * FROM refresh_geojson_geometries();
206+
"""
207+
cursor.execute(sql) #
208+
209+
else:
210+
pass
211+
212+
return
213+
214+
def save(self, tile, request, context=None):
215+
216+
self.save_geojson(tile=tile, request=request, is_function_save_method=True)
217+
return
218+
219+
def post_save(self, *args, **kwargs):
220+
raise NotImplementedError
221+
222+
def delete(self, tile, request):
223+
raise NotImplementedError
224+
225+
def on_import(self, tile):
226+
self.save_geojson(tile=tile, request=None, is_function_save_method=False)
227+
return
228+
229+
def after_function_save(self, tile, request):
230+
raise NotImplementedError

0 commit comments

Comments
 (0)