Example #1
0
    def copy(self):
        """
        Returns a copy of this resource instance including a copy of all tiles associated with this resource instance

        """
        # need this here to prevent a circular import error
        from arches.app.models.tile import Tile

        id_map = {}
        new_resource = Resource()
        new_resource.graph = self.graph

        if len(self.tiles) == 0:
            self.tiles = Tile.objects.filter(resourceinstance=self)

        for tile in self.tiles:
            new_tile = Tile()
            new_tile.data = tile.data
            new_tile.nodegroup = tile.nodegroup
            new_tile.parenttile = tile.parenttile
            new_tile.resourceinstance = new_resource
            new_tile.sortorder = tile.sortorder

            new_resource.tiles.append(new_tile)
            id_map[tile.pk] = new_tile

        for tile in new_resource.tiles:
            if tile.parenttile:
                tile.parenttile = id_map[tile.parenttile_id]

        with transaction.atomic():
            new_resource.save()

        return new_resource
Example #2
0
    def copy(self):
        """
        Returns a copy of this resource instance includeing a copy of all tiles associated with this resource instance

        """
        # need this here to prevent a circular import error
        from arches.app.models.tile import Tile

        id_map = {}
        new_resource = Resource()
        new_resource.graph = self.graph

        if len(self.tiles) == 0:
            self.tiles = Tile.objects.filter(resourceinstance=self)

        for tile in self.tiles:
            new_tile = Tile()
            new_tile.data = tile.data
            new_tile.nodegroup = tile.nodegroup
            new_tile.parenttile = tile.parenttile
            new_tile.resourceinstance = new_resource
            new_tile.sortorder = tile.sortorder

            new_resource.tiles.append(new_tile)
            id_map[tile.pk] = new_tile

        for tile in new_resource.tiles:
            if tile.parenttile:
                tile.parenttile = id_map[tile.parenttile_id]

        with transaction.atomic():
            new_resource.save()

        return new_resource
Example #3
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()
Example #4
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()
Example #5
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()
Example #6
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()
Example #7
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()
Example #8
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()
Example #9
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()