def getResources(req, resourceType):
     kwargs = {
         'path': '/metadata/' + resourceType + '/',
         'method': req.method         
     }
     if resourceType == 'record':
         return hide_unpublished(req.user, proxyRequest(**kwargs))
     else: return proxyRequest(**kwargs)
 def getFile(req, resourceId, fileName):        
     response = hide_unpublished(req.user, proxyRequest(path='/metadata/record/' + resourceId + '/', method='GET'))
     if response.content == '':
         return HttpResponseForbidden('You do not have permission to view this resource')
     else:
         kwargs = {
             'path': '/metadata/record/' + resourceId + '/file/' + fileName,
             'method': req.method         
         }            
         return proxyRequest(**kwargs)
def getCollectionRecords(req, resourceId):
    if req.method != "GET":
        return HttpResponseNotAllowed(["GET"])

    kwargs = {"path": "/metadata/collection/" + resourceId + "/records/", "method": req.method}
    dbResponse = proxyRequest(**kwargs)
    if dbResponse.status_code == 200:
        return hide_unpublished(req.user, proxyRequest(**kwargs))
    else:
        return dbResponse
 def getResource(req, resourceType, resourceId):
     kwargs = {
         'path': '/metadata/' + resourceType + '/' + resourceId + '/',
         'method': req.method         
     }
     if resourceType == 'record':
         response = hide_unpublished(req.user, proxyRequest(**kwargs))
         if response.content == '':
             return HttpResponseForbidden('You do not have permission to view this resource')
         return response            
     else:
         return proxyRequest(**kwargs)
 def deleteFile(req, resourceId, fileName):
     if not can_edit(req.user, resourceId): 
         return HttpResponseForbidden('You do not have permission to edit this resource')
     
     kwargs = {
         'path': '/metadata/record/' + resourceId + '/file/' + fileName,
         'method': req.method         
     }
     return proxyRequest(**kwargs)
def viewRecord(req, resourceId, viewFormat):
    if req.method != 'GET':
        return HttpResponseNotAllowed(['GET'])
    
    kwargs = {
        'path': '/metadata/record/' + resourceId + '.' + viewFormat,
        'method': req.method         
    }
    return hide_unpublished(req.user, proxyRequest(**kwargs), viewFormat)
 def getFiles(req, resourceId):
     res = get_object_or_404(Resource, metadata_id=resourceId)
     if res.can_view(req.user):            
         kwargs = {
             'path': '/metadata/record/' + resourceId + '/file/',
             'method': req.method         
         }
         return proxyRequest(**kwargs)
     else:
         return HttpResponseForbidden('You cannot view this resource.')            
def viewRecords(req, viewFormat):
    if req.method != 'GET':
        return HttpResponseNotAllowed(['GET'])
    
    kwargs = {
        'path': '/metadata/record.' + viewFormat,
        'method': req.method         
    }
    if viewFormat == 'iso.xml': viewFormat = 'waf'
    return hide_unpublished(req.user, proxyRequest(**kwargs), viewFormat)
def allSchemas(req):
    allowed = [ 'GET' ]
    if req.method not in allowed:
        return HttpResponseNotAllowed(allowed)
    
    kwargs = {
        'path': '/metadata/schema/',
        'method': req.method         
    } 
    return proxyRequest(**kwargs)
 def deleteResource(req, resourceType, resourceId):
     if not can_edit(req.user, resourceId, resourceType): 
         return HttpResponseForbidden('You do not have permission to edit this resource')
     
     kwargs = {
         'path': '/metadata/' + resourceType + '/' + resourceId + '/',
         'method': req.method         
     }
     original = proxyRequest(kwargs['path'], 'GET')
     if original.status_code == 200: content = json.loads(original.content)        
     response = proxyRequest(**kwargs)
     if response.status_code == 204:
         kwargs = {
             'user': req.user,
             'resourceId': resourceId,
             'content': content,
             'resourceType': resourceType,
             'isDelete': True        
         }
         track_resource(**kwargs)
     return response
def harvestRecord(req):
    if req.method != 'POST':
        return HttpResponseNotAllowed(['POST'])
    
    kwargs = {
        'path': '/metadata/harvest/',
        'method': req.method,
        'body': req.body,
        'headers': { 'Content-Type': 'application/json' }          
    }
    response = proxyRequest(**kwargs)
    if response.status_code == 200:
        # Track the newly created resources
        content = json.loads(response.content)
        for res in content:
            loc = res.strip('/').split('/')
            kwargs = {
                'user': req.user,
                'resourceId': loc.pop(),
                'content': json.loads(proxyRequest(res, 'GET').content)          
            }
            track_resource(**kwargs)
    return response
