|
@@ -5,14 +5,50 @@ to view and create/edit file comments
|
|
comments are stored in xattr user.xdg.comment
|
|
comments are stored in xattr user.xdg.comment
|
|
|
|
|
|
depends on python-pyxattr
|
|
depends on python-pyxattr
|
|
|
|
+
|
|
|
|
+because files are so often over-written, save a copy
|
|
|
|
+of the comments in a database ~/.dirnotes.db
|
|
|
|
+
|
|
|
|
+these comments stick to the symlink
|
|
|
|
+
|
|
"""
|
|
"""
|
|
|
|
|
|
COMMENT_KEY = "user.xdg.comment"
|
|
COMMENT_KEY = "user.xdg.comment"
|
|
|
|
+DATABASE_NAME = "~/.dirnotes.db"
|
|
|
|
|
|
import sys,os,argparse
|
|
import sys,os,argparse
|
|
from PyQt4.QtGui import *
|
|
from PyQt4.QtGui import *
|
|
from PyQt4 import QtGui, QtCore
|
|
from PyQt4 import QtGui, QtCore
|
|
-import xattr
|
|
|
|
|
|
+import xattr, sqlite3, time
|
|
|
|
+
|
|
|
|
+DATABASE_NAME = os.path.expanduser(DATABASE_NAME)
|
|
|
|
+
|
|
|
|
+class DataBase:
|
|
|
|
+ ''' the date here is the st_mtime, a float
|
|
|
|
+ and the filName is a fully qualified name'''
|
|
|
|
+ def __init__(self):
|
|
|
|
+ try:
|
|
|
|
+ self.db = sqlite3.connect(DATABASE_NAME)
|
|
|
|
+ except sqlite3.OperationalError:
|
|
|
|
+ print("Database %s not found" % DATABASE_NAME)
|
|
|
|
+ raise OperationalError
|
|
|
|
+ c = self.db.cursor()
|
|
|
|
+ try:
|
|
|
|
+ c.execute("select * from dirnotes")
|
|
|
|
+ except sqlite3.OperationalError:
|
|
|
|
+ print("Table %s created" % ("dirnotes"))
|
|
|
|
+ c.execute("create table dirnotes (name, date, size, comment)")
|
|
|
|
+
|
|
|
|
+ def getData(self, fileName):
|
|
|
|
+ c = self.db.cursor()
|
|
|
|
+ c.execute("select * from dirnotes where name=?",(fileName,))
|
|
|
|
+ return c.fetchone()
|
|
|
|
+ def setData(self, fileName, _date, _size, comment):
|
|
|
|
+ c = self.db.cursor()
|
|
|
|
+ c.execute("insert into dirnotes values (?,?,?,?)",
|
|
|
|
+ (fileName, _date, _size, comment))
|
|
|
|
+ self.db.commit()
|
|
|
|
+ return True
|
|
|
|
|
|
def parse():
|
|
def parse():
|
|
parser = argparse.ArgumentParser(description='dirnotes application')
|
|
parser = argparse.ArgumentParser(description='dirnotes application')
|
|
@@ -25,60 +61,103 @@ def parse():
|
|
|
|
|
|
def debug(x):
|
|
def debug(x):
|
|
print("debugging " + x.text() + " r:" + str(x.row()) + " c:" + str(x.column()))
|
|
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():
|
|
|
|
+ def __init__(self, fileName):
|
|
|
|
+ self.fileName = fileName
|
|
|
|
+ # also get the date, directory or not, etc
|
|
|
|
+ self.directory = "a"
|
|
|
|
+ self.comment = ''
|
|
|
|
+ try:
|
|
|
|
+ self.comment = xattr.getxattr(fileName,COMMENT_KEY)
|
|
|
|
+ except:
|
|
|
|
+ pass
|
|
|
|
+ def getName(self):
|
|
|
|
+ return self.fileName
|
|
|
|
+ def getComment(self):
|
|
|
|
+ return self.comment
|
|
|
|
+ def setComment(self,newComment):
|
|
|
|
+ self.comment = newComment
|
|
|
|
+ try:
|
|
|
|
+ xattr.setxattr(self.fileName,COMMENT_KEY,self.comment)
|
|
|
|
+ except:
|
|
|
|
+ print("problem setting the comment on file %s" % self.fileName)
|
|
|
|
|
|
class DirNotes(QMainWindow):
|
|
class DirNotes(QMainWindow):
|
|
- def __init__(self, parent=None):
|
|
|
|
|
|
+ def __init__(self, filename, parent=None):
|
|
super(DirNotes,self).__init__(parent)
|
|
super(DirNotes,self).__init__(parent)
|
|
- pass
|
|
|
|
|
|
+ win = QWidget()
|
|
|
|
+ self.setCentralWidget(win)
|
|
|
|
+
|
|
|
|
+ lb = QTableWidget()
|
|
|
|
+ lb.setColumnCount(2)
|
|
|
|
+ lb.horizontalHeader().setResizeMode( 1, QHeaderView.Stretch );
|
|
|
|
+ # resize the comments column
|
|
|
|
+ # and resize the parent window to match the directory size
|
|
|
|
+
|
|
|
|
+ # allow multiple entries on the line at this point
|
|
|
|
+ #d = os.listdir(p.filename[0])
|
|
|
|
+ #d.sort()
|
|
|
|
+ current, dirs, files = os.walk(filename,followlinks=True).next()
|
|
|
|
+ dirs = map(lambda x:x+'/', dirs)
|
|
|
|
+ dirs.sort()
|
|
|
|
+ files.sort()
|
|
|
|
+
|
|
|
|
+ d = dirs + files
|
|
|
|
+ lb.setRowCount(len(d))
|
|
|
|
+
|
|
|
|
+ self.files = []
|
|
|
|
+ for i in range(len(d)):
|
|
|
|
+ this_file = FileObj(d[i])
|
|
|
|
+ self.files = self.files + [this_file]
|
|
|
|
+ item = QTableWidgetItem(this_file.getName())
|
|
|
|
+ item.setFlags(QtCore.Qt.ItemIsEnabled)
|
|
|
|
+ lb.setItem(i,0,item)
|
|
|
|
+ #lb.itemAt(i,0).setFlags(Qt.ItemIsEnabled) #NoItemFlags)
|
|
|
|
+ comment = this_file.getComment()
|
|
|
|
+ lb.setItem(i,1,QTableWidgetItem(comment))
|
|
|
|
+ lb.setHorizontalHeaderItem(0,QTableWidgetItem("file"))
|
|
|
|
+ lb.setHorizontalHeaderItem(1,QTableWidgetItem("comment"))
|
|
|
|
+ lb.resizeColumnsToContents()
|
|
|
|
+ lb.verticalHeader().setVisible(False)
|
|
|
|
+
|
|
|
|
+ e = QLabel("View and edit file comments stored in extended attributes user.xdg.comment")
|
|
|
|
+
|
|
|
|
+ layout = QVBoxLayout()
|
|
|
|
+ layout.addWidget(e)
|
|
|
|
+ layout.addWidget(lb)
|
|
|
|
+ win.setLayout(layout)
|
|
|
|
+
|
|
|
|
+ lb.itemChanged.connect(debug)
|
|
|
|
+
|
|
|
|
+ QShortcut(QKeySequence("Ctrl+Q"), self, self.close)
|
|
|
|
+ self.setWindowTitle("test")
|
|
|
|
+ self.setMinimumSize(600,400)
|
|
def closeEvent(self,e):
|
|
def closeEvent(self,e):
|
|
print("closing")
|
|
print("closing")
|
|
|
|
|
|
if __name__=="__main__":
|
|
if __name__=="__main__":
|
|
p = parse()
|
|
p = parse()
|
|
-
|
|
|
|
- a = QApplication([])
|
|
|
|
-
|
|
|
|
- # allow multiple entries on the line at this point
|
|
|
|
- d = os.listdir(p.filename[0])
|
|
|
|
- d.sort()
|
|
|
|
-
|
|
|
|
- lb = QTableWidget()
|
|
|
|
- lb.setRowCount(len(d))
|
|
|
|
- lb.setColumnCount(2)
|
|
|
|
- lb.horizontalHeader().setResizeMode( 1, QHeaderView.Stretch );
|
|
|
|
- # resize the comments column
|
|
|
|
- # and resize the parent window to match the directory size
|
|
|
|
- for i in range(len(d)):
|
|
|
|
- item = QTableWidgetItem(d[i])
|
|
|
|
- item.setFlags(QtCore.Qt.ItemIsEnabled)
|
|
|
|
- lb.setItem(i,0,item)
|
|
|
|
- #lb.itemAt(i,0).setFlags(Qt.ItemIsEnabled) #NoItemFlags)
|
|
|
|
- comment = ""
|
|
|
|
- try:
|
|
|
|
- comment = xattr.getxattr(d[i],COMMENT_KEY)
|
|
|
|
- except:
|
|
|
|
- continue
|
|
|
|
- lb.setItem(i,1,QTableWidgetItem(comment))
|
|
|
|
- lb.setHorizontalHeaderItem(0,QTableWidgetItem("file"))
|
|
|
|
- lb.setHorizontalHeaderItem(1,QTableWidgetItem("comment"))
|
|
|
|
- lb.resizeColumnsToContents()
|
|
|
|
-
|
|
|
|
- win = QWidget()
|
|
|
|
- layout = QVBoxLayout()
|
|
|
|
- win.setLayout(layout)
|
|
|
|
- e = QLabel(win)
|
|
|
|
- e.setText("View and edit file comments stored in extended attributes user.xdg.comment")
|
|
|
|
- layout.addWidget(e)
|
|
|
|
- layout.addWidget(lb)
|
|
|
|
|
|
|
|
- lb.itemChanged.connect(debug)
|
|
|
|
|
|
+ db = DataBase()
|
|
|
|
+ db.setData("a",float(time.time()),12345,"a comment")
|
|
|
|
+ print(db.getData("a"))
|
|
|
|
+ (f,d,s,c) = db.getData("a")
|
|
|
|
+ print(time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(d)))
|
|
|
|
|
|
- QShortcut(QKeySequence("Ctrl+Q"), win, win.close)
|
|
|
|
- win.setWindowTitle("test")
|
|
|
|
- win.setMinimumSize(600,400)
|
|
|
|
- win.show()
|
|
|
|
|
|
+ a = QApplication([])
|
|
|
|
+ dn = DirNotes(p.filename[0])
|
|
|
|
+ dn.show()
|
|
|
|
|
|
a.exec_()
|
|
a.exec_()
|
|
|
|
|
|
#xattr.setxattr(filename,COMMENT_KEY,commentText)
|
|
#xattr.setxattr(filename,COMMENT_KEY,commentText)
|
|
|
|
|
|
|
|
+
|
|
|
|
+''' files from directories
|
|
|
|
+use os.isfile()
|
|
|
|
+os.isdir()
|
|
|
|
+current, dirs, files = os.walk("path").next()
|
|
|
|
+possible set folllowLinks=True'''
|