Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes from beta testing #986

Merged
merged 12 commits into from
Jul 8, 2024
24 changes: 14 additions & 10 deletions backend/endpoints/collections.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ async def update_collection(
"""

data = await request.form()

collection = db_collection_handler.get_collection(id)

if collection.user_id != request.user.id:
Expand All @@ -158,7 +159,6 @@ async def update_collection(
"name": data.get("name", collection.name),
"description": data.get("description", collection.description),
"roms": list(set(roms)),
"url_cover": data.get("url_cover", collection.url_cover),
"is_public": data.get("is_public", collection.is_public),
"user_id": request.user.id,
}
Expand Down Expand Up @@ -187,16 +187,20 @@ async def update_collection(
file_location_l = f"{artwork_path}/big.{file_ext}"
with open(file_location_l, "wb+") as artwork_l:
artwork_l.write(artwork_file)
cleaned_data.update({"url_cover": ""})
else:
cleaned_data["url_cover"] = data.get("url_cover", collection.url_cover)
path_cover_s, path_cover_l = fs_resource_handler.get_cover(
overwrite=cleaned_data["url_cover"] != collection.url_cover,
entity=collection,
url_cover=cleaned_data.get("url_cover", ""),
)
cleaned_data.update(
{"path_cover_s": path_cover_s, "path_cover_l": path_cover_l}
)
if data.get("url_cover", "") != collection.url_cover:
cleaned_data.update(
{"url_cover": data.get("url_cover", collection.url_cover)}
)
path_cover_s, path_cover_l = fs_resource_handler.get_cover(
overwrite=True,
entity=collection,
url_cover=data.get("url_cover", ""),
)
cleaned_data.update(
{"path_cover_s": path_cover_s, "path_cover_l": path_cover_l}
)

return db_collection_handler.update_collection(id, cleaned_data)

Expand Down
53 changes: 30 additions & 23 deletions backend/endpoints/rom.py
Original file line number Diff line number Diff line change
Expand Up @@ -300,17 +300,29 @@ async def update_rom(
"moby_id": data.get("moby_id", None),
}

if cleaned_data["moby_id"]:
if (
cleaned_data.get("moby_id", "")
and int(cleaned_data.get("moby_id", "")) != rom.moby_id
):
moby_rom = meta_moby_handler.get_rom_by_id(cleaned_data["moby_id"])
cleaned_data.update(moby_rom)
else:
cleaned_data.update({"moby_metadata": {}})
path_screenshots = fs_resource_handler.get_rom_screenshots(
rom=rom,
url_screenshots=cleaned_data.get("url_screenshots", []),
)
cleaned_data.update({"path_screenshots": path_screenshots})

if cleaned_data["igdb_id"]:
if (
cleaned_data.get("igdb_id", "")
and int(cleaned_data.get("igdb_id", "")) != rom.igdb_id
):
igdb_rom = meta_igdb_handler.get_rom_by_id(cleaned_data["igdb_id"])
cleaned_data.update(igdb_rom)
else:
cleaned_data.update({"igdb_metadata": {}})
path_screenshots = fs_resource_handler.get_rom_screenshots(
rom=rom,
url_screenshots=cleaned_data.get("url_screenshots", []),
)
cleaned_data.update({"path_screenshots": path_screenshots})

cleaned_data.update(
{
Expand Down Expand Up @@ -356,7 +368,7 @@ async def update_rom(
cleaned_data.update(fs_resource_handler.remove_cover(rom))
cleaned_data.update({"url_cover": ""})
else:
if artwork is not None:
if artwork:
file_ext = artwork.filename.split(".")[-1]
(
path_cover_l,
Expand All @@ -377,23 +389,18 @@ async def update_rom(
file_location_l = f"{artwork_path}/big.{file_ext}"
with open(file_location_l, "wb+") as artwork_l:
artwork_l.write(artwork_file)
cleaned_data.update({"url_cover": ""})
else:
cleaned_data.update({"url_cover": data.get("url_cover", rom.url_cover)})
path_cover_s, path_cover_l = fs_resource_handler.get_cover(
overwrite=cleaned_data["url_cover"] != rom.url_cover,
entity=rom,
url_cover=cleaned_data.get("url_cover", ""),
)
cleaned_data.update(
{"path_cover_s": path_cover_s, "path_cover_l": path_cover_l}
)

if cleaned_data["igdb_id"] != rom.igdb_id or cleaned_data["moby_id"] != rom.moby_id:
path_screenshots = fs_resource_handler.get_rom_screenshots(
rom=rom,
url_screenshots=cleaned_data.get("url_screenshots", []),
)
cleaned_data.update({"path_screenshots": path_screenshots})
if data.get("url_cover", "") != rom.url_cover:
cleaned_data.update({"url_cover": data.get("url_cover", rom.url_cover)})
path_cover_s, path_cover_l = fs_resource_handler.get_cover(
overwrite=True,
entity=rom,
url_cover=data.get("url_cover", ""),
)
cleaned_data.update(
{"path_cover_s": path_cover_s, "path_cover_l": path_cover_l}
)

db_rom_handler.update_rom(id, cleaned_data)

Expand Down
19 changes: 15 additions & 4 deletions backend/endpoints/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from handler.auth import auth_handler
from handler.database import db_user_handler
from handler.filesystem import fs_asset_handler
from logger.logger import log
from models.user import Role, User

router = APIRouter()
Expand Down Expand Up @@ -39,6 +40,14 @@ def add_user(request: Request, username: str, password: str, role: str) -> UserS
UserSchema: Created user info
"""

if username in [user.username for user in db_user_handler.get_users()]:
msg = f"Username {username} already exists"
log.error(msg)
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail=msg,
)

