示例#1
0
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)

        collections = permission_policy.collections_user_has_any_permission_for(
            self.request.user, ["add", "change"])
        if len(collections) < 2:
            collections = None

        Document = get_document_model()

        context.update({
            "search_form":
            self.form,
            "popular_tags":
            popular_tags_for_model(get_document_model()),
            "user_can_add":
            permission_policy.user_has_permission(self.request.user, "add"),
            "collections":
            collections,
            "current_collection":
            self.current_collection,
            "app_label":
            Document._meta.app_label,
            "model_name":
            Document._meta.model_name,
        })
        return context
示例#2
0
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)

        collections = permission_policy.collections_user_has_any_permission_for(
            self.request.user, ['add', 'change'])
        if len(collections) < 2:
            collections = None

        Document = get_document_model()

        context.update({
            'search_form':
            self.form,
            'popular_tags':
            popular_tags_for_model(get_document_model()),
            'user_can_add':
            permission_policy.user_has_permission(self.request.user, 'add'),
            'collections':
            collections,
            'current_collection':
            self.current_collection,
            'app_label':
            Document._meta.app_label,
            'model_name':
            Document._meta.model_name,
        })
        return context
    def test_filtering_tags(self):
        get_document_model().objects.get(id=3).tags.add('test')

        response = self.get_response(tags='test')
        content = json.loads(response.content.decode('UTF-8'))

        document_id_list = self.get_document_id_list(content)
        self.assertEqual(document_id_list, [3])
示例#4
0
    def test_tags(self):
        get_document_model().objects.get(id=1).tags.add("hello")
        get_document_model().objects.get(id=1).tags.add("world")

        response = self.get_response(1)
        content = json.loads(response.content.decode("UTF-8"))

        self.assertIn("tags", content["meta"])
        self.assertEqual(content["meta"]["tags"], ["hello", "world"])
    def test_tags(self):
        get_document_model().objects.get(id=1).tags.add('hello')
        get_document_model().objects.get(id=1).tags.add('world')

        response = self.get_response(1)
        content = json.loads(response.content.decode('UTF-8'))

        self.assertIn('tags', content['meta'])
        self.assertEqual(content['meta']['tags'], ['hello', 'world'])
示例#6
0
    def test_add_post_with_collections(self):
        """
        This tests that a POST request to the add view saves the document
        and returns an edit form, when collections are active
        """

        root_collection = Collection.get_first_root_node()
        evil_plans_collection = root_collection.add_child(name="Evil plans")

        response = self.client.post(
            reverse('wagtaildocs:add_multiple'), {
                'files[]': SimpleUploadedFile('test.png',
                                              b"Simple text document"),
                'collection': evil_plans_collection.id
            },
            HTTP_X_REQUESTED_WITH='XMLHttpRequest')

        # Check response
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response['Content-Type'], 'application/json')
        self.assertTemplateUsed(response,
                                'wagtaildocs/multiple/edit_form.html')

        # Check document
        self.assertIn('doc', response.context)
        self.assertEqual(response.context['doc'].title, 'test.png')
        self.assertTrue(response.context['doc'].file_size)
        self.assertTrue(response.context['doc'].file_hash)

        # check that it is in the 'evil plans' collection
        doc = get_document_model().objects.get(title='test.png')
        root_collection = Collection.get_first_root_node()
        self.assertEqual(doc.collection, evil_plans_collection)

        # Check form
        self.assertIn('form', response.context)
        self.assertEqual(
            set(response.context['form'].fields),
            set(get_document_model().admin_form_fields) - {'file'}
            | {'collection'},
        )
        self.assertEqual(response.context['form'].initial['title'], 'test.png')

        # Check JSON
        response_json = json.loads(response.content.decode())
        self.assertIn('doc_id', response_json)
        self.assertIn('form', response_json)
        self.assertIn('success', response_json)
        self.assertEqual(response_json['doc_id'], response.context['doc'].id)
        self.assertTrue(response_json['success'])

        # form should contain a collection chooser
        self.assertIn('Collection', response_json['form'])
示例#7
0
    def get_context_data(self, parent_context):
        site_name = get_site_for_user(self.request.user)["site_name"]

        return {
            "total_docs": get_document_model().objects.count(),
            "site_name": site_name,
        }
示例#8
0
    def test_limit_total_count(self):
        response = self.get_response(limit=2)
        content = json.loads(response.content.decode("UTF-8"))

        # The total count must not be affected by "limit"
        self.assertEqual(content["meta"]["total_count"],
                         get_document_model().objects.count())
