Browse Source

Merge pull request #1159 from rafalp/update-isort

Update isort config
Rafał Pitoń 6 years ago
parent
commit
9f303b1b51
523 changed files with 1584 additions and 1974 deletions
  1. 4 11
      .isort.cfg
  2. 4 0
      dev
  3. 1 0
      misago/acl/apps.py
  4. 1 2
      misago/acl/cache.py
  5. 1 1
      misago/acl/migrations/0001_initial.py
  6. 0 1
      misago/acl/migrations/0003_default_roles.py
  7. 2 2
      misago/acl/migrations/0004_cache_version.py
  8. 0 1
      misago/acl/panels.py
  9. 1 2
      misago/acl/providers.py
  10. 1 1
      misago/acl/tests/test_acl_algebra.py
  11. 1 1
      misago/acl/tests/test_getting_user_acl.py
  12. 2 2
      misago/acl/tests/test_mock_role_admin_form_data.py
  13. 2 2
      misago/acl/tests/test_patching_user_acl.py
  14. 2 2
      misago/acl/tests/test_providers.py
  15. 5 5
      misago/acl/tests/test_roleadmin_views.py
  16. 1 1
      misago/acl/tests/test_serializing_user_acl.py
  17. 1 1
      misago/acl/tests/test_user_acl_context_processor.py
  18. 1 1
      misago/acl/tests/test_user_acl_middleware.py
  19. 1 2
      misago/acl/views.py
  20. 1 2
      misago/admin/auth.py
  21. 1 1
      misago/admin/forms.py
  22. 1 1
      misago/admin/test.py
  23. 3 3
      misago/admin/tests/test_admin_form_templatetags.py
  24. 1 1
      misago/admin/tests/test_admin_hierarchy.py
  25. 2 2
      misago/admin/tests/test_admin_index.py
  26. 3 3
      misago/admin/tests/test_admin_views.py
  27. 1 1
      misago/admin/tests/test_forms.py
  28. 1 3
      misago/admin/urls.py
  29. 3 4
      misago/admin/views/__init__.py
  30. 2 2
      misago/admin/views/auth.py
  31. 2 4
      misago/admin/views/errorpages.py
  32. 1 1
      misago/admin/views/generic/base.py
  33. 1 2
      misago/admin/views/generic/list.py
  34. 5 8
      misago/admin/views/index.py
  35. 1 1
      misago/cache/management/commands/invalidateversionedcaches.py
  36. 2 2
      misago/cache/migrations/0001_initial.py
  37. 1 1
      misago/cache/tests/conftest.py
  38. 3 3
      misago/cache/tests/test_assert_invalidates_cache.py
  39. 1 1
      misago/cache/tests/test_cache_versions_middleware.py
  40. 1 1
      misago/cache/tests/test_getting_cache_versions.py
  41. 2 2
      misago/cache/tests/test_invalidating_caches.py
  42. 4 6
      misago/categories/forms.py
  43. 2 2
      misago/categories/management/commands/fixcategoriestree.py
  44. 1 1
      misago/categories/management/commands/prunecategories.py
  45. 2 2
      misago/categories/management/commands/synchronizecategories.py
  46. 2 3
      misago/categories/migrations/0001_initial.py
  47. 1 2
      misago/categories/migrations/0002_default_categories.py
  48. 0 1
      misago/categories/migrations/0003_categories_roles.py
  49. 0 1
      misago/categories/migrations/0006_moderation_queue_roles.py
  50. 0 1
      misago/categories/migrations/0007_best_answers_roles.py
  51. 7 9
      misago/categories/models.py
  52. 4 5
      misago/categories/permissions.py
  53. 3 6
      misago/categories/serializers.py
  54. 1 3
      misago/categories/signals.py
  55. 6 6
      misago/categories/tests/test_categories_admin_views.py
  56. 4 4
      misago/categories/tests/test_category_model.py
  57. 4 4
      misago/categories/tests/test_fixcategoriestree.py
  58. 6 6
      misago/categories/tests/test_permissions_admin_views.py
  59. 3 3
      misago/categories/tests/test_prunecategories.py
  60. 3 3
      misago/categories/tests/test_synchronizecategories.py
  61. 5 5
      misago/categories/tests/test_utils.py
  62. 3 3
      misago/categories/tests/test_views.py
  63. 3 3
      misago/categories/urls/__init__.py
  64. 2 3
      misago/categories/urls/api.py
  65. 2 3
      misago/categories/utils.py
  66. 6 6
      misago/categories/views/categoriesadmin.py
  67. 2 4
      misago/categories/views/categorieslist.py
  68. 7 8
      misago/categories/views/permsadmin.py
  69. 1 2
      misago/conf/cache.py
  70. 1 2
      misago/conf/context_processors.py
  71. 1 1
      misago/conf/forms.py
  72. 2 3
      misago/conf/migrations/0002_cache_version.py
  73. 1 1
      misago/conf/test.py
  74. 1 1
      misago/conf/tests/conftest.py
  75. 2 2
      misago/conf/tests/test_admin_views.py
  76. 1 1
      misago/conf/tests/test_context_processors.py
  77. 1 2
      misago/conf/tests/test_dynamic_settings_middleware.py
  78. 2 2
      misago/conf/tests/test_getting_dynamic_settings_values.py
  79. 0 1
      misago/conf/tests/test_getting_static_settings_values.py
  80. 2 2
      misago/conf/tests/test_hydrators.py
  81. 2 2
      misago/conf/tests/test_migrationutils.py
  82. 1 1
      misago/conf/tests/test_models.py
  83. 2 2
      misago/conf/tests/test_overridding_dynamic_settings.py
  84. 1 2
      misago/conf/views.py
  85. 7 7
      misago/conftest.py
  86. 1 3
      misago/core/apipatch.py
  87. 2 2
      misago/core/cache.py
  88. 3 4
      misago/core/errorpages.py
  89. 1 3
      misago/core/exceptionhandler.py
  90. 1 2
      misago/core/mail.py
  91. 2 2
      misago/core/middleware.py
  92. 1 2
      misago/core/migrations/0002_basic_settings.py
  93. 1 2
      misago/core/momentjs.py
  94. 1 2
      misago/core/rest_permissions.py
  95. 1 2
      misago/core/shortcuts.py
  96. 1 2
      misago/core/slugify.py
  97. 1 1
      misago/core/templatetags/misago_absoluteurl.py
  98. 0 1
      misago/core/templatetags/misago_batch.py
  99. 0 1
      misago/core/templatetags/misago_capture.py
  100. 1 2
      misago/core/templatetags/misago_json.py
  101. 0 1
      misago/core/templatetags/misago_pagetitle.py
  102. 0 1
      misago/core/templatetags/misago_shorthands.py
  103. 0 1
      misago/core/templatetags/misago_stringutils.py
  104. 1 3
      misago/core/testproject/urls.py
  105. 0 1
      misago/core/testproject/urlswitherrorhandlers.py
  106. 8 10
      misago/core/testproject/views.py
  107. 1 1
      misago/core/tests/test_apipatch.py
  108. 1 2
      misago/core/tests/test_checks.py
  109. 2 2
      misago/core/tests/test_chunk_queryset.py
  110. 1 1
      misago/core/tests/test_common_middleware_redirect.py
  111. 1 1
      misago/core/tests/test_context_processors.py
  112. 1 1
      misago/core/tests/test_deprecations.py
  113. 6 9
      misago/core/tests/test_errorpages.py
  114. 5 7
      misago/core/tests/test_exceptionhandler_middleware.py
  115. 3 4
      misago/core/tests/test_exceptionhandlers.py
  116. 1 1
      misago/core/tests/test_frontendcontext_middleware.py
  117. 0 1
      misago/core/tests/test_jsi18n.py
  118. 4 4
      misago/core/tests/test_mail.py
  119. 1 1
      misago/core/tests/test_momentjs.py
  120. 1 1
      misago/core/tests/test_page.py
  121. 2 3
      misago/core/tests/test_pgpartialindex.py
  122. 5 6
      misago/core/tests/test_serializers.py
  123. 1 1
      misago/core/tests/test_setup.py
  124. 1 1
      misago/core/tests/test_shortcuts.py
  125. 10 11
      misago/core/tests/test_templatetags.py
  126. 4 4
      misago/core/tests/test_utils.py
  127. 1 1
      misago/core/tests/test_validators.py
  128. 0 1
      misago/core/utils.py
  129. 0 1
      misago/faker/englishcorpus.py
  130. 3 4
      misago/faker/management/commands/createfakebans.py
  131. 4 5
      misago/faker/management/commands/createfakecategories.py
  132. 1 2
      misago/faker/management/commands/createfakefollowers.py
  133. 6 8
      misago/faker/management/commands/createfakethreads.py
  134. 4 6
      misago/faker/management/commands/createfakeusers.py
  135. 1 1
      misago/faker/tests/test_englishcorpus.py
  136. 0 1
      misago/legal/api.py
  137. 0 1
      misago/legal/context_processors.py
  138. 1 2
      misago/legal/migrations/0001_initial.py
  139. 2 2
      misago/legal/migrations/0002_agreement_useragreement.py
  140. 2 3
      misago/legal/migrations/0003_create_agreements_from_settings.py
  141. 2 3
      misago/legal/models.py
  142. 1 2
      misago/legal/signals.py
  143. 2 2
      misago/legal/tests/test_admin_views.py
  144. 2 2
      misago/legal/tests/test_api.py
  145. 3 3
      misago/legal/tests/test_context_processors.py
  146. 2 2
      misago/legal/tests/test_required_agreement.py
  147. 3 3
      misago/legal/tests/test_utils.py
  148. 1 1
      misago/legal/tests/test_views.py
  149. 1 2
      misago/legal/urls/__init__.py
  150. 1 2
      misago/legal/urls/api.py
  151. 2 3
      misago/legal/utils.py
  152. 4 5
      misago/legal/views/admin.py
  153. 2 2
      misago/legal/views/legal.py
  154. 1 3
      misago/markup/bbcode/blocks.py
  155. 0 1
      misago/markup/finalise.py
  156. 0 1
      misago/markup/md/shortimgs.py
  157. 0 1
      misago/markup/md/striketrough.py
  158. 0 2
      misago/markup/mentions.py
  159. 3 6
      misago/markup/parser.py
  160. 1 1
      misago/markup/pipeline.py
  161. 1 1
      misago/markup/serializers.py
  162. 0 1
      misago/markup/templatetags/misago_editor.py
  163. 1 1
      misago/markup/tests/test_api.py
  164. 1 1
      misago/markup/tests/test_checksums.py
  165. 1 1
      misago/markup/tests/test_finalise.py
  166. 2 2
      misago/markup/tests/test_mentions.py
  167. 2 2
      misago/markup/tests/test_parser.py
  168. 0 1
      misago/markup/urls.py
  169. 2 6
      misago/readtracker/categoriestracker.py
  170. 1 1
      misago/readtracker/dates.py
  171. 2 2
      misago/readtracker/management/commands/clearreadtracker.py
  172. 2 2
      misago/readtracker/migrations/0002_postread.py
  173. 2 3
      misago/readtracker/migrations/0003_migrate_reads_to_posts.py
  174. 3 4
      misago/readtracker/signals.py
  175. 8 8
      misago/readtracker/tests/test_categoriestracker.py
  176. 6 6
      misago/readtracker/tests/test_clearreadtracker.py
  177. 2 2
      misago/readtracker/tests/test_dates.py
  178. 16 16
      misago/readtracker/tests/test_poststracker.py
  179. 9 9
      misago/readtracker/tests/test_threadstracker.py
  180. 2 3
      misago/readtracker/threadstracker.py
  181. 3 5
      misago/search/api.py
  182. 3 3
      misago/search/permissions.py
  183. 1 1
      misago/search/searchproviders.py
  184. 3 3
      misago/search/tests/test_api.py
  185. 3 3
      misago/search/tests/test_searchproviders.py
  186. 3 3
      misago/search/tests/test_views.py
  187. 1 1
      misago/search/urls/__init__.py
  188. 1 2
      misago/search/urls/api.py
  189. 0 1
      misago/threads/anonymize.py
  190. 6 8
      misago/threads/api/attachments.py
  191. 3 3
      misago/threads/api/pollvotecreateendpoint.py
  192. 7 9
      misago/threads/api/postendpoints/delete.py
  193. 7 8
      misago/threads/api/postendpoints/edits.py
  194. 1 1
      misago/threads/api/postendpoints/likes.py
  195. 3 4
      misago/threads/api/postendpoints/merge.py
  196. 2 3
      misago/threads/api/postendpoints/move.py
  197. 4 5
      misago/threads/api/postendpoints/patch_event.py
  198. 9 11
      misago/threads/api/postendpoints/patch_post.py
  199. 2 2
      misago/threads/api/postendpoints/read.py
  200. 4 5
      misago/threads/api/postendpoints/split.py
  201. 1 1
      misago/threads/api/postingendpoint/__init__.py
  202. 4 6
      misago/threads/api/postingendpoint/attachments.py
  203. 7 9
      misago/threads/api/postingendpoint/category.py
  204. 1 2
      misago/threads/api/postingendpoint/close.py
  205. 3 4
      misago/threads/api/postingendpoint/emailnotification.py
  206. 1 3
      misago/threads/api/postingendpoint/floodprotection.py
  207. 1 2
      misago/threads/api/postingendpoint/hide.py
  208. 1 2
      misago/threads/api/postingendpoint/moderationqueue.py
  209. 7 9
      misago/threads/api/postingendpoint/participants.py
  210. 2 3
      misago/threads/api/postingendpoint/pin.py
  211. 3 4
      misago/threads/api/postingendpoint/privatethread.py
  212. 5 11
      misago/threads/api/postingendpoint/reply.py
  213. 1 2
      misago/threads/api/postingendpoint/savechanges.py
  214. 1 3
      misago/threads/api/postingendpoint/subscribe.py
  215. 2 3
      misago/threads/api/postingendpoint/syncprivatethreads.py
  216. 1 2
      misago/threads/api/postingendpoint/updatestats.py
  217. 4 5
      misago/threads/api/threadendpoints/delete.py
  218. 6 7
      misago/threads/api/threadendpoints/editor.py
  219. 2 2
      misago/threads/api/threadendpoints/list.py
  220. 9 10
      misago/threads/api/threadendpoints/merge.py
  221. 16 17
      misago/threads/api/threadendpoints/patch.py
  222. 10 12
      misago/threads/api/threadpoll.py
  223. 11 18
      misago/threads/api/threadposts.py
  224. 10 12
      misago/threads/api/threads.py
  225. 1 1
      misago/threads/checksums.py
  226. 1 2
      misago/threads/events.py
  227. 1 2
      misago/threads/filtersearch.py
  228. 4 4
      misago/threads/management/commands/clearattachments.py
  229. 3 3
      misago/threads/management/commands/rebuildpostssearch.py
  230. 3 3
      misago/threads/management/commands/synchronizethreads.py
  231. 4 4
      misago/threads/management/commands/updatepostschecksums.py
  232. 2 3
      misago/threads/mergeconflict.py
  233. 1 2
      misago/threads/middleware.py
  234. 1 2
      misago/threads/migrations/0002_threads_settings.py
  235. 0 1
      misago/threads/migrations/0003_attachment_types.py
  236. 1 1
      misago/threads/migrations/0004_update_settings.py
  237. 1 1
      misago/threads/migrations/0008_auto_20180310_2234.py
  238. 3 4
      misago/threads/models/attachment.py
  239. 10 10
      misago/threads/models/post.py
  240. 1 1
      misago/threads/models/subscription.py
  241. 6 6
      misago/threads/models/thread.py
  242. 1 1
      misago/threads/models/threadparticipant.py
  243. 0 1
      misago/threads/moderation/posts.py
  244. 1 2
      misago/threads/moderation/threads.py
  245. 1 3
      misago/threads/participants.py
  246. 4 5
      misago/threads/permissions/attachments.py
  247. 9 9
      misago/threads/permissions/bestanswers.py
  248. 5 6
      misago/threads/permissions/polls.py
  249. 7 8
      misago/threads/permissions/privatethreads.py
  250. 11 11
      misago/threads/permissions/threads.py
  251. 3 5
      misago/threads/search.py
  252. 2 4
      misago/threads/serializers/attachment.py
  253. 4 6
      misago/threads/serializers/feed.py
  254. 13 14
      misago/threads/serializers/moderation.py
  255. 2 4
      misago/threads/serializers/poll.py
  256. 1 3
      misago/threads/serializers/pollvote.py
  257. 4 6
      misago/threads/serializers/post.py
  258. 2 4
      misago/threads/serializers/postedit.py
  259. 2 4
      misago/threads/serializers/postlike.py
  260. 4 7
      misago/threads/serializers/thread.py
  261. 1 2
      misago/threads/serializers/threadparticipant.py
  262. 4 6
      misago/threads/signals.py
  263. 0 1
      misago/threads/templatetags/misago_poststags.py
  264. 4 5
      misago/threads/test.py
  265. 8 10
      misago/threads/tests/test_anonymize_data.py
  266. 4 4
      misago/threads/tests/test_attachmentadmin_views.py
  267. 6 7
      misago/threads/tests/test_attachments_api.py
  268. 10 10
      misago/threads/tests/test_attachments_middleware.py
  269. 3 3
      misago/threads/tests/test_attachmenttypeadmin_views.py
  270. 7 7
      misago/threads/tests/test_attachmentview.py
  271. 5 5
      misago/threads/tests/test_clearattachments.py
  272. 5 6
      misago/threads/tests/test_delete_user_likes.py
  273. 4 4
      misago/threads/tests/test_emailnotification_middleware.py
  274. 7 7
      misago/threads/tests/test_events.py
  275. 4 4
      misago/threads/tests/test_floodprotection.py
  276. 3 3
      misago/threads/tests/test_floodprotection_middleware.py
  277. 6 7
      misago/threads/tests/test_gotoviews.py
  278. 5 7
      misago/threads/tests/test_mergeconflict.py
  279. 1 1
      misago/threads/tests/test_paginator.py
  280. 4 4
      misago/threads/tests/test_participants.py
  281. 4 4
      misago/threads/tests/test_post_mentions.py
  282. 4 4
      misago/threads/tests/test_post_model.py
  283. 4 4
      misago/threads/tests/test_posts_moderation.py
  284. 5 6
      misago/threads/tests/test_privatethread_patch_api.py
  285. 3 4
      misago/threads/tests/test_privatethread_reply_api.py
  286. 5 5
      misago/threads/tests/test_privatethread_start_api.py
  287. 3 4
      misago/threads/tests/test_privatethread_view.py
  288. 2 2
      misago/threads/tests/test_privatethreads.py
  289. 4 5
      misago/threads/tests/test_privatethreads_api.py
  290. 3 4
      misago/threads/tests/test_privatethreads_lists.py
  291. 3 3
      misago/threads/tests/test_search.py
  292. 5 6
      misago/threads/tests/test_subscription_middleware.py
  293. 5 5
      misago/threads/tests/test_subscriptions.py
  294. 3 4
      misago/threads/tests/test_sync_unread_private_threads.py
  295. 3 3
      misago/threads/tests/test_synchronizethreads.py
  296. 4 5
      misago/threads/tests/test_thread_bulkpatch_api.py
  297. 6 6
      misago/threads/tests/test_thread_editreply_api.py
  298. 5 6
      misago/threads/tests/test_thread_merge_api.py
  299. 4 4
      misago/threads/tests/test_thread_model.py
  300. 5 6
      misago/threads/tests/test_thread_patch_api.py
  301. 3 3
      misago/threads/tests/test_thread_poll_api.py
  302. 4 5
      misago/threads/tests/test_thread_pollcreate_api.py
  303. 3 4
      misago/threads/tests/test_thread_polldelete_api.py
  304. 3 4
      misago/threads/tests/test_thread_polledit_api.py
  305. 3 4
      misago/threads/tests/test_thread_pollvotes_api.py
  306. 3 4
      misago/threads/tests/test_thread_postbulkdelete_api.py
  307. 5 5
      misago/threads/tests/test_thread_postbulkpatch_api.py
  308. 3 4
      misago/threads/tests/test_thread_postdelete_api.py
  309. 2 3
      misago/threads/tests/test_thread_postedits_api.py
  310. 3 4
      misago/threads/tests/test_thread_postlikes_api.py
  311. 7 7
      misago/threads/tests/test_thread_postmerge_api.py
  312. 7 7
      misago/threads/tests/test_thread_postmove_api.py
  313. 5 5
      misago/threads/tests/test_thread_postpatch_api.py
  314. 1 2
      misago/threads/tests/test_thread_postread_api.py
  315. 7 7
      misago/threads/tests/test_thread_postsplit_api.py
  316. 6 6
      misago/threads/tests/test_thread_reply_api.py
  317. 4 4
      misago/threads/tests/test_thread_start_api.py
  318. 3 3
      misago/threads/tests/test_threadparticipant_model.py
  319. 8 8
      misago/threads/tests/test_threads_api.py
  320. 7 8
      misago/threads/tests/test_threads_bulkdelete_api.py
  321. 9 9
      misago/threads/tests/test_threads_editor_api.py
  322. 10 11
      misago/threads/tests/test_threads_merge_api.py
  323. 4 4
      misago/threads/tests/test_threads_moderation.py
  324. 7 7
      misago/threads/tests/test_threadslists.py
  325. 11 11
      misago/threads/tests/test_threadview.py
  326. 2 3
      misago/threads/tests/test_treesmap.py
  327. 4 4
      misago/threads/tests/test_updatepostschecksums.py
  328. 3 3
      misago/threads/tests/test_utils.py
  329. 2 2
      misago/threads/tests/test_validate_post.py
  330. 1 1
      misago/threads/tests/test_validators.py
  331. 1 2
      misago/threads/threadtypes/privatethread.py
  332. 1 2
      misago/threads/threadtypes/thread.py
  333. 2 2
      misago/threads/threadtypes/treesmap.py
  334. 5 9
      misago/threads/urls/__init__.py
  335. 5 6
      misago/threads/urls/api.py
  336. 5 6
      misago/threads/validators.py
  337. 7 8
      misago/threads/viewmodels/category.py
  338. 3 4
      misago/threads/viewmodels/post.py
  339. 9 10
      misago/threads/viewmodels/posts.py
  340. 12 13
      misago/threads/viewmodels/thread.py
  341. 11 14
      misago/threads/viewmodels/threads.py
  342. 3 3
      misago/threads/views/admin/attachments.py
  343. 3 3
      misago/threads/views/admin/attachmenttypes.py
  344. 2 3
      misago/threads/views/attachment.py
  345. 4 4
      misago/threads/views/goto.py
  346. 2 2
      misago/threads/views/list.py
  347. 1 1
      misago/threads/views/thread.py
  348. 2 3
      misago/urls.py
  349. 2 4
      misago/users/activepostersranking.py
  350. 0 1
      misago/users/admin.py
  351. 10 20
      misago/users/api/auth.py
  352. 1 2
      misago/users/api/captcha.py
  353. 3 5
      misago/users/api/mention.py
  354. 2 2
      misago/users/api/ranks.py
  355. 4 5
      misago/users/api/rest_permissions.py
  356. 8 9
      misago/users/api/userendpoints/avatar.py
  357. 5 6
      misago/users/api/userendpoints/changeemail.py
  358. 4 5
      misago/users/api/userendpoints/changepassword.py
  359. 8 9
      misago/users/api/userendpoints/create.py
  360. 2 4
      misago/users/api/userendpoints/editdetails.py
  361. 5 7
      misago/users/api/userendpoints/list.py
  362. 5 6
      misago/users/api/userendpoints/signature.py
  363. 4 5
      misago/users/api/userendpoints/username.py
  364. 5 8
      misago/users/api/usernamechanges.py
  365. 17 23
      misago/users/api/users.py
  366. 1 2
      misago/users/apps.py
  367. 0 1
      misago/users/authbackends.py
  368. 1 2
      misago/users/avatars/__init__.py
  369. 2 5
      misago/users/avatars/dynamic.py
  370. 5 8
      misago/users/avatars/gallery.py
  371. 1 3
      misago/users/avatars/gravatar.py
  372. 3 4
      misago/users/avatars/store.py
  373. 2 4
      misago/users/avatars/uploaded.py
  374. 0 1
      misago/users/captcha.py
  375. 3 3
      misago/users/datadownloads/__init__.py
  376. 1 2
      misago/users/datadownloads/dataarchive.py
  377. 1 2
      misago/users/decorators.py
  378. 8 9
      misago/users/forms/admin.py
  379. 1 2
      misago/users/forms/auth.py
  380. 2 7
      misago/users/forms/register.py
  381. 2 1
      misago/users/management/commands/buildactivepostersranking.py
  382. 4 5
      misago/users/management/commands/createsuperuser.py
  383. 2 3
      misago/users/management/commands/deleteinactiveusers.py
  384. 4 6
      misago/users/management/commands/deletemarkedusers.py
  385. 2 2
      misago/users/management/commands/deleteprofilefield.py
  386. 3 3
      misago/users/management/commands/expireuserdatadownloads.py
  387. 3 4
      misago/users/management/commands/invalidatebans.py
  388. 1 2
      misago/users/management/commands/listusedprofilefields.py
  389. 3 3
      misago/users/management/commands/loadavatargallery.py
  390. 2 3
      misago/users/management/commands/populateonlinetracker.py
  391. 7 8
      misago/users/management/commands/prepareuserdatadownloads.py
  392. 2 2
      misago/users/management/commands/removeoldips.py
  393. 3 4
      misago/users/management/commands/synchronizeusers.py
  394. 1 2
      misago/users/migrations/0002_users_settings.py
  395. 1 2
      misago/users/migrations/0004_default_ranks.py
  396. 1 1
      misago/users/migrations/0006_update_settings.py
  397. 1 0
      misago/users/migrations/0009_redo_partial_indexes.py
  398. 1 0
      misago/users/migrations/0011_auto_20180331_2208.py
  399. 2 2
      misago/users/migrations/0012_audittrail.py
  400. 3 2
      misago/users/migrations/0014_datadownload.py
  401. 1 1
      misago/users/migrations/0016_cache_version.py
  402. 1 1
      misago/users/migrations/0017_move_bans_to_cache_version.py
  403. 1 1
      misago/users/models/avatar.py
  404. 1 1
      misago/users/models/avatargallery.py
  405. 4 4
      misago/users/models/ban.py
  406. 2 2
      misago/users/models/rank.py
  407. 13 13
      misago/users/models/user.py
  408. 2 3
      misago/users/online/tracker.py
  409. 2 3
      misago/users/online/utils.py
  410. 1 2
      misago/users/pages.py
  411. 3 3
      misago/users/permissions/account.py
  412. 0 1
      misago/users/permissions/decorators.py
  413. 4 5
      misago/users/permissions/delete.py
  414. 5 6
      misago/users/permissions/moderation.py
  415. 4 6
      misago/users/permissions/profiles.py
  416. 1 1
      misago/users/profilefields/__init__.py
  417. 1 2
      misago/users/profilefields/basefields.py
  418. 2 1
      misago/users/profilefields/default.py
  419. 1 1
      misago/users/profilefields/serializers.py
  420. 4 4
      misago/users/registration.py
  421. 1 3
      misago/users/search.py
  422. 2 4
      misago/users/serializers/auth.py
  423. 3 5
      misago/users/serializers/ban.py
  424. 1 2
      misago/users/serializers/datadownload.py
  425. 2 4
      misago/users/serializers/moderation.py
  426. 4 6
      misago/users/serializers/options.py
  427. 2 3
      misago/users/serializers/rank.py
  428. 2 5
      misago/users/serializers/user.py
  429. 1 3
      misago/users/serializers/usernamechange.py
  430. 1 1
      misago/users/setupnewuser.py
  431. 2 4
      misago/users/signals.py
  432. 1 1
      misago/users/signatures.py
  433. 9 12
      misago/users/social/pipeline.py
  434. 1 2
      misago/users/social/utils.py
  435. 0 1
      misago/users/templatetags/misago_avatars.py
  436. 4 4
      misago/users/tests/test_activation_views.py
  437. 4 4
      misago/users/tests/test_activepostersranking.py
  438. 4 4
      misago/users/tests/test_audittrail.py
  439. 3 3
      misago/users/tests/test_auth_api.py
  440. 2 2
      misago/users/tests/test_auth_backend.py
  441. 1 1
      misago/users/tests/test_avatar_filter.py
  442. 5 13
      misago/users/tests/test_avatars.py
  443. 2 2
      misago/users/tests/test_avatarserver_views.py
  444. 1 1
      misago/users/tests/test_ban_model.py
  445. 2 2
      misago/users/tests/test_banadmin_views.py
  446. 5 5
      misago/users/tests/test_bans.py
  447. 1 2
      misago/users/tests/test_bio_profilefield.py
  448. 1 1
      misago/users/tests/test_captcha_api.py
  449. 2 2
      misago/users/tests/test_credentialchange.py
  450. 7 8
      misago/users/tests/test_datadownloads.py
  451. 3 4
      misago/users/tests/test_datadownloads_dataarchive.py
  452. 4 4
      misago/users/tests/test_datadownloadsadmin_views.py
  453. 3 3
      misago/users/tests/test_decorators.py
  454. 2 2
      misago/users/tests/test_deleteinactiveusers.py
  455. 2 2
      misago/users/tests/test_deletemarkedusers.py
  456. 2 2
      misago/users/tests/test_deleteprofilefield.py
  457. 1 1
      misago/users/tests/test_djangoadmin_auth.py
  458. 3 3
      misago/users/tests/test_djangoadmin_user.py
  459. 4 5
      misago/users/tests/test_expireuserdatadownloads.py
  460. 4 4
      misago/users/tests/test_forgottenpassword_views.py
  461. 1 2
      misago/users/tests/test_gender_profilefield.py
  462. 2 2
      misago/users/tests/test_getting_user_status.py
  463. 5 6
      misago/users/tests/test_invalidatebans.py
  464. 2 3
      misago/users/tests/test_joinip_profilefield.py
  465. 6 6
      misago/users/tests/test_lists_views.py
  466. 2 2
      misago/users/tests/test_listusedprofilefields.py
  467. 2 2
      misago/users/tests/test_loadavatargallery.py
  468. 2 2
      misago/users/tests/test_mention_api.py
  469. 2 2
      misago/users/tests/test_namechanges.py
  470. 2 2
      misago/users/tests/test_new_user_setup.py
  471. 1 1
      misago/users/tests/test_options_views.py
  472. 2 2
      misago/users/tests/test_populate_online_tracker_command.py
  473. 5 5
      misago/users/tests/test_prepareuserdatadownloads.py
  474. 5 5
      misago/users/tests/test_profile_views.py
  475. 1 2
      misago/users/tests/test_profilefields.py
  476. 5 5
      misago/users/tests/test_rankadmin_views.py
  477. 1 1
      misago/users/tests/test_realip_middleware.py
  478. 1 2
      misago/users/tests/test_remove_old_ips_command.py
  479. 2 2
      misago/users/tests/test_rest_permissions.py
  480. 2 2
      misago/users/tests/test_search.py
  481. 2 2
      misago/users/tests/test_signatures.py
  482. 10 12
      misago/users/tests/test_social_pipeline.py
  483. 1 1
      misago/users/tests/test_social_utils.py
  484. 1 1
      misago/users/tests/test_testutils.py
  485. 1 1
      misago/users/tests/test_token_creation_and_validation.py
  486. 1 2
      misago/users/tests/test_twitter_profilefield.py
  487. 6 6
      misago/users/tests/test_user_avatar_api.py
  488. 1 1
      misago/users/tests/test_user_changeemail_api.py
  489. 1 1
      misago/users/tests/test_user_changepassword_api.py
  490. 4 4
      misago/users/tests/test_user_create_api.py
  491. 2 2
      misago/users/tests/test_user_creation.py
  492. 2 2
      misago/users/tests/test_user_datadownloads_api.py
  493. 2 2
      misago/users/tests/test_user_details_api.py
  494. 2 2
      misago/users/tests/test_user_editdetails_api.py
  495. 2 2
      misago/users/tests/test_user_feeds_api.py
  496. 3 3
      misago/users/tests/test_user_middleware.py
  497. 4 5
      misago/users/tests/test_user_model.py
  498. 2 2
      misago/users/tests/test_user_requestdatadownload_api.py
  499. 2 2
      misago/users/tests/test_user_signature_api.py
  500. 3 3
      misago/users/tests/test_user_username_api.py
  501. 9 10
      misago/users/tests/test_useradmin_views.py
  502. 2 2
      misago/users/tests/test_usernamechanges_api.py
  503. 7 7
      misago/users/tests/test_users_api.py
  504. 1 1
      misago/users/tests/test_utils.py
  505. 3 3
      misago/users/tests/test_validators.py
  506. 2 2
      misago/users/urls/__init__.py
  507. 5 6
      misago/users/urls/api.py
  508. 1 4
      misago/users/validators.py
  509. 4 4
      misago/users/viewmodels/activeposters.py
  510. 4 4
      misago/users/viewmodels/followers.py
  511. 2 3
      misago/users/viewmodels/posts.py
  512. 4 4
      misago/users/viewmodels/rankusers.py
  513. 7 7
      misago/users/viewmodels/threads.py
  514. 4 5
      misago/users/views/activation.py
  515. 3 3
      misago/users/views/admin/bans.py
  516. 4 4
      misago/users/views/admin/datadownloads.py
  517. 3 3
      misago/users/views/admin/ranks.py
  518. 14 17
      misago/users/views/admin/users.py
  519. 1 2
      misago/users/views/avatarserver.py
  520. 4 4
      misago/users/views/forgottenpassword.py
  521. 5 5
      misago/users/views/lists.py
  522. 3 3
      misago/users/views/options.py
  523. 8 13
      misago/users/views/profile.py

+ 4 - 11
.isort.cfg

@@ -1,14 +1,7 @@
 [settings]
 [settings]
-line_length=100
-lines_after_imports=2
-known_crispyforms=crispy_forms
-known_django=django
-known_faker=faker
-kmown_mptt=mptt
-knowm_requests=requests
-known_restframework=rest_framework
-known_unidecode=unidecode
+include_trailing_comma=true
+line_length=88
+lines_after_imports=1
 known_first_party=misago
 known_first_party=misago
-sections=FUTURE,STDLIB,THIRDPARTY,FAKER,MPTT,REQUESTS,RESTFRAMEWORK,UNIDECODE,DJANGO,FIRSTPARTY,LOCALFOLDER
-multi_line_output=4
+multi_line_output=3
 verbose=true
 verbose=true

+ 4 - 0
dev

@@ -89,6 +89,7 @@ intro() {
     echo "    ${BOLD}bash${NORMAL}              starts bash session inside running Misago container."
     echo "    ${BOLD}bash${NORMAL}              starts bash session inside running Misago container."
     echo "    ${BOLD}run${NORMAL}               runs \"docker-compose run --rm misago\"."
     echo "    ${BOLD}run${NORMAL}               runs \"docker-compose run --rm misago\"."
     echo "    ${BOLD}psql${NORMAL}              runs psql connected to development database."
     echo "    ${BOLD}psql${NORMAL}              runs psql connected to development database."
+    echo "    ${BOLD}fmtpy${NORMAL}             runs isort + black on python code."
     echo
     echo
 }
 }
 
 
@@ -310,6 +311,9 @@ if [[ $1 ]]; then
         run_psql
         run_psql
     elif [[ $1 = "psql_in_docker" ]]; then
     elif [[ $1 = "psql_in_docker" ]]; then
         psql_in_docker
         psql_in_docker
+    elif [[ $1 = "fmtpy" ]]; then
+        isort -rc misago
+        black devproject misago
     else
     else
         invalid_argument $1
         invalid_argument $1
     fi
     fi

+ 1 - 0
misago/acl/apps.py

@@ -1,4 +1,5 @@
 from django.apps import AppConfig
 from django.apps import AppConfig
+
 from .providers import providers
 from .providers import providers
 
 
 
 

+ 1 - 2
misago/acl/cache.py

@@ -1,8 +1,7 @@
 from django.core.cache import cache
 from django.core.cache import cache
 
 
-from misago.cache.versions import invalidate_cache
-
 from . import ACL_CACHE
 from . import ACL_CACHE
+from ..cache.versions import invalidate_cache
 
 
 
 
 def get_acl_cache(user, cache_versions):
 def get_acl_cache(user, cache_versions):

+ 1 - 1
misago/acl/migrations/0001_initial.py

@@ -1,7 +1,7 @@
 from django.contrib.postgres.fields import JSONField
 from django.contrib.postgres.fields import JSONField
 from django.db import migrations, models
 from django.db import migrations, models
 
 
-from misago.acl.models import permissions_default
+from ..models import permissions_default
 
 
 
 
 class Migration(migrations.Migration):
 class Migration(migrations.Migration):

+ 0 - 1
misago/acl/migrations/0003_default_roles.py

@@ -1,6 +1,5 @@
 from django.db import migrations
 from django.db import migrations
 
 
-
 _ = lambda s: s
 _ = lambda s: s
 
 
 
 

+ 2 - 2
misago/acl/migrations/0004_cache_version.py

@@ -1,8 +1,8 @@
 # -*- coding: utf-8 -*-
 # -*- coding: utf-8 -*-
 from django.db import migrations
 from django.db import migrations
 
 
-from misago.acl import ACL_CACHE
-from misago.cache.operations import StartCacheVersioning
+from .. import ACL_CACHE
+from ...cache.operations import StartCacheVersioning
 
 
 
 
 class Migration(migrations.Migration):
 class Migration(migrations.Migration):

+ 0 - 1
misago/acl/panels.py

@@ -1,5 +1,4 @@
 from debug_toolbar.panels import Panel
 from debug_toolbar.panels import Panel
-
 from django.utils.translation import gettext_lazy as _
 from django.utils.translation import gettext_lazy as _
 
 
 
 

+ 1 - 2
misago/acl/providers.py

@@ -1,7 +1,6 @@
 from importlib import import_module
 from importlib import import_module
 
 
-from misago.conf import settings
-
+from ..conf import settings
 
 
 _NOT_INITIALIZED_ERROR = (
 _NOT_INITIALIZED_ERROR = (
     "PermissionProviders instance has to load providers with load() "
     "PermissionProviders instance has to load providers with load() "

+ 1 - 1
misago/acl/tests/test_acl_algebra.py

@@ -1,4 +1,4 @@
-from misago.acl import algebra
+from .. import algebra
 
 
 
 
 def test_greatest_value_is_returned():
 def test_greatest_value_is_returned():

+ 1 - 1
misago/acl/tests/test_getting_user_acl.py

@@ -1,4 +1,4 @@
-from misago.acl.useracl import get_user_acl
+from ..useracl import get_user_acl
 
 
 
 
 def test_getter_returns_authenticated_user_acl(cache_versions, user):
 def test_getter_returns_authenticated_user_acl(cache_versions, user):

+ 2 - 2
misago/acl/tests/test_mock_role_admin_form_data.py

@@ -1,5 +1,5 @@
-from misago.acl.models import Role
-from misago.acl.test import mock_role_form_data
+from ..models import Role
+from ..test import mock_role_form_data
 
 
 
 
 def test_factory_for_change_role_permissions_form_data():
 def test_factory_for_change_role_permissions_form_data():

+ 2 - 2
misago/acl/tests/test_patching_user_acl.py

@@ -1,5 +1,5 @@
-from misago.acl import useracl
-from misago.acl.test import patch_user_acl
+from .. import useracl
+from ..test import patch_user_acl
 
 
 
 
 def callable_acl_patch(user, user_acl):
 def callable_acl_patch(user, user_acl):

+ 2 - 2
misago/acl/tests/test_providers.py

@@ -1,7 +1,7 @@
 import pytest
 import pytest
 
 
-from misago.acl.providers import PermissionProviders
-from misago.conf import settings
+from ...conf import settings
+from ..providers import PermissionProviders
 
 
 
 
 def test_providers_are_not_loaded_on_container_init():
 def test_providers_are_not_loaded_on_container_init():

+ 5 - 5
misago/acl/tests/test_roleadmin_views.py

@@ -1,10 +1,10 @@
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.acl import ACL_CACHE
-from misago.acl.models import Role
-from misago.acl.test import mock_role_form_data
-from misago.cache.test import assert_invalidates_cache
-from misago.admin.test import AdminTestCase
+from .. import ACL_CACHE
+from ...admin.test import AdminTestCase
+from ...cache.test import assert_invalidates_cache
+from ..models import Role
+from ..test import mock_role_form_data
 
 
 
 
 def create_data(data_dict):
 def create_data(data_dict):

+ 1 - 1
misago/acl/tests/test_serializing_user_acl.py

@@ -1,6 +1,6 @@
 import json
 import json
 
 
-from misago.acl.useracl import get_user_acl, serialize_user_acl
+from ..useracl import get_user_acl, serialize_user_acl
 
 
 
 
 def test_user_acl_is_serializeable(cache_versions, user):
 def test_user_acl_is_serializeable(cache_versions, user):

+ 1 - 1
misago/acl/tests/test_user_acl_context_processor.py

@@ -1,6 +1,6 @@
 from unittest.mock import Mock
 from unittest.mock import Mock
 
 
-from misago.acl.context_processors import user_acl
+from ..context_processors import user_acl
 
 
 
 
 def test_context_processor_adds_request_user_acl_to_context():
 def test_context_processor_adds_request_user_acl_to_context():

+ 1 - 1
misago/acl/tests/test_user_acl_middleware.py

@@ -1,6 +1,6 @@
 from unittest.mock import Mock
 from unittest.mock import Mock
 
 
-from misago.acl.middleware import user_acl_middleware
+from ..middleware import user_acl_middleware
 
 
 
 
 def test_middleware_sets_attr_on_request(cache_versions, user):
 def test_middleware_sets_attr_on_request(cache_versions, user):

+ 1 - 2
misago/acl/views.py

@@ -3,8 +3,7 @@ from django.shortcuts import redirect
 from django.urls import reverse
 from django.urls import reverse
 from django.utils.translation import gettext_lazy as _
 from django.utils.translation import gettext_lazy as _
 
 
-from misago.admin.views import generic
-
+from ..admin.views import generic
 from .forms import RoleForm, get_permissions_forms
 from .forms import RoleForm, get_permissions_forms
 from .models import Role
 from .models import Role
 
 

+ 1 - 2
misago/admin/auth.py

@@ -5,8 +5,7 @@ from django.contrib import auth as dj_auth
 from django.contrib import messages
 from django.contrib import messages
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
 
 
-from misago.conf import settings
-
+from ..conf import settings
 
 
 KEY_TOKEN = "misago_admin_session_token"
 KEY_TOKEN = "misago_admin_session_token"
 KEY_UPDATED = "misago_admin_session_updated"
 KEY_UPDATED = "misago_admin_session_updated"

+ 1 - 1
misago/admin/forms.py

@@ -1,7 +1,7 @@
 from django.forms import DateTimeField, RadioSelect, TypedChoiceField, ValidationError
 from django.forms import DateTimeField, RadioSelect, TypedChoiceField, ValidationError
 from django.utils.translation import gettext_lazy as _
 from django.utils.translation import gettext_lazy as _
 
 
-from misago.core.utils import parse_iso8601_string
+from ..core.utils import parse_iso8601_string
 
 
 
 
 class IsoDateTimeField(DateTimeField):
 class IsoDateTimeField(DateTimeField):

+ 1 - 1
misago/admin/test.py

@@ -1,6 +1,6 @@
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.users.test import SuperUserTestCase
+from ..users.test import SuperUserTestCase
 
 
 
 
 class AdminTestCase(SuperUserTestCase):
 class AdminTestCase(SuperUserTestCase):

+ 3 - 3
misago/admin/tests/test_admin_form_templatetags.py

@@ -2,15 +2,15 @@ import pytest
 from django import forms
 from django import forms
 from django.template import Context, Template, TemplateSyntaxError
 from django.template import Context, Template, TemplateSyntaxError
 
 
-from misago.admin.templatetags.misago_admin_form import (
+from ..forms import YesNoSwitch
+from ..templatetags.misago_admin_form import (
+    is_multiple_choice_field,
     is_radio_select_field,
     is_radio_select_field,
     is_select_field,
     is_select_field,
-    is_multiple_choice_field,
     is_textarea_field,
     is_textarea_field,
     render_attrs,
     render_attrs,
     render_bool_attrs,
     render_bool_attrs,
 )
 )
-from misago.admin.forms import YesNoSwitch
 
 
 
 
 class Form(forms.Form):
 class Form(forms.Form):

+ 1 - 1
misago/admin/tests/test_admin_hierarchy.py

@@ -1,6 +1,6 @@
 from django.test import TestCase
 from django.test import TestCase
 
 
-from misago.admin.hierarchy import Node
+from ..hierarchy import Node
 
 
 
 
 class NodeTests(TestCase):
 class NodeTests(TestCase):

+ 2 - 2
misago/admin/tests/test_admin_index.py

@@ -1,8 +1,8 @@
 from django.test import TestCase, override_settings
 from django.test import TestCase, override_settings
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.admin.test import AdminTestCase
-from misago.admin.views.index import check_misago_address
+from ..test import AdminTestCase
+from ..views.index import check_misago_address
 
 
 
 
 class AdminIndexViewTests(AdminTestCase):
 class AdminIndexViewTests(AdminTestCase):

+ 3 - 3
misago/admin/tests/test_admin_views.py

@@ -1,9 +1,9 @@
 from django.test import TestCase
 from django.test import TestCase
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.admin.test import AdminTestCase
-from misago.admin.views import get_protected_namespace
-from misago.users.test import create_test_user
+from ...users.test import create_test_user
+from ..test import AdminTestCase
+from ..views import get_protected_namespace
 
 
 
 
 class MockRequest(object):
 class MockRequest(object):

+ 1 - 1
misago/admin/tests/test_forms.py

@@ -1,7 +1,7 @@
 from django import forms
 from django import forms
 from django.test import TestCase
 from django.test import TestCase
 
 
-from misago.admin.forms import YesNoSwitch
+from ..forms import YesNoSwitch
 
 
 
 
 class YesNoForm(forms.Form):
 class YesNoForm(forms.Form):

+ 1 - 3
misago/admin/urls.py

@@ -1,10 +1,8 @@
 from django.conf.urls import url
 from django.conf.urls import url
 
 
-from misago import admin
-
+from .. import admin
 from .views import auth, index
 from .views import auth, index
 
 
-
 urlpatterns = [
 urlpatterns = [
     # "misago:admin:index" link symbolises "root" of Misago admin links space
     # "misago:admin:index" link symbolises "root" of Misago admin links space
     # any request with path that falls below this one is assumed to be directed
     # any request with path that falls below this one is assumed to be directed

+ 3 - 4
misago/admin/views/__init__.py

@@ -1,10 +1,9 @@
 from django.urls import reverse, NoReverseMatch
 from django.urls import reverse, NoReverseMatch
 from django.shortcuts import render as dj_render
 from django.shortcuts import render as dj_render
 
 
-from misago.conf import settings
-
-from misago.admin import site
-from misago.admin.auth import is_admin_session, update_admin_session
+from ...conf import settings
+from .. import site
+from ..auth import is_admin_session, update_admin_session
 from .auth import login
 from .auth import login
 
 
 
 

+ 2 - 2
misago/admin/views/auth.py

@@ -5,8 +5,8 @@ from django.views.decorators.cache import never_cache
 from django.views.decorators.csrf import csrf_protect
 from django.views.decorators.csrf import csrf_protect
 from django.views.decorators.debug import sensitive_post_parameters
 from django.views.decorators.debug import sensitive_post_parameters
 
 
-from misago.admin import auth
-from misago.users.forms.auth import AdminAuthenticationForm
+from .. import auth
+from ...users.forms.auth import AdminAuthenticationForm
 
 
 
 
 @sensitive_post_parameters()
 @sensitive_post_parameters()

+ 2 - 4
misago/admin/views/errorpages.py

@@ -1,10 +1,8 @@
 from django.shortcuts import redirect
 from django.shortcuts import redirect
 
 
-from misago.admin.auth import is_admin_session, update_admin_session
-from misago.core.utils import get_exception_message
-
 from . import get_protected_namespace, protected_admin_view, render
 from . import get_protected_namespace, protected_admin_view, render
-
+from ...core.utils import get_exception_message
+from ..auth import is_admin_session, update_admin_session
 
 
 # Magic error page used by admin
 # Magic error page used by admin
 @protected_admin_view
 @protected_admin_view

+ 1 - 1
misago/admin/views/generic/base.py

@@ -1,6 +1,6 @@
 from django.views import View
 from django.views import View
 
 
-from misago.admin.views import render
+from .. import render
 
 
 
 
 class AdminView(View):
 class AdminView(View):

+ 1 - 2
misago/admin/views/generic/list.py

@@ -7,8 +7,7 @@ from django.shortcuts import redirect
 from django.urls import reverse
 from django.urls import reverse
 from django.utils.translation import gettext_lazy as _
 from django.utils.translation import gettext_lazy as _
 
 
-from misago.core.exceptions import ExplicitFirstPage
-
+from ....core.exceptions import ExplicitFirstPage
 from .base import AdminView
 from .base import AdminView
 
 
 
 

+ 5 - 8
misago/admin/views/index.py

@@ -1,17 +1,14 @@
 import requests
 import requests
-from requests.exceptions import RequestException
-
 from django.contrib.auth import get_user_model
 from django.contrib.auth import get_user_model
 from django.http import Http404, JsonResponse
 from django.http import Http404, JsonResponse
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
-
-from misago import __version__
-from misago.conf import settings
-from misago.core.cache import cache
-from misago.threads.models import Post, Thread
+from requests.exceptions import RequestException
 
 
 from . import render
 from . import render
-
+from ... import __version__
+from ...conf import settings
+from ...core.cache import cache
+from ...threads.models import Post, Thread
 
 
 VERSION_CHECK_CACHE_KEY = "misago_version_check"
 VERSION_CHECK_CACHE_KEY = "misago_version_check"
 
 

+ 1 - 1
misago/cache/management/commands/invalidateversionedcaches.py

@@ -1,6 +1,6 @@
 from django.core.management.base import BaseCommand
 from django.core.management.base import BaseCommand
 
 
-from misago.cache.versions import invalidate_all_caches
+from ...versions import invalidate_all_caches
 
 
 
 
 class Command(BaseCommand):
 class Command(BaseCommand):

+ 2 - 2
misago/cache/migrations/0001_initial.py

@@ -1,7 +1,7 @@
 # Generated by Django 1.11.16 on 2018-11-25 15:15
 # Generated by Django 1.11.16 on 2018-11-25 15:15
 from django.db import migrations, models
 from django.db import migrations, models
 
 
-import misago.cache.utils
+from .. import utils
 
 
 
 
 class Migration(migrations.Migration):
 class Migration(migrations.Migration):
@@ -21,7 +21,7 @@ class Migration(migrations.Migration):
                 (
                 (
                     "version",
                     "version",
                     models.CharField(
                     models.CharField(
-                        default=misago.cache.utils.generate_version_string, max_length=8
+                        default=utils.generate_version_string, max_length=8
                     ),
                     ),
                 ),
                 ),
             ],
             ],

+ 1 - 1
misago/cache/tests/conftest.py

@@ -1,6 +1,6 @@
 import pytest
 import pytest
 
 
-from misago.cache.models import CacheVersion
+from ..models import CacheVersion
 
 
 
 
 @pytest.fixture
 @pytest.fixture

+ 3 - 3
misago/cache/tests/test_assert_invalidates_cache.py

@@ -1,8 +1,8 @@
 import pytest
 import pytest
 
 
-from misago.cache.models import CacheVersion
-from misago.cache.test import assert_invalidates_cache
-from misago.cache.versions import invalidate_cache
+from ..models import CacheVersion
+from ..test import assert_invalidates_cache
+from ..versions import invalidate_cache
 
 
 
 
 def test_assertion_fails_if_specified_cache_is_not_invaldiated(cache_version):
 def test_assertion_fails_if_specified_cache_is_not_invaldiated(cache_version):

+ 1 - 1
misago/cache/tests/test_cache_versions_middleware.py

@@ -2,7 +2,7 @@ from unittest.mock import Mock
 
 
 import pytest
 import pytest
 
 
-from misago.cache.middleware import cache_versions_middleware
+from ..middleware import cache_versions_middleware
 
 
 
 
 @pytest.fixture
 @pytest.fixture

+ 1 - 1
misago/cache/tests/test_getting_cache_versions.py

@@ -1,4 +1,4 @@
-from misago.cache.versions import (
+from ..versions import (
     CACHE_NAME,
     CACHE_NAME,
     get_cache_versions,
     get_cache_versions,
     get_cache_versions_from_cache,
     get_cache_versions_from_cache,

+ 2 - 2
misago/cache/tests/test_invalidating_caches.py

@@ -1,7 +1,7 @@
 import pytest
 import pytest
 
 
-from misago.cache.versions import CACHE_NAME, invalidate_cache, invalidate_all_caches
-from misago.cache.models import CacheVersion
+from ..models import CacheVersion
+from ..versions import CACHE_NAME, invalidate_all_caches, invalidate_cache
 
 
 
 
 @pytest.fixture
 @pytest.fixture

+ 4 - 6
misago/categories/forms.py

@@ -1,15 +1,13 @@
-from mptt.forms import TreeNodeChoiceField, TreeNodeMultipleChoiceField
-
 from django import forms
 from django import forms
 from django.db import models
 from django.db import models
 from django.utils.html import conditional_escape, mark_safe
 from django.utils.html import conditional_escape, mark_safe
 from django.utils.translation import gettext_lazy as _
 from django.utils.translation import gettext_lazy as _
-
-from misago.admin.forms import YesNoSwitch
-from misago.core.validators import validate_sluggable
-from misago.threads.threadtypes import trees_map
+from mptt.forms import TreeNodeChoiceField, TreeNodeMultipleChoiceField
 
 
 from . import THREADS_ROOT_NAME
 from . import THREADS_ROOT_NAME
+from ..admin.forms import YesNoSwitch
+from ..core.validators import validate_sluggable
+from ..threads.threadtypes import trees_map
 from .models import Category, CategoryRole
 from .models import Category, CategoryRole
 
 
 
 

+ 2 - 2
misago/categories/management/commands/fixcategoriestree.py

@@ -1,7 +1,7 @@
 from django.core.management.base import BaseCommand
 from django.core.management.base import BaseCommand
 
 
-from misago.acl.cache import clear_acl_cache
-from misago.categories.models import Category
+from ....acl.cache import clear_acl_cache
+from ...models import Category
 
 
 
 
 class Command(BaseCommand):
 class Command(BaseCommand):

+ 1 - 1
misago/categories/management/commands/prunecategories.py

@@ -3,7 +3,7 @@ from datetime import timedelta
 from django.core.management.base import BaseCommand
 from django.core.management.base import BaseCommand
 from django.utils import timezone
 from django.utils import timezone
 
 
-from misago.categories.models import Category
+from ...models import Category
 
 
 
 
 class Command(BaseCommand):
 class Command(BaseCommand):

+ 2 - 2
misago/categories/management/commands/synchronizecategories.py

@@ -2,8 +2,8 @@ import time
 
 
 from django.core.management.base import BaseCommand
 from django.core.management.base import BaseCommand
 
 
-from misago.categories.models import Category
-from misago.core.management.progressbar import show_progress
+from ....core.management.progressbar import show_progress
+from ...models import Category
 
 
 
 
 class Command(BaseCommand):
 class Command(BaseCommand):

+ 2 - 3
misago/categories/migrations/0001_initial.py

@@ -1,11 +1,10 @@
-import mptt.fields
-
 import django.db.models.deletion
 import django.db.models.deletion
+import mptt.fields
 from django.conf import settings
 from django.conf import settings
 from django.contrib.postgres.fields import JSONField
 from django.contrib.postgres.fields import JSONField
 from django.db import migrations, models
 from django.db import migrations, models
 
 
-from misago.acl.models import permissions_default
+from ...acl.models import permissions_default
 
 
 
 
 class Migration(migrations.Migration):
 class Migration(migrations.Migration):

+ 1 - 2
misago/categories/migrations/0002_default_categories.py

@@ -1,7 +1,6 @@
 from django.db import migrations
 from django.db import migrations
 
 
-from misago.core.utils import slugify
-
+from ...core.utils import slugify
 
 
 _ = lambda s: s
 _ = lambda s: s
 
 

+ 0 - 1
misago/categories/migrations/0003_categories_roles.py

@@ -1,6 +1,5 @@
 from django.db import migrations
 from django.db import migrations
 
 
-
 _ = lambda s: s
 _ = lambda s: s
 
 
 
 

+ 0 - 1
misago/categories/migrations/0006_moderation_queue_roles.py

@@ -1,6 +1,5 @@
 from django.db import migrations
 from django.db import migrations
 
 
-
 _ = lambda s: s
 _ = lambda s: s
 
 
 
 

+ 0 - 1
misago/categories/migrations/0007_best_answers_roles.py

@@ -1,7 +1,6 @@
 # Generated by Django 1.11.9 on 2018-03-18 20:40
 # Generated by Django 1.11.9 on 2018-03-18 20:40
 from django.db import migrations
 from django.db import migrations
 
 
-
 _ = lambda s: s
 _ = lambda s: s
 
 
 
 

+ 7 - 9
misago/categories/models.py

@@ -1,16 +1,14 @@
+from django.db import models
 from mptt.managers import TreeManager
 from mptt.managers import TreeManager
 from mptt.models import MPTTModel, TreeForeignKey
 from mptt.models import MPTTModel, TreeForeignKey
 
 
-from django.db import models
-
-from misago.acl.cache import clear_acl_cache
-from misago.acl.models import BaseRole
-from misago.conf import settings
-from misago.core.cache import cache
-from misago.core.utils import slugify
-from misago.threads.threadtypes import trees_map
-
 from . import PRIVATE_THREADS_ROOT_NAME, THREADS_ROOT_NAME
 from . import PRIVATE_THREADS_ROOT_NAME, THREADS_ROOT_NAME
+from ..acl.cache import clear_acl_cache
+from ..acl.models import BaseRole
+from ..conf import settings
+from ..core.cache import cache
+from ..core.utils import slugify
+from ..threads.threadtypes import trees_map
 
 
 CACHE_NAME = "misago_categories_tree"
 CACHE_NAME = "misago_categories_tree"
 
 

+ 4 - 5
misago/categories/permissions.py

@@ -4,11 +4,10 @@ from django.core.exceptions import PermissionDenied
 from django.http import Http404
 from django.http import Http404
 from django.utils.translation import gettext_lazy as _
 from django.utils.translation import gettext_lazy as _
 
 
-from misago.acl import algebra
-from misago.acl.decorators import return_boolean
-from misago.admin.forms import YesNoSwitch
-from misago.users.models import AnonymousUser
-
+from ..acl import algebra
+from ..acl.decorators import return_boolean
+from ..admin.forms import YesNoSwitch
+from ..users.models import AnonymousUser
 from .models import Category, CategoryRole, RoleCategoryACL
 from .models import Category, CategoryRole, RoleCategoryACL
 
 
 
 

+ 3 - 6
misago/categories/serializers.py

@@ -1,13 +1,10 @@
-from rest_framework import serializers
-
 from django.urls import reverse
 from django.urls import reverse
+from rest_framework import serializers
 
 
-from misago.core.serializers import MutableFields
-from misago.core.utils import format_plaintext_for_html
-
+from ..core.serializers import MutableFields
+from ..core.utils import format_plaintext_for_html
 from .models import Category
 from .models import Category
 
 
-
 __all__ = ["CategorySerializer"]
 __all__ = ["CategorySerializer"]
 
 
 
 

+ 1 - 3
misago/categories/signals.py

@@ -1,10 +1,8 @@
 from django.dispatch import Signal, receiver
 from django.dispatch import Signal, receiver
 
 
-from misago.users.signals import anonymize_user_data, username_changed
-
+from ..users.signals import anonymize_user_data, username_changed
 from .models import Category
 from .models import Category
 
 
-
 delete_category_content = Signal()
 delete_category_content = Signal()
 move_category_content = Signal(providing_args=["new_category"])
 move_category_content = Signal(providing_args=["new_category"])
 
 

+ 6 - 6
misago/categories/tests/test_categories_admin_views.py

@@ -1,11 +1,11 @@
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.acl import ACL_CACHE
-from misago.admin.test import AdminTestCase
-from misago.cache.test import assert_invalidates_cache
-from misago.categories.models import Category
-from misago.threads import test
-from misago.threads.models import Thread
+from ...acl import ACL_CACHE
+from ...admin.test import AdminTestCase
+from ...cache.test import assert_invalidates_cache
+from ...threads import test
+from ...threads.models import Thread
+from ..models import Category
 
 
 
 
 class CategoryAdminTestCase(AdminTestCase):
 class CategoryAdminTestCase(AdminTestCase):

+ 4 - 4
misago/categories/tests/test_category_model.py

@@ -1,9 +1,9 @@
 from django.test import TestCase
 from django.test import TestCase
 
 
-from misago.categories import THREADS_ROOT_NAME
-from misago.categories.models import Category
-from misago.threads import test
-from misago.threads.threadtypes import trees_map
+from .. import THREADS_ROOT_NAME
+from ...threads import test
+from ...threads.threadtypes import trees_map
+from ..models import Category
 
 
 
 
 class CategoryManagerTests(TestCase):
 class CategoryManagerTests(TestCase):

+ 4 - 4
misago/categories/tests/test_fixcategoriestree.py

@@ -3,10 +3,10 @@ from io import StringIO
 from django.core.management import call_command
 from django.core.management import call_command
 from django.test import TestCase
 from django.test import TestCase
 
 
-from misago.acl import ACL_CACHE
-from misago.cache.test import assert_invalidates_cache
-from misago.categories.management.commands import fixcategoriestree
-from misago.categories.models import Category
+from ...acl import ACL_CACHE
+from ...cache.test import assert_invalidates_cache
+from ..management.commands import fixcategoriestree
+from ..models import Category
 
 
 
 
 def run_command():
 def run_command():

+ 6 - 6
misago/categories/tests/test_permissions_admin_views.py

@@ -1,11 +1,11 @@
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.acl import ACL_CACHE
-from misago.acl.models import Role
-from misago.acl.test import mock_role_form_data
-from misago.admin.test import AdminTestCase
-from misago.cache.test import assert_invalidates_cache
-from misago.categories.models import Category, CategoryRole
+from ...acl import ACL_CACHE
+from ...acl.models import Role
+from ...acl.test import mock_role_form_data
+from ...admin.test import AdminTestCase
+from ...cache.test import assert_invalidates_cache
+from ..models import Category, CategoryRole
 
 
 
 
 def create_data(data_dict):
 def create_data(data_dict):

+ 3 - 3
misago/categories/tests/test_prunecategories.py

@@ -5,9 +5,9 @@ from django.core.management import call_command
 from django.test import TestCase
 from django.test import TestCase
 from django.utils import timezone
 from django.utils import timezone
 
 
-from misago.categories.management.commands import prunecategories
-from misago.categories.models import Category
-from misago.threads import test
+from ...threads import test
+from ..management.commands import prunecategories
+from ..models import Category
 
 
 
 
 class PruneCategoriesTests(TestCase):
 class PruneCategoriesTests(TestCase):

+ 3 - 3
misago/categories/tests/test_synchronizecategories.py

@@ -3,9 +3,9 @@ from io import StringIO
 from django.core.management import call_command
 from django.core.management import call_command
 from django.test import TestCase
 from django.test import TestCase
 
 
-from misago.categories.management.commands import synchronizecategories
-from misago.categories.models import Category
-from misago.threads import test
+from ...threads import test
+from ..management.commands import synchronizecategories
+from ..models import Category
 
 
 
 
 class SynchronizeCategoriesTests(TestCase):
 class SynchronizeCategoriesTests(TestCase):

+ 5 - 5
misago/categories/tests/test_utils.py

@@ -1,8 +1,8 @@
-from misago.acl.useracl import get_user_acl
-from misago.categories.models import Category
-from misago.categories.utils import get_categories_tree, get_category_path
-from misago.conftest import get_cache_versions
-from misago.users.test import AuthenticatedUserTestCase
+from ...acl.useracl import get_user_acl
+from ...conftest import get_cache_versions
+from ...users.test import AuthenticatedUserTestCase
+from ..models import Category
+from ..utils import get_categories_tree, get_category_path
 
 
 cache_versions = get_cache_versions()
 cache_versions = get_cache_versions()
 
 

+ 3 - 3
misago/categories/tests/test_views.py

@@ -2,9 +2,9 @@ import json
 
 
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.acl.test import patch_user_acl
-from misago.categories.models import Category
-from misago.users.test import AuthenticatedUserTestCase
+from ...acl.test import patch_user_acl
+from ...users.test import AuthenticatedUserTestCase
+from ..models import Category
 
 
 
 
 class CategoryViewsTests(AuthenticatedUserTestCase):
 class CategoryViewsTests(AuthenticatedUserTestCase):

+ 3 - 3
misago/categories/urls/__init__.py

@@ -1,9 +1,9 @@
 from django.conf.urls import url
 from django.conf.urls import url
 
 
-from misago.conf import settings
-from misago.core.views import home_redirect
+from ...conf import settings
+from ...core.views import home_redirect
 
 
-from misago.categories.views.categorieslist import categories
+from ..views.categorieslist import categories
 
 
 if settings.MISAGO_THREADS_ON_INDEX:
 if settings.MISAGO_THREADS_ON_INDEX:
     URL_PATH = r"^categories/$"
     URL_PATH = r"^categories/$"

+ 2 - 3
misago/categories/urls/api.py

@@ -1,6 +1,5 @@
-from misago.categories.api import CategoryViewSet
-from misago.core.apirouter import MisagoApiRouter
-
+from ...core.apirouter import MisagoApiRouter
+from ..api import CategoryViewSet
 
 
 router = MisagoApiRouter()
 router = MisagoApiRouter()
 router.register(r"categories", CategoryViewSet, base_name="category")
 router.register(r"categories", CategoryViewSet, base_name="category")

+ 2 - 3
misago/categories/utils.py

@@ -1,6 +1,5 @@
-from misago.acl.objectacl import add_acl_to_obj
-from misago.readtracker import categoriestracker
-
+from ..acl.objectacl import add_acl_to_obj
+from ..readtracker import categoriestracker
 from .models import Category
 from .models import Category
 
 
 
 

+ 6 - 6
misago/categories/views/categoriesadmin.py

@@ -2,12 +2,12 @@ from django.contrib import messages
 from django.shortcuts import redirect
 from django.shortcuts import redirect
 from django.utils.translation import gettext_lazy as _
 from django.utils.translation import gettext_lazy as _
 
 
-from misago.acl.cache import clear_acl_cache
-from misago.admin.views import generic
-from misago.categories import THREADS_ROOT_NAME
-from misago.categories.forms import CategoryFormFactory, DeleteFormFactory
-from misago.categories.models import Category, RoleCategoryACL
-from misago.threads.threadtypes import trees_map
+from .. import THREADS_ROOT_NAME
+from ...acl.cache import clear_acl_cache
+from ...admin.views import generic
+from ...threads.threadtypes import trees_map
+from ..forms import CategoryFormFactory, DeleteFormFactory
+from ..models import Category, RoleCategoryACL
 
 
 
 
 class CategoryAdmin(generic.AdminBaseMixin):
 class CategoryAdmin(generic.AdminBaseMixin):

+ 2 - 4
misago/categories/views/categorieslist.py

@@ -1,10 +1,8 @@
 from django.shortcuts import render
 from django.shortcuts import render
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.categories.serializers import (
-    CategoryWithPosterSerializer as CategorySerializer,
-)
-from misago.categories.utils import get_categories_tree
+from ..serializers import CategoryWithPosterSerializer as CategorySerializer
+from ..utils import get_categories_tree
 
 
 
 
 def categories(request):
 def categories(request):

+ 7 - 8
misago/categories/views/permsadmin.py

@@ -2,18 +2,17 @@ from django.contrib import messages
 from django.shortcuts import redirect
 from django.shortcuts import redirect
 from django.utils.translation import gettext_lazy as _
 from django.utils.translation import gettext_lazy as _
 
 
-from misago.acl.cache import clear_acl_cache
-from misago.acl.forms import get_permissions_forms
-from misago.acl.models import Role
-from misago.acl.views import RoleAdmin, RolesList
-from misago.admin.views import generic
-from misago.categories.forms import (
+from ...acl.cache import clear_acl_cache
+from ...acl.forms import get_permissions_forms
+from ...acl.models import Role
+from ...acl.views import RoleAdmin, RolesList
+from ...admin.views import generic
+from ..forms import (
     CategoryRoleForm,
     CategoryRoleForm,
     CategoryRolesACLFormFactory,
     CategoryRolesACLFormFactory,
     RoleCategoryACLFormFactory,
     RoleCategoryACLFormFactory,
 )
 )
-from misago.categories.models import Category, CategoryRole, RoleCategoryACL
-
+from ..models import Category, CategoryRole, RoleCategoryACL
 from .categoriesadmin import CategoriesList, CategoryAdmin
 from .categoriesadmin import CategoriesList, CategoryAdmin
 
 
 
 

+ 1 - 2
misago/conf/cache.py

@@ -1,8 +1,7 @@
 from django.core.cache import cache
 from django.core.cache import cache
 
 
-from misago.cache.versions import invalidate_cache
-
 from . import SETTINGS_CACHE
 from . import SETTINGS_CACHE
+from ..cache.versions import invalidate_cache
 
 
 
 
 def get_settings_cache(cache_versions):
 def get_settings_cache(cache_versions):

+ 1 - 2
misago/conf/context_processors.py

@@ -2,9 +2,8 @@ from django.contrib.staticfiles.templatetags.staticfiles import static
 from django.urls import reverse
 from django.urls import reverse
 from django.utils.translation import get_language
 from django.utils.translation import get_language
 
 
-from misago.users.social.utils import get_enabled_social_auth_sites_list
-
 from . import settings
 from . import settings
+from ..users.social.utils import get_enabled_social_auth_sites_list
 
 
 BLANK_AVATAR_URL = static(settings.MISAGO_BLANK_AVATAR)
 BLANK_AVATAR_URL = static(settings.MISAGO_BLANK_AVATAR)
 
 

+ 1 - 1
misago/conf/forms.py

@@ -2,7 +2,7 @@ from django import forms
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
 from django.utils.translation import ngettext
 from django.utils.translation import ngettext
 
 
-from misago.admin.forms import YesNoSwitch
+from ..admin.forms import YesNoSwitch
 
 
 __all__ = ["ChangeSettingsForm"]
 __all__ = ["ChangeSettingsForm"]
 
 

+ 2 - 3
misago/conf/migrations/0002_cache_version.py

@@ -1,9 +1,8 @@
 # Generated by Django 1.11.16 on 2018-12-02 15:54
 # Generated by Django 1.11.16 on 2018-12-02 15:54
 from django.db import migrations
 from django.db import migrations
 
 
-from misago.cache.operations import StartCacheVersioning
-
-from misago.conf import SETTINGS_CACHE
+from .. import SETTINGS_CACHE
+from ...cache.operations import StartCacheVersioning
 
 
 
 
 class Migration(migrations.Migration):
 class Migration(migrations.Migration):

+ 1 - 1
misago/conf/test.py

@@ -1,6 +1,6 @@
 from functools import wraps
 from functools import wraps
 
 
-from misago.conf.dynamicsettings import DynamicSettings
+from .dynamicsettings import DynamicSettings
 
 
 
 
 class override_dynamic_settings:
 class override_dynamic_settings:

+ 1 - 1
misago/conf/tests/conftest.py

@@ -1,6 +1,6 @@
 import pytest
 import pytest
 
 
-from misago.conf.models import Setting, SettingsGroup
+from ..models import Setting, SettingsGroup
 
 
 
 
 @pytest.fixture
 @pytest.fixture

+ 2 - 2
misago/conf/tests/test_admin_views.py

@@ -1,7 +1,7 @@
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.admin.test import AdminTestCase
-from misago.conf.models import SettingsGroup
+from ...admin.test import AdminTestCase
+from ..models import SettingsGroup
 
 
 
 
 class AdminSettingsViewsTests(AdminTestCase):
 class AdminSettingsViewsTests(AdminTestCase):

+ 1 - 1
misago/conf/tests/test_context_processors.py

@@ -2,7 +2,7 @@ from unittest.mock import Mock
 
 
 import pytest
 import pytest
 
 
-from misago.conf.context_processors import conf
+from ..context_processors import conf
 
 
 
 
 def test_request_settings_are_included_in_template_context(db, dynamic_settings):
 def test_request_settings_are_included_in_template_context(db, dynamic_settings):

+ 1 - 2
misago/conf/tests/test_dynamic_settings_middleware.py

@@ -1,10 +1,9 @@
 from unittest.mock import Mock, PropertyMock
 from unittest.mock import Mock, PropertyMock
 
 
 import pytest
 import pytest
-
 from django.utils.functional import SimpleLazyObject
 from django.utils.functional import SimpleLazyObject
 
 
-from misago.conf.middleware import dynamic_settings_middleware
+from ..middleware import dynamic_settings_middleware
 
 
 
 
 @pytest.fixture
 @pytest.fixture

+ 2 - 2
misago/conf/tests/test_getting_dynamic_settings_values.py

@@ -1,7 +1,7 @@
 import pytest
 import pytest
 
 
-from misago.conf import SETTINGS_CACHE
-from misago.conf.dynamicsettings import DynamicSettings
+from .. import SETTINGS_CACHE
+from ..dynamicsettings import DynamicSettings
 
 
 
 
 def test_settings_are_loaded_from_database_if_cache_is_not_available(
 def test_settings_are_loaded_from_database_if_cache_is_not_available(

+ 0 - 1
misago/conf/tests/test_getting_static_settings_values.py

@@ -1,5 +1,4 @@
 import pytest
 import pytest
-
 from django.test import override_settings
 from django.test import override_settings
 
 
 
 

+ 2 - 2
misago/conf/tests/test_hydrators.py

@@ -1,7 +1,7 @@
 from django.test import TestCase
 from django.test import TestCase
 
 
-from misago.conf.hydrators import dehydrate_value, hydrate_value
-from misago.conf.models import Setting
+from ..hydrators import dehydrate_value, hydrate_value
+from ..models import Setting
 
 
 
 
 class HydratorsTests(TestCase):
 class HydratorsTests(TestCase):

+ 2 - 2
misago/conf/tests/test_migrationutils.py

@@ -1,8 +1,8 @@
 from django.apps import apps
 from django.apps import apps
 from django.test import TestCase
 from django.test import TestCase
 
 
-from misago.conf import migrationutils
-from misago.conf.models import SettingsGroup
+from .. import migrationutils
+from ..models import SettingsGroup
 
 
 
 
 class DBConfMigrationUtilsTests(TestCase):
 class DBConfMigrationUtilsTests(TestCase):

+ 1 - 1
misago/conf/tests/test_models.py

@@ -1,6 +1,6 @@
 from django.test import TestCase
 from django.test import TestCase
 
 
-from misago.conf.models import Setting
+from ..models import Setting
 
 
 
 
 class SettingModelTests(TestCase):
 class SettingModelTests(TestCase):

+ 2 - 2
misago/conf/tests/test_overridding_dynamic_settings.py

@@ -1,7 +1,7 @@
 import pytest
 import pytest
 
 
-from misago.conf.dynamicsettings import DynamicSettings
-from misago.conf.test import override_dynamic_settings
+from ..dynamicsettings import DynamicSettings
+from ..test import override_dynamic_settings
 
 
 
 
 def test_dynamic_setting_can_be_overridden_using_context_manager(dynamic_settings):
 def test_dynamic_setting_can_be_overridden_using_context_manager(dynamic_settings):

+ 1 - 2
misago/conf/views.py

@@ -2,8 +2,7 @@ from django.contrib import messages
 from django.shortcuts import redirect
 from django.shortcuts import redirect
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
 
 
-from misago.admin.views import render as mi_render
-
+from ..admin.views import render as mi_render
 from .cache import clear_settings_cache
 from .cache import clear_settings_cache
 from .forms import ChangeSettingsForm
 from .forms import ChangeSettingsForm
 from .models import SettingsGroup
 from .models import SettingsGroup

+ 7 - 7
misago/conftest.py

@@ -1,12 +1,12 @@
 import pytest
 import pytest
 
 
-from misago.acl import ACL_CACHE, useracl
-from misago.conf import SETTINGS_CACHE
-from misago.conf.dynamicsettings import DynamicSettings
-from misago.conf.staticsettings import StaticSettings
-from misago.users import BANS_CACHE
-from misago.users.models import AnonymousUser
-from misago.users.test import create_test_superuser, create_test_user
+from .acl import ACL_CACHE, useracl
+from .conf import SETTINGS_CACHE
+from .conf.dynamicsettings import DynamicSettings
+from .conf.staticsettings import StaticSettings
+from .users import BANS_CACHE
+from .users.models import AnonymousUser
+from .users.test import create_test_superuser, create_test_user
 
 
 
 
 def get_cache_versions():
 def get_cache_versions():

+ 1 - 3
misago/core/apipatch.py

@@ -1,9 +1,7 @@
-from rest_framework.response import Response
-
 from django.core.exceptions import PermissionDenied
 from django.core.exceptions import PermissionDenied
 from django.db import transaction
 from django.db import transaction
 from django.http import Http404
 from django.http import Http404
-
+from rest_framework.response import Response
 
 
 ALLOWED_OPS = ("add", "remove", "replace")
 ALLOWED_OPS = ("add", "remove", "replace")
 
 

+ 2 - 2
misago/core/cache.py

@@ -1,6 +1,6 @@
+from django.core.cache import InvalidCacheBackendError
 from django.core.cache import cache as default_cache
 from django.core.cache import cache as default_cache
-from django.core.cache import InvalidCacheBackendError, caches
-
+from django.core.cache import caches
 
 
 try:
 try:
     cache = caches["misago"]
     cache = caches["misago"]

+ 3 - 4
misago/core/errorpages.py

@@ -3,10 +3,9 @@ from django.shortcuts import render
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
 from social_core import exceptions as social_exceptions
 from social_core import exceptions as social_exceptions
 
 
-from misago.admin.views.errorpages import admin_csrf_failure, admin_error_page
-from misago.core.exceptions import SocialAuthFailed, SocialAuthBanned
-from misago.users.social.utils import get_social_auth_backend_name
-
+from ..admin.views.errorpages import admin_csrf_failure, admin_error_page
+from ..users.social.utils import get_social_auth_backend_name
+from .exceptions import SocialAuthBanned, SocialAuthFailed
 from .utils import get_exception_message, is_request_to_misago
 from .utils import get_exception_message, is_request_to_misago
 
 
 
 

+ 1 - 3
misago/core/exceptionhandler.py

@@ -1,15 +1,13 @@
-from rest_framework.views import exception_handler as rest_exception_handler
-
 from django.core.exceptions import PermissionDenied
 from django.core.exceptions import PermissionDenied
 from django.http import Http404, HttpResponsePermanentRedirect, JsonResponse
 from django.http import Http404, HttpResponsePermanentRedirect, JsonResponse
 from django.urls import reverse
 from django.urls import reverse
+from rest_framework.views import exception_handler as rest_exception_handler
 from social_core.exceptions import SocialAuthBaseException
 from social_core.exceptions import SocialAuthBaseException
 from social_core.utils import social_logger
 from social_core.utils import social_logger
 
 
 from . import errorpages
 from . import errorpages
 from .exceptions import AjaxError, Banned, ExplicitFirstPage, OutdatedSlug
 from .exceptions import AjaxError, Banned, ExplicitFirstPage, OutdatedSlug
 
 
-
 HANDLED_EXCEPTIONS = (
 HANDLED_EXCEPTIONS = (
     AjaxError,
     AjaxError,
     Banned,
     Banned,

+ 1 - 2
misago/core/mail.py

@@ -2,8 +2,7 @@ from django.core import mail as djmail
 from django.template.loader import render_to_string
 from django.template.loader import render_to_string
 from django.utils.translation import get_language
 from django.utils.translation import get_language
 
 
-from misago.conf import settings
-
+from ..conf import settings
 from .utils import get_host_from_address
 from .utils import get_host_from_address
 
 
 
 

+ 2 - 2
misago/core/middleware.py

@@ -1,7 +1,7 @@
 from django.utils.deprecation import MiddlewareMixin
 from django.utils.deprecation import MiddlewareMixin
 
 
-from misago.core import exceptionhandler
-from misago.core.utils import is_request_to_misago
+from . import exceptionhandler
+from .utils import is_request_to_misago
 
 
 
 
 class ExceptionHandlerMiddleware(MiddlewareMixin):
 class ExceptionHandlerMiddleware(MiddlewareMixin):

+ 1 - 2
misago/core/migrations/0002_basic_settings.py

@@ -1,7 +1,6 @@
 from django.db import migrations
 from django.db import migrations
 
 
-from misago.conf.migrationutils import migrate_settings_group
-
+from ...conf.migrationutils import migrate_settings_group
 
 
 _ = lambda s: s
 _ = lambda s: s
 
 

+ 1 - 2
misago/core/momentjs.py

@@ -1,5 +1,4 @@
-from misago.conf import settings
-
+from ..conf import settings
 
 
 MOMENT_STATIC_PATH = "misago/momentjs/%s.js"
 MOMENT_STATIC_PATH = "misago/momentjs/%s.js"
 
 

+ 1 - 2
misago/core/rest_permissions.py

@@ -1,7 +1,6 @@
-from rest_framework.permissions import SAFE_METHODS, BasePermission
-
 from django.core.exceptions import PermissionDenied
 from django.core.exceptions import PermissionDenied
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
+from rest_framework.permissions import SAFE_METHODS, BasePermission
 
 
 
 
 class IsAuthenticatedOrReadOnly(BasePermission):
 class IsAuthenticatedOrReadOnly(BasePermission):

+ 1 - 2
misago/core/shortcuts.py

@@ -1,6 +1,5 @@
-from rest_framework.response import Response
-
 from django.http import Http404
 from django.http import Http404
+from rest_framework.response import Response
 
 
 
 
 def paginate(
 def paginate(

+ 1 - 2
misago/core/slugify.py

@@ -1,6 +1,5 @@
-from unidecode import unidecode
-
 from django.template.defaultfilters import slugify as django_slugify
 from django.template.defaultfilters import slugify as django_slugify
+from unidecode import unidecode
 
 
 
 
 def default(string):
 def default(string):

+ 1 - 1
misago/core/templatetags/misago_absoluteurl.py

@@ -1,7 +1,7 @@
 from django import template
 from django import template
 from django.urls import NoReverseMatch, reverse
 from django.urls import NoReverseMatch, reverse
 
 
-from misago.conf import settings
+from ...conf import settings
 
 
 register = template.Library()
 register = template.Library()
 
 

+ 0 - 1
misago/core/templatetags/misago_batch.py

@@ -1,6 +1,5 @@
 from django import template
 from django import template
 
 
-
 register = template.Library()
 register = template.Library()
 
 
 
 

+ 0 - 1
misago/core/templatetags/misago_capture.py

@@ -9,7 +9,6 @@ Syntax:
 
 
 from django import template
 from django import template
 
 
-
 register = template.Library()
 register = template.Library()
 SYNTAX_ERROR = 'capture tag syntax is "capture [trimmed] as [value]"'
 SYNTAX_ERROR = 'capture tag syntax is "capture [trimmed] as [value]"'
 
 

+ 1 - 2
misago/core/templatetags/misago_json.py

@@ -3,8 +3,7 @@ import json
 from django import template
 from django import template
 from django.utils.safestring import mark_safe
 from django.utils.safestring import mark_safe
 
 
-from misago.core.utils import encode_json_html
-
+from ..utils import encode_json_html
 
 
 register = template.Library()
 register = template.Library()
 
 

+ 0 - 1
misago/core/templatetags/misago_pagetitle.py

@@ -1,7 +1,6 @@
 from django import template
 from django import template
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
 
 
-
 register = template.Library()
 register = template.Library()
 
 
 
 

+ 0 - 1
misago/core/templatetags/misago_shorthands.py

@@ -1,6 +1,5 @@
 from django import template
 from django import template
 
 
-
 register = template.Library()
 register = template.Library()
 
 
 
 

+ 0 - 1
misago/core/templatetags/misago_stringutils.py

@@ -1,6 +1,5 @@
 from django import template
 from django import template
 
 
-
 register = template.Library()
 register = template.Library()
 
 
 
 

+ 1 - 3
misago/core/testproject/urls.py

@@ -7,10 +7,8 @@ from django.views.decorators.cache import cache_page
 from django.views.decorators.http import last_modified
 from django.views.decorators.http import last_modified
 from django.views.i18n import JavaScriptCatalog
 from django.views.i18n import JavaScriptCatalog
 
 
-from misago.users.forms.auth import AdminAuthenticationForm
-
 from . import views
 from . import views
-
+from ...users.forms.auth import AdminAuthenticationForm
 
 
 admin.autodiscover()
 admin.autodiscover()
 admin.site.login_form = AdminAuthenticationForm
 admin.site.login_form = AdminAuthenticationForm

+ 0 - 1
misago/core/testproject/urlswitherrorhandlers.py

@@ -1,5 +1,4 @@
 from .urls import *
 from .urls import *
 
 
-
 handler403 = "misago.core.testproject.views.mock_custom_403_error_page"
 handler403 = "misago.core.testproject.views.mock_custom_403_error_page"
 handler404 = "misago.core.testproject.views.mock_custom_404_error_page"
 handler404 = "misago.core.testproject.views.mock_custom_404_error_page"

+ 8 - 10
misago/core/testproject/views.py

@@ -1,17 +1,15 @@
-from rest_framework.decorators import api_view
-
 from django.core.exceptions import PermissionDenied
 from django.core.exceptions import PermissionDenied
 from django.http import Http404, HttpResponse
 from django.http import Http404, HttpResponse
-from social_core.exceptions import AuthFailed, NotAllowedToDisconnect, WrongBackend
+from rest_framework.decorators import api_view
 from social_core.backends.github import GithubOAuth2
 from social_core.backends.github import GithubOAuth2
+from social_core.exceptions import AuthFailed, NotAllowedToDisconnect, WrongBackend
 
 
-from misago.core import errorpages
-from misago.core.decorators import require_POST
-from misago.core.exceptions import Banned, SocialAuthBanned, SocialAuthFailed
-from misago.core.shortcuts import paginate, paginated_response, validate_slug
-from misago.core.views import home_redirect
-from misago.users.models import Ban
-
+from .. import errorpages
+from ...users.models import Ban
+from ..decorators import require_POST
+from ..exceptions import Banned, SocialAuthBanned, SocialAuthFailed
+from ..shortcuts import paginate, paginated_response, validate_slug
+from ..views import home_redirect
 from .models import Model
 from .models import Model
 from .serializers import MockSerializer
 from .serializers import MockSerializer
 
 

+ 1 - 1
misago/core/tests/test_apipatch.py

@@ -2,7 +2,7 @@ from django.core.exceptions import PermissionDenied
 from django.http import Http404
 from django.http import Http404
 from django.test import TestCase
 from django.test import TestCase
 
 
-from misago.core.apipatch import ApiPatch, InvalidAction
+from ..apipatch import ApiPatch, InvalidAction
 
 
 
 
 class MockRequest(object):
 class MockRequest(object):

+ 1 - 2
misago/core/tests/test_checks.py

@@ -2,8 +2,7 @@ import warnings
 
 
 from django.test import TestCase
 from django.test import TestCase
 
 
-from misago.core import SUPPORTED_ENGINES, check_db_engine
-
+from .. import SUPPORTED_ENGINES, check_db_engine
 
 
 INVALID_ENGINES = [
 INVALID_ENGINES = [
     "django.db.backends.sqlite3",
     "django.db.backends.sqlite3",

+ 2 - 2
misago/core/tests/test_chunk_queryset.py

@@ -1,7 +1,7 @@
 from django.test import TestCase
 from django.test import TestCase
 
 
-from misago.core.models import CacheVersion
-from misago.core.pgutils import chunk_queryset
+from ..models import CacheVersion
+from ..pgutils import chunk_queryset
 
 
 
 
 class ChunkQuerysetTest(TestCase):
 class ChunkQuerysetTest(TestCase):

+ 1 - 1
misago/core/tests/test_common_middleware_redirect.py

@@ -1,4 +1,4 @@
-from misago.users.test import AuthenticatedUserTestCase
+from ...users.test import AuthenticatedUserTestCase
 
 
 
 
 class CommonMiddlewareRedirectTests(AuthenticatedUserTestCase):
 class CommonMiddlewareRedirectTests(AuthenticatedUserTestCase):

+ 1 - 1
misago/core/tests/test_context_processors.py

@@ -1,7 +1,7 @@
 from django.test import TestCase
 from django.test import TestCase
 from django.utils import translation
 from django.utils import translation
 
 
-from misago.core import context_processors
+from .. import context_processors
 
 
 
 
 class MockRequest(object):
 class MockRequest(object):

+ 1 - 1
misago/core/tests/test_deprecations.py

@@ -2,7 +2,7 @@ import warnings
 
 
 from django.test import TestCase
 from django.test import TestCase
 
 
-from misago.core.deprecations import RemovedInMisagoWarning, warn
+from ..deprecations import RemovedInMisagoWarning, warn
 
 
 
 
 class DeprecationsTests(TestCase):
 class DeprecationsTests(TestCase):

+ 6 - 9
misago/core/tests/test_errorpages.py

@@ -4,15 +4,12 @@ from django.test import Client, TestCase, override_settings
 from django.test.client import RequestFactory
 from django.test.client import RequestFactory
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.acl.useracl import get_user_acl
-from misago.users.models import AnonymousUser
-from misago.conf.dynamicsettings import DynamicSettings
-from misago.conftest import get_cache_versions
-from misago.core.testproject.views import (
-    mock_custom_403_error_page,
-    mock_custom_404_error_page,
-)
-from misago.core.utils import encode_json_html
+from ...acl.useracl import get_user_acl
+from ...conf.dynamicsettings import DynamicSettings
+from ...conftest import get_cache_versions
+from ...users.models import AnonymousUser
+from ..testproject.views import mock_custom_403_error_page, mock_custom_404_error_page
+from ..utils import encode_json_html
 
 
 
 
 class CSRFErrorViewTests(TestCase):
 class CSRFErrorViewTests(TestCase):

+ 5 - 7
misago/core/tests/test_exceptionhandler_middleware.py

@@ -3,13 +3,11 @@ from django.test import TestCase
 from django.test.client import RequestFactory
 from django.test.client import RequestFactory
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.acl.useracl import get_user_acl
-from misago.conf.dynamicsettings import DynamicSettings
-from misago.core.middleware import ExceptionHandlerMiddleware
-from misago.conftest import get_cache_versions
-from misago.users.models import AnonymousUser
-
-from misago.core.middleware import ExceptionHandlerMiddleware
+from ...acl.useracl import get_user_acl
+from ...conf.dynamicsettings import DynamicSettings
+from ...conftest import get_cache_versions
+from ...users.models import AnonymousUser
+from ..middleware import ExceptionHandlerMiddleware
 
 
 
 
 def create_request():
 def create_request():

+ 3 - 4
misago/core/tests/test_exceptionhandlers.py

@@ -3,10 +3,9 @@ from django.core.exceptions import PermissionDenied
 from django.http import Http404
 from django.http import Http404
 from django.test import TestCase
 from django.test import TestCase
 
 
-from misago.core import exceptionhandler
-from misago.core.exceptions import Banned
-from misago.users.models import Ban
-
+from .. import exceptionhandler
+from ...users.models import Ban
+from ..exceptions import Banned
 
 
 INVALID_EXCEPTIONS = [
 INVALID_EXCEPTIONS = [
     django_exceptions.ObjectDoesNotExist,
     django_exceptions.ObjectDoesNotExist,

+ 1 - 1
misago/core/tests/test_frontendcontext_middleware.py

@@ -1,6 +1,6 @@
 from django.test import TestCase
 from django.test import TestCase
 
 
-from misago.core.middleware import FrontendContextMiddleware
+from ..middleware import FrontendContextMiddleware
 
 
 
 
 class MockRequest(object):
 class MockRequest(object):

+ 0 - 1
misago/core/tests/test_jsi18n.py

@@ -5,7 +5,6 @@ from django.test import TestCase
 from django.urls import reverse
 from django.urls import reverse
 from django.utils import translation
 from django.utils import translation
 
 
-
 MISAGO_DIR = os.path.dirname(
 MISAGO_DIR = os.path.dirname(
     os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
     os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
 )
 )

+ 4 - 4
misago/core/tests/test_mail.py

@@ -2,10 +2,10 @@ from django.core import mail
 from django.test import TestCase
 from django.test import TestCase
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.cache.versions import get_cache_versions
-from misago.conf.dynamicsettings import DynamicSettings
-from misago.core.mail import build_mail, mail_user, mail_users
-from misago.users.test import create_test_user
+from ...cache.versions import get_cache_versions
+from ...conf.dynamicsettings import DynamicSettings
+from ...users.test import create_test_user
+from ..mail import build_mail, mail_user, mail_users
 
 
 
 
 class MailTests(TestCase):
 class MailTests(TestCase):

+ 1 - 1
misago/core/tests/test_momentjs.py

@@ -1,6 +1,6 @@
 from django.test import TestCase
 from django.test import TestCase
 
 
-from misago.core.momentjs import clean_language_name, get_locale_url
+from ..momentjs import clean_language_name, get_locale_url
 
 
 
 
 class MomentJSTests(TestCase):
 class MomentJSTests(TestCase):

+ 1 - 1
misago/core/tests/test_page.py

@@ -1,6 +1,6 @@
 from django.test import TestCase
 from django.test import TestCase
 
 
-from misago.core.page import Page
+from ..page import Page
 
 
 
 
 class SiteTests(TestCase):
 class SiteTests(TestCase):

+ 2 - 3
misago/core/tests/test_pgpartialindex.py

@@ -1,9 +1,8 @@
 from django.db import connection
 from django.db import connection
 from django.test import TestCase
 from django.test import TestCase
 
 
-from misago.threads.models import Thread
-
-from misago.core.pgutils import PgPartialIndex
+from ...threads.models import Thread
+from ..pgutils import PgPartialIndex
 
 
 
 
 class PgPartialIndexTests(TestCase):
 class PgPartialIndexTests(TestCase):

+ 5 - 6
misago/core/tests/test_serializers.py

@@ -1,11 +1,10 @@
-from rest_framework import serializers
-
 from django.test import TestCase
 from django.test import TestCase
+from rest_framework import serializers
 
 
-from misago.categories.models import Category
-from misago.core.serializers import MutableFields
-from misago.threads import test
-from misago.threads.models import Thread
+from ...categories.models import Category
+from ...threads import test
+from ...threads.models import Thread
+from ..serializers import MutableFields
 
 
 
 
 class Serializer(serializers.ModelSerializer, MutableFields):
 class Serializer(serializers.ModelSerializer, MutableFields):

+ 1 - 1
misago/core/tests/test_setup.py

@@ -3,7 +3,7 @@ import os
 from django.test import TestCase
 from django.test import TestCase
 from django.utils.encoding import smart_str
 from django.utils.encoding import smart_str
 
 
-from misago.core import setup
+from .. import setup
 
 
 
 
 class MockParser(object):
 class MockParser(object):

+ 1 - 1
misago/core/tests/test_shortcuts.py

@@ -2,7 +2,7 @@ from django.http import Http404
 from django.test import TestCase, override_settings
 from django.test import TestCase, override_settings
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.core.shortcuts import get_int_or_404
+from ..shortcuts import get_int_or_404
 
 
 
 
 @override_settings(ROOT_URLCONF="misago.core.testproject.urls")
 @override_settings(ROOT_URLCONF="misago.core.testproject.urls")

+ 10 - 11
misago/core/tests/test_templatetags.py

@@ -1,9 +1,8 @@
 from django.template import Context, Template
 from django.template import Context, Template
 from django.test import TestCase, override_settings
 from django.test import TestCase, override_settings
 
 
-from misago.core.templatetags import misago_batch
-from misago.core.templatetags.misago_absoluteurl import absoluteurl
-
+from ..templatetags.misago_absoluteurl import absoluteurl
+from ..templatetags.misago_batch import batch, batchnonefilled
 
 
 TEST_ADDRESS = "https://testsite.com/"
 TEST_ADDRESS = "https://testsite.com/"
 
 
@@ -74,19 +73,19 @@ Hello, <b>{{ the_var|safe }}</b>
 class BatchTests(TestCase):
 class BatchTests(TestCase):
     def test_batch(self):
     def test_batch(self):
         """standard batch yields valid results"""
         """standard batch yields valid results"""
-        batch = "loremipsum"
-        yields = [["l", "o", "r"], ["e", "m", "i"], ["p", "s", "u"], ["m"]]
+        value = "loremipsum"
+        result = [["l", "o", "r"], ["e", "m", "i"], ["p", "s", "u"], ["m"]]
 
 
-        for i, test_yield in enumerate(misago_batch.batch(batch, 3)):
-            self.assertEqual(test_yield, yields[i])
+        for i, test_result in enumerate(batch(value, 3)):
+            self.assertEqual(test_result, result[i])
 
 
     def test_batchnonefilled(self):
     def test_batchnonefilled(self):
         """none-filled batch yields valid results"""
         """none-filled batch yields valid results"""
-        batch = "loremipsum"
-        yields = [["l", "o", "r"], ["e", "m", "i"], ["p", "s", "u"], ["m", None, None]]
+        value = "loremipsum"
+        result = [["l", "o", "r"], ["e", "m", "i"], ["p", "s", "u"], ["m", None, None]]
 
 
-        for i, test_yield in enumerate(misago_batch.batchnonefilled(batch, 3)):
-            self.assertEqual(test_yield, yields[i])
+        for i, test_result in enumerate(batchnonefilled(value, 3)):
+            self.assertEqual(test_result, result[i])
 
 
 
 
 class MockUser(object):
 class MockUser(object):

+ 4 - 4
misago/core/tests/test_utils.py

@@ -3,16 +3,16 @@ from django.test import TestCase
 from django.test.client import RequestFactory
 from django.test.client import RequestFactory
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.core.utils import (
+from ..utils import (
+    clean_ids_list,
     clean_return_path,
     clean_return_path,
     format_plaintext_for_html,
     format_plaintext_for_html,
+    get_exception_message,
+    get_host_from_address,
     is_referer_local,
     is_referer_local,
     is_request_to_misago,
     is_request_to_misago,
     parse_iso8601_string,
     parse_iso8601_string,
     slugify,
     slugify,
-    get_exception_message,
-    clean_ids_list,
-    get_host_from_address,
 )
 )
 
 
 
 

+ 1 - 1
misago/core/tests/test_validators.py

@@ -1,7 +1,7 @@
 from django.core.exceptions import ValidationError
 from django.core.exceptions import ValidationError
 from django.test import TestCase
 from django.test import TestCase
 
 
-from misago.core.validators import validate_sluggable
+from ..validators import validate_sluggable
 
 
 
 
 class ValidateSluggableTests(TestCase):
 class ValidateSluggableTests(TestCase):

+ 0 - 1
misago/core/utils.py

@@ -8,7 +8,6 @@ from django.utils import html, timezone
 from django.utils.encoding import force_text
 from django.utils.encoding import force_text
 from django.utils.module_loading import import_string
 from django.utils.module_loading import import_string
 
 
-
 MISAGO_SLUGIFY = getattr(settings, "MISAGO_SLUGIFY", "misago.core.slugify.default")
 MISAGO_SLUGIFY = getattr(settings, "MISAGO_SLUGIFY", "misago.core.slugify.default")
 
 
 slugify = import_string(MISAGO_SLUGIFY)
 slugify = import_string(MISAGO_SLUGIFY)

+ 0 - 1
misago/faker/englishcorpus.py

@@ -1,7 +1,6 @@
 import os
 import os
 import random
 import random
 
 
-
 PHRASES_FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)), "phrases.txt")
 PHRASES_FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)), "phrases.txt")
 
 
 
 

+ 3 - 4
misago/faker/management/commands/createfakebans.py

@@ -2,13 +2,12 @@ import random
 import sys
 import sys
 from datetime import timedelta
 from datetime import timedelta
 
 
-from faker import Factory
-
 from django.core.management.base import BaseCommand
 from django.core.management.base import BaseCommand
 from django.utils import timezone
 from django.utils import timezone
+from faker import Factory
 
 
-from misago.core.management.progressbar import show_progress
-from misago.users.models import Ban
+from ....core.management.progressbar import show_progress
+from ....users.models import Ban
 
 
 
 
 def fake_username_ban(fake):
 def fake_username_ban(fake):

+ 4 - 5
misago/faker/management/commands/createfakecategories.py

@@ -1,13 +1,12 @@
 import random
 import random
 import time
 import time
 
 
-from faker import Factory
-
 from django.core.management.base import BaseCommand
 from django.core.management.base import BaseCommand
+from faker import Factory
 
 
-from misago.acl.cache import clear_acl_cache
-from misago.categories.models import Category, RoleCategoryACL
-from misago.core.management.progressbar import show_progress
+from ....acl.cache import clear_acl_cache
+from ....categories.models import Category, RoleCategoryACL
+from ....core.management.progressbar import show_progress
 
 
 
 
 class Command(BaseCommand):
 class Command(BaseCommand):

+ 1 - 2
misago/faker/management/commands/createfakefollowers.py

@@ -4,8 +4,7 @@ import time
 from django.contrib.auth import get_user_model
 from django.contrib.auth import get_user_model
 from django.core.management.base import BaseCommand
 from django.core.management.base import BaseCommand
 
 
-from misago.core.management.progressbar import show_progress
-
+from ....core.management.progressbar import show_progress
 
 
 User = get_user_model()
 User = get_user_model()
 
 

+ 6 - 8
misago/faker/management/commands/createfakethreads.py

@@ -1,19 +1,17 @@
 import random
 import random
 import time
 import time
 
 
-from faker import Factory
-
 from django.contrib.auth import get_user_model
 from django.contrib.auth import get_user_model
 from django.core.management.base import BaseCommand
 from django.core.management.base import BaseCommand
 from django.db.transaction import atomic
 from django.db.transaction import atomic
 from django.utils import timezone
 from django.utils import timezone
+from faker import Factory
 
 
-from misago.categories.models import Category
-from misago.core.management.progressbar import show_progress
-from misago.faker.englishcorpus import EnglishCorpus
-from misago.threads.checksums import update_post_checksum
-from misago.threads.models import Post, Thread
-
+from ....categories.models import Category
+from ....core.management.progressbar import show_progress
+from ....threads.checksums import update_post_checksum
+from ....threads.models import Post, Thread
+from ...englishcorpus import EnglishCorpus
 
 
 PLACEKITTEN_URL = "https://placekitten.com/g/%s/%s"
 PLACEKITTEN_URL = "https://placekitten.com/g/%s/%s"
 
 

+ 4 - 6
misago/faker/management/commands/createfakeusers.py

@@ -1,17 +1,15 @@
 import random
 import random
 import time
 import time
 
 
-from faker import Factory
-
 from django.contrib.auth import get_user_model
 from django.contrib.auth import get_user_model
 from django.core.exceptions import ValidationError
 from django.core.exceptions import ValidationError
 from django.core.management.base import BaseCommand
 from django.core.management.base import BaseCommand
 from django.db import IntegrityError
 from django.db import IntegrityError
+from faker import Factory
 
 
-from misago.core.management.progressbar import show_progress
-from misago.users.avatars import dynamic, gallery
-from misago.users.models import Rank
-
+from ....core.management.progressbar import show_progress
+from ....users.avatars import dynamic, gallery
+from ....users.models import Rank
 
 
 User = get_user_model()
 User = get_user_model()
 
 

+ 1 - 1
misago/faker/tests/test_englishcorpus.py

@@ -1,6 +1,6 @@
 from django.test import TestCase
 from django.test import TestCase
 
 
-from misago.faker.englishcorpus import EnglishCorpus
+from ..englishcorpus import EnglishCorpus
 
 
 
 
 class EnglishCorpusTests(TestCase):
 class EnglishCorpusTests(TestCase):

+ 0 - 1
misago/legal/api.py

@@ -2,7 +2,6 @@ from django.contrib.auth import logout
 from django.core.exceptions import PermissionDenied
 from django.core.exceptions import PermissionDenied
 from django.shortcuts import get_object_or_404
 from django.shortcuts import get_object_or_404
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
-
 from rest_framework.decorators import api_view
 from rest_framework.decorators import api_view
 from rest_framework.response import Response
 from rest_framework.response import Response
 
 

+ 0 - 1
misago/legal/context_processors.py

@@ -3,7 +3,6 @@ from django.urls import reverse
 from .models import Agreement
 from .models import Agreement
 from .utils import get_parsed_agreement_text, get_required_user_agreement
 from .utils import get_parsed_agreement_text, get_required_user_agreement
 
 
-
 # fixme: rename this context processor to more suitable name
 # fixme: rename this context processor to more suitable name
 def legal_links(request):
 def legal_links(request):
     agreements = Agreement.objects.get_agreements()
     agreements = Agreement.objects.get_agreements()

+ 1 - 2
misago/legal/migrations/0001_initial.py

@@ -1,7 +1,6 @@
 from django.db import migrations
 from django.db import migrations
 
 
-from misago.conf.migrationutils import migrate_settings_group
-
+from ...conf.migrationutils import migrate_settings_group
 
 
 _ = lambda s: s
 _ = lambda s: s
 
 

+ 2 - 2
misago/legal/migrations/0002_agreement_useragreement.py

@@ -1,8 +1,8 @@
 # Generated by Django 1.11.15 on 2018-08-15 20:58
 # Generated by Django 1.11.15 on 2018-08-15 20:58
-from django.conf import settings
-from django.db import migrations, models
 import django.db.models.deletion
 import django.db.models.deletion
 import django.utils.timezone
 import django.utils.timezone
+from django.conf import settings
+from django.db import migrations, models
 
 
 
 
 class Migration(migrations.Migration):
 class Migration(migrations.Migration):

+ 2 - 3
misago/legal/migrations/0003_create_agreements_from_settings.py

@@ -1,9 +1,8 @@
 # Generated by Django 1.11.15 on 2018-08-16 14:22
 # Generated by Django 1.11.15 on 2018-08-16 14:22
 from django.db import migrations
 from django.db import migrations
 
 
-from misago.conf.migrationutils import migrate_settings_group
-from misago.legal.models import Agreement as MisagoAgreement
-
+from ...conf.migrationutils import migrate_settings_group
+from ..models import Agreement as MisagoAgreement
 
 
 _ = lambda s: s
 _ = lambda s: s
 
 

+ 2 - 3
misago/legal/models.py

@@ -2,9 +2,8 @@ from django.db import models
 from django.utils import timezone
 from django.utils import timezone
 from django.utils.translation import gettext_lazy as _
 from django.utils.translation import gettext_lazy as _
 
 
-from misago.conf import settings
-from misago.core.cache import cache
-
+from ..conf import settings
+from ..core.cache import cache
 
 
 CACHE_KEY = "misago_agreements"
 CACHE_KEY = "misago_agreements"
 
 

+ 1 - 2
misago/legal/signals.py

@@ -1,7 +1,6 @@
 from django.dispatch import receiver
 from django.dispatch import receiver
 
 
-from misago.users.signals import anonymize_user_data, username_changed
-
+from ..users.signals import anonymize_user_data, username_changed
 from .models import Agreement
 from .models import Agreement
 
 
 
 

+ 2 - 2
misago/legal/tests/test_admin_views.py

@@ -1,7 +1,7 @@
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.admin.test import AdminTestCase
-from misago.legal.models import Agreement
+from ...admin.test import AdminTestCase
+from ..models import Agreement
 
 
 
 
 class AgreementAdminViewsTests(AdminTestCase):
 class AgreementAdminViewsTests(AdminTestCase):

+ 2 - 2
misago/legal/tests/test_api.py

@@ -2,8 +2,8 @@ import json
 
 
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.legal.models import Agreement
-from misago.users.test import AuthenticatedUserTestCase
+from ...users.test import AuthenticatedUserTestCase
+from ..models import Agreement
 
 
 
 
 class SubmitAgreementTests(AuthenticatedUserTestCase):
 class SubmitAgreementTests(AuthenticatedUserTestCase):

+ 3 - 3
misago/legal/tests/test_context_processors.py

@@ -1,8 +1,8 @@
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.legal.context_processors import legal_links
-from misago.legal.models import Agreement
-from misago.users.test import AuthenticatedUserTestCase
+from ...users.test import AuthenticatedUserTestCase
+from ..context_processors import legal_links
+from ..models import Agreement
 
 
 
 
 class MockRequest(object):
 class MockRequest(object):

+ 2 - 2
misago/legal/tests/test_required_agreement.py

@@ -1,7 +1,7 @@
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.legal.models import Agreement
-from misago.users.test import AuthenticatedUserTestCase
+from ...users.test import AuthenticatedUserTestCase
+from ..models import Agreement
 
 
 
 
 class RequiredAgreementTests(AuthenticatedUserTestCase):
 class RequiredAgreementTests(AuthenticatedUserTestCase):

+ 3 - 3
misago/legal/tests/test_utils.py

@@ -1,13 +1,13 @@
 from django.test import TestCase
 from django.test import TestCase
 
 
-from misago.legal.models import Agreement, UserAgreement
-from misago.legal.utils import (
+from ...users.test import UserTestCase
+from ..models import Agreement, UserAgreement
+from ..utils import (
     get_parsed_agreement_text,
     get_parsed_agreement_text,
     get_required_user_agreement,
     get_required_user_agreement,
     save_user_agreement_acceptance,
     save_user_agreement_acceptance,
     set_agreement_as_active,
     set_agreement_as_active,
 )
 )
-from misago.users.test import UserTestCase
 
 
 
 
 class MockRequest(object):
 class MockRequest(object):

+ 1 - 1
misago/legal/tests/test_views.py

@@ -1,7 +1,7 @@
 from django.test import TestCase
 from django.test import TestCase
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.legal.models import Agreement
+from ..models import Agreement
 
 
 
 
 class PrivacyPolicyTests(TestCase):
 class PrivacyPolicyTests(TestCase):

+ 1 - 2
misago/legal/urls/__init__.py

@@ -1,7 +1,6 @@
 from django.conf.urls import url
 from django.conf.urls import url
 
 
-from misago.legal.views import privacy_policy, terms_of_service
-
+from ..views import privacy_policy, terms_of_service
 
 
 urlpatterns = [
 urlpatterns = [
     url(r"^privacy-policy/$", privacy_policy, name="privacy-policy"),
     url(r"^privacy-policy/$", privacy_policy, name="privacy-policy"),

+ 1 - 2
misago/legal/urls/api.py

@@ -1,7 +1,6 @@
 from django.conf.urls import url
 from django.conf.urls import url
 
 
-from misago.legal.api import submit_agreement
-
+from ..api import submit_agreement
 
 
 urlpatterns = [
 urlpatterns = [
     url(r"^submit-agreement/(?P<pk>\d+)/$", submit_agreement, name="submit-agreement")
     url(r"^submit-agreement/(?P<pk>\d+)/$", submit_agreement, name="submit-agreement")

+ 2 - 3
misago/legal/utils.py

@@ -3,9 +3,8 @@ from hashlib import md5
 from django.conf import settings
 from django.conf import settings
 from django.utils.encoding import force_bytes
 from django.utils.encoding import force_bytes
 
 
-from misago.core.cache import cache
-from misago.markup import common_flavour
-
+from ..core.cache import cache
+from ..markup import common_flavour
 from .models import Agreement, UserAgreement
 from .models import Agreement, UserAgreement
 
 
 
 

+ 4 - 5
misago/legal/views/admin.py

@@ -2,11 +2,10 @@ from django.contrib import messages
 from django.utils import timezone
 from django.utils import timezone
 from django.utils.translation import gettext_lazy as _
 from django.utils.translation import gettext_lazy as _
 
 
-from misago.admin.views import generic
-
-from misago.legal.forms import AgreementForm, SearchAgreementsForm
-from misago.legal.models import Agreement
-from misago.legal.utils import set_agreement_as_active
+from ...admin.views import generic
+from ..forms import AgreementForm, SearchAgreementsForm
+from ..models import Agreement
+from ..utils import set_agreement_as_active
 
 
 
 
 class AgreementAdmin(generic.AdminBaseMixin):
 class AgreementAdmin(generic.AdminBaseMixin):

+ 2 - 2
misago/legal/views/legal.py

@@ -1,7 +1,7 @@
 from django.shortcuts import get_object_or_404, redirect, render
 from django.shortcuts import get_object_or_404, redirect, render
 
 
-from misago.legal.models import Agreement
-from misago.legal.utils import get_parsed_agreement_text
+from ..models import Agreement
+from ..utils import get_parsed_agreement_text
 
 
 
 
 def legal_view(request, agreement_type):
 def legal_view(request, agreement_type):

+ 1 - 3
misago/markup/bbcode/blocks.py

@@ -1,14 +1,12 @@
 import re
 import re
 
 
 import markdown
 import markdown
+from django.utils.crypto import get_random_string
 from markdown.blockprocessors import BlockProcessor, HRProcessor
 from markdown.blockprocessors import BlockProcessor, HRProcessor
 from markdown.extensions.fenced_code import FencedBlockPreprocessor
 from markdown.extensions.fenced_code import FencedBlockPreprocessor
 from markdown.preprocessors import Preprocessor
 from markdown.preprocessors import Preprocessor
 from markdown.util import etree
 from markdown.util import etree
 
 
-from django.utils.crypto import get_random_string
-
-
 QUOTE_START = get_random_string(32)
 QUOTE_START = get_random_string(32)
 QUOTE_END = get_random_string(32)
 QUOTE_END = get_random_string(32)
 
 

+ 0 - 1
misago/markup/finalise.py

@@ -2,7 +2,6 @@ import re
 
 
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
 
 
-
 HEADER_RE = re.compile(
 HEADER_RE = re.compile(
     r"""
     r"""
 <div class="quote-heading">(?P<title>.*?)</div>
 <div class="quote-heading">(?P<title>.*?)</div>

+ 0 - 1
misago/markup/md/shortimgs.py

@@ -2,7 +2,6 @@ import markdown
 from markdown.inlinepatterns import LinkPattern
 from markdown.inlinepatterns import LinkPattern
 from markdown.util import etree
 from markdown.util import etree
 
 
-
 IMAGES_RE = r"\!(\s?)\((<.*?>|([^\)]*))\)"
 IMAGES_RE = r"\!(\s?)\((<.*?>|([^\)]*))\)"
 
 
 
 

+ 0 - 1
misago/markup/md/striketrough.py

@@ -1,7 +1,6 @@
 import markdown
 import markdown
 from markdown.inlinepatterns import SimpleTagPattern
 from markdown.inlinepatterns import SimpleTagPattern
 
 
-
 STRIKETROUGH_RE = r"(~{2})(.+?)\2"
 STRIKETROUGH_RE = r"(~{2})(.+?)\2"
 
 
 
 

+ 0 - 2
misago/markup/mentions.py

@@ -1,10 +1,8 @@
 import re
 import re
 
 
 from bs4 import BeautifulSoup
 from bs4 import BeautifulSoup
-
 from django.contrib.auth import get_user_model
 from django.contrib.auth import get_user_model
 
 
-
 SUPPORTED_TAGS = ("h1", "h2", "h3", "h4", "h5", "h6", "div", "p")
 SUPPORTED_TAGS = ("h1", "h2", "h3", "h4", "h5", "h6", "div", "p")
 USERNAME_RE = re.compile(r"@[0-9a-z]+", re.IGNORECASE)
 USERNAME_RE = re.compile(r"@[0-9a-z]+", re.IGNORECASE)
 MENTIONS_LIMIT = 24
 MENTIONS_LIMIT = 24

+ 3 - 6
misago/markup/parser.py

@@ -3,21 +3,18 @@ import warnings
 import bleach
 import bleach
 import markdown
 import markdown
 from bs4 import BeautifulSoup
 from bs4 import BeautifulSoup
-from htmlmin.minify import html_minify
-from markdown.extensions.fenced_code import FencedCodeExtension
-
 from django.http import Http404
 from django.http import Http404
 from django.urls import resolve
 from django.urls import resolve
+from htmlmin.minify import html_minify
+from markdown.extensions.fenced_code import FencedCodeExtension
 
 
-from misago.conf import settings
-
+from ..conf import settings
 from .bbcode import blocks, inline
 from .bbcode import blocks, inline
 from .md.shortimgs import ShortImagesExtension
 from .md.shortimgs import ShortImagesExtension
 from .md.striketrough import StriketroughExtension
 from .md.striketrough import StriketroughExtension
 from .mentions import add_mentions
 from .mentions import add_mentions
 from .pipeline import pipeline
 from .pipeline import pipeline
 
 
-
 MISAGO_ATTACHMENT_VIEWS = ("misago:attachment", "misago:attachment-thumbnail")
 MISAGO_ATTACHMENT_VIEWS = ("misago:attachment", "misago:attachment-thumbnail")
 
 
 
 

+ 1 - 1
misago/markup/pipeline.py

@@ -2,7 +2,7 @@ from importlib import import_module
 
 
 from bs4 import BeautifulSoup
 from bs4 import BeautifulSoup
 
 
-from misago.conf import settings
+from ..conf import settings
 
 
 
 
 class MarkupPipeline(object):
 class MarkupPipeline(object):

+ 1 - 1
misago/markup/serializers.py

@@ -1,6 +1,6 @@
 from rest_framework import serializers
 from rest_framework import serializers
 
 
-from misago.threads.validators import validate_post_length
+from ..threads.validators import validate_post_length
 
 
 
 
 class MarkupSerializer(serializers.Serializer):
 class MarkupSerializer(serializers.Serializer):

+ 0 - 1
misago/markup/templatetags/misago_editor.py

@@ -2,7 +2,6 @@ from django import template
 from django.template import Context
 from django.template import Context
 from django.template.loader import get_template
 from django.template.loader import get_template
 
 
-
 register = template.Library()
 register = template.Library()
 
 
 
 

+ 1 - 1
misago/markup/tests/test_api.py

@@ -1,6 +1,6 @@
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.users.test import AuthenticatedUserTestCase
+from ...users.test import AuthenticatedUserTestCase
 
 
 
 
 class ParseMarkupApiTests(AuthenticatedUserTestCase):
 class ParseMarkupApiTests(AuthenticatedUserTestCase):

+ 1 - 1
misago/markup/tests/test_checksums.py

@@ -1,6 +1,6 @@
 from django.test import TestCase
 from django.test import TestCase
 
 
-from misago.markup import checksums
+from .. import checksums
 
 
 
 
 class ChecksumsTests(TestCase):
 class ChecksumsTests(TestCase):

+ 1 - 1
misago/markup/tests/test_finalise.py

@@ -1,6 +1,6 @@
 from django.test import TestCase
 from django.test import TestCase
 
 
-from misago.markup.finalise import finalise_markup
+from ..finalise import finalise_markup
 
 
 
 
 class QuoteTests(TestCase):
 class QuoteTests(TestCase):

+ 2 - 2
misago/markup/tests/test_mentions.py

@@ -1,5 +1,5 @@
-from misago.markup.mentions import add_mentions
-from misago.users.test import AuthenticatedUserTestCase
+from ...users.test import AuthenticatedUserTestCase
+from ..mentions import add_mentions
 
 
 
 
 class MockRequest(object):
 class MockRequest(object):

+ 2 - 2
misago/markup/tests/test_parser.py

@@ -1,7 +1,7 @@
 from django.test import TestCase
 from django.test import TestCase
 
 
-from misago.markup.parser import parse
-from misago.users.test import create_test_user
+from ...users.test import create_test_user
+from ..parser import parse
 
 
 
 
 class MockRequest(object):
 class MockRequest(object):

+ 0 - 1
misago/markup/urls.py

@@ -2,5 +2,4 @@ from django.conf.urls import url
 
 
 from .api import parse_markup
 from .api import parse_markup
 
 
-
 urlpatterns = [url(r"^parse-markup/$", parse_markup, name="parse-markup")]
 urlpatterns = [url(r"^parse-markup/$", parse_markup, name="parse-markup")]

+ 2 - 6
misago/readtracker/categoriestracker.py

@@ -1,9 +1,5 @@
-from misago.threads.models import Post, Thread
-from misago.threads.permissions import (
-    exclude_invisible_posts,
-    exclude_invisible_threads,
-)
-
+from ..threads.models import Post, Thread
+from ..threads.permissions import exclude_invisible_posts, exclude_invisible_threads
 from .dates import get_cutoff_date
 from .dates import get_cutoff_date
 
 
 
 

+ 1 - 1
misago/readtracker/dates.py

@@ -2,7 +2,7 @@ from datetime import timedelta
 
 
 from django.utils import timezone
 from django.utils import timezone
 
 
-from misago.conf import settings
+from ..conf import settings
 
 
 
 
 def get_cutoff_date(user=None):
 def get_cutoff_date(user=None):

+ 2 - 2
misago/readtracker/management/commands/clearreadtracker.py

@@ -1,7 +1,7 @@
 from django.core.management.base import BaseCommand
 from django.core.management.base import BaseCommand
 
 
-from misago.readtracker.dates import get_cutoff_date
-from misago.readtracker.models import PostRead
+from ...dates import get_cutoff_date
+from ...models import PostRead
 
 
 
 
 class Command(BaseCommand):
 class Command(BaseCommand):

+ 2 - 2
misago/readtracker/migrations/0002_postread.py

@@ -1,8 +1,8 @@
 # Generated by Django 1.11.5 on 2017-10-07 14:32
 # Generated by Django 1.11.5 on 2017-10-07 14:32
-from django.conf import settings
-from django.db import migrations, models
 import django.db.models.deletion
 import django.db.models.deletion
 import django.utils.timezone
 import django.utils.timezone
+from django.conf import settings
+from django.db import migrations, models
 
 
 
 
 class Migration(migrations.Migration):
 class Migration(migrations.Migration):

+ 2 - 3
misago/readtracker/migrations/0003_migrate_reads_to_posts.py

@@ -1,12 +1,11 @@
 # Generated by Django 1.11.5 on 2017-10-07 14:49
 # Generated by Django 1.11.5 on 2017-10-07 14:49
 from datetime import timedelta
 from datetime import timedelta
 
 
-from django.db import migrations
 from django.conf import settings
 from django.conf import settings
+from django.db import migrations
 from django.utils import timezone
 from django.utils import timezone
 
 
-from misago.conf import defaults
-
+from ...conf import defaults
 
 
 try:
 try:
     READS_CUTOFF = settings.MISAGO_READTRACKER_CUTOFF
     READS_CUTOFF = settings.MISAGO_READTRACKER_CUTOFF

+ 3 - 4
misago/readtracker/signals.py

@@ -1,9 +1,8 @@
 from django.dispatch import Signal, receiver
 from django.dispatch import Signal, receiver
 
 
-from misago.categories import PRIVATE_THREADS_ROOT_NAME
-from misago.categories.signals import delete_category_content, move_category_content
-from misago.threads.signals import merge_thread, move_thread, merge_post, move_post
-
+from ..categories import PRIVATE_THREADS_ROOT_NAME
+from ..categories.signals import delete_category_content, move_category_content
+from ..threads.signals import merge_post, merge_thread, move_post, move_thread
 
 
 thread_read = Signal(providing_args=["thread"])
 thread_read = Signal(providing_args=["thread"])
 
 

+ 8 - 8
misago/readtracker/tests/test_categoriestracker.py

@@ -3,14 +3,14 @@ from datetime import timedelta
 from django.test import TestCase
 from django.test import TestCase
 from django.utils import timezone
 from django.utils import timezone
 
 
-from misago.acl.useracl import get_user_acl
-from misago.categories.models import Category
-from misago.conf import settings
-from misago.conftest import get_cache_versions
-from misago.readtracker import poststracker, categoriestracker
-from misago.readtracker.models import PostRead
-from misago.threads import test
-from misago.users.test import create_test_user
+from .. import categoriestracker, poststracker
+from ...acl.useracl import get_user_acl
+from ...categories.models import Category
+from ...conf import settings
+from ...conftest import get_cache_versions
+from ...threads import test
+from ...users.test import create_test_user
+from ..models import PostRead
 
 
 cache_versions = get_cache_versions()
 cache_versions = get_cache_versions()
 
 

+ 6 - 6
misago/readtracker/tests/test_clearreadtracker.py

@@ -5,12 +5,12 @@ from django.core.management import call_command
 from django.test import TestCase
 from django.test import TestCase
 from django.utils import timezone
 from django.utils import timezone
 
 
-from misago.categories.models import Category
-from misago.conf import settings
-from misago.readtracker.management.commands import clearreadtracker
-from misago.readtracker.models import PostRead
-from misago.threads import test
-from misago.users.test import create_test_user
+from ...categories.models import Category
+from ...conf import settings
+from ...threads import test
+from ...users.test import create_test_user
+from ..management.commands import clearreadtracker
+from ..models import PostRead
 
 
 
 
 class ClearReadTrackerTests(TestCase):
 class ClearReadTrackerTests(TestCase):

+ 2 - 2
misago/readtracker/tests/test_dates.py

@@ -3,8 +3,8 @@ from datetime import timedelta
 from django.test import TestCase
 from django.test import TestCase
 from django.utils import timezone
 from django.utils import timezone
 
 
-from misago.conf import settings
-from misago.readtracker.dates import get_cutoff_date, is_date_tracked
+from ...conf import settings
+from ..dates import get_cutoff_date, is_date_tracked
 
 
 
 
 class MockUser(object):
 class MockUser(object):

+ 16 - 16
misago/readtracker/tests/test_poststracker.py

@@ -3,12 +3,12 @@ from datetime import timedelta
 from django.test import TestCase
 from django.test import TestCase
 from django.utils import timezone
 from django.utils import timezone
 
 
-from misago.categories.models import Category
-from misago.conf import settings
-from misago.readtracker import poststracker
-from misago.readtracker.models import PostRead
-from misago.threads import test
-from misago.users.test import create_test_user
+from ...categories.models import Category
+from ...conf import settings
+from ...threads import test
+from ...users.test import create_test_user
+from ..models import PostRead
+from ..poststracker import make_read_aware, save_read
 
 
 
 
 class AnonymousUser(object):
 class AnonymousUser(object):
@@ -24,16 +24,16 @@ class PostsTrackerTests(TestCase):
 
 
     def test_falsy_value(self):
     def test_falsy_value(self):
         """passing falsy value to readtracker causes no errors"""
         """passing falsy value to readtracker causes no errors"""
-        poststracker.make_read_aware(self.user, None)
-        poststracker.make_read_aware(self.user, False)
-        poststracker.make_read_aware(self.user, [])
+        make_read_aware(self.user, None)
+        make_read_aware(self.user, False)
+        make_read_aware(self.user, [])
 
 
     def test_anon_post_before_cutoff(self):
     def test_anon_post_before_cutoff(self):
         """non-tracked post is marked as read for anonymous users"""
         """non-tracked post is marked as read for anonymous users"""
         posted_on = timezone.now() - timedelta(days=settings.MISAGO_READTRACKER_CUTOFF)
         posted_on = timezone.now() - timedelta(days=settings.MISAGO_READTRACKER_CUTOFF)
         post = test.reply_thread(self.thread, posted_on=posted_on)
         post = test.reply_thread(self.thread, posted_on=posted_on)
 
 
-        poststracker.make_read_aware(AnonymousUser(), post)
+        make_read_aware(AnonymousUser(), post)
         self.assertTrue(post.is_read)
         self.assertTrue(post.is_read)
         self.assertFalse(post.is_new)
         self.assertFalse(post.is_new)
 
 
@@ -41,7 +41,7 @@ class PostsTrackerTests(TestCase):
         """tracked post is marked as read for anonymous users"""
         """tracked post is marked as read for anonymous users"""
         post = test.reply_thread(self.thread, posted_on=timezone.now())
         post = test.reply_thread(self.thread, posted_on=timezone.now())
 
 
-        poststracker.make_read_aware(AnonymousUser(), post)
+        make_read_aware(AnonymousUser(), post)
         self.assertTrue(post.is_read)
         self.assertTrue(post.is_read)
         self.assertFalse(post.is_new)
         self.assertFalse(post.is_new)
 
 
@@ -50,7 +50,7 @@ class PostsTrackerTests(TestCase):
         posted_on = timezone.now() - timedelta(days=settings.MISAGO_READTRACKER_CUTOFF)
         posted_on = timezone.now() - timedelta(days=settings.MISAGO_READTRACKER_CUTOFF)
         post = test.reply_thread(self.thread, posted_on=posted_on)
         post = test.reply_thread(self.thread, posted_on=posted_on)
 
 
-        poststracker.make_read_aware(self.user, post)
+        make_read_aware(self.user, post)
         self.assertTrue(post.is_read)
         self.assertTrue(post.is_read)
         self.assertFalse(post.is_new)
         self.assertFalse(post.is_new)
 
 
@@ -58,7 +58,7 @@ class PostsTrackerTests(TestCase):
         """tracked post is marked as unread for authenticated users"""
         """tracked post is marked as unread for authenticated users"""
         post = test.reply_thread(self.thread, posted_on=timezone.now())
         post = test.reply_thread(self.thread, posted_on=timezone.now())
 
 
-        poststracker.make_read_aware(self.user, post)
+        make_read_aware(self.user, post)
         self.assertFalse(post.is_read)
         self.assertFalse(post.is_read)
         self.assertTrue(post.is_new)
         self.assertTrue(post.is_new)
 
 
@@ -67,7 +67,7 @@ class PostsTrackerTests(TestCase):
         posted_on = timezone.now() - timedelta(days=1)
         posted_on = timezone.now() - timedelta(days=1)
         post = test.reply_thread(self.thread, posted_on=posted_on)
         post = test.reply_thread(self.thread, posted_on=posted_on)
 
 
-        poststracker.make_read_aware(self.user, post)
+        make_read_aware(self.user, post)
         self.assertTrue(post.is_read)
         self.assertTrue(post.is_read)
         self.assertFalse(post.is_new)
         self.assertFalse(post.is_new)
 
 
@@ -75,8 +75,8 @@ class PostsTrackerTests(TestCase):
         """tracked post is marked as read for authenticated users with read entry"""
         """tracked post is marked as read for authenticated users with read entry"""
         post = test.reply_thread(self.thread, posted_on=timezone.now())
         post = test.reply_thread(self.thread, posted_on=timezone.now())
 
 
-        poststracker.save_read(self.user, post)
-        poststracker.make_read_aware(self.user, post)
+        save_read(self.user, post)
+        make_read_aware(self.user, post)
 
 
         self.assertTrue(post.is_read)
         self.assertTrue(post.is_read)
         self.assertFalse(post.is_new)
         self.assertFalse(post.is_new)

+ 9 - 9
misago/readtracker/tests/test_threadstracker.py

@@ -3,15 +3,15 @@ from datetime import timedelta
 from django.test import TestCase
 from django.test import TestCase
 from django.utils import timezone
 from django.utils import timezone
 
 
-from misago.acl.objectacl import add_acl_to_obj
-from misago.acl.useracl import get_user_acl
-from misago.categories.models import Category
-from misago.conf import settings
-from misago.conftest import get_cache_versions
-from misago.readtracker import poststracker, threadstracker
-from misago.readtracker.models import PostRead
-from misago.threads import test
-from misago.users.test import create_test_user
+from .. import poststracker, threadstracker
+from ...acl.objectacl import add_acl_to_obj
+from ...acl.useracl import get_user_acl
+from ...categories.models import Category
+from ...conf import settings
+from ...conftest import get_cache_versions
+from ...threads import test
+from ...users.test import create_test_user
+from ..models import PostRead
 
 
 cache_versions = get_cache_versions()
 cache_versions = get_cache_versions()
 
 

+ 2 - 3
misago/readtracker/threadstracker.py

@@ -1,6 +1,5 @@
-from misago.threads.models import Post
-from misago.threads.permissions import exclude_invisible_posts
-
+from ..threads.models import Post
+from ..threads.permissions import exclude_invisible_posts
 from .dates import get_cutoff_date
 from .dates import get_cutoff_date
 
 
 
 

+ 3 - 5
misago/search/api.py

@@ -1,14 +1,12 @@
 from time import time
 from time import time
 
 
-from rest_framework.decorators import api_view
-from rest_framework.response import Response
-
 from django.core.exceptions import PermissionDenied
 from django.core.exceptions import PermissionDenied
 from django.urls import reverse
 from django.urls import reverse
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
+from rest_framework.decorators import api_view
+from rest_framework.response import Response
 
 
-from misago.core.shortcuts import get_int_or_404
-
+from ..core.shortcuts import get_int_or_404
 from .searchproviders import searchproviders
 from .searchproviders import searchproviders
 
 
 
 

+ 3 - 3
misago/search/permissions.py

@@ -1,9 +1,9 @@
 from django import forms
 from django import forms
 from django.utils.translation import gettext_lazy as _
 from django.utils.translation import gettext_lazy as _
 
 
-from misago.acl import algebra
-from misago.acl.models import Role
-from misago.admin.forms import YesNoSwitch
+from ..acl import algebra
+from ..acl.models import Role
+from ..admin.forms import YesNoSwitch
 
 
 
 
 class PermissionsForm(forms.Form):
 class PermissionsForm(forms.Form):

+ 1 - 1
misago/search/searchproviders.py

@@ -1,7 +1,7 @@
 from django.core.exceptions import PermissionDenied
 from django.core.exceptions import PermissionDenied
 from django.utils.module_loading import import_string
 from django.utils.module_loading import import_string
 
 
-from misago.conf import settings
+from ..conf import settings
 
 
 
 
 class SearchProviders(object):
 class SearchProviders(object):

+ 3 - 3
misago/search/tests/test_api.py

@@ -1,8 +1,8 @@
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.acl.test import patch_user_acl
-from misago.search.searchproviders import searchproviders
-from misago.users.test import AuthenticatedUserTestCase
+from ...acl.test import patch_user_acl
+from ...users.test import AuthenticatedUserTestCase
+from ..searchproviders import searchproviders
 
 
 
 
 class SearchApiTests(AuthenticatedUserTestCase):
 class SearchApiTests(AuthenticatedUserTestCase):

+ 3 - 3
misago/search/tests/test_searchproviders.py

@@ -1,9 +1,9 @@
 from django.core.exceptions import PermissionDenied
 from django.core.exceptions import PermissionDenied
 from django.test import TestCase
 from django.test import TestCase
 
 
-from misago.conf import settings
-from misago.search.searchprovider import SearchProvider
-from misago.search.searchproviders import SearchProviders
+from ...conf import settings
+from ..searchprovider import SearchProvider
+from ..searchproviders import SearchProviders
 
 
 
 
 class MockProvider(SearchProvider):
 class MockProvider(SearchProvider):

+ 3 - 3
misago/search/tests/test_views.py

@@ -1,8 +1,8 @@
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.acl.test import patch_user_acl
-from misago.threads.search import SearchThreads
-from misago.users.test import AuthenticatedUserTestCase
+from ...acl.test import patch_user_acl
+from ...threads.search import SearchThreads
+from ...users.test import AuthenticatedUserTestCase
 
 
 
 
 class LandingTests(AuthenticatedUserTestCase):
 class LandingTests(AuthenticatedUserTestCase):

+ 1 - 1
misago/search/urls/__init__.py

@@ -1,6 +1,6 @@
 from django.conf.urls import url
 from django.conf.urls import url
 
 
-from misago.search.views import landing, search
+from ..views import landing, search
 
 
 urlpatterns = [
 urlpatterns = [
     url(r"^search/$", landing, name="search"),
     url(r"^search/$", landing, name="search"),

+ 1 - 2
misago/search/urls/api.py

@@ -1,7 +1,6 @@
 from django.conf.urls import url
 from django.conf.urls import url
 
 
-from misago.search import api
-
+from .. import api
 
 
 urlpatterns = [
 urlpatterns = [
     url(r"^search/$", api.search, name="search"),
     url(r"^search/$", api.search, name="search"),

+ 0 - 1
misago/threads/anonymize.py

@@ -1,6 +1,5 @@
 from django.urls import reverse
 from django.urls import reverse
 
 
-
 ANONYMIZABLE_EVENTS = (
 ANONYMIZABLE_EVENTS = (
     "added_participant",
     "added_participant",
     "changed_owner",
     "changed_owner",

+ 6 - 8
misago/threads/api/attachments.py

@@ -1,15 +1,13 @@
-from rest_framework import viewsets
-from rest_framework.response import Response
-
 from django.core.exceptions import PermissionDenied, ValidationError
 from django.core.exceptions import PermissionDenied, ValidationError
 from django.template.defaultfilters import filesizeformat
 from django.template.defaultfilters import filesizeformat
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
+from rest_framework import viewsets
+from rest_framework.response import Response
 
 
-from misago.acl.objectacl import add_acl_to_obj
-from misago.threads.models import Attachment, AttachmentType
-from misago.threads.serializers import AttachmentSerializer
-from misago.users.audittrail import create_audit_trail
-
+from ...acl.objectacl import add_acl_to_obj
+from ...users.audittrail import create_audit_trail
+from ..models import Attachment, AttachmentType
+from ..serializers import AttachmentSerializer
 
 
 IMAGE_EXTENSIONS = ("jpg", "jpeg", "png", "gif")
 IMAGE_EXTENSIONS = ("jpg", "jpeg", "png", "gif")
 
 

+ 3 - 3
misago/threads/api/pollvotecreateendpoint.py

@@ -2,9 +2,9 @@ from copy import deepcopy
 
 
 from rest_framework.response import Response
 from rest_framework.response import Response
 
 
-from misago.acl.objectacl import add_acl_to_obj
-from misago.threads.permissions import allow_vote_poll
-from misago.threads.serializers import PollSerializer, NewVoteSerializer
+from ...acl.objectacl import add_acl_to_obj
+from ..permissions import allow_vote_poll
+from ..serializers import NewVoteSerializer, PollSerializer
 
 
 
 
 def poll_vote_create(request, thread, poll):
 def poll_vote_create(request, thread, poll):

+ 7 - 9
misago/threads/api/postendpoints/delete.py

@@ -1,20 +1,18 @@
-from rest_framework.response import Response
-
 from django.core.exceptions import PermissionDenied
 from django.core.exceptions import PermissionDenied
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
 from django.utils.translation import ngettext
 from django.utils.translation import ngettext
+from rest_framework.response import Response
 
 
-from misago.conf import settings
-from misago.core.utils import clean_ids_list
-from misago.threads.moderation import posts as moderation
-from misago.threads.permissions import (
+from ....conf import settings
+from ....core.utils import clean_ids_list
+from ...moderation import posts as moderation
+from ...permissions import (
     allow_delete_best_answer,
     allow_delete_best_answer,
     allow_delete_event,
     allow_delete_event,
     allow_delete_post,
     allow_delete_post,
+    exclude_invisible_posts,
 )
 )
-from misago.threads.permissions import exclude_invisible_posts
-from misago.threads.serializers import DeletePostsSerializer
-
+from ...serializers import DeletePostsSerializer
 
 
 DELETE_LIMIT = settings.MISAGO_POSTS_PER_PAGE + settings.MISAGO_POSTS_TAIL
 DELETE_LIMIT = settings.MISAGO_POSTS_PER_PAGE + settings.MISAGO_POSTS_TAIL
 
 

+ 7 - 8
misago/threads/api/postendpoints/edits.py

@@ -1,17 +1,16 @@
-from rest_framework.response import Response
-
 from django.core.exceptions import PermissionDenied
 from django.core.exceptions import PermissionDenied
 from django.db.models import F
 from django.db.models import F
 from django.shortcuts import get_object_or_404
 from django.shortcuts import get_object_or_404
 from django.utils import timezone
 from django.utils import timezone
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
+from rest_framework.response import Response
 
 
-from misago.acl.objectacl import add_acl_to_obj
-from misago.core.shortcuts import get_int_or_404
-from misago.markup import common_flavour
-from misago.threads.checksums import update_post_checksum
-from misago.threads.serializers import PostEditSerializer, PostSerializer
-from misago.users.online.utils import make_users_status_aware
+from ....acl.objectacl import add_acl_to_obj
+from ....core.shortcuts import get_int_or_404
+from ....markup import common_flavour
+from ....users.online.utils import make_users_status_aware
+from ...checksums import update_post_checksum
+from ...serializers import PostEditSerializer, PostSerializer
 
 
 
 
 def get_edit_endpoint(request, post):
 def get_edit_endpoint(request, post):

+ 1 - 1
misago/threads/api/postendpoints/likes.py

@@ -1,6 +1,6 @@
 from rest_framework.response import Response
 from rest_framework.response import Response
 
 
-from misago.threads.serializers import PostLikeSerializer
+from ...serializers import PostLikeSerializer
 
 
 
 
 def likes_list_endpoint(request, post):
 def likes_list_endpoint(request, post):

+ 3 - 4
misago/threads/api/postendpoints/merge.py

@@ -1,10 +1,9 @@
-from rest_framework.response import Response
-
 from django.core.exceptions import PermissionDenied
 from django.core.exceptions import PermissionDenied
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
+from rest_framework.response import Response
 
 
-from misago.acl.objectacl import add_acl_to_obj
-from misago.threads.serializers import MergePostsSerializer, PostSerializer
+from ....acl.objectacl import add_acl_to_obj
+from ...serializers import MergePostsSerializer, PostSerializer
 
 
 
 
 def posts_merge_endpoint(request, thread):
 def posts_merge_endpoint(request, thread):

+ 2 - 3
misago/threads/api/postendpoints/move.py

@@ -1,9 +1,8 @@
-from rest_framework.response import Response
-
 from django.core.exceptions import PermissionDenied
 from django.core.exceptions import PermissionDenied
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
+from rest_framework.response import Response
 
 
-from misago.threads.serializers import MovePostsSerializer
+from ...serializers import MovePostsSerializer
 
 
 
 
 def posts_move_endpoint(request, thread, viewmodel):
 def posts_move_endpoint(request, thread, viewmodel):

+ 4 - 5
misago/threads/api/postendpoints/patch_event.py

@@ -1,11 +1,10 @@
 from django.core.exceptions import PermissionDenied
 from django.core.exceptions import PermissionDenied
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
 
 
-from misago.acl.objectacl import add_acl_to_obj
-from misago.core.apipatch import ApiPatch
-from misago.threads.moderation import posts as moderation
-from misago.threads.permissions import allow_hide_event, allow_unhide_event
-
+from ....acl.objectacl import add_acl_to_obj
+from ....core.apipatch import ApiPatch
+from ...moderation import posts as moderation
+from ...permissions import allow_hide_event, allow_unhide_event
 
 
 event_patch_dispatcher = ApiPatch()
 event_patch_dispatcher = ApiPatch()
 
 

+ 9 - 11
misago/threads/api/postendpoints/patch_post.py

@@ -1,23 +1,21 @@
-from rest_framework import serializers
-from rest_framework.response import Response
-
 from django.core.exceptions import PermissionDenied
 from django.core.exceptions import PermissionDenied
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
+from rest_framework import serializers
+from rest_framework.response import Response
 
 
-from misago.acl.objectacl import add_acl_to_obj
-from misago.conf import settings
-from misago.core.apipatch import ApiPatch
-from misago.threads.models import PostLike
-from misago.threads.moderation import posts as moderation
-from misago.threads.permissions import (
+from ....acl.objectacl import add_acl_to_obj
+from ....conf import settings
+from ....core.apipatch import ApiPatch
+from ...models import PostLike
+from ...moderation import posts as moderation
+from ...permissions import (
     allow_approve_post,
     allow_approve_post,
     allow_hide_best_answer,
     allow_hide_best_answer,
     allow_hide_post,
     allow_hide_post,
     allow_protect_post,
     allow_protect_post,
     allow_unhide_post,
     allow_unhide_post,
+    exclude_invisible_posts,
 )
 )
-from misago.threads.permissions import exclude_invisible_posts
-
 
 
 PATCH_LIMIT = settings.MISAGO_POSTS_PER_PAGE + settings.MISAGO_POSTS_TAIL
 PATCH_LIMIT = settings.MISAGO_POSTS_PER_PAGE + settings.MISAGO_POSTS_TAIL
 
 

+ 2 - 2
misago/threads/api/postendpoints/read.py

@@ -1,7 +1,7 @@
 from rest_framework.response import Response
 from rest_framework.response import Response
 
 
-from misago.readtracker import poststracker, threadstracker
-from misago.readtracker.signals import thread_read
+from ....readtracker import poststracker, threadstracker
+from ....readtracker.signals import thread_read
 
 
 
 
 def post_read_endpoint(request, thread, post):
 def post_read_endpoint(request, thread, post):

+ 4 - 5
misago/threads/api/postendpoints/split.py

@@ -1,11 +1,10 @@
-from rest_framework.response import Response
-
 from django.core.exceptions import PermissionDenied
 from django.core.exceptions import PermissionDenied
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
+from rest_framework.response import Response
 
 
-from misago.threads.models import Thread
-from misago.threads.moderation import threads as moderation
-from misago.threads.serializers import SplitPostsSerializer
+from ...models import Thread
+from ...moderation import threads as moderation
+from ...serializers import SplitPostsSerializer
 
 
 
 
 def posts_split_endpoint(request, thread):
 def posts_split_endpoint(request, thread):

+ 1 - 1
misago/threads/api/postingendpoint/__init__.py

@@ -5,7 +5,7 @@ from django.http import QueryDict
 from django.utils import timezone
 from django.utils import timezone
 from django.utils.module_loading import import_string
 from django.utils.module_loading import import_string
 
 
-from misago.conf import settings
+from ....conf import settings
 
 
 
 
 class PostingInterrupt(Exception):
 class PostingInterrupt(Exception):

+ 4 - 6
misago/threads/api/postingendpoint/attachments.py

@@ -1,13 +1,11 @@
-from rest_framework import serializers
-
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
 from django.utils.translation import ngettext
 from django.utils.translation import ngettext
-
-from misago.acl.objectacl import add_acl_to_obj
-from misago.conf import settings
-from misago.threads.serializers import AttachmentSerializer
+from rest_framework import serializers
 
 
 from . import PostingEndpoint, PostingMiddleware
 from . import PostingEndpoint, PostingMiddleware
+from ....acl.objectacl import add_acl_to_obj
+from ....conf import settings
+from ...serializers import AttachmentSerializer
 
 
 
 
 class AttachmentsMiddleware(PostingMiddleware):
 class AttachmentsMiddleware(PostingMiddleware):

+ 7 - 9
misago/threads/api/postingendpoint/category.py

@@ -1,17 +1,15 @@
-from rest_framework import serializers
-
 from django.core.exceptions import PermissionDenied
 from django.core.exceptions import PermissionDenied
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext_lazy
 from django.utils.translation import gettext_lazy
-
-from misago.acl.objectacl import add_acl_to_obj
-from misago.categories import THREADS_ROOT_NAME
-from misago.categories.models import Category
-from misago.categories.permissions import can_browse_category, can_see_category
-from misago.threads.permissions import allow_start_thread
-from misago.threads.threadtypes import trees_map
+from rest_framework import serializers
 
 
 from . import PostingEndpoint, PostingMiddleware
 from . import PostingEndpoint, PostingMiddleware
+from ....acl.objectacl import add_acl_to_obj
+from ....categories import THREADS_ROOT_NAME
+from ....categories.models import Category
+from ....categories.permissions import can_browse_category, can_see_category
+from ...permissions import allow_start_thread
+from ...threadtypes import trees_map
 
 
 
 
 class CategoryMiddleware(PostingMiddleware):
 class CategoryMiddleware(PostingMiddleware):

+ 1 - 2
misago/threads/api/postingendpoint/close.py

@@ -1,8 +1,7 @@
 from rest_framework import serializers
 from rest_framework import serializers
 
 
-from misago.threads import moderation
-
 from . import PostingEndpoint, PostingMiddleware
 from . import PostingEndpoint, PostingMiddleware
+from ... import moderation
 
 
 
 
 class CloseMiddleware(PostingMiddleware):
 class CloseMiddleware(PostingMiddleware):

+ 3 - 4
misago/threads/api/postingendpoint/emailnotification.py

@@ -1,10 +1,9 @@
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
 
 
-from misago.acl import useracl
-from misago.core.mail import build_mail, send_messages
-from misago.threads.permissions import can_see_post, can_see_thread
-
 from . import PostingEndpoint, PostingMiddleware
 from . import PostingEndpoint, PostingMiddleware
+from ....acl import useracl
+from ....core.mail import build_mail, send_messages
+from ...permissions import can_see_post, can_see_thread
 
 
 
 
 class EmailNotificationMiddleware(PostingMiddleware):
 class EmailNotificationMiddleware(PostingMiddleware):

+ 1 - 3
misago/threads/api/postingendpoint/floodprotection.py

@@ -3,10 +3,8 @@ from datetime import timedelta
 from django.utils import timezone
 from django.utils import timezone
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
 
 
-from misago.conf import settings
-
 from . import PostingEndpoint, PostingInterrupt, PostingMiddleware
 from . import PostingEndpoint, PostingInterrupt, PostingMiddleware
-
+from ....conf import settings
 
 
 MIN_POSTING_PAUSE = 3
 MIN_POSTING_PAUSE = 3
 
 

+ 1 - 2
misago/threads/api/postingendpoint/hide.py

@@ -1,8 +1,7 @@
 from rest_framework import serializers
 from rest_framework import serializers
 
 
-from misago.threads import moderation
-
 from . import PostingEndpoint, PostingMiddleware
 from . import PostingEndpoint, PostingMiddleware
+from ... import moderation
 
 
 
 
 class HideMiddleware(PostingMiddleware):
 class HideMiddleware(PostingMiddleware):

+ 1 - 2
misago/threads/api/postingendpoint/moderationqueue.py

@@ -1,6 +1,5 @@
-from misago.categories import PRIVATE_THREADS_ROOT_NAME
-
 from . import PostingEndpoint, PostingMiddleware
 from . import PostingEndpoint, PostingMiddleware
+from ....categories import PRIVATE_THREADS_ROOT_NAME
 
 
 
 
 class ModerationQueueMiddleware(PostingMiddleware):
 class ModerationQueueMiddleware(PostingMiddleware):

+ 7 - 9
misago/threads/api/postingendpoint/participants.py

@@ -1,16 +1,14 @@
-from rest_framework import serializers
-
 from django.contrib.auth import get_user_model
 from django.contrib.auth import get_user_model
 from django.core.exceptions import PermissionDenied
 from django.core.exceptions import PermissionDenied
-from django.utils.translation import gettext as _, ngettext
-
-from misago.acl import useracl
-from misago.categories import PRIVATE_THREADS_ROOT_NAME
-from misago.threads.participants import add_participants, set_owner
-from misago.threads.permissions import allow_message_user
+from django.utils.translation import gettext as _
+from django.utils.translation import ngettext
+from rest_framework import serializers
 
 
 from . import PostingEndpoint, PostingMiddleware
 from . import PostingEndpoint, PostingMiddleware
-
+from ....acl import useracl
+from ....categories import PRIVATE_THREADS_ROOT_NAME
+from ...participants import add_participants, set_owner
+from ...permissions import allow_message_user
 
 
 User = get_user_model()
 User = get_user_model()
 
 

+ 2 - 3
misago/threads/api/postingendpoint/pin.py

@@ -1,9 +1,8 @@
 from rest_framework import serializers
 from rest_framework import serializers
 
 
-from misago.threads import moderation
-from misago.threads.models import Thread
-
 from . import PostingEndpoint, PostingMiddleware
 from . import PostingEndpoint, PostingMiddleware
+from ... import moderation
+from ...models import Thread
 
 
 
 
 class PinMiddleware(PostingMiddleware):
 class PinMiddleware(PostingMiddleware):

+ 3 - 4
misago/threads/api/postingendpoint/privatethread.py

@@ -1,8 +1,7 @@
-from misago.acl.objectacl import add_acl_to_obj
-from misago.categories import PRIVATE_THREADS_ROOT_NAME
-from misago.categories.models import Category
-
 from . import PostingEndpoint, PostingMiddleware
 from . import PostingEndpoint, PostingMiddleware
+from ....acl.objectacl import add_acl_to_obj
+from ....categories import PRIVATE_THREADS_ROOT_NAME
+from ....categories.models import Category
 
 
 
 
 class PrivateThreadMiddleware(PostingMiddleware):
 class PrivateThreadMiddleware(PostingMiddleware):

+ 5 - 11
misago/threads/api/postingendpoint/reply.py

@@ -1,17 +1,11 @@
-from rest_framework import serializers
-
 from django.utils.translation import gettext_lazy
 from django.utils.translation import gettext_lazy
-
-from misago.markup import common_flavour
-from misago.threads.checksums import update_post_checksum
-from misago.threads.validators import (
-    validate_post,
-    validate_post_length,
-    validate_thread_title,
-)
-from misago.users.audittrail import create_audit_trail
+from rest_framework import serializers
 
 
 from . import PostingEndpoint, PostingMiddleware
 from . import PostingEndpoint, PostingMiddleware
+from ....markup import common_flavour
+from ....users.audittrail import create_audit_trail
+from ...checksums import update_post_checksum
+from ...validators import validate_post, validate_post_length, validate_thread_title
 
 
 
 
 class ReplyMiddleware(PostingMiddleware):
 class ReplyMiddleware(PostingMiddleware):

+ 1 - 2
misago/threads/api/postingendpoint/savechanges.py

@@ -1,8 +1,7 @@
 from collections import OrderedDict
 from collections import OrderedDict
 
 
-from misago.categories.models import Category
-
 from . import PostingMiddleware
 from . import PostingMiddleware
+from ....categories.models import Category
 
 
 
 
 class SaveChangesMiddleware(PostingMiddleware):
 class SaveChangesMiddleware(PostingMiddleware):

+ 1 - 3
misago/threads/api/postingendpoint/subscribe.py

@@ -1,9 +1,7 @@
 from django.contrib.auth import get_user_model
 from django.contrib.auth import get_user_model
 
 
-from misago.threads.models import Subscription
-
 from . import PostingEndpoint, PostingMiddleware
 from . import PostingEndpoint, PostingMiddleware
-
+from ...models import Subscription
 
 
 User = get_user_model()
 User = get_user_model()
 
 

+ 2 - 3
misago/threads/api/postingendpoint/syncprivatethreads.py

@@ -1,7 +1,6 @@
-from misago.categories import PRIVATE_THREADS_ROOT_NAME
-from misago.threads.participants import set_users_unread_private_threads_sync
-
 from . import PostingEndpoint, PostingMiddleware
 from . import PostingEndpoint, PostingMiddleware
+from ....categories import PRIVATE_THREADS_ROOT_NAME
+from ...participants import set_users_unread_private_threads_sync
 
 
 
 
 class SyncPrivateThreadsMiddleware(PostingMiddleware):
 class SyncPrivateThreadsMiddleware(PostingMiddleware):

+ 1 - 2
misago/threads/api/postingendpoint/updatestats.py

@@ -1,8 +1,7 @@
 from django.db.models import F
 from django.db.models import F
 
 
-from misago.categories import THREADS_ROOT_NAME
-
 from . import PostingEndpoint, PostingMiddleware
 from . import PostingEndpoint, PostingMiddleware
+from ....categories import THREADS_ROOT_NAME
 
 
 
 
 class UpdateStatsMiddleware(PostingMiddleware):
 class UpdateStatsMiddleware(PostingMiddleware):

+ 4 - 5
misago/threads/api/threadendpoints/delete.py

@@ -1,10 +1,9 @@
-from rest_framework.response import Response
-
 from django.db import transaction
 from django.db import transaction
+from rest_framework.response import Response
 
 
-from misago.threads.moderation import threads as moderation
-from misago.threads.permissions import allow_delete_thread
-from misago.threads.serializers import DeleteThreadsSerializer
+from ...moderation import threads as moderation
+from ...permissions import allow_delete_thread
+from ...serializers import DeleteThreadsSerializer
 
 
 
 
 @transaction.atomic
 @transaction.atomic

+ 6 - 7
misago/threads/api/threadendpoints/editor.py

@@ -1,13 +1,12 @@
-from rest_framework.response import Response
-
 from django.core.exceptions import PermissionDenied
 from django.core.exceptions import PermissionDenied
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
+from rest_framework.response import Response
 
 
-from misago.acl.objectacl import add_acl_to_obj
-from misago.categories import THREADS_ROOT_NAME
-from misago.categories.models import Category
-from misago.threads.permissions import can_start_thread
-from misago.threads.threadtypes import trees_map
+from ....acl.objectacl import add_acl_to_obj
+from ....categories import THREADS_ROOT_NAME
+from ....categories.models import Category
+from ...permissions import can_start_thread
+from ...threadtypes import trees_map
 
 
 
 
 def thread_start_editor(request):
 def thread_start_editor(request):

+ 2 - 2
misago/threads/api/threadendpoints/list.py

@@ -1,7 +1,7 @@
 from rest_framework.response import Response
 from rest_framework.response import Response
 
 
-from misago.core.shortcuts import get_int_or_404
-from misago.threads.viewmodels import (
+from ....core.shortcuts import get_int_or_404
+from ...viewmodels import (
     ForumThreads,
     ForumThreads,
     PrivateThreads,
     PrivateThreads,
     PrivateThreadsCategory,
     PrivateThreadsCategory,

+ 9 - 10
misago/threads/api/threadendpoints/merge.py

@@ -1,16 +1,15 @@
-from rest_framework.exceptions import ValidationError
-from rest_framework.response import Response
-
 from django.core.exceptions import PermissionDenied
 from django.core.exceptions import PermissionDenied
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
+from rest_framework.exceptions import ValidationError
+from rest_framework.response import Response
 
 
-from misago.acl.objectacl import add_acl_to_obj
-from misago.threads.events import record_event
-from misago.threads.mergeconflict import MergeConflict
-from misago.threads.models import Thread
-from misago.threads.moderation import threads as moderation
-from misago.threads.permissions import allow_merge_thread
-from misago.threads.serializers import (
+from ....acl.objectacl import add_acl_to_obj
+from ...events import record_event
+from ...mergeconflict import MergeConflict
+from ...models import Thread
+from ...moderation import threads as moderation
+from ...permissions import allow_merge_thread
+from ...serializers import (
     MergeThreadSerializer,
     MergeThreadSerializer,
     MergeThreadsSerializer,
     MergeThreadsSerializer,
     ThreadsListSerializer,
     ThreadsListSerializer,

+ 16 - 17
misago/threads/api/threadendpoints/patch.py

@@ -1,47 +1,46 @@
-from rest_framework import serializers
-from rest_framework.response import Response
-
 from django.contrib.auth import get_user_model
 from django.contrib.auth import get_user_model
 from django.core.exceptions import PermissionDenied, ValidationError
 from django.core.exceptions import PermissionDenied, ValidationError
 from django.http import Http404
 from django.http import Http404
 from django.shortcuts import get_object_or_404
 from django.shortcuts import get_object_or_404
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
+from rest_framework import serializers
+from rest_framework.response import Response
 
 
-from misago.acl import useracl
-from misago.acl.objectacl import add_acl_to_obj
-from misago.categories.models import Category
-from misago.categories.permissions import allow_browse_category, allow_see_category
-from misago.categories.serializers import CategorySerializer
-from misago.conf import settings
-from misago.core.apipatch import ApiPatch
-from misago.core.shortcuts import get_int_or_404
-from misago.threads.moderation import threads as moderation
-from misago.threads.participants import (
+from ....acl import useracl
+from ....acl.objectacl import add_acl_to_obj
+from ....categories.models import Category
+from ....categories.permissions import allow_browse_category, allow_see_category
+from ....categories.serializers import CategorySerializer
+from ....conf import settings
+from ....core.apipatch import ApiPatch
+from ....core.shortcuts import get_int_or_404
+from ...moderation import threads as moderation
+from ...participants import (
     add_participant,
     add_participant,
     change_owner,
     change_owner,
     make_participants_aware,
     make_participants_aware,
     remove_participant,
     remove_participant,
 )
 )
-from misago.threads.permissions import (
+from ...permissions import (
     allow_add_participant,
     allow_add_participant,
     allow_add_participants,
     allow_add_participants,
     allow_approve_thread,
     allow_approve_thread,
     allow_change_best_answer,
     allow_change_best_answer,
     allow_change_owner,
     allow_change_owner,
     allow_edit_thread,
     allow_edit_thread,
-    allow_pin_thread,
     allow_hide_thread,
     allow_hide_thread,
     allow_mark_as_best_answer,
     allow_mark_as_best_answer,
     allow_mark_best_answer,
     allow_mark_best_answer,
     allow_move_thread,
     allow_move_thread,
+    allow_pin_thread,
     allow_remove_participant,
     allow_remove_participant,
     allow_see_post,
     allow_see_post,
     allow_start_thread,
     allow_start_thread,
     allow_unhide_thread,
     allow_unhide_thread,
     allow_unmark_best_answer,
     allow_unmark_best_answer,
 )
 )
-from misago.threads.serializers import ThreadParticipantSerializer
-from misago.threads.validators import validate_thread_title
+from ...serializers import ThreadParticipantSerializer
+from ...validators import validate_thread_title
 
 
 PATCH_LIMIT = settings.MISAGO_THREADS_PER_PAGE + settings.MISAGO_THREADS_TAIL
 PATCH_LIMIT = settings.MISAGO_THREADS_PER_PAGE + settings.MISAGO_THREADS_TAIL
 
 

+ 10 - 12
misago/threads/api/threadpoll.py

@@ -1,31 +1,29 @@
-from rest_framework import viewsets
-from rest_framework.decorators import detail_route
-from rest_framework.response import Response
-
 from django.core.exceptions import PermissionDenied
 from django.core.exceptions import PermissionDenied
 from django.db import transaction
 from django.db import transaction
 from django.http import Http404
 from django.http import Http404
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
+from rest_framework import viewsets
+from rest_framework.decorators import detail_route
+from rest_framework.response import Response
 
 
-from misago.acl.objectacl import add_acl_to_obj
-from misago.core.shortcuts import get_int_or_404
-from misago.threads.models import Poll
-from misago.threads.permissions import (
+from ...acl.objectacl import add_acl_to_obj
+from ...core.shortcuts import get_int_or_404
+from ...users.audittrail import create_audit_trail
+from ..models import Poll
+from ..permissions import (
     allow_delete_poll,
     allow_delete_poll,
     allow_edit_poll,
     allow_edit_poll,
     allow_see_poll_votes,
     allow_see_poll_votes,
     allow_start_poll,
     allow_start_poll,
     can_start_poll,
     can_start_poll,
 )
 )
-from misago.threads.serializers import (
+from ..serializers import (
     EditPollSerializer,
     EditPollSerializer,
     NewPollSerializer,
     NewPollSerializer,
     PollSerializer,
     PollSerializer,
     PollVoteSerializer,
     PollVoteSerializer,
 )
 )
-from misago.threads.viewmodels import ForumThread
-from misago.users.audittrail import create_audit_trail
-
+from ..viewmodels import ForumThread
 from .pollvotecreateendpoint import poll_vote_create
 from .pollvotecreateendpoint import poll_vote_create
 
 
 
 

+ 11 - 18
misago/threads/api/threadposts.py

@@ -1,31 +1,24 @@
-from rest_framework import viewsets
-from rest_framework.decorators import detail_route, list_route
-from rest_framework.response import Response
-
 from django.core.exceptions import PermissionDenied
 from django.core.exceptions import PermissionDenied
 from django.db import transaction
 from django.db import transaction
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
+from rest_framework import viewsets
+from rest_framework.decorators import detail_route, list_route
+from rest_framework.response import Response
 
 
-from misago.acl.objectacl import add_acl_to_obj
-from misago.core.shortcuts import get_int_or_404
-from misago.threads.models import Post
-from misago.threads.permissions import allow_edit_post, allow_reply_thread
-from misago.threads.serializers import AttachmentSerializer, PostSerializer
-from misago.threads.viewmodels import (
-    ForumThread,
-    PrivateThread,
-    ThreadPost,
-    ThreadPosts,
-)
-from misago.users.online.utils import make_users_status_aware
-
+from ...acl.objectacl import add_acl_to_obj
+from ...core.shortcuts import get_int_or_404
+from ...users.online.utils import make_users_status_aware
+from ..models import Post
+from ..permissions import allow_edit_post, allow_reply_thread
+from ..serializers import AttachmentSerializer, PostSerializer
+from ..viewmodels import ForumThread, PrivateThread, ThreadPost, ThreadPosts
 from .postendpoints.delete import delete_bulk, delete_post
 from .postendpoints.delete import delete_bulk, delete_post
 from .postendpoints.edits import get_edit_endpoint, revert_post_endpoint
 from .postendpoints.edits import get_edit_endpoint, revert_post_endpoint
 from .postendpoints.likes import likes_list_endpoint
 from .postendpoints.likes import likes_list_endpoint
 from .postendpoints.merge import posts_merge_endpoint
 from .postendpoints.merge import posts_merge_endpoint
 from .postendpoints.move import posts_move_endpoint
 from .postendpoints.move import posts_move_endpoint
 from .postendpoints.patch_event import event_patch_endpoint
 from .postendpoints.patch_event import event_patch_endpoint
-from .postendpoints.patch_post import post_patch_endpoint, bulk_patch_endpoint
+from .postendpoints.patch_post import bulk_patch_endpoint, post_patch_endpoint
 from .postendpoints.read import post_read_endpoint
 from .postendpoints.read import post_read_endpoint
 from .postendpoints.split import posts_split_endpoint
 from .postendpoints.split import posts_split_endpoint
 from .postingendpoint import PostingEndpoint
 from .postingendpoint import PostingEndpoint

+ 10 - 12
misago/threads/api/threads.py

@@ -1,23 +1,21 @@
-from rest_framework import viewsets
-from rest_framework.decorators import detail_route, list_route
-from rest_framework.response import Response
-
 from django.core.exceptions import PermissionDenied
 from django.core.exceptions import PermissionDenied
 from django.db import transaction
 from django.db import transaction
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
+from rest_framework import viewsets
+from rest_framework.decorators import detail_route, list_route
+from rest_framework.response import Response
 
 
-from misago.categories import PRIVATE_THREADS_ROOT_NAME, THREADS_ROOT_NAME
-from misago.core.shortcuts import get_int_or_404
-from misago.threads.models import Post, Thread
-from misago.threads.moderation import threads as moderation
-from misago.threads.permissions import allow_use_private_threads
-from misago.threads.viewmodels import (
+from ...categories import PRIVATE_THREADS_ROOT_NAME, THREADS_ROOT_NAME
+from ...core.shortcuts import get_int_or_404
+from ..models import Post, Thread
+from ..moderation import threads as moderation
+from ..permissions import allow_use_private_threads
+from ..viewmodels import (
     ForumThread,
     ForumThread,
     PrivateThread,
     PrivateThread,
-    ThreadsRootCategory,
     PrivateThreadsCategory,
     PrivateThreadsCategory,
+    ThreadsRootCategory,
 )
 )
-
 from .postingendpoint import PostingEndpoint
 from .postingendpoint import PostingEndpoint
 from .threadendpoints.delete import delete_bulk, delete_thread
 from .threadendpoints.delete import delete_bulk, delete_thread
 from .threadendpoints.editor import thread_start_editor
 from .threadendpoints.editor import thread_start_editor

+ 1 - 1
misago/threads/checksums.py

@@ -1,4 +1,4 @@
-from misago.markup import checksums
+from ..markup import checksums
 
 
 
 
 def is_post_valid(post):
 def is_post_valid(post):

+ 1 - 2
misago/threads/events.py

@@ -1,7 +1,6 @@
 from django.utils import timezone
 from django.utils import timezone
 
 
-from misago.readtracker import poststracker
-
+from ..readtracker import poststracker
 from .models import Post
 from .models import Post
 
 
 
 

+ 1 - 2
misago/threads/filtersearch.py

@@ -1,7 +1,6 @@
 from django.utils.module_loading import import_string
 from django.utils.module_loading import import_string
 
 
-from misago.conf import settings
-
+from ..conf import settings
 
 
 filters_list = settings.MISAGO_POST_SEARCH_FILTERS
 filters_list = settings.MISAGO_POST_SEARCH_FILTERS
 SEARCH_FILTERS = list(map(import_string, filters_list))
 SEARCH_FILTERS = list(map(import_string, filters_list))

+ 4 - 4
misago/threads/management/commands/clearattachments.py

@@ -4,10 +4,10 @@ from datetime import timedelta
 from django.core.management.base import BaseCommand
 from django.core.management.base import BaseCommand
 from django.utils import timezone
 from django.utils import timezone
 
 
-from misago.conf import settings
-from misago.core.management.progressbar import show_progress
-from misago.core.pgutils import chunk_queryset
-from misago.threads.models import Attachment
+from ....conf import settings
+from ....core.management.progressbar import show_progress
+from ....core.pgutils import chunk_queryset
+from ...models import Attachment
 
 
 
 
 class Command(BaseCommand):
 class Command(BaseCommand):

+ 3 - 3
misago/threads/management/commands/rebuildpostssearch.py

@@ -2,9 +2,9 @@ import time
 
 
 from django.core.management.base import BaseCommand
 from django.core.management.base import BaseCommand
 
 
-from misago.core.management.progressbar import show_progress
-from misago.core.pgutils import chunk_queryset
-from misago.threads.models import Post
+from ....core.management.progressbar import show_progress
+from ....core.pgutils import chunk_queryset
+from ...models import Post
 
 
 
 
 class Command(BaseCommand):
 class Command(BaseCommand):

+ 3 - 3
misago/threads/management/commands/synchronizethreads.py

@@ -2,9 +2,9 @@ import time
 
 
 from django.core.management.base import BaseCommand
 from django.core.management.base import BaseCommand
 
 
-from misago.core.management.progressbar import show_progress
-from misago.core.pgutils import chunk_queryset
-from misago.threads.models import Thread
+from ....core.management.progressbar import show_progress
+from ....core.pgutils import chunk_queryset
+from ...models import Thread
 
 
 
 
 class Command(BaseCommand):
 class Command(BaseCommand):

+ 4 - 4
misago/threads/management/commands/updatepostschecksums.py

@@ -2,10 +2,10 @@ import time
 
 
 from django.core.management.base import BaseCommand
 from django.core.management.base import BaseCommand
 
 
-from misago.core.management.progressbar import show_progress
-from misago.core.pgutils import chunk_queryset
-from misago.threads.checksums import update_post_checksum
-from misago.threads.models import Post
+from ....core.management.progressbar import show_progress
+from ....core.pgutils import chunk_queryset
+from ...checksums import update_post_checksum
+from ...models import Post
 
 
 
 
 class Command(BaseCommand):
 class Command(BaseCommand):

+ 2 - 3
misago/threads/mergeconflict.py

@@ -1,8 +1,7 @@
-from rest_framework.exceptions import ValidationError
-
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
+from rest_framework.exceptions import ValidationError
 
 
-from misago.threads.models import Poll
+from .models import Poll
 
 
 
 
 class MergeConflictHandler(object):
 class MergeConflictHandler(object):

+ 1 - 2
misago/threads/middleware.py

@@ -1,7 +1,6 @@
 from django.utils.deprecation import MiddlewareMixin
 from django.utils.deprecation import MiddlewareMixin
 
 
-from misago.categories.models import Category
-
+from ..categories.models import Category
 from .models import Thread
 from .models import Thread
 from .viewmodels import filter_read_threads_queryset
 from .viewmodels import filter_read_threads_queryset
 
 

+ 1 - 2
misago/threads/migrations/0002_threads_settings.py

@@ -1,7 +1,6 @@
 from django.db import migrations
 from django.db import migrations
 
 
-from misago.conf.migrationutils import migrate_settings_group
-
+from ...conf.migrationutils import migrate_settings_group
 
 
 _ = lambda s: s
 _ = lambda s: s
 
 

+ 0 - 1
misago/threads/migrations/0003_attachment_types.py

@@ -1,7 +1,6 @@
 # Generated by Django 1.9.7 on 2016-10-04 21:41
 # Generated by Django 1.9.7 on 2016-10-04 21:41
 from django.db import migrations
 from django.db import migrations
 
 
-
 ATTACHMENTS = [
 ATTACHMENTS = [
     {
     {
         "name": "GIF",
         "name": "GIF",

+ 1 - 1
misago/threads/migrations/0004_update_settings.py

@@ -1,6 +1,6 @@
 from django.db import migrations
 from django.db import migrations
 
 
-from misago.conf.migrationutils import migrate_settings_group
+from ...conf.migrationutils import migrate_settings_group
 
 
 _ = lambda s: s
 _ = lambda s: s
 
 

+ 1 - 1
misago/threads/migrations/0008_auto_20180310_2234.py

@@ -1,7 +1,7 @@
 # Generated by Django 1.11.9 on 2018-03-10 22:34
 # Generated by Django 1.11.9 on 2018-03-10 22:34
+import django.db.models.deletion
 from django.conf import settings
 from django.conf import settings
 from django.db import migrations, models
 from django.db import migrations, models
-import django.db.models.deletion
 
 
 
 
 class Migration(migrations.Migration):
 class Migration(migrations.Migration):

+ 3 - 4
misago/threads/models/attachment.py

@@ -2,17 +2,16 @@ import os
 from hashlib import md5
 from hashlib import md5
 from io import BytesIO
 from io import BytesIO
 
 
-from PIL import Image
-
 from django.core.files import File
 from django.core.files import File
 from django.core.files.base import ContentFile
 from django.core.files.base import ContentFile
 from django.db import models
 from django.db import models
 from django.urls import reverse
 from django.urls import reverse
 from django.utils import timezone
 from django.utils import timezone
 from django.utils.crypto import get_random_string
 from django.utils.crypto import get_random_string
+from PIL import Image
 
 
-from misago.conf import settings
-from misago.core.utils import slugify
+from ...conf import settings
+from ...core.utils import slugify
 
 
 
 
 def upload_to(instance, filename):
 def upload_to(instance, filename):

+ 10 - 10
misago/threads/models/post.py

@@ -1,17 +1,17 @@
 import copy
 import copy
 
 
-from django.contrib.postgres.indexes import GinIndex
 from django.contrib.postgres.fields import JSONField
 from django.contrib.postgres.fields import JSONField
+from django.contrib.postgres.indexes import GinIndex
 from django.contrib.postgres.search import SearchVector, SearchVectorField
 from django.contrib.postgres.search import SearchVector, SearchVectorField
 from django.db import models
 from django.db import models
 from django.utils import timezone
 from django.utils import timezone
 
 
-from misago.conf import settings
-from misago.core.pgutils import PgPartialIndex
-from misago.core.utils import parse_iso8601_string
-from misago.markup import finalise_markup
-from misago.threads.checksums import is_post_valid, update_post_checksum
-from misago.threads.filtersearch import filter_search
+from ...conf import settings
+from ...core.pgutils import PgPartialIndex
+from ...core.utils import parse_iso8601_string
+from ...markup import finalise_markup
+from ..checksums import is_post_valid, update_post_checksum
+from ..filtersearch import filter_search
 
 
 
 
 class Post(models.Model):
 class Post(models.Model):
@@ -97,7 +97,7 @@ class Post(models.Model):
         return "%s..." % self.original[10:].strip()
         return "%s..." % self.original[10:].strip()
 
 
     def delete(self, *args, **kwargs):
     def delete(self, *args, **kwargs):
-        from misago.threads.signals import delete_post
+        from ..signals import delete_post
 
 
         delete_post.send(sender=self)
         delete_post.send(sender=self)
 
 
@@ -133,12 +133,12 @@ class Post(models.Model):
         if other_post.is_best_answer:
         if other_post.is_best_answer:
             self.thread.best_answer_is_protected = other_post.is_protected
             self.thread.best_answer_is_protected = other_post.is_protected
 
 
-        from misago.threads.signals import merge_post
+        from ..signals import merge_post
 
 
         merge_post.send(sender=self, other_post=other_post)
         merge_post.send(sender=self, other_post=other_post)
 
 
     def move(self, new_thread):
     def move(self, new_thread):
-        from misago.threads.signals import move_post
+        from ..signals import move_post
 
 
         if self.is_best_answer:
         if self.is_best_answer:
             self.thread.clear_best_answer()
             self.thread.clear_best_answer()

+ 1 - 1
misago/threads/models/subscription.py

@@ -1,7 +1,7 @@
 from django.db import models
 from django.db import models
 from django.utils import timezone
 from django.utils import timezone
 
 
-from misago.conf import settings
+from ...conf import settings
 
 
 
 
 class Subscription(models.Model):
 class Subscription(models.Model):

+ 6 - 6
misago/threads/models/thread.py

@@ -3,9 +3,9 @@ from django.db import models
 from django.utils import timezone
 from django.utils import timezone
 from django.utils.translation import gettext_lazy as _
 from django.utils.translation import gettext_lazy as _
 
 
-from misago.conf import settings
-from misago.core.pgutils import PgPartialIndex
-from misago.core.utils import slugify
+from ...conf import settings
+from ...core.pgutils import PgPartialIndex
+from ...core.utils import slugify
 
 
 
 
 class Thread(models.Model):
 class Thread(models.Model):
@@ -122,7 +122,7 @@ class Thread(models.Model):
         return self.title
         return self.title
 
 
     def delete(self, *args, **kwargs):
     def delete(self, *args, **kwargs):
-        from misago.threads.signals import delete_thread
+        from ..signals import delete_thread
 
 
         delete_thread.send(sender=self)
         delete_thread.send(sender=self)
 
 
@@ -132,12 +132,12 @@ class Thread(models.Model):
         if self.pk == other_thread.pk:
         if self.pk == other_thread.pk:
             raise ValueError("thread can't be merged with itself")
             raise ValueError("thread can't be merged with itself")
 
 
-        from misago.threads.signals import merge_thread
+        from ..signals import merge_thread
 
 
         merge_thread.send(sender=self, other_thread=other_thread)
         merge_thread.send(sender=self, other_thread=other_thread)
 
 
     def move(self, new_category):
     def move(self, new_category):
-        from misago.threads.signals import move_thread
+        from ..signals import move_thread
 
 
         self.category = new_category
         self.category = new_category
         move_thread.send(sender=self)
         move_thread.send(sender=self)

+ 1 - 1
misago/threads/models/threadparticipant.py

@@ -1,6 +1,6 @@
 from django.db import models
 from django.db import models
 
 
-from misago.conf import settings
+from ...conf import settings
 
 
 
 
 class ThreadParticipantManager(models.Manager):
 class ThreadParticipantManager(models.Manager):

+ 0 - 1
misago/threads/moderation/posts.py

@@ -4,7 +4,6 @@ from django.utils.translation import gettext as _
 
 
 from .exceptions import ModerationError
 from .exceptions import ModerationError
 
 
-
 __all__ = [
 __all__ = [
     "approve_post",
     "approve_post",
     "protect_post",
     "protect_post",

+ 1 - 2
misago/threads/moderation/threads.py

@@ -1,8 +1,7 @@
 from django.db import transaction
 from django.db import transaction
 from django.utils import timezone
 from django.utils import timezone
 
 
-from misago.threads.events import record_event
-
+from ..events import record_event
 
 
 __all__ = [
 __all__ = [
     "change_thread_title",
     "change_thread_title",

+ 1 - 3
misago/threads/participants.py

@@ -1,12 +1,10 @@
 from django.contrib.auth import get_user_model
 from django.contrib.auth import get_user_model
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
 
 
-from misago.core.mail import build_mail, send_messages
-
+from ..core.mail import build_mail, send_messages
 from .events import record_event
 from .events import record_event
 from .models import ThreadParticipant
 from .models import ThreadParticipant
 
 
-
 User = get_user_model()
 User = get_user_model()
 
 
 
 

+ 4 - 5
misago/threads/permissions/attachments.py

@@ -1,11 +1,10 @@
 from django import forms
 from django import forms
 from django.utils.translation import gettext_lazy as _
 from django.utils.translation import gettext_lazy as _
 
 
-from misago.acl import algebra
-from misago.acl.models import Role
-from misago.admin.forms import YesNoSwitch
-from misago.threads.models import Attachment
-
+from ...acl import algebra
+from ...acl.models import Role
+from ...admin.forms import YesNoSwitch
+from ..models import Attachment
 
 
 # Admin Permissions Forms
 # Admin Permissions Forms
 class PermissionsForm(forms.Form):
 class PermissionsForm(forms.Form):

+ 9 - 9
misago/threads/permissions/bestanswers.py

@@ -1,15 +1,15 @@
 from django import forms
 from django import forms
 from django.core.exceptions import PermissionDenied
 from django.core.exceptions import PermissionDenied
 from django.utils import timezone
 from django.utils import timezone
-from django.utils.translation import gettext_lazy as _, ngettext
-
-from misago.acl import algebra
-from misago.acl.decorators import return_boolean
-from misago.admin.forms import YesNoSwitch
-from misago.categories.models import Category, CategoryRole
-from misago.categories.permissions import get_categories_roles
-from misago.threads.models import Post, Thread
-
+from django.utils.translation import gettext_lazy as _
+from django.utils.translation import ngettext
+
+from ...acl import algebra
+from ...acl.decorators import return_boolean
+from ...admin.forms import YesNoSwitch
+from ...categories.models import Category, CategoryRole
+from ...categories.permissions import get_categories_roles
+from ..models import Post, Thread
 
 
 __all__nope = [
 __all__nope = [
     "allow_mark_best_answer",
     "allow_mark_best_answer",

+ 5 - 6
misago/threads/permissions/polls.py

@@ -4,12 +4,11 @@ from django.utils import timezone
 from django.utils.translation import gettext_lazy as _
 from django.utils.translation import gettext_lazy as _
 from django.utils.translation import ngettext
 from django.utils.translation import ngettext
 
 
-from misago.acl import algebra
-from misago.acl.decorators import return_boolean
-from misago.acl.models import Role
-from misago.admin.forms import YesNoSwitch
-from misago.threads.models import Poll, Thread
-
+from ...acl import algebra
+from ...acl.decorators import return_boolean
+from ...acl.models import Role
+from ...admin.forms import YesNoSwitch
+from ..models import Poll, Thread
 
 
 __all__ = [
 __all__ = [
     "allow_start_poll",
     "allow_start_poll",

+ 7 - 8
misago/threads/permissions/privatethreads.py

@@ -3,14 +3,13 @@ from django.core.exceptions import PermissionDenied
 from django.http import Http404
 from django.http import Http404
 from django.utils.translation import gettext_lazy as _
 from django.utils.translation import gettext_lazy as _
 
 
-from misago.acl import algebra
-from misago.acl.decorators import return_boolean
-from misago.acl.models import Role
-from misago.admin.forms import YesNoSwitch
-from misago.categories import PRIVATE_THREADS_ROOT_NAME
-from misago.categories.models import Category
-from misago.threads.models import Thread
-
+from ...acl import algebra
+from ...acl.decorators import return_boolean
+from ...acl.models import Role
+from ...admin.forms import YesNoSwitch
+from ...categories import PRIVATE_THREADS_ROOT_NAME
+from ...categories.models import Category
+from ..models import Thread
 
 
 __all__ = [
 __all__ = [
     "allow_use_private_threads",
     "allow_use_private_threads",

+ 11 - 11
misago/threads/permissions/threads.py

@@ -3,17 +3,17 @@ from django.core.exceptions import PermissionDenied
 from django.db.models import Q
 from django.db.models import Q
 from django.http import Http404
 from django.http import Http404
 from django.utils import timezone
 from django.utils import timezone
-from django.utils.translation import gettext_lazy as _, ngettext
-
-from misago.acl import algebra
-from misago.acl.decorators import return_boolean
-from misago.acl.models import Role
-from misago.acl.objectacl import add_acl_to_obj
-from misago.admin.forms import YesNoSwitch
-from misago.categories.models import Category, CategoryRole
-from misago.categories.permissions import get_categories_roles
-from misago.threads.models import Post, Thread
-
+from django.utils.translation import gettext_lazy as _
+from django.utils.translation import ngettext
+
+from ...acl import algebra
+from ...acl.decorators import return_boolean
+from ...acl.models import Role
+from ...acl.objectacl import add_acl_to_obj
+from ...admin.forms import YesNoSwitch
+from ...categories.models import Category, CategoryRole
+from ...categories.permissions import get_categories_roles
+from ..models import Post, Thread
 
 
 __all__ = [
 __all__ = [
     "allow_see_thread",
     "allow_see_thread",

+ 3 - 5
misago/threads/search.py

@@ -1,10 +1,9 @@
 from django.contrib.postgres.search import SearchQuery, SearchRank, SearchVector
 from django.contrib.postgres.search import SearchQuery, SearchRank, SearchVector
 from django.utils.translation import gettext_lazy as _
 from django.utils.translation import gettext_lazy as _
 
 
-from misago.conf import settings
-from misago.core.shortcuts import paginate, pagination_dict
-from misago.search import SearchProvider
-
+from ..conf import settings
+from ..core.shortcuts import paginate, pagination_dict
+from ..search import SearchProvider
 from .filtersearch import filter_search
 from .filtersearch import filter_search
 from .models import Post, Thread
 from .models import Post, Thread
 from .permissions import exclude_invisible_threads
 from .permissions import exclude_invisible_threads
@@ -12,7 +11,6 @@ from .serializers import FeedSerializer
 from .utils import add_categories_to_items
 from .utils import add_categories_to_items
 from .viewmodels import ThreadsRootCategory
 from .viewmodels import ThreadsRootCategory
 
 
-
 HITS_CEILING = settings.MISAGO_POSTS_PER_PAGE * 5
 HITS_CEILING = settings.MISAGO_POSTS_PER_PAGE * 5
 
 
 
 

+ 2 - 4
misago/threads/serializers/attachment.py

@@ -1,9 +1,7 @@
-from rest_framework import serializers
-
 from django.urls import reverse
 from django.urls import reverse
+from rest_framework import serializers
 
 
-from misago.threads.models import Attachment
-
+from ..models import Attachment
 
 
 __all__ = ["AttachmentSerializer"]
 __all__ = ["AttachmentSerializer"]
 
 

+ 4 - 6
misago/threads/serializers/feed.py

@@ -1,13 +1,11 @@
 from rest_framework import serializers
 from rest_framework import serializers
 
 
-from misago.categories.serializers import CategorySerializer
-from misago.core.serializers import MutableFields
-from misago.threads.models import Post
-from misago.users.serializers import UserSerializer
-
+from ...categories.serializers import CategorySerializer
+from ...core.serializers import MutableFields
+from ...users.serializers import UserSerializer
+from ..models import Post
 from .post import PostSerializer
 from .post import PostSerializer
 
 
-
 __all__ = ["FeedSerializer"]
 __all__ = ["FeedSerializer"]
 
 
 FeedUserSerializer = UserSerializer.subset_fields(
 FeedUserSerializer = UserSerializer.subset_fields(

+ 13 - 14
misago/threads/serializers/moderation.py

@@ -1,15 +1,15 @@
-from rest_framework import serializers
-
 from django.core.exceptions import PermissionDenied, ValidationError
 from django.core.exceptions import PermissionDenied, ValidationError
 from django.http import Http404
 from django.http import Http404
-from django.utils.translation import gettext as _, gettext_lazy, ngettext
-
-from misago.acl.objectacl import add_acl_to_obj
-from misago.categories import THREADS_ROOT_NAME
-from misago.conf import settings
-from misago.threads.mergeconflict import MergeConflict
-from misago.threads.models import Thread
-from misago.threads.permissions import (
+from django.utils.translation import gettext as _
+from django.utils.translation import gettext_lazy, ngettext
+from rest_framework import serializers
+
+from ...acl.objectacl import add_acl_to_obj
+from ...categories import THREADS_ROOT_NAME
+from ...conf import settings
+from ..mergeconflict import MergeConflict
+from ..models import Thread
+from ..permissions import (
     allow_delete_best_answer,
     allow_delete_best_answer,
     allow_delete_event,
     allow_delete_event,
     allow_delete_post,
     allow_delete_post,
@@ -23,10 +23,9 @@ from misago.threads.permissions import (
     can_start_thread,
     can_start_thread,
     exclude_invisible_posts,
     exclude_invisible_posts,
 )
 )
-from misago.threads.threadtypes import trees_map
-from misago.threads.utils import get_thread_id_from_url
-from misago.threads.validators import validate_category, validate_thread_title
-
+from ..threadtypes import trees_map
+from ..utils import get_thread_id_from_url
+from ..validators import validate_category, validate_thread_title
 
 
 POSTS_LIMIT = settings.MISAGO_POSTS_PER_PAGE + settings.MISAGO_POSTS_TAIL
 POSTS_LIMIT = settings.MISAGO_POSTS_PER_PAGE + settings.MISAGO_POSTS_TAIL
 THREADS_LIMIT = settings.MISAGO_THREADS_PER_PAGE + settings.MISAGO_THREADS_TAIL
 THREADS_LIMIT = settings.MISAGO_THREADS_PER_PAGE + settings.MISAGO_THREADS_TAIL

+ 2 - 4
misago/threads/serializers/poll.py

@@ -1,12 +1,10 @@
-from rest_framework import serializers
-
 from django.urls import reverse
 from django.urls import reverse
 from django.utils.crypto import get_random_string
 from django.utils.crypto import get_random_string
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
 from django.utils.translation import ngettext
 from django.utils.translation import ngettext
+from rest_framework import serializers
 
 
-from misago.threads.models import Poll
-
+from ..models import Poll
 
 
 __all__ = [
 __all__ = [
     "PollSerializer",
     "PollSerializer",

+ 1 - 3
misago/threads/serializers/pollvote.py

@@ -1,9 +1,7 @@
-from rest_framework import serializers
-
 from django.urls import reverse
 from django.urls import reverse
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
 from django.utils.translation import ngettext
 from django.utils.translation import ngettext
-
+from rest_framework import serializers
 
 
 __all__ = ["NewVoteSerializer", "PollVoteSerializer"]
 __all__ = ["NewVoteSerializer", "PollVoteSerializer"]
 
 

+ 4 - 6
misago/threads/serializers/post.py

@@ -1,11 +1,9 @@
-from rest_framework import serializers
-
 from django.urls import reverse
 from django.urls import reverse
+from rest_framework import serializers
 
 
-from misago.core.serializers import MutableFields
-from misago.threads.models import Post
-from misago.users.serializers import UserSerializer as BaseUserSerializer
-
+from ...core.serializers import MutableFields
+from ...users.serializers import UserSerializer as BaseUserSerializer
+from ..models import Post
 
 
 __all__ = ["PostSerializer"]
 __all__ = ["PostSerializer"]
 
 

+ 2 - 4
misago/threads/serializers/postedit.py

@@ -1,9 +1,7 @@
-from rest_framework import serializers
-
 from django.urls import reverse
 from django.urls import reverse
+from rest_framework import serializers
 
 
-from misago.threads.models import PostEdit
-
+from ..models import PostEdit
 
 
 __all__ = ["PostEditSerializer"]
 __all__ = ["PostEditSerializer"]
 
 

+ 2 - 4
misago/threads/serializers/postlike.py

@@ -1,9 +1,7 @@
-from rest_framework import serializers
-
 from django.urls import reverse
 from django.urls import reverse
+from rest_framework import serializers
 
 
-from misago.threads.models import PostLike
-
+from ..models import PostLike
 
 
 __all__ = ["PostLikeSerializer"]
 __all__ = ["PostLikeSerializer"]
 
 

+ 4 - 7
misago/threads/serializers/thread.py

@@ -1,15 +1,12 @@
-from rest_framework import serializers
-
 from django.urls import reverse
 from django.urls import reverse
+from rest_framework import serializers
 
 
-from misago.categories.serializers import CategorySerializer
-from misago.core.serializers import MutableFields
-from misago.threads.models import Thread
-
+from ...categories.serializers import CategorySerializer
+from ...core.serializers import MutableFields
+from ..models import Thread
 from .poll import PollSerializer
 from .poll import PollSerializer
 from .threadparticipant import ThreadParticipantSerializer
 from .threadparticipant import ThreadParticipantSerializer
 
 
-
 __all__ = ["ThreadSerializer", "PrivateThreadSerializer", "ThreadsListSerializer"]
 __all__ = ["ThreadSerializer", "PrivateThreadSerializer", "ThreadsListSerializer"]
 
 
 BasicCategorySerializer = CategorySerializer.subset_fields(
 BasicCategorySerializer = CategorySerializer.subset_fields(

+ 1 - 2
misago/threads/serializers/threadparticipant.py

@@ -1,7 +1,6 @@
 from rest_framework import serializers
 from rest_framework import serializers
 
 
-from misago.threads.models import ThreadParticipant
-
+from ..models import ThreadParticipant
 
 
 __all__ = ["ThreadParticipantSerializer"]
 __all__ = ["ThreadParticipantSerializer"]
 
 

+ 4 - 6
misago/threads/signals.py

@@ -6,20 +6,18 @@ from django.db.models.signals import pre_delete
 from django.dispatch import Signal, receiver
 from django.dispatch import Signal, receiver
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
 
 
-from misago.categories.models import Category
-from misago.categories.signals import delete_category_content, move_category_content
-from misago.core.pgutils import chunk_queryset
-from misago.users.signals import (
+from ..categories.models import Category
+from ..categories.signals import delete_category_content, move_category_content
+from ..core.pgutils import chunk_queryset
+from ..users.signals import (
     anonymize_user_data,
     anonymize_user_data,
     archive_user_data,
     archive_user_data,
     delete_user_content,
     delete_user_content,
     username_changed,
     username_changed,
 )
 )
-
 from .anonymize import ANONYMIZABLE_EVENTS, anonymize_event, anonymize_post_last_likes
 from .anonymize import ANONYMIZABLE_EVENTS, anonymize_event, anonymize_post_last_likes
 from .models import Attachment, Poll, PollVote, Post, PostEdit, PostLike, Thread
 from .models import Attachment, Poll, PollVote, Post, PostEdit, PostLike, Thread
 
 
-
 delete_post = Signal()
 delete_post = Signal()
 delete_thread = Signal()
 delete_thread = Signal()
 merge_post = Signal(providing_args=["other_post"])
 merge_post = Signal(providing_args=["other_post"])

+ 0 - 1
misago/threads/templatetags/misago_poststags.py

@@ -2,7 +2,6 @@ from django import template
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
 from django.utils.translation import ngettext
 from django.utils.translation import ngettext
 
 
-
 register = template.Library()
 register = template.Library()
 
 
 
 

+ 4 - 5
misago/threads/test.py

@@ -3,11 +3,10 @@ from datetime import timedelta
 from django.contrib.auth import get_user_model
 from django.contrib.auth import get_user_model
 from django.utils import timezone
 from django.utils import timezone
 
 
-from misago.acl.test import patch_user_acl
-from misago.categories.models import Category
-from misago.core.utils import slugify
-from misago.users.test import create_test_user
-
+from ..acl.test import patch_user_acl
+from ..categories.models import Category
+from ..core.utils import slugify
+from ..users.test import create_test_user
 from .checksums import update_post_checksum
 from .checksums import update_post_checksum
 from .models import Poll, Post, Thread
 from .models import Poll, Post, Thread
 
 

+ 8 - 10
misago/threads/tests/test_anonymize_data.py

@@ -1,22 +1,20 @@
 from django.test import RequestFactory
 from django.test import RequestFactory
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.cache.versions import get_cache_versions
-from misago.categories.models import Category
-from misago.conf.dynamicsettings import DynamicSettings
-from misago.users.test import AuthenticatedUserTestCase
-
-from misago.threads import test
-from misago.threads.api.postendpoints.patch_post import patch_is_liked
-from misago.threads.models import Post
-from misago.threads.participants import (
+from .. import test
+from ...cache.versions import get_cache_versions
+from ...categories.models import Category
+from ...conf.dynamicsettings import DynamicSettings
+from ...users.test import AuthenticatedUserTestCase, create_test_user
+from ..api.postendpoints.patch_post import patch_is_liked
+from ..models import Post
+from ..participants import (
     add_participant,
     add_participant,
     change_owner,
     change_owner,
     make_participants_aware,
     make_participants_aware,
     remove_participant,
     remove_participant,
     set_owner,
     set_owner,
 )
 )
-from misago.users.test import create_test_user
 
 
 
 
 class AnonymizeEventsTests(AuthenticatedUserTestCase):
 class AnonymizeEventsTests(AuthenticatedUserTestCase):

+ 4 - 4
misago/threads/tests/test_attachmentadmin_views.py

@@ -1,9 +1,9 @@
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.admin.test import AdminTestCase
-from misago.categories.models import Category
-from misago.threads import test
-from misago.threads.models import Attachment, AttachmentType
+from .. import test
+from ...admin.test import AdminTestCase
+from ...categories.models import Category
+from ..models import Attachment, AttachmentType
 
 
 
 
 class AttachmentAdminViewsTests(AdminTestCase):
 class AttachmentAdminViewsTests(AdminTestCase):

+ 6 - 7
misago/threads/tests/test_attachments_api.py

@@ -1,14 +1,13 @@
 import os
 import os
 
 
-from PIL import Image
-
 from django.urls import reverse
 from django.urls import reverse
+from PIL import Image
 
 
-from misago.acl.models import Role
-from misago.acl.test import patch_user_acl
-from misago.conf import settings
-from misago.threads.models import Attachment, AttachmentType
-from misago.users.test import AuthenticatedUserTestCase
+from ...acl.models import Role
+from ...acl.test import patch_user_acl
+from ...conf import settings
+from ...users.test import AuthenticatedUserTestCase
+from ..models import Attachment, AttachmentType
 
 
 TESTFILES_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "testfiles")
 TESTFILES_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "testfiles")
 TEST_DOCUMENT_PATH = os.path.join(TESTFILES_DIR, "document.pdf")
 TEST_DOCUMENT_PATH = os.path.join(TESTFILES_DIR, "document.pdf")

+ 10 - 10
misago/threads/tests/test_attachments_middleware.py

@@ -2,19 +2,19 @@ from unittest.mock import Mock
 
 
 from rest_framework import serializers
 from rest_framework import serializers
 
 
-from misago.acl import useracl
-from misago.acl.test import patch_user_acl
-from misago.categories.models import Category
-from misago.conf import settings
-from misago.conftest import get_cache_versions
-from misago.threads import test
-from misago.threads.api.postingendpoint import PostingEndpoint
-from misago.threads.api.postingendpoint.attachments import (
+from .. import test
+from ...acl import useracl
+from ...acl.test import patch_user_acl
+from ...categories.models import Category
+from ...conf import settings
+from ...conftest import get_cache_versions
+from ...users.test import AuthenticatedUserTestCase
+from ..api.postingendpoint import PostingEndpoint
+from ..api.postingendpoint.attachments import (
     AttachmentsMiddleware,
     AttachmentsMiddleware,
     validate_attachments_count,
     validate_attachments_count,
 )
 )
-from misago.threads.models import Attachment, AttachmentType
-from misago.users.test import AuthenticatedUserTestCase
+from ..models import Attachment, AttachmentType
 
 
 cache_versions = get_cache_versions()
 cache_versions = get_cache_versions()
 
 

+ 3 - 3
misago/threads/tests/test_attachmenttypeadmin_views.py

@@ -1,8 +1,8 @@
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.acl.models import Role
-from misago.admin.test import AdminTestCase
-from misago.threads.models import AttachmentType
+from ...acl.models import Role
+from ...admin.test import AdminTestCase
+from ..models import AttachmentType
 
 
 
 
 class AttachmentTypeAdminViewsTests(AdminTestCase):
 class AttachmentTypeAdminViewsTests(AdminTestCase):

+ 7 - 7
misago/threads/tests/test_attachmentview.py

@@ -2,13 +2,13 @@ import os
 
 
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.acl.models import Role
-from misago.acl.test import patch_user_acl
-from misago.categories.models import Category
-from misago.conf import settings
-from misago.threads import test
-from misago.threads.models import Attachment, AttachmentType
-from misago.users.test import AuthenticatedUserTestCase
+from .. import test
+from ...acl.models import Role
+from ...acl.test import patch_user_acl
+from ...categories.models import Category
+from ...conf import settings
+from ...users.test import AuthenticatedUserTestCase
+from ..models import Attachment, AttachmentType
 
 
 TESTFILES_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "testfiles")
 TESTFILES_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "testfiles")
 TEST_DOCUMENT_PATH = os.path.join(TESTFILES_DIR, "document.pdf")
 TEST_DOCUMENT_PATH = os.path.join(TESTFILES_DIR, "document.pdf")

+ 5 - 5
misago/threads/tests/test_clearattachments.py

@@ -5,11 +5,11 @@ from django.core.management import call_command
 from django.test import TestCase
 from django.test import TestCase
 from django.utils import timezone
 from django.utils import timezone
 
 
-from misago.categories.models import Category
-from misago.conf import settings
-from misago.threads import test
-from misago.threads.management.commands import clearattachments
-from misago.threads.models import Attachment, AttachmentType
+from .. import test
+from ...categories.models import Category
+from ...conf import settings
+from ..management.commands import clearattachments
+from ..models import Attachment, AttachmentType
 
 
 
 
 class ClearAttachmentsTests(TestCase):
 class ClearAttachmentsTests(TestCase):

+ 5 - 6
misago/threads/tests/test_delete_user_likes.py

@@ -1,11 +1,10 @@
 from django.test import RequestFactory
 from django.test import RequestFactory
 
 
-from misago.categories.models import Category
-from misago.users.test import AuthenticatedUserTestCase, create_test_user
-
-from misago.threads import test
-from misago.threads.api.postendpoints.patch_post import patch_is_liked
-from misago.threads.models import Post
+from .. import test
+from ...categories.models import Category
+from ...users.test import AuthenticatedUserTestCase, create_test_user
+from ..api.postendpoints.patch_post import patch_is_liked
+from ..models import Post
 
 
 
 
 class DeleteUserLikesTests(AuthenticatedUserTestCase):
 class DeleteUserLikesTests(AuthenticatedUserTestCase):

+ 4 - 4
misago/threads/tests/test_emailnotification_middleware.py

@@ -6,10 +6,10 @@ from django.urls import reverse
 from django.utils import timezone
 from django.utils import timezone
 from django.utils.encoding import smart_str
 from django.utils.encoding import smart_str
 
 
-from misago.categories.models import Category
-from misago.threads import test
-from misago.threads.test import patch_category_acl, patch_other_user_category_acl
-from misago.users.test import AuthenticatedUserTestCase, create_test_user
+from .. import test
+from ...categories.models import Category
+from ...users.test import AuthenticatedUserTestCase, create_test_user
+from ..test import patch_category_acl, patch_other_user_category_acl
 
 
 
 
 class EmailNotificationTests(AuthenticatedUserTestCase):
 class EmailNotificationTests(AuthenticatedUserTestCase):

+ 7 - 7
misago/threads/tests/test_events.py

@@ -3,13 +3,13 @@ from unittest.mock import Mock
 from django.test import TestCase
 from django.test import TestCase
 from django.utils import timezone
 from django.utils import timezone
 
 
-from misago.acl import useracl
-from misago.acl.objectacl import add_acl_to_obj
-from misago.categories.models import Category
-from misago.conftest import get_cache_versions
-from misago.threads.events import record_event
-from misago.threads.models import Thread
-from misago.users.test import create_test_user
+from ...acl import useracl
+from ...acl.objectacl import add_acl_to_obj
+from ...categories.models import Category
+from ...conftest import get_cache_versions
+from ...users.test import create_test_user
+from ..events import record_event
+from ..models import Thread
 
 
 cache_versions = get_cache_versions()
 cache_versions = get_cache_versions()
 
 

+ 4 - 4
misago/threads/tests/test_floodprotection.py

@@ -1,9 +1,9 @@
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.acl.test import patch_user_acl
-from misago.categories.models import Category
-from misago.threads import test
-from misago.users.test import AuthenticatedUserTestCase
+from .. import test
+from ...acl.test import patch_user_acl
+from ...categories.models import Category
+from ...users.test import AuthenticatedUserTestCase
 
 
 
 
 class FloodProtectionTests(AuthenticatedUserTestCase):
 class FloodProtectionTests(AuthenticatedUserTestCase):

+ 3 - 3
misago/threads/tests/test_floodprotection_middleware.py

@@ -2,9 +2,9 @@ from datetime import timedelta
 
 
 from django.utils import timezone
 from django.utils import timezone
 
 
-from misago.threads.api.postingendpoint import PostingInterrupt
-from misago.threads.api.postingendpoint.floodprotection import FloodProtectionMiddleware
-from misago.users.test import AuthenticatedUserTestCase
+from ...users.test import AuthenticatedUserTestCase
+from ..api.postingendpoint import PostingInterrupt
+from ..api.postingendpoint.floodprotection import FloodProtectionMiddleware
 
 
 user_acl = {"can_omit_flood_protection": False}
 user_acl = {"can_omit_flood_protection": False}
 
 

+ 6 - 7
misago/threads/tests/test_gotoviews.py

@@ -1,12 +1,11 @@
 from django.utils import timezone
 from django.utils import timezone
 
 
-from misago.categories.models import Category
-from misago.conf import settings
-from misago.readtracker.poststracker import save_read
-from misago.threads import test
-from misago.threads.test import patch_category_acl
-from misago.users.test import AuthenticatedUserTestCase
-
+from .. import test
+from ...categories.models import Category
+from ...conf import settings
+from ...readtracker.poststracker import save_read
+from ...users.test import AuthenticatedUserTestCase
+from ..test import patch_category_acl
 
 
 GOTO_URL = "%s#post-%s"
 GOTO_URL = "%s#post-%s"
 GOTO_PAGE_URL = "%s%s/#post-%s"
 GOTO_PAGE_URL = "%s%s/#post-%s"

+ 5 - 7
misago/threads/tests/test_mergeconflict.py

@@ -1,12 +1,10 @@
-from rest_framework.exceptions import ValidationError
-
 from django.test import TestCase
 from django.test import TestCase
+from rest_framework.exceptions import ValidationError
 
 
-from misago.categories.models import Category
-
-from misago.threads import test
-from misago.threads.mergeconflict import MergeConflict
-from misago.users.test import create_test_user
+from .. import test
+from ...categories.models import Category
+from ...users.test import create_test_user
+from ..mergeconflict import MergeConflict
 
 
 
 
 class MergeConflictTests(TestCase):
 class MergeConflictTests(TestCase):

+ 1 - 1
misago/threads/tests/test_paginator.py

@@ -2,7 +2,7 @@ from itertools import product
 
 
 from django.test import TestCase
 from django.test import TestCase
 
 
-from misago.threads.paginator import PostsPaginator
+from ..paginator import PostsPaginator
 
 
 
 
 class PostsPaginatorTests(TestCase):
 class PostsPaginatorTests(TestCase):

+ 4 - 4
misago/threads/tests/test_participants.py

@@ -1,15 +1,15 @@
 from django.test import TestCase
 from django.test import TestCase
 from django.utils import timezone
 from django.utils import timezone
 
 
-from misago.categories.models import Category
-from misago.threads.models import Post, Thread, ThreadParticipant
-from misago.threads.participants import (
+from ...categories.models import Category
+from ...users.test import create_test_user
+from ..models import Post, Thread, ThreadParticipant
+from ..participants import (
     has_participants,
     has_participants,
     make_participants_aware,
     make_participants_aware,
     set_owner,
     set_owner,
     set_users_unread_private_threads_sync,
     set_users_unread_private_threads_sync,
 )
 )
-from misago.users.test import create_test_user
 
 
 
 
 class ParticipantsTests(TestCase):
 class ParticipantsTests(TestCase):

+ 4 - 4
misago/threads/tests/test_post_mentions.py

@@ -1,10 +1,10 @@
 from django.test.client import BOUNDARY, MULTIPART_CONTENT, encode_multipart
 from django.test.client import BOUNDARY, MULTIPART_CONTENT, encode_multipart
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.categories.models import Category
-from misago.markup.mentions import MENTIONS_LIMIT
-from misago.threads import test
-from misago.users.test import AuthenticatedUserTestCase, create_test_user
+from .. import test
+from ...categories.models import Category
+from ...markup.mentions import MENTIONS_LIMIT
+from ...users.test import AuthenticatedUserTestCase, create_test_user
 
 
 
 
 class PostMentionsTests(AuthenticatedUserTestCase):
 class PostMentionsTests(AuthenticatedUserTestCase):

+ 4 - 4
misago/threads/tests/test_post_model.py

@@ -3,10 +3,10 @@ from datetime import timedelta
 from django.test import TestCase
 from django.test import TestCase
 from django.utils import timezone
 from django.utils import timezone
 
 
-from misago.categories.models import Category
-from misago.threads.checksums import update_post_checksum
-from misago.threads.models import Post, Thread
-from misago.users.test import create_test_user
+from ...categories.models import Category
+from ...users.test import create_test_user
+from ..checksums import update_post_checksum
+from ..models import Post, Thread
 
 
 
 
 class PostModelTests(TestCase):
 class PostModelTests(TestCase):

+ 4 - 4
misago/threads/tests/test_posts_moderation.py

@@ -1,7 +1,7 @@
-from misago.categories.models import Category
-from misago.threads import moderation, test
-from misago.threads.models import Post, Thread
-from misago.users.test import AuthenticatedUserTestCase
+from .. import moderation, test
+from ...categories.models import Category
+from ...users.test import AuthenticatedUserTestCase
+from ..models import Post, Thread
 
 
 
 
 class PostsModerationTests(AuthenticatedUserTestCase):
 class PostsModerationTests(AuthenticatedUserTestCase):

+ 5 - 6
misago/threads/tests/test_privatethread_patch_api.py

@@ -2,12 +2,11 @@ import json
 
 
 from django.core import mail
 from django.core import mail
 
 
-from misago.acl.test import patch_user_acl
-from misago.threads import test
-from misago.threads.test import other_user_cant_use_private_threads
-from misago.threads.models import Thread, ThreadParticipant
-from misago.users.test import create_test_user
-
+from .. import test
+from ...acl.test import patch_user_acl
+from ...users.test import create_test_user
+from ..models import Thread, ThreadParticipant
+from ..test import other_user_cant_use_private_threads
 from .test_privatethreads import PrivateThreadsTestCase
 from .test_privatethreads import PrivateThreadsTestCase
 
 
 
 

+ 3 - 4
misago/threads/tests/test_privatethread_reply_api.py

@@ -1,7 +1,6 @@
-from misago.threads import test
-from misago.threads.models import ThreadParticipant
-from misago.users.test import create_test_user
-
+from .. import test
+from ...users.test import create_test_user
+from ..models import ThreadParticipant
 from .test_privatethreads import PrivateThreadsTestCase
 from .test_privatethreads import PrivateThreadsTestCase
 
 
 
 

+ 5 - 5
misago/threads/tests/test_privatethread_start_api.py

@@ -3,11 +3,11 @@ from django.core import mail
 from django.urls import reverse
 from django.urls import reverse
 from django.utils.encoding import smart_str
 from django.utils.encoding import smart_str
 
 
-from misago.acl.test import patch_user_acl
-from misago.categories.models import Category
-from misago.threads.models import ThreadParticipant
-from misago.threads.test import other_user_cant_use_private_threads
-from misago.users.test import AuthenticatedUserTestCase, create_test_user
+from ...acl.test import patch_user_acl
+from ...categories.models import Category
+from ...users.test import AuthenticatedUserTestCase, create_test_user
+from ..models import ThreadParticipant
+from ..test import other_user_cant_use_private_threads
 
 
 User = get_user_model()
 User = get_user_model()
 
 

+ 3 - 4
misago/threads/tests/test_privatethread_view.py

@@ -1,7 +1,6 @@
-from misago.acl.test import patch_user_acl
-from misago.threads import test
-from misago.threads.models import ThreadParticipant
-
+from .. import test
+from ...acl.test import patch_user_acl
+from ..models import ThreadParticipant
 from .test_privatethreads import PrivateThreadsTestCase
 from .test_privatethreads import PrivateThreadsTestCase
 
 
 
 

+ 2 - 2
misago/threads/tests/test_privatethreads.py

@@ -1,5 +1,5 @@
-from misago.categories.models import Category
-from misago.users.test import AuthenticatedUserTestCase
+from ...categories.models import Category
+from ...users.test import AuthenticatedUserTestCase
 
 
 
 
 class PrivateThreadsTestCase(AuthenticatedUserTestCase):
 class PrivateThreadsTestCase(AuthenticatedUserTestCase):

+ 4 - 5
misago/threads/tests/test_privatethreads_api.py

@@ -1,10 +1,9 @@
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.acl.test import patch_user_acl
-from misago.threads import test
-from misago.threads.models import Thread, ThreadParticipant
-from misago.threads.test import patch_private_threads_acl
-
+from .. import test
+from ...acl.test import patch_user_acl
+from ..models import Thread, ThreadParticipant
+from ..test import patch_private_threads_acl
 from .test_privatethreads import PrivateThreadsTestCase
 from .test_privatethreads import PrivateThreadsTestCase
 
 
 
 

+ 3 - 4
misago/threads/tests/test_privatethreads_lists.py

@@ -1,9 +1,8 @@
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.acl.test import patch_user_acl
-from misago.threads import test
-from misago.threads.models import ThreadParticipant
-
+from .. import test
+from ...acl.test import patch_user_acl
+from ..models import ThreadParticipant
 from .test_privatethreads import PrivateThreadsTestCase
 from .test_privatethreads import PrivateThreadsTestCase
 
 
 
 

+ 3 - 3
misago/threads/tests/test_search.py

@@ -1,8 +1,8 @@
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.categories.models import Category
-from misago.threads import test
-from misago.users.test import AuthenticatedUserTestCase
+from .. import test
+from ...categories.models import Category
+from ...users.test import AuthenticatedUserTestCase
 
 
 
 
 class SearchApiTests(AuthenticatedUserTestCase):
 class SearchApiTests(AuthenticatedUserTestCase):

+ 5 - 6
misago/threads/tests/test_subscription_middleware.py

@@ -1,12 +1,11 @@
 from django.contrib.auth import get_user_model
 from django.contrib.auth import get_user_model
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.acl.test import patch_user_acl
-from misago.categories.models import Category
-from misago.threads import test
-from misago.threads.test import patch_category_acl
-from misago.users.test import AuthenticatedUserTestCase
-
+from .. import test
+from ...acl.test import patch_user_acl
+from ...categories.models import Category
+from ...users.test import AuthenticatedUserTestCase
+from ..test import patch_category_acl
 
 
 User = get_user_model()
 User = get_user_model()
 
 

+ 5 - 5
misago/threads/tests/test_subscriptions.py

@@ -3,11 +3,11 @@ from datetime import timedelta
 from django.test import TestCase
 from django.test import TestCase
 from django.utils import timezone
 from django.utils import timezone
 
 
-from misago.categories.models import Category
-from misago.threads import test
-from misago.threads.subscriptions import make_subscription_aware
-from misago.users.models import AnonymousUser
-from misago.users.test import create_test_user
+from .. import test
+from ...categories.models import Category
+from ...users.models import AnonymousUser
+from ...users.test import create_test_user
+from ..subscriptions import make_subscription_aware
 
 
 
 
 class SubscriptionsTests(TestCase):
 class SubscriptionsTests(TestCase):

+ 3 - 4
misago/threads/tests/test_sync_unread_private_threads.py

@@ -1,7 +1,6 @@
-from misago.threads import test
-from misago.threads.models import ThreadParticipant
-from misago.users.test import create_test_user
-
+from .. import test
+from ...users.test import create_test_user
+from ..models import ThreadParticipant
 from .test_privatethreads import PrivateThreadsTestCase
 from .test_privatethreads import PrivateThreadsTestCase
 
 
 
 

+ 3 - 3
misago/threads/tests/test_synchronizethreads.py

@@ -3,9 +3,9 @@ from io import StringIO
 from django.core.management import call_command
 from django.core.management import call_command
 from django.test import TestCase
 from django.test import TestCase
 
 
-from misago.categories.models import Category
-from misago.threads import test
-from misago.threads.management.commands import synchronizethreads
+from .. import test
+from ...categories.models import Category
+from ..management.commands import synchronizethreads
 
 
 
 
 class SynchronizeThreadsTests(TestCase):
 class SynchronizeThreadsTests(TestCase):

+ 4 - 5
misago/threads/tests/test_thread_bulkpatch_api.py

@@ -2,11 +2,10 @@ import json
 
 
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.categories.models import Category
-from misago.threads import test
-from misago.threads.models import Thread
-from misago.threads.test import patch_category_acl, patch_other_category_acl
-
+from .. import test
+from ...categories.models import Category
+from ..models import Thread
+from ..test import patch_category_acl, patch_other_category_acl
 from .test_threads_api import ThreadsApiTestCase
 from .test_threads_api import ThreadsApiTestCase
 
 
 
 

+ 6 - 6
misago/threads/tests/test_thread_editreply_api.py

@@ -4,12 +4,12 @@ from django.test.client import BOUNDARY, MULTIPART_CONTENT, encode_multipart
 from django.urls import reverse
 from django.urls import reverse
 from django.utils import timezone
 from django.utils import timezone
 
 
-from misago.acl.test import patch_user_acl
-from misago.categories.models import Category
-from misago.threads import test
-from misago.threads.models import Post, Thread
-from misago.threads.test import patch_category_acl
-from misago.users.test import AuthenticatedUserTestCase
+from .. import test
+from ...acl.test import patch_user_acl
+from ...categories.models import Category
+from ...users.test import AuthenticatedUserTestCase
+from ..models import Post, Thread
+from ..test import patch_category_acl
 
 
 
 
 class EditReplyTests(AuthenticatedUserTestCase):
 class EditReplyTests(AuthenticatedUserTestCase):

+ 5 - 6
misago/threads/tests/test_thread_merge_api.py

@@ -1,11 +1,10 @@
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.categories.models import Category
-from misago.readtracker import poststracker
-from misago.threads import test
-from misago.threads.models import Poll, PollVote, Thread
-from misago.threads.test import patch_category_acl, patch_other_category_acl
-
+from .. import test
+from ...categories.models import Category
+from ...readtracker import poststracker
+from ..models import Poll, PollVote, Thread
+from ..test import patch_category_acl, patch_other_category_acl
 from .test_threads_api import ThreadsApiTestCase
 from .test_threads_api import ThreadsApiTestCase
 
 
 
 

+ 4 - 4
misago/threads/tests/test_thread_model.py

@@ -3,10 +3,10 @@ from datetime import timedelta
 from django.test import TestCase
 from django.test import TestCase
 from django.utils import timezone
 from django.utils import timezone
 
 
-from misago.categories.models import Category
-from misago.threads import test
-from misago.threads.models import Poll, Post, Thread, ThreadParticipant
-from misago.users.test import create_test_user
+from .. import test
+from ...categories.models import Category
+from ...users.test import create_test_user
+from ..models import Poll, Post, Thread, ThreadParticipant
 
 
 
 
 class ThreadModelTests(TestCase):
 class ThreadModelTests(TestCase):

+ 5 - 6
misago/threads/tests/test_thread_patch_api.py

@@ -3,12 +3,11 @@ from datetime import timedelta
 
 
 from django.utils import timezone
 from django.utils import timezone
 
 
-from misago.categories.models import Category
-from misago.readtracker import poststracker
-from misago.threads import test
-from misago.threads.test import patch_category_acl, patch_other_category_acl
-from misago.threads.models import Thread
-
+from .. import test
+from ...categories.models import Category
+from ...readtracker import poststracker
+from ..models import Thread
+from ..test import patch_category_acl, patch_other_category_acl
 from .test_threads_api import ThreadsApiTestCase
 from .test_threads_api import ThreadsApiTestCase
 
 
 
 

+ 3 - 3
misago/threads/tests/test_thread_poll_api.py

@@ -2,9 +2,9 @@ import json
 
 
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.categories.models import Category
-from misago.threads import test
-from misago.users.test import AuthenticatedUserTestCase
+from .. import test
+from ...categories.models import Category
+from ...users.test import AuthenticatedUserTestCase
 
 
 
 
 class ThreadPollApiTestCase(AuthenticatedUserTestCase):
 class ThreadPollApiTestCase(AuthenticatedUserTestCase):

+ 4 - 5
misago/threads/tests/test_thread_pollcreate_api.py

@@ -1,10 +1,9 @@
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.acl.test import patch_user_acl
-from misago.threads.models import Poll, Thread
-from misago.threads.serializers.poll import MAX_POLL_OPTIONS
-from misago.threads.test import patch_category_acl
-
+from ...acl.test import patch_user_acl
+from ..models import Poll, Thread
+from ..serializers.poll import MAX_POLL_OPTIONS
+from ..test import patch_category_acl
 from .test_thread_poll_api import ThreadPollApiTestCase
 from .test_thread_poll_api import ThreadPollApiTestCase
 
 
 
 

+ 3 - 4
misago/threads/tests/test_thread_polldelete_api.py

@@ -3,10 +3,9 @@ from datetime import timedelta
 from django.urls import reverse
 from django.urls import reverse
 from django.utils import timezone
 from django.utils import timezone
 
 
-from misago.acl.test import patch_user_acl
-from misago.threads.models import Poll, PollVote, Thread
-from misago.threads.test import patch_category_acl
-
+from ...acl.test import patch_user_acl
+from ..models import Poll, PollVote, Thread
+from ..test import patch_category_acl
 from .test_thread_poll_api import ThreadPollApiTestCase
 from .test_thread_poll_api import ThreadPollApiTestCase
 
 
 
 

+ 3 - 4
misago/threads/tests/test_thread_polledit_api.py

@@ -3,10 +3,9 @@ from datetime import timedelta
 from django.urls import reverse
 from django.urls import reverse
 from django.utils import timezone
 from django.utils import timezone
 
 
-from misago.acl.test import patch_user_acl
-from misago.threads.serializers.poll import MAX_POLL_OPTIONS
-from misago.threads.test import patch_category_acl
-
+from ...acl.test import patch_user_acl
+from ..serializers.poll import MAX_POLL_OPTIONS
+from ..test import patch_category_acl
 from .test_thread_poll_api import ThreadPollApiTestCase
 from .test_thread_poll_api import ThreadPollApiTestCase
 
 
 
 

+ 3 - 4
misago/threads/tests/test_thread_pollvotes_api.py

@@ -4,10 +4,9 @@ from django.contrib.auth import get_user_model
 from django.urls import reverse
 from django.urls import reverse
 from django.utils import timezone
 from django.utils import timezone
 
 
-from misago.acl.test import patch_user_acl
-from misago.threads.models import Poll
-from misago.threads.test import patch_category_acl
-
+from ...acl.test import patch_user_acl
+from ..models import Poll
+from ..test import patch_category_acl
 from .test_thread_poll_api import ThreadPollApiTestCase
 from .test_thread_poll_api import ThreadPollApiTestCase
 
 
 User = get_user_model()
 User = get_user_model()

+ 3 - 4
misago/threads/tests/test_thread_postbulkdelete_api.py

@@ -4,10 +4,9 @@ from datetime import timedelta
 from django.urls import reverse
 from django.urls import reverse
 from django.utils import timezone
 from django.utils import timezone
 
 
-from misago.threads import test
-from misago.threads.models import Post, Thread
-from misago.threads.test import patch_category_acl
-
+from .. import test
+from ..models import Post, Thread
+from ..test import patch_category_acl
 from .test_threads_api import ThreadsApiTestCase
 from .test_threads_api import ThreadsApiTestCase
 
 
 
 

+ 5 - 5
misago/threads/tests/test_thread_postbulkpatch_api.py

@@ -4,11 +4,11 @@ from datetime import timedelta
 from django.urls import reverse
 from django.urls import reverse
 from django.utils import timezone
 from django.utils import timezone
 
 
-from misago.categories.models import Category
-from misago.threads import test
-from misago.threads.models import Post, Thread
-from misago.threads.test import patch_category_acl
-from misago.users.test import AuthenticatedUserTestCase
+from .. import test
+from ...categories.models import Category
+from ...users.test import AuthenticatedUserTestCase
+from ..models import Post, Thread
+from ..test import patch_category_acl
 
 
 
 
 class ThreadPostBulkPatchApiTestCase(AuthenticatedUserTestCase):
 class ThreadPostBulkPatchApiTestCase(AuthenticatedUserTestCase):

+ 3 - 4
misago/threads/tests/test_thread_postdelete_api.py

@@ -3,10 +3,9 @@ from datetime import timedelta
 from django.urls import reverse
 from django.urls import reverse
 from django.utils import timezone
 from django.utils import timezone
 
 
-from misago.threads import test
-from misago.threads.models import Post, Thread
-from misago.threads.test import patch_category_acl
-
+from .. import test
+from ..models import Post, Thread
+from ..test import patch_category_acl
 from .test_threads_api import ThreadsApiTestCase
 from .test_threads_api import ThreadsApiTestCase
 
 
 
 

+ 2 - 3
misago/threads/tests/test_thread_postedits_api.py

@@ -1,8 +1,7 @@
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.threads import test
-from misago.threads.test import patch_category_acl
-
+from .. import test
+from ..test import patch_category_acl
 from .test_threads_api import ThreadsApiTestCase
 from .test_threads_api import ThreadsApiTestCase
 
 
 
 

+ 3 - 4
misago/threads/tests/test_thread_postlikes_api.py

@@ -1,9 +1,8 @@
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.threads import test
-from misago.threads.test import patch_category_acl
-from misago.threads.serializers import PostLikeSerializer
-
+from .. import test
+from ..serializers import PostLikeSerializer
+from ..test import patch_category_acl
 from .test_threads_api import ThreadsApiTestCase
 from .test_threads_api import ThreadsApiTestCase
 
 
 
 

+ 7 - 7
misago/threads/tests/test_thread_postmerge_api.py

@@ -2,13 +2,13 @@ import json
 
 
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.categories.models import Category
-from misago.readtracker import poststracker
-from misago.threads import test
-from misago.threads.models import Post, Thread
-from misago.threads.serializers.moderation import POSTS_LIMIT
-from misago.threads.test import patch_category_acl
-from misago.users.test import AuthenticatedUserTestCase
+from .. import test
+from ...categories.models import Category
+from ...readtracker import poststracker
+from ...users.test import AuthenticatedUserTestCase
+from ..models import Post, Thread
+from ..serializers.moderation import POSTS_LIMIT
+from ..test import patch_category_acl
 
 
 
 
 class ThreadPostMergeApiTestCase(AuthenticatedUserTestCase):
 class ThreadPostMergeApiTestCase(AuthenticatedUserTestCase):

+ 7 - 7
misago/threads/tests/test_thread_postmove_api.py

@@ -2,13 +2,13 @@ import json
 
 
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.categories.models import Category
-from misago.readtracker import poststracker
-from misago.threads import test
-from misago.threads.models import Thread
-from misago.threads.serializers.moderation import POSTS_LIMIT
-from misago.threads.test import patch_category_acl, patch_other_category_acl
-from misago.users.test import AuthenticatedUserTestCase
+from .. import test
+from ...categories.models import Category
+from ...readtracker import poststracker
+from ...users.test import AuthenticatedUserTestCase
+from ..models import Thread
+from ..serializers.moderation import POSTS_LIMIT
+from ..test import patch_category_acl, patch_other_category_acl
 
 
 
 
 class ThreadPostMoveApiTestCase(AuthenticatedUserTestCase):
 class ThreadPostMoveApiTestCase(AuthenticatedUserTestCase):

+ 5 - 5
misago/threads/tests/test_thread_postpatch_api.py

@@ -4,11 +4,11 @@ from datetime import timedelta
 from django.urls import reverse
 from django.urls import reverse
 from django.utils import timezone
 from django.utils import timezone
 
 
-from misago.categories.models import Category
-from misago.threads import test
-from misago.threads.models import Thread, Post
-from misago.threads.test import patch_category_acl
-from misago.users.test import AuthenticatedUserTestCase
+from .. import test
+from ...categories.models import Category
+from ...users.test import AuthenticatedUserTestCase
+from ..models import Post, Thread
+from ..test import patch_category_acl
 
 
 
 
 class ThreadPostPatchApiTestCase(AuthenticatedUserTestCase):
 class ThreadPostPatchApiTestCase(AuthenticatedUserTestCase):

+ 1 - 2
misago/threads/tests/test_thread_postread_api.py

@@ -1,8 +1,7 @@
 from django.urls import reverse
 from django.urls import reverse
 from django.utils import timezone
 from django.utils import timezone
 
 
-from misago.threads import test
-
+from .. import test
 from .test_threads_api import ThreadsApiTestCase
 from .test_threads_api import ThreadsApiTestCase
 
 
 
 

+ 7 - 7
misago/threads/tests/test_thread_postsplit_api.py

@@ -2,13 +2,13 @@ import json
 
 
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.categories.models import Category
-from misago.readtracker import poststracker
-from misago.threads import test
-from misago.threads.models import Post, Thread
-from misago.threads.serializers.moderation import POSTS_LIMIT
-from misago.threads.test import patch_category_acl, patch_other_category_acl
-from misago.users.test import AuthenticatedUserTestCase
+from .. import test
+from ...categories.models import Category
+from ...readtracker import poststracker
+from ...users.test import AuthenticatedUserTestCase
+from ..models import Post, Thread
+from ..serializers.moderation import POSTS_LIMIT
+from ..test import patch_category_acl, patch_other_category_acl
 
 
 
 
 class ThreadPostSplitApiTestCase(AuthenticatedUserTestCase):
 class ThreadPostSplitApiTestCase(AuthenticatedUserTestCase):

+ 6 - 6
misago/threads/tests/test_thread_reply_api.py

@@ -1,11 +1,11 @@
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.acl.test import patch_user_acl
-from misago.categories.models import Category
-from misago.threads import test
-from misago.threads.models import Thread
-from misago.threads.test import patch_category_acl
-from misago.users.test import AuthenticatedUserTestCase
+from .. import test
+from ...acl.test import patch_user_acl
+from ...categories.models import Category
+from ...users.test import AuthenticatedUserTestCase
+from ..models import Thread
+from ..test import patch_category_acl
 
 
 
 
 class ReplyThreadTests(AuthenticatedUserTestCase):
 class ReplyThreadTests(AuthenticatedUserTestCase):

+ 4 - 4
misago/threads/tests/test_thread_start_api.py

@@ -1,9 +1,9 @@
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.acl.test import patch_user_acl
-from misago.categories.models import Category
-from misago.threads.test import patch_category_acl
-from misago.users.test import AuthenticatedUserTestCase
+from ...acl.test import patch_user_acl
+from ...categories.models import Category
+from ...users.test import AuthenticatedUserTestCase
+from ..test import patch_category_acl
 
 
 
 
 class StartThreadTests(AuthenticatedUserTestCase):
 class StartThreadTests(AuthenticatedUserTestCase):

+ 3 - 3
misago/threads/tests/test_threadparticipant_model.py

@@ -1,9 +1,9 @@
 from django.test import TestCase
 from django.test import TestCase
 from django.utils import timezone
 from django.utils import timezone
 
 
-from misago.categories.models import Category
-from misago.threads.models import Post, Thread, ThreadParticipant
-from misago.users.test import create_test_user
+from ...categories.models import Category
+from ...users.test import create_test_user
+from ..models import Post, Thread, ThreadParticipant
 
 
 
 
 class ThreadParticipantTests(TestCase):
 class ThreadParticipantTests(TestCase):

+ 8 - 8
misago/threads/tests/test_threads_api.py

@@ -1,15 +1,15 @@
 from datetime import timedelta
 from datetime import timedelta
 
 
-from django.utils import timezone
 from django.urls import reverse
 from django.urls import reverse
+from django.utils import timezone
 
 
-from misago.categories import THREADS_ROOT_NAME
-from misago.categories.models import Category
-from misago.threads import test
-from misago.threads.models import Thread
-from misago.threads.test import patch_category_acl
-from misago.threads.threadtypes import trees_map
-from misago.users.test import AuthenticatedUserTestCase
+from .. import test
+from ...categories import THREADS_ROOT_NAME
+from ...categories.models import Category
+from ...users.test import AuthenticatedUserTestCase
+from ..models import Thread
+from ..test import patch_category_acl
+from ..threadtypes import trees_map
 
 
 
 
 class ThreadsApiTestCase(AuthenticatedUserTestCase):
 class ThreadsApiTestCase(AuthenticatedUserTestCase):

+ 7 - 8
misago/threads/tests/test_threads_bulkdelete_api.py

@@ -2,14 +2,13 @@ import json
 
 
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.categories import PRIVATE_THREADS_ROOT_NAME
-from misago.categories.models import Category
-from misago.threads import test
-from misago.threads.models import Thread
-from misago.threads.serializers.moderation import THREADS_LIMIT
-from misago.threads.test import patch_category_acl
-from misago.threads.threadtypes import trees_map
-
+from .. import test
+from ...categories import PRIVATE_THREADS_ROOT_NAME
+from ...categories.models import Category
+from ..models import Thread
+from ..serializers.moderation import THREADS_LIMIT
+from ..test import patch_category_acl
+from ..threadtypes import trees_map
 from .test_threads_api import ThreadsApiTestCase
 from .test_threads_api import ThreadsApiTestCase
 
 
 
 

+ 9 - 9
misago/threads/tests/test_threads_editor_api.py

@@ -2,15 +2,15 @@ import os
 
 
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.acl import useracl
-from misago.acl.objectacl import add_acl_to_obj
-from misago.categories.models import Category
-from misago.conftest import get_cache_versions
-from misago.threads import test
-from misago.threads.models import Attachment
-from misago.threads.serializers import AttachmentSerializer
-from misago.threads.test import patch_category_acl
-from misago.users.test import AuthenticatedUserTestCase
+from .. import test
+from ...acl import useracl
+from ...acl.objectacl import add_acl_to_obj
+from ...categories.models import Category
+from ...conftest import get_cache_versions
+from ...users.test import AuthenticatedUserTestCase
+from ..models import Attachment
+from ..serializers import AttachmentSerializer
+from ..test import patch_category_acl
 
 
 TESTFILES_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "testfiles")
 TESTFILES_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "testfiles")
 TEST_DOCUMENT_PATH = os.path.join(TESTFILES_DIR, "document.pdf")
 TEST_DOCUMENT_PATH = os.path.join(TESTFILES_DIR, "document.pdf")

+ 10 - 11
misago/threads/tests/test_threads_merge_api.py

@@ -2,17 +2,16 @@ import json
 
 
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.acl import useracl
-from misago.acl.objectacl import add_acl_to_obj
-from misago.categories.models import Category
-from misago.conftest import get_cache_versions
-from misago.readtracker import poststracker
-from misago.threads import test
-from misago.threads.models import Poll, PollVote, Post, Thread
-from misago.threads.serializers import ThreadsListSerializer
-from misago.threads.serializers.moderation import THREADS_LIMIT
-from misago.threads.test import patch_category_acl, patch_other_category_acl
-
+from .. import test
+from ...acl import useracl
+from ...acl.objectacl import add_acl_to_obj
+from ...categories.models import Category
+from ...conftest import get_cache_versions
+from ...readtracker import poststracker
+from ..models import Poll, PollVote, Post, Thread
+from ..serializers import ThreadsListSerializer
+from ..serializers.moderation import THREADS_LIMIT
+from ..test import patch_category_acl, patch_other_category_acl
 from .test_threads_api import ThreadsApiTestCase
 from .test_threads_api import ThreadsApiTestCase
 
 
 cache_versions = get_cache_versions()
 cache_versions = get_cache_versions()

+ 4 - 4
misago/threads/tests/test_threads_moderation.py

@@ -1,7 +1,7 @@
-from misago.categories.models import Category
-from misago.threads import moderation, test
-from misago.threads.models import Thread
-from misago.users.test import AuthenticatedUserTestCase
+from .. import moderation, test
+from ...categories.models import Category
+from ...users.test import AuthenticatedUserTestCase
+from ..models import Thread
 
 
 
 
 class MockRequest(object):
 class MockRequest(object):

+ 7 - 7
misago/threads/tests/test_threadslists.py

@@ -4,13 +4,13 @@ from django.urls import reverse
 from django.utils import timezone
 from django.utils import timezone
 from django.utils.encoding import smart_str
 from django.utils.encoding import smart_str
 
 
-from misago.acl.test import patch_user_acl
-from misago.categories.models import Category
-from misago.conf import settings
-from misago.readtracker import poststracker
-from misago.threads import test
-from misago.users.models import AnonymousUser
-from misago.users.test import AuthenticatedUserTestCase
+from .. import test
+from ...acl.test import patch_user_acl
+from ...categories.models import Category
+from ...conf import settings
+from ...readtracker import poststracker
+from ...users.models import AnonymousUser
+from ...users.test import AuthenticatedUserTestCase
 
 
 LISTS_URLS = ("", "my/", "new/", "unread/", "subscribed/")
 LISTS_URLS = ("", "my/", "new/", "unread/", "subscribed/")
 
 

+ 11 - 11
misago/threads/tests/test_threadview.py

@@ -1,16 +1,16 @@
 from unittest.mock import Mock
 from unittest.mock import Mock
 
 
-from misago.acl import useracl
-from misago.acl.test import patch_user_acl
-from misago.categories.models import Category
-from misago.conf import settings
-from misago.conftest import get_cache_versions
-from misago.threads import test
-from misago.threads.checksums import update_post_checksum
-from misago.threads.events import record_event
-from misago.threads.moderation import threads as threads_moderation
-from misago.threads.moderation import hide_post
-from misago.users.test import AuthenticatedUserTestCase
+from .. import test
+from ...acl import useracl
+from ...acl.test import patch_user_acl
+from ...categories.models import Category
+from ...conf import settings
+from ...conftest import get_cache_versions
+from ...users.test import AuthenticatedUserTestCase
+from ..checksums import update_post_checksum
+from ..events import record_event
+from ..moderation import hide_post
+from ..moderation import threads as threads_moderation
 
 
 cache_versions = get_cache_versions()
 cache_versions = get_cache_versions()
 
 

+ 2 - 3
misago/threads/tests/test_treesmap.py

@@ -1,8 +1,7 @@
 from django.test import TestCase
 from django.test import TestCase
 
 
-from misago.categories.models import Category
-from misago.threads.threadtypes.treesmap import TreesMap
-
+from ...categories.models import Category
+from ..threadtypes.treesmap import TreesMap
 
 
 THREAD_TYPE = "misago.threads.threadtypes.thread.Thread"
 THREAD_TYPE = "misago.threads.threadtypes.thread.Thread"
 
 

+ 4 - 4
misago/threads/tests/test_updatepostschecksums.py

@@ -3,10 +3,10 @@ from io import StringIO
 from django.core.management import call_command
 from django.core.management import call_command
 from django.test import TestCase
 from django.test import TestCase
 
 
-from misago.categories.models import Category
-from misago.threads import test
-from misago.threads.management.commands import updatepostschecksums
-from misago.threads.models import Post
+from .. import test
+from ...categories.models import Category
+from ..management.commands import updatepostschecksums
+from ..models import Post
 
 
 
 
 class UpdatePostsChecksumsTests(TestCase):
 class UpdatePostsChecksumsTests(TestCase):

+ 3 - 3
misago/threads/tests/test_utils.py

@@ -1,8 +1,8 @@
 from django.test import TestCase
 from django.test import TestCase
 
 
-from misago.categories.models import Category
-from misago.threads import test
-from misago.threads.utils import add_categories_to_items, get_thread_id_from_url
+from .. import test
+from ...categories.models import Category
+from ..utils import add_categories_to_items, get_thread_id_from_url
 
 
 
 
 class AddCategoriesToItemsTests(TestCase):
 class AddCategoriesToItemsTests(TestCase):

+ 2 - 2
misago/threads/tests/test_validate_post.py

@@ -1,7 +1,7 @@
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.categories.models import Category
-from misago.users.test import AuthenticatedUserTestCase
+from ...categories.models import Category
+from ...users.test import AuthenticatedUserTestCase
 
 
 
 
 class ValidatePostTests(AuthenticatedUserTestCase):
 class ValidatePostTests(AuthenticatedUserTestCase):

+ 1 - 1
misago/threads/tests/test_validators.py

@@ -3,7 +3,7 @@ from unittest.mock import Mock
 from django.core.exceptions import ValidationError
 from django.core.exceptions import ValidationError
 from django.test import TestCase
 from django.test import TestCase
 
 
-from misago.threads.validators import validate_post_length, validate_thread_title
+from ..validators import validate_post_length, validate_thread_title
 
 
 
 
 class ValidatePostLengthTests(TestCase):
 class ValidatePostLengthTests(TestCase):

+ 1 - 2
misago/threads/threadtypes/privatethread.py

@@ -1,9 +1,8 @@
 from django.urls import reverse
 from django.urls import reverse
 from django.utils.translation import gettext_lazy as _
 from django.utils.translation import gettext_lazy as _
 
 
-from misago.categories import PRIVATE_THREADS_ROOT_NAME
-
 from . import ThreadType
 from . import ThreadType
+from ...categories import PRIVATE_THREADS_ROOT_NAME
 
 
 
 
 class PrivateThread(ThreadType):
 class PrivateThread(ThreadType):

+ 1 - 2
misago/threads/threadtypes/thread.py

@@ -1,9 +1,8 @@
 from django.urls import reverse
 from django.urls import reverse
 from django.utils.translation import gettext_lazy as _
 from django.utils.translation import gettext_lazy as _
 
 
-from misago.categories import THREADS_ROOT_NAME
-
 from . import ThreadType
 from . import ThreadType
+from ...categories import THREADS_ROOT_NAME
 
 
 
 
 class Thread(ThreadType):
 class Thread(ThreadType):

+ 2 - 2
misago/threads/threadtypes/treesmap.py

@@ -1,6 +1,6 @@
 from django.utils.module_loading import import_string
 from django.utils.module_loading import import_string
 
 
-from misago.conf import settings
+from ...conf import settings
 
 
 
 
 class TreesMap(object):
 class TreesMap(object):
@@ -24,7 +24,7 @@ class TreesMap(object):
         return loaded_types
         return loaded_types
 
 
     def load_trees(self, types):
     def load_trees(self, types):
-        from misago.categories.models import Category
+        from ...categories.models import Category
 
 
         trees = {}
         trees = {}
         for category in Category.objects.filter(level=0, special_role__in=types.keys()):
         for category in Category.objects.filter(level=0, special_role__in=types.keys()):

+ 5 - 9
misago/threads/urls/__init__.py

@@ -1,9 +1,9 @@
 from django.conf.urls import url
 from django.conf.urls import url
 
 
-from misago.conf import settings
+from ...conf import settings
 
 
-from misago.threads.views.attachment import attachment_server
-from misago.threads.views.goto import (
+from ..views.attachment import attachment_server
+from ..views.goto import (
     ThreadGotoPostView,
     ThreadGotoPostView,
     ThreadGotoLastView,
     ThreadGotoLastView,
     ThreadGotoNewView,
     ThreadGotoNewView,
@@ -13,12 +13,8 @@ from misago.threads.views.goto import (
     PrivateThreadGotoLastView,
     PrivateThreadGotoLastView,
     PrivateThreadGotoNewView,
     PrivateThreadGotoNewView,
 )
 )
-from misago.threads.views.list import (
-    ForumThreadsList,
-    CategoryThreadsList,
-    PrivateThreadsList,
-)
-from misago.threads.views.thread import ThreadView, PrivateThreadView
+from ..views.list import ForumThreadsList, CategoryThreadsList, PrivateThreadsList
+from ..views.thread import ThreadView, PrivateThreadView
 
 
 LISTS_TYPES = ("all", "my", "new", "unread", "subscribed", "unapproved")
 LISTS_TYPES = ("all", "my", "new", "unread", "subscribed", "unapproved")
 
 

+ 5 - 6
misago/threads/urls/api.py

@@ -1,9 +1,8 @@
-from misago.core.apirouter import MisagoApiRouter
-from misago.threads.api.attachments import AttachmentViewSet
-from misago.threads.api.threadpoll import ThreadPollViewSet
-from misago.threads.api.threadposts import PrivateThreadPostsViewSet, ThreadPostsViewSet
-from misago.threads.api.threads import PrivateThreadViewSet, ThreadViewSet
-
+from ...core.apirouter import MisagoApiRouter
+from ..api.attachments import AttachmentViewSet
+from ..api.threadpoll import ThreadPollViewSet
+from ..api.threadposts import PrivateThreadPostsViewSet, ThreadPostsViewSet
+from ..api.threads import PrivateThreadViewSet, ThreadViewSet
 
 
 router = MisagoApiRouter()
 router = MisagoApiRouter()
 
 

+ 5 - 6
misago/threads/validators.py

@@ -3,12 +3,11 @@ from django.utils.module_loading import import_string
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
 from django.utils.translation import ngettext
 from django.utils.translation import ngettext
 
 
-from misago.categories import THREADS_ROOT_NAME
-from misago.categories.models import Category
-from misago.categories.permissions import can_browse_category, can_see_category
-from misago.conf import settings
-from misago.core.validators import validate_sluggable
-
+from ..categories import THREADS_ROOT_NAME
+from ..categories.models import Category
+from ..categories.permissions import can_browse_category, can_see_category
+from ..conf import settings
+from ..core.validators import validate_sluggable
 from .threadtypes import trees_map
 from .threadtypes import trees_map
 
 
 
 

+ 7 - 8
misago/threads/viewmodels/category.py

@@ -1,13 +1,12 @@
 from django.http import Http404
 from django.http import Http404
 
 
-from misago.acl.objectacl import add_acl_to_obj
-from misago.categories.models import Category
-from misago.categories.permissions import allow_browse_category, allow_see_category
-from misago.categories.serializers import CategorySerializer
-from misago.core.shortcuts import validate_slug
-from misago.core.viewmodel import ViewModel as BaseViewModel
-from misago.threads.permissions import allow_use_private_threads
-
+from ...acl.objectacl import add_acl_to_obj
+from ...categories.models import Category
+from ...categories.permissions import allow_browse_category, allow_see_category
+from ...categories.serializers import CategorySerializer
+from ...core.shortcuts import validate_slug
+from ...core.viewmodel import ViewModel as BaseViewModel
+from ..permissions import allow_use_private_threads
 
 
 __all__ = ["ThreadsRootCategory", "ThreadsCategory", "PrivateThreadsCategory"]
 __all__ = ["ThreadsRootCategory", "ThreadsCategory", "PrivateThreadsCategory"]
 
 

+ 3 - 4
misago/threads/viewmodels/post.py

@@ -1,9 +1,8 @@
 from django.shortcuts import get_object_or_404
 from django.shortcuts import get_object_or_404
 
 
-from misago.acl.objectacl import add_acl_to_obj
-from misago.core.viewmodel import ViewModel as BaseViewModel
-from misago.threads.permissions import exclude_invisible_posts
-
+from ...acl.objectacl import add_acl_to_obj
+from ...core.viewmodel import ViewModel as BaseViewModel
+from ..permissions import exclude_invisible_posts
 
 
 __all__ = ["ThreadPost"]
 __all__ = ["ThreadPost"]
 
 

+ 9 - 10
misago/threads/viewmodels/posts.py

@@ -1,13 +1,12 @@
-from misago.acl.objectacl import add_acl_to_obj
-from misago.conf import settings
-from misago.core.shortcuts import paginate, pagination_dict
-from misago.readtracker.poststracker import make_read_aware
-from misago.threads.paginator import PostsPaginator
-from misago.threads.permissions import exclude_invisible_posts
-from misago.threads.serializers import PostSerializer
-from misago.threads.utils import add_likes_to_posts
-from misago.users.online.utils import make_users_status_aware
-
+from ...acl.objectacl import add_acl_to_obj
+from ...conf import settings
+from ...core.shortcuts import paginate, pagination_dict
+from ...readtracker.poststracker import make_read_aware
+from ...users.online.utils import make_users_status_aware
+from ..paginator import PostsPaginator
+from ..permissions import exclude_invisible_posts
+from ..serializers import PostSerializer
+from ..utils import add_likes_to_posts
 
 
 __all__ = ["ThreadPosts"]
 __all__ = ["ThreadPosts"]
 
 

+ 12 - 13
misago/threads/viewmodels/thread.py

@@ -1,23 +1,22 @@
 from django.shortcuts import get_object_or_404
 from django.shortcuts import get_object_or_404
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
 
 
-from misago.acl.objectacl import add_acl_to_obj
-from misago.categories import PRIVATE_THREADS_ROOT_NAME, THREADS_ROOT_NAME
-from misago.categories.models import Category
-from misago.core.shortcuts import validate_slug
-from misago.core.viewmodel import ViewModel as BaseViewModel
-from misago.readtracker.threadstracker import make_read_aware
-from misago.threads.models import Poll, Thread
-from misago.threads.participants import make_participants_aware
-from misago.threads.permissions import (
+from ...acl.objectacl import add_acl_to_obj
+from ...categories import PRIVATE_THREADS_ROOT_NAME, THREADS_ROOT_NAME
+from ...categories.models import Category
+from ...core.shortcuts import validate_slug
+from ...core.viewmodel import ViewModel as BaseViewModel
+from ...readtracker.threadstracker import make_read_aware
+from ..models import Poll, Thread
+from ..participants import make_participants_aware
+from ..permissions import (
     allow_see_private_thread,
     allow_see_private_thread,
     allow_see_thread,
     allow_see_thread,
     allow_use_private_threads,
     allow_use_private_threads,
 )
 )
-from misago.threads.serializers import PrivateThreadSerializer, ThreadSerializer
-from misago.threads.subscriptions import make_subscription_aware
-from misago.threads.threadtypes import trees_map
-
+from ..serializers import PrivateThreadSerializer, ThreadSerializer
+from ..subscriptions import make_subscription_aware
+from ..threadtypes import trees_map
 
 
 __all__ = ["ForumThread", "PrivateThread"]
 __all__ = ["ForumThread", "PrivateThread"]
 
 

+ 11 - 14
misago/threads/viewmodels/threads.py

@@ -7,20 +7,17 @@ from django.utils import timezone
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext_lazy
 from django.utils.translation import gettext_lazy
 
 
-from misago.acl.objectacl import add_acl_to_obj
-from misago.conf import settings
-from misago.core.shortcuts import paginate, pagination_dict
-from misago.readtracker import threadstracker
-from misago.readtracker.dates import get_cutoff_date
-from misago.threads.models import Post, Thread
-from misago.threads.participants import make_participants_aware
-from misago.threads.permissions import (
-    exclude_invisible_posts,
-    exclude_invisible_threads,
-)
-from misago.threads.serializers import ThreadsListSerializer
-from misago.threads.subscriptions import make_subscription_aware
-from misago.threads.utils import add_categories_to_items
+from ...acl.objectacl import add_acl_to_obj
+from ...conf import settings
+from ...core.shortcuts import paginate, pagination_dict
+from ...readtracker import threadstracker
+from ...readtracker.dates import get_cutoff_date
+from ..models import Post, Thread
+from ..participants import make_participants_aware
+from ..permissions import exclude_invisible_posts, exclude_invisible_threads
+from ..serializers import ThreadsListSerializer
+from ..subscriptions import make_subscription_aware
+from ..utils import add_categories_to_items
 
 
 __all__ = ["ForumThreads", "PrivateThreads", "filter_read_threads_queryset"]
 __all__ = ["ForumThreads", "PrivateThreads", "filter_read_threads_queryset"]
 
 

+ 3 - 3
misago/threads/views/admin/attachments.py

@@ -2,9 +2,9 @@ from django.contrib import messages
 from django.db import transaction
 from django.db import transaction
 from django.utils.translation import gettext_lazy as _
 from django.utils.translation import gettext_lazy as _
 
 
-from misago.admin.views import generic
-from misago.threads.forms import SearchAttachmentsForm
-from misago.threads.models import Attachment, Post
+from ....admin.views import generic
+from ...forms import SearchAttachmentsForm
+from ...models import Attachment, Post
 
 
 
 
 class AttachmentAdmin(generic.AdminBaseMixin):
 class AttachmentAdmin(generic.AdminBaseMixin):

+ 3 - 3
misago/threads/views/admin/attachmenttypes.py

@@ -2,9 +2,9 @@ from django.contrib import messages
 from django.db.models import Count
 from django.db.models import Count
 from django.utils.translation import gettext_lazy as _
 from django.utils.translation import gettext_lazy as _
 
 
-from misago.admin.views import generic
-from misago.threads.forms import AttachmentTypeForm
-from misago.threads.models import AttachmentType
+from ....admin.views import generic
+from ...forms import AttachmentTypeForm
+from ...models import AttachmentType
 
 
 
 
 class AttachmentTypeAdmin(generic.AdminBaseMixin):
 class AttachmentTypeAdmin(generic.AdminBaseMixin):

+ 2 - 3
misago/threads/views/attachment.py

@@ -2,9 +2,8 @@ from django.core.exceptions import PermissionDenied
 from django.http import Http404
 from django.http import Http404
 from django.shortcuts import get_object_or_404, redirect
 from django.shortcuts import get_object_or_404, redirect
 
 
-from misago.conf import settings
-from misago.threads.models import Attachment, AttachmentType
-
+from ...conf import settings
+from ..models import Attachment, AttachmentType
 
 
 ATTACHMENT_404_URL = "".join((settings.STATIC_URL, settings.MISAGO_404_IMAGE))
 ATTACHMENT_404_URL = "".join((settings.STATIC_URL, settings.MISAGO_404_IMAGE))
 ATTACHMENT_403_URL = "".join((settings.STATIC_URL, settings.MISAGO_403_IMAGE))
 ATTACHMENT_403_URL = "".join((settings.STATIC_URL, settings.MISAGO_403_IMAGE))

+ 4 - 4
misago/threads/views/goto.py

@@ -6,10 +6,10 @@ from django.shortcuts import get_object_or_404, redirect
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
 from django.views import View
 from django.views import View
 
 
-from misago.conf import settings
-from misago.readtracker.dates import get_cutoff_date
-from misago.threads.permissions import exclude_invisible_posts
-from misago.threads.viewmodels import ForumThread, PrivateThread
+from ...conf import settings
+from ...readtracker.dates import get_cutoff_date
+from ..permissions import exclude_invisible_posts
+from ..viewmodels import ForumThread, PrivateThread
 
 
 
 
 class GotoView(View):
 class GotoView(View):

+ 2 - 2
misago/threads/views/list.py

@@ -3,8 +3,8 @@ from django.shortcuts import render
 from django.urls import reverse
 from django.urls import reverse
 from django.views import View
 from django.views import View
 
 
-from misago.core.shortcuts import get_int_or_404
-from misago.threads.viewmodels import (
+from ...core.shortcuts import get_int_or_404
+from ..viewmodels import (
     ForumThreads,
     ForumThreads,
     PrivateThreads,
     PrivateThreads,
     PrivateThreadsCategory,
     PrivateThreadsCategory,

+ 1 - 1
misago/threads/views/thread.py

@@ -2,7 +2,7 @@ from django.shortcuts import render
 from django.urls import reverse
 from django.urls import reverse
 from django.views import View
 from django.views import View
 
 
-from misago.threads.viewmodels import ForumThread, PrivateThread, ThreadPosts
+from ..viewmodels import ForumThread, PrivateThread, ThreadPosts
 
 
 
 
 class ThreadBase(View):
 class ThreadBase(View):

+ 2 - 3
misago/urls.py

@@ -1,9 +1,8 @@
 from django.conf.urls import include, url
 from django.conf.urls import include, url
 from django.views.generic import TemplateView
 from django.views.generic import TemplateView
 
 
-from misago.conf import settings
-from misago.core.views import forum_index
-
+from .conf import settings
+from .core.views import forum_index
 
 
 app_name = "misago"
 app_name = "misago"
 
 

+ 2 - 4
misago/users/activepostersranking.py

@@ -4,12 +4,10 @@ from django.contrib.auth import get_user_model
 from django.db.models import Count
 from django.db.models import Count
 from django.utils import timezone
 from django.utils import timezone
 
 
-from misago.categories.models import Category
-from misago.conf import settings
-
+from ..categories.models import Category
+from ..conf import settings
 from .models import ActivityRanking
 from .models import ActivityRanking
 
 
-
 User = get_user_model()
 User = get_user_model()
 
 
 
 

+ 0 - 1
misago/users/admin.py

@@ -25,7 +25,6 @@ from .views.admin.users import (
     UsersList,
     UsersList,
 )
 )
 
 
-
 djadmin.site.register(model_or_iterable=get_user_model(), admin_class=UserAdminModel)
 djadmin.site.register(model_or_iterable=get_user_model(), admin_class=UserAdminModel)
 
 
 
 

+ 10 - 20
misago/users/api/auth.py

@@ -1,35 +1,25 @@
-from rest_framework import status
-from rest_framework.decorators import api_view, permission_classes
-from rest_framework.response import Response
-
 from django.contrib import auth
 from django.contrib import auth
 from django.contrib.auth.password_validation import validate_password
 from django.contrib.auth.password_validation import validate_password
 from django.core.exceptions import ValidationError
 from django.core.exceptions import ValidationError
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
 from django.views.decorators.csrf import csrf_protect
 from django.views.decorators.csrf import csrf_protect
+from rest_framework import status
+from rest_framework.decorators import api_view, permission_classes
+from rest_framework.response import Response
 
 
-from misago.conf import settings
-from misago.core.decorators import require_dict_data
-from misago.core.mail import mail_user
-from misago.users.bans import get_user_ban
-from misago.users.forms.auth import (
-    AuthenticationForm,
-    ResendActivationForm,
-    ResetPasswordForm,
-)
-from misago.users.serializers import (
-    AnonymousUserSerializer,
-    AuthenticatedUserSerializer,
-)
-from misago.users.tokens import (
+from ...conf import settings
+from ...core.decorators import require_dict_data
+from ...core.mail import mail_user
+from ..bans import get_user_ban
+from ..forms.auth import AuthenticationForm, ResendActivationForm, ResetPasswordForm
+from ..serializers import AnonymousUserSerializer, AuthenticatedUserSerializer
+from ..tokens import (
     is_password_change_token_valid,
     is_password_change_token_valid,
     make_activation_token,
     make_activation_token,
     make_password_change_token,
     make_password_change_token,
 )
 )
-
 from .rest_permissions import UnbannedAnonOnly, UnbannedOnly
 from .rest_permissions import UnbannedAnonOnly, UnbannedOnly
 
 
-
 User = auth.get_user_model()
 User = auth.get_user_model()
 
 
 
 

+ 1 - 2
misago/users/api/captcha.py

@@ -1,8 +1,7 @@
+from django.http import Http404
 from rest_framework.decorators import api_view
 from rest_framework.decorators import api_view
 from rest_framework.response import Response
 from rest_framework.response import Response
 
 
-from django.http import Http404
-
 
 
 @api_view()
 @api_view()
 def question(request):
 def question(request):

+ 3 - 5
misago/users/api/mention.py

@@ -1,11 +1,9 @@
-from rest_framework.decorators import api_view
-from rest_framework.response import Response
-
 from django.contrib.auth import get_user_model
 from django.contrib.auth import get_user_model
 from django.contrib.staticfiles.templatetags.staticfiles import static
 from django.contrib.staticfiles.templatetags.staticfiles import static
+from rest_framework.decorators import api_view
+from rest_framework.response import Response
 
 
-from misago.conf import settings
-
+from ...conf import settings
 
 
 User = get_user_model()
 User = get_user_model()
 
 

+ 2 - 2
misago/users/api/ranks.py

@@ -1,7 +1,7 @@
 from rest_framework import mixins, viewsets
 from rest_framework import mixins, viewsets
 
 
-from misago.users.models import Rank
-from misago.users.serializers import RankSerializer
+from ..models import Rank
+from ..serializers import RankSerializer
 
 
 
 
 class RanksViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
 class RanksViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):

+ 4 - 5
misago/users/api/rest_permissions.py

@@ -1,11 +1,10 @@
-from rest_framework.permissions import BasePermission
-
 from django.core.exceptions import PermissionDenied
 from django.core.exceptions import PermissionDenied
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
+from rest_framework.permissions import BasePermission
 
 
-from misago.core.exceptions import Banned
-from misago.users.bans import get_request_ip_ban
-from misago.users.models import Ban
+from ...core.exceptions import Banned
+from ..bans import get_request_ip_ban
+from ..models import Ban
 
 
 
 
 class UnbannedOnly(BasePermission):
 class UnbannedOnly(BasePermission):

+ 8 - 9
misago/users/api/userendpoints/avatar.py

@@ -1,17 +1,16 @@
 import json
 import json
 
 
-from rest_framework import status
-from rest_framework.response import Response
-
 from django.core.exceptions import ValidationError
 from django.core.exceptions import ValidationError
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
+from rest_framework import status
+from rest_framework.response import Response
 
 
-from misago.conf import settings
-from misago.core.decorators import require_dict_data
-from misago.core.utils import format_plaintext_for_html
-from misago.users import avatars
-from misago.users.models import AvatarGallery
-from misago.users.serializers import ModerateAvatarSerializer
+from ... import avatars
+from ....conf import settings
+from ....core.decorators import require_dict_data
+from ....core.utils import format_plaintext_for_html
+from ...models import AvatarGallery
+from ...serializers import ModerateAvatarSerializer
 
 
 
 
 @require_dict_data
 @require_dict_data

+ 5 - 6
misago/users/api/userendpoints/changeemail.py

@@ -1,12 +1,11 @@
+from django.utils.translation import gettext as _
 from rest_framework import status
 from rest_framework import status
 from rest_framework.response import Response
 from rest_framework.response import Response
 
 
-from django.utils.translation import gettext as _
-
-from misago.conf import settings
-from misago.core.mail import mail_user
-from misago.users.credentialchange import store_new_credential
-from misago.users.serializers import ChangeEmailSerializer
+from ....conf import settings
+from ....core.mail import mail_user
+from ...credentialchange import store_new_credential
+from ...serializers import ChangeEmailSerializer
 
 
 
 
 def change_email_endpoint(request, pk=None):
 def change_email_endpoint(request, pk=None):

+ 4 - 5
misago/users/api/userendpoints/changepassword.py

@@ -1,11 +1,10 @@
+from django.utils.translation import gettext as _
 from rest_framework import status
 from rest_framework import status
 from rest_framework.response import Response
 from rest_framework.response import Response
 
 
-from django.utils.translation import gettext as _
-
-from misago.core.mail import mail_user
-from misago.users.credentialchange import store_new_credential
-from misago.users.serializers import ChangePasswordSerializer
+from ....core.mail import mail_user
+from ...credentialchange import store_new_credential
+from ...serializers import ChangePasswordSerializer
 
 
 
 
 def change_password_endpoint(request, pk=None):
 def change_password_endpoint(request, pk=None):

+ 8 - 9
misago/users/api/userendpoints/create.py

@@ -1,22 +1,21 @@
-from rest_framework import status
-from rest_framework.response import Response
-
 from django.contrib.auth import authenticate, get_user_model, login
 from django.contrib.auth import authenticate, get_user_model, login
 from django.core.exceptions import PermissionDenied, ValidationError
 from django.core.exceptions import PermissionDenied, ValidationError
 from django.db import IntegrityError
 from django.db import IntegrityError
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
 from django.views.decorators.csrf import csrf_protect
 from django.views.decorators.csrf import csrf_protect
+from rest_framework import status
+from rest_framework.response import Response
 
 
-from misago.conf import settings
-from misago.legal.models import Agreement
-from misago.users import captcha
-from misago.users.forms.register import RegisterForm
-from misago.users.registration import (
+from ... import captcha
+from ....conf import settings
+from ....legal.models import Agreement
+from ...forms.register import RegisterForm
+from ...registration import (
     get_registration_result_json,
     get_registration_result_json,
     save_user_agreements,
     save_user_agreements,
     send_welcome_email,
     send_welcome_email,
 )
 )
-from misago.users.setupnewuser import setup_new_user
+from ...setupnewuser import setup_new_user
 
 
 User = get_user_model()
 User = get_user_model()
 
 

+ 2 - 4
misago/users/api/userendpoints/editdetails.py

@@ -1,9 +1,7 @@
-from rest_framework.response import Response
-
 from django import forms
 from django import forms
+from rest_framework.response import Response
 
 
-
-from misago.users.profilefields import profilefields, serialize_profilefields_data
+from ...profilefields import profilefields, serialize_profilefields_data
 
 
 
 
 def edit_details_endpoint(request, user):
 def edit_details_endpoint(request, user):

+ 5 - 7
misago/users/api/userendpoints/list.py

@@ -1,13 +1,11 @@
-from rest_framework.response import Response
-
 from django.contrib.auth import get_user_model
 from django.contrib.auth import get_user_model
 from django.shortcuts import get_object_or_404
 from django.shortcuts import get_object_or_404
+from rest_framework.response import Response
 
 
-from misago.core.shortcuts import get_int_or_404
-from misago.users.models import Rank
-from misago.users.serializers import UserCardSerializer
-from misago.users.viewmodels import ActivePosters, RankUsers
-
+from ....core.shortcuts import get_int_or_404
+from ...models import Rank
+from ...serializers import UserCardSerializer
+from ...viewmodels import ActivePosters, RankUsers
 
 
 User = get_user_model()
 User = get_user_model()
 
 

+ 5 - 6
misago/users/api/userendpoints/signature.py

@@ -1,12 +1,11 @@
-from rest_framework import status
-from rest_framework.response import Response
-
 from django.core.exceptions import PermissionDenied
 from django.core.exceptions import PermissionDenied
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
+from rest_framework import status
+from rest_framework.response import Response
 
 
-from misago.core.utils import format_plaintext_for_html
-from misago.users.serializers import EditSignatureSerializer
-from misago.users.signatures import is_user_signature_valid, set_user_signature
+from ....core.utils import format_plaintext_for_html
+from ...serializers import EditSignatureSerializer
+from ...signatures import is_user_signature_valid, set_user_signature
 
 
 
 
 def signature_endpoint(request):
 def signature_endpoint(request):

+ 4 - 5
misago/users/api/userendpoints/username.py

@@ -1,11 +1,10 @@
-from rest_framework import status
-from rest_framework.response import Response
-
 from django.db import IntegrityError
 from django.db import IntegrityError
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
+from rest_framework import status
+from rest_framework.response import Response
 
 
-from misago.users.namechanges import get_username_options
-from misago.users.serializers import ChangeUsernameSerializer
+from ...namechanges import get_username_options
+from ...serializers import ChangeUsernameSerializer
 
 
 
 
 def username_endpoint(request):
 def username_endpoint(request):

+ 5 - 8
misago/users/api/usernamechanges.py

@@ -1,19 +1,16 @@
-from rest_framework import viewsets
-from rest_framework.response import Response
-
 from django.contrib.auth import get_user_model
 from django.contrib.auth import get_user_model
 from django.core.exceptions import PermissionDenied
 from django.core.exceptions import PermissionDenied
 from django.db.models import Q
 from django.db.models import Q
 from django.shortcuts import get_object_or_404
 from django.shortcuts import get_object_or_404
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
+from rest_framework import viewsets
+from rest_framework.response import Response
 
 
-from misago.core.shortcuts import get_int_or_404, paginate, pagination_dict
-from misago.users.models import UsernameChange
-from misago.users.serializers import UsernameChangeSerializer
-
+from ...core.shortcuts import get_int_or_404, paginate, pagination_dict
+from ..models import UsernameChange
+from ..serializers import UsernameChangeSerializer
 from .rest_permissions import BasePermission
 from .rest_permissions import BasePermission
 
 
-
 User = get_user_model()
 User = get_user_model()
 
 
 
 

+ 17 - 23
misago/users/api/users.py

@@ -1,8 +1,3 @@
-from rest_framework import status, viewsets
-from rest_framework.decorators import detail_route
-from rest_framework.parsers import FormParser, JSONParser, MultiPartParser
-from rest_framework.response import Response
-
 from django.contrib.auth import get_user_model
 from django.contrib.auth import get_user_model
 from django.core.exceptions import PermissionDenied
 from django.core.exceptions import PermissionDenied
 from django.db import transaction
 from django.db import transaction
@@ -10,20 +5,21 @@ from django.db.models import F
 from django.http import Http404
 from django.http import Http404
 from django.shortcuts import get_object_or_404
 from django.shortcuts import get_object_or_404
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
+from rest_framework import status, viewsets
+from rest_framework.decorators import detail_route
+from rest_framework.parsers import FormParser, JSONParser, MultiPartParser
+from rest_framework.response import Response
 
 
-from misago.acl.objectacl import add_acl_to_obj
-from misago.categories.models import Category
-from misago.conf import settings
-from misago.core.rest_permissions import IsAuthenticatedOrReadOnly
-from misago.core.shortcuts import get_int_or_404
-from misago.threads.moderation import hide_post, hide_thread
-from misago.users.bans import get_user_ban
-from misago.users.datadownloads import (
-    request_user_data_download,
-    user_has_data_download_request,
-)
-from misago.users.online.utils import get_user_status
-from misago.users.permissions import (
+from ...acl.objectacl import add_acl_to_obj
+from ...categories.models import Category
+from ...conf import settings
+from ...core.rest_permissions import IsAuthenticatedOrReadOnly
+from ...core.shortcuts import get_int_or_404
+from ...threads.moderation import hide_post, hide_thread
+from ..bans import get_user_ban
+from ..datadownloads import request_user_data_download, user_has_data_download_request
+from ..online.utils import get_user_status
+from ..permissions import (
     allow_browse_users_list,
     allow_browse_users_list,
     allow_delete_user,
     allow_delete_user,
     allow_edit_profile_details,
     allow_edit_profile_details,
@@ -32,16 +28,15 @@ from misago.users.permissions import (
     allow_rename_user,
     allow_rename_user,
     allow_see_ban_details,
     allow_see_ban_details,
 )
 )
-from misago.users.profilefields import profilefields, serialize_profilefields_data
-from misago.users.serializers import (
+from ..profilefields import profilefields, serialize_profilefields_data
+from ..serializers import (
     BanDetailsSerializer,
     BanDetailsSerializer,
     DataDownloadSerializer,
     DataDownloadSerializer,
     DeleteOwnAccountSerializer,
     DeleteOwnAccountSerializer,
     ForumOptionsSerializer,
     ForumOptionsSerializer,
     UserSerializer,
     UserSerializer,
 )
 )
-from misago.users.viewmodels import Followers, Follows, UserPosts, UserThreads
-
+from ..viewmodels import Followers, Follows, UserPosts, UserThreads
 from .rest_permissions import BasePermission, UnbannedAnonOnly
 from .rest_permissions import BasePermission, UnbannedAnonOnly
 from .userendpoints.avatar import avatar_endpoint, moderate_avatar_endpoint
 from .userendpoints.avatar import avatar_endpoint, moderate_avatar_endpoint
 from .userendpoints.changeemail import change_email_endpoint
 from .userendpoints.changeemail import change_email_endpoint
@@ -52,7 +47,6 @@ from .userendpoints.list import list_endpoint
 from .userendpoints.signature import signature_endpoint
 from .userendpoints.signature import signature_endpoint
 from .userendpoints.username import moderate_username_endpoint, username_endpoint
 from .userendpoints.username import moderate_username_endpoint, username_endpoint
 
 
-
 User = get_user_model()
 User = get_user_model()
 
 
 
 

+ 1 - 2
misago/users/apps.py

@@ -1,8 +1,7 @@
 from django.apps import AppConfig
 from django.apps import AppConfig
 from django.utils.translation import gettext_lazy as _
 from django.utils.translation import gettext_lazy as _
 
 
-from misago.conf import settings
-
+from ..conf import settings
 from .pages import user_profile, usercp, users_list
 from .pages import user_profile, usercp, users_list
 
 
 
 

+ 0 - 1
misago/users/authbackends.py

@@ -1,7 +1,6 @@
 from django.contrib.auth import get_user_model
 from django.contrib.auth import get_user_model
 from django.contrib.auth.backends import ModelBackend
 from django.contrib.auth.backends import ModelBackend
 
 
-
 User = get_user_model()
 User = get_user_model()
 
 
 
 

+ 1 - 2
misago/users/avatars/__init__.py

@@ -1,5 +1,4 @@
-from misago.conf import settings
-
+from ...conf import settings
 from . import store, gravatar, dynamic, gallery, uploaded
 from . import store, gravatar, dynamic, gallery, uploaded
 
 
 AVATAR_TYPES = ("gravatar", "dynamic", "gallery", "uploaded")
 AVATAR_TYPES = ("gravatar", "dynamic", "gallery", "uploaded")

+ 2 - 5
misago/users/avatars/dynamic.py

@@ -1,13 +1,10 @@
 import os
 import os
 
 
-from PIL import Image, ImageColor, ImageDraw, ImageFont
-
 from django.utils.module_loading import import_string
 from django.utils.module_loading import import_string
-
-from misago.conf import settings
+from PIL import Image, ImageColor, ImageDraw, ImageFont
 
 
 from . import store
 from . import store
-
+from ...conf import settings
 
 
 COLOR_WHEEL = (
 COLOR_WHEEL = (
     "#d32f2f",
     "#d32f2f",

+ 5 - 8
misago/users/avatars/gallery.py

@@ -1,14 +1,11 @@
 import random
 import random
 from pathlib import Path
 from pathlib import Path
 
 
-from PIL import Image
-
 from django.core.files.base import ContentFile
 from django.core.files.base import ContentFile
-
-from misago.conf import settings
+from PIL import Image
 
 
 from . import store
 from . import store
-
+from ...conf import settings
 
 
 DEFAULT_GALLERY = "__default__"
 DEFAULT_GALLERY = "__default__"
 
 
@@ -20,7 +17,7 @@ def get_available_galleries(include_default=False):
     Only jpgs, gifs and pngs are supported avatar images.
     Only jpgs, gifs and pngs are supported avatar images.
     Galleries are
     Galleries are
     """
     """
-    from misago.users.models import AvatarGallery
+    from ..models import AvatarGallery
 
 
     galleries = []
     galleries = []
     galleries_dicts = {}
     galleries_dicts = {}
@@ -40,13 +37,13 @@ def get_available_galleries(include_default=False):
 
 
 
 
 def galleries_exist():
 def galleries_exist():
-    from misago.users.models import AvatarGallery
+    from ..models import AvatarGallery
 
 
     return AvatarGallery.objects.exists()
     return AvatarGallery.objects.exists()
 
 
 
 
 def load_avatar_galleries():
 def load_avatar_galleries():
-    from misago.users.models import AvatarGallery
+    from ..models import AvatarGallery
 
 
     galleries = []
     galleries = []
     for directory in Path(settings.MISAGO_AVATAR_GALLERY).iterdir():
     for directory in Path(settings.MISAGO_AVATAR_GALLERY).iterdir():

+ 1 - 3
misago/users/avatars/gravatar.py

@@ -3,10 +3,8 @@ from io import BytesIO
 import requests
 import requests
 from PIL import Image
 from PIL import Image
 
 
-from misago.conf import settings
-
 from . import store
 from . import store
-
+from ...conf import settings
 
 
 GRAVATAR_URL = "http://www.gravatar.com/avatar/%s?s=%s&d=404"
 GRAVATAR_URL = "http://www.gravatar.com/avatar/%s?s=%s&d=404"
 
 

+ 3 - 4
misago/users/avatars/store.py

@@ -2,12 +2,11 @@ import os
 from hashlib import md5
 from hashlib import md5
 from io import BytesIO
 from io import BytesIO
 
 
-from PIL import Image
-
 from django.core.files.base import ContentFile
 from django.core.files.base import ContentFile
 from django.utils.crypto import get_random_string
 from django.utils.crypto import get_random_string
+from PIL import Image
 
 
-from misago.conf import settings
+from ...conf import settings
 
 
 
 
 def normalize_image(image):
 def normalize_image(image):
@@ -29,7 +28,7 @@ def delete_avatar(user, delete_tmp=True, delete_src=True):
 
 
 
 
 def store_avatar(user, image):
 def store_avatar(user, image):
-    from misago.users.models import Avatar
+    from ..models import Avatar
 
 
     image = normalize_image(image)
     image = normalize_image(image)
 
 

+ 2 - 4
misago/users/avatars/uploaded.py

@@ -1,13 +1,11 @@
 from pathlib import Path
 from pathlib import Path
 
 
-from PIL import Image
-
 from django.core.exceptions import ValidationError
 from django.core.exceptions import ValidationError
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
-
-from misago.conf import settings
+from PIL import Image
 
 
 from . import store
 from . import store
+from ...conf import settings
 
 
 ALLOWED_EXTENSIONS = (".gif", ".png", ".jpg", ".jpeg")
 ALLOWED_EXTENSIONS = (".gif", ".png", ".jpg", ".jpeg")
 ALLOWED_MIME_TYPES = ("image/gif", "image/jpeg", "image/png", "image/mpo")
 ALLOWED_MIME_TYPES = ("image/gif", "image/jpeg", "image/png", "image/mpo")

+ 0 - 1
misago/users/captcha.py

@@ -1,5 +1,4 @@
 import requests
 import requests
-
 from django.core.exceptions import ValidationError
 from django.core.exceptions import ValidationError
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
 
 

+ 3 - 3
misago/users/datadownloads/__init__.py

@@ -2,9 +2,9 @@ from datetime import timedelta
 
 
 from django.utils import timezone
 from django.utils import timezone
 
 
-from misago.conf import settings
-from misago.users.models import DataDownload
-from misago.users.signals import archive_user_data
+from ...conf import settings
+from ..models import DataDownload
+from ..signals import archive_user_data
 
 
 from .dataarchive import DataArchive
 from .dataarchive import DataArchive
 
 

+ 1 - 2
misago/users/datadownloads/dataarchive.py

@@ -5,8 +5,7 @@ from django.core.files import File
 from django.utils import timezone
 from django.utils import timezone
 from django.utils.crypto import get_random_string
 from django.utils.crypto import get_random_string
 
 
-from misago.core.utils import slugify
-
+from ...core.utils import slugify
 
 
 FILENAME_MAX_LEN = 50
 FILENAME_MAX_LEN = 50
 
 

+ 1 - 2
misago/users/decorators.py

@@ -3,8 +3,7 @@ from django.core.exceptions import PermissionDenied
 from django.shortcuts import redirect
 from django.shortcuts import redirect
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
 
 
-from misago.core.exceptions import Banned
-
+from ..core.exceptions import Banned
 from .bans import get_request_ip_ban
 from .bans import get_request_ip_ban
 from .models import Ban
 from .models import Ban
 
 

+ 8 - 9
misago/users/forms/admin.py

@@ -1,18 +1,17 @@
 from django import forms
 from django import forms
-from django.db.models import Q
 from django.contrib.auth import get_user_model
 from django.contrib.auth import get_user_model
 from django.contrib.auth.password_validation import validate_password
 from django.contrib.auth.password_validation import validate_password
+from django.db.models import Q
 from django.utils.translation import gettext_lazy as _
 from django.utils.translation import gettext_lazy as _
 from django.utils.translation import ngettext
 from django.utils.translation import ngettext
 
 
-from misago.acl.models import Role
-from misago.admin.forms import IsoDateTimeField, YesNoSwitch
-from misago.core.validators import validate_sluggable
-
-from misago.users.models import Ban, DataDownload, Rank
-from misago.users.profilefields import profilefields
-from misago.users.utils import hash_email
-from misago.users.validators import validate_email, validate_username
+from ...acl.models import Role
+from ...admin.forms import IsoDateTimeField, YesNoSwitch
+from ...core.validators import validate_sluggable
+from ..models import Ban, DataDownload, Rank
+from ..profilefields import profilefields
+from ..utils import hash_email
+from ..validators import validate_email, validate_username
 
 
 User = get_user_model()
 User = get_user_model()
 
 

+ 1 - 2
misago/users/forms/auth.py

@@ -5,8 +5,7 @@ from django.core.exceptions import ValidationError
 from django.core.validators import validate_email
 from django.core.validators import validate_email
 from django.utils.translation import gettext_lazy as _
 from django.utils.translation import gettext_lazy as _
 
 
-from misago.users.bans import get_user_ban
-
+from ..bans import get_user_ban
 
 
 User = get_user_model()
 User = get_user_model()
 
 

+ 2 - 7
misago/users/forms/register.py

@@ -4,13 +4,8 @@ from django.contrib.auth.password_validation import validate_password
 from django.core.exceptions import ValidationError
 from django.core.exceptions import ValidationError
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
 
 
-from misago.users.bans import get_email_ban, get_ip_ban, get_username_ban
-from misago.users.validators import (
-    validate_email,
-    validate_new_registration,
-    validate_username,
-)
-
+from ..bans import get_email_ban, get_ip_ban, get_username_ban
+from ..validators import validate_email, validate_new_registration, validate_username
 
 
 User = get_user_model()
 User = get_user_model()
 
 

+ 2 - 1
misago/users/management/commands/buildactivepostersranking.py

@@ -1,7 +1,8 @@
 from time import time
 from time import time
+
 from django.core.management.base import BaseCommand
 from django.core.management.base import BaseCommand
 
 
-from misago.users.activepostersranking import build_active_posters_ranking
+from ...activepostersranking import build_active_posters_ranking
 
 
 
 
 class Command(BaseCommand):
 class Command(BaseCommand):

+ 4 - 5
misago/users/management/commands/createsuperuser.py

@@ -12,11 +12,10 @@ from django.core.management.base import BaseCommand
 from django.db import DEFAULT_DB_ALIAS, IntegrityError
 from django.db import DEFAULT_DB_ALIAS, IntegrityError
 from django.utils.encoding import force_str
 from django.utils.encoding import force_str
 
 
-from misago.cache.versions import get_cache_versions
-from misago.conf.dynamicsettings import DynamicSettings
-
-from misago.users.setupnewuser import setup_new_user
-from misago.users.validators import validate_email, validate_username
+from ....cache.versions import get_cache_versions
+from ....conf.dynamicsettings import DynamicSettings
+from ...setupnewuser import setup_new_user
+from ...validators import validate_email, validate_username
 
 
 User = get_user_model()
 User = get_user_model()
 
 

+ 2 - 3
misago/users/management/commands/deleteinactiveusers.py

@@ -4,9 +4,8 @@ from django.contrib.auth import get_user_model
 from django.core.management.base import BaseCommand
 from django.core.management.base import BaseCommand
 from django.utils import timezone
 from django.utils import timezone
 
 
-from misago.conf import settings
-from misago.core.pgutils import chunk_queryset
-
+from ....conf import settings
+from ....core.pgutils import chunk_queryset
 
 
 User = get_user_model()
 User = get_user_model()
 
 

+ 4 - 6
misago/users/management/commands/deletemarkedusers.py

@@ -1,11 +1,9 @@
 from django.contrib.auth import get_user_model
 from django.contrib.auth import get_user_model
-from django.core.management.base import CommandError, BaseCommand
-
-from misago.conf import settings
-from misago.core.pgutils import chunk_queryset
-
-from misago.users.permissions import can_delete_own_account
+from django.core.management.base import BaseCommand, CommandError
 
 
+from ....conf import settings
+from ....core.pgutils import chunk_queryset
+from ...permissions import can_delete_own_account
 
 
 User = get_user_model()
 User = get_user_model()
 
 

+ 2 - 2
misago/users/management/commands/deleteprofilefield.py

@@ -1,7 +1,7 @@
 from django.contrib.auth import get_user_model
 from django.contrib.auth import get_user_model
-from django.core.management.base import CommandError, BaseCommand
+from django.core.management.base import BaseCommand, CommandError
 
 
-from misago.core.pgutils import chunk_queryset
+from ....core.pgutils import chunk_queryset
 
 
 User = get_user_model()
 User = get_user_model()
 
 

+ 3 - 3
misago/users/management/commands/expireuserdatadownloads.py

@@ -1,9 +1,9 @@
 from django.core.management.base import BaseCommand
 from django.core.management.base import BaseCommand
 from django.utils import timezone
 from django.utils import timezone
 
 
-from misago.core.pgutils import chunk_queryset
-from misago.users.datadownloads import expire_user_data_download
-from misago.users.models import DataDownload
+from ....core.pgutils import chunk_queryset
+from ...datadownloads import expire_user_data_download
+from ...models import DataDownload
 
 
 
 
 class Command(BaseCommand):
 class Command(BaseCommand):

+ 3 - 4
misago/users/management/commands/invalidatebans.py

@@ -1,10 +1,9 @@
 from django.core.management.base import BaseCommand
 from django.core.management.base import BaseCommand
 from django.utils import timezone
 from django.utils import timezone
 
 
-from misago.cache.versions import get_cache_versions
-
-from misago.users import BANS_CACHE
-from misago.users.models import Ban, BanCache
+from ....cache.versions import get_cache_versions
+from ....users import BANS_CACHE
+from ...models import Ban, BanCache
 
 
 
 
 class Command(BaseCommand):
 class Command(BaseCommand):

+ 1 - 2
misago/users/management/commands/listusedprofilefields.py

@@ -1,8 +1,7 @@
 from django.contrib.auth import get_user_model
 from django.contrib.auth import get_user_model
 from django.core.management.base import BaseCommand
 from django.core.management.base import BaseCommand
 
 
-from misago.core.pgutils import chunk_queryset
-
+from ....core.pgutils import chunk_queryset
 
 
 User = get_user_model()
 User = get_user_model()
 
 

+ 3 - 3
misago/users/management/commands/loadavatargallery.py

@@ -1,8 +1,8 @@
 from django.core.management.base import BaseCommand
 from django.core.management.base import BaseCommand
 
 
-from misago.conf import settings
-from misago.users.avatars.gallery import load_avatar_galleries
-from misago.users.models import AvatarGallery
+from ....conf import settings
+from ...avatars.gallery import load_avatar_galleries
+from ...models import AvatarGallery
 
 
 
 
 class Command(BaseCommand):
 class Command(BaseCommand):

+ 2 - 3
misago/users/management/commands/populateonlinetracker.py

@@ -1,9 +1,8 @@
 from django.contrib.auth import get_user_model
 from django.contrib.auth import get_user_model
 from django.core.management.base import BaseCommand
 from django.core.management.base import BaseCommand
 
 
-from misago.core.pgutils import chunk_queryset
-from misago.users.models import Online
-
+from ....core.pgutils import chunk_queryset
+from ...models import Online
 
 
 User = get_user_model()
 User = get_user_model()
 
 

+ 7 - 8
misago/users/management/commands/prepareuserdatadownloads.py

@@ -3,14 +3,13 @@ import logging
 from django.core.management.base import BaseCommand
 from django.core.management.base import BaseCommand
 from django.utils.translation import gettext
 from django.utils.translation import gettext
 
 
-from misago.cache.versions import get_cache_versions
-from misago.conf import settings
-from misago.conf.dynamicsettings import DynamicSettings
-from misago.core.mail import mail_user
-from misago.core.pgutils import chunk_queryset
-from misago.users.datadownloads import prepare_user_data_download
-from misago.users.models import DataDownload
-
+from ....cache.versions import get_cache_versions
+from ....conf import settings
+from ....conf.dynamicsettings import DynamicSettings
+from ....core.mail import mail_user
+from ....core.pgutils import chunk_queryset
+from ...datadownloads import prepare_user_data_download
+from ...models import DataDownload
 
 
 logger = logging.getLogger("misago.users.datadownloads")
 logger = logging.getLogger("misago.users.datadownloads")
 
 

+ 2 - 2
misago/users/management/commands/removeoldips.py

@@ -1,7 +1,7 @@
 from django.core.management import BaseCommand
 from django.core.management import BaseCommand
 
 
-from misago.conf import settings
-from misago.users.signals import remove_old_ips
+from ....conf import settings
+from ...signals import remove_old_ips
 
 
 
 
 class Command(BaseCommand):
 class Command(BaseCommand):

+ 3 - 4
misago/users/management/commands/synchronizeusers.py

@@ -3,10 +3,9 @@ import time
 from django.contrib.auth import get_user_model
 from django.contrib.auth import get_user_model
 from django.core.management.base import BaseCommand
 from django.core.management.base import BaseCommand
 
 
-from misago.categories.models import Category
-from misago.core.management.progressbar import show_progress
-from misago.core.pgutils import chunk_queryset
-
+from ....categories.models import Category
+from ....core.management.progressbar import show_progress
+from ....core.pgutils import chunk_queryset
 
 
 User = get_user_model()
 User = get_user_model()
 
 

+ 1 - 2
misago/users/migrations/0002_users_settings.py

@@ -1,7 +1,6 @@
 from django.db import migrations
 from django.db import migrations
 
 
-from misago.conf.migrationutils import migrate_settings_group
-
+from ...conf.migrationutils import migrate_settings_group
 
 
 _ = lambda s: s
 _ = lambda s: s
 
 

+ 1 - 2
misago/users/migrations/0004_default_ranks.py

@@ -1,8 +1,7 @@
 from django.db import migrations
 from django.db import migrations
 from django.utils.translation import gettext
 from django.utils.translation import gettext
 
 
-from misago.core.utils import slugify
-
+from ...core.utils import slugify
 
 
 _ = lambda s: s
 _ = lambda s: s
 
 

+ 1 - 1
misago/users/migrations/0006_update_settings.py

@@ -1,7 +1,7 @@
 # Generated by Django 1.10.5 on 2017-02-05 14:34
 # Generated by Django 1.10.5 on 2017-02-05 14:34
 from django.db import migrations
 from django.db import migrations
 
 
-from misago.conf.migrationutils import migrate_settings_group
+from ...conf.migrationutils import migrate_settings_group
 
 
 _ = lambda s: s
 _ = lambda s: s
 
 

+ 1 - 0
misago/users/migrations/0009_redo_partial_indexes.py

@@ -1,5 +1,6 @@
 # Generated by Django 1.11.1 on 2017-05-26 21:56
 # Generated by Django 1.11.1 on 2017-05-26 21:56
 from django.db import migrations
 from django.db import migrations
+
 import misago.core.pgutils
 import misago.core.pgutils
 
 
 
 

+ 1 - 0
misago/users/migrations/0011_auto_20180331_2208.py

@@ -1,5 +1,6 @@
 # Generated by Django 1.11.11 on 2018-03-31 22:08
 # Generated by Django 1.11.11 on 2018-03-31 22:08
 from django.db import migrations, models
 from django.db import migrations, models
+
 import misago.core.pgutils
 import misago.core.pgutils
 
 
 
 

+ 2 - 2
misago/users/migrations/0012_audittrail.py

@@ -1,8 +1,8 @@
 # Generated by Django 1.11.13 on 2018-06-03 18:46
 # Generated by Django 1.11.13 on 2018-06-03 18:46
-from django.conf import settings
-from django.db import migrations, models
 import django.db.models.deletion
 import django.db.models.deletion
 import django.utils.timezone
 import django.utils.timezone
+from django.conf import settings
+from django.db import migrations, models
 
 
 
 
 class Migration(migrations.Migration):
 class Migration(migrations.Migration):

+ 3 - 2
misago/users/migrations/0014_datadownload.py

@@ -1,8 +1,9 @@
 # Generated by Django 1.11.13 on 2018-06-24 00:13
 # Generated by Django 1.11.13 on 2018-06-24 00:13
-from django.conf import settings
-from django.db import migrations, models
 import django.db.models.deletion
 import django.db.models.deletion
 import django.utils.timezone
 import django.utils.timezone
+from django.conf import settings
+from django.db import migrations, models
+
 import misago.users.models.datadownload
 import misago.users.models.datadownload
 
 
 
 

+ 1 - 1
misago/users/migrations/0016_cache_version.py

@@ -1,7 +1,7 @@
 # Generated by Django 1.11.16 on 2018-11-25 15:31
 # Generated by Django 1.11.16 on 2018-11-25 15:31
 from django.db import migrations
 from django.db import migrations
 
 
-from misago.cache.operations import StartCacheVersioning
+from ...cache.operations import StartCacheVersioning
 
 
 
 
 class Migration(migrations.Migration):
 class Migration(migrations.Migration):

+ 1 - 1
misago/users/migrations/0017_move_bans_to_cache_version.py

@@ -1,7 +1,7 @@
 # Generated by Django 1.11.16 on 2018-11-29 20:28
 # Generated by Django 1.11.16 on 2018-11-29 20:28
 from django.db import migrations, models
 from django.db import migrations, models
 
 
-from misago.users import BANS_CACHE
+from .. import BANS_CACHE
 
 
 
 
 def populate_cache_version(apps, _):
 def populate_cache_version(apps, _):

+ 1 - 1
misago/users/models/avatar.py

@@ -1,7 +1,7 @@
 from django.conf import settings
 from django.conf import settings
 from django.db import models
 from django.db import models
 
 
-from misago.users.avatars import store
+from ..avatars import store
 
 
 
 
 class Avatar(models.Model):
 class Avatar(models.Model):

+ 1 - 1
misago/users/models/avatargallery.py

@@ -1,6 +1,6 @@
 from django.db import models
 from django.db import models
 
 
-from misago.users.avatars import store
+from ..avatars import store
 
 
 
 
 class AvatarGallery(models.Model):
 class AvatarGallery(models.Model):

+ 4 - 4
misago/users/models/ban.py

@@ -5,8 +5,8 @@ from django.db import IntegrityError, models
 from django.utils import timezone
 from django.utils import timezone
 from django.utils.translation import gettext_lazy as _
 from django.utils.translation import gettext_lazy as _
 
 
-from misago.cache.versions import invalidate_cache
-from misago.users import BANS_CACHE
+from .. import BANS_CACHE
+from ...cache.versions import invalidate_cache
 
 
 
 
 class BansManager(models.Manager):
 class BansManager(models.Manager):
@@ -92,7 +92,7 @@ class Ban(models.Model):
         return super().save(*args, **kwargs)
         return super().save(*args, **kwargs)
 
 
     def get_serialized_message(self):
     def get_serialized_message(self):
-        from misago.users.serializers import BanMessageSerializer
+        from ..serializers import BanMessageSerializer
 
 
         return BanMessageSerializer(self).data
         return BanMessageSerializer(self).data
 
 
@@ -138,7 +138,7 @@ class BanCache(models.Model):
             pass  # first come is first serve with ban cache
             pass  # first come is first serve with ban cache
 
 
     def get_serialized_message(self):
     def get_serialized_message(self):
-        from misago.users.serializers import BanMessageSerializer
+        from ..serializers import BanMessageSerializer
 
 
         temp_ban = Ban(
         temp_ban = Ban(
             id=1,
             id=1,

+ 2 - 2
misago/users/models/rank.py

@@ -1,8 +1,8 @@
 from django.db import models, transaction
 from django.db import models, transaction
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.acl.cache import clear_acl_cache
-from misago.core.utils import slugify
+from ...acl.cache import clear_acl_cache
+from ...core.utils import slugify
 
 
 
 
 class RankManager(models.Manager):
 class RankManager(models.Manager):

+ 13 - 13
misago/users/models/user.py

@@ -1,8 +1,9 @@
 from hashlib import md5
 from hashlib import md5
 
 
+from django.contrib.auth.models import AbstractBaseUser
 from django.contrib.auth.models import AnonymousUser as DjangoAnonymousUser
 from django.contrib.auth.models import AnonymousUser as DjangoAnonymousUser
+from django.contrib.auth.models import PermissionsMixin
 from django.contrib.auth.models import UserManager as BaseUserManager
 from django.contrib.auth.models import UserManager as BaseUserManager
-from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin
 from django.contrib.auth.password_validation import validate_password
 from django.contrib.auth.password_validation import validate_password
 from django.contrib.postgres.fields import ArrayField, HStoreField, JSONField
 from django.contrib.postgres.fields import ArrayField, HStoreField, JSONField
 from django.core.mail import send_mail
 from django.core.mail import send_mail
@@ -11,15 +12,14 @@ from django.urls import reverse
 from django.utils import timezone
 from django.utils import timezone
 from django.utils.translation import gettext_lazy as _
 from django.utils.translation import gettext_lazy as _
 
 
-from misago.acl.models import Role
-from misago.conf import settings
-from misago.core.pgutils import PgPartialIndex
-from misago.core.utils import slugify
-from misago.users import avatars
-from misago.users.audittrail import create_user_audit_trail
-from misago.users.signatures import is_user_signature_valid
-from misago.users.utils import hash_email
-
+from .. import avatars
+from ...acl.models import Role
+from ...conf import settings
+from ...core.pgutils import PgPartialIndex
+from ...core.utils import slugify
+from ..audittrail import create_user_audit_trail
+from ..signatures import is_user_signature_valid
+from ..utils import hash_email
 from .online import Online
 from .online import Online
 from .rank import Rank
 from .rank import Rank
 
 
@@ -251,7 +251,7 @@ class User(AbstractBaseUser, PermissionsMixin):
         return super().delete(*args, **kwargs)
         return super().delete(*args, **kwargs)
 
 
     def delete_content(self):
     def delete_content(self):
-        from misago.users.signals import delete_user_content
+        from ..signals import delete_user_content
 
 
         delete_user_content.send(sender=self)
         delete_user_content.send(sender=self)
 
 
@@ -269,7 +269,7 @@ class User(AbstractBaseUser, PermissionsMixin):
         self.username = settings.MISAGO_ANONYMOUS_USERNAME
         self.username = settings.MISAGO_ANONYMOUS_USERNAME
         self.slug = slugify(self.username)
         self.slug = slugify(self.username)
 
 
-        from misago.users.signals import anonymize_user_data
+        from ..signals import anonymize_user_data
 
 
         anonymize_user_data.send(sender=self)
         anonymize_user_data.send(sender=self)
 
 
@@ -329,7 +329,7 @@ class User(AbstractBaseUser, PermissionsMixin):
                     changed_by, new_username, old_username
                     changed_by, new_username, old_username
                 )
                 )
 
 
-                from misago.users.signals import username_changed
+                from ..signals import username_changed
 
 
                 username_changed.send(sender=self)
                 username_changed.send(sender=self)
 
 

+ 2 - 3
misago/users/online/tracker.py

@@ -1,8 +1,7 @@
-from rest_framework.request import Request
-
 from django.utils import timezone
 from django.utils import timezone
+from rest_framework.request import Request
 
 
-from misago.users.models import Online
+from ..models import Online
 
 
 
 
 def mute_tracker(request):
 def mute_tracker(request):

+ 2 - 3
misago/users/online/utils.py

@@ -2,9 +2,8 @@ from datetime import timedelta
 
 
 from django.utils import timezone
 from django.utils import timezone
 
 
-from misago.users.bans import get_user_ban
-from misago.users.models import BanCache, Online
-
+from ..bans import get_user_ban
+from ..models import BanCache, Online
 
 
 ACTIVITY_CUTOFF = timedelta(minutes=2)
 ACTIVITY_CUTOFF = timedelta(minutes=2)
 
 

+ 1 - 2
misago/users/pages.py

@@ -1,5 +1,4 @@
-from misago.core.page import Page
-
+from ..core.page import Page
 
 
 usercp = Page("usercp")
 usercp = Page("usercp")
 users_list = Page("users list")
 users_list = Page("users list")

+ 3 - 3
misago/users/permissions/account.py

@@ -1,9 +1,9 @@
 from django import forms
 from django import forms
 from django.utils.translation import gettext_lazy as _
 from django.utils.translation import gettext_lazy as _
 
 
-from misago.acl import algebra
-from misago.acl.models import Role
-from misago.admin.forms import YesNoSwitch
+from ...acl import algebra
+from ...acl.models import Role
+from ...admin.forms import YesNoSwitch
 
 
 
 
 class PermissionsForm(forms.Form):
 class PermissionsForm(forms.Form):

+ 0 - 1
misago/users/permissions/decorators.py

@@ -1,7 +1,6 @@
 from django.core.exceptions import PermissionDenied
 from django.core.exceptions import PermissionDenied
 from django.utils.translation import gettext_lazy as _
 from django.utils.translation import gettext_lazy as _
 
 
-
 __all__ = ["authenticated_only", "anonymous_only"]
 __all__ = ["authenticated_only", "anonymous_only"]
 
 
 
 

+ 4 - 5
misago/users/permissions/delete.py

@@ -7,11 +7,10 @@ from django.utils import timezone
 from django.utils.translation import gettext_lazy as _
 from django.utils.translation import gettext_lazy as _
 from django.utils.translation import ngettext
 from django.utils.translation import ngettext
 
 
-from misago.acl import algebra
-from misago.acl.decorators import return_boolean
-from misago.acl.models import Role
-from misago.conf import settings
-
+from ...acl import algebra
+from ...acl.decorators import return_boolean
+from ...acl.models import Role
+from ...conf import settings
 
 
 __all__ = [
 __all__ = [
     "allow_delete_user",
     "allow_delete_user",

+ 5 - 6
misago/users/permissions/moderation.py

@@ -7,12 +7,11 @@ from django.template.defaultfilters import date as format_date
 from django.utils import timezone
 from django.utils import timezone
 from django.utils.translation import gettext_lazy as _
 from django.utils.translation import gettext_lazy as _
 
 
-from misago.acl import algebra
-from misago.acl.decorators import return_boolean
-from misago.acl.models import Role
-from misago.admin.forms import YesNoSwitch
-from misago.users.bans import get_user_ban
-
+from ...acl import algebra
+from ...acl.decorators import return_boolean
+from ...acl.models import Role
+from ...admin.forms import YesNoSwitch
+from ..bans import get_user_ban
 
 
 __all__ = [
 __all__ = [
     "allow_rename_user",
     "allow_rename_user",

+ 4 - 6
misago/users/permissions/profiles.py

@@ -3,14 +3,12 @@ from django.contrib.auth import get_user_model
 from django.core.exceptions import PermissionDenied
 from django.core.exceptions import PermissionDenied
 from django.utils.translation import gettext_lazy as _
 from django.utils.translation import gettext_lazy as _
 
 
-from misago.acl import algebra
-from misago.acl.decorators import return_boolean
-from misago.acl.models import Role
-from misago.admin.forms import YesNoSwitch
-
+from ...acl import algebra
+from ...acl.decorators import return_boolean
+from ...acl.models import Role
+from ...admin.forms import YesNoSwitch
 from .decorators import authenticated_only
 from .decorators import authenticated_only
 
 
-
 __all__ = [
 __all__ = [
     "allow_browse_users_list",
     "allow_browse_users_list",
     "can_browse_users_list",
     "can_browse_users_list",

+ 1 - 1
misago/users/profilefields/__init__.py

@@ -6,7 +6,7 @@ from django.urls import reverse
 from django.utils.module_loading import import_string
 from django.utils.module_loading import import_string
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
 
 
-from misago.conf import settings
+from ...conf import settings
 
 
 from .basefields import *
 from .basefields import *
 from .serializers import serialize_profilefields_data
 from .serializers import serialize_profilefields_data

+ 1 - 2
misago/users/profilefields/basefields.py

@@ -2,8 +2,7 @@ from django import forms
 from django.db.models import Q
 from django.db.models import Q
 from django.utils import html
 from django.utils import html
 
 
-from misago.core.utils import format_plaintext_for_html
-
+from ...core.utils import format_plaintext_for_html
 
 
 __all__ = [
 __all__ = [
     "ProfileField",
     "ProfileField",

+ 2 - 1
misago/users/profilefields/default.py

@@ -1,7 +1,8 @@
 import re
 import re
 
 
 from django.forms import ValidationError
 from django.forms import ValidationError
-from django.utils.translation import gettext, gettext_lazy as _
+from django.utils.translation import gettext
+from django.utils.translation import gettext_lazy as _
 
 
 from . import basefields
 from . import basefields
 
 

+ 1 - 1
misago/users/profilefields/serializers.py

@@ -1,4 +1,4 @@
-from misago.users.permissions import can_edit_profile_details
+from ..permissions import can_edit_profile_details
 
 
 
 
 def serialize_profilefields_data(request, profilefields, user):
 def serialize_profilefields_data(request, profilefields, user):

+ 4 - 4
misago/users/registration.py

@@ -1,9 +1,9 @@
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
 
 
-from misago.core.mail import mail_user
-from misago.legal.models import Agreement
-from misago.legal.utils import save_user_agreement_acceptance
-from misago.users.tokens import make_activation_token
+from ..core.mail import mail_user
+from ..legal.models import Agreement
+from ..legal.utils import save_user_agreement_acceptance
+from .tokens import make_activation_token
 
 
 
 
 def send_welcome_email(request, user):
 def send_welcome_email(request, user):

+ 1 - 3
misago/users/search.py

@@ -3,11 +3,9 @@ from django.core.exceptions import PermissionDenied
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext_lazy
 from django.utils.translation import gettext_lazy
 
 
-from misago.search import SearchProvider
-
+from ..search import SearchProvider
 from .serializers import UserCardSerializer
 from .serializers import UserCardSerializer
 
 
-
 HEAD_RESULTS = 8
 HEAD_RESULTS = 8
 TAIL_RESULTS = 8
 TAIL_RESULTS = 8
 
 

+ 2 - 4
misago/users/serializers/auth.py

@@ -1,10 +1,8 @@
-from rest_framework import serializers
-
 from django.contrib.auth import get_user_model
 from django.contrib.auth import get_user_model
 from django.urls import reverse
 from django.urls import reverse
+from rest_framework import serializers
 
 
-from misago.acl.useracl import serialize_user_acl
-
+from ...acl.useracl import serialize_user_acl
 from .user import UserSerializer
 from .user import UserSerializer
 
 
 User = get_user_model()
 User = get_user_model()

+ 3 - 5
misago/users/serializers/ban.py

@@ -1,10 +1,8 @@
-from rest_framework import serializers
-
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
+from rest_framework import serializers
 
 
-from misago.core.utils import format_plaintext_for_html
-from misago.users.models import Ban
-
+from ...core.utils import format_plaintext_for_html
+from ..models import Ban
 
 
 __all__ = ["BanMessageSerializer", "BanDetailsSerializer"]
 __all__ = ["BanMessageSerializer", "BanDetailsSerializer"]
 
 

+ 1 - 2
misago/users/serializers/datadownload.py

@@ -1,7 +1,6 @@
 from rest_framework import serializers
 from rest_framework import serializers
 
 
-from misago.users.models import DataDownload
-
+from ..models import DataDownload
 
 
 __all__ = ["DataDownloadSerializer"]
 __all__ = ["DataDownloadSerializer"]
 
 

+ 2 - 4
misago/users/serializers/moderation.py

@@ -1,10 +1,8 @@
-from rest_framework import serializers
-
 from django.contrib.auth import get_user_model
 from django.contrib.auth import get_user_model
 from django.utils.translation import ngettext
 from django.utils.translation import ngettext
+from rest_framework import serializers
 
 
-from misago.conf import settings
-
+from ...conf import settings
 
 
 User = get_user_model()
 User = get_user_model()
 
 

+ 4 - 6
misago/users/serializers/options.py

@@ -1,13 +1,11 @@
-from rest_framework import serializers
-
 from django.contrib.auth import get_user_model, logout
 from django.contrib.auth import get_user_model, logout
 from django.contrib.auth.password_validation import validate_password
 from django.contrib.auth.password_validation import validate_password
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
+from rest_framework import serializers
 
 
-from misago.users.online.tracker import clear_tracking
-from misago.users.permissions import allow_delete_own_account
-from misago.users.validators import validate_email, validate_username
-
+from ..online.tracker import clear_tracking
+from ..permissions import allow_delete_own_account
+from ..validators import validate_email, validate_username
 
 
 User = get_user_model()
 User = get_user_model()
 
 

+ 2 - 3
misago/users/serializers/rank.py

@@ -1,8 +1,7 @@
 from rest_framework import serializers
 from rest_framework import serializers
 
 
-from misago.core.utils import format_plaintext_for_html
-from misago.users.models import Rank
-
+from ...core.utils import format_plaintext_for_html
+from ..models import Rank
 
 
 __all__ = ["RankSerializer"]
 __all__ = ["RankSerializer"]
 
 

+ 2 - 5
misago/users/serializers/user.py

@@ -1,12 +1,9 @@
-from rest_framework import serializers
-
 from django.contrib.auth import get_user_model
 from django.contrib.auth import get_user_model
 from django.urls import reverse
 from django.urls import reverse
-
-from misago.core.serializers import MutableFields
+from rest_framework import serializers
 
 
 from . import RankSerializer
 from . import RankSerializer
-
+from ...core.serializers import MutableFields
 
 
 User = get_user_model()
 User = get_user_model()
 
 

+ 1 - 3
misago/users/serializers/usernamechange.py

@@ -1,10 +1,8 @@
 from rest_framework import serializers
 from rest_framework import serializers
 
 
-from misago.users.models import UsernameChange
-
+from ..models import UsernameChange
 from .user import UserSerializer as BaseUserSerializer
 from .user import UserSerializer as BaseUserSerializer
 
 
-
 __all__ = ["UsernameChangeSerializer"]
 __all__ = ["UsernameChangeSerializer"]
 
 
 UserSerializer = BaseUserSerializer.subset_fields("id", "username", "avatars", "url")
 UserSerializer = BaseUserSerializer.subset_fields("id", "username", "avatars", "url")

+ 1 - 1
misago/users/setupnewuser.py

@@ -1,5 +1,5 @@
-from .avatars import set_default_avatar
 from .audittrail import create_user_audit_trail
 from .audittrail import create_user_audit_trail
+from .avatars import set_default_avatar
 from .models import User
 from .models import User
 
 
 
 

+ 2 - 4
misago/users/signals.py

@@ -7,13 +7,11 @@ from django.dispatch import Signal, receiver
 from django.utils import timezone
 from django.utils import timezone
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
 
 
-from misago.conf import settings
-from misago.core.pgutils import chunk_queryset
-
+from ..conf import settings
+from ..core.pgutils import chunk_queryset
 from .models import AuditTrail
 from .models import AuditTrail
 from .profilefields import profilefields
 from .profilefields import profilefields
 
 
-
 User = get_user_model()
 User = get_user_model()
 
 
 anonymize_user_data = Signal()
 anonymize_user_data = Signal()

+ 1 - 1
misago/users/signatures.py

@@ -1,4 +1,4 @@
-from misago.markup import checksums, signature_flavour
+from ..markup import checksums, signature_flavour
 
 
 
 
 def set_user_signature(request, user, user_acl, signature):
 def set_user_signature(request, user, user_acl, signature):

+ 9 - 12
misago/users/social/pipeline.py

@@ -8,28 +8,25 @@ from django.urls import reverse
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
 from social_core.pipeline.partial import partial
 from social_core.pipeline.partial import partial
 
 
-from misago.core.exceptions import SocialAuthFailed, SocialAuthBanned
-from misago.legal.models import Agreement
-
-from misago.users.bans import get_request_ip_ban, get_user_ban
-from misago.users.forms.register import SocialAuthRegisterForm
-from misago.users.models import Ban
-from misago.users.registration import (
+from ...core.exceptions import SocialAuthBanned, SocialAuthFailed
+from ...legal.models import Agreement
+from ..bans import get_request_ip_ban, get_user_ban
+from ..forms.register import SocialAuthRegisterForm
+from ..models import Ban
+from ..registration import (
     get_registration_result_json,
     get_registration_result_json,
     save_user_agreements,
     save_user_agreements,
     send_welcome_email,
     send_welcome_email,
 )
 )
-from misago.users.setupnewuser import setup_new_user
-from misago.users.validators import (
+from ..setupnewuser import setup_new_user
+from ..validators import (
     ValidationError,
     ValidationError,
-    validate_new_registration,
     validate_email,
     validate_email,
+    validate_new_registration,
     validate_username,
     validate_username,
 )
 )
-
 from .utils import get_social_auth_backend_name, perpare_username
 from .utils import get_social_auth_backend_name, perpare_username
 
 
-
 User = get_user_model()
 User = get_user_model()
 
 
 
 

+ 1 - 2
misago/users/social/utils.py

@@ -2,8 +2,7 @@ from django.urls import reverse
 from social_core.backends.utils import load_backends
 from social_core.backends.utils import load_backends
 from unidecode import unidecode
 from unidecode import unidecode
 
 
-from misago.conf import settings
-
+from ...conf import settings
 from .backendsnames import BACKENDS_NAMES
 from .backendsnames import BACKENDS_NAMES
 
 
 
 

+ 0 - 1
misago/users/templatetags/misago_avatars.py

@@ -1,6 +1,5 @@
 from django import template
 from django import template
 
 
-
 register = template.Library()
 register = template.Library()
 
 
 
 

+ 4 - 4
misago/users/tests/test_activation_views.py

@@ -2,10 +2,10 @@ from django.contrib.auth import get_user_model
 from django.test import TestCase
 from django.test import TestCase
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.core.utils import encode_json_html
-from misago.users.models import Ban
-from misago.users.test import create_test_user
-from misago.users.tokens import make_activation_token
+from ...core.utils import encode_json_html
+from ..models import Ban
+from ..test import create_test_user
+from ..tokens import make_activation_token
 
 
 User = get_user_model()
 User = get_user_model()
 
 

+ 4 - 4
misago/users/tests/test_activepostersranking.py

@@ -2,13 +2,13 @@ from datetime import timedelta
 
 
 from django.utils import timezone
 from django.utils import timezone
 
 
-from misago.categories.models import Category
-from misago.threads.test import post_thread
-from misago.users.activepostersranking import (
+from ...categories.models import Category
+from ...threads.test import post_thread
+from ..activepostersranking import (
     build_active_posters_ranking,
     build_active_posters_ranking,
     get_active_posters_ranking,
     get_active_posters_ranking,
 )
 )
-from misago.users.test import AuthenticatedUserTestCase, create_test_user
+from ..test import AuthenticatedUserTestCase, create_test_user
 
 
 
 
 class TestActivePostersRanking(AuthenticatedUserTestCase):
 class TestActivePostersRanking(AuthenticatedUserTestCase):

+ 4 - 4
misago/users/tests/test_audittrail.py

@@ -3,10 +3,10 @@ from datetime import timedelta
 from django.contrib.auth import get_user_model
 from django.contrib.auth import get_user_model
 from django.utils import timezone
 from django.utils import timezone
 
 
-from misago.users.audittrail import create_audit_trail, create_user_audit_trail
-from misago.users.models import AuditTrail
-from misago.users.signals import remove_old_ips
-from misago.users.test import UserTestCase, create_test_user
+from ..audittrail import create_audit_trail, create_user_audit_trail
+from ..models import AuditTrail
+from ..signals import remove_old_ips
+from ..test import UserTestCase, create_test_user
 
 
 User = get_user_model()
 User = get_user_model()
 
 

+ 3 - 3
misago/users/tests/test_auth_api.py

@@ -2,9 +2,9 @@ from django.contrib.auth import get_user_model
 from django.core import mail
 from django.core import mail
 from django.test import TestCase
 from django.test import TestCase
 
 
-from misago.users.models import Ban
-from misago.users.test import create_test_user
-from misago.users.tokens import make_password_change_token
+from ..models import Ban
+from ..test import create_test_user
+from ..tokens import make_password_change_token
 
 
 
 
 class GatewayTests(TestCase):
 class GatewayTests(TestCase):

+ 2 - 2
misago/users/tests/test_auth_backend.py

@@ -1,8 +1,8 @@
 from django.contrib.auth import get_user_model
 from django.contrib.auth import get_user_model
 from django.test import TestCase
 from django.test import TestCase
 
 
-from misago.users.authbackends import MisagoBackend
-from misago.users.test import create_test_user
+from ..authbackends import MisagoBackend
+from ..test import create_test_user
 
 
 backend = MisagoBackend()
 backend = MisagoBackend()
 
 

+ 1 - 1
misago/users/tests/test_avatar_filter.py

@@ -1,6 +1,6 @@
 import pytest
 import pytest
 
 
-from misago.users.templatetags.misago_avatars import avatar
+from ..templatetags.misago_avatars import avatar
 
 
 
 
 @pytest.fixture
 @pytest.fixture

+ 5 - 13
misago/users/tests/test_avatars.py

@@ -1,23 +1,15 @@
 from pathlib import Path
 from pathlib import Path
 from unittest.mock import Mock
 from unittest.mock import Mock
 
 
-from PIL import Image
-
 from django.core.exceptions import ValidationError
 from django.core.exceptions import ValidationError
 from django.test import TestCase
 from django.test import TestCase
 from django.utils.crypto import get_random_string
 from django.utils.crypto import get_random_string
+from PIL import Image
 
 
-from misago.conf import settings
-from misago.users.avatars import (
-    dynamic,
-    gallery,
-    gravatar,
-    set_default_avatar,
-    store,
-    uploaded,
-)
-from misago.users.models import Avatar, AvatarGallery
-from misago.users.test import create_test_user
+from ...conf import settings
+from ..avatars import dynamic, gallery, gravatar, set_default_avatar, store, uploaded
+from ..models import Avatar, AvatarGallery
+from ..test import create_test_user
 
 
 
 
 class AvatarsStoreTests(TestCase):
 class AvatarsStoreTests(TestCase):

+ 2 - 2
misago/users/tests/test_avatarserver_views.py

@@ -1,8 +1,8 @@
 from django.test import TestCase
 from django.test import TestCase
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.conf import settings
-from misago.users.test import create_test_user
+from ...conf import settings
+from ..test import create_test_user
 
 
 
 
 class AvatarServerTests(TestCase):
 class AvatarServerTests(TestCase):

+ 1 - 1
misago/users/tests/test_ban_model.py

@@ -1,6 +1,6 @@
 from django.test import TestCase
 from django.test import TestCase
 
 
-from misago.users.models import Ban
+from ..models import Ban
 
 
 
 
 class BansManagerTests(TestCase):
 class BansManagerTests(TestCase):

+ 2 - 2
misago/users/tests/test_banadmin_views.py

@@ -2,8 +2,8 @@ from datetime import datetime, timedelta
 
 
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.admin.test import AdminTestCase
-from misago.users.models import Ban
+from ...admin.test import AdminTestCase
+from ..models import Ban
 
 
 
 
 class BanAdminViewsTests(AdminTestCase):
 class BanAdminViewsTests(AdminTestCase):

+ 5 - 5
misago/users/tests/test_bans.py

@@ -3,8 +3,9 @@ from datetime import timedelta
 from django.test import TestCase
 from django.test import TestCase
 from django.utils import timezone
 from django.utils import timezone
 
 
-from misago.conftest import get_cache_versions
-from misago.users.bans import (
+from ...conftest import get_cache_versions
+from ...users import BANS_CACHE
+from ..bans import (
     ban_ip,
     ban_ip,
     ban_user,
     ban_user,
     get_email_ban,
     get_email_ban,
@@ -13,9 +14,8 @@ from misago.users.bans import (
     get_user_ban,
     get_user_ban,
     get_username_ban,
     get_username_ban,
 )
 )
-from misago.users import BANS_CACHE
-from misago.users.models import Ban
-from misago.users.test import create_test_user
+from ..models import Ban
+from ..test import create_test_user
 
 
 cache_versions = get_cache_versions()
 cache_versions = get_cache_versions()
 
 

+ 1 - 2
misago/users/tests/test_bio_profilefield.py

@@ -1,8 +1,7 @@
 from django.contrib.auth import get_user_model
 from django.contrib.auth import get_user_model
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.admin.test import AdminTestCase
-
+from ...admin.test import AdminTestCase
 
 
 User = get_user_model()
 User = get_user_model()
 
 

+ 1 - 1
misago/users/tests/test_captcha_api.py

@@ -1,7 +1,7 @@
 from django.test import TestCase
 from django.test import TestCase
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.conf.test import override_dynamic_settings
+from ...conf.test import override_dynamic_settings
 
 
 test_qa_question = "Do you like pies?"
 test_qa_question = "Do you like pies?"
 test_qa_help_text = 'Type in "yes".'
 test_qa_help_text = 'Type in "yes".'

+ 2 - 2
misago/users/tests/test_credentialchange.py

@@ -1,7 +1,7 @@
 from django.test import TestCase
 from django.test import TestCase
 
 
-from misago.users import credentialchange
-from misago.users.test import create_test_user
+from ...users import credentialchange
+from ..test import create_test_user
 
 
 
 
 class MockRequest(object):
 class MockRequest(object):

+ 7 - 8
misago/users/tests/test_datadownloads.py

@@ -2,19 +2,18 @@ import os
 
 
 from django.core.files import File
 from django.core.files import File
 
 
-from misago.categories.models import Category
-from misago.threads.models import Attachment, AttachmentType
-from misago.threads.test import post_thread, post_poll
-from misago.users.audittrail import create_user_audit_trail
-from misago.users.datadownloads import (
+from ...categories.models import Category
+from ...threads.models import Attachment, AttachmentType
+from ...threads.test import post_poll, post_thread
+from ..audittrail import create_user_audit_trail
+from ..datadownloads import (
     expire_user_data_download,
     expire_user_data_download,
     prepare_user_data_download,
     prepare_user_data_download,
     request_user_data_download,
     request_user_data_download,
     user_has_data_download_request,
     user_has_data_download_request,
 )
 )
-from misago.users.models import DataDownload
-from misago.users.test import AuthenticatedUserTestCase
-
+from ..models import DataDownload
+from ..test import AuthenticatedUserTestCase
 
 
 TESTFILES_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "testfiles")
 TESTFILES_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "testfiles")
 TEST_FILE_PATH = os.path.join(TESTFILES_DIR, "avatar.png")
 TEST_FILE_PATH = os.path.join(TESTFILES_DIR, "avatar.png")

+ 3 - 4
misago/users/tests/test_datadownloads_dataarchive.py

@@ -5,14 +5,13 @@ from django.core.files import File
 from django.test import TestCase
 from django.test import TestCase
 from django.utils import timezone
 from django.utils import timezone
 
 
-from misago.conf import settings
-from misago.users.datadownloads.dataarchive import (
+from ...conf import settings
+from ..datadownloads.dataarchive import (
     FILENAME_MAX_LEN,
     FILENAME_MAX_LEN,
     DataArchive,
     DataArchive,
     trim_long_filename,
     trim_long_filename,
 )
 )
-from misago.users.test import AuthenticatedUserTestCase
-
+from ..test import AuthenticatedUserTestCase
 
 
 DATA_DOWNLOADS_WORKING_DIR = settings.MISAGO_USER_DATA_DOWNLOADS_WORKING_DIR
 DATA_DOWNLOADS_WORKING_DIR = settings.MISAGO_USER_DATA_DOWNLOADS_WORKING_DIR
 TESTFILES_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "testfiles")
 TESTFILES_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "testfiles")

+ 4 - 4
misago/users/tests/test_datadownloadsadmin_views.py

@@ -3,10 +3,10 @@ import os
 from django.core.files import File
 from django.core.files import File
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.admin.test import AdminTestCase
-from misago.users.datadownloads import request_user_data_download
-from misago.users.models import DataDownload
-from misago.users.test import create_test_user
+from ...admin.test import AdminTestCase
+from ..datadownloads import request_user_data_download
+from ..models import DataDownload
+from ..test import create_test_user
 
 
 TESTFILES_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "testfiles")
 TESTFILES_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "testfiles")
 TEST_FILE_PATH = os.path.join(TESTFILES_DIR, "avatar.png")
 TEST_FILE_PATH = os.path.join(TESTFILES_DIR, "avatar.png")

+ 3 - 3
misago/users/tests/test_decorators.py

@@ -1,8 +1,8 @@
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.core.utils import encode_json_html
-from misago.users.models import Ban
-from misago.users.test import UserTestCase
+from ...core.utils import encode_json_html
+from ..models import Ban
+from ..test import UserTestCase
 
 
 
 
 class DenyAuthenticatedTests(UserTestCase):
 class DenyAuthenticatedTests(UserTestCase):

+ 2 - 2
misago/users/tests/test_deleteinactiveusers.py

@@ -6,8 +6,8 @@ from django.core.management import call_command
 from django.test import TestCase, override_settings
 from django.test import TestCase, override_settings
 from django.utils import timezone
 from django.utils import timezone
 
 
-from misago.users.management.commands import deleteinactiveusers
-from misago.users.test import create_test_user
+from ..management.commands import deleteinactiveusers
+from ..test import create_test_user
 
 
 User = get_user_model()
 User = get_user_model()
 
 

+ 2 - 2
misago/users/tests/test_deletemarkedusers.py

@@ -4,8 +4,8 @@ from django.contrib.auth import get_user_model
 from django.core.management import call_command
 from django.core.management import call_command
 from django.test import TestCase, override_settings
 from django.test import TestCase, override_settings
 
 
-from misago.users.management.commands import deletemarkedusers
-from misago.users.test import create_test_user
+from ..management.commands import deletemarkedusers
+from ..test import create_test_user
 
 
 User = get_user_model()
 User = get_user_model()
 
 

+ 2 - 2
misago/users/tests/test_deleteprofilefield.py

@@ -3,8 +3,8 @@ from io import StringIO
 from django.core.management import call_command
 from django.core.management import call_command
 from django.test import TestCase
 from django.test import TestCase
 
 
-from misago.users.management.commands import deleteprofilefield
-from misago.users.test import create_test_user
+from ..management.commands import deleteprofilefield
+from ..test import create_test_user
 
 
 
 
 class DeleteProfileFieldTests(TestCase):
 class DeleteProfileFieldTests(TestCase):

+ 1 - 1
misago/users/tests/test_djangoadmin_auth.py

@@ -1,7 +1,7 @@
 from django.test import override_settings
 from django.test import override_settings
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.admin.test import AdminTestCase
+from ...admin.test import AdminTestCase
 
 
 
 
 @override_settings(ROOT_URLCONF="misago.core.testproject.urls")
 @override_settings(ROOT_URLCONF="misago.core.testproject.urls")

+ 3 - 3
misago/users/tests/test_djangoadmin_user.py

@@ -3,9 +3,9 @@ from django.test import override_settings
 from django.urls import reverse
 from django.urls import reverse
 from django.utils import formats
 from django.utils import formats
 
 
-from misago.admin.test import AdminTestCase
-from misago.users.djangoadmin import UserAdminModel
-from misago.users.test import create_test_user
+from ...admin.test import AdminTestCase
+from ..djangoadmin import UserAdminModel
+from ..test import create_test_user
 
 
 
 
 @override_settings(ROOT_URLCONF="misago.core.testproject.urls")
 @override_settings(ROOT_URLCONF="misago.core.testproject.urls")

+ 4 - 5
misago/users/tests/test_expireuserdatadownloads.py

@@ -5,11 +5,10 @@ from io import StringIO
 from django.core.files import File
 from django.core.files import File
 from django.core.management import call_command
 from django.core.management import call_command
 
 
-from misago.users.datadownloads import request_user_data_download
-from misago.users.management.commands import expireuserdatadownloads
-from misago.users.models import DataDownload
-from misago.users.test import AuthenticatedUserTestCase
-
+from ..datadownloads import request_user_data_download
+from ..management.commands import expireuserdatadownloads
+from ..models import DataDownload
+from ..test import AuthenticatedUserTestCase
 
 
 TESTFILES_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "testfiles")
 TESTFILES_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "testfiles")
 TEST_FILE_PATH = os.path.join(TESTFILES_DIR, "avatar.png")
 TEST_FILE_PATH = os.path.join(TESTFILES_DIR, "avatar.png")

+ 4 - 4
misago/users/tests/test_forgottenpassword_views.py

@@ -1,9 +1,9 @@
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.core.utils import encode_json_html
-from misago.users.models import Ban
-from misago.users.test import UserTestCase, create_test_user
-from misago.users.tokens import make_password_change_token
+from ...core.utils import encode_json_html
+from ..models import Ban
+from ..test import UserTestCase, create_test_user
+from ..tokens import make_password_change_token
 
 
 
 
 class ForgottenPasswordViewsTests(UserTestCase):
 class ForgottenPasswordViewsTests(UserTestCase):

+ 1 - 2
misago/users/tests/test_gender_profilefield.py

@@ -1,8 +1,7 @@
 from django.contrib.auth import get_user_model
 from django.contrib.auth import get_user_model
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.admin.test import AdminTestCase
-
+from ...admin.test import AdminTestCase
 
 
 User = get_user_model()
 User = get_user_model()
 
 

+ 2 - 2
misago/users/tests/test_getting_user_status.py

@@ -1,7 +1,7 @@
 from unittest.mock import Mock
 from unittest.mock import Mock
 
 
-from misago.users.online.utils import get_user_status
-from misago.users.test import AuthenticatedUserTestCase, create_test_user
+from ..online.utils import get_user_status
+from ..test import AuthenticatedUserTestCase, create_test_user
 
 
 
 
 class GetUserStatusTests(AuthenticatedUserTestCase):
 class GetUserStatusTests(AuthenticatedUserTestCase):

+ 5 - 6
misago/users/tests/test_invalidatebans.py

@@ -5,12 +5,11 @@ from django.core.management import call_command
 from django.test import TestCase
 from django.test import TestCase
 from django.utils import timezone
 from django.utils import timezone
 
 
-from misago.cache.versions import get_cache_versions
-
-from misago.users import bans
-from misago.users.management.commands import invalidatebans
-from misago.users.models import Ban, BanCache
-from misago.users.test import create_test_user
+from ...cache.versions import get_cache_versions
+from ...users import bans
+from ..management.commands import invalidatebans
+from ..models import Ban, BanCache
+from ..test import create_test_user
 
 
 
 
 class InvalidateBansTests(TestCase):
 class InvalidateBansTests(TestCase):

+ 2 - 3
misago/users/tests/test_joinip_profilefield.py

@@ -1,9 +1,8 @@
 from django.contrib.auth import get_user_model
 from django.contrib.auth import get_user_model
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.acl.test import patch_user_acl
-from misago.admin.test import AdminTestCase
-
+from ...acl.test import patch_user_acl
+from ...admin.test import AdminTestCase
 
 
 User = get_user_model()
 User = get_user_model()
 
 

+ 6 - 6
misago/users/tests/test_lists_views.py

@@ -1,11 +1,11 @@
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.acl.test import patch_user_acl
-from misago.categories.models import Category
-from misago.threads.test import post_thread
-from misago.users.activepostersranking import build_active_posters_ranking
-from misago.users.models import Rank
-from misago.users.test import AuthenticatedUserTestCase, create_test_user
+from ...acl.test import patch_user_acl
+from ...categories.models import Category
+from ...threads.test import post_thread
+from ..activepostersranking import build_active_posters_ranking
+from ..models import Rank
+from ..test import AuthenticatedUserTestCase, create_test_user
 
 
 
 
 class UsersListTestCase(AuthenticatedUserTestCase):
 class UsersListTestCase(AuthenticatedUserTestCase):

+ 2 - 2
misago/users/tests/test_listusedprofilefields.py

@@ -3,8 +3,8 @@ from io import StringIO
 from django.core.management import call_command
 from django.core.management import call_command
 from django.test import TestCase
 from django.test import TestCase
 
 
-from misago.users.management.commands import listusedprofilefields
-from misago.users.test import create_test_user
+from ..management.commands import listusedprofilefields
+from ..test import create_test_user
 
 
 
 
 class ListUsedProfileFieldsTests(TestCase):
 class ListUsedProfileFieldsTests(TestCase):

+ 2 - 2
misago/users/tests/test_loadavatargallery.py

@@ -3,8 +3,8 @@ from io import StringIO
 from django.core.management import call_command
 from django.core.management import call_command
 from django.test import TestCase
 from django.test import TestCase
 
 
-from misago.users.management.commands import loadavatargallery
-from misago.users.models import AvatarGallery
+from ..management.commands import loadavatargallery
+from ..models import AvatarGallery
 
 
 
 
 class LoadAvatarGalleryTests(TestCase):
 class LoadAvatarGalleryTests(TestCase):

+ 2 - 2
misago/users/tests/test_mention_api.py

@@ -1,8 +1,8 @@
 from django.test import TestCase
 from django.test import TestCase
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.conf import settings
-from misago.users.test import create_test_user
+from ...conf import settings
+from ..test import create_test_user
 
 
 
 
 class AuthenticateApiTests(TestCase):
 class AuthenticateApiTests(TestCase):

+ 2 - 2
misago/users/tests/test_namechanges.py

@@ -1,8 +1,8 @@
 from datetime import timedelta
 from datetime import timedelta
 
 
-from misago.users.namechanges import (
-    get_next_available_namechange,
+from ..namechanges import (
     get_left_namechanges,
     get_left_namechanges,
+    get_next_available_namechange,
     get_username_options,
     get_username_options,
 )
 )
 
 

+ 2 - 2
misago/users/tests/test_new_user_setup.py

@@ -1,7 +1,7 @@
 from django.contrib.auth import get_user_model
 from django.contrib.auth import get_user_model
 
 
-from misago.conf.test import override_dynamic_settings
-from misago.users.setupnewuser import set_default_subscription_options, setup_new_user
+from ...conf.test import override_dynamic_settings
+from ..setupnewuser import set_default_subscription_options, setup_new_user
 
 
 User = get_user_model()
 User = get_user_model()
 
 

+ 1 - 1
misago/users/tests/test_options_views.py

@@ -1,7 +1,7 @@
 from django.core import mail
 from django.core import mail
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.users.test import AuthenticatedUserTestCase
+from ..test import AuthenticatedUserTestCase
 
 
 
 
 class OptionsViewsTests(AuthenticatedUserTestCase):
 class OptionsViewsTests(AuthenticatedUserTestCase):

+ 2 - 2
misago/users/tests/test_populate_online_tracker_command.py

@@ -2,8 +2,8 @@ from io import StringIO
 
 
 from django.core.management import call_command
 from django.core.management import call_command
 
 
-from misago.users.management.commands import populateonlinetracker
-from misago.users.models import Online
+from ..management.commands import populateonlinetracker
+from ..models import Online
 
 
 
 
 def test_management_command_creates_online_tracker_for_user_without_one(user):
 def test_management_command_creates_online_tracker_for_user_without_one(user):

+ 5 - 5
misago/users/tests/test_prepareuserdatadownloads.py

@@ -3,11 +3,11 @@ from io import StringIO
 from django.core import mail
 from django.core import mail
 from django.core.management import call_command
 from django.core.management import call_command
 
 
-from misago.conf import settings
-from misago.users.datadownloads import request_user_data_download
-from misago.users.management.commands import prepareuserdatadownloads
-from misago.users.models import DataDownload
-from misago.users.test import AuthenticatedUserTestCase
+from ...conf import settings
+from ..datadownloads import request_user_data_download
+from ..management.commands import prepareuserdatadownloads
+from ..models import DataDownload
+from ..test import AuthenticatedUserTestCase
 
 
 
 
 class PrepareUserDataDownloadsTests(AuthenticatedUserTestCase):
 class PrepareUserDataDownloadsTests(AuthenticatedUserTestCase):

+ 5 - 5
misago/users/tests/test_profile_views.py

@@ -1,10 +1,10 @@
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.acl.test import patch_user_acl
-from misago.categories.models import Category
-from misago.threads import test
-from misago.users.models import Ban
-from misago.users.test import AuthenticatedUserTestCase, create_test_user
+from ...acl.test import patch_user_acl
+from ...categories.models import Category
+from ...threads import test
+from ..models import Ban
+from ..test import AuthenticatedUserTestCase, create_test_user
 
 
 
 
 class UserProfileViewsTests(AuthenticatedUserTestCase):
 class UserProfileViewsTests(AuthenticatedUserTestCase):

+ 1 - 2
misago/users/tests/test_profilefields.py

@@ -1,8 +1,7 @@
 from django.contrib.auth import get_user_model
 from django.contrib.auth import get_user_model
 from django.test import TestCase
 from django.test import TestCase
 
 
-from misago.users.profilefields import ProfileFields
-
+from ..profilefields import ProfileFields
 
 
 User = get_user_model()
 User = get_user_model()
 
 

+ 5 - 5
misago/users/tests/test_rankadmin_views.py

@@ -1,10 +1,10 @@
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.acl import ACL_CACHE
-from misago.acl.models import Role
-from misago.admin.test import AdminTestCase
-from misago.cache.test import assert_invalidates_cache
-from misago.users.models import Rank
+from ...acl import ACL_CACHE
+from ...acl.models import Role
+from ...admin.test import AdminTestCase
+from ...cache.test import assert_invalidates_cache
+from ..models import Rank
 
 
 
 
 class RankAdminViewsTests(AdminTestCase):
 class RankAdminViewsTests(AdminTestCase):

+ 1 - 1
misago/users/tests/test_realip_middleware.py

@@ -1,6 +1,6 @@
 from django.test import TestCase
 from django.test import TestCase
 
 
-from misago.users.middleware import RealIPMiddleware
+from ..middleware import RealIPMiddleware
 
 
 
 
 class MockRequest(object):
 class MockRequest(object):

+ 1 - 2
misago/users/tests/test_remove_old_ips_command.py

@@ -6,8 +6,7 @@ from django.core.management import call_command
 from django.test import override_settings
 from django.test import override_settings
 from django.utils import timezone
 from django.utils import timezone
 
 
-from misago.users.management.commands import removeoldips
-
+from ..management.commands import removeoldips
 
 
 IP_STORE_TIME = 2
 IP_STORE_TIME = 2
 
 

+ 2 - 2
misago/users/tests/test_rest_permissions.py

@@ -1,7 +1,7 @@
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.users.models import Ban
-from misago.users.test import UserTestCase
+from ..models import Ban
+from ..test import UserTestCase
 
 
 
 
 class UnbannedOnlyTests(UserTestCase):
 class UnbannedOnlyTests(UserTestCase):

+ 2 - 2
misago/users/tests/test_search.py

@@ -1,7 +1,7 @@
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.acl.test import patch_user_acl
-from misago.users.test import AuthenticatedUserTestCase, create_test_user
+from ...acl.test import patch_user_acl
+from ..test import AuthenticatedUserTestCase, create_test_user
 
 
 
 
 class SearchApiTests(AuthenticatedUserTestCase):
 class SearchApiTests(AuthenticatedUserTestCase):

+ 2 - 2
misago/users/tests/test_signatures.py

@@ -2,8 +2,8 @@ from unittest.mock import Mock
 
 
 import pytest
 import pytest
 
 
-from misago.acl.useracl import get_user_acl
-from misago.users import signatures
+from ...acl.useracl import get_user_acl
+from ...users import signatures
 
 
 
 
 @pytest.fixture
 @pytest.fixture

+ 10 - 12
misago/users/tests/test_social_pipeline.py

@@ -6,16 +6,15 @@ from django.test import RequestFactory
 from social_core.backends.github import GithubOAuth2
 from social_core.backends.github import GithubOAuth2
 from social_django.utils import load_strategy
 from social_django.utils import load_strategy
 
 
-from misago.acl import ACL_CACHE
-from misago.acl.useracl import get_user_acl
-from misago.conf.dynamicsettings import DynamicSettings
-from misago.core.exceptions import SocialAuthFailed, SocialAuthBanned
-from misago.conf.test import override_dynamic_settings
-from misago.conftest import get_cache_versions
-from misago.legal.models import Agreement
-
-from misago.users.models import AnonymousUser, Ban, BanCache
-from misago.users.social.pipeline import (
+from ...acl import ACL_CACHE
+from ...acl.useracl import get_user_acl
+from ...conf.dynamicsettings import DynamicSettings
+from ...conf.test import override_dynamic_settings
+from ...conftest import get_cache_versions
+from ...core.exceptions import SocialAuthBanned, SocialAuthFailed
+from ...legal.models import Agreement
+from ..models import AnonymousUser, Ban, BanCache
+from ..social.pipeline import (
     associate_by_email,
     associate_by_email,
     create_user,
     create_user,
     create_user_with_form,
     create_user_with_form,
@@ -24,8 +23,7 @@ from misago.users.social.pipeline import (
     validate_ip_not_banned,
     validate_ip_not_banned,
     validate_user_not_banned,
     validate_user_not_banned,
 )
 )
-from misago.users.test import UserTestCase
-
+from ..test import UserTestCase
 
 
 User = get_user_model()
 User = get_user_model()
 
 

+ 1 - 1
misago/users/tests/test_social_utils.py

@@ -1,7 +1,7 @@
 from django.test import TestCase, override_settings
 from django.test import TestCase, override_settings
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.users.social.utils import get_enabled_social_auth_sites_list
+from ..social.utils import get_enabled_social_auth_sites_list
 
 
 
 
 class SocialUtilsTests(TestCase):
 class SocialUtilsTests(TestCase):

+ 1 - 1
misago/users/tests/test_testutils.py

@@ -1,6 +1,6 @@
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.users.test import AuthenticatedUserTestCase, SuperUserTestCase, UserTestCase
+from ..test import AuthenticatedUserTestCase, SuperUserTestCase, UserTestCase
 
 
 
 
 class UserTestCaseTests(UserTestCase):
 class UserTestCaseTests(UserTestCase):

+ 1 - 1
misago/users/tests/test_token_creation_and_validation.py

@@ -1,4 +1,4 @@
-from misago.users import tokens
+from ...users import tokens
 
 
 
 
 def test_token_can_be_created_for_user(user):
 def test_token_can_be_created_for_user(user):

+ 1 - 2
misago/users/tests/test_twitter_profilefield.py

@@ -1,8 +1,7 @@
 from django.contrib.auth import get_user_model
 from django.contrib.auth import get_user_model
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.admin.test import AdminTestCase
-
+from ...admin.test import AdminTestCase
 
 
 User = get_user_model()
 User = get_user_model()
 
 

+ 6 - 6
misago/users/tests/test_user_avatar_api.py

@@ -4,12 +4,12 @@ from pathlib import Path
 
 
 from django.contrib.auth import get_user_model
 from django.contrib.auth import get_user_model
 
 
-from misago.acl.test import patch_user_acl
-from misago.conf import settings
-from misago.conf.test import override_dynamic_settings
-from misago.users.avatars import gallery, store
-from misago.users.models import AvatarGallery
-from misago.users.test import AuthenticatedUserTestCase, create_test_user
+from ...acl.test import patch_user_acl
+from ...conf import settings
+from ...conf.test import override_dynamic_settings
+from ..avatars import gallery, store
+from ..models import AvatarGallery
+from ..test import AuthenticatedUserTestCase, create_test_user
 
 
 TESTFILES_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "testfiles")
 TESTFILES_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "testfiles")
 TEST_AVATAR_PATH = os.path.join(TESTFILES_DIR, "avatar.png")
 TEST_AVATAR_PATH = os.path.join(TESTFILES_DIR, "avatar.png")

+ 1 - 1
misago/users/tests/test_user_changeemail_api.py

@@ -1,7 +1,7 @@
 from django.core import mail
 from django.core import mail
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.users.test import AuthenticatedUserTestCase, create_test_user
+from ..test import AuthenticatedUserTestCase, create_test_user
 
 
 
 
 class UserChangeEmailTests(AuthenticatedUserTestCase):
 class UserChangeEmailTests(AuthenticatedUserTestCase):

+ 1 - 1
misago/users/tests/test_user_changepassword_api.py

@@ -1,7 +1,7 @@
 from django.core import mail
 from django.core import mail
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.users.test import AuthenticatedUserTestCase
+from ..test import AuthenticatedUserTestCase
 
 
 
 
 class UserChangePasswordTests(AuthenticatedUserTestCase):
 class UserChangePasswordTests(AuthenticatedUserTestCase):

+ 4 - 4
misago/users/tests/test_user_create_api.py

@@ -2,10 +2,10 @@ from django.contrib.auth import get_user_model
 from django.core import mail
 from django.core import mail
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.conf.test import override_dynamic_settings
-from misago.legal.models import Agreement
-from misago.users.models import Ban, Online
-from misago.users.test import UserTestCase
+from ...conf.test import override_dynamic_settings
+from ...legal.models import Agreement
+from ..models import Ban, Online
+from ..test import UserTestCase
 
 
 User = get_user_model()
 User = get_user_model()
 
 

+ 2 - 2
misago/users/tests/test_user_creation.py

@@ -1,8 +1,8 @@
 import pytest
 import pytest
 from django.contrib.auth import get_user_model
 from django.contrib.auth import get_user_model
 
 
-from misago.users.models import Rank
-from misago.users.utils import hash_email
+from ..models import Rank
+from ..utils import hash_email
 
 
 User = get_user_model()
 User = get_user_model()
 
 

+ 2 - 2
misago/users/tests/test_user_datadownloads_api.py

@@ -1,5 +1,5 @@
-from misago.users.datadownloads import request_user_data_download
-from misago.users.test import AuthenticatedUserTestCase
+from ..datadownloads import request_user_data_download
+from ..test import AuthenticatedUserTestCase
 
 
 
 
 class UserDataDownloadsApiTests(AuthenticatedUserTestCase):
 class UserDataDownloadsApiTests(AuthenticatedUserTestCase):

+ 2 - 2
misago/users/tests/test_user_details_api.py

@@ -1,7 +1,7 @@
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.acl.test import patch_user_acl
-from misago.users.test import AuthenticatedUserTestCase, create_test_user
+from ...acl.test import patch_user_acl
+from ..test import AuthenticatedUserTestCase, create_test_user
 
 
 
 
 class UserDetailsApiTests(AuthenticatedUserTestCase):
 class UserDetailsApiTests(AuthenticatedUserTestCase):

+ 2 - 2
misago/users/tests/test_user_editdetails_api.py

@@ -1,7 +1,7 @@
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.acl.test import patch_user_acl
-from misago.users.test import AuthenticatedUserTestCase, create_test_user
+from ...acl.test import patch_user_acl
+from ..test import AuthenticatedUserTestCase, create_test_user
 
 
 
 
 class UserEditDetailsApiTests(AuthenticatedUserTestCase):
 class UserEditDetailsApiTests(AuthenticatedUserTestCase):

+ 2 - 2
misago/users/tests/test_user_feeds_api.py

@@ -1,7 +1,7 @@
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.threads import test
-from misago.threads.tests.test_threads_api import ThreadsApiTestCase
+from ...threads import test
+from ...threads.tests.test_threads_api import ThreadsApiTestCase
 
 
 
 
 class UserThreadsApiTests(ThreadsApiTestCase):
 class UserThreadsApiTests(ThreadsApiTestCase):

+ 3 - 3
misago/users/tests/test_user_middleware.py

@@ -1,8 +1,8 @@
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.users.bans import ban_ip, ban_user
-from misago.users.models import Ban
-from misago.users.test import AuthenticatedUserTestCase
+from ..bans import ban_ip, ban_user
+from ..models import Ban
+from ..test import AuthenticatedUserTestCase
 
 
 
 
 class UserMiddlewareTest(AuthenticatedUserTestCase):
 class UserMiddlewareTest(AuthenticatedUserTestCase):

+ 4 - 5
misago/users/tests/test_user_model.py

@@ -2,11 +2,10 @@ from pathlib import Path
 
 
 from django.test import TestCase
 from django.test import TestCase
 
 
-from misago.conf import settings
-from misago.core.utils import slugify
-
-from misago.users.avatars import dynamic
-from misago.users.models import Avatar, User
+from ...conf import settings
+from ...core.utils import slugify
+from ..avatars import dynamic
+from ..models import Avatar, User
 
 
 
 
 class UserTests(TestCase):
 class UserTests(TestCase):

+ 2 - 2
misago/users/tests/test_user_requestdatadownload_api.py

@@ -1,7 +1,7 @@
 from django.test.utils import override_settings
 from django.test.utils import override_settings
 
 
-from misago.users.datadownloads import request_user_data_download
-from misago.users.test import AuthenticatedUserTestCase
+from ..datadownloads import request_user_data_download
+from ..test import AuthenticatedUserTestCase
 
 
 
 
 class UserRequestDataDownload(AuthenticatedUserTestCase):
 class UserRequestDataDownload(AuthenticatedUserTestCase):

+ 2 - 2
misago/users/tests/test_user_signature_api.py

@@ -1,5 +1,5 @@
-from misago.acl.test import patch_user_acl
-from misago.users.test import AuthenticatedUserTestCase
+from ...acl.test import patch_user_acl
+from ..test import AuthenticatedUserTestCase
 
 
 
 
 class UserSignatureTests(AuthenticatedUserTestCase):
 class UserSignatureTests(AuthenticatedUserTestCase):

+ 3 - 3
misago/users/tests/test_user_username_api.py

@@ -1,8 +1,8 @@
 import json
 import json
 
 
-from misago.acl.test import patch_user_acl
-from misago.conf.test import override_dynamic_settings
-from misago.users.test import AuthenticatedUserTestCase, create_test_user
+from ...acl.test import patch_user_acl
+from ...conf.test import override_dynamic_settings
+from ..test import AuthenticatedUserTestCase, create_test_user
 
 
 
 
 class UserUsernameTests(AuthenticatedUserTestCase):
 class UserUsernameTests(AuthenticatedUserTestCase):

+ 9 - 10
misago/users/tests/test_useradmin_views.py

@@ -2,16 +2,15 @@ from django.contrib.auth import get_user_model
 from django.core import mail
 from django.core import mail
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.acl.models import Role
-from misago.admin.test import AdminTestCase
-from misago.categories.models import Category
-from misago.legal.models import Agreement
-from misago.legal.utils import save_user_agreement_acceptance
-from misago.threads.test import post_thread, reply_thread
-
-from misago.users.datadownloads import request_user_data_download
-from misago.users.models import Ban, DataDownload, Rank
-from misago.users.test import create_test_user
+from ...acl.models import Role
+from ...admin.test import AdminTestCase
+from ...categories.models import Category
+from ...legal.models import Agreement
+from ...legal.utils import save_user_agreement_acceptance
+from ...threads.test import post_thread, reply_thread
+from ..datadownloads import request_user_data_download
+from ..models import Ban, DataDownload, Rank
+from ..test import create_test_user
 
 
 User = get_user_model()
 User = get_user_model()
 
 

+ 2 - 2
misago/users/tests/test_usernamechanges_api.py

@@ -1,5 +1,5 @@
-from misago.acl.test import patch_user_acl
-from misago.users.test import AuthenticatedUserTestCase
+from ...acl.test import patch_user_acl
+from ..test import AuthenticatedUserTestCase
 
 
 
 
 class UsernameChangesApiTests(AuthenticatedUserTestCase):
 class UsernameChangesApiTests(AuthenticatedUserTestCase):

+ 7 - 7
misago/users/tests/test_users_api.py

@@ -6,13 +6,13 @@ from django.test import override_settings
 from django.urls import reverse
 from django.urls import reverse
 from django.utils.encoding import smart_str
 from django.utils.encoding import smart_str
 
 
-from misago.acl.test import patch_user_acl
-from misago.categories.models import Category
-from misago.threads.models import Post, Thread
-from misago.threads.test import post_thread
-from misago.users.activepostersranking import build_active_posters_ranking
-from misago.users.models import Ban, Rank
-from misago.users.test import AuthenticatedUserTestCase, create_test_user
+from ...acl.test import patch_user_acl
+from ...categories.models import Category
+from ...threads.models import Post, Thread
+from ...threads.test import post_thread
+from ..activepostersranking import build_active_posters_ranking
+from ..models import Ban, Rank
+from ..test import AuthenticatedUserTestCase, create_test_user
 
 
 User = get_user_model()
 User = get_user_model()
 
 

+ 1 - 1
misago/users/tests/test_utils.py

@@ -1,6 +1,6 @@
 from django.test import TestCase
 from django.test import TestCase
 
 
-from misago.users.utils import hash_email
+from ..utils import hash_email
 
 
 
 
 class HashEmailTests(TestCase):
 class HashEmailTests(TestCase):

+ 3 - 3
misago/users/tests/test_validators.py

@@ -3,9 +3,9 @@ from unittest.mock import Mock
 from django.core.exceptions import ValidationError
 from django.core.exceptions import ValidationError
 from django.test import TestCase
 from django.test import TestCase
 
 
-from misago.users.models import Ban
-from misago.users.test import create_test_user
-from misago.users.validators import (
+from ..models import Ban
+from ..test import create_test_user
+from ..validators import (
     validate_email,
     validate_email,
     validate_email_available,
     validate_email_available,
     validate_email_banned,
     validate_email_banned,

+ 2 - 2
misago/users/urls/__init__.py

@@ -1,8 +1,8 @@
 from django.conf.urls import include, url
 from django.conf.urls import include, url
 
 
-from misago.core.views import home_redirect
+from ...core.views import home_redirect
 
 
-from misago.users.views import (
+from ..views import (
     activation,
     activation,
     auth,
     auth,
     avatarserver,
     avatarserver,

+ 5 - 6
misago/users/urls/api.py

@@ -1,11 +1,10 @@
 from django.conf.urls import url
 from django.conf.urls import url
 
 
-from misago.core.apirouter import MisagoApiRouter
-from misago.users.api import auth, captcha, mention
-from misago.users.api.ranks import RanksViewSet
-from misago.users.api.usernamechanges import UsernameChangesViewSet
-from misago.users.api.users import UserViewSet
-
+from ...core.apirouter import MisagoApiRouter
+from ..api import auth, captcha, mention
+from ..api.ranks import RanksViewSet
+from ..api.usernamechanges import UsernameChangesViewSet
+from ..api.users import UserViewSet
 
 
 urlpatterns = [
 urlpatterns = [
     url(r"^auth/$", auth.gateway, name="auth"),
     url(r"^auth/$", auth.gateway, name="auth"),

+ 1 - 4
misago/users/validators.py

@@ -2,7 +2,6 @@ import json
 import re
 import re
 
 
 import requests
 import requests
-
 from django.contrib.auth import get_user_model
 from django.contrib.auth import get_user_model
 from django.core.exceptions import ValidationError
 from django.core.exceptions import ValidationError
 from django.core.validators import validate_email as validate_email_content
 from django.core.validators import validate_email as validate_email_content
@@ -11,11 +10,9 @@ from django.utils.module_loading import import_string
 from django.utils.translation import gettext_lazy as _
 from django.utils.translation import gettext_lazy as _
 from django.utils.translation import ngettext
 from django.utils.translation import ngettext
 
 
-from misago.conf import settings
-
+from ..conf import settings
 from .bans import get_email_ban, get_username_ban
 from .bans import get_email_ban, get_username_ban
 
 
-
 USERNAME_RE = re.compile(r"^[0-9a-z]+$", re.IGNORECASE)
 USERNAME_RE = re.compile(r"^[0-9a-z]+$", re.IGNORECASE)
 
 
 User = get_user_model()
 User = get_user_model()

+ 4 - 4
misago/users/viewmodels/activeposters.py

@@ -1,7 +1,7 @@
-from misago.conf import settings
-from misago.users.activepostersranking import get_active_posters_ranking
-from misago.users.online.utils import make_users_status_aware
-from misago.users.serializers import UserCardSerializer
+from ...conf import settings
+from ..activepostersranking import get_active_posters_ranking
+from ..online.utils import make_users_status_aware
+from ..serializers import UserCardSerializer
 
 
 
 
 class ActivePosters(object):
 class ActivePosters(object):

+ 4 - 4
misago/users/viewmodels/followers.py

@@ -1,9 +1,9 @@
 from django.http import Http404
 from django.http import Http404
 
 
-from misago.conf import settings
-from misago.core.shortcuts import paginate, pagination_dict
-from misago.users.online.utils import make_users_status_aware
-from misago.users.serializers import UserCardSerializer
+from ...conf import settings
+from ...core.shortcuts import paginate, pagination_dict
+from ..online.utils import make_users_status_aware
+from ..serializers import UserCardSerializer
 
 
 
 
 class Followers(object):
 class Followers(object):

+ 2 - 3
misago/users/viewmodels/posts.py

@@ -1,6 +1,5 @@
-from misago.threads.models import Thread
-from misago.threads.permissions import exclude_invisible_threads
-
+from ...threads.models import Thread
+from ...threads.permissions import exclude_invisible_threads
 from .threads import UserThreads
 from .threads import UserThreads
 
 
 
 

+ 4 - 4
misago/users/viewmodels/rankusers.py

@@ -1,7 +1,7 @@
-from misago.conf import settings
-from misago.core.shortcuts import paginate, pagination_dict
-from misago.users.online.utils import make_users_status_aware
-from misago.users.serializers import UserCardSerializer
+from ...conf import settings
+from ...core.shortcuts import paginate, pagination_dict
+from ..online.utils import make_users_status_aware
+from ..serializers import UserCardSerializer
 
 
 
 
 class RankUsers(object):
 class RankUsers(object):

+ 7 - 7
misago/users/viewmodels/threads.py

@@ -1,10 +1,10 @@
-from misago.acl.objectacl import add_acl_to_obj
-from misago.conf import settings
-from misago.core.shortcuts import paginate, pagination_dict
-from misago.threads.permissions import exclude_invisible_threads
-from misago.threads.serializers import FeedSerializer
-from misago.threads.utils import add_categories_to_items
-from misago.threads.viewmodels import ThreadsRootCategory
+from ...acl.objectacl import add_acl_to_obj
+from ...conf import settings
+from ...core.shortcuts import paginate, pagination_dict
+from ...threads.permissions import exclude_invisible_threads
+from ...threads.serializers import FeedSerializer
+from ...threads.utils import add_categories_to_items
+from ...threads.viewmodels import ThreadsRootCategory
 
 
 
 
 class UserThreads(object):
 class UserThreads(object):

+ 4 - 5
misago/users/views/activation.py

@@ -3,11 +3,10 @@ from django.shortcuts import get_object_or_404, render
 from django.urls import reverse
 from django.urls import reverse
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
 
 
-from misago.core.exceptions import Banned
-from misago.users.bans import get_user_ban
-from misago.users.decorators import deny_authenticated, deny_banned_ips
-from misago.users.tokens import is_activation_token_valid
-
+from ...core.exceptions import Banned
+from ..bans import get_user_ban
+from ..decorators import deny_authenticated, deny_banned_ips
+from ..tokens import is_activation_token_valid
 
 
 User = get_user_model()
 User = get_user_model()
 
 

+ 3 - 3
misago/users/views/admin/bans.py

@@ -1,9 +1,9 @@
 from django.contrib import messages
 from django.contrib import messages
 from django.utils.translation import gettext_lazy as _
 from django.utils.translation import gettext_lazy as _
 
 
-from misago.admin.views import generic
-from misago.users.forms.admin import BanForm, SearchBansForm
-from misago.users.models import Ban
+from ....admin.views import generic
+from ...forms.admin import BanForm, SearchBansForm
+from ...models import Ban
 
 
 
 
 class BanAdmin(generic.AdminBaseMixin):
 class BanAdmin(generic.AdminBaseMixin):

+ 4 - 4
misago/users/views/admin/datadownloads.py

@@ -1,14 +1,14 @@
 from django.contrib import messages
 from django.contrib import messages
 from django.utils.translation import gettext_lazy as _
 from django.utils.translation import gettext_lazy as _
 
 
-from misago.admin.views import generic
-from misago.users.datadownloads import (
+from ....admin.views import generic
+from ...datadownloads import (
     expire_user_data_download,
     expire_user_data_download,
     request_user_data_download,
     request_user_data_download,
     user_has_data_download_request,
     user_has_data_download_request,
 )
 )
-from misago.users.forms.admin import RequestDataDownloadsForm, SearchDataDownloadsForm
-from misago.users.models import DataDownload
+from ...forms.admin import RequestDataDownloadsForm, SearchDataDownloadsForm
+from ...models import DataDownload
 
 
 
 
 class DataDownloadAdmin(generic.AdminBaseMixin):
 class DataDownloadAdmin(generic.AdminBaseMixin):

+ 3 - 3
misago/users/views/admin/ranks.py

@@ -3,9 +3,9 @@ from django.shortcuts import redirect
 from django.urls import reverse
 from django.urls import reverse
 from django.utils.translation import gettext_lazy as _
 from django.utils.translation import gettext_lazy as _
 
 
-from misago.admin.views import generic
-from misago.users.forms.admin import RankForm
-from misago.users.models import Rank
+from ....admin.views import generic
+from ...forms.admin import RankForm
+from ...models import Rank
 
 
 
 
 class RankAdmin(generic.AdminBaseMixin):
 class RankAdmin(generic.AdminBaseMixin):

+ 14 - 17
misago/users/views/admin/users.py

@@ -5,29 +5,26 @@ from django.http import JsonResponse
 from django.shortcuts import redirect
 from django.shortcuts import redirect
 from django.utils.translation import gettext_lazy as _
 from django.utils.translation import gettext_lazy as _
 
 
-from misago.acl.useracl import get_user_acl
-from misago.admin.auth import start_admin_session
-from misago.admin.views import generic
-from misago.categories.models import Category
-from misago.core.mail import mail_users
-from misago.core.pgutils import chunk_queryset
-from misago.threads.models import Thread
-from misago.users.avatars.dynamic import set_avatar as set_dynamic_avatar
-from misago.users.datadownloads import (
-    request_user_data_download,
-    user_has_data_download_request,
-)
-from misago.users.forms.admin import (
+from ....acl.useracl import get_user_acl
+from ....admin.auth import start_admin_session
+from ....admin.views import generic
+from ....categories.models import Category
+from ....core.mail import mail_users
+from ....core.pgutils import chunk_queryset
+from ....threads.models import Thread
+from ...avatars.dynamic import set_avatar as set_dynamic_avatar
+from ...datadownloads import request_user_data_download, user_has_data_download_request
+from ...forms.admin import (
     BanUsersForm,
     BanUsersForm,
     EditUserForm,
     EditUserForm,
     EditUserFormFactory,
     EditUserFormFactory,
     NewUserForm,
     NewUserForm,
     create_search_users_form,
     create_search_users_form,
 )
 )
-from misago.users.models import Ban
-from misago.users.profilefields import profilefields
-from misago.users.setupnewuser import setup_new_user
-from misago.users.signatures import set_user_signature
+from ...models import Ban
+from ...profilefields import profilefields
+from ...setupnewuser import setup_new_user
+from ...signatures import set_user_signature
 
 
 User = get_user_model()
 User = get_user_model()
 
 

+ 1 - 2
misago/users/views/avatarserver.py

@@ -2,8 +2,7 @@ from django.contrib.auth import get_user_model
 from django.contrib.staticfiles.templatetags.staticfiles import static
 from django.contrib.staticfiles.templatetags.staticfiles import static
 from django.shortcuts import redirect
 from django.shortcuts import redirect
 
 
-from misago.conf import settings
-
+from ...conf import settings
 
 
 User = get_user_model()
 User = get_user_model()
 
 

+ 4 - 4
misago/users/views/forgottenpassword.py

@@ -3,10 +3,10 @@ from django.shortcuts import get_object_or_404, render
 from django.urls import reverse
 from django.urls import reverse
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
 
 
-from misago.core.exceptions import Banned
-from misago.users.bans import get_user_ban
-from misago.users.decorators import deny_banned_ips
-from misago.users.tokens import is_password_change_token_valid
+from ...core.exceptions import Banned
+from ..bans import get_user_ban
+from ..decorators import deny_banned_ips
+from ..tokens import is_password_change_token_valid
 
 
 
 
 def reset_view(f):
 def reset_view(f):

+ 5 - 5
misago/users/views/lists.py

@@ -2,11 +2,11 @@ from django.shortcuts import get_object_or_404, redirect, render
 from django.urls import reverse
 from django.urls import reverse
 from django.views import View
 from django.views import View
 
 
-from misago.core.utils import format_plaintext_for_html
-from misago.users.models import Rank
-from misago.users.pages import users_list
-from misago.users.permissions import allow_browse_users_list
-from misago.users.viewmodels import ActivePosters, RankUsers
+from ...core.utils import format_plaintext_for_html
+from ..models import Rank
+from ..pages import users_list
+from ..permissions import allow_browse_users_list
+from ..viewmodels import ActivePosters, RankUsers
 
 
 
 
 class ListView(View):
 class ListView(View):

+ 3 - 3
misago/users/views/options.py

@@ -3,9 +3,9 @@ from django.db import IntegrityError
 from django.shortcuts import render
 from django.shortcuts import render
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
 
 
-from misago.users.credentialchange import read_new_credential
-from misago.users.decorators import deny_guests
-from misago.users.pages import usercp
+from ..credentialchange import read_new_credential
+from ..decorators import deny_guests
+from ..pages import usercp
 
 
 
 
 @deny_guests
 @deny_guests

+ 8 - 13
misago/users/views/profile.py

@@ -3,19 +3,14 @@ from django.http import Http404
 from django.shortcuts import get_object_or_404, redirect, render
 from django.shortcuts import get_object_or_404, redirect, render
 from django.views import View
 from django.views import View
 
 
-from misago.acl.objectacl import add_acl_to_obj
-from misago.core.shortcuts import paginate, pagination_dict, validate_slug
-from misago.users.bans import get_user_ban
-from misago.users.online.utils import get_user_status
-from misago.users.pages import user_profile
-from misago.users.profilefields import profilefields, serialize_profilefields_data
-from misago.users.serializers import (
-    BanDetailsSerializer,
-    UsernameChangeSerializer,
-    UserSerializer,
-)
-from misago.users.viewmodels import Followers, Follows, UserPosts, UserThreads
-
+from ...acl.objectacl import add_acl_to_obj
+from ...core.shortcuts import paginate, pagination_dict, validate_slug
+from ..bans import get_user_ban
+from ..online.utils import get_user_status
+from ..pages import user_profile
+from ..profilefields import profilefields, serialize_profilefields_data
+from ..serializers import BanDetailsSerializer, UsernameChangeSerializer, UserSerializer
+from ..viewmodels import Followers, Follows, UserPosts, UserThreads
 
 
 User = get_user_model()
 User = get_user_model()