Skip to content

Commit

Permalink
Merge pull request #1133 from rommapp/romm-1107
Browse files Browse the repository at this point in the history
[ROMM-1107] Add env variable to disable in-browser emulation
  • Loading branch information
gantoine authored Aug 29, 2024
2 parents 880e155 + f44d127 commit c55d63b
Show file tree
Hide file tree
Showing 14 changed files with 147 additions and 32 deletions.
29 changes: 20 additions & 9 deletions backend/config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@

load_dotenv()


def str_to_bool(value: str) -> bool:
return value.lower() in ("true", "1")


# GUNICORN
DEV_PORT: Final = int(os.environ.get("VITE_BACKEND_DEV_PORT", "5000"))
DEV_HOST: Final = "127.0.0.1"
Expand Down Expand Up @@ -53,35 +58,41 @@
ROMM_AUTH_SECRET_KEY: Final = os.environ.get(
"ROMM_AUTH_SECRET_KEY", secrets.token_hex(32)
)
DISABLE_CSRF_PROTECTION = os.environ.get("DISABLE_CSRF_PROTECTION", "false") == "true"
DISABLE_DOWNLOAD_ENDPOINT_AUTH = (
os.environ.get("DISABLE_DOWNLOAD_ENDPOINT_AUTH", "false") == "true"
DISABLE_CSRF_PROTECTION = str_to_bool(
os.environ.get("DISABLE_CSRF_PROTECTION", "false")
)
DISABLE_DOWNLOAD_ENDPOINT_AUTH = str_to_bool(
os.environ.get("DISABLE_DOWNLOAD_ENDPOINT_AUTH", "false")
)

# SCANS
SCAN_TIMEOUT: Final = int(os.environ.get("SCAN_TIMEOUT", 60 * 60 * 4)) # 4 hours

# TASKS
ENABLE_RESCAN_ON_FILESYSTEM_CHANGE: Final = (
os.environ.get("ENABLE_RESCAN_ON_FILESYSTEM_CHANGE", "false") == "true"
ENABLE_RESCAN_ON_FILESYSTEM_CHANGE: Final = str_to_bool(
os.environ.get("ENABLE_RESCAN_ON_FILESYSTEM_CHANGE", "false")
)
RESCAN_ON_FILESYSTEM_CHANGE_DELAY: Final = int(
os.environ.get("RESCAN_ON_FILESYSTEM_CHANGE_DELAY", 5) # 5 minutes
)
ENABLE_SCHEDULED_RESCAN: Final = (
os.environ.get("ENABLE_SCHEDULED_RESCAN", "false") == "true"
ENABLE_SCHEDULED_RESCAN: Final = str_to_bool(
os.environ.get("ENABLE_SCHEDULED_RESCAN", "false")
)
SCHEDULED_RESCAN_CRON: Final = os.environ.get(
"SCHEDULED_RESCAN_CRON",
"0 3 * * *", # At 3:00 AM every day
)
ENABLE_SCHEDULED_UPDATE_SWITCH_TITLEDB: Final = (
os.environ.get("ENABLE_SCHEDULED_UPDATE_SWITCH_TITLEDB", "false") == "true"
ENABLE_SCHEDULED_UPDATE_SWITCH_TITLEDB: Final = str_to_bool(
os.environ.get("ENABLE_SCHEDULED_UPDATE_SWITCH_TITLEDB", "false")
)
SCHEDULED_UPDATE_SWITCH_TITLEDB_CRON: Final = os.environ.get(
"SCHEDULED_UPDATE_SWITCH_TITLEDB_CRON",
"0 4 * * *", # At 4:00 AM every day
)

# EMULATION
DISABLE_EMULATOR_JS = str_to_bool(os.environ.get("DISABLE_EMULATOR_JS", "false"))
DISABLE_RUFFLE_RS = str_to_bool(os.environ.get("DISABLE_RUFFLE_RS", "false"))

# TESTING
IS_PYTEST_RUN: Final = bool(os.environ.get("PYTEST_VERSION", False))
6 changes: 6 additions & 0 deletions backend/endpoints/heartbeat.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
from config import (
DISABLE_EMULATOR_JS,
DISABLE_RUFFLE_RS,
ENABLE_RESCAN_ON_FILESYSTEM_CHANGE,
ENABLE_SCHEDULED_RESCAN,
ENABLE_SCHEDULED_UPDATE_SWITCH_TITLEDB,
Expand Down Expand Up @@ -55,4 +57,8 @@ def heartbeat() -> HeartbeatResponse:
"MESSAGE": "Updates the Nintendo Switch TitleDB file",
},
},
"EMULATION": {
"DISABLE_EMULATOR_JS": DISABLE_EMULATOR_JS,
"DISABLE_RUFFLE_RS": DISABLE_RUFFLE_RS,
},
}
6 changes: 6 additions & 0 deletions backend/endpoints/responses/heartbeat.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ class MetadataSourcesDict(TypedDict):
STEAMGRIDDB_ENABLED: bool


class EmulationDict(TypedDict):
DISABLE_EMULATOR_JS: bool
DISABLE_RUFFLE_RS: bool


class HeartbeatResponse(TypedDict):
VERSION: str
SHOW_SETUP_WIZARD: bool
Expand All @@ -30,3 +35,4 @@ class HeartbeatResponse(TypedDict):
ANY_SOURCE_ENABLED: bool
METADATA_SOURCES: MetadataSourcesDict
FS_PLATFORMS: list
EMULATION: EmulationDict
4 changes: 4 additions & 0 deletions env.template
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,7 @@ ENABLE_SCHEDULED_RESCAN=true
SCHEDULED_RESCAN_CRON=0 3 * * *
ENABLE_SCHEDULED_UPDATE_SWITCH_TITLEDB=true
SCHEDULED_UPDATE_SWITCH_TITLEDB_CRON=0 4 * * *

# In-browser emulation
DISABLE_EMULATOR_JS=false
DISABLE_RUFFLE_RS=false
2 changes: 2 additions & 0 deletions frontend/src/__generated__/index.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions frontend/src/__generated__/models/EmulationDict.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions frontend/src/__generated__/models/HeartbeatResponse.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions frontend/src/__generated__/models/TinfoilFeedSchema.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 18 additions & 0 deletions frontend/src/__generated__/models/TinfoilFeedTitleDBSchema.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 16 additions & 5 deletions frontend/src/components/Details/ActionBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,29 @@ import AdminMenu from "@/components/common/Game/AdminMenu.vue";
import romApi from "@/services/api/rom";
import storeDownload from "@/stores/download";
import type { DetailedRom } from "@/stores/roms";
import storeHeartbeat from "@/stores/heartbeat";
import type { Events } from "@/types/emitter";
import { getDownloadLink, isEJSEmulationSupported, isRuffleEmulationSupported } from "@/utils";
import {
getDownloadLink,
isEJSEmulationSupported,
isRuffleEmulationSupported,
} from "@/utils";
import type { Emitter } from "mitt";
import { inject, ref } from "vue";
import { inject, ref, computed } from "vue";
// Props
const props = defineProps<{ rom: DetailedRom }>();
const downloadStore = storeDownload();
const heartbeatStore = storeHeartbeat();
const emitter = inject<Emitter<Events>>("emitter");
const playInfoIcon = ref("mdi-play");
const ejsEmulationSupported = isEJSEmulationSupported(props.rom.platform_slug);
const ruffleEmulationSupported = isRuffleEmulationSupported(props.rom.platform_slug);
const ejsEmulationSupported = computed(() =>
isEJSEmulationSupported(props.rom.platform_slug, heartbeatStore.value),
);
const ruffleEmulationSupported = computed(() =>
isRuffleEmulationSupported(props.rom.platform_slug, heartbeatStore.value),
);
// Functions
async function copyDownloadLink(rom: DetailedRom) {
Expand All @@ -26,7 +37,7 @@ async function copyDownloadLink(rom: DetailedRom) {
getDownloadLink({
rom,
files: downloadStore.filesToDownload,
})
}),
);
if (navigator.clipboard && window.isSecureContext) {
await navigator.clipboard.writeText(downloadLink);
Expand Down
34 changes: 24 additions & 10 deletions frontend/src/components/common/Game/Card/ActionBar.vue
Original file line number Diff line number Diff line change
@@ -1,20 +1,34 @@
<script setup lang="ts">
import { computed } from "vue";
import AdminMenu from "@/components/common/Game/AdminMenu.vue";
import romApi from "@/services/api/rom";
import storeDownload from "@/stores/download";
import storeHeartbeat from "@/stores/heartbeat";
import type { SimpleRom } from "@/stores/roms";
import { isEJSEmulationSupported, isRuffleEmulationSupported } from "@/utils";
// Props
defineProps<{ rom: SimpleRom }>();
const props = defineProps<{ rom: SimpleRom }>();
const downloadStore = storeDownload();
const heartbeatStore = storeHeartbeat();
const ejsEmulationSupported = computed(() => {
return isEJSEmulationSupported(props.rom.platform_slug, heartbeatStore.value);
});
const ruffleEmulationSupported = computed(() => {
return isRuffleEmulationSupported(
props.rom.platform_slug,
heartbeatStore.value,
);
});
</script>

<template>
<v-row no-gutters>
<v-col>
<v-col class="d-flex">
<v-btn
class="action-bar-btn-small"
class="action-bar-btn-small flex-grow-1"
size="x-small"
:disabled="downloadStore.value.includes(rom.id)"
icon="mdi-download"
Expand All @@ -23,10 +37,10 @@ const downloadStore = storeDownload();
@click="romApi.downloadRom({ rom })"
/>
</v-col>
<v-col>
<v-col class="d-flex">
<v-btn
v-if="isEJSEmulationSupported(rom.platform_slug)"
class="action-bar-btn-small"
v-if="ejsEmulationSupported"
class="action-bar-btn-small flex-grow-1"
size="x-small"
@click="
$router.push({
Expand All @@ -39,8 +53,8 @@ const downloadStore = storeDownload();
variant="text"
/>
<v-btn
v-if="isRuffleEmulationSupported(rom.platform_slug)"
class="action-bar-btn-small"
v-if="ruffleEmulationSupported"
class="action-bar-btn-small flex-grow-1"
size="x-small"
@click="
$router.push({
Expand All @@ -56,7 +70,7 @@ const downloadStore = storeDownload();
<v-menu location="bottom">
<template #activator="{ props }">
<v-btn
class="action-bar-btn-small"
class="action-bar-btn-small flex-grow-1"
size="x-small"
v-bind="props"
icon="mdi-dots-vertical"
Expand All @@ -71,7 +85,7 @@ const downloadStore = storeDownload();

<style scoped>
.action-bar-btn-small {
max-width: 22px;
max-height: 30px;
width: unset;
}
</style>
22 changes: 18 additions & 4 deletions frontend/src/components/common/Game/Table.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import RAvatar from "@/components/common/Game/RAvatar.vue";
import romApi from "@/services/api/rom";
import storeDownload from "@/stores/download";
import storeRoms, { type SimpleRom } from "@/stores/roms";
import storeHeartbeat from "@/stores/heartbeat";
import type { Events } from "@/types/emitter";
import {
formatBytes,
Expand All @@ -30,6 +31,7 @@ const router = useRouter();
const route = useRoute();
const downloadStore = storeDownload();
const romsStore = storeRoms();
const heartbeatStore = storeHeartbeat();
const page = ref(parseInt(window.location.hash.slice(1)) || 1);
const storedRomsPerPage = parseInt(localStorage.getItem("romsPerPage") ?? "");
const itemsPerPage = ref(isNaN(storedRomsPerPage) ? 25 : storedRomsPerPage);
Expand Down Expand Up @@ -82,14 +84,22 @@ function rowClick(_: Event, row: { item: SimpleRom }) {
function updateDataTablePages() {
pageCount.value = Math.ceil(
romsStore.filteredRoms.length / itemsPerPage.value
romsStore.filteredRoms.length / itemsPerPage.value,
);
}
function updateUrlHash() {
window.location.hash = String(page.value);
}
function checkIfEJSEmulationSupported(platformSlug: string) {
return isEJSEmulationSupported(platformSlug, heartbeatStore.value);
}
function checkIfRuffleEmulationSupported(platformSlug: string) {
return isRuffleEmulationSupported(platformSlug, heartbeatStore.value);
}
watch(itemsPerPage, async () => {
localStorage.setItem("romsPerPage", itemsPerPage.value.toString());
updateDataTablePages();
Expand Down Expand Up @@ -137,7 +147,11 @@ onMounted(() => {
>
<template #append>
<v-chip
v-if="item.sibling_roms && item.sibling_roms.length > 0 && showSiblings"
v-if="
item.sibling_roms &&
item.sibling_roms.length > 0 &&
showSiblings
"
class="translucent-dark ml-2"
size="x-small"
>
Expand Down Expand Up @@ -176,7 +190,7 @@ onMounted(() => {
<v-icon>mdi-download</v-icon>
</v-btn>
<v-btn
v-if="isEJSEmulationSupported(item.platform_slug)"
v-if="checkIfEJSEmulationSupported(item.platform_slug)"
size="small"
@click.stop="
$router.push({
Expand All @@ -188,7 +202,7 @@ onMounted(() => {
<v-icon>mdi-play</v-icon>
</v-btn>
<v-btn
v-if="isRuffleEmulationSupported(item.platform_slug)"
v-if="checkIfRuffleEmulationSupported(item.platform_slug)"
size="small"
@click.stop="
$router.push({
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/stores/heartbeat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import type { HeartbeatResponse } from "@/__generated__";
import { defineStore } from "pinia";
import { computed } from "vue";

export type Heartbeat = HeartbeatResponse;

export default defineStore("heartbeat", {
state: () => {
return { value: {} as HeartbeatResponse };
Expand Down
Loading

0 comments on commit c55d63b

Please sign in to comment.