Beispiel #1
0
    def test_apply_provisional_edit(self):
        """
        Tests that provisional edit data is properly created

        """

        json = {
            "resourceinstance_id": "40000000-0000-0000-0000-000000000000",
            "parenttile_id": "",
            "nodegroup_id": "72048cb3-adbc-11e6-9ccf-14109fd34195",
            "tileid": "",
            "data": {
                "72048cb3-adbc-11e6-9ccf-14109fd34195": "TEST 1"
            },
        }

        user = User.objects.create_user(username="******",
                                        password="******")
        provisional_tile = Tile(json)
        request = HttpRequest()
        request.user = user
        provisional_tile.save(index=False, request=request)
        provisional_tile.apply_provisional_edit(user, {"test": "test"},
                                                "update")
        provisionaledits = provisional_tile.provisionaledits
        userid = str(user.id)
        self.assertEqual(provisionaledits[userid]["action"], "update")
        self.assertEqual(provisionaledits[userid]["reviewer"], None)
        self.assertEqual(provisionaledits[userid]["value"], {"test": "test"})
        self.assertEqual(provisionaledits[userid]["status"], "review")
        self.assertEqual(provisionaledits[userid]["reviewtimestamp"], None)
Beispiel #2
0
    def test_apply_provisional_edit(self):
        """
        Tests that provisional edit data is properly created

        """

        json = {
            "resourceinstance_id": "40000000-0000-0000-0000-000000000000",
            "parenttile_id": '',
            "nodegroup_id": "72048cb3-adbc-11e6-9ccf-14109fd34195",
            "tileid": "",
            "data": {
              "72048cb3-adbc-11e6-9ccf-14109fd34195": "TEST 1"
            }
        }

        user = User.objects.create_user(username='******', password='******')
        provisional_tile = Tile(json)
        request = HttpRequest()
        request.user = user
        provisional_tile.save(index=False, request=request)
        provisional_tile.apply_provisional_edit(user, {"test":"test"}, 'update')
        provisionaledits = JSONDeserializer().deserialize(provisional_tile.provisionaledits)
        userid = str(user.id)
        self.assertEqual(provisionaledits[userid]['action'], 'update')
        self.assertEqual(provisionaledits[userid]['reviewer'], None)
        self.assertEqual(provisionaledits[userid]['value'], {"test":"test"})
        self.assertEqual(provisionaledits[userid]['status'], "review")
        self.assertEqual(provisionaledits[userid]['reviewtimestamp'], None)
Beispiel #3
0
    def test_save(self):
        """
        Test that we can save a Tile object back to the database

        """
        login = self.client.login(username='******', password='******')

        json = {
            "tiles": {
                "72048cb3-adbc-11e6-9ccf-14109fd34195": [{
                    "tiles": {},
                    "resourceinstance_id": "40000000-0000-0000-0000-000000000000",
                    "parenttile_id": '',
                    "nodegroup_id": "72048cb3-adbc-11e6-9ccf-14109fd34195",
                    "tileid": "",
                    "data": {
                      "72048cb3-adbc-11e6-9ccf-14109fd34195": "TEST 1"
                    }
                }]
            },
            "resourceinstance_id": "40000000-0000-0000-0000-000000000000",
            "parenttile_id": '',
            "nodegroup_id": "7204869c-adbc-11e6-8bec-14109fd34195",
            "tileid": "",
            "data": {}
        }

        t = Tile(json)
        t.save(index=False)

        tiles = Tile.objects.filter(resourceinstance_id="40000000-0000-0000-0000-000000000000")

        self.assertEqual(tiles.count(), 2)
Beispiel #4
0
    def test_tile_cardinality(self):
        """
        Tests that the tile is not saved if the cardinality is violated
        by testin to save a tile with the same values as existing one

        """

        self.user = User.objects.get(username="******")
        first_json = {
            "resourceinstance_id": "40000000-0000-0000-0000-000000000000",
            "parenttile_id": "",
            "nodegroup_id": "72048cb3-adbc-11e6-9ccf-14109fd34195",
            "tileid": "",
            "data": {
                "72048cb3-adbc-11e6-9ccf-14109fd34195": "AUTHORITATIVE"
            },
        }
        first_tile = Tile(first_json)
        request = HttpRequest()
        request.user = self.user
        first_tile.save(index=False, request=request)

        second_json = {
            "resourceinstance_id": "40000000-0000-0000-0000-000000000000",
            "parenttile_id": "",
            "nodegroup_id": "72048cb3-adbc-11e6-9ccf-14109fd34195",
            "tileid": "",
            "data": {
                "72048cb3-adbc-11e6-9ccf-14109fd34195": "AUTHORITATIVE"
            },
        }
        second_tile = Tile(second_json)

        with self.assertRaises(TileCardinalityError):
            second_tile.save(index=False, request=request)
Beispiel #5
0
    def test_tile_deletion(self):
        """
        Tests that a tile is deleted when a user is a reviewer or owner.

        """

        json = {
            "resourceinstance_id": "40000000-0000-0000-0000-000000000000",
            "parenttile_id": '',
            "nodegroup_id": "72048cb3-adbc-11e6-9ccf-14109fd34195",
            "tileid": "",
            "data": {
              "72048cb3-adbc-11e6-9ccf-14109fd34195": "TEST 1"
            }
        }

        owner = User.objects.create_user(username='******', password='******')
        reviewer = User.objects.get(username='******')

        tile1 = Tile(json)
        owner_request = HttpRequest()
        owner_request.user = owner
        tile1.save(index=False, request=owner_request)
        tile1.delete(request=owner_request)

        tile2 = Tile(json)
        reviewer_request = HttpRequest()
        reviewer_request.user = reviewer
        tile2.save(index=False, request=reviewer_request)
        tile2.delete(request=reviewer_request)

        self.assertEqual(len(Tile.objects.all()), 0)
Beispiel #6
0
    def test_provisional_deletion(self):
        """
        Tests that a tile is NOT deleted if a user does not have the
        privlages to delete a tile and that the proper provisionaledit is
        applied.

        """

        json = {
            "resourceinstance_id": "40000000-0000-0000-0000-000000000000",
            "parenttile_id": '',
            "nodegroup_id": "72048cb3-adbc-11e6-9ccf-14109fd34195",
            "tileid": "",
            "data": {
              "72048cb3-adbc-11e6-9ccf-14109fd34195": "TEST 1"
            }
        }

        provisional_user = User.objects.create_user(username='******', password='******')
        reviewer = User.objects.get(username='******')

        tile = Tile(json)
        reviewer_request = HttpRequest()
        reviewer_request.user = reviewer
        tile.save(index=False, request=reviewer_request)

        provisional_request = HttpRequest()
        provisional_request.user = provisional_user
        tile.delete(request=provisional_request)

        self.assertEqual(len(Tile.objects.all()), 1)
Beispiel #7
0
    def test_create_new_provisional(self):
        """
        Test that a new provisional tile is created when a user IS NOT a reviwer.

        """

        self.user = User.objects.create_user(username="******",
                                             password="******")

        json = {
            "resourceinstance_id": "40000000-0000-0000-0000-000000000000",
            "parenttile_id": "",
            "nodegroup_id": "72048cb3-adbc-11e6-9ccf-14109fd34195",
            "tileid": "",
            "data": {
                "72048cb3-adbc-11e6-9ccf-14109fd34195": "PROVISIONAL"
            },
        }

        provisional_tile = Tile(json)
        request = HttpRequest()
        request.user = self.user
        provisional_tile.save(index=False, request=request)

        self.assertEqual(provisional_tile.is_provisional(), True)
Beispiel #8
0
    def test_simple_get(self):
        """
        Test that we can get a Tile object

        """

        json = {
            "tiles": {},
            "resourceinstance_id": "40000000-0000-0000-0000-000000000000",
            "parenttile_id": '',
            "nodegroup_id": "20000000-0000-0000-0000-000000000001",
            "tileid": "",
            "data": {
                "20000000-0000-0000-0000-000000000004": "TEST 1"
            }
        }

        t = Tile(json)
        t.save()

        t2 = Tile.get(tileid=t.tileid)

        self.assertEqual(t.tileid, t2.tileid)
        self.assertEqual(t2.data["20000000-0000-0000-0000-000000000004"],
                         "TEST 1")
Beispiel #9
0
    def test_apply_provisional_edit(self):
        """
        Tests that provisional edit data is properly created

        """

        json = {
            "resourceinstance_id": "40000000-0000-0000-0000-000000000000",
            "parenttile_id": '',
            "nodegroup_id": "72048cb3-adbc-11e6-9ccf-14109fd34195",
            "tileid": "",
            "data": {
                "72048cb3-adbc-11e6-9ccf-14109fd34195": "TEST 1"
            }
        }

        user = User.objects.create_user(username='******',
                                        password='******')
        provisional_tile = Tile(json)
        request = HttpRequest()
        request.user = user
        provisional_tile.save(index=False, request=request)
        provisional_tile.apply_provisional_edit(user, {"test": "test"},
                                                'update')
        provisionaledits = JSONDeserializer().deserialize(
            provisional_tile.provisionaledits)
        userid = str(user.id)
        self.assertEqual(provisionaledits[userid]['action'], 'update')
        self.assertEqual(provisionaledits[userid]['reviewer'], None)
        self.assertEqual(provisionaledits[userid]['value'], {"test": "test"})
        self.assertEqual(provisionaledits[userid]['status'], "review")
        self.assertEqual(provisionaledits[userid]['reviewtimestamp'], None)
Beispiel #10
0
    def test_tile_deletion(self):
        """
        Tests that a tile is deleted when a user is a reviewer or owner.

        """

        json = {
            "resourceinstance_id": "40000000-0000-0000-0000-000000000000",
            "parenttile_id": '',
            "nodegroup_id": "72048cb3-adbc-11e6-9ccf-14109fd34195",
            "tileid": "",
            "data": {
                "72048cb3-adbc-11e6-9ccf-14109fd34195": "TEST 1"
            }
        }

        owner = User.objects.create_user(username='******',
                                         password='******')
        reviewer = User.objects.get(username='******')

        tile1 = Tile(json)
        owner_request = HttpRequest()
        owner_request.user = owner
        tile1.save(index=False, request=owner_request)
        tile1.delete(request=owner_request)

        tile2 = Tile(json)
        reviewer_request = HttpRequest()
        reviewer_request.user = reviewer
        tile2.save(index=False, request=reviewer_request)
        tile2.delete(request=reviewer_request)

        self.assertEqual(len(Tile.objects.all()), 0)
Beispiel #11
0
    def test_save(self):
        """
        Test that we can save a Tile object back to the database

        """
        login = self.client.login(username='******', password='******')

        json = {
            "tiles": {
                "72048cb3-adbc-11e6-9ccf-14109fd34195": [{
                    "tiles": {},
                    "resourceinstance_id": "40000000-0000-0000-0000-000000000000",
                    "parenttile_id": '',
                    "nodegroup_id": "72048cb3-adbc-11e6-9ccf-14109fd34195",
                    "tileid": "",
                    "data": {
                      "72048cb3-adbc-11e6-9ccf-14109fd34195": "TEST 1"
                    }
                }]
            },
            "resourceinstance_id": "40000000-0000-0000-0000-000000000000",
            "parenttile_id": '',
            "nodegroup_id": "7204869c-adbc-11e6-8bec-14109fd34195",
            "tileid": "",
            "data": {}
        }

        t = Tile(json)
        t.save(index=False)

        tiles = Tile.objects.filter(resourceinstance_id="40000000-0000-0000-0000-000000000000")

        self.assertEqual(tiles.count(), 2)
