Skip to content
This repository was archived by the owner on Nov 6, 2025. It is now read-only.

Commit f761ef8

Browse files
Serene-ArcChanceNCounter
authored andcommitted
Switch to pathlib
1 parent ef4bca3 commit f761ef8

File tree

4 files changed

+82
-79
lines changed

4 files changed

+82
-79
lines changed

bak/__main__.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import os
22
from datetime import datetime
3+
from pathlib import Path
34
from shutil import copy2
45

56
import click
@@ -33,6 +34,7 @@ def create(filename, version):
3334
elif not filename:
3435
__print_help()
3536
else:
37+
filename = Path(filename).expanduser().resolve()
3638
commands.create_bakfile(filename)
3739

3840

@@ -42,6 +44,7 @@ def bak_up(filename):
4244
if not filename:
4345
click.echo("A filename or operation is required.\n"
4446
"\tbak --help")
47+
filename = Path(filename).expanduser().resolve()
4548
if not commands.bak_up_cmd(filename):
4649
# TODO descriptive failures
4750
click.echo("An error occurred.")
@@ -61,6 +64,7 @@ def bak_down(filename, keep, quietly):
6164
if not filename:
6265
click.echo("A filename or operation is required.\n"
6366
"\tbak --help")
67+
filename = Path(filename).expanduser().resolve()
6468
commands.bak_down_cmd(filename, keep, quietly)
6569

6670

@@ -71,18 +75,22 @@ def bak_down(filename, keep, quietly):
7175
help="Delete all related .bakfiles without confirming")
7276
@click.argument("filename", required=True, type=click.Path(exists=True))
7377
def bak_off(filename, quietly):
78+
filename = Path(filename).expanduser().resolve()
7479
if not commands.bak_off_cmd(filename, quietly):
7580
# TODO better output here
7681
click.echo("Operation cancelled or failed.")
7782

83+
7884
@bak.command("open", help="View or edit a .bakfile in an external program")
7985
@click.option("--using", "--in", "--with",
8086
help="Program to open (default: $PAGER or less)",
8187
required=False, hidden=True)
8288
@click.argument("filename", required=True, type=click.Path(exists=True))
8389
def bak_print(filename, using):
90+
filename = Path(filename).expanduser().resolve()
8491
commands.bak_print_cmd(filename, using)
8592

93+
8694
@bak.command("get-bak",
8795
help="Outputs the real path of a .bakfile. "
8896
"Useful for piping, and not much else.",
@@ -91,6 +99,7 @@ def bak_print(filename, using):
9199
required=True,
92100
type=click.Path(exists=True))
93101
def bak_get(to_where_you_once_belonged):
102+
to_where_you_once_belonged = Path(to_where_you_once_belonged).expanduser().resolve()
94103
commands.bak_getfile_cmd(to_where_you_once_belonged)
95104

96105

@@ -101,8 +110,10 @@ def bak_get(to_where_you_once_belonged):
101110
required=False)
102111
@click.argument("filename", required=True, type=click.Path(exists=True))
103112
def bak_diff(filename, using):
113+
filename = Path(filename).expanduser().resolve()
104114
commands.bak_diff_cmd(filename, command=using)
105115

116+
106117
@bak.command("list",
107118
help="List all .bakfiles, or a particular file's")
108119
@click.option("--relpaths",
@@ -111,11 +122,14 @@ def bak_diff(filename, using):
111122
is_flag=True,
112123
default=commands.bak_list_relpaths)
113124
@click.argument("filename",
114-
# help="List a particular file's .bakfiles",
115-
required=False,
116-
type=click.Path(exists=True))
125+
# help="List a particular file's .bakfiles",
126+
required=False,
127+
type=click.Path(exists=True))
117128
def bak_list(relpaths, filename):
129+
if filename:
130+
filename = Path(filename).expanduser().resolve()
118131
commands.show_bak_list(filename=filename or None, relative_paths=relpaths)
119132

133+
120134
if __name__ == "__main__":
121135
bak()

bak/commands/__init__.py

Lines changed: 52 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import os
22
import sqlite3
3+
from pathlib import Path
34

