save-scummer


Namesave-scummer JSON
Version 0.1.0 PyPI version JSON
download
home_page
SummaryA simple CLI utility to backup and restore game saves
upload_time2023-12-29 17:38:42
maintainer
docs_urlNone
authorJordan Cook
requires_python>=3.7
license
keywords backup game restore roguelike roguelite save
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Save Scummer

[![Build](https://github.com/JWCook/save-scummer/workflows/Build/badge.svg?branch=main)](https://github.com/JWCook/save-scummer/actions)
[![PyPI](https://img.shields.io/pypi/v/save-scummer?color=blue)](https://pypi.org/project/save-scummer)
[![PyPI - Python Versions](https://img.shields.io/pypi/pyversions/save-scummer)](https://pypi.org/project/save-scummer)

* [Features](#features)
* [Installation](#installation)
  * [Autocompletion](#autocompletion--optional-)
* [Usage](#usage)
  * [Add](#add)
  * [Backup](#backup)
  * [List](#list)
  * [Restore](#restore)
    * [Backup specifiers](#backup-specifiers)
    * [Restore Examples](#restore-examples)


Save-Scummer is a simple CLI utility to backup and restore game saves.
This is intended for rogue-lite games like **Rogue Legacy**, **FTL** and **Don't Starve**,
but it could also be applied to other games or non-game applications.

I made this because I enjoy roguelike/rogue-lite games, but when one starts to get too difficult,
I may resort to [save-scumming](https://tvtropes.org/pmwiki/pmwiki.php/Main/SaveScumming) as an
option to make the game a bit easier. When doing that manually, I find myself wasting precious _seconds_
of time copying files back and forth, so naturally I decided to waste _hours_ making it (semi-)automated
instead.

A full backup utility (like [Duplicati](https://github.com/duplicati/duplicati)) or sync utility
(like [rsync](https://github.com/WayneD/rsync)) will obviously have _many_ more features, but for the
basic case of handling game saves, I wanted something simpler with concise command line usage.

# Features
* Just provide a save directory (or glob pattern) to configure a new game
* Easily make backups, and restore them by most recent (default), time expressions
  (to indicate how far back in time you want to go), or choose from a list
* Tab autocompletion

# Installation
Install with [pipx](https://pipx.pypa.io/stable/) (recommended):
```sh
pipx install save-scummer
```

Or with pip:
```sh
pip install save-scummer
```

## Autocompletion (optional)
Tab autocompletion is available for most common shells: **bash, fish, zsh** and Windows **PowerShell**.
To install, run:
```sh
ssc --install [shell name]
``````

# Usage
Save-scummer provides the command `save-scummer` (also aliased as `ssc`) with the following subcommands:

```sh
sh: ssc COMMAND [ARGS]...

Options:
  --help  Show this message and exit.

Commands:
  add      Add a game and its save directory
  backup   Create a backup of one, multiple, or all games
  ls       List all currently configured games
  restore  Restore a backup of the specified game
```

## Add
Use `ssc add` to add (or update) a game and its save directory.

Relative paths, user paths, and [glob patterns](https://en.wikipedia.org/wiki/Glob_(programming))
are supported:
```sh
ssc add game1 ~/Games/game1           # Add a dir (including any subdirs)
ssc add game1 '~/Games/game1/**'      # Equivalent glob pattern (quotes required)
ssc add game2 'C:\Games\game2\*.sav'  # Add files ending in .sav
````

## Backup
Use `ssc backup` to create a new backup. Just specify the game title, and an optional description:
```sh
ssc backup game1 -d 'level 10 with full health'
```
Or just backup everything:
```sh
ssc backup --all
```

## List
Use `ssc ls` to show a summary of all configured games:
```sh
╒════════╤═════════════════╤═════════════════════════════════╕
│ Title  │ Total backups   │ Last saved                      │
╞════════╪═════════════════╪═════════════════════════════════╡
│ game1  │ 0               │ never                           │
├────────┼─────────────────┼─────────────────────────────────┤
│ game2  │ 7 (94.96 KB)    │ 2021-01-19 15:20 (23 hours ago) │
╘════════╧═════════════════╧═════════════════════════════════╛
```

Or use `ssc ls [game title]` to show more details on a specific game and its backups:
```sh
Game:               game2
Total backups:      7 (94.96 KB)
Last saved:         2021-01-19 15:20 (23 hours ago)
Last backed up:     2021-01-19 16:24 (22 hours ago)
Source directory:   /home/user/game2/saves
Backup directory:   /home/user/.local/share/save-scummer/backups/game2
Backup files:
0:  game2-2021-01-26T19:23:26.zip
1:  game2-2021-01-20T16:33:42-pre-restore.zip
2:  game2-2021-01-19T19:26:10.zip
3:  game2-2021-01-19T18:31:58.zip
4:  game2-2021-01-18T12:17:52.zip
5:  game2-2021-01-17T16:18:09.zip
6:  game2-2021-01-17T15:01:58.zip
```

Note that "Last saved" is the time that the source files were created/modified.

## Restore

Use `ssc restore` to restore a backup. A specific backup can be indicated by backup
 **index, age, date/time, or filename**. Otherwise, the most recent backup is restored.

```sh
Usage: ssc restore [OPTIONS] [TITLE]

Options:
  -i, --index INTEGER  Backup number (starting at 0, from newest to oldest)
  -a, --age TEXT       Minimum age (relative to current time)
  -d, --date TEXT      Maximum date/time (absolute)
  -f TEXT              Backup filename; either absolute or relative to backup dir
```

### Backup specifiers

**Index:**
The backup index, sorted from newest to oldest, e.g.
**"Restore the save from x backups ago."** 0 is the latest backup, 1 is the
backup made before that, etc.
Negative values can also be given; -1 would give you the oldest backup.
See `ls` command for full list of available backups.

**Age:**
Minimum age of the save to restore, e.g **"I want to go back in time by 1 hour."**
Amounts of time can be specified in 'HH:MM' format, or with a number followed by a unit.
Examples:
* '1:30' (an hour and a half ago)
* '30m' (or '30 minutes')
* '6h' (or '6 hours')
* '9 hours, 15 minutes' (or '9:15')
* '2d' (or '2 days')
* See [pytimeparse](https://github.com/wroberts/pytimeparse) for more formats

**Date/Time:**
Maximum date/time of the save to restore, e.g., **"I want to go back in
time to 1:30 yesterday."** Most date/time formats are supported.
Examples:
* '16:30' or '4:30 PM' (today)
* '2021-01-20'
* 'August 3 2020'
* Most date/time formats are supported; see
[dateutil](https://dateutil.readthedocs.io/en/stable/examples.html#parse-examples)
for more examples.

**Filename:**
Either a full path or just the filename (relative to the backup dir)

### Restore Examples

```sh
# Just restore the most recent backup
ssc restore game1

# Restore the backup made 2 backups ago (aka the 3rd most recent)
ssc restore game1 -i 2

# Restore a backup from (at least) an hour and a half ago
ssc restore game1 -a '1:30'

# Restore a backup from (at least) 2 days ago
ssc restore game1 -a 2d

# Restore a backup from 4:00 PM today or earlier
ssc restore game1 -d '4:00 PM'

# Restore a backup from March 22 or earlier
ssc restore game1 -d 'Mar 22 2021'

# Restore a backup by filename
ssc restore game1 -f game1-2021-01-20T00:09:10.zip
```

# Development setup
To set up for local development:
```sh
git clone https://github.com/JWCook/save-scummer && cd save-scummer
pip install -Ue '.[dev]'
```

To run linting, formatting, etc.:
```sh
pre-commit run -a
```

            

Raw data

            {
    "_id": null,
    "home_page": "",
    "name": "save-scummer",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.7",
    "maintainer_email": "",
    "keywords": "backup,game,restore,roguelike,roguelite,save",
    "author": "Jordan Cook",
    "author_email": "",
    "download_url": "https://files.pythonhosted.org/packages/44/44/8309867188ad837cf58df296c370e9be007380be2fe0e79f391fb192fb01/save_scummer-0.1.0.tar.gz",
    "platform": null,
    "description": "# Save Scummer\n\n[![Build](https://github.com/JWCook/save-scummer/workflows/Build/badge.svg?branch=main)](https://github.com/JWCook/save-scummer/actions)\n[![PyPI](https://img.shields.io/pypi/v/save-scummer?color=blue)](https://pypi.org/project/save-scummer)\n[![PyPI - Python Versions](https://img.shields.io/pypi/pyversions/save-scummer)](https://pypi.org/project/save-scummer)\n\n* [Features](#features)\n* [Installation](#installation)\n  * [Autocompletion](#autocompletion--optional-)\n* [Usage](#usage)\n  * [Add](#add)\n  * [Backup](#backup)\n  * [List](#list)\n  * [Restore](#restore)\n    * [Backup specifiers](#backup-specifiers)\n    * [Restore Examples](#restore-examples)\n\n\nSave-Scummer is a simple CLI utility to backup and restore game saves.\nThis is intended for rogue-lite games like **Rogue Legacy**, **FTL** and **Don't Starve**,\nbut it could also be applied to other games or non-game applications.\n\nI made this because I enjoy roguelike/rogue-lite games, but when one starts to get too difficult,\nI may resort to [save-scumming](https://tvtropes.org/pmwiki/pmwiki.php/Main/SaveScumming) as an\noption to make the game a bit easier. When doing that manually, I find myself wasting precious _seconds_\nof time copying files back and forth, so naturally I decided to waste _hours_ making it (semi-)automated\ninstead.\n\nA full backup utility (like [Duplicati](https://github.com/duplicati/duplicati)) or sync utility\n(like [rsync](https://github.com/WayneD/rsync)) will obviously have _many_ more features, but for the\nbasic case of handling game saves, I wanted something simpler with concise command line usage.\n\n# Features\n* Just provide a save directory (or glob pattern) to configure a new game\n* Easily make backups, and restore them by most recent (default), time expressions\n  (to indicate how far back in time you want to go), or choose from a list\n* Tab autocompletion\n\n# Installation\nInstall with [pipx](https://pipx.pypa.io/stable/) (recommended):\n```sh\npipx install save-scummer\n```\n\nOr with pip:\n```sh\npip install save-scummer\n```\n\n## Autocompletion (optional)\nTab autocompletion is available for most common shells: **bash, fish, zsh** and Windows **PowerShell**.\nTo install, run:\n```sh\nssc --install [shell name]\n``````\n\n# Usage\nSave-scummer provides the command `save-scummer` (also aliased as `ssc`) with the following subcommands:\n\n```sh\nsh: ssc COMMAND [ARGS]...\n\nOptions:\n  --help  Show this message and exit.\n\nCommands:\n  add      Add a game and its save directory\n  backup   Create a backup of one, multiple, or all games\n  ls       List all currently configured games\n  restore  Restore a backup of the specified game\n```\n\n## Add\nUse `ssc add` to add (or update) a game and its save directory.\n\nRelative paths, user paths, and [glob patterns](https://en.wikipedia.org/wiki/Glob_(programming))\nare supported:\n```sh\nssc add game1 ~/Games/game1           # Add a dir (including any subdirs)\nssc add game1 '~/Games/game1/**'      # Equivalent glob pattern (quotes required)\nssc add game2 'C:\\Games\\game2\\*.sav'  # Add files ending in .sav\n````\n\n## Backup\nUse `ssc backup` to create a new backup. Just specify the game title, and an optional description:\n```sh\nssc backup game1 -d 'level 10 with full health'\n```\nOr just backup everything:\n```sh\nssc backup --all\n```\n\n## List\nUse `ssc ls` to show a summary of all configured games:\n```sh\n\u2552\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2564\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2564\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2555\n\u2502 Title  \u2502 Total backups   \u2502 Last saved                      \u2502\n\u255e\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u256a\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u256a\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2561\n\u2502 game1  \u2502 0               \u2502 never                           \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 game2  \u2502 7 (94.96 KB)    \u2502 2021-01-19 15:20 (23 hours ago) \u2502\n\u2558\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2567\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2567\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255b\n```\n\nOr use `ssc ls [game title]` to show more details on a specific game and its backups:\n```sh\nGame:               game2\nTotal backups:      7 (94.96 KB)\nLast saved:         2021-01-19 15:20 (23 hours ago)\nLast backed up:     2021-01-19 16:24 (22 hours ago)\nSource directory:   /home/user/game2/saves\nBackup directory:   /home/user/.local/share/save-scummer/backups/game2\nBackup files:\n0:  game2-2021-01-26T19:23:26.zip\n1:  game2-2021-01-20T16:33:42-pre-restore.zip\n2:  game2-2021-01-19T19:26:10.zip\n3:  game2-2021-01-19T18:31:58.zip\n4:  game2-2021-01-18T12:17:52.zip\n5:  game2-2021-01-17T16:18:09.zip\n6:  game2-2021-01-17T15:01:58.zip\n```\n\nNote that \"Last saved\" is the time that the source files were created/modified.\n\n## Restore\n\nUse `ssc restore` to restore a backup. A specific backup can be indicated by backup\n **index, age, date/time, or filename**. Otherwise, the most recent backup is restored.\n\n```sh\nUsage: ssc restore [OPTIONS] [TITLE]\n\nOptions:\n  -i, --index INTEGER  Backup number (starting at 0, from newest to oldest)\n  -a, --age TEXT       Minimum age (relative to current time)\n  -d, --date TEXT      Maximum date/time (absolute)\n  -f TEXT              Backup filename; either absolute or relative to backup dir\n```\n\n### Backup specifiers\n\n**Index:**\nThe backup index, sorted from newest to oldest, e.g.\n**\"Restore the save from x backups ago.\"** 0 is the latest backup, 1 is the\nbackup made before that, etc.\nNegative values can also be given; -1 would give you the oldest backup.\nSee `ls` command for full list of available backups.\n\n**Age:**\nMinimum age of the save to restore, e.g **\"I want to go back in time by 1 hour.\"**\nAmounts of time can be specified in 'HH:MM' format, or with a number followed by a unit.\nExamples:\n* '1:30' (an hour and a half ago)\n* '30m' (or '30 minutes')\n* '6h' (or '6 hours')\n* '9 hours, 15 minutes' (or '9:15')\n* '2d' (or '2 days')\n* See [pytimeparse](https://github.com/wroberts/pytimeparse) for more formats\n\n**Date/Time:**\nMaximum date/time of the save to restore, e.g., **\"I want to go back in\ntime to 1:30 yesterday.\"** Most date/time formats are supported.\nExamples:\n* '16:30' or '4:30 PM' (today)\n* '2021-01-20'\n* 'August 3 2020'\n* Most date/time formats are supported; see\n[dateutil](https://dateutil.readthedocs.io/en/stable/examples.html#parse-examples)\nfor more examples.\n\n**Filename:**\nEither a full path or just the filename (relative to the backup dir)\n\n### Restore Examples\n\n```sh\n# Just restore the most recent backup\nssc restore game1\n\n# Restore the backup made 2 backups ago (aka the 3rd most recent)\nssc restore game1 -i 2\n\n# Restore a backup from (at least) an hour and a half ago\nssc restore game1 -a '1:30'\n\n# Restore a backup from (at least) 2 days ago\nssc restore game1 -a 2d\n\n# Restore a backup from 4:00 PM today or earlier\nssc restore game1 -d '4:00 PM'\n\n# Restore a backup from March 22 or earlier\nssc restore game1 -d 'Mar 22 2021'\n\n# Restore a backup by filename\nssc restore game1 -f game1-2021-01-20T00:09:10.zip\n```\n\n# Development setup\nTo set up for local development:\n```sh\ngit clone https://github.com/JWCook/save-scummer && cd save-scummer\npip install -Ue '.[dev]'\n```\n\nTo run linting, formatting, etc.:\n```sh\npre-commit run -a\n```\n",
    "bugtrack_url": null,
    "license": "",
    "summary": "A simple CLI utility to backup and restore game saves",
    "version": "0.1.0",
    "project_urls": {
        "Source code": "https://github.com/JWCook/save-scummer"
    },
    "split_keywords": [
        "backup",
        "game",
        "restore",
        "roguelike",
        "roguelite",
        "save"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "1b5933d529a63ae8034938aca2389b309f4cb9ba1172eb13736f370416c1d850",
                "md5": "99cbca9f9f2038d08b27cfc821eda0f1",
                "sha256": "b87dced3acfcb49e942b6a68af5d331f8a09b9f5fcbe7c169325a231e1401beb"
            },
            "downloads": -1,
            "filename": "save_scummer-0.1.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "99cbca9f9f2038d08b27cfc821eda0f1",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 13332,
            "upload_time": "2023-12-29T17:38:41",
            "upload_time_iso_8601": "2023-12-29T17:38:41.340246Z",
            "url": "https://files.pythonhosted.org/packages/1b/59/33d529a63ae8034938aca2389b309f4cb9ba1172eb13736f370416c1d850/save_scummer-0.1.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "44448309867188ad837cf58df296c370e9be007380be2fe0e79f391fb192fb01",
                "md5": "49e766a0e50bd55cdd86583e69dd2051",
                "sha256": "1023617e6beb97f875770610501215fcd4bf31f026e7c9d97a9800633bb8c9b7"
            },
            "downloads": -1,
            "filename": "save_scummer-0.1.0.tar.gz",
            "has_sig": false,
            "md5_digest": "49e766a0e50bd55cdd86583e69dd2051",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.7",
            "size": 10903,
            "upload_time": "2023-12-29T17:38:42",
            "upload_time_iso_8601": "2023-12-29T17:38:42.802241Z",
            "url": "https://files.pythonhosted.org/packages/44/44/8309867188ad837cf58df296c370e9be007380be2fe0e79f391fb192fb01/save_scummer-0.1.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-12-29 17:38:42",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "JWCook",
    "github_project": "save-scummer",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "save-scummer"
}
        
Elapsed time: 0.41823s