Beispiel #12
0
    def test_provisional_deletion(self):
        """
        Tests that a tile is NOT deleted if a user does not have the
        privlages to delete a tile and that the proper provisionaledit is
        applied.

        """

        json = {
            "resourceinstance_id": "40000000-0000-0000-0000-000000000000",
            "parenttile_id": '',
            "nodegroup_id": "72048cb3-adbc-11e6-9ccf-14109fd34195",
            "tileid": "",
            "data": {
                "72048cb3-adbc-11e6-9ccf-14109fd34195": "TEST 1"
            }
        }

        provisional_user = User.objects.create_user(
            username='******', password='******')
        reviewer = User.objects.get(username='******')

        tile = Tile(json)
        reviewer_request = HttpRequest()
        reviewer_request.user = reviewer
        tile.save(index=False, request=reviewer_request)

        provisional_request = HttpRequest()
        provisional_request.user = provisional_user
        tile.delete(request=provisional_request)

        self.assertEqual(len(Tile.objects.all()), 1)
Beispiel #13
0
    def test_save_provisional_from_athoritative(self):
        """
        Test that a provisional edit is created when a user that is not a
        reviewer edits an athoritative tile

        """

        json = {
            "tiles": [{
                "tiles": [],
                "resourceinstance_id": "40000000-0000-0000-0000-000000000000",
                "parenttile_id": '',
                "nodegroup_id": "72048cb3-adbc-11e6-9ccf-14109fd34195",
                "tileid": "",
                "data": {
                    "72048cb3-adbc-11e6-9ccf-14109fd34195": "AUTHORITATIVE"
                }
            }],
            "resourceinstance_id":
            "40000000-0000-0000-0000-000000000000",
            "parenttile_id":
            '',
            "nodegroup_id":
            "7204869c-adbc-11e6-8bec-14109fd34195",
            "tileid":
            "",
            "data": {}
        }

        t = Tile(json)
        t.save(index=False)
        self.user = User.objects.create_user(username='******',
                                             password='******')
        login = self.client.login(username='******',
                                  password='******')
        tiles = Tile.objects.filter(
            resourceinstance_id="40000000-0000-0000-0000-000000000000")

        provisional_tile = None
        for tile in tiles:
            provisional_tile = tile
            provisional_tile.data[
                "72048cb3-adbc-11e6-9ccf-14109fd34195"] = 'PROVISIONAL'
        request = HttpRequest()
        request.user = self.user
        provisional_tile.save(index=False, request=request)
        tiles = Tile.objects.filter(
            resourceinstance_id="40000000-0000-0000-0000-000000000000")

        provisionaledits = provisional_tile.provisionaledits
        self.assertEqual(tiles.count(), 2)
        self.assertEqual(
            provisional_tile.data["72048cb3-adbc-11e6-9ccf-14109fd34195"],
            'AUTHORITATIVE')
        self.assertEqual(provisionaledits[str(self.user.id)]['action'],
                         'update')
        self.assertEqual(provisionaledits[str(self.user.id)]['status'],
                         'review')
Beispiel #14
0
    def post(self, request):
        if self.action == 'update_tile':
            json = request.POST.get('data', None)
            if json != None:
                data = JSONDeserializer().deserialize(json)
                tile_id = data['tileid']
                if tile_id != None and tile_id != '':
                    old_tile = Tile.objects.get(pk=tile_id)
                    clean_resource_cache(old_tile)
                tile = Tile(data)
                if tile.filter_by_perm(request.user, 'write_nodegroup'):
                    with transaction.atomic():
                        try:
                            tile.save(request=request)
                        except ValidationError as e:
                            return JSONResponse(
                                {
                                    'status': 'false',
                                    'message': e.args
                                },
                                status=500)
                        tile.after_update_all()
                        clean_resource_cache(tile)
                        update_system_settings_cache(tile)
                    return JSONResponse(tile)
                else:
                    return JSONResponse(
                        {
                            'status':
                            'false',
                            'message':
                            [_('Request Failed'),
                             _('Permission Denied')]
                        },
                        status=500)

        if self.action == 'reorder_tiles':
            json = request.body
            if json != None:
                data = JSONDeserializer().deserialize(json)

                if 'tiles' in data and len(data['tiles']) > 0:
                    sortorder = 0
                    with transaction.atomic():
                        for tile in data['tiles']:
                            t = Tile(tile)
                            if t.filter_by_perm(request.user,
                                                'write_nodegroup'):
                                t.sortorder = sortorder
                                t.save(update_fields=['sortorder'],
                                       request=request)
                                sortorder = sortorder + 1

                    return JSONResponse(data)

        return HttpResponseNotFound()
Beispiel #15
0
    def test_save(self):
        """
        Test that we can save a Tile object back to the database

        """

        json = {
            "tiles": {
                "19999999-0000-0000-0000-000000000000": [{
                    "tiles": {},
                    "resourceinstance_id":
                    "40000000-0000-0000-0000-000000000000",
                    "parenttile_id":
                    '',
                    "nodegroup_id":
                    "19999999-0000-0000-0000-000000000000",
                    "tileid":
                    "",
                    "data": {
                        "20000000-0000-0000-0000-000000000004": "TEST 1",
                        "20000000-0000-0000-0000-000000000002": "TEST 2",
                        "20000000-0000-0000-0000-000000000003": "TEST 3"
                    }
                }],
                "32999999-0000-0000-0000-000000000000": [{
                    "tiles": {},
                    "resourceinstance_id":
                    "40000000-0000-0000-0000-000000000000",
                    "parenttile_id":
                    '',
                    "nodegroup_id":
                    "32999999-0000-0000-0000-000000000000",
                    "tileid":
                    "",
                    "data": {
                        "20000000-0000-0000-0000-000000000004": "TEST 4",
                        "20000000-0000-0000-0000-000000000002": "TEST 5",
                    }
                }]
            },
            "resourceinstance_id": "40000000-0000-0000-0000-000000000000",
            "parenttile_id": '',
            "nodegroup_id": "20000000-0000-0000-0000-000000000001",
            "tileid": "",
            "data": {}
        }

        t = Tile(json)
        t.save()

        tiles = models.Tile.objects.filter(
            resourceinstance_id="40000000-0000-0000-0000-000000000000")
        self.assertEqual(tiles.count(), 3)
Beispiel #16
0
 def push_edits_to_db(self):
     # read all docs that have changes
     # save back to postgres db
     db = self.couch.create_db('project_' + str(self.id))
     ret = []
     for row in db.view('_all_docs', include_docs=True):
         ret.append(row)
         if 'tileid' in row.doc:
             tile = Tile(row.doc)
             #if tile.filter_by_perm(request.user, 'write_nodegroup'):
             with transaction.atomic():
                 tile.save()
             #tile = models.TileModel.objects.get(pk=row.doc.tileid).update(**row.doc)
     return ret
Beispiel #17
0
 def push_edits_to_db(self):
     # read all docs that have changes
     # save back to postgres db
     db = self.couch['project_' + str(self.id)]
     ret = []
     for row in db.view('_all_docs', include_docs=True):
         ret.append(row)
         if 'tileid' in row.doc:
             tile = Tile(row.doc)
             #if tile.filter_by_perm(request.user, 'write_nodegroup'):
             with transaction.atomic():
                 tile.save()
             #tile = models.TileModel.objects.get(pk=row.doc.tileid).update(**row.doc)
     return ret
Beispiel #18
0
    def test_save_provisional_from_athoritative(self):
        """
        Test that a provisional edit is created when a user that is not a
        reviewer edits an athoritative tile

        """

        json = {
            "tiles": {
                "72048cb3-adbc-11e6-9ccf-14109fd34195": [{
                    "tiles": {},
                    "resourceinstance_id": "40000000-0000-0000-0000-000000000000",
                    "parenttile_id": '',
                    "nodegroup_id": "72048cb3-adbc-11e6-9ccf-14109fd34195",
                    "tileid": "",
                    "data": {
                      "72048cb3-adbc-11e6-9ccf-14109fd34195": "AUTHORITATIVE"
                    }
                }]
            },
            "resourceinstance_id": "40000000-0000-0000-0000-000000000000",
            "parenttile_id": '',
            "nodegroup_id": "7204869c-adbc-11e6-8bec-14109fd34195",
            "tileid": "",
            "data": {}
        }

        t = Tile(json)
        t.save(index=False)
        self.user = User.objects.create_user(username='******', password='******')
        login = self.client.login(username='******', password='******')
        tiles = Tile.objects.filter(resourceinstance_id="40000000-0000-0000-0000-000000000000")

        provisional_tile = None
        for tile in tiles:
            if "72048cb3-adbc-11e6-9ccf-14109fd34195" in tile.data:
                provisional_tile = tile
                provisional_tile.data["72048cb3-adbc-11e6-9ccf-14109fd34195"] = 'PROVISIONAL'
        request = HttpRequest()
        request.user = self.user
        provisional_tile.save(index=False, request=request)
        tiles = Tile.objects.filter(resourceinstance_id="40000000-0000-0000-0000-000000000000")

        provisionaledits = JSONDeserializer().deserialize(provisional_tile.provisionaledits)
        self.assertEqual(tiles.count(), 2)
        self.assertEqual(provisional_tile.data["72048cb3-adbc-11e6-9ccf-14109fd34195"], 'AUTHORITATIVE')
        self.assertEqual(provisionaledits[str(self.user.id)]['action'], 'update')
        self.assertEqual(provisionaledits[str(self.user.id)]['status'], 'review')
    def test_save(self):
        """
        Test that we can save a Tile object back to the database

        """

        json = {
            "tiles": {
                "19999999-0000-0000-0000-000000000000": [{
                    "tiles": {},
                    "resourceinstance_id": "40000000-0000-0000-0000-000000000000",
                    "parenttile_id": '',
                    "nodegroup_id": "19999999-0000-0000-0000-000000000000",
                    "tileid": "",
                    "data": {
                      "20000000-0000-0000-0000-000000000004": "TEST 1",
                      "20000000-0000-0000-0000-000000000002": "TEST 2",
                      "20000000-0000-0000-0000-000000000003": "TEST 3"
                    }
                }],
                "32999999-0000-0000-0000-000000000000": [{
                    "tiles": {},
                    "resourceinstance_id": "40000000-0000-0000-0000-000000000000",
                    "parenttile_id": '',
                    "nodegroup_id": "32999999-0000-0000-0000-000000000000",
                    "tileid": "",
                    "data": {
                      "20000000-0000-0000-0000-000000000004": "TEST 4",
                      "20000000-0000-0000-0000-000000000002": "TEST 5",
                    }
                }]
            },
            "resourceinstance_id": "40000000-0000-0000-0000-000000000000",
            "parenttile_id": '',
            "nodegroup_id": "20000000-0000-0000-0000-000000000001",
            "tileid": "",
            "data": {}
        }

        t = Tile(json)
        t.save()

        tiles = models.Tile.objects.filter(resourceinstance_id="40000000-0000-0000-0000-000000000000")
        self.assertEqual(tiles.count(), 3)
Beispiel #20
0
    def test_create_new_provisional(self):
        """
        Test that a new provisional tile is created when a user IS NOT a reviwer
        and that an authoritative tile is created when a user IS a reviwer.

        """

        self.user = User.objects.get(username='******')

        json = {
            "resourceinstance_id": "40000000-0000-0000-0000-000000000000",
            "parenttile_id": '',
            "nodegroup_id": "72048cb3-adbc-11e6-9ccf-14109fd34195",
            "tileid": "",
            "data": {
                "72048cb3-adbc-11e6-9ccf-14109fd34195": "AUTHORITATIVE"
            }
        }

        authoritative_tile = Tile(json)
        request = HttpRequest()
        request.user = self.user
        authoritative_tile.save(index=False, request=request)

        self.user = User.objects.create_user(username='******',
                                             password='******')

        json = {
            "resourceinstance_id": "40000000-0000-0000-0000-000000000000",
            "parenttile_id": '',
            "nodegroup_id": "72048cb3-adbc-11e6-9ccf-14109fd34195",
            "tileid": "",
            "data": {
                "72048cb3-adbc-11e6-9ccf-14109fd34195": "PROVISIONAL"
            }
        }

        provisional_tile = Tile(json)
        request = HttpRequest()
        request.user = self.user
        provisional_tile.save(index=False, request=request)

        self.assertEqual(provisional_tile.is_provisional(), True)
        self.assertEqual(authoritative_tile.is_provisional(), False)
