Compare commits

...

19 Commits

Author SHA1 Message Date
kramo
1b654de6c9 v0.1.2 2023-02-01 16:45:48 +01:00
kramo
9242801395 Update screenshot 2023-02-01 16:39:50 +01:00
kramo
a9a5a1d3c2 Rename to Cartridges 2023-02-01 16:34:26 +01:00
kramo
de4fd79144 Update icons 2023-01-31 18:39:43 +01:00
kramo
077bfd5c10 Merge pull request #1 from imLinguin/heroic_improvements
Improve images import from Heroic
2023-01-30 18:32:29 +01:00
Paweł Lidwin
7351d26469 Fix flatpak manifest 2023-01-30 18:19:29 +01:00
Paweł Lidwin
08729a1dba Improve images import from Heroic 2023-01-30 18:18:38 +01:00
kramo
3d2c26937d Gtk.FileDialog syntax 2023-01-29 14:46:57 +01:00
kramo
6d72292c2d Update icon 2023-01-29 14:35:44 +01:00
kramo
99e6cbf169 Support for Heroic import 2023-01-29 14:27:27 +01:00
kramo
4759357764 Remove arbitrary full session bus access 2023-01-29 10:49:24 +01:00
kra-mo
731ed439d5 Update GTK code style 2023-01-14 23:47:27 +01:00
kramo
e3181adfc2 Update icon 2023-01-13 14:09:36 +01:00
kra-mo
26ebc45095 Update for Gtk.FileDialog 2023-01-04 17:21:43 +01:00
kramo
ffa926dc7c Update README.md 2022-12-26 15:27:51 +01:00
kramo
2d27493f91 Update README.md 2022-12-26 15:27:26 +01:00
kra-mo
3b4e946111 Update README.md 2022-12-26 15:18:26 +01:00
kra-mo
728ac4a9df Create screenshot.webp 2022-12-26 15:17:00 +01:00
kramo
2a897a3832 Update README.md 2022-12-26 15:13:10 +01:00
38 changed files with 995 additions and 586 deletions

View File

