Compare commits

...

14 Commits
0.6.0 ... 0.7.0

Author SHA1 Message Date
Daniel Quinn
e293f70a91 Merge pull request #247 from danielquinn/issue/235
Allow correspondents to be deleted without deleting their documents
2017-07-15 19:41:33 +01:00
Daniel Quinn
347986a2b3 Allow correspondents to be deleted without deleting their documents
Fixes #235
2017-07-15 19:13:10 +01:00
Daniel Quinn
ede274386b Detect .tif files properly
Fixes #232
2017-07-15 19:02:11 +01:00
Daniel Quinn
3e083354cc Merge pull request #246 from kskyten/vb_memory
Add memory to the virtual machine
2017-07-10 15:02:45 +01:00
Kusti Skytén
b2b4f6516a Add memory to the virtual machine
Fixes #244
2017-07-10 16:55:51 +03:00
Daniel Quinn
2ae702c7bb Merge pull request #245 from tooomm/patch-1
README: unify badges (versioneye)
2017-07-09 18:25:28 +01:00
tooomm
b748420a94 unify badges (versioneye)
normal > flat style
2017-07-09 15:17:42 +02:00
Daniel Quinn
8a4546ce0d Merge pull request #242 from MasterofJOKers/setup_collectstatic
Mention "collectstatic" in the docs
2017-06-27 13:07:07 +01:00
MasterofJOKers
167412a003 Mention "collectstatic" in the docs
When using the built-in webserver in debug mode, the static files are
handled automatically. From the Django docs:

	During development, if you use django.contrib.staticfiles, this will
	be done automatically by runserver when DEBUG is set to True (see
	django.contrib.staticfiles.views.serve()).

	This method is grossly inefficient and probably insecure, so it is
	unsuitable for production.

This means, when using a real webserver, it also has to serve the static
files, i.e.  CSS and JavaScript. For that, one needs to run `./manage.py
collectstatic` first.
2017-06-26 17:08:37 +02:00
Daniel Quinn
e8d90b42a1 Merge pull request #240 from ddddavidmartin/timezone_documentation_clarification
Add link to Django documentation for time zone setting in example config.
2017-06-24 09:24:42 +01:00
David Martin
d8c7e9de5f Add link to documentation for time zone setting in example config.
It is not obvious which time zones the option in the config file
accepts. Having a link to the official django documentation makes it
clear.
2017-06-24 12:27:26 +10:00
Daniel Quinn
2ac1b78a2c Move testing ENV vars into pytest.ini 2017-06-19 10:57:30 +01:00
Daniel Quinn
e8e38befb7 Fix test for new email secret 2017-06-19 10:24:23 +01:00
Daniel Quinn
b30629dd60 Remove debugging info 2017-06-19 09:22:26 +01:00
15 changed files with 125 additions and 23 deletions

View File

@@ -140,5 +140,5 @@ work and they need the money a lot more than I do.
:target: https://gitter.im/danielquinn/paperless?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge
.. |Travis| image:: https://travis-ci.org/danielquinn/paperless.svg?branch=master
:target: https://travis-ci.org/danielquinn/paperless
.. |Dependencies| image:: https://www.versioneye.com/user/projects/57b33b81d9f1b00016faa500/badge.svg?style=flat-square
.. |Dependencies| image:: https://www.versioneye.com/user/projects/57b33b81d9f1b00016faa500/badge.svg
:target: https://www.versioneye.com/user/projects/57b33b81d9f1b00016faa500

5
Vagrantfile vendored
View File

@@ -12,4 +12,9 @@ Vagrant.configure(VAGRANT_API_VERSION) do |config|
# Networking details
config.vm.network "private_network", ip: "172.28.128.4"
config.vm.provider "virtualbox" do |vb|
# Customize the amount of memory on the VM:
vb.memory = "1024"
end
end

View File

