示例#1
0
def nodes_download(request):
    """
    Download multiple nodes (documents and folders) packed
    as tar.gz archive.
    """

    node_ids = request.GET.getlist('node_ids[]')
    nodes = BaseTreeNode.objects.filter(id__in=node_ids)
    nodes_perms = request.user.get_perms_dict(nodes, Access.ALL_PERMS)
    for node in nodes:
        if not nodes_perms[node.id].get(Access.PERM_READ, False):
            msg = _("%s does not have permission to read %s") % (
                request.user.username, node.title)

            return msg, HttpResponseForbidden.status_code

    with NamedTemporaryFile(prefix="download_") as fileobj:
        build_tar_archive(fileobj=fileobj, node_ids=node_ids)
        # reset fileobj to initial position
        fileobj.seek(0)
        data = fileobj.read()
        resp = HttpResponse(data, content_type="application/x-tar")
        disposition = "attachment; filename=download.tar"
        resp['Content-Disposition'] = disposition

        return resp
示例#2
0
def node_download(request, id):
    """
    Any user with read permission on the node must be
    able to download it.

    Node is either documennt or a folder.
    """
    version = request.GET.get('version', None)

    try:
        node = BaseTreeNode.objects.get(id=id)
    except BaseTreeNode.DoesNotExist:
        raise Http404("Node does not exists")

    if request.user.has_perm(Access.PERM_READ, node):

        if node.is_document():
            try:
                file_handle = open(default_storage.abspath(
                    node.path().url(version=version)
                ), "rb")
            except OSError:
                logger.error(
                    "Cannot open local version of %s" % node.path.url()
                )
                return redirect('admin:browse')

            resp = HttpResponse(
                file_handle.read(),
                content_type="application/pdf"
            )
            disposition = "attachment; filename=%s" % node.title
            resp['Content-Disposition'] = disposition
            file_handle.close()

            return resp
        else:  # node is a folder

            with NamedTemporaryFile(prefix="download_") as fileobj:
                # collected into an archive all direct children of
                # selected folder
                node_ids = [_node.id for _node in node.get_children()]
                build_tar_archive(
                    fileobj=fileobj,
                    node_ids=node_ids
                )
                # reset fileobj to initial position
                fileobj.seek(0)
                data = fileobj.read()
                resp = HttpResponse(
                    data,
                    content_type="application/x-tar"
                )
                disposition = f"attachment; filename={node.title}.tar"
                resp['Content-Disposition'] = disposition

                return resp

    return HttpResponseForbidden()
示例#3
0
    def test_basic_two_folders(self):
        """
        Creates following hierarchy:

            + Folder_1
            +   berlin_f_1.pdf
            + Folder_2
            +   berlin_f_2.pdf
            + berlin_root_1.pdf
            + berlin_root_2.pdf
        """
        f1 = Folder.objects.create(title='Folder_1',
                                   parent=None,
                                   user=self.testcase_user)
        f2 = Folder.objects.create(title='Folder_2',
                                   parent=None,
                                   user=self.testcase_user)

        document_path = os.path.join(BASE_DIR, "data", "berlin.pdf")

        doc_in_root_1 = Document.objects.create_document(
            user=self.testcase_user,
            title='berlin_root_1.pdf',
            size=os.path.getsize(document_path),
            lang='deu',
            file_name='berlin_root_1.pdf',
            page_count=3)
        default_storage.copy_doc(
            src=document_path,
            dst=doc_in_root_1.path.url(),
        )

        doc_in_root_2 = Document.objects.create_document(
            user=self.testcase_user,
            title='berlin_root_2.pdf',
            size=os.path.getsize(document_path),
            lang='deu',
            file_name='berlin_root_2.pdf',
            page_count=3)
        default_storage.copy_doc(
            src=document_path,
            dst=doc_in_root_2.path.url(),
        )

        doc_in_f_1 = Document.objects.create_document(
            user=self.testcase_user,
            title='berlin_f_1.pdf',
            size=os.path.getsize(document_path),
            lang='deu',
            parent_id=f1.id,
            file_name='berlin_f_1.pdf',
            page_count=3)
        default_storage.copy_doc(
            src=document_path,
            dst=doc_in_f_1.path.url(),
        )

        doc_in_f_2 = Document.objects.create_document(
            user=self.testcase_user,
            title='berlin_f_2.pdf',
            size=os.path.getsize(document_path),
            lang='deu',
            parent_id=f2.id,
            file_name='berlin_f_2.pdf',
            page_count=3)
        default_storage.copy_doc(
            src=document_path,
            dst=doc_in_f_2.path.url(),
        )
        """
        User selected two documents in the root dir berlin_root_1.pdf,
        and berlin_root_1.pdf plus Folder_1 and Folder_2.
        Selection is marked with square brackets [...]

            + [Folder_1]
            +   berlin_f_1.pdf
            + [Folder_2]
            +   berlin_f_2.pdf
            + [berlin_root_1.pdf]
            + [berlin_root_2.pdf]
        """
        selected_ids = [doc_in_root_1.id, doc_in_root_2.id, f1.id, f2.id]

        with io.BytesIO() as memoryfile:
            build_tar_archive(  # <-- THIS IS WHAT WE ARE TESTING
                fileobj=memoryfile,
                node_ids=selected_ids)
            memoryfile.seek(0)
            archive_file = tarfile.open(fileobj=memoryfile, mode='r')
            berlin_root_1_handle = archive_file.extractfile(
                'berlin_root_1.pdf')
            data = berlin_root_1_handle.read()
            self.assertTrue(len(data) > 0)

            berlin_f_1_handle = archive_file.extractfile(
                'Folder_1/berlin_f_1.pdf')
            data = berlin_f_1_handle.read()
            self.assertTrue(len(data) > 0)

            berlin_f_2_handle = archive_file.extractfile(
                'Folder_2/berlin_f_2.pdf')
            data = berlin_f_2_handle.read()
            self.assertTrue(len(data) > 0)

            with self.assertRaises(KeyError):
                # there is no file Accounting/Expenses/Paris.pdf
                # in archive, thus, KeyError exception is expected
                archive_file.extractfile('Accounting/Expenses/Paris.pdf')