def oneSchema(req, schemaId):
    allowed = [ 'GET' ]
    if req.method not in allowed:
        return HttpResponseNotAllowed(allowed)
    
    path = '/metadata/schema/' + urllib.quote_plus(schemaId.encode("utf-8")) + '/'
    if req.GET.get('resolve', False):
        path = '%s?resolve=%s' % (path, req.GET.get('resolve'))
    if req.GET.get('emptyInstance', False):
        path = '%s?emptyInstance=%s' % (path, req.GET.get('emptyInstance'))
    
    kwargs = {
        'path': path,
        'method': req.method         
    }
    return proxyRequest(**kwargs)
def search(req): # Filter out unpublished? Tricky with the limit/skip and count parts of search results.
    if req.method != 'POST':
        return HttpResponseNotAllowed(['POST'])
    
    # Adjust the search to return ALL results, but record the limit and skip params
    search = json.loads(req.body)
    requestedLimit = search.get('limit', None)
    requestedSkip = search.get('skip', 0)
    try: del search['limit']
    except KeyError: pass
    try: del search['skip']
    except KeyError: pass
    
    # Perform a search that returns all the results
    fullSearch = json.dumps(search)    
    kwargs = {
        'path': '/metadata/search/',
        'method': req.method,
        'body': fullSearch,
        'headers': { 'Content-Type': 'application/json' }          
    }    
    fullResult = json.loads(proxyRequest(**kwargs).content)
    
    # Filter the full result set based on user permissions
    filteredResults = []
    for result in [ res['doc'] for res in fullResult['rows'] ]:
        try:
            res = Resource.objects.get(metadata_id=result['_id'])
            if res.can_view(req.user):
                filteredResults.append(result)
        except Resource.DoesNotExist:
            pass
        
    # Build the response, applying the original limit and skip parameters
    if requestedLimit: requestedLimit = requestedSkip + requestedLimit
    results = {
        'total_rows': len(filteredResults),
        'results': filteredResults[requestedSkip:requestedLimit],
        'skip': requestedSkip          
    }    
    
    return HttpResponse(json.dumps(results), content_type='application/json')
 def updateResource(req, resourceType, resourceId):
     if not can_edit(req.user, resourceId, resourceType): 
         return HttpResponseForbidden('You do not have permission to edit this resource')
     
     kwargs = {
         'path': '/metadata/' + resourceType + '/' + resourceId + '/',
         'method': req.method,
         'body': req.body,
         'headers': { 'Content-Type': 'application/json' }          
     }
     response = proxyRequest(**kwargs)
     if response.status_code == 204:
         kwargs = {
             'user': req.user,
             'resourceId': resourceId,
             'content': json.loads(req.body),
             'resourceType': resourceType          
         }
         track_resource(**kwargs)
     return response
 def newResource(req, resourceType):
     body = json.loads(req.body)
     body['MetadataContact'] = req.user.get_profile().to_contact()
     
     kwargs = {
         'path': '/metadata/' + resourceType + '/',
         'method': req.method,
         'body': json.dumps(body),
         'headers': { 'Content-Type': 'application/json' }          
     }
     response = proxyRequest(**kwargs)
     if response.status_code == 201:
         loc = response['Location'].strip('/').split('/')
         kwargs = {
             'user': req.user,
             'resourceId': loc.pop(),
             'content': json.loads(req.body),
             'resourceType': resourceType          
         }
         track_resource(**kwargs)
     return response
def make_published(modeladmin, request, queryset):
    # Have to update CouchDB too...
    class DummyRequest():
        def __init__(self, method, user, body="{}"):
            self.method = method
            self.user = user
            self.body = body

    for record in queryset:
        # Get the full Record
        kwargs = {
            'path': '/metadata/record/' + record.metadata_id + '/',
            'method': 'GET'
        }
        original = proxyRequest(**kwargs)

        # Update it
        final = json.loads(original.content)
        final["Published"] = True

        # Send the update
        update = DummyRequest("PUT", request.user, json.dumps(final))
        result = oneResource(update, "record", record.metadata_id)
        print result
