123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- #!/usr/bin/python
- """ a simple gui or command line app
- to view and create/edit file comments
- comments are stored in xattr user.xdg.comment
- 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"
- DATABASE_NAME = "~/.dirnotes.db"
- import sys,os,argparse
- from PyQt4.QtGui import *
- from PyQt4 import QtGui, QtCore
- import xattr, sqlite3, time
- DATABASE_NAME = os.path.expanduser(DATABASE_NAME)
- class DataBase:
- ''' the database is flat
- fileName: fully qualified name
- st_mtime: a float
- size: a long
- comment: a string
- comment_time: a float, the time of the comment save
- this is effectively a log file, as well as a resource for a restore
- (in case a file-move is done without comment)
- the database is associated with a user, in the $HOME dir
- '''
- def __init__(self):
- '''try to open the database; if not found, create it'''
- 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 TEXT, date REAL, size INTEGER, comment TEXT, comment_date REAL)")
-
- 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, time.time()))
- self.db.commit()
- return True
- def parse():
- parser = argparse.ArgumentParser(description='dirnotes application')
- parser.add_argument('filename',metavar='filename',type=str,
- nargs="*",help='filename or directory',default=".")
- parser.add_argument('-n','--nogui',action="store_const",const="1",
- help='use text base interface')
- parser.add_argument('-v','--version',action='version',version='%(prog)s 0.2')
- 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():
- 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):
- def __init__(self, filename, parent=None):
- super(DirNotes,self).__init__(parent)
- 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):
- print("closing")
-
- if __name__=="__main__":
- p = parse()
-
- 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([])
- dn = DirNotes(p.filename[0])
- dn.show()
-
- a.exec_()
-
- #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'''
|