Beispiel #21
0
    def test_create_new_provisional(self):
        """
        Test that a new provisional tile is created when a user IS NOT a reviwer
        and that an authoritative tile is created when a user IS a reviwer.

        """

        self.user = User.objects.get(username='******')

        json = {
            "resourceinstance_id": "40000000-0000-0000-0000-000000000000",
            "parenttile_id": '',
            "nodegroup_id": "72048cb3-adbc-11e6-9ccf-14109fd34195",
            "tileid": "",
            "data": {
              "72048cb3-adbc-11e6-9ccf-14109fd34195": "AUTHORITATIVE"
            }
        }

        authoritative_tile = Tile(json)
        request = HttpRequest()
        request.user = self.user
        authoritative_tile.save(index=False, request=request)

        self.user = User.objects.create_user(username='******', password='******')

        json = {
            "resourceinstance_id": "40000000-0000-0000-0000-000000000000",
            "parenttile_id": '',
            "nodegroup_id": "72048cb3-adbc-11e6-9ccf-14109fd34195",
            "tileid": "",
            "data": {
              "72048cb3-adbc-11e6-9ccf-14109fd34195": "PROVISIONAL"
            }
        }

        provisional_tile = Tile(json)
        request = HttpRequest()
        request.user = self.user
        provisional_tile.save(index=False, request=request)

        self.assertEqual(provisional_tile.is_provisional(), True)
        self.assertEqual(authoritative_tile.is_provisional(), False)
Beispiel #22
0
    def post(self, request):
        if self.action == 'update_tile':
            json = request.POST.get('data', None)
            if json != None:
                data = JSONDeserializer().deserialize(json)
                tile_id = data['tileid']
                if tile_id != None and tile_id != '':
                    old_tile = Tile.objects.get(pk=tile_id)
                    clean_resource_cache(old_tile)
                tile = Tile(data)
                if tile.filter_by_perm(request.user, 'write_nodegroup'):
                    with transaction.atomic():
                        try:
                            tile.save(request=request)
                        except ValidationError as e:
                            return JSONResponse({'status':'false','message':e.args}, status=500)
                        tile.after_update_all()
                        clean_resource_cache(tile)
                        update_system_settings_cache(tile)
                    return JSONResponse(tile)
                else:
                    return JSONResponse({'status':'false','message': [_('Request Failed'), _('Permission Denied')]}, status=500)

        if self.action == 'reorder_tiles':
            json = request.body
            if json != None:
                data = JSONDeserializer().deserialize(json)

                if 'tiles' in data and len(data['tiles']) > 0:
                    sortorder = 0
                    with transaction.atomic():
                        for tile in data['tiles']:
                            t = Tile(tile)
                            if t.filter_by_perm(request.user, 'write_nodegroup'):
                                t.sortorder = sortorder
                                t.save(update_fields=['sortorder'], request=request)
                                sortorder = sortorder + 1

                    return JSONResponse(data)

        return HttpResponseNotFound()
Beispiel #23
0
    def test_simple_get(self):
        """
        Test that we can get a Tile object

        """

        json = {
            "resourceinstance_id": "40000000-0000-0000-0000-000000000000",
            "parenttile_id": '',
            "nodegroup_id": "72048cb3-adbc-11e6-9ccf-14109fd34195",
            "tileid": "",
            "data": {
              "72048cb3-adbc-11e6-9ccf-14109fd34195": "TEST 1"
            }
        }

        t = Tile(json)
        t.save(index=False)

        t2 = Tile.objects.get(tileid=t.tileid)

        self.assertEqual(t.tileid, t2.tileid)
        self.assertEqual(t2.data["72048cb3-adbc-11e6-9ccf-14109fd34195"], "TEST 1")
Beispiel #24
0
    def test_user_owns_provisional(self):
        """
        Tests that a user is the owner of a provisional edit

        """

        json = {
            "resourceinstance_id": "40000000-0000-0000-0000-000000000000",
            "parenttile_id": '',
            "nodegroup_id": "72048cb3-adbc-11e6-9ccf-14109fd34195",
            "tileid": "",
            "data": {
              "72048cb3-adbc-11e6-9ccf-14109fd34195": "TEST 1"
            }
        }

        user = User.objects.create_user(username='******', password='******')
        provisional_tile = Tile(json)
        request = HttpRequest()
        request.user = user
        provisional_tile.save(index=False, request=request)

        self.assertEqual(provisional_tile.user_owns_provisional(user), True)
Beispiel #25
0
    def test_user_owns_provisional(self):
        """
        Tests that a user is the owner of a provisional edit

        """

        json = {
            "resourceinstance_id": "40000000-0000-0000-0000-000000000000",
            "parenttile_id": '',
            "nodegroup_id": "72048cb3-adbc-11e6-9ccf-14109fd34195",
            "tileid": "",
            "data": {
              "72048cb3-adbc-11e6-9ccf-14109fd34195": "TEST 1"
            }
        }

        user = User.objects.create_user(username='******', password='******')
        provisional_tile = Tile(json)
        request = HttpRequest()
        request.user = user
        provisional_tile.save(index=False, request=request)

        self.assertEqual(provisional_tile.user_owns_provisional(user), True)
Beispiel #26
0
    def test_simple_get(self):
        """
        Test that we can get a Tile object

        """

        json = {
            "resourceinstance_id": "40000000-0000-0000-0000-000000000000",
            "parenttile_id": '',
            "nodegroup_id": "72048cb3-adbc-11e6-9ccf-14109fd34195",
            "tileid": "",
            "data": {
              "72048cb3-adbc-11e6-9ccf-14109fd34195": "TEST 1"
            }
        }

        t = Tile(json)
        t.save(index=False)

        t2 = Tile.objects.get(tileid=t.tileid)

        self.assertEqual(t.tileid, t2.tileid)
        self.assertEqual(t2.data["72048cb3-adbc-11e6-9ccf-14109fd34195"], "TEST 1")
Beispiel #27
0
    def post(self, request):
        if self.action == 'update_tile':
            json = request.POST.get('data', None)
            if json != None:
                data = JSONDeserializer().deserialize(json)
                tile = Tile(data)
                with transaction.atomic():
                    try:
                        tile.save(request=request)
                    except ValidationError as e:
                        return JSONResponse(
                            {
                                'status': 'false',
                                'message': e.args
                            }, status=500)

                return JSONResponse(tile)

        if self.action == 'reorder_tiles':
            json = request.body
            if json != None:
                data = JSONDeserializer().deserialize(json)

                if 'tiles' in data and len(data['tiles']) > 0:
                    sortorder = 0
                    with transaction.atomic():
                        for tile in data['tiles']:
                            t = Tile(tile)
                            t.sortorder = sortorder
                            t.save(update_fields=['sortorder'],
                                   request=request)
                            sortorder = sortorder + 1

                    return JSONResponse(data)

        return HttpResponseNotFound()
    def test_simple_get(self):
        """
        Test that we can get a Tile object

        """

        json = {
            "tiles": {},
            "resourceinstance_id": "40000000-0000-0000-0000-000000000000",
            "parenttile_id": '',
            "nodegroup_id": "20000000-0000-0000-0000-000000000001",
            "tileid": "",
            "data": {
              "20000000-0000-0000-0000-000000000004": "TEST 1"
            }
        }

        t = Tile(json)
        t.save()

        t2 = Tile.get(tileid=t.tileid)

        self.assertEqual(t.tileid, t2.tileid)
        self.assertEqual(t2.data["20000000-0000-0000-0000-000000000004"], "TEST 1")
Beispiel #29
0
    def test_create_new_authoritative(self):
        """
        Test that a new authoritative tile is created when a user IS a reviwer.

        """

        self.user = User.objects.get(username="******")

        json = {
            "resourceinstance_id": "40000000-0000-0000-0000-000000000000",
            "parenttile_id": "",
            "nodegroup_id": "72048cb3-adbc-11e6-9ccf-14109fd34195",
            "tileid": "",
            "data": {
                "72048cb3-adbc-11e6-9ccf-14109fd34195": "AUTHORITATIVE"
            },
        }

        authoritative_tile = Tile(json)
        request = HttpRequest()
        request.user = self.user
        authoritative_tile.save(index=False, request=request)

        self.assertEqual(authoritative_tile.is_provisional(), False)
Beispiel #30
0
    def post(self, request):
        if self.action == 'update_tile':
            json = request.POST.get('data', None)
            accepted_provisional = request.POST.get('accepted_provisional',
                                                    None)
            if accepted_provisional != None:
                accepted_provisional_edit = JSONDeserializer().deserialize(
                    accepted_provisional)
            if json != None:
                data = JSONDeserializer().deserialize(json)
                if data['resourceinstance_id'] == '':
                    data['resourceinstance_id'] = uuid.uuid4()
                try:
                    models.ResourceInstance.objects.get(
                        pk=data['resourceinstance_id'])
                except ObjectDoesNotExist:
                    resource = Resource()
                    graphid = models.Node.objects.filter(
                        nodegroup=data['nodegroup_id'])[0].graph_id
                    resource.graph_id = graphid
                    resource.save(user=request.user)
                    data['resourceinstance_id'] = resource.pk
                    resource.index()
                tile_id = data['tileid']
                if tile_id != None and tile_id != '':
                    old_tile = Tile.objects.get(pk=tile_id)
                    clean_resource_cache(old_tile)
                tile = Tile(data)
                if tile.filter_by_perm(request.user, 'write_nodegroup'):
                    with transaction.atomic():
                        try:
                            if accepted_provisional == None:
                                tile.save(request=request)
                            else:
                                if accepted_provisional is not None:
                                    provisional_editor = User.objects.get(
                                        pk=accepted_provisional_edit["user"])
                                tile.save(
                                    provisional_edit_log_details={
                                        "user": request.user,
                                        "action": "accept edit",
                                        "edit": accepted_provisional_edit,
                                        "provisional_editor":
                                        provisional_editor
                                    })
                            if tile_id == '4345f530-aa90-48cf-b4b3-92d1185ca439':
                                import couchdb
                                import json as json_json
                                couch = couchdb.Server(settings.COUCHDB_URL)
                                for project in models.MobileSurveyModel.objects.all(
                                ):
                                    db = couch['project_' + str(project.id)]
                                    #tile = models.TileModel.objects.get(pk='4345f530-aa90-48cf-b4b3-92d1185ca439')
                                    tile_json = json_json.loads(
                                        JSONSerializer().serialize(tile))
                                    tile_json['_id'] = tile_json['tileid']
                                    for row in db.view('_all_docs',
                                                       include_docs=True):
                                        if 'tileid' in row.doc and tile_json[
                                                '_id'] == row.doc['_id']:
                                            tile_json['_rev'] = row.doc['_rev']
                                            db.save(tile_json)

                            if tile.provisionaledits is not None and str(
                                    request.user.id) in tile.provisionaledits:
                                tile.data = tile.provisionaledits[str(
                                    request.user.id)]['value']

                        except ValidationError as e:
                            return JSONResponse(
                                {
                                    'status': 'false',
                                    'message': e.args
                                },
                                status=500)
                        tile.after_update_all()
                        clean_resource_cache(tile)
                        update_system_settings_cache(tile)

                    return JSONResponse(tile)
                else:
                    return JSONResponse(
                        {
                            'status':
                            'false',
                            'message':
                            [_('Request Failed'),
                             _('Permission Denied')]
                        },
                        status=500)

        if self.action == 'reorder_tiles':
            json = request.body
            if json != None:
                data = JSONDeserializer().deserialize(json)

                if 'tiles' in data and len(data['tiles']) > 0:
                    sortorder = 0
                    with transaction.atomic():
                        for tile in data['tiles']:
                            t = Tile(tile)
                            if t.filter_by_perm(request.user,
                                                'write_nodegroup'):
                                t.sortorder = sortorder
                                t.save(update_fields=['sortorder'],
                                       request=request)
                                sortorder = sortorder + 1

                    return JSONResponse(data)

        if self.action == 'delete_provisional_tile':
            user = request.POST.get('user', None)
            tileid = request.POST.get('tileid', None)
            users = request.POST.get('users', None)
            tile = Tile.objects.get(tileid=tileid)
            is_provisional = tile.is_provisional()

            if tileid is not None and user is not None:
                provisionaledits = self.delete_provisional_edit(
                    tile, user, reviewer=request.user)

            elif tileid is not None and users is not None:
                users = jsonparser.loads(users)
                for user in users:
                    self.delete_provisional_edit(tile,
                                                 user,
                                                 reviewer=request.user)

            if is_provisional == True:
                return JSONResponse({'result': 'delete'})
            else:
                return JSONResponse({'result': 'success'})

        return HttpResponseNotFound()
