views.py 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. import json
  2. import logging
  3. from django.conf import settings
  4. from django.contrib.auth.decorators import login_required
  5. from django.contrib.auth.mixins import LoginRequiredMixin
  6. from django.db.models import Avg, Count, F
  7. from django.http import HttpResponse
  8. from django.views.generic import DetailView, ListView
  9. from django.views.generic.list import MultipleObjectMixin
  10. from games.tasks import update_roms
  11. from .models import Developer, Game, GameCollection, GameSystem, Genre, Publisher
  12. logger = logging.Logger(__name__)
  13. class RecentGameList(LoginRequiredMixin, ListView):
  14. model = Game
  15. paginate_by = 20
  16. queryset = Game.objects.order_by("-created")[:200]
  17. class LibraryGameList(ListView, LoginRequiredMixin):
  18. template_name = "games/game_library_list.html"
  19. model = Game
  20. paginate_by = 200
  21. def get_context_data(self, **kwargs):
  22. game_system_slug = self.request.GET.get("game_system")
  23. order_by = self.request.GET.get("order_by", "name")
  24. if order_by[0] == "-":
  25. order_by = order_by[1:]
  26. object_list = Game.objects.order_by(F(order_by).desc(nulls_last=True))
  27. else:
  28. object_list = Game.objects.order_by(F(order_by).asc(nulls_last=True))
  29. if game_system_slug:
  30. object_list = object_list.filter(
  31. game_system__retropie_slug=game_system_slug
  32. )
  33. context = super(LibraryGameList, self).get_context_data(
  34. object_list=object_list, **kwargs
  35. )
  36. return context
  37. class FilterableBaseListView(ListView, LoginRequiredMixin):
  38. def get_queryset(self, **kwargs):
  39. order_by = self.request.GET.get("order_by", "name")
  40. queryset = super().get_queryset(**kwargs)
  41. queryset = queryset.annotate(num_games=Count("game")).annotate(
  42. rating=Avg("game__rating")
  43. )
  44. if order_by[0] == "-":
  45. order_by = order_by[1:]
  46. queryset = queryset.order_by(F(order_by).desc(nulls_last=True))
  47. else:
  48. queryset = queryset.order_by(F(order_by).asc(nulls_last=True))
  49. return queryset
  50. class PublisherList(FilterableBaseListView):
  51. model = Publisher
  52. class DeveloperList(FilterableBaseListView):
  53. model = Developer
  54. class GenreList(FilterableBaseListView):
  55. model = Genre
  56. class GameDetail(DetailView, LoginRequiredMixin):
  57. model = Game
  58. class GamePlayDetail(DetailView, LoginRequiredMixin):
  59. template_name = "games/game_play_detail.html"
  60. model = Game
  61. class GameSystemList(ListView, LoginRequiredMixin):
  62. model = GameSystem
  63. class GameSystemDetail(DetailView, MultipleObjectMixin, LoginRequiredMixin):
  64. model = GameSystem
  65. paginate_by = 20
  66. def get_context_data(self, **kwargs):
  67. object_list = Game.objects.filter(game_system=self.get_object())
  68. context = super(GameSystemDetail, self).get_context_data(
  69. object_list=object_list, **kwargs
  70. )
  71. return context
  72. class GenreDetail(DetailView, MultipleObjectMixin, LoginRequiredMixin):
  73. model = Genre
  74. paginate_by = 20
  75. def get_context_data(self, **kwargs):
  76. object_list = Game.objects.filter(genre=self.get_object())
  77. context = super(GenreDetail, self).get_context_data(
  78. object_list=object_list, **kwargs
  79. )
  80. return context
  81. class PublisherDetail(DetailView, MultipleObjectMixin, LoginRequiredMixin):
  82. model = Publisher
  83. paginate_by = 20
  84. def get_context_data(self, **kwargs):
  85. object_list = Game.objects.filter(publisher=self.get_object())
  86. context = super(PublisherDetail, self).get_context_data(
  87. object_list=object_list, **kwargs
  88. )
  89. return context
  90. class DeveloperDetail(DetailView, MultipleObjectMixin, LoginRequiredMixin):
  91. model = Developer
  92. paginate_by = 20
  93. def get_context_data(self, **kwargs):
  94. object_list = Game.objects.filter(developer=self.get_object())
  95. context = super(DeveloperDetail, self).get_context_data(
  96. object_list=object_list, **kwargs
  97. )
  98. return context
  99. class GameCollectionList(ListView, LoginRequiredMixin):
  100. model = GameCollection
  101. class GameCollectionDetail(DetailView, LoginRequiredMixin):
  102. model = GameCollection
  103. def get_context_data(self, **kwargs):
  104. collection = self.get_object()
  105. order_by = self.request.GET.get("order_by", "release_date")
  106. object_list = collection.games.all()
  107. if order_by[0] == "-":
  108. order_by = order_by[1:]
  109. object_list = object_list.order_by(F(order_by).desc(nulls_last=True))
  110. else:
  111. object_list = object_list.order_by(F(order_by).asc(nulls_last=True))
  112. context = super(GameCollectionDetail, self).get_context_data(
  113. object_list=object_list, **kwargs
  114. )
  115. return context
  116. @login_required
  117. def trigger_rom_update(request):
  118. full_scan = request.GET.get("full_scan")
  119. if full_scan == "true":
  120. full_scan = True
  121. else:
  122. full_scan = False
  123. all_slugs = settings.GAME_SYSTEM_DEFAULTS.keys()
  124. try:
  125. update_roms.delay(all_slugs, full_scan=full_scan)
  126. except FileNotFoundError:
  127. return HttpResponse(
  128. json.dumps({"success": False, "msg": "Skyscraper is not installed"}),
  129. mimetype="application/json",
  130. )
  131. return HttpResponse(
  132. json.dumps({"success": True, "msg": "Library scan started"}),
  133. mimetype="application/json",
  134. )