Browse Source

Restructure some things

Move the utility out of the management command and update settings to be
more flexible going forward.
Colin Powell 3 years ago
parent
commit
b997b4b7dc

+ 3 - 1
emus/settings.py

@@ -10,6 +10,7 @@ For the full list of settings and their values, see
 https://docs.djangoproject.com/en/3.1/ref/settings/
 """
 
+import os
 from pathlib import Path
 
 # Build paths inside the project like this: BASE_DIR / 'subdir'.
@@ -121,4 +122,5 @@ USE_TZ = True
 
 STATIC_URL = "/static/"
 MEDIA_URL = "/media/"
-MEDIA_ROOT = "/home/powellc/RetroPie/roms"
+MEDIA_ROOT = "media"
+ROMS_DIR = os.path.join(MEDIA_ROOT, "roms")

+ 7 - 0
emus/utils.py

@@ -0,0 +1,7 @@
+from enum import Enum
+
+
+class ChoiceEnum(Enum):
+    @classmethod
+    def choices(cls):
+        return tuple((x.name, x.value) for x in cls)

+ 9 - 50
games/management/commands/export_gamelist_xml_file.py

@@ -2,64 +2,23 @@ import xml.etree.ElementTree as ET
 
 from django.core.management.base import BaseCommand, CommandError
 
-from dateutil import parser
-from games.models import Developer, Game, GameSystem, Genre, Publisher
-
-
-def export_gamelist_file_to_path_for_system(file_path, game_system):
-    exported_games = []
-    root = ET.Element("gameList")
-
-    tree = ET.ElementTree(root)
-    tree.write("filename.xml")
-    games = Game.objects.filter(game_system=game_system)
-    for game in games:
-        game_node = ET.SubElement(root, "game")
-
-        genre_str = ", ".join(game.genre.all().values_list("name", flat=True))
-        release_date_str = ""
-        if game.release_date:
-            release_date_str = game.release_date.strftime("%Y%m%dT00000")
-        ET.SubElement(game_node, "path").text = (
-            game.rom_file.path if game.rom_file else ""
-        )
-        ET.SubElement(game_node, "name").text = game.name
-        ET.SubElement(game_node, "thumbnail").text = ""
-        ET.SubElement(game_node, "image").text = (
-            game.screenshot.path if game.screenshot else ""
-        )
-        ET.SubElement(game_node, "marquee").text = (
-            game.marquee.path if game.marquee else ""
-        )
-        ET.SubElement(game_node, "video").text = game.video.path if game.video else ""
-        ET.SubElement(game_node, "rating").text = str(game.rating)
-        ET.SubElement(game_node, "desc").text = game.description
-        ET.SubElement(game_node, "releasedate").text = release_date_str
-        ET.SubElement(game_node, "developer").text = str(game.developer)
-        ET.SubElement(game_node, "publisher").text = str(game.publisher)
-        ET.SubElement(game_node, "genre").text = genre_str
-        ET.SubElement(game_node, "players").text = str(game.players)
-        if game.kid_game:
-            ET.SubElement(game_node, "kidgame").text = "true"
-
-        exported_games.append(game)
-    tree = ET.ElementTree(root)
-    tree.write(file_path, xml_declaration=True, encoding="utf-8")
-
-    return exported_games
+from games.utils import export_gamelist_file_to_path_for_system
 
 
 class Command(BaseCommand):
     help = "Export all games found to a given gamelist XML file"
 
     def add_arguments(self, parser):
-        parser.add_argument("file_path", nargs="+", type=str)
-        parser.add_argument("system", nargs="+", type=str)
+        parser.add_argument("system", type=str)
+        parser.add_argument(
+            "--file",
+            action="store_true",
+            help="Export to a specific file",
+        )
 
     def handle(self, *args, **options):
-        game_system = GameSystem.objects.get(retropie_slug=options["system"][0])
         games = export_gamelist_file_to_path_for_system(
-            options["file_path"][0],
-            game_system,
+            options["system"],
+            options["file"],
         )
         self.stdout.write(self.style.SUCCESS(f"Successfully exported {len(games)}"))

+ 9 - 92
games/management/commands/import_gamelist_xml_file.py

@@ -1,105 +1,22 @@
-import xml.etree.ElementTree as ET
-
 from django.core.management.base import BaseCommand, CommandError
 
-from dateutil import parser
-from games.models import Developer, Game, GameSystem, Genre, Publisher
-
-US_STRINGS = ["(u)", "(usa)", "(us)"]
-JP_STRINGS = ["(j)", "japan", "jp"]
-EU_STRINGS = ["(e)", "eur", "europe", "pal"]
-
-
-def import_gamelist_file_to_db_for_system(file_path, game_system):
-    imported_games = []
-    gamelist = ET.parse(file_path)
-
-    games = gamelist.findall("game")
-    for game in games:
-        name = game.find("name").text
-        english_patched = "patched" in name.lower()
-        undub = "undub" in name.lower()
-        hack = "hack" in name.lower()
-
-        region = None
-
-        if any(us in name.lower() for us in US_STRINGS):
-            region = Game.Region.US.name
-        if any(jp in name.lower() for jp in JP_STRINGS):
-            region = Game.Region.JP.name
-        if any(eu in name.lower() for eu in EU_STRINGS):
-            region = Game.Region.EU.name
-
-        release_date_str = game.find("releasedate").text
-        developer_str = game.find("developer").text
-        publisher_str = game.find("publisher").text
-        genres_str = game.find("genre").text
-
-        rating_str = game.find("rating").text
-        players_str = game.find("players").text
-        try:
-            kid_game = game.find("kidgame").text == "true"
-        except AttributeError:
-            kid_game = False
-
-        genre_str_list = genres_str.split(", ")
-        genre_list = []
-        if genres_str:
-            for genre_str in genre_str_list:
-                genre, _created = Genre.objects.get_or_create(name=genre_str)
-                genre_list.append(genre)
-
-        players = int(players_str) if players_str else 1
-        rating = float(rating_str) if rating_str else None
-        publisher = None
-        if publisher_str:
-            publisher, _created = Publisher.objects.get_or_create(name=publisher_str)
-        developer = None
-        if developer_str:
-            developer, _created = Developer.objects.get_or_create(name=developer_str)
-        release_date = parser.parse(release_date_str) if release_date_str else None
-        screenshot_path = game.find("image").text
-        rom_path = game.find("path").text
-        video_path = game.find("video").text
-        marquee_path = game.find("marquee").text
-        description = game.find("desc").text
-
-        obj, created = Game.objects.get_or_create(name=name)
-
-        obj.game_system = game_system
-        obj.developer = developer
-        obj.publisher = publisher
-        obj.players = players
-        obj.description = description
-        obj.release_date = release_date
-        obj.rating = rating
-        obj.genre.set(genre_list)
-        obj.screenshot = screenshot_path
-        obj.rom_file = rom_path
-        obj.video = video_path
-        obj.marquee = marquee_path
-        obj.kid_game = kid_game
-        obj.english_patched = english_patched
-        obj.hack = hack
-        obj.undub = undub
-        obj.region = region
-        obj.save()
-
-        imported_games.append(game)
-    return imported_games
+from games.utils import import_gamelist_file_to_db_for_system
 
 
 class Command(BaseCommand):
     help = "Import all games found in a given gamelist XML file"
 
     def add_arguments(self, parser):
-        parser.add_argument("file_path", nargs="+", type=str)
-        parser.add_argument("system", nargs="+", type=str)
+        parser.add_argument("system", type=str)
+        parser.add_argument(
+            "--file",
+            action="store_true",
+            help="Import from specific file",
+        )
 
     def handle(self, *args, **options):
-        game_system = GameSystem.objects.get(retropie_slug=options["system"][0])
         games = import_gamelist_file_to_db_for_system(
-            options["file_path"][0],
-            game_system,
+            options["system"],
+            options["file"],
         )
         self.stdout.write(self.style.SUCCESS(f"Successfully imported {len(games)}"))

+ 2 - 3
games/models.py

@@ -1,11 +1,10 @@
 from enum import Enum
 
+from django.conf import settings
 from django.core.validators import MaxValueValidator, MinValueValidator
 from django.db import models
-from django.conf import settings
-
 from django_extensions.db.fields import AutoSlugField
-from games.utils import ChoiceEnum
+from emus.utils import ChoiceEnum
 
 
 def get_screenshot_upload_path(instance, filename):

+ 150 - 5
games/utils.py

@@ -1,7 +1,152 @@
-from enum import Enum
+import os
+import xml.etree.ElementTree as ET
 
+from dateutil import parser
+from django.conf import settings
 
-class ChoiceEnum(Enum):
-    @classmethod
-    def choices(cls):
-        return tuple((x.name, x.value) for x in cls)
+from .models import Developer, Game, GameSystem, Genre, Publisher
+
+US_STRINGS = ["(u)", "(usa)", "(us)"]
+JP_STRINGS = ["(j)", "japan", "jp"]
+EU_STRINGS = ["(e)", "eur", "europe", "pal"]
+
+
+def update_media_root_for_import(file_path):
+    """Given a file path, re-write it for our app MEDIA_ROOT"""
+    split_path = file_path.split("/")
+    file_name = split_path[-1]
+    game_system_slug = split_path[-2]
+    return os.path.join(settings.ROMS_DIR, game_system_slug, file_name)
+
+
+def import_gamelist_file_to_db_for_system(game_system_slug, file_path=None):
+    imported_games = []
+    if not file_path:
+        file_path = os.path.join(settings.ROMS_DIR, game_system_slug, "gamelist.xml")
+    gamelist = ET.parse(file_path)
+    game_system = GameSystem.objects.get(retropie_slug=game_system_slug)
+
+    games = gamelist.findall("game")
+    for game in games:
+        name = game.find("name").text
+        english_patched = "patched" in name.lower()
+        undub = "undub" in name.lower()
+        hack = "hack" in name.lower()
+
+        region = None
+
+        if any(us in name.lower() for us in US_STRINGS):
+            region = Game.Region.US.name
+        if any(jp in name.lower() for jp in JP_STRINGS):
+            region = Game.Region.JP.name
+        if any(eu in name.lower() for eu in EU_STRINGS):
+            region = Game.Region.EU.name
+
+        release_date_str = game.find("releasedate").text
+        developer_str = game.find("developer").text
+        publisher_str = game.find("publisher").text
+        genres_str = game.find("genre").text
+
+        rating_str = game.find("rating").text
+        players_str = "1"
+        if game.find("players"):
+            players_str = game.find("players").text
+        try:
+            kid_game = game.find("kidgame").text == "true"
+        except AttributeError:
+            kid_game = False
+
+        genre_list = []
+        if genres_str:
+            genre_str_list = genres_str.split(", ")
+            for genre_str in genre_str_list:
+                genre, _created = Genre.objects.get_or_create(name=genre_str)
+                genre_list.append(genre)
+
+        players = int(players_str) if players_str else 1
+        rating = float(rating_str) if rating_str else None
+        publisher = None
+        if publisher_str:
+            publisher, _created = Publisher.objects.get_or_create(name=publisher_str)
+        developer = None
+        if developer_str:
+            developer, _created = Developer.objects.get_or_create(name=developer_str)
+        release_date = parser.parse(release_date_str) if release_date_str else None
+        screenshot_path = game.find("image").text
+        rom_path = game.find("path").text
+        video_path = game.find("video").text
+        marquee_path = game.find("marquee").text
+        description = game.find("desc").text
+
+        obj, created = Game.objects.get_or_create(name=name)
+
+        obj.game_system = game_system
+        obj.developer = developer
+        obj.publisher = publisher
+        obj.players = players
+        obj.description = description
+        obj.release_date = release_date
+        obj.rating = rating
+        obj.genre.set(genre_list)
+        obj.screenshot = screenshot_path
+        obj.rom_file = rom_path
+        obj.video = video_path
+        obj.marquee = marquee_path
+        obj.kid_game = kid_game
+        obj.english_patched = english_patched
+        obj.hack = hack
+        obj.undub = undub
+        obj.region = region
+        obj.save()
+
+        imported_games.append(game)
+    return imported_games
+
+
+def export_gamelist_file_to_path_for_system(game_system_slug, file_path=None):
+    exported_games = []
+    game_system = GameSystem.objects.get(retropie_slug=game_system_slug)
+
+    if not file_path:
+        file_path = f"/tmp/{game_system_slug}-gamelist.xml"
+        # file_path = os.path.join(settings.ROMS_DIR, game_system_slug, "gamelist.xml")
+
+    root = ET.Element("gameList")
+
+    tree = ET.ElementTree(root)
+    tree.write("filename.xml")
+    games = Game.objects.filter(game_system=game_system)
+    for game in games:
+        game_node = ET.SubElement(root, "game")
+
+        genre_str = ", ".join(game.genre.all().values_list("name", flat=True))
+        release_date_str = ""
+        if game.release_date:
+            release_date_str = game.release_date.strftime("%Y%m%dT00000")
+        ET.SubElement(game_node, "path").text = (
+            game.rom_file.path if game.rom_file else ""
+        )
+        ET.SubElement(game_node, "name").text = game.name
+        ET.SubElement(game_node, "thumbnail").text = ""
+        ET.SubElement(game_node, "image").text = (
+            game.screenshot.path if game.screenshot else ""
+        )
+        ET.SubElement(game_node, "marquee").text = (
+            game.marquee.path if game.marquee else ""
+        )
+        ET.SubElement(game_node, "video").text = game.video.path if game.video else ""
+        ET.SubElement(game_node, "rating").text = str(game.rating)
+        ET.SubElement(game_node, "desc").text = game.description
+        ET.SubElement(game_node, "releasedate").text = release_date_str
+        ET.SubElement(game_node, "developer").text = str(game.developer)
+        ET.SubElement(game_node, "publisher").text = str(game.publisher)
+        ET.SubElement(game_node, "genre").text = genre_str
+        ET.SubElement(game_node, "players").text = str(game.players)
+        if game.kid_game:
+            ET.SubElement(game_node, "kidgame").text = "true"
+
+        exported_games.append(game)
+    tree = ET.ElementTree(root)
+    tree.write(file_path, xml_declaration=True, encoding="utf-8")
+
+    return exported_games