| 
														
															@@ -1,4 +1,9 @@ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 #!/usr/bin/python3 
														 | 
														
														 | 
														
															 #!/usr/bin/python3 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+# TODO: get rid of sqlite cursors; execute on connection 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+# TODO: add index to table creation 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+# TODO: why are there TWO sqlite.connect()?? 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+#   try auto-commit (isolation_level = "IMMEDIATE") 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+#   try dict-parameters in sql statements 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 # TODO: pick up comment for cwd and display at the top somewhere, or maybe status line 
														 | 
														
														 | 
														
															 # TODO: pick up comment for cwd and display at the top somewhere, or maybe status line 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 """ a simple gui or command line app 
														 | 
														
														 | 
														
															 """ a simple gui or command line app 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 to view and create/edit file comments 
														 | 
														
														 | 
														
															 to view and create/edit file comments 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -18,7 +23,7 @@ nav tools are enabled, so you can double-click to go into a dir 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 """ 
														 | 
														
														 | 
														
															 """ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															-VERSION = "0.4" 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+VERSION = "0.5" 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 helpMsg = f"""<table width=100%><tr><td><h1>Dirnotes</h1><td> 
														 | 
														
														 | 
														
															 helpMsg = f"""<table width=100%><tr><td><h1>Dirnotes</h1><td> 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 <td align=right>Version: {VERSION}</td></tr></table> 
														 | 
														
														 | 
														
															 <td align=right>Version: {VERSION}</td></tr></table> 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -52,8 +57,7 @@ media (as long as the disk format allows it). 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 the comment box gets a light yellow background. 
														 | 
														
														 | 
														
															 the comment box gets a light yellow background. 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 """ 
														 | 
														
														 | 
														
															 """ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															-import sys,os,argparse,stat,getpass 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-#~ from dirWidget import DirWidget 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+import sys,os,argparse,stat,getpass,shutil 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 from PyQt5.QtGui import * 
														 | 
														
														 | 
														
															 from PyQt5.QtGui import * 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 from PyQt5.QtWidgets import * 
														 | 
														
														 | 
														
															 from PyQt5.QtWidgets import * 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 from PyQt5.QtCore import Qt, pyqtSignal 
														 | 
														
														 | 
														
															 from PyQt5.QtCore import Qt, pyqtSignal 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -108,30 +112,16 @@ class dnDataBase: 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     except sqlite3.OperationalError: 
														 | 
														
														 | 
														
															     except sqlite3.OperationalError: 
														 | 
													
												
											
												
													
														| 
														 | 
														
															       print(f"Database {dbFile} not found") 
														 | 
														
														 | 
														
															       print(f"Database {dbFile} not found") 
														 | 
													
												
											
												
													
														| 
														 | 
														
															       raise 
														 | 
														
														 | 
														
															       raise 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    self.db_cursor = self.db.cursor() 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     try: 
														 | 
														
														 | 
														
															     try: 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-      self.db_cursor.execute("select * from dirnotes") 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+      self.db.execute("select * from dirnotes") 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     except sqlite3.OperationalError: 
														 | 
														
														 | 
														
															     except sqlite3.OperationalError: 
														 | 
													
												
											
												
													
														| 
														 | 
														
															       print_v("Table %s created" % ("dirnotes")) 
														 | 
														
														 | 
														
															       print_v("Table %s created" % ("dirnotes")) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-      self.db_cursor.execute("create table dirnotes (name TEXT, date DATETIME, size INTEGER, comment TEXT, comment_date DATETIME, author TEXT)") 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-     
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+      self.db.execute("create table dirnotes (name TEXT, date DATETIME, size INTEGER, comment TEXT, comment_date DATETIME, author TEXT)") 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+      self.db_cursor.execute("create index dirnotes_i on dirnotes(name)")  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  # getData is only used by the restore-from-database.......consider deleting it 
														 | 
													
												
											
												
													
														| 
														 | 
														
															   def getData(self, fileName): 
														 | 
														
														 | 
														
															   def getData(self, fileName): 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    self.db_cursor.execute("select * from dirnotes where name=? and comment<>'' order by comment_date desc",(os.path.abspath(fileName),)) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    return self.db_cursor.fetchone() 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-  def setData(self, fileName, comment): 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    s = os.lstat(fileName) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    print_v ("params: %s %s %d %s %s" % ((os.path.abspath(fileName),  
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        dnDataBase.epochToDb(s.st_mtime), s.st_size, comment,  
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        dnDataBase.epochToDb(time.time())))) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    try: 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-      self.db_cursor.execute("insert into dirnotes values (?,datetime(?,'unixepoch','localtime'),?,?,datetime(?,'unixepoch','localtime'),?)", 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        (os.path.abspath(fileName), s.st_mtime, s.st_size, str(comment), time.time(), getpass.getuser())) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-      self.db.commit() 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    except sqlite3.OperationalError: 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-      print("database is locked or unwriteable") 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-      errorBox("database is locked or unwriteable") 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-      #TODO: put up a message box for locked database 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															- 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    c = self.db.execute("select * from dirnotes where name=? and comment<>'' order by comment_date desc",(os.path.abspath(fileName),)) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    return c.fetchone() 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															   @staticmethod 
														 | 
														
														 | 
														
															   @staticmethod 
														 | 
													
												
											
												
													
														| 
														 | 
														
															   def epochToDb(epoch): 
														 | 
														
														 | 
														
															   def epochToDb(epoch): 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -157,13 +147,14 @@ class FileObj(): 
														 | 
													
												
											
												
													
														| 
														 | 
														
															   FILE_IS_LINK   = -2 
														 | 
														
														 | 
														
															   FILE_IS_LINK   = -2 
														 | 
													
												
											
												
													
														| 
														 | 
														
															   FILE_IS_SOCKET = -3 
														 | 
														
														 | 
														
															   FILE_IS_SOCKET = -3 
														 | 
													
												
											
												
													
														| 
														 | 
														
															   def __init__(self, fileName): 
														 | 
														
														 | 
														
															   def __init__(self, fileName): 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    self.fileName = os.path.abspath(fileName) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    self.displayName = os.path.split(fileName)[1] 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    self.fileName = os.path.abspath(fileName) # full path; dirs end WITHOUT a terminal / 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    self.displayName = os.path.split(fileName)[1]   # base name; dirs end with a / 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     s = os.lstat(self.fileName) 
														 | 
														
														 | 
														
															     s = os.lstat(self.fileName) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     self.date = s.st_mtime 
														 | 
														
														 | 
														
															     self.date = s.st_mtime 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     if stat.S_ISDIR(s.st_mode): 
														 | 
														
														 | 
														
															     if stat.S_ISDIR(s.st_mode): 
														 | 
													
												
											
												
													
														| 
														 | 
														
															       self.size = FileObj.FILE_IS_DIR 
														 | 
														
														 | 
														
															       self.size = FileObj.FILE_IS_DIR 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-      self.displayName += '/' 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+      if not self.displayName.endswith('/'): 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        self.displayName += '/' 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     elif stat.S_ISLNK(s.st_mode): 
														 | 
														
														 | 
														
															     elif stat.S_ISLNK(s.st_mode): 
														 | 
													
												
											
												
													
														| 
														 | 
														
															       self.size = FileObj.FILE_IS_LINK 
														 | 
														
														 | 
														
															       self.size = FileObj.FILE_IS_LINK 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     elif stat.S_ISSOCK(s.st_mode): 
														 | 
														
														 | 
														
															     elif stat.S_ISSOCK(s.st_mode): 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -187,13 +178,13 @@ class FileObj(): 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															   def getName(self): 
														 | 
														
														 | 
														
															   def getName(self): 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     return self.fileName 
														 | 
														
														 | 
														
															     return self.fileName 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-  def getFileName(self): 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  def getDisplayName(self): 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     return self.displayName 
														 | 
														
														 | 
														
															     return self.displayName 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															   # with an already open database cursor 
														 | 
														
														 | 
														
															   # with an already open database cursor 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-  def loadDbComment(self,cursor): 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    cursor.execute("select comment,author,comment_date from dirnotes where name=? and comment<>'' order by comment_date desc",(self.fileName,)) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    a = cursor.fetchone() 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  def loadDbComment(self,db): 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    c = db.execute("select comment,author,comment_date from dirnotes where name=? and comment<>'' order by comment_date desc",(self.fileName,)) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    a = c.fetchone() 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     if a: 
														 | 
														
														 | 
														
															     if a: 
														 | 
													
												
											
												
													
														| 
														 | 
														
															       self.dbComment, self.dbAuthor, self.dbDate = a 
														 | 
														
														 | 
														
															       self.dbComment, self.dbAuthor, self.dbDate = a 
														 | 
													
												
											
												
													
														| 
														 | 
														
															       self.commentsDiffer = True if self.xattrComment == self.dbComment else False 
														 | 
														
														 | 
														
															       self.commentsDiffer = True if self.xattrComment == self.dbComment else False 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -204,19 +195,19 @@ class FileObj(): 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     return self.dbAuthor 
														 | 
														
														 | 
														
															     return self.dbAuthor 
														 | 
													
												
											
												
													
														| 
														 | 
														
															   def getDbDate(self): 
														 | 
														
														 | 
														
															   def getDbDate(self): 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     return self.dbDate 
														 | 
														
														 | 
														
															     return self.dbDate 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-  def setDbComment(self,newComment): 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    try: 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-      self.db = sqlite3.connect(dbName) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    except sqlite3.OperationalError: 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-      print_v(f"database {dbName} not found") 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-      raise 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    c = self.db.cursor() 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  def setDbComment(self,db,newComment): 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     s = os.lstat(self.fileName) 
														 | 
														
														 | 
														
															     s = os.lstat(self.fileName) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     try: 
														 | 
														
														 | 
														
															     try: 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-      c.execute("insert into dirnotes (name,date,size,comment,comment_date,author) values (?,datetime(?,'unixepoch','localtime'),?,?,datetime(?,'unixepoch','localtime'),?)", 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-          (os.path.abspath(self.fileName), s.st_mtime, s.st_size, 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+      # TODO: copy from /g/test_file to /home/patb/project/dirnotes/r    fails on database.commit() 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+      print_v(f"setDbComment db {db}, file: {self.fileName}") 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+      print_v("insert into dirnotes (name,date,size,comment,comment_date,author) values (?,datetime(?,'unixepoch','localtime'),?,?,datetime(?,'unixepoch','localtime'),?)", 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+          (self.fileName, s.st_mtime, s.st_size, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															           str(newComment), time.time(), getpass.getuser())) 
														 | 
														
														 | 
														
															           str(newComment), time.time(), getpass.getuser())) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-      self.db.commit() 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+      db.execute("insert into dirnotes (name,date,size,comment,comment_date,author) values (?,datetime(?,'unixepoch','localtime'),?,?,datetime(?,'unixepoch','localtime'),?)", 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+          (self.fileName, s.st_mtime, s.st_size, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+          str(newComment), time.time(), getpass.getuser())) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+      print_v(f"setDbComment, execute done, about to commit()") 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+      db.commit() 
														 | 
													
												
											
												
													
														| 
														 | 
														
															       print_v(f"database write for {self.fileName}") 
														 | 
														
														 | 
														
															       print_v(f"database write for {self.fileName}") 
														 | 
													
												
											
												
													
														| 
														 | 
														
															       self.dbComment = newComment 
														 | 
														
														 | 
														
															       self.dbComment = newComment 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     except sqlite3.OperationalError: 
														 | 
														
														 | 
														
															     except sqlite3.OperationalError: 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -341,47 +332,6 @@ icon = ["32 32 6 1",  # the QPixmap constructor allows for str[] 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 "  ...........................   ", 
														 | 
														
														 | 
														
															 "  ...........................   ", 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 "                                "] 
														 | 
														
														 | 
														
															 "                                "] 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															-''' a widget that shows only a dir listing 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															- ''' 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															- 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-class DirWidget(QListWidget): 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-  ''' a simple widget that shows a list of directories, staring 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-  at the directory passed into the constructor 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															- 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-  a mouse click or 'enter' key will send a 'selected' signal to 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-  anyone who connects to this. 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															- 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-  the .. parent directory is shown for all dirs except / 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															- 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-  the most interesting parts of the interface are: 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-  constructor - send in the directory to view 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-  method - currentPath() returns text of current path 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-  signal - selected calls a slot with a single arg: new path 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-  ''' 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															- 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-  selected = pyqtSignal(str) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-  def __init__(self, directory='.', parent=None): 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    super(DirWidget,self).__init__(parent) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    self.directory = directory 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    self.refill() 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    self.itemActivated.connect(self.selectionByLWI) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    # it would be nice to pick up single-mouse-click for selection as well 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    # but that seems to be a system-preferences global 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-  def selectionByLWI(self, li): 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    self.directory = os.path.abspath(self.directory + '/' + str(li.text())) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    self.refill() 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    self.selected.emit(self.directory) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-  def refill(self): 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    current,dirs,files = next(os.walk(self.directory,followlinks=True)) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    dirs.sort() 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    if '/' not in dirs: 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-      dirs = ['..'] + dirs 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    self.clear() 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    for d in dirs: 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-      li = QListWidgetItem(d,self) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-  def currentPath(self): 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    return self.directory 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-     
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 # sortable TableWidgetItem, based on idea by Aledsandar 
														 | 
														
														 | 
														
															 # sortable TableWidgetItem, based on idea by Aledsandar 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 # http://stackoverflow.com/questions/12673598/python-numerical-sorting-in-qtablewidget 
														 | 
														
														 | 
														
															 # http://stackoverflow.com/questions/12673598/python-numerical-sorting-in-qtablewidget 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -457,7 +407,7 @@ class DirNotes(QMainWindow): 
														 | 
													
												
											
												
													
														| 
														 | 
														
															      
														 | 
														
														 | 
														
															      
														 | 
													
												
											
												
													
														| 
														 | 
														
															     if len(filename)>0: 
														 | 
														
														 | 
														
															     if len(filename)>0: 
														 | 
													
												
											
												
													
														| 
														 | 
														
															       for i in range(lb.rowCount()): 
														 | 
														
														 | 
														
															       for i in range(lb.rowCount()): 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        if filename == lb.item(i,0).data(32).getFileName(): 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        if filename == lb.item(i,0).data(32).getDisplayName(): 
														 | 
													
												
											
												
													
														| 
														 | 
														
															           lb.setCurrentCell(i,3) 
														 | 
														
														 | 
														
															           lb.setCurrentCell(i,3) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															           break 
														 | 
														
														 | 
														
															           break 
														 | 
													
												
											
												
													
														| 
														 | 
														
															      
														 | 
														
														 | 
														
															      
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -509,19 +459,16 @@ class DirNotes(QMainWindow): 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     if not fo.isDir() and not fo.isLink():  # TODO: add check for socket  
														 | 
														
														 | 
														
															     if not fo.isDir() and not fo.isLink():  # TODO: add check for socket  
														 | 
													
												
											
												
													
														| 
														 | 
														
															       print_v(f"copy file {fo.getName()}") 
														 | 
														
														 | 
														
															       print_v(f"copy file {fo.getName()}") 
														 | 
													
												
											
												
													
														| 
														 | 
														
															       # open the dir.picker 
														 | 
														
														 | 
														
															       # open the dir.picker 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-      # TODO: move all this out to a function 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-      qd = QDialog(self.parent) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-      qd.setWindowTitle("Select destination for FileCopy") 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-      qd.setWindowModality(Qt.ApplicationModal) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-      dw = DirWidget('.',qd) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-      d_ok = QPushButton('select') 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-      d_ok.setDefault(True) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-      d_ok.clicked.connect(QDialog.accept) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-      d_nope = QPushButton('cancel') 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-      d_nope.clicked.connect(QDialog.reject) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-      # if returns from <enter>, copy the file and comments 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-      r = qd.exec()  
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+      r = QFileDialog.getExistingDirectory(self.parent, "Select destination for FileCopy") 
														 | 
													
												
											
												
													
														| 
														 | 
														
															       print_v(f"copy to {r}") 
														 | 
														
														 | 
														
															       print_v(f"copy to {r}") 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+      if r: 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        dest = os.path.join(r,fo.getDisplayName()) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        try: 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+          shutil.copy2(fo.getName(), dest) # copy2 preserves the xattr 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+          f = FileObj(dest)       # can't make the FileObj until it exists 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+          f.setDbComment(self.db,fo.getDbComment()) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        except: 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+          errorBox(f"file copy to <{dest}> failed; check permissions") 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     pass 
														 | 
														
														 | 
														
															     pass 
														 | 
													
												
											
												
													
														| 
														 | 
														
															        
														 | 
														
														 | 
														
															        
														 | 
													
												
											
												
													
														| 
														 | 
														
															   def refill(self): 
														 | 
														
														 | 
														
															   def refill(self): 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -550,13 +497,13 @@ class DirNotes(QMainWindow): 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     # this is a list of all the file 
														 | 
														
														 | 
														
															     # this is a list of all the file 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     #~ print("insert {} items into cleared table {}".format(len(d),current)) 
														 | 
														
														 | 
														
															     #~ print("insert {} items into cleared table {}".format(len(d),current)) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     for i,name in enumerate(d): 
														 | 
														
														 | 
														
															     for i,name in enumerate(d): 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-      this_file = FileObj(current+'/'+name) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-      this_file.loadDbComment(self.db.db_cursor) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+      this_file = FileObj(os.path.join(current,name)) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+      this_file.loadDbComment(self.db) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															       print_v("FileObj created as {} and the db-comment is <{}>".format(this_file.displayName, this_file.dbComment)) 
														 | 
														
														 | 
														
															       print_v("FileObj created as {} and the db-comment is <{}>".format(this_file.displayName, this_file.dbComment)) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															       #~ print("insert order check: {} {} {} {}".format(d[i],i,this_file.getName(),this_file.getDate())) 
														 | 
														
														 | 
														
															       #~ print("insert order check: {} {} {} {}".format(d[i],i,this_file.getName(),this_file.getDate())) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															       #~ self.files.update({this_file.getName(),this_file}) 
														 | 
														
														 | 
														
															       #~ self.files.update({this_file.getName(),this_file}) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															       self.files = self.files + [this_file] 
														 | 
														
														 | 
														
															       self.files = self.files + [this_file] 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-      display_name = this_file.getFileName() 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+      display_name = this_file.getDisplayName() 
														 | 
													
												
											
												
													
														| 
														 | 
														
															       if this_file.getSize() == FileObj.FILE_IS_DIR: 
														 | 
														
														 | 
														
															       if this_file.getSize() == FileObj.FILE_IS_DIR: 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         item = SortableTableWidgetItem(display_name,' '+display_name, this_file)  # directories sort first 
														 | 
														
														 | 
														
															         item = SortableTableWidgetItem(display_name,' '+display_name, this_file)  # directories sort first 
														 | 
													
												
											
												
													
														| 
														 | 
														
															       else: 
														 | 
														
														 | 
														
															       else: 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -569,7 +516,7 @@ class DirNotes(QMainWindow): 
														 | 
													
												
											
												
													
														| 
														 | 
														
															       # get the comment from database & xattrs, either can fail 
														 | 
														
														 | 
														
															       # get the comment from database & xattrs, either can fail 
														 | 
													
												
											
												
													
														| 
														 | 
														
															       comment = this_file.getComment() 
														 | 
														
														 | 
														
															       comment = this_file.getComment() 
														 | 
													
												
											
												
													
														| 
														 | 
														
															       other_comment = this_file.getOtherComment() 
														 | 
														
														 | 
														
															       other_comment = this_file.getOtherComment() 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-      ci = QTableWidgetItem(comment) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+      ci = SortableTableWidgetItem(comment,'',this_file) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															       ci.setToolTip(f"comment: {comment}\ncomment date: {this_file.getDbDate()}\nauthor: {this_file.getDbAuthor()}") 
														 | 
														
														 | 
														
															       ci.setToolTip(f"comment: {comment}\ncomment date: {this_file.getDbDate()}\nauthor: {this_file.getDbAuthor()}") 
														 | 
													
												
											
												
													
														| 
														 | 
														
															       if other_comment != comment: 
														 | 
														
														 | 
														
															       if other_comment != comment: 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         ci.setBackground(QBrush(QColor(255,255,160))) 
														 | 
														
														 | 
														
															         ci.setBackground(QBrush(QColor(255,255,160))) 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -607,11 +554,10 @@ class DirNotes(QMainWindow): 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     print_v("      selected file: "+self.lb.item(x.row(),0).file_object.getName()) 
														 | 
														
														 | 
														
															     print_v("      selected file: "+self.lb.item(x.row(),0).file_object.getName()) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     the_file = self.lb.item(x.row(),0).file_object 
														 | 
														
														 | 
														
															     the_file = self.lb.item(x.row(),0).file_object 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     print_v("      and the row file is "+the_file.getName()) 
														 | 
														
														 | 
														
															     print_v("      and the row file is "+the_file.getName()) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    the_file.setDbComment(str(x.text())) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    the_file.setDbComment(self.db,str(x.text())) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     r = the_file.setXattrComment(str(x.text()))  
														 | 
														
														 | 
														
															     r = the_file.setXattrComment(str(x.text()))  
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    # TODO: change this to FileObj.setDbComment() 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     if r: 
														 | 
														
														 | 
														
															     if r: 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-      self.db.setData(the_file.getName(),x.text()) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+      the_file.setDbComment(self.db,x.text()) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															   def switchMode(self): 
														 | 
														
														 | 
														
															   def switchMode(self): 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     global mode 
														 | 
														
														 | 
														
															     global mode 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -686,7 +632,7 @@ if __name__=="__main__": 
														 | 
													
												
											
												
													
														| 
														 | 
														
															    
														 | 
														
														 | 
														
															    
														 | 
													
												
											
												
													
														| 
														 | 
														
															   print_v(f"here is the .json {repr(config)}") 
														 | 
														
														 | 
														
															   print_v(f"here is the .json {repr(config)}") 
														 | 
													
												
											
												
													
														| 
														 | 
														
															   dbName = os.path.expanduser(config["database"]) 
														 | 
														
														 | 
														
															   dbName = os.path.expanduser(config["database"]) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-  db = dnDataBase(dbName) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  db = dnDataBase(dbName).db 
														 | 
													
												
											
												
													
														| 
														 | 
														
															   xattr_comment = config["xattr_tag"] 
														 | 
														
														 | 
														
															   xattr_comment = config["xattr_tag"] 
														 | 
													
												
											
												
													
														| 
														 | 
														
															   xattr_author  = xattr_comment + ".author" 
														 | 
														
														 | 
														
															   xattr_author  = xattr_comment + ".author" 
														 | 
													
												
											
												
													
														| 
														 | 
														
															   xattr_date    = xattr_comment + ".date" 
														 | 
														
														 | 
														
															   xattr_date    = xattr_comment + ".date" 
														 |