createfakethreads.py 7.0 KB

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