Feature: number of pages of document in documents list
This commit is contained in:
parent
609fa9a212
commit
865856b06d
@ -1046,11 +1046,11 @@
|
|||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/data/document.ts</context>
|
<context context-type="sourcefile">src/app/data/document.ts</context>
|
||||||
<context context-type="linenumber">62</context>
|
<context context-type="linenumber">63</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/data/document.ts</context>
|
<context context-type="sourcefile">src/app/data/document.ts</context>
|
||||||
<context context-type="linenumber">95</context>
|
<context context-type="linenumber">100</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="293524471897878391" datatype="html">
|
<trans-unit id="293524471897878391" datatype="html">
|
||||||
@ -1954,11 +1954,11 @@
|
|||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/data/document.ts</context>
|
<context context-type="sourcefile">src/app/data/document.ts</context>
|
||||||
<context context-type="linenumber">38</context>
|
<context context-type="linenumber">39</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/data/document.ts</context>
|
<context context-type="sourcefile">src/app/data/document.ts</context>
|
||||||
<context context-type="linenumber">92</context>
|
<context context-type="linenumber">97</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="5968132631442328843" datatype="html">
|
<trans-unit id="5968132631442328843" datatype="html">
|
||||||
@ -2414,7 +2414,7 @@
|
|||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-list/document-card-small/document-card-small.component.html</context>
|
<context context-type="sourcefile">src/app/components/document-list/document-card-small/document-card-small.component.html</context>
|
||||||
<context context-type="linenumber">120</context>
|
<context context-type="linenumber">128</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/manage/custom-fields/custom-fields.component.html</context>
|
<context context-type="sourcefile">src/app/components/manage/custom-fields/custom-fields.component.html</context>
|
||||||
@ -2760,7 +2760,7 @@
|
|||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/data/document.ts</context>
|
<context context-type="sourcefile">src/app/data/document.ts</context>
|
||||||
<context context-type="linenumber">46</context>
|
<context context-type="linenumber">47</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="4369111787961525769" datatype="html">
|
<trans-unit id="4369111787961525769" datatype="html">
|
||||||
@ -2972,7 +2972,7 @@
|
|||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-list/document-card-small/document-card-small.component.html</context>
|
<context context-type="sourcefile">src/app/components/document-list/document-card-small/document-card-small.component.html</context>
|
||||||
<context context-type="linenumber">131</context>
|
<context context-type="linenumber">139</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="searchResults.noResults" datatype="html">
|
<trans-unit id="searchResults.noResults" datatype="html">
|
||||||
@ -3361,11 +3361,11 @@
|
|||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/data/document.ts</context>
|
<context context-type="sourcefile">src/app/data/document.ts</context>
|
||||||
<context context-type="linenumber">42</context>
|
<context context-type="linenumber">43</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/data/document.ts</context>
|
<context context-type="sourcefile">src/app/data/document.ts</context>
|
||||||
<context context-type="linenumber">93</context>
|
<context context-type="linenumber">98</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="4873149362496451858" datatype="html">
|
<trans-unit id="4873149362496451858" datatype="html">
|
||||||
@ -5514,7 +5514,7 @@
|
|||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
|
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
|
||||||
<context context-type="linenumber">277</context>
|
<context context-type="linenumber">286</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="78870852467682010" datatype="html">
|
<trans-unit id="78870852467682010" datatype="html">
|
||||||
@ -5529,7 +5529,7 @@
|
|||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
|
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
|
||||||
<context context-type="linenumber">312</context>
|
<context context-type="linenumber">321</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="157572966557284263" datatype="html">
|
<trans-unit id="157572966557284263" datatype="html">
|
||||||
@ -5544,7 +5544,7 @@
|
|||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
|
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
|
||||||
<context context-type="linenumber">319</context>
|
<context context-type="linenumber">328</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="8911158217491828773" datatype="html">
|
<trans-unit id="8911158217491828773" datatype="html">
|
||||||
@ -5842,11 +5842,11 @@
|
|||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/data/document.ts</context>
|
<context context-type="sourcefile">src/app/data/document.ts</context>
|
||||||
<context context-type="linenumber">34</context>
|
<context context-type="linenumber">35</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/data/document.ts</context>
|
<context context-type="sourcefile">src/app/data/document.ts</context>
|
||||||
<context context-type="linenumber">90</context>
|
<context context-type="linenumber">95</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="1379170675585571971" datatype="html">
|
<trans-unit id="1379170675585571971" datatype="html">
|
||||||
@ -5883,11 +5883,11 @@
|
|||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/data/document.ts</context>
|
<context context-type="sourcefile">src/app/data/document.ts</context>
|
||||||
<context context-type="linenumber">50</context>
|
<context context-type="linenumber">51</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/data/document.ts</context>
|
<context context-type="sourcefile">src/app/data/document.ts</context>
|
||||||
<context context-type="linenumber">89</context>
|
<context context-type="linenumber">94</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="5066119607229701477" datatype="html">
|
<trans-unit id="5066119607229701477" datatype="html">
|
||||||
@ -5910,11 +5910,11 @@
|
|||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/data/document.ts</context>
|
<context context-type="sourcefile">src/app/data/document.ts</context>
|
||||||
<context context-type="linenumber">54</context>
|
<context context-type="linenumber">55</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/data/document.ts</context>
|
<context context-type="sourcefile">src/app/data/document.ts</context>
|
||||||
<context context-type="linenumber">91</context>
|
<context context-type="linenumber">96</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="2091353339965748767" datatype="html">
|
<trans-unit id="2091353339965748767" datatype="html">
|
||||||
@ -5937,7 +5937,7 @@
|
|||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/data/document.ts</context>
|
<context context-type="sourcefile">src/app/data/document.ts</context>
|
||||||
<context context-type="linenumber">58</context>
|
<context context-type="linenumber">59</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="6205355627445317276" datatype="html">
|
<trans-unit id="6205355627445317276" datatype="html">
|
||||||
@ -6730,7 +6730,7 @@
|
|||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
|
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
|
||||||
<context context-type="linenumber">288</context>
|
<context context-type="linenumber">297</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="106713086593101376" datatype="html">
|
<trans-unit id="106713086593101376" datatype="html">
|
||||||
@ -6785,19 +6785,30 @@
|
|||||||
<context context-type="linenumber">82,83</context>
|
<context context-type="linenumber">82,83</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
<trans-unit id="197162226430950645" datatype="html">
|
||||||
|
<source>{VAR_PLURAL, plural, =1 {1 page} other {<x id="INTERPOLATION"/> pages}}</source>
|
||||||
|
<context-group purpose="location">
|
||||||
|
<context context-type="sourcefile">src/app/components/document-list/document-card-large/document-card-large.component.html</context>
|
||||||
|
<context context-type="linenumber">117</context>
|
||||||
|
</context-group>
|
||||||
|
<context-group purpose="location">
|
||||||
|
<context context-type="sourcefile">src/app/components/document-list/document-card-small/document-card-small.component.html</context>
|
||||||
|
<context context-type="linenumber">95</context>
|
||||||
|
</context-group>
|
||||||
|
</trans-unit>
|
||||||
<trans-unit id="5739581984228459958" datatype="html">
|
<trans-unit id="5739581984228459958" datatype="html">
|
||||||
<source>Shared</source>
|
<source>Shared</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-list/document-card-large/document-card-large.component.html</context>
|
<context context-type="sourcefile">src/app/components/document-list/document-card-large/document-card-large.component.html</context>
|
||||||
<context context-type="linenumber">121</context>
|
<context context-type="linenumber">127</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-list/document-card-small/document-card-small.component.html</context>
|
<context context-type="sourcefile">src/app/components/document-list/document-card-small/document-card-small.component.html</context>
|
||||||
<context context-type="linenumber">106</context>
|
<context context-type="linenumber">114</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/data/document.ts</context>
|
<context context-type="sourcefile">src/app/data/document.ts</context>
|
||||||
<context context-type="linenumber">70</context>
|
<context context-type="linenumber">71</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/pipes/username.pipe.ts</context>
|
<context context-type="sourcefile">src/app/pipes/username.pipe.ts</context>
|
||||||
@ -6808,7 +6819,7 @@
|
|||||||
<source>Score:</source>
|
<source>Score:</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-list/document-card-large/document-card-large.component.html</context>
|
<context context-type="sourcefile">src/app/components/document-list/document-card-large/document-card-large.component.html</context>
|
||||||
<context context-type="linenumber">126</context>
|
<context context-type="linenumber">132</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="3661756380991326939" datatype="html">
|
<trans-unit id="3661756380991326939" datatype="html">
|
||||||
@ -6947,11 +6958,11 @@
|
|||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/data/document.ts</context>
|
<context context-type="sourcefile">src/app/data/document.ts</context>
|
||||||
<context context-type="linenumber">74</context>
|
<context context-type="linenumber">75</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/data/document.ts</context>
|
<context context-type="sourcefile">src/app/data/document.ts</context>
|
||||||
<context context-type="linenumber">88</context>
|
<context context-type="linenumber">93</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="6954625430271090777" datatype="html">
|
<trans-unit id="6954625430271090777" datatype="html">
|
||||||
@ -6983,11 +6994,11 @@
|
|||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/data/document.ts</context>
|
<context context-type="sourcefile">src/app/data/document.ts</context>
|
||||||
<context context-type="linenumber">66</context>
|
<context context-type="linenumber">67</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/data/document.ts</context>
|
<context context-type="sourcefile">src/app/data/document.ts</context>
|
||||||
<context context-type="linenumber">96</context>
|
<context context-type="linenumber">101</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="3557446856808034218" datatype="html">
|
<trans-unit id="3557446856808034218" datatype="html">
|
||||||
@ -7025,25 +7036,51 @@
|
|||||||
<context context-type="linenumber">243</context>
|
<context context-type="linenumber">243</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
<trans-unit id="4874754501044009042" datatype="html">
|
||||||
|
<source>Sort by number of pages</source>
|
||||||
|
<context-group purpose="location">
|
||||||
|
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
|
||||||
|
<context context-type="linenumber">252</context>
|
||||||
|
</context-group>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="3817498941817715969" datatype="html">
|
||||||
|
<source>Pages</source>
|
||||||
|
<context-group purpose="location">
|
||||||
|
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
|
||||||
|
<context context-type="linenumber">256</context>
|
||||||
|
</context-group>
|
||||||
|
<context-group purpose="location">
|
||||||
|
<context context-type="sourcefile">src/app/data/document.ts</context>
|
||||||
|
<context context-type="linenumber">79</context>
|
||||||
|
</context-group>
|
||||||
|
<context-group purpose="location">
|
||||||
|
<context context-type="sourcefile">src/app/data/document.ts</context>
|
||||||
|
<context context-type="linenumber">102</context>
|
||||||
|
</context-group>
|
||||||
|
<context-group purpose="location">
|
||||||
|
<context context-type="sourcefile">src/app/data/paperless-config.ts</context>
|
||||||
|
<context context-type="linenumber">90</context>
|
||||||
|
</context-group>
|
||||||
|
</trans-unit>
|
||||||
<trans-unit id="329406837759048287" datatype="html">
|
<trans-unit id="329406837759048287" datatype="html">
|
||||||
<source> Shared </source>
|
<source> Shared </source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
|
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
|
||||||
<context context-type="linenumber">250,252</context>
|
<context context-type="linenumber">259,261</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="2179847500064178686" datatype="html">
|
<trans-unit id="2179847500064178686" datatype="html">
|
||||||
<source>Edit document</source>
|
<source>Edit document</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
|
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
|
||||||
<context context-type="linenumber">284</context>
|
<context context-type="linenumber">293</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="2807800733729323332" datatype="html">
|
<trans-unit id="2807800733729323332" datatype="html">
|
||||||
<source>Yes</source>
|
<source>Yes</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
|
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
|
||||||
<context context-type="linenumber">335</context>
|
<context context-type="linenumber">349</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/pipes/yes-no.pipe.ts</context>
|
<context context-type="sourcefile">src/app/pipes/yes-no.pipe.ts</context>
|
||||||
@ -7054,7 +7091,7 @@
|
|||||||
<source>No</source>
|
<source>No</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
|
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
|
||||||
<context context-type="linenumber">335</context>
|
<context context-type="linenumber">349</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/pipes/yes-no.pipe.ts</context>
|
<context context-type="sourcefile">src/app/pipes/yes-no.pipe.ts</context>
|
||||||
@ -7988,14 +8025,14 @@
|
|||||||
<source>Modified</source>
|
<source>Modified</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/data/document.ts</context>
|
<context context-type="sourcefile">src/app/data/document.ts</context>
|
||||||
<context context-type="linenumber">94</context>
|
<context context-type="linenumber">99</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="4460262093225954455" datatype="html">
|
<trans-unit id="4460262093225954455" datatype="html">
|
||||||
<source>Search score</source>
|
<source>Search score</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/data/document.ts</context>
|
<context context-type="sourcefile">src/app/data/document.ts</context>
|
||||||
<context context-type="linenumber">102</context>
|
<context context-type="linenumber">108</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<note priority="1" from="description">Score is a value returned by the full text search engine and specifies how well a result matches the given query</note>
|
<note priority="1" from="description">Score is a value returned by the full text search engine and specifies how well a result matches the given query</note>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
@ -8111,13 +8148,6 @@
|
|||||||
<context context-type="linenumber">83</context>
|
<context context-type="linenumber">83</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="3817498941817715969" datatype="html">
|
|
||||||
<source>Pages</source>
|
|
||||||
<context-group purpose="location">
|
|
||||||
<context context-type="sourcefile">src/app/data/paperless-config.ts</context>
|
|
||||||
<context context-type="linenumber">90</context>
|
|
||||||
</context-group>
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="1713271461473302108" datatype="html">
|
<trans-unit id="1713271461473302108" datatype="html">
|
||||||
<source>Mode</source>
|
<source>Mode</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
|
@ -65,6 +65,7 @@ const savedView: SavedView = {
|
|||||||
DisplayField.CORRESPONDENT,
|
DisplayField.CORRESPONDENT,
|
||||||
DisplayField.DOCUMENT_TYPE,
|
DisplayField.DOCUMENT_TYPE,
|
||||||
DisplayField.STORAGE_PATH,
|
DisplayField.STORAGE_PATH,
|
||||||
|
DisplayField.PAGES_COUNT,
|
||||||
`${DisplayField.CUSTOM_FIELD}11` as any,
|
`${DisplayField.CUSTOM_FIELD}11` as any,
|
||||||
`${DisplayField.CUSTOM_FIELD}15` as any,
|
`${DisplayField.CUSTOM_FIELD}15` as any,
|
||||||
],
|
],
|
||||||
@ -344,6 +345,7 @@ describe('SavedViewWidgetComponent', () => {
|
|||||||
expect(component.getColumnTitle(DisplayField.STORAGE_PATH)).toEqual(
|
expect(component.getColumnTitle(DisplayField.STORAGE_PATH)).toEqual(
|
||||||
'Storage path'
|
'Storage path'
|
||||||
)
|
)
|
||||||
|
expect(component.getColumnTitle(DisplayField.PAGES_COUNT)).toEqual('Pages')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should get correct column title for custom field', () => {
|
it('should get correct column title for custom field', () => {
|
||||||
|
@ -111,6 +111,12 @@
|
|||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@if (displayFields.includes(DisplayField.PAGES_COUNT) && document.pages_count) {
|
||||||
|
<div class="list-group-item bg-light text-dark p-1 border-0 d-flex align-items-center">
|
||||||
|
<i-bs width=".9em" height=".9em" class="me-2 text-muted" name="files"></i-bs>
|
||||||
|
<small i18n>{document.pages_count, plural, =1 {1 page} other {{{document.pages_count}} pages}}</small>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
@if (displayFields.includes(DisplayField.OWNER) && document.owner && document.owner !== settingsService.currentUser.id) {
|
@if (displayFields.includes(DisplayField.OWNER) && document.owner && document.owner !== settingsService.currentUser.id) {
|
||||||
<div class="list-group-item bg-light text-dark p-1 border-0 d-flex align-items-center">
|
<div class="list-group-item bg-light text-dark p-1 border-0 d-flex align-items-center">
|
||||||
<i-bs width=".9em" height=".9em" class="me-2 text-muted" name="person-fill-lock"></i-bs><small>{{document.owner | username}}</small>
|
<i-bs width=".9em" height=".9em" class="me-2 text-muted" name="person-fill-lock"></i-bs><small>{{document.owner | username}}</small>
|
||||||
|
@ -31,6 +31,7 @@ const doc = {
|
|||||||
correspondent: 8,
|
correspondent: 8,
|
||||||
document_type: 10,
|
document_type: 10,
|
||||||
storage_path: null,
|
storage_path: null,
|
||||||
|
pages_count: 8,
|
||||||
notes: [
|
notes: [
|
||||||
{
|
{
|
||||||
id: 11,
|
id: 11,
|
||||||
@ -80,6 +81,7 @@ describe('DocumentCardLargeComponent', () => {
|
|||||||
it('should display a document', () => {
|
it('should display a document', () => {
|
||||||
expect(fixture.nativeElement.textContent).toContain('Document 10')
|
expect(fixture.nativeElement.textContent).toContain('Document 10')
|
||||||
expect(fixture.nativeElement.textContent).toContain('Cupcake ipsum')
|
expect(fixture.nativeElement.textContent).toContain('Cupcake ipsum')
|
||||||
|
expect(fixture.nativeElement.textContent).toContain('8 pages')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should show preview on mouseover after delay to preload content', fakeAsync(() => {
|
it('should show preview on mouseover after delay to preload content', fakeAsync(() => {
|
||||||
|
@ -88,6 +88,14 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
@if (displayFields.includes(DisplayField.PAGES_COUNT) && document.pages_count) {
|
||||||
|
<div class="list-group-item bg-transparent p-0 border-0 d-flex flex-wrap-reverse justify-content-between">
|
||||||
|
<div class="ps-0 p-1" placement="top">
|
||||||
|
<i-bs width="1em" height="1em" class="me-2 text-muted" name="files"></i-bs>
|
||||||
|
<small i18n>{document.pages_count, plural, =1 {1 page} other {{{document.pages_count}} pages}}</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
@if (displayFields.includes(DisplayField.ASN) && document.archive_serial_number | isNumber) {
|
@if (displayFields.includes(DisplayField.ASN) && document.archive_serial_number | isNumber) {
|
||||||
<div class="ps-0 p-1">
|
<div class="ps-0 p-1">
|
||||||
<i-bs width="1em" height="1em" class="me-2 text-muted" name="upc-scan"></i-bs>
|
<i-bs width="1em" height="1em" class="me-2 text-muted" name="upc-scan"></i-bs>
|
||||||
|
@ -34,6 +34,7 @@ const doc = {
|
|||||||
correspondent: 8,
|
correspondent: 8,
|
||||||
document_type: 10,
|
document_type: 10,
|
||||||
storage_path: null,
|
storage_path: null,
|
||||||
|
pages_count: 12,
|
||||||
notes: [
|
notes: [
|
||||||
{
|
{
|
||||||
id: 11,
|
id: 11,
|
||||||
@ -91,6 +92,10 @@ describe('DocumentCardSmallComponent', () => {
|
|||||||
fixture.detectChanges()
|
fixture.detectChanges()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should display a document', () => {
|
||||||
|
expect(fixture.nativeElement.textContent).toContain('12 pages')
|
||||||
|
})
|
||||||
|
|
||||||
it('should display a document, limit tags to 5', () => {
|
it('should display a document, limit tags to 5', () => {
|
||||||
expect(fixture.nativeElement.textContent).toContain('Document 10')
|
expect(fixture.nativeElement.textContent).toContain('Document 10')
|
||||||
expect(
|
expect(
|
||||||
|
@ -246,6 +246,15 @@
|
|||||||
(sort)="onSort($event)"
|
(sort)="onSort($event)"
|
||||||
i18n>Added</th>
|
i18n>Added</th>
|
||||||
}
|
}
|
||||||
|
@if (activeDisplayFields.includes(DisplayField.PAGES_COUNT)) {
|
||||||
|
<th class="cursor-pointer"
|
||||||
|
pngxSortable="pages_count"
|
||||||
|
title="Sort by number of pages" i18n-title
|
||||||
|
[currentSortField]="list.sortField"
|
||||||
|
[currentSortReverse]="list.sortReverse"
|
||||||
|
(sort)="onSort($event)"
|
||||||
|
i18n>Pages</th>
|
||||||
|
}
|
||||||
@if (activeDisplayFields.includes(DisplayField.SHARED)) {
|
@if (activeDisplayFields.includes(DisplayField.SHARED)) {
|
||||||
<th i18n>
|
<th i18n>
|
||||||
Shared
|
Shared
|
||||||
@ -330,6 +339,11 @@
|
|||||||
{{d.added | customDate}}
|
{{d.added | customDate}}
|
||||||
</td>
|
</td>
|
||||||
}
|
}
|
||||||
|
@if (activeDisplayFields.includes(DisplayField.PAGES_COUNT)) {
|
||||||
|
<td>
|
||||||
|
{{ d.pages_count }}
|
||||||
|
</td>
|
||||||
|
}
|
||||||
@if (activeDisplayFields.includes(DisplayField.SHARED)) {
|
@if (activeDisplayFields.includes(DisplayField.SHARED)) {
|
||||||
<td>
|
<td>
|
||||||
@if (d.is_shared_by_requester) { <ng-container i18n>Yes</ng-container> } @else { <ng-container i18n>No</ng-container> }
|
@if (d.is_shared_by_requester) { <ng-container i18n>Yes</ng-container> } @else { <ng-container i18n>No</ng-container> }
|
||||||
|
@ -602,7 +602,7 @@ describe('DocumentListComponent', () => {
|
|||||||
|
|
||||||
expect(
|
expect(
|
||||||
fixture.debugElement.queryAll(By.directive(SortableDirective))
|
fixture.debugElement.queryAll(By.directive(SortableDirective))
|
||||||
).toHaveLength(9)
|
).toHaveLength(10)
|
||||||
|
|
||||||
expect(component.notesEnabled).toBeTruthy()
|
expect(component.notesEnabled).toBeTruthy()
|
||||||
settingsService.set(SETTINGS_KEYS.NOTES_ENABLED, false)
|
settingsService.set(SETTINGS_KEYS.NOTES_ENABLED, false)
|
||||||
@ -610,14 +610,14 @@ describe('DocumentListComponent', () => {
|
|||||||
expect(component.notesEnabled).toBeFalsy()
|
expect(component.notesEnabled).toBeFalsy()
|
||||||
expect(
|
expect(
|
||||||
fixture.debugElement.queryAll(By.directive(SortableDirective))
|
fixture.debugElement.queryAll(By.directive(SortableDirective))
|
||||||
).toHaveLength(8)
|
).toHaveLength(9)
|
||||||
|
|
||||||
// insufficient perms
|
// insufficient perms
|
||||||
jest.spyOn(permissionService, 'currentUserCan').mockReturnValue(false)
|
jest.spyOn(permissionService, 'currentUserCan').mockReturnValue(false)
|
||||||
fixture.detectChanges()
|
fixture.detectChanges()
|
||||||
expect(
|
expect(
|
||||||
fixture.debugElement.queryAll(By.directive(SortableDirective))
|
fixture.debugElement.queryAll(By.directive(SortableDirective))
|
||||||
).toHaveLength(4)
|
).toHaveLength(5)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support toggle on document objects', () => {
|
it('should support toggle on document objects', () => {
|
||||||
|
@ -26,6 +26,7 @@ export enum DisplayField {
|
|||||||
OWNER = 'owner',
|
OWNER = 'owner',
|
||||||
SHARED = 'shared',
|
SHARED = 'shared',
|
||||||
ASN = 'asn',
|
ASN = 'asn',
|
||||||
|
PAGES_COUNT = 'pagescount',
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DEFAULT_DISPLAY_FIELDS = [
|
export const DEFAULT_DISPLAY_FIELDS = [
|
||||||
@ -73,6 +74,10 @@ export const DEFAULT_DISPLAY_FIELDS = [
|
|||||||
id: DisplayField.ASN,
|
id: DisplayField.ASN,
|
||||||
name: $localize`ASN`,
|
name: $localize`ASN`,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: DisplayField.PAGES_COUNT,
|
||||||
|
name: $localize`Pages`,
|
||||||
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
export const DEFAULT_DASHBOARD_VIEW_PAGE_SIZE = 10
|
export const DEFAULT_DASHBOARD_VIEW_PAGE_SIZE = 10
|
||||||
@ -94,6 +99,7 @@ export const DOCUMENT_SORT_FIELDS = [
|
|||||||
{ field: 'modified', name: $localize`Modified` },
|
{ field: 'modified', name: $localize`Modified` },
|
||||||
{ field: 'num_notes', name: $localize`Notes` },
|
{ field: 'num_notes', name: $localize`Notes` },
|
||||||
{ field: 'owner', name: $localize`Owner` },
|
{ field: 'owner', name: $localize`Owner` },
|
||||||
|
{ field: 'pages_count', name: $localize`Pages` },
|
||||||
]
|
]
|
||||||
|
|
||||||
export const DOCUMENT_SORT_FIELDS_FULLTEXT = [
|
export const DOCUMENT_SORT_FIELDS_FULLTEXT = [
|
||||||
@ -164,4 +170,6 @@ export interface Document extends ObjectWithPermissions {
|
|||||||
|
|
||||||
// write-only field
|
// write-only field
|
||||||
remove_inbox_tags?: boolean
|
remove_inbox_tags?: boolean
|
||||||
|
|
||||||
|
pages_count?: number
|
||||||
}
|
}
|
||||||
|
@ -345,6 +345,7 @@ export class SettingsService {
|
|||||||
DisplayField.CREATED,
|
DisplayField.CREATED,
|
||||||
DisplayField.ADDED,
|
DisplayField.ADDED,
|
||||||
DisplayField.ASN,
|
DisplayField.ASN,
|
||||||
|
DisplayField.PAGES_COUNT,
|
||||||
DisplayField.SHARED,
|
DisplayField.SHARED,
|
||||||
].includes(field.id)
|
].includes(field.id)
|
||||||
) {
|
) {
|
||||||
|
@ -586,6 +586,7 @@ class ConsumerPlugin(
|
|||||||
date = None
|
date = None
|
||||||
thumbnail = None
|
thumbnail = None
|
||||||
archive_path = None
|
archive_path = None
|
||||||
|
pages_count = None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self._send_progress(
|
self._send_progress(
|
||||||
@ -621,6 +622,7 @@ class ConsumerPlugin(
|
|||||||
)
|
)
|
||||||
date = parse_date(self.filename, text)
|
date = parse_date(self.filename, text)
|
||||||
archive_path = document_parser.get_archive_path()
|
archive_path = document_parser.get_archive_path()
|
||||||
|
pages_count = document_parser.get_pages_count(self.working_copy, mime_type)
|
||||||
|
|
||||||
except ParseError as e:
|
except ParseError as e:
|
||||||
document_parser.cleanup()
|
document_parser.cleanup()
|
||||||
@ -662,7 +664,12 @@ class ConsumerPlugin(
|
|||||||
try:
|
try:
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
# store the document.
|
# store the document.
|
||||||
document = self._store(text=text, date=date, mime_type=mime_type)
|
document = self._store(
|
||||||
|
text=text,
|
||||||
|
date=date,
|
||||||
|
pages_count=pages_count,
|
||||||
|
mime_type=mime_type,
|
||||||
|
)
|
||||||
|
|
||||||
# If we get here, it was successful. Proceed with post-consume
|
# If we get here, it was successful. Proceed with post-consume
|
||||||
# hooks. If they fail, nothing will get changed.
|
# hooks. If they fail, nothing will get changed.
|
||||||
@ -790,6 +797,7 @@ class ConsumerPlugin(
|
|||||||
self,
|
self,
|
||||||
text: str,
|
text: str,
|
||||||
date: Optional[datetime.datetime],
|
date: Optional[datetime.datetime],
|
||||||
|
pages_count: int,
|
||||||
mime_type: str,
|
mime_type: str,
|
||||||
) -> Document:
|
) -> Document:
|
||||||
# If someone gave us the original filename, use it instead of doc.
|
# If someone gave us the original filename, use it instead of doc.
|
||||||
@ -835,6 +843,7 @@ class ConsumerPlugin(
|
|||||||
created=create_date,
|
created=create_date,
|
||||||
modified=create_date,
|
modified=create_date,
|
||||||
storage_type=storage_type,
|
storage_type=storage_type,
|
||||||
|
pages_count=pages_count,
|
||||||
original_filename=self.filename,
|
original_filename=self.filename,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -80,6 +80,7 @@ def get_schema():
|
|||||||
has_owner=BOOLEAN(),
|
has_owner=BOOLEAN(),
|
||||||
viewer_id=KEYWORD(commas=True),
|
viewer_id=KEYWORD(commas=True),
|
||||||
checksum=TEXT(),
|
checksum=TEXT(),
|
||||||
|
pages_count=NUMERIC(sortable=True),
|
||||||
original_filename=TEXT(sortable=True),
|
original_filename=TEXT(sortable=True),
|
||||||
is_shared=BOOLEAN(),
|
is_shared=BOOLEAN(),
|
||||||
)
|
)
|
||||||
@ -181,6 +182,7 @@ def update_document(writer: AsyncWriter, doc: Document):
|
|||||||
has_owner=doc.owner is not None,
|
has_owner=doc.owner is not None,
|
||||||
viewer_id=viewer_ids if viewer_ids else None,
|
viewer_id=viewer_ids if viewer_ids else None,
|
||||||
checksum=doc.checksum,
|
checksum=doc.checksum,
|
||||||
|
pages_count=doc.pages_count,
|
||||||
original_filename=doc.original_filename,
|
original_filename=doc.original_filename,
|
||||||
is_shared=len(viewer_ids) > 0,
|
is_shared=len(viewer_ids) > 0,
|
||||||
)
|
)
|
||||||
@ -247,6 +249,7 @@ class DelayedQuery:
|
|||||||
"archive_serial_number": "asn",
|
"archive_serial_number": "asn",
|
||||||
"num_notes": "num_notes",
|
"num_notes": "num_notes",
|
||||||
"owner": "owner",
|
"owner": "owner",
|
||||||
|
"pages_count": "pages_count",
|
||||||
}
|
}
|
||||||
|
|
||||||
if field.startswith("-"):
|
if field.startswith("-"):
|
||||||
|
109
src/documents/migrations/1053_document_pages_count.py
Normal file
109
src/documents/migrations/1053_document_pages_count.py
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
# Generated by Django 4.2.16 on 2024-09-21 15:44
|
||||||
|
|
||||||
|
import datetime
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import pikepdf
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations
|
||||||
|
from django.db import models
|
||||||
|
from django.utils import timezone
|
||||||
|
from django.utils.termcolors import colorize as colourise
|
||||||
|
|
||||||
|
from documents.parsers import get_default_file_extension
|
||||||
|
|
||||||
|
|
||||||
|
class Document:
|
||||||
|
"""
|
||||||
|
Django's migrations restrict access to model methods, so this is a snapshot
|
||||||
|
of the methods that existed at the time this migration was written, since
|
||||||
|
we need to make use of a lot of these shortcuts here.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, doc):
|
||||||
|
self.pk = doc.pk
|
||||||
|
self.correspondent = doc.correspondent
|
||||||
|
self.title = doc.title
|
||||||
|
self.mime_type = doc.mime_type
|
||||||
|
self.filename = doc.filename
|
||||||
|
self.created = doc.created
|
||||||
|
|
||||||
|
def __str__(self) -> str:
|
||||||
|
# Convert UTC database time to local time
|
||||||
|
created = datetime.date.isoformat(timezone.localdate(self.created))
|
||||||
|
|
||||||
|
res = f"{created}"
|
||||||
|
|
||||||
|
if self.correspondent:
|
||||||
|
res += f" {self.correspondent}"
|
||||||
|
if self.title:
|
||||||
|
res += f" {self.title}"
|
||||||
|
return res
|
||||||
|
|
||||||
|
@property
|
||||||
|
def file_type(self):
|
||||||
|
return get_default_file_extension(self.mime_type)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def source_path(self) -> Path:
|
||||||
|
if self.filename:
|
||||||
|
fname = str(self.filename)
|
||||||
|
return (settings.ORIGINALS_DIR / Path(fname)).resolve()
|
||||||
|
|
||||||
|
|
||||||
|
def add_number_of_pages_to_pages_count(apps, schema_editor):
|
||||||
|
documentModel = apps.get_model("documents", "Document")
|
||||||
|
|
||||||
|
if not documentModel.objects.all().exists():
|
||||||
|
return
|
||||||
|
|
||||||
|
for doc in documentModel.objects.filter(mime_type="application/pdf"):
|
||||||
|
document = Document(doc)
|
||||||
|
|
||||||
|
print(
|
||||||
|
" {} {} {}".format(
|
||||||
|
colourise("*", fg="green"),
|
||||||
|
colourise("Calculating number of pages for", fg="white"),
|
||||||
|
colourise(document.filename, fg="cyan"),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
pdf = pikepdf.open(document.source_path)
|
||||||
|
|
||||||
|
if pdf.pages is not None:
|
||||||
|
doc.pages_count = len(pdf.pages)
|
||||||
|
doc.save()
|
||||||
|
|
||||||
|
|
||||||
|
def remove_number_of_pages_to_pages_count(apps, schema_editor):
|
||||||
|
documentModel = apps.get_model("documents", "Document")
|
||||||
|
|
||||||
|
if not documentModel.objects.all().exists():
|
||||||
|
return
|
||||||
|
|
||||||
|
for document in documentModel.objects.filter(mime_type="application/pdf"):
|
||||||
|
document.pages_count = 0
|
||||||
|
document.save()
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
dependencies = [
|
||||||
|
("documents", "1052_document_transaction_id"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="document",
|
||||||
|
name="pages_count",
|
||||||
|
field=models.PositiveIntegerField(
|
||||||
|
blank=False,
|
||||||
|
null=True,
|
||||||
|
unique=False,
|
||||||
|
db_index=False,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
migrations.RunPython(
|
||||||
|
add_number_of_pages_to_pages_count,
|
||||||
|
remove_number_of_pages_to_pages_count,
|
||||||
|
),
|
||||||
|
]
|
@ -205,6 +205,18 @@ class Document(SoftDeleteModel, ModelWithOwner):
|
|||||||
help_text=_("The checksum of the archived document."),
|
help_text=_("The checksum of the archived document."),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
pages_count = models.PositiveIntegerField(
|
||||||
|
_("pages count"),
|
||||||
|
blank=False,
|
||||||
|
null=True,
|
||||||
|
unique=False,
|
||||||
|
db_index=False,
|
||||||
|
validators=[MinValueValidator(1)],
|
||||||
|
help_text=_(
|
||||||
|
"The number of pages of the document.",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
created = models.DateTimeField(_("created"), default=timezone.now, db_index=True)
|
created = models.DateTimeField(_("created"), default=timezone.now, db_index=True)
|
||||||
|
|
||||||
modified = models.DateTimeField(
|
modified = models.DateTimeField(
|
||||||
@ -414,6 +426,7 @@ class SavedView(ModelWithOwner):
|
|||||||
OWNER = ("owner", _("Owner"))
|
OWNER = ("owner", _("Owner"))
|
||||||
SHARED = ("shared", _("Shared"))
|
SHARED = ("shared", _("Shared"))
|
||||||
ASN = ("asn", _("ASN"))
|
ASN = ("asn", _("ASN"))
|
||||||
|
PAGES_COUNT = ("pagescount", _("Pages"))
|
||||||
CUSTOM_FIELD = ("custom_field_%d", ("Custom Field"))
|
CUSTOM_FIELD = ("custom_field_%d", ("Custom Field"))
|
||||||
|
|
||||||
name = models.CharField(_("name"), max_length=128)
|
name = models.CharField(_("name"), max_length=128)
|
||||||
|
@ -367,6 +367,9 @@ class DocumentParser(LoggingMixin):
|
|||||||
def extract_metadata(self, document_path, mime_type):
|
def extract_metadata(self, document_path, mime_type):
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
def get_pages_count(self, document_path, mime_type):
|
||||||
|
return None
|
||||||
|
|
||||||
def parse(self, document_path, mime_type, file_name=None):
|
def parse(self, document_path, mime_type, file_name=None):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
@ -759,6 +759,7 @@ class DocumentSerializer(
|
|||||||
original_file_name = SerializerMethodField()
|
original_file_name = SerializerMethodField()
|
||||||
archived_file_name = SerializerMethodField()
|
archived_file_name = SerializerMethodField()
|
||||||
created_date = serializers.DateField(required=False)
|
created_date = serializers.DateField(required=False)
|
||||||
|
pages_count = SerializerMethodField()
|
||||||
|
|
||||||
custom_fields = CustomFieldInstanceSerializer(
|
custom_fields = CustomFieldInstanceSerializer(
|
||||||
many=True,
|
many=True,
|
||||||
@ -779,6 +780,9 @@ class DocumentSerializer(
|
|||||||
required=False,
|
required=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def get_pages_count(self, obj):
|
||||||
|
return obj.pages_count
|
||||||
|
|
||||||
def get_original_file_name(self, obj):
|
def get_original_file_name(self, obj):
|
||||||
return obj.original_filename
|
return obj.original_filename
|
||||||
|
|
||||||
@ -894,6 +898,7 @@ class DocumentSerializer(
|
|||||||
"notes",
|
"notes",
|
||||||
"custom_fields",
|
"custom_fields",
|
||||||
"remove_inbox_tags",
|
"remove_inbox_tags",
|
||||||
|
"pages_count",
|
||||||
)
|
)
|
||||||
list_serializer_class = OwnedObjectListSerializer
|
list_serializer_class = OwnedObjectListSerializer
|
||||||
|
|
||||||
|
@ -361,6 +361,7 @@ class DocumentViewSet(
|
|||||||
"archive_serial_number",
|
"archive_serial_number",
|
||||||
"num_notes",
|
"num_notes",
|
||||||
"owner",
|
"owner",
|
||||||
|
"pages_count",
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
@ -444,6 +445,24 @@ class DocumentViewSet(
|
|||||||
logger.warning(f"No parser for {mime_type}")
|
logger.warning(f"No parser for {mime_type}")
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
def get_pages_count(self, file, mime_type):
|
||||||
|
if not os.path.isfile(file):
|
||||||
|
return None
|
||||||
|
|
||||||
|
parser_class = get_parser_class_for_mime_type(mime_type)
|
||||||
|
if parser_class:
|
||||||
|
parser = parser_class(progress_callback=None, logging_group=None)
|
||||||
|
|
||||||
|
try:
|
||||||
|
return parser.get_pages_count(file)
|
||||||
|
except Exception: # pragma: no cover
|
||||||
|
logger.exception(f"Issue getting pages count for {file}")
|
||||||
|
# TODO: cover GPG errors, remove later.
|
||||||
|
return []
|
||||||
|
else: # pragma: no cover
|
||||||
|
logger.warning(f"No parser for {mime_type}")
|
||||||
|
return []
|
||||||
|
|
||||||
def get_filesize(self, filename):
|
def get_filesize(self, filename):
|
||||||
if os.path.isfile(filename):
|
if os.path.isfile(filename):
|
||||||
return os.stat(filename).st_size
|
return os.stat(filename).st_size
|
||||||
|
@ -41,6 +41,15 @@ class RasterisedDocumentParser(DocumentParser):
|
|||||||
"""
|
"""
|
||||||
return OcrConfig()
|
return OcrConfig()
|
||||||
|
|
||||||
|
def get_pages_count(self, document_path, mime_type):
|
||||||
|
pages_count = None
|
||||||
|
if mime_type == "application/pdf":
|
||||||
|
import pikepdf
|
||||||
|
|
||||||
|
pdf = pikepdf.open(document_path)
|
||||||
|
pages_count = len(pdf.pages)
|
||||||
|
return pages_count
|
||||||
|
|
||||||
def extract_metadata(self, document_path, mime_type):
|
def extract_metadata(self, document_path, mime_type):
|
||||||
result = []
|
result = []
|
||||||
if mime_type == "application/pdf":
|
if mime_type == "application/pdf":
|
||||||
|
@ -57,6 +57,20 @@ class TestParser(DirectoriesMixin, FileSystemAssertsMixin, TestCase):
|
|||||||
|
|
||||||
self.assertContainsStrings(text.strip(), ["This is a test document."])
|
self.assertContainsStrings(text.strip(), ["This is a test document."])
|
||||||
|
|
||||||
|
def test_get_pages_count(self):
|
||||||
|
parser = RasterisedDocumentParser(uuid.uuid4())
|
||||||
|
pages_count = parser.get_pages_count(
|
||||||
|
os.path.join(self.SAMPLE_FILES, "simple-digital.pdf"),
|
||||||
|
"application/pdf",
|
||||||
|
)
|
||||||
|
self.assertEqual(pages_count, 1)
|
||||||
|
|
||||||
|
pages_count = parser.get_pages_count(
|
||||||
|
os.path.join(self.SAMPLE_FILES, "multi-page-mixed.pdf"),
|
||||||
|
"application/pdf",
|
||||||
|
)
|
||||||
|
self.assertEqual(pages_count, 6)
|
||||||
|
|
||||||
def test_thumbnail(self):
|
def test_thumbnail(self):
|
||||||
parser = RasterisedDocumentParser(uuid.uuid4())
|
parser = RasterisedDocumentParser(uuid.uuid4())
|
||||||
thumb = parser.get_thumbnail(
|
thumb = parser.get_thumbnail(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user