--- /dev/null
+"""
+Implementation of the XDG Recent File Storage Specification Version 0.2
+http://standards.freedesktop.org/recent-file-spec
+"""
+
+import xml.dom.minidom, xml.sax.saxutils
+import os, time, fcntl
+from xdg.Exceptions import *
+
+class RecentFiles:
+ def __init__(self):
+ self.RecentFiles = []
+ self.filename = ""
+
+ def parse(self, filename=None):
+ if not filename:
+ filename = os.path.join(os.getenv("HOME"), ".recently-used")
+
+ try:
+ doc = xml.dom.minidom.parse(filename)
+ except IOError:
+ raise ParsingError('File not found', filename)
+ except xml.parsers.expat.ExpatError:
+ raise ParsingError('Not a valid .menu file', filename)
+
+ self.filename = filename
+
+ for child in doc.childNodes:
+ if child.nodeType == xml.dom.Node.ELEMENT_NODE:
+ if child.tagName == "RecentFiles":
+ for recent in child.childNodes:
+ if recent.nodeType == xml.dom.Node.ELEMENT_NODE:
+ if recent.tagName == "RecentItem":
+ self.__parseRecentItem(recent)
+
+ self.sort()
+
+ def __parseRecentItem(self, item):
+ recent = RecentFile()
+ self.RecentFiles.append(recent)
+
+ for attribute in item.childNodes:
+ if attribute.nodeType == xml.dom.Node.ELEMENT_NODE:
+ if attribute.tagName == "URI":
+ recent.URI = attribute.childNodes[0].nodeValue
+ elif attribute.tagName == "Mime-Type":
+ recent.MimeType = attribute.childNodes[0].nodeValue
+ elif attribute.tagName == "Timestamp":
+ recent.Timestamp = attribute.childNodes[0].nodeValue
+ elif attribute.tagName == "Private":
+ recent.Prviate = True
+ elif attribute.tagName == "Groups":
+
+ for group in attribute.childNodes:
+ if group.nodeType == xml.dom.Node.ELEMENT_NODE:
+ if group.tagName == "Group":
+ recent.Groups.append(group.childNodes[0].nodeValue)
+
+ def write(self, filename=None):
+ if not filename and not self.filename:
+ raise ParsingError('File not found', filename)
+ elif not filename:
+ filename = self.filename
+
+ f = open(filename, "w")
+ fcntl.lockf(f, fcntl.LOCK_EX)
+ f.write('<?xml version="1.0"?>\n')
+ f.write("<RecentFiles>\n")
+
+ for r in self.RecentFiles:
+ f.write(" <RecentItem>\n")
+ f.write(" <URI>%s</URI>\n" % xml.sax.saxutils.escape(r.URI))
+ f.write(" <Mime-Type>%s</Mime-Type>\n" % r.MimeType)
+ f.write(" <Timestamp>%s</Timestamp>\n" % r.Timestamp)
+ if r.Private == True:
+ f.write(" <Private/>\n")
+ if len(r.Groups) > 0:
+ f.write(" <Groups>\n")
+ for group in r.Groups:
+ f.write(" <Group>%s</Group>\n" % group)
+ f.write(" </Groups>\n")
+ f.write(" </RecentItem>\n")
+
+ f.write("</RecentFiles>\n")
+ fcntl.lockf(f, fcntl.LOCK_UN)
+ f.close()
+
+ def getFiles(self, mimetypes=None, groups=None, limit=0):
+ tmp = []
+ i = 0
+ for item in self.RecentFiles:
+ if groups:
+ for group in groups:
+ if group in item.Groups:
+ tmp.append(item)
+ i += 1
+ elif mimetypes:
+ for mimetype in mimetypes:
+ if mimetype == item.MimeType:
+ tmp.append(item)
+ i += 1
+ else:
+ if item.Private == False:
+ tmp.append(item)
+ i += 1
+ if limit != 0 and i == limit:
+ break
+
+ return tmp
+
+ def addFile(self, item, mimetype, groups=None, private=False):
+ # check if entry already there
+ if item in self.RecentFiles:
+ index = self.RecentFiles.index(item)
+ recent = self.RecentFiles[index]
+ else:
+ # delete if more then 500 files
+ if len(self.RecentFiles) == 500:
+ self.RecentFiles.pop()
+ # add entry
+ recent = RecentFile()
+ self.RecentFiles.append(recent)
+
+ recent.URI = item
+ recent.MimeType = mimetype
+ recent.Timestamp = int(time.time())
+ recent.Private = private
+ recent.Groups = groups
+
+ self.sort()
+
+ def deleteFile(self, item):
+ if item in self.RecentFiles:
+ self.RecentFiles.remove(item)
+
+ def sort(self):
+ self.RecentFiles.sort()
+ self.RecentFiles.reverse()
+
+
+class RecentFile:
+ def __init__(self):
+ self.URI = ""
+ self.MimeType = ""
+ self.Timestamp = ""
+ self.Private = False
+ self.Groups = []
+
+ def __cmp__(self, other):
+ return cmp(self.Timestamp, other.Timestamp)
+
+ def __eq__(self, other):
+ if self.URI == str(other):
+ return True
+ else:
+ return False
+
+ def __str__(self):
+ return self.URI