def dataset_view(request, siloname, id):
    if not granary.issilo(siloname):
        raise Http404
    
    rdfsilo = granary.get_rdf_silo(siloname)
    if not rdfsilo.exists(id):
        raise Http404
            
    c = Context()
    silo = siloname
    #tmpl_context variables needed: c.silo_name, c.zipfiles, c.ident, c.id, c.path
    c.silo_name = siloname
    c.id = id
    ident = request.user
    c.ident = ident.username
    dataset = rdfsilo.get_item(id)

    creator = None
    if dataset.manifest and dataset.manifest.state and 'metadata' in dataset.manifest.state and dataset.manifest.state['metadata'] and \
                                   'createdby' in dataset.manifest.state['metadata'] and dataset.manifest.state['metadata']['createdby']:
        creator = dataset.manifest.state['metadata']['createdby']

    http_method = request.method
        
    if http_method == "GET":
        c.editor = False
        if settings.METADATA_EMBARGOED:
            if not ident:
                return HttpResponse("Not Authorised", status=401)
            silos = authz(ident)
            if silo not in silos:
                return HttpResponseForbidden("Forbidden")
            silos_admin = authz(ident, permission='administrator')
            silos_manager = authz(ident, permission='manager')
            if c.ident == creator or silo in silos_admin or silo in silos_manager:
                c.editor = True
        elif ident:
            silos = authz(ident)
            if silo in silos:
                silos_admin = authz(ident, permission='administrator')
                silos_manager = authz(ident, permission='manager')
                if ident['repoze.who.userid'] == creator or silo in silos_admin or silo in silos_manager:
                    c.editor = True
    else:
        #identity management of item 
        if not ident:
            return HttpResponse("Not Authorised", status=401)
        silos = authz(ident)      
        if silo not in silos:
            return HttpResponseForbidden("Forbidden")
        silos_admin = authz(ident, permission='administrator')
        silos_manager = authz(ident, permission='manager')
        if not (c.ident == creator or silo in silos_admin or silo in silos_manager):
            return HttpResponseForbidden("Forbidden")

    if http_method == "GET":
        c.zipfiles = get_zipfiles_in_dataset(dataset)
        # conneg return
        accept_list = None
        if 'HTTP_ACCEPT' in request.META:
            try:
                accept_list = conneg_parse(request.META['HTTP_ACCEPT'])
            except:
                accept_list= [MT("text", "html")]
        if not accept_list:
            accept_list= [MT("text", "html")]
        mimetype = accept_list.pop(0)
        while(mimetype):
            if str(mimetype).lower() in ["text/html", "text/xhtml"]:
                return render_to_response("/list_of_zipfiles.html", {'c':c,})
            elif str(mimetype).lower() in ["text/plain", "application/json"]:
                return HttpResponse(json.dumps(list(c.zipfiles.keys())), 
                                    mimetype = 'application/json; charset="UTF-8"')
            try:
                mimetype = accept_list.pop(0)
            except IndexError:
                mimetype = None
        #Whoops nothing satisfies - return text/html            
        return render_to_response("/list_of_zipfiles.html", {'c':c,})
    elif http_method == "POST":
        params = request.POST
        if not (params.has_key("filename") and params['filename']):
            return HttpResponse("You must supply a filename to unpack", status=400)

        item_real_filepath = dataset.to_dirpath()
        target_filepath = "%s/%s"%(item_real_filepath, params['filename'])
        if not os.path.isfile(target_filepath):
            return HttpResponse("File to unpack not found", status=404)
        if not check_file_mimetype(target_filepath, 'application/zip'):
            return HttpResponse("File is not of type application/zip", status=415)

        if params.has_key("id") and params['id']:
            target_dataset_name = params['id']
        else:
            target_dataset_name = id

        #step 1: Create / initialize target dataset 
        if not rdfsilo.exists(target_dataset_name):
            if not allowable_id2(target_dataset_name):
                return HttpResponse("Data package name can contain only the following characters - %s and has to be more than 1 character"%ag.naming_rule_humanized,
                                    status=400,
                                    mimetype="text/plain")
            target_dataset = create_new(rdfsilo, target_dataset_name, c.ident)
            hr = HttpResponse("Created",
                                status=201,
                                mimetype="text/plain")
            hr["Content-Location"] = reverse("dataset_view", kwargs={'siloname': siloname, 'id': target_dataset_name})
        else:
            hr = HttpResponse("204 Updated",
                                status=204,
                                mimetype="text/plain")
            target_dataset = rdfsilo.get_item(target_dataset_name)

        #step 2: Unpack zip item 
            
        try:
            unpack_zip_item(target_dataset, dataset, params['filename'], rdfsilo, c.ident)
        except BadZipfile:
            return HttpResponse("BadZipfile: Couldn't unpack zipfile", status=400, mimetype="text/plain")

        # FIXME: err.. wat is this?!
        target_dataset.sync()
        target_dataset.sync()
        target_dataset.sync()

        if hr.status == 201:
            try:
                b.creation(silo, id, ident=c.ident)
            except:
                pass
        else:
            try:
                b.change(silo, id, ident=c.ident)
            except:
                pass

        # conneg return
        accept_list = None
        if 'HTTP_ACCEPT' in request.META:
            try:
                accept_list = conneg_parse(request.META['HTTP_ACCEPT'])
            except:
                accept_list= [MT("text", "html")]
        if not accept_list:
            accept_list= [MT("text", "html")]
        mimetype = accept_list.pop(0)
        while(mimetype):
            if str(mimetype).lower() in ["text/html", "text/xhtml"]:
                return redirect(reverse("dataset_view", kwargs={'silo': silo, 'id': id}))
            elif str(mimetype).lower() in ["text/plain", "application/json"]:
                hr.mimetype = "text/plain"
                return hr
            try:
                mimetype = accept_list.pop(0)
            except IndexError:
                mimetype = None
        # Whoops - nothing satisfies - return text/plain
        hr.mimetype = "text/plain"
        return hr
