django-todo 2.5.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. django_todo-2.5.2.dist-info/METADATA +464 -0
  2. django_todo-2.5.2.dist-info/RECORD +80 -0
  3. django_todo-2.5.2.dist-info/WHEEL +5 -0
  4. django_todo-2.5.2.dist-info/licenses/LICENSE +27 -0
  5. django_todo-2.5.2.dist-info/top_level.txt +1 -0
  6. todo/__init__.py +9 -0
  7. todo/admin.py +56 -0
  8. todo/check.py +17 -0
  9. todo/data/import_example.csv +4 -0
  10. todo/defaults.py +28 -0
  11. todo/features.py +16 -0
  12. todo/forms.py +87 -0
  13. todo/mail/__init__.py +0 -0
  14. todo/mail/consumers/__init__.py +9 -0
  15. todo/mail/consumers/tracker.py +171 -0
  16. todo/mail/delivery.py +27 -0
  17. todo/mail/producers/__init__.py +9 -0
  18. todo/mail/producers/imap.py +98 -0
  19. todo/management/__init__.py +0 -0
  20. todo/management/commands/__init__.py +0 -0
  21. todo/management/commands/hopper.py +152 -0
  22. todo/management/commands/import_csv.py +57 -0
  23. todo/management/commands/mail_worker.py +41 -0
  24. todo/migrations/0001_initial.py +101 -0
  25. todo/migrations/0002_auto_20150614_2339.py +18 -0
  26. todo/migrations/0003_assignee_optional.py +26 -0
  27. todo/migrations/0004_rename_list_tasklist.py +45 -0
  28. todo/migrations/0005_auto_20180212_2325.py +17 -0
  29. todo/migrations/0006_rename_item_model.py +14 -0
  30. todo/migrations/0007_auto_update_created_date.py +17 -0
  31. todo/migrations/0008_mail_tracker.py +46 -0
  32. todo/migrations/0009_priority_optional.py +19 -0
  33. todo/migrations/0010_attachment.py +46 -0
  34. todo/migrations/0011_add_related_name_to_created_by.py +20 -0
  35. todo/migrations/0012_add_related_name_to_comments.py +20 -0
  36. todo/migrations/__init__.py +0 -0
  37. todo/models.py +186 -0
  38. todo/operations/__init__.py +0 -0
  39. todo/operations/csv_importer.py +211 -0
  40. todo/static/todo/css/styles.css +4 -0
  41. todo/static/todo/js/jquery.tablednd_0_5.js +382 -0
  42. todo/templates/base.html +1 -0
  43. todo/templates/todo/add_list.html +23 -0
  44. todo/templates/todo/add_task_external.html +47 -0
  45. todo/templates/todo/base.html +7 -0
  46. todo/templates/todo/del_list.html +33 -0
  47. todo/templates/todo/email/assigned_body.txt +25 -0
  48. todo/templates/todo/email/assigned_subject.txt +1 -0
  49. todo/templates/todo/email/newcomment_body.txt +23 -0
  50. todo/templates/todo/import_csv.html +85 -0
  51. todo/templates/todo/include/task_edit.html +55 -0
  52. todo/templates/todo/include/toggle_delete.html +12 -0
  53. todo/templates/todo/list_detail.html +114 -0
  54. todo/templates/todo/list_lists.html +33 -0
  55. todo/templates/todo/search_results.html +30 -0
  56. todo/templates/todo/task_detail.html +212 -0
  57. todo/templatetags/__init__.py +0 -0
  58. todo/templatetags/todo_tags.py +9 -0
  59. todo/tests/__init__.py +0 -0
  60. todo/tests/conftest.py +42 -0
  61. todo/tests/test_import.py +76 -0
  62. todo/tests/test_tracker.py +116 -0
  63. todo/tests/test_utils.py +80 -0
  64. todo/tests/test_views.py +352 -0
  65. todo/urls.py +49 -0
  66. todo/utils.py +174 -0
  67. todo/views/__init__.py +12 -0
  68. todo/views/add_list.py +48 -0
  69. todo/views/del_list.py +41 -0
  70. todo/views/delete_task.py +42 -0
  71. todo/views/external_add.py +81 -0
  72. todo/views/import_csv.py +34 -0
  73. todo/views/list_detail.py +85 -0
  74. todo/views/list_lists.py +54 -0
  75. todo/views/remove_attachment.py +40 -0
  76. todo/views/reorder_tasks.py +35 -0
  77. todo/views/search.py +43 -0
  78. todo/views/task_autocomplete.py +29 -0
  79. todo/views/task_detail.py +151 -0
  80. todo/views/toggle_done.py +43 -0