@@ -1,6 +1,16 @@
Changelog
#########
* 0.7.0
* **Potentially breaking change**: As per `#235`_, Paperless will no longer
automatically delete documents attached to correspondents when those
correspondents are themselves deleted. This was Django's default
behaviour, but didn't make much sense in Paperless' case. Thanks to
`Thomas Brueggemann`_ and `David Martin`_ for their input on this one.
* Fix for `#232`_ wherein Paperless wasn't recognising ``.tif`` files
properly. Thanks to `ayounggun`_ for reporting this one and to
`Kusti Skytén`_ for posting the correct solution in the Github issue.
* 0.6.0
* Abandon the shared-secret trick we were using for the POST API in favour
of BasicAuth or Django session.
@@ -219,6 +229,8 @@ Changelog
.. _David Martin: https://github.com/ddddavidmartin
.. _Paperless Desktop: https://github.com/thomasbrueggemann/paperless-desktop
.. _Joshua Gilman: https://github.com/jmgilman
.. _ayounggun: https://github.com/ayounggun
.. _Kusti Skytén: https://github.com/kskyten
.. _#20: https://github.com/danielquinn/paperless/issues/20
.. _#44: https://github.com/danielquinn/paperless/issues/44
@@ -256,5 +268,6 @@ Changelog
.. _#228: https://github.com/danielquinn/paperless/pull/228
.. _#229: https://github.com/danielquinn/paperless/pull/229
.. _#230: https://github.com/danielquinn/paperless/pull/230
.. _#232: https://github.com/danielquinn/paperless/issues/232
.. _#235: https://github.com/danielquinn/paperless/issues/235
.. _#236: https://github.com/danielquinn/paperless/issues/236

View File

@@ -394,7 +394,10 @@ Using a Real Webserver
The default is to use Django's development server, as that's easy and does the
job well enough on a home network. However, if you want to do things right,
it's probably a good idea to use a webserver capable of handling more than one
thread.
thread. You will also have to let the webserver serve the static files (CSS,
JavaScript) from the directory configured in ``PAPERLESS_STATICDIR``. For that,
you need to run ``./manage.py collectstatic`` in the ``src`` directory. The
default static files directory is ``../static``.
Apache
~~~~~~

View File

@@ -156,7 +156,9 @@ PAPERLESS_PASSPHRASE="secret"
#### Interface ####
###############################################################################
# Override the default UTC time zone here
# Override the default UTC time zone here.
# See https://docs.djangoproject.com/en/1.10/ref/settings/#std:setting-TIME_ZONE
# for details on how to set it.
#PAPERLESS_TIME_ZONE=UTC

View File

@@ -16,9 +16,11 @@ pytz>=2016.10
gunicorn==19.6.0
# For the tests
factory-boy
pytest
pytest-django
pytest-sugar
pytest-env
pep8
flake8
tox

View File

