mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-04-15 10:13:15 -05:00
Merge branch 'dev'
This commit is contained in:
commit
8371c2399f
@ -43,14 +43,12 @@ def select_action(modeladmin, request, queryset, title, action, modelclass, succ
|
|||||||
media=modeladmin.media,
|
media=modeladmin.media,
|
||||||
action=action,
|
action=action,
|
||||||
objects=modelclass.objects.all(),
|
objects=modelclass.objects.all(),
|
||||||
itemname=model_ngettext(modelclass,1)
|
itemname=model_ngettext(modelclass, 1)
|
||||||
)
|
)
|
||||||
|
|
||||||
request.current_app = modeladmin.admin_site.name
|
request.current_app = modeladmin.admin_site.name
|
||||||
|
|
||||||
return TemplateResponse(request,
|
return TemplateResponse(request, "admin/%s/%s/select_object.html" % (app_label, opts.model_name), context)
|
||||||
"admin/%s/%s/select_object.html" % (app_label, opts.model_name)
|
|
||||||
, context)
|
|
||||||
|
|
||||||
|
|
||||||
def simple_action(modeladmin, request, queryset, success_message="", document_action=None, queryset_action=None):
|
def simple_action(modeladmin, request, queryset, success_message="", document_action=None, queryset_action=None):
|
||||||
@ -70,6 +68,7 @@ def simple_action(modeladmin, request, queryset, success_message="", document_ac
|
|||||||
"count": n, "items": model_ngettext(modeladmin.opts, n)
|
"count": n, "items": model_ngettext(modeladmin.opts, n)
|
||||||
}, messages.SUCCESS)
|
}, messages.SUCCESS)
|
||||||
|
|
||||||
|
# Return None to display the change list page again.
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
@ -99,7 +98,7 @@ def set_correspondent_on_selected(modeladmin, request, queryset):
|
|||||||
action="set_correspondent_on_selected",
|
action="set_correspondent_on_selected",
|
||||||
modelclass=Correspondent,
|
modelclass=Correspondent,
|
||||||
success_message="Successfully set correspondent %(selected_object)s on %(count)d %(items)s.",
|
success_message="Successfully set correspondent %(selected_object)s on %(count)d %(items)s.",
|
||||||
queryset_action=lambda queryset, correspondent: queryset.update(correspondent=correspondent))
|
queryset_action=lambda qs, correspondent: qs.update(correspondent=correspondent))
|
||||||
set_correspondent_on_selected.short_description = "Set correspondent on selected documents"
|
set_correspondent_on_selected.short_description = "Set correspondent on selected documents"
|
||||||
|
|
||||||
|
|
||||||
@ -116,7 +115,7 @@ def set_document_type_on_selected(modeladmin, request, queryset):
|
|||||||
action="set_document_type_on_selected",
|
action="set_document_type_on_selected",
|
||||||
modelclass=DocumentType,
|
modelclass=DocumentType,
|
||||||
success_message="Successfully set document type %(selected_object)s on %(count)d %(items)s.",
|
success_message="Successfully set document type %(selected_object)s on %(count)d %(items)s.",
|
||||||
queryset_action=lambda queryset, document_type: queryset.update(document_type=document_type))
|
queryset_action=lambda qs, document_type: qs.update(document_type=document_type))
|
||||||
set_document_type_on_selected.short_description = "Set document type on selected documents"
|
set_document_type_on_selected.short_description = "Set document type on selected documents"
|
||||||
|
|
||||||
|
|
||||||
|
@ -94,9 +94,10 @@ class RecentCorrespondentFilter(admin.RelatedFieldListFilter):
|
|||||||
|
|
||||||
def field_choices(self, field, request, model_admin):
|
def field_choices(self, field, request, model_admin):
|
||||||
lookups = []
|
lookups = []
|
||||||
date_limit = datetime.now() - timedelta(days=365*settings.PAPERLESS_RECENT_CORRESPONDENT_YEARS)
|
if settings.PAPERLESS_RECENT_CORRESPONDENT_YEARS and settings.PAPERLESS_RECENT_CORRESPONDENT_YEARS > 0:
|
||||||
for c in Correspondent.objects.filter(documents__created__gte = date_limit).distinct():
|
date_limit = datetime.now() - timedelta(days=365*settings.PAPERLESS_RECENT_CORRESPONDENT_YEARS)
|
||||||
lookups.append( (c.id, c.name) )
|
for c in Correspondent.objects.filter(documents__created__gte=date_limit).distinct():
|
||||||
|
lookups.append((c.id, c.name))
|
||||||
return lookups
|
return lookups
|
||||||
|
|
||||||
|
|
||||||
@ -153,6 +154,7 @@ class DocumentTypeAdmin(CommonAdmin):
|
|||||||
return obj.document_count
|
return obj.document_count
|
||||||
document_count.admin_order_field = "document_count"
|
document_count.admin_order_field = "document_count"
|
||||||
|
|
||||||
|
|
||||||
class DocumentAdmin(CommonAdmin):
|
class DocumentAdmin(CommonAdmin):
|
||||||
|
|
||||||
class Media:
|
class Media:
|
||||||
@ -199,10 +201,10 @@ class DocumentAdmin(CommonAdmin):
|
|||||||
extra_context['download_url'] = doc.download_url
|
extra_context['download_url'] = doc.download_url
|
||||||
extra_context['file_type'] = doc.file_type
|
extra_context['file_type'] = doc.file_type
|
||||||
if self.document_queue and object_id and int(object_id) in self.document_queue:
|
if self.document_queue and object_id and int(object_id) in self.document_queue:
|
||||||
#There is a queue of documents
|
# There is a queue of documents
|
||||||
current_index = self.document_queue.index(int(object_id))
|
current_index = self.document_queue.index(int(object_id))
|
||||||
if current_index < len(self.document_queue) - 1:
|
if current_index < len(self.document_queue) - 1:
|
||||||
#... and there are still documents in the queue
|
# ... and there are still documents in the queue
|
||||||
extra_context['next_object'] = self.document_queue[current_index + 1]
|
extra_context['next_object'] = self.document_queue[current_index + 1]
|
||||||
return super(DocumentAdmin, self).change_view(
|
return super(DocumentAdmin, self).change_view(
|
||||||
request, object_id, form_url, extra_context=extra_context,
|
request, object_id, form_url, extra_context=extra_context,
|
||||||
|
@ -127,7 +127,7 @@ class DocumentClassifier(object):
|
|||||||
def classify_document(self, document, classify_correspondent=False, classify_document_type=False, classify_tags=False, replace_tags=False):
|
def classify_document(self, document, classify_correspondent=False, classify_document_type=False, classify_tags=False, replace_tags=False):
|
||||||
X = self.data_vectorizer.transform([preprocess_content(document.content)])
|
X = self.data_vectorizer.transform([preprocess_content(document.content)])
|
||||||
|
|
||||||
update_fields=()
|
update_fields = ()
|
||||||
|
|
||||||
if classify_correspondent and self.correspondent_classifier is not None:
|
if classify_correspondent and self.correspondent_classifier is not None:
|
||||||
y_correspondent = self.correspondent_classifier.predict(X)
|
y_correspondent = self.correspondent_classifier.predict(X)
|
||||||
|
@ -3,7 +3,7 @@ import os.path
|
|||||||
import pickle
|
import pickle
|
||||||
|
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
from documents.classifier import DocumentClassifier
|
from documents.classifier import DocumentClassifier
|
||||||
from paperless import settings
|
from paperless import settings
|
||||||
from ...mixins import Renderable
|
from ...mixins import Renderable
|
||||||
|
|
||||||
|
23
src/documents/templates/admin/documents/document/change_form.html
Executable file → Normal file
23
src/documents/templates/admin/documents/document/change_form.html
Executable file → Normal file
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
{{ block.super }}
|
{{ block.super }}
|
||||||
|
|
||||||
{% if file_type in "pdf jpg png" %}
|
{% if file_type in "asd" %}
|
||||||
|
|
||||||
<div id="change_form_twocolumn_parent">
|
<div id="change_form_twocolumn_parent">
|
||||||
<div id="change_form_form_parent"></div>
|
<div id="change_form_form_parent"></div>
|
||||||
@ -23,16 +23,17 @@
|
|||||||
django.jQuery("#content-main").append(django.jQuery("#change_form_twocolumn_parent"));
|
django.jQuery("#content-main").append(django.jQuery("#change_form_twocolumn_parent"));
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{% if next_object %}
|
{% endif %}
|
||||||
<script type="text/javascript">//<![CDATA[
|
|
||||||
(function($){
|
{% if next_object %}
|
||||||
$('<input type="submit" value="Save and edit next" name="_saveandeditnext" />')
|
<script type="text/javascript">//<![CDATA[
|
||||||
.prependTo('div.submit-row');
|
(function($){
|
||||||
$('<input type="hidden" value="{{next_object}}" name="_next_object" />')
|
$('<input type="submit" value="Save and edit next" name="_saveandeditnext" />')
|
||||||
.prependTo('div.submit-row');
|
.prependTo('div.submit-row');
|
||||||
})(django.jQuery);
|
$('<input type="hidden" value="{{next_object}}" name="_next_object" />')
|
||||||
//]]></script>
|
.prependTo('div.submit-row');
|
||||||
{% endif %}
|
})(django.jQuery);
|
||||||
|
//]]></script>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
@ -38,7 +38,7 @@
|
|||||||
<input type="hidden" name="action" value="{{action}}"/>
|
<input type="hidden" name="action" value="{{action}}"/>
|
||||||
<input type="hidden" name="post" value="yes"/>
|
<input type="hidden" name="post" value="yes"/>
|
||||||
<p>
|
<p>
|
||||||
<input type="submit" value="{% trans " Confirm" %}" />
|
<input type="submit" value="{% trans "Confirm" %}" />
|
||||||
<a href="#" class="button cancel-link">{% trans "Go back" %}</a>
|
<a href="#" class="button cancel-link">{% trans "Go back" %}</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
1
src/documents/templates/admin/documents/document/viewers/viewer_image.html
Executable file → Normal file
1
src/documents/templates/admin/documents/document/viewers/viewer_image.html
Executable file → Normal file
@ -1,2 +1 @@
|
|||||||
<img src="{{download_url}}" style="max-width: 100%">
|
<img src="{{download_url}}" style="max-width: 100%">
|
||||||
|
|
||||||
|
163
src/documents/templates/admin/documents/document/viewers/viewer_pdf.html
Executable file → Normal file
163
src/documents/templates/admin/documents/document/viewers/viewer_pdf.html
Executable file → Normal file
@ -3,117 +3,128 @@
|
|||||||
<div>
|
<div>
|
||||||
<input id="prev" value="Previous" class="default" type="button">
|
<input id="prev" value="Previous" class="default" type="button">
|
||||||
<input id="next" value="Next" class="default" type="button">
|
<input id="next" value="Next" class="default" type="button">
|
||||||
|
|
||||||
<span>Page: <span id="page_num"></span> / <span id="page_count"></span></span>
|
<span>Page: <span id="page_num"></span> / <span id="page_count"></span></span>
|
||||||
|
|
||||||
<input id="zoomin" value="+" class="default" type="button">
|
<input id="zoomin" value="+" class="default" type="button">
|
||||||
<input id="zoomout" value="-" class="default" type="button">
|
<input id="zoomout" value="-" class="default" type="button">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="width: 100%; overflow: auto;">
|
<div style="width: 100%; overflow: auto;">
|
||||||
<canvas id="the-canvas"></canvas>
|
<canvas id="the-canvas"></canvas>
|
||||||
</div>
|
</div>
|
||||||
<script type="text/javascript" src="{% static 'documents/js/pdf.js' %}"></script>
|
<script type="text/javascript" src="{% static 'documents/js/pdf.js' %}"></script>
|
||||||
<script type="text/javascript" src="{% static 'documents/js/pdf.worker.js' %}"></script>
|
<script type="text/javascript" src="{% static 'documents/js/pdf.worker.js' %}"></script>
|
||||||
{# Load and display PDF document#}
|
|
||||||
<script>
|
{# Load and display PDF document#}
|
||||||
|
<script>
|
||||||
var pdfjsLib = window['pdfjs-dist/build/pdf'];
|
var pdfjsLib = window['pdfjs-dist/build/pdf'];
|
||||||
|
|
||||||
var pdfDoc = null,
|
var pdfDoc = null,
|
||||||
pageNum = 1,
|
pageNum = 1,
|
||||||
pageRendering = false,
|
pageRendering = false,
|
||||||
pageNumPending = null,
|
pageNumPending = null,
|
||||||
scale = 1.0,
|
scale = 1.0,
|
||||||
canvas = document.getElementById('the-canvas'),
|
canvas = document.getElementById('the-canvas'),
|
||||||
ctx = canvas.getContext('2d');
|
ctx = canvas.getContext('2d');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get page info from document, resize canvas accordingly, and render page.
|
* Get page info from document, resize canvas accordingly, and render page.
|
||||||
* @param num Page number.
|
* @param num Page number.
|
||||||
*/
|
*/
|
||||||
function renderPage(num) {
|
function renderPage(num) {
|
||||||
pageRendering = true;
|
pageRendering = true;
|
||||||
// Using promise to fetch the page
|
// Using promise to fetch the page
|
||||||
pdfDoc.getPage(num).then(function(page) {
|
pdfDoc.getPage(num).then(function(page) {
|
||||||
var viewport = page.getViewport(scale);
|
var viewport = page.getViewport(scale);
|
||||||
canvas.height = viewport.height;
|
canvas.height = viewport.height;
|
||||||
canvas.width = viewport.width;
|
canvas.width = viewport.width;
|
||||||
// Render PDF page into canvas context
|
// Render PDF page into canvas context
|
||||||
var renderContext = {
|
var renderContext = {
|
||||||
canvasContext: ctx,
|
canvasContext: ctx,
|
||||||
viewport: viewport
|
viewport: viewport
|
||||||
};
|
};
|
||||||
var renderTask = page.render(renderContext);
|
var renderTask = page.render(renderContext);
|
||||||
// Wait for rendering to finish
|
// Wait for rendering to finish
|
||||||
renderTask.promise.then(function () {
|
renderTask.promise.then(function () {
|
||||||
pageRendering = false;
|
pageRendering = false;
|
||||||
if (pageNumPending !== null) {
|
if (pageNumPending !== null) {
|
||||||
// New page rendering is pending
|
// New page rendering is pending
|
||||||
renderPage(pageNumPending);
|
renderPage(pageNumPending);
|
||||||
pageNumPending = null;
|
pageNumPending = null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
// Update page counters
|
// Update page counters
|
||||||
document.getElementById('page_num').textContent = num;
|
document.getElementById('page_num').textContent = num;
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* If another page rendering in progress, waits until the rendering is
|
/**
|
||||||
* finised. Otherwise, executes rendering immediately.
|
* If another page rendering in progress, waits until the rendering is
|
||||||
*/
|
* finised. Otherwise, executes rendering immediately.
|
||||||
function queueRenderPage(num) {
|
*/
|
||||||
|
function queueRenderPage(num) {
|
||||||
if (pageRendering) {
|
if (pageRendering) {
|
||||||
pageNumPending = num;
|
pageNumPending = num;
|
||||||
} else {
|
} else {
|
||||||
renderPage(num);
|
renderPage(num);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* Displays previous page.
|
/**
|
||||||
*/
|
* Displays previous page.
|
||||||
function onPrevPage() {
|
*/
|
||||||
|
function onPrevPage() {
|
||||||
if (pageNum <= 1) {
|
if (pageNum <= 1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
pageNum--;
|
pageNum--;
|
||||||
queueRenderPage(pageNum);
|
queueRenderPage(pageNum);
|
||||||
}
|
}
|
||||||
document.getElementById('prev').addEventListener('click', onPrevPage);
|
|
||||||
/**
|
document.getElementById('prev').addEventListener('click', onPrevPage);
|
||||||
* Displays next page.
|
|
||||||
*/
|
/**
|
||||||
function onNextPage() {
|
* Displays next page.
|
||||||
|
*/
|
||||||
|
function onNextPage() {
|
||||||
if (pageNum >= pdfDoc.numPages) {
|
if (pageNum >= pdfDoc.numPages) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
pageNum++;
|
pageNum++;
|
||||||
queueRenderPage(pageNum);
|
queueRenderPage(pageNum);
|
||||||
}
|
}
|
||||||
document.getElementById('next').addEventListener('click', onNextPage);
|
|
||||||
/**
|
document.getElementById('next').addEventListener('click', onNextPage);
|
||||||
* Displays next page.
|
|
||||||
*/
|
/**
|
||||||
function onZoomIn() {
|
* Displays next page.
|
||||||
|
*/
|
||||||
|
function onZoomIn() {
|
||||||
scale *= 1.2;
|
scale *= 1.2;
|
||||||
queueRenderPage(pageNum);
|
queueRenderPage(pageNum);
|
||||||
}
|
}
|
||||||
document.getElementById('zoomin').addEventListener('click', onZoomIn);
|
|
||||||
/**
|
document.getElementById('zoomin').addEventListener('click', onZoomIn);
|
||||||
* Displays next page.
|
|
||||||
*/
|
/**
|
||||||
function onZoomOut() {
|
* Displays next page.
|
||||||
|
*/
|
||||||
|
function onZoomOut() {
|
||||||
scale /= 1.2;
|
scale /= 1.2;
|
||||||
queueRenderPage(pageNum);
|
queueRenderPage(pageNum);
|
||||||
}
|
}
|
||||||
document.getElementById('zoomout').addEventListener('click', onZoomOut);
|
|
||||||
/**
|
document.getElementById('zoomout').addEventListener('click', onZoomOut);
|
||||||
* Asynchronously downloads PDF.
|
|
||||||
*/
|
/**
|
||||||
pdfjsLib.getDocument("{{download_url}}").then(function (pdfDoc_) {
|
* Asynchronously downloads PDF.
|
||||||
|
*/
|
||||||
|
pdfjsLib.getDocument("{{download_url}}").then(function (pdfDoc_) {
|
||||||
pdfDoc = pdfDoc_;
|
pdfDoc = pdfDoc_;
|
||||||
document.getElementById('page_count').textContent = pdfDoc.numPages;
|
document.getElementById('page_count').textContent = pdfDoc.numPages;
|
||||||
// Initial/first page rendering
|
// Initial/first page rendering
|
||||||
renderPage(pageNum);
|
renderPage(pageNum);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -298,4 +298,8 @@ FY_END = os.getenv("PAPERLESS_FINANCIAL_YEAR_END")
|
|||||||
# Specify the default date order (for autodetected dates)
|
# Specify the default date order (for autodetected dates)
|
||||||
DATE_ORDER = os.getenv("PAPERLESS_DATE_ORDER", "DMY")
|
DATE_ORDER = os.getenv("PAPERLESS_DATE_ORDER", "DMY")
|
||||||
|
|
||||||
PAPERLESS_RECENT_CORRESPONDENT_YEARS = int(os.getenv("PAPERLESS_RECENT_CORRESPONDENT_YEARS", 1))
|
# Specify for how many years a correspondent is considered recent. Recent
|
||||||
|
# correspondents will be shown in a separate "Recent correspondents" filter as
|
||||||
|
# well. Set to 0 to disable this filter.
|
||||||
|
PAPERLESS_RECENT_CORRESPONDENT_YEARS = int(os.getenv(
|
||||||
|
"PAPERLESS_RECENT_CORRESPONDENT_YEARS", 0))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user