11import os
22import sqlite3
3+ from pathlib import Path
34
45from datetime import datetime
5- from typing import List
6+ from typing import Optional
67from shutil import copy2
78from subprocess import call
89from sys import stderr , stdout
2324# TODO: customizable file extension
2425
2526try :
26- data_dir = os .environ ["XDG_DATA_HOME" ]
27+ data_dir = Path ( os .environ ["XDG_DATA_HOME" ]). expanduser (). resolve ()
2728except KeyError :
28- data_dir = os . path . expanduser ("~/.local/share" )
29+ data_dir = Path ("~/.local/share" ). expanduser (). resolve ( )
2930try :
30- config_dir = os .environ ["XDG_CONFIG_HOME" ]
31+ config_dir = Path ( os .environ ["XDG_CONFIG_HOME" ]). expanduser (). resolve ()
3132except 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
4241bak_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
4746db_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):
7564default_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 console .print (f"Creating { filename } .bak" )
223212 return create_bakfile (filename )
@@ -228,7 +217,7 @@ def bak_up_cmd(filename: str):
228217 select_prompt = (
229218 ("Enter a number to overwrite a .bakfile, or:\n (V)iew (L)ist (C)ancel" , "C" )))
230219
231- if old_bakfile == None :
220+ if old_bakfile is None :
232221 console .print ("Cancelled." )
233222 return True
234223 elif not isinstance (old_bakfile , bakfile .BakFile ):
@@ -240,7 +229,7 @@ def bak_up_cmd(filename: str):
240229 return True
241230
242231
243- def bak_down_cmd (filename : str ,
232+ def bak_down_cmd (filename : Path ,
244233 keep_bakfile : bool = False ,
245234 quiet : bool = False ):
246235 """ Restore `filename` from .bakfile. Prompts if ambiguous (such as
@@ -251,7 +240,6 @@ def bak_down_cmd(filename: str,
251240 keep_bakfile (bool): If False, .bakfile is deleted (default: False)
252241 """
253242 console = Console ()
254- filename = expandpath (filename )
255243 bakfile_entries = db_handler .get_bakfile_entries (filename )
256244 if not bakfile_entries :
257245 console .print (f"No bakfiles found for { filename } " )
@@ -260,7 +248,7 @@ def bak_down_cmd(filename: str,
260248 bakfile_entry = _do_select_bakfile (bakfile_entries ) if len (
261249 bakfile_entries ) > 1 else bakfile_entries [0 ]
262250
263- if bakfile_entry == None :
251+ if bakfile_entry is None :
264252 console .print (f"No bakfiles found for { filename } " )
265253 return
266254 elif not bakfile_entry :
@@ -295,7 +283,7 @@ def __remove_bakfiles(bakfile_entries):
295283 db_handler .del_bakfile_entry (entry )
296284
297285
298- def bak_off_cmd (filename : ( None , str , os . path ) ,
286+ def bak_off_cmd (filename : Optional [ Path ] ,
299287 quietly = False ):
300288 """ Used when finished. Deletes `filename.bak`. Prompts if ambiguous:
301289 3 .bakfiles detected:
@@ -310,10 +298,9 @@ def bak_off_cmd(filename: (None, str, os.path),
310298 filename ([type], optional): [description]. Defaults to None.
311299 """
312300 console = Console ()
313- filename = expandpath (filename )
314301 bakfiles = db_handler .get_bakfile_entries (filename )
315- if bakfiles == []:
316- console .print (f"No bakfiles found for { os . path . abspath ( filename ) } " )
302+ if bakfiles is []:
303+ console .print (f"No bakfiles found for { filename } " )
317304 return False
318305 confirm = input (
319306 f"Confirming: Remove { len (bakfiles )} .bakfiles for { filename } ? "
@@ -336,8 +323,8 @@ def bak_print_cmd(bak_to_print: (str, bakfile.BakFile),
336323 select_prompt = (
337324 "Enter a number to select a .bakfile, or:\n (D)iff (L)ist (C)ancel" ,
338325 "C" ))
339- # "View which .bakfile? (#)",
340- # "c"))
326+ # "View which .bakfile? (#)",
327+ # "c"))
341328 if _bak_to_print == None :
342329 console .print (
343330 f"No bakfiles found for { os .path .abspath (bak_to_print )} " )
@@ -363,18 +350,18 @@ def bak_getfile_cmd(bak_to_get: (str, bakfile.BakFile)):
363350 print (bak_to_get .bakfile_loc )
364351
365352
366- def bak_diff_cmd (filename : str , command = 'diff' ):
353+ def bak_diff_cmd (filename : ( bakfile . BakFile , Path ) , command = 'diff' ):
367354 # TODO write tests for this (mildly tricky)
368355 console = Console ()
369356
370357 bak_to_diff = filename if isinstance (filename , bakfile .BakFile ) else \
371- _get_bakfile_entry (expandpath ( filename ),
358+ _get_bakfile_entry (filename . resolve ( ),
372359 select_prompt = (
373360 ("Enter a number to diff a .bakfile, or:\n (V)iew (L)ist (C)ancel" , "C" )))
374361 if not command :
375362 command = cfg ['bak_diff_exec' ] or 'diff'
376- if bak_to_diff == None :
377- console .print (f"No bakfiles found for { os . path . abspath ( filename )} " )
363+ if bak_to_diff is None :
364+ console .print (f"No bakfiles found for { filename . resolve ( )} " )
378365 return
379366 if not bak_to_diff :
380367 return
0 commit comments