示例#9
0
def DocumentsQuery():
    mdl = get_document_model()
    mdl_type = get_document_type()

    class Mixin:
        document = graphene.Field(mdl_type, id=graphene.ID())
        documents = QuerySetList(
            graphene.NonNull(mdl_type),
            enable_search=True,
            required=True,
            collection=graphene.Argument(
                graphene.ID, description="Filter by collection id"),
        )
        document_type = graphene.String(required=True)

        def resolve_document(self, info, id, **kwargs):
            """Returns a document given the id, if in a public collection"""
            try:
                return mdl.objects.filter(
                    collection__view_restrictions__isnull=True).get(pk=id)
            except BaseException:
                return None

        def resolve_documents(self, info, **kwargs):
            """Returns all documents in a public collection"""
            qs = mdl.objects.filter(collection__view_restrictions__isnull=True)
            return resolve_queryset(qs, info, **kwargs)

        def resolve_document_type(self, info, **kwargs):
            return get_document_type()

    return Mixin
示例#10
0
def add(request):
    Document = get_document_model()
    DocumentForm = get_document_form(Document)

    if request.method == 'POST':
        doc = Document(uploaded_by_user=request.user)
        form = DocumentForm(request.POST, request.FILES, instance=doc, user=request.user)
        if form.is_valid():
            doc.file_size = doc.file.size

            # Set new document file hash
            doc.file.seek(0)
            doc._set_file_hash(doc.file.read())
            doc.file.seek(0)

            form.save()

            # Reindex the document to make sure all tags are indexed
            search_index.insert_or_update_object(doc)

            messages.success(request, _("Document '{0}' added.").format(doc.title), buttons=[
                messages.button(reverse('wagtaildocs:edit', args=(doc.id,)), _('Edit'))
            ])
            return redirect('wagtaildocs:index')
        else:
            messages.error(request, _("The document could not be saved due to errors."))
    else:
        form = DocumentForm(user=request.user)

    return render(request, "wagtaildocs/documents/add.html", {
        'form': form,
    })
    def test_limit_max_none_gives_no_errors(self):
        response = self.get_response(limit=1000000)
        content = json.loads(response.content.decode('UTF-8'))

        self.assertEqual(response.status_code, 200)
        self.assertEqual(len(content['items']),
                         get_document_model().objects.count())
示例#12
0
    def get_context(self):
        site_name = get_site_for_user(self.request.user)['site_name']

        return {
            'total_docs': get_document_model().objects.count(),
            'site_name': site_name,
        }
示例#13
0
class DocumentBulkAction(BulkAction):
    permission_policy = documents_permission_policy
    models = [get_document_model()]

    def get_all_objects_in_listing_query(self, parent_id):
        listing_objects = self.model.objects.all()
        if parent_id is not None:
            listing_objects = listing_objects.filter(collection_id=parent_id)

        listing_objects = listing_objects.values_list('pk', flat=True)

        if 'q' in self.request.GET:
            query_string = self.request.GET.get('q', '')
            listing_objects = listing_objects.search(query_string).results()

        return listing_objects

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['items_with_no_access'] = [{
            'item':
            document,
            'can_edit':
            self.permission_policy.user_has_permission_for_instance(
                self.request.user, 'change', document)
        } for document in context['items_with_no_access']]
        return context
def import_documents(apps, schema_editor):
    documents = get_document_model().objects.all()
    with connection.cursor() as cursor:
        for wtdoc in WTDocument.objects.exclude(id__in=documents):
            cursor.execute(
                'Insert into wagtail_textract_document (document_ptr_id, transcription) values (%s, \'\')',
                [wtdoc.id])
示例#15
0
def delete(request, document_id):
    Document = get_document_model()
    doc = get_object_or_404(Document, id=document_id)

    if not permission_policy.user_has_permission_for_instance(
            request.user, "delete", doc):
        raise PermissionDenied

    next_url = get_valid_next_url_from_request(request)

    if request.method == "POST":
        doc.delete()
        messages.success(request,
                         _("Document '{0}' deleted.").format(doc.title))
        return redirect(next_url) if next_url else redirect(
            "wagtaildocs:index")

    return TemplateResponse(
        request,
        "wagtaildocs/documents/confirm_delete.html",
        {
            "document": doc,
            "next": next_url,
        },
    )
示例#16
0
def document_chosen(request, document_id):
    document = get_object_or_404(get_document_model(), id=document_id)

    return render_modal_workflow(
        request, None, None,
        None, json_data={'step': 'document_chosen', 'result': get_document_result_data(document)}
    )
示例#17
0
def serve_document_from_s3(document, request):
    """
    Download document from S3.

    This is to avoid reading the whole document by the Wagtail view
    and potentially risking DoS attack and the server timing out.
    """
    # Skip this hook if not using django-storages boto3 backend.
    if not issubclass(get_storage_class(), S3Boto3Storage):
        return

    # Send document_served signal, same as Wagtail does.
    # https://github.com/wagtail/wagtail/blob/7938e81ab48327a084ac1dced9474c998fd44c2d/wagtail/documents/views/serve.py#L32-L33
    document_served.send(sender=get_document_model(),
                         instance=document,
                         request=request)

    # Service file directly from S3.
    file_url = document.file.url

    # Generate redirect response and add never_cache headers.
    # Delete all existing headers.
    response = redirect(file_url)
    del response["Cache-control"]
    add_never_cache_headers(response)
    return response
