예제 #1
0
    def form_valid(self, form):
        """
        If the form is valid, save the associated model.
        """
        doc_form = form.cleaned_data

        file = doc_form.pop('doc_file', None)
        if file:
            tempdir = tempfile.mkdtemp(dir=settings.STATIC_ROOT)
            dirname = os.path.basename(tempdir)
            filepath = storage_manager.save(f"{dirname}/{file.name}", file)
            storage_path = storage_manager.path(filepath)
            self.object = resource_manager.update(
                self.object.uuid,
                instance=self.object,
                vals=dict(
                    owner=self.request.user,
                    files=[storage_path])
            )
            if tempdir != os.path.dirname(storage_path):
                shutil.rmtree(tempdir, ignore_errors=True)

        register_event(self.request, EventType.EVENT_CHANGE, self.object)
        url = hookset.document_detail_url(self.object)
        return HttpResponseRedirect(url)
예제 #2
0
def download_resource_file(url: str, target_name: str) -> str:
    """Download a resource file and store it using GeoNode's `storage_manager`.

    Downloads use the django `UploadedFile` helper classes. Depending on the size of the
    remote resource, we may download it into an in-memory buffer or store it on a
    temporary location on disk. After having downloaded the file, we use `storage_manager`
    to save it in the appropriate location.

    """

    response = requests.get(url, stream=True)
    response.raise_for_status()
    file_size = response.headers.get("Content-Length")
    content_type = response.headers.get("Content-Type")
    charset = response.apparent_encoding
    if file_size is not None and int(
            file_size) < config.HARVESTED_RESOURCE_FILE_MAX_MEMORY_SIZE:
        logger.debug("Downloading to an in-memory buffer...")
        file_ = uploadedfile.InMemoryUploadedFile(None, None, target_name,
                                                  content_type, file_size,
                                                  charset)
    else:
        logger.debug("Downloading to a temporary file...")
        file_ = uploadedfile.TemporaryUploadedFile(target_name, content_type,
                                                   file_size, charset)
    with file_.open("wb+") as fd:
        for chunk in response.iter_content(chunk_size=None,
                                           decode_unicode=False):
            fd.write(chunk)
        fd.seek(0)
        result = storage_manager.save(target_name, fd)
    return result
예제 #3
0
    def test_thumb_utils_methods(self, image):
        """
        Bunch of tests on thumb_utils helpers.
        """
        filename = 'test-thumb'
        upload_path = thumb_utils.thumb_path(filename)
        self.assertEqual(upload_path, os.path.join(settings.THUMBNAIL_LOCATION, filename))
        thumb_utils.remove_thumbs(filename)
        self.assertFalse(thumb_utils.thumb_exists(filename))
        f = BytesIO(test_image.tobytes())
        f.name = filename
        storage_manager.save(upload_path, File(f))
        self.assertTrue(thumb_utils.thumb_exists(filename))
        self.assertEqual(thumb_utils.thumb_size(upload_path), 10000)

        # cleanup: remove saved thumbnail
        thumb_utils.remove_thumbs(filename)
        self.assertFalse(thumb_utils.thumb_exists(filename))
