{"id":20641900,"url":"https://github.com/ungive/omega-api-decks","last_synced_at":"2025-04-16T01:38:01.130Z","repository":{"id":55865868,"uuid":"285712078","full_name":"ungive/omega-api-decks","owner":"ungive","description":"Generate an image for your deck or convert it to another parsable format","archived":false,"fork":false,"pushed_at":"2024-06-01T18:55:12.000Z","size":3887,"stargazers_count":14,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-11T19:58:47.910Z","etag":null,"topics":["api","decks","yugioh"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ungive.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-08-07T01:53:35.000Z","updated_at":"2025-02-13T20:52:08.000Z","dependencies_parsed_at":"2024-06-01T19:57:51.025Z","dependency_job_id":"910dc521-2945-40e9-8074-fd67ece14d68","html_url":"https://github.com/ungive/omega-api-decks","commit_stats":null,"previous_names":["jonasberge/omega-api-decks","ungive/omega-api-decks"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ungive%2Fomega-api-decks","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ungive%2Fomega-api-decks/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ungive%2Fomega-api-decks/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ungive%2Fomega-api-decks/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ungive","download_url":"https://codeload.github.com/ungive/omega-api-decks/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249182786,"owners_count":21226123,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","decks","yugioh"],"created_at":"2024-11-16T16:07:11.766Z","updated_at":"2025-04-16T01:38:01.110Z","avatar_url":"https://github.com/ungive.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"## omega-api-decks\n\n![Thumbnail showing a generated deck list image](examples/imageify/banner.jpg)\n\nThis is a service for converting a deck list to any of the following things:\n\n- another format\n- an image of the deck and all its cards\n- a `JSON` object containing all information about the deck\n\nIt can also be used to simply detect the format of your input.\n\n---\n\n### Configuration\n\nYou can configure the behaviour of the API in [`config/config.php`](config/config.php).\n\n### Environment Variables\n\nIn order to run this application, you need to configure some environment variables:\n\n```bash\nDATABASE_URL=https://example.com/database/cards.cdb\nCARD_IMAGE_LOOKUP_JSON_URL=https://example.com/image_urls.json\nCARD_IMAGE_URL=https://example.com/images\nCARD_IMAGE_URL_EXT=jpg\nREQUEST_TOKEN=somerandomstring\nREQUEST_TOKEN_IN_UI=true\nWEBHOOK_UPDATE_TOKEN=somerandomstring\nPORT=8080\n```\n\nAn example can be found in the file `.env.example`.\n\nURLs for images are built like this: `{CARD_IMAGE_URL}/{passcode}.{CARD_IMAGE_URL_EXT}`. There is also a `CARD_IMAGE_LOOKUP_JSON_URL` which should give a JSON file that maps card IDs (`passcode`) to a valid image URL. At least one of these options must be given. If both are given, the results of `CARD_IMAGE_URL` are preferred.\n\nThe `REQUEST_TOKEN` is optional and if present, requires a token in the URL path for authorized access to every API endpoint. Pass it as `?token=somerandomstring` with the value that is set in your env-file. Set `REQUEST_TOKEN_IN_UI` to `false`, `no` or `0` if you wish to hide the token in the web interface, which might be desirable if the token is used to make sure only authorized parties can use the API. By default, the token is visible through the UI, so users can convert deck codes with the web interface. At this time, the UI simply doesn't work if `REQUEST_TOKEN_IN_UI` is set to a falsey value (this might be updated in the future by implementing an option to disable the UI).\n\nThe `WEBHOOK_UPDATE_TOKEN` exists to prevent unauthorized requests to the [`webhook/update`](public/webhook/update.php) endpoint. It must be set and is separate from the `REQUEST_TOKEN`. Pass it as `?token=somerandomstring` with the value that is set in your env-file.\n\nMake sure you generate a secure (random) token and rebuild the container whenever you change any environment variables.\n\n### Production\n\nMake sure to create a `.env` file with above environment variables.\n\nRun the following commands and you're ready to go:\n\n```\n# docker compose up -d --build production\n# docker compose exec -u www-data production update-database\n# docker compose exec -u www-data production populate-cache\n```\n\n**NOTE**: It's important to run the above `exec` commands as the user `www-data`, otherwise created files will be owned by `root` and cannot be modified by the `httpd` instance when invoked through HTTP.\n\n[`update-database`](scripts/update-database.php) will automatically download and store the newest card database from your configured source (`DATABASE_URL`). This might take a bit depending of the size of the download and your bandwidth. After that you won't have to download it again.\n\nPopulating the image cache will take a while, as all card images are downloaded and scaled down. In case an image is missing in the local cache during a request, it is downloaded within that request and persisted locally. It's thus not strictly necessary to pre-populate the cache, but doing this will reduce the number of cache misses during any request and the delay that this process would cause to a minimum. Once an image is cached it will be reused by all subsequent requests. The images are scaled down to normalize their resolution and only store as much data as is necessary.\n\n### Development\n\nMake sure to create a `.env.dev` file with above environment variables.\n\nRun the following commands to set up your development environment:\n\n```\n# ./composer.sh install\n# docker compose up -d --build development\n# docker compose exec development update-database\n# scripts/permissions.sh\n```\n\nThe last command fixes permissions of the `data`-folder in the root of the project, so that it can be written to by the development container.\n\n---\n\n### Supported Deck Formats\n\n|Format|Identifier|\n|:-|:-:|\n|[**`YDK`**](examples/formats/ydk.txt)|`ydk`|\n|[**`YDKE`**](examples/formats/ydke.txt)|`ydke`|\n|[**`Omega code`**](examples/formats/omega.txt)|`omega`|\n|[**`List of card names`**](examples/formats/names.txt)|`names`|\n|[**`JSON object`**](examples/formats/json.json)|`json`|\n\nCards in the list of names are associated with a deck by the following rules:\n\n- The first 40 non-Extra Deck cards go to the Main Deck\n- The first 15 Extra Deck cards go to the Extra Deck\n- Up to 60 cards before the first Extra Deck card go to the Main Deck\n- The remaining cards are put into the Side Deck\n\nAlternatively, one can describe where cards belong by putting a line in front of them that contains the name of the respective deck (`main`, `side` or `extra`, case-insensitive), similar to how it works with the [`YDK`](examples/formats/ydk.txt) format.\n\n### Common Query Parameters\n\nAll endpoints have the following set of query parameters in common:\n\n**`?list=\u003cinput\u003e`** — A deck list in any format. This format may be any of the above and is detected on the fly.\n\n**`?\u003cidentifier\u003e=\u003cinput\u003e`** — `\u003cidentifier\u003e` may be any valid identifier and informs the service about the input format. This way the service does not have to guess based on the input. This is the recommended option in case the input format is known at the time of requesting this endpoint.\n\n`\u003cinput\u003e` resembles the deck list that is to be handled by the request.\n\nAll JSON endpoints also have the `?pretty` query parameter which formats JSON nicely.\n\n`NOTE`: Query parameters must be URL encoded (e.g. with `encodeURIComponent()` in JavaScript).\n\n---\n\n### Endpoints\n\n##### `/imageify`\nGenerates an image of the deck list like you know it from YGOPro and friends.  \nThe optional query parameter `\u0026quality=\u003cvalue\u003e` configures the resulting image quality. Accepts values from 0 (worst) to 100 (best).\n\n#### JSON endpoints\n\n##### `/detect`\nParses input and returns its format.\n\n##### `/parse`\nParses input and outputs deck information in form of a `JSON` object.\n\n##### `/convert`\nConverts a deck list from one format to all other formats.  \nThe optional query parameter `\u0026to=\u003cidentifier\u003e` restricts the conversion to only one format.\n\n#### JSON structure\n\nThe JSON for a successful response is structure in the following way:\n```json\n{\n  \"success\": true,\n  \"meta\": {\n    \"format\": \"\u003cidentifier\u003e\"\n  },\n  \"data\": {\n\n  }\n}\n```\nThe `meta` object contains meta information about the request like the type of the input.\nThe `data` object contains the generated data of the respective endpoint.\n\nAn erroneous request returns JSON of this structure:\n```json\n{\n  \"success\": false,\n  \"meta\": {\n    \"error\": \"\u003cmessage\u003e\"\n  },\n  \"data\": {}\n}\n```\nThe `error` field contains an error message describing why your request failed.\n\n---\n\n### Examples\n\nUsing the [JSON input from the examples directory](examples/formats/json.json):\n\n`GET /convert?pretty\u0026to=omega\u0026list={\"main\":[27204311,2720...`\n\nConverts the deck list to an Omega code. This is the response:\n```json\n{\n    \"success\": true,\n    \"meta\": {\n        \"format\": \"json\"\n    },\n    \"data\": {\n        \"formats\": {\n            \"omega\": \"0+a6LjWfEYbv\\/L\\/MAMIXps0AY4kjoiww\\/PbQdlYYFuz7zgDDKmaXWGB4zsmPjCC8uMSeGYRfys5kheHgpcuZQXj3GXs4XnDhIQscP7oGx\\/ll7xlguPCSLrM1cx1L\\/+bXjBYbk1k0uaWYg753MQcD8Ub3TWD8MGIuGIPsBNkBAA==\"\n        }\n    }\n}\n```\n\nYou can omit the `to` query parameter to get all formats:\n\n```json\n{\n    \"success\": true,\n    \"meta\": {\n        \"format\": \"json\"\n    },\n    \"data\": {\n        \"formats\": {\n            \"omega\": \"0+a6LjWfEYbv\\/L\\/MAMIXps0AY4kjoiww\\/PbQdlYYFuz7zgDDKmaXWGB4zsmPjCC8uMSeGYRfys5kheHgpcuZQXj3GXs4XnDhIQscP7oGx\\/ll7xlguPCSLrM1cx1L\\/+bXjBYbk1k0uaWYg753MQcD8Ub3TWD8MGIuGIPsBNkBAA==\",\n            \"ydke\": \"ydke:\\/\\/1xqfAdcanwHXGp8B3P\\/TANz\\/0wDQlpgA0JaYABjEFQQYxBUEGMQVBO3CtwXtwrcF7cK3BRGO9wARjvcAEY73ACQ20gQkNtIEJDbSBJzJ8QGcyfEBo3Q\\/A6N0PwPpHZkF6R2ZBekdmQVTpacDU6WnA7vMPwO7zD8Du8w\\/A6DQ4QSg0OEEoNDhBKDi1gSg4tYEoOLWBG927wBvdu8Ab3bvAA==!cdItAzsDfgSPs+sB!OLFjBCkLGgNS94oDU\\/eKA7FHsgOxR7ID4VidA+FYnQOjdD8DU6WnAw==!\",\n            \"ydk\": \"#main\\n27204311\\n27204311\\n27204311\\n13893596\\n13893596\\n10000080\\n10000080\\n68535320\\n68535320\\n68535320\\n95929069\\n95929069\\n95929069\\n16223761\\n16223761\\n16223761\\n80885284\\n80885284\\n80885284\\n32623004\\n32623004\\n54490275\\n54490275\\n93920745\\n93920745\\n93920745\\n61318483\\n61318483\\n54512827\\n54512827\\n54512827\\n81907872\\n81907872\\n81907872\\n81191584\\n81191584\\n81191584\\n15693423\\n15693423\\n15693423\\n#extra\\n53334641\\n75367227\\n32224143\\n!side\\n73642296\\n52038441\\n59438930\\n59438931\\n62015409\\n62015409\\n60643553\\n60643553\\n54490275\\n61318483\",\n            \"names\": \"3 Nibiru, the Primal Being\\n2 Exodius the Ultimate Forbidden Lord\\n2 The Winged Dragon of Ra - Sphere Mode\\n3 Fire Hand\\n3 Ice Hand\\n3 Thunder Hand\\n3 Ghostrick Jiangshi\\n2 Nopenguin\\n2 Ghostrick Yuki-onna\\n3 Penguin Soldier\\n2 Ghostrick Jackfrost\\n3 Ghostrick Lantern\\n3 Ghostrick Specter\\n3 Recurring Nightmare\\n3 Evenly Matched\\n\\n1 Ghostrick Angel of Mischief\\n1 Ghostrick Alucard\\n1 Ghostrick Socuteboss\\n\\n\\n1 Ghost Belle \u0026 Haunted Mansion\\n1 Ghost Mourner \u0026 Moonlit Chill\\n1 Ghost Ogre \u0026 Snow Rabbit\\n1 Ghost Ogre \u0026 Snow Rabbit\\n2 Ghost Reaper \u0026 Winter Cherries\\n2 Ghost Sister \u0026 Spooky Dogwood\\n1 Ghostrick Yuki-onna\\n1 Ghostrick Jackfrost\",\n            \"json\": \"{\\\"main\\\":[27204311,27204311,27204311,13893596,13893596,10000080,10000080,68535320,68535320,68535320,95929069,95929069,95929069,16223761,16223761,16223761,80885284,80885284,80885284,32623004,32623004,54490275,54490275,93920745,93920745,93920745,61318483,61318483,54512827,54512827,54512827,81907872,81907872,81907872,81191584,81191584,81191584,15693423,15693423,15693423],\\\"extra\\\":[53334641,75367227,32224143],\\\"side\\\":[73642296,52038441,59438930,59438931,62015409,62015409,60643553,60643553,54490275,61318483]}\"\n        }\n    }\n}\n```\n\nUsing the `/imageify` endpoint, you might generate an image like this:\n\n![Image of a Deck List](/examples/imageify/deck-list.jpeg)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fungive%2Fomega-api-decks","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fungive%2Fomega-api-decks","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fungive%2Fomega-api-decks/lists"}