createfakethreads.py 7.0 KB

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