1 # Copyright (C) 2007 by the Free Software Foundation, Inc.
3 # This program is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU General Public License
5 # as published by the Free Software Foundation; either version 2
6 # of the License, or (at your option) any later version.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program; if not, write to the Free Software
15 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
18 """Implementations of the IRequests and IListRequests interfaces."""
20 from datetime
import timedelta
21 from storm
.locals import *
22 from zope
.interface
import implements
24 from Mailman
.configuration
import config
25 from Mailman
.database
import Model
26 from Mailman
.database
.types
import Enum
27 from Mailman
.interfaces
import IListRequests
, IPendable
, IRequests
, RequestType
37 class DataPendable(dict):
43 implements(IListRequests
)
45 def __init__(self
, mailing_list
):
46 self
.mailing_list
= mailing_list
50 return config
.db
.store
.find(
51 _Request
, mailing_list
=self
.mailing_list
).count()
53 def count_of(self
, request_type
):
54 return config
.db
.store
.find(
56 mailing_list
=self
.mailing_list
, request_type
=request_type
).count()
59 def held_requests(self
):
60 results
= config
.db
.store
.find(
61 _Request
, mailing_list
=self
.mailing_list
)
62 for request
in results
:
65 def of_type(self
, request_type
):
66 results
= config
.db
.store
.find(
68 mailing_list
=self
.mailing_list
, request_type
=request_type
)
69 for request
in results
:
72 def hold_request(self
, request_type
, key
, data
=None):
73 if request_type
not in RequestType
:
74 raise TypeError(request_type
)
78 # We're abusing the pending database as a way of storing arbitrary
79 # key/value pairs, where both are strings. This isn't ideal but
80 # it lets us get auxiliary data almost for free. We may need to
81 # lock this down more later.
82 pendable
= DataPendable()
84 token
= config
.db
.pendings
.add(pendable
, timedelta(days
=5000))
86 request
= _Request(key
, request_type
, self
.mailing_list
, data_hash
)
87 config
.db
.store
.add(request
)
90 def get_request(self
, request_id
):
91 result
= config
.db
.store
.get(_Request
, request_id
)
94 if result
.data_hash
is None:
95 return result
.key
, result
.data_hash
96 pendable
= config
.db
.pendings
.confirm(result
.data_hash
, expunge
=False)
99 return result
.key
, data
101 def delete_request(self
, request_id
):
102 result
= _Request
.get(request_id
)
104 raise KeyError(request_id
)
105 # Throw away the pended data.
106 config
.db
.pendings
.confirm(result
.data_hash
)
112 implements(IRequests
)
114 def get_list_requests(self
, mailing_list
):
115 return ListRequests(mailing_list
)
119 class _Request(Model
):
120 """Table for mailing list hold requests."""
122 id = Int(primary
=True, default
=AutoReload
)
124 request_type
= Enum()
127 mailing_list_id
= Int()
128 mailing_list
= Reference(mailing_list_id
, 'MailingList.id')
130 def __init__(self
, key
, request_type
, mailing_list
, data_hash
):
132 self
.request_type
= request_type
133 self
.mailing_list
= mailing_list
134 self
.data_hash
= data_hash