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