Browse Source

made in-app imports relative, utility for converting abs imports to rel ones

Rafał Pitoń 9 years ago
parent
commit
cc198368a5
272 changed files with 679 additions and 551 deletions
  1. 20 4
      fixabsoluteimports.py
  2. 1 1
      misago/acl/__init__.py
  3. 1 1
      misago/acl/admin.py
  4. 4 3
      misago/acl/api.py
  5. 1 1
      misago/acl/builder.py
  6. 3 2
      misago/acl/forms.py
  7. 2 1
      misago/acl/models.py
  8. 1 1
      misago/acl/tests/test_acl_algebra.py
  9. 2 1
      misago/acl/tests/test_api.py
  10. 1 1
      misago/acl/tests/test_providers.py
  11. 3 2
      misago/acl/tests/test_roleadmin_views.py
  12. 2 2
      misago/acl/tests/test_testutils.py
  13. 2 1
      misago/acl/testutils.py
  14. 3 2
      misago/acl/views.py
  15. 3 3
      misago/admin/__init__.py
  16. 2 2
      misago/admin/discoverer.py
  17. 3 3
      misago/admin/middleware.py
  18. 1 1
      misago/admin/tests/test_admin_hierarchy.py
  19. 2 2
      misago/admin/tests/test_admin_views.py
  20. 2 1
      misago/admin/urls.py
  21. 3 3
      misago/admin/views/__init__.py
  22. 2 1
      misago/admin/views/auth.py
  23. 2 2
      misago/admin/views/errorpages.py
  24. 4 4
      misago/admin/views/generic/__init__.py
  25. 1 1
      misago/admin/views/generic/base.py
  26. 1 1
      misago/admin/views/generic/formsbuttons.py
  27. 2 1
      misago/admin/views/generic/list.py
  28. 2 1
      misago/admin/views/index.py
  29. 2 2
      misago/categories/admin.py
  30. 1 1
      misago/categories/apps.py
  31. 2 1
      misago/categories/forms.py
  32. 1 1
      misago/categories/management/commands/prunecategories.py
  33. 2 1
      misago/categories/management/commands/synchronizecategories.py
  34. 2 2
      misago/categories/models.py
  35. 2 1
      misago/categories/permissions.py
  36. 2 1
      misago/categories/serializers.py
  37. 2 1
      misago/categories/signals.py
  38. 2 1
      misago/categories/tests/test_categories_admin_views.py
  39. 2 1
      misago/categories/tests/test_category_model.py
  40. 2 1
      misago/categories/tests/test_permissions_admin_views.py
  41. 3 2
      misago/categories/tests/test_prunecategories.py
  42. 3 2
      misago/categories/tests/test_synchronizecategories.py
  43. 3 2
      misago/categories/tests/test_utils.py
  44. 3 2
      misago/categories/tests/test_views.py
  45. 1 1
      misago/categories/urls/__init__.py
  46. 1 1
      misago/categories/urls/api.py
  47. 2 1
      misago/categories/utils.py
  48. 2 2
      misago/categories/views/__init__.py
  49. 3 2
      misago/categories/views/categoriesadmin.py
  50. 4 3
      misago/categories/views/permsadmin.py
  51. 1 1
      misago/conf/__init__.py
  52. 1 1
      misago/conf/admin.py
  53. 1 1
      misago/conf/context_processors.py
  54. 2 2
      misago/conf/dbsettings.py
  55. 1 1
      misago/conf/gateway.py
  56. 3 2
      misago/conf/migrationutils.py
  57. 2 1
      misago/conf/models.py
  58. 2 1
      misago/conf/tests/test_admin_views.py
  59. 3 2
      misago/conf/tests/test_context_processors.py
  60. 2 2
      misago/conf/tests/test_hydrators.py
  61. 3 2
      misago/conf/tests/test_migrationutils.py
  62. 1 1
      misago/conf/tests/test_models.py
  63. 4 3
      misago/conf/tests/test_settings.py
  64. 4 3
      misago/conf/views.py
  65. 1 1
      misago/core/apipaginator.py
  66. 9 9
      misago/core/cachebuster.py
  67. 1 1
      misago/core/decorators.py
  68. 2 1
      misago/core/errorpages.py
  69. 2 2
      misago/core/exceptionhandler.py
  70. 1 1
      misago/core/management/commands/remakemisagochecksums.py
  71. 2 2
      misago/core/middleware/exceptionhandler.py
  72. 1 1
      misago/core/middleware/threadstore.py
  73. 2 2
      misago/core/migrationutils.py
  74. 2 2
      misago/core/shortcuts.py
  75. 2 1
      misago/core/testproject/urls.py
  76. 1 1
      misago/core/testproject/urlswitherrorhandlers.py
  77. 7 6
      misago/core/testproject/views.py
  78. 1 1
      misago/core/tests/test_apipaginator.py
  79. 1 1
      misago/core/tests/test_apipatch.py
  80. 4 4
      misago/core/tests/test_cachebuster.py
  81. 1 1
      misago/core/tests/test_context_processors.py
  82. 2 1
      misago/core/tests/test_errorpages.py
  83. 2 1
      misago/core/tests/test_exceptionhandler_middleware.py
  84. 3 2
      misago/core/tests/test_exceptionhandlers.py
  85. 1 1
      misago/core/tests/test_fileserver.py
  86. 1 1
      misago/core/tests/test_forms.py
  87. 1 1
      misago/core/tests/test_frontendcontext_middleware.py
  88. 2 2
      misago/core/tests/test_migrationutils.py
  89. 1 1
      misago/core/tests/test_misagodbrelations.py
  90. 1 1
      misago/core/tests/test_misagorequirements.py
  91. 1 1
      misago/core/tests/test_momentjs.py
  92. 1 1
      misago/core/tests/test_page.py
  93. 1 1
      misago/core/tests/test_remakemisagochecksums.py
  94. 1 1
      misago/core/tests/test_serializer.py
  95. 1 1
      misago/core/tests/test_setup.py
  96. 1 1
      misago/core/tests/test_shortcuts.py
  97. 3 3
      misago/core/tests/test_templatetags.py
  98. 1 1
      misago/core/tests/test_testmailsetup.py
  99. 2 2
      misago/core/tests/test_threadstore.py
  100. 1 7
      misago/core/tests/test_utils.py
  101. 1 1
      misago/core/tests/test_validators.py
  102. 2 2
      misago/core/testutils.py
  103. 1 1
      misago/core/validators.py
  104. 1 1
      misago/core/views.py
  105. 2 1
      misago/legal/tests.py
  106. 1 1
      misago/legal/urls.py
  107. 3 3
      misago/markup/__init__.py
  108. 1 1
      misago/markup/flavours.py
  109. 3 3
      misago/markup/parser.py
  110. 1 1
      misago/markup/tests/test_checksums.py
  111. 1 1
      misago/markup/tests/test_parser.py
  112. 1 1
      misago/readtracker/apps.py
  113. 4 3
      misago/readtracker/categoriestracker.py
  114. 1 1
      misago/readtracker/tests/test_dates.py
  115. 2 1
      misago/readtracker/tests/test_readtracker.py
  116. 3 3
      misago/readtracker/threadstracker.py
  117. 3 2
      misago/threads/api/threadendpoints/list.py
  118. 7 6
      misago/threads/api/threadendpoints/merge.py
  119. 4 3
      misago/threads/api/threadendpoints/patch.py
  120. 3 2
      misago/threads/api/threadposts.py
  121. 9 8
      misago/threads/api/threads.py
  122. 1 1
      misago/threads/apps.py
  123. 1 1
      misago/threads/events.py
  124. 2 1
      misago/threads/management/commands/synchronizethreads.py
  125. 1 1
      misago/threads/middleware.py
  126. 4 4
      misago/threads/models/__init__.py
  127. 6 5
      misago/threads/models/post.py
  128. 3 3
      misago/threads/models/thread.py
  129. 3 3
      misago/threads/moderation/__init__.py
  130. 1 1
      misago/threads/moderation/posts.py
  131. 1 1
      misago/threads/moderation/threads.py
  132. 3 2
      misago/threads/participants.py
  133. 2 2
      misago/threads/permissions/__init__.py
  134. 2 1
      misago/threads/permissions/threads.py
  135. 3 3
      misago/threads/serializers/__init__.py
  136. 5 4
      misago/threads/serializers/moderation.py
  137. 2 1
      misago/threads/serializers/post.py
  138. 2 1
      misago/threads/serializers/thread.py
  139. 2 1
      misago/threads/signals.py
  140. 1 1
      misago/threads/subscriptions.py
  141. 3 2
      misago/threads/tests/-test_floodprotection_middleware.py
  142. 4 3
      misago/threads/tests/test_events.py
  143. 3 2
      misago/threads/tests/test_participants.py
  144. 3 2
      misago/threads/tests/test_post_model.py
  145. 3 2
      misago/threads/tests/test_posts_moderation.py
  146. 3 2
      misago/threads/tests/test_subscriptions.py
  147. 3 2
      misago/threads/tests/test_synchronizethreads.py
  148. 2 1
      misago/threads/tests/test_thread_model.py
  149. 2 1
      misago/threads/tests/test_thread_patch_api.py
  150. 2 1
      misago/threads/tests/test_threadparticipant_model.py
  151. 4 3
      misago/threads/tests/test_threads_api.py
  152. 6 5
      misago/threads/tests/test_threads_merge_api.py
  153. 3 2
      misago/threads/tests/test_threads_moderation.py
  154. 2 1
      misago/threads/tests/test_threadslists.py
  155. 3 2
      misago/threads/tests/test_threadview.py
  156. 2 1
      misago/threads/tests/test_typestree.py
  157. 3 2
      misago/threads/tests/test_utils.py
  158. 2 1
      misago/threads/tests/test_validators.py
  159. 2 1
      misago/threads/testutils.py
  160. 1 1
      misago/threads/threadtypes/privatethread.py
  161. 1 1
      misago/threads/threadtypes/thread.py
  162. 2 2
      misago/threads/urls/__init__.py
  163. 3 2
      misago/threads/urls/api.py
  164. 3 2
      misago/threads/viewmodels/posts.py
  165. 5 4
      misago/threads/viewmodels/thread.py
  166. 6 5
      misago/threads/viewmodels/threads.py
  167. 2 2
      misago/threads/views/list.py
  168. 2 2
      misago/threads/views/thread.py
  169. 2 1
      misago/users/activepostersranking.py
  170. 5 19
      misago/users/admin.py
  171. 7 6
      misago/users/api/auth.py
  172. 2 2
      misago/users/api/ranks.py
  173. 3 2
      misago/users/api/userendpoints/avatar.py
  174. 3 2
      misago/users/api/userendpoints/changeemail.py
  175. 3 2
      misago/users/api/userendpoints/changepassword.py
  176. 8 7
      misago/users/api/userendpoints/create.py
  177. 5 4
      misago/users/api/userendpoints/list.py
  178. 3 2
      misago/users/api/userendpoints/signature.py
  179. 3 2
      misago/users/api/userendpoints/username.py
  180. 4 3
      misago/users/api/usernamechanges.py
  181. 16 15
      misago/users/api/users.py
  182. 3 3
      misago/users/apps.py
  183. 1 1
      misago/users/avatars/__init__.py
  184. 2 1
      misago/users/avatars/dynamic.py
  185. 2 2
      misago/users/avatars/gallery.py
  186. 2 1
      misago/users/avatars/gravatar.py
  187. 2 1
      misago/users/avatars/store.py
  188. 2 1
      misago/users/avatars/uploaded.py
  189. 2 1
      misago/users/bans.py
  190. 2 2
      misago/users/context_processors.py
  191. 3 2
      misago/users/decorators.py
  192. 3 2
      misago/users/forms/admin.py
  193. 3 2
      misago/users/forms/auth.py
  194. 2 1
      misago/users/forms/moderation.py
  195. 3 2
      misago/users/forms/options.py
  196. 2 1
      misago/users/forms/register.py
  197. 2 1
      misago/users/forms/rename.py
  198. 2 1
      misago/users/management/commands/bansmaintenance.py
  199. 2 1
      misago/users/management/commands/buildactivepostersranking.py
  200. 1 1
      misago/users/management/commands/createsuperuser.py
  201. 1 1
      misago/users/management/commands/populateonlinetracker.py
  202. 1 1
      misago/users/management/commands/updateblankavatar.py
  203. 4 3
      misago/users/middleware.py
  204. 5 5
      misago/users/models/__init__.py
  205. 2 2
      misago/users/models/ban.py
  206. 8 7
      misago/users/models/user.py
  207. 1 1
      misago/users/namechanges.py
  208. 1 1
      misago/users/online/tracker.py
  209. 2 2
      misago/users/online/utils.py
  210. 2 1
      misago/users/permissions/moderation.py
  211. 2 1
      misago/users/permissions/profiles.py
  212. 3 2
      misago/users/permissions/warnings.py
  213. 3 2
      misago/users/rest_permissions.py
  214. 3 3
      misago/users/serializers/__init__.py
  215. 2 1
      misago/users/serializers/ban.py
  216. 2 1
      misago/users/serializers/rank.py
  217. 2 1
      misago/users/serializers/user.py
  218. 2 2
      misago/users/serializers/usernamechange.py
  219. 2 2
      misago/users/tests/test_activation_views.py
  220. 3 2
      misago/users/tests/test_activepostersranking.py
  221. 2 2
      misago/users/tests/test_auth_api.py
  222. 2 1
      misago/users/tests/test_avatars.py
  223. 1 1
      misago/users/tests/test_avatarserver_views.py
  224. 1 1
      misago/users/tests/test_ban_model.py
  225. 2 1
      misago/users/tests/test_banadmin_views.py
  226. 2 10
      misago/users/tests/test_bans.py
  227. 3 3
      misago/users/tests/test_bansmaintenance.py
  228. 1 1
      misago/users/tests/test_commands.py
  229. 1 1
      misago/users/tests/test_credentialchange.py
  230. 2 2
      misago/users/tests/test_decorators.py
  231. 3 3
      misago/users/tests/test_forgottenpassword_views.py
  232. 3 2
      misago/users/tests/test_lists_views.py
  233. 1 1
      misago/users/tests/test_namechanges.py
  234. 1 1
      misago/users/tests/test_options_views.py
  235. 2 2
      misago/users/tests/test_populateonlinetracker.py
  236. 3 2
      misago/users/tests/test_profile_views.py
  237. 2 1
      misago/users/tests/test_rankadmin_views.py
  238. 1 1
      misago/users/tests/test_realip_middleware.py
  239. 2 2
      misago/users/tests/test_rest_permissions.py
  240. 1 1
      misago/users/tests/test_signatures.py
  241. 1 1
      misago/users/tests/test_testutils.py
  242. 1 1
      misago/users/tests/test_tokens.py
  243. 1 1
      misago/users/tests/test_updateblankavatar.py
  244. 3 2
      misago/users/tests/test_user_avatar_api.py
  245. 1 1
      misago/users/tests/test_user_changeemail_api.py
  246. 1 1
      misago/users/tests/test_user_changepassword_api.py
  247. 3 2
      misago/users/tests/test_user_create_api.py
  248. 1 1
      misago/users/tests/test_user_model.py
  249. 2 1
      misago/users/tests/test_user_signature_api.py
  250. 2 1
      misago/users/tests/test_user_username_api.py
  251. 2 1
      misago/users/tests/test_useradmin_views.py
  252. 2 1
      misago/users/tests/test_usernamechanges_api.py
  253. 4 3
      misago/users/tests/test_users_api.py
  254. 1 1
      misago/users/tests/test_utils.py
  255. 3 2
      misago/users/tests/test_validators.py
  256. 2 1
      misago/users/tests/test_warningadmin_views.py
  257. 3 2
      misago/users/tests/test_warnings.py
  258. 2 1
      misago/users/testutils.py
  259. 1 1
      misago/users/urls/__init__.py
  260. 5 4
      misago/users/urls/api.py
  261. 2 1
      misago/users/validators.py
  262. 5 4
      misago/users/views/activation.py
  263. 3 2
      misago/users/views/admin/bans.py
  264. 3 2
      misago/users/views/admin/ranks.py
  265. 6 5
      misago/users/views/admin/users.py
  266. 3 2
      misago/users/views/admin/warnings.py
  267. 2 1
      misago/users/views/avatarserver.py
  268. 4 3
      misago/users/views/forgottenpassword.py
  269. 6 5
      misago/users/views/lists.py
  270. 3 3
      misago/users/views/options.py
  271. 9 8
      misago/users/views/profile.py
  272. 1 1
      misago/users/warnings.py

+ 20 - 4
fixabsoluteimports.py

@@ -10,7 +10,7 @@ def walk_directory(root, dirs, files):
 def clean_file(file_path):
 def clean_file(file_path):
     py_source = file(file_path).read()
     py_source = file(file_path).read()
     if 'misago.' in py_source:
     if 'misago.' in py_source:
-        package = file_path.rstrip('.py').split('/')[:-1]
+        package = file_path.rstrip('.py').split('/')
 
 
         parse_file = True
         parse_file = True
         save_file = False
         save_file = False
@@ -44,19 +44,32 @@ def clean_file(file_path):
 
 
 def clean_import(package, import_path):
 def clean_import(package, import_path):
     if len(package) < 2 or len(import_path) < 2:
     if len(package) < 2 or len(import_path) < 2:
+        # skip non-app import
         return
         return
 
 
     if package[:2] != import_path[:2]:
     if package[:2] != import_path[:2]:
+        # skip other app import
         return
         return
 
 
     if package == import_path:
     if package == import_path:
-        # import from sibling module
+        # import from direct child
         return ['', '']
         return ['', '']
 
 
+    if package[:-1] == import_path[:-1]:
+        # import from sibling module
+        return ['', import_path[-1]]
+
     if len(package) < len(import_path) and package == import_path[:len(package)]:
     if len(package) < len(import_path) and package == import_path[:len(package)]:
         # import from child module
         # import from child module
         return [''] + import_path[len(package):]
         return [''] + import_path[len(package):]
 
 
+    if len(package) > len(import_path) and package[:len(import_path)] == import_path:
+        # import from parent module
+        return [''] * (len(package) - len(import_path) + 1)
+
+    # relative up and down path
+    relative_path = []
+
     # find upwards path
     # find upwards path
     overlap_len = 2
     overlap_len = 2
     while True:
     while True:
@@ -64,10 +77,13 @@ def clean_import(package, import_path):
             break
             break
         overlap_len += 1
         overlap_len += 1
 
 
-    upward_path = (['', ''] * (len(package) - overlap_len))[:-1]
+    relative_path += ([''] * (len(package) - overlap_len))[:-1]
 
 
     # append eventual downwards path
     # append eventual downwards path
-    return upward_path + import_path[overlap_len:]
+    if import_path[overlap_len:]:
+        relative_path += [''] + import_path[overlap_len:]
+
+    return relative_path
 
 
 
 
 if __name__ == '__main__':
 if __name__ == '__main__':

+ 1 - 1
misago/acl/__init__.py

@@ -1,4 +1,4 @@
-from misago.acl.api import get_user_acl, add_acl, serialize_acl
+from .api import get_user_acl, add_acl, serialize_acl
 
 
 
 
 default_app_config = 'misago.acl.apps.MisagoACLsConfig'
 default_app_config = 'misago.acl.apps.MisagoACLsConfig'

+ 1 - 1
misago/acl/admin.py

@@ -1,7 +1,7 @@
 from django.conf.urls import url
 from django.conf.urls import url
 from django.utils.translation import ugettext_lazy as _
 from django.utils.translation import ugettext_lazy as _
 
 
-from misago.acl.views import DeleteRole, EditRole, NewRole, RolesList, RoleUsers
+from .views import DeleteRole, EditRole, NewRole, RolesList, RoleUsers
 
 
 
 
 class MisagoAdminExtension(object):
 class MisagoAdminExtension(object):

+ 4 - 3
misago/acl/api.py

@@ -12,12 +12,13 @@ import copy
 
 
 from django.contrib.auth import get_user_model
 from django.contrib.auth import get_user_model
 
 