示例#18
0
def get_document_model():
    warnings.warn(
        "wagtail.documents.models.get_document_model "
        "has been moved to wagtail.documents.get_document_model",
        RemovedInWagtail210Warning)
    from wagtail.documents import get_document_model
    return get_document_model()
    def test_offset_total_count(self):
        response = self.get_response(offset=10)
        content = json.loads(response.content.decode('UTF-8'))

        # The total count must not be affected by "offset"
        self.assertEqual(content['meta']['total_count'],
                         get_document_model().objects.count())
示例#20
0
    def setUp(self):
        self.login()

        # Create a document for running tests on
        self.doc = get_document_model().objects.create(
            title="Test document",
            file=get_test_document_file(),
        )
示例#21
0
def document_etag(request, document_id, document_filename):
    Document = get_document_model()
    if hasattr(Document, "file_hash"):
        return (
            Document.objects.filter(id=document_id)
            .values_list("file_hash", flat=True)
            .first()
        )
示例#22
0
 def setUpClass(cls):
     super().setUpClass()
     Document = get_document_model()
     fields = tuple(f for f in Document.admin_form_fields
                    if f != 'collection')
     cls.__patcher = mock.patch.object(Document, 'admin_form_fields',
                                       fields)
     cls.__patcher.start()
示例#23
0
    def test_deprecated_get_document_model(self):
        from wagtail.documents.models import Document
        from wagtail.documents.models import get_document_model
        with warnings.catch_warnings(record=True) as ws:
            warnings.simplefilter('always')

            self.assertIs(Document, get_document_model())
            self.assertEqual(len(ws), 1)
            self.assertIs(ws[0].category, RemovedInWagtail210Warning)
示例#24
0
def update_collection_document_acls(collection):
    acl = get_acl_for_collection(collection)
    documents = get_document_model().objects.filter(collection=collection)
    for document in documents:
        logger.debug(
            'Set document ACL to "%s" on "%s"',
            acl,
            document.file.name,
        )
        document.file.file.obj.Acl().put(ACL=acl)
示例#25
0
    def test_document_file_deleted_oncommit(self):
        with transaction.atomic():
            document = get_document_model().objects.create(
                title="Test Image", file=get_test_image_file())
            filename = document.file.name

            self.assertTrue(document.file.storage.exists(filename))
            document.delete()
            self.assertTrue(document.file.storage.exists(filename))
        self.assertFalse(document.file.storage.exists(filename))
示例#26
0
def get_user_documents(user, documents=None):
    """
    Return collections and documents for the user
    """
    collections = get_user_collections(user)
    if not documents:
        documents = get_document_model().objects.all()
    if not user.is_superuser:
        documents = documents.filter(collection__in=collections)

    return documents
示例#27
0
def usage(request, document_id):
    Document = get_document_model()
    doc = get_object_or_404(Document, id=document_id)

    paginator = Paginator(doc.get_usage(), per_page=20)
    used_by = paginator.get_page(request.GET.get('p'))

    return render(request, "wagtaildocs/documents/usage.html", {
        'document': doc,
        'used_by': used_by
    })
示例#28
0
 def resolve_search(self, info, **kwargs):
     query = kwargs.get("query")
     if query:
         s = get_search_backend()
         results = []
         models = [get_document_model(), get_image_model()]
         for app in registry.apps:
             models += apps.all_models[app].values()
         for model in models:
             results += s.search(query, model)
         return results
     return None
示例#29
0
def unregister_signal_handlers():
    Image = get_image_model()
    Document = get_document_model()

    for model in get_page_models():
        page_published.disconnect(purge_page_from_cache, sender=model)
        page_unpublished.disconnect(purge_page_from_cache, sender=model)

    post_save.disconnect(purge_image_from_cache, sender=Image)
    post_delete.disconnect(purge_image_from_cache, sender=Image)
    post_save.disconnect(purge_document_from_cache, sender=Document)
    post_delete.disconnect(purge_document_from_cache, sender=Document)
示例#30
0
def document_chooser_upload(request):
    Document = get_document_model()
    DocumentForm = get_document_form(Document)

    if request.method == "POST":
        document = Document(uploaded_by_user=request.user)
        form = DocumentForm(
            request.POST,
            request.FILES,
            instance=document,
            user=request.user,
            prefix="document-chooser-upload",
        )

        if form.is_valid():
            document.file_size = document.file.size

            # Set new document file hash
            document.file.seek(0)
            document._set_file_hash(document.file.read())
            document.file.seek(0)

            form.save()

            # Reindex the document to make sure all tags are indexed
            search_index.insert_or_update_object(document)

            return render_modal_workflow(
                request,
                None,
                None,
                None,
                json_data={
                    "step": "document_chosen",
                    "result": get_document_result_data(document),
                },
            )
    else:
        form = DocumentForm(user=request.user,
                            prefix="document-chooser-upload")

    documents = Document.objects.order_by("title")

    return render_modal_workflow(
        request,
        "non_admin_draftail/document/chooser.html",
        None,
        {
            "documents": documents,
            "uploadform": form
        },
        json_data=get_chooser_context(),
    )