Example #2
0
def dataset_view(request, siloname, id):
    if not granary.issilo(siloname):
        raise Http404

    rdfsilo = granary.get_rdf_silo(siloname)
    if not rdfsilo.exists(id):
        raise Http404

    c = Context()
    silo = siloname
    #tmpl_context variables needed: c.silo_name, c.zipfiles, c.ident, c.id, c.path
    c.silo_name = siloname
    c.id = id
    ident = request.user
    c.ident = ident.username
    dataset = rdfsilo.get_item(id)

    creator = None
    if dataset.manifest and dataset.manifest.state and 'metadata' in dataset.manifest.state and dataset.manifest.state['metadata'] and \
                                   'createdby' in dataset.manifest.state['metadata'] and dataset.manifest.state['metadata']['createdby']:
        creator = dataset.manifest.state['metadata']['createdby']

    http_method = request.method

    if http_method == "GET":
        c.editor = False
        if settings.METADATA_EMBARGOED:
            if not ident:
                return HttpResponse("Not Authorised", status=401)
            silos = authz(ident)
            if silo not in silos:
                return HttpResponseForbidden("Forbidden")
            silos_admin = authz(ident, permission='administrator')
            silos_manager = authz(ident, permission='manager')
            if c.ident == creator or silo in silos_admin or silo in silos_manager:
                c.editor = True
        elif ident:
            silos = authz(ident)
            if silo in silos:
                silos_admin = authz(ident, permission='administrator')
                silos_manager = authz(ident, permission='manager')
                if ident[
                        'repoze.who.userid'] == creator or silo in silos_admin or silo in silos_manager:
                    c.editor = True
    else:
        #identity management of item
        if not ident:
            return HttpResponse("Not Authorised", status=401)
        silos = authz(ident)
        if silo not in silos:
            return HttpResponseForbidden("Forbidden")
        silos_admin = authz(ident, permission='administrator')
        silos_manager = authz(ident, permission='manager')
        if not (c.ident == creator or silo in silos_admin
                or silo in silos_manager):
            return HttpResponseForbidden("Forbidden")

    if http_method == "GET":
        c.zipfiles = get_zipfiles_in_dataset(dataset)
        # conneg return
        accept_list = None
        if 'HTTP_ACCEPT' in request.META:
            try:
                accept_list = conneg_parse(request.META['HTTP_ACCEPT'])
            except:
                accept_list = [MT("text", "html")]
        if not accept_list:
            accept_list = [MT("text", "html")]
        mimetype = accept_list.pop(0)
        while (mimetype):
            if str(mimetype).lower() in ["text/html", "text/xhtml"]:
                return render_to_response("/list_of_zipfiles.html", {
                    'c': c,
                })
            elif str(mimetype).lower() in ["text/plain", "application/json"]:
                return HttpResponse(
                    json.dumps(list(c.zipfiles.keys())),
                    mimetype='application/json; charset="UTF-8"')
            try:
                mimetype = accept_list.pop(0)
            except IndexError:
                mimetype = None
        #Whoops nothing satisfies - return text/html
        return render_to_response("/list_of_zipfiles.html", {
            'c': c,
        })
    elif http_method == "POST":
        params = request.POST
        if not (params.has_key("filename") and params['filename']):
            return HttpResponse("You must supply a filename to unpack",
                                status=400)

        item_real_filepath = dataset.to_dirpath()
        target_filepath = "%s/%s" % (item_real_filepath, params['filename'])
        if not os.path.isfile(target_filepath):
            return HttpResponse("File to unpack not found", status=404)
        if not check_file_mimetype(target_filepath, 'application/zip'):
            return HttpResponse("File is not of type application/zip",
                                status=415)

        if params.has_key("id") and params['id']:
            target_dataset_name = params['id']
        else:
            target_dataset_name = id

        #step 1: Create / initialize target dataset
        if not rdfsilo.exists(target_dataset_name):
            if not allowable_id2(target_dataset_name):
                return HttpResponse(
                    "Data package name can contain only the following characters - %s and has to be more than 1 character"
                    % ag.naming_rule_humanized,
                    status=400,
                    mimetype="text/plain")
            target_dataset = create_new(rdfsilo, target_dataset_name, c.ident)
            hr = HttpResponse("Created", status=201, mimetype="text/plain")
            hr["Content-Location"] = reverse("dataset_view",
                                             kwargs={
                                                 'siloname': siloname,
                                                 'id': target_dataset_name
                                             })
        else:
            hr = HttpResponse("204 Updated", status=204, mimetype="text/plain")
            target_dataset = rdfsilo.get_item(target_dataset_name)

        #step 2: Unpack zip item

        try:
            unpack_zip_item(target_dataset, dataset, params['filename'],
                            rdfsilo, c.ident)
        except BadZipfile:
            return HttpResponse("BadZipfile: Couldn't unpack zipfile",
                                status=400,
                                mimetype="text/plain")

        # FIXME: err.. wat is this?!
        target_dataset.sync()
        target_dataset.sync()
        target_dataset.sync()

        if hr.status == 201:
            try:
                b.creation(silo, id, ident=c.ident)
            except:
                pass
        else:
            try:
                b.change(silo, id, ident=c.ident)
            except:
                pass

        # conneg return
        accept_list = None
        if 'HTTP_ACCEPT' in request.META:
            try:
                accept_list = conneg_parse(request.META['HTTP_ACCEPT'])
            except:
                accept_list = [MT("text", "html")]
        if not accept_list:
            accept_list = [MT("text", "html")]
        mimetype = accept_list.pop(0)
        while (mimetype):
            if str(mimetype).lower() in ["text/html", "text/xhtml"]:
                return redirect(
                    reverse("dataset_view", kwargs={
                        'silo': silo,
                        'id': id
                    }))
            elif str(mimetype).lower() in ["text/plain", "application/json"]:
                hr.mimetype = "text/plain"
                return hr
            try:
                mimetype = accept_list.pop(0)
            except IndexError:
                mimetype = None
        # Whoops - nothing satisfies - return text/plain
        hr.mimetype = "text/plain"
        return hr
