3
3
import socket
4
4
import sqlite3
5
5
from datetime import date , datetime , timedelta
6
- from os . path import normpath , split
6
+ from pathlib import Path , PosixPath
7
7
from uuid import uuid4
8
8
9
9
import icalendar
23
23
24
24
25
25
def register_adapters_and_converters ():
26
+ sqlite3 .register_adapter (Path , str )
27
+ sqlite3 .register_adapter (PosixPath , str )
28
+
29
+ sqlite3 .register_converter ('path' , lambda p : Path (p .decode ()))
26
30
sqlite3 .register_converter (
27
31
'timestamp' ,
28
32
lambda d : datetime .fromtimestamp (float (d ), LOCAL_TIMEZONE )
@@ -242,7 +246,7 @@ def complete(self):
242
246
243
247
@cached_property
244
248
def path (self ):
245
- return os . path . join ( self .list .path , self .filename )
249
+ return self .list .path . joinpath ( self .filename )
246
250
247
251
def cancel (self ):
248
252
self .status = 'CANCELLED'
@@ -340,7 +344,7 @@ def _read(self, path):
340
344
return component
341
345
342
346
def write (self ):
343
- if os . path . exists ( self .todo .path ):
347
+ if self .todo .path . exists ( ):
344
348
self ._write_existing (self .todo .path )
345
349
else :
346
350
self ._write_new (self .todo .path )
@@ -390,8 +394,10 @@ class Cache:
390
394
SCHEMA_VERSION = 5
391
395
392
396
def __init__ (self , path ):
393
- self .cache_path = str (path )
394
- os .makedirs (os .path .dirname (self .cache_path ), exist_ok = True )
397
+ self .cache_path = path
398
+ # XXX: Use the below once we drop python3.4
399
+ # self.cache_path.parent.mkdir(parents=True, exist_ok=True)
400
+ os .makedirs (self .cache_path .parent , exist_ok = True )
395
401
396
402
self ._conn = sqlite3 .connect (
397
403
str (self .cache_path ),
@@ -438,7 +444,7 @@ def create_tables(self):
438
444
'''
439
445
CREATE TABLE IF NOT EXISTS lists (
440
446
"name" TEXT PRIMARY KEY,
441
- "path" TEXT ,
447
+ "path" path ,
442
448
"colour" TEXT,
443
449
CONSTRAINT path_unique UNIQUE (path)
444
450
);
@@ -448,7 +454,7 @@ def create_tables(self):
448
454
self ._conn .execute (
449
455
'''
450
456
CREATE TABLE IF NOT EXISTS files (
451
- "path" TEXT PRIMARY KEY,
457
+ "path" path PRIMARY KEY,
452
458
"list_name" TEXT,
453
459
"mtime" INTEGER,
454
460
@@ -461,7 +467,7 @@ def create_tables(self):
461
467
self ._conn .execute (
462
468
'''
463
469
CREATE TABLE IF NOT EXISTS todos (
464
- "file_path" TEXT ,
470
+ "file_path" path ,
465
471
466
472
"id" INTEGER PRIMARY KEY,
467
473
"uid" TEXT,
@@ -488,7 +494,7 @@ def create_tables(self):
488
494
489
495
def clear (self ):
490
496
self ._conn .close ()
491
- os . remove ( self .cache_path )
497
+ self .cache_path . unlink
492
498
self ._conn = None
493
499
494
500
def add_list (self , name , path , colour ):
@@ -684,7 +690,7 @@ def todos(
684
690
params .extend (s .upper () for s in status )
685
691
686
692
if lists :
687
- lists = [l . name if isinstance ( l , List ) else l for l in lists ]
693
+ lists = [str ( l ) for l in lists ]
688
694
q = ', ' .join (['?' ] * len (lists ))
689
695
extra_where .append ('AND files.list_name IN ({})' .format (q ))
690
696
params .extend (lists )
@@ -789,7 +795,7 @@ def _todo_from_db(self, row):
789
795
todo .sequence = row ['sequence' ]
790
796
todo .last_modified = row ['last_modified' ]
791
797
todo .list = self .lists_map [row ['list_name' ]]
792
- todo .filename = os . path . basename ( row ['path' ])
798
+ todo .filename = row ['path' ]. name
793
799
todo .rrule = row ['rrule' ]
794
800
return todo
795
801
@@ -864,18 +870,16 @@ def __init__(self, name, path, colour=None):
864
870
@staticmethod
865
871
def colour_for_path (path ):
866
872
try :
867
- with open (os .path .join (path , 'color' )) as f :
868
- return f .read ().strip ()
873
+ return path .joinpath ('color' ).read_text ().strip ()
869
874
except (OSError , IOError ):
870
875
logger .debug ('No colour for list %s' , path )
871
876
872
877
@staticmethod
873
878
def name_for_path (path ):
874
879
try :
875
- with open (os .path .join (path , 'displayname' )) as f :
876
- return f .read ().strip ()
880
+ return path .joinpath ('displayname' ).read_text ().strip ()
877
881
except (OSError , IOError ):
878
- return split ( normpath ( path ))[ 1 ]
882
+ return path . name
879
883
880
884
def __eq__ (self , other ):
881
885
if isinstance (other , List ):
@@ -896,8 +900,8 @@ class Database:
896
900
"""
897
901
898
902
def __init__ (self , paths , cache_path ):
899
- self .cache = Cache (cache_path )
900
- self .paths = [str (path ) for path in paths ]
903
+ self .cache = Cache (Path ( cache_path ) )
904
+ self .paths = [Path (path ) for path in paths ]
901
905
self .update_cache ()
902
906
903
907
def update_cache (self ):
@@ -912,13 +916,11 @@ def update_cache(self):
912
916
path ,
913
917
List .colour_for_path (path ),
914
918
)
915
- for entry in os . listdir ( path ):
916
- if not entry .endswith ('.ics' ):
919
+ for entry in path . iterdir ( ):
920
+ if not entry .name . endswith ('.ics' ):
917
921
continue
918
- entry_path = os .path .join (path , entry )
919
- mtime = _getmtime (entry_path )
920
- paths_to_mtime [entry_path ] = mtime
921
- paths_to_list_name [entry_path ] = list_name
922
+ paths_to_mtime [entry ] = _getmtime (entry )
923
+ paths_to_list_name [entry ] = list_name
922
924
923
925
self .cache .expire_files (paths_to_mtime )
924
926
@@ -932,11 +934,10 @@ def update_cache(self):
932
934
continue
933
935
934
936
try :
935
- with open (entry_path , 'rb' ) as f :
936
- cal = f .read ()
937
- cal = icalendar .Calendar .from_ical (cal )
938
- for component in cal .walk ('VTODO' ):
939
- self .cache .add_vtodo (component , entry_path )
937
+ data = entry_path .read_bytes ()
938
+ cal = icalendar .Calendar .from_ical (data )
939
+ for component in cal .walk ('VTODO' ):
940
+ self .cache .add_vtodo (component , entry_path )
940
941
except Exception as e :
941
942
logger .exception ("Failed to read entry %s." , entry_path )
942
943
@@ -953,14 +954,13 @@ def lists(self):
953
954
954
955
def move (self , todo , new_list , from_list = None ):
955
956
from_list = from_list or todo .list
956
- orig_path = os .path .join ( from_list . path , todo .filename )
957
- dest_path = os .path .join ( new_list . path , todo .filename )
957
+ orig_path = from_list .path .joinpath ( todo .filename )
958
+ dest_path = new_list .path .joinpath ( todo .filename )
958
959
959
- os .rename (orig_path , dest_path )
960
+ orig_path .rename (dest_path )
960
961
961
962
def delete (self , todo ):
962
- path = os .path .join (todo .list .path , todo .filename )
963
- os .remove (path )
963
+ todo .list .path .joinpath (todo .filename ).unlink ()
964
964
965
965
def flush (self ):
966
966
for todo in self .todos (status = ['ANY' ]):
@@ -989,5 +989,5 @@ def save(self, todo):
989
989
990
990
991
991
def _getmtime (path ):
992
- stat = os .stat (path )
992
+ stat = path .stat ()
993
993
return getattr (stat , 'st_mtime_ns' , stat .st_mtime )
0 commit comments