Beispiel #31
0
    def post(self, request):
        if self.action == 'update_tile':
            json = request.POST.get('data', None)
            accepted_provisional = request.POST.get('accepted_provisional',
                                                    None)
            if accepted_provisional is not None:
                accepted_provisional_edit = JSONDeserializer().deserialize(
                    accepted_provisional)
            if json is not None:
                data = JSONDeserializer().deserialize(json)
                data[
                    'resourceinstance_id'] = '' if 'resourceinstance_id' not in data else data[
                        'resourceinstance_id']
                if data['resourceinstance_id'] == '':
                    data['resourceinstance_id'] = uuid.uuid4()
                try:
                    models.ResourceInstance.objects.get(
                        pk=data['resourceinstance_id'])
                except ObjectDoesNotExist:
                    resource = Resource()
                    graphid = models.Node.objects.filter(
                        nodegroup=data['nodegroup_id'])[0].graph_id
                    resource.graph_id = graphid
                    try:
                        resource.save(user=request.user)
                        data['resourceinstance_id'] = resource.pk
                        resource.index()
                    except ModelInactiveError as e:
                        message = _(
                            'Unable to save. Please verify the model status is active'
                        )
                        return JSONResponse(
                            {
                                'status': 'false',
                                'message': [_(e.title),
                                            _(str(message))]
                            },
                            status=500)
                tile_id = data['tileid']
                resource_instance = models.ResourceInstance.objects.get(
                    pk=data['resourceinstance_id'])
                is_active = resource_instance.graph.isactive
                if tile_id is not None and tile_id != '':
                    try:
                        old_tile = Tile.objects.get(pk=tile_id)
                        clean_resource_cache(old_tile)
                    except ObjectDoesNotExist as e:
                        return self.handle_save_error(
                            e, _('This tile is no longer available'),
                            _('It was likely deleted by another user'))

                tile = Tile(data)

                if tile.filter_by_perm(
                        request.user, 'write_nodegroup') and is_active is True:
                    try:
                        with transaction.atomic():
                            try:
                                if accepted_provisional is None:
                                    try:
                                        tile.save(request=request)
                                    except TileValidationError as e:
                                        resource_tiles = models.TileModel.objects.filter(
                                            resourceinstance=tile.
                                            resourceinstance)
                                        if resource_tiles.count() == 0:
                                            Resource.objects.get(
                                                pk=tile.resourceinstance_id
                                            ).delete(request.user)
                                        title = _(
                                            'Unable to save. Please verify your input is valid'
                                        )
                                        return self.handle_save_error(
                                            e, tile_id, title=title)
                                    except ModelInactiveError as e:
                                        message = _(
                                            'Unable to save. Please verify the model status is active'
                                        )
                                        return JSONResponse(
                                            {
                                                'status':
                                                'false',
                                                'message':
                                                [_(e.title),
                                                 _(str(message))]
                                            },
                                            status=500)
                                else:
                                    if accepted_provisional is not None:
                                        provisional_editor = User.objects.get(
                                            pk=accepted_provisional_edit[
                                                "user"])
                                        prov_edit_log_details = {
                                            "user":
                                            request.user,
                                            "action":
                                            "accept edit",
                                            "edit":
                                            accepted_provisional_edit,
                                            "provisional_editor":
                                            provisional_editor
                                        }
                                    tile.save(request=request,
                                              provisional_edit_log_details=
                                              prov_edit_log_details)

                                if tile.provisionaledits is not None and str(
                                        request.user.id
                                ) in tile.provisionaledits:
                                    tile.data = tile.provisionaledits[str(
                                        request.user.id)]['value']

                            except Exception as e:
                                return self.handle_save_error(e, tile_id)

                            tile.after_update_all()
                            clean_resource_cache(tile)
                            update_system_settings_cache(tile)

                    except Exception as e:
                        return self.handle_save_error(e, tile_id)

                    return JSONResponse(tile)
                elif is_active is False:
                    response = {
                        'status':
                        'false',
                        'message': [
                            _('Request Failed'),
                            _('Unable to Save. Verify model status is active')
                        ]
                    }
                    return JSONResponse(response, status=500)
                else:
                    response = {
                        'status': 'false',
                        'message':
                        [_('Request Failed'),
                         _('Permission Denied')]
                    }
                    return JSONResponse(response, status=500)

        if self.action == 'reorder_tiles':
            json = request.body
            if json is not None:
                data = JSONDeserializer().deserialize(json)

                if 'tiles' in data and len(data['tiles']) > 0:
                    sortorder = 0
                    with transaction.atomic():
                        for tile in data['tiles']:
                            t = Tile(tile)
                            if t.filter_by_perm(request.user,
                                                'write_nodegroup'):
                                t.sortorder = sortorder
                                t.save(update_fields=['sortorder'],
                                       request=request)
                                sortorder = sortorder + 1

                    return JSONResponse(data)

        if self.action == 'delete_provisional_tile':
            user = request.POST.get('user', None)
            tileid = request.POST.get('tileid', None)
            users = request.POST.get('users', None)
            tile = Tile.objects.get(tileid=tileid)
            is_provisional = tile.is_provisional()

            if tileid is not None and user is not None:
                provisionaledits = self.delete_provisional_edit(
                    tile, user, request)

            elif tileid is not None and users is not None:
                users = jsonparser.loads(users)
                for user in users:
                    self.delete_provisional_edit(tile, user, request)

            if is_provisional == True:
                return JSONResponse({'result': 'delete'})
            else:
                return JSONResponse({'result': 'success'})

        return HttpResponseNotFound()
Beispiel #32
0
    def post(self, request):
        if self.action == 'update_tile':
            json = request.POST.get('data', None)
            if json != None:
                data = JSONDeserializer().deserialize(json)
                try:
                    models.ResourceInstance.objects.get(pk=data['resourceinstance_id'])
                except ObjectDoesNotExist:
                    resource = Resource()
                    resource.resourceinstanceid = data['resourceinstance_id']
                    graphid = models.Node.objects.filter(nodegroup=data['nodegroup_id'])[0].graph_id
                    resource.graph_id = graphid
                    resource.save(user=request.user)
                    resource.index()
                tile_id = data['tileid']
                if tile_id != None and tile_id != '':
                    old_tile = Tile.objects.get(pk=tile_id)
                    clean_resource_cache(old_tile)
                tile = Tile(data)
                if tile.filter_by_perm(request.user, 'write_nodegroup'):
                    with transaction.atomic():
                        try:
                            tile.save(request=request)
                            if tile_id == '4345f530-aa90-48cf-b4b3-92d1185ca439':
                                import couchdb
                                import json as json_json
                                couch = couchdb.Server(settings.COUCHDB_URL)
                                for project in models.MobileSurveyModel.objects.all():
                                    db = couch['project_' + str(project.id)]
                                    #tile = models.TileModel.objects.get(pk='4345f530-aa90-48cf-b4b3-92d1185ca439')
                                    tile_json = json_json.loads(JSONSerializer().serialize(tile))
                                    tile_json['_id'] = tile_json['tileid']
                                    for row in db.view('_all_docs', include_docs=True):
                                        if 'tileid' in row.doc and tile_json['_id'] == row.doc['_id']:
                                            tile_json['_rev'] = row.doc['_rev']
                                            db.save(tile_json)

                        except ValidationError as e:
                            return JSONResponse({'status':'false','message':e.args}, status=500)
                        tile.after_update_all()
                        clean_resource_cache(tile)
                        update_system_settings_cache(tile)
                    return JSONResponse(tile)
                else:
                    return JSONResponse({'status':'false','message': [_('Request Failed'), _('Permission Denied')]}, status=500)

        if self.action == 'reorder_tiles':
            json = request.body
            if json != None:
                data = JSONDeserializer().deserialize(json)

                if 'tiles' in data and len(data['tiles']) > 0:
                    sortorder = 0
                    with transaction.atomic():
                        for tile in data['tiles']:
                            t = Tile(tile)
                            if t.filter_by_perm(request.user, 'write_nodegroup'):
                                t.sortorder = sortorder
                                t.save(update_fields=['sortorder'], request=request)
                                sortorder = sortorder + 1

                    return JSONResponse(data)

        if self.action == 'delete_provisional_tile':
            data = request.POST
            if 'tileid' in data:
                provisionaledits = self.delete_provisional_edit(data, request)
                return JSONResponse(provisionaledits)

            else:
                payload = data.get('payload', None)
                if payload is not None:
                    edits = jsonparser.loads(payload)
                    for edit in edits['edits']:
                        provisionaledits = self.delete_provisional_edit(edit, request)
                return JSONResponse({'result':'success'})

        return HttpResponseNotFound()
