1import cPickle as pickle 2import os.path 3import time 4from zope.interface import implements 5 6from twisted.application import service 7from twisted.python import log 8 9from pastebin import interfaces 10from pastebin import pasting 11 12 13class Record(object): 14 15 def __init__(self, oid, author, time): 16 self.oid = oid 17 self.author = author 18 self.time = time 19 self.version = 0 20 21 22class FSPasteBinService(service.Service): 23 24 implements(interfaces.IPasteBin) 25 26 def __init__(self, storageDir): 27 self._dir = storageDir 28 29 def getListOfPastings(self, limit=None): 30 if limit is None: 31 limited = self._index 32 else: 33 limited = self._index[0:limit] 34 return [(r.oid, r.author, r.time) for r in limited] 35 36 def _makeFilename(self, name): 37 return os.path.join(self._dir, name) 38 39 def _loadPastingData(self, oid): 40 f = file(self._makeFilename(str(oid)), 'rb') 41 return pickle.load(f) 42 43 def _savePastingData(self, oid, data): 44 f = file(self._makeFilename(str(oid)), 'wb') 45 pickle.dump(data, f, pickle.HIGHEST_PROTOCOL) 46 47 def getPasting(self, oid): 48 data = self._loadPastingData(oid) 49 return Pasting(data) 50 51 def addPasting(self, author, text): 52 oid = self._nextOid 53 now = time.gmtime() 54 data = [{'author':author, 'time':now, 'text':text}] 55 self._savePastingData(oid, data) 56 self._index.insert(0, Record(oid, author, now)) 57 self._nextOid += 1 58 return oid 59 60 def updatePasting(self, oid, author, text): 61 now = time.gmtime() 62 data = self._loadPastingData(oid) 63 data.append({'author':author, 'time':now, 'text':text}) 64 self._savePastingData(oid, data) 65 for i, r in enumerate(self._index): 66 if r.oid == oid: 67 r.time = now 68 self._index.insert(0,self._index.pop(i)) 69 70 def startService(self): 71 log.msg('Loading index') 72 try: 73 f = file(self._makeFilename('index'), 'rb') 74 d = pickle.load(f) 75 self._index = d['index'] 76 self._nextOid = d['nextOid'] 77 except IOError: 78 self._index = [] 79 self._nextOid = 1 80 81 def stopService(self): 82 log.msg('Storing index') 83 d = {'index':self._index, 'nextOid':self._nextOid} 84 f = file(self._makeFilename('index'), 'wb') 85 pickle.dump(d, f, pickle.HIGHEST_PROTOCOL) 86 87class Pasting(object): 88 89 implements(pasting.IPasting) 90 91 def __init__(self, data): 92 self._data = data 93 94 def getLatestVersion(self): 95 return self.getVersion(-1) 96 97 def getVersion(self, version): 98 return Version(self._data[version]) 99 100 def getHistory(self): 101 history = [(i,d['author'],d['time']) for i,d in enumerate(self._data)] 102 history.reverse() 103 return history 104 105 106class Version: 107 108 implements(pasting.IVersion) 109 110 def __init__(self, data): 111 self._data = data 112 113 def getAuthor(self): 114 return self._data['author'] 115 116 def getText(self): 117 return self._data['text'] 118 119 def getTime(self): 120 return self._data['time'] 121