From 5248989b08e4543e01cb76b3b62e6d62a52987aa Mon Sep 17 00:00:00 2001 From: DrMxrcy <58747968+DrMxrcy@users.noreply.github.com> Date: Tue, 4 Apr 2023 16:46:31 -0400 Subject: [PATCH] Add Romm (#310) * Add Romm * Update docker-compose.yml * Remove Comments * Review Updates * Update config.json --- apps/romm/config.json | 44 ++++++++ apps/romm/data/config.yml | 0 apps/romm/docker-compose.yml | 48 +++++++++ apps/romm/metadata/description.md | 170 ++++++++++++++++++++++++++++++ apps/romm/metadata/logo.jpg | Bin 0 -> 9778 bytes 5 files changed, 262 insertions(+) create mode 100644 apps/romm/config.json create mode 100644 apps/romm/data/config.yml create mode 100644 apps/romm/docker-compose.yml create mode 100644 apps/romm/metadata/description.md create mode 100644 apps/romm/metadata/logo.jpg diff --git a/apps/romm/config.json b/apps/romm/config.json new file mode 100644 index 00000000..f7618532 --- /dev/null +++ b/apps/romm/config.json @@ -0,0 +1,44 @@ +{ + "$schema": "../schema.json", + "name": "RomM", + "port": 8178, + "available": true, + "exposable": true, + "id": "romm", + "tipi_version": 1, + "version": "1.6.2", + "categories": ["gaming"], + "description": "RomM (Rom Manager) is a web based retro roms manager integrated with IGDB.", + "short_desc": "RomM (Rom Manager) is a web based retro roms manager integrated with IGDB.", + "author": "Zurdi15", + "source": "https://github.com/zurdi15/romm", + "form_fields": [ + { + "type": "random", + "label": "ROMM_MYSQL_PASSWORD", + "min": 32, + "env_variable": "ROMM_MYSQL_PASSWORD" + }, + { + "type": "text", + "label": "IGDB Client ID", + "hint": "IGDB Client ID", + "required": true, + "env_variable": "ROMM_IGDB_CLIENT_ID" + }, + { + "type": "text", + "label": "IGDB Client Secret", + "hint": "IGDB Client Secret", + "required": true, + "env_variable": "ROMM_IGDB_CLIENT_SECRET" + }, + { + "type": "text", + "label": "Steam Grid DB API", + "hint": "Steam Grid DB API", + "required": false, + "env_variable": "ROMM_STEAMGRIDDB_API_KEY" + } + ] +} diff --git a/apps/romm/data/config.yml b/apps/romm/data/config.yml new file mode 100644 index 00000000..e69de29b diff --git a/apps/romm/docker-compose.yml b/apps/romm/docker-compose.yml new file mode 100644 index 00000000..0e24e6a6 --- /dev/null +++ b/apps/romm/docker-compose.yml @@ -0,0 +1,48 @@ +version: "3" + +services: + romm: + image: zurdi15/romm:1.6.2 + container_name: romm + environment: + - ROMM_DB_DRIVER=mariadb + - DB_HOST=romm-db + - DB_PORT=3306 + - DB_USER=tipi + - DB_NAME=romm + - DB_PASSWD=${ROMM_MYSQL_PASSWORD} + - CLIENT_ID=${ROMM_IGDB_CLIENT_ID} + - CLIENT_SECRET=${ROMM_IGDB_CLIENT_SECRET} + - STEAMGRIDDB_API_KEY="${ROMM_STEAMGRIDDB_API_KEY}" + restart: unless-stopped + volumes: + - ${ROOT_FOLDER_HOST}/media/data/roms:/romm/library + - ${APP_DATA_DIR}/data/romm-resources:/romm/resources + - ${APP_DATA_DIR}/data/config.yml:/romm/config.yml + ports: + - ${APP_PORT}:80 + depends_on: + - romm-db + networks: + - tipi_main_network + labels: + traefik.enable: ${APP_EXPOSED} + traefik.http.routers.romm.rule: Host(`${APP_DOMAIN}`) + traefik.http.routers.romm.entrypoints: websecure + traefik.http.routers.romm.service: romm + traefik.http.routers.romm.tls.certresolver: myresolver + traefik.http.services.romm.loadbalancer.server.port: 80 + + romm-db: + image: lscr.io/linuxserver/mariadb:latest + container_name: romm-db + environment: + - MYSQL_ROOT_PASSWORD=${ROMM_MYSQL_PASSWORD} + - MYSQL_DATABASE=romm + - MYSQL_USER=tipi + - MYSQL_PASSWORD=${ROMM_MYSQL_PASSWORD} + volumes: + - ${APP_DATA_DIR}/data/mysql/config:/config + restart: "unless-stopped" + networks: + - tipi_main_network \ No newline at end of file diff --git a/apps/romm/metadata/description.md b/apps/romm/metadata/description.md new file mode 100644 index 00000000..6e0683ea --- /dev/null +++ b/apps/romm/metadata/description.md @@ -0,0 +1,170 @@ +# Overview + +Inspired by [Jellyfin](https://jellyfin.org/) and after found that the awesome [Gameyfin](https://github.com/grimsi/gameyfin) project is not supported for arm64 architectures and it is a general game library manager, I decided to develop my own game library solution, focused on retro gaming. + +For now, it is only available as a docker [image](https://hub.docker.com/r/zurdi15/romm) (amd64/arm64) + +## [](https://github.com/zurdi15/romm#-features)⚡ Features + +- Scans your game library (all at once or by platform) and enriches it with IGDB metadata +- Access your library via your web-browser +- Possibility to select one of the matching IGDB results if the scan doesn't get the right one +- EmuDeck folder structure compatibility +- Download games directly from your web-browser +- Edit your game files directly from your web-browser +- Region, revision/version and extra tags support +- Works with SQLite or MaridDB (SQLite by default) +- Responsive design +- Light and dark theme + +## [](https://github.com/zurdi15/romm#-roadmap)🛠 Roadmap + +- Upload games directly from your web-browser - [issue #54](https://github.com/zurdi15/romm/issues/54) +- Manage save files directly from your web-browser - [issue #55](https://github.com/zurdi15/romm/issues/55) +- Set a custom cover for each game - [issue #53](https://github.com/zurdi15/romm/issues/53) +- Multiple files games support - [issue #40](https://github.com/zurdi15/romm/issues/40) + +# [](https://github.com/zurdi15/romm#prerequisites)Prerequisites + +## [](https://github.com/zurdi15/romm#️-folder-structure)⚠️ Folder structure + +RomM accepts two different folder structure by priority. + +RomM will try to find the structure 1 and if it doesn't exists, RomM will try to find structure 2. + +- Structure 1 (priority high) - roms folder at root of library folder: + +``` +library/ +├─ roms/ + ├─ gbc/ + │ ├─ rom_1.gbc + │ ├─ rom_2.gbc + │ + ├─ gba/ + │ ├─ rom_1.gba + │ ├─ rom_2.gba + │ + ├─ gb/ + ├─ rom_1.gb + ├─ rom_1.gb +``` + +- Structure 2 (priority low) - roms folder inside each platform folder + +``` +library/ +├─ gbc/ +│ ├─ roms/ +│ ├─ rom_1.gbc +│ ├─ rom_2.gbc +| +├─ gba/ +│ ├─ roms/ +│ ├─ rom_1.gba +│ ├─ rom_2.gba +| +├─ gb/ +│ ├─ roms/ +│ ├─ rom_1.gb +│ ├─ rom_1.gb +``` + +# [](https://github.com/zurdi15/romm#configuration)Configuration + +## [](https://github.com/zurdi15/romm#️-config-yml-file)⚙️ Config yml file + +RomM can be configured through a yml file. This is used to exclude folders and files with a certain extension to be scanned. For a configuration change to take effect, RomM must be restarted. + +Config file example: + +``` +exclude: + folders: + - 'folder_1_to_exclude' + - 'folder_2_to_exclude' + files: + - 'txt' + - 'file_extension_to_exclude' +``` + +# [](https://github.com/zurdi15/romm#naming-convention)Naming convention + +## [](https://github.com/zurdi15/romm#-platforms-support)🎮 Platforms support + +If the RomM [folder structure](https://github.com/zurdi15/romm#%E2%9A%A0%EF%B8%8F-folder-structure) is followed, any kind of platform/folder-name is supported for the core features. For having extra metadata as well as cover images and platforms icons, the following table shows how to name your platforms folders. This will change over the time, adding games metadata for more platforms. Make sure that the platforms folder names are lowercase. + +| slug | name | games metadata | +| --- | --- | :-: | +| 3ds | Nintendo 3DS | ✅ | +| amiga | Amiga | ✅ | +| arcade | Arcade | ✅ | +| atari | atari | ❌ | +| coleco | coleco | ❌ | +| c64 | Commodore C64/128/MAX | ✅ | +| cpc | cpc | ❌ | +| cps1 | cps1 | ❌ | +| cps2 | cps2 | ❌ | +| cps3 | cps3 | ❌ | +| daphne | daphne | ❌ | +| dc | Dreamcast | ✅ | +| dos | DOS | ✅ | +| fairchild | fairchild | ❌ | +| fba2012 | fba2012 | ❌ | +| fbneo | fbneo | ❌ | +| fds | Family Computer Disk System | ✅ | +| gb | Game Boy | ✅ | +| gba | Game Boy Advance | ✅ | +| gbc | Game Boy Color | ✅ | +| gg | gg | ❌ | +| gw | gw | ❌ | +| intellivision | Intellivision | ✅ | +| jaguar | Atari Jaguar | ✅ | +| lynx | Atari Lynx | ✅ | +| md | md | ❌ | +| megaduck | megaduck | ❌ | +| ms | ms | ❌ | +| msx | MSX | ✅ | +| n64 | Nintendo 64 | ✅ | +| nds | Nintendo DS | ✅ | +| neocd | neocd | ❌ | +| neogeo | neogeo | ❌ | +| nes | Nintendo Entertainment System | ✅ | +| ngc | Nintendo GameCube | ✅ | +| ngp | ngp | ❌ | +| odyssey | odyssey | ❌ | +| pce | pce | ❌ | +| pcecd | pcecd | ❌ | +| pico | pico | ❌ | +| poke | poke | ❌ | +| ps | PlayStation | ✅ | +| ps2 | PlayStation 2 | ✅ | +| ps3 | PlayStation 3 | ✅ | +| ps4 | ps4 | ❌ | +| psp | PlayStation Portable | ✅ | +| psvita | PlayStation Vita | ✅ | +| scummvm | scummvm | ❌ | +| segacd | Sega CD | ✅ | +| segasgone | segasgone | ❌ | +| sgb | sgb | ❌ | +| sgfx | sgfx | ❌ | +| snes | Super Nintendo Entertainment System | ✅ | +| supervision | supervision | ❌ | +| switch | Nintendo Switch | ✅ | +| wii | Wii | ✅ | +| win | PC (Microsoft Windows) | ✅ | +| wiiu | Wii U | ✅ | +| xbox | Xbox | ✅ | +| xbox360 | Xbox 360 | ✅ | +| xboxone | Xbox One | ✅ | + +## [](https://github.com/zurdi15/romm#-tags-support)📑 Tags support + +Games can be tagged with region, revision or other tags using parenthesis in the file name. Region and revision tags must be built with the following reserved words: + +- Region tags must be prefixed with **"reg-"**: (reg-EUR) / (reg-USA) / (reg-Japan) / (reg-whatever) +- Revision tags must be prefixed with **"rev-"**: (rev-1) / (rev-v2) / (rev-whatever) +- Any other tag can have any structure +- Example: **my\_game (reg-EUR)(rev-1)(aditional\_tag\_1)(aditional\_tag\_2).gba** + +Tags can be used with the search bar to help to filter your library. diff --git a/apps/romm/metadata/logo.jpg b/apps/romm/metadata/logo.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6f798ac69dc544ad948925997a7e888644c469f8 GIT binary patch literal 9778 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 literal 0 HcmV?d00001