Beispiel #33
0
    def push_edits_to_db(self, synclog=None):
        # read all docs that have changes
        # save back to postgres db
        db = self.couch.create_db('project_' + str(self.id))
        user_lookup = {}
        is_reviewer = False
        with transaction.atomic():
            couch_docs = self.couch.all_docs(db)
            for row in couch_docs:
                if row.doc['type'] == 'resource':
                    if self.check_if_revision_exists(row.doc) is False:
                        if 'provisional_resource' in row.doc and row.doc[
                                'provisional_resource'] == 'true':
                            resourceinstance, created = ResourceInstance.objects.update_or_create(
                                resourceinstanceid=uuid.UUID(
                                    str(row.doc['resourceinstanceid'])),
                                defaults={
                                    'graph_id':
                                    uuid.UUID(str(row.doc['graph_id']))
                                })
                            if created is True:
                                self.save_revision_log(row.doc, synclog,
                                                       'create')
                            else:
                                self.save_revision_log(row.doc, synclog,
                                                       'update')

                            print('Resource {0} Saved'.format(
                                row.doc['resourceinstanceid']))
                    else:
                        print('{0}: already saved'.format(row.doc['_rev']))

            for row in couch_docs:
                if row.doc['type'] == 'tile' and \
                        ResourceInstance.objects.filter(pk=row.doc['resourceinstance_id']).exists():
                    if self.check_if_revision_exists(row.doc) is False:
                        if 'provisionaledits' in row.doc and row.doc[
                                'provisionaledits'] is not None:
                            action = 'update'
                            try:
                                tile = Tile.objects.get(
                                    tileid=row.doc['tileid'])
                                if row.doc['provisionaledits'] != '':
                                    for user_edits in row.doc[
                                            'provisionaledits'].items():
                                        # user_edits is a tuple with the user number in
                                        # position 0, prov. edit data in position 1
                                        for nodeid, value in iter(
                                                user_edits[1]
                                            ['value'].items()):
                                            datatype_factory = DataTypeFactory(
                                            )
                                            node = models.Node.objects.get(
                                                nodeid=nodeid)
                                            datatype = datatype_factory.get_instance(
                                                node.datatype)
                                            newvalue = datatype.process_mobile_data(
                                                tile, node, db, row.doc, value)
                                            if newvalue is not None:
                                                user_edits[1]['value'][
                                                    nodeid] = newvalue

                                        if tile.provisionaledits is None:
                                            tile.provisionaledits = {}
                                            tile.provisionaledits[
                                                user_edits[0]] = user_edits[1]
                                            self.handle_reviewer_edits(
                                                user_edits[0], tile)
                                        else:
                                            self.assign_provisional_edit(
                                                user_edits[0], user_edits[1],
                                                tile)

                                # If there are conflicting documents, lets clear those out
                                if '_conflicts' in row.doc:
                                    for conflict_rev in row.doc['_conflicts']:
                                        conflict_data = db.get(
                                            row.id, rev=conflict_rev)
                                        if conflict_data[
                                                'provisionaledits'] != '':
                                            for user_edits in conflict_data[
                                                    'provisionaledits'].items(
                                                    ):
                                                self.assign_provisional_edit(
                                                    user_edits[0],
                                                    user_edits[1], tile)
                                        # Remove conflicted revision from couch
                                        db.delete(conflict_data)

                            except Tile.DoesNotExist:
                                action = 'create'
                                tile = Tile(row.doc)
                                if row.doc['provisionaledits'] != '':
                                    for user_edits in row.doc[
                                            'provisionaledits'].items():
                                        for nodeid, value in iter(
                                                user_edits[1]
                                            ['value'].items()):
                                            datatype_factory = DataTypeFactory(
                                            )
                                            node = models.Node.objects.get(
                                                nodeid=nodeid)
                                            datatype = datatype_factory.get_instance(
                                                node.datatype)
                                            newvalue = datatype.process_mobile_data(
                                                tile, node, db, row.doc, value)
                                            if newvalue is not None:
                                                user_edits[1]['value'][
                                                    nodeid] = newvalue
                                        tile.provisionaledits[
                                            user_edits[0]] = user_edits[1]
                                        self.handle_reviewer_edits(
                                            user_edits[0], tile)

                            # If user is reviewer, apply as authoritative edit
                            if tile.provisionaledits != '':
                                for user_edits in tile.provisionaledits.items(
                                ):
                                    if user_edits[0] not in user_lookup:
                                        user = User.objects.get(
                                            pk=user_edits[0])
                                        user_lookup[user_edits[
                                            0]] = user.groups.filter(
                                                name='Resource Reviewer'
                                            ).exists()

                                for user_id, is_reviewer in user_lookup.items(
                                ):
                                    if is_reviewer:
                                        try:
                                            tile.data = tile.provisionaledits.pop(
                                                user_id)['value']
                                        except KeyError:
                                            pass

                            tile.save()
                            self.save_revision_log(row.doc, synclog, action)
                            print('Tile {0} Saved'.format(row.doc['tileid']))
                            db.compact()
    def save_bngpoint(self, tile, request, is_function_save_method=True):
        """Finds the BNG Alphanumeric value for the centroid of the envelope(extent) of the Geometry,
        and saves that value to the bng_output_nodegroup of the tile.

        Args:
            self: GeoJSONToBNGPoint object.

            tile: Tile to attach / amend bng_output_nodegroup of.

            request: WSGI Request used to varify call is result of user action. N.B. Function Returns if empty.

            is_function_save_method: a bool stating whether the function calling it is the save function.
        """

        # First let's check if this call is as a result of an inbound request (user action) or
        # as a result of the complementary BNGPointToGeoJSON function saving a new GeoJson.
        if request is None and is_function_save_method == True:
            return

        srid_LatLong = 4326
        srid_BngAbs = 27700
        # Reference grid for Easting/Northing to BNG Alphas.

        os_grid = {
            "09": "NA",
            "19": "NB",
            "29": "NC",
            "39": "ND",
            "49": "NE",
            "59": "OA",
            "69": "OB",
            "08": "NF",
            "18": "NG",
            "28": "NH",
            "38": "NJ",
            "48": "NK",
            "58": "OF",
            "68": "OG",
            "07": "NL",
            "17": "NM",
            "27": "NN",
            "37": "NO",
            "47": "NP",
            "57": "OL",
            "67": "OM",
            "06": "NQ",
            "16": "NR",
            "26": "NS",
            "36": "NT",
            "46": "NU",
            "56": "OQ",
            "66": "OR",
            "05": "NV",
            "15": "NW",
            "25": "NX",
            "35": "NY",
            "45": "NZ",
            "55": "OV",
            "65": "OW",
            "04": "SA",
            "14": "SB",
            "24": "SC",
            "34": "SD",
            "44": "SE",
            "54": "TA",
            "64": "TB",
            "03": "SF",
            "13": "SG",
            "23": "SH",
            "33": "SJ",
            "43": "SK",
            "53": "TF",
            "63": "TG",
            "02": "SL",
            "12": "SM",
            "22": "SN",
            "32": "SO",
            "42": "SP",
            "52": "TL",
            "62": "TM",
            "01": "SQ",
            "11": "SR",
            "21": "SS",
            "31": "ST",
            "41": "SU",
            "51": "TQ",
            "61": "TR",
            "00": "SV",
            "10": "SW",
            "20": "SX",
            "30": "SY",
            "40": "SZ",
            "50": "TV",
            "60": "TW",
        }

        geojsonnode = self.config["geojson_input_node"]
        bngnode = self.config["bng_output_node"]

        geojsonValue = tile.data[geojsonnode]

        if geojsonValue != None:

            # Grab a copy of the Geometry collection.
            geoJsFeatures = geojsonValue["features"]

            # Get the first feature as a GeosGeometry.
            geosGeom_union = GEOSGeometry(json.dumps(geoJsFeatures[0]["geometry"]))

            # update list.
            geoJsFeatures = geoJsFeatures[1:]

            # loop through list of geoJsFeatures.
            for item in geoJsFeatures:
                # .union seems to generate 'GEOS_ERROR: IllegalArgumentException:'
                # exceptions, but they seem spurious and are automatically ignored.
                geosGeom_union = geosGeom_union.union(GEOSGeometry(json.dumps(item["geometry"])))

            # find the centroid of the envelope for the resultant Geometry Collection.
            centroidPoint = geosGeom_union.envelope.centroid

            # Explicitly declare the SRID for the current lat/long.
            centroidPoint = GEOSGeometry(centroidPoint, srid=srid_LatLong)

            # Transform to Absolute BNG.
            centroidPoint.transform(srid_BngAbs, False)

            # Get initial Easting and Northing digits. N.B. Left Zero pad integer coords to 6 digits!
            easting = str(int(centroidPoint.coords[0])).zfill(6)
            northing = str(int(centroidPoint.coords[1])).zfill(6)
            gridref = easting[0] + northing[0]

            # Get AlphaNumeric BNG
            try:
                gridref = os_grid[gridref] + easting[1:6] + northing[1:6]
            except KeyError:
                raise Exception("Conversion Error : Coordinates outside of BNG for England.")

            if self.config["bng_output_nodegroup"] == str(tile.nodegroup_id):
                tile.data[bngnode] = gridref
            else:

                previously_saved_tiles = Tile.objects.filter(
                    nodegroup_id=self.config["bng_output_nodegroup"], resourceinstance_id=tile.resourceinstance_id
                )

                # Update pre-existing tiles, or Create new one.
                if len(previously_saved_tiles) > 0:
                    for p in previously_saved_tiles:
                        p.data[bngnode] = gridref
                        p.save()
                else:
                    new_bng_tile = Tile().get_blank_tile_from_nodegroup_id(
                        self.config["bng_output_nodegroup"], resourceid=tile.resourceinstance_id, parenttile=tile.parenttile
                    )
                    new_bng_tile.data[bngnode] = gridref
                    new_bng_tile.save()

            return

        return
