Skip to content

Commit

Permalink
Multi lang and multi region support
Browse files Browse the repository at this point in the history
  • Loading branch information
gantoine committed Dec 3, 2023
1 parent 0a74a3e commit be0b36c
Show file tree
Hide file tree
Showing 11 changed files with 238 additions and 79 deletions.
44 changes: 44 additions & 0 deletions backend/alembic/versions/0012_add_regions_languages.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
"""empty message
Revision ID: 0012_add_regions_languages
Revises: 0011_drop_has_cover
Create Date: 2023-12-03 10:54:46.859106
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import mysql

# revision identifiers, used by Alembic.
revision = '0012_'
down_revision = '0011_drop_has_cover'
branch_labels = None
depends_on = None


def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('roms', schema=None) as batch_op:
batch_op.add_column(sa.Column('regions', sa.JSON(), nullable=True))
batch_op.add_column(sa.Column('languages', sa.JSON(), nullable=True))

with op.batch_alter_table('roms', schema=None) as batch_op:
# Set default values for languages and regions
batch_op.execute("UPDATE roms SET languages = '[]'")
batch_op.execute("UPDATE roms SET regions = JSON_ARRAY(region)")
batch_op.drop_column('region')

# ### end Alembic commands ###


def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('roms', schema=None) as batch_op:
batch_op.add_column(sa.Column('region', mysql.VARCHAR(length=20), nullable=True))

with op.batch_alter_table('roms', schema=None) as batch_op:
batch_op.execute("UPDATE roms SET region = JSON_UNQUOTE(JSON_EXTRACT(regions, '$[0]'))")
batch_op.drop_column('languages')
batch_op.drop_column('regions')

# ### end Alembic commands ###
11 changes: 6 additions & 5 deletions backend/endpoints/rom.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,14 @@ class RomSchema(BaseModel):
has_cover: bool
url_cover: str

region: Optional[str]
revision: Optional[str]
tags: list
regions: list[str]
languages: list[str]
tags: list[str]
multi: bool
files: list
url_screenshots: list
path_screenshots: list
files: list[str]
url_screenshots: list[str]
path_screenshots: list[str]
full_path: str
download_path: str

Expand Down
3 changes: 2 additions & 1 deletion backend/models/rom.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,9 @@ class Rom(BaseModel):
path_cover_l: str = Column(Text, default=DEFAULT_PATH_COVER_L)
url_cover: str = Column(Text, default=DEFAULT_PATH_COVER_L)

region: str = Column(String(20))
revision: str = Column(String(20))
regions: JSON = Column(JSON, default=[])
languages: JSON = Column(JSON, default=[])
tags: JSON = Column(JSON, default=[])
multi: bool = Column(Boolean, default=False)
files: JSON = Column(JSON, default=[])
Expand Down
71 changes: 40 additions & 31 deletions backend/utils/__init__.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,25 @@
import re

import numpy as np

LANGUAGES = [
"Ar",
"Da",
"De",
"En",
"En-US",
"Es",
"Fi",
"Fr",
"It",
"Ja",
"Ko",
"Nl",
"Pl",
"Pt",
"Pt-BR",
"Ru",
"Sv",
"Zh",
"Zh-Hans",
"Zh-Hant",
"nolang",
("Ar", "Arabic"),
("Da", "Danish"),
("De", "German"),
("En", "English"),
("Es", "Spanish"),
("Fi", "Finnish"),
("Fr", "French"),
("It", "Italian"),
("Ja", "Japanese"),
("Ko", "Korean"),
("Nl", "Dutch"),
("No", "Norwegian"),
("Pl", "Polish"),
("Pt", "Portuguese"),
("Ru", "Russian"),
("Sv", "Swedish"),
("Zh", "Chinese"),
("nolang", "No Language"),
]

REGIONS = [
Expand Down Expand Up @@ -58,31 +55,43 @@
REGIONS_BY_SHORTCODE = {region[0].lower(): region[1] for region in REGIONS}
REGIONS_NAME_KEYS = [region[1].lower() for region in REGIONS]

LANGUAGES_BY_SHORTCODE = {lang[0].lower(): lang[1] for lang in LANGUAGES}
LANGUAGES_NAME_KEYS = [lang[1].lower() for lang in LANGUAGES]

TAG_REGEX = r"\(([^)]+)\)|\[([^]]+)\]"
EXTENSION_REGEX = r"\.(([a-z]+\.)*\w+)$"


def parse_tags(file_name: str) -> tuple:
reg = ""
rev = ""
regs = []
langs = []
other_tags = []
tags = re.findall(TAG_REGEX, file_name)

for p_tag, s_tag in tags:
tag = p_tag or s_tag
tags = [tag[0] or tag[1] for tag in re.findall(TAG_REGEX, file_name)]
tags = np.array([tag.split(",") for tag in tags]).flatten()
tags = [tag.strip() for tag in tags]

for tag in tags:
if tag.lower() in REGIONS_BY_SHORTCODE.keys():
reg = REGIONS_BY_SHORTCODE[tag.lower()]
regs.append(REGIONS_BY_SHORTCODE[tag.lower()])
continue

if tag.lower() in REGIONS_NAME_KEYS:
reg = tag
regs.append(tag)
continue

if tag.lower() in LANGUAGES_BY_SHORTCODE.keys():
langs.append(LANGUAGES_BY_SHORTCODE[tag.lower()])
continue

if tag.lower() in LANGUAGES_NAME_KEYS:
langs.append(tag)
continue

if "reg" in tag.lower():
match = re.match(r"^reg[\s|-](.*)$", tag, re.IGNORECASE)
if match:
reg = (
regs.append(
REGIONS_BY_SHORTCODE[match.group(1).lower()]
if match.group(1).lower() in REGIONS_BY_SHORTCODE.keys()
else match.group(1)
Expand All @@ -96,7 +105,7 @@ def parse_tags(file_name: str) -> tuple:
continue

other_tags.append(tag)
return reg, rev, other_tags
return regs, rev, langs, other_tags


def get_file_name_with_no_tags(file_name: str) -> str:
Expand Down
5 changes: 3 additions & 2 deletions backend/utils/fastapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ async def scan_rom(
multi_files=rom_attrs["files"],
roms_path=roms_path,
)
reg, rev, other_tags = parse_tags(rom_attrs["file_name"])
regs, rev, langs, other_tags = parse_tags(rom_attrs["file_name"])
rom_attrs.update(
{
"file_path": roms_path,
Expand All @@ -72,8 +72,9 @@ async def scan_rom(
"file_size": file_size,
"file_size_units": file_size_units,
"multi": rom_attrs["multi"],
"region": reg,
"regions": regs,
"revision": rev,
"languages": langs,
"tags": other_tags,
}
)
Expand Down
1 change: 0 additions & 1 deletion frontend/src/components/Details/Info.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
<script setup>
import storeDownload from "@/stores/download";
import { regionToEmoji } from "@/utils/utils";
const props = defineProps(["rom"]);
const downloadStore = storeDownload();
Expand Down
15 changes: 8 additions & 7 deletions frontend/src/components/Details/Title.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
<script setup>
import { useDisplay } from "vuetify";
import PlatformIcon from "@/components/Platform/PlatformIcon.vue";
import { regionToEmoji } from "@/utils/utils";
import { regionToEmoji, languageToEmoji } from "@/utils/utils";
const props = defineProps(["rom"]);
const { xs, sm, md, smAndUp } = useDisplay();
const regionEmoji = regionToEmoji(props.rom.region);
const { smAndUp } = useDisplay();
</script>
<template>
<v-row no-gutters>
Expand All @@ -23,10 +22,12 @@ const regionEmoji = regionToEmoji(props.rom.region);
<platform-icon :platform="rom.platform_slug"></platform-icon>
</v-avatar>
</v-chip>
<v-chip-group v-if="rom.region || rom.revision" class="ml-3 pa-0 text-white text-shadow">
<v-chip v-if="regionEmoji">{{ regionEmoji }}</v-chip>
<v-chip v-if="!regionEmoji" v-show="rom.region">
{{ regionEmoji || rom.region }}
<v-chip-group class="ml-3 pa-0 text-white text-shadow">
<v-chip v-if="rom.regions.length > 0" title="Regions">
<span v-for="region in rom.regions">{{ regionToEmoji(region) }}&nbsp;</span>
</v-chip>
<v-chip v-if="rom.languages.length > 0" title="Languages">
<span v-for="language in rom.languages">{{ languageToEmoji(language) }}&nbsp;</span>
</v-chip>
<v-chip v-show="rom.revision">
Rev {{ rom.revision }}
Expand Down
20 changes: 17 additions & 3 deletions frontend/src/components/Game/Card/Cover.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import { ref } from "vue";
import storeDownload from "@/stores/download";
import storeRoms from "@/stores/roms";
import { regionToEmoji } from "@/utils/utils";
import { regionToEmoji, languageToEmoji } from "@/utils/utils";
// Props
const props = defineProps([
Expand Down Expand Up @@ -100,14 +100,28 @@ function onTouchEnd() {
</v-expand-transition>
<v-chip-group class="pl-1 pt-0 text-black position-absolute chips">
<v-chip
v-show="rom.region"
v-if="rom.regions.length > 0"
title="Region"
size="large"
class="pr-2 pl-2 bg-chip"
density="compact"
label
>
{{ regionToEmoji(rom.region) || rom.region }}
<span v-for="region in rom.regions">
{{ regionToEmoji(region) }}&nbsp;
</span>
</v-chip>
<v-chip
v-if="rom.languages.length > 0"
title="Language"
size="large"
class="pr-2 pl-2 bg-chip"
density="compact"
label
>
<span v-for="language in rom.languages">
{{ languageToEmoji(language) }}&nbsp;
</span>
</v-chip>
</v-chip-group>
<v-icon
Expand Down
Loading

0 comments on commit be0b36c

Please sign in to comment.