From 99e6cbf169af7a6602adf1a496d4602dd8f28193 Mon Sep 17 00:00:00 2001 From: kramo Date: Sun, 29 Jan 2023 14:27:27 +0100 Subject: [PATCH] Support for Heroic import --- README.md | 2 +- data/hu.kramo.GameShelf.gschema.xml | 12 + data/hu.kramo.GameShelf.metainfo.xml.in | 2 +- hu.kramo.GameShelf.json | 3 +- meson.build | 2 +- po/POTFILES | 5 +- po/gameshelf.pot | 357 +++++++++++++---------- po/hu.mo | Bin 3824 -> 4540 bytes po/hu.po | 365 +++++++++++++----------- src/gtk/preferences.blp | 44 ++- src/main.py | 11 +- src/meson.build | 1 + src/preferences.py | 21 +- src/utils/heroic_parser.py | 158 ++++++++++ src/utils/steam_parser.py | 16 +- src/window.blp | 5 + 16 files changed, 663 insertions(+), 341 deletions(-) create mode 100644 src/utils/heroic_parser.py diff --git a/README.md b/README.md index b210d7b..97c3ee3 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Game Shelf is a simple game launcher written in Python using GTK4 + Libadwaita. ### Features - Manually adding and editing games -- Importing games from Steam +- Importing games from Steam and Heroic - Hiding games - Searching and sorting by title, date added and last played diff --git a/data/hu.kramo.GameShelf.gschema.xml b/data/hu.kramo.GameShelf.gschema.xml index 8c8ed94..787701a 100644 --- a/data/hu.kramo.GameShelf.gschema.xml +++ b/data/hu.kramo.GameShelf.gschema.xml @@ -4,8 +4,20 @@ false + + true + + + true + + + true + "~/.steam/" + + + "~/.var/app/com.heroicgameslauncher.hgl/config/heroic/" diff --git a/data/hu.kramo.GameShelf.metainfo.xml.in b/data/hu.kramo.GameShelf.metainfo.xml.in index 1d6f16e..95e63d7 100644 --- a/data/hu.kramo.GameShelf.metainfo.xml.in +++ b/data/hu.kramo.GameShelf.metainfo.xml.in @@ -6,7 +6,7 @@ Game Shelf Launch all your games -

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.

+

Game Shelf 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.