Beispiel #35
0
    def push_edits_to_db(self, synclog=None, userid=None):
        # read all docs that have changes
        # save back to postgres db
        db = self.couch.create_db('project_' + str(self.id))
        user_lookup = {}
        is_reviewer = False
        sync_user = None
        sync_user_id = None
        if userid is not None:
            sync_user = User.objects.get(pk=userid)
            sync_user_id = str(sync_user.id)

        with transaction.atomic():
            couch_docs = self.couch.all_docs(db)
            for row in couch_docs:
                if row.doc['type'] == 'resource':
                    if self.check_if_revision_exists(row.doc) is False:
                        if 'provisional_resource' in row.doc and row.doc[
                                'provisional_resource'] == 'true':
                            resourceinstance, created = ResourceInstance.objects.update_or_create(
                                resourceinstanceid=uuid.UUID(
                                    str(row.doc['resourceinstanceid'])),
                                defaults={
                                    'graph_id':
                                    uuid.UUID(str(row.doc['graph_id']))
                                })
                            if created is True:
                                self.save_revision_log(row.doc, synclog,
                                                       'create')
                            else:
                                self.save_revision_log(row.doc, synclog,
                                                       'update')

                            print('Resource {0} Saved'.format(
                                row.doc['resourceinstanceid']))
                    else:
                        print('{0}: already saved'.format(row.doc['_rev']))

            for row in couch_docs:
                if row.doc['type'] == 'tile' and \
                        ResourceInstance.objects.filter(pk=row.doc['resourceinstance_id']).exists():
                    if self.check_if_revision_exists(row.doc) is False:
                        if 'provisionaledits' in row.doc and row.doc[
                                'provisionaledits'] is not None:
                            action = 'update'
                            try:
                                tile = Tile.objects.get(
                                    tileid=row.doc['tileid'])
                                prov_edit = self.get_provisional_edit(
                                    row.doc, tile, sync_user_id, db)
                                if prov_edit is not None:
                                    tile.data = prov_edit

                                # If there are conflicting documents, lets clear those out
                                if '_conflicts' in row.doc:
                                    for conflict_rev in row.doc['_conflicts']:
                                        conflict_data = db.get(
                                            row.id, rev=conflict_rev)
                                        if conflict_data['provisionaledits'] != '' and \
                                                conflict_data['provisionaledits'] is not None:
                                            if sync_user_id in conflict_data[
                                                    'provisionaledits']:
                                                tile.data = conflict_data[
                                                    'provisionaledits'][
                                                        sync_user_id]['value']
                                        # Remove conflicted revision from couch
                                        db.delete(conflict_data)

                            except Tile.DoesNotExist:
                                action = 'create'
                                tile = Tile(row.doc)
                                prov_edit = self.get_provisional_edit(
                                    row.doc, tile, sync_user_id, db)
                                if prov_edit is not None:
                                    tile.data = prov_edit

                            self.handle_reviewer_edits(sync_user, tile)
                            tile.save(user=sync_user)
                            self.save_revision_log(row.doc, synclog, action)
                            print('Tile {0} Saved'.format(row.doc['tileid']))
                            db.compact()
    def save(self, tile, request):
        """ Finds the equivalen GeoJSON for a BNG Alphanumeric value and saves that value to the 
            geojson nodegroup of the tile.

            Agrs:
                self: BNGPointToGeoJSON object.

                tile: Tile to attach / amend geojson_nodegroup of.

                request: WSGI Request used to varify call is result of user action. N.B. Function Returns if empty.
        """

        # print 'calling save'

        # First let's check if this call is as a result of an inbound request (user action) or
        # as a result of the complementary GeoJSONToBNGPoint function saving a new BngPoint.
        if request is None:
            return

        bngValueReturned = ""
        gridSquare = {
            "NT": [3, 6],
            "NU": [4, 6],
            "NX": [2, 5],
            "NY": [3, 5],
            "NZ": [4, 5],
            "SD": [3, 4],
            "SE": [4, 4],
            "TA": [5, 4],
            "SJ": [3, 3],
            "SK": [4, 3],
            "TF": [5, 3],
            "TG": [6, 3],
            "SO": [3, 2],
            "SP": [4, 2],
            "TL": [5, 2],
            "TM": [6, 2],
            "SS": [2, 1],
            "ST": [3, 1],
            "SU": [4, 1],
            "TQ": [5, 1],
            "TR": [6, 1],
            "SV": [0, 0],
            "SW": [1, 0],
            "SX": [2, 0],
            "SY": [3, 0],
            "SZ": [4, 0],
            "TV": [5, 0]
        }

        bngnode = self.config[u"bng_node"]
        geojsonNode = self.config[u"geojson_node"]

        bngValueReturned = tile.data[bngnode]

        if bngValueReturned != None:
            '''
            The following section turns the alphanumberic BNG value in the tile into a point geometry object and then transforms that object 
            into WGS 1984 long/lat projection system.
            '''

            dt = datetime.now()
            gridSquareLetters = bngValueReturned[0:2]
            bngValueNumbers = bngValueReturned[2:]
            splitSection = len(bngValueNumbers) / 2
            gridSquareNumbers = gridSquare[gridSquareLetters]
            eastingValue = str(gridSquareNumbers[0]) + str(
                bngValueNumbers[:splitSection])
            northingValue = str(gridSquareNumbers[1]) + str(
                bngValueNumbers[splitSection:])

            osgb36PointString = 'POINT (' + eastingValue + ' ' + northingValue + ')'
            osgb36Point = GEOSGeometry(osgb36PointString, srid=27700)
            osgb36Point.transform(4326, False)
            pointGeoJSON = json.loads(osgb36Point.geojson)
            '''
                This section creates a geojson object required in the format required by Arches.  The date and time the object was 
                created has also been added in the feature's properties.
            '''

            uuidForRecord = uuid.uuid4().hex
            geometryValue = {
                "type":
                "FeatureCollection",
                "features": [{
                    "geometry": pointGeoJSON,
                    "type": "Feature",
                    "id": str(uuidForRecord),
                    "properties": {
                        "datetime": dt.strftime("%d/%m/%Y %H:%M:%S")
                    }
                }]
            }

            geometryValueJson = geometryValue
            '''
            The Tile.objects.filter function from tiles.py is called to return any tiles with the geojson_nodegroup value 
            as the nodegroup_id and the current tile's resource instance ID as its resourceinstance_id value; any tiles returned 
            are added to the previously_saved_tiles variable.

            If there are tiles returned then the new geojson object overwrites the current value.

            If there are no tiles returned, a new tile is created for the geojson nodegroup using tile.py's get_blank_tile 
            function.  If there is a key within the data object in the new node with the same id as the geojson_nodegroup value 
            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 
            value.

            The new tile is saved and then the mv_geojson_geoms materialised view is refreshed so the point geometry will be displayed 
            on the Search map.
            '''
            previously_saved_tiles = Tile.objects.filter(
                nodegroup_id=self.config[u"geojson_nodegroup"],
                resourceinstance_id=tile.resourceinstance_id)

            if len(previously_saved_tiles) > 0:
                for p in previously_saved_tiles:
                    p.data[geojsonNode] = geometryValueJson
                    p.save()
            else:

                geoJSONnodegroup = Tile().get_blank_tile_from_nodegroup_id(
                    self.config[u"geojson_nodegroup"],
                    resourceid=tile.resourceinstance_id,
                    parenttile=tile.parenttile)
                geoJSONnodegroup.data[
                    self.config[u"geojson_node"]] = geometryValueJson

                if self.config[u"geojson_nodegroup"] in geoJSONnodegroup.data:
                    del geoJSONnodegroup.data[
                        self.config[u"geojson_nodegroup"]]

                geoJSONnodegroup.save()
            '''
            The resource object for the tile is returned and then reindexed.
            '''

            #resource = Resource.objects.get(resourceinstanceid=tile.resourceinstance_id)
            #resource.index()

            cursor = connection.cursor()
            sql = """
                    REFRESH MATERIALIZED VIEW mv_geojson_geoms;
                """
            cursor.execute(sql)

            resource = Resource.objects.get(
                resourceinstanceid=tile.resourceinstance_id)
            #resource.index()

        else:
            pass
        '''
        The tile is saved.
        '''

        tile.save()

        return
Beispiel #37
0
    def post(self, request):
        if self.action == 'update_tile':
            json = request.POST.get('data', None)
            if json != None:
                data = JSONDeserializer().deserialize(json)
                try:
                    models.ResourceInstance.objects.get(
                        pk=data['resourceinstance_id'])
                except ObjectDoesNotExist:
                    resource = Resource()
                    resource.resourceinstanceid = data['resourceinstance_id']
                    graphid = models.Node.objects.filter(
                        nodegroup=data['nodegroup_id'])[0].graph_id
                    resource.graph_id = graphid
                    resource.save(user=request.user)
                    resource.index()
                tile_id = data['tileid']
                if tile_id != None and tile_id != '':
                    old_tile = Tile.objects.get(pk=tile_id)
                    clean_resource_cache(old_tile)
                tile = Tile(data)
                if tile.filter_by_perm(request.user, 'write_nodegroup'):
                    with transaction.atomic():
                        try:
                            tile.save(request=request)
                            if tile_id == '4345f530-aa90-48cf-b4b3-92d1185ca439':
                                import couchdb
                                import json as json_json
                                couch = couchdb.Server(settings.COUCHDB_URL)
                                for project in models.MobileSurveyModel.objects.all(
                                ):
                                    db = couch['project_' + str(project.id)]
                                    #tile = models.TileModel.objects.get(pk='4345f530-aa90-48cf-b4b3-92d1185ca439')
                                    tile_json = json_json.loads(
                                        JSONSerializer().serialize(tile))
                                    tile_json['_id'] = tile_json['tileid']
                                    for row in db.view('_all_docs',
                                                       include_docs=True):
                                        if 'tileid' in row.doc and tile_json[
                                                '_id'] == row.doc['_id']:
                                            tile_json['_rev'] = row.doc['_rev']
                                            db.save(tile_json)

                        except ValidationError as e:
                            return JSONResponse(
                                {
                                    'status': 'false',
                                    'message': e.args
                                },
                                status=500)
                        tile.after_update_all()
                        clean_resource_cache(tile)
                        update_system_settings_cache(tile)
                    return JSONResponse(tile)
                else:
                    return JSONResponse(
                        {
                            'status':
                            'false',
                            'message':
                            [_('Request Failed'),
                             _('Permission Denied')]
                        },
                        status=500)

        if self.action == 'reorder_tiles':
            json = request.body
            if json != None:
                data = JSONDeserializer().deserialize(json)

                if 'tiles' in data and len(data['tiles']) > 0:
                    sortorder = 0
                    with transaction.atomic():
                        for tile in data['tiles']:
                            t = Tile(tile)
                            if t.filter_by_perm(request.user,
                                                'write_nodegroup'):
                                t.sortorder = sortorder
                                t.save(update_fields=['sortorder'],
                                       request=request)
                                sortorder = sortorder + 1

                    return JSONResponse(data)

        if self.action == 'delete_provisional_tile':
            data = request.POST
            if 'tileid' in data:
                provisionaledits = self.delete_provisional_edit(data, request)
                return JSONResponse(provisionaledits)

            else:
                payload = data.get('payload', None)
                if payload is not None:
                    edits = jsonparser.loads(payload)
                    for edit in edits['edits']:
                        provisionaledits = self.delete_provisional_edit(
                            edit, request)
                return JSONResponse({'result': 'success'})

        return HttpResponseNotFound()
