mirror of
https://github.com/c9moser/sgbackup.git
synced 2026-01-19 19:40:13 +00:00
devel-commit
This commit is contained in:
parent
aca16784e7
commit
7f96010822
16
.githooks/pre-commit
Executable file
16
.githooks/pre-commit
Executable file
@ -0,0 +1,16 @@
|
||||
#!/bin/sh
|
||||
# vim: syn=sh ts=4 sts=4 sw=4 smartindent expandtab ff=unix
|
||||
|
||||
SELF="$(realpath $0)"
|
||||
GITHOOKS_DIR="$(dirname "$SELF")" ; export GITHOOKS_DIR
|
||||
PROJECT_ROOT="$(dirname "$(dirname "$SELF")")" ; export PROJECT_ROOT
|
||||
|
||||
pre_commit_d="${GITHOOKS_DIR}/pre-commit-d"
|
||||
|
||||
for i in $(ls "$pre_commit_d"); do
|
||||
script="${pre_commit_d}/$i"
|
||||
if [ -x "$script" ]; then
|
||||
"$script" "$@"
|
||||
fi
|
||||
done
|
||||
|
||||
48
.githooks/pre-commit.d/fix_line_endings.sh
Executable file
48
.githooks/pre-commit.d/fix_line_endings.sh
Executable file
@ -0,0 +1,48 @@
|
||||
#!/usr/bin/env bash
|
||||
# vim: syn=sh ts=4 sts=4 sw=4 smartindent expandtab ff=unix
|
||||
|
||||
dos2unix=$(which dos2unix)
|
||||
unix2dos=$(which unix2dos)
|
||||
|
||||
githooks="pre-commit prepare-commit-msg commit-msg post-commit applypatch-msg pre-applypatch post-applypatch pre-rebase post-rewrite post-checkout post-merge"
|
||||
|
||||
dos2unix_used=NO
|
||||
|
||||
__IFS="$IFS"
|
||||
IFS=$'\n'
|
||||
if [ -n "$dos2unix" -a "$unix2dos" ]; then
|
||||
for line in $(git status -s); do
|
||||
if [[ line == A* || $line == M* ]]; then
|
||||
file="${line:3}"
|
||||
abspath="${PROJECT_ROOT}/$file"
|
||||
|
||||
if [[ $file == *.py || $file == *.sh || file == *.rst ]]; then
|
||||
$dos2unix "$abspath"
|
||||
git add "$file"
|
||||
dos2unix_used=YES
|
||||
continue
|
||||
fi
|
||||
|
||||
#check if we are updating a githook
|
||||
for githook in $githooks; do
|
||||
if [ "$file" = ".githooks/$githook" ]; then
|
||||
$dos2unix "$abspath"
|
||||
git add "$file"
|
||||
dos2unix_used=YES
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if [ "$dos2unix_used" = "YES" ]; then
|
||||
continue
|
||||
fi
|
||||
if [[ "$file" == *.txt ]]; then
|
||||
$unix2dos "$abspath"
|
||||
git add "$file"
|
||||
fi
|
||||
done
|
||||
else
|
||||
echo "\"dos2unix\" and/or \"unix2dos\" not found!" >&2
|
||||
fi
|
||||
IFS="$__IFS"
|
||||
16
.gitignore
vendored
16
.gitignore
vendored
@ -169,3 +169,19 @@ cython_debug/
|
||||
|
||||
# PyPI configuration file
|
||||
.pypirc
|
||||
|
||||
.vscode/
|
||||
.vsccode/*
|
||||
|
||||
# logfiles
|
||||
*.log
|
||||
*.LOG
|
||||
*.[Ll][Oo][Gg]
|
||||
|
||||
# editor files
|
||||
*~
|
||||
*.swp
|
||||
*.tmp
|
||||
*.temp
|
||||
|
||||
apidoc/
|
||||
|
||||
24
pyproject.toml
Normal file
24
pyproject.toml
Normal file
@ -0,0 +1,24 @@
|
||||
[build-system]
|
||||
builbackend = 'setuptools.build_meta'
|
||||
requires = ['setuptools >= 61.0']
|
||||
|
||||
[project]
|
||||
dynamic = ["version"]
|
||||
name = 'sgbackup'
|
||||
version = '0.0.0'
|
||||
requires_python = '>= 3.11'
|
||||
description = 'Savegame Backup Tool'
|
||||
readme = 'README.md'
|
||||
license = {file = 'LICENSE'}
|
||||
authors = [
|
||||
{name = 'Christian Moser', email = 'christian@mydevel.at'},
|
||||
]
|
||||
dependencies = ['gi','yaml']
|
||||
|
||||
[project.scripts]
|
||||
sgbackup = 'sgbackup:cli_main'
|
||||
csgbackup = 'sgbackup:curses_main'
|
||||
|
||||
[project.gui-scripts]
|
||||
gsgbackup = 'sgbackup:gui_main'
|
||||
|
||||
40
sgbackup/__init__.py
Normal file
40
sgbackup/__init__.py
Normal file
@ -0,0 +1,40 @@
|
||||
###############################################################################
|
||||
# sgbackup - The SaveGame Backup tool #
|
||||
# Copyright (C) 2024 Christian Moser #
|
||||
# #
|
||||
# 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 <https://www.gnu.org/licenses/>. #
|
||||
###############################################################################
|
||||
|
||||
import gi
|
||||
gi.require_version('Gtk','4.0')
|
||||
|
||||
__version__ = "0.0.1"
|
||||
from .settings import settings
|
||||
from . import _logging
|
||||
from .main import cli_main,curses_main,gui_main
|
||||
from . import game
|
||||
from .command import Command
|
||||
from . import commands
|
||||
from . import archiver
|
||||
|
||||
__ALL__ = [
|
||||
"settings"
|
||||
"cli_main",
|
||||
"gui_main",
|
||||
"curses_main",
|
||||
'game',
|
||||
"Command",
|
||||
"commands",
|
||||
"archiver",
|
||||
]
|
||||
23
sgbackup/__main__.py
Normal file
23
sgbackup/__main__.py
Normal file
@ -0,0 +1,23 @@
|
||||
###############################################################################
|
||||
# sgbackup - The SaveGame Backup tool #
|
||||
# Copyright (C) 2024 Christian Moser #
|
||||
# #
|
||||
# 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 <https://www.gnu.org/licenses/>. #
|
||||
###############################################################################
|
||||
|
||||
from .main import cli_main
|
||||
import sys
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(cli_main())
|
||||
28
sgbackup/_logging.py
Normal file
28
sgbackup/_logging.py
Normal file
@ -0,0 +1,28 @@
|
||||
###############################################################################
|
||||
# sgbackup - The SaveGame Backup tool #
|
||||
# Copyright (C) 2024 Christian Moser #
|
||||
# #
|
||||
# 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 <https://www.gnu.org/licenses/>. #
|
||||
###############################################################################
|
||||
|
||||
import os
|
||||
|
||||
import logging
|
||||
import logging.config
|
||||
from .settings import settings
|
||||
|
||||
if os.path.isfile(settings.logger_conf):
|
||||
logging.config.fileConfig(settings.logger_conf)
|
||||
else:
|
||||
logging.config.fileConfig(os.path.join(os.path.dirname(__file__),"logger.conf"))
|
||||
20
sgbackup/archiver.py
Normal file
20
sgbackup/archiver.py
Normal file
@ -0,0 +1,20 @@
|
||||
###############################################################################
|
||||
# sgbackup - The SaveGame Backup tool #
|
||||
# Copyright (C) 2024 Christian Moser #
|
||||
# #
|
||||
# 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 <https://www.gnu.org/licenses/>. #
|
||||
###############################################################################
|
||||
|
||||
class Archiver:
|
||||
pass
|
||||
43
sgbackup/command.py
Normal file
43
sgbackup/command.py
Normal file
@ -0,0 +1,43 @@
|
||||
|
||||
###############################################################################
|
||||
# sgbackup - The SaveGame Backup tool #
|
||||
# Copyright (C) 2024 Christian Moser #
|
||||
# #
|
||||
# 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 <https://www.gnu.org/licenses/>. #
|
||||
###############################################################################
|
||||
|
||||
class Command:
|
||||
def __init__(self,id:str,name:str,description:str):
|
||||
self.__id = id
|
||||
self.__name = name
|
||||
self.__description = description
|
||||
|
||||
def get_name(self):
|
||||
return self.__name
|
||||
|
||||
def get_id(self):
|
||||
return self.__id
|
||||
|
||||
def get_description(self):
|
||||
return self.__description
|
||||
|
||||
def get_help(self):
|
||||
raise NotImplementedError("Command.get_help() is not implemented!")
|
||||
|
||||
def get_synopsis(self):
|
||||
raise NotImplementedError("Command.get_synopsis() is not implemented!")
|
||||
|
||||
def execute(self,argv:list):
|
||||
raise NotImplementedError("Command.execute is not implemented!")
|
||||
|
||||
48
sgbackup/commands/__init__.py
Normal file
48
sgbackup/commands/__init__.py
Normal file
@ -0,0 +1,48 @@
|
||||
###############################################################################
|
||||
# sgbackup - The SaveGame Backup tool #
|
||||
# Copyright (C) 2024 Christian Moser #
|
||||
# #
|
||||
# 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 <https://www.gnu.org/licenses/>. #
|
||||
###############################################################################
|
||||
|
||||
import os
|
||||
|
||||
COMMANDS = {}
|
||||
|
||||
_mods = ['commandbase']
|
||||
|
||||
for _f in os.listdir(os.path.dirname(__file__)):
|
||||
if _f.startswith('_'):
|
||||
continue
|
||||
|
||||
if _f.endswith('.py') or _f.endswith('.pyc'):
|
||||
if (_f.endswith('py')):
|
||||
_m = _f[0:-3]
|
||||
else:
|
||||
_m = _f[0:-4]
|
||||
|
||||
if _m not in _mods:
|
||||
exec("\n".join([
|
||||
"from . import " + _m,
|
||||
"_mods += _m",
|
||||
"_mod = " + _m]))
|
||||
if hasattr(_mod,"COMMANDS") and len(_mod.COMMANDS) > 0:
|
||||
for _cmd in _mod.COMMANDS:
|
||||
COMMANDS[_cmd.get_id()] = _cmd
|
||||
del _cmd
|
||||
|
||||
del _mods
|
||||
del _f
|
||||
del _m
|
||||
del _mod
|
||||
38
sgbackup/commands/help.py
Normal file
38
sgbackup/commands/help.py
Normal file
@ -0,0 +1,38 @@
|
||||
###############################################################################
|
||||
# sgbackup - The SaveGame Backup tool #
|
||||
# Copyright (C) 2024 Christian Moser #
|
||||
# #
|
||||
# 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 <https://www.gnu.org/licenses/>. #
|
||||
###############################################################################
|
||||
|
||||
from sgbackup import __version__ as VERSION, Command
|
||||
|
||||
class VersionCommand(Command):
|
||||
def __init__(self):
|
||||
super().__init__('version', 'Version', 'Show version information.')
|
||||
|
||||
def get_synopsis(self):
|
||||
return 'sgbackup version'
|
||||
|
||||
def get_help(self):
|
||||
return super().get_help()
|
||||
|
||||
def execute(self, argv):
|
||||
print("sgbackup - {}".format(VERSION))
|
||||
return 0
|
||||
# VersionCommand class
|
||||
|
||||
COMMANDS = [
|
||||
VersionCommand(),
|
||||
]
|
||||
0
sgbackup/curses/__init__.py
Normal file
0
sgbackup/curses/__init__.py
Normal file
0
sgbackup/curses/__main__.py
Normal file
0
sgbackup/curses/__main__.py
Normal file
1015
sgbackup/game.py
Normal file
1015
sgbackup/game.py
Normal file
File diff suppressed because it is too large
Load Diff
18
sgbackup/gui/__init__.py
Normal file
18
sgbackup/gui/__init__.py
Normal file
@ -0,0 +1,18 @@
|
||||
###############################################################################
|
||||
# sgbackup - The SaveGame Backup tool #
|
||||
# Copyright (C) 2024 Christian Moser #
|
||||
# #
|
||||
# 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 <https://www.gnu.org/licenses/>. #
|
||||
###############################################################################
|
||||
from .application import Application
|
||||
24
sgbackup/gui/__main__.py
Normal file
24
sgbackup/gui/__main__.py
Normal file
@ -0,0 +1,24 @@
|
||||
###############################################################################
|
||||
# sgbackup - The SaveGame Backup tool #
|
||||
# Copyright (C) 2024 Christian Moser #
|
||||
# #
|
||||
# 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 <https://www.gnu.org/licenses/>. #
|
||||
###############################################################################
|
||||
|
||||
import sys
|
||||
from ..main import gui_main
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(gui_main())
|
||||
|
||||
83
sgbackup/gui/application.py
Normal file
83
sgbackup/gui/application.py
Normal file
@ -0,0 +1,83 @@
|
||||
###############################################################################
|
||||
# sgbackup - The SaveGame Backup tool #
|
||||
# Copyright (C) 2024 Christian Moser #
|
||||
# #
|
||||
# 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 <https://www.gnu.org/licenses/>. #
|
||||
###############################################################################
|
||||
|
||||
from gi.repository import Gtk,GObject,Gio
|
||||
from .appwindow import AppWindow
|
||||
|
||||
import logging; logger=logging.getLogger(__name__)
|
||||
|
||||
class Application(Gtk.Application):
|
||||
def __init__(self,*args,**kwargs):
|
||||
AppFlags = Gio.ApplicationFlags
|
||||
kwargs['application_id'] = 'org.sgbackup.sgbackup'
|
||||
kwargs['flags'] = AppFlags.FLAGS_NONE
|
||||
Gtk.Application.__init__(self,*args,**kwargs)
|
||||
|
||||
self.__logger = logger.getChild('Application')
|
||||
self.__builder = None
|
||||
self.__appwindow = None
|
||||
|
||||
@property
|
||||
def _logger(self):
|
||||
return self.__logger
|
||||
|
||||
@GObject.Property
|
||||
def appwindow(self):
|
||||
return self.__appwindow
|
||||
|
||||
def do_startup(self):
|
||||
self._logger.debug('do_startup()')
|
||||
if not self.__builder:
|
||||
self.__builder = Gtk.Builder.new()
|
||||
|
||||
Gtk.Application.do_startup(self)
|
||||
|
||||
action_about = Gio.SimpleAction.new('about',None)
|
||||
action_about.connect('activate',self.on_action_about)
|
||||
self.add_action(action_about)
|
||||
|
||||
action_quit = Gio.SimpleAction.new('quit',None)
|
||||
action_quit.connect('activate',self.on_action_quit)
|
||||
self.add_action(action_quit)
|
||||
|
||||
action_settings = Gio.SimpleAction.new('settings',None)
|
||||
action_settings.connect('activate',self.on_action_settings)
|
||||
self.add_action(action_settings)
|
||||
|
||||
# add accels
|
||||
self.set_accels_for_action('app.quit',["<Primary>q"])
|
||||
|
||||
@GObject.Property
|
||||
def builder(self):
|
||||
return self.__builder
|
||||
|
||||
def do_activate(self):
|
||||
self._logger.debug('do_activate()')
|
||||
if not (self.__appwindow):
|
||||
self.__appwindow = AppWindow(application=self)
|
||||
|
||||
self.appwindow.present()
|
||||
|
||||
def on_action_about(self,action,param):
|
||||
pass
|
||||
|
||||
def on_action_settings(self,action,param):
|
||||
pass
|
||||
|
||||
def on_action_quit(self,action,param):
|
||||
self.quit()
|
||||
32
sgbackup/gui/appmenu.ui
Normal file
32
sgbackup/gui/appmenu.ui
Normal file
@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<interface>
|
||||
<menu id='appmenu'>
|
||||
<section>
|
||||
<item>
|
||||
<attribute name='label' translatable='true'>_Settings</attribute>
|
||||
<attribute name='action'>app.settings</attribute>
|
||||
</item>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<submenu>
|
||||
<attribute name='label' translatable='true'>_Help</attribute>
|
||||
<section id='appmenu.help.help'></section>
|
||||
|
||||
<section id='appmenu.help.about'>
|
||||
<item>
|
||||
<attribute name='label' translatable='true'>_About SGBackup</attribute>
|
||||
<attribute name='action' translatable='true'>app.about</attribute>
|
||||
</item>
|
||||
</section>
|
||||
</submenu>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<item>
|
||||
<attribute name='label' translatable='true'>_Quit</attribute>
|
||||
<attribute name='action'>app.quit</attribute>
|
||||
</item>
|
||||
</section>
|
||||
</menu>
|
||||
</interface>
|
||||
86
sgbackup/gui/appwindow.py
Normal file
86
sgbackup/gui/appwindow.py
Normal file
@ -0,0 +1,86 @@
|
||||
###############################################################################
|
||||
# sgbackup - The SaveGame Backup tool #
|
||||
# Copyright (C) 2024 Christian Moser #
|
||||
# #
|
||||
# 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 <https://www.gnu.org/licenses/>. #
|
||||
###############################################################################
|
||||
|
||||
from gi.repository import Gtk,Gio,GObject
|
||||
|
||||
import os
|
||||
from .gameview import GameView
|
||||
from .backupview import BackupView
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
def __init__(self,application=None,**kwargs):
|
||||
kwargs['title'] = "SGBackup"
|
||||
|
||||
if (application is not None):
|
||||
kwargs['application']=application
|
||||
if (hasattr(application,'builder')):
|
||||
builder = application.builder
|
||||
else:
|
||||
builder = Gtk.Builder.new()
|
||||
|
||||
Gtk.ApplicationWindow.__init__(self,**kwargs)
|
||||
self.set_default_size(800,600)
|
||||
|
||||
self.__builder = builder
|
||||
self.builder.add_from_file(os.path.join(os.path.dirname(__file__),'appmenu.ui'))
|
||||
gmenu = self.builder.get_object('appmenu')
|
||||
appmenu_popover = Gtk.PopoverMenu.new_from_model(gmenu)
|
||||
image = Gtk.Image.new_from_icon_name('open-menu-symbolic')
|
||||
menubutton = Gtk.MenuButton.new()
|
||||
menubutton.set_popover(appmenu_popover)
|
||||
menubutton.set_child(image)
|
||||
headerbar = Gtk.HeaderBar.new()
|
||||
headerbar.pack_start(menubutton)
|
||||
self.set_titlebar(headerbar)
|
||||
|
||||
vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
||||
|
||||
self.__vpaned = Gtk.Paned(orientation=Gtk.Orientation.VERTICAL)
|
||||
self.__vpaned.set_hexpand(True)
|
||||
self.__vpaned.set_vexpand(True)
|
||||
self.__vpaned.set_wide_handle(True)
|
||||
self.__gameview = GameView()
|
||||
self.__vpaned.set_start_child(self.gameview)
|
||||
self.__backupview = BackupView(self.gameview)
|
||||
self.__vpaned.set_end_child(self.backupview)
|
||||
self.__vpaned.set_resize_start_child(True)
|
||||
self.__vpaned.set_resize_end_child(True)
|
||||
|
||||
vbox.append(self.__vpaned)
|
||||
|
||||
statusbar = Gtk.Statusbar()
|
||||
statusbar.set_hexpand(True)
|
||||
statusbar.set_vexpand(False)
|
||||
statusbar.push(0,'Running ...')
|
||||
vbox.append(statusbar)
|
||||
|
||||
self.set_child(vbox)
|
||||
|
||||
@GObject.Property
|
||||
def builder(self):
|
||||
return self.__builder
|
||||
|
||||
@GObject.Property
|
||||
def backupview(self):
|
||||
return self.__backupview
|
||||
|
||||
@GObject.Property
|
||||
def gameview(self):
|
||||
return self.__gameview
|
||||
|
||||
|
||||
30
sgbackup/gui/backupview.py
Normal file
30
sgbackup/gui/backupview.py
Normal file
@ -0,0 +1,30 @@
|
||||
###############################################################################
|
||||
# sgbackup - The SaveGame Backup tool #
|
||||
# Copyright (C) 2024 Christian Moser #
|
||||
# #
|
||||
# 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 <https://www.gnu.org/licenses/>. #
|
||||
###############################################################################
|
||||
|
||||
from gi.repository import Gtk,Gio,GObject
|
||||
|
||||
from .gameview import GameView
|
||||
|
||||
class BackupView(Gtk.ScrolledWindow):
|
||||
def __init__(self,gameview:GameView):
|
||||
Gtk.ScrolledWindow.__init__(self)
|
||||
self.__gameview = GameView
|
||||
|
||||
@GObject.Property
|
||||
def gameview(self):
|
||||
return self.__gameview
|
||||
24
sgbackup/gui/gameview.py
Normal file
24
sgbackup/gui/gameview.py
Normal file
@ -0,0 +1,24 @@
|
||||
###############################################################################
|
||||
# sgbackup - The SaveGame Backup tool #
|
||||
# Copyright (C) 2024 Christian Moser #
|
||||
# #
|
||||
# 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 <https://www.gnu.org/licenses/>. #
|
||||
###############################################################################
|
||||
|
||||
from gi.repository import Gtk,Gio,GObject
|
||||
|
||||
class GameView(Gtk.ScrolledWindow):
|
||||
def __init__(self):
|
||||
Gtk.ScrolledWindow.__init__(self)
|
||||
|
||||
17
sgbackup/gui/settingsdialog.py
Normal file
17
sgbackup/gui/settingsdialog.py
Normal file
@ -0,0 +1,17 @@
|
||||
###############################################################################
|
||||
# sgbackup - The SaveGame Backup tool #
|
||||
# Copyright (C) 2024 Christian Moser #
|
||||
# #
|
||||
# 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 <https://www.gnu.org/licenses/>. #
|
||||
###############################################################################
|
||||
40
sgbackup/logger.conf
Normal file
40
sgbackup/logger.conf
Normal file
@ -0,0 +1,40 @@
|
||||
[loggers]
|
||||
keys=root,console,file
|
||||
|
||||
[handlers]
|
||||
keys=consoleHandler,fileHandler
|
||||
|
||||
[formatters]
|
||||
keys=consoleFormatter,fileFormatter
|
||||
|
||||
[logger_root]
|
||||
level=DEBUG
|
||||
handlers=consoleHandler,fileHandler
|
||||
|
||||
[logger_console]
|
||||
level=DEBUG
|
||||
handlers=consoleHandler
|
||||
propagate=0
|
||||
qualname=console
|
||||
|
||||
[logger_file]
|
||||
level=DEBUG
|
||||
handlers=fileHandler
|
||||
propagate=0
|
||||
qualname=file
|
||||
|
||||
[handler_consoleHandler]
|
||||
class=StreamHandler
|
||||
formatter=consoleFormatter
|
||||
level=DEBUG
|
||||
|
||||
[handler_fileHandler]
|
||||
class=handlers.RotatingFileHandler
|
||||
args=('sgbackup.log','a',10485760,10,'UTF-8',False,)
|
||||
formatter=fileFormatter
|
||||
|
||||
[formatter_consoleFormatter]
|
||||
format=[%(levelname)s:%(name)s] %(message)s
|
||||
|
||||
[formatter_fileFormatter]
|
||||
format=[%(asctime)s-%(levelname)s:%(name)s] %(message)s
|
||||
20
sgbackup/logger.yaml
Normal file
20
sgbackup/logger.yaml
Normal file
@ -0,0 +1,20 @@
|
||||
version: 1
|
||||
formatters:
|
||||
console:
|
||||
format: '[%(levelname)s:%(name)s] %(message)s'
|
||||
file:
|
||||
format: '[%(asctime)s - %(levelname)s:%(name)s] %(message)'
|
||||
handlers:
|
||||
console:
|
||||
class: logging.StreamHandler
|
||||
level: DEBUG
|
||||
formatter: console
|
||||
stream: 'ext://sys.stdout'
|
||||
loggers:
|
||||
console:
|
||||
handlers: [console]
|
||||
level: DEBUG
|
||||
propagate: no
|
||||
root:
|
||||
level: DEBUG
|
||||
handlers: [console]
|
||||
42
sgbackup/main.py
Normal file
42
sgbackup/main.py
Normal file
@ -0,0 +1,42 @@
|
||||
#enconding: utf-8
|
||||
###############################################################################
|
||||
# sgbackup - The SaveGame Backup tool #
|
||||
# Copyright (C) 2024 Christian Moser #
|
||||
# #
|
||||
# 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 <https://www.gnu.org/licenses/>. #
|
||||
###############################################################################
|
||||
|
||||
import logging
|
||||
from . import gui
|
||||
from .gui.application import Application
|
||||
from .steam import SteamLibrary
|
||||
import sys
|
||||
|
||||
logger=logging.getLogger(__name__)
|
||||
|
||||
|
||||
def cli_main():
|
||||
logger.debug("Running cli_main()")
|
||||
return 0
|
||||
|
||||
def curses_main():
|
||||
logger.debug("Running curses_main()")
|
||||
return 0
|
||||
|
||||
|
||||
def gui_main():
|
||||
logger.debug("Running gui_main()")
|
||||
gui.app = Application()
|
||||
gui.app.run()
|
||||
return 0
|
||||
85
sgbackup/settings.py
Normal file
85
sgbackup/settings.py
Normal file
@ -0,0 +1,85 @@
|
||||
###############################################################################
|
||||
# sgbackup - The SaveGame Backup tool #
|
||||
# Copyright (C) 2024 Christian Moser #
|
||||
# #
|
||||
# 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 <https://www.gnu.org/licenses/>. #
|
||||
###############################################################################
|
||||
|
||||
from configparser import ConfigParser
|
||||
import os
|
||||
import sys
|
||||
|
||||
from gi.repository import GLib,GObject
|
||||
|
||||
class Settings(GObject.GObject):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
self.__configparser = ConfigParser()
|
||||
self.__config_dir = os.path.join(GLib.get_user_config_dir(),'sgbackup')
|
||||
self.__gameconf_dir = os.path.join(self.__config_dir,'games')
|
||||
self.__logger_conf = os.path.join(self.__config_dir,'logger.conf')
|
||||
|
||||
self.__config_file = os.path.join(self.__config_dir,'sgbackup.conf')
|
||||
if (os.path.isfile(self.__config_file)):
|
||||
with open(self.__config_file,'r') as conf:
|
||||
self.__configparser.read_file(conf)
|
||||
|
||||
@GObject.Property(nick="parser")
|
||||
def parser(self)->ConfigParser:
|
||||
return self.__configparser
|
||||
|
||||
@GObject.Property(type=str,nick="config-dir")
|
||||
def config_dir(self)->str:
|
||||
return self.__config_dir
|
||||
|
||||
@GObject.Property(type=str,nick="config-file")
|
||||
def config_file(self)->str:
|
||||
return self.__config_file
|
||||
|
||||
@GObject.Property(type=str,nick="gameconf-dir")
|
||||
def gameconf_dir(self)->str:
|
||||
return self.__gameconf_dir
|
||||
|
||||
@GObject.Property(type=str,nick="logger-conf")
|
||||
def logger_conf(self)->str:
|
||||
return self.__logger_conf
|
||||
|
||||
|
||||
@GObject.Property(type=str,nick="backup-dir")
|
||||
def backup_dir(self)->str:
|
||||
if self.parser.has_option('sgbackup','backupDirectory'):
|
||||
return self.parser.get('sgbackup','backupDirectory')
|
||||
return GLib.build_filename(GLib.build_filename(GLib.get_home_dir(),'SavagameBackups'))
|
||||
@backup_dir.setter
|
||||
def backup_dir(self,directory:str):
|
||||
if not os.path.isabs(directory):
|
||||
raise ValueError("\"backup_dir\" needs to be an absolute path!")
|
||||
return self.parser.set('sgbackup','backupDirectory',directory)
|
||||
|
||||
@GObject.Property(type=str)
|
||||
def loglevel(self)->str:
|
||||
if self.parser.has_option('sgbackup','logLevel'):
|
||||
return self.parser.get('sgbackup','logLevel')
|
||||
return "INFO"
|
||||
|
||||
def save(self):
|
||||
self.emit('save')
|
||||
|
||||
@GObject.Signal(name='save',flags=GObject.SIGNAL_RUN_LAST,return_type=None,arg_types=())
|
||||
def do_save(self):
|
||||
with open(self.config_file,'w') as ofile:
|
||||
self.__configparser.write(ofile)
|
||||
|
||||
settings = Settings()
|
||||
296
sgbackup/steam.py
Normal file
296
sgbackup/steam.py
Normal file
@ -0,0 +1,296 @@
|
||||
###############################################################################
|
||||
# sgbackup - The SaveGame Backup tool #
|
||||
# Copyright (C) 2024 Christian Moser #
|
||||
# #
|
||||
# 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 <https://www.gnu.org/licenses/>. #
|
||||
###############################################################################
|
||||
|
||||
import os
|
||||
import re
|
||||
from pathlib import Path
|
||||
import sys
|
||||
import json
|
||||
|
||||
from .settings import settings
|
||||
|
||||
PLATFORM_WINDOWS = (sys.platform.lower() == 'win32')
|
||||
|
||||
|
||||
from gi.repository.GObject import GObject,Property,Signal
|
||||
|
||||
|
||||
class AcfFileParser(object):
|
||||
"""
|
||||
Parses steam acf files to a dict.
|
||||
"""
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def __parse_section(self,lines:list):
|
||||
option_pattern = re.compile("^\"(.+)\"([ \\t]+)\"(.*)\"$")
|
||||
section_pattern = re.compile("^\"(.+)\"")
|
||||
line_count = 0
|
||||
ret = {}
|
||||
|
||||
line_count=0
|
||||
while line_count < len(lines):
|
||||
line = lines[line_count]
|
||||
line_count+=1
|
||||
|
||||
if line == '}':
|
||||
break
|
||||
|
||||
s=line.strip()
|
||||
match = option_pattern.fullmatch(line)
|
||||
if match:
|
||||
name=line[match.start(1):match.end(1)]
|
||||
value=line[match.start(3):match.end(3)]
|
||||
ret[name] = value
|
||||
else:
|
||||
match2 = section_pattern.fullmatch(line)
|
||||
if match2:
|
||||
name=line[match2.start(1):match2.end(1)]
|
||||
if lines[line_count] == '{':
|
||||
line_count += 1
|
||||
n_lines,sect = self.__parse_section(lines[line_count:])
|
||||
line_count += n_lines
|
||||
ret[name]=sect
|
||||
|
||||
|
||||
return line_count,ret
|
||||
|
||||
|
||||
|
||||
def parse_file(self,acf_file)->dict:
|
||||
if not os.path.isfile(acf_file):
|
||||
raise FileNotFoundError("File \"{s}\" does not exist!")
|
||||
|
||||
with open(acf_file,'r') as ifile:
|
||||
buffer = ifile.read()
|
||||
lines = [l.strip() for l in buffer.split('\n')]
|
||||
if lines[0] == "\"AppState\"" and lines[1] == "{":
|
||||
n_lines,sect = self.__parse_section(lines[2:])
|
||||
return sect
|
||||
|
||||
raise RuntimeError("Not a acf file!")
|
||||
|
||||
class IgnoreSteamApp(GObject):
|
||||
@staticmethod
|
||||
def new_from_dict(conf:dict):
|
||||
if ('appid' in conf and 'name' in conf):
|
||||
appid = conf['appid']
|
||||
name = conf['name']
|
||||
reason = conf['reason'] if 'reason' in conf else ""
|
||||
return SteamIgnoreApp(appid,name,reason)
|
||||
|
||||
return None
|
||||
|
||||
def __init__(self,appid:int,name:str,reason:str):
|
||||
GObject.__init__(self)
|
||||
self.__appid = int(appid)
|
||||
self.__name = name
|
||||
self.__reason = reason
|
||||
|
||||
@Property(type=int)
|
||||
def appid(self)->str:
|
||||
return self.__appid
|
||||
|
||||
@Property(type=str)
|
||||
def name(self)->str:
|
||||
return self.__name
|
||||
@name.setter
|
||||
def name(self,name:str):
|
||||
self.__name = name
|
||||
|
||||
@Property(type=str)
|
||||
def reason(self)->str:
|
||||
return self.__reason
|
||||
@reason.setter
|
||||
def reason(self,reason:str):
|
||||
self.__reason = reason
|
||||
|
||||
|
||||
def serialize(self):
|
||||
return {
|
||||
'appid': self.appid,
|
||||
'name': self.name,
|
||||
'reason': self.reason,
|
||||
}
|
||||
|
||||
class SteamApp(GObject):
|
||||
def __init__(self,appid:int,name:str,installdir:str):
|
||||
GObject.__init__(self)
|
||||
self.__appid = int(appid)
|
||||
self.__name = name
|
||||
self.__installdir = installdir
|
||||
|
||||
@Property(type=int)
|
||||
def appid(self):
|
||||
return self.__appid
|
||||
|
||||
@Property
|
||||
def name(self):
|
||||
return self.__name
|
||||
|
||||
@Property
|
||||
def installdir(self):
|
||||
return self.__installdir
|
||||
|
||||
def __str__(self):
|
||||
return '{}: {}'.format(self.appid,self.name)
|
||||
|
||||
def __gt__(self,other):
|
||||
return self.appid > other.appid
|
||||
|
||||
def __lt__(self,other):
|
||||
return self.appid < other.appid
|
||||
|
||||
def __eq__(self,other):
|
||||
return self.appid == other.appid
|
||||
|
||||
|
||||
class SteamLibrary(GObject):
|
||||
def __init__(self,library_path:str):
|
||||
GObject.__init__(self)
|
||||
self.directory = library_path
|
||||
|
||||
@Property(type=str)
|
||||
def directory(self):
|
||||
return self.__directory
|
||||
|
||||
@directory.setter
|
||||
def directory(self,directory:str):
|
||||
if not os.path.isabs(directory):
|
||||
raise ValueError("\"directory\" is not an absolute path!")
|
||||
if not os.path.isdir(directory):
|
||||
raise NotADirectoryError("\"{}\" is not a directory or does not exist!".format(directory))
|
||||
|
||||
self.__directory = directory
|
||||
|
||||
@Property
|
||||
def path(self)->Path:
|
||||
return Path(self.directory).resolve()
|
||||
|
||||
@Property
|
||||
def steam_apps(self)->list:
|
||||
parser = AcfFileParser()
|
||||
appdir = self.path / "steamapps"
|
||||
commondir = appdir / "common"
|
||||
|
||||
ret = []
|
||||
for acf_file in appdir.glob('appmanifest_*.acf'):
|
||||
if not acf_file.is_file():
|
||||
continue
|
||||
try:
|
||||
data = parser.parse_file(str(acf_file))
|
||||
app = SteamApp(data['appid'],data['name'],str(commondir/data['installdir']))
|
||||
ret.append(app)
|
||||
except:
|
||||
pass
|
||||
|
||||
return sorted(ret)
|
||||
|
||||
class Steam(GObject):
|
||||
def __init__(self):
|
||||
GObject.__init__(self)
|
||||
self.__libraries = []
|
||||
self.__ignore_apps = []
|
||||
|
||||
if not self.steamlib_list_file.is_file():
|
||||
if (PLATFORM_WINDOWS):
|
||||
libdirs=[
|
||||
"C:\\Program Files (x86)\\steam",
|
||||
"C:\\Program Files\\steam",
|
||||
]
|
||||
for i in libdirs:
|
||||
if (os.path.isdir(i)):
|
||||
self.__libraries.append(SteamLibrary(i))
|
||||
break
|
||||
else:
|
||||
with open(str(self.steamlib_list_file),'r',encoding="utf-8") as ifile:
|
||||
for line in (i.strip() for i in ifile.readlines()):
|
||||
if not line or line.startswith('#'):
|
||||
continue
|
||||
libdir = Path(line).resolve()
|
||||
if libdir.is_dir():
|
||||
try:
|
||||
self.add_library(str(libdir))
|
||||
except:
|
||||
pass
|
||||
|
||||
ignore_apps = []
|
||||
if self.ignore_apps_file.is_file():
|
||||
with open(str(self.ignore_apps_file),'r',encoding="utf-8") as ifile:
|
||||
ignore_list = json.loads(ifile.read())
|
||||
for ignore in ignore_list:
|
||||
try:
|
||||
ignore_app = IgnoreSteamApp.new_from_dict(ignore)
|
||||
except:
|
||||
continue
|
||||
if ignore_app:
|
||||
self.__ignore_apps.append(ignore_app)
|
||||
self.__ignore_apps = sorted(ignore_apps)
|
||||
#__init__()
|
||||
|
||||
@Property
|
||||
def steamlib_list_file(self)->Path:
|
||||
return Path(settings.config_dir).resolve() / 'steamlib.lst'
|
||||
|
||||
@Property
|
||||
def ignore_apps_file(self)->Path:
|
||||
return Path(settings.config_dir).resolve / 'ignore_steamapps.json'
|
||||
|
||||
@Property
|
||||
def libraries(self):
|
||||
return self.__libraries
|
||||
|
||||
@Property
|
||||
def ignore_apps(self):
|
||||
return self.__ignore_apps
|
||||
|
||||
def __write_steamlib_list_file(self):
|
||||
with open(self.steamlib_list_file,'w',encoding='utf-8') as ofile:
|
||||
ofile.write('\n'.join(str(sl.directory) for sl in self.libraries))
|
||||
|
||||
def add_library(self,steamlib:SteamLibrary|str):
|
||||
if isinstance(steamlib,SteamLibrary):
|
||||
lib = steamlib
|
||||
else:
|
||||
lib = SteamLibrary(steamlib)
|
||||
|
||||
lib_exists = False
|
||||
for i in self.libraries:
|
||||
if i.derctory == lib.directory:
|
||||
lib_exists = True
|
||||
break
|
||||
|
||||
if not lib_exists:
|
||||
self.__libraries.append(lib)
|
||||
self.__write_steamlib_list_file()
|
||||
|
||||
def remove_library(self,steamlib:SteamLibrary|str):
|
||||
if isinstance(steamlib,SteamLibrary):
|
||||
libdir = steamlib.directory
|
||||
else:
|
||||
libdir = str(steamlib)
|
||||
|
||||
delete_libs=[]
|
||||
for i in range(len(self.__libraries)):
|
||||
if self.__libraries[i].directory == libdir:
|
||||
delete_libs.append(i)
|
||||
|
||||
if delete_libs:
|
||||
for i in sorted(delete_libs,reverse=True):
|
||||
del self.__libraries[i]
|
||||
self.__write_steamlib_list_file()
|
||||
44
sphinx/conf.py
Normal file
44
sphinx/conf.py
Normal file
@ -0,0 +1,44 @@
|
||||
# vim: syn=python ts=4 sts=4 sw=4 smartindent autoindent expandtab
|
||||
|
||||
import sys,os
|
||||
|
||||
PROJECT_ROOT = os.path.dirname(os.path.dirname(__file__))
|
||||
sys.path.insert(0,PROJECT_ROOT)
|
||||
import sgbackup
|
||||
|
||||
project = 'sgbackup'
|
||||
copyright = '2024-2025, Christian Moser'
|
||||
author = 'Christian Moser'
|
||||
version = sgbackup.__version__
|
||||
|
||||
exclude_patterns = [
|
||||
'_build',
|
||||
'Thumbs.db',
|
||||
'.DS_Store',
|
||||
'*~',
|
||||
'*.swp',
|
||||
'*.tmp',
|
||||
'*.temp',
|
||||
'*.log',
|
||||
]
|
||||
|
||||
extensions = [
|
||||
'sphinx.ext.autodoc'
|
||||
]
|
||||
language = 'en'
|
||||
master_doc = 'index'
|
||||
source_suffix = '.rst'
|
||||
templates_path = ['templates']
|
||||
|
||||
html_theme = 'sphinx_rtd_theme'
|
||||
html_show_sourcelink = False
|
||||
#html_static_path = ['_static']
|
||||
|
||||
autoclass_content='both'
|
||||
autodoc_class_signature='mixed'
|
||||
autodoc_default_options={
|
||||
'member_order':'alphabetical',
|
||||
'undoc_members':'true',
|
||||
'exclude_memebers':'__weakref__',
|
||||
}
|
||||
|
||||
29
sphinx/index.rst
Normal file
29
sphinx/index.rst
Normal file
@ -0,0 +1,29 @@
|
||||
==========================
|
||||
sgbackup API documentation
|
||||
==========================
|
||||
|
||||
.. title:: sgbackup API
|
||||
|
||||
Descritpion
|
||||
-----------
|
||||
|
||||
Sgbackup is a savegame backup tool written in Python. It has a commandline and a graphical
|
||||
interface using *Gtk4*.
|
||||
|
||||
The minimum Python version is **3.11**.
|
||||
|
||||
It has\ *Gtk4*\ and\ *GObject Introspection*\ as a dependency.
|
||||
|
||||
Table of Contents
|
||||
-----------------
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
install.rst
|
||||
|
||||
modules/sgbackup.rst
|
||||
modules/sgbackup.settings.rst
|
||||
modules/sgbackup.game.rst
|
||||
modules/sgbackup.archiver.rst
|
||||
|
||||
3
sphinx/install.rst
Normal file
3
sphinx/install.rst
Normal file
@ -0,0 +1,3 @@
|
||||
========================
|
||||
Installing sgbackup
|
||||
========================
|
||||
5
sphinx/modules.rst
Normal file
5
sphinx/modules.rst
Normal file
@ -0,0 +1,5 @@
|
||||
.. title:: Modules
|
||||
|
||||
.. toctree:: 2
|
||||
modules/sgbackup
|
||||
modules/game
|
||||
10
sphinx/modules/sgbackup.rst
Normal file
10
sphinx/modules/sgbackup.rst
Normal file
@ -0,0 +1,10 @@
|
||||
============
|
||||
sgbackup API
|
||||
============
|
||||
|
||||
.. title:: sgbackup API
|
||||
|
||||
|
||||
.. automodule:: sgbackup
|
||||
:imported-mebers:
|
||||
:undoc-members:
|
||||
Loading…
Reference in New Issue
Block a user