-from misago.acl import version
-from misago.acl.builder import build_acl
-from misago.acl.providers import providers
 from misago.core import threadstore
 from misago.core import threadstore
 from misago.core.cache import cache
 from misago.core.cache import cache
 
 
+from . import version
+from .builder import build_acl
+from .providers import providers
+
 
 
 def get_user_acl(user):
 def get_user_acl(user):
     """
     """

+ 1 - 1
misago/acl/builder.py

@@ -1,4 +1,4 @@
-from misago.acl.providers import providers
+from .providers import providers
 
 
 
 
 def build_acl(roles):
 def build_acl(roles):

+ 3 - 2
misago/acl/forms.py

@@ -1,9 +1,10 @@
 from django.utils.translation import ugettext_lazy as _
 from django.utils.translation import ugettext_lazy as _
 
 
-from misago.acl.models import Role
-from misago.acl.providers import providers
 from misago.core import forms
 from misago.core import forms
 
 
+from .models import Role
+from .providers import providers
+
 
 
 class RoleForm(forms.ModelForm):
 class RoleForm(forms.ModelForm):
     name = forms.CharField(label=_("Role name"))
     name = forms.CharField(label=_("Role name"))

+ 2 - 1
misago/acl/models.py

@@ -2,10 +2,11 @@
 from django.db import models
 from django.db import models
 from django.dispatch import receiver
 from django.dispatch import receiver
 
 
-from misago.acl import version as acl_version
 from misago.core import serializer
 from misago.core import serializer
 from misago.core.signals import secret_key_changed
 from misago.core.signals import secret_key_changed
 
 
+from . import version as acl_version
+
 
 
 class BaseRole(models.Model):
 class BaseRole(models.Model):
     name = models.CharField(max_length=255)
     name = models.CharField(max_length=255)

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

@@ -1,6 +1,6 @@
 from django.test import TestCase
 from django.test import TestCase
 
 
-from misago.acl import algebra
+from .. import algebra
 
 
 
 
 class ComparisionsTests(TestCase):
 class ComparisionsTests(TestCase):

+ 2 - 1
misago/acl/tests/test_api.py

@@ -1,8 +1,9 @@
 from django.test import TestCase
 from django.test import TestCase
 
 
-from misago.acl.api import get_user_acl
 from misago.users.models import AnonymousUser, User
 from misago.users.models import AnonymousUser, User
 
 
+from ..api import get_user_acl
+
 
 
 class GetUserACLTests(TestCase):
 class GetUserACLTests(TestCase):
     def test_get_authenticated_acl(self):
     def test_get_authenticated_acl(self):

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

@@ -4,7 +4,7 @@ from types import ModuleType
 from django.conf import settings
 from django.conf import settings
 from django.test import TestCase
 from django.test import TestCase
 
 
-from misago.acl.providers import PermissionProviders
+from ..providers import PermissionProviders
 
 
 
 
 class TestType(object):
 class TestType(object):

+ 3 - 2
misago/acl/tests/test_roleadmin_views.py

@@ -1,9 +1,10 @@
 from django.core.urlresolvers import reverse
 from django.core.urlresolvers import reverse
 
 
-from misago.acl.models import Role
-from misago.acl.testutils import fake_post_data
 from misago.admin.testutils import AdminTestCase
 from misago.admin.testutils import AdminTestCase
 
 
+from ..models import Role
+from ..testutils import fake_post_data
+
 
 
 def fake_data(data_dict):
 def fake_data(data_dict):
     return fake_post_data(Role(), data_dict)
     return fake_post_data(Role(), data_dict)

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

@@ -1,7 +1,7 @@
 from django.test import TestCase
 from django.test import TestCase
 
 
-from misago.acl.models import Role
-from misago.acl.testutils import fake_post_data
+from ..models import Role
+from ..testutils import fake_post_data
 
 
 
 
 class FakeTestDataTests(TestCase):
 class FakeTestDataTests(TestCase):

+ 2 - 1
misago/acl/testutils.py

@@ -1,9 +1,10 @@
 # pylint: disable=protected-access
 # pylint: disable=protected-access
 from hashlib import md5
 from hashlib import md5
 
 
-from misago.acl.forms import get_permissions_forms
 from misago.core import threadstore
 from misago.core import threadstore
 
 
+from .forms import get_permissions_forms
+
 
 
 def fake_post_data(target, data_dict):
 def fake_post_data(target, data_dict):
     """
     """

+ 3 - 2
misago/acl/views.py

@@ -3,10 +3,11 @@ from django.core.urlresolvers import reverse
 from django.shortcuts import redirect
 from django.shortcuts import redirect
 from django.utils.translation import ugettext_lazy as _
 from django.utils.translation import ugettext_lazy as _
 
 
-from misago.acl.forms import RoleForm, get_permissions_forms
-from misago.acl.models import Role
 from misago.admin.views import generic
 from misago.admin.views import generic
 
 
+from .forms import RoleForm, get_permissions_forms
+from .models import Role
+
 
 
 class RoleAdmin(generic.AdminBaseMixin):
 class RoleAdmin(generic.AdminBaseMixin):
     root_link = 'misago:admin:permissions:users:index'
     root_link = 'misago:admin:permissions:users:index'

+ 3 - 3
misago/admin/__init__.py

@@ -1,6 +1,6 @@
-from misago.admin.hierarchy import site  # noqa
-from misago.admin.urlpatterns import urlpatterns  # noqa
-from misago.admin.discoverer import discover_misago_admin  # noqa
+from .hierarchy import site  # noqa
+from .urlpatterns import urlpatterns  # noqa
+from .discoverer import discover_misago_admin  # noqa
 
 
 
 
 default_app_config = 'misago.admin.apps.MisagoAdminConfig'
 default_app_config = 'misago.admin.apps.MisagoAdminConfig'

+ 2 - 2
misago/admin/discoverer.py

@@ -2,8 +2,8 @@ from importlib import import_module
 
 
 from django.apps import apps
 from django.apps import apps
 
 
-from misago.admin.hierarchy import site
-from misago.admin.urlpatterns import urlpatterns
+from .hierarchy import site
+from .urlpatterns import urlpatterns
 
 
 
 
 __ALL__ = ['discover_misago_admin']
 __ALL__ = ['discover_misago_admin']

+ 3 - 3
misago/admin/middleware.py

@@ -1,8 +1,8 @@
 from django.shortcuts import redirect
 from django.shortcuts import redirect
 
 
-from misago.admin import auth
-from misago.admin.views import get_protected_namespace
-from misago.admin.views.auth import login
+from . import auth
+from .views import get_protected_namespace
+from .views.auth import login
 
 
 
 
 class AdminAuthMiddleware(object):
 class AdminAuthMiddleware(object):

+ 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_views.py

@@ -2,8 +2,8 @@ from django.contrib.auth import get_user_model
 from django.core.urlresolvers import reverse
 from django.core.urlresolvers import reverse
 from django.test import TestCase
 from django.test import TestCase
 
 
-from misago.admin.testutils import AdminTestCase
-from misago.admin.views import get_protected_namespace
+from ..testutils import AdminTestCase
+from ..views import get_protected_namespace
 
 
 
 
 class FakeRequest(object):
 class FakeRequest(object):

+ 2 - 1
misago/admin/urls.py

@@ -1,7 +1,8 @@
 from django.conf.urls import include, patterns, url
 from django.conf.urls import include, patterns, url
 
 
 from misago import admin
 from misago import admin
