mirror of
https://github.com/c9moser/sgbackup.git
synced 2026-01-19 19:40:13 +00:00
2025.01.07 09:40:43
This commit is contained in:
parent
ab4b11f118
commit
ec55f3b8eb
@ -16,5 +16,51 @@
|
|||||||
# along with this program. If not, see <https://www.gnu.org/licenses/>. #
|
# along with this program. If not, see <https://www.gnu.org/licenses/>. #
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
from gi.repository.GObject import (
|
||||||
|
GObject,
|
||||||
|
Property,
|
||||||
|
Signal,
|
||||||
|
SignalFlags,
|
||||||
|
signal_accumulator_true_handled,
|
||||||
|
)
|
||||||
|
|
||||||
|
from .game import Game
|
||||||
|
|
||||||
class Archiver:
|
class Archiver:
|
||||||
pass
|
def __init__(self,key:str,name:str,extensions:list[str],decription:str|None=None):
|
||||||
|
self.__key = key
|
||||||
|
self.__name = name
|
||||||
|
if decription:
|
||||||
|
self.__description = decription
|
||||||
|
else:
|
||||||
|
self.__description = ""
|
||||||
|
|
||||||
|
@Property(type=str)
|
||||||
|
def name(self)->str:
|
||||||
|
return self.__name
|
||||||
|
|
||||||
|
@Property
|
||||||
|
def key(self)->str:
|
||||||
|
return self.__key
|
||||||
|
|
||||||
|
@Property
|
||||||
|
def description(self)->str:
|
||||||
|
return self.__description
|
||||||
|
|
||||||
|
def backup(self,game)->bool:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def restore(self,game,file)->bool:
|
||||||
|
pass
|
||||||
|
|
||||||
|
@Signal(name="backup",flags=SignalFlags.RUN_FIRST,
|
||||||
|
return_type=bool, arg_types=(GObject,str),
|
||||||
|
accumulator=signal_accumulator_true_handled)
|
||||||
|
def do_backup(self,game:Game,filename:str):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@Signal(name="restore",flags=SignalFlags.RUN_FIRST,
|
||||||
|
return_type=bool,arg_types=(GObject,str),
|
||||||
|
accumulator=signal_accumulator_true_handled)
|
||||||
|
def do_backup(self,game:Game,filanme:str):
|
||||||
|
pass
|
||||||
492
sgbackup/game.py
492
sgbackup/game.py
@ -46,21 +46,71 @@ else:
|
|||||||
|
|
||||||
|
|
||||||
class SavegameType(StrEnum):
|
class SavegameType(StrEnum):
|
||||||
|
"""
|
||||||
|
SavegameType The savegame type for `Game` instance.
|
||||||
|
|
||||||
|
The SavegameType selects the `GameData` provider for the
|
||||||
|
`Game` instance.
|
||||||
|
"""
|
||||||
|
|
||||||
|
#: UNSET The SavegameType is unset
|
||||||
UNSET = "unset"
|
UNSET = "unset"
|
||||||
|
|
||||||
|
#: OTHER Not listed game-provider.
|
||||||
|
#:
|
||||||
|
#: **Currently not supported!**
|
||||||
OTHER = "other"
|
OTHER = "other"
|
||||||
|
|
||||||
|
#: WINDOWS Native Windows game
|
||||||
WINDOWS = "windows"
|
WINDOWS = "windows"
|
||||||
|
|
||||||
|
#: LINUX Native Linux game
|
||||||
LINUX = "linux"
|
LINUX = "linux"
|
||||||
|
|
||||||
|
#: MACOS Native MacOS game
|
||||||
MACOS = "macos"
|
MACOS = "macos"
|
||||||
|
|
||||||
|
#: STEAM_WINDOWS *Steam* for Windows
|
||||||
STEAM_WINDOWS = "steam_windows"
|
STEAM_WINDOWS = "steam_windows"
|
||||||
|
|
||||||
|
#: STEAM_LINUX *Steam* for Linux
|
||||||
STEAM_LINUX = "steam_linux"
|
STEAM_LINUX = "steam_linux"
|
||||||
|
|
||||||
|
#: STEAM_MACOS *Steam* for MacOS
|
||||||
STEAM_MACOS = "steam_macos"
|
STEAM_MACOS = "steam_macos"
|
||||||
|
|
||||||
|
#: GOG WINDOWS *Good old Games* for Windows
|
||||||
|
#:
|
||||||
|
#: **Currently not supported!**
|
||||||
GOG_WINDOWS = "gog_windows"
|
GOG_WINDOWS = "gog_windows"
|
||||||
|
|
||||||
|
#: GOG_LINUX *Good old Games* for Linux
|
||||||
|
#:
|
||||||
|
#: **Currently not supported!**
|
||||||
GOG_LINUX = "gog_linux"
|
GOG_LINUX = "gog_linux"
|
||||||
|
|
||||||
|
#: EPIC_WINDOWS *Epic Games* for Windows
|
||||||
|
#:
|
||||||
|
#: **Currently not supported!**
|
||||||
EPIC_WINDOWS = "epic_windows"
|
EPIC_WINDOWS = "epic_windows"
|
||||||
|
|
||||||
|
#: EPIC_LINUX *Epic Games* for Linux
|
||||||
|
#:
|
||||||
|
#: **Currently not supported!**
|
||||||
EPIC_LINUX = "epic_linux"
|
EPIC_LINUX = "epic_linux"
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def from_string(typestring:str):
|
def from_string(typestring:str):
|
||||||
|
"""
|
||||||
|
from_string Get SavegameType from string.
|
||||||
|
|
||||||
|
:param typestring: The string to parse
|
||||||
|
:type typestring: str
|
||||||
|
:return: The SavegameType if any. If no matching SavegameType is found,
|
||||||
|
SavegameType.UNSET is returned.
|
||||||
|
:rtype: SavegameType
|
||||||
|
"""
|
||||||
|
|
||||||
st=SavegameType
|
st=SavegameType
|
||||||
s=typestring.lower()
|
s=typestring.lower()
|
||||||
if (s == 'other'):
|
if (s == 'other'):
|
||||||
@ -71,31 +121,53 @@ class SavegameType(StrEnum):
|
|||||||
return st.LINUX
|
return st.LINUX
|
||||||
elif (s == 'macos'):
|
elif (s == 'macos'):
|
||||||
return st.MACOS
|
return st.MACOS
|
||||||
elif (s == 'steam_windows' or s == 'steamwindows' or s == 'steam.windows'):
|
elif (s == 'steam_windows' or s == 'steam-windows' or s == 'steamwindows' or s == 'steam.windows'):
|
||||||
return st.STEAM_WINDOWS
|
return st.STEAM_WINDOWS
|
||||||
elif (s == 'steam_linux' or s == 'steamlinux' or s == 'steam.linux'):
|
elif (s == 'steam_linux' or s == 'steam-linux' or s == 'steamlinux' or s == 'steam.linux'):
|
||||||
return st.STEAM_LINUX
|
return st.STEAM_LINUX
|
||||||
elif (s == 'steam_macos' or s == 'steammacos' or s == 'steam.macos'):
|
elif (s == 'steam_macos' or s == 'steam-macos' or s == 'steammacos' or s == 'steam.macos'):
|
||||||
return st.STEAM_MACOS
|
return st.STEAM_MACOS
|
||||||
elif (s == 'gog_winows' or s == 'gogwindows' or s == 'gog.windows'):
|
elif (s == 'gog_winows' or s == 'gog-windows' or s == 'gogwindows' or s == 'gog.windows'):
|
||||||
return st.GOG_WINDOWS
|
return st.GOG_WINDOWS
|
||||||
elif (s == 'gog_linux' or s == 'goglinux' or s == 'gog.linux'):
|
elif (s == 'gog_linux' or s == 'gog-linux' or s == 'goglinux' or s == 'gog.linux'):
|
||||||
return st.GOG_LINUX
|
return st.GOG_LINUX
|
||||||
elif (s == 'epic_windows' or s == 'epicwindows' or s == 'epic.windows'):
|
elif (s == 'epic_windows' or s == 'epic-windows' or s == 'epicwindows' or s == 'epic.windows'):
|
||||||
return st.EPIC_WINDOWS
|
return st.EPIC_WINDOWS
|
||||||
elif (s == 'epic_linux' or s == 'epiclinux' or s == 'epic.linux'):
|
elif (s == 'epic_linux' or s == 'epic-linux' or s == 'epiclinux' or s == 'epic.linux'):
|
||||||
return st.EPIC_LINUX
|
return st.EPIC_LINUX
|
||||||
|
|
||||||
return st.UNSET
|
return st.UNSET
|
||||||
|
|
||||||
|
|
||||||
class GameFileType(StrEnum):
|
class GameFileType(StrEnum):
|
||||||
|
"""
|
||||||
|
GameFileType The file matcher type for `GameFileMatcher`.
|
||||||
|
|
||||||
|
The path to be matched is originating from *${SAVEGAME_ROOT}/${SAVEGAME_DIR}*.
|
||||||
|
"""
|
||||||
|
|
||||||
|
#: GLOB Glob matching.
|
||||||
GLOB = "glob"
|
GLOB = "glob"
|
||||||
|
|
||||||
|
#: REGEX Regex file matching
|
||||||
REGEX = "regex"
|
REGEX = "regex"
|
||||||
|
|
||||||
|
#: FILENAME Filename matching.
|
||||||
FILENAME = "filename"
|
FILENAME = "filename"
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def from_string(typestring:str):
|
def from_string(typestring:str):
|
||||||
|
"""
|
||||||
|
from_string Get the `GameFileType` from a string.
|
||||||
|
|
||||||
|
If an illegal string-value is given this method raises a `ValueError`.
|
||||||
|
|
||||||
|
:param typestring: The string to be used.
|
||||||
|
:type typestring: str
|
||||||
|
:raises ValueError: If an illegal string is given.
|
||||||
|
:return: The corresponding Enum-value
|
||||||
|
:rtype: GameFileType
|
||||||
|
"""
|
||||||
s = typestring.lower()
|
s = typestring.lower()
|
||||||
if (s == 'glob'):
|
if (s == 'glob'):
|
||||||
return GameFileType.GLOB
|
return GameFileType.GLOB
|
||||||
@ -104,9 +176,12 @@ class GameFileType(StrEnum):
|
|||||||
elif (s == 'filename'):
|
elif (s == 'filename'):
|
||||||
return GameFileType.FILENAME
|
return GameFileType.FILENAME
|
||||||
|
|
||||||
raise ValueError("Unknown GameFileType \"{}\"!".fomrat(typestring))
|
raise ValueError("Unknown GameFileType \"{}\"!".format(typestring))
|
||||||
|
|
||||||
class GameFileMatcher(GObject):
|
class GameFileMatcher(GObject):
|
||||||
|
"""
|
||||||
|
GameFileMatcher Match savegame files if they are to be included in the backup.
|
||||||
|
"""
|
||||||
__gtype_name__ = "GameFileMatcher"
|
__gtype_name__ = "GameFileMatcher"
|
||||||
|
|
||||||
def __init__(self,match_type:GameFileType,match_file:str):
|
def __init__(self,match_type:GameFileType,match_file:str):
|
||||||
@ -116,7 +191,14 @@ class GameFileMatcher(GObject):
|
|||||||
|
|
||||||
@Property
|
@Property
|
||||||
def match_type(self)->GameFileType:
|
def match_type(self)->GameFileType:
|
||||||
|
"""
|
||||||
|
match_type The type of the matcher.
|
||||||
|
|
||||||
|
:type: GameFileType
|
||||||
|
"""
|
||||||
|
|
||||||
return self.__match_type
|
return self.__match_type
|
||||||
|
|
||||||
@match_type.setter
|
@match_type.setter
|
||||||
def match_type(self,type:GameFileType):
|
def match_type(self,type:GameFileType):
|
||||||
if not isinstance(type,GameFileType):
|
if not isinstance(type,GameFileType):
|
||||||
@ -125,15 +207,27 @@ class GameFileMatcher(GObject):
|
|||||||
|
|
||||||
@Property(type=str)
|
@Property(type=str)
|
||||||
def match_file(self)->str:
|
def match_file(self)->str:
|
||||||
|
"""
|
||||||
|
match_file The matcher value.
|
||||||
|
|
||||||
|
:type: str
|
||||||
|
"""
|
||||||
return self.__match_file
|
return self.__match_file
|
||||||
@match_file.setter
|
@match_file.setter
|
||||||
def match_file(self,file:str):
|
def match_file(self,file:str):
|
||||||
self.__match_file = file
|
self.__match_file = file
|
||||||
|
|
||||||
## @}
|
def match(self,rel_filename:str)->bool:
|
||||||
|
"""
|
||||||
def match(self,rel_filename:str):
|
match Match the file.
|
||||||
def match_glob(filename):
|
|
||||||
|
:param rel_filename: The relative filename originating from
|
||||||
|
*${SAVEGAME_ROOT}/${SAVEGAME_DIR}*.
|
||||||
|
:type rel_filename: str
|
||||||
|
:rtype: bool
|
||||||
|
:returns: True if file matches
|
||||||
|
"""
|
||||||
|
def match_glob(filename)->bool:
|
||||||
return fnmatch.fnmatch(filename,self.match_file)
|
return fnmatch.fnmatch(filename,self.match_file)
|
||||||
# match_glob()
|
# match_glob()
|
||||||
|
|
||||||
@ -170,8 +264,7 @@ class GameData(GObject):
|
|||||||
__gtype_name__ = 'GameData'
|
__gtype_name__ = 'GameData'
|
||||||
|
|
||||||
"""
|
"""
|
||||||
:class: GameData
|
:class: GameData Base class for savegame specific data data.
|
||||||
:brief: Base class for platform specific data.
|
|
||||||
"""
|
"""
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
savegame_type:SavegameType,
|
savegame_type:SavegameType,
|
||||||
@ -185,8 +278,8 @@ class GameData(GObject):
|
|||||||
self.__savegame_root = savegame_root
|
self.__savegame_root = savegame_root
|
||||||
self.__savegame_dir = savegame_dir
|
self.__savegame_dir = savegame_dir
|
||||||
self.__variables = {}
|
self.__variables = {}
|
||||||
self.__filematch = []
|
self.__filematchers = []
|
||||||
self.__ignorematch = []
|
self.__ignorematchers = []
|
||||||
|
|
||||||
if variables is not None:
|
if variables is not None:
|
||||||
variables.update(variables)
|
variables.update(variables)
|
||||||
@ -202,15 +295,14 @@ class GameData(GObject):
|
|||||||
@Property
|
@Property
|
||||||
def savegame_type(self)->SavegameType:
|
def savegame_type(self)->SavegameType:
|
||||||
"""
|
"""
|
||||||
:attr: savegame_type
|
:type: SavegameType
|
||||||
:brief: Type of the class.
|
|
||||||
"""
|
"""
|
||||||
return self.__savegame_type
|
return self.__savegame_type
|
||||||
|
|
||||||
@Property(type=str)
|
@Property(type=str)
|
||||||
def savegame_root(self)->str:
|
def savegame_root(self)->str:
|
||||||
"""
|
"""
|
||||||
:attr: savegame_root
|
:type: str
|
||||||
"""
|
"""
|
||||||
return self.__savegame_root
|
return self.__savegame_root
|
||||||
|
|
||||||
@ -221,7 +313,7 @@ class GameData(GObject):
|
|||||||
@Property
|
@Property
|
||||||
def savegame_dir(self)->str:
|
def savegame_dir(self)->str:
|
||||||
"""
|
"""
|
||||||
:attr: savegame_dir
|
:type: str
|
||||||
"""
|
"""
|
||||||
return self.__savegame_dir
|
return self.__savegame_dir
|
||||||
|
|
||||||
@ -230,7 +322,10 @@ class GameData(GObject):
|
|||||||
self.__savegame_dir = sgdir
|
self.__savegame_dir = sgdir
|
||||||
|
|
||||||
@Property
|
@Property
|
||||||
def variables(self)->dict:
|
def variables(self)->dict[str:str]:
|
||||||
|
"""
|
||||||
|
:type: dict[str:str]
|
||||||
|
"""
|
||||||
return self.__variables
|
return self.__variables
|
||||||
@variables.setter
|
@variables.setter
|
||||||
def variables(self,vars:dict|None):
|
def variables(self,vars:dict|None):
|
||||||
@ -240,109 +335,225 @@ class GameData(GObject):
|
|||||||
self.__variables = dict(vars)
|
self.__variables = dict(vars)
|
||||||
|
|
||||||
@Property
|
@Property
|
||||||
def file_match(self):
|
def file_matchers(self)->list[GameFileMatcher]:
|
||||||
return self.__filematch
|
"""
|
||||||
@file_match.setter
|
:type: list[GameFileMatcher]
|
||||||
def file_match(self,fm:list[GameFileMatcher]|None):
|
"""
|
||||||
|
return self.__filematchers
|
||||||
|
|
||||||
|
@file_matchers.setter
|
||||||
|
def file_matchers(self,fm:list[GameFileMatcher]|None):
|
||||||
if not fm:
|
if not fm:
|
||||||
self.__filematch = []
|
self.__filematchers = []
|
||||||
else:
|
else:
|
||||||
for matcher in fm:
|
for matcher in fm:
|
||||||
if not isinstance(matcher,GameFileMatcher):
|
if not isinstance(matcher,GameFileMatcher):
|
||||||
raise TypeError("\"file_match\" needs to be \"None\" or a list of \"GameFileMatcher\" instances!")
|
raise TypeError("\"file_match\" needs to be \"None\" or a list of \"GameFileMatcher\" instances!")
|
||||||
self.__filematch = list(fm)
|
self.__filematchers = list(fm)
|
||||||
|
|
||||||
|
|
||||||
@Property
|
@Property
|
||||||
def ignore_match(self):
|
def ignore_matchers(self)->list[GameFileMatcher]:
|
||||||
return self.__ignorematch
|
"""
|
||||||
@file_match.setter
|
:type: list[GameFileMatcher]
|
||||||
def file_match(self,im:list[GameFileMatcher]|None):
|
"""
|
||||||
|
return self.__ignorematchers
|
||||||
|
@ignore_matchers.setter
|
||||||
|
def ignore_matchers(self,im:list[GameFileMatcher]|None):
|
||||||
if not im:
|
if not im:
|
||||||
self.__ignorematch = []
|
self.__ignorematchers = []
|
||||||
else:
|
else:
|
||||||
for matcher in im:
|
for matcher in im:
|
||||||
if not isinstance(matcher,GameFileMatcher):
|
if not isinstance(matcher,GameFileMatcher):
|
||||||
raise TypeError("\"ignore_match\" needs to be \"None\" or a list of \"GameFileMatcher\" instances!")
|
raise TypeError("\"ignore_match\" needs to be \"None\" or a list of \"GameFileMatcher\" instances!")
|
||||||
self.__ignorematch = list(im)
|
self.__ignorematchers = list(im)
|
||||||
|
|
||||||
def has_variable(self,name:str)->bool:
|
def has_variable(self,name:str)->bool:
|
||||||
|
"""
|
||||||
|
has_variable Check if variable exists.
|
||||||
|
|
||||||
|
:param name: The variable name.
|
||||||
|
:type name: str
|
||||||
|
:return: `True` if the variable exists.
|
||||||
|
:rtype: bool
|
||||||
|
"""
|
||||||
|
|
||||||
return (name in self.__variables)
|
return (name in self.__variables)
|
||||||
|
|
||||||
def get_variable(self,name:str)->str:
|
def get_variable(self,name:str)->str:
|
||||||
|
"""
|
||||||
|
get_variable Get a variable value byy variable name.
|
||||||
|
|
||||||
|
:param name: The variable name
|
||||||
|
:type name: str
|
||||||
|
:return: The vairable value if the variable exists or an empty string.
|
||||||
|
:rtype: str
|
||||||
|
"""
|
||||||
if name not in self.__variables:
|
if name not in self.__variables:
|
||||||
return ""
|
return ""
|
||||||
return self.__variables[name]
|
return self.__variables[name]
|
||||||
|
|
||||||
def set_variable(self,name:str,value:str):
|
def set_variable(self,name:str,value:str):
|
||||||
|
"""
|
||||||
|
set_variable Set a variable.
|
||||||
|
|
||||||
|
If the variable exists, it is replaced by the new variable.
|
||||||
|
|
||||||
|
:param name: The variable name.
|
||||||
|
:type name: str
|
||||||
|
:param value: The variable value.
|
||||||
|
:type value: str
|
||||||
|
"""
|
||||||
self.__variables[name] = value
|
self.__variables[name] = value
|
||||||
|
|
||||||
def delete_variable(self,name:str):
|
def delete_variable(self,name:str):
|
||||||
|
"""
|
||||||
|
delete_variable Deletes as variable if the variable exists
|
||||||
|
|
||||||
|
:param name: The vairable name to delete.
|
||||||
|
:type name: str
|
||||||
|
"""
|
||||||
if name in self.__variables:
|
if name in self.__variables:
|
||||||
del self.__variables[name]
|
del self.__variables[name]
|
||||||
|
|
||||||
def get_variables(self):
|
def get_variables(self)->dict[str:str]:
|
||||||
|
"""
|
||||||
|
get_variables Get the variables set by this instance.
|
||||||
|
|
||||||
|
:return: The variables as a dict.
|
||||||
|
:rtype: dict[str:str]
|
||||||
|
"""
|
||||||
return self.variables
|
return self.variables
|
||||||
|
|
||||||
def match_file(self,rel_filename:str):
|
def match_file(self,rel_filename:str)->bool:
|
||||||
if not self.__filematch:
|
"""
|
||||||
|
match_file Matches a file with the `GameFileMatcher`s for this class.
|
||||||
|
|
||||||
|
This method returns `True` if there is no `GameFileMatcher` set for
|
||||||
|
`GameData.file_match`.
|
||||||
|
|
||||||
|
:param rel_filename: The relative filename originating from *$SAVEGAME_DIR*
|
||||||
|
:type rel_filename: str
|
||||||
|
:return: `True` if the file matches.
|
||||||
|
:rtype: bool
|
||||||
|
"""
|
||||||
|
if not self.file_matchers:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
for fm in self.__filematch:
|
for fm in self.file_matchers:
|
||||||
if fm.match(rel_filename):
|
if fm.match(rel_filename):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def match_ignore(self,rel_filename:str):
|
def match_ignore(self,rel_filename:str)->bool:
|
||||||
if not self.__ignorematch:
|
"""
|
||||||
|
match_ignore Matches file agains the ignore_match `GameFileMatcher`s.
|
||||||
|
|
||||||
|
This method returns `False` if there is no `GameFileMatcher` set in
|
||||||
|
`GameData.ignore_match`.
|
||||||
|
|
||||||
|
:param rel_filename: The relative filename originating from *$SAVEGAME_DIR*
|
||||||
|
:type rel_filename: str
|
||||||
|
:return: `True` if the file matches.
|
||||||
|
:rtype: bool
|
||||||
|
"""
|
||||||
|
if not self.ignore_matchers:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
for fm in self.__ignorematch:
|
for fm in self.ignore_matchers:
|
||||||
if fm.match(rel_filename):
|
if fm.match(rel_filename):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def match(self,rel_filename:str):
|
def match(self,rel_filename:str)->bool:
|
||||||
|
"""
|
||||||
|
match Match files against `file_match` and `ignore_match`.
|
||||||
|
|
||||||
|
If this method returns `True` the file should be included in the
|
||||||
|
savegame backup.
|
||||||
|
|
||||||
|
:param rel_filename: The relative filename originating from *$SAVEGAME_DIR*
|
||||||
|
:type rel_filename: str
|
||||||
|
:return: True if the file should be included in the savegame backup.
|
||||||
|
:rtype: bool
|
||||||
|
"""
|
||||||
if self.match_file(rel_filename) and not self.match_ignore(rel_filename):
|
if self.match_file(rel_filename) and not self.match_ignore(rel_filename):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def add_file_match(self,matcher:GameFileMatcher):
|
def add_file_match(self,matcher:GameFileMatcher):
|
||||||
|
"""
|
||||||
|
add_file_match Add a `GameFileMatcher` to `file_match`.
|
||||||
|
|
||||||
|
:param matcher: The `GameFileMatcher` to add.
|
||||||
|
:type matcher: GameFileMatcher
|
||||||
|
:raises TypeError: If the `matcher` is not a `GameFileMatcher` instance.
|
||||||
|
"""
|
||||||
if not isinstance(matcher,GameFileMatcher):
|
if not isinstance(matcher,GameFileMatcher):
|
||||||
raise TypeError("matcher is not a \"GameFileMatcher\" instance!")
|
raise TypeError("matcher is not a \"GameFileMatcher\" instance!")
|
||||||
self.__filematch.append(matcher)
|
self.__filematchers.append(matcher)
|
||||||
|
|
||||||
def remove_file_match(self,matcher:GameFileMatcher):
|
def remove_file_match(self,matcher:GameFileMatcher):
|
||||||
for i in reversed(range(len(self.__filematch))):
|
"""
|
||||||
if (matcher == self.__filematch[i]):
|
remove_file_match Remove a file_matcher.
|
||||||
del self.__filematch[i]
|
|
||||||
|
:param matcher: The `GameFileMatcher` to remove.
|
||||||
|
:type matcher: GameFileMatcher
|
||||||
|
"""
|
||||||
|
for i in reversed(range(len(self.__filematchers))):
|
||||||
|
if (matcher == self.__filematchers[i]):
|
||||||
|
del self.__filematchers[i]
|
||||||
|
|
||||||
def add_ignore_match(self,matcher:GameFileMatcher):
|
def add_ignore_match(self,matcher:GameFileMatcher):
|
||||||
|
"""
|
||||||
|
add_file_match Add a `GameFileMatcher` to `ignore_match`.
|
||||||
|
|
||||||
|
:param matcher: The `GameFileMatcher` to add.
|
||||||
|
:type matcher: GameFileMatcher
|
||||||
|
:raises TypeError: If the `matcher` is not a `GameFileMatcher` instance.
|
||||||
|
"""
|
||||||
if not isinstance(matcher,GameFileMatcher):
|
if not isinstance(matcher,GameFileMatcher):
|
||||||
raise TypeError("matcher is not a \"GameFileMatcher\" instance!")
|
raise TypeError("matcher is not a \"GameFileMatcher\" instance!")
|
||||||
self.__ignorematch.append(matcher)
|
self.__ignorematchers.append(matcher)
|
||||||
|
|
||||||
def remove_ignore_match(self,matcher:GameFileMatcher):
|
def remove_ignore_match(self,matcher:GameFileMatcher):
|
||||||
for i in reversed(range(len(self.__ignorematch))):
|
"""
|
||||||
if (matcher == self.__ignorematch[i]):
|
remove_file_match Remove a ignore_match.
|
||||||
del self.__ignorematch[i]
|
|
||||||
|
:param matcher: The `GameFileMatcher` to remove.
|
||||||
|
:type matcher: GameFileMatcher
|
||||||
|
"""
|
||||||
|
|
||||||
|
for i in reversed(range(len(self.__ignorematchers))):
|
||||||
|
if (matcher == self.__ignorematchers[i]):
|
||||||
|
del self.__ignorematchers[i]
|
||||||
|
|
||||||
def serialize(self)->dict:
|
def serialize(self)->dict:
|
||||||
|
"""
|
||||||
|
serialize Serialize the instance to a dict.
|
||||||
|
|
||||||
|
This method should be overloaded by child-classes, so that their data
|
||||||
|
is exported too.
|
||||||
|
|
||||||
|
:return: The dict holding the data for recreating an instance of this class.
|
||||||
|
:rtype: dict
|
||||||
|
"""
|
||||||
ret = {
|
ret = {
|
||||||
'savegame_root': self.savegame_root,
|
'savegame_root': self.savegame_root,
|
||||||
'savegame_dir': self.savegame_dir,
|
'savegame_dir': self.savegame_dir,
|
||||||
}
|
}
|
||||||
if (self.__variables):
|
if (self.__variables):
|
||||||
ret['variables'] = self.variables
|
ret['variables'] = self.variables
|
||||||
if (self.file_match):
|
if (self.file_matchers):
|
||||||
fm = []
|
fm = []
|
||||||
for matcher in self.file_match:
|
for matcher in self.file_matchers:
|
||||||
fm.append({'type':matcher.match_type.value,'match':matcher.match_file})
|
fm.append({'type':matcher.match_type.value,'match':matcher.match_file})
|
||||||
ret['file_match'] = fm
|
ret['file_match'] = fm
|
||||||
|
|
||||||
if (self.add_ignore_match):
|
if (self.ignore_matchers):
|
||||||
im = []
|
im = []
|
||||||
for matcher in self.ignore_match:
|
for matcher in self.ignore_matchers:
|
||||||
im.append({'type':matcher.match_type.value,'match':matcher.match_file})
|
im.append({'type':matcher.match_type.value,'match':matcher.match_file})
|
||||||
ret['ignore_match'] = im
|
ret['ignore_match'] = im
|
||||||
|
|
||||||
@ -978,7 +1189,19 @@ class Game(GObject):
|
|||||||
if not isinstance(data,SteamMacOSGame):
|
if not isinstance(data,SteamMacOSGame):
|
||||||
raise TypeError("SteamWindowsGame")
|
raise TypeError("SteamWindowsGame")
|
||||||
self.__steam_macos = data
|
self.__steam_macos = data
|
||||||
|
|
||||||
|
@Property
|
||||||
|
def savegame_root(self)->str|None:
|
||||||
|
if not self.game_data:
|
||||||
|
return None
|
||||||
|
return self.game_data.savegame_root
|
||||||
|
|
||||||
|
@Property
|
||||||
|
def savegame_dir(self)->str|None:
|
||||||
|
if not self.game_data:
|
||||||
|
return None
|
||||||
|
return self.game_data.savegame_dir
|
||||||
|
|
||||||
def add_variable(self,name:str,value:str):
|
def add_variable(self,name:str,value:str):
|
||||||
self.__variables[str(name)] = str(value)
|
self.__variables[str(name)] = str(value)
|
||||||
|
|
||||||
@ -1038,58 +1261,121 @@ class Game(GObject):
|
|||||||
|
|
||||||
with open(new_path,'wt',encoding='utf-8') as ofile:
|
with open(new_path,'wt',encoding='utf-8') as ofile:
|
||||||
ofile.write(json.dumps(self.serialize(),ensure_ascii=False,indent=4))
|
ofile.write(json.dumps(self.serialize(),ensure_ascii=False,indent=4))
|
||||||
|
|
||||||
|
|
||||||
|
def __bool__(self):
|
||||||
|
return (bool(self.game_data) and bool(self.savegame_root) and bool(self.savegame_dir))
|
||||||
|
|
||||||
|
def is_backup_file(self,filename:str):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def get_backup_files(self)->dict[str:str]|None:
|
||||||
|
def get_backup_files_recursive(sgroot:pathlib.Path,sgdir:str,subdir:str|None=None):
|
||||||
|
ret = {}
|
||||||
|
if subdir:
|
||||||
|
path = sgroot / sgdir / subdir
|
||||||
|
else:
|
||||||
|
path = sgroot / sgdir
|
||||||
|
|
||||||
|
ret = {}
|
||||||
|
for dirent in os.listdir(path):
|
||||||
|
file_path = path / dirent
|
||||||
|
if file_path.is_file():
|
||||||
|
if subdir:
|
||||||
|
fname = (os.path.join(subdir,dirent))
|
||||||
|
else:
|
||||||
|
fname = dirent
|
||||||
|
|
||||||
|
if self.game_data.match(fname):
|
||||||
|
ret[str(path)] = os.path.join(sgdir,fname)
|
||||||
|
elif file_path.is_dir():
|
||||||
|
ret.update(get_backup_files_recursive(sgroot,sgdir,os.path.join(subdir,dirent)))
|
||||||
|
|
||||||
|
return ret
|
||||||
|
|
||||||
|
if not bool(self):
|
||||||
|
return None
|
||||||
|
|
||||||
|
sgroot = pathlib.Path(self.savegame_root).resolve()
|
||||||
|
sgdir = self.savegame_dir
|
||||||
|
sgpath = sgroot / sgdir
|
||||||
|
if not os.path.exists(sgpath):
|
||||||
|
return None
|
||||||
|
|
||||||
|
backup_files = get_backup_files_recursive(sgroot,sgdir)
|
||||||
|
|
||||||
GAMES={}
|
|
||||||
STEAM_GAMES={}
|
|
||||||
STEAM_LINUX_GAMES={}
|
|
||||||
STEAM_WINDOWS_GAMES={}
|
|
||||||
STEAM_MACOS_GAMES={}
|
|
||||||
|
|
||||||
def __init_games():
|
|
||||||
gameconf_dir = settings.gameconf_dir
|
|
||||||
if not os.path.isdir(gameconf_dir):
|
|
||||||
return
|
|
||||||
|
|
||||||
for gcf in (os.path.join(gameconf_dir,i) for i in os.listdir(gameconf_dir)):
|
class GameManager(GObject):
|
||||||
if not os.path.isfile(gcf) or not gcf.endswith('.gameconf'):
|
__global_gamemanager = None
|
||||||
continue
|
|
||||||
|
@staticmethod
|
||||||
|
def get_global():
|
||||||
|
if GameManager.__global_gamemanager is None:
|
||||||
|
GameManager.__global_gamemanager = GameManager()
|
||||||
|
return GameManager.__global_gamemanager
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
GObject.__init__(self)
|
||||||
|
|
||||||
|
self.__games = {}
|
||||||
|
self.__steam_games = {}
|
||||||
|
self.__steam_linux_games = {}
|
||||||
|
self.__steam_windows_games = {}
|
||||||
|
self.__steam_macos_games = {}
|
||||||
|
|
||||||
|
self.load()
|
||||||
|
|
||||||
|
@Property(type=object)
|
||||||
|
def games(self)->dict[str:Game]:
|
||||||
|
return self.__games
|
||||||
|
|
||||||
|
@Property(type=object)
|
||||||
|
def stam_games(self)->dict[int:Game]:
|
||||||
|
return self.__steam_games
|
||||||
|
|
||||||
|
@Property(type=object)
|
||||||
|
def steam_windows_games(self)->dict[int:Game]:
|
||||||
|
return self.__steam_windows_games
|
||||||
|
|
||||||
|
@Property(type=object)
|
||||||
|
def steam_linux_games(self)->dict[int:Game]:
|
||||||
|
return self.__steam_linux_games
|
||||||
|
|
||||||
|
@Property(type=object)
|
||||||
|
def steam_macos_games(self)->dict[int:Game]:
|
||||||
|
return self.__steam_macos_games
|
||||||
|
|
||||||
|
def load(self):
|
||||||
|
if self.__games:
|
||||||
|
self.__games = {}
|
||||||
|
|
||||||
try:
|
gameconf_dir = settings.gameconf_dir
|
||||||
game = Game.new_from_json_file(gcf)
|
if not os.path.isdir(gameconf_dir):
|
||||||
if not game:
|
return
|
||||||
|
|
||||||
|
for gcf in (os.path.join(gameconf_dir,i) for i in os.listdir(gameconf_dir)):
|
||||||
|
if not os.path.isfile(gcf) or not gcf.endswith('.gameconf'):
|
||||||
continue
|
continue
|
||||||
except:
|
|
||||||
continue
|
try:
|
||||||
|
game = Game.new_from_json_file(gcf)
|
||||||
|
if not game:
|
||||||
|
continue
|
||||||
|
except Exception as ex:
|
||||||
|
logger.error("Unable to load gameconf {gameconf}! ({what})".format(
|
||||||
|
gameconf = os.path.basename(gcf),
|
||||||
|
what = str(ex)))
|
||||||
|
continue
|
||||||
|
|
||||||
|
self.add_game(game)
|
||||||
|
|
||||||
GAMES[game.key] = game
|
def add_game(self,game:Game):
|
||||||
if (game.steam_windows):
|
self.__[game.key] = game
|
||||||
if not game.steam_windows.appid in STEAM_GAMES:
|
|
||||||
STEAM_GAMES[game.steam_windows.appid] = game
|
|
||||||
STEAM_WINDOWS_GAMES[game.steam_windows.appid] = game
|
|
||||||
if (game.steam_linux):
|
|
||||||
if not game.steam_linux.appid in STEAM_GAMES:
|
|
||||||
STEAM_GAMES[game.steam_linux.appid] = game
|
|
||||||
STEAM_LINUX_GAMES[game.steam_linux.appid] = game
|
|
||||||
if (game.steam_macos):
|
if (game.steam_macos):
|
||||||
if not game.steam_macos.appid in STEAM_GAMES:
|
self.__steam_games[game.steam_macos.appid] = game
|
||||||
STEAM_GAMES[game.steam_macos.appid] = game
|
self.__steam_macos_games[game.steam_macos.appid] = game
|
||||||
STEAM_MACOS_GAMES[game.steam_macos.appid] = game
|
if (game.steam_linux):
|
||||||
__init_games()
|
self.__steam_games[game.steam_linux.appid] = game
|
||||||
|
self.__steam_linux_games[game.steam_linux.appid] = game
|
||||||
def add_game(game:Game):
|
if (game.steam_windows):
|
||||||
GAMES[game.key] = game
|
self.__steam_games[game.steam_windows.appid] = game
|
||||||
if game.steam_windows:
|
self.__steam_windows_games[game.steam_windows.appid] = game
|
||||||
if not game.steam_windows.appid in STEAM_GAMES:
|
|
||||||
STEAM_GAMES[game.steam_windows.appid] = game
|
|
||||||
STEAM_WINDOWS_GAMES[game.steam_windows.appid] = game
|
|
||||||
if (game.steam_linux):
|
|
||||||
if not game.steam_linux.appid in STEAM_GAMES:
|
|
||||||
STEAM_GAMES[game.steam_linux.appid] = game
|
|
||||||
STEAM_LINUX_GAMES[game.steam_linux.appid] = game
|
|
||||||
if (game.steam_macos):
|
|
||||||
if not game.steam_macos.appid in STEAM_GAMES:
|
|
||||||
STEAM_GAMES[game.steam_macos.appid] = game
|
|
||||||
STEAM_MACOS_GAMES[game.steam_macos.appid] = game
|
|
||||||
|
|
||||||
|
|||||||
@ -16,7 +16,7 @@
|
|||||||
# along with this program. If not, see <https://www.gnu.org/licenses/>. #
|
# along with this program. If not, see <https://www.gnu.org/licenses/>. #
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
from ._app import Application,AppWindow
|
from ._app import Application,AppWindow,GameView,BackupView
|
||||||
from ._settingsdialog import SettingsDialog
|
from ._settingsdialog import SettingsDialog
|
||||||
from ._gamedialog import GameDialog
|
from ._gamedialog import GameDialog
|
||||||
|
|
||||||
|
|||||||
@ -28,11 +28,19 @@ from .. import game
|
|||||||
from ..settings import settings
|
from ..settings import settings
|
||||||
from ._settingsdialog import SettingsDialog
|
from ._settingsdialog import SettingsDialog
|
||||||
from ._gamedialog import GameDialog
|
from ._gamedialog import GameDialog
|
||||||
|
from ..game import Game
|
||||||
|
|
||||||
|
__gtype_name__ = __name__
|
||||||
|
|
||||||
class GameView(Gtk.ScrolledWindow):
|
class GameView(Gtk.ScrolledWindow):
|
||||||
__gtype_name__ = "sgbackup-gui-GameView"
|
__gtype_name__ = "GameView"
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
"""
|
||||||
|
GameView The View for games.
|
||||||
|
|
||||||
|
This is widget presents a clumnview for the installed games.
|
||||||
|
"""
|
||||||
Gtk.ScrolledWindow.__init__(self)
|
Gtk.ScrolledWindow.__init__(self)
|
||||||
|
|
||||||
self.__liststore = Gio.ListStore.new(game.Game)
|
self.__liststore = Gio.ListStore.new(game.Game)
|
||||||
@ -78,7 +86,7 @@ class GameView(Gtk.ScrolledWindow):
|
|||||||
return self.__liststore
|
return self.__liststore
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def _columnview(self):
|
def _columnview(self)->Gtk.ColumnView:
|
||||||
return self.__columnview
|
return self.__columnview
|
||||||
|
|
||||||
def _on_key_column_setup(self,factory,item):
|
def _on_key_column_setup(self,factory,item):
|
||||||
@ -149,6 +157,15 @@ class GameView(Gtk.ScrolledWindow):
|
|||||||
dialog.props.secondary_use_markup = False
|
dialog.props.secondary_use_markup = False
|
||||||
dialog.connect('response',on_dialog_response)
|
dialog.connect('response',on_dialog_response)
|
||||||
dialog.present()
|
dialog.present()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def current_game(self)->Game|None:
|
||||||
|
selection = self._columnview.get_model()
|
||||||
|
pos = selection.get_selected()
|
||||||
|
if pos == Gtk.INVALID_LIST_POSITION:
|
||||||
|
return None
|
||||||
|
return selection.get_model().get_item(pos)
|
||||||
|
|
||||||
# GameView class
|
# GameView class
|
||||||
|
|
||||||
class BackupViewData(GObject.GObject):
|
class BackupViewData(GObject.GObject):
|
||||||
@ -188,6 +205,9 @@ class BackupViewData(GObject.GObject):
|
|||||||
@GObject.Property
|
@GObject.Property
|
||||||
def timestamp(self):
|
def timestamp(self):
|
||||||
return self.__timestamp
|
return self.__timestamp
|
||||||
|
|
||||||
|
def _on_selection_changed(self,selection):
|
||||||
|
pass
|
||||||
|
|
||||||
class BackupView(Gtk.ScrolledWindow):
|
class BackupView(Gtk.ScrolledWindow):
|
||||||
__gtype_name__ = "BackupView"
|
__gtype_name__ = "BackupView"
|
||||||
@ -443,6 +463,6 @@ class Application(Gtk.Application):
|
|||||||
flags=GObject.SignalFlags.RUN_LAST,
|
flags=GObject.SignalFlags.RUN_LAST,
|
||||||
return_type=None,
|
return_type=None,
|
||||||
arg_types=(SettingsDialog,))
|
arg_types=(SettingsDialog,))
|
||||||
def settings_dialog_init(self,dialog):
|
def do_settings_dialog_init(self,dialog):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|||||||
@ -28,11 +28,32 @@ from ..game import (
|
|||||||
SteamLinuxGame,
|
SteamLinuxGame,
|
||||||
SteamWindowsGame,
|
SteamWindowsGame,
|
||||||
SteamMacOSGame,
|
SteamMacOSGame,
|
||||||
|
GameManager,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class GameVariableData(GObject.GObject):
|
class GameVariableData(GObject.GObject):
|
||||||
|
"""
|
||||||
|
GameVariableData The Gio.ListStore data for Variables.
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self,name:str,value:str):
|
def __init__(self,name:str,value:str):
|
||||||
|
"""
|
||||||
|
GameVariableData
|
||||||
|
|
||||||
|
:param name: The variable name
|
||||||
|
:type name: str
|
||||||
|
:param value: The variable value
|
||||||
|
:type value: str
|
||||||
|
|
||||||
|
Properties
|
||||||
|
__________
|
||||||
|
.. py:property:: name
|
||||||
|
:type: str
|
||||||
|
|
||||||
|
.. py:property:: value
|
||||||
|
:type: str
|
||||||
|
"""
|
||||||
GObject.GObject.__init__(self)
|
GObject.GObject.__init__(self)
|
||||||
self.name = name
|
self.name = name
|
||||||
self.value = value
|
self.value = value
|
||||||
@ -52,13 +73,27 @@ class GameVariableData(GObject.GObject):
|
|||||||
self.__value = value
|
self.__value = value
|
||||||
|
|
||||||
class RegistryKeyData(GObject.GObject):
|
class RegistryKeyData(GObject.GObject):
|
||||||
def __init__(self,regkey=None):
|
"""
|
||||||
|
RegistyKeyData The data for Windows registry keys.
|
||||||
|
"""
|
||||||
|
def __init__(self,regkey:str|None=None):
|
||||||
|
"""
|
||||||
|
RegistryKeyData
|
||||||
|
|
||||||
|
:param regkey: The registry key ot set, defaults to None
|
||||||
|
:type regkey: str | None, optional
|
||||||
|
|
||||||
|
Properties
|
||||||
|
__________
|
||||||
|
.. py:property:: regkey
|
||||||
|
:type: str
|
||||||
|
"""
|
||||||
GObject.GObject.__init__(self)
|
GObject.GObject.__init__(self)
|
||||||
if not regkey:
|
if not regkey:
|
||||||
self.__regkey = ""
|
self.__regkey = ""
|
||||||
|
|
||||||
@GObject.Property(type=str)
|
@GObject.Property(type=str)
|
||||||
def regkey(self):
|
def regkey(self)->str:
|
||||||
return self.__regkey
|
return self.__regkey
|
||||||
@regkey.setter
|
@regkey.setter
|
||||||
def regkey(self,key:str):
|
def regkey(self,key:str):
|
||||||
@ -67,14 +102,35 @@ class RegistryKeyData(GObject.GObject):
|
|||||||
def __bool__(self):
|
def __bool__(self):
|
||||||
return bool(self.__regkey)
|
return bool(self.__regkey)
|
||||||
|
|
||||||
|
|
||||||
class GameFileMatcherData(GObject.GObject):
|
class GameFileMatcherData(GObject.GObject):
|
||||||
|
"""
|
||||||
|
GameFileMatcherData The data for the file matcher.
|
||||||
|
"""
|
||||||
def __init__(self,match_type:GameFileType,match_value:str):
|
def __init__(self,match_type:GameFileType,match_value:str):
|
||||||
|
"""
|
||||||
|
GameFileMatcherData
|
||||||
|
|
||||||
|
:param match_type: The type of the game file matcher.
|
||||||
|
:type match_type: GameFileType
|
||||||
|
:param match_value: The value to match the file.
|
||||||
|
:type match_value: str
|
||||||
|
|
||||||
|
Properties
|
||||||
|
__________
|
||||||
|
.. py:property:: match_type
|
||||||
|
:type: GameFileType
|
||||||
|
|
||||||
|
.. py:property:: match_value
|
||||||
|
:type: str
|
||||||
|
"""
|
||||||
GObject.GObject.__init__(self)
|
GObject.GObject.__init__(self)
|
||||||
self.match_type = match_type
|
self.match_type = match_type
|
||||||
self.match_value = match_value
|
self.match_value = match_value
|
||||||
|
|
||||||
@GObject.Property
|
@GObject.Property
|
||||||
def match_type(self)->GameFileType:
|
def match_type(self)->GameFileType:
|
||||||
|
|
||||||
return self.__match_type
|
return self.__match_type
|
||||||
@match_type.setter
|
@match_type.setter
|
||||||
def match_type(self,type:GameFileType):
|
def match_type(self,type:GameFileType):
|
||||||
@ -83,12 +139,30 @@ class GameFileMatcherData(GObject.GObject):
|
|||||||
@GObject.Property(type=str)
|
@GObject.Property(type=str)
|
||||||
def match_value(self)->str:
|
def match_value(self)->str:
|
||||||
return self.__match_value
|
return self.__match_value
|
||||||
|
|
||||||
@match_value.setter
|
@match_value.setter
|
||||||
def match_value(self,value:str):
|
def match_value(self,value:str):
|
||||||
self.__match_value = value
|
self.__match_value = value
|
||||||
|
|
||||||
class GameFileTypeData(GObject.GObject):
|
class GameFileTypeData(GObject.GObject):
|
||||||
|
""" GameFileTypeData The *Gio.Liststore* data for GameFileType *Gtk.DropDown* widgets."""
|
||||||
def __init__(self,match_type:GameFileType,name:str):
|
def __init__(self,match_type:GameFileType,name:str):
|
||||||
|
"""
|
||||||
|
GameFileTypeData
|
||||||
|
|
||||||
|
:param match_type: The matcher type
|
||||||
|
:type match_type: GameFileType
|
||||||
|
:param name: The name of the matcher type
|
||||||
|
:type name: str
|
||||||
|
|
||||||
|
Properties:
|
||||||
|
___________
|
||||||
|
.. py:property:: match_type
|
||||||
|
:type: GameFileType
|
||||||
|
|
||||||
|
.. py:property:: name
|
||||||
|
:type: str
|
||||||
|
"""
|
||||||
GObject.GObject.__init__(self)
|
GObject.GObject.__init__(self)
|
||||||
self.__match_type = match_type
|
self.__match_type = match_type
|
||||||
self.__name = name
|
self.__name = name
|
||||||
@ -102,7 +176,34 @@ class GameFileTypeData(GObject.GObject):
|
|||||||
return self.__name
|
return self.__name
|
||||||
|
|
||||||
class SavegameTypeData(GObject.GObject):
|
class SavegameTypeData(GObject.GObject):
|
||||||
|
"""
|
||||||
|
SavegameTypeData Holds the data for the SavegameType *Gtk.DropDown*.
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self,type:SavegameType,name:str,icon_name:str):
|
def __init__(self,type:SavegameType,name:str,icon_name:str):
|
||||||
|
"""
|
||||||
|
SavegameTypeData
|
||||||
|
|
||||||
|
:param type: The SavegameType to select.
|
||||||
|
:type type: SavegameType
|
||||||
|
:param name: The name of the SavegameType.
|
||||||
|
:type name: str
|
||||||
|
:param icon_name: The Icon name to display for the SavegameType
|
||||||
|
:type icon_name: str
|
||||||
|
|
||||||
|
Properties
|
||||||
|
__________
|
||||||
|
|
||||||
|
.. py:property:: savegame_type
|
||||||
|
:type: SavegameType
|
||||||
|
|
||||||
|
.. py:property:: name
|
||||||
|
:type: str
|
||||||
|
|
||||||
|
.. py:property:: icon_name
|
||||||
|
:type: str
|
||||||
|
|
||||||
|
"""
|
||||||
GObject.GObject.__init__(self)
|
GObject.GObject.__init__(self)
|
||||||
self.__sgtype = type
|
self.__sgtype = type
|
||||||
self.__name = name
|
self.__name = name
|
||||||
@ -122,7 +223,27 @@ class SavegameTypeData(GObject.GObject):
|
|||||||
|
|
||||||
|
|
||||||
class GameVariableDialog(Gtk.Dialog):
|
class GameVariableDialog(Gtk.Dialog):
|
||||||
|
"""
|
||||||
|
GameVariableDialog The dialog for setting game variables.
|
||||||
|
|
||||||
|
It is bound to on the GameDialog variable columnviews. This dialog
|
||||||
|
will update the given columnview automatically if the response is
|
||||||
|
*Gtk.Response.APPLY* and destroy itself on any response.
|
||||||
|
|
||||||
|
If not variable is given, this dialog will create a new one
|
||||||
|
|
||||||
|
"""
|
||||||
def __init__(self,parent:Gtk.Window,columnview:Gtk.ColumnView,variable:GameVariableData|None=None):
|
def __init__(self,parent:Gtk.Window,columnview:Gtk.ColumnView,variable:GameVariableData|None=None):
|
||||||
|
"""
|
||||||
|
GameVariableDialog
|
||||||
|
|
||||||
|
:param parent: The parent window (should be a GameDialog instance).
|
||||||
|
:type parent: Gtk.Window
|
||||||
|
:param columnview: The Columnview to operate on.
|
||||||
|
:type columnview: Gtk.ColumnView
|
||||||
|
:param variable: The variable to edit, defaults to None
|
||||||
|
:type variable: GameVariableData | None, optional
|
||||||
|
"""
|
||||||
Gtk.Dialog.__init__(self)
|
Gtk.Dialog.__init__(self)
|
||||||
self.set_transient_for(parent)
|
self.set_transient_for(parent)
|
||||||
self.set_default_size(600,-1)
|
self.set_default_size(600,-1)
|
||||||
@ -186,14 +307,24 @@ class GameVariableDialog(Gtk.Dialog):
|
|||||||
model = self.__columnview.get_model().get_model()
|
model = self.__columnview.get_model().get_model()
|
||||||
model.append(GameVariableData(self.__name_entry.get_text(),self.__value_entry.get_text()))
|
model.append(GameVariableData(self.__name_entry.get_text(),self.__value_entry.get_text()))
|
||||||
self.hide()
|
self.hide()
|
||||||
self.destroy()
|
self.destroy()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class GameDialog(Gtk.Dialog):
|
class GameDialog(Gtk.Dialog):
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
parent:Gtk.Window|None=None,
|
parent:Gtk.Window|None=None,
|
||||||
game:Game|None=Game):
|
game:Game|None=None):
|
||||||
|
"""
|
||||||
|
GameDialog This dialog is for setting game config.
|
||||||
|
|
||||||
|
The dialog automatically saves the game.
|
||||||
|
|
||||||
|
:param parent: The parent Window, defaults to None
|
||||||
|
:type parent: Gtk.Window | None, optional
|
||||||
|
:param game: The game to configure, defaults to None
|
||||||
|
:type game: Game | None, optional
|
||||||
|
"""
|
||||||
|
|
||||||
Gtk.Dialog.__init__(self)
|
Gtk.Dialog.__init__(self)
|
||||||
if (parent):
|
if (parent):
|
||||||
@ -685,6 +816,9 @@ class GameDialog(Gtk.Dialog):
|
|||||||
return widget
|
return widget
|
||||||
|
|
||||||
def reset(self):
|
def reset(self):
|
||||||
|
"""
|
||||||
|
reset Resets the dialog to the Game set on init or clears the dialog if no Game was set.
|
||||||
|
"""
|
||||||
self.__active_switch.set_active(True)
|
self.__active_switch.set_active(True)
|
||||||
self.__live_switch.set_active(True)
|
self.__live_switch.set_active(True)
|
||||||
self.__name_entry.set_text("")
|
self.__name_entry.set_text("")
|
||||||
@ -758,11 +892,11 @@ class GameDialog(Gtk.Dialog):
|
|||||||
|
|
||||||
#filematch
|
#filematch
|
||||||
fm_model = self.__windows.filematch.columnview.get_model().get_model()
|
fm_model = self.__windows.filematch.columnview.get_model().get_model()
|
||||||
for fm in self.__game.windows.filematch:
|
for fm in self.__game.windows.file_matchers:
|
||||||
fm_model.append(GameFileMatcherData(fm.match_type,fm.match_file))
|
fm_model.append(GameFileMatcherData(fm.match_type,fm.match_file))
|
||||||
|
|
||||||
im_model = self.__windows.ignorematch.columnview.get_model().get_model()
|
im_model = self.__windows.ignorematch.columnview.get_model().get_model()
|
||||||
for im in self.__game.windows.ignorematch:
|
for im in self.__game.windows.ignore_matchers:
|
||||||
im_model.append(GameFileMatcherData(im.match_type,im.match_file))
|
im_model.append(GameFileMatcherData(im.match_type,im.match_file))
|
||||||
|
|
||||||
# set lookup regkeys
|
# set lookup regkeys
|
||||||
@ -787,11 +921,11 @@ class GameDialog(Gtk.Dialog):
|
|||||||
|
|
||||||
#filematch
|
#filematch
|
||||||
fm_model = self.__linux.filematch.columnview.get_model().get_model()
|
fm_model = self.__linux.filematch.columnview.get_model().get_model()
|
||||||
for fm in self.__game.linux.filematch:
|
for fm in self.__game.linux.file_matchers:
|
||||||
fm_model.append(GameFileMatcherData(fm.match_type,fm.match_file))
|
fm_model.append(GameFileMatcherData(fm.match_type,fm.match_file))
|
||||||
|
|
||||||
im_model = self.__linux.ignorematch.columnview.get_model().get_model()
|
im_model = self.__linux.ignorematch.columnview.get_model().get_model()
|
||||||
for im in self.__game.linux.ignorematch:
|
for im in self.__game.linux.ignore_matchers:
|
||||||
im_model.append(GameFileMatcherData(im.match_type,im.match_file))
|
im_model.append(GameFileMatcherData(im.match_type,im.match_file))
|
||||||
|
|
||||||
var_model = self.__linux.variables.columnview.get_model().get_model()
|
var_model = self.__linux.variables.columnview.get_model().get_model()
|
||||||
@ -805,11 +939,11 @@ class GameDialog(Gtk.Dialog):
|
|||||||
|
|
||||||
#filematch
|
#filematch
|
||||||
fm_model = self.__macos.filematch.columnview.get_model().get_model()
|
fm_model = self.__macos.filematch.columnview.get_model().get_model()
|
||||||
for fm in self.__game.macos.filematch:
|
for fm in self.__game.macos.file_matchers:
|
||||||
fm_model.append(GameFileMatcherData(fm.match_type,fm.match_file))
|
fm_model.append(GameFileMatcherData(fm.match_type,fm.match_file))
|
||||||
|
|
||||||
im_model = self.__macos.ignorematch.columnview.get_model().get_model()
|
im_model = self.__macos.ignorematch.columnview.get_model().get_model()
|
||||||
for im in self.__game.macos.ignorematch:
|
for im in self.__game.macos.ignore_matchers:
|
||||||
im_model.append(GameFileMatcherData(im.match_type,im.match_file))
|
im_model.append(GameFileMatcherData(im.match_type,im.match_file))
|
||||||
|
|
||||||
var_model = self.__macos.variables.columnview.get_model().get_model()
|
var_model = self.__macos.variables.columnview.get_model().get_model()
|
||||||
@ -824,11 +958,11 @@ class GameDialog(Gtk.Dialog):
|
|||||||
|
|
||||||
#filematch
|
#filematch
|
||||||
fm_model = self.__steam_windows.filematch.columnview.get_model().get_model()
|
fm_model = self.__steam_windows.filematch.columnview.get_model().get_model()
|
||||||
for fm in self.__game.steam_windows.filematch:
|
for fm in self.__game.steam_windows.file_matchers:
|
||||||
fm_model.append(GameFileMatcherData(fm.match_type,fm.match_file))
|
fm_model.append(GameFileMatcherData(fm.match_type,fm.match_file))
|
||||||
|
|
||||||
im_model = self.__steam_windows.ignorematch.columnview.get_model().get_model()
|
im_model = self.__steam_windows.ignorematch.columnview.get_model().get_model()
|
||||||
for im in self.__game.steam_windows.ignorematch:
|
for im in self.__game.steam_windows.ignore_matchers:
|
||||||
im_model.append(GameFileMatcherData(im.match_type,im.match_file))
|
im_model.append(GameFileMatcherData(im.match_type,im.match_file))
|
||||||
|
|
||||||
var_model = self.__steam_windows.variables.columnview.get_model().get_model()
|
var_model = self.__steam_windows.variables.columnview.get_model().get_model()
|
||||||
@ -842,11 +976,11 @@ class GameDialog(Gtk.Dialog):
|
|||||||
self.__steam_linux.installdir_entry.set_text(self.__game.steam_linux.installdir)
|
self.__steam_linux.installdir_entry.set_text(self.__game.steam_linux.installdir)
|
||||||
|
|
||||||
fm_model = self.__steam_linux.filematch.columnview.get_model().get_model()
|
fm_model = self.__steam_linux.filematch.columnview.get_model().get_model()
|
||||||
for fm in self.__game.steam_linux.filematch:
|
for fm in self.__game.steam_linux.file_matchers:
|
||||||
fm_model.append(GameFileMatcherData(fm.match_type,fm.match_file))
|
fm_model.append(GameFileMatcherData(fm.match_type,fm.match_file))
|
||||||
|
|
||||||
im_model = self.__steam_linux.ignorematch.columnview.get_model().get_model()
|
im_model = self.__steam_linux.ignorematch.columnview.get_model().get_model()
|
||||||
for im in self.__game.steam_linux.ignorematch:
|
for im in self.__game.steam_linux.ignore_matchers:
|
||||||
im_model.append(GameFileMatcherData(im.match_type,im.match_file))
|
im_model.append(GameFileMatcherData(im.match_type,im.match_file))
|
||||||
|
|
||||||
var_model = self.__steam_linux.variables.columnview.get_model().get_model()
|
var_model = self.__steam_linux.variables.columnview.get_model().get_model()
|
||||||
@ -860,11 +994,11 @@ class GameDialog(Gtk.Dialog):
|
|||||||
self.__steam_macos.installdir_entry.set_text(self.__game.steam_macos.installdir)
|
self.__steam_macos.installdir_entry.set_text(self.__game.steam_macos.installdir)
|
||||||
|
|
||||||
fm_model = self.__steam_macos.filematch.columnview.get_model().get_model()
|
fm_model = self.__steam_macos.filematch.columnview.get_model().get_model()
|
||||||
for fm in self.__game.steam_macos.filematch:
|
for fm in self.__game.steam_macos.file_matchers:
|
||||||
fm_model.append(GameFileMatcherData(fm.match_type,fm.match_file))
|
fm_model.append(GameFileMatcherData(fm.match_type,fm.match_file))
|
||||||
|
|
||||||
im_model = self.__steam_macos.ignorematch.columnview.get_model().get_model()
|
im_model = self.__steam_macos.ignorematch.columnview.get_model().get_model()
|
||||||
for im in self.__game.steam_macos.ignorematch:
|
for im in self.__game.steam_macos.ignore_matchers:
|
||||||
im_model.append(GameFileMatcherData(im.match_type,im.match_file))
|
im_model.append(GameFileMatcherData(im.match_type,im.match_file))
|
||||||
|
|
||||||
var_model = self.__steam_macos.variables.columnview.get_model().get_model()
|
var_model = self.__steam_macos.variables.columnview.get_model().get_model()
|
||||||
@ -873,6 +1007,9 @@ class GameDialog(Gtk.Dialog):
|
|||||||
# reset()
|
# reset()
|
||||||
|
|
||||||
def save(self):
|
def save(self):
|
||||||
|
"""
|
||||||
|
save Saves the game configuration to file.
|
||||||
|
"""
|
||||||
def get_game_data(widget):
|
def get_game_data(widget):
|
||||||
fm_model = widget.filematch.columnview.get_model().get_model()
|
fm_model = widget.filematch.columnview.get_model().get_model()
|
||||||
im_model = widget.ignorematch.columnview.get_model().get_model()
|
im_model = widget.ignorematch.columnview.get_model().get_model()
|
||||||
@ -1078,14 +1215,28 @@ class GameDialog(Gtk.Dialog):
|
|||||||
self.__steam_macos = None
|
self.__steam_macos = None
|
||||||
|
|
||||||
self.__game.save()
|
self.__game.save()
|
||||||
|
GameManager.get_global().add_game(self.__game)
|
||||||
|
|
||||||
|
|
||||||
def get_is_valid(self):
|
def get_is_valid(self)->bool:
|
||||||
|
"""
|
||||||
|
get_is_valid Check if the configuration is valid for saving.
|
||||||
|
|
||||||
|
:returns: bool
|
||||||
|
"""
|
||||||
if (self.__key_entry.get_text() and self.__name_entry.get_text() and self.__sgname_entry.get_text()):
|
if (self.__key_entry.get_text() and self.__name_entry.get_text() and self.__sgname_entry.get_text()):
|
||||||
sgtype_data = self.__savegame_type_dropdown.get_selected_item()
|
sgtype_data = self.__savegame_type_dropdown.get_selected_item()
|
||||||
return self.get_is_valid_savegame_type(sgtype_data.savegame_type)
|
return self.get_is_valid_savegame_type(sgtype_data.savegame_type)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def get_is_valid_savegame_type(self,sgtype:SavegameType)->bool:
|
def get_is_valid_savegame_type(self,sgtype:SavegameType)->bool:
|
||||||
|
"""
|
||||||
|
get_is_valid_savegame_type Check if the data for a SavegameType savegame is valid.
|
||||||
|
|
||||||
|
:param sgtype: The type of the Savegame provider
|
||||||
|
:type: sgbackup.game.SavegameType
|
||||||
|
:returns: bool
|
||||||
|
"""
|
||||||
def check_is_valid(widget):
|
def check_is_valid(widget):
|
||||||
return (bool(widget.sgroot_entry.get_text()) and bool(widget.sgdir_entry.get_text()))
|
return (bool(widget.sgroot_entry.get_text()) and bool(widget.sgdir_entry.get_text()))
|
||||||
|
|
||||||
|
|||||||
@ -1,21 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<gresources>
|
|
||||||
<gresource prefix="/org/sgbackup/sgbackup/icons/32x32/apps">
|
|
||||||
<file>sgbackup.png</file>
|
|
||||||
</gresource>
|
|
||||||
<gresource prefix="/org/sgbackup/sgbacukp/icons/64x64/apps">
|
|
||||||
<file>sgbackup.png</file>
|
|
||||||
</gresource>
|
|
||||||
<gresource prefix="/org/sgbackup/sgbackup/icons/128x128/apps">
|
|
||||||
<file>sgbackup.png</file>
|
|
||||||
</gresource>
|
|
||||||
<gresource prefix="/org/sgbackup/sgbackup/icons/256x256/apps">
|
|
||||||
<file>sgbackup.png</file>
|
|
||||||
</gresource>
|
|
||||||
<gresource prefix="/org/sgbackup/sgbackup/icons/512x512/apps">
|
|
||||||
<file>sgbackup.png</file>
|
|
||||||
</gresource>
|
|
||||||
<gresource prefix="/org/sgbackup/sgbackup/icons/scalable/apps">
|
|
||||||
<file>icons8-windows-10.svg</file>
|
|
||||||
</gresource>
|
|
||||||
</gresources>
|
|
||||||
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 12 KiB |
@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
||||||
|
<svg fill="#000000" width="800px" height="800px" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M9.531 20.317h-3.719c-0.291 0-0.531 0.24-0.531 0.537v2.667c0 0.281 0.24 0.531 0.531 0.531h3.735v1.76h-4.667c-0.744 0-1.359-0.615-1.359-1.375v-4.516c0-0.749 0.615-1.359 1.375-1.359h4.635zM10.88 15.385c0 0.776-0.625 1.401-1.401 1.401h-5.973v-1.803h5.041c0.297 0 0.532-0.235 0.532-0.531v-5.932c0-0.297-0.235-0.537-0.532-0.537h-2.692c-0.303-0.005-0.548 0.235-0.548 0.537v2.692c0 0.308 0.24 0.532 0.532 0.532h2.161v1.801h-3.093c-0.771 0-1.401-0.615-1.401-1.385v-4.588c0-0.761 0.631-1.385 1.401-1.385h4.563c0.771 0 1.395 0.624 1.395 1.385v7.812zM28.479 25.812h-1.76v-5.495h-1.24c-0.291 0-0.531 0.24-0.531 0.537v4.957h-1.776v-5.495h-1.24c-0.292 0-0.531 0.24-0.531 0.537v4.957h-1.776v-5.891c0-0.749 0.615-1.359 1.375-1.359h7.479zM28.495 15.385c0 0.776-0.631 1.401-1.401 1.401h-5.973v-1.803h5.041c0.292 0 0.532-0.235 0.532-0.531v-5.932c0-0.297-0.24-0.537-0.532-0.537h-2.708c-0.297 0-0.532 0.24-0.532 0.537v2.692c0 0.308 0.24 0.532 0.532 0.532h2.161v1.801h-3.084c-0.771 0-1.395-0.615-1.395-1.385v-4.588c0-0.761 0.624-1.385 1.395-1.385h4.573c0.776 0 1.401 0.624 1.401 1.385v7.812zM18.292 6.188h-4.584c-0.776 0-1.391 0.624-1.391 1.385v4.588c0 0.771 0.615 1.385 1.391 1.385h4.584c0.76 0 1.391-0.615 1.391-1.385v-4.588c0-0.761-0.631-1.385-1.391-1.385zM17.896 8.521v2.692c0 0.297-0.24 0.532-0.536 0.532h-2.709c-0.291 0-0.531-0.235-0.531-0.532v-2.683c0-0.291 0.229-0.531 0.531-0.531h2.683c0.307 0 0.531 0.24 0.531 0.531zM16.839 18.563h-4.521c-0.755 0-1.369 0.609-1.369 1.359v4.516c0 0.76 0.615 1.375 1.369 1.375h4.521c0.76 0 1.375-0.615 1.375-1.375v-4.516c0-0.749-0.615-1.359-1.375-1.359zM16.437 20.855v2.667c0 0.291-0.235 0.531-0.531 0.531v-0.011h-2.652c-0.296 0-0.536-0.239-0.536-0.536v-2.651c0-0.292 0.24-0.537 0.536-0.537h2.667c0.292 0 0.532 0.245 0.532 0.537zM31.317 1.469c-0.432-0.448-1.031-0.693-1.651-0.699h-27.333c-1.292-0.005-2.339 1.041-2.333 2.333v25.792c-0.005 1.292 1.041 2.339 2.333 2.333h27.333c1.292 0.005 2.339-1.041 2.333-2.333v-25.792c0-0.635-0.265-1.224-0.683-1.651zM31.317 28.896c0.011 0.911-0.733 1.656-1.651 1.651h-27.333c-0.921 0.016-1.672-0.735-1.667-1.651v-25.792c-0.005-0.911 0.74-1.656 1.651-1.651h27.333c0.917 0 1.656 0.74 1.656 1.651v25.792z"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.3 KiB |
@ -8,7 +8,7 @@ keys=consoleHandler,fileHandler
|
|||||||
keys=consoleFormatter,fileFormatter
|
keys=consoleFormatter,fileFormatter
|
||||||
|
|
||||||
[logger_root]
|
[logger_root]
|
||||||
level=DEBUG
|
level=INFO
|
||||||
handlers=consoleHandler,fileHandler
|
handlers=consoleHandler,fileHandler
|
||||||
|
|
||||||
[logger_console]
|
[logger_console]
|
||||||
|
|||||||
@ -22,7 +22,7 @@ from pathlib import Path
|
|||||||
import sys
|
import sys
|
||||||
import json
|
import json
|
||||||
from .settings import settings
|
from .settings import settings
|
||||||
from .game import STEAM_GAMES,STEAM_WINDOWS_GAMES,STEAM_LINUX_GAMES,STEAM_MACOS_GAMES
|
from .game import GameManager
|
||||||
|
|
||||||
__gtype_name__ = __name__
|
__gtype_name__ = __name__
|
||||||
|
|
||||||
@ -102,7 +102,7 @@ class IgnoreSteamApp(GObject):
|
|||||||
appid = conf['appid']
|
appid = conf['appid']
|
||||||
name = conf['name']
|
name = conf['name']
|
||||||
reason = conf['reason'] if 'reason' in conf else ""
|
reason = conf['reason'] if 'reason' in conf else ""
|
||||||
return SteamIgnoreApp(appid,name,reason)
|
return IgnoreSteamApp(appid,name,reason)
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@ -331,23 +331,25 @@ class Steam(GObject):
|
|||||||
return sorted(new_apps)
|
return sorted(new_apps)
|
||||||
|
|
||||||
def update_steam_apps(self):
|
def update_steam_apps(self):
|
||||||
|
gm = GameManager.get_global()
|
||||||
|
|
||||||
for lib in self.libraries():
|
for lib in self.libraries():
|
||||||
for app in lib.steam_apps:
|
for app in lib.steam_apps:
|
||||||
if PLATFORM_WINDOWS:
|
if PLATFORM_WINDOWS:
|
||||||
if ((app.appid in STEAM_WINDOWS_GAMES)
|
if ((app.appid in gm.steam_windows_games)
|
||||||
and (STEAM_WINDOWS_GAMES[app.appid].installdir != app.installdir)):
|
and (gm.steam_windows_games[app.appid].installdir != app.installdir)):
|
||||||
game = STEAM_WINDOWS_GAMES[app.appid]
|
game = gm.steam_windows_games[app.appid]
|
||||||
game.installdir = app.installdir
|
game.installdir = app.installdir
|
||||||
game.save()
|
game.save()
|
||||||
elif PLATFORM_LINUX:
|
elif PLATFORM_LINUX:
|
||||||
if ((app.appid in STEAM_LINUX_GAMES)
|
if ((app.appid in gm.steam_linux_games)
|
||||||
and (STEAM_LINUX_GAMES[app.appid].installdir != app.installdir)):
|
and (gm.steam_linux_games[app.appid].installdir != app.installdir)):
|
||||||
game = STEAM_LINUX_GAMES[app.appid]
|
game = gm.steam_linux_games[app.appid]
|
||||||
game.installdir = app.installdir
|
game.installdir = app.installdir
|
||||||
game.save()
|
game.save()
|
||||||
elif PLATFORM_MACOS:
|
elif PLATFORM_MACOS:
|
||||||
if ((app.appid in STEAM_MACOS_GAMES)
|
if ((app.appid in gm.steam_macos_games)
|
||||||
and (STEAM_MACOS_GAMES[app.appid].installdir != app.installdir)):
|
and (gm.steam_macos_games[app.appid].installdir != app.installdir)):
|
||||||
game = STEAM_MACOS_GAMES[app.appid]
|
game = gm.steam_macos_games[app.appid]
|
||||||
game.installdir = app.installdir
|
game.installdir = app.installdir
|
||||||
game.save()
|
game.save()
|
||||||
|
|||||||
@ -27,7 +27,12 @@ extensions = [
|
|||||||
]
|
]
|
||||||
language = 'en'
|
language = 'en'
|
||||||
master_doc = 'index'
|
master_doc = 'index'
|
||||||
source_suffix = '.rst'
|
source_suffix = {
|
||||||
|
'.rst': "restructuredtext",
|
||||||
|
'.txt': "restructuredtext",
|
||||||
|
'.md': 'markdown',
|
||||||
|
'.markdown': 'mardown',
|
||||||
|
}
|
||||||
templates_path = ['templates']
|
templates_path = ['templates']
|
||||||
|
|
||||||
html_theme = 'sphinx_rtd_theme'
|
html_theme = 'sphinx_rtd_theme'
|
||||||
|
|||||||
@ -26,4 +26,6 @@ Table of Contents
|
|||||||
modules/sgbackup.settings.rst
|
modules/sgbackup.settings.rst
|
||||||
modules/sgbackup.game.rst
|
modules/sgbackup.game.rst
|
||||||
modules/sgbackup.archiver.rst
|
modules/sgbackup.archiver.rst
|
||||||
|
modules/sgbackup.gui.rst
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
76
sphinx/modules/sgbackup.game.rst
Normal file
76
sphinx/modules/sgbackup.game.rst
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
=====================
|
||||||
|
Module: sgbackup.game
|
||||||
|
=====================
|
||||||
|
|
||||||
|
.. title:: sgbackup API documentation
|
||||||
|
|
||||||
|
Game classes
|
||||||
|
------------
|
||||||
|
|
||||||
|
.. autoclass:: sgbackup.game.Game
|
||||||
|
:members:
|
||||||
|
:undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
|
|
||||||
|
.. autoclass:: sgbackup.game.GameManager
|
||||||
|
:members:
|
||||||
|
:undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
|
|
||||||
|
|
||||||
|
GameData classes
|
||||||
|
----------------
|
||||||
|
|
||||||
|
.. autoclass:: sgbackup.game.GameData
|
||||||
|
:members:
|
||||||
|
:undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
|
|
||||||
|
.. autoclass:: sgbackup.game.WindowsGame
|
||||||
|
:members:
|
||||||
|
:undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
|
|
||||||
|
.. autoclass:: sgbackup.game.LinuxGame
|
||||||
|
:members:
|
||||||
|
:undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
|
|
||||||
|
.. autoclass:: sgbackup.game.MacOSGame
|
||||||
|
:members:
|
||||||
|
:undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
|
|
||||||
|
.. autoclass:: sgbackup.game.SteamWindowsGame
|
||||||
|
:members:
|
||||||
|
:undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
|
|
||||||
|
.. autoclass:: sgbackup.game.SteamLinuxGame
|
||||||
|
:members:
|
||||||
|
:undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
|
|
||||||
|
.. autoclass:: sgbackup.game.SteamMacOSGame
|
||||||
|
:members:
|
||||||
|
:undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
|
|
||||||
|
|
||||||
|
Helper classes
|
||||||
|
--------------
|
||||||
|
|
||||||
|
.. autoclass:: sgbackup.game.GameFileMatcher
|
||||||
|
:members:
|
||||||
|
:show-inheritance:
|
||||||
|
|
||||||
|
Enums
|
||||||
|
-----
|
||||||
|
|
||||||
|
.. autoclass:: sgbackup.game.SavegameType
|
||||||
|
:members:
|
||||||
|
:show-inheritance:
|
||||||
|
|
||||||
|
.. autoclass:: sgbackup.game.GameFileType
|
||||||
|
:members:
|
||||||
|
:show-inheritance:
|
||||||
18
sphinx/modules/sgbackup.gui-app.rst
Normal file
18
sphinx/modules/sgbackup.gui-app.rst
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
============
|
||||||
|
Applicaction
|
||||||
|
============
|
||||||
|
|
||||||
|
Applicaction
|
||||||
|
------------
|
||||||
|
|
||||||
|
.. autoclass:: sgbackup.gui.Application
|
||||||
|
:members:
|
||||||
|
:undoc-members:
|
||||||
|
|
||||||
|
Application Window
|
||||||
|
------------------
|
||||||
|
|
||||||
|
.. autoclass:: sgbackup.gui.AppWindow
|
||||||
|
:members:
|
||||||
|
:undoc-members:
|
||||||
|
|
||||||
22
sphinx/modules/sgbackup.gui-data.rst
Normal file
22
sphinx/modules/sgbackup.gui-data.rst
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
==========================
|
||||||
|
Module: sgbackup.gui._game
|
||||||
|
==========================
|
||||||
|
|
||||||
|
Game data classes
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
.. autoclass:: sgbackup.gui._gamedialog.GameFileMatcherData
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. autoclass:: sgbackup.gui._gamedialog.GameFileTypeData
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. autoclass:: sgbackup.gui._gamedialog.GameVariableData
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. autoclass:: sgbackup.gui._gamedialog.RegistryKeyData
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. autoclass:: sgbackup.gui._gamedialog.SavegameTypeData
|
||||||
|
:members:
|
||||||
|
|
||||||
23
sphinx/modules/sgbackup.gui-dialogs.rst
Normal file
23
sphinx/modules/sgbackup.gui-dialogs.rst
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
=======
|
||||||
|
Dialogs
|
||||||
|
=======
|
||||||
|
|
||||||
|
.. title:: sgbackup API documentation
|
||||||
|
|
||||||
|
SettingsDialog
|
||||||
|
---------------
|
||||||
|
|
||||||
|
.. autoclass:: sgbackup.gui.SettingsDialog
|
||||||
|
:members:
|
||||||
|
:undoc-members:
|
||||||
|
|
||||||
|
|
||||||
|
GameDialog
|
||||||
|
----------
|
||||||
|
|
||||||
|
.. autoclass:: sgbackup.gui.GameDialog
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. autoclass:: sgbackup.gui._gamedialog.GameVariableDialog
|
||||||
|
:members:
|
||||||
|
|
||||||
11
sphinx/modules/sgbackup.gui-widgets.rst
Normal file
11
sphinx/modules/sgbackup.gui-widgets.rst
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
=======
|
||||||
|
Widgets
|
||||||
|
=======
|
||||||
|
|
||||||
|
.. autoclass:: sgbackup.gui.GameView
|
||||||
|
:members:
|
||||||
|
:undoc-members:
|
||||||
|
|
||||||
|
.. autoclass:: sgbackup.gui.BackupView
|
||||||
|
:members:
|
||||||
|
:undoc-members:
|
||||||
11
sphinx/modules/sgbackup.gui.rst
Normal file
11
sphinx/modules/sgbackup.gui.rst
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
=====================
|
||||||
|
Package: sgbackup.gui
|
||||||
|
=====================
|
||||||
|
|
||||||
|
.. title:: sgbackup API documentation
|
||||||
|
|
||||||
|
.. toctree:: 1
|
||||||
|
sgbackup.gui-app.rst
|
||||||
|
sgbackup.gui-widgets.rst
|
||||||
|
sgbackup.gui-dialogs.rst
|
||||||
|
sgbackup.gui-data.rst
|
||||||
@ -4,7 +4,7 @@ sgbackup API
|
|||||||
|
|
||||||
.. title:: sgbackup API
|
.. title:: sgbackup API
|
||||||
|
|
||||||
|
.. toctree:: 1
|
||||||
|
sgbackup.game.rst
|
||||||
|
sgbackup.gui.rst
|
||||||
|
|
||||||
.. automodule:: sgbackup
|
|
||||||
:imported-mebers:
|
|
||||||
:undoc-members:
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user