Última actividad 4 hours ago

A python script to search through multiple (or all) snapshots of restic for a specified path

restic-search.py Sin formato
1#!/usr/bin/env python3
2import sys
3from argparse import ArgumentParser
4from json import loads
5from pathlib import Path
6from subprocess import PIPE, Popen
7from sys import stderr
8from typing import TypedDict
9
10parser = ArgumentParser(prog="restic-search")
11parser.add_argument("search", type=str, nargs="+")
12parser.add_argument(
13 "-n", "--last", type=int, help="Only search through the n latest snapshots"
14)
15
16
17class Snapshot(TypedDict):
18 id: str
19
20
21def restic_snapshots() -> list[Snapshot]:
22 ps = Popen(["restic", "snapshots", "--json"], stdout=PIPE)
23 stdout, _ = ps.communicate()
24 if ps.returncode != 0:
25 raise RuntimeError(
26 f"Error while running restic snapshots: returncode {ps.returncode}"
27 )
28 j = loads(stdout.decode("utf-8"))
29 return j
30
31
32def restic_ls(snapshot_id: str) -> list[str]:
33 ps = Popen(["restic", "ls", snapshot_id], stdout=PIPE)
34 stdout, _ = ps.communicate()
35 if ps.returncode != 0:
36 raise RuntimeError(f"Error while running restic ls: returncode {ps.returncode}")
37 return stdout.decode("utf-8").split("\n")
38
39
40if __name__ == "__main__":
41 args = parser.parse_args()
42 stderr.write("Listing snapshots...\n")
43 snapshots = restic_snapshots()
44 if args.last:
45 snapshots = snapshots[-args.last :]
46 results = []
47 for snapshot in snapshots:
48 stderr.write(f"Listing files in snapshot {snapshot['id']}...\n")
49 files = restic_ls(snapshot["id"])
50 for file in files:
51 path = Path(file)
52 for search in args.search:
53 if path.match(search):
54 results.append((search, file, snapshot["id"]))
55
56 for result in results:
57 print(f"{result[0]}\t{result[1]}\t{result[2]}")
58