|  | @@ -59,6 +59,14 @@ class DataBase:
 | 
											
												
													
														|  |  			(fileName, _date, _size, comment, time.time()))
 |  |  			(fileName, _date, _size, comment, time.time()))
 | 
											
												
													
														|  |  		self.db.commit()
 |  |  		self.db.commit()
 | 
											
												
													
														|  |  		return True
 |  |  		return True
 | 
											
												
													
														|  | 
 |  | +	def log(self, fileName, comment):
 | 
											
												
													
														|  | 
 |  | +		''' TODO: convert filename to canonical '''
 | 
											
												
													
														|  | 
 |  | +		c = self.db.cursor()
 | 
											
												
													
														|  | 
 |  | +		s = os.stat(fileName)
 | 
											
												
													
														|  | 
 |  | +		print "params: %s %f %d %s %f" % ((os.path.abspath(fileName), s.st_mtime, s.st_size, comment, time.time()))
 | 
											
												
													
														|  | 
 |  | +		c.execute("insert into dirnotes values (?,?,?,?,?)",
 | 
											
												
													
														|  | 
 |  | +			(fileName, s.st_mtime, s.st_size, str(comment), time.time()))
 | 
											
												
													
														|  | 
 |  | +		self.db.commit()
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  def parse():
 |  |  def parse():
 | 
											
												
													
														|  |  	parser = argparse.ArgumentParser(description='dirnotes application')
 |  |  	parser = argparse.ArgumentParser(description='dirnotes application')
 | 
											
										
											
												
													
														|  | @@ -73,20 +81,16 @@ def parse():
 | 
											
												
													
														|  |  	group.add_argument('-m','--sort-by-date',metavar='sort',action='store_const',const='d')
 |  |  	group.add_argument('-m','--sort-by-date',metavar='sort',action='store_const',const='d')
 | 
											
												
													
														|  |  	return parser.parse_args()
 |  |  	return parser.parse_args()
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -def debug(x):
 |  | 
 | 
											
												
													
														|  | -	print("debugging " + x.text() + " r:" + str(x.row()) + " c:" + str(x.column()))
 |  | 
 | 
											
												
													
														|  | -	the_file = dn.files[x.row()]
 |  | 
 | 
											
												
													
														|  | -	the_file.setComment(str(x.text())) 
 |  | 
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  class FileObj():
 |  |  class FileObj():
 | 
											
												
													
														|  |  	def __init__(self, fileName):
 |  |  	def __init__(self, fileName):
 | 
											
												
													
														|  |  		self.fileName = fileName
 |  |  		self.fileName = fileName
 | 
											
												
													
														|  |  		# also get the date, directory or not, etc
 |  |  		# also get the date, directory or not, etc
 | 
											
												
													
														|  | -		self.directory = "a"
 |  | 
 | 
											
												
													
														|  |  		self.comment = ''
 |  |  		self.comment = ''
 | 
											
												
													
														|  |  		try:
 |  |  		try:
 | 
											
												
													
														|  |  			self.comment = xattr.getxattr(fileName,COMMENT_KEY)
 |  |  			self.comment = xattr.getxattr(fileName,COMMENT_KEY)
 | 
											
												
													
														|  | -		except:
 |  | 
 | 
											
												
													
														|  | 
 |  | +		except Exception as e:
 | 
											
												
													
														|  | 
 |  | +			print("comment read on %s failed, execption %s" % (self.fileName,e)) 
 | 
											
												
													
														|  |  			pass
 |  |  			pass
 | 
											
												
													
														|  |  	def getName(self):
 |  |  	def getName(self):
 | 
											
												
													
														|  |  		return self.fileName
 |  |  		return self.fileName
 | 
											
										
											
												
													
														|  | @@ -96,18 +100,35 @@ class FileObj():
 | 
											
												
													
														|  |  		self.comment = newComment
 |  |  		self.comment = newComment
 | 
											
												
													
														|  |  		try:
 |  |  		try:
 | 
											
												
													
														|  |  			xattr.setxattr(self.fileName,COMMENT_KEY,self.comment)
 |  |  			xattr.setxattr(self.fileName,COMMENT_KEY,self.comment)
 | 
											
												
													
														|  | -		except:
 |  | 
 | 
											
												
													
														|  | -			print("problem setting the comment on file %s" % self.fileName)
 |  | 
 | 
											
												
													
														|  | 
 |  | +			return True
 | 
											
												
													
														|  | 
 |  | +		# we need to move these cases out to a handler 
 | 
											
												
													
														|  | 
 |  | +		except Exception as e:
 | 
											
												
													
														|  | 
 |  | +			print("problem setting the comment on file %s" % (self.fileName,))
 | 
											
												
													
														|  | 
 |  | +			if os.access(self.fileName, os.W_OK)!=True:
 | 
											
												
													
														|  | 
 |  | +				print("you don't appear to have write permissions on this file")
 | 
											
												
													
														|  | 
 |  | +				# change the listbox background to yellow
 | 
											
												
													
														|  | 
 |  | +				self.displayBox.notifyUnchanged()				
 | 
											
												
													
														|  | 
 |  | +			elif "Errno 95" in str(e):
 | 
											
												
													
														|  | 
 |  | +				print("is this a VFAT or EXFAT volume? these don't allow comments")
 | 
											
												
													
														|  | 
 |  | +			return False
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  class DirNotes(QMainWindow):
 |  |  class DirNotes(QMainWindow):
 | 
											
												
													
														|  | -	def __init__(self, filename, parent=None):
 |  | 
 | 
											
												
													
														|  | 
 |  | +	''' the main window of the app
 | 
											
												
													
														|  | 
 |  | +		has 3 list boxes: dir_left, dir_right (may be invisible) and files
 | 
											
												
													
														|  | 
 |  | +		
 | 
											
												
													
														|  | 
 |  | +		'''
 | 
											
												
													
														|  | 
 |  | +	def __init__(self, filename, db, parent=None):
 | 
											
												
													
														|  |  		super(DirNotes,self).__init__(parent)
 |  |  		super(DirNotes,self).__init__(parent)
 | 
											
												
													
														|  |  		win = QWidget()
 |  |  		win = QWidget()
 | 
											
												
													
														|  |  		self.setCentralWidget(win)
 |  |  		self.setCentralWidget(win)
 | 
											
												
													
														|  | 
 |  | +		self.db = db
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  		lb = QTableWidget()
 |  |  		lb = QTableWidget()
 | 
											
												
													
														|  |  		lb.setColumnCount(2)
 |  |  		lb.setColumnCount(2)
 | 
											
												
													
														|  |  		lb.horizontalHeader().setResizeMode( 1, QHeaderView.Stretch );
 |  |  		lb.horizontalHeader().setResizeMode( 1, QHeaderView.Stretch );
 | 
											
												
													
														|  | 
 |  | +		lb.verticalHeader().setDefaultSectionSize(20);	# thinner rows
 | 
											
												
													
														|  | 
 |  | +		lb.verticalHeader().setVisible(False)
 | 
											
												
													
														|  | 
 |  | +		
 | 
											
												
													
														|  |  		# resize the comments column
 |  |  		# resize the comments column
 | 
											
												
													
														|  |  		# and resize the parent window to match the directory size
 |  |  		# and resize the parent window to match the directory size
 | 
											
												
													
														|  |  
 |  |  
 | 
											
										
											
												
													
														|  | @@ -124,7 +145,7 @@ class DirNotes(QMainWindow):
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  		self.files = []
 |  |  		self.files = []
 | 
											
												
													
														|  |  		for i in range(len(d)):
 |  |  		for i in range(len(d)):
 | 
											
												
													
														|  | -			this_file = FileObj(d[i])
 |  | 
 | 
											
												
													
														|  | 
 |  | +			this_file = FileObj(current+'/'+d[i])
 | 
											
												
													
														|  |  			self.files = self.files + [this_file]
 |  |  			self.files = self.files + [this_file]
 | 
											
												
													
														|  |  			item = QTableWidgetItem(this_file.getName())
 |  |  			item = QTableWidgetItem(this_file.getName())
 | 
											
												
													
														|  |  			item.setFlags(QtCore.Qt.ItemIsEnabled)
 |  |  			item.setFlags(QtCore.Qt.ItemIsEnabled)
 | 
											
										
											
												
													
														|  | @@ -135,7 +156,6 @@ class DirNotes(QMainWindow):
 | 
											
												
													
														|  |  		lb.setHorizontalHeaderItem(0,QTableWidgetItem("file"))
 |  |  		lb.setHorizontalHeaderItem(0,QTableWidgetItem("file"))
 | 
											
												
													
														|  |  		lb.setHorizontalHeaderItem(1,QTableWidgetItem("comment"))
 |  |  		lb.setHorizontalHeaderItem(1,QTableWidgetItem("comment"))
 | 
											
												
													
														|  |  		lb.resizeColumnsToContents()
 |  |  		lb.resizeColumnsToContents()
 | 
											
												
													
														|  | -		lb.verticalHeader().setVisible(False)
 |  | 
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  		e = QLabel("View and edit file comments stored in extended attributes user.xdg.comment")
 |  |  		e = QLabel("View and edit file comments stored in extended attributes user.xdg.comment")
 | 
											
												
													
														|  |  
 |  |  
 | 
											
										
											
												
													
														|  | @@ -144,7 +164,7 @@ class DirNotes(QMainWindow):
 | 
											
												
													
														|  |  		layout.addWidget(lb)
 |  |  		layout.addWidget(lb)
 | 
											
												
													
														|  |  		win.setLayout(layout)
 |  |  		win.setLayout(layout)
 | 
											
												
													
														|  |  		
 |  |  		
 | 
											
												
													
														|  | -		lb.itemChanged.connect(debug)
 |  | 
 | 
											
												
													
														|  | 
 |  | +		lb.itemChanged.connect(self.change)
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  		QShortcut(QKeySequence("Ctrl+Q"), self, self.close)	
 |  |  		QShortcut(QKeySequence("Ctrl+Q"), self, self.close)	
 | 
											
												
													
														|  |  		self.setWindowTitle("test")
 |  |  		self.setWindowTitle("test")
 | 
											
										
											
												
													
														|  | @@ -152,17 +172,25 @@ class DirNotes(QMainWindow):
 | 
											
												
													
														|  |  	def closeEvent(self,e):
 |  |  	def closeEvent(self,e):
 | 
											
												
													
														|  |  		print("closing")
 |  |  		print("closing")
 | 
											
												
													
														|  |  		
 |  |  		
 | 
											
												
													
														|  | 
 |  | +	def change(self,x):
 | 
											
												
													
														|  | 
 |  | +		print("debugging " + x.text() + " r:" + str(x.row()) + " c:" + str(x.column()))
 | 
											
												
													
														|  | 
 |  | +		the_file = dn.files[x.row()]
 | 
											
												
													
														|  | 
 |  | +		r = the_file.setComment(str(x.text())) 
 | 
											
												
													
														|  | 
 |  | +		if r:
 | 
											
												
													
														|  | 
 |  | +			self.db.log(the_file.getName(),x.text())
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +		
 | 
											
												
													
														|  |  if __name__=="__main__":
 |  |  if __name__=="__main__":
 | 
											
												
													
														|  |  	p = parse()
 |  |  	p = parse()
 | 
											
												
													
														|  | 
 |  | +	if p.dirname[-1]=='/':
 | 
											
												
													
														|  | 
 |  | +		p.dirname = p.dirname[:-1]
 | 
											
												
													
														|  | 
 |  | +	print(dir(p))
 | 
											
												
													
														|  | 
 |  | +	print(p.dirname)
 | 
											
												
													
														|  |  	
 |  |  	
 | 
											
												
													
														|  |  	db = DataBase()
 |  |  	db = DataBase()
 | 
											
												
													
														|  | -	db.setData("a",float(time.time()),1244445,"a comment")
 |  | 
 | 
											
												
													
														|  | -	print(db.getData("a"))
 |  | 
 | 
											
												
													
														|  | -	(f,d,s,c,cd) = db.getData("a")
 |  | 
 | 
											
												
													
														|  | -	print(time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(d)))
 |  | 
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  	a = QApplication([])
 |  |  	a = QApplication([])
 | 
											
												
													
														|  | -	dn = DirNotes(p.dirname[0])
 |  | 
 | 
											
												
													
														|  | 
 |  | +	dn = DirNotes(p.dirname,db)
 | 
											
												
													
														|  |  	dn.show()
 |  |  	dn.show()
 | 
											
												
													
														|  |  	
 |  |  	
 | 
											
												
													
														|  |  	a.exec_()
 |  |  	a.exec_()
 | 
											
										
											
												
													
														|  | @@ -175,3 +203,27 @@ use os.isfile()
 | 
											
												
													
														|  |  os.isdir()
 |  |  os.isdir()
 | 
											
												
													
														|  |  current, dirs, files = os.walk("path").next()
 |  |  current, dirs, files = os.walk("path").next()
 | 
											
												
													
														|  |  possible set folllowLinks=True'''
 |  |  possible set folllowLinks=True'''
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +''' notes from the wdrm project
 | 
											
												
													
														|  | 
 |  | +table showed 
 | 
											
												
													
														|  | 
 |  | +filename, size, date size, date, desc
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +at start, fills the list of all the files
 | 
											
												
													
														|  | 
 |  | +skip the . entry
 | 
											
												
													
														|  | 
 |  | +'''
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +''' should we also do user.xdg.tags="TagA,TagB" ?
 | 
											
												
													
														|  | 
 |  | +user.charset
 | 
											
												
													
														|  | 
 |  | +user.creator=application_name or user.xdg.creator
 | 
											
												
													
														|  | 
 |  | +user.xdg.origin.url
 | 
											
												
													
														|  | 
 |  | +user.xdg.language=[RFC3066/ISO639]
 | 
											
												
													
														|  | 
 |  | +user.xdg.publisher
 | 
											
												
													
														|  | 
 |  | +'''
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +''' to allow column-sorting, you use the sortByColumn and set the Horiz-header to clickable
 | 
											
												
													
														|  | 
 |  | +'''
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +''' TODO: also need a way to display-&-restore comments from the database '''
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +
 |