threads.py 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. from __future__ import unicode_literals
  2. from django.contrib.auth import get_user_model
  3. from django.utils import timezone
  4. from misago.categories.models import Category
  5. from misago.threads.checksums import update_post_checksum
  6. from misago.threads.models import Thread, Post, PostEdit, PostLike
  7. from . import fetch_assoc, markup, movedids, localise_datetime
  8. UserModel = get_user_model()
  9. def move_threads(stdout, style):
  10. special_categories = get_special_categories_dict()
  11. for thread in fetch_assoc('SELECT * FROM misago_thread ORDER BY id'):
  12. if special_categories.get(thread['forum_id']) == 'reports':
  13. stdout.write(style.WARNING(
  14. "Skipping report: %s" % thread['name']))
  15. continue
  16. if not thread['start_post_id']:
  17. stdout.write(style.ERROR(
  18. "Corrupted thread: %s" % thread['name']))
  19. continue
  20. if special_categories.get(thread['forum_id']) == 'private_threads':
  21. category = Category.objects.private_threads()
  22. else:
  23. if thread['prefix_id']:
  24. label_id = '%s-%s' % (thread['prefix_id'], thread['forum_id'])
  25. category_pk = movedids.get('label', label_id)
  26. else:
  27. category_pk = movedids.get('category', thread['forum_id'])
  28. category = Category.objects.get(pk=category_pk)
  29. new_thread = Thread.objects.create(
  30. category=category,
  31. title=thread['name'],
  32. slug=thread['slug'],
  33. started_on=timezone.now(),
  34. last_post_on=timezone.now(),
  35. starter_name='none',
  36. starter_slug='none',
  37. weight=thread['weight'],
  38. is_hidden=thread['deleted'],
  39. is_closed=thread['closed'],
  40. )
  41. movedids.set('thread', thread['id'], new_thread.pk)
  42. def move_posts():
  43. special_categories = get_special_categories_dict()
  44. for post in fetch_assoc('SELECT * FROM misago_post ORDER BY id'):
  45. if special_categories.get(post['forum_id']) == 'reports':
  46. continue
  47. thread_pk = movedids.get('thread', post['thread_id'])
  48. thread = Thread.objects.select_related('category').get(pk=thread_pk)
  49. poster = None
  50. last_editor = None
  51. if post['user_id']:
  52. poster_id = movedids.get('user', post['user_id'])
  53. poster = UserModel.objects.get(pk=poster_id)
  54. if post['edit_user_id']:
  55. last_editor_id = movedids.get('user', post['edit_user_id'])
  56. last_editor = UserModel.objects.get(pk=last_editor_id)
  57. deleter = None
  58. deleter_name = None
  59. deleter_slug = None
  60. if post['deleted']:
  61. deleter = UserModel.objects.filter(
  62. is_staff=True
  63. ).order_by('id').last()
  64. if deleter:
  65. deleter_name = deleter.username
  66. deleter_slug = deleter.slug
  67. else:
  68. deleter = poster
  69. deleter_name = poster.username
  70. deleter_slug = poster.slug
  71. new_post = Post.objects.create(
  72. category=thread.category,
  73. thread=thread,
  74. poster=poster,
  75. poster_name=post['user_name'],
  76. poster_ip=post['ip'],
  77. original=markup.convert_original(post['post']),
  78. parsed=markup.convert_parsed(post['post_preparsed']),
  79. posted_on=localise_datetime(post['date']),
  80. updated_on=localise_datetime(post['current_date'] or post['date']),
  81. hidden_on=localise_datetime(post['delete_date'] or post['date']),
  82. edits=post['edits'],
  83. last_editor=last_editor,
  84. last_editor_name=post['edit_user_name'],
  85. last_editor_slug=post['edit_user_slug'],
  86. hidden_by=deleter,
  87. hidden_by_name=deleter_name,
  88. hidden_by_slug=deleter_slug,
  89. is_hidden=post['deleted'],
  90. is_protected=post['protected'],
  91. likes=post['upvotes']
  92. )
  93. update_post_checksum(new_post)
  94. new_post.save()
  95. movedids.set('post', post['id'], new_post.pk)
  96. def move_mentions():
  97. for metion in fetch_assoc('SELECT * FROM misago_post_mentions'):
  98. try:
  99. post_pk = movedids.get('post', metion['post_id'])
  100. user_pk = movedids.get('user', metion['user_id'])
  101. post = Post.objects.get(pk=post_pk)
  102. user = UserModel.objects.get(pk=user_pk)
  103. post.mentions.add(user)
  104. except:
  105. continue
  106. def move_edits():
  107. query = 'SELECT DISTINCT post_id FROM misago_change ORDER BY post_id'
  108. for edit in fetch_assoc(query):
  109. post_pk = movedids.get('post', edit['post_id'])
  110. post = Post.objects.select_related().get(pk=post_pk)
  111. move_post_edits(post, edit['post_id'])
  112. def move_post_edits(post, old_id):
  113. query = '''
  114. SELECT *
  115. FROM
  116. misago_change
  117. WHERE
  118. post_id = %s AND `change` <> 0
  119. ORDER BY
  120. id
  121. '''
  122. changelog = []
  123. for edit in fetch_assoc(query, [old_id]):
  124. if edit['user_id']:
  125. editor_pk = movedids.get('user', edit['user_id'])
  126. editor = UserModel.objects.get(pk=editor_pk)
  127. else:
  128. editor = None
  129. if changelog:
  130. changelog[-1].edited_to = edit['post_content']
  131. changelog.append(PostEdit(
  132. category=post.category,
  133. thread=post.thread,
  134. post=post,
  135. edited_on=localise_datetime(edit['date']),
  136. editor=editor,
  137. editor_name=edit['user_name'],
  138. editor_slug=edit['user_slug'],
  139. editor_ip=edit['ip'],
  140. edited_from=edit['post_content'],
  141. edited_to=post.original,
  142. ))
  143. if changelog:
  144. PostEdit.objects.bulk_create(changelog)
  145. def move_likes():
  146. query = '''
  147. SELECT *
  148. FROM
  149. misago_karma
  150. WHERE
  151. score > 0
  152. ORDER BY
  153. id
  154. '''
  155. posts = []
  156. for karma in fetch_assoc(query):
  157. post_pk = movedids.get('post', karma['post_id'])
  158. post = Post.objects.select_related().get(pk=post_pk)
  159. if karma['user_id']:
  160. liker_pk = movedids.get('user', karma['user_id'])
  161. liker = UserModel.objects.get(pk=liker_pk)
  162. else:
  163. liker = None
  164. PostLike.objects.create(
  165. category=post.category,
  166. thread=post.thread,
  167. post=post,
  168. liker=liker,
  169. liker_name=karma['user_name'],
  170. liker_slug=karma['user_slug'],
  171. liker_ip=karma['ip'],
  172. liked_on=localise_datetime(karma['date']),
  173. )
  174. posts.append(post_pk)
  175. for post in Post.objects.filter(id__in=posts).iterator():
  176. post.last_likes = []
  177. for like in post.postlike_set.all()[:4]:
  178. post.last_likes.append({
  179. 'id': like.liker_id,
  180. 'username': like.liker_name
  181. })
  182. post.save(update_fields=['last_likes'])
  183. def get_special_categories_dict():
  184. special_categories = {}
  185. query = '''
  186. SELECT
  187. id, special
  188. FROM
  189. misago_forum
  190. WHERE
  191. special IS NOT NULL
  192. '''
  193. for special in fetch_assoc(query):
  194. special_categories[special['id']] = special['special']
  195. return special_categories