utils.py 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. import os
  2. import xml.etree.ElementTree as ET
  3. from dateutil import parser
  4. from django.conf import settings
  5. from .models import Developer, Game, GameSystem, Genre, Publisher
  6. import logging
  7. logger = logging.Logger(__name__)
  8. US_STRINGS = ["(u)", "(usa)", "(us)"]
  9. JP_STRINGS = ["(j)", "japan", "jp"]
  10. EU_STRINGS = ["(e)", "eur", "europe", "pal"]
  11. def update_media_root_for_import(file_path):
  12. """Given a file path, re-write it for our app MEDIA_ROOT"""
  13. split_path = file_path.split("/")
  14. file_name = split_path[-1]
  15. game_system_slug = split_path[-2]
  16. return os.path.join(settings.ROMS_DIR, game_system_slug, file_name)
  17. def import_gamelist_file_to_db_for_system(game_system_slug, file_path=None):
  18. imported_games = []
  19. if not file_path:
  20. file_path = os.path.join(settings.ROMS_DIR, game_system_slug, "gamelist.xml")
  21. if not os.path.exists(file_path):
  22. logger.info(
  23. "File path for {game_system_slug} had no gamelist.xml file, run a scraper first!"
  24. )
  25. return
  26. gamelist = ET.parse(file_path)
  27. game_system = GameSystem.objects.filter(retropie_slug=game_system_slug).first()
  28. if not game_system:
  29. game_system = GameSystem.objects.create(
  30. name=game_system_slug, retropie_slug=game_system_slug
  31. )
  32. games = gamelist.findall("game")
  33. for game in games:
  34. name = game.find("name").text
  35. english_patched = "patched" in name.lower()
  36. undub = "undub" in name.lower()
  37. hack = "hack" in name.lower()
  38. region = None
  39. if any(us in name.lower() for us in US_STRINGS):
  40. region = Game.Region.US.name
  41. if any(jp in name.lower() for jp in JP_STRINGS):
  42. region = Game.Region.JP.name
  43. if any(eu in name.lower() for eu in EU_STRINGS):
  44. region = Game.Region.EU.name
  45. release_date_str = game.find("releasedate").text
  46. developer_str = game.find("developer").text
  47. publisher_str = game.find("publisher").text
  48. genres_str = game.find("genre").text
  49. rating_str = game.find("rating").text
  50. players_str = "1"
  51. if game.find("players"):
  52. players_str = game.find("players").text
  53. try:
  54. kid_game = game.find("kidgame").text == "true"
  55. except AttributeError:
  56. kid_game = False
  57. genre_list = []
  58. if genres_str:
  59. genre_str_list = genres_str.split(", ")
  60. for genre_str in genre_str_list:
  61. genre, _created = Genre.objects.get_or_create(name=genre_str)
  62. genre_list.append(genre)
  63. players = int(players_str) if players_str else 1
  64. rating = float(rating_str) if rating_str else None
  65. publisher = None
  66. if publisher_str:
  67. publisher, _created = Publisher.objects.get_or_create(name=publisher_str)
  68. developer = None
  69. if developer_str:
  70. developer, _created = Developer.objects.get_or_create(name=developer_str)
  71. release_date = parser.parse(release_date_str) if release_date_str else None
  72. screenshot_path = game.find("image").text
  73. rom_path = game.find("path").text
  74. video_path = game.find("video").text
  75. marquee_path = game.find("marquee").text
  76. description = game.find("desc").text
  77. obj, created = Game.objects.get_or_create(name=name)
  78. obj.game_system = game_system
  79. obj.developer = developer
  80. obj.publisher = publisher
  81. obj.players = players
  82. obj.description = description
  83. obj.release_date = release_date
  84. obj.rating = rating
  85. obj.genre.set(genre_list)
  86. obj.screenshot = screenshot_path
  87. obj.rom_file = rom_path
  88. obj.video = video_path
  89. obj.marquee = marquee_path
  90. obj.kid_game = kid_game
  91. obj.english_patched = english_patched
  92. obj.hack = hack
  93. obj.undub = undub
  94. obj.region = region
  95. obj.save()
  96. imported_games.append(game)
  97. return imported_games
  98. def export_gamelist_file_to_path_for_system(game_system_slug, file_path=None):
  99. exported_games = []
  100. game_system = GameSystem.objects.get(retropie_slug=game_system_slug)
  101. if not file_path:
  102. file_path = f"/tmp/{game_system_slug}-gamelist.xml"
  103. # file_path = os.path.join(settings.ROMS_DIR, game_system_slug, "gamelist.xml")
  104. root = ET.Element("gameList")
  105. tree = ET.ElementTree(root)
  106. tree.write(file_path)
  107. games = Game.objects.filter(game_system=game_system)
  108. for game in games:
  109. game_node = ET.SubElement(root, "game")
  110. genre_str = ", ".join(game.genre.all().values_list("name", flat=True))
  111. release_date_str = ""
  112. if game.release_date:
  113. release_date_str = game.release_date.strftime("%Y%m%dT00000")
  114. ET.SubElement(game_node, "path").text = (
  115. game.rom_file.path if game.rom_file else ""
  116. )
  117. ET.SubElement(game_node, "name").text = game.name
  118. ET.SubElement(game_node, "thumbnail").text = ""
  119. ET.SubElement(game_node, "image").text = (
  120. game.screenshot.path if game.screenshot else ""
  121. )
  122. ET.SubElement(game_node, "marquee").text = (
  123. game.marquee.path if game.marquee else ""
  124. )
  125. ET.SubElement(game_node, "video").text = game.video.path if game.video else ""
  126. ET.SubElement(game_node, "rating").text = str(game.rating)
  127. ET.SubElement(game_node, "desc").text = game.description
  128. ET.SubElement(game_node, "releasedate").text = release_date_str
  129. ET.SubElement(game_node, "developer").text = str(game.developer)
  130. ET.SubElement(game_node, "publisher").text = str(game.publisher)
  131. ET.SubElement(game_node, "genre").text = genre_str
  132. ET.SubElement(game_node, "players").text = str(game.players)
  133. if game.kid_game:
  134. ET.SubElement(game_node, "kidgame").text = "true"
  135. exported_games.append(game)
  136. tree = ET.ElementTree(root)
  137. tree.write(file_path, xml_declaration=True, encoding="utf-8")
  138. return exported_games, file_path