Beispiel #38
0
    def save(self,tile,request):
    
        ## variable to control verbose output. not hooked into anywhere else in the app,
        ## but useful during development
        verbose = False
        if verbose:
            print(f"verbose: {verbose}")

        ## return early if there is no spatial data to use for a comparison
        spatial_node_id = self.config['spatial_node_id']
        if tile.data[spatial_node_id] == None or tile.data[spatial_node_id] == []:
            ## apparently if there is None in the triggering nodegroup,
            ## an error will occur AFTER this function has returned. So,
            ## for now, setting the value to an empty list to handle this.
            tile.data[spatial_node_id] = []
            return

        ## get geoms from the current tile
        geoms = [feature['geometry'] for feature in tile.data[spatial_node_id]['features']]

        ## create and iterate list of input table/field/target sets
        ## the UI should produce "table_name.field_name" strings

        table_field_targets = self.config['inputs']

        for table_field_target in table_field_targets:
            if verbose:
                print(f"processing input: {table_field_target}")
            ## skip if the table_name.field_name input is not valid
            if not "." in table_field_target['table_field']:
                continue

            ## parse input sets
            table,field = table_field_target['table_field'].split(".")[0],table_field_target['table_field'].split(".")[1]
            target_node_id = table_field_target['target_node_id']
            target_ng_id = models.Node.objects.filter(nodeid=target_node_id)[0].nodegroup_id

            # process each geom and create a list of all values
            vals = []
            for geom in geoms:
                val = attribute_from_postgis(table,field,geom)
                vals+=val
            attributes = list(set(vals))
            if len(attributes) == 0:
                continue

            ## get the datatype of the target node, and if necessary convert the
            ## attributes to value ids. note that prefLabels are expected here,
            ## NOT actual concept ids. what actually gets passed to the tile data
            ## are valueids for the preflabels, not UUIDs for the concept.
            node = models.Node.objects.get(pk=target_node_id)
            target_node_datatype = node.datatype
            if target_node_datatype in ["concept","concept-list"]:
                vals = [get_valueid_from_preflabel(v) for v in attributes]
                attributes = [v for v in vals if v]

            ## if the target node is inside of the currently edited node group,
            ## just set the new value right here
            if str(target_ng_id) == str(tile.nodegroup_id):
                if verbose:
                    print("  inside same nodegroup")
                ## set precedent for correlating new values with target node
                ## datatype. the following will work on a limited basis
                if target_node_datatype == "concept-list":
                    tile.data[target_node_id] = attributes
                elif target_node_datatype == "concept":
                    tile.data[target_node_id] = attributes[0]
                else:
                    tile.data[target_node_id] = attributes[0]

                tile.dirty = False
                continue

            ## if the tile that is to be updated already exists, then it is easy
            ## to find and update it. this should be combined with a 
            if verbose:
                print("  checking for previously saved tiles with this target_ng_id")
            previously_saved_tiles = Tile.objects.filter(nodegroup_id=target_ng_id,resourceinstance_id=tile.resourceinstance_id)
            if verbose:
                print(f" {len(previously_saved_tiles)} found")
            if len(previously_saved_tiles) > 0:
                for t in previously_saved_tiles:
                    if target_node_datatype == "concept-list":
                        t.data[target_node_id] = attributes
                    elif target_node_datatype == "concept":
                        t.data[target_node_id] = attributes[0]
                    else:
                        t.data[target_node_id] = attributes[0]
                    t.save()
                continue
            
            if verbose:
                print("  must need a brand new tile")
            parenttile = Tile().get_blank_tile(target_node_id,resourceid=tile.resourceinstance_id)
            existing_pts = Tile.objects.filter(nodegroup_id=parenttile.nodegroup_id,resourceinstance_id=tile.resourceinstance_id)
            
            ## if there is no parent tile yet, it should be fine to save the newly created one
            if len(existing_pts) == 0:
                for ng_id,tilelist in parenttile.tiles.iteritems():
                    if ng_id == target_ng_id:
                        if verbose:
                            print("  creating new parent tile and tile")
                        for t in tilelist:
                            if target_node_datatype == "concept-list":
                                t.data[target_node_id] = attributes
                            elif target_node_datatype == "concept":
                                t.data[target_node_id] = attributes[0]
                            else:
                                t.data[target_node_id] = attributes[0]
                parenttile.save()
                continue
                
            ## if there is one parent tile already, then we need to relate the new tile
            ## to it, and then save the new tile, but not the new parent tile
            if len(existing_pts) == 1:
                for ng_id,tilelist in parenttile.tiles.iteritems():
                    if ng_id == target_ng_id:
                        if verbose:
                            print("  creating new tile and assigning to existing parent tile")
                        for t in tilelist:
                            if target_node_datatype == "concept-list":
                                t.data[target_node_id] = attributes
                            elif target_node_datatype == "concept":
                                t.data[target_node_id] = attributes[0]
                            else:
                                t.data[target_node_id] = attributes[0]
                        t.parenttile = existing_pts[0]
                        t.save()
                        continue
            
            ## if there are multiple parent tiles already, it's likely that the brand new
            ## one could be saved without any problem (as in len(existing_pts) == 0 above)
            ## but this has not been tested yet.
            if len(existing_pts) > 1:
                if verbose:
                    print("  there are multiple existing parent tiles. this circumstance"\
                        "is not supported at this time.")
                continue
            
            # tos = Tile.objects.filter(resourceinstance_id=tile.resourceinstance_id)
            # for to in tos:
                # print(to.serialize())
            # print(len(tos))

        return
    def save_geojson(self, tile, request, is_function_save_method=True):
        """Finds the equivalen GeoJSON for a BNG Alphanumeric value and saves that value to the
        geojson nodegroup of the tile.

        Args:
            self : BNGPointToGeoJSON object.

            tile : Tile to attach / amend geojson_nodegroup of.

            request : WSGI Request used to varify call is result of user action. N.B. Function Returns if empty.

            is_function_save_method : a bool stating whether the function calling it is the save function.
        """

        # First let's check if this call is as a result of an inbound request (user action) or
        # as a result of the complementary GeoJSONToBNGPoint function saving a new BngPoint.
        if request is None and is_function_save_method == True:
            return

        bngValueReturned = ""
        gridSquare = {
            "NA": [0, 9],
            "NB": [1, 9],
            "NC": [2, 9],
            "ND": [3, 9],
            "NE": [4, 9],
            "OA": [5, 9],
            "OB": [6, 9],
            "NF": [0, 8],
            "NG": [1, 8],
            "NH": [2, 8],
            "NJ": [3, 8],
            "NK": [4, 8],
            "OF": [5, 8],
            "OG": [6, 8],
            "NL": [0, 7],
            "NM": [1, 7],
            "NN": [2, 7],
            "NO": [3, 7],
            "NP": [4, 7],
            "OL": [5, 7],
            "OM": [6, 7],
            "NQ": [0, 6],
            "NR": [1, 6],
            "NS": [2, 6],
            "NT": [3, 6],
            "NU": [4, 6],
            "OQ": [5, 6],
            "OR": [6, 6],
            "NV": [0, 5],
            "NW": [1, 5],
            "NX": [2, 5],
            "NY": [3, 5],
            "NZ": [4, 5],
            "OV": [5, 5],
            "OW": [6, 5],
            "SA": [0, 4],
            "SB": [1, 4],
            "SC": [2, 4],
            "SD": [3, 4],
            "SE": [4, 4],
            "TA": [5, 4],
            "TB": [6, 4],
            "SF": [0, 3],
            "SG": [1, 3],
            "SH": [2, 3],
            "SJ": [3, 3],
            "SK": [4, 3],
            "TF": [5, 3],
            "TG": [6, 3],
            "SL": [0, 2],
            "SM": [1, 2],
            "SN": [2, 2],
            "SO": [3, 2],
            "SP": [4, 2],
            "TL": [5, 2],
            "TM": [6, 2],
            "SQ": [0, 1],
            "SR": [1, 1],
            "SS": [2, 1],
            "ST": [3, 1],
            "SU": [4, 1],
            "TQ": [5, 1],
            "TR": [6, 1],
            "SV": [0, 0],
            "SW": [1, 0],
            "SX": [2, 0],
            "SY": [3, 0],
            "SZ": [4, 0],
            "TV": [5, 0],
            "TW": [6, 0],
        }

        bngnode = self.config["bng_node"]
        geojsonNode = self.config["geojson_node"]
        bngValueReturned = tile.data[bngnode]

        if bngValueReturned != None:
            """
            The following section turns the alphanumberic BNG value in the tile into a point geometry object and then transforms that object
            into WGS 1984 long/lat projection system.
            """

            dt = datetime.now()
            gridSquareLetters = bngValueReturned[0:2]
            bngValueNumbers = bngValueReturned[2:]
            splitSection = int(len(bngValueNumbers) / 2)
            gridSquareNumbers = gridSquare[gridSquareLetters]
            eastingValue = str(gridSquareNumbers[0]) + str(bngValueNumbers[:splitSection])
            northingValue = str(gridSquareNumbers[1]) + str(bngValueNumbers[splitSection:])
            osgb36PointString = "POINT (" + eastingValue + " " + northingValue + ")"
            osgb36Point = GEOSGeometry(osgb36PointString, srid=27700)
            osgb36Point.transform(4326, False)
            pointGeoJSON = json.loads(osgb36Point.geojson)

            """
                This section creates a geojson object required in the format required by Arches.  The date and time the object was
                created has also been added in the feature's properties.
            """

            uuidForRecord = uuid.uuid4().hex
            bngFeature = {
                "geometry": pointGeoJSON,
                "type": "Feature",
                "id": str(uuidForRecord),
                "properties": {"datetime": dt.strftime("%d/%m/%Y %H:%M:%S"), "bngref": str(bngValueReturned)},
            }

            geometryValue = {"type": "FeatureCollection", "features": [bngFeature]}

            geometryValueJson = geometryValue

            """
            The Tile.objects.filter function from tiles.py is called to return any tiles with the geojson_nodegroup value
            as the nodegroup_id and the current tile's resource instance ID as its resourceinstance_id value; any tiles returned
            are added to the previously_saved_tiles variable.

            If there are tiles returned then the new geojson object overwrites the current value.

            If there are no tiles returned, a new tile is created for the geojson nodegroup using tile.py's get_blank_tile
            function.  If there is a key within the data object in the new node with the same id as the geojson_nodegroup value
            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
            value.

            The new tile is saved and then the mv_geojson_geoms materialised view is refreshed so the point geometry will be displayed
            on the Search map.
            """
            if self.config["geojson_nodegroup"] == str(tile.nodegroup_id):
                tile.data[geojsonNode] = geometryValueJson
            else:
                previously_saved_tiles = Tile.objects.filter(
                    nodegroup_id=self.config["geojson_nodegroup"], resourceinstance_id=tile.resourceinstance_id
                )

                if len(previously_saved_tiles) > 0:
                    for p in previously_saved_tiles:
                        old_geojson = p.data[geojsonNode]
                        p.data[geojsonNode] = geometryValueJson

                        for f in old_geojson["features"]:
                            if "bngref" not in f["properties"]:
                                p.data[geojsonNode]["features"].append(f)

                        p.save()
                else:
                    new_geojson_tile = Tile().get_blank_tile_from_nodegroup_id(
                        self.config["geojson_nodegroup"], resourceid=tile.resourceinstance_id, parenttile=tile.parenttile
                    )
                    new_geojson_tile.data[self.config["geojson_node"]] = geometryValueJson

                    if self.config["geojson_nodegroup"] in new_geojson_tile.data:
                        del new_geojson_tile.data[self.config["geojson_nodegroup"]]

                    new_geojson_tile.save()

            cursor = connection.cursor()
            sql = """
                    SELECT * FROM refresh_geojson_geometries();
                """
            cursor.execute(sql)  #

        else:
            pass

        return
Beispiel #40
0
    def post(self, request):
        if self.action == 'update_tile':
            json = request.POST.get('data', None)
            accepted_provisional = request.POST.get('accepted_provisional',
                                                    None)
            if accepted_provisional != None:
                accepted_provisional_edit = JSONDeserializer().deserialize(
                    accepted_provisional)
            if json != None:
                data = JSONDeserializer().deserialize(json)
                if data['resourceinstance_id'] == '':
                    data['resourceinstance_id'] = uuid.uuid4()
                try:
                    models.ResourceInstance.objects.get(
                        pk=data['resourceinstance_id'])
                except ObjectDoesNotExist:
                    resource = Resource()
                    graphid = models.Node.objects.filter(
                        nodegroup=data['nodegroup_id'])[0].graph_id
                    resource.graph_id = graphid
                    resource.save(user=request.user)
                    data['resourceinstance_id'] = resource.pk
                    resource.index()
                tile_id = data['tileid']
                if tile_id != None and tile_id != '':
                    try:
                        old_tile = Tile.objects.get(pk=tile_id)
                        clean_resource_cache(old_tile)
                    except ObjectDoesNotExist:
                        return JSONResponse(
                            {
                                'status':
                                'false',
                                'message': [
                                    _('This tile is no longer available'),
                                    _('It was likely deleted by another user')
                                ]
                            },
                            status=500)
                tile = Tile(data)
                if tile.filter_by_perm(request.user, 'write_nodegroup'):
                    with transaction.atomic():
                        try:
                            if accepted_provisional == None:
                                try:
                                    tile.save(request=request)
                                except TileValidationError as e:
                                    resource_tiles = models.TileModel.objects.filter(
                                        resourceinstance=tile.resourceinstance)
                                    if resource_tiles.count() == 0:
                                        Resource.objects.get(
                                            pk=tile.resourceinstance_id
                                        ).delete(request.user, 'test')
                                    return JSONResponse(
                                        {
                                            'status':
                                            'false',
                                            'message': [
                                                e.message,
                                                _('Unable to Save. Please verify your input is valid'
                                                  )
                                            ]
                                        },
                                        status=500)
                                except Exception as e:
                                    message = "Unable to save. A {0} has occurred. Arguments: {1!r}".format(
                                        type(e).__name__, e.args)
                                    return JSONResponse(
                                        {
                                            'status':
                                            'false',
                                            'message': [
                                                message,
                                                _('Please contact your system administrator'
                                                  )
                                            ]
                                        },
                                        status=500)
                            else:
                                if accepted_provisional is not None:
                                    provisional_editor = User.objects.get(
                                        pk=accepted_provisional_edit["user"])
                                tile.save(
                                    provisional_edit_log_details={
                                        "user": request.user,
                                        "action": "accept edit",
                                        "edit": accepted_provisional_edit,
                                        "provisional_editor":
                                        provisional_editor
                                    })

                            if tile.provisionaledits is not None and str(
                                    request.user.id) in tile.provisionaledits:
                                tile.data = tile.provisionaledits[str(
                                    request.user.id)]['value']

                        except ValidationError as e:
                            return JSONResponse(
                                {
                                    'status': 'false',
                                    'message': e.args
                                },
                                status=500)
                        except Exception as e:
                            exception_title = 'Saving tile failed'
                            exception_message = str(e)
                            if hasattr(e, 'message') and e.message:
                                exception_message += "({0})".format(e.message)

                            logger.error(exception_title +
                                         ''' [Tile id: {tile_id}] \
                                         [Exception message: {message}] \
                                         [Exception trace: {trace}]'''.format(
                                             tile_id=tile_id,
                                             message=exception_message,
                                             trace=traceback.format_exc()))

                            return JSONResponse(
                                {
                                    'status':
                                    'false',
                                    'message': [
                                        _(exception_title),
                                        _(str(exception_message))
                                    ]
                                },
                                status=500)
                        tile.after_update_all()
                        clean_resource_cache(tile)
                        update_system_settings_cache(tile)

                    return JSONResponse(tile)
                else:
                    return JSONResponse(
                        {
                            'status':
                            'false',
                            'message':
                            [_('Request Failed'),
                             _('Permission Denied')]
                        },
                        status=500)

        if self.action == 'reorder_tiles':
            json = request.body
            if json != None:
                data = JSONDeserializer().deserialize(json)

                if 'tiles' in data and len(data['tiles']) > 0:
                    sortorder = 0
                    with transaction.atomic():
                        for tile in data['tiles']:
                            t = Tile(tile)
                            if t.filter_by_perm(request.user,
                                                'write_nodegroup'):
                                t.sortorder = sortorder
                                t.save(update_fields=['sortorder'],
                                       request=request)
                                sortorder = sortorder + 1

                    return JSONResponse(data)

        if self.action == 'delete_provisional_tile':
            user = request.POST.get('user', None)
            tileid = request.POST.get('tileid', None)
            users = request.POST.get('users', None)
            tile = Tile.objects.get(tileid=tileid)
            is_provisional = tile.is_provisional()

            if tileid is not None and user is not None:
                provisionaledits = self.delete_provisional_edit(
                    tile, user, reviewer=request.user)

            elif tileid is not None and users is not None:
                users = jsonparser.loads(users)
                for user in users:
                    self.delete_provisional_edit(tile,
                                                 user,
                                                 reviewer=request.user)

            if is_provisional == True:
                return JSONResponse({'result': 'delete'})
            else:
                return JSONResponse({'result': 'success'})

        return HttpResponseNotFound()