45
from datetime import datetime
5-
from typing import List
6+
from typing import Optional
67
from shutil import copy2
78
from subprocess import call
89
from sys import stderr, stdout
@@ -23,49 +24,37 @@
2324
# TODO: customizable file extension
2425

2526
try:
26-
data_dir = os.environ["XDG_DATA_HOME"]
27+
data_dir = Path(os.environ["XDG_DATA_HOME"]).expanduser().resolve()
2728
except KeyError:
28-
data_dir = os.path.expanduser("~/.local/share")
29+
data_dir = Path("~/.local/share").expanduser().resolve()
2930
try:
30-
config_dir = os.environ["XDG_CONFIG_HOME"]
31+
config_dir = Path(os.environ["XDG_CONFIG_HOME"]).expanduser().resolve()
3132
except KeyError:
32-
config_dir = os.path.expanduser("~/.config")
33+
config_dir = Path("~/.config").expanduser().resolve()
3334

34-
config_file = os.path.join(config_dir, 'bak.cfg')
35-
cfg = Config(config_file)
35+
config_file = config_dir / 'bak.cfg'
36+
cfg = Config(str(config_file))
3637

37-
bak_dir = cfg['bakfile_location'] or os.path.join(data_dir,
38-
"bak", "bakfiles")
39-
bak_db_loc = cfg['bak_database_location'] or \
40-
os.path.join(data_dir, "bak", "bak.db")
38+
bak_dir = cfg['bakfile_location'] or data_dir / 'bak' / 'bakfiles'
39+
bak_db_loc = cfg['bak_database_location'] or data_dir / 'bak' / 'bak.db'
4140

4241
bak_list_relpaths = cfg['bak_list_relative_paths']
4342

44-
if not os.path.exists(bak_dir):
45-
os.makedirs(bak_dir)
43+
if not bak_dir.exists():
44+
bak_dir.mkdir(parents=True)
4645

4746
db_handler = bak_db.BakDBHandler(bak_db_loc)
4847

4948