-from misago.admin.views import auth, index
+
+from .views import auth, index
 
 
 
 
 urlpatterns = [
 urlpatterns = [

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

@@ -2,9 +2,9 @@ from django.conf import settings
 from django.core.urlresolvers import reverse, NoReverseMatch
 from django.core.urlresolvers import reverse, NoReverseMatch
 from django.shortcuts import render as dj_render
 from django.shortcuts import render as dj_render
 
 
-from misago.admin import site
-from misago.admin.auth import is_admin_session, update_admin_session
-from misago.admin.views.auth import login
+from .. import site
+from ..auth import is_admin_session, update_admin_session
+from .auth import login
 
 
 
 
 __ALL__ = ['get_protected_namespace', 'render', 'protected_admin_view']
 __ALL__ = ['get_protected_namespace', 'render', 'protected_admin_view']

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

@@ -5,9 +5,10 @@ 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 misago.users.forms.auth import AdminAuthenticationForm
 
 
+from .. import auth
+
 
 
 @sensitive_post_parameters()
 @sensitive_post_parameters()
 @csrf_protect
 @csrf_protect

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

@@ -1,7 +1,7 @@
 from django.shortcuts import redirect
 from django.shortcuts import redirect
 
 
-from misago.admin.auth import is_admin_session, update_admin_session
-from misago.admin.views import get_protected_namespace, protected_admin_view, render
+from . import get_protected_namespace, protected_admin_view, render
+from ..auth import is_admin_session, update_admin_session
 
 
 
 
 # Magic error page used by admin
 # Magic error page used by admin

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

@@ -1,6 +1,6 @@
 # flake8: noqa
 # flake8: noqa
-from misago.admin.views.generic.mixin import AdminBaseMixin
-from misago.admin.views.generic.base import AdminView
-from misago.admin.views.generic.list import ListView, MassActionError
-from misago.admin.views.generic.formsbuttons import (
+from .mixin import AdminBaseMixin
+from .base import AdminView
+from .list import ListView, MassActionError
+from .formsbuttons import (
     TargetedView, FormView, ModelFormView, ButtonView)
     TargetedView, FormView, ModelFormView, ButtonView)

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

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

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

@@ -2,7 +2,7 @@ from django.contrib import messages
 from django.db import transaction
 from django.db import transaction
 from django.shortcuts import redirect
 from django.shortcuts import redirect
 
 
-from misago.admin.views.generic.base import AdminView
+from .base import AdminView
 
 
 
 
 class TargetedView(AdminView):
 class TargetedView(AdminView):

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

@@ -7,9 +7,10 @@ from django.db import transaction
 from django.shortcuts import redirect
 from django.shortcuts import redirect
 from django.utils.translation import ugettext_lazy as _
 from django.utils.translation import ugettext_lazy as _
 
 
-from misago.admin.views.generic.base import AdminView
 from misago.core.exceptions import ExplicitFirstPage
 from misago.core.exceptions import ExplicitFirstPage
 
 
+from .base import AdminView
+
 
 
 class MassActionError(Exception):
 class MassActionError(Exception):
     pass
     pass

+ 2 - 1
misago/admin/views/index.py

@@ -7,11 +7,12 @@ from django.http import Http404, JsonResponse
 from django.utils.translation import ugettext as _
 from django.utils.translation import ugettext as _
 
 
 from misago import __version__
 from misago import __version__
-from misago.admin.views import render
 from misago.core.cache import cache
 from misago.core.cache import cache
 from misago.threads.models import Post, Thread
 from misago.threads.models import Post, Thread
 from misago.users.models import ACTIVATION_REQUIRED_NONE, User
 from misago.users.models import ACTIVATION_REQUIRED_NONE, User
 
 
+from . import render
+
 
 
 VERSION_CHECK_CACHE_KEY = "misago_version_check"
 VERSION_CHECK_CACHE_KEY = "misago_version_check"
 
 

+ 2 - 2
misago/categories/admin.py

@@ -1,7 +1,7 @@
 from django.conf.urls import url
 from django.conf.urls import url
 from django.utils.translation import ugettext_lazy as _
 from django.utils.translation import ugettext_lazy as _
 
 
-from misago.categories.views.categoriesadmin import (
+from .views.categoriesadmin import (
     CategoriesList,
     CategoriesList,
     DeleteCategory,
     DeleteCategory,
     EditCategory,
     EditCategory,
@@ -9,7 +9,7 @@ from misago.categories.views.categoriesadmin import (
     MoveUpCategory,
     MoveUpCategory,
     NewCategory
     NewCategory
 )
 )
-from misago.categories.views.permsadmin import (
+from .views.permsadmin import (
     CategoryPermissions,
     CategoryPermissions,
     CategoryRolesList,
     CategoryRolesList,
     DeleteCategoryRole,
     DeleteCategoryRole,

+ 1 - 1
misago/categories/apps.py

@@ -7,4 +7,4 @@ class MisagoCategoriesConfig(AppConfig):
     verbose_name = "Misago Categories"
     verbose_name = "Misago Categories"
 
 
     def ready(self):
     def ready(self):
-        from misago.categories import signals
+        from . import signals

+ 2 - 1
misago/categories/forms.py

@@ -4,11 +4,12 @@ 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 ugettext_lazy as _
 from django.utils.translation import ugettext_lazy as _
 
 
-from misago.categories.models import THREADS_ROOT_NAME, Category, CategoryRole
 from misago.core import forms
 from misago.core import forms
 from misago.core.validators import validate_sluggable
 from misago.core.validators import validate_sluggable
 from misago.threads.threadtypes import trees_map
 from misago.threads.threadtypes import trees_map
 
 
+from .models import THREADS_ROOT_NAME, Category, CategoryRole
+
 
 
 """
 """
 Fields
 Fields

+ 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 - 1
misago/categories/management/commands/synchronizecategories.py

@@ -1,8 +1,9 @@
 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.management.progressbar import show_progress
 
 
+from ...models import Category
+
 
 
 class Command(BaseCommand):
 class Command(BaseCommand):
     help = 'Synchronizes categories'
     help = 'Synchronizes categories'

+ 2 - 2
misago/categories/models.py

@@ -137,11 +137,11 @@ class Category(MPTTModel):
             self.empty_last_thread()
             self.empty_last_thread()
 
 
     def delete_content(self):
     def delete_content(self):
-        from misago.categories.signals import delete_category_content
+        from .signals import delete_category_content
         delete_category_content.send(sender=self)
         delete_category_content.send(sender=self)
 
 
     def move_content(self, new_category):
     def move_content(self, new_category):
-        from misago.categories.signals import move_category_content
+        from .signals import move_category_content
         move_category_content.send(sender=self, new_category=new_category)
         move_category_content.send(sender=self, new_category=new_category)
 
 
     def get_absolute_url(self):
     def get_absolute_url(self):

+ 2 - 1
misago/categories/permissions.py

@@ -5,10 +5,11 @@ from django.utils.translation import ugettext_lazy as _
 
 
 from misago.acl import algebra
 from misago.acl import algebra
 from misago.acl.decorators import return_boolean
 from misago.acl.decorators import return_boolean
-from misago.categories.models import Category, CategoryRole, RoleCategoryACL
 from misago.core import forms
 from misago.core import forms
 from misago.users.models import AnonymousUser
 from misago.users.models import AnonymousUser
 
 
+from .models import Category, CategoryRole, RoleCategoryACL
+
 
 
 """
 """
 Admin Permissions Form
 Admin Permissions Form

+ 2 - 1
misago/categories/serializers.py

@@ -2,9 +2,10 @@ from django.core.urlresolvers import reverse
 
 
 from rest_framework import serializers
 from rest_framework import serializers
 
 
-from misago.categories.models import Category
 from misago.core.utils import format_plaintext_for_html
 from misago.core.utils import format_plaintext_for_html
 
 
+from .models import Category
+
 
 
 __all__ = [
 __all__ = [
     'BasicCategorySerializer',
     'BasicCategorySerializer',

+ 2 - 1
misago/categories/signals.py

@@ -1,10 +1,11 @@
 from django.dispatch import Signal, receiver
 from django.dispatch import Signal, receiver
 
 
-from misago.categories.models import Category, CategoryRole
 from misago.core import serializer
 from misago.core import serializer
 from misago.core.signals import secret_key_changed
 from misago.core.signals import secret_key_changed
 from misago.users.signals import username_changed
 from misago.users.signals import username_changed
 
 
+from .models import Category, CategoryRole
+
 
 
 delete_category_content = Signal()
 delete_category_content = Signal()
 move_category_content = Signal(providing_args=["new_category"])
 move_category_content = Signal(providing_args=["new_category"])

+ 2 - 1
misago/categories/tests/test_categories_admin_views.py

@@ -1,7 +1,8 @@
 from django.core.urlresolvers import reverse
 from django.core.urlresolvers import reverse
 
 
 from misago.admin.testutils import AdminTestCase
 from misago.admin.testutils import AdminTestCase
-from misago.categories.models import Category
+
+from ..models import Category
 
 
 
 
 class CategoryAdminViewsTests(AdminTestCase):
 class CategoryAdminViewsTests(AdminTestCase):

+ 2 - 1
misago/categories/tests/test_category_model.py

@@ -1,10 +1,11 @@
 from django.utils import timezone
 from django.utils import timezone
 
 
-from misago.categories.models import THREADS_ROOT_NAME, Category
 from misago.core.testutils import MisagoTestCase
 from misago.core.testutils import MisagoTestCase
 from misago.threads import testutils
 from misago.threads import testutils
 from misago.threads.threadtypes import trees_map
 from misago.threads.threadtypes import trees_map
 
 
+from ..models import THREADS_ROOT_NAME, Category
+
 
 
 class CategoryManagerTests(MisagoTestCase):
 class CategoryManagerTests(MisagoTestCase):
     def test_private_threads(self):
     def test_private_threads(self):

+ 2 - 1
misago/categories/tests/test_permissions_admin_views.py

@@ -3,7 +3,8 @@ from django.core.urlresolvers import reverse
 from misago.acl.models import Role
 from misago.acl.models import Role
 from misago.acl.testutils import fake_post_data
 from misago.acl.testutils import fake_post_data
 from misago.admin.testutils import AdminTestCase
 from misago.admin.testutils import AdminTestCase
-from misago.categories.models import Category, CategoryRole
+
+from ..models import Category, CategoryRole
 
 
 
 
 def fake_data(data_dict):
 def fake_data(data_dict):

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

@@ -4,10 +4,11 @@ from django.test import TestCase
 from django.utils import timezone
 from django.utils import timezone
 from django.utils.six import StringIO
 from django.utils.six import StringIO
 
 
-from misago.categories.management.commands import prunecategories
-from misago.categories.models import Category
 from misago.threads import testutils
 from misago.threads import testutils
 
 
+from ..management.commands import prunecategories
+from ..models import Category
+
 
 
 class PruneCategoriesTests(TestCase):
 class PruneCategoriesTests(TestCase):
     def test_category_prune_by_start_date(self):
     def test_category_prune_by_start_date(self):

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

@@ -1,10 +1,11 @@
 from django.test import TestCase
 from django.test import TestCase
 from django.utils.six import StringIO
 from django.utils.six import StringIO
 
 
-from misago.categories.management.commands import synchronizecategories
-from misago.categories.models import Category
 from misago.threads import testutils
 from misago.threads import testutils
 
 
+from ..management.commands import synchronizecategories
+from ..models import Category
+
 
 
 class SynchronizeCategoriesTests(TestCase):
 class SynchronizeCategoriesTests(TestCase):
     def test_categories_sync(self):
     def test_categories_sync(self):

+ 3 - 2
misago/categories/tests/test_utils.py

@@ -1,9 +1,10 @@
 from misago.acl.testutils import override_acl
 from misago.acl.testutils import override_acl
-from misago.categories.models import Category
-from misago.categories.utils import get_categories_tree, get_category_path
 from misago.core import threadstore
 from misago.core import threadstore
 from misago.users.testutils import AuthenticatedUserTestCase
 from misago.users.testutils import AuthenticatedUserTestCase
 
 
+from ..models import Category
+from ..utils import get_categories_tree, get_category_path
+
 
 
 class CategoriesUtilsTests(AuthenticatedUserTestCase):
 class CategoriesUtilsTests(AuthenticatedUserTestCase):
     def setUp(self):
     def setUp(self):

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

@@ -1,10 +1,11 @@
 from django.core.urlresolvers import reverse
 from django.core.urlresolvers import reverse
 
 
 from misago.acl.testutils import override_acl
 from misago.acl.testutils import override_acl
-from misago.categories.models import Category
-from misago.categories.utils import get_categories_tree
 from misago.users.testutils import AuthenticatedUserTestCase
 from misago.users.testutils import AuthenticatedUserTestCase
 
 
+from ..models import Category
+from ..utils import get_categories_tree
+
 
 
 class CategoryViewsTests(AuthenticatedUserTestCase):
 class CategoryViewsTests(AuthenticatedUserTestCase):
     def test_index_renders(self):
     def test_index_renders(self):

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

@@ -2,7 +2,7 @@ from django.conf import settings
 from django.conf.urls import url
 from django.conf.urls import url
 
 
 from misago.core.views import home_redirect
 from misago.core.views import home_redirect
-from misago.categories.views import categories
+from ..views import categories
 
 
 
 
 if settings.MISAGO_THREADS_ON_INDEX:
 if settings.MISAGO_THREADS_ON_INDEX:

+ 1 - 1
misago/categories/urls/api.py

@@ -1,6 +1,6 @@
 from django.conf.urls import url
 from django.conf.urls import url
 
 
-from misago.categories.views import api
+from ..views import api
 
 
 
 
 urlpatterns = [
 urlpatterns = [

+ 2 - 1
misago/categories/utils.py

@@ -1,8 +1,9 @@
 from misago.acl import add_acl
 from misago.acl import add_acl
-from misago.categories.models import Category
 from misago.core import threadstore
 from misago.core import threadstore
 from misago.readtracker import categoriestracker
 from misago.readtracker import categoriestracker
 
 
+from .models import Category
+
 
 
 __all__ = [
 __all__ = [
     'get_categories_tree',
     'get_categories_tree',

+ 2 - 2
misago/categories/views/__init__.py

@@ -4,8 +4,8 @@ from django.shortcuts import render
 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 misago.categories.serializers import CategorySerializer
-from misago.categories.utils import get_categories_tree
+from ..serializers import CategorySerializer
+from ..utils import get_categories_tree
 
 
 
 
 def categories(request):
 def categories(request):

+ 3 - 2
misago/categories/views/categoriesadmin.py

@@ -4,10 +4,11 @@ from django.utils.translation import ugettext_lazy as _
 
 
 from misago.acl import version as acl_version
 from misago.acl import version as acl_version
 from misago.admin.views import generic
 from misago.admin.views import generic
-from misago.categories.forms import CategoryFormFactory, DeleteFormFactory
-from misago.categories.models import THREADS_ROOT_NAME, Category, RoleCategoryACL
 from misago.threads.threadtypes import trees_map
 from misago.threads.threadtypes import trees_map
 
 
+from ..forms import CategoryFormFactory, DeleteFormFactory
+from ..models import THREADS_ROOT_NAME, Category, RoleCategoryACL
+
 
 
 class CategoryAdmin(generic.AdminBaseMixin):
 class CategoryAdmin(generic.AdminBaseMixin):
     root_link = 'misago:admin:categories:nodes:index'
     root_link = 'misago:admin:categories:nodes:index'

+ 4 - 3
misago/categories/views/permsadmin.py

@@ -7,9 +7,10 @@ from misago.acl.forms import get_permissions_forms
 from misago.acl.models import Role
 from misago.acl.models import Role
 from misago.acl.views import RoleAdmin, RolesList
 from misago.acl.views import RoleAdmin, RolesList
 from misago.admin.views import generic
 from misago.admin.views import generic
-from misago.categories.forms import CategoryRoleForm, CategoryRolesACLFormFactory, RoleCategoryACLFormFactory
-from misago.categories.models import Category, CategoryRole, RoleCategoryACL
-from misago.categories.views.categoriesadmin import CategoriesList, CategoryAdmin
+
+from ..forms import CategoryRoleForm, CategoryRolesACLFormFactory, RoleCategoryACLFormFactory
+from ..models import Category, CategoryRole, RoleCategoryACL
+from .categoriesadmin import CategoriesList, CategoryAdmin
 
 
 
 
 class CategoryRoleAdmin(generic.AdminBaseMixin):
 class CategoryRoleAdmin(generic.AdminBaseMixin):

+ 1 - 1
misago/conf/__init__.py

@@ -1,4 +1,4 @@
-from misago.conf.gateway import settings, db_settings  # noqa
+from .gateway import settings, db_settings  # noqa
 
 
 
 
 default_app_config = 'misago.conf.apps.MisagoConfConfig'
 default_app_config = 'misago.conf.apps.MisagoConfConfig'

+ 1 - 1
misago/conf/admin.py

@@ -1,7 +1,7 @@
 from django.conf.urls import url
 from django.conf.urls import url
 from django.utils.translation import ugettext_lazy as _
 from django.utils.translation import ugettext_lazy as _
 
 
-from misago.conf import views
+from . import views
 
 
 
 
 class MisagoAdminExtension(object):
 class MisagoAdminExtension(object):

+ 1 - 1
misago/conf/context_processors.py

@@ -2,7 +2,7 @@ import json
 
 
 from django.core.urlresolvers import reverse
 from django.core.urlresolvers import reverse
 
 
-from misago.conf.gateway import db_settings, dj_settings  # noqa
+from .gateway import db_settings, dj_settings  # noqa
 
 
 
 
 def settings(request):
 def settings(request):

+ 2 - 2
misago/conf/dbsettings.py

@@ -19,7 +19,7 @@ class DBSettings(object):
         return data
         return data
 
 
     def _read_db(self):
     def _read_db(self):
-        from misago.conf.models import Setting
+        from .models import Setting
 
 
         data = {}
         data = {}
         for setting in Setting.objects.iterator():
         for setting in Setting.objects.iterator():
@@ -45,7 +45,7 @@ class DBSettings(object):
         return public_settings
         return public_settings
 
 
     def get_lazy_setting(self, setting):
     def get_lazy_setting(self, setting):
-        from misago.conf.models import Setting
+        from .models import Setting
 
 
         try:
         try:
             if self._settings[setting]['is_lazy']:
             if self._settings[setting]['is_lazy']:

+ 1 - 1
misago/conf/gateway.py

@@ -1,6 +1,6 @@
 from django.conf import settings as dj_settings
 from django.conf import settings as dj_settings
 
 
-from misago.conf.dbsettings import db_settings
+from .dbsettings import db_settings
 
 
 
 
 class SettingsGateway(object):
 class SettingsGateway(object):

+ 3 - 2
misago/conf/migrationutils.py

@@ -1,8 +1,9 @@
-from misago.conf.dbsettings import CACHE_KEY
-from misago.conf.hydrators import dehydrate_value
 from misago.core import serializer
 from misago.core import serializer
 from misago.core.cache import cache as default_cache
 from misago.core.cache import cache as default_cache
 
 
+from .dbsettings import CACHE_KEY
+from .hydrators import dehydrate_value
+
 
 
 def get_group(SettingsGroup, group_key):
 def get_group(SettingsGroup, group_key):
     try:
     try:

+ 2 - 1
misago/conf/models.py

@@ -1,10 +1,11 @@
 from django.db import models
 from django.db import models
 from django.dispatch import receiver
 from django.dispatch import receiver
 
 
-from misago.conf import hydrators
 from misago.core import serializer
 from misago.core import serializer
 from misago.core.signals import secret_key_changed
 from misago.core.signals import secret_key_changed
 
 
+from . import hydrators
+
 
 
 class SettingsGroupsManager(models.Manager):
 class SettingsGroupsManager(models.Manager):
     def ordered_alphabetically(self):
     def ordered_alphabetically(self):

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

@@ -1,7 +1,8 @@
 from django.core.urlresolvers import reverse
 from django.core.urlresolvers import reverse
 
 
 from misago.admin.testutils import AdminTestCase
 from misago.admin.testutils import AdminTestCase
-from misago.conf.models import SettingsGroup
+
+from ..models import SettingsGroup
 
 
 
 
 class AdminSettingsViewsTests(AdminTestCase):
 class AdminSettingsViewsTests(AdminTestCase):

+ 3 - 2
misago/conf/tests/test_context_processors.py

@@ -1,9 +1,10 @@
 from django.test import TestCase
 from django.test import TestCase
 
 
-from misago.conf.context_processors import settings
-from misago.conf.dbsettings import db_settings
 from misago.core import threadstore
 from misago.core import threadstore
 
 
+from ..context_processors import settings
+from ..dbsettings import db_settings
+
 
 
 class MockRequest(object):
 class MockRequest(object):
     pass
     pass

+ 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):

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

@@ -1,10 +1,11 @@
 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 misago.core import threadstore
 from misago.core import threadstore
 
 
+from .. import migrationutils
+from ..models import SettingsGroup
+
 
 
 class DBConfMigrationUtilsTests(TestCase):
 class DBConfMigrationUtilsTests(TestCase):
     def setUp(self):
     def setUp(self):

+ 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):

+ 4 - 3
misago/conf/tests/test_settings.py

@@ -2,12 +2,13 @@ from django.apps import apps
 from django.conf import settings as dj_settings
 from django.conf import settings as dj_settings
 from django.test import TestCase
 from django.test import TestCase
 
 
-from misago.conf.dbsettings import db_settings
-from misago.conf.gateway import settings as gateway
-from misago.conf.migrationutils import migrate_settings_group
 from misago.core import threadstore
 from misago.core import threadstore
 from misago.core.cache import cache
 from misago.core.cache import cache
 
 
+from ..dbsettings import db_settings
+from ..gateway import settings as gateway
+from ..migrationutils import migrate_settings_group
+
 
 
 class DBSettingsTests(TestCase):
 class DBSettingsTests(TestCase):
     def test_get_existing_setting(self):
     def test_get_existing_setting(self):

+ 4 - 3
misago/conf/views.py

@@ -3,9 +3,10 @@ from django.shortcuts import redirect
 from django.utils.translation import ugettext as _
 from django.utils.translation import ugettext as _
 
 
 from misago.admin.views import render as mi_render
 from misago.admin.views import render as mi_render
-from misago.conf import db_settings
-from misago.conf.forms import ChangeSettingsForm
-from misago.conf.models import SettingsGroup
+
+from . import db_settings
+from .forms import ChangeSettingsForm
+from .models import SettingsGroup
 
 
 
 
 def render(request, template, context=None):
 def render(request, template, context=None):

+ 1 - 1
misago/core/apipaginator.py

@@ -6,7 +6,7 @@ from rest_framework.exceptions import NotFound
 from rest_framework.pagination import PageNumberPagination
 from rest_framework.pagination import PageNumberPagination
 from rest_framework.response import Response
 from rest_framework.response import Response
 
 
-from misago.core.shortcuts import pagination_dict
+from .shortcuts import pagination_dict
 
 
 
 
 class BaseApiPaginator(PageNumberPagination):
 class BaseApiPaginator(PageNumberPagination):

+ 9 - 9
misago/core/cachebuster.py

@@ -1,6 +1,6 @@
 from django.db.models import F
 from django.db.models import F
 
 
-from misago.core import threadstore
+from . import threadstore
 
 
 
 
 CACHE_KEY = 'misago_cachebuster'
 CACHE_KEY = 'misago_cachebuster'
@@ -8,11 +8,11 @@ CACHE_KEY = 'misago_cachebuster'
 
 
 class CacheBusterController(object):
 class CacheBusterController(object):
     def register_cache(self, cache):
     def register_cache(self, cache):
-        from misago.core.models import CacheVersion
+        from .models import CacheVersion
         CacheVersion.objects.create(cache=cache)
         CacheVersion.objects.create(cache=cache)
 
 
     def unregister_cache(self, cache):
     def unregister_cache(self, cache):
-        from misago.core.models import CacheVersion
+        from .models import CacheVersion
 
 
         try:
         try:
             cache = CacheVersion.objects.get(cache=cache)
             cache = CacheVersion.objects.get(cache=cache)
@@ -32,7 +32,7 @@ class CacheBusterController(object):
         return data
         return data
 
 
     def read_cache(self):
     def read_cache(self):
-        from misago.core.cache import cache as default_cache
+        from .cache import cache as default_cache
 
 
         data = default_cache.get(CACHE_KEY, 'nada')
         data = default_cache.get(CACHE_KEY, 'nada')
         if data == 'nada':
         if data == 'nada':
@@ -41,7 +41,7 @@ class CacheBusterController(object):
         return data
         return data
 
 
     def read_db(self):
     def read_db(self):
-        from misago.core.models import CacheVersion
+        from .models import CacheVersion
 
 
         data = {}
         data = {}
         for cache_version in CacheVersion.objects.iterator():
         for cache_version in CacheVersion.objects.iterator():
@@ -61,8 +61,8 @@ class CacheBusterController(object):
             raise ValueError('Cache "%s" is not registered' % cache)
             raise ValueError('Cache "%s" is not registered' % cache)
 
 
     def invalidate_cache(self, cache):
     def invalidate_cache(self, cache):
-        from misago.core.cache import cache as default_cache
-        from misago.core.models import CacheVersion
+        from .cache import cache as default_cache
+        from .models import CacheVersion
 
 
         self.cache[cache] += 1
         self.cache[cache] += 1
         CacheVersion.objects.filter(cache=cache).update(
         CacheVersion.objects.filter(cache=cache).update(
@@ -70,8 +70,8 @@ class CacheBusterController(object):
         default_cache.delete(CACHE_KEY)
         default_cache.delete(CACHE_KEY)
 
 
     def invalidate_all(self):
     def invalidate_all(self):
-        from misago.core.cache import cache as default_cache
-        from misago.core.models import CacheVersion
+        from .cache import cache as default_cache
+        from .models import CacheVersion
 
 
         CacheVersion.objects.update(version=F('version') + 1)
         CacheVersion.objects.update(version=F('version') + 1)
         default_cache.delete(CACHE_KEY)
         default_cache.delete(CACHE_KEY)

+ 1 - 1
misago/core/decorators.py

@@ -1,4 +1,4 @@
-from misago.core.errorpages import not_allowed
+from .errorpages import not_allowed
 
 
 
 
 def ajax_only(f):
 def ajax_only(f):

+ 2 - 1
misago/core/errorpages.py

@@ -3,7 +3,8 @@ from django.shortcuts import render
 from django.utils.translation import ugettext as _
 from django.utils.translation import ugettext as _
 
 
 from misago.admin.views.errorpages import admin_csrf_failure, admin_error_page
 from misago.admin.views.errorpages import admin_csrf_failure, admin_error_page
-from misago.core.utils import is_request_to_misago
+
+from .utils import is_request_to_misago
 
 
 
 
 def _ajax_error(code=406, message=None):
 def _ajax_error(code=406, message=None):

+ 2 - 2
misago/core/exceptionhandler.py

@@ -5,8 +5,8 @@ from django.utils.translation import gettext as _
 
 
 from rest_framework.views import exception_handler as rest_exception_handler
 from rest_framework.views import exception_handler as rest_exception_handler
 
 
-from misago.core import errorpages
-from misago.core.exceptions import AjaxError, Banned, ExplicitFirstPage, OutdatedSlug
+from . import errorpages
+from .exceptions import AjaxError, Banned, ExplicitFirstPage, OutdatedSlug
 
 
 
 
 HANDLED_EXCEPTIONS = (AjaxError, Banned, ExplicitFirstPage, Http404,
 HANDLED_EXCEPTIONS = (AjaxError, Banned, ExplicitFirstPage, Http404,

+ 1 - 1
misago/core/management/commands/remakemisagochecksums.py

@@ -2,7 +2,7 @@ from django.core.management.base import BaseCommand
 from django.utils.encoding import force_str
 from django.utils.encoding import force_str
 from django.utils.six.moves import input
 from django.utils.six.moves import input
 
 
-from misago.core.signals import secret_key_changed
+from ...signals import secret_key_changed
 
 
 
 
 class Command(BaseCommand):
 class Command(BaseCommand):

+ 2 - 2
misago/core/middleware/exceptionhandler.py

@@ -1,5 +1,5 @@
-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(object):
 class ExceptionHandlerMiddleware(object):

+ 1 - 1
misago/core/middleware/threadstore.py

@@ -1,4 +1,4 @@
-from misago.core import threadstore
+from .. import threadstore
 
 
 
 
 class ThreadStoreMiddleware(object):
 class ThreadStoreMiddleware(object):

+ 2 - 2
misago/core/migrationutils.py

@@ -1,5 +1,5 @@
-from misago.core.cache import cache as default_cache
-from misago.core.cachebuster import CACHE_KEY
+from .cache import cache as default_cache
+from .cachebuster import CACHE_KEY
 
 
 
 
 def _CacheVersion(apps):
 def _CacheVersion(apps):

+ 2 - 2
misago/core/shortcuts.py

@@ -9,7 +9,7 @@ def paginate(object_list, page, per_page, orphans=0,
              allow_explicit_first_page=False):
              allow_explicit_first_page=False):
     from django.http import Http404
     from django.http import Http404
     from django.core.paginator import Paginator, EmptyPage
     from django.core.paginator import Paginator, EmptyPage
-    from misago.core.exceptions import ExplicitFirstPage
+    from .exceptions import ExplicitFirstPage
 
 
     if page in (1, "1") and not allow_explicit_first_page:
     if page in (1, "1") and not allow_explicit_first_page:
         raise ExplicitFirstPage()
         raise ExplicitFirstPage()
@@ -69,7 +69,7 @@ def pagination_dict(page, include_page_range=True):
 
 
 
 
 def validate_slug(model, slug):
 def validate_slug(model, slug):
-    from misago.core.exceptions import OutdatedSlug
+    from .exceptions import OutdatedSlug
     if model.slug != slug:
     if model.slug != slug:
         raise OutdatedSlug(model)
         raise OutdatedSlug(model)
 
 

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

@@ -2,9 +2,10 @@ from django.conf.urls import include, url
 # Setup Django admin to work with Misago auth
 # Setup Django admin to work with Misago auth
 from django.contrib import admin
 from django.contrib import admin
 
 
-from misago.core.testproject import views
 from misago.users.forms.auth import AdminAuthenticationForm
 from misago.users.forms.auth import AdminAuthenticationForm
 
 
+from . import views
+
 
 
 admin.autodiscover()
 admin.autodiscover()
 admin.site.login_form = AdminAuthenticationForm
 admin.site.login_form = AdminAuthenticationForm

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

@@ -1,4 +1,4 @@
-from misago.core.testproject.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'

+ 7 - 6
misago/core/testproject/views.py

@@ -2,14 +2,15 @@ from django.contrib.auth import get_user_model
 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 misago.core import errorpages, mail
-from misago.core.decorators import require_POST
-from misago.core.exceptions import Banned
-from misago.core.shortcuts import paginate, validate_slug
-from misago.core.testproject.models import Model
-from misago.core.views import home_redirect
 from misago.users.models import Ban
 from misago.users.models import Ban
 
 
+from .. import errorpages, mail
+from ..decorators import require_POST
+from ..exceptions import Banned
+from ..shortcuts import paginate, validate_slug
+from ..views import home_redirect
+from .models import Model
+
 
 
 def test_mail_user(request):
 def test_mail_user(request):
     User = get_user_model()
     User = get_user_model()

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

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

+ 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):

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

@@ -1,7 +1,7 @@
-from misago.core import cachebuster, threadstore
-from misago.core.cache import cache
-from misago.core.models import CacheVersion
-from misago.core.testutils import MisagoTestCase
+from .. import cachebuster, threadstore
+from ..cache import cache
+from ..models import CacheVersion
+from ..testutils import MisagoTestCase
 
 
 
 
 class CacheBusterTests(MisagoTestCase):
 class CacheBusterTests(MisagoTestCase):

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

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

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

@@ -2,9 +2,10 @@ from django.core.urlresolvers import reverse
 from django.test import Client, TestCase
 from django.test import Client, TestCase
 from django.test.client import RequestFactory
 from django.test.client import RequestFactory
 
 
-from misago.core.testproject.views import mock_custom_403_error_page, mock_custom_404_error_page
 from misago.users.models import AnonymousUser
 from misago.users.models import AnonymousUser
 
 
+from ..testproject.views import mock_custom_403_error_page, mock_custom_404_error_page
+
 
 
 class CSRFErrorViewTests(TestCase):
 class CSRFErrorViewTests(TestCase):
     def test_csrf_failure(self):
     def test_csrf_failure(self):

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

@@ -3,9 +3,10 @@ from django.http import Http404
 from django.test import TestCase
 from django.test import TestCase
 from django.test.client import RequestFactory
 from django.test.client import RequestFactory
 
 
-from misago.core.middleware.exceptionhandler import ExceptionHandlerMiddleware
 from misago.users.models import AnonymousUser
 from misago.users.models import AnonymousUser
 
 
+from ..middleware.exceptionhandler import ExceptionHandlerMiddleware
+
 
 
 class ExceptionHandlerMiddlewareTests(TestCase):
 class ExceptionHandlerMiddlewareTests(TestCase):
     def setUp(self):
     def setUp(self):

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

@@ -3,10 +3,11 @@ 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 misago.users.models import Ban
 
 
+from .. import exceptionhandler
+from ..exceptions import Banned
+
 
 
 INVALID_EXCEPTIONS = (
 INVALID_EXCEPTIONS = (
     django_exceptions.ObjectDoesNotExist,
     django_exceptions.ObjectDoesNotExist,

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

@@ -2,7 +2,7 @@ from django.conf import settings
 from django.http import HttpResponse, StreamingHttpResponse
 from django.http import HttpResponse, StreamingHttpResponse
 from django.test import TestCase
 from django.test import TestCase
 
 
-from misago.core import fileserver
+from .. import fileserver
 
 
 
 
 class FileServerTests(TestCase):
 class FileServerTests(TestCase):

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

@@ -1,6 +1,6 @@
 from django.test import TestCase
 from django.test import TestCase
 
 
-from misago.core import forms
+from .. import forms
 
 
 
 
 class YesNoForm(forms.Form):
 class YesNoForm(forms.Form):

+ 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.frontendcontext import FrontendContextMiddleware
+from ..middleware.frontendcontext import FrontendContextMiddleware
 
 
 
 
 class MockRequest(object):
 class MockRequest(object):

+ 2 - 2
misago/core/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.core import migrationutils
-from misago.core.models import CacheVersion
+from .. import migrationutils
+from ..models import CacheVersion
 
 
 
 
 class CacheBusterUtilsTests(TestCase):
 class CacheBusterUtilsTests(TestCase):

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

@@ -1,7 +1,7 @@
 from django.test import TestCase
 from django.test import TestCase
 from django.utils.six import StringIO
 from django.utils.six import StringIO
 
 
-from misago.core.management.commands import misagodbrelations
+from ..management.commands import misagodbrelations
 
 
 
 
 class MisagoDBRelationsTests(TestCase):
 class MisagoDBRelationsTests(TestCase):

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

@@ -1,7 +1,7 @@
 from django.test import TestCase
 from django.test import TestCase
 from django.utils.six import StringIO
 from django.utils.six import StringIO
 
 
-from misago.core.management.commands import misagorequirements
+from ..management.commands import misagorequirements
 
 
 
 
 class MisagoRequirementsTests(TestCase):
 class MisagoRequirementsTests(TestCase):

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

@@ -1,7 +1,7 @@
 from django.conf import settings
 from django.conf import settings
 from django.test import TestCase
 from django.test import TestCase
 
 
-from misago.core.momentjs import get_locale_path, list_available_locales
+from ..momentjs import get_locale_path, list_available_locales
 
 
 
 
 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):

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

@@ -1,7 +1,7 @@
 from django.test import TestCase
 from django.test import TestCase
 from django.utils.six import StringIO
 from django.utils.six import StringIO
 
 
-from misago.core.management.commands import remakemisagochecksums
+from ..management.commands import remakemisagochecksums
 
 
 
 
 class RemakeMisagoChecksumsTests(TestCase):
 class RemakeMisagoChecksumsTests(TestCase):

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

@@ -1,6 +1,6 @@
 from django.test import TestCase
 from django.test import TestCase
 
 
-from misago.core import serializer
+from .. import serializer
 
 
 
 
 class SerializerTests(TestCase):
 class SerializerTests(TestCase):

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

@@ -2,7 +2,7 @@ import os
 
 
 from django.test import TestCase
 from django.test import TestCase
 
 
-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.core.urlresolvers import reverse
 from django.http import Http404
 from django.http import Http404
 from django.test import TestCase
 from django.test import TestCase
 
 
-from misago.core.shortcuts import get_int_or_404
+from ..shortcuts import get_int_or_404
 
 
 
 
 class PaginateTests(TestCase):
 class PaginateTests(TestCase):

+ 3 - 3
misago/core/tests/test_templatetags.py

@@ -1,9 +1,9 @@
 from django.template import Context, Template, TemplateSyntaxError
 from django.template import Context, Template, TemplateSyntaxError
 from django.test import TestCase
 from django.test import TestCase
 
 
-from misago.core import forms
-from misago.core.shortcuts import paginate
-from misago.core.templatetags import misago_batch
+from .. import forms
+from ..shortcuts import paginate
+from ..templatetags import misago_batch
 
 
 
 
 class CaptureTests(TestCase):
 class CaptureTests(TestCase):

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

@@ -2,7 +2,7 @@ from django.core import mail
 from django.test import TestCase
 from django.test import TestCase
 from django.utils.six import StringIO
 from django.utils.six import StringIO
 
 
-from misago.core.management.commands import testemailsetup
+from ..management.commands import testemailsetup
 
 
 
 
 class TestEmailSetupTests(TestCase):
 class TestEmailSetupTests(TestCase):

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

@@ -2,8 +2,8 @@ from django.core.urlresolvers import reverse
 from django.test import TestCase
 from django.test import TestCase
 from django.test.client import RequestFactory
 from django.test.client import RequestFactory
 
 
-from misago.core import threadstore
-from misago.core.middleware.threadstore import ThreadStoreMiddleware
+from .. import threadstore
+from ..middleware.threadstore import ThreadStoreMiddleware
 
 
 
 
 class ThreadStoreTests(TestCase):
 class ThreadStoreTests(TestCase):

+ 1 - 7
misago/core/tests/test_utils.py

@@ -4,13 +4,7 @@ from django.test import TestCase
 from django.test.client import RequestFactory
 from django.test.client import RequestFactory
 from django.utils import timezone
 from django.utils import timezone
 
 
-from misago.core.utils import (
-    clean_return_path,
-    format_plaintext_for_html,
-    is_referer_local,
-    is_request_to_misago,
-    slugify
-)
+from ..utils import clean_return_path, format_plaintext_for_html, is_referer_local, is_request_to_misago, slugify
 
 
 
 
 VALID_PATHS = (
 VALID_PATHS = (

+ 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):

+ 2 - 2
misago/core/testutils.py

@@ -1,7 +1,7 @@
 from django.test import TestCase
 from django.test import TestCase
 
 
-from misago.core import threadstore
-from misago.core.cache import cache
+from . import threadstore
+from .cache import cache
 
 
 
 
 class MisagoTestCase(TestCase):
 class MisagoTestCase(TestCase):

+ 1 - 1
misago/core/validators.py

@@ -1,7 +1,7 @@
 from django.core.exceptions import ValidationError
 from django.core.exceptions import ValidationError
 from django.utils.translation import ugettext_lazy as _
 from django.utils.translation import ugettext_lazy as _
 
 
-from misago.core.utils import slugify
+from .utils import slugify
 
 
 
 
 class validate_sluggable(object):
 class validate_sluggable(object):

+ 1 - 1
misago/core/views.py

@@ -6,7 +6,7 @@ from django.views import i18n
 from django.views.decorators.cache import cache_page
 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 misago.core import momentjs
+from . import momentjs
 
 
 
 
 def forum_index(request):
 def forum_index(request):

+ 2 - 1
misago/legal/tests.py

@@ -2,7 +2,8 @@ from django.core.urlresolvers import reverse
 from django.test import TestCase
 from django.test import TestCase
 
 
 from misago.conf import settings
 from misago.conf import settings
-from misago.legal.context_processors import legal_links
+
+from .context_processors import legal_links
 
 
 
 
 class MockRequest(object):
 class MockRequest(object):

+ 1 - 1
misago/legal/urls.py

@@ -1,6 +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 = [

+ 3 - 3
misago/markup/__init__.py

@@ -1,8 +1,8 @@
 # flake8: noqa
 # flake8: noqa
-from misago.markup.flavours import (common as common_flavour,
+from .flavours import (common as common_flavour,
                                     signature as signature_flavour)
                                     signature as signature_flavour)
-from misago.markup.parser import parse
-from misago.markup.editor import Editor
+from .parser import parse
+from .editor import Editor
 
 
 
 
 default_app_config = 'misago.markup.apps.MisagoMarkupConfig'
 default_app_config = 'misago.markup.apps.MisagoMarkupConfig'

+ 1 - 1
misago/markup/flavours.py

@@ -1,4 +1,4 @@
-from misago.markup.parser import parse
+from .parser import parse
 
 
 
 
 def common(request, poster, text, allow_mentions=True):
 def common(request, poster, text, allow_mentions=True):

+ 3 - 3
misago/markup/parser.py

@@ -3,9 +3,9 @@ import markdown
 from bs4 import BeautifulSoup
 from bs4 import BeautifulSoup
 from htmlmin.minify import html_minify
 from htmlmin.minify import html_minify
 
 
-from misago.markup.bbcode import blocks, inline
-from misago.markup.md.shortimgs import ShortImagesExtension
-from misago.markup.pipeline import pipeline
+from .bbcode import blocks, inline
+from .md.shortimgs import ShortImagesExtension
+from .pipeline import pipeline
 
 
 
 
 __all__ = ['parse']
 __all__ = ['parse']

+ 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_parser.py

@@ -3,7 +3,7 @@ from __future__ import unicode_literals
 
 
 from django.test import TestCase
 from django.test import TestCase
 
 
-from misago.markup.parser import parse
+from ..parser import parse
 
 
 
 
 class MockRequest(object):
 class MockRequest(object):

+ 1 - 1
misago/readtracker/apps.py

@@ -7,4 +7,4 @@ class MisagoReadTrackerConfig(AppConfig):
     verbose_name = "Misago Read Tracker"
     verbose_name = "Misago Read Tracker"
 
 
     def ready(self):
     def ready(self):
-        from misago.readtracker import signals
+        from . import signals

+ 4 - 3
misago/readtracker/categoriestracker.py

@@ -1,11 +1,12 @@
 from django.db.models import F
 from django.db.models import F
 from django.utils import timezone
 from django.utils import timezone
 
 
-from misago.readtracker import signals
-from misago.readtracker.dates import is_date_tracked
-from misago.readtracker.models import CategoryRead
 from misago.threads.permissions import exclude_invisible_threads
 from misago.threads.permissions import exclude_invisible_threads
 
 
+from . import signals
+from .dates import is_date_tracked
+from .models import CategoryRead
+
 
 
 __all__ = ['make_read_aware', 'sync_record']
 __all__ = ['make_read_aware', 'sync_record']
 
 

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

@@ -3,7 +3,7 @@ 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.readtracker.dates import is_date_tracked
+from ..dates import is_date_tracked
 
 
 
 
 class MockUser(object):
 class MockUser(object):

+ 2 - 1
misago/readtracker/tests/test_readtracker.py

@@ -6,10 +6,11 @@ from django.utils import timezone
 
 
 from misago.acl import add_acl
 from misago.acl import add_acl
 from misago.categories.models import Category
 from misago.categories.models import Category
-from misago.readtracker import categoriestracker, threadstracker
 from misago.threads import testutils
 from misago.threads import testutils
 from misago.users.models import AnonymousUser
 from misago.users.models import AnonymousUser
 
 
+from .. import categoriestracker, threadstracker
+
 
 
 class ReadTrackerTests(TestCase):
 class ReadTrackerTests(TestCase):
     def setUp(self):
     def setUp(self):

+ 3 - 3
misago/readtracker/threadstracker.py

@@ -1,9 +1,9 @@
 from django.db.transaction import atomic
 from django.db.transaction import atomic
 from django.utils import timezone
 from django.utils import timezone
 
 
-from misago.readtracker import categoriestracker, signals
-from misago.readtracker.dates import is_date_tracked
-from misago.readtracker.models import CategoryRead, ThreadRead
+from . import categoriestracker, signals
+from .dates import is_date_tracked
+from .models import CategoryRead, ThreadRead
 
 
 
 
 __all__ = ['make_read_aware', 'read_thread']
 __all__ = ['make_read_aware', 'read_thread']

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

@@ -1,8 +1,9 @@
 from rest_framework.response import Response
 from rest_framework.response import Response
 
 
 from misago.core.shortcuts import get_int_or_404
 from misago.core.shortcuts import get_int_or_404
-from misago.threads.viewmodels.category import ThreadsCategory, ThreadsRootCategory
-from misago.threads.viewmodels.threads import ForumThreads
+
+from ...viewmodels.category import ThreadsCategory, ThreadsRootCategory
+from ...viewmodels.threads import ForumThreads
 
 
 
 
 class ListEndpointBase(object):
 class ListEndpointBase(object):

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

@@ -8,12 +8,13 @@ from rest_framework.response import Response
 from misago.acl import add_acl
 from misago.acl import add_acl
 from misago.categories.models import THREADS_ROOT_NAME, Category
 from misago.categories.models import THREADS_ROOT_NAME, Category
 from misago.categories.permissions import can_browse_category, can_see_category
 from misago.categories.permissions import can_browse_category, can_see_category
-from misago.threads.events import record_event
-from misago.threads.models import Thread
-from misago.threads.permissions import can_see_thread
-from misago.threads.serializers import MergeThreadsSerializer, ThreadListSerializer
-from misago.threads.threadtypes import trees_map
-from misago.threads.utils import add_categories_to_threads
+
+from ...events import record_event
+from ...models import Thread
+from ...permissions import can_see_thread
+from ...serializers import MergeThreadsSerializer, ThreadListSerializer
+from ...threadtypes import trees_map
+from ...utils import add_categories_to_threads
 
 
 
 
 MERGE_LIMIT = 20 # no more than 20 threads can be merged in single action
 MERGE_LIMIT = 20 # no more than 20 threads can be merged in single action

+ 4 - 3
misago/threads/api/threadendpoints/patch.py

@@ -7,9 +7,10 @@ from misago.categories.permissions import allow_browse_category, allow_see_categ
 from misago.categories.serializers import CategorySerializer
 from misago.categories.serializers import CategorySerializer
 from misago.core.apipatch import ApiPatch
 from misago.core.apipatch import ApiPatch
 from misago.core.shortcuts import get_int_or_404, get_object_or_404
 from misago.core.shortcuts import get_int_or_404, get_object_or_404
-from misago.threads.moderation import threads as moderation
-from misago.threads.permissions import allow_start_thread
-from misago.threads.utils import add_categories_to_threads
+
+from ...moderation import threads as moderation
+from ...permissions import allow_start_thread
+from ...utils import add_categories_to_threads
 
 
 
 
 thread_patch_endpoint = ApiPatch()
 thread_patch_endpoint = ApiPatch()

+ 3 - 2
misago/threads/api/threadposts.py

@@ -2,8 +2,9 @@ from rest_framework import viewsets
 from rest_framework.response import Response
 from rest_framework.response import Response
 
 
 from misago.core.shortcuts import get_int_or_404
 from misago.core.shortcuts import get_int_or_404
-from misago.threads.viewmodels.posts import ThreadPosts
-from misago.threads.viewmodels.thread import ForumThread
+
+from ..viewmodels.posts import ThreadPosts
+from ..viewmodels.thread import ForumThread
 
 
 
 
 class ViewSet(viewsets.ViewSet):
 class ViewSet(viewsets.ViewSet):

+ 9 - 8
misago/threads/api/threads.py

@@ -11,14 +11,15 @@ from misago.categories.models import THREADS_ROOT_NAME, Category
 from misago.categories.permissions import allow_browse_category, allow_see_category
 from misago.categories.permissions import allow_browse_category, allow_see_category
 from misago.core.shortcuts import get_int_or_404, get_object_or_404
 from misago.core.shortcuts import get_int_or_404, get_object_or_404
 from misago.readtracker.categoriestracker import read_category
 from misago.readtracker.categoriestracker import read_category
-from misago.threads.api.threadendpoints.list import threads_list_endpoint
-from misago.threads.api.threadendpoints.merge import threads_merge_endpoint
-from misago.threads.api.threadendpoints.patch import thread_patch_endpoint
-from misago.threads.models import Subscription
-from misago.threads.moderation import threads as moderation
-from misago.threads.subscriptions import make_subscription_aware
-from misago.threads.threadtypes import trees_map
-from misago.threads.viewmodels.thread import ForumThread
+
+from ..models import Subscription
+from ..moderation import threads as moderation
+from ..subscriptions import make_subscription_aware
+from ..threadtypes import trees_map
+from ..viewmodels.thread import ForumThread
+from .threadendpoints.list import threads_list_endpoint
+from .threadendpoints.merge import threads_merge_endpoint
+from .threadendpoints.patch import thread_patch_endpoint
 
 
 
 
 class ViewSet(viewsets.ViewSet):
 class ViewSet(viewsets.ViewSet):

+ 1 - 1
misago/threads/apps.py

@@ -7,4 +7,4 @@ class MisagoThreadsConfig(AppConfig):
     verbose_name = "Misago Threads"
     verbose_name = "Misago Threads"
 
 
     def ready(self):
     def ready(self):
-        from misago.threads import signals
+        from . import signals

+ 1 - 1
misago/threads/events.py

@@ -1,6 +1,6 @@
 from django.utils import timezone
 from django.utils import timezone
 
 
-from misago.threads.models import Post
+from .models import Post
 
 
 
 
 def record_event(request, thread, event, context=None, commit=True):
 def record_event(request, thread, event, context=None, commit=True):

+ 2 - 1
misago/threads/management/commands/synchronizethreads.py

@@ -4,7 +4,8 @@ from django.core.management.base import BaseCommand
 
 
 from misago.core.management.progressbar import show_progress
 from misago.core.management.progressbar import show_progress
 from misago.core.pgutils import batch_update
 from misago.core.pgutils import batch_update
-from misago.threads.models import Thread
+
+from ...models import Thread
 
 
 
 
 class Command(BaseCommand):
 class Command(BaseCommand):

+ 1 - 1
misago/threads/middleware.py

@@ -1,4 +1,4 @@
-from misago.threads.counts import sync_user_unread_private_threads_count
+from .counts import sync_user_unread_private_threads_count
 
 
 
 
 class UnreadThreadsCountMiddleware(object):
 class UnreadThreadsCountMiddleware(object):

+ 4 - 4
misago/threads/models/__init__.py

@@ -1,5 +1,5 @@
 # flake8: noqa
 # flake8: noqa
-from misago.threads.models.post import Post
-from misago.threads.models.thread import *
-from misago.threads.models.threadparticipant import ThreadParticipant
-from misago.threads.models.subscription import Subscription
+from .post import Post
+from .thread import *
+from .threadparticipant import ThreadParticipant
+from .subscription import Subscription

+ 6 - 5
misago/threads/models/post.py

@@ -5,8 +5,9 @@ from django.dispatch import receiver
 from django.utils import timezone
 from django.utils import timezone
 
 
 from misago.conf import settings
 from misago.conf import settings
-from misago.threads import threadtypes
-from misago.threads.checksums import is_post_valid, update_post_checksum
+
+from .. import threadtypes
+from ..checksums import is_post_valid, update_post_checksum
 
 
 
 
 class Post(models.Model):
 class Post(models.Model):
@@ -67,7 +68,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)
 
 
         super(Post, self).delete(*args, **kwargs)
         super(Post, self).delete(*args, **kwargs)
@@ -91,11 +92,11 @@ class Post(models.Model):
         other_post.parsed = '%s\n%s' % (other_post.parsed, self.parsed)
         other_post.parsed = '%s\n%s' % (other_post.parsed, self.parsed)
         update_post_checksum(other_post)
         update_post_checksum(other_post)
 
 
-        from misago.threads.signals import merge_post
+        from ..signals import merge_post
         merge_post.send(sender=self, other_thread=other_post)
         merge_post.send(sender=self, other_thread=other_post)
 
 
     def move(self, new_thread):
     def move(self, new_thread):
-        from misago.threads.signals import move_post
+        from ..signals import move_post
 
 
         self.category = new_thread.category
         self.category = new_thread.category
         self.thread = new_thread
         self.thread = new_thread

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

@@ -99,7 +99,7 @@ class Thread(models.Model):
         return Thread.objects.select_for_update().get(id=self.id)
         return Thread.objects.select_for_update().get(id=self.id)
 
 
     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)
 
 
         super(Thread, self).delete(*args, **kwargs)
         super(Thread, self).delete(*args, **kwargs)
@@ -108,11 +108,11 @@ 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)

+ 3 - 3
misago/threads/moderation/__init__.py

@@ -1,4 +1,4 @@
 # flake8: noqa
 # flake8: noqa
-from misago.threads.moderation.exceptions import *
-from misago.threads.moderation.threads import *
-from misago.threads.moderation.posts import *
+from .exceptions import *
+from .threads import *
+from .posts import *

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

@@ -2,7 +2,7 @@ from django.db.transaction import atomic
 from django.utils import timezone
 from django.utils import timezone
 from django.utils.translation import ugettext as _
 from django.utils.translation import ugettext as _
 
 
-from misago.threads.moderation.exceptions import ModerationError
+from .exceptions import ModerationError
 
 
 
 
 def approve_post(user, post):
 def approve_post(user, post):

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

@@ -2,7 +2,7 @@ from django.db.transaction import atomic
 from django.utils import timezone
 from django.utils import timezone
 from django.utils.translation import ugettext as _
 from django.utils.translation import ugettext as _
 
 
-from misago.threads.events import record_event
+from ..events import record_event
 
 
 
 
 @atomic
 @atomic

+ 3 - 2
misago/threads/participants.py

@@ -1,8 +1,9 @@
 from django.utils.translation import ugettext as _
 from django.utils.translation import ugettext as _
 
 
 from misago.core.mail import mail_user
 from misago.core.mail import mail_user
-from misago.threads.models import ThreadParticipant
-from misago.threads.signals import remove_thread_participant
+
+from .models import ThreadParticipant
+from .signals import remove_thread_participant
 
 
 
 
 def thread_has_participants(thread):
 def thread_has_participants(thread):

+ 2 - 2
misago/threads/permissions/__init__.py

@@ -1,3 +1,3 @@
 # flake8: noqa
 # flake8: noqa
-from misago.threads.permissions.privatethreads import *
-from misago.threads.permissions.threads import *
+from .privatethreads import *
+from .threads import *

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

@@ -11,7 +11,8 @@ from misago.acl.models import Role
 from misago.categories.models import Category, CategoryRole, RoleCategoryACL
 from misago.categories.models import Category, CategoryRole, RoleCategoryACL
 from misago.categories.permissions import get_categories_roles
 from misago.categories.permissions import get_categories_roles
 from misago.core import forms
 from misago.core import forms
-from misago.threads.models import Post, Thread
+
+from ..models import Post, Thread
 
 
 
 
 __all__ = [
 __all__ = [

+ 3 - 3
misago/threads/serializers/__init__.py

@@ -1,3 +1,3 @@
-from misago.threads.serializers.thread import *
-from misago.threads.serializers.moderation import *
-from misago.threads.serializers.post import *
+from .thread import *
+from .moderation import *
+from .post import *

+ 5 - 4
misago/threads/serializers/moderation.py

@@ -6,10 +6,11 @@ from rest_framework import serializers
 from misago.acl import add_acl
 from misago.acl import add_acl
 from misago.categories.models import THREADS_ROOT_NAME, Category
 from misago.categories.models import THREADS_ROOT_NAME, Category
 from misago.categories.permissions import can_browse_category, can_see_category
 from misago.categories.permissions import can_browse_category, can_see_category
-from misago.threads.models import THREAD_WEIGHT_DEFAULT, THREAD_WEIGHT_GLOBAL
-from misago.threads.permissions import allow_start_thread
-from misago.threads.threadtypes import trees_map
-from misago.threads.validators import validate_title
+
+from ..models import THREAD_WEIGHT_DEFAULT, THREAD_WEIGHT_GLOBAL
+from ..permissions import allow_start_thread
+from ..threadtypes import trees_map
+from ..validators import validate_title
 
 
 
 
 def validate_category(user, category_id, allow_root=False):
 def validate_category(user, category_id, allow_root=False):

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

@@ -2,9 +2,10 @@ from django.core.urlresolvers import reverse
 
 
 from rest_framework import serializers
 from rest_framework import serializers
 
 
-from misago.threads.models import Post
 from misago.users.serializers import UserSerializer
 from misago.users.serializers import UserSerializer
 
 
+from ..models import Post
+
 
 
 __all__ = [
 __all__ = [
     'PostSerializer',
     'PostSerializer',

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

@@ -3,7 +3,8 @@ from django.core.urlresolvers import reverse
 from rest_framework import serializers
 from rest_framework import serializers
 
 
 from misago.categories.serializers import BasicCategorySerializer
 from misago.categories.serializers import BasicCategorySerializer
-from misago.threads.models import Thread
+
+from ..models import Thread
 
 
 
 
 __all__ = [
 __all__ = [

+ 2 - 1
misago/threads/signals.py

@@ -6,9 +6,10 @@ from django.dispatch import Signal, receiver
 from misago.categories.models import Category
 from misago.categories.models import Category
 from misago.categories.signals import delete_category_content, move_category_content
 from misago.categories.signals import delete_category_content, move_category_content
 from misago.core.pgutils import batch_delete, batch_update
 from misago.core.pgutils import batch_delete, batch_update
-from misago.threads.models import Post, Thread
 from misago.users.signals import delete_user_content, username_changed
 from misago.users.signals import delete_user_content, username_changed
 
 
+from .models import Post, Thread
+
 
 
 delete_post = Signal()
 delete_post = Signal()
 delete_thread = Signal()
 delete_thread = Signal()

+ 1 - 1
misago/threads/subscriptions.py

@@ -1,4 +1,4 @@
-from misago.threads.models import Subscription
+from .models import Subscription
 
 
 
 
 __all__ = ['make_subscription_aware']
 __all__ = ['make_subscription_aware']

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

@@ -2,10 +2,11 @@ from datetime import timedelta
 
 
 from django.utils import timezone
 from django.utils import timezone
 
 
-from misago.threads.posting import PostingInterrupt
-from misago.threads.posting.floodprotection import MIN_POSTING_PAUSE, FloodProtectionMiddleware
 from misago.users.testutils import AuthenticatedUserTestCase
 from misago.users.testutils import AuthenticatedUserTestCase
 
 
+from ..posting import PostingInterrupt
+from ..posting.floodprotection import MIN_POSTING_PAUSE, FloodProtectionMiddleware
+
 
 
 class FloodProtectionMiddlewareTests(AuthenticatedUserTestCase):
 class FloodProtectionMiddlewareTests(AuthenticatedUserTestCase):
     def test_flood_protection_middleware_on_no_posts(self):
     def test_flood_protection_middleware_on_no_posts(self):

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

@@ -7,9 +7,10 @@ from django.utils import timezone
 
 
 from misago.acl import add_acl
 from misago.acl import add_acl
 from misago.categories.models import Category
 from misago.categories.models import Category
-from misago.threads.events import record_event
-from misago.threads.models import Post, Thread
-from misago.threads.testutils import reply_thread
+
+from ..events import record_event
+from ..models import Post, Thread
+from ..testutils import reply_thread
 
 
 
 
 class MockRequest(object):
 class MockRequest(object):

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

@@ -3,8 +3,9 @@ from django.test import TestCase
 from django.utils import timezone
 from django.utils import timezone
 
 
 from misago.categories.models import Category
 from misago.categories.models import Category
-from misago.threads.models import Post, Thread, ThreadParticipant
-from misago.threads.participants import (
+
+from ..models import Post, Thread, ThreadParticipant
+from ..participants import (
     add_owner,
     add_owner,
     make_thread_participants_aware,
     make_thread_participants_aware,
     remove_participant,
     remove_participant,

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

@@ -5,8 +5,9 @@ from django.test import TestCase
 from django.utils import timezone
 from django.utils import timezone
 
 
 from misago.categories.models import Category
 from misago.categories.models import Category
-from misago.threads.checksums import update_post_checksum
-from misago.threads.models import Post, Thread
+
+from ..checksums import update_post_checksum
+from ..models import Post, Thread
 
 
 
 
 class PostModelTests(TestCase):
 class PostModelTests(TestCase):

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

@@ -1,8 +1,9 @@
 from misago.categories.models import Category
 from misago.categories.models import Category
-from misago.threads import moderation, testutils
-from misago.threads.models import Post, Thread
 from misago.users.testutils import AuthenticatedUserTestCase
 from misago.users.testutils import AuthenticatedUserTestCase
 
 
+from .. import moderation, testutils
+from ..models import Post, Thread
+
 
 
 class PostsModerationTests(AuthenticatedUserTestCase):
 class PostsModerationTests(AuthenticatedUserTestCase):
     def setUp(self):
     def setUp(self):

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

@@ -5,10 +5,11 @@ from django.test import TestCase
 from django.utils import timezone
 from django.utils import timezone
 
 
 from misago.categories.models import Category
 from misago.categories.models import Category
-from misago.threads import testutils
-from misago.threads.subscriptions import make_subscription_aware
 from misago.users.models import AnonymousUser
 from misago.users.models import AnonymousUser
 
 
+from .. import testutils
+from ..subscriptions import make_subscription_aware
+
 
 
 class SubscriptionsTests(TestCase):
 class SubscriptionsTests(TestCase):
     def setUp(self):
     def setUp(self):

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

@@ -2,8 +2,9 @@ from django.test import TestCase
 from django.utils.six import StringIO
 from django.utils.six import StringIO
 
 
 from misago.categories.models import Category
 from misago.categories.models import Category
-from misago.threads import testutils
-from misago.threads.management.commands import synchronizethreads
+
+from .. import testutils
+from ..management.commands import synchronizethreads
 
 
 
 
 class SynchronizeThreadsTests(TestCase):
 class SynchronizeThreadsTests(TestCase):

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

@@ -5,7 +5,8 @@ from django.test import TestCase
 from django.utils import timezone
 from django.utils import timezone
 
 
 from misago.categories.models import Category
 from misago.categories.models import Category
-from misago.threads.models import Post, Thread, ThreadParticipant
+
+from ..models import Post, Thread, ThreadParticipant
 
 
 
 
 class ThreadModelTests(TestCase):
 class ThreadModelTests(TestCase):

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

@@ -2,7 +2,8 @@ import json
 
 
 from misago.acl.testutils import override_acl
 from misago.acl.testutils import override_acl
 from misago.categories.models import Category
 from misago.categories.models import Category
-from misago.threads.tests.test_threads_api import ThreadsApiTestCase
+
+from .test_threads_api import ThreadsApiTestCase
 
 
 
 
 class ThreadPinGloballyApiTests(ThreadsApiTestCase):
 class ThreadPinGloballyApiTests(ThreadsApiTestCase):

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

@@ -3,7 +3,8 @@ from django.test import TestCase
 from django.utils import timezone
 from django.utils import timezone
 
 
 from misago.categories.models import Category
 from misago.categories.models import Category
-from misago.threads.models import Post, Thread, ThreadParticipant
+
+from ..models import Post, Thread, ThreadParticipant
 
 
 
 
 class ThreadParticipantTests(TestCase):
 class ThreadParticipantTests(TestCase):

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

@@ -2,11 +2,12 @@ import json
 
 
 from misago.acl.testutils import override_acl
 from misago.acl.testutils import override_acl
 from misago.categories.models import THREADS_ROOT_NAME, Category
 from misago.categories.models import THREADS_ROOT_NAME, Category
-from misago.threads import testutils
-from misago.threads.models import Thread
-from misago.threads.threadtypes import trees_map
 from misago.users.testutils import AuthenticatedUserTestCase
 from misago.users.testutils import AuthenticatedUserTestCase
 
 
+from .. import testutils
+from ..models import Thread
+from ..threadtypes import trees_map
+
 
 
 class ThreadsApiTestCase(AuthenticatedUserTestCase):
 class ThreadsApiTestCase(AuthenticatedUserTestCase):
     def setUp(self):
     def setUp(self):

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

@@ -5,11 +5,12 @@ from django.core.urlresolvers import reverse
 from misago.acl import add_acl
 from misago.acl import add_acl
 from misago.acl.testutils import override_acl
 from misago.acl.testutils import override_acl
 from misago.categories.models import Category
 from misago.categories.models import Category
-from misago.threads import testutils
-from misago.threads.api.threadendpoints.merge import MERGE_LIMIT
-from misago.threads.models import Post, Thread
-from misago.threads.serializers import ThreadListSerializer
-from misago.threads.tests.test_threads_api import ThreadsApiTestCase
+
+from .. import testutils
+from ..api.threadendpoints.merge import MERGE_LIMIT
+from ..models import Post, Thread
+from ..serializers import ThreadListSerializer
+from .test_threads_api import ThreadsApiTestCase
 
 
 
 
 class ThreadsMergeApiTests(ThreadsApiTestCase):
 class ThreadsMergeApiTests(ThreadsApiTestCase):

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

@@ -1,8 +1,9 @@
 from misago.categories.models import Category
 from misago.categories.models import Category
-from misago.threads import moderation, testutils
-from misago.threads.models import Post, Thread
 from misago.users.testutils import AuthenticatedUserTestCase
 from misago.users.testutils import AuthenticatedUserTestCase
 
 
+from .. import moderation, testutils
+from ..models import Post, Thread
+
 
 
 class MockRequest(object):
 class MockRequest(object):
     def __init__(self, user):
     def __init__(self, user):

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

@@ -9,9 +9,10 @@ from misago.categories.models import Category
 from misago.core import threadstore
 from misago.core import threadstore
 from misago.core.cache import cache
 from misago.core.cache import cache
 from misago.readtracker import categoriestracker, threadstracker
 from misago.readtracker import categoriestracker, threadstracker
-from misago.threads import testutils
 from misago.users.testutils import AuthenticatedUserTestCase
 from misago.users.testutils import AuthenticatedUserTestCase
 
 
+from .. import testutils
+
 
 
 LISTS_URLS = (
 LISTS_URLS = (
     '',
     '',

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

@@ -1,9 +1,10 @@
 from misago.acl.testutils import override_acl
 from misago.acl.testutils import override_acl
 from misago.categories.models import Category
 from misago.categories.models import Category
-from misago.threads import testutils
-from misago.threads.models import Thread
 from misago.users.testutils import AuthenticatedUserTestCase
 from misago.users.testutils import AuthenticatedUserTestCase
 
 
+from .. import testutils
+from ..models import Thread
+
 
 
 class ThreadViewTestCase(AuthenticatedUserTestCase):
 class ThreadViewTestCase(AuthenticatedUserTestCase):
     def setUp(self):
     def setUp(self):

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

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

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

@@ -1,7 +1,8 @@
 from misago.categories.models import Category
 from misago.categories.models import Category
 from misago.core.testutils import MisagoTestCase
 from misago.core.testutils import MisagoTestCase
-from misago.threads import testutils
-from misago.threads.utils import add_categories_to_threads
+
+from .. import testutils
+from ..utils import add_categories_to_threads
 
 
 
 
 class AddCategoriesToThreadsTests(MisagoTestCase):
 class AddCategoriesToThreadsTests(MisagoTestCase):

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

@@ -2,7 +2,8 @@ from django.core.exceptions import ValidationError
 from django.test import TestCase
 from django.test import TestCase
 
 
 from misago.conf import settings
 from misago.conf import settings
-from misago.threads.validators import validate_title
+
+from ..validators import validate_title
 
 
 
 
 class ValidateTitleTests(TestCase):
 class ValidateTitleTests(TestCase):

+ 2 - 1
misago/threads/testutils.py

@@ -3,7 +3,8 @@ from datetime import timedelta
 from django.utils import timezone
 from django.utils import timezone
 
 
 from misago.core.utils import slugify
 from misago.core.utils import slugify
-from misago.threads.models import Post, Thread
+
+from .models import Post, Thread
 
 
 
 
 def post_thread(category, title='Test thread', poster='Tester',
 def post_thread(category, title='Test thread', poster='Tester',

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

@@ -1,7 +1,7 @@
 from django.core.urlresolvers import reverse
 from django.core.urlresolvers import reverse
 from django.utils.translation import ugettext_lazy as _
 from django.utils.translation import ugettext_lazy as _
 
 
-from misago.threads.threadtypes import ThreadType
+from . import ThreadType
 
 
 
 
 class PrivateThread(ThreadType):
 class PrivateThread(ThreadType):

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

@@ -1,7 +1,7 @@
 from django.core.urlresolvers import reverse
 from django.core.urlresolvers import reverse
 from django.utils.translation import ugettext_lazy as _
 from django.utils.translation import ugettext_lazy as _
 
 
-from misago.threads.threadtypes import ThreadType
+from . import ThreadType
 
 
 
 
 class Thread(ThreadType):
 class Thread(ThreadType):

+ 2 - 2
misago/threads/urls/__init__.py

@@ -1,8 +1,8 @@
 from django.conf import settings
 from django.conf import settings
 from django.conf.urls import url
 from django.conf.urls import url
 
 
-from misago.threads.views.list import ForumThreads, CategoryThreads, PrivateThreads
-from misago.threads.views.thread import Thread, PrivateThread
+from ..views.list import ForumThreads, CategoryThreads, PrivateThreads
+from ..views.thread import Thread, PrivateThread
 
 
 
 
 LISTS_TYPES = (
 LISTS_TYPES = (

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

@@ -1,6 +1,7 @@
 from misago.core.apirouter import MisagoApiRouter
 from misago.core.apirouter import MisagoApiRouter
-from misago.threads.api.threadposts import ThreadPostsViewSet
-from misago.threads.api.threads import ThreadViewSet
+
+from ..api.threadposts import ThreadPostsViewSet
+from ..api.threads import ThreadViewSet
 
 
 
 
 router = MisagoApiRouter()
 router = MisagoApiRouter()

+ 3 - 2
misago/threads/viewmodels/posts.py

@@ -3,10 +3,11 @@ from django.conf import settings
 from misago.acl import add_acl
 from misago.acl import add_acl
 from misago.core.shortcuts import paginate, pagination_dict
 from misago.core.shortcuts import paginate, pagination_dict
 from misago.readtracker.threadstracker import make_posts_read_aware
 from misago.readtracker.threadstracker import make_posts_read_aware
-from misago.threads.permissions.threads import exclude_invisible_posts
-from misago.threads.serializers import ThreadPostSerializer
 from misago.users.online.utils import make_users_status_aware
 from misago.users.online.utils import make_users_status_aware
 
 
+from ..permissions.threads import exclude_invisible_posts
+from ..serializers import ThreadPostSerializer
+
 
 
 class ViewModel(object):
 class ViewModel(object):
     def __init__(self, request, thread, page):
     def __init__(self, request, thread, page):

+ 5 - 4
misago/threads/viewmodels/thread.py

@@ -5,10 +5,11 @@ from misago.acl import add_acl
 from misago.categories.models import Category
 from misago.categories.models import Category
 from misago.core.shortcuts import validate_slug
 from misago.core.shortcuts import validate_slug
 from misago.readtracker.threadstracker import make_read_aware
 from misago.readtracker.threadstracker import make_read_aware
-from misago.threads.models import Thread
-from misago.threads.permissions.threads import allow_see_thread
-from misago.threads.serializers import ThreadSerializer
-from misago.threads.subscriptions import make_subscription_aware
+
+from ..models import Thread
+from ..permissions.threads import allow_see_thread
+from ..serializers import ThreadSerializer
+from ..subscriptions import make_subscription_aware
 
 
 
 
 BASE_QUERYSET = Thread.objects.select_related(
 BASE_QUERYSET = Thread.objects.select_related(

+ 6 - 5
misago/threads/viewmodels/threads.py

@@ -11,11 +11,12 @@ from django.utils.translation import ugettext_lazy
 from misago.acl import add_acl
 from misago.acl import add_acl
 from misago.core.shortcuts import paginate, pagination_dict
 from misago.core.shortcuts import paginate, pagination_dict
 from misago.readtracker import threadstracker
 from misago.readtracker import threadstracker
-from misago.threads.models import Thread
-from misago.threads.permissions import exclude_invisible_threads
-from misago.threads.serializers import ThreadListSerializer
-from misago.threads.subscriptions import make_subscription_aware
-from misago.threads.utils import add_categories_to_threads
+
+from ..models import Thread
+from ..permissions import exclude_invisible_threads
+from ..serializers import ThreadListSerializer
+from ..subscriptions import make_subscription_aware
+from ..utils import add_categories_to_threads
 
 
 
 
 LISTS_NAMES = {
 LISTS_NAMES = {

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

@@ -4,8 +4,8 @@ from django.http import Http404
 from django.shortcuts import render
 from django.shortcuts import render
 from django.views.generic import View
 from django.views.generic import View
 
 
-from misago.threads.viewmodels.category import PrivateThreadsCategory, ThreadsCategory, ThreadsRootCategory
-from misago.threads.viewmodels.threads import ForumThreads, PrivateThreads
+from ..viewmodels.category import PrivateThreadsCategory, ThreadsCategory, ThreadsRootCategory
+from ..viewmodels.threads import ForumThreads, PrivateThreads
 
 
 
 
 class ListBase(View):
 class ListBase(View):

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

@@ -2,8 +2,8 @@ from django.core.urlresolvers import reverse
 from django.shortcuts import render
 from django.shortcuts import render
 from django.views.generic import View
 from django.views.generic import View
 
 
-from misago.threads.viewmodels.posts import ThreadPosts
-from misago.threads.viewmodels.thread import ForumThread
+from ..viewmodels.posts import ThreadPosts
+from ..viewmodels.thread import ForumThread
 
 
 
 
 class ThreadBase(View):
 class ThreadBase(View):

+ 2 - 1
misago/users/activepostersranking.py

@@ -6,7 +6,8 @@ from django.db.models import Count
 from django.utils import timezone
 from django.utils import timezone
 
 
 from misago.categories.models import Category
 from misago.categories.models import Category
-from misago.users.models import ActivityRanking
+
+from .models import ActivityRanking
 
 
 
 
 def get_active_posters_ranking():
 def get_active_posters_ranking():

+ 5 - 19
misago/users/admin.py

@@ -2,9 +2,9 @@ from django.conf.urls import url
 from django.contrib import admin as djadmin
 from django.contrib import admin as djadmin
 from django.utils.translation import ugettext_lazy as _
 from django.utils.translation import ugettext_lazy as _
 
 
-from misago.users.djangoadmin import User, UserAdminModel
-from misago.users.views.admin.bans import BansList, DeleteBan, EditBan, NewBan
-from misago.users.views.admin.ranks import (
+from .djangoadmin import User, UserAdminModel
+from .views.admin.bans import BansList, DeleteBan, EditBan, NewBan
+from .views.admin.ranks import (
     DefaultRank,
     DefaultRank,
     DeleteRank,
     DeleteRank,
     EditRank,
     EditRank,
@@ -14,22 +14,8 @@ from misago.users.views.admin.ranks import (
     RanksList,
     RanksList,
     RankUsers
     RankUsers
 )
 )
-from misago.users.views.admin.users import (
-    DeleteAccountStep,
-    DeletePostsStep,
-    DeleteThreadsStep,
-    EditUser,
-    NewUser,
-    UsersList
-)
-from misago.users.views.admin.warnings import (
-    DeleteWarning,
-    EditWarning,
-    MoveDownWarning,
-    MoveUpWarning,
-    NewWarning,
-    WarningsList
-)
+from .views.admin.users import DeleteAccountStep, DeletePostsStep, DeleteThreadsStep, EditUser, NewUser, UsersList
+from .views.admin.warnings import DeleteWarning, EditWarning, MoveDownWarning, MoveUpWarning, NewWarning, WarningsList
 
 
 
 
 # register misago user model in django admin panel
 # register misago user model in django admin panel

+ 7 - 6
misago/users/api/auth.py

@@ -9,12 +9,13 @@ from rest_framework.response import Response
 
 
 from misago.conf import settings
 from misago.conf import settings
 from misago.core.mail import mail_user
 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.rest_permissions import UnbannedAnonOnly, UnbannedOnly
-from misago.users.serializers import AnonymousUserSerializer, AuthenticatedUserSerializer
-from misago.users.tokens import is_password_change_token_valid, make_activation_token, make_password_change_token
-from misago.users.validators import validate_password
+
+from ..bans import get_user_ban
+from ..forms.auth import AuthenticationForm, ResendActivationForm, ResetPasswordForm
+from ..rest_permissions import UnbannedAnonOnly, UnbannedOnly
+from ..serializers import AnonymousUserSerializer, AuthenticatedUserSerializer
+from ..tokens import is_password_change_token_valid, make_activation_token, make_password_change_token
+from ..validators import validate_password
 
 
 
 
 def gateway(request):
 def gateway(request):

+ 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):

+ 3 - 2
misago/users/api/userendpoints/avatar.py

@@ -8,8 +8,9 @@ from rest_framework.response import Response
 
 
 from misago.conf import settings
 from misago.conf import settings
 from misago.core.utils import format_plaintext_for_html
 from misago.core.utils import format_plaintext_for_html
-from misago.users import avatars
-from misago.users.forms.moderation import ModerateAvatarForm
+
+from ... import avatars
+from ...forms.moderation import ModerateAvatarForm
 
 
 
 
 def avatar_endpoint(request, pk=None):
 def avatar_endpoint(request, pk=None):

+ 3 - 2
misago/users/api/userendpoints/changeemail.py

@@ -5,8 +5,9 @@ from rest_framework.response import Response
 
 
 from misago.conf import settings
 from misago.conf import settings
 from misago.core.mail import mail_user
 from misago.core.mail import mail_user
-from misago.users.credentialchange import store_new_credential
-from misago.users.forms.options import ChangeEmailForm
+
+from ...credentialchange import store_new_credential
+from ...forms.options import ChangeEmailForm
 
 
 
 
 def change_email_endpoint(request, pk=None):
 def change_email_endpoint(request, pk=None):

+ 3 - 2
misago/users/api/userendpoints/changepassword.py

@@ -5,8 +5,9 @@ from rest_framework.response import Response
 
 
 from misago.conf import settings
 from misago.conf import settings
 from misago.core.mail import mail_user
 from misago.core.mail import mail_user
-from misago.users.credentialchange import store_new_credential
-from misago.users.forms.options import ChangePasswordForm
+
+from ...credentialchange import store_new_credential
+from ...forms.options import ChangePasswordForm
 
 
 
 
 def change_password_endpoint(request, pk=None):
 def change_password_endpoint(request, pk=None):

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

@@ -9,13 +9,14 @@ from rest_framework.response import Response
 from misago.conf import settings
 from misago.conf import settings
 from misago.core import forms
 from misago.core import forms
 from misago.core.mail import mail_user
 from misago.core.mail import mail_user
-from misago.users import captcha
-from misago.users.bans import ban_ip
-from misago.users.forms.register import RegisterForm
-from misago.users.models import ACTIVATION_REQUIRED_ADMIN, ACTIVATION_REQUIRED_USER
-from misago.users.serializers import AuthenticatedUserSerializer
-from misago.users.tokens import make_activation_token
-from misago.users.validators import validate_new_registration
+
+from ... import captcha
+from ...bans import ban_ip
+from ...forms.register import RegisterForm
+from ...models import ACTIVATION_REQUIRED_ADMIN, ACTIVATION_REQUIRED_USER
+from ...serializers import AuthenticatedUserSerializer
+from ...tokens import make_activation_token
+from ...validators import validate_new_registration
 
 
 
 
 @csrf_protect
 @csrf_protect

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

@@ -11,10 +11,11 @@ from misago.conf import settings
 from misago.core.apipaginator import ApiPaginator
 from misago.core.apipaginator import ApiPaginator
 from misago.core.cache import cache
 from misago.core.cache import cache
 from misago.core.shortcuts import get_int_or_404, get_object_or_404
 from misago.core.shortcuts import get_int_or_404, get_object_or_404
-from misago.users.activepostersranking import get_active_posters_ranking
-from misago.users.models import Rank
-from misago.users.online.utils import make_users_status_aware
-from misago.users.serializers import ScoredUserSerializer, UserSerializer
+
+from ...activepostersranking import get_active_posters_ranking
+from ...models import Rank
+from ...online.utils import make_users_status_aware
+from ...serializers import ScoredUserSerializer, UserSerializer
 
 
 
 
 Paginator = ApiPaginator(settings.MISAGO_USERS_PER_PAGE, 4)
 Paginator = ApiPaginator(settings.MISAGO_USERS_PER_PAGE, 4)

+ 3 - 2
misago/users/api/userendpoints/signature.py

@@ -6,8 +6,9 @@ from rest_framework.response import Response
 
 
 from misago.conf import settings
 from misago.conf import settings
 from misago.core.utils import format_plaintext_for_html
 from misago.core.utils import format_plaintext_for_html
-from misago.users.forms.options import EditSignatureForm
-from misago.users.signatures import is_user_signature_valid, set_user_signature
+
+from ...forms.options import EditSignatureForm
+from ...signatures import is_user_signature_valid, set_user_signature
 
 
 
 
 def signature_endpoint(request):
 def signature_endpoint(request):

+ 3 - 2
misago/users/api/userendpoints/username.py

@@ -5,8 +5,9 @@ from rest_framework import status
 from rest_framework.response import Response
 from rest_framework.response import Response
 
 
 from misago.conf import settings
 from misago.conf import settings
-from misago.users.forms.rename import ChangeUsernameForm
-from misago.users.namechanges import UsernameChanges
+
+from ...forms.rename import ChangeUsernameForm
+from ...namechanges import UsernameChanges
 
 
 
 
 def username_endpoint(request):
 def username_endpoint(request):

+ 4 - 3
misago/users/api/usernamechanges.py

@@ -8,9 +8,10 @@ from rest_framework.response import Response
 
 
 from misago.core.apipaginator import ApiPaginator
 from misago.core.apipaginator import ApiPaginator
 from misago.core.shortcuts import get_int_or_404, get_object_or_404
 from misago.core.shortcuts import get_int_or_404, get_object_or_404
-from misago.users.models import UsernameChange
-from misago.users.rest_permissions import BasePermission
-from misago.users.serializers.usernamechange import UsernameChangeSerializer
+
+from ..models import UsernameChange
+from ..rest_permissions import BasePermission
+from ..serializers.usernamechange import UsernameChangeSerializer
 
 
 
 
 class UsernameChangesViewSetPermission(BasePermission):
 class UsernameChangesViewSetPermission(BasePermission):

+ 16 - 15
misago/users/api/users.py

@@ -16,21 +16,22 @@ from misago.core.cache import cache
 from misago.core.shortcuts import get_int_or_404, get_object_or_404
 from misago.core.shortcuts import get_int_or_404, get_object_or_404
 from misago.threads.moderation.posts import hide_post
 from misago.threads.moderation.posts import hide_post
 from misago.threads.moderation.threads import hide_thread
 from misago.threads.moderation.threads import hide_thread
-from misago.users.api.userendpoints.avatar import avatar_endpoint, moderate_avatar_endpoint
-from misago.users.api.userendpoints.changeemail import change_email_endpoint
-from misago.users.api.userendpoints.changepassword import change_password_endpoint
-from misago.users.api.userendpoints.create import create_endpoint
-from misago.users.api.userendpoints.list import list_endpoint
-from misago.users.api.userendpoints.signature import signature_endpoint
-from misago.users.api.userendpoints.username import moderate_username_endpoint, username_endpoint
-from misago.users.bans import get_user_ban
-from misago.users.forms.options import ForumOptionsForm
-from misago.users.online.utils import get_user_status
-from misago.users.permissions.delete import allow_delete_user
-from misago.users.permissions.moderation import allow_moderate_avatar, allow_rename_user
-from misago.users.permissions.profiles import allow_browse_users_list, allow_follow_user, allow_see_ban_details
-from misago.users.rest_permissions import BasePermission, IsAuthenticatedOrReadOnly, UnbannedAnonOnly
-from misago.users.serializers import BanDetailsSerializer, UserProfileSerializer, UserSerializer
+
+from ..bans import get_user_ban
+from ..forms.options import ForumOptionsForm
+from ..online.utils import get_user_status
+from ..permissions.delete import allow_delete_user
+from ..permissions.moderation import allow_moderate_avatar, allow_rename_user
+from ..permissions.profiles import allow_browse_users_list, allow_follow_user, allow_see_ban_details
+from ..rest_permissions import BasePermission, IsAuthenticatedOrReadOnly, UnbannedAnonOnly
+from ..serializers import BanDetailsSerializer, UserProfileSerializer, UserSerializer
+from .userendpoints.avatar import avatar_endpoint, moderate_avatar_endpoint
+from .userendpoints.changeemail import change_email_endpoint
+from .userendpoints.changepassword import change_password_endpoint
+from .userendpoints.create import create_endpoint
+from .userendpoints.list import list_endpoint
+from .userendpoints.signature import signature_endpoint
+from .userendpoints.username import moderate_username_endpoint, username_endpoint
 
 
 
 
 class UserViewSetPermission(BasePermission):
 class UserViewSetPermission(BasePermission):

+ 3 - 3
misago/users/apps.py

@@ -1,7 +1,7 @@
 from django.apps import AppConfig
 from django.apps import AppConfig
 from django.utils.translation import ugettext_lazy as _
 from django.utils.translation import ugettext_lazy as _
 
 
-from misago.users.pages import user_profile, usercp, users_list
+from .pages import user_profile, usercp, users_list
 
 
 
 
 class MisagoUsersConfig(AppConfig):
 class MisagoUsersConfig(AppConfig):
@@ -10,7 +10,7 @@ class MisagoUsersConfig(AppConfig):
     verbose_name = "Misago Auth"
     verbose_name = "Misago Auth"
 
 
     def ready(self):
     def ready(self):
-        from misago.users import signals
+        from . import signals
 
 
         self.register_default_usercp_pages()
         self.register_default_usercp_pages()
         self.register_default_users_list_pages()
         self.register_default_users_list_pages()
@@ -81,7 +81,7 @@ class MisagoUsersConfig(AppConfig):
         def can_see_ban_details(request, profile):
         def can_see_ban_details(request, profile):
             if request.user.is_authenticated():
             if request.user.is_authenticated():
                 if request.user.acl['can_see_ban_details']:
                 if request.user.acl['can_see_ban_details']:
-                    from misago.users.bans import get_user_ban
+                    from .bans import get_user_ban
                     return bool(get_user_ban(profile))
                     return bool(get_user_ban(profile))
                 else:
                 else:
                     return False
                     return False

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

@@ -1,6 +1,6 @@
 from misago.conf import settings
 from misago.conf import settings
 
 
-from misago.users.avatars 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 - 1
misago/users/avatars/dynamic.py

@@ -5,7 +5,8 @@ from importlib import import_module
 from PIL import Image, ImageColor, ImageDraw, ImageFilter, ImageFont
 from PIL import Image, ImageColor, ImageDraw, ImageFilter, ImageFont
 
 
 from misago.conf import settings
 from misago.conf import settings
-from misago.users.avatars import store
+
+from . import store
 
 
 
 
 def set_avatar(user):
 def set_avatar(user):

+ 2 - 2
misago/users/avatars/gallery.py

@@ -5,8 +5,8 @@ from PIL import Image
 
 
 from django.conf import settings
 from django.conf import settings
 
 
-from misago.users.avatars import store
-from misago.users.avatars.paths import MEDIA_AVATARS
+from . import store
+from .paths import MEDIA_AVATARS
 
 
 
 
 def get_available_galleries(include_default=False):
 def get_available_galleries(include_default=False):

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

@@ -4,7 +4,8 @@ import requests
 from PIL import Image
 from PIL import Image
 
 
 from misago.conf import settings
 from misago.conf import settings
-from misago.users.avatars import store
+
+from . import store
 
 
 
 
 GRAVATAR_URL = 'http://www.gravatar.com/avatar/%s?s=%s&d=404'
 GRAVATAR_URL = 'http://www.gravatar.com/avatar/%s?s=%s&d=404'

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

@@ -5,7 +5,8 @@ from path import Path
 from PIL import Image
 from PIL import Image
 
 
 from misago.conf import settings
 from misago.conf import settings
-from misago.users.avatars.paths import AVATARS_STORE
+
+from .paths import AVATARS_STORE
 
 
 
 
 def normalize_image(image):
 def normalize_image(image):

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

@@ -8,7 +8,8 @@ from django.core.exceptions import ValidationError
 from django.utils.translation import ugettext as _
 from django.utils.translation import ugettext as _
 
 
 from misago.conf import settings
 from misago.conf import settings
-from misago.users.avatars import store
+
+from . import store
 
 
 
 
 ALLOWED_EXTENSIONS = ('.gif', '.png', '.jpg', '.jpeg')
 ALLOWED_EXTENSIONS = ('.gif', '.png', '.jpg', '.jpeg')

+ 2 - 1
misago/users/bans.py

@@ -11,7 +11,8 @@ from django.utils import timezone
 from django.utils.dateparse import parse_datetime
 from django.utils.dateparse import parse_datetime
 
 
 from misago.core import cachebuster
 from misago.core import cachebuster
-from misago.users.models import BAN_IP, Ban, BanCache
+
+from .models import BAN_IP, Ban, BanCache
 
 
 
 
 BAN_CACHE_SESSION_KEY = 'misago_ip_check'
 BAN_CACHE_SESSION_KEY = 'misago_ip_check'

+ 2 - 2
misago/users/context_processors.py

@@ -1,7 +1,7 @@
 from django.core.urlresolvers import reverse
 from django.core.urlresolvers import reverse
 
 
-from misago.users.pages import user_profile, usercp, users_list
-from misago.users.serializers import AnonymousUserSerializer, AuthenticatedUserSerializer
+from .pages import user_profile, usercp, users_list
+from .serializers import AnonymousUserSerializer, AuthenticatedUserSerializer
 
 
 
 
 def user_links(request):
 def user_links(request):

+ 3 - 2
misago/users/decorators.py

@@ -3,8 +3,9 @@ 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 misago.core.exceptions import Banned
-from misago.users.bans import get_request_ip_ban
-from misago.users.models import BAN_IP, Ban
+
+from .bans import get_request_ip_ban
+from .models import BAN_IP, Ban
 
 
 
 
 def deny_authenticated(f):
 def deny_authenticated(f):

+ 3 - 2
misago/users/forms/admin.py

@@ -6,7 +6,8 @@ from misago.acl.models import Role
 from misago.conf import settings
 from misago.conf import settings
 from misago.core import forms, threadstore
 from misago.core import forms, threadstore
 from misago.core.validators import validate_sluggable
 from misago.core.validators import validate_sluggable
-from misago.users.models import (
+
+from ..models import (
     AUTO_SUBSCRIBE_CHOICES,
     AUTO_SUBSCRIBE_CHOICES,
     BANS_CHOICES,
     BANS_CHOICES,
     PRIVATE_THREAD_INVITES_LIMITS_CHOICES,
     PRIVATE_THREAD_INVITES_LIMITS_CHOICES,
@@ -15,7 +16,7 @@ from misago.users.models import (
     Rank,
     Rank,
     WarningLevel
     WarningLevel
 )
 )
-from misago.users.validators import validate_email, validate_password, validate_username
+from ..validators import validate_email, validate_password, validate_username
 
 
 
 
 """
 """

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

@@ -5,8 +5,9 @@ from django.core.validators import validate_email
 from django.utils.translation import ugettext_lazy as _
 from django.utils.translation import ugettext_lazy as _
 
 
 from misago.core import forms
 from misago.core import forms
-from misago.users.bans import get_user_ban
-from misago.users.validators import validate_password
+
+from ..bans import get_user_ban
+from ..validators import validate_password
 
 
 
 
 class MisagoAuthMixin(object):
 class MisagoAuthMixin(object):

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

@@ -7,7 +7,8 @@ from django.utils.translation import ungettext
 
 
 from misago.conf import settings
 from misago.conf import settings
 from misago.core import forms
 from misago.core import forms
-from misago.users.bans import ban_user
+
+from ..bans import ban_user
 
 
 
 
 class WarnUserForm(forms.Form):
 class WarnUserForm(forms.Form):

+ 3 - 2
misago/users/forms/options.py

@@ -4,8 +4,9 @@ from django.utils.translation import ungettext
 
 
 from misago.conf import settings
 from misago.conf import settings
 from misago.core import forms
 from misago.core import forms
-from misago.users.models import AUTO_SUBSCRIBE_CHOICES, PRIVATE_THREAD_INVITES_LIMITS_CHOICES
-from misago.users.validators import validate_email, validate_password
+
+from ..models import AUTO_SUBSCRIBE_CHOICES, PRIVATE_THREAD_INVITES_LIMITS_CHOICES
+from ..validators import validate_email, validate_password
 
 
 
 
 class ForumOptionsForm(forms.ModelForm):
 class ForumOptionsForm(forms.ModelForm):

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

@@ -1,5 +1,6 @@
 from misago.core import forms
 from misago.core import forms
-from misago.users import validators
+
+from .. import validators
 
 
 
 
 class RegisterForm(forms.Form):
 class RegisterForm(forms.Form):

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

@@ -1,7 +1,8 @@
 from django.utils.translation import ugettext_lazy as _
 from django.utils.translation import ugettext_lazy as _
 
 
 from misago.core import forms
 from misago.core import forms
-from misago.users.validators import validate_username
+
+from ..validators import validate_username
 
 
 
 
 class ChangeUsernameForm(forms.Form):
 class ChangeUsernameForm(forms.Form):

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

@@ -2,7 +2,8 @@ from django.core.management.base import BaseCommand
 from django.utils import timezone
 from django.utils import timezone
 
 
 from misago.core import cachebuster
 from misago.core import cachebuster
-from misago.users.models import Ban, BanCache
+
+from ...models import Ban, BanCache
 
 
 
 
 class Command(BaseCommand):
 class Command(BaseCommand):

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

@@ -1,7 +1,8 @@
 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.management.progressbar import show_progress
-from misago.users.activepostersranking import build_active_posters_ranking
+
+from ...activepostersranking import build_active_posters_ranking
 
 
 
 
 class Command(BaseCommand):
 class Command(BaseCommand):

+ 1 - 1
misago/users/management/commands/createsuperuser.py

@@ -13,7 +13,7 @@ from django.db import DEFAULT_DB_ALIAS, IntegrityError
 from django.utils.encoding import force_str
 from django.utils.encoding import force_str
 from django.utils.six.moves import input
 from django.utils.six.moves import input
 
 
-from misago.users.validators import validate_email, validate_password, validate_username
+from ...validators import validate_email, validate_password, validate_username
 
 
 
 
 class NotRunningInTTYException(Exception):
 class NotRunningInTTYException(Exception):

+ 1 - 1
misago/users/management/commands/populateonlinetracker.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 BaseCommand
 from django.core.management.base import BaseCommand
 
 
-from misago.users.models import Online
+from ...models import Online
 
 
 
 
 class Command(BaseCommand):
 class Command(BaseCommand):

+ 1 - 1
misago/users/management/commands/updateblankavatar.py

@@ -6,7 +6,7 @@ from PIL import Image
 from django.conf import settings
 from django.conf import settings
 from django.core.management.base import BaseCommand
 from django.core.management.base import BaseCommand
 
 
-from misago.users.avatars.paths import AVATARS_STORE, BLANK_AVATAR
+from ...avatars.paths import AVATARS_STORE, BLANK_AVATAR
 
 
 
 
 class Command(BaseCommand):
 class Command(BaseCommand):

+ 4 - 3
misago/users/middleware.py

@@ -5,9 +5,10 @@ from django.contrib.auth.models import AnonymousUser as DjAnonymousUser
 from django.core.urlresolvers import resolve
 from django.core.urlresolvers import resolve
 
 
 from misago.conf import settings
 from misago.conf import settings
-from misago.users.bans import get_request_ip_ban, get_user_ban
-from misago.users.models import AnonymousUser, Online
-from misago.users.online import tracker
+
+from .bans import get_request_ip_ban, get_user_ban
+from .models import AnonymousUser, Online
+from .online import tracker
 
 
 
 
 class RealIPMiddleware(object):
 class RealIPMiddleware(object):

+ 5 - 5
misago/users/models/__init__.py

@@ -1,6 +1,6 @@
 # flake8: noqa
 # flake8: noqa
-from misago.users.models.rank import *
-from misago.users.models.user import *
-from misago.users.models.activityranking import *
-from misago.users.models.ban import *
-from misago.users.models.warnings import *
+from .rank import *
+from .user import *
+from .activityranking import *
+from .ban import *
+from .warnings import *

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

@@ -92,7 +92,7 @@ class Ban(models.Model):
         return super(Ban, self).save(*args, **kwargs)
         return super(Ban, self).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
 
 
     @property
     @property
@@ -136,7 +136,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,
             check_type=BAN_USERNAME,
             check_type=BAN_USERNAME,

+ 8 - 7
misago/users/models/user.py

@@ -14,10 +14,11 @@ from misago.acl import get_user_acl
 from misago.acl.models import Role
 from misago.acl.models import Role
 from misago.conf import settings
 from misago.conf import settings
 from misago.core.utils import slugify
 from misago.core.utils import slugify
-from misago.users import avatars
-from misago.users.models.rank import Rank
-from misago.users.signatures import is_user_signature_valid, make_signature_checksum
-from misago.users.utils import hash_email
+
+from .. import avatars
+from ..signatures import is_user_signature_valid, make_signature_checksum
+from ..utils import hash_email
+from .rank import Rank
 
 
 
 
 __all__ = [
 __all__ = [
@@ -72,7 +73,7 @@ PRIVATE_THREAD_INVITES_LIMITS_CHOICES = (
 
 
 class UserManager(BaseUserManager):
 class UserManager(BaseUserManager):
     def create_user(self, username, email, password=None, set_default_avatar=False, **extra_fields):
     def create_user(self, username, email, password=None, set_default_avatar=False, **extra_fields):
-        from misago.users.validators import validate_email, validate_password, validate_username
+        from ..validators import validate_email, validate_password, validate_username
 
 
         with transaction.atomic():
         with transaction.atomic():
             if not email:
             if not email:
@@ -277,7 +278,7 @@ class User(AbstractBaseUser, PermissionsMixin):
         return super(User, self).delete(*args, **kwargs)
         return super(User, self).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)
 
 
     @property
     @property
@@ -377,7 +378,7 @@ class User(AbstractBaseUser, PermissionsMixin):
                 self.record_name_change(
                 self.record_name_change(
                     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)
 
 
     def record_name_change(self, changed_by, new_username, old_username):
     def record_name_change(self, changed_by, new_username, old_username):

+ 1 - 1
misago/users/namechanges.py

@@ -5,7 +5,7 @@ from datetime import timedelta
 
 
 from django.utils import timezone
 from django.utils import timezone
 
 
-from misago.users.models import UsernameChange
+from .models import UsernameChange
 
 
 
 
 class UsernameChanges(object):
 class UsernameChanges(object):

+ 1 - 1
misago/users/online/tracker.py

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

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

@@ -2,8 +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)

+ 2 - 1
misago/users/permissions/moderation.py

@@ -10,7 +10,8 @@ from misago.acl import algebra
 from misago.acl.decorators import return_boolean
 from misago.acl.decorators import return_boolean
 from misago.acl.models import Role
 from misago.acl.models import Role
 from misago.core import forms
 from misago.core import forms
-from misago.users.bans import get_user_ban
+
+from ..bans import get_user_ban
 
 
 
 
 """
 """

+ 2 - 1
misago/users/permissions/profiles.py

@@ -6,7 +6,8 @@ from misago.acl import algebra
 from misago.acl.decorators import return_boolean
 from misago.acl.decorators import return_boolean
 from misago.acl.models import Role
 from misago.acl.models import Role
 from misago.core import forms
 from misago.core import forms
-from misago.users.permissions.decorators import authenticated_only
+
+from .decorators import authenticated_only
 
 
 
 
 """
 """

+ 3 - 2
misago/users/permissions/warnings.py

@@ -6,8 +6,9 @@ from misago.acl import algebra
 from misago.acl.decorators import return_boolean
 from misago.acl.decorators import return_boolean
 from misago.acl.models import Role
 from misago.acl.models import Role
 from misago.core import forms
 from misago.core import forms
-from misago.users.models import UserWarning
-from misago.users.permissions.decorators import authenticated_only
+
+from ..models import UserWarning
+from .decorators import authenticated_only
 
 
 
 
 """
 """

+ 3 - 2
misago/users/rest_permissions.py

@@ -4,8 +4,9 @@ from django.utils.translation import ugettext as _
 from rest_framework.permissions import SAFE_METHODS, AllowAny, BasePermission
 from rest_framework.permissions import SAFE_METHODS, AllowAny, BasePermission
 
 
 from misago.core.exceptions import Banned
 from misago.core.exceptions import Banned
-from misago.users.bans import get_request_ip_ban
-from misago.users.models import BAN_IP, Ban
+
+from .bans import get_request_ip_ban
+from .models import BAN_IP, Ban
 
 
 
 
 __all__ = [
 __all__ = [

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

@@ -1,3 +1,3 @@
-from misago.users.serializers.ban import *
-from misago.users.serializers.rank import *
-from misago.users.serializers.user import *
+from .ban import *
+from .rank import *
+from .user import *

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

@@ -3,7 +3,8 @@ from django.utils.translation import ugettext as _
 from rest_framework import serializers
 from rest_framework import serializers
 
 
 from misago.core.utils import format_plaintext_for_html
 from misago.core.utils import format_plaintext_for_html
-from misago.users.models import BAN_IP, Ban
+
+from ..models import BAN_IP, Ban
 
 
 
 
 __all__ = [
 __all__ = [

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

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

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

@@ -4,7 +4,8 @@ from django.core.urlresolvers import reverse
 from rest_framework import serializers
 from rest_framework import serializers
 
 
 from misago.acl import serialize_acl
 from misago.acl import serialize_acl
-from misago.users.serializers import RankSerializer
+
+from . import RankSerializer
 
 
 
 
 __all__ = [
 __all__ = [

+ 2 - 2
misago/users/serializers/usernamechange.py

@@ -1,7 +1,7 @@
 from rest_framework import serializers
 from rest_framework import serializers
 
 
-from misago.users.models import UsernameChange
-from misago.users.serializers.user import BasicUserSerializer
+from ..models import UsernameChange
+from .user import BasicUserSerializer
 
 
 
 
 __all__ = ['UsernameChangeSerializer']
 __all__ = ['UsernameChangeSerializer']

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

@@ -2,8 +2,8 @@ from django.contrib.auth import get_user_model
 from django.core.urlresolvers import reverse
 from django.core.urlresolvers import reverse
 from django.test import TestCase
 from django.test import TestCase
 
 
-from misago.users.models import BAN_USERNAME, Ban
-from misago.users.tokens import make_activation_token
+from ..models import BAN_USERNAME, Ban
+from ..tokens import make_activation_token
 
 
 
 
 class ActivationViewsTests(TestCase):
 class ActivationViewsTests(TestCase):

+ 3 - 2
misago/users/tests/test_activepostersranking.py

@@ -4,8 +4,9 @@ from misago.categories.models import Category
 from misago.core import threadstore
 from misago.core import threadstore
 from misago.core.cache import cache
 from misago.core.cache import cache
 from misago.threads.testutils import post_thread
 from misago.threads.testutils import post_thread
-from misago.users.activepostersranking import build_active_posters_ranking, get_active_posters_ranking
-from misago.users.testutils import AuthenticatedUserTestCase
+
+from ..activepostersranking import build_active_posters_ranking, get_active_posters_ranking
+from ..testutils import AuthenticatedUserTestCase
 
 
 
 
 class TestActivePostersRanking(AuthenticatedUserTestCase):
 class TestActivePostersRanking(AuthenticatedUserTestCase):

+ 2 - 2
misago/users/tests/test_auth_api.py

@@ -4,8 +4,8 @@ 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_USERNAME, Ban
-from misago.users.tokens import make_activation_token, make_password_change_token
+from ..models import BAN_USERNAME, Ban
+from ..tokens import make_activation_token, make_password_change_token
 
 
 
 
 class GatewayTests(TestCase):
 class GatewayTests(TestCase):

+ 2 - 1
misago/users/tests/test_avatars.py

@@ -6,7 +6,8 @@ from django.core.exceptions import ValidationError
 from django.test import TestCase
 from django.test import TestCase
 
 
 from misago.conf import settings
 from misago.conf import settings
-from misago.users.avatars import dynamic, gallery, gravatar, store, uploaded
+
+from ..avatars import dynamic, gallery, gravatar, store, uploaded
 
 
 
 
 class AvatarsStoreTests(TestCase):
 class AvatarsStoreTests(TestCase):

+ 1 - 1
misago/users/tests/test_avatarserver_views.py

@@ -3,7 +3,7 @@ from django.contrib.auth import get_user_model
 from django.core.urlresolvers import reverse
 from django.core.urlresolvers import reverse
 from django.test import TestCase
 from django.test import TestCase
 
 
-from misago.users.views.avatarserver import clean_size
+from ..views.avatarserver import clean_size
 
 
 
 
 class AvatarServerTests(TestCase):
 class AvatarServerTests(TestCase):

+ 1 - 1
misago/users/tests/test_ban_model.py

@@ -1,7 +1,7 @@
 #-*- coding: utf-8 -*-
 #-*- coding: utf-8 -*-
 from django.test import TestCase
 from django.test import TestCase
 
 
-from misago.users.models import BAN_EMAIL, BAN_IP, BAN_USERNAME, Ban
+from ..models import BAN_EMAIL, BAN_IP, BAN_USERNAME, Ban
 
 
 
 
 class BansManagerTests(TestCase):
 class BansManagerTests(TestCase):

+ 2 - 1
misago/users/tests/test_banadmin_views.py

@@ -3,7 +3,8 @@ from datetime import date, datetime, timedelta
 from django.core.urlresolvers import reverse
 from django.core.urlresolvers import reverse
 
 
 from misago.admin.testutils import AdminTestCase
 from misago.admin.testutils import AdminTestCase
-from misago.users.models import Ban
+
+from ..models import Ban
 
 
 
 
 class BanAdminViewsTests(AdminTestCase):
 class BanAdminViewsTests(AdminTestCase):

+ 2 - 10
misago/users/tests/test_bans.py

@@ -4,16 +4,8 @@ from django.contrib.auth import get_user_model
 from django.test import TestCase
 from django.test import TestCase
 from django.utils import timezone
 from django.utils import timezone
 
 
-from misago.users.bans import (
-    ban_ip,
-    ban_user,
-    get_email_ban,
-    get_ip_ban,
-    get_request_ip_ban,
-    get_user_ban,
-    get_username_ban
-)
-from misago.users.models import BAN_EMAIL, BAN_IP, BAN_USERNAME, Ban
+from ..bans import ban_ip, ban_user, get_email_ban, get_ip_ban, get_request_ip_ban, get_user_ban, get_username_ban
+from ..models import BAN_EMAIL, BAN_IP, BAN_USERNAME, Ban
 
 
 
 
 class GetBanTests(TestCase):
 class GetBanTests(TestCase):

+ 3 - 3
misago/users/tests/test_bansmaintenance.py

@@ -5,9 +5,9 @@ from django.test import TestCase
 from django.utils import timezone
 from django.utils import timezone
 from django.utils.six import StringIO
 from django.utils.six import StringIO
 
 
-from misago.users import bans
-from misago.users.management.commands import bansmaintenance
-from misago.users.models import Ban, BanCache
+from .. import bans
+from ..management.commands import bansmaintenance
+from ..models import Ban, BanCache
 
 
 
 
 class BansMaintenanceTests(TestCase):
 class BansMaintenanceTests(TestCase):

+ 1 - 1
misago/users/tests/test_commands.py

@@ -1,7 +1,7 @@
 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.models import User
+from ..models import User
 
 
 
 
 class CreateSuperUserTests(TestCase):
 class CreateSuperUserTests(TestCase):

+ 1 - 1
misago/users/tests/test_credentialchange.py

@@ -1,7 +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 import credentialchange
+from .. import credentialchange
 
 
 
 
 class MockRequest(object):
 class MockRequest(object):

+ 2 - 2
misago/users/tests/test_decorators.py

@@ -1,7 +1,7 @@
 from django.core.urlresolvers import reverse
 from django.core.urlresolvers import reverse
 
 
-from misago.users.models import BAN_IP, Ban
-from misago.users.testutils import UserTestCase
+from ..models import BAN_IP, Ban
+from ..testutils import UserTestCase
 
 
 
 
 class DenyAuthenticatedTests(UserTestCase):
 class DenyAuthenticatedTests(UserTestCase):

+ 3 - 3
misago/users/tests/test_forgottenpassword_views.py

@@ -1,9 +1,9 @@
 from django.contrib.auth import get_user_model
 from django.contrib.auth import get_user_model
 from django.core.urlresolvers import reverse
 from django.core.urlresolvers import reverse
 
 
-from misago.users.models import BAN_USERNAME, Ban
-from misago.users.testutils import UserTestCase
-from misago.users.tokens import make_password_change_token
+from ..models import BAN_USERNAME, Ban
+from ..testutils import UserTestCase
+from ..tokens import make_password_change_token
 
 
 
 
 class ForgottenPasswordViewsTests(UserTestCase):
 class ForgottenPasswordViewsTests(UserTestCase):

+ 3 - 2
misago/users/tests/test_lists_views.py

@@ -2,8 +2,9 @@ from django.contrib.auth import get_user_model
 from django.core.urlresolvers import reverse
 from django.core.urlresolvers import reverse
 
 
 from misago.acl.testutils import override_acl
 from misago.acl.testutils import override_acl
-from misago.users.models import Rank
-from misago.users.testutils import AuthenticatedUserTestCase
+
+from ..models import Rank
+from ..testutils import AuthenticatedUserTestCase
 
 
 
 
 class UsersListTestCase(AuthenticatedUserTestCase):
 class UsersListTestCase(AuthenticatedUserTestCase):

+ 1 - 1
misago/users/tests/test_namechanges.py

@@ -1,7 +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.namechanges import UsernameChanges
+from ..namechanges import UsernameChanges
 
 
 
 
 class UsernameChangesTests(TestCase):
 class UsernameChangesTests(TestCase):

+ 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.core.urlresolvers import reverse
 from django.core.urlresolvers import reverse
 
 
-from misago.users.testutils import AuthenticatedUserTestCase
+from ..testutils import AuthenticatedUserTestCase
 
 
 
 
 class OptionsViewsTests(AuthenticatedUserTestCase):
 class OptionsViewsTests(AuthenticatedUserTestCase):

+ 2 - 2
misago/users/tests/test_populateonlinetracker.py

@@ -2,8 +2,8 @@ from django.contrib.auth import get_user_model
 from django.test import TestCase
 from django.test import TestCase
 from django.utils.six import StringIO
 from django.utils.six import StringIO
 
 
-from misago.users.management.commands import populateonlinetracker
-from misago.users.models import Online
+from ..management.commands import populateonlinetracker
+from ..models import Online
 
 
 
 
 class PopulateOnlineTrackerTests(TestCase):
 class PopulateOnlineTrackerTests(TestCase):

+ 3 - 2
misago/users/tests/test_profile_views.py

@@ -2,8 +2,9 @@ from django.contrib.auth import get_user_model
 from django.core.urlresolvers import reverse
 from django.core.urlresolvers import reverse
 
 
 from misago.acl.testutils import override_acl
 from misago.acl.testutils import override_acl
-from misago.users.models import Ban
-from misago.users.testutils import AuthenticatedUserTestCase
+
+from ..models import Ban
+from ..testutils import AuthenticatedUserTestCase
 
 
 
 
 class UserProfileViewsTests(AuthenticatedUserTestCase):
 class UserProfileViewsTests(AuthenticatedUserTestCase):

+ 2 - 1
misago/users/tests/test_rankadmin_views.py

@@ -2,7 +2,8 @@ from django.core.urlresolvers import reverse
 
 
 from misago.acl.models import Role
 from misago.acl.models import Role
 from misago.admin.testutils import AdminTestCase
 from misago.admin.testutils import AdminTestCase
-from misago.users.models import Rank
+
+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):

+ 2 - 2
misago/users/tests/test_rest_permissions.py

@@ -1,7 +1,7 @@
 from django.core.urlresolvers import reverse
 from django.core.urlresolvers import reverse
 
 
-from misago.users.models import BAN_IP, Ban
-from misago.users.testutils import UserTestCase
+from ..models import BAN_IP, Ban
+from ..testutils import UserTestCase
 
 
 
 
 class UnbannedOnlyTests(UserTestCase):
 class UnbannedOnlyTests(UserTestCase):

+ 1 - 1
misago/users/tests/test_signatures.py

@@ -1,7 +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 import signatures
+from .. import signatures
 
 
 
 
 class MockRequest(object):
 class MockRequest(object):

+ 1 - 1
misago/users/tests/test_testutils.py

@@ -2,7 +2,7 @@ import json
 
 
 from django.core.urlresolvers import reverse
 from django.core.urlresolvers import reverse
 
 
-from misago.users.testutils import AuthenticatedUserTestCase, SuperUserTestCase, UserTestCase
+from ..testutils import AuthenticatedUserTestCase, SuperUserTestCase, UserTestCase
 
 
 
 
 class UserTestCaseTests(UserTestCase):
 class UserTestCaseTests(UserTestCase):

+ 1 - 1
misago/users/tests/test_tokens.py

@@ -1,7 +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 import tokens
+from .. import tokens
 
 
 
 
 class TokensTests(TestCase):
 class TokensTests(TestCase):

+ 1 - 1
misago/users/tests/test_updateblankavatar.py

@@ -1,7 +1,7 @@
 from django.test import TestCase
 from django.test import TestCase
 from django.utils.six import StringIO
 from django.utils.six import StringIO
 
 
-from misago.users.management.commands import updateblankavatar
+from ..management.commands import updateblankavatar
 
 
 
 
 class UpdateBlankAvatarTests(TestCase):
 class UpdateBlankAvatarTests(TestCase):

+ 3 - 2
misago/users/tests/test_user_avatar_api.py

@@ -7,8 +7,9 @@ from django.core.urlresolvers import reverse
 
 
 from misago.acl.testutils import override_acl
 from misago.acl.testutils import override_acl
 from misago.conf import settings
 from misago.conf import settings
-from misago.users.avatars import store
-from misago.users.testutils import AuthenticatedUserTestCase
+
+from ..avatars import store
+from ..testutils import AuthenticatedUserTestCase
 
 
 
 
 class UserAvatarTests(AuthenticatedUserTestCase):
 class UserAvatarTests(AuthenticatedUserTestCase):

+ 1 - 1
misago/users/tests/test_user_changeemail_api.py

@@ -1,7 +1,7 @@
 from django.contrib.auth import get_user_model
 from django.contrib.auth import get_user_model
 from django.core import mail
 from django.core import mail
 
 
-from misago.users.testutils import AuthenticatedUserTestCase
+from ..testutils import AuthenticatedUserTestCase
 
 
 
 
 class UserChangeEmailTests(AuthenticatedUserTestCase):
 class UserChangeEmailTests(AuthenticatedUserTestCase):

+ 1 - 1
misago/users/tests/test_user_changepassword_api.py

@@ -1,7 +1,7 @@
 from django.contrib.auth import get_user_model
 from django.contrib.auth import get_user_model
 from django.core import mail
 from django.core import mail
 
 
-from misago.users.testutils import AuthenticatedUserTestCase
+from ..testutils import AuthenticatedUserTestCase
 
 
 
 
 class UserChangePasswordTests(AuthenticatedUserTestCase):
 class UserChangePasswordTests(AuthenticatedUserTestCase):

+ 3 - 2
misago/users/tests/test_user_create_api.py

@@ -3,8 +3,9 @@ from django.core import mail
 from django.core.urlresolvers import reverse
 from django.core.urlresolvers import reverse
 
 
 from misago.conf import settings
 from misago.conf import settings
-from misago.users.models import Online
-from misago.users.testutils import UserTestCase
+
+from ..models import Online
+from ..testutils import UserTestCase
 
 
 
 
 class UserCreateTests(UserTestCase):
 class UserCreateTests(UserTestCase):

+ 1 - 1
misago/users/tests/test_user_model.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.users.models import User
+from ..models import User
 
 
 
 
 class UserManagerTests(TestCase):
 class UserManagerTests(TestCase):

+ 2 - 1
misago/users/tests/test_user_signature_api.py

@@ -4,7 +4,8 @@ from django.contrib.auth import get_user_model
 
 
 from misago.acl.testutils import override_acl
 from misago.acl.testutils import override_acl
 from misago.conf import settings
 from misago.conf import settings
-from misago.users.testutils import AuthenticatedUserTestCase
+
+from ..testutils import AuthenticatedUserTestCase
 
 
 
 
 class UserSignatureTests(AuthenticatedUserTestCase):
 class UserSignatureTests(AuthenticatedUserTestCase):

+ 2 - 1
misago/users/tests/test_user_username_api.py

@@ -4,7 +4,8 @@ from django.contrib.auth import get_user_model
 
 
 from misago.acl.testutils import override_acl
 from misago.acl.testutils import override_acl
 from misago.conf import settings
 from misago.conf import settings
-from misago.users.testutils import AuthenticatedUserTestCase
+
+from ..testutils import AuthenticatedUserTestCase
 
 
 
 
 class UserUsernameTests(AuthenticatedUserTestCase):
 class UserUsernameTests(AuthenticatedUserTestCase):

+ 2 - 1
misago/users/tests/test_useradmin_views.py

@@ -8,7 +8,8 @@ from misago.acl.models import Role
 from misago.admin.testutils import AdminTestCase
 from misago.admin.testutils import AdminTestCase
 from misago.categories.models import Category
 from misago.categories.models import Category
 from misago.threads.testutils import post_thread, reply_thread
 from misago.threads.testutils import post_thread, reply_thread
-from misago.users.models import Ban, Rank
+
+from ..models import Ban, Rank
 
 
 
 
 class UserAdminViewsTests(AdminTestCase):
 class UserAdminViewsTests(AdminTestCase):

+ 2 - 1
misago/users/tests/test_usernamechanges_api.py

@@ -1,7 +1,8 @@
 from django.contrib.auth import get_user_model
 from django.contrib.auth import get_user_model
 
 
 from misago.acl.testutils import override_acl
 from misago.acl.testutils import override_acl
-from misago.users.testutils import AuthenticatedUserTestCase
+
+from ..testutils import AuthenticatedUserTestCase
 
 
 
 
 class UsernameChangesApiTests(AuthenticatedUserTestCase):
 class UsernameChangesApiTests(AuthenticatedUserTestCase):

+ 4 - 3
misago/users/tests/test_users_api.py

@@ -10,9 +10,10 @@ from misago.core import threadstore
 from misago.core.cache import cache
 from misago.core.cache import cache
 from misago.threads.models import Post, Thread
 from misago.threads.models import Post, Thread
 from misago.threads.testutils import post_thread
 from misago.threads.testutils import post_thread
-from misago.users.activepostersranking import build_active_posters_ranking
-from misago.users.models import BAN_USERNAME, Ban, Rank
-from misago.users.testutils import AuthenticatedUserTestCase
+
+from ..activepostersranking import build_active_posters_ranking
+from ..models import BAN_USERNAME, Ban, Rank
+from ..testutils import AuthenticatedUserTestCase
 
 
 
 
 class ActivePostersListTests(AuthenticatedUserTestCase):
 class ActivePostersListTests(AuthenticatedUserTestCase):

+ 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 UserModelTests(TestCase):
 class UserModelTests(TestCase):

+ 3 - 2
misago/users/tests/test_validators.py

@@ -4,8 +4,9 @@ from django.core.exceptions import PermissionDenied, ValidationError
 from django.test import TestCase
 from django.test import TestCase
 
 
 from misago.conf import settings
 from misago.conf import settings
-from misago.users.models import BAN_EMAIL, BAN_USERNAME, Ban
-from misago.users.validators import (
+
+from ..models import BAN_EMAIL, BAN_USERNAME, Ban
+from ..validators import (
     validate_email,
     validate_email,
     validate_email_available,
     validate_email_available,
     validate_email_banned,
     validate_email_banned,

+ 2 - 1
misago/users/tests/test_warningadmin_views.py

@@ -1,7 +1,8 @@
 from django.core.urlresolvers import reverse
 from django.core.urlresolvers import reverse
 
 
 from misago.admin.testutils import AdminTestCase
 from misago.admin.testutils import AdminTestCase
-from misago.users.models import WarningLevel
+
+from ..models import WarningLevel
 
 
 
 
 class WarningsAdminViewsTests(AdminTestCase):
 class WarningsAdminViewsTests(AdminTestCase):

+ 3 - 2
misago/users/tests/test_warnings.py

@@ -6,8 +6,9 @@ from django.utils import timezone
 
 
 from misago.core import threadstore
 from misago.core import threadstore
 from misago.core.cache import cache
 from misago.core.cache import cache
-from misago.users import warnings
-from misago.users.models import UserWarning, WarningLevel
+
+from .. import warnings
+from ..models import UserWarning, WarningLevel
 
 
 
 
 class WarningsTests(TestCase):
 class WarningsTests(TestCase):

+ 2 - 1
misago/users/testutils.py

@@ -2,7 +2,8 @@ from django.contrib.auth import get_user_model
 from django.core.urlresolvers import reverse
 from django.core.urlresolvers import reverse
 
 
 from misago.core.testutils import MisagoTestCase
 from misago.core.testutils import MisagoTestCase
-from misago.users.models import AnonymousUser
+
+from .models import AnonymousUser
 
 
 
 
 class UserTestCase(MisagoTestCase):
 class UserTestCase(MisagoTestCase):

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

@@ -1,6 +1,6 @@
 from django.conf.urls import include, url
 from django.conf.urls import include, url
 from misago.core.views import home_redirect
 from misago.core.views import home_redirect
-from misago.users.views import activation, auth, avatarserver, forgottenpassword, lists, options, profile
+from ..views import activation, auth, avatarserver, forgottenpassword, lists, options, profile
 
 
 
 
 urlpatterns = [
 urlpatterns = [

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

@@ -1,10 +1,11 @@
 from django.conf.urls import url
 from django.conf.urls import url
 
 
 from misago.core.apirouter import MisagoApiRouter
 from misago.core.apirouter import MisagoApiRouter
-from misago.users.api import auth, captcha
-from misago.users.api.ranks import RanksViewSet
-from misago.users.api.usernamechanges import UsernameChangesViewSet
-from misago.users.api.users import UserViewSet
+
+from ..api import auth, captcha
+from ..api.ranks import RanksViewSet
+from ..api.usernamechanges import UsernameChangesViewSet
+from ..api.users import UserViewSet
 
 
 
 
 urlpatterns = [
 urlpatterns = [

+ 2 - 1
misago/users/validators.py

@@ -11,7 +11,8 @@ from django.utils.translation import ugettext_lazy as _
 from django.utils.translation import ungettext
 from django.utils.translation import ungettext
 
 
 from misago.conf import settings
 from misago.conf import settings
-from misago.users.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)

+ 5 - 4
misago/users/views/activation.py

@@ -6,10 +6,11 @@ from django.utils.translation import ugettext as _
 from misago.conf import settings
 from misago.conf import settings
 from misago.core.exceptions import Banned
 from misago.core.exceptions import Banned
 from misago.core.mail import mail_user
 from misago.core.mail import mail_user
-from misago.users.bans import get_user_ban
-from misago.users.decorators import deny_authenticated, deny_banned_ips
-from misago.users.models import ACTIVATION_REQUIRED_NONE
-from misago.users.tokens import is_activation_token_valid
+
+from ..bans import get_user_ban
+from ..decorators import deny_authenticated, deny_banned_ips
+from ..models import ACTIVATION_REQUIRED_NONE
+from ..tokens import is_activation_token_valid
 
 
 
 
 def activation_view(f):
 def activation_view(f):

+ 3 - 2
misago/users/views/admin/bans.py

@@ -2,8 +2,9 @@ from django.contrib import messages
 from django.utils.translation import ugettext_lazy as _
 from django.utils.translation import ugettext_lazy as _
 
 
 from misago.admin.views import generic
 from misago.admin.views import generic
-from misago.users.forms.admin import BanForm, SearchBansForm
-from misago.users.models import Ban
+
+from ...forms.admin import BanForm, SearchBansForm
+from ...models import Ban
 
 
 
 
 class BanAdmin(generic.AdminBaseMixin):
 class BanAdmin(generic.AdminBaseMixin):

+ 3 - 2
misago/users/views/admin/ranks.py

@@ -4,8 +4,9 @@ from django.shortcuts import redirect
 from django.utils.translation import ugettext_lazy as _
 from django.utils.translation import ugettext_lazy as _
 
 
 from misago.admin.views import generic
 from misago.admin.views import generic
-from misago.users.forms.admin import RankForm
-from misago.users.models import Rank
+
+from ...forms.admin import RankForm
+from ...models import Rank
 
 
 
 
 class RankAdmin(generic.AdminBaseMixin):
 class RankAdmin(generic.AdminBaseMixin):

+ 6 - 5
misago/users/views/admin/users.py

@@ -12,11 +12,12 @@ from misago.conf import settings
 from misago.core.mail import mail_users
 from misago.core.mail import mail_users
 from misago.core.pgutils import batch_update
 from misago.core.pgutils import batch_update
 from misago.threads.models import Thread
 from misago.threads.models import Thread
-from misago.users.avatars.dynamic import set_avatar as set_dynamic_avatar
-from misago.users.forms.admin import BanUsersForm, EditUserForm, NewUserForm, SearchUsersForm, StaffFlagUserFormFactory
-from misago.users.models import ACTIVATION_REQUIRED_NONE, Ban, User
-from misago.users.models.ban import BAN_EMAIL, BAN_IP, BAN_USERNAME
-from misago.users.signatures import set_user_signature
+
+from ...avatars.dynamic import set_avatar as set_dynamic_avatar
+from ...forms.admin import BanUsersForm, EditUserForm, NewUserForm, SearchUsersForm, StaffFlagUserFormFactory
+from ...models import ACTIVATION_REQUIRED_NONE, Ban, User
+from ...models.ban import BAN_EMAIL, BAN_IP, BAN_USERNAME
+from ...signatures import set_user_signature
 
 
 
 
 class UserAdmin(generic.AdminBaseMixin):
 class UserAdmin(generic.AdminBaseMixin):

+ 3 - 2
misago/users/views/admin/warnings.py

@@ -2,8 +2,9 @@ from django.contrib import messages
 from django.utils.translation import ugettext_lazy as _
 from django.utils.translation import ugettext_lazy as _
 
 
 from misago.admin.views import generic
 from misago.admin.views import generic
-from misago.users.forms.admin import WarningLevelForm
-from misago.users.models import WarningLevel
+
+from ...forms.admin import WarningLevelForm
+from ...models import WarningLevel
 
 
 
 
 class WarningsAdmin(generic.AdminBaseMixin):
 class WarningsAdmin(generic.AdminBaseMixin):

+ 2 - 1
misago/users/views/avatarserver.py

@@ -7,7 +7,8 @@ from django.contrib.auth import get_user_model
 from django.views.decorators.cache import cache_control, never_cache
 from django.views.decorators.cache import cache_control, never_cache
 
 
 from misago.core.fileserver import make_file_response
 from misago.core.fileserver import make_file_response
-from misago.users.avatars import store
+
+from ..avatars import store
 
 
 
 
 @cache_control(private=True, must_revalidate=True, max_age=5 * 24 * 3600)
 @cache_control(private=True, must_revalidate=True, max_age=5 * 24 * 3600)

+ 4 - 3
misago/users/views/forgottenpassword.py

@@ -4,9 +4,10 @@ from django.shortcuts import get_object_or_404, render
 from django.utils.translation import ugettext as _
 from django.utils.translation import ugettext as _
 
 
 from misago.core.exceptions import Banned
 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 ..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):

+ 6 - 5
misago/users/views/lists.py

@@ -6,11 +6,12 @@ from django.shortcuts import redirect
 
 
 from misago.core.shortcuts import get_object_or_404, paginate, pagination_dict
 from misago.core.shortcuts import get_object_or_404, paginate, pagination_dict
 from misago.core.utils import format_plaintext_for_html
 from misago.core.utils import format_plaintext_for_html
-from misago.users.activepostersranking import get_active_posters_ranking
-from misago.users.models import Rank
-from misago.users.pages import users_list
-from misago.users.permissions.profiles import allow_browse_users_list
-from misago.users.serializers import ScoredUserSerializer, UserSerializer
+
+from ..activepostersranking import get_active_posters_ranking
+from ..models import Rank
+from ..pages import users_list
+from ..permissions.profiles import allow_browse_users_list
+from ..serializers import ScoredUserSerializer, UserSerializer
 
 
 
 
 def render(request, template, context):
 def render(request, template, context):

+ 3 - 3
misago/users/views/options.py

@@ -4,9 +4,9 @@ from django.db import IntegrityError
 from django.shortcuts import render
 from django.shortcuts import render
 from django.utils.translation import ugettext as _
 from django.utils.translation import ugettext 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

+ 9 - 8
misago/users/views/profile.py

@@ -14,14 +14,15 @@ from misago.core.decorators import require_POST
 from misago.core.shortcuts import get_object_or_404, paginate, pagination_dict, validate_slug
 from misago.core.shortcuts import get_object_or_404, paginate, pagination_dict, validate_slug
 from misago.core.utils import clean_return_path
 from misago.core.utils import clean_return_path
 from misago.threads.permissions import allow_message_user
 from misago.threads.permissions import allow_message_user
-from misago.users.bans import get_user_ban
-from misago.users.decorators import deny_guests
-from misago.users.online.utils import get_user_status
-from misago.users.pages import user_profile
-from misago.users.permissions.profiles import allow_block_user, allow_follow_user
-from misago.users.serializers import BanDetailsSerializer, UserProfileSerializer, UserSerializer
-from misago.users.serializers.usernamechange import UsernameChangeSerializer
-from misago.users.warnings import get_user_warning_level, get_user_warning_obj, get_warning_levels
+
+from ..bans import get_user_ban
+from ..decorators import deny_guests
+from ..online.utils import get_user_status
+from ..pages import user_profile
+from ..permissions.profiles import allow_block_user, allow_follow_user
+from ..serializers import BanDetailsSerializer, UserProfileSerializer, UserSerializer
+from ..serializers.usernamechange import UsernameChangeSerializer
+from ..warnings import get_user_warning_level, get_user_warning_obj, get_warning_levels
 
 
 
 
 def profile_view(f):
 def profile_view(f):

+ 1 - 1
misago/users/warnings.py

@@ -2,7 +2,7 @@ from datetime import timedelta
 
 
 from django.utils import timezone
 from django.utils import timezone
 
 
-from misago.users.models import WarningLevel
+from .models import WarningLevel
 
 
 
 
 def get_warning_levels():
 def get_warning_levels():