def silo_view(request, siloname):
    """
GET: Obtain a list of datasets in a silo

Returns
401 if not a valid user
403 if not authorized
Accept:text/html
Returns the ids of each dataset in the silo, along with a form for changing the embargo information and deleting the dataset. A form for dataset creation is also available.
Accept: text/plain, application/json
200 OK
Returns a JSON-encoded list of dataset ids in that silo along with the embargo information for each dataset
The file datasetsInSiloInformation.txt contains an example of the data returned (data_returned)
Accept:*/*, default
Returns text/HTML listing the ids of each dataset, along with a form for changing the embargo information and deleting the dataset. A form for dataset creation is also available.
    """
    if not granary.issilo(siloname):
        # No silo here
        response = HttpResponse()
        response.status_code = 404
        return response
        
    # Deal with request methods - GET then POST
    if request.method == "GET":
        c = create_context(request.user)
        
        c.silo_name = siloname

        # FIXME: Make these unhardcoded
        if siloname in ['ww1archives', 'digitalbooks']:
            abort(501, "The silo %s contains too many data packages to list"%siloname)
        c.editor = False
        
        c.read_state = can_read(request.user, siloname)
        
        if state == MDONLY:
            if settings.METADATA_EMBARGOED:
                # Forbidden
                response = HttpResponse()
                response.status_code = 403
                return response

        if can_write(request.user, siloname):
            c.editor = True

        options = request.REQUEST
        c.start = 0
        if 'start' in options and options['start']:
            try:
                c.start = int(options['start'])
            except ValueError:
                c.start = 0
        c.rows = 100
        if 'rows' in options and options['rows']:
            try:
                c.rows = int(options['rows'])
            except ValueError:
                c.rows = 100
                
                     
        c_silo = granary.get_rdf_silo(siloname)
        # Get title of silo
        state_info = granary.describe_silo(siloname)
        if 'title' in state_info and state_info['title']:
            c.title = state_info['title']
        # Get number of data packages in silo
        numFound = get_datasets_count(siloname)
        try:
            c.numFound = int(numFound)
        except ValueError:
            c.numFound = 0

        c.embargos = {}
        # FIXME: A crushingly slow way to check?
        for item in get_datasets(siloname, start=c.start, rows=c.rows):
            try:
                c.embargos[item] = is_embargoed(c_silo, item)
            except:
                c.embargos[item] = None
        c.items = c.embargos.keys()
        
        # pagination
        c.permissible_offsets = []
        c.pages_to_show = 5
        try:
            remainder = c.numFound % c.rows
            if remainder > 0:
                c.lastPage = c.numFound - remainder
            else:
                c.lastPage = c.numFound - c.rows

            if c.numFound > c.rows:
                offset_start = c.start - ( (c.pages_to_show/2) * c.rows )
                if offset_start < 0:
                    offset_start = 0
   
                offset_end = offset_start + (c.pages_to_show * c.rows)
                if offset_end > c.numFound:
                    offset_end = c.numFound
                    if remainder > 0:
                        offset_start = c.lastPage - (c.pages_to_show * c.rows)
                    else:
                        offset_start = c.lastPage - ((c.pages_to_show-1) * c.rows)

                    if offset_start < 0:
                        offset_start = 0
                              
                c.permissible_offsets = list( xrange( offset_start, offset_end, c.rows) )
        except ValueError:
            # FIXME: Not a good solution, escaping here
            pass
            
        return render_html_or_json(request, c, '/siloview.html', c.embargos)
    elif request.method == "POST":
        """
POST: Create new dataset

Parameters
id	 {id to create}
embargoed	 {true|false} (optional).
If the parameter is not supplied, a default value of true will be used.
embargoed_until	 {ISO8601 date} (optional).
If embargoed = true and no date has been supplied, a default time delta of 70 years will be used
title	{(Optional)}
Returns
409 if dataset already exists 
401 If not a valid user 
403 if not authorized 
403 if the name of the dataset does not confirm to the naming rule (name can contain only the followin characters 0-9a-zA-Z-_:
Accept: text/html
302 to splash page for newly created dataset
Accept: text/plain, application/json
201 created
Accept: */*, default
Returns text/plain, 201 created
PUT, DELETE: NOOP
        """
                
        if not can_write(request.user, siloname):
            # Forbidden
            response = HttpResponse()
            response.status_code = 403
            return response
        else:
            params = request.POST.dict()

            if not params.has_key("id"):
                response = HttpResponse()
                response.status_code = 400
                response.content = "400 Bad Request: Parameter 'id' is not available"
                return response
                
            c_silo = granary.get_rdf_silo(siloname)        
            if c_silo.exists(params['id']):
                response = HttpResponse()
                response.status_code = 409
                response.content = "409 Conflict: Data package already exists"
                return response

            # Supported params:
            # id, title, embargoed, embargoed_until, embargo_days_from_now
            id = params['id']
            if not allowable_id2(id):
                response = HttpResponse()
                response.status_code = 400
                response.content = "400 Bad request. Data package name not valid"
                return response

            del params['id']
            item = create_new(c_silo, id, request.user.username, **params)
            add_dataset(siloname, id)
            # Broadcast change as message
            try:
                b.creation(siloname, id, ident=request.user.username)
            except:
                pass
                 
            # conneg return
            
            if "HTTP_ACCEPT" in request.META.keys():
                if str(request.META['HTTP_ACCEPT']).lower() in ["text/html", "text/xhtml"]:
                    redirect('datasets_main_view', siloname=siloname, id=id)
            
            response = HttpResponse()
            response.status_code = 201
            response.content = "201 Created"
            response['Content-Location'] = reverse('datasets_main_view', siloname=siloname, id=id)
            return response