@@ -1,2 +1,50 @@
# game-shelf
A GTK4 + Libadwaita game launcher <div align="center">
<img src="data/icons/hicolor/scalable/apps/hu.kramo.Cartridges.svg" width="128" height="128">
# Cartridges
A GTK4 + Libadwaita game launcher
<img src="data/screenshot.webp">
</div>
## The Project
Cartridges is a simple game launcher written in Python using GTK4 + Libadwaita.
### Features
- Manually adding and editing games
- Importing games from Steam and Heroic
- Hiding games
- Searching and sorting by title, date added and last played
## Building
### GNOME Builder
1. Download [GNOME Builder](https://flathub.org/apps/details/org.gnome.Builder).
2. Click "Clone Repository" with `https://github.com/kra-mo/game-shelf.git` as the URL.
3. Click on the build button (hammer) at the top.
4. Install `org.gnome.Platform` from the [gnome-nightly repository](https://wiki.gnome.org/Apps/Nightly) if needed.
## Installation
### From Releases
1. Install `org.gnome.Platform` from the [gnome-nightly repository](https://wiki.gnome.org/Apps/Nightly) if needed.
2. Download the latest release from Releases.
3. Install it via GNOME Software or `flatpak install hu.kramo.Cartridges.flatpak`.
### From GNOME Builder
Click the down arrow next to the hammer at the top of your GNOME Builder window, then click "Export". This will create a flatpak that then can be installed on your system.
## Contributing
### Code
Fork the repository, make your changes, then create a pull request.
### Translations
Currently, translations can be added manually with the following steps:
1. Clone the repository.
2. If it isn't already there, add your language to `/po/LINGUAS`.
3. Create a new translation from the `/po/cartridges.pot` file with a program such as [Poedit](https://poedit.net/).
4. Save the file as `[YOUR LANGUAGE CODE].po` to `/po/`.
5. Create a pull request with your translations.

View File

@@ -1,7 +1,7 @@
[Desktop Entry] [Desktop Entry]
Name=Game Shelf Name=Cartridges
Exec=gameshelf Exec=cartridges
Icon=hu.kramo.GameShelf Icon=hu.kramo.Cartridges
Terminal=false Terminal=false
Type=Application Type=Application
Categories=Game; Categories=Game;

View File

@@ -1,11 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<schemalist gettext-domain="gameshelf"> <schemalist gettext-domain="cartridges">
<schema id="hu.kramo.GameShelf" path="/hu/kramo/GameShelf/"> <schema id="hu.kramo.Cartridges" path="/hu/kramo/Cartridges/">
<key name="exit-after-launch" type="b"> <key name="exit-after-launch" type="b">
<default>false</default> <default>false</default>
</key> </key>
<key name="heroic-import-epic" type="b">
<default>true</default>
</key>
<key name="heroic-import-gog" type="b">
<default>true</default>
</key>
<key name="heroic-import-sideload" type="b">
<default>true</default>
</key>
<key name="steam-location" type="s"> <key name="steam-location" type="s">
<default>"~/.steam/"</default> <default>"~/.steam/"</default>
</key>
<key name="heroic-location" type="s">
<default>"~/.var/app/com.heroicgameslauncher.hgl/config/heroic/"</default>
</key> </key>
<key name="sort-mode" type="s"> <key name="sort-mode" type="s">
<choices> <choices>

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<component type="desktop-application">
<id>hu.kramo.Cartridges.desktop</id>
<metadata_license>CC0-1.0</metadata_license>
<project_license>GPL-3.0-or-later</project_license>
<name>Cartridges</name>
<summary>Launch all your games</summary>
<description>
<p>Cartridges is a simple game launcher. It has support for importing your games from Steam and Heroic with organizational features such as hiding and sorting by date added or last played.</p>
</description>
<launchable type="desktop-id">hu.kramo.Cartridges.desktop</launchable>
<developer_name>kramo</developer_name>
</component>

View File

@@ -1,13 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<component type="desktop-application">
<id>hu.kramo.GameShelf.desktop</id>
<metadata_license>CC0-1.0</metadata_license>
<project_license>GPL-3.0-or-later</project_license>
<name>Game Shelf</name>
<summary>Launch all your games</summary>
<description>
<p>Game Shelf is a simple game launcher. It has support for importing your games from Steam with organizational features such as hiding and sorting by date added or last played.</p>
</description>
<launchable type="desktop-id">hu.kramo.GameShelf.desktop</launchable>
<developer_name>kramo</developer_name>
</component>

View File

@@ -0,0 +1,33 @@
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" fill="none">
<path fill="url(#a)" d="M111 29H17a8 8 0 0 0-8 8v70a8 8 0 0 0 8 8h94a8 8 0 0 0 8-8V37a8 8 0 0 0-8-8Z"/>
<path fill="#C061CB" d="M111 29H17c-4.418 0-8 3.681-8 8.222v57.556c0 4.54 3.582 8.222 8 8.222h94c4.418 0 8-3.681 8-8.222V37.222c0-4.54-3.582-8.222-8-8.222Z"/>
<path fill="#000" d="M84 42H44a4 4 0 0 0-4 4v40a4 4 0 0 0 4 4h40a4 4 0 0 0 4-4V46a4 4 0 0 0-4-4Z"/>
<path fill="url(#b)" d="M81 50H47a2 2 0 0 0-2 2v28a2 2 0 0 0 2 2h34a2 2 0 0 0 2-2V52a2 2 0 0 0-2-2Z"/>
<path fill="#000" d="M102 61v-1a5 5 0 0 0-10 0v1a5 5 0 0 0 10 0ZM114 55v-1a5 5 0 0 0-10 0v1a5 5 0 0 0 10 0Z"/>
<path fill="#3D3846" d="M97 64c2.761 0 5-2.015 5-4.5S99.761 55 97 55s-5 2.015-5 4.5 2.239 4.5 5 4.5ZM109 58c2.761 0 5-2.015 5-4.5s-2.239-4.5-5-4.5-5 2.015-5 4.5 2.239 4.5 5 4.5Z"/>
<path fill="#000" d="M29 56.5a3.5 3.5 0 1 0-7 0v13a3.5 3.5 0 1 0 7 0v-13Z"/>
<path fill="#000" d="M33 58H18a3 3 0 0 0-3 3v2a3 3 0 0 0 3 3h15a3 3 0 0 0 3-3v-2a3 3 0 0 0-3-3Z"/>
<path fill="#3D3846" d="M29 54.5a3.5 3.5 0 1 0-7 0v13a3.5 3.5 0 1 0 7 0v-13Z"/>
<path fill="#3D3846" d="M33 58H18a3 3 0 1 0 0 6h15a3 3 0 1 0 0-6Z"/>
<path fill="#000" d="M71 109a2 2 0 1 1 4 0 2 2 0 0 1-4 0Z"/>
<path fill="#9141AC" d="M71.063 108.5a2 2 0 0 0 3.874 0 1.999 1.999 0 0 1-2.817 2.294 1.996 1.996 0 0 1-1.057-2.294Z"/>
<path fill="#000" d="M66 107H56a2 2 0 1 0 0 4h10a2 2 0 1 0 0-4Z"/>
<path fill="#9141AC" d="M54.063 108.5A2 2 0 0 0 56 111h10a2.005 2.005 0 0 0 1.582-.775 1.996 1.996 0 0 0 .355-1.725A1.999 1.999 0 0 1 66 110H56a1.998 1.998 0 0 1-1.937-1.5Z"/>
<path fill="#613583" d="M110 74H96a1 1 0 1 0 0 2h14a1 1 0 0 0 0-2ZM110 79H96a1 1 0 1 0 0 2h14a1 1 0 0 0 0-2ZM110 84H96a1 1 0 1 0 0 2h14a1 1 0 0 0 0-2Z"/>
<path fill="#000" d="M21.5 79h-3a2.5 2.5 0 0 0 0 5h3a2.5 2.5 0 0 0 0-5ZM32.5 79h-3a2.5 2.5 0 0 0 0 5h3a2.5 2.5 0 0 0 0-5Z"/>
<path fill="#3D3846" d="M22 79h-4a2 2 0 1 0 0 4h4a2 2 0 1 0 0-4ZM33 79h-4a2 2 0 1 0 0 4h4a2 2 0 1 0 0-4Z"/>
<defs>
<linearGradient id="a" x1="9" x2="119" y1="115" y2="115" gradientUnits="userSpaceOnUse">
<stop stop-color="#613583"/>
<stop offset=".05" stop-color="#9141AC"/>
<stop offset=".22" stop-color="#613583"/>
<stop offset=".78" stop-color="#613583"/>
<stop offset=".95" stop-color="#9141AC"/>
<stop offset="1" stop-color="#613583"/>
</linearGradient>
<linearGradient id="b" x1="45" x2="45" y1="50" y2="82" gradientUnits="userSpaceOnUse">
<stop stop-color="#BDD0D5"/>
<stop offset="1" stop-color="#305749"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@@ -1,22 +0,0 @@
<svg width="128" height="128" viewBox="0 0 128 128" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="20" y="8" width="88" height="112" rx="9" fill="#C64600"/>
<rect x="20" y="8" width="88" height="95" rx="9" fill="#FF7800"/>
<rect x="26" y="14" width="76" height="50" rx="4" fill="black"/>
<rect x="38" y="20" width="52" height="38" rx="4" fill="url(#paint0_linear_5_31)"/>
<rect x="54" y="107" width="9" height="9" rx="4.5" fill="#241F31"/>
<rect x="70" y="109" width="5" height="5" rx="2.5" fill="#241F31"/>
<rect x="40" y="73" width="7" height="21" rx="3.5" fill="black"/>
<rect x="54" y="80" width="7" height="21" rx="3.5" transform="rotate(90 54 80)" fill="black"/>
<rect x="40" y="72" width="7" height="21" rx="3.5" fill="#241F31"/>
<rect x="54" y="79" width="7" height="21" rx="3.5" transform="rotate(90 54 79)" fill="#241F31"/>
<rect x="80" y="80" width="11" height="11" rx="5.5" transform="rotate(90 80 80)" fill="black"/>
<rect x="94" y="73" width="11" height="11" rx="5.5" transform="rotate(90 94 73)" fill="black"/>
<rect x="80" y="79" width="11" height="11" rx="5.5" transform="rotate(90 80 79)" fill="#241F31"/>
<rect x="94" y="72" width="11" height="11" rx="5.5" transform="rotate(90 94 72)" fill="#241F31"/>
<defs>
<linearGradient id="paint0_linear_5_31" x1="38" y1="20" x2="38" y2="58" gradientUnits="userSpaceOnUse">
<stop stop-color="#597E53"/>
<stop offset="1" stop-color="#97AE79"/>
</linearGradient>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M3 3C1.89543 3 1 3.89543 1 5V11C1 12.1046 1.89543 13 3 13H13C14.1046 13 15 12.1046 15 11V5C15 3.89543 14.1046 3 13 3H3ZM6 5C5.44772 5 5 5.44772 5 6V10C5 10.5523 5.44772 11 6 11H10C10.5523 11 11 10.5523 11 10V6C11 5.44772 10.5523 5 10 5H6ZM12 8C12 7.44772 12.4477 7 13 7C13.5523 7 14 7.44772 14 8C14 8.55228 13.5523 9 13 9C12.4477 9 12 8.55228 12 8ZM3 7C2.44772 7 2 7.44772 2 8C2 8.55228 2.44772 9 3 9C3.55228 9 4 8.55228 4 8C4 7.44772 3.55228 7 3 7Z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 618 B

View File

@@ -1,3 +0,0 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M3 1C2.44772 1 2 1.44772 2 2V14C2 14.5523 2.44772 15 3 15H13C13.5523 15 14 14.5523 14 14V2C14 1.44772 13.5523 1 13 1H3ZM5 2C4.44772 2 4 2.44772 4 3V6C4 6.55228 4.44772 7 5 7H11C11.5523 7 12 6.55228 12 6V3C12 2.44772 11.5523 2 11 2H5ZM4 10.5C4 9.67157 4.67157 9 5.5 9C6.32843 9 7 9.67157 7 10.5C7 11.3284 6.32843 12 5.5 12C4.67157 12 4 11.3284 4 10.5ZM10 9C9.44772 9 9 9.44771 9 10C9 10.5523 9.44771 11 10 11H11C11.5523 11 12 10.5523 12 10C12 9.44771 11.5523 9 11 9H10Z" fill="black"/>
</svg>

Before

Width:  |  Height:  |  Size: 637 B

View File

@@ -1,4 +1,4 @@
application_id = 'hu.kramo.GameShelf' application_id = 'hu.kramo.Cartridges'
scalable_dir = join_paths('hicolor', 'scalable', 'apps') scalable_dir = join_paths('hicolor', 'scalable', 'apps')
install_data( install_data(

View File

@@ -1,6 +1,6 @@
desktop_file = i18n.merge_file( desktop_file = i18n.merge_file(
input: 'hu.kramo.GameShelf.desktop.in', input: 'hu.kramo.Cartridges.desktop.in',
output: 'hu.kramo.GameShelf.desktop', output: 'hu.kramo.Cartridges.desktop',
type: 'desktop', type: 'desktop',
po_dir: '../po', po_dir: '../po',
install: true, install: true,
@@ -13,8 +13,8 @@ if desktop_utils.found()
endif endif
appstream_file = i18n.merge_file( appstream_file = i18n.merge_file(
input: 'hu.kramo.GameShelf.metainfo.xml.in', input: 'hu.kramo.Cartridges.metainfo.xml.in',
output: 'hu.kramo.GameShelf.metainfo.xml', output: 'hu.kramo.Cartridges.metainfo.xml',
po_dir: '../po', po_dir: '../po',
install: true, install: true,
install_dir: join_paths(get_option('datadir'), 'metainfo') install_dir: join_paths(get_option('datadir'), 'metainfo')
@@ -25,7 +25,7 @@ if appstream_util.found()
test('Validate appstream file', appstream_util, args: ['validate', appstream_file]) test('Validate appstream file', appstream_util, args: ['validate', appstream_file])
endif endif
install_data('hu.kramo.GameShelf.gschema.xml', install_data('hu.kramo.Cartridges.gschema.xml',
install_dir: join_paths(get_option('datadir'), 'glib-2.0/schemas') install_dir: join_paths(get_option('datadir'), 'glib-2.0/schemas')
) )

BIN
data/screenshot.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 876 KiB

View File

@@ -1,17 +1,18 @@
{ {
"app-id" : "hu.kramo.GameShelf", "app-id" : "hu.kramo.Cartridges",
"runtime" : "org.gnome.Platform", "runtime" : "org.gnome.Platform",
"runtime-version" : "master", "runtime-version" : "master",
"sdk" : "org.gnome.Sdk", "sdk" : "org.gnome.Sdk",
"command" : "gameshelf", "command" : "cartridges",
"finish-args" : [ "finish-args" : [
"--share=ipc", "--share=ipc",
"--socket=fallback-x11", "--socket=fallback-x11",
"--device=dri", "--device=dri",
"--socket=wayland", "--socket=wayland",
"--socket=session-bus", "--talk-name=org.freedesktop.Flatpak",
"--filesystem=xdg-run/gvfsd", "--filesystem=xdg-run/gvfsd",
"--filesystem=~/.steam/steam/" "--filesystem=~/.steam/steam/",
"--filesystem=~/.var/app/com.heroicgameslauncher.hgl/config/heroic/"
], ],
"cleanup" : [ "cleanup" : [
"/include", "/include",
@@ -26,13 +27,13 @@
], ],
"modules" : [ "modules" : [
{ {
"name" : "gameshelf", "name" : "cartridges",
"builddir" : true, "builddir" : true,
"buildsystem" : "meson", "buildsystem" : "meson",
"sources" : [ "sources" : [
{ {
"type" : "git", "type" : "dir",
"url" : "file:///home/kramo/Projects" "path" : "."
} }
] ]
} }

View File

@@ -1,5 +1,5 @@
project('gameshelf', project('cartridges',
version: '0.1.0', version: '0.1.2',
meson_version: '>= 0.59.0', meson_version: '>= 0.59.0',
default_options: [ 'warning_level=2', 'werror=false', ], default_options: [ 'warning_level=2', 'werror=false', ],
) )

View File

@@ -1,6 +1,3 @@
data/hu.kramo.GameShelf.desktop.in
data/hu.kramo.GameShelf.metainfo.xml.in
src/main.py src/main.py
src/window.py src/window.py
src/window.blp src/window.blp
@@ -12,3 +9,5 @@ src/gtk/preferences.blp
src/utils/create_details_window.py src/utils/create_details_window.py
src/utils/create_dialog.py src/utils/create_dialog.py
src/utils/steam_parser.py
src/utils/heroic_parser.py

302
po/cartridges.pot Normal file
View File

@@ -0,0 +1,302 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-01-29 14:12+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
#. Create toast for undoing the remove action
#: src/main.py:133
msgid "removed"
msgstr ""
#: src/main.py:134
msgid "Undo"
msgstr ""
#: src/window.py:195
msgid "Today"
msgstr ""
#: src/window.py:197
msgid "Yesterday"
msgstr ""
#: src/window.py:221
msgid "Added: "
msgstr ""
#: src/window.py:222
msgid "Last played: "
msgstr ""
#: src/window.py:222
msgid "Last played: Never"
msgstr ""
#: src/window.blp:6 src/window.blp:14 src/utils/steam_parser.py:98
#: src/utils/heroic_parser.py:153
msgid "No Games Found"
msgstr ""
#: src/window.blp:7
msgid "Try a different search."
msgstr ""
#: src/window.blp:15
msgid "Use the + button to add games."
msgstr ""
#: src/window.blp:22
msgid "No Hidden Games"
msgstr ""
#: src/window.blp:23
msgid "Games you hide will appear here."
msgstr ""
#: src/window.blp:29
msgid "Cartridges"
msgstr ""
#: src/window.blp:52
msgid "Game Details"
msgstr ""
#: src/window.blp:90
msgid "Game Title"
msgstr ""
#: src/window.blp:132 src/gtk/game.blp:62 src/gtk/game.blp:88
msgid "Play"
msgstr ""
#: src/window.blp:241
msgid "Hidden Games"
msgstr ""
#: src/window.blp:299
msgid "Sort"
msgstr ""
#: src/window.blp:302
msgid "A-Z"
msgstr ""
#: src/window.blp:308
msgid "Z-A"
msgstr ""
#: src/window.blp:314
msgid "Newest"
msgstr ""
#: src/window.blp:320
msgid "Oldest"
msgstr ""
#: src/window.blp:326
msgid "Last Played"
msgstr ""
#: src/window.blp:333
msgid "Show Hidden"
msgstr ""
#: src/window.blp:341
msgid "Preferences"
msgstr ""
#: src/window.blp:346
msgid "Keyboard Shortcuts"
msgstr ""
#: src/window.blp:351
msgid "About Cartridges"
msgstr ""
#: src/window.blp:360
msgid "Add Game"
msgstr ""
#: src/window.blp:365
msgid "Import From Steam"
msgstr ""
#: src/window.blp:370
msgid "Import From Heroic"
msgstr ""
#: src/window.blp:379 src/window.blp:398 src/gtk/game.blp:69
#: src/gtk/game.blp:95
msgid "Edit"
msgstr ""
#: src/window.blp:384 src/gtk/game.blp:74
msgid "Hide"
msgstr ""
#: src/window.blp:389 src/window.blp:408 src/gtk/game.blp:79
#: src/gtk/game.blp:105
msgid "Remove"
msgstr ""
#: src/window.blp:403 src/gtk/game.blp:100
msgid "Unhide"
msgstr ""
#: src/gtk/game.blp:32 src/utils/create_details_window.py:82
msgid "Title"
msgstr ""
#: src/gtk/preferences.blp:10
msgid "General"
msgstr ""
#: src/gtk/preferences.blp:13
msgid "Exit After Launching Games"
msgstr ""
#: src/gtk/preferences.blp:25
msgid "Steam Install Location"
msgstr ""
#: src/gtk/preferences.blp:26 src/gtk/preferences.blp:40
msgid "Directory to use when importing games"
msgstr ""
#: src/gtk/preferences.blp:39
msgid "Heroic Install Location"
msgstr ""
#: src/gtk/preferences.blp:49
msgid "Import Epic Games"
msgstr ""
#: src/gtk/preferences.blp:57
msgid "Import GOG Games"
msgstr ""
#: src/gtk/preferences.blp:65
msgid "Import Sideloaded Games"
msgstr ""
#: src/utils/create_details_window.py:38
msgid "Add New Game"
msgstr ""
#: src/utils/create_details_window.py:42
msgid "Confirm"
msgstr ""
#: src/utils/create_details_window.py:44
msgid "Edit Game Details"
msgstr ""
#: src/utils/create_details_window.py:48
msgid "Apply"
msgstr ""
#: src/utils/create_details_window.py:51
msgid "Images"
msgstr ""
#: src/utils/create_details_window.py:83
msgid "The title of the game"
msgstr ""
#: src/utils/create_details_window.py:88
msgid "Executable"
msgstr ""
#: src/utils/create_details_window.py:89
msgid "File to open or command to run when launching the game"
msgstr ""
#: src/utils/create_details_window.py:98
msgid "Cancel"
msgstr ""
#: src/utils/create_details_window.py:141
#: src/utils/create_details_window.py:145
msgid "Couldn't Add Game"
msgstr ""
#: src/utils/create_details_window.py:141
#: src/utils/create_details_window.py:166
msgid "Game title cannot be empty."
msgstr ""
#: src/utils/create_details_window.py:145
#: src/utils/create_details_window.py:170
msgid "Executable cannot be empty."
msgstr ""
#: src/utils/create_details_window.py:166
#: src/utils/create_details_window.py:170
msgid "Couldn't Apply Preferences"
msgstr ""
#: src/utils/create_dialog.py:24
msgid "Dismiss"
msgstr ""
#: src/utils/steam_parser.py:49 src/utils/heroic_parser.py:49
msgid "Couldn't Import Games"
msgstr ""
#: src/utils/steam_parser.py:49
msgid "Steam directory cannot be found."
msgstr ""
#: src/utils/steam_parser.py:49
msgid "Set Steam Location"
msgstr ""
#: src/utils/steam_parser.py:98
msgid "No new games found in Steam library."
msgstr ""
#: src/utils/steam_parser.py:100 src/utils/steam_parser.py:102
msgid "Steam Games Imported"
msgstr ""
#: src/utils/steam_parser.py:100 src/utils/heroic_parser.py:155
msgid "Successfully imported 1 game."
msgstr ""
#: src/utils/steam_parser.py:102 src/utils/heroic_parser.py:157
msgid "Successfully imported"
msgstr ""
#: src/utils/steam_parser.py:102 src/utils/heroic_parser.py:157
msgid "games."
msgstr ""
#: src/utils/heroic_parser.py:49
msgid "Heroic directory cannot be found."
msgstr ""
#: src/utils/heroic_parser.py:49
msgid "Set Heroic Location"
msgstr ""
#: src/utils/heroic_parser.py:153
msgid "No new games found in Heroic library."
msgstr ""
#: src/utils/heroic_parser.py:155 src/utils/heroic_parser.py:157
msgid "Heroic Games Imported"
msgstr ""

View File

@@ -1,259 +0,0 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-12-26 14:29+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
#: game.blp:32 ../utils/create_details_window.py:72
msgid "Title"
msgstr ""
#: game.blp:62 game.blp:88 ../window.blp:132
msgid "Play"
msgstr ""
#: game.blp:69 game.blp:95 ../window.blp:374 ../window.blp:393
msgid "Edit"
msgstr ""
#: game.blp:74 ../window.blp:379
msgid "Hide"
msgstr ""
#: game.blp:79 game.blp:105 ../window.blp:384 ../window.blp:403
msgid "Remove"
msgstr ""
#: game.blp:100 ../window.blp:398
msgid "Unhide"
msgstr ""
#: preferences.blp:10
msgid "General"
msgstr ""
#: preferences.blp:13
msgid "Exit after launching a game"
msgstr ""
#: preferences.blp:25
msgid "Steam install location"
msgstr ""
#: preferences.blp:26
msgid "Directory to use when importing games"
msgstr ""
#: ../window.blp:6 ../window.blp:14 ../utils/steam_parser.py:98
msgid "No Games Found"
msgstr ""
#: ../window.blp:7
msgid "Try a different search."
msgstr ""
#: ../window.blp:15
msgid "Use the + button to add games."
msgstr ""
#: ../window.blp:22
msgid "No Hidden Games"
msgstr ""
#: ../window.blp:23
msgid "Games you hide will appear here."
msgstr ""
#: ../window.blp:29
msgid "Game Shelf"
msgstr ""
#: ../window.blp:52
msgid "Game Details"
msgstr ""
#: ../window.blp:90
msgid "Game Title"
msgstr ""
#: ../window.blp:241
msgid "Hidden Games"
msgstr ""
#: ../window.blp:299
msgid "Sort"
msgstr ""
#: ../window.blp:302
msgid "A-Z"
msgstr ""
#: ../window.blp:308
msgid "Z-A"
msgstr ""
#: ../window.blp:314
msgid "Newest"
msgstr ""
#: ../window.blp:320
msgid "Oldest"
msgstr ""
#: ../window.blp:326
msgid "Last Played"
msgstr ""
#: ../window.blp:333
msgid "Show Hidden"
msgstr ""
#: ../window.blp:341
msgid "Preferences"
msgstr ""
#: ../window.blp:346
msgid "Keyboard Shortcuts"
msgstr ""
#: ../window.blp:351
msgid "About Game Shelf"
msgstr ""
#: ../window.blp:360
msgid "Add Game"
msgstr ""
#: ../window.blp:365
msgid "Import From Steam"
msgstr ""
#. Create toast for undoing the remove action
#: ../main.py:126
msgid " removed"
msgstr ""
#: ../main.py:127
msgid "Undo"
msgstr ""
#: ../window.py:196
msgid "Today"
msgstr ""
#: ../window.py:198
msgid "Yesterday"
msgstr ""
#: ../window.py:222
msgid "Added: "
msgstr ""
#: ../window.py:223
msgid "Last played: "
msgstr ""
#: ../window.py:223
msgid "Last played: Never"
msgstr ""
#: ../utils/create_details_window.py:33
msgid "Add New Game"
msgstr ""
#: ../utils/create_details_window.py:37
msgid "Confirm"
msgstr ""
#: ../utils/create_details_window.py:39
msgid "Edit Game Details"
msgstr ""
#: ../utils/create_details_window.py:43
msgid "Apply"
msgstr ""
#: ../utils/create_details_window.py:46
msgid "Images"
msgstr ""
#: ../utils/create_details_window.py:73
msgid "The title of the game"
msgstr ""
#: ../utils/create_details_window.py:77
msgid "Executable"
msgstr ""
#: ../utils/create_details_window.py:78
msgid "File to open or command to run when launching the game"
msgstr ""
#: ../utils/create_details_window.py:86
msgid "Cancel"
msgstr ""
#: ../utils/create_details_window.py:133 ../utils/create_details_window.py:137
msgid "Couldn't Add Game"
msgstr ""
#: ../utils/create_details_window.py:133 ../utils/create_details_window.py:158
msgid "Game title cannot be empty."
msgstr ""
#: ../utils/create_details_window.py:137 ../utils/create_details_window.py:162
msgid "Executable cannot be empty."
msgstr ""
#: ../utils/create_details_window.py:158 ../utils/create_details_window.py:162
msgid "Couldn't Apply Preferences"
msgstr ""
#: ../utils/create_dialog.py:24
msgid "Dismiss"
msgstr ""
#: ../utils/steam_parser.py:49
msgid "Couldn't Import Games"
msgstr ""
#: ../utils/steam_parser.py:49
msgid "Steam directory cannot be found."
msgstr ""
#: ../utils/steam_parser.py:49
msgid "Set Steam Location"
msgstr ""
#: ../utils/steam_parser.py:98
msgid "No new games found in Steam library."
msgstr ""
#: ../utils/steam_parser.py:100 ../utils/steam_parser.py:102
msgid "Steam Games Imported"
msgstr ""
#: ../utils/steam_parser.py:100
msgid "Successfully imported 1 game."
msgstr ""
#: ../utils/steam_parser.py:102
msgid "Successfully imported "
msgstr ""
#: ../utils/steam_parser.py:102
msgid " games."
msgstr ""

BIN
po/hu.mo

Binary file not shown.

365
po/hu.po
View File

@@ -7,8 +7,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-12-26 14:29+0100\n" "POT-Creation-Date: 2023-01-29 14:12+0100\n"
"PO-Revision-Date: 2022-12-26 14:33+0100\n" "PO-Revision-Date: 2023-01-29 14:19+0100\n"
"Last-Translator: kramo <contact@kramo.hu>\n" "Last-Translator: kramo <contact@kramo.hu>\n"
"Language-Team: \n" "Language-Team: \n"
"Language: hu\n" "Language: hu\n"
@@ -18,243 +18,286 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Poedit 3.2.2\n" "X-Generator: Poedit 3.2.2\n"
#: game.blp:32 ../utils/create_details_window.py:72
msgid "Title"
msgstr "Cím"
#: game.blp:62 game.blp:88 ../window.blp:132
msgid "Play"
msgstr "Játék"
#: game.blp:69 game.blp:95 ../window.blp:374 ../window.blp:393
msgid "Edit"
msgstr "Szerkeszt"
#: game.blp:74 ../window.blp:379
msgid "Hide"
msgstr "Elrejt"
#: game.blp:79 game.blp:105 ../window.blp:384 ../window.blp:403
msgid "Remove"
msgstr "Eltávolít"
#: game.blp:100 ../window.blp:398
msgid "Unhide"
msgstr "Mutat"
#: preferences.blp:10
msgid "General"
msgstr "Általános"
#: preferences.blp:13
msgid "Exit after launching a game"
msgstr "Kilépés játék indítása után"
#: preferences.blp:25
msgid "Steam install location"
msgstr "Steam telepítés helye"
#: preferences.blp:26
msgid "Directory to use when importing games"
msgstr "Az importáláskor használatos mappa"
#: ../window.blp:6 ../window.blp:14 ../utils/steam_parser.py:98
msgid "No Games Found"
msgstr "Nem Találhatóak Játékok"
#: ../window.blp:7
msgid "Try a different search."
msgstr "Próbálkozz más kereséssel."
#: ../window.blp:15
msgid "Use the + button to add games."
msgstr "Használd a + gombot a játékok hozzáadásához."
#: ../window.blp:22
msgid "No Hidden Games"
msgstr "Nincsenek Rejtett Játékok"
#: ../window.blp:23
msgid "Games you hide will appear here."
msgstr "A rejtett játékaid itt lesznek megtalálhatók."
#: ../window.blp:29
msgid "Game Shelf"
msgstr "Játékpolc"
#: ../window.blp:52
msgid "Game Details"
msgstr "Játék Részletei"
#: ../window.blp:90
msgid "Game Title"
msgstr "Cím"
#: ../window.blp:241
msgid "Hidden Games"
msgstr "Rejtett Játékok"
#: ../window.blp:299
msgid "Sort"
msgstr "Rendezés"
#: ../window.blp:302
msgid "A-Z"
msgstr "A-Z"
#: ../window.blp:308
msgid "Z-A"
msgstr "Z-A"
#: ../window.blp:314
msgid "Newest"
msgstr "Legújabb"
#: ../window.blp:320
msgid "Oldest"
msgstr "Legrégebbi"
#: ../window.blp:326
msgid "Last Played"
msgstr "Legutóbb játszott"
#: ../window.blp:333
msgid "Show Hidden"
msgstr "Rejtett Játékok"
#: ../window.blp:341
msgid "Preferences"
msgstr "Beállítások"
#: ../window.blp:346
msgid "Keyboard Shortcuts"
msgstr "Billentyűparancsok"
#: ../window.blp:351
msgid "About Game Shelf"
msgstr "A Játékpolcról"
#: ../window.blp:360
msgid "Add Game"
msgstr "Játék Hozzáadása"
#: ../window.blp:365
msgid "Import From Steam"
msgstr "Importálás Steam-ből"
#. Create toast for undoing the remove action #. Create toast for undoing the remove action
#: ../main.py:126 #: src/main.py:133
msgid " removed" msgid "removed"
msgstr " eltávolítva" msgstr "eltávolítva"
#: ../main.py:127 #: src/main.py:134
msgid "Undo" msgid "Undo"
msgstr "Visszavonás" msgstr "Visszavonás"
#: ../window.py:196 #: src/window.py:195
msgid "Today" msgid "Today"
msgstr "Ma" msgstr "Ma"
#: ../window.py:198 #: src/window.py:197
msgid "Yesterday" msgid "Yesterday"
msgstr "Tegnap" msgstr "Tegnap"
#: ../window.py:222 #: src/window.py:221
msgid "Added: " msgid "Added: "
msgstr "Hozzáadva: " msgstr "Hozzáadva: "
#: ../window.py:223 #: src/window.py:222
msgid "Last played: " msgid "Last played: "
msgstr "Legutóbb játszva: " msgstr "Legutóbb játszva: "
#: ../window.py:223 #: src/window.py:222
msgid "Last played: Never" msgid "Last played: Never"
msgstr "Legutóbb játszva: Soha" msgstr "Legutóbb játszva: Soha"
#: ../utils/create_details_window.py:33 #: src/window.blp:6 src/window.blp:14 src/utils/steam_parser.py:98
#: src/utils/heroic_parser.py:153
msgid "No Games Found"
msgstr "Nem Találhatóak Játékok"
#: src/window.blp:7
msgid "Try a different search."
msgstr "Próbálkozz más kereséssel."
#: src/window.blp:15
msgid "Use the + button to add games."
msgstr "Használd a + gombot a játékok hozzáadásához."
#: src/window.blp:22
msgid "No Hidden Games"
msgstr "Nincsenek Rejtett Játékok"
#: src/window.blp:23
msgid "Games you hide will appear here."
msgstr "A rejtett játékaid itt lesznek megtalálhatók."
#: src/window.blp:29
msgid "Cartridges"
msgstr "Játékpolc"
#: src/window.blp:52
msgid "Game Details"
msgstr "Játék Részletei"
#: src/window.blp:90
msgid "Game Title"
msgstr "Cím"
#: src/window.blp:132 src/gtk/game.blp:62 src/gtk/game.blp:88
msgid "Play"
msgstr "Játék"
#: src/window.blp:241
msgid "Hidden Games"
msgstr "Rejtett Játékok"
#: src/window.blp:299
msgid "Sort"
msgstr "Rendezés"
#: src/window.blp:302
msgid "A-Z"
msgstr "A-Z"
#: src/window.blp:308
msgid "Z-A"
msgstr "Z-A"
#: src/window.blp:314
msgid "Newest"
msgstr "Legújabb"
#: src/window.blp:320
msgid "Oldest"
msgstr "Legrégebbi"
#: src/window.blp:326
msgid "Last Played"
msgstr "Legutóbb játszott"
#: src/window.blp:333
msgid "Show Hidden"
msgstr "Rejtett Játékok"
#: src/window.blp:341
msgid "Preferences"
msgstr "Beállítások"
#: src/window.blp:346
msgid "Keyboard Shortcuts"
msgstr "Billentyűparancsok"
#: src/window.blp:351
msgid "About Cartridges"
msgstr "A Játékpolcról"
#: src/window.blp:360
msgid "Add Game"
msgstr "Játék Hozzáadása"
#: src/window.blp:365
msgid "Import From Steam"
msgstr "Importálás Steam-ből"
#: src/window.blp:370
msgid "Import From Heroic"
msgstr "Importálás Heroic-ból"
#: src/window.blp:379 src/window.blp:398 src/gtk/game.blp:69
#: src/gtk/game.blp:95
msgid "Edit"
msgstr "Szerkeszt"
#: src/window.blp:384 src/gtk/game.blp:74
msgid "Hide"
msgstr "Elrejt"
#: src/window.blp:389 src/window.blp:408 src/gtk/game.blp:79
#: src/gtk/game.blp:105
msgid "Remove"
msgstr "Eltávolít"
#: src/window.blp:403 src/gtk/game.blp:100
msgid "Unhide"
msgstr "Mutat"
#: src/gtk/game.blp:32 src/utils/create_details_window.py:82
msgid "Title"
msgstr "Cím"
#: src/gtk/preferences.blp:10
msgid "General"
msgstr "Általános"
#: src/gtk/preferences.blp:13
msgid "Exit After Launching Games"
msgstr "Kilépés Játékok Indítása Után"
#: src/gtk/preferences.blp:25
msgid "Steam Install Location"
msgstr "Steam Telepítés Helye"
#: src/gtk/preferences.blp:26 src/gtk/preferences.blp:40
msgid "Directory to use when importing games"
msgstr "Az importáláskor használatos mappa"
#: src/gtk/preferences.blp:39
msgid "Heroic Install Location"
msgstr "Heroic Telepítés Helye"
#: src/gtk/preferences.blp:49
msgid "Import Epic Games"
msgstr "Epic Games Játékok Importálása"
#: src/gtk/preferences.blp:57
msgid "Import GOG Games"
msgstr "GOG Játékok Importálása"
#: src/gtk/preferences.blp:65
msgid "Import Sideloaded Games"
msgstr "Manuálisan Hozzáadott Játékok Importálása"
#: src/utils/create_details_window.py:38
msgid "Add New Game" msgid "Add New Game"
msgstr "Új Játék Hozzáadása" msgstr "Új Játék Hozzáadása"
#: ../utils/create_details_window.py:37 #: src/utils/create_details_window.py:42
msgid "Confirm" msgid "Confirm"
msgstr "Megerősít" msgstr "Megerősít"
#: ../utils/create_details_window.py:39 #: src/utils/create_details_window.py:44
msgid "Edit Game Details" msgid "Edit Game Details"
msgstr "Játék Részleteinek Szerkesztése" msgstr "Játék Részleteinek Szerkesztése"
#: ../utils/create_details_window.py:43 #: src/utils/create_details_window.py:48
msgid "Apply" msgid "Apply"
msgstr "Alkalmaz" msgstr "Alkalmaz"
#: ../utils/create_details_window.py:46 #: src/utils/create_details_window.py:51
msgid "Images" msgid "Images"
msgstr "Képek" msgstr "Képek"
#: ../utils/create_details_window.py:73 #: src/utils/create_details_window.py:83
msgid "The title of the game" msgid "The title of the game"
msgstr "A játék címe" msgstr "A játék címe"
#: ../utils/create_details_window.py:77 #: src/utils/create_details_window.py:88
msgid "Executable" msgid "Executable"
msgstr "Program" msgstr "Program"
#: ../utils/create_details_window.py:78 #: src/utils/create_details_window.py:89
msgid "File to open or command to run when launching the game" msgid "File to open or command to run when launching the game"
msgstr "Fájl megnyitása vagy parancs futtatása a játék indításakor" msgstr "Fájl megnyitása vagy parancs futtatása a játék indításakor"
#: ../utils/create_details_window.py:86 #: src/utils/create_details_window.py:98
msgid "Cancel" msgid "Cancel"
msgstr "Mégse" msgstr "Mégse"
#: ../utils/create_details_window.py:133 ../utils/create_details_window.py:137 #: src/utils/create_details_window.py:141
#: src/utils/create_details_window.py:145
msgid "Couldn't Add Game" msgid "Couldn't Add Game"
msgstr "Nem Lehet Hozzáadni a Játékot" msgstr "Nem Lehet Hozzáadni a Játékot"
#: ../utils/create_details_window.py:133 ../utils/create_details_window.py:158 #: src/utils/create_details_window.py:141
#: src/utils/create_details_window.py:166
msgid "Game title cannot be empty." msgid "Game title cannot be empty."
msgstr "A cím nem lehet üres." msgstr "A cím nem lehet üres."
#: ../utils/create_details_window.py:137 ../utils/create_details_window.py:162 #: src/utils/create_details_window.py:145
#: src/utils/create_details_window.py:170
msgid "Executable cannot be empty." msgid "Executable cannot be empty."
msgstr "A program nem lehet üres." msgstr "A program nem lehet üres."
#: ../utils/create_details_window.py:158 ../utils/create_details_window.py:162 #: src/utils/create_details_window.py:166
#: src/utils/create_details_window.py:170
msgid "Couldn't Apply Preferences" msgid "Couldn't Apply Preferences"
msgstr "Nem Lehet Menteni a Beállításokat" msgstr "Nem Lehet Menteni a Beállításokat"
#: ../utils/create_dialog.py:24 #: src/utils/create_dialog.py:24
msgid "Dismiss" msgid "Dismiss"
msgstr "Rendben" msgstr "Rendben"
#: ../utils/steam_parser.py:49 #: src/utils/steam_parser.py:49 src/utils/heroic_parser.py:49
msgid "Couldn't Import Games" msgid "Couldn't Import Games"
msgstr "Nem Lehet Importálni a Játékot" msgstr "Nem Lehet Importálni a Játékot"
#: ../utils/steam_parser.py:49 #: src/utils/steam_parser.py:49
msgid "Steam directory cannot be found." msgid "Steam directory cannot be found."
msgstr "A Steam mappa nem található." msgstr "A Steam mappa nem található."
#: ../utils/steam_parser.py:49 #: src/utils/steam_parser.py:49
msgid "Set Steam Location" msgid "Set Steam Location"
msgstr "Steam Mappa Kiválasztása" msgstr "Steam Mappa Kiválasztása"
#: ../utils/steam_parser.py:98 #: src/utils/steam_parser.py:98
msgid "No new games found in Steam library." msgid "No new games found in Steam library."
msgstr "Nem találhatók új játékok a Steam könyvtárban." msgstr "Nem találhatók új játékok a Steam könyvtárban."
#: ../utils/steam_parser.py:100 ../utils/steam_parser.py:102 #: src/utils/steam_parser.py:100 src/utils/steam_parser.py:102
msgid "Steam Games Imported" msgid "Steam Games Imported"
msgstr "Steam Játékok Importálva" msgstr "Steam Játékok Importálva"
#: ../utils/steam_parser.py:100 #: src/utils/steam_parser.py:100 src/utils/heroic_parser.py:155
msgid "Successfully imported 1 game." msgid "Successfully imported 1 game."
msgstr "1 játék sikeresen importálva." msgstr "1 játék sikeresen importálva."
#: ../utils/steam_parser.py:102 #: src/utils/steam_parser.py:102 src/utils/heroic_parser.py:157
msgid "Successfully imported " msgid "Successfully imported"
msgstr "Sikeresen importálva " msgstr "Sikeresen importálva"
#: ../utils/steam_parser.py:102 #: src/utils/steam_parser.py:102 src/utils/heroic_parser.py:157
msgid " games." msgid "games."
msgstr " játék." msgstr "játék."
#: src/utils/heroic_parser.py:49
msgid "Heroic directory cannot be found."
msgstr "A Heroic mappa nem található."
#: src/utils/heroic_parser.py:49
msgid "Set Heroic Location"
msgstr "Heroic Mappa Kiválasztása"
#: src/utils/heroic_parser.py:153
msgid "No new games found in Heroic library."
msgstr "Nem találhatók új játékok a Heroic könyvtárban."
#: src/utils/heroic_parser.py:155 src/utils/heroic_parser.py:157
msgid "Heroic Games Imported"
msgstr "Heroic Játékok Importálva"

View File

@@ -1 +1 @@
i18n.gettext('gameshelf', preset: 'glib') i18n.gettext('cartridges', preset: 'glib')

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<gresources> <gresources>
<gresource prefix="/hu/kramo/GameShelf"> <gresource prefix="/hu/kramo/Cartridges">
<file preprocess="xml-stripblanks">window.ui</file> <file preprocess="xml-stripblanks">window.ui</file>
<file preprocess="xml-stripblanks">gtk/help-overlay.ui</file> <file preprocess="xml-stripblanks">gtk/help-overlay.ui</file>
<file preprocess="xml-stripblanks">gtk/game.ui</file> <file preprocess="xml-stripblanks">gtk/game.ui</file>

View File

@@ -1,6 +1,6 @@
#!@PYTHON@ #!@PYTHON@
# gameshelf.in # cartridges.in
# #
# Copyright 2022 kramo # Copyright 2022 kramo
# #
@@ -31,16 +31,16 @@ localedir = '@localedir@'
sys.path.insert(1, pkgdatadir) sys.path.insert(1, pkgdatadir)
signal.signal(signal.SIGINT, signal.SIG_DFL) signal.signal(signal.SIGINT, signal.SIG_DFL)
locale.bindtextdomain('gameshelf', localedir) locale.bindtextdomain('cartridges', localedir)
locale.textdomain('gameshelf') locale.textdomain('cartridges')
gettext.install('gameshelf', localedir) gettext.install('cartridges', localedir)
if __name__ == '__main__': if __name__ == '__main__':
import gi import gi
from gi.repository import Gio from gi.repository import Gio
resource = Gio.Resource.load(os.path.join(pkgdatadir, 'gameshelf.gresource')) resource = Gio.Resource.load(os.path.join(pkgdatadir, 'cartridges.gresource'))
resource._register() resource._register()
from gameshelf import main from cartridges import main
sys.exit(main.main(VERSION)) sys.exit(main.main(VERSION))

View File

@@ -19,7 +19,7 @@
from gi.repository import Gtk from gi.repository import Gtk
@Gtk.Template(resource_path='/hu/kramo/GameShelf/gtk/game.ui') @Gtk.Template(resource_path='/hu/kramo/Cartridges/gtk/game.ui')
class game(Gtk.Box): class game(Gtk.Box):
__gtype_name__ = 'game' __gtype_name__ = 'game'

View File

@@ -3,14 +3,14 @@ using Adw 1;
template PreferencesWindow : Adw.PreferencesWindow { template PreferencesWindow : Adw.PreferencesWindow {
search-enabled: false; search-enabled: false;
default-height: 400; default-height: 500;
Adw.PreferencesPage { Adw.PreferencesPage {
Adw.PreferencesGroup { Adw.PreferencesGroup {
title: _("General"); title: _("General");
Adw.ActionRow { Adw.ActionRow {
title: _("Exit after launching a game"); title: _("Exit After Launching Games");
Switch exit_after_launch_switch { Switch exit_after_launch_switch {
valign: center; valign: center;
@@ -22,7 +22,7 @@ template PreferencesWindow : Adw.PreferencesWindow {
title: "Steam"; title: "Steam";
Adw.ActionRow { Adw.ActionRow {
title: _("Steam install location"); title: _("Steam Install Location");
subtitle: _("Directory to use when importing games"); subtitle: _("Directory to use when importing games");
Button steam_file_chooser_button { Button steam_file_chooser_button {
@@ -31,5 +31,43 @@ template PreferencesWindow : Adw.PreferencesWindow {
} }
} }
} }
Adw.PreferencesGroup {
title: "Heroic";
Adw.ActionRow {
title: _("Heroic Install Location");
subtitle: _("Directory to use when importing games");
Button heroic_file_chooser_button {
icon-name: "folder-symbolic";
valign: center;
}
}
Adw.ActionRow {
title: _("Import Epic Games");
Switch import_epic_games_switch {
valign: center;
}
}
Adw.ActionRow {
title: _("Import GOG Games");
Switch import_gog_games_switch {
valign: center;
}
}
Adw.ActionRow {
title: _("Import Sideloaded Games");
Switch import_sideload_games_switch {
valign: center;
}
}
}
} }
} }

View File

@@ -24,21 +24,23 @@ gi.require_version("Adw", "1")
from gi.repository import Gtk, Gio, GLib, Adw from gi.repository import Gtk, Gio, GLib, Adw
from .window import GameShelfWindow from .window import CartridgesWindow
from .preferences import PreferencesWindow from .preferences import PreferencesWindow
from .toggle_hidden import toggle_hidden from .toggle_hidden import toggle_hidden
from .save_games import save_games from .save_games import save_games
from .run_command import run_command from .run_command import run_command
from .steam_parser import steam_parser from .steam_parser import steam_parser
from .heroic_parser import heroic_parser
from .create_details_window import create_details_window from .create_details_window import create_details_window
class GameShelfApplication(Adw.Application): class CartridgesApplication(Adw.Application):
def __init__(self): def __init__(self):
super().__init__(application_id="hu.kramo.GameShelf", flags=Gio.ApplicationFlags.FLAGS_NONE) super().__init__(application_id="hu.kramo.Cartridges", flags=Gio.ApplicationFlags.FLAGS_NONE)
self.create_action("quit", self.on_quit_action, ["<primary>q"]) self.create_action("quit", self.on_quit_action, ["<primary>q"])
self.create_action("about", self.on_about_action) self.create_action("about", self.on_about_action)
self.create_action("preferences", self.on_preferences_action) self.create_action("preferences", self.on_preferences_action)
self.create_action("steam_import", self.on_steam_import_action) self.create_action("steam_import", self.on_steam_import_action)
self.create_action("heroic_import", self.on_heroic_import_action)
self.create_action("launch_game", self.on_launch_game_action) self.create_action("launch_game", self.on_launch_game_action)
self.create_action("hide_game", self.on_hide_game_action) self.create_action("hide_game", self.on_hide_game_action)
self.create_action("edit_details", self.on_edit_details_action) self.create_action("edit_details", self.on_edit_details_action)
@@ -50,7 +52,7 @@ class GameShelfApplication(Adw.Application):
# Create the main window # Create the main window
win = self.props.active_window win = self.props.active_window
if not win: if not win:
win = GameShelfWindow(application=self) win = CartridgesWindow(application=self)
win.present() win.present()
@@ -68,10 +70,10 @@ class GameShelfApplication(Adw.Application):
def on_about_action(self, widget, callback=None): def on_about_action(self, widget, callback=None):
about = Adw.AboutWindow(transient_for=self.props.active_window, about = Adw.AboutWindow(transient_for=self.props.active_window,
application_name="Game Shelf", application_name="Cartridges",
application_icon="hu.kramo.GameShelf", application_icon="hu.kramo.Cartridges",
developer_name="kramo", developer_name="kramo",
version="0.1.0", version="0.1.2",
developers=["kramo"], developers=["kramo"],
copyright="© 2022 kramo", copyright="© 2022 kramo",
license_type=Gtk.License.GPL_3_0) license_type=Gtk.License.GPL_3_0)
@@ -85,6 +87,11 @@ class GameShelfApplication(Adw.Application):
save_games(games) save_games(games)
self.props.active_window.update_games(games.keys()) self.props.active_window.update_games(games.keys())
def on_heroic_import_action(self, widget, callback=None):
games = heroic_parser(self.props.active_window, self.on_heroic_import_action)
save_games(games)
self.props.active_window.update_games(games.keys())
def on_launch_game_action(self, widget, callback=None): def on_launch_game_action(self, widget, callback=None):
# Launch the game and update the last played value # Launch the game and update the last played value
@@ -112,7 +119,7 @@ class GameShelfApplication(Adw.Application):
# Add "removed=True" to the game properties so it can be deleted on next init # Add "removed=True" to the game properties so it can be deleted on next init
game_id = self.props.active_window.active_game_id game_id = self.props.active_window.active_game_id
open_file = open(os.path.join(os.path.join(os.environ.get("XDG_DATA_HOME"), "games", game_id + ".json")), "r") open_file = open(os.path.join(os.path.join(os.environ.get("XDG_DATA_HOME"), "cartridges", "games", game_id + ".json")), "r")
data = json.loads(open_file.read()) data = json.loads(open_file.read())
open_file.close() open_file.close()
data["removed"] = True data["removed"] = True
@@ -123,7 +130,7 @@ class GameShelfApplication(Adw.Application):
self.props.active_window.on_go_back_action(None, None) self.props.active_window.on_go_back_action(None, None)
# Create toast for undoing the remove action # Create toast for undoing the remove action
toast = Adw.Toast.new(self.props.active_window.games[game_id]["name"] + (_(" removed"))) toast = Adw.Toast.new(self.props.active_window.games[game_id]["name"] + " " + (_("removed")))
toast.set_button_label(_("Undo")) toast.set_button_label(_("Undo"))
toast.connect("button-clicked", self.props.active_window.on_undo_remove_action, game_id) toast.connect("button-clicked", self.props.active_window.on_undo_remove_action, game_id)
toast.set_priority(Adw.ToastPriority.HIGH) toast.set_priority(Adw.ToastPriority.HIGH)
@@ -146,6 +153,6 @@ class GameShelfApplication(Adw.Application):
self.set_accels_for_action(f"win.{name}", shortcuts) self.set_accels_for_action(f"win.{name}", shortcuts)
def main(version): def main(version):
app = GameShelfApplication() app = CartridgesApplication()
return app.run(sys.argv) return app.run(sys.argv)

View File

@@ -1,5 +1,5 @@
pkgdatadir = join_paths(get_option('prefix'), get_option('datadir'), meson.project_name()) pkgdatadir = join_paths(get_option('prefix'), get_option('datadir'), meson.project_name())
moduledir = join_paths(pkgdatadir, 'gameshelf') moduledir = join_paths(pkgdatadir, 'cartridges')
gnome = import('gnome') gnome = import('gnome')
blueprints = custom_target('blueprints', blueprints = custom_target('blueprints',
@@ -13,8 +13,8 @@ blueprints = custom_target('blueprints',
command: [find_program('blueprint-compiler'), 'batch-compile', '@OUTPUT@', '@CURRENT_SOURCE_DIR@', '@INPUT@'], command: [find_program('blueprint-compiler'), 'batch-compile', '@OUTPUT@', '@CURRENT_SOURCE_DIR@', '@INPUT@'],
) )
gnome.compile_resources('gameshelf', gnome.compile_resources('cartridges',
'gameshelf.gresource.xml', 'cartridges.gresource.xml',
gresource_bundle: true, gresource_bundle: true,
install: true, install: true,
install_dir: pkgdatadir, install_dir: pkgdatadir,
@@ -30,20 +30,21 @@ conf.set('localedir', join_paths(get_option('prefix'), get_option('localedir')))
conf.set('pkgdatadir', pkgdatadir) conf.set('pkgdatadir', pkgdatadir)
configure_file( configure_file(
input: 'gameshelf.in', input: 'cartridges.in',
output: 'gameshelf', output: 'cartridges',
configuration: conf, configuration: conf,
install: true, install: true,
install_dir: get_option('bindir') install_dir: get_option('bindir')
) )
gameshelf_sources = [ cartridges_sources = [
'__init__.py', '__init__.py',
'main.py', 'main.py',
'window.py', 'window.py',
'preferences.py', 'preferences.py',
'game.py', 'game.py',
'utils/steam_parser.py', 'utils/steam_parser.py',
'utils/heroic_parser.py',
'utils/run_command.py', 'utils/run_command.py',
'utils/get_games.py', 'utils/get_games.py',
'utils/get_cover.py', 'utils/get_cover.py',
@@ -54,4 +55,4 @@ gameshelf_sources = [
'utils/create_details_window.py' 'utils/create_details_window.py'
] ]
install_data(gameshelf_sources, install_dir: moduledir) install_data(cartridges_sources, install_dir: moduledir)

View File

@@ -19,12 +19,17 @@
from gi.repository import Adw, Gtk, Gio, GLib from gi.repository import Adw, Gtk, Gio, GLib
@Gtk.Template(resource_path='/hu/kramo/GameShelf/gtk/preferences.ui') @Gtk.Template(resource_path='/hu/kramo/Cartridges/gtk/preferences.ui')
class PreferencesWindow(Adw.PreferencesWindow): class PreferencesWindow(Adw.PreferencesWindow):
__gtype_name__ = 'PreferencesWindow' __gtype_name__ = 'PreferencesWindow'
exit_after_launch_switch = Gtk.Template.Child() exit_after_launch_switch = Gtk.Template.Child()
import_epic_games_switch = Gtk.Template.Child()
import_gog_games_switch = Gtk.Template.Child()
import_sideload_games_switch = Gtk.Template.Child()
steam_file_chooser_button = Gtk.Template.Child() steam_file_chooser_button = Gtk.Template.Child()
heroic_file_chooser_button = Gtk.Template.Child()
def __init__(self, parent_widget, **kwargs): def __init__(self, parent_widget, **kwargs):
super().__init__(**kwargs) super().__init__(**kwargs)
@@ -32,8 +37,11 @@ class PreferencesWindow(Adw.PreferencesWindow):
self.set_transient_for(parent_widget) self.set_transient_for(parent_widget)
schema = parent_widget.schema schema = parent_widget.schema
schema.bind("exit-after-launch", self.exit_after_launch_switch, "active", Gio.SettingsBindFlags.DEFAULT) schema.bind("exit-after-launch", self.exit_after_launch_switch, "active", Gio.SettingsBindFlags.DEFAULT)
schema.bind("heroic-import-epic", self.import_epic_games_switch, "active", Gio.SettingsBindFlags.DEFAULT)
schema.bind("heroic-import-gog", self.import_gog_games_switch, "active", Gio.SettingsBindFlags.DEFAULT)
schema.bind("heroic-import-sideload", self.import_sideload_games_switch, "active", Gio.SettingsBindFlags.DEFAULT)
filechooser = Gtk.FileDialog.new() filechooser = Gtk.FileDialog()
def set_steam_dir(source, result, user_data): def set_steam_dir(source, result, user_data):
try: try:
@@ -41,7 +49,14 @@ class PreferencesWindow(Adw.PreferencesWindow):
except GLib.GError: except GLib.GError:
pass pass
def choose_folder(widget): def set_heroic_dir(source, result, user_data):
filechooser.select_folder(parent_widget, None, None, set_steam_dir, None) try:
schema.set_string("heroic-location", filechooser.select_folder_finish(result).get_path())
except GLib.GError:
pass
self.steam_file_chooser_button.connect("clicked", choose_folder) def choose_folder(widget, function):
filechooser.select_folder(parent_widget, None, function, None)
self.steam_file_chooser_button.connect("clicked", choose_folder, set_steam_dir)
self.heroic_file_chooser_button.connect("clicked", choose_folder, set_heroic_dir)

View File

@@ -19,12 +19,17 @@
def create_details_window(parent_widget, game_id = None): def create_details_window(parent_widget, game_id = None):
import os, json, time import os, json, time
from gi.repository import Adw, Gtk, GLib, GdkPixbuf from gi.repository import Adw, Gtk, Gio, GLib, GdkPixbuf
from .create_dialog import create_dialog from .create_dialog import create_dialog
from .save_games import save_games from .save_games import save_games
from .save_cover import save_cover from .save_cover import save_cover
window = Adw.Window.new() window = Adw.Window(
modal = True,
default_width = 450,
default_height = 650,
transient_for = parent_widget
)
games = parent_widget.games games = parent_widget.games
pixbuf = None pixbuf = None
@@ -32,8 +37,8 @@ def create_details_window(parent_widget, game_id = None):
if game_id == None: if game_id == None:
window.set_title(_("Add New Game")) window.set_title(_("Add New Game"))
cover = Gtk.Picture.new_for_pixbuf(parent_widget.placeholder_pixbuf) cover = Gtk.Picture.new_for_pixbuf(parent_widget.placeholder_pixbuf)
name = Gtk.Entry.new() name = Gtk.Entry()
executable = Gtk.Entry.new() executable = Gtk.Entry()
apply_button = Gtk.Button.new_with_label(_("Confirm")) apply_button = Gtk.Button.new_with_label(_("Confirm"))
else: else:
window.set_title(_("Edit Game Details")) window.set_title(_("Edit Game Details"))
@@ -42,43 +47,50 @@ def create_details_window(parent_widget, game_id = None):
executable = Gtk.Entry.new_with_buffer(Gtk.EntryBuffer.new((games[game_id]["executable"]), -1)) executable = Gtk.Entry.new_with_buffer(Gtk.EntryBuffer.new((games[game_id]["executable"]), -1))
apply_button = Gtk.Button.new_with_label(_("Apply")) apply_button = Gtk.Button.new_with_label(_("Apply"))
file_filter = Gtk.FileFilter.new() image_filter = Gtk.FileFilter(
file_filter.set_name(_("Images")) name= _("Images")
file_filter.add_pixbuf_formats() )
filechooser = Gtk.FileDialog.new() image_filter.add_pixbuf_formats()
filechooser.set_current_filter(file_filter) file_filters = Gio.ListStore.new(Gtk.FileFilter)
file_filters.append(image_filter)
filechooser = Gtk.FileDialog()
filechooser.set_filters(file_filters)
cover.add_css_class("card") cover.add_css_class("card")
cover.set_size_request(200, 300) cover.set_size_request(200, 300)
cover_button = Gtk.Button.new_from_icon_name("document-edit-symbolic") cover_button = Gtk.Button(
cover_button.set_halign(Gtk.Align.END) icon_name = "document-edit-symbolic",
cover_button.set_valign(Gtk.Align.END) halign = Gtk.Align.END,
cover_button.set_margin_bottom(6) valign = Gtk.Align.END,
cover_button.set_margin_end(6) margin_bottom = 6,
cover_button.add_css_class("circular") margin_end = 6,
cover_button.add_css_class("osd") css_classes = ["circular", "osd"],
)
cover_overlay = Gtk.Overlay.new() cover_overlay = Gtk.Overlay(
cover_overlay.set_child(cover) child = cover,
halign = Gtk.Align.CENTER,
valign = Gtk.Align.CENTER,
)
cover_overlay.add_overlay(cover_button) cover_overlay.add_overlay(cover_button)
cover_overlay.set_halign(Gtk.Align.CENTER)
cover_overlay.set_valign(Gtk.Align.CENTER)
cover_group = Adw.PreferencesGroup.new() cover_group = Adw.PreferencesGroup()
cover_group.add(cover_overlay) cover_group.add(cover_overlay)
title_group = Adw.PreferencesGroup.new() title_group = Adw.PreferencesGroup(
title_group.set_title(_("Title")) title = _("Title"),
title_group.set_description(_("The title of the game")) description = _("The title of the game"),
)
title_group.add(name) title_group.add(name)
exec_group = Adw.PreferencesGroup.new() exec_group = Adw.PreferencesGroup(
exec_group.set_title(_("Executable")) title = _("Executable"),
exec_group.set_description(_("File to open or command to run when launching the game")) description = _("File to open or command to run when launching the game"),
)
exec_group.add(executable) exec_group.add(executable)
general_page = Adw.PreferencesPage.new() general_page = Adw.PreferencesPage()
general_page.add(cover_group) general_page.add(cover_group)
general_page.add(title_group) general_page.add(title_group)
general_page.add(exec_group) general_page.add(exec_group)
@@ -87,27 +99,23 @@ def create_details_window(parent_widget, game_id = None):
apply_button.add_css_class("suggested-action") apply_button.add_css_class("suggested-action")
header_bar = Adw.HeaderBar.new() header_bar = Adw.HeaderBar(
header_bar.set_show_start_title_buttons(False) show_start_title_buttons = False,
header_bar.set_show_end_title_buttons(False) show_end_title_buttons = False,
)
header_bar.pack_start(cancel_button) header_bar.pack_start(cancel_button)
header_bar.pack_end(apply_button) header_bar.pack_end(apply_button)
main_box = Gtk.Box.new(Gtk.Orientation.VERTICAL, 0) main_box = Gtk.Box.new(Gtk.Orientation.VERTICAL, 0)
main_box.append(header_bar) main_box.append(header_bar)
main_box.append(general_page) main_box.append(general_page)
window.set_modal(True)
window.set_default_size(500, 650)
window.set_content(main_box) window.set_content(main_box)
window.set_transient_for(parent_widget)
def choose_cover(widget): def choose_cover(widget):
filechooser.open(window, None, None, set_cover, None) filechooser.open(window, None, set_cover, None)
def set_cover(source, result, _): def set_cover(source, result, _):
nonlocal pixbuf nonlocal pixbuf
try: try:
pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(filechooser.open_finish(result).get_path(), 200, 300, False) pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(filechooser.open_finish(result).get_path(), 200, 300, False)
cover.set_pixbuf(pixbuf) cover.set_pixbuf(pixbuf)
@@ -123,7 +131,6 @@ def create_details_window(parent_widget, game_id = None):
values = {} values = {}
games_dir = os.path.join(os.environ.get("XDG_DATA_HOME"), "games")
final_name = name.get_buffer().get_text() final_name = name.get_buffer().get_text()
final_executable = executable.get_buffer().get_text() final_executable = executable.get_buffer().get_text()
@@ -185,7 +192,7 @@ def create_details_window(parent_widget, game_id = None):
name.connect("activate", focus_executable) name.connect("activate", focus_executable)
executable.connect("activate", apply_preferences) executable.connect("activate", apply_preferences)
shortcut_controller = Gtk.ShortcutController.new() shortcut_controller = Gtk.ShortcutController()
shortcut_controller.add_shortcut(Gtk.Shortcut.new(Gtk.ShortcutTrigger.parse_string('Escape'), Gtk.CallbackAction.new(close_window))) shortcut_controller.add_shortcut(Gtk.Shortcut.new(Gtk.ShortcutTrigger.parse_string('Escape'), Gtk.CallbackAction.new(close_window)))
window.add_controller(shortcut_controller) window.add_controller(shortcut_controller)

View File

@@ -21,7 +21,7 @@ def get_cover(game, parent_widget):
from gi.repository import GdkPixbuf from gi.repository import GdkPixbuf
import os import os
cover_path = os.path.join(os.environ.get("XDG_DATA_HOME"), "covers", game["game_id"] + ".dat") cover_path = os.path.join(os.environ.get("XDG_DATA_HOME"), "cartridges", "covers", game["game_id"] + ".dat")
if os.path.isfile(cover_path) == False: if os.path.isfile(cover_path) == False:
return parent_widget.placeholder_pixbuf return parent_widget.placeholder_pixbuf

View File

@@ -20,7 +20,7 @@
def get_games(): def get_games():
import os, json import os, json
games_dir = os.path.join(os.environ.get("XDG_DATA_HOME"), "games") games_dir = os.path.join(os.environ.get("XDG_DATA_HOME"), "cartridges", "games")
games = {} games = {}
if os.path.exists(games_dir) == False: if os.path.exists(games_dir) == False:

180
src/utils/heroic_parser.py Normal file
View File

@@ -0,0 +1,180 @@
# heroic_parser.py
#
# Copyright 2022 kramo
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# SPDX-License-Identifier: GPL-3.0-or-later
def heroic_parser(parent_widget, action):
import os, json, time, hashlib
from gi.repository import Gtk, GLib
from .create_dialog import create_dialog
from .save_cover import save_cover
schema = parent_widget.schema
heroic_dir = os.path.expanduser(os.path.join(schema.get_string("heroic-location")))
def heroic_not_found():
filechooser = Gtk.FileDialog.new()
def set_heroic_dir(source, result, _):
try:
schema.set_string("heroic-location", filechooser.select_folder_finish(result).get_path())
heroic_dir = heroic_dir = os.path.join(schema.get_string("heroic-location"))
action(None, None)
except GLib.GError:
return
def choose_folder(widget):
filechooser.select_folder(parent_widget, None, set_heroic_dir, None)
def response(widget, response):
if response == "choose_folder":
choose_folder(widget)
create_dialog(parent_widget, _("Couldn't Import Games"), _("Heroic directory cannot be found."),
"choose_folder", _("Set Heroic Location")).connect("response", response)
if os.path.exists(os.path.join(heroic_dir, "config.json")) == True:
pass
else:
heroic_not_found()
return {}
heroic_games = {}
current_time = int(time.time())
# Import Epic games
if not schema.get_boolean("heroic-import-epic"):
pass
elif os.path.exists(os.path.join(heroic_dir, "lib-cache", "installInfo.json")) and os.path.exists(
os.path.join(heroic_dir, "lib-cache", "library.json")):
open_file = open(os.path.join(heroic_dir, "lib-cache", "installInfo.json"), "r")
data = open_file.read()
open_file.close()
installInfo = json.loads(data)
open_file = open(os.path.join(heroic_dir, "lib-cache", "library.json"), "r")
data = open_file.read()
library = json.loads(data)
open_file.close()
for item in installInfo:
if installInfo[item].get("install") is not None:
values = {}
app_name = installInfo[item]["game"]["app_name"]
values["game_id"] = "heroic_epic_" + app_name
if values["game_id"] in parent_widget.games and "removed" not in parent_widget.games[
values["game_id"]].keys():
continue
values["name"] = installInfo[item]["game"]["title"]
values["executable"] = "xdg-open heroic://launch/" + app_name
values["hidden"] = False
values["source"] = "heroic_epic"
values["added"] = current_time
values["last_played"] = 0
for game in library["library"]:
if game["app_name"] == app_name:
image_path = os.path.join(heroic_dir, "images-cache",
hashlib.sha256((game[
"art_square"] + "?h=400&resize=1&w=300").encode()).hexdigest())
if os.path.exists(image_path):
values["pixbuf_options"] = save_cover(values, parent_widget, image_path)
break
heroic_games[values["game_id"]] = values
# Import GOG games
if not schema.get_boolean("heroic-import-gog"):
pass
elif os.path.exists(os.path.join(heroic_dir, "gog_store", "installed.json")):
open_file = open(os.path.join(heroic_dir, "gog_store", "installed.json"), "r")
data = open_file.read()
open_file.close()
installed = json.loads(data)
for item in installed["installed"]:
values = {}
app_name = item["appName"]
values["game_id"] = "heroic_gog_" + app_name
if values["game_id"] in parent_widget.games and "removed" not in parent_widget.games[
values["game_id"]].keys():
continue
# Get game title from library.json as it's not present in installed.json
open_file = open(os.path.join(heroic_dir, "gog_store", "library.json"), "r")
data = open_file.read()
open_file.close()
library = json.loads(data)
for game in library["games"]:
if game["app_name"] == app_name:
values["name"] = game["title"]
image_path = os.path.join(heroic_dir, "images-cache",
hashlib.sha256(game["art_square"].encode()).hexdigest())
if os.path.exists(image_path):
values["pixbuf_options"] = save_cover(values, parent_widget, image_path)
break
values["executable"] = "xdg-open heroic://launch/" + app_name
values["hidden"] = False
values["source"] = "heroic_gog"
values["added"] = current_time
values["last_played"] = 0
heroic_games[values["game_id"]] = values
# Import sideloaded games
if schema.get_boolean("heroic-import-sideload") == False:
pass
elif os.path.exists(os.path.join(heroic_dir, "sideload_apps", "library.json")) == True:
open_file = open(os.path.join(heroic_dir, "sideload_apps", "library.json"), "r")
data = open_file.read()
open_file.close()
library = json.loads(data)
for item in library["games"]:
values = {}
app_name = item["app_name"]
values["game_id"] = "heroic_sideload_" + app_name
if values["game_id"] in parent_widget.games and "removed" not in parent_widget.games[
values["game_id"]].keys():
continue
values["name"] = item["title"]
values["executable"] = "xdg-open heroic://launch/" + app_name
values["hidden"] = False
values["source"] = "heroic_sideload"
values["added"] = current_time
values["last_played"] = 0
image_path = os.path.join(heroic_dir, "images-cache",
hashlib.sha256(item["art_square"].encode()).hexdigest())
if os.path.exists(image_path):
values["pixbuf_options"] = save_cover(values, parent_widget, image_path)
heroic_games[values["game_id"]] = values
if len(heroic_games) == 0:
create_dialog(parent_widget, _("No Games Found"), _("No new games found in Heroic library."))
elif len(heroic_games) == 1:
create_dialog(parent_widget, _("Heroic Games Imported"), _("Successfully imported 1 game."))
elif len(heroic_games) > 1:
create_dialog(parent_widget, _("Heroic Games Imported"),
_("Successfully imported") + " " + str(len(heroic_games)) + " " + _("games."))
return heroic_games

View File

@@ -24,5 +24,5 @@ def run_command(parent_widget, executable):
subprocess.Popen(["flatpak-spawn --host " + executable], shell=True, start_new_session=True) subprocess.Popen(["flatpak-spawn --host " + executable], shell=True, start_new_session=True)
if Gio.Settings.new("hu.kramo.GameShelf").get_boolean("exit-after-launch") == True: if Gio.Settings.new("hu.kramo.Cartridges").get_boolean("exit-after-launch") == True:
sys.exit() sys.exit()

View File

@@ -21,7 +21,7 @@ def save_cover(game, parent_widget, file_path, pixbuf = None, game_id = None):
from gi.repository import GdkPixbuf from gi.repository import GdkPixbuf
import os import os
covers_dir = os.path.join(os.environ.get("XDG_DATA_HOME"), "covers") covers_dir = os.path.join(os.environ.get("XDG_DATA_HOME"), "cartridges", "covers")
if os.path.exists(covers_dir) == False: if os.path.exists(covers_dir) == False:
os.makedirs(covers_dir) os.makedirs(covers_dir)

View File

@@ -19,7 +19,7 @@
def save_games(games): def save_games(games):
import os, json import os, json
games_dir = os.path.join(os.environ.get("XDG_DATA_HOME"), "games") games_dir = os.path.join(os.environ.get("XDG_DATA_HOME"), "cartridges", "games")
existing = [] existing = []
if os.path.exists(games_dir) == False: if os.path.exists(games_dir) == False:

View File

@@ -40,7 +40,7 @@ def steam_parser(parent_widget, action):
return return
def choose_folder(widget): def choose_folder(widget):
filechooser.select_folder(parent_widget, None, None, set_steam_dir, None) filechooser.select_folder(parent_widget, None, set_steam_dir, None)
def response(widget, response): def response(widget, response):
if response == "choose_folder": if response == "choose_folder":
@@ -58,23 +58,23 @@ def steam_parser(parent_widget, action):
steam_not_found() steam_not_found()
return {} return {}
steam_dir = os.path.join(schema.get_string("steam-location")) steam_dir = schema.get_string("steam-location")
appmanifests = [] appmanifests = []
datatypes = ["appid", "name"] datatypes = ["appid", "name"]
steam_games = {} steam_games = {}
current_time = int(time.time()) current_time = int(time.time())
for file in os.listdir(os.path.join(steam_dir, "steamapps")): for open_file in os.listdir(os.path.join(steam_dir, "steamapps")):
path = os.path.join(steam_dir, "steamapps", file) path = os.path.join(steam_dir, "steamapps", open_file)
if os.path.isfile(path) and "appmanifest" in file: if os.path.isfile(path) and "appmanifest" in open_file:
appmanifests.append(path) appmanifests.append(path)
for appmanifest in appmanifests: for appmanifest in appmanifests:
values = {} values = {}
file = open(appmanifest, "r") open_file = open(appmanifest, "r")
data = file.read() data = open_file.read()
file.close() open_file.close()
for datatype in datatypes: for datatype in datatypes:
value = re.findall("\"" + datatype + "\"\t\t\"(.*)\"\n", data) value = re.findall("\"" + datatype + "\"\t\t\"(.*)\"\n", data)
values [datatype] = value[0] values [datatype] = value[0]
@@ -99,5 +99,5 @@ def steam_parser(parent_widget, action):
elif len(steam_games) == 1: elif len(steam_games) == 1:
create_dialog(parent_widget, _("Steam Games Imported"), _("Successfully imported 1 game.")) create_dialog(parent_widget, _("Steam Games Imported"), _("Successfully imported 1 game."))
elif len(steam_games) > 1: elif len(steam_games) > 1:
create_dialog(parent_widget, _("Steam Games Imported"), _("Successfully imported ") + str(len(steam_games)) + _(" games.")) create_dialog(parent_widget, _("Steam Games Imported"), _("Successfully imported") + " " + str(len(steam_games)) + " " + _("games."))
return steam_games return steam_games

View File

@@ -19,7 +19,7 @@
def toggle_hidden(game): def toggle_hidden(game):
import os, json import os, json
games_dir = os.path.join(os.environ.get("XDG_DATA_HOME"), "games") games_dir = os.path.join(os.environ.get("XDG_DATA_HOME"), "cartridges", "games")
if os.path.exists(games_dir) == False: if os.path.exists(games_dir) == False:
return return

View File

@@ -25,8 +25,8 @@ Adw.StatusPage hidden_notice_empty {
valign: center; valign: center;
} }
template GameShelfWindow : Adw.ApplicationWindow { template CartridgesWindow : Adw.ApplicationWindow {
title: _("Game Shelf"); title: _("Cartridges");
default-width: 1110; default-width: 1110;
default-height: 820; default-height: 820;
@@ -348,7 +348,7 @@ menu primary_menu {
} }
item { item {
label: _("About Game Shelf"); label: _("About Cartridges");
action: "app.about"; action: "app.about";
} }
} }
@@ -365,6 +365,11 @@ menu add_games {
label: _("Import From Steam"); label: _("Import From Steam");
action: "app.steam_import"; action: "app.steam_import";
} }
item {
label: _("Import From Heroic");
action: "app.heroic_import";
}
} }
} }

View File

@@ -26,9 +26,9 @@ from .get_cover import get_cover
from .get_games import get_games from .get_games import get_games
from .save_games import save_games from .save_games import save_games
@Gtk.Template(resource_path="/hu/kramo/GameShelf/window.ui") @Gtk.Template(resource_path="/hu/kramo/Cartridges/window.ui")
class GameShelfWindow(Adw.ApplicationWindow): class CartridgesWindow(Adw.ApplicationWindow):
__gtype_name__ = "GameShelfWindow" __gtype_name__ = "CartridgesWindow"
toast_overlay = Gtk.Template.Child() toast_overlay = Gtk.Template.Child()
stack = Gtk.Template.Child() stack = Gtk.Template.Child()
@@ -77,14 +77,14 @@ class GameShelfWindow(Adw.ApplicationWindow):
self.overview.set_measure_overlay(self.overview_box, True) self.overview.set_measure_overlay(self.overview_box, True)
self.overview.set_clip_overlay(self.overview_box, False) self.overview.set_clip_overlay(self.overview_box, False)
self.schema = Gio.Settings.new("hu.kramo.GameShelf") self.schema = Gio.Settings.new("hu.kramo.Cartridges")
self.placeholder_pixbuf = GdkPixbuf.Pixbuf.new_from_resource_at_scale("/hu/kramo/GameShelf/assets/library_placeholder.svg", 200, 300, False) self.placeholder_pixbuf = GdkPixbuf.Pixbuf.new_from_resource_at_scale("/hu/kramo/Cartridges/assets/library_placeholder.svg", 200, 300, False)
games = get_games() games = get_games()
for game in games: for game in games:
if "removed" in games[game].keys(): if "removed" in games[game].keys():
os.remove(os.path.join(os.environ.get("XDG_DATA_HOME"), "games", game + ".json")) os.remove(os.path.join(os.environ.get("XDG_DATA_HOME"), "cartridges", "games", game + ".json"))
try: try:
os.remove(os.path.join(os.environ.get("XDG_DATA_HOME"), "covers", game + ".dat")) os.remove(os.path.join(os.environ.get("XDG_DATA_HOME"), "cartridges", "covers", game + ".dat"))
except FileNotFoundError: except FileNotFoundError:
pass pass
@@ -127,7 +127,7 @@ class GameShelfWindow(Adw.ApplicationWindow):
self.hidden_library.append(entry) self.hidden_library.append(entry)
entry.cover_button.connect("clicked", self.show_overview, game_id) entry.cover_button.connect("clicked", self.show_overview, game_id)
entry.menu_button.connect("state-flags-changed", self.set_active_game, game_id) entry.menu_button.get_popover().connect("notify::visible", self.set_active_game, game_id)
if self.visible_widgets == {}: if self.visible_widgets == {}:
self.library_bin.set_child(self.notice_empty) self.library_bin.set_child(self.notice_empty)
@@ -185,9 +185,8 @@ class GameShelfWindow(Adw.ApplicationWindow):
self.hidden_library_bin.set_child(self.hidden_scrolledwindow) self.hidden_library_bin.set_child(self.hidden_scrolledwindow)
return filtered return filtered
def set_active_game(self, widget, flags, game): def set_active_game(self, widget, _, game):
if "GTK_STATE_FLAG_FOCUS_WITHIN" in flags.value_names: self.active_game_id = game
self.active_game_id = game
def get_time(self, timestamp): def get_time(self, timestamp):
date = datetime.datetime.fromtimestamp(timestamp) date = datetime.datetime.fromtimestamp(timestamp)
@@ -375,7 +374,7 @@ class GameShelfWindow(Adw.ApplicationWindow):
game_id = list(self.toasts)[-1] game_id = list(self.toasts)[-1]
except IndexError: except IndexError:
return return
open_file = open(os.path.join(os.path.join(os.environ.get("XDG_DATA_HOME"), "games", game_id + ".json")), "r") open_file = open(os.path.join(os.path.join(os.environ.get("XDG_DATA_HOME"), "cartridges", "games", game_id + ".json")), "r")
data = json.loads(open_file.read()) data = json.loads(open_file.read())
open_file.close() open_file.close()
data.pop("removed") data.pop("removed")