hu.kramo.GameShelf.desktop kramo diff --git a/hu.kramo.GameShelf.json b/hu.kramo.GameShelf.json index 74801bb..94c44d0 100644 --- a/hu.kramo.GameShelf.json +++ b/hu.kramo.GameShelf.json @@ -11,7 +11,8 @@ "--socket=wayland", "--talk-name=org.freedesktop.Flatpak", "--filesystem=xdg-run/gvfsd", - "--filesystem=~/.steam/steam/" + "--filesystem=~/.steam/steam/", + "--filesystem=~/.var/app/com.heroicgameslauncher.hgl/config/heroic/" ], "cleanup" : [ "/include", diff --git a/meson.build b/meson.build index acb58b4..608ed9c 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('gameshelf', - version: '0.1.0', + version: '0.1.1', meson_version: '>= 0.59.0', default_options: [ 'warning_level=2', 'werror=false', ], ) diff --git a/po/POTFILES b/po/POTFILES index a733a63..26720fe 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -1,6 +1,3 @@ -data/hu.kramo.GameShelf.desktop.in -data/hu.kramo.GameShelf.metainfo.xml.in - src/main.py src/window.py src/window.blp @@ -12,3 +9,5 @@ src/gtk/preferences.blp src/utils/create_details_window.py src/utils/create_dialog.py +src/utils/steam_parser.py +src/utils/heroic_parser.py diff --git a/po/gameshelf.pot b/po/gameshelf.pot index eb6ad26..6b008d7 100644 --- a/po/gameshelf.pot +++ b/po/gameshelf.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\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: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,243 +17,286 @@ msgstr "" "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" +#: src/main.py:133 +msgid "removed" msgstr "" -#: ../main.py:127 +#: src/main.py:134 msgid "Undo" msgstr "" -#: ../window.py:196 +#: src/window.py:195 msgid "Today" msgstr "" -#: ../window.py:198 +#: src/window.py:197 msgid "Yesterday" msgstr "" -#: ../window.py:222 +#: src/window.py:221 msgid "Added: " msgstr "" -#: ../window.py:223 +#: src/window.py:222 msgid "Last played: " msgstr "" -#: ../window.py:223 +#: src/window.py:222 msgid "Last played: Never" msgstr "" -#: ../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 "" + +#: 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 "Game Shelf" +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 Game Shelf" +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 "" -#: ../utils/create_details_window.py:37 +#: src/utils/create_details_window.py:42 msgid "Confirm" msgstr "" -#: ../utils/create_details_window.py:39 +#: src/utils/create_details_window.py:44 msgid "Edit Game Details" msgstr "" -#: ../utils/create_details_window.py:43 +#: src/utils/create_details_window.py:48 msgid "Apply" msgstr "" -#: ../utils/create_details_window.py:46 +#: src/utils/create_details_window.py:51 msgid "Images" msgstr "" -#: ../utils/create_details_window.py:73 +#: src/utils/create_details_window.py:83 msgid "The title of the game" msgstr "" -#: ../utils/create_details_window.py:77 +#: src/utils/create_details_window.py:88 msgid "Executable" msgstr "" -#: ../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" msgstr "" -#: ../utils/create_details_window.py:86 +#: src/utils/create_details_window.py:98 msgid "Cancel" msgstr "" -#: ../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" msgstr "" -#: ../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." msgstr "" -#: ../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." msgstr "" -#: ../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" msgstr "" -#: ../utils/create_dialog.py:24 +#: src/utils/create_dialog.py:24 msgid "Dismiss" msgstr "" -#: ../utils/steam_parser.py:49 +#: src/utils/steam_parser.py:49 src/utils/heroic_parser.py:49 msgid "Couldn't Import Games" msgstr "" -#: ../utils/steam_parser.py:49 +#: src/utils/steam_parser.py:49 msgid "Steam directory cannot be found." msgstr "" -#: ../utils/steam_parser.py:49 +#: src/utils/steam_parser.py:49 msgid "Set Steam Location" msgstr "" -#: ../utils/steam_parser.py:98 +#: src/utils/steam_parser.py:98 msgid "No new games found in Steam library." msgstr "" -#: ../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" msgstr "" -#: ../utils/steam_parser.py:100 +#: src/utils/steam_parser.py:100 src/utils/heroic_parser.py:155 msgid "Successfully imported 1 game." msgstr "" -#: ../utils/steam_parser.py:102 -msgid "Successfully imported " +#: src/utils/steam_parser.py:102 src/utils/heroic_parser.py:157 +msgid "Successfully imported" msgstr "" -#: ../utils/steam_parser.py:102 -msgid " games." +#: 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 "" diff --git a/po/hu.mo b/po/hu.mo index 043e2764055b00c224cfd515a36bd2a288da9d4b..3b44edf7253c83ea478ce64d41a4379377872bc6 100644 GIT binary patch delta 2210 zcmZ|PU2Kz89LMo9+*k*DfxQA_@{GCpwidb#-G zc41;9A!2-@F?iz=Nd}2xATb6>6syrI16N*1jNXuFG%;QnVleUhYfp8)aI$|t=Q(}O z+y9*Im!>N%i{Dlkziuc)#Aae_l`$?JFXlsKwJ~==5w61$3}8K$;}$H%b}Ydz6%DkCZD|2j$Q-5?wU9=v#-M%fM`hx1)IgK=`(wD4 z=U1=-&)D{5)Oa6ZC4P!kcpY1r-+WKy9xN@(zu1miNGEE*Zri>aYj_?-E$A8heG2vd z39Q8zu^!(<2QQ#@ehr)OrhP6ZZHqdyO;n_V+EE*7z&_N<2k~wkLHe2)>Q1EX_eYT= zniJStWXwzU`>U*88T=fzu&;3g{)EbSNjdpv^QM|7P1J~dXSSk)Ayj7eV>4!uOJm+Z zO?U;hpwF-czq0MWqVCG?sQz`F#{l-CGIty`&*=*CubsX{gLeKlhVeuD!jGt5#c!yU z*KmMaupPCtG1S5jSv}m!a~$>lY1FvOs7v_?Zo?a>qby(KCaB_|Qq+a&7(wl90@X2Y zeHnH8-@zUD4QeOrxsl396Ee1GMYVUK`uC$UauBufqp0y0PudrJ)JiX)&iV_~rMZa? z-bUs!P4rgAg2=xL(}8+_2a;_wj=D=OcHk5$LuXKTW(jrVXOW~Xn)j#_(V(VVK)Mfo#LA)t+)D&kG%Bkri?ULy-~V1L3~ZB{p0x7?4E{82Y> zIOC<9G51Jf^4VBo${BWNytIFC^-`yoO2#Jh&rW1!HkrzJQL{JS8cC!xZanUcB`4iX zESa$FepO(ze|xp_)SlTwSCjAR45gAYPQLd)nhs<c9)O^T4RT?R@71rZlEA3zR??w7$ffj!-Q0or_8vJD7Sml)V8Zs$w zCOPLt{T~9mDmsJP!@-UoC*0K=?(w_Je!kSV=1@`nNOmccJvW`4b|Q&r_T5Z&DeXE> z`0ua1+Gkg@;*DIcvP!O=mwy z%+Imi)P$P|`TZ4#8|^py+}T;z8I8>`vYTGWWyC*QG2W0nQ0G58_HR`*`{Bx3f2i_& T!*ls`hKv`d<6JUMZphZ3|B+*1 delta 1636 zcmYk+Z)_Ar7{~Fct`nx@q-#QvTF_h=1Yp4wm88d`;>N!w$JZ#KT9Kc4*pl-d0?f9~9KZMO(kD~gI zAwM(8VF^z8_G7q=>uFqNOvRk$q?3m4u@`Tk2AIbNtmkPx(1=M~g{!gGo5Af|A4CQ4 zF{)qHdluFI8?<;GHU52U=KbaYCwftWR!&VT>V=)yfg7+12eAeB`St^-{v+6md2GW; zd>oJa`{z;PUqFrXop1jUJ9xjj=5O3Yb-ar!@K3auB=23g(YptGxPAqdxd|j$=D644 zO0G|$#`_W#=-2ot&S3(7!HU-MHYbC1#{BMY^pZc#Xfx{mZd6A0paMI9-IztC{C(t6 z^AYMrpQ2`Z3N3zt%E(n*hxbrRy}XJ1Gf6W*Z$*^B^|&9^UO+a9nZUDT`bCw zqSxo9q6}#k3aFo|J)p8_f%wS#%o9`v^$b;6(xz1*ph~>1Te#4AZlvy{D&_if(aZ*^ zi$$9!PCHua4(eignv(&lX1$im9*dV|1FCFZApV5?DNCily8o4@IM=7O%eN`TTDO$H zeiHRB`7Bk-5f?iWV~b&~FdiPBUh+>@@On8c+9(*y507T^BQ}UTxsIh(SKqic zxvyBr*`ab6^d`*fF=Q<&t};)vkOYceGHXF`|7TuGDLnPeiV%?OXStZLfQ^eaKyDx2ZU|au|h2 gHO5TIj)u|Op&7~^35#JV%-ihZK;waR^X;Gi2ahqzHvj+t diff --git a/po/hu.po b/po/hu.po index 48fe439..7671a56 100644 --- a/po/hu.po +++ b/po/hu.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-12-26 14:29+0100\n" -"PO-Revision-Date: 2022-12-26 14:33+0100\n" +"POT-Creation-Date: 2023-01-29 14:12+0100\n" +"PO-Revision-Date: 2023-01-29 14:19+0100\n" "Last-Translator: kramo \n" "Language-Team: \n" "Language: hu\n" @@ -18,243 +18,286 @@ msgstr "" "Plural-Forms: nplurals=2; plural=(n != 1);\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 -#: ../main.py:126 -msgid " removed" -msgstr " eltávolítva" +#: src/main.py:133 +msgid "removed" +msgstr "eltávolítva" -#: ../main.py:127 +#: src/main.py:134 msgid "Undo" msgstr "Visszavonás" -#: ../window.py:196 +#: src/window.py:195 msgid "Today" msgstr "Ma" -#: ../window.py:198 +#: src/window.py:197 msgid "Yesterday" msgstr "Tegnap" -#: ../window.py:222 +#: src/window.py:221 msgid "Added: " msgstr "Hozzáadva: " -#: ../window.py:223 +#: src/window.py:222 msgid "Last played: " msgstr "Legutóbb játszva: " -#: ../window.py:223 +#: src/window.py:222 msgid "Last played: Never" 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 "Game Shelf" +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 Game Shelf" +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" msgstr "Új Játék Hozzáadása" -#: ../utils/create_details_window.py:37 +#: src/utils/create_details_window.py:42 msgid "Confirm" msgstr "Megerősít" -#: ../utils/create_details_window.py:39 +#: src/utils/create_details_window.py:44 msgid "Edit Game Details" msgstr "Játék Részleteinek Szerkesztése" -#: ../utils/create_details_window.py:43 +#: src/utils/create_details_window.py:48 msgid "Apply" msgstr "Alkalmaz" -#: ../utils/create_details_window.py:46 +#: src/utils/create_details_window.py:51 msgid "Images" msgstr "Képek" -#: ../utils/create_details_window.py:73 +#: src/utils/create_details_window.py:83 msgid "The title of the game" msgstr "A játék címe" -#: ../utils/create_details_window.py:77 +#: src/utils/create_details_window.py:88 msgid "Executable" 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" 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" 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" 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." 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." 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" msgstr "Nem Lehet Menteni a Beállításokat" -#: ../utils/create_dialog.py:24 +#: src/utils/create_dialog.py:24 msgid "Dismiss" msgstr "Rendben" -#: ../utils/steam_parser.py:49 +#: src/utils/steam_parser.py:49 src/utils/heroic_parser.py:49 msgid "Couldn't Import Games" 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." msgstr "A Steam mappa nem található." -#: ../utils/steam_parser.py:49 +#: src/utils/steam_parser.py:49 msgid "Set Steam Location" 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." 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" 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." msgstr "1 játék sikeresen importálva." -#: ../utils/steam_parser.py:102 -msgid "Successfully imported " -msgstr "Sikeresen importálva " +#: src/utils/steam_parser.py:102 src/utils/heroic_parser.py:157 +msgid "Successfully imported" +msgstr "Sikeresen importálva" -#: ../utils/steam_parser.py:102 -msgid " games." -msgstr " játék." +#: src/utils/steam_parser.py:102 src/utils/heroic_parser.py:157 +msgid "games." +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" diff --git a/src/gtk/preferences.blp b/src/gtk/preferences.blp index 0a01957..556c0b0 100644 --- a/src/gtk/preferences.blp +++ b/src/gtk/preferences.blp @@ -3,14 +3,14 @@ using Adw 1; template PreferencesWindow : Adw.PreferencesWindow { search-enabled: false; - default-height: 400; + default-height: 500; Adw.PreferencesPage { Adw.PreferencesGroup { title: _("General"); Adw.ActionRow { - title: _("Exit after launching a game"); + title: _("Exit After Launching Games"); Switch exit_after_launch_switch { valign: center; @@ -22,7 +22,7 @@ template PreferencesWindow : Adw.PreferencesWindow { title: "Steam"; Adw.ActionRow { - title: _("Steam install location"); + title: _("Steam Install Location"); subtitle: _("Directory to use when importing games"); 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; + } + } + } } } diff --git a/src/main.py b/src/main.py index fe63180..2a001e6 100644 --- a/src/main.py +++ b/src/main.py @@ -30,6 +30,7 @@ from .toggle_hidden import toggle_hidden from .save_games import save_games from .run_command import run_command from .steam_parser import steam_parser +from .heroic_parser import heroic_parser from .create_details_window import create_details_window class GameShelfApplication(Adw.Application): @@ -39,6 +40,7 @@ class GameShelfApplication(Adw.Application): self.create_action("about", self.on_about_action) self.create_action("preferences", self.on_preferences_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("hide_game", self.on_hide_game_action) self.create_action("edit_details", self.on_edit_details_action) @@ -71,7 +73,7 @@ class GameShelfApplication(Adw.Application): application_name="Game Shelf", application_icon="hu.kramo.GameShelf", developer_name="kramo", - version="0.1.0", + version="0.1.1", developers=["kramo"], copyright="© 2022 kramo", license_type=Gtk.License.GPL_3_0) @@ -85,6 +87,11 @@ class GameShelfApplication(Adw.Application): save_games(games) 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): # Launch the game and update the last played value @@ -123,7 +130,7 @@ class GameShelfApplication(Adw.Application): self.props.active_window.on_go_back_action(None, None) # 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.connect("button-clicked", self.props.active_window.on_undo_remove_action, game_id) toast.set_priority(Adw.ToastPriority.HIGH) diff --git a/src/meson.build b/src/meson.build index f072156..d1eabf7 100644 --- a/src/meson.build +++ b/src/meson.build @@ -44,6 +44,7 @@ gameshelf_sources = [ 'preferences.py', 'game.py', 'utils/steam_parser.py', + 'utils/heroic_parser.py', 'utils/run_command.py', 'utils/get_games.py', 'utils/get_cover.py', diff --git a/src/preferences.py b/src/preferences.py index 64d26c6..d999310 100644 --- a/src/preferences.py +++ b/src/preferences.py @@ -24,7 +24,12 @@ class PreferencesWindow(Adw.PreferencesWindow): __gtype_name__ = 'PreferencesWindow' 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() + heroic_file_chooser_button = Gtk.Template.Child() def __init__(self, parent_widget, **kwargs): super().__init__(**kwargs) @@ -32,6 +37,9 @@ class PreferencesWindow(Adw.PreferencesWindow): self.set_transient_for(parent_widget) schema = parent_widget.schema 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() @@ -41,7 +49,14 @@ class PreferencesWindow(Adw.PreferencesWindow): except GLib.GError: pass - def choose_folder(widget): - filechooser.select_folder(parent_widget, None, None, set_steam_dir, None) + def set_heroic_dir(source, result, user_data): + 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, 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) diff --git a/src/utils/heroic_parser.py b/src/utils/heroic_parser.py new file mode 100644 index 0000000..505be4b --- /dev/null +++ b/src/utils/heroic_parser.py @@ -0,0 +1,158 @@ +# 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 . +# +# SPDX-License-Identifier: GPL-3.0-or-later + +def heroic_parser(parent_widget, action): + import os, json, time + + 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 schema.get_boolean("heroic-import-epic") == False: + pass + elif os.path.exists(os.path.join(heroic_dir, "lib-cache", "installInfo.json")) == True: + open_file = open(os.path.join(heroic_dir, "lib-cache", "installInfo.json"), "r") + data = open_file.read() + open_file.close() + installInfo = json.loads(data) + for item in installInfo: + if installInfo[item]["install"] != 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 + if os.path.isfile(os.path.join(heroic_dir, "icons", app_name + ".jpg")) == True: + values["pixbuf_options"] = save_cover(values, parent_widget, os.path.join(os.path.join(heroic_dir, "icons", app_name + ".jpg"))) + + heroic_games[values["game_id"]] = values + + # Import GOG games + if schema.get_boolean("heroic-import-gog") == False: + pass + elif os.path.exists(os.path.join(heroic_dir, "gog_store", "installed.json")) == True: + 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"] + break + + values["executable"] = "xdg-open heroic://launch/" + app_name + values["hidden"] = False + values["source"] = "heroic_gog" + values["added"] = current_time + values["last_played"] = 0 + if os.path.isfile(os.path.join(heroic_dir, "icons", app_name + ".jpg")) == True: + values["pixbuf_options"] = save_cover(values, parent_widget, os.path.join(os.path.join(heroic_dir, "icons", app_name + ".jpg"))) + 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 + if os.path.isfile(os.path.join(heroic_dir, "icons", app_name + ".jpg")) == True: + values["pixbuf_options"] = save_cover(values, parent_widget, os.path.join(os.path.join(heroic_dir, "icons", app_name + ".jpg"))) + 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 diff --git a/src/utils/steam_parser.py b/src/utils/steam_parser.py index 9d154bb..6815d63 100644 --- a/src/utils/steam_parser.py +++ b/src/utils/steam_parser.py @@ -58,23 +58,23 @@ def steam_parser(parent_widget, action): steam_not_found() return {} - steam_dir = os.path.join(schema.get_string("steam-location")) + steam_dir = schema.get_string("steam-location") appmanifests = [] datatypes = ["appid", "name"] steam_games = {} current_time = int(time.time()) - for file in os.listdir(os.path.join(steam_dir, "steamapps")): - path = os.path.join(steam_dir, "steamapps", file) - if os.path.isfile(path) and "appmanifest" in file: + for open_file in os.listdir(os.path.join(steam_dir, "steamapps")): + path = os.path.join(steam_dir, "steamapps", open_file) + if os.path.isfile(path) and "appmanifest" in open_file: appmanifests.append(path) for appmanifest in appmanifests: values = {} - file = open(appmanifest, "r") - data = file.read() - file.close() + open_file = open(appmanifest, "r") + data = open_file.read() + open_file.close() for datatype in datatypes: value = re.findall("\"" + datatype + "\"\t\t\"(.*)\"\n", data) values [datatype] = value[0] @@ -99,5 +99,5 @@ def steam_parser(parent_widget, action): elif len(steam_games) == 1: create_dialog(parent_widget, _("Steam Games Imported"), _("Successfully imported 1 game.")) 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 diff --git a/src/window.blp b/src/window.blp index 4636705..bfbd00b 100644 --- a/src/window.blp +++ b/src/window.blp @@ -365,6 +365,11 @@ menu add_games { label: _("Import From Steam"); action: "app.steam_import"; } + + item { + label: _("Import From Heroic"); + action: "app.heroic_import"; + } } }