@@ -0,0 +1,464 @@
1
+ Metadata-Version: 2.4
2
+ Name: django-todo
3
+ Version: 2.5.2
4
+ Summary: A multi-user, multi-group task management and assignment system for Django.
5
+ Author-email: Scot Hacker <shacker@birdhouse.org>
6
+ License: BSD-3-Clause
7
+ Project-URL: Homepage, http://django-todo.org
8
+ Classifier: Environment :: Web Environment
9
+ Classifier: Framework :: Django
10
+ Classifier: Framework :: Django :: 4.0
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: BSD License
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3 :: Only
17
+ Classifier: Programming Language :: Python :: 3.9
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Requires-Python: >=3.9
21
+ Description-Content-Type: text/markdown
22
+ License-File: LICENSE
23
+ Requires-Dist: Django>=4.0
24
+ Requires-Dist: factory-boy
25
+ Requires-Dist: titlecase
26
+ Requires-Dist: bleach
27
+ Requires-Dist: django-autocomplete-light
28
+ Requires-Dist: html2text
29
+ Dynamic: license-file
30
+
31
+ # django-todo
32
+
33
+ django-todo is a pluggable, multi-user, multi-group task management and
34
+ assignment application for Django, designed to be dropped into an existing site as a reusable app. django-todo can be used as a personal to-do tracker, or a group task management system, or a ticketing system for organizations (or all of these at once!)
35
+
36
+ **The best way to learn how django-todo works is to visit the live demo site at [django-todo.org](http://django-todo.org)!**
37
+
38
+ ## Features
39
+
40
+ * Drag and drop task prioritization
41
+ * Email task notification
42
+ * Search
43
+ * Comments on tasks
44
+ * Public-facing submission form for tickets
45
+ * Mobile-friendly (work in progress)
46
+ * Separate view for My Tasks (across lists)
47
+ * Batch-import tasks via CSV
48
+ * Batch-export tasks in CSV Format
49
+ * Multiple file attachments per task (see settings)
50
+ * Integrated mail tracking (unify a task list with an email box)
51
+
52
+
53
+ ## Requirements
54
+
55
+ * Django 2.0+
56
+ * Python 3.6+
57
+ * jQuery (full version, not "slim", for drag/drop prioritization)
58
+ * Bootstrap v5 (to work with provided templates, though you can override them)
59
+ * bleach (`pip install bleach`)
60
+ * django-autocomplete-light (optional, required for task merging)
61
+
62
+ ## Overview
63
+
64
+ We assume that your organization has multiple groups of employees, each with multiple users (where actual users and groups map to Django Users and Groups). Users may belong to multiple groups, and each group can have multiple todo lists.
65
+
66
+ You must have at least one Group set up in Django admin, and that group must have at least one User as a member. This is true even if you're the sole user of django-todo.
67
+
68
+ Users can view and modify all to-do lists belonging to their group(s). Only users with `is_staff` can add or delete lists.
69
+
70
+ Identical list names can exist in different groups, but not in the same group.
71
+
72
+ Emails are generated to the assigned-to person when new tasks are created.
73
+
74
+ File attachments of a few types are allowed on tasks by default. See settings to disable or to limit filetypes. If you are concerned about file sizes, limit them in your web server configuration (not currently handled separately by django-todo).
75
+
76
+ Comment threads can be added to tasks. Each participant in a thread receives email when new comments are added.
77
+
78
+ django-todo is auth-only. You must set up a login system and at least one group before deploying.
79
+
80
+ All tasks are "created by" the current user and can optionally be "assigned to" a specific user. Unassigned tickets appear as belonging to "anyone" in the UI.
81
+
82
+ django-todo v2 makes use of features only available in Django 2.0. It will not work in previous versions. v2 is only tested against Python 3.x -- no guarantees if running it against older versions.
83
+
84
+ ## Installation
85
+
86
+ django-todo is a Django app, not a project site. It needs a site to live in. You can either install it into an existing Django project site, or clone the django-todo [demo site (GTD)](https://github.com/shacker/gtd).
87
+
88
+ If using your own site, be sure you have jQuery and Bootstrap v5 wired up and working.
89
+
90
+ django-todo views that require it will insert additional CSS/JavaScript into page heads, so your project's base templates must include:
91
+
92
+ ```jinja
93
+ {% block extrahead %}{% endblock extrahead %}
94
+ {% block extra_js %}{% endblock extra_js %}
95
+ ```
96
+
97
+ django-todo comes with its own `todo/base.html`, which extends your master `base.html`. All content lives inside of:
98
+
99
+ `{% block content %}{% endblock %}`
100
+
101
+ If you use some other name for your main content area, you'll need to override and alter the provided templates.
102
+
103
+ All views are login-required. Therefore, you must have a working user authentication system.
104
+
105
+ For email notifications to work, make sure your site/project is [set up to send email](https://docs.djangoproject.com/en/2.0/topics/email/).
106
+
107
+ Make sure you've installed the Django "sites" framework and have specified the default site in settings, e.g. `SITE_ID = 1`
108
+
109
+ Put django-todo/todo somewhere on your Python path, or install via pip:
110
+
111
+ pip install django-todo
112
+
113
+
114
+ Add to your settings:
115
+
116
+ ```
117
+ INSTALLED_APPS = (
118
+ ...
119
+ 'todo',
120
+ )
121
+ ```
122
+
123
+ Migrate in database tables:
124
+
125
+ `python manage.py migrate todo`
126
+
127
+ Add to your URL conf:
128
+
129
+ `path('todo/', include('todo.urls', namespace="todo")),`
130
+
131
+ Add links to your site's navigation system:
132
+
133
+ ```
134
+ <a href="{% url 'todo:lists' %}">Todo Lists</a>
135
+ <a href="{% url 'todo:mine' %}">My Tasks</a>
136
+ ```
137
+
138
+ django-todo makes use of the Django `messages` system. Make sure you have something like [this](https://docs.djangoproject.com/en/2.1/ref/contrib/messages/#displaying-messages) (link) in your `base.html`.
139
+
140
+ Log in and access `/todo`!
141
+
142
+ ### Customizing Templates
143
+
144
+ The provided templates are fairly bare-bones, and are meant as starting points only. Unlike previous versions of django-todo, they now ship as Bootstrap examples, but feel free to override them - there is no hard dependency on Bootstrap. To override a template, create a `todo` folder in your project's `templates` dir, then copy the template you want to override from django-todo source and into that dir.
145
+
146
+ ### Filing Public Tickets
147
+
148
+ If you wish to use the public ticket-filing system, first create the list into which those tickets should be filed, then add its slug to `TODO_DEFAULT_LIST_SLUG` in settings (more on settings below).
149
+
150
+ ## Settings
151
+
152
+ Optional configuration params, which can be added to your project settings:
153
+
154
+ ```python
155
+ # Restrict access to ALL todo lists/views to `is_staff` users.
156
+ # If False or unset, all users can see all views (but more granular permissions are still enforced
157
+ # within views, such as requiring staff for adding and deleting lists).
158
+ TODO_STAFF_ONLY = True
159
+
160
+ # If you use the "public" ticket filing option, to whom should these tickets be assigned?
161
+ # Must be a valid username in your system. If unset, unassigned tickets go to "Anyone."
162
+ TODO_DEFAULT_ASSIGNEE = 'johndoe'
163
+
164
+ # If you use the "public" ticket filing option, to which list should these tickets be saved?
165
+ # Defaults to first list found, which is probably not what you want!
166
+ TODO_DEFAULT_LIST_SLUG = 'tickets'
167
+
168
+ # If you use the "public" ticket filing option, to which *named URL* should the user be
169
+ # redirected after submitting? (since they can't see the rest of the ticket system).
170
+ # Defaults to "/"
171
+ TODO_PUBLIC_SUBMIT_REDIRECT = 'dashboard'
172
+
173
+ # Enable or disable file attachments on Tasks
174
+ # Optionally limit list of allowed filetypes
175
+ TODO_ALLOW_FILE_ATTACHMENTS = True
176
+ TODO_ALLOWED_FILE_ATTACHMENTS = [".jpg", ".gif", ".csv", ".pdf", ".zip"]
177
+ TODO_MAXIMUM_ATTACHMENT_SIZE = 5000000 # In bytes
178
+
179
+ # Additional classes the comment body should hold.
180
+ # Adding "text-monospace" makes comment monospace
181
+ TODO_COMMENT_CLASSES = []
182
+
183
+ # The following setting is relevant only if you have enabled email generation (see below).
184
+ # If set to `True`, links in generated emails start by the `http` protocol.
185
+ # If set to `False` or unset, those links start by the `https` protocol, falling back to the latter by default.
186
+ # This setting is only recommended on development environments, on production environments `https` is a security standard.
187
+ TODO_MAIL_LINK_FORCE_HTTP = True
188
+
189
+ # The following setting is relevant if you want emails being generated on task assignment and comments on tasks.
190
+ # Without a proper mail backend email generation is skipped silently.
191
+ TODO_MAIL_BACKENDS
192
+
193
+ # The following setting is relevant only if you want todo to track a support mailbox -
194
+ # see Mail Tracking below.
195
+ TODO_MAIL_TRACKERS
196
+ ```
197
+
198
+ The current django-todo version number is available from the [todo package](https://github.com/shacker/django-todo/blob/master/todo/__init__.py):
199
+
200
+ python -c "import todo; print(todo.__version__)"
201
+
202
+ ## Importing Tasks via CSV
203
+
204
+ django-todo has the ability to batch-import ("upsert") tasks from a specifically formatted CSV spreadsheet. This ability is provided through both a management command and a web interface.
205
+
206
+ **Management Command**
207
+
208
+ `./manage.py import_csv -f /path/to/file.csv`
209
+
210
+ **Web Importer**
211
+
212
+ Link from your navigation to `{url "todo:import_csv"}`. Follow the resulting link for the CSV web upload view.
213
+
214
+
215
+ ### CSV Formatting
216
+
217
+ Copy `todo/data/import_example.csv` to another location on your system and edit in a spreadsheet or directly.
218
+
219
+ **Do not edit the header row!**
220
+
221
+ The first four columns: `'Title', 'Group', 'Task List', 'Created By'` are required -- all others are optional and should work pretty much exactly like manual task entry via the web UI.
222
+
223
+ Note: Internally, Tasks are keyed to TaskLists, not to Groups (TaskLists are in Gruops). However, we request the Group in the CSV
224
+ because it's possible to have multiple TaskLists with the same name in different groups; i.e. we need it for namespacing and permissions.
225
+
226
+
227
+ ### Import Rules
228
+
229
+ Because data entered via CSV is not going through the same view permissions enforced in the rest of django-todo, and to simplify data dependency logic, and to pre-empt disagreements between django-todo users, the importer will *not* create new users, groups, or task lists. All users, groups, and task lists referenced in your CSV must already exist, and group memberships must be correct.
230
+
231
+ Any validation error (e.g. unparse-able dates, incorrect group memberships) **will result in that row being skipped.**
232
+
233
+ A report of rows upserted and rows skipped (with line numbers and reasons) is provided at the end of the run.
234
+
235
+ ### Upsert Logic
236
+
237
+ For each valid row, we need to decide whether to create a new task or update an existing one. django-todo matches on the unique combination of the four required columns. If we find a task that matches those, we *update* the rest of the columns. In other words, if you import a CSV once, then edit the Assigned To for a task and import it again, the original task will be updated with a new assignee (and same for the other columns).
238
+
239
+ Otherwise we create a new task.
240
+
241
+
242
+ ## Mail Tracking
243
+
244
+ What if you could turn django-todo into a shared mailbox? Django-todo includes an optional feature that allows emails
245
+ sent to a dedicated mailbox to be pushed into todo as new tasks, and responses to be added as comments on those tasks.
246
+ This allows support teams to work with a fully unified email + bug tracking system to avoid confusion over who's seen or
247
+ responded to what.
248
+
249
+ To enable mail tracking, you need to:
250
+
251
+ - Define an email backend for outgoing emails
252
+ - Define an email backend for incoming emails
253
+ - Start a worker, which will wait for new emails
254
+
255
+ In settings:
256
+
257
+ ```python
258
+ from todo.mail.producers import imap_producer
259
+ from todo.mail.consumers import tracker_consumer
260
+ from todo.mail.delivery import smtp_backend, console_backend
261
+
262
+ # email notifications configuration
263
+ # each task list can get its own delivery method
264
+ TODO_MAIL_BACKENDS = {
265
+ # mail-queue is the slug of the task list, not the worker name
266
+ "mail-queue": smtp_backend(
267
+ host="smtp.example.com",
268
+ port=465,
269
+ use_ssl=True,
270
+ username="test@example.com",
271
+ password="foobar",
272
+ # used as the From field when sending notifications.
273
+ # a username might be prepended later on
274
+ from_address="test@example.com",
275
+ # additionnal headers
276
+ headers={}
277
+ ),
278
+ }
279
+
280
+ # incoming mail worker configuration
281
+ TODO_MAIL_TRACKERS = {
282
+ # configuration for worker "test_tracker"
283
+ "test_tracker": {
284
+ "producer": imap_producer(
285
+ host="imap.example.com",
286
+ username="text@example.com",
287
+ password="foobar",
288
+ # process_all=False, # by default, only unseen emails are processed
289
+ # preserve=False, # delete emails if False
290
+ # nap_duration=1, # duration of the pause between polling rounds
291
+ # input_folder="INBOX", # where to read emails from
292
+ ),
293
+ "consumer": tracker_consumer(
294
+ group="Mail Queuers",
295
+ task_list_slug="mail-queue",
296
+ priority=1,
297
+ task_title_format="[TEST_MAIL] {subject}",
298
+ )
299
+ }
300
+ }
301
+ ```
302
+
303
+ Optionally, the email addresses of incoming emails can be mapped back to django users. If a user emails the test_tracker, and also is a registered User in your application, the user will show up as having created the task or comment. By default, only the email address will show up.
304
+
305
+ This isn't enabled by default, as some domains are misconfigured and do not prevent impersonation. If this option is enabled and your setup doesn't properly authenticate emails, malicious incoming emails might mistakenly be attributed to users.
306
+
307
+ Settings:
308
+ ```python
309
+ TODO_MAIL_USER_MAPPER = None # Set to True if you would like to match users. If you do not have authentication setup, do not set this to True.
310
+ ```
311
+
312
+ A mail worker can be started with:
313
+
314
+ ```sh
315
+ ./manage.py mail_worker test_tracker
316
+ ```
317
+
318
+ Some views and URLs were renamed in 2.0 for logical consistency. If this affects you, see source code and the demo GTD site for reference to the new URL names.
319
+
320
+ If you want to log mail events, make sure to properly configure django logging:
321
+
322
+ ```python
323
+ LOGGING = {
324
+ 'version': 1,
325
+ 'disable_existing_loggers': False,
326
+ 'handlers': {
327
+ 'console': {
328
+ 'class': 'logging.StreamHandler',
329
+ },
330
+ },
331
+ 'loggers': {
332
+ '': {
333
+ 'handlers': ['console'],
334
+ 'level': 'DEBUG',
335
+ 'propagate': True,
336
+ },
337
+ },
338
+ }
339
+ ```
340
+
341
+
342
+ ## Running Tests
343
+
344
+ django-todo uses pytest exclusively for testing. The best way to run the suite is to clone django-todo into its own directory, install pytest, then:
345
+
346
+ pip install pytest pytest-django
347
+ pip install --editable .
348
+ pytest -x -v
349
+
350
+ ## Version History
351
+
352
+ **2.5.2** Migrate from setup.cfg to pyproject.toml
353
+
354
+ **2.5.1** Upgrade templates to Bootstrap 5; fix CSV importer crash on non-UTF-8 and BOM-encoded files; remove stale docs/index.md
355
+
356
+ **2.5.0** Change setup to pyprojec.toml
357
+
358
+ **2.4.11** Add SECURITY.md
359
+
360
+ **2.4.10** It is now possible to use unicode characters (such as Chinese) as the only chars in a list title.
361
+
362
+ **2.4.9** Fixed: Editing a task should not change its completed/incomplete status
363
+
364
+ **2.4.8** Fix bug when setting default values for unspecified settings
365
+
366
+ **2.4.7** Support custom user model in external_add
367
+
368
+ **2.4.6** Use `defaults` hash for default settings, update perms and tests
369
+
370
+ **2.4.5** Re-enable "notify" feature during task edit
371
+
372
+ **2.4.4** Fix issues with setup.py / installation
373
+
374
+ **2.4.0** Implement optional file attachments on tasks
375
+
376
+ **2.3.2** Update setup.py metadata
377
+
378
+ **2.3.1** Improve error handling for badly formatted or non-existent CSV uploads.
379
+
380
+ **2.3.0** Implement mail tracking system. Added ability to batch-import tasks via CSV. Fixed task re-ordering if task deleted behind the scenes.
381
+
382
+ **2.2.2** Update dependencies
383
+
384
+ **2.2.1** Convert task delete and toggle_done views to POST only
385
+
386
+ **2.2.0** Re-instate enforcement of TODO_STAFF_ONLY setting
387
+
388
+ **2.1.1** Correct Python version requirement in documentation to Python 3.6
389
+
390
+ **2.1.1** Split up views into separate modules.
391
+
392
+ **2.1.0** December 2018: No longer allowing Javascript in task or comment bodies. Misc bug fixes.
393
+
394
+ **2.0.3** April 2018: Bump production status in setup.py
395
+
396
+ **2.0.2** April 2018: Improve notification email subjects and bodies
397
+
398
+ **2.0.1** April 2018: Refactored "toggle done" and "delete" actions from list view.
399
+
400
+ **2.0** April 2018: Major project refactor, with almost completely rewritten views, templates, and todo's first real test suite.
401
+
402
+ **1.6.2** Added support for unicode characters in list name/slugs.
403
+
404
+ **1.6.1** Minor bug fixes.
405
+
406
+ **1.6** Allow unassigned ("Anyone") tasks. Clean-up / modernize templates and views. Testing infrastructure in place.
407
+
408
+ **1.5** flake8 support, Item note no longer a required field, fix warnings for Django 1.8, Python 2/3-compatible unicode strings, simple search for tasks, get_absolute_url() for items.
409
+
410
+ **1.4** - Removed styling from default templates. Added excludes fields from Form definitions to prevent warnings. Removed deprecated 'cycle' tags from templates. Added settings for various elements for public ticket submissions.
411
+
412
+ **1.3** - Removed stray direct_to_template reference. Quoted all named URL references for Django 1.5 compatibility.
413
+
414
+ **1.2** - Added CSRF protection to all sample templates. Added integrated search function. Now showing the ratio of completed/total items for each
415
+ list. Better separation of media and templates. Cleaned up Item editing form (removed extraneous fields). Re-assigning tasks now properly limits
416
+ the list of assignees. Moved project to github.
417
+
418
+ **1.1** - Completion date was set properly when checking items off a list, but not when saving from an Item detail page. Added a save method on Item to
419
+ fix. Fixed documentation bug re: context_processors. Newly added comments are now emailed to everyone who has participated in a thread on a task.
420
+
421
+ **1.0.1** - When viewing a single task that you want to close, it's useful to be able to comment on and close a task at the same time. We were using
422
+ django-comments so these were different models in different views. Solution was to stop using django-comments and roll our own, then rewire the
423
+ view. Apologies if you were using a previous version - you may need to port over your comments to the new system.
424
+
425
+ **1.0.0** - Major upgrade to release version. Drag and drop task prioritization. E-mail notifications (now works more like a ticket system). More
426
+ attractive date picker. Bug fixes.
427
+
428
+ **0.9.5** - Fixed jquery bug when editing existing events - datepicker now shows correct date. Removed that damned Django pony from base template.
429
+
430
+ **0.9.4** - Replaced str with unicode in models. Fixed links back to lists in "My Tasks" view.
431
+
432
+ **0.9.3** - Missing link to the individual task editing view
433
+
434
+ **0.9.2** - Now fails gracefully when trying to add a 2nd list with the same name to the same group. - Due dates for tasks are now truly optional. -
435
+ Corrected datetime editing conflict when editing tasks - Max length of a task name has been raised from 60 to 140 chars. If upgrading, please
436
+ modify your database accordingly (field todo_item.name = maxlength 140). - Security: Users supplied with direct task URLs can no longer view/edit
437
+ tasks outside their group scope Same for list views - authorized views only. - Correct item and group counts on homepage (note - admin users see
438
+ ALL groups, not just the groups they "belong" to)
439
+
440
+ **0.9.1** - Removed context_processors.py - leftover turdlet
441
+
442
+ **0.9** - First release
443
+
444
+ ## Todo 2.0 Upgrade Notes
445
+
446
+ django-todo 2.0 was rebuilt almost from the ground up, and included some radical changes, including model name changes. As a result, it is *not compatible* with data from django-todo 1.x. If you would like to upgrade an existing installation, try this:
447
+
448
+ * Use `./manage.py dumpdata todo --indent 4 > todo.json` to export your old todo data
449
+ * Edit the dump file, replacing the old model names `Item` and `List` with the new model names (`Task` and `TaskList`)
450
+ * Delete your existing todo data
451
+ * Uninstall the old todo app and reinstall
452
+ * Migrate, then use `./manage.py loaddata todo.json` to import the edited data
453
+
454
+ ### Why not provide migrations?
455
+
456
+ That was the plan, but unfortunately, `makemigrations` created new tables and dropped the old ones, making this a destructive update. Renaming models is unfortunately not something `makemigrations` can do, and I really didn't want to keep the badly named original models. Sorry!
457
+
458
+ ### Datepicker
459
+
460
+ django-todo no longer references a jQuery datepicker, but defaults to native html5 browser datepicker. Feel free to implement one of your choosing.
461
+
462
+ ### URLs
463
+
464
+ Some views and URLs were renamed for logical consistency. If this affects you, see source code and the demo GTD site for reference to the new URL names.
@@ -0,0 +1,80 @@
1
+ django_todo-2.5.2.dist-info/licenses/LICENSE,sha256=Kzh6Rjp3YDKN83WXk8lX5MmnSICzUrS0osKvYnOAr98,1567
2
+ todo/__init__.py,sha256=_ny10BNayr0tmDJCf32Au5bZekxNsXsYpKkjsNwCwJY,231
3
+ todo/admin.py,sha256=Saq4qpu6xC2Ho2EdLeElSms6SmBneYy5pny6MYhfUEw,1722
4
+ todo/check.py,sha256=xocc3qHSm-rQKJGjSFdYdiLjduZeFtDMP5ng-EAurBE,599
5
+ todo/defaults.py,sha256=PJdDK7F3h0K7NpBD14rTiIYFNkBOhI2kRHPtT8q3Zfo,871
6
+ todo/features.py,sha256=4-eZrJs-k45vfFf8q3F9uMv7B5S5-EtgK7CKuytu5hU,491
7
+ todo/forms.py,sha256=r-KfL7ZPREoB4zD29HvZk09QxmcmLazWp3afmL4rDxg,2982
8
+ todo/models.py,sha256=g1B0Hbg89wucSKsQpR2qQmo552CWJqOOuOlf9xWHsfs,6465
9
+ todo/urls.py,sha256=4Gk4gl6P7PDYf_9VLOWy_LKSVn_RgHK8HejEnRIzEjk,1827
10
+ todo/utils.py,sha256=KNrOIM3smVmqwhHFc2Lj32VcF-efkOJiF4k4ebDQgzg,5641
11
+ todo/data/import_example.csv,sha256=vK9uvBCOOrQ71VIGCfthD88aOesyN2VcPaHqn2RyxR8,368
12
+ todo/mail/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
+ todo/mail/delivery.py,sha256=JNs5CozmgiSeG6HS1KnC76c0ulAzI46zOutMl9vKcHU,913
14
+ todo/mail/consumers/__init__.py,sha256=j2K-5fyuusvP2buyPLBAkvjmF9kPo-LnB_xr3I7DBNQ,307
15
+ todo/mail/consumers/tracker.py,sha256=wSIJfjGTiAAHwv19cSEHl7wkmSZZMV8QaFFg_GyDbkw,5746
16
+ todo/mail/producers/__init__.py,sha256=fK4jqKrIZn7H8lSlQS1bZ8l9GzExqNpXZBT-jM8pXqY,289
17
+ todo/mail/producers/imap.py,sha256=oePRsH3LhYWBk3aGupX5z7y4hCNdHvojfJ-NInsJoV8,2996
18
+ todo/management/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
+ todo/management/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
+ todo/management/commands/hopper.py,sha256=nR9eAZJ9tc7ASf_gcmdNvdcxeR7UnNLbCVMIw2trc0E,5182
21
+ todo/management/commands/import_csv.py,sha256=Ax7iUnBaEd--paOBrODkpFJRXwTl47nIul2diMGYoYQ,2018
22
+ todo/management/commands/mail_worker.py,sha256=2IBg66Fz8nZRf4WPeh_MQKM5FDKD0Vhecy3WkwizfiM,1189
23
+ todo/migrations/0001_initial.py,sha256=ZNGnOk8M7vQp8DTTV415OvECtptP_hcXlG8nVXxBhMk,3703
24
+ todo/migrations/0002_auto_20150614_2339.py,sha256=CFxrNsxgRhi9GZHYv_tQU_CSKSk9DGzxLEb3YyIy4ns,478
25
+ todo/migrations/0003_assignee_optional.py,sha256=ZpGQ2qau5XMNy6cnsJ--rMcmx4zzGrezAeyLi7TzY3g,711
26
+ todo/migrations/0004_rename_list_tasklist.py,sha256=0NxceghH-Ub0YxGIJHB4XMoIUJgeHK5rsX7AR3gwXUA,1594
27
+ todo/migrations/0005_auto_20180212_2325.py,sha256=6s8ZOiGGOmmlYCkXZSPAqvStbUIjmnY_wr5iAq6nHoE,495
28
+ todo/migrations/0006_rename_item_model.py,sha256=Cze7Y5A1YCn9JpphYeibfl-4tJ5eyJ5gYb2l0JVH-ZE,391
29
+ todo/migrations/0007_auto_update_created_date.py,sha256=rfIn9Q3hfaRunMGhzKaP723HbDAire8tU4jbKxqfCPM,442
30
+ todo/migrations/0008_mail_tracker.py,sha256=CHDBrUBPhDaSV8JZs0MwqXIdqYwSMq2tg__94Kd_TVA,1432
31
+ todo/migrations/0009_priority_optional.py,sha256=hJdEtdst_fR0or1MARNW3MGmTPYCeeEL3JTaMdMlNIc,506
32
+ todo/migrations/0010_attachment.py,sha256=wT606U-ZJVwNpvfvBkZV2Xxf490c3TVrQlbsJKYRuow,1415
33
+ todo/migrations/0011_add_related_name_to_created_by.py,sha256=SsiHRsqWOhHi4mgtQ0kucb50D4hk9vMkeZRCMtq25ME,558
34
+ todo/migrations/0012_add_related_name_to_comments.py,sha256=S6HMP3oXBMX5UwZU475BkkSGDnbKlqLCZm9PPo-gflY,576
35
+ todo/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
36
+ todo/operations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
37
+ todo/operations/csv_importer.py,sha256=c17KFTvPDHkthko2yk1KmCn0vqvfc6k8SZLrXuXoRDQ,8258
38
+ todo/static/todo/css/styles.css,sha256=Vqp6aMC9OlTvN0699DwL-dqJg5cVjgKtiqMIJHD1srE,47
39
+ todo/static/todo/js/jquery.tablednd_0_5.js,sha256=JdpGnJUyes0iI0BSQ4XLsStdwAPBUJLYKvRDnR8uVo8,16664
40
+ todo/templates/base.html,sha256=xEl3xmzl1hIxqxRVOEGNO-wipMvmKBZmDu0N1Ykd6-Q,77
41
+ todo/templates/todo/add_list.html,sha256=MeBKJiGwXWFhjViuQ5lLKegSAqY8hy_-3_kvVk5pIGU,708
42
+ todo/templates/todo/add_task_external.html,sha256=eGND_Z--KDk3tCVtzl5t9_c3KWSJsUFpuDJuqvO2SSA,1618
43
+ todo/templates/todo/base.html,sha256=HmC2H-3FJsIQHCufMwtl4kKuPnja0m_P7Xj8HWsydMA,223
44
+ todo/templates/todo/del_list.html,sha256=IOh6m_UHszptDuuFD-cKQJYrMN5wlJopmOy6JY72hGk,1048
45
+ todo/templates/todo/import_csv.html,sha256=vWf5MgIYAyeE9Nr0yuRsZnsdiEaPk9j0TNTfDYwxmfQ,2069
46
+ todo/templates/todo/list_detail.html,sha256=wB7i5ld5QDifxHlGxxPixGcHxHQzoAP0i8kpOEzvzX0,3547
47
+ todo/templates/todo/list_lists.html,sha256=MMlm1r3bWGIrz2Ch08gpLkanaQpiKMJDSlXuQDI9XwU,1027
48
+ todo/templates/todo/search_results.html,sha256=CpD0aeJ7DEfrmuP6uYfS2EUHTv3fJaLycaFdPxT7ksc,911
49
+ todo/templates/todo/task_detail.html,sha256=OecMOywRq7DJlpyCszdWcVTCbI3Irxzefmbgm-gAM0E,6592
50
+ todo/templates/todo/email/assigned_body.txt,sha256=5T7gfa8z9UzN4zMRb7uogEhbOPJRt27N4aNY9GUTVlA,625
51
+ todo/templates/todo/email/assigned_subject.txt,sha256=wItusXqJ2iIiZHMfOv88DDybf1F_03kUzw3s9GHj-ic,93
52
+ todo/templates/todo/email/newcomment_body.txt,sha256=L3qlSgfZWbSTvwUT09FiuSP7LsoPG9gfEWfNNVVmilw,536
53
+ todo/templates/todo/include/task_edit.html,sha256=ELgCQG_qZ4RU6zZxpV2bUu87l0zGLTUjVc5y4_ws3C0,2255
54
+ todo/templates/todo/include/toggle_delete.html,sha256=68uBtSTngI7msOb9kthXN0BhNiRFNHm-2VVigLBKSyU,466
55
+ todo/templatetags/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
56
+ todo/templatetags/todo_tags.py,sha256=BlLRCcUGCJ62tcm28d52QokSHC30_iinDjmNaSmZ-D0,236
57
+ todo/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
58
+ todo/tests/conftest.py,sha256=n1sHd7ANGfLSF1PguiLhs-k4f7FTJyjm7g_04tQJDL0,1783
59
+ todo/tests/test_import.py,sha256=WcOIAB2Bszm_2GP9k1yDTkp-beOfEXuJPg6w0RsPiuc,2550
60
+ todo/tests/test_tracker.py,sha256=gp9PTZAhLEyYmYU_A2YdJEiCJXES-d08QVpybZ3OevQ,3878
61
+ todo/tests/test_utils.py,sha256=p_JzcYET7jQSlFYMtCdJ6iCkP3s8oSwuVxAQ_juzgjw,2879
62
+ todo/tests/test_views.py,sha256=1-Y0jl4Mnt8NLAnHypkgZLgmKBMQWELPXxuqhmR87tI,12113
63
+ todo/views/__init__.py,sha256=z20M0Qxne4u_eiGEf79ELM6kbjAGY-NH3XT8h_N9-18,724
64
+ todo/views/add_list.py,sha256=L0wEV8h8Sj97SezwPFRy2d4bhggUjPWjiLp4BzhSl-s,1771
65
+ todo/views/del_list.py,sha256=g9Rkg26pOnCZxf9Xdnmsg6uUuIn71L_G7I8aQXhMgtg,1682
66
+ todo/views/delete_task.py,sha256=wN70I7l7uI7bcqZ7KTTNKRxvIZu_6OTG3wbXCVJbijU,1267
67
+ todo/views/external_add.py,sha256=OomyK_QKfKl1jXhZ3vxMOSqw2o9UFq3bDfCa-QlVED8,3240
68
+ todo/views/import_csv.py,sha256=7S9uvxv32BMUQkQCiPOHVxLSjNFV4I07iwh6Wwf5POI,1068
69
+ todo/views/list_detail.py,sha256=4TXvmzWy3CzVBtzjvCPCDhIxCEboeDpDQBbhaBMnps4,2889
70
+ todo/views/list_lists.py,sha256=ZGo6PgsmAYsAqFGgYLNbuFnQ3Ioh_yrahNcxlMFfS-c,1663
71
+ todo/views/remove_attachment.py,sha256=XYWuUHc9dSn3dNMeXl6Kamyl7bfubDWdIj-s_G6ShB8,1321
72
+ todo/views/reorder_tasks.py,sha256=nUEsYzOQKgxIqXOy6FLMWixYqEeGzx66HONoJSpXwcI,1265
73
+ todo/views/search.py,sha256=RYE209esrOKEwAV0l6inznwIiVIxK1jWVNmxuKG1__w,1435
74
+ todo/views/task_autocomplete.py,sha256=_Xz0mSGrLhi-elzX6tNAAJylTXV7QZdKhWaSu-WEVv4,1060
75
+ todo/views/task_detail.py,sha256=vI589jQdwV9gw-lEFI4uIm-N3q6xvp5De7VvRqR1BVc,5280
76
+ todo/views/toggle_done.py,sha256=h5bMF1wbIm7IVXGI4mNmwKkkVS7-Nv_dk0OIdyZI7mU,1382
77
+ django_todo-2.5.2.dist-info/METADATA,sha256=1l5ZhIcdDlx0rxtP9zScIDKngqMPNBZiuWjhqvJneo4,20666
78
+ django_todo-2.5.2.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
79
+ django_todo-2.5.2.dist-info/top_level.txt,sha256=c1x0MAVpTPy2QFoNZ9fz48_PoX9pcGKJOwNu8vee_hs,5
80
+ django_todo-2.5.2.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (82.0.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,27 @@
1
+ Copyright (c) 2010, Scot Hacker, Birdhouse Arts and individual contributors.
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without modification,
5
+ are permitted provided that the following conditions are met:
6
+
7
+ 1. Redistributions of source code must retain the above copyright notice,
8
+ this list of conditions and the following disclaimer.
9
+
10
+ 2. Redistributions in binary form must reproduce the above copyright
11
+ notice, this list of conditions and the following disclaimer in the
12
+ documentation and/or other materials provided with the distribution.
13
+
14
+ 3. Neither the name of Birdhouse Arts nor the names of its contributors
15
+ may be used to endorse or promote products derived from this software
16
+ without specific prior written permission.
17
+
18
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
22
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
25
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1 @@
1
+ todo
todo/__init__.py ADDED
@@ -0,0 +1,9 @@
1
+
2
+ try:
3
+ # if django is not installed,
4
+ # skips check because it blocks automated installs
5
+ import django
6
+ from . import check
7
+ except ModuleNotFoundError:
8
+ # this can happen during install time, if django is not installed yet!
9
+ pass
todo/admin.py ADDED
@@ -0,0 +1,56 @@
1
+ import csv
2
+ import datetime
3
+
4
+ from django.contrib import admin
5
+ from django.http import HttpResponse
6
+
7
+ from todo.models import Attachment, Comment, Task, TaskList
8
+
9
+
10
+ def export_to_csv(modeladmin, request, queryset):
11
+ opts = modeladmin.model._meta
12
+ content_disposition = f"attachment; filename={opts.verbose_name}.csv"
13
+ response = HttpResponse(content_type="text/csv")
14
+ response["Content-Disposition"] = content_disposition
15
+ writer = csv.writer(response)
16
+ fields = [
17
+ field for field in opts.get_fields() if not (field.many_to_many and not field.one_to_many)
18
+ ]
19
+ # Write a first row with header information
20
+ writer.writerow([field.verbose_name for field in fields])
21
+ # Write data rows
22
+ for obj in queryset:
23
+ data_row = []
24
+ for field in fields:
25
+ value = getattr(obj, field.name)
26
+ if isinstance(value, datetime.datetime):
27
+ value = value.strftime("%d/%m/%Y")
28
+ data_row.append(value)
29
+ writer.writerow(data_row)
30
+ return response
31
+
32
+
33
+ export_to_csv.short_description = "Export to CSV"
34
+
35
+
36
+ class TaskAdmin(admin.ModelAdmin):
37
+ list_display = ("title", "task_list", "completed", "priority", "due_date")
38
+ list_filter = ("task_list",)
39
+ ordering = ("priority",)
40
+ search_fields = ("title",)
41
+ actions = [export_to_csv]
42
+
43
+
44
+ class CommentAdmin(admin.ModelAdmin):
45
+ list_display = ("author", "date", "snippet")
46
+
47
+
48
+ class AttachmentAdmin(admin.ModelAdmin):
49
+ list_display = ("task", "added_by", "timestamp", "file")
50
+ autocomplete_fields = ["added_by", "task"]
51
+
52
+
53
+ admin.site.register(TaskList)
54
+ admin.site.register(Comment, CommentAdmin)
55
+ admin.site.register(Task, TaskAdmin)
56
+ admin.site.register(Attachment, AttachmentAdmin)
todo/check.py ADDED
@@ -0,0 +1,17 @@
1
+ from django.core.checks import Error, register
2
+
3
+ # the sole purpose of this warning is to prevent people who have
4
+ # django-autocomplete-light installed but not configured to start the app
5
+ @register()
6
+ def dal_check(app_configs, **kwargs):
7
+ from django.conf import settings
8
+ from todo.features import HAS_AUTOCOMPLETE
9
+
10
+ if not HAS_AUTOCOMPLETE:
11
+ return []
12
+
13
+ errors = []
14
+ missing_apps = {"dal", "dal_select2"} - set(settings.INSTALLED_APPS)
15
+ for missing_app in missing_apps:
16
+ errors.append(Error("{} needs to be in INSTALLED_APPS".format(missing_app)))
17
+ return errors
@@ -0,0 +1,4 @@
1
+ Title,Group,Task List,Created By,Created Date,Due Date,Completed,Assigned To,Note,Priority
2
+ Make dinner,Scuba Divers,Web project,shacker,,2019-06-14,No,,Please check with mgmt first,3
3
+ Bake bread,Scuba Divers,Example List,mr_random,2012-03-14,,Yes,,,
4
+ Bring dessert,Scuba Divers,Web project,user1,2015-06-248,,,user1,Every generation throws a hero up the pop charts,77