33import socket
44import sqlite3
55from datetime import date , datetime , timedelta
6- from os . path import normpath , split
6+ from pathlib import Path , PosixPath
77from uuid import uuid4
88
99import icalendar
2323
2424
2525def 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 ()))
2630 sqlite3 .register_converter (
2731 'timestamp' ,
2832 lambda d : datetime .fromtimestamp (float (d ), LOCAL_TIMEZONE )
@@ -242,7 +246,7 @@ def complete(self):
242246
243247 @cached_property
244248 def path (self ):
245- return os . path . join ( self .list .path , self .filename )
249+ return self .list .path . joinpath ( self .filename )
246250
247251 def cancel (self ):
248252 self .status = 'CANCELLED'
@@ -340,7 +344,7 @@ def _read(self, path):
340344 return component
341345
342346 def write (self ):
343- if os . path . exists ( self .todo .path ):
347+ if self .todo .path . exists ( ):
344348 self ._write_existing (self .todo .path )
345349 else :
346350 self ._write_new (self .todo .path )
@@ -390,8 +394,10 @@ class Cache:
390394 SCHEMA_VERSION = 5
391395
392396 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 )
395401
396402 self ._conn = sqlite3 .connect (
397403 str (self .cache_path ),
@@ -438,7 +444,7 @@ def create_tables(self):
438444 '''
439445 CREATE TABLE IF NOT EXISTS lists (
440446 "name" TEXT PRIMARY KEY,
441- "path" TEXT ,
447+ "path" path ,
442448 "colour" TEXT,
443449 CONSTRAINT path_unique UNIQUE (path)
444450 );
@@ -448,7 +454,7 @@ def create_tables(self):
448454 self ._conn .execute (
449455 '''
450456 CREATE TABLE IF NOT EXISTS files (
451- "path" TEXT PRIMARY KEY,
457+ "path" path PRIMARY KEY,
452458 "list_name" TEXT,
453459 "mtime" INTEGER,
454460
@@ -461,7 +467,7 @@ def create_tables(self):
461467 self ._conn .execute (
462468 '''
463469 CREATE TABLE IF NOT EXISTS todos (
464- "file_path" TEXT ,
470+ "file_path" path ,
465471
466472 "id" INTEGER PRIMARY KEY,
467473 "uid" TEXT,
@@ -488,7 +494,7 @@ def create_tables(self):
488494
489495 def clear (self ):
490496 self ._conn .close ()
491- os . remove ( self .cache_path )
497+ self .cache_path . unlink
492498 self ._conn = None
493499
494500 def add_list (self , name , path , colour ):
@@ -684,7 +690,7 @@ def todos(
684690 params .extend (s .upper () for s in status )
685691
686692 if lists :
687- lists = [l . name if isinstance ( l , List ) else l for l in lists ]
693+ lists = [str ( l ) for l in lists ]
688694 q = ', ' .join (['?' ] * len (lists ))
689695 extra_where .append ('AND files.list_name IN ({})' .format (q ))
690696 params .extend (lists )
@@ -789,7 +795,7 @@ def _todo_from_db(self, row):
789795 todo .sequence = row ['sequence' ]
790796 todo .last_modified = row ['last_modified' ]
791797 todo .list = self .lists_map [row ['list_name' ]]
792- todo .filename = os . path . basename ( row ['path' ])
798+ todo .filename = row ['path' ]. name
793799 todo .rrule = row ['rrule' ]
794800 return todo
795801
@@ -864,18 +870,16 @@ def __init__(self, name, path, colour=None):
864870 @staticmethod
865871 def colour_for_path (path ):
866872 try :
867- with open (os .path .join (path , 'color' )) as f :
868- return f .read ().strip ()
873+ return path .joinpath ('color' ).read_text ().strip ()
869874 except (OSError , IOError ):
870875 logger .debug ('No colour for list %s' , path )
871876
872877 @staticmethod
873878 def name_for_path (path ):
874879 try :
875- with open (os .path .join (path , 'displayname' )) as f :
876- return f .read ().strip ()
880+ return path .joinpath ('displayname' ).read_text ().strip ()
877881 except (OSError , IOError ):
878- return split ( normpath ( path ))[ 1 ]
882+ return path . name
879883
880884 def __eq__ (self , other ):
881885 if isinstance (other , List ):
@@ -896,8 +900,8 @@ class Database:
896900 """
897901
898902 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 ]
901905 self .update_cache ()
902906
903907 def update_cache (self ):
@@ -912,13 +916,11 @@ def update_cache(self):
912916 path ,
913917 List .colour_for_path (path ),
914918 )
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' ):
917921 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
922924
923925 self .cache .expire_files (paths_to_mtime )
924926
@@ -932,11 +934,10 @@ def update_cache(self):
932934 continue
933935
934936 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 )
940941 except Exception as e :
941942 logger .exception ("Failed to read entry %s." , entry_path )
942943
@@ -953,14 +954,13 @@ def lists(self):
953954
954955 def move (self , todo , new_list , from_list = None ):
955956 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 )
958959
959- os .rename (orig_path , dest_path )
960+ orig_path .rename (dest_path )
960961
961962 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 ()
964964
965965 def flush (self ):
966966 for todo in self .todos (status = ['ANY' ]):
@@ -989,5 +989,5 @@ def save(self, todo):
989989
990990
991991def _getmtime (path ):
992- stat = os .stat (path )
992+ stat = path .stat ()
993993 return getattr (stat , 'st_mtime_ns' , stat .st_mtime )
0 commit comments