예제 #4
0
파일: base.py 프로젝트: ridhodwid/geonode
def download_resource_file(url: str, target_name: str) -> Path:
    """Download a resource file and store it using GeoNode's `storage_manager`.

    Downloads use the django `UploadedFile` helper classes. Depending on the size of the
    remote resource, we may download it into an in-memory buffer or store it on a
    temporary location on disk. After having downloaded the file, we use `storage_manager`
    to save it in the appropriate location.

    """

    response = requests.get(url, stream=True)
    response.raise_for_status()
    file_size = response.headers.get("Content-Length")
    content_type = response.headers.get("Content-Type")
    charset = response.apparent_encoding
    size_threshold = config.get_setting(
        "HARVESTED_RESOURCE_FILE_MAX_MEMORY_SIZE")
    if file_size is not None and int(file_size) < size_threshold:
        logger.debug("Downloading to an in-memory buffer...")
        buf = io.BytesIO()
        file_ = uploadedfile.InMemoryUploadedFile(buf, None, target_name,
                                                  content_type, file_size,
                                                  charset)
    else:
        logger.debug("Downloading to a temporary file...")
        file_ = uploadedfile.TemporaryUploadedFile(target_name, content_type,
                                                   file_size, charset)
        # NOTE: there is no need to explicitly delete the file represented by
        # `file_`, it is being deleted implicitly
    with file_.open("wb+") as fd:
        for chunk in response.iter_content(chunk_size=None,
                                           decode_unicode=False):
            fd.write(chunk)
        fd.seek(0)
        if storage_manager.exists(target_name):
            logger.debug(f"file {target_name!r} already exists, replacing...")
            storage_manager.delete(target_name)
        file_name = storage_manager.save(target_name, fd)
        result = Path(storage_manager.path(file_name))
    return result
예제 #5
0
    def form_valid(self, form):
        """
        If the form is valid, save the associated model.
        """
        doc_form = form.cleaned_data

        file = doc_form.pop('doc_file', None)
        if file:
            tempdir = tempfile.mkdtemp(dir=settings.STATIC_ROOT)
            dirname = os.path.basename(tempdir)
            filepath = storage_manager.save(f"{dirname}/{file.name}", file)
            storage_path = storage_manager.path(filepath)
            self.object = resource_manager.create(
                None,
                resource_type=Document,
                defaults=dict(owner=self.request.user,
                              doc_url=doc_form.pop('doc_url', None),
                              title=doc_form.pop('title', file.name),
                              files=[storage_path]))
            if tempdir != os.path.dirname(storage_path):
                shutil.rmtree(tempdir, ignore_errors=True)
        else:
            self.object = resource_manager.create(
                None,
                resource_type=Document,
                defaults=dict(owner=self.request.user,
                              doc_url=doc_form.pop('doc_url', None),
                              title=doc_form.pop('title', None)))

        if settings.ADMIN_MODERATE_UPLOADS:
            self.object.is_approved = False
        if settings.RESOURCE_PUBLISHING:
            self.object.is_published = False

        resource_manager.set_permissions(
            None,
            instance=self.object,
            permissions=form.cleaned_data["permissions"],
            created=True)

        abstract = None
        date = None
        regions = []
        keywords = []
        bbox = None
        url = hookset.document_detail_url(self.object)

        out = {'success': False}

        if getattr(settings, 'EXIF_ENABLED', False):
            try:
                from geonode.documents.exif.utils import exif_extract_metadata_doc
                exif_metadata = exif_extract_metadata_doc(self.object)
                if exif_metadata:
                    date = exif_metadata.get('date', None)
                    keywords.extend(exif_metadata.get('keywords', []))
                    bbox = exif_metadata.get('bbox', None)
                    abstract = exif_metadata.get('abstract', None)
            except Exception:
                logger.debug("Exif extraction failed.")

        resource_manager.update(
            self.object.uuid,
            instance=self.object,
            keywords=keywords,
            regions=regions,
            vals=dict(abstract=abstract,
                      date=date,
                      date_type="Creation",
                      bbox_polygon=BBOXHelper.from_xy(bbox).as_polygon()
                      if bbox else None),
            notify=True)
        resource_manager.set_thumbnail(self.object.uuid,
                                       instance=self.object,
                                       overwrite=False)

        register_event(self.request, EventType.EVENT_UPLOAD, self.object)

        if self.request.GET.get('no__redirect', False):
            out['success'] = True
            out['url'] = url
            if out['success']:
                status_code = 200
            else:
                status_code = 400
            return HttpResponse(json.dumps(out),
                                content_type='application/json',
                                status=status_code)
        else:
            return HttpResponseRedirect(url)