0001-add-python3-support-40614.patch
debian/control | ||
---|---|---|
2 | 2 |
Maintainer: Entr'ouvert <info@entrouvert.com> |
3 | 3 |
Section: python |
4 | 4 |
Priority: optional |
5 |
Build-Depends: python-setuptools (>= 0.6b3), python-all (>= 2.6), debhelper (>= 7.4.3), |
|
6 |
python-django (>= 1.8) |
|
5 |
Build-Depends: python3-setuptools, python3-all, python3-django, python-setuptools (>= 0.6b3), python-all (>= 2.6), debhelper (>= 7.4.3), python-django (>= 1.8) |
|
7 | 6 |
Standards-Version: 3.9.1 |
8 |
X-Python-Version: >= 2.7 |
|
7 | ||
8 |
Package: python3-django-journal |
|
9 |
Architecture: all |
|
10 |
Depends: ${misc:Depends}, ${python3:Depends}, |
|
11 |
python3-django (>= 1:1.11) |
|
12 |
Description: Django application to keep a structured -- i.e. not just log |
|
13 |
strings -- journal of events in your project (Python 3 module) |
|
14 | ||
9 | 15 | |
10 | 16 |
Package: python-django-journal |
11 | 17 |
Architecture: all |
django_journal/actions.py | ||
---|---|---|
3 | 3 | |
4 | 4 |
from django.utils.translation import ugettext_lazy as _ |
5 | 5 |
from django.http import HttpResponse |
6 |
from django.core import exceptions
|
|
6 |
from django.utils.encoding import force_text
|
|
7 | 7 | |
8 | 8 | |
9 | 9 |
from . import models |
... | ... | |
14 | 14 |
for tag in list(tags): |
15 | 15 |
tags.add('%s__id' % tag) |
16 | 16 |
tags |= set(models.Tag.objects.filter(stringdata__journal__in=queryset).values_list('name', flat=True)) |
17 |
extra_headers = map(lambda s: s.encode('utf-8'), sorted(tags))
|
|
17 |
extra_headers = list(sorted(tags))
|
|
18 | 18 |
yield header+extra_headers |
19 | 19 |
for journal in queryset: |
20 | 20 |
row = { |
21 | 21 |
'time': journal.time.isoformat(' '), |
22 |
'tag': journal.tag.name.encode('utf-8'),
|
|
23 |
'message': unicode(journal).encode('utf-8'),
|
|
22 |
'tag': force_text(journal.tag.name),
|
|
23 |
'message': force_text(journal),
|
|
24 | 24 |
} |
25 | 25 |
for stringdata in journal.stringdata_set.all(): |
26 | 26 |
row_name = stringdata.tag.name.encode('utf-8') |
27 |
row[row_name] = stringdata.content.encode('utf-8')
|
|
27 |
row[force_text(row_name)] = force_text(stringdata.content)
|
|
28 | 28 |
for objectdata in journal.objectdata_set.all(): |
29 |
row_name = objectdata.tag.name.encode('utf-8')
|
|
30 |
row[row_name+'__id'] = str(objectdata.object_id)
|
|
29 |
row_name = force_text(objectdata.tag.name)
|
|
30 |
row[row_name + '__id'] = str(objectdata.object_id)
|
|
31 | 31 |
if objectdata.content_object is None: |
32 | 32 |
row[row_name] = '<deleted>' |
33 | 33 |
else: |
34 |
row[row_name] = unicode(objectdata.content_object).encode('utf-8')
|
|
34 |
row[row_name] = force_text(objectdata.content_object)
|
|
35 | 35 |
yield row |
36 | 36 | |
37 | 37 |
def export_as_csv(modeladmin, request, queryset): |
django_journal/journal.py | ||
---|---|---|
3 | 3 |
from django.conf import settings |
4 | 4 |
from django.contrib.contenttypes.models import ContentType |
5 | 5 |
import django.db.models |
6 |
from django.utils.encoding import force_text |
|
6 | 7 | |
7 | 8 |
from .decorator import atomic |
8 | 9 |
from .exceptions import JournalException |
... | ... | |
28 | 29 |
kwargs: |
29 | 30 |
a mapping of object or data to interpolate in the format string |
30 | 31 |
''' |
31 |
template = unicode(template)
|
|
32 |
template = force_text(template)
|
|
32 | 33 |
tag = Tag.objects.using(using).get_cached(name=tag) |
33 | 34 |
template = Template.objects.using(using).get_cached(content=template) |
34 | 35 |
try: |
35 | 36 |
message = template.content.format(**kwargs) |
36 |
except (KeyError, IndexError), e:
|
|
37 |
except (KeyError, IndexError) as e:
|
|
37 | 38 |
raise JournalException( |
38 | 39 |
'Missing variable for the template message', template, e) |
39 | 40 |
try: |
... | ... | |
51 | 52 |
pass # we tried, really, we tried |
52 | 53 |
journal = Journal.objects.using(using).create(tag=tag, template=template, |
53 | 54 |
message=unicode_truncate(message, 128)) |
54 |
for name, value in kwargs.iteritems():
|
|
55 |
for name, value in kwargs.items(): |
|
55 | 56 |
if value is None: |
56 | 57 |
continue |
57 | 58 |
tag = Tag.objects.using(using).get_cached(name=name) |
... | ... | |
61 | 62 |
object_id=value.pk |
62 | 63 |
) |
63 | 64 |
else: |
64 |
journal.stringdata_set.create(tag=tag, content=unicode(value))
|
|
65 |
journal.stringdata_set.create(tag=tag, content=force_text(value))
|
|
65 | 66 |
return journal |
66 | 67 | |
67 | 68 |
django_journal/models.py | ||
---|---|---|
2 | 2 | |
3 | 3 |
from django.db import models |
4 | 4 |
from django.contrib.contenttypes.fields import GenericForeignKey |
5 |
from django.utils.encoding import python_2_unicode_compatible |
|
5 | 6 |
from django.utils.translation import ugettext_lazy as _ |
6 | 7 | |
7 |
import managers |
|
8 |
from . import managers
|
|
8 | 9 | |
9 | 10 | |
11 |
@python_2_unicode_compatible |
|
10 | 12 |
class Tag(models.Model): |
11 | 13 |
'''Tag allows typing event and data linked to events. |
12 | 14 | |
... | ... | |
17 | 19 |
name = models.CharField(verbose_name=_('name'), max_length=32, unique=True, |
18 | 20 |
db_index=True) |
19 | 21 | |
20 |
def __unicode__(self):
|
|
22 |
def __str__(self):
|
|
21 | 23 |
return self.name |
22 | 24 | |
23 | 25 |
def natural_key(self): |
... | ... | |
28 | 30 |
verbose_name = _('tag') |
29 | 31 | |
30 | 32 | |
33 |
@python_2_unicode_compatible |
|
31 | 34 |
class Template(models.Model): |
32 | 35 |
'''Template for formatting an event. |
33 | 36 | |
... | ... | |
38 | 41 |
content = models.TextField(verbose_name=_('content'), unique=True, |
39 | 42 |
db_index=True) |
40 | 43 | |
41 |
def __unicode__(self):
|
|
44 |
def __str__(self):
|
|
42 | 45 |
return self.content |
43 | 46 | |
44 | 47 |
def natural_key(self): |
... | ... | |
48 | 51 |
ordering = ('content',) |
49 | 52 | |
50 | 53 | |
54 |
@python_2_unicode_compatible |
|
51 | 55 |
class Journal(models.Model): |
52 | 56 |
'''One line of the journal. |
53 | 57 | |
... | ... | |
98 | 102 |
tag=Tag.objects.get_cached(name=tag_name), |
99 | 103 |
content_object=obj).save() |
100 | 104 | |
101 |
def __unicode__(self):
|
|
105 |
def __str__(self):
|
|
102 | 106 |
ctx = self.message_context() |
103 | 107 |
return self.template.content.format(**ctx) |
104 | 108 | |
... | ... | |
127 | 131 |
verbose_name = _('linked text string') |
128 | 132 | |
129 | 133 | |
134 |
@python_2_unicode_compatible |
|
130 | 135 |
class ObjectData(models.Model): |
131 | 136 |
'''Object data associated with a recorded event. |
132 | 137 | |
... | ... | |
150 | 155 |
unique_together = (('journal', 'tag'),) |
151 | 156 |
verbose_name = _('linked object') |
152 | 157 | |
153 |
def __unicode__(self):
|
|
158 |
def __str__(self):
|
|
154 | 159 |
return u'{0}:{1}:{2}'.format(self.journal.id, self.tag, self.content_object) |
tests/test_main.py | ||
---|---|---|
1 | 1 |
from django.test import TestCase |
2 | 2 |
from django.contrib.auth.models import User, Group |
3 | 3 |
from django.db import transaction |
4 |
from django.utils.encoding import force_text |
|
4 | 5 | |
5 | 6 | |
6 | 7 |
from django_journal.journal import record, error_record |
... | ... | |
30 | 31 | |
31 | 32 |
def test_login(self): |
32 | 33 |
for i, event in zip(range(20), Journal.objects.for_tag('login').order_by('id')): |
33 |
self.assertEqual(unicode(event), 'user{0} logged in'.format(i))
|
|
34 |
self.assertEqual(force_text(event), 'user{0} logged in'.format(i))
|
|
34 | 35 | |
35 | 36 |
def test_groups(self): |
36 | 37 |
for i, event in zip(range(40), Journal.objects.for_tag('group-changed').order_by('id')): |
37 |
self.assertEqual(unicode(event),
|
|
38 |
self.assertEqual(force_text(event),
|
|
38 | 39 |
'user{0} gave group group{0} to user{1}'.format(i, (i+1)%20)) |
39 | 40 | |
40 | 41 |
def test_logout(self): |
41 | 42 |
for i, event in zip(range(20), Journal.objects.for_tag('logout').order_by('id')): |
42 |
self.assertEqual(unicode(event), 'user{0} logged out'.format(i))
|
|
43 |
self.assertEqual(force_text(event), 'user{0} logged out'.format(i))
|
|
43 | 44 | |
44 | 45 |
def test_export_as_csv(self): |
45 | 46 |
qs = Journal.objects.all() |
tox.ini | ||
---|---|---|
1 | 1 |
[tox] |
2 | 2 |
toxworkdir = /tmp/tox-{env:USER}/django-journal/{env:BRANCH_NAME:} |
3 |
envlist = py2-coverage-{django111,django18} |
|
3 |
envlist = py2-coverage-{django111,django18},py3-django111
|
|
4 | 4 | |
5 | 5 | |
6 | 6 |
[testenv] |
7 |
basepython = python2 |
|
8 | 7 |
usedevelop = True |
9 | 8 |
deps = |
10 | 9 |
django18: django<1.9 |
11 |
- |