user = User(
username=username,
hashed_password=auth_handler.get_password_hash(password),
Expand Down Expand Up @@ -115,9 +124,9 @@ def update_user(

db_user = db_user_handler.get_user(id)
if not db_user:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail="User not found"
)
msg = f"Username with id {id} not found"
log.error(msg)
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=msg)

# Admin users can edit any user, while other users can only edit self
if db_user.id != request.user.id and request.user.role != Role.ADMIN:
Expand All @@ -128,9 +137,11 @@ def update_user(
if form_data.username and form_data.username != db_user.username:
existing_user = db_user_handler.get_user_by_username(form_data.username.lower())
if existing_user:
msg = f"Username {form_data.username} already exists"
log.error(msg)
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Username already in use by another user",
detail=msg,
)

cleaned_data["username"] = form_data.username.lower()
Expand Down
5 changes: 2 additions & 3 deletions examples/docker-compose.example.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,11 @@ services:
- DB_NAME=romm # Should match MYSQL_DATABASE in mariadb
- DB_USER=romm-user # Should match MYSQL_USER in mariadb
- DB_PASSWD= # Should match MYSQL_PASSWORD in mariadb
- ROMM_AUTH_SECRET_KEY= # Generate a key with `openssl rand -hex 32`
- IGDB_CLIENT_ID= # Generate an ID and SECRET in IGDB
- IGDB_CLIENT_SECRET= # https://api-docs.igdb.com/#account-creation
- MOBYGAMES_API_KEY= # https://www.mobygames.com/info/api/
- ROMM_AUTH_SECRET_KEY= # Generate a key with `openssl rand -hex 32`
- ROMM_AUTH_USERNAME=admin
- ROMM_AUTH_PASSWORD= # default: admin
- STEAMGRIDDB_API_KEY # https://github.com/rommapp/romm/wiki/Generate-API-Keys#steamgriddb
volumes:
- romm_resources:/romm/resources # Resources fetched from IGDB (covers, screenshots, etc.)
- romm_redis_data:/redis-data # Cached data for background tasks
Expand Down
71 changes: 34 additions & 37 deletions frontend/src/components/Details/Saves.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ import type { SaveSchema } from "@/__generated__";
import UploadSavesDialog from "@/components/common/Game/Dialog/Asset/UploadSaves.vue";
import { type DetailedRom } from "@/stores/roms";
import type { Events } from "@/types/emitter";
import { formatBytes } from "@/utils";
import { formatBytes, formatTimestamp } from "@/utils";
import type { Emitter } from "mitt";
import { inject, onMounted, ref, watch } from "vue";
import { useDisplay } from "vuetify";