50-
def expandpath(i_path):
51-
return os.path.abspath(os.path.expanduser(i_path))
52-
53-
54-
def _assemble_bakfile(filename):
49+
def _assemble_bakfile(filename: Path):
5550
time_now = datetime.now()
56-
splitname = os.path.split(expandpath(filename))
57-
bakfile_name = "".join([".".join(i[1:].replace("/", "-")
58-
for i in splitname[:-1]) +
59-
'-' +
60-
splitname[-1],
61-
".",
62-
'-'.join(str(
63-
time_now.timestamp()).split('.')),
64-
".bak"]).replace(" ", "-")
65-
bakfile_path = os.path.join(bak_dir, bakfile_name)
66-
67-
new_bak_entry = bakfile.BakFile(os.path.basename(filename),
68-
os.path.abspath(filename),
51+
bakfile_name = "".join(
52+
["-".join(i for i in filename.parent.parts[1:])
53+
+ '-' + filename.name, ".", '-'.join(str(time_now.timestamp()).split('.')), ".bak"]).replace(" ", "-")
54+
bakfile_path = bak_dir / bakfile_name
55+
56+
new_bak_entry = bakfile.BakFile(filename.name,
57+
filename,
6958
bakfile_path,
7059
time_now,
7160
time_now)
@@ -75,10 +64,10 @@ def _assemble_bakfile(filename):
7564
default_select_prompt = ("Enter a number, or: (V)iew (D)iff (C)ancel", 'C')
7665

7766

78-
def _get_bakfile_entry(filename,
67+
def _get_bakfile_entry(filename: Path,
7968
select_prompt=default_select_prompt,
8069
err=True):
81-
entries = db_handler.get_bakfile_entries(expandpath(filename))
70+
entries = db_handler.get_bakfile_entries(filename.resolve())
8271
if (entries is False) or len(entries) == 0:
8372
return None
8473
# If there's only one bakfile corresponding to filename, return that.
@@ -101,6 +90,7 @@ def _do_select_bakfile(bakfiles: List[bakfile.BakFile],
10190

10291
def get_choice():
10392
return click.prompt(*select_prompt, err=err).lower()
93+
10494
choice = get_choice()
10595

10696
while True:
@@ -142,7 +132,7 @@ def get_choice():
142132
get_choice()
143133

144134

145-
def show_bak_list(filename: (None, str, os.path) = None,
135+
def show_bak_list(filename: Optional[Path] = None,
146136
relative_paths: bool = False):
147137
""" Prints list of .bakfiles with metadata
148138
@@ -153,21 +143,21 @@ def show_bak_list(filename: (None, str, os.path) = None,
153143
# pass
154144
bakfiles: List[bakfile.BakFile]
155145
bakfiles = db_handler.get_bakfile_entries(filename) if filename else \
156-
db_handler.get_all_entries()
146+
db_handler.get_all_entries()
157147

158148
console = Console()
159-
if bakfiles == []:
149+
if bakfiles is []:
160150
console.print(f"No .bakfiles found for "
161-
f"{os.path.abspath(os.path.expanduser(filename))}" if \
162-
filename else "No .bakfiles found")
151+
f"{filename}" if
152+
filename else "No .bakfiles found")
163153
return
164-
165-
_title = f".bakfiles of {os.path.abspath(os.path.expanduser(filename))}" if \
166-
filename else ".bakfiles"
154+
155+
_title = f".bakfiles of {filename}" if \
156+
filename else ".bakfiles"
167157

168158
table = Table(title=_title,
169159
show_lines=True, box=box.HEAVY_EDGE)
170-
160+
171161
table.add_column("")
172162
table.add_column("Original File")
173163
table.add_column("Date Created")
@@ -176,33 +166,33 @@ def show_bak_list(filename: (None, str, os.path) = None,
176166
i = 1
177167
for _bakfile in bakfiles:
178168
table.add_row(str(i),
179-
(os.path.relpath(_bakfile.original_file)) if \
180-
relative_paths else \
169+
(filename.resolve()) if
170+
relative_paths else
181171
_bakfile.orig_abspath,
182172
_bakfile.date_created.split('.')[0],
183173
_bakfile.date_modified.split('.')[0])
184-
i+=1
174+
i += 1
185175

186176
console.print(table)
187177

188-
def create_bakfile(filename: str):
178+
179+
def create_bakfile(filename: Path):
189180
""" Default command. Roughly equivalent to
190181
cp filename $XDG_DATA_DIR/.bakfiles/filename.bak
191182
but inserts relevant metadata into the database.
192183
193184
Arguments:
194185
filename: (str|os.path)
195186
"""
196-
filename = expandpath(filename)
197-
if not os.path.exists(filename):
187+
if not filename.exists():
198188
# TODO descriptive failure
199189
return False
200190
new_bakfile = _assemble_bakfile(filename)
201191
copy2(new_bakfile.orig_abspath, new_bakfile.bakfile_loc)
202192
db_handler.create_bakfile_entry(new_bakfile)
203193

204194

205-
def bak_up_cmd(filename: str):
195+
def bak_up_cmd(filename: Path):
206196
""" Overwrite an existing .bakfile with the file's current contents
207197
208198
Args:
@@ -215,9 +205,8 @@ def bak_up_cmd(filename: str):
215205

216206
console = Console()
217207

218-
filename = expandpath(filename)
219208
old_bakfile = db_handler.get_bakfile_entries(filename)
220-
if old_bakfile == None:
209+
if old_bakfile is None:
221210
console.print(f"No bakfile found for {filename}")
222211
return True
223212
# Disambiguate
@@ -226,7 +215,7 @@ def bak_up_cmd(filename: str):
226215
select_prompt=(
227216
("Enter a number to overwrite a .bakfile, or:\n(V)iew (L)ist (C)ancel", "C")))
228217

229-
if old_bakfile == None:
218+
if old_bakfile is None:
230219
console.print("Cancelled.")
231220
return True
232221
elif not isinstance(old_bakfile, bakfile.BakFile):
@@ -238,7 +227,7 @@ def bak_up_cmd(filename: str):
238227
return True
239228

240229

241-
def bak_down_cmd(filename: str,
230+
def bak_down_cmd(filename: Path,
242231
keep_bakfile: bool = False,
243232
quiet: bool = False):
244233
""" Restore `filename` from .bakfile. Prompts if ambiguous (such as
@@ -249,7 +238,6 @@ def bak_down_cmd(filename: str,
249238
keep_bakfile (bool): If False, .bakfile is deleted (default: False)
250239
"""
251240
console = Console()
252-
filename = expandpath(filename)
253241
bakfile_entries = db_handler.get_bakfile_entries(filename)
254242
if not bakfile_entries:
255243
console.print(f"No bakfiles found for {filename}")
@@ -258,7 +246,7 @@ def bak_down_cmd(filename: str,
258246
bakfile_entry = _do_select_bakfile(bakfile_entries) if len(
259247
bakfile_entries) > 1 else bakfile_entries[0]
260248

261-
if bakfile_entry == None:
249+
if bakfile_entry is None:
262250
console.print(f"No bakfiles found for {filename}")
263251
return
264252
elif not bakfile_entry:
@@ -293,7 +281,7 @@ def __remove_bakfiles(bakfile_entries):
293281
db_handler.del_bakfile_entry(entry)
294282

295283

296-
def bak_off_cmd(filename: (None, str, os.path),
284+
def bak_off_cmd(filename: Optional[Path],
297285
quietly=False):
298286
""" Used when finished. Deletes `filename.bak`. Prompts if ambiguous:
299287
3 .bakfiles detected:
@@ -308,10 +296,9 @@ def bak_off_cmd(filename: (None, str, os.path),
308296
filename ([type], optional): [description]. Defaults to None.
309297
"""
310298
console = Console()
311-
filename = expandpath(filename)
312299
bakfiles = db_handler.get_bakfile_entries(filename)
313-
if bakfiles == []:
314-
console.print(f"No bakfiles found for {os.path.abspath(filename)}")
300+
if bakfiles is []:
301+
console.print(f"No bakfiles found for {filename}")
315302
return False
316303
confirm = input(
317304
f"Confirming: Remove {len(bakfiles)} .bakfiles for {filename}? "
@@ -334,8 +321,8 @@ def bak_print_cmd(bak_to_print: (str, bakfile.BakFile),
334321
select_prompt=(
335322
"Enter a number to select a .bakfile, or:\n(D)iff (L)ist (C)ancel",
336323
"C"))
337-
# "View which .bakfile? (#)",
338-
# "c"))
324+
# "View which .bakfile? (#)",
325+
# "c"))
339326
if _bak_to_print == None:
340327
console.print(
341328
f"No bakfiles found for {os.path.abspath(bak_to_print)}")
@@ -361,18 +348,18 @@ def bak_getfile_cmd(bak_to_get: (str, bakfile.BakFile)):
361348
print(bak_to_get.bakfile_loc)
362349

363350

364-
def bak_diff_cmd(filename: str, command='diff'):
351+
def bak_diff_cmd(filename: (bakfile.BakFile, Path), command='diff'):
365352
# TODO write tests for this (mildly tricky)
366353
console = Console()
367354

368355
bak_to_diff = filename if isinstance(filename, bakfile.BakFile) else \
369-
_get_bakfile_entry(expandpath(filename),
356+
_get_bakfile_entry(filename.resolve(),
370357
select_prompt=(
371358
("Enter a number to diff a .bakfile, or:\n(V)iew (L)ist (C)ancel", "C")))
372359
if not command:
373360
command = cfg['bak_diff_exec'] or 'diff'
374-
if bak_to_diff == None:
375-
console.print(f"No bakfiles found for {os.path.abspath(filename)}")
361+
if bak_to_diff is None:
362+
console.print(f"No bakfiles found for {filename.resolve()}")
376363
return
377364
if not bak_to_diff:
378365
return

bak/data/bak_db.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
import os
22
import sqlite3
3+
from pathlib import Path
34

45
from .bakfile import BakFile
56

67

7-
class BakDBHandler():
8-
db_loc: str
8+
class BakDBHandler:
9+
db_loc: Path
910

10-
def __init__(self, db_loc: str):
11+
def __init__(self, db_loc: Path):
1112
self.db_loc = db_loc
1213

13-
if not os.path.exists(self.db_loc):
14+
if not self.db_loc.exists():
1415
db_conn = sqlite3.connect(self.db_loc)
1516
db_conn.execute("""
1617
CREATE TABLE bakfiles (original_file,

0 commit comments

Comments
 (0)