createfakethreads.py 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. from __future__ import unicode_literals
  2. import random
  3. import time
  4. from faker import Factory
  5. from django.contrib.auth import get_user_model
  6. from django.core.management.base import BaseCommand
  7. from django.db.transaction import atomic
  8. from django.utils import timezone
  9. from misago.categories.models import Category
  10. from misago.core.management.progressbar import show_progress
  11. from misago.faker.englishcorpus import EnglishCorpus
  12. from misago.threads.checksums import update_post_checksum
  13. from misago.threads.models import Post, Thread
  14. PLACEKITTEN_URL = 'https://placekitten.com/g/%s/%s'
  15. UserModel = get_user_model()
  16. corpus = EnglishCorpus()
  17. corpus_short = EnglishCorpus(max_length=150)
  18. class Command(BaseCommand):
  19. help = 'Creates random threads and posts for dev and testing purposes.'
  20. def add_arguments(self, parser):
  21. parser.add_argument(
  22. 'threads', help="number of threads to create", nargs='?', type=int, default=5
  23. )
  24. def handle(self, *args, **options):
  25. items_to_create = options['threads']
  26. categories = list(Category.objects.all_categories())
  27. fake = Factory.create()
  28. self.stdout.write('Creating fake threads...\n')
  29. message = '\nSuccessfully created %s fake threads in %s'
  30. created_threads = 0
  31. start_time = time.time()
  32. show_progress(self, created_threads, items_to_create)
  33. while created_threads < items_to_create:
  34. with atomic():
  35. datetime = timezone.now()
  36. category = random.choice(categories)
  37. user = UserModel.objects.order_by('?')[:1][0]
  38. thread_is_unapproved = random.randint(0, 100) > 90
  39. thread_is_hidden = random.randint(0, 100) > 90
  40. thread_is_closed = random.randint(0, 100) > 90
  41. thread = Thread(
  42. category=category,
  43. started_on=datetime,
  44. starter_name='-',
  45. starter_slug='-',
  46. last_post_on=datetime,
  47. last_poster_name='-',
  48. last_poster_slug='-',
  49. replies=0,
  50. is_unapproved=thread_is_unapproved,
  51. is_hidden=thread_is_hidden,
  52. is_closed=thread_is_closed
  53. )
  54. thread.set_title(corpus_short.random_choice())
  55. thread.save()
  56. original, parsed = self.fake_post_content()
  57. post = Post.objects.create(
  58. category=category,
  59. thread=thread,
  60. poster=user,
  61. poster_name=user.username,
  62. poster_ip=fake.ipv4(),
  63. original=original,
  64. parsed=parsed,
  65. posted_on=datetime,
  66. updated_on=datetime
  67. )
  68. update_post_checksum(post)
  69. post.save(update_fields=['checksum'])
  70. thread.set_first_post(post)
  71. thread.set_last_post(post)
  72. thread.save()
  73. user.threads += 1
  74. user.posts += 1
  75. user.save()
  76. thread_type = random.randint(0, 100)
  77. if thread_type > 98:
  78. thread_replies = random.randint(200, 2500)
  79. elif thread_type > 50:
  80. thread_replies = random.randint(5, 30)
  81. else:
  82. thread_replies = random.randint(0, 10)
  83. for _ in range(thread_replies):
  84. datetime = timezone.now()
  85. user = UserModel.objects.order_by('?')[:1][0]
  86. original, parsed = self.fake_post_content()
  87. is_unapproved = random.randint(0, 100) > 97
  88. post = Post.objects.create(
  89. category=category,
  90. thread=thread,
  91. poster=user,
  92. poster_name=user.username,
  93. poster_ip=fake.ipv4(),
  94. original=original,
  95. parsed=parsed,
  96. is_unapproved=is_unapproved,
  97. posted_on=datetime,
  98. updated_on=datetime
  99. )
  100. if not is_unapproved:
  101. is_hidden = random.randint(0, 100) > 97
  102. else:
  103. is_hidden = False
  104. if is_hidden:
  105. post.is_hidden = True
  106. if random.randint(0, 100) < 80:
  107. user = UserModel.objects.order_by('?')[:1][0]
  108. post.hidden_by = user
  109. post.hidden_by_name = user.username
  110. post.hidden_by_slug = user.username
  111. else:
  112. post.hidden_by_name = fake.first_name()
  113. post.hidden_by_slug = post.hidden_by_name.lower()
  114. update_post_checksum(post)
  115. post.save()
  116. user.posts += 1
  117. user.save()
  118. thread.synchronize()
  119. thread.save()
  120. created_threads += 1
  121. show_progress(self, created_threads, items_to_create, start_time)
  122. pinned_threads = random.randint(0, int(created_threads * 0.025)) or 1
  123. self.stdout.write('\nPinning %s threads...' % pinned_threads)
  124. for _ in range(0, pinned_threads):
  125. thread = Thread.objects.order_by('?')[:1][0]
  126. if random.randint(0, 100) > 75:
  127. thread.weight = 2
  128. else:
  129. thread.weight = 1
  130. thread.save()
  131. for category in categories:
  132. category.synchronize()
  133. category.save()
  134. total_time = time.time() - start_time
  135. total_humanized = time.strftime('%H:%M:%S', time.gmtime(total_time))
  136. self.stdout.write(message % (created_threads, total_humanized))
  137. def fake_post_content(self):
  138. raw = []
  139. parsed = []
  140. if random.randint(0, 100) > 80:
  141. paragraphs_to_make = random.randint(1, 20)
  142. else:
  143. paragraphs_to_make = random.randint(1, 5)
  144. for _ in range(paragraphs_to_make):
  145. if random.randint(0, 100) > 95:
  146. cat_width = random.randint(1, 16) * random.choice([100, 90, 80])
  147. cat_height = random.randint(1, 12) * random.choice([100, 90, 80])
  148. cat_url = PLACEKITTEN_URL % (cat_width, cat_height)
  149. raw.append('!(%s)' % cat_url)
  150. parsed.append('<p><img src="%s" alt=""/></p>' % cat_url)
  151. else:
  152. if random.randint(0, 100) > 95:
  153. sentences_to_make = random.randint(1, 20)
  154. else:
  155. sentences_to_make = random.randint(1, 7)
  156. raw.append(' '.join(corpus.random_sentences(sentences_to_make)))
  157. parsed.append('<p>%s</p>' % raw[-1])
  158. return "\n\n".join(raw), "\n".join(parsed)