Example #4
0
def silo_view(request, siloname):
    """
GET: Obtain a list of datasets in a silo

Returns
401 if not a valid user
403 if not authorized
Accept:text/html
Returns the ids of each dataset in the silo, along with a form for changing the embargo information and deleting the dataset. A form for dataset creation is also available.
Accept: text/plain, application/json
200 OK
Returns a JSON-encoded list of dataset ids in that silo along with the embargo information for each dataset
The file datasetsInSiloInformation.txt contains an example of the data returned (data_returned)
Accept:*/*, default
Returns text/HTML listing the ids of each dataset, along with a form for changing the embargo information and deleting the dataset. A form for dataset creation is also available.
    """
    if not granary.issilo(siloname):
        # No silo here
        response = HttpResponse()
        response.status_code = 404
        return response

    # Deal with request methods - GET then POST
    if request.method == "GET":
        c = create_context(request.user)

        c.silo_name = siloname

        # FIXME: Make these unhardcoded
        if siloname in ['ww1archives', 'digitalbooks']:
            abort(
                501, "The silo %s contains too many data packages to list" %
                siloname)
        c.editor = False

        c.read_state = can_read(request.user, siloname)

        if state == MDONLY:
            if settings.METADATA_EMBARGOED:
                # Forbidden
                response = HttpResponse()
                response.status_code = 403
                return response

        if can_write(request.user, siloname):
            c.editor = True

        options = request.REQUEST
        c.start = 0
        if 'start' in options and options['start']:
            try:
                c.start = int(options['start'])
            except ValueError:
                c.start = 0
        c.rows = 100
        if 'rows' in options and options['rows']:
            try:
                c.rows = int(options['rows'])
            except ValueError:
                c.rows = 100

        c_silo = granary.get_rdf_silo(siloname)
        # Get title of silo
        state_info = granary.describe_silo(siloname)
        if 'title' in state_info and state_info['title']:
            c.title = state_info['title']
        # Get number of data packages in silo
        numFound = get_datasets_count(siloname)
        try:
            c.numFound = int(numFound)
        except ValueError:
            c.numFound = 0

        c.embargos = {}
        # FIXME: A crushingly slow way to check?
        for item in get_datasets(siloname, start=c.start, rows=c.rows):
            try:
                c.embargos[item] = is_embargoed(c_silo, item)
            except:
                c.embargos[item] = None
        c.items = c.embargos.keys()

        # pagination
        c.permissible_offsets = []
        c.pages_to_show = 5
        try:
            remainder = c.numFound % c.rows
            if remainder > 0:
                c.lastPage = c.numFound - remainder
            else:
                c.lastPage = c.numFound - c.rows

            if c.numFound > c.rows:
                offset_start = c.start - ((c.pages_to_show / 2) * c.rows)
                if offset_start < 0:
                    offset_start = 0

                offset_end = offset_start + (c.pages_to_show * c.rows)
                if offset_end > c.numFound:
                    offset_end = c.numFound
                    if remainder > 0:
                        offset_start = c.lastPage - (c.pages_to_show * c.rows)
                    else:
                        offset_start = c.lastPage - (
                            (c.pages_to_show - 1) * c.rows)

                    if offset_start < 0:
                        offset_start = 0

                c.permissible_offsets = list(
                    xrange(offset_start, offset_end, c.rows))
        except ValueError:
            # FIXME: Not a good solution, escaping here
            pass

        return render_html_or_json(request, c, '/siloview.html', c.embargos)
    elif request.method == "POST":
        """
POST: Create new dataset

Parameters
id	 {id to create}
embargoed	 {true|false} (optional).
If the parameter is not supplied, a default value of true will be used.
embargoed_until	 {ISO8601 date} (optional).
If embargoed = true and no date has been supplied, a default time delta of 70 years will be used
title	{(Optional)}
Returns
409 if dataset already exists 
401 If not a valid user 
403 if not authorized 
403 if the name of the dataset does not confirm to the naming rule (name can contain only the followin characters 0-9a-zA-Z-_:
Accept: text/html
302 to splash page for newly created dataset
Accept: text/plain, application/json
201 created
Accept: */*, default
Returns text/plain, 201 created
PUT, DELETE: NOOP
        """

        if not can_write(request.user, siloname):
            # Forbidden
            response = HttpResponse()
            response.status_code = 403
            return response
        else:
            params = request.POST.dict()

            if not params.has_key("id"):
                response = HttpResponse()
                response.status_code = 400
                response.content = "400 Bad Request: Parameter 'id' is not available"
                return response

            c_silo = granary.get_rdf_silo(siloname)
            if c_silo.exists(params['id']):
                response = HttpResponse()
                response.status_code = 409
                response.content = "409 Conflict: Data package already exists"
                return response

            # Supported params:
            # id, title, embargoed, embargoed_until, embargo_days_from_now
            id = params['id']
            if not allowable_id2(id):
                response = HttpResponse()
                response.status_code = 400
                response.content = "400 Bad request. Data package name not valid"
                return response

            del params['id']
            item = create_new(c_silo, id, request.user.username, **params)
            add_dataset(siloname, id)
            # Broadcast change as message
            try:
                b.creation(siloname, id, ident=request.user.username)
            except:
                pass

            # conneg return

            if "HTTP_ACCEPT" in request.META.keys():
                if str(request.META['HTTP_ACCEPT']).lower() in [
                        "text/html", "text/xhtml"
                ]:
                    redirect('datasets_main_view', siloname=siloname, id=id)

            response = HttpResponse()
            response.status_code = 201
            response.content = "201 Created"
            response['Content-Location'] = reverse('datasets_main_view',
                                                   siloname=siloname,
                                                   id=id)
            return response