// Props
const { xs, smAndUp, mdAndUp } = useDisplay();
const { xs, mdAndUp } = useDisplay();
const props = defineProps<{ rom: DetailedRom }>();
const selectedSaves = ref<SaveSchema[]>([]);
const emitter = inject<Emitter<Events>>("emitter");
Expand All @@ -20,6 +20,24 @@ const HEADERS = [
sortable: true,
key: "file_name",
},
{
title: "Core",
align: "start",
sortable: true,
key: "emulator",
},
{
title: "Updated",
align: "start",
sortable: true,
key: "updated_at",
},
{
title: "Size",
align: "start",
sortable: true,
key: "file_size_bytes",
},
{ title: "", align: "end", key: "actions", sortable: false },
] as const;
const page = ref(1);
Expand Down Expand Up @@ -108,43 +126,22 @@ onMounted(() => {
</template>
<template #item.file_name="{ item }">
<td class="name-row">
<v-list-item class="px-0">
<v-row no-gutters>
<v-col>
{{ item.file_name }}
</v-col>
</v-row>
<v-row v-if="!smAndUp" no-gutters>
<v-col>
<v-chip size="x-small" label
>{{ formatBytes(item.file_size_bytes) }}
</v-chip>
<v-chip
v-if="item.emulator"
size="x-small"
class="ml-1 text-orange"
label
>{{ item.emulator }}
</v-chip>
</v-col>
</v-row>
<template #append>
<template v-if="smAndUp">
<v-chip
v-if="item.emulator"
size="x-small"
class="text-orange"
label
>{{ item.emulator }}
</v-chip>
<v-chip class="ml-1" size="x-small" label
>{{ formatBytes(item.file_size_bytes) }}
</v-chip>
</template>
</template>
</v-list-item>
<span>{{ item.file_name }}</span>
</td>
</template>
<template #item.emulator="{ item }">
<v-chip size="x-small" color="orange" label>{{ item.emulator }} </v-chip>
</template>
<template #item.updated_at="{ item }">
<v-chip size="x-small" label>
{{ formatTimestamp(item.updated_at) }}
</v-chip>
</template>
<template #item.file_size_bytes="{ item }">
<v-chip size="x-small" label
>{{ formatBytes(item.file_size_bytes) }}
</v-chip>
</template>
<template #no-data
><span>No saves found for {{ rom.name }}</span></template
>
Expand Down
73 changes: 35 additions & 38 deletions frontend/src/components/Details/States.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ import type { StateSchema } from "@/__generated__";
import UploadStatesDialog from "@/components/common/Game/Dialog/Asset/UploadStates.vue";
import { type DetailedRom } from "@/stores/roms";
import type { Events } from "@/types/emitter";
import { formatBytes } from "@/utils";
import { formatBytes, formatTimestamp } from "@/utils";
import type { Emitter } from "mitt";
import { inject, onMounted, ref, watch } from "vue";
import { useDisplay } from "vuetify";

// Props
const { xs, smAndUp, mdAndUp } = useDisplay();
const { xs, mdAndUp } = useDisplay();
const props = defineProps<{ rom: DetailedRom }>();
const selectedStates = ref<StateSchema[]>([]);
const emitter = inject<Emitter<Events>>("emitter");
Expand All @@ -21,6 +21,24 @@ const HEADERS = [
sortable: true,
key: "file_name",
},
{
title: "Core",
align: "start",
sortable: true,
key: "emulator",
},
{
title: "Updated",
align: "start",
sortable: true,
key: "updated_at",
},
{
title: "Size",
align: "start",
sortable: true,
key: "file_size_bytes",
},
{ title: "", align: "end", key: "actions", sortable: false },
] as const;
const page = ref(1);
Expand Down Expand Up @@ -109,43 +127,22 @@ onMounted(() => {
</template>
<template #item.file_name="{ item }">
<td class="name-row">
<v-list-item class="px-0">
<v-row no-gutters>
<v-col>
{{ item.file_name }}
</v-col>
</v-row>
<v-row v-if="!smAndUp" no-gutters>
<v-col>
<v-chip size="x-small" label
>{{ formatBytes(item.file_size_bytes) }}
</v-chip>
<v-chip
v-if="item.emulator"
size="x-small"
class="ml-1 text-orange"
label
>{{ item.emulator }}
</v-chip>
</v-col>
</v-row>
<template #append>
<template v-if="smAndUp">
<v-chip
v-if="item.emulator"
size="x-small"
class="text-orange"
label
>{{ item.emulator }}
</v-chip>
<v-chip class="ml-1" size="x-small" label
>{{ formatBytes(item.file_size_bytes) }}
</v-chip>
</template>
</template>
</v-list-item>
<span>{{ item.file_name }}</span>
</td>
</template>
<template #item.emulator="{ item }">
<v-chip size="x-small" color="orange" label>{{ item.emulator }}</v-chip>
</template>
<template #item.updated_at="{ item }">
<v-chip size="x-small" label>
{{ formatTimestamp(item.updated_at) }}
</v-chip>
</template>
<template #item.file_size_bytes="{ item }">
<v-chip size="x-small" label
>{{ formatBytes(item.file_size_bytes) }}
</v-chip>
</template>
<template #no-data
><span>No states found for {{ rom.name }}</span></template
>
Expand Down Expand Up @@ -203,6 +200,6 @@ onMounted(() => {
</template>
<style scoped>
.name-row {
min-width: 350px;
min-width: 300px;
}
</style>
Loading
Loading