Beispiel #41
0
    def post(self, request, graphid=None):
        try:
            body = json.loads(request.body)
            file_data = body['file_data']
            column_name_to_node_data_map = body['column_name_to_node_data_map']

            nodegroup_data = {}

            for node_data in column_name_to_node_data_map.values():
                nodegroup_id = node_data.get('nodegroup_id')

                if nodegroup_id:
                    if not nodegroup_data.get(nodegroup_id):
                        nodegroup_data[nodegroup_id] = []

                    nodegroup_data[nodegroup_id].append(node_data['node_id'])

            for file_datum in file_data:
                for row_data in file_datum['data']:
                    resource_instance = Resource(graph_id=graphid)
                    resource_instance.save()

                    parsed_data = row_data['parsed_data']

                    tile_data = {}

                    for nodegroup_id in nodegroup_data.keys():
                        if not tile_data.get(nodegroup_id):
                            tile_data[nodegroup_id] = {}

                        for node_id in nodegroup_data[nodegroup_id]:
                            tile_data[nodegroup_id][node_id] = parsed_data.get(
                                node_id)

                    for nodegroup_id in tile_data.keys():
                        tile = TileProxyModel(
                            data=tile_data[nodegroup_id],
                            resourceinstance=resource_instance,
                            nodegroup_id=nodegroup_id,
                            # nodegroup_id = 'f7c974a0-29f4-11eb-8487-aae9fe8789ac',  # Related Observations
                        )

                        tile.save()

                    file_datum['created_resources'][row_data['row_id']] = {
                        'resourceinstance_id': str(resource_instance.pk),
                        'row_id': row_data['row_id'],
                        'tile_data': tile_data,
                    }

            return JSONResponse({
                'file_data': file_data,
            }, status=200)

        except Exception as e:
            if settings.DEBUG is True:
                exc_type, exc_value, exc_traceback = sys.exc_info()
                formatted = traceback.format_exception(exc_type, exc_value,
                                                       exc_traceback)
                if len(formatted):
                    for message in formatted:
                        print(message)
            return JSONResponse(
                {"error": "resource data could not be saved: %s" % e},
                status=500,
                reason=e)
Beispiel #42
0
    def push_edits_to_db(self, synclog=None, userid=None):
        # read all docs that have changes
        # save back to postgres db
        db = self.couch.create_db("project_" + str(self.id))
        user_lookup = {}
        is_reviewer = False
        sync_user = None
        sync_user_id = None
        if userid is not None:
            sync_user = User.objects.get(pk=userid)
            sync_user_id = str(sync_user.id)

        with transaction.atomic():
            couch_docs = self.couch.all_docs(db)
            for row in couch_docs:
                if row.doc["type"] == "resource":
                    if self.check_if_revision_exists(row.doc) is False:
                        if "provisional_resource" in row.doc and row.doc[
                                "provisional_resource"] == "true":
                            resourceinstance, created = ResourceInstance.objects.update_or_create(
                                resourceinstanceid=uuid.UUID(
                                    str(row.doc["resourceinstanceid"])),
                                defaults=dict(graph_id=uuid.UUID(
                                    str(row.doc["graph_id"]))),
                            )
                            if created is True:
                                self.save_revision_log(row.doc, synclog,
                                                       "create")
                            else:
                                self.save_revision_log(row.doc, synclog,
                                                       "update")

                            print("Resource {0} Saved".format(
                                row.doc["resourceinstanceid"]))
                    else:
                        print("{0}: already saved".format(row.doc["_rev"]))

            for row in couch_docs:
                if row.doc[
                        "type"] == "tile" and ResourceInstance.objects.filter(
                            pk=row.doc["resourceinstance_id"]).exists():
                    if self.check_if_revision_exists(row.doc) is False:
                        if "provisionaledits" in row.doc and row.doc[
                                "provisionaledits"] is not None:
                            action = "update"
                            try:
                                tile = Tile.objects.get(
                                    tileid=row.doc["tileid"])
                                prov_edit = self.get_provisional_edit(
                                    row.doc, tile, sync_user_id, db)
                                if prov_edit is not None:
                                    tile.data = prov_edit

                                # If there are conflicting documents, lets clear those out
                                if "_conflicts" in row.doc:
                                    for conflict_rev in row.doc["_conflicts"]:
                                        conflict_data = db.get(
                                            row.id, rev=conflict_rev)
                                        if conflict_data[
                                                "provisionaledits"] != "" and conflict_data[
                                                    "provisionaledits"] is not None:
                                            if sync_user_id in conflict_data[
                                                    "provisionaledits"]:
                                                tile.data = conflict_data[
                                                    "provisionaledits"][
                                                        sync_user_id]["value"]
                                        # Remove conflicted revision from couch
                                        db.delete(conflict_data)

                            except Tile.DoesNotExist:
                                action = "create"
                                tile = Tile(row.doc)
                                prov_edit = self.get_provisional_edit(
                                    row.doc, tile, sync_user_id, db)
                                if prov_edit is not None:
                                    tile.data = prov_edit

                            self.handle_reviewer_edits(sync_user, tile)
                            tile.save(user=sync_user)
                            self.save_revision_log(row.doc, synclog, action)
                            print("Tile {0} Saved".format(row.doc["tileid"]))
                            db.compact()
Beispiel #43
0
    def post(self, request):
        if self.action == "update_tile":
            json = request.POST.get("data", None)
            accepted_provisional = request.POST.get("accepted_provisional",
                                                    None)
            if accepted_provisional is not None:
                accepted_provisional_edit = JSONDeserializer().deserialize(
                    accepted_provisional)
            if json is not None:
                data = JSONDeserializer().deserialize(json)
                data[
                    "resourceinstance_id"] = "" if "resourceinstance_id" not in data else data[
                        "resourceinstance_id"]
                if data["resourceinstance_id"] == "":
                    data["resourceinstance_id"] = uuid.uuid4()
                try:
                    models.ResourceInstance.objects.get(
                        pk=data["resourceinstance_id"])
                except ObjectDoesNotExist:
                    try:
                        resource = Resource(
                            uuid.UUID(str(data["resourceinstance_id"])))
                    except ValueError:
                        resource = Resource()
                    graphid = models.Node.objects.filter(
                        nodegroup=data["nodegroup_id"])[0].graph_id
                    resource.graph_id = graphid
                    try:
                        resource.save(user=request.user)
                        data["resourceinstance_id"] = resource.pk
                        resource.index()
                    except ModelInactiveError as e:
                        message = _(
                            "Unable to save. Please verify the model status is active"
                        )
                        return JSONResponse(
                            {
                                "status": "false",
                                "message": [_(e.title),
                                            _(str(message))]
                            },
                            status=500)
                tile_id = data["tileid"]
                resource_instance = models.ResourceInstance.objects.get(
                    pk=data["resourceinstance_id"])
                is_active = resource_instance.graph.isactive
                if tile_id is not None and tile_id != "":
                    try:
                        old_tile = Tile.objects.get(pk=tile_id)
                    except ObjectDoesNotExist as e:
                        return self.handle_save_error(
                            e, _("This tile is no longer available"),
                            _("It was likely deleted by another user"))

                tile = Tile(data)

                if tile.filter_by_perm(
                        request.user, "write_nodegroup") and is_active is True:
                    try:
                        with transaction.atomic():
                            try:
                                if accepted_provisional is None:
                                    try:
                                        tile.save(request=request)
                                    except TileValidationError as e:
                                        resource_tiles = models.TileModel.objects.filter(
                                            resourceinstance=tile.
                                            resourceinstance)
                                        if resource_tiles.count() == 0:
                                            Resource.objects.get(
                                                pk=tile.resourceinstance_id
                                            ).delete(request.user)
                                        title = _(
                                            "Unable to save. Please verify your input is valid"
                                        )
                                        return self.handle_save_error(
                                            e, tile_id, title=title)
                                    except ModelInactiveError as e:
                                        message = _(
                                            "Unable to save. Please verify the model status is active"
                                        )
                                        return JSONResponse(
                                            {
                                                "status":
                                                "false",
                                                "message":
                                                [_(e.title),
                                                 _(str(message))]
                                            },
                                            status=500)
                                else:
                                    if accepted_provisional is not None:
                                        provisional_editor = User.objects.get(
                                            pk=accepted_provisional_edit[
                                                "user"])
                                        prov_edit_log_details = {
                                            "user":
                                            request.user,
                                            "action":
                                            "accept edit",
                                            "edit":
                                            accepted_provisional_edit,
                                            "provisional_editor":
                                            provisional_editor,
                                        }
                                    tile.save(request=request,
                                              provisional_edit_log_details=
                                              prov_edit_log_details)

                                if tile.provisionaledits is not None and str(
                                        request.user.id
                                ) in tile.provisionaledits:
                                    tile.data = tile.provisionaledits[str(
                                        request.user.id)]["value"]

                            except Exception as e:
                                return self.handle_save_error(e, tile_id)

                            tile.after_update_all()
                            update_system_settings_cache(tile)

                    except Exception as e:
                        return self.handle_save_error(e, tile_id)

                    return JSONResponse(tile)
                elif is_active is False:
                    response = {
                        "status":
                        "false",
                        "message": [
                            _("Request Failed"),
                            _("Unable to Save. Verify model status is active")
                        ]
                    }
                    return JSONResponse(response, status=500)
                else:
                    return JSONErrorResponse(_("Request Failed"),
                                             _("Permission Denied"))

        if self.action == "reorder_tiles":
            json = request.body
            if json is not None:
                data = JSONDeserializer().deserialize(json)

                if "tiles" in data and len(data["tiles"]) > 0:
                    sortorder = 0
                    with transaction.atomic():
                        for tile in data["tiles"]:
                            t = Tile(tile)
                            if t.filter_by_perm(request.user,
                                                "write_nodegroup"):
                                t.sortorder = sortorder
                                t.save(update_fields=["sortorder"],
                                       request=request)
                                sortorder = sortorder + 1

                    return JSONResponse(data)

        if self.action == "delete_provisional_tile":
            user = request.POST.get("user", None)
            tileid = request.POST.get("tileid", None)
            users = request.POST.get("users", None)
            tile = Tile.objects.get(tileid=tileid)
            is_provisional = tile.is_provisional()

            if tileid is not None and user is not None:
                provisionaledits = self.delete_provisional_edit(
                    tile, user, request)

            elif tileid is not None and users is not None:
                users = jsonparser.loads(users)
                for user in users:
                    self.delete_provisional_edit(tile, user, request)

            if is_provisional == True:
                return JSONResponse({"result": "delete"})
            else:
                return JSONResponse({"result": "success"})

        return HttpResponseNotFound()