def uploadRecord(req):
    if req.method != 'POST':
        return HttpResponseNotAllowed(['POST'])
    
    collections = req.POST['collection'].replace(' ', '').split(',')
    uploadFormat = req.POST['uploadFormat']
    
    """
    decode_data_dict function is to identify 
        if the given dictionary can be decoded with the listed formats  
    """
    def decode_data_dict(data_dict):
        encodings = ["ascii", "utf8", "cp1252"]
        jDict = None
        for encoding in encodings:
            try:
                jDict = json.dumps(data_dict, encoding=encoding)
                break
            except:
                continue
    
        if jDict:
            return jDict
        else:
            return HttpResponse('Cannot decode the data to ' + ', '.join(encodings) + '!')
    
    """
    parseCSV function is to read csv file,
        and return a list of records
    """
    
    def parseCSV(rows):
        requiredFields = [
          'title', 'description', 'publication_date', 'north_bounding_latitude',
          'south_bounding_latitude', 'east_bounding_longitude', 'west_bounding_longitude',
          'metadata_contact_org_name', 'metadata_contact_email', 'originator_contact_org_name',
          'originator_contact_person_name', 'originator_contact_position_name', 'originator_contact_email',
          'originator_contact_phone', 'metadata_uuid', 'metadata_date'
        ]
        isTitleRow = True
        fields = []
        data = []
        for row in rows:
            if isTitleRow:
                for rf in requiredFields:
                    if rf not in row:
                        return HttpResponse('Your uploaded CSV lost ' + rf + ' field!')
                for f in row:
                    fields.append(f)
                isTitleRow = False
            else:
                if len(row) != len(fields):
                    return HttpResponse('Data have extra fields which cannot be identified!')
                else:
                    record = {}
                    for i, val in enumerate(row):
                        record[fields[i]] = val
                    data.append(record)
        return data
    
    ids = []
    files = req.FILES.getlist('file')
    
    for f in files:
        data = ""
        """
        If the format of the uploaded file is CSV, read the file using parseCSV function.
        Otherwise, read the file content as a string.
        """
        if uploadFormat == 'csv':
            data = parseCSV(csv.reader(f))
            if type(data) != list:
                return data
        else:
            data = f.read()       
        
        """
        Construct the data dictionary for the proxy request,
            and determine if the dictionary can be converted to a json object
        """
        bodyDict = {
            "destinationCollections": collections,
            "format": uploadFormat,
            "data": data
        }
        
        jBodyDict = decode_data_dict(bodyDict)
    
        kwargs = {
            'path': '/metadata/upload/',
            'method': req.method,
            'body': jBodyDict,
            'headers': { 'Content-Type': 'application/json' }          
        }
        response = proxyRequest(**kwargs)
    
        if response.status_code == 200:
            """
            Keep Django database update with CouchDB
            """
            content = json.loads(response.content)
            for res in content:
                loc = res.strip('/').split('/')
                meta_id = loc.pop()
                kwargs = {
                    'user': req.user,
                    'resourceId': meta_id,
                    'content': json.loads(proxyRequest(res, 'GET').content)          
                }
                track_resource(**kwargs)
                ids.append(meta_id)
        else:
            return response
    numIDs = len(ids)
    context = {'newResources': ids, 'num': numIDs}    
    return render(req, 'repository/upload-results.jade', context)
  
        
def get_metadata(resource):
    return proxyRequest('/metadata/record/%s/' % resource.metadata_id, 'GET').content
Exemple #19
0
def sync():
    # Purge existing data
    Resource.objects.all().delete()
    ResourceCollection.objects.all().delete()
    Contact.objects.all().delete()

    # Retrieve all the metadata collections from CouchDB
    collectionResponse = proxyRequest("/metadata/collection/", "GET")
    collections = json.loads(collectionResponse.content)

    # Create a ResourceCollection for each one
    for collection in collections:
        try:
            col = ResourceCollection.objects.get(collection_id=collection["id"])
            col.title = collection["Title"]
            col.description = collection.get("Description", "")
            col.save()
        except ResourceCollection.DoesNotExist:
            col = ResourceCollection.objects.create(
                collection_id=collection["id"], title=collection["Title"], description=collection.get("Description", "")
            )

    # Add parent collections, needs to be done in a separate loop so that all parents are already in place
    for collection in collections:
        col = ResourceCollection.objects.get(collection_id=collection["id"])
        for parentId in collection.get("ParentCollections", []):
            try:
                par = ResourceCollection.objects.get(collection_id=parentId)
                col.parents.add(par)
            except ResourceCollection.DoesNotExist:
                pass

    # Retrieve all the metadata records from CouchDB
    recordResponse = proxyRequest("/metadata/record/", "GET")
    records = json.loads(recordResponse.content)

    # Create a Resource for each one
    for record in records:
        try:
            res = Resource.objects.get(metadata_id=record["id"])
            res.title = record["Title"]
            res.published = record["Published"]
            res.save()
        except Resource.DoesNotExist:
            res = Resource.objects.create(
                metadata_id=record["id"], title=record["Title"], published=record.get("Published", False)
            )

        # Add the Resource to the appropriate ResourceCollections
        for collection_id in record.get("Collections", []):
            try:
                col = ResourceCollection.objects.get(collection_id=collection_id)
                res.collections.add(col)
            except ResourceCollection.DoesNotExist:
                pass

        # Contact tracking
        contacts = record["Authors"] + record["Distributors"]
        for contact in contacts:
            personName = contact.get("Name", "No Name Was Given")
            orgName = contact.get("OrganizationName", "No Name Was Given")
            if personName in ["No Name Was Given", ""]:
                name = orgName
            else:
                name = personName

            try:
                Contact.objects.get(name=name)
            except Contact.DoesNotExist:
                Contact.objects.create(name=name, json=json.dumps(contact))