@@ -165,7 +165,6 @@ class MailFetcher(Loggable):
self._enabled = bool(self._host)
self.last_checked = datetime.datetime.now()
print(self._connection, self._host, self._port, self._username, self._password, self._inbox, self._enabled, self.last_checked)
def pull(self):
"""

View File

@@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.5 on 2017-07-15 17:12
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('documents', '0017_auto_20170512_0507'),
]
operations = [
migrations.AlterField(
model_name='document',
name='correspondent',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='documents', to='documents.Correspondent'),
),
]

View File

@@ -172,7 +172,12 @@ class Document(models.Model):
TYPES = (TYPE_PDF, TYPE_PNG, TYPE_JPG, TYPE_GIF, TYPE_TIF,)
correspondent = models.ForeignKey(
Correspondent, blank=True, null=True, related_name="documents")
Correspondent,
blank=True,
null=True,
related_name="documents",
on_delete=models.SET_NULL
)
title = models.CharField(max_length=128, blank=True, db_index=True)
@@ -316,45 +321,45 @@ class FileInfo(object):
r"(?P<correspondent>.*) - "
r"(?P<title>.*) - "
r"(?P<tags>[a-z0-9\-,]*)"
r"\.(?P<extension>pdf|jpe?g|png|gif|tiff)$",
r"\.(?P<extension>pdf|jpe?g|png|gif|tiff?)$",
flags=re.IGNORECASE
)),
("created-title-tags", re.compile(
r"^(?P<created>\d\d\d\d\d\d\d\d(\d\d\d\d\d\d)?Z) - "
r"(?P<title>.*) - "
r"(?P<tags>[a-z0-9\-,]*)"
r"\.(?P<extension>pdf|jpe?g|png|gif|tiff)$",
r"\.(?P<extension>pdf|jpe?g|png|gif|tiff?)$",
flags=re.IGNORECASE
)),
("created-correspondent-title", re.compile(
r"^(?P<created>\d\d\d\d\d\d\d\d(\d\d\d\d\d\d)?Z) - "
r"(?P<correspondent>.*) - "
r"(?P<title>.*)"
r"\.(?P<extension>pdf|jpe?g|png|gif|tiff)$",
r"\.(?P<extension>pdf|jpe?g|png|gif|tiff?)$",
flags=re.IGNORECASE
)),
("created-title", re.compile(
r"^(?P<created>\d\d\d\d\d\d\d\d(\d\d\d\d\d\d)?Z) - "
r"(?P<title>.*)"
r"\.(?P<extension>pdf|jpe?g|png|gif|tiff)$",
r"\.(?P<extension>pdf|jpe?g|png|gif|tiff?)$",
flags=re.IGNORECASE
)),
("correspondent-title-tags", re.compile(
r"(?P<correspondent>.*) - "
r"(?P<title>.*) - "
r"(?P<tags>[a-z0-9\-,]*)"
r"\.(?P<extension>pdf|jpe?g|png|gif|tiff)$",
r"\.(?P<extension>pdf|jpe?g|png|gif|tiff?)$",
flags=re.IGNORECASE
)),
("correspondent-title", re.compile(
r"(?P<correspondent>.*) - "
r"(?P<title>.*)?"
r"\.(?P<extension>pdf|jpe?g|png|gif|tiff)$",
r"\.(?P<extension>pdf|jpe?g|png|gif|tiff?)$",
flags=re.IGNORECASE
)),
("title", re.compile(
r"(?P<title>.*)"
r"\.(?P<extension>pdf|jpe?g|png|gif|tiff)$",
r"\.(?P<extension>pdf|jpe?g|png|gif|tiff?)$",
flags=re.IGNORECASE
))
])
@@ -397,6 +402,8 @@ class FileInfo(object):
r = extension.lower()
if r == "jpeg":
return "jpg"
if r == "tif":
return "tiff"
return r
@classmethod

View File

@@ -0,0 +1,17 @@
import factory
from ..models import Document, Correspondent
class CorrespondentFactory(factory.DjangoModelFactory):
class Meta:
model = Correspondent
name = factory.Faker("name")
class DocumentFactory(factory.DjangoModelFactory):
class Meta:
model = Document

View File

@@ -58,9 +58,9 @@ class TestAttributes(TestCase):
TAGS = ("tag1", "tag2", "tag3")
EXTENSIONS = (
"pdf", "png", "jpg", "jpeg", "gif",
"PDF", "PNG", "JPG", "JPEG", "GIF",
"PdF", "PnG", "JpG", "JPeG", "GiF",
"pdf", "png", "jpg", "jpeg", "gif", "tiff", "tif",
"PDF", "PNG", "JPG", "JPEG", "GIF", "TIFF", "TIF",
"PdF", "PnG", "JpG", "JPeG", "GiF", "TiFf", "TiF",
)
def _test_guess_attributes_from_name(self, path, sender, title, tags):
@@ -80,6 +80,8 @@ class TestAttributes(TestCase):
self.assertEqual(tuple([t.slug for t in file_info.tags]), tags, f)
if extension.lower() == "jpeg":
self.assertEqual(file_info.extension, "jpg", f)
elif extension.lower() == "tif":
self.assertEqual(file_info.extension, "tiff", f)
else:
self.assertEqual(file_info.extension, extension.lower(), f)

View File

@@ -0,0 +1,31 @@
from django.test import TestCase
from ..models import Document, Correspondent
from .factories import DocumentFactory, CorrespondentFactory
class CorrespondentTestCase(TestCase):
def test___str__(self):
for s in ("test", "οχι", "test with fun_charÅc'\"terß"):
correspondent = CorrespondentFactory.create(name=s)
self.assertEqual(str(correspondent), s)
class DocumentTestCase(TestCase):
def test_correspondent_deletion_does_not_cascade(self):
self.assertEqual(Correspondent.objects.all().count(), 0)
correspondent = CorrespondentFactory.create()
self.assertEqual(Correspondent.objects.all().count(), 1)
self.assertEqual(Document.objects.all().count(), 0)
DocumentFactory.create(correspondent=correspondent)
self.assertEqual(Document.objects.all().count(), 1)
self.assertIsNotNone(Document.objects.all().first().correspondent)
correspondent.delete()
self.assertEqual(Correspondent.objects.all().count(), 0)
self.assertEqual(Document.objects.all().count(), 1)
self.assertIsNone(Document.objects.all().first().correspondent)

View File

@@ -1 +1 @@
__version__ = (0, 6, 0)
__version__ = (0, 6, 1)

View File

@@ -1,3 +1,7 @@
[pytest]
DJANGO_SETTINGS_MODULE=paperless.settings
env =
PAPERLESS_CONSUME=/tmp
PAPERLESS_PASSPHRASE=THISISNOTASECRET
PAPERLESS_SECRET=paperless
PAPERLESS_EMAIL_SECRET=paperless

View File

@@ -8,12 +8,8 @@ skipsdist = True
envlist = py34, py35, py36, pep8
[testenv]
commands = {envpython} manage.py test
commands = pytest
deps = -r{toxinidir}/../requirements.txt
setenv =
PAPERLESS_CONSUME=/tmp
PAPERLESS_PASSPHRASE=THISISNOTASECRET
PAPERLESS_SECRET=paperless
[testenv:pep8]
commands=pep8