Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 483 lines (415 sloc) 18.543 kB
82ae3f3 petitions - first cut
Devi authored
1
2 from __future__ import with_statement
3
4 import web
0c13f96 @asldevi -wyr mails sent to senators also
asldevi authored
5 from utils import forms, helpers, auth, wyrapp
b356718 @asldevi remove sessions
asldevi authored
6 from settings import db, render, render_plain
c3bc533 @simonbc Petition UI: require sign up to create a new petition, new petition page
simonbc authored
7 from utils.auth import require_login
d931232 @asldevi remove first, last names from signup form
asldevi authored
8 from utils.users import fill_user_details, update_user_details
0c13f96 @asldevi -wyr mails sent to senators also
asldevi authored
9 from utils.writerep import require_captcha, send_msgs
04757d0 @asldevi verified and unverified cookies,
asldevi authored
10 import config
227b253 @asldevi bug fixes, thanks unittests!
asldevi authored
11 import simplejson
82ae3f3 petitions - first cut
Devi authored
12
978cf42 @asldevi petition - url fixes, avoid share duplicates etc.
asldevi authored
13 from datetime import datetime
ea5df21 @asldevi bug fixes in petitions i210, i211, i213, i214, i215, i217 and i218
asldevi authored
14 import urllib
978cf42 @asldevi petition - url fixes, avoid share duplicates etc.
asldevi authored
15
82ae3f3 petitions - first cut
Devi authored
16 urls = (
417b9d2 @aaronsw web.py upgrade
authored
17 '', 'redir',
18 '/', 'index',
c3bc533 @simonbc Petition UI: require sign up to create a new petition, new petition page
simonbc authored
19 '/new', 'new',
73fee6f @simonbc share my email checkbox. first and last name on same line in sign and…
simonbc authored
20 '/login', 'login',
21 '/signup', 'signup',
978cf42 @asldevi petition - url fixes, avoid share duplicates etc.
asldevi authored
22 '/verify', 'checkID',
23 '/(.*)/signatories', 'signatories',
417b9d2 @aaronsw web.py upgrade
authored
24 '/(.*)', 'petition'
6615660 @asldevi ask user to set password after creating petition
asldevi authored
25 )
417b9d2 @aaronsw web.py upgrade
authored
26
27 class redir:
28 def GET(self): raise web.seeother('/')
c3bc533 @simonbc Petition UI: require sign up to create a new petition, new petition page
simonbc authored
29
3a7b601 @asldevi Check URL availability with AJAX
asldevi authored
30 class checkID:
31 def POST(self):
32 "Return True if petition with id `pid` does not exist"
33 pid = web.input().pid
34 exists = bool(db.select('petition', where='id=$pid', vars=locals()))
c3bc533 @simonbc Petition UI: require sign up to create a new petition, new petition page
simonbc authored
35 return pid != 'new' and not(exists)
417b9d2 @aaronsw web.py upgrade
authored
36
82ae3f3 petitions - first cut
Devi authored
37 class index:
4961d5f @asldevi create index pages
asldevi authored
38 def index(self):
39 pids = db.select('petition', what='id', where='petition.deleted is null and petition.published is not null')
40 return (('/c/%s' % p.id, '/c/%s/signatories' % p.id) for p in pids)
41
82ae3f3 petitions - first cut
Devi authored
42 def GET(self):
c3bc533 @simonbc Petition UI: require sign up to create a new petition, new petition page
simonbc authored
43 petitions = db.select(['petition', 'signatory'],
04757d0 @asldevi verified and unverified cookies,
asldevi authored
44 what='petition.id, petition.title, count(signatory.user_id) as signature_count',
b3f4c75 @asldevi bug fix in signatory count
asldevi authored
45 where='petition.deleted is null and petition.published is not null '
46 'and petition.id = signatory.petition_id and signatory.deleted is null',
04757d0 @asldevi verified and unverified cookies,
asldevi authored
47 group='petition.id, petition.title',
48 order='count(signatory.user_id) desc'
49 )
029241d @simonbc fieldset css was lost on style.css webchick merge, put it back in. re…
simonbc authored
50
34a70b8 @asldevi merge
asldevi authored
51 msg, msg_type = helpers.get_delete_msg()
029241d @simonbc fieldset css was lost on style.css webchick merge, put it back in. re…
simonbc authored
52 return render.petition_list(petitions, msg)
c3bc533 @simonbc Petition UI: require sign up to create a new petition, new petition page
simonbc authored
53
0c13f96 @asldevi -wyr mails sent to senators also
asldevi authored
54 def send_to_congress(uid, i, signid):
55 #@@@ compose here too
227b253 @asldevi bug fixes, thanks unittests!
asldevi authored
56 env = simplejson.loads(i.get('captcha_env', '{}'))
0c13f96 @asldevi -wyr mails sent to senators also
asldevi authored
57 i.msg = i.msg + '\n' + i.get('comment', '')
227b253 @asldevi bug fixes, thanks unittests!
asldevi authored
58 send_msgs(uid, i, source_id='s%s' % signid, env=env)
e3ccacb @asldevi draft mode for petitions
asldevi authored
59
0c13f96 @asldevi -wyr mails sent to senators also
asldevi authored
60 def create_petition(i, email):
73fee6f @simonbc share my email checkbox. first and last name on same line in sign and…
simonbc authored
61 tocongress = i.get('tocongress', 'off') == 'on'
0c13f96 @asldevi -wyr mails sent to senators also
asldevi authored
62 i.pid = i.pid.replace(' ', '-')
73fee6f @simonbc share my email checkbox. first and last name on same line in sign and…
simonbc authored
63 u = helpers.get_user_by_email(email)
e3ccacb @asldevi draft mode for petitions
asldevi authored
64 is_draft = 'save' in i
65 published = None if is_draft else datetime.now()
33ae876 @asldevi fix for #153
asldevi authored
66 try:
e3ccacb @asldevi draft mode for petitions
asldevi authored
67 db.insert('petition', seqname=False, id=i.pid, title=i.ptitle,
68 created=datetime.now(), published=published,
0c13f96 @asldevi -wyr mails sent to senators also
asldevi authored
69 description=i.msg, owner_id=u.id, to_congress=tocongress)
70 except: return
e3ccacb @asldevi draft mode for petitions
asldevi authored
71
72 if is_draft:
73 msg = """Petition saved for publishing later."""
74 helpers.set_msg(msg)
75 else:
dc79f3e @asldevi don't show sign form for drafts; allow only owner to share drafts; ot…
asldevi authored
76 create_first_signature(i, u.email)
e3ccacb @asldevi draft mode for petitions
asldevi authored
77
dc79f3e @asldevi don't show sign form for drafts; allow only owner to share drafts; ot…
asldevi authored
78 def create_first_signature(i, email):
e3ccacb @asldevi draft mode for petitions
asldevi authored
79 tocongress = i.get('tocongress', 'off') == 'on'
80 i.pid = i.pid.replace(' ', '-')
81 u = helpers.get_user_by_email(email)
0c13f96 @asldevi -wyr mails sent to senators also
asldevi authored
82 signid = save_signature(i, i.pid, u.id)
83 if tocongress: send_to_congress(u.id, i, signid)
e3ccacb @asldevi draft mode for petitions
asldevi authored
84 sendmail_to_signatory(u, i.pid)
73fee6f @simonbc share my email checkbox. first and last name on same line in sign and…
simonbc authored
85 msg = """Congratulations, you've created your petition.
e3ccacb @asldevi draft mode for petitions
asldevi authored
86 Now share it with all your friends."""
73fee6f @simonbc share my email checkbox. first and last name on same line in sign and…
simonbc authored
87 helpers.set_msg(msg)
b222188 @asldevi Ajax verification for zip and captcha (works w/o js too)
asldevi authored
88
82ae3f3 petitions - first cut
Devi authored
89 class new:
0c13f96 @asldevi -wyr mails sent to senators also
asldevi authored
90 def GET(self, pf=None, wf=None):
91 pf = pf or forms.petitionform()
92 if not wf:
93 #create a new form and initialize with current user details
94 wf = forms.wyrform()
95 u = helpers.get_user()
96 u and fill_user_details(wf, u)
97 captcha_html = wyrapp.prepare_for_captcha(wf)
98 msg, msg_type = helpers.get_delete_msg()
99 return render.petitionform(pf, wf, captchas=captcha_html, msg=msg)
100
101 def POST(self):
102 i = web.input()
c3bc533 @simonbc Petition UI: require sign up to create a new petition, new petition page
simonbc authored
103 tocongress = i.get('tocongress', 'off') == 'on'
0c13f96 @asldevi -wyr mails sent to senators also
asldevi authored
104 pf, wf = forms.petitionform(), forms.wyrform()
105 i.email = 'one@valid.mail' # to make wf valid, find a better work around
106 wyr_valid = (not(tocongress) or wf.validates(i))
107 captcha_needed = require_captcha(i)
108 wyr_valid = wyr_valid and not captcha_needed
109
110 if not pf.validates(i) or not wyr_valid:
227b253 @asldevi bug fixes, thanks unittests!
asldevi authored
111 if captcha_needed: wf.valid, wf.note = False, 'Please fill the captcha below'
0c13f96 @asldevi -wyr mails sent to senators also
asldevi authored
112 pf.fill(i), wf.fill(i)
113 return self.GET(pf, wf)
c3bc533 @simonbc Petition UI: require sign up to create a new petition, new petition page
simonbc authored
114
73fee6f @simonbc share my email checkbox. first and last name on same line in sign and…
simonbc authored
115 email = helpers.get_loggedin_email()
116 if not email:
117 return login().GET(i)
118
0c13f96 @asldevi -wyr mails sent to senators also
asldevi authored
119 create_petition(i, email)
73fee6f @simonbc share my email checkbox. first and last name on same line in sign and…
simonbc authored
120 raise web.seeother('/%s' % i.pid)
c3bc533 @simonbc Petition UI: require sign up to create a new petition, new petition page
simonbc authored
121
73fee6f @simonbc share my email checkbox. first and last name on same line in sign and…
simonbc authored
122 class login:
ab3586d @aaronsw fix crasher
authored
123 def GET(self, i=None, wf=None):
124 i = i or web.input()
73fee6f @simonbc share my email checkbox. first and last name on same line in sign and…
simonbc authored
125 lf, sf = forms.loginform(), forms.signupform()
b222188 @asldevi Ajax verification for zip and captcha (works w/o js too)
asldevi authored
126 pf, wf = forms.petitionform(), (wf or forms.wyrform())
73fee6f @simonbc share my email checkbox. first and last name on same line in sign and…
simonbc authored
127 pf.fill(i), wf.fill(i)
ba32bcd @asldevi bug fix in petition drafts
asldevi authored
128 is_draft = 'save' in i
129 return render.petitionlogin(lf, sf, pf, wf, is_draft=is_draft)
73fee6f @simonbc share my email checkbox. first and last name on same line in sign and…
simonbc authored
130
131 def POST(self):
132 i = web.input()
b222188 @asldevi Ajax verification for zip and captcha (works w/o js too)
asldevi authored
133 lf, wf = forms.loginform(), forms.wyrform()
73fee6f @simonbc share my email checkbox. first and last name on same line in sign and…
simonbc authored
134 if not lf.validates(i):
b222188 @asldevi Ajax verification for zip and captcha (works w/o js too)
asldevi authored
135 pf, sf = forms.petitionform(), forms.signupform()
73fee6f @simonbc share my email checkbox. first and last name on same line in sign and…
simonbc authored
136 lf.fill(i), pf.fill(i), wf.fill(i)
dc79f3e @asldevi don't show sign form for drafts; allow only owner to share drafts; ot…
asldevi authored
137 is_draft = 'save' in i
138 return render.petitionlogin(lf, sf, pf, wf, is_draft=is_draft)
0c13f96 @asldevi -wyr mails sent to senators also
asldevi authored
139 create_petition(i, i.useremail)
73fee6f @simonbc share my email checkbox. first and last name on same line in sign and…
simonbc authored
140 raise web.seeother('/%s' % i.pid)
141
142 class signup:
143 def POST(self):
144 i = web.input()
b222188 @asldevi Ajax verification for zip and captcha (works w/o js too)
asldevi authored
145 sf, wf = forms.signupform(), forms.wyrform()
73fee6f @simonbc share my email checkbox. first and last name on same line in sign and…
simonbc authored
146 if not sf.validates(i):
b222188 @asldevi Ajax verification for zip and captcha (works w/o js too)
asldevi authored
147 lf, pf = forms.loginform(), forms.petitionform()
73fee6f @simonbc share my email checkbox. first and last name on same line in sign and…
simonbc authored
148 sf.fill(i), pf.fill(i), wf.fill(i)
149 return render.petitionlogin(lf, sf, pf, wf)
d931232 @asldevi remove first, last names from signup form
asldevi authored
150 user = auth.new_user(i.email, i.password)
73fee6f @simonbc share my email checkbox. first and last name on same line in sign and…
simonbc authored
151 helpers.set_login_cookie(i.email)
0c13f96 @asldevi -wyr mails sent to senators also
asldevi authored
152 create_petition(i, i.email)
73fee6f @simonbc share my email checkbox. first and last name on same line in sign and…
simonbc authored
153 raise web.seeother('/%s' % i.pid)
c3bc533 @simonbc Petition UI: require sign up to create a new petition, new petition page
simonbc authored
154
0c13f96 @asldevi -wyr mails sent to senators also
asldevi authored
155 def save_signature(i, pid, uid):
ea5df21 @asldevi bug fixes in petitions i210, i211, i213, i214, i215, i217 and i218
asldevi authored
156 where = 'petition_id=$pid AND user_id=$uid'
1e4ffae @asldevi -login no more required for wyr
asldevi authored
157 signed = db.select('signatory', where=where, vars=locals())
158 share_with = (i.get('share_with', 'off') == 'on' and 'N') or 'A'
0c13f96 @asldevi -wyr mails sent to senators also
asldevi authored
159 update_user_details(i)
6615660 @asldevi ask user to set password after creating petition
asldevi authored
160 if not signed:
fcdd17b @asldevi track shares of petitions "#71"
asldevi authored
161 referrer = get_referrer(pid, uid)
0c13f96 @asldevi -wyr mails sent to senators also
asldevi authored
162 signid = db.insert('signatory', user_id=uid, share_with=share_with,
163 petition_id=pid, comment=i.get('comment'), referrer=referrer)
1e4ffae @asldevi -login no more required for wyr
asldevi authored
164 helpers.set_msg("Thanks for your signing! Why don't you tell your friends about it now?")
0c13f96 @asldevi -wyr mails sent to senators also
asldevi authored
165 return signid
1e4ffae @asldevi -login no more required for wyr
asldevi authored
166 else:
ea5df21 @asldevi bug fixes in petitions i210, i211, i213, i214, i215, i217 and i218
asldevi authored
167 db.update('signatory', where='user_id=$uid and petition_id=$pid',
168 comment=i.get('comment'), deleted=None, vars=locals())
0c13f96 @asldevi -wyr mails sent to senators also
asldevi authored
169 helpers.set_msg("Your signature has been changed. Why don't you tell your friends about it now?")
170 return 'old_%s' % signed[0].id
171
04757d0 @asldevi verified and unverified cookies,
asldevi authored
172 def sendmail_to_signatory(user, pid):
0c13f96 @asldevi -wyr mails sent to senators also
asldevi authored
173 """sends a thanks mail to the user, with request to share the petition with friends.
174 """
1e4ffae @asldevi -login no more required for wyr
asldevi authored
175 p = get_petition_by_id(pid)
176 p.url = 'http://watchdog.net/c/%s' % (pid)
4bd272f @asldevi petitions - delete and unsign; msg_type to differentiate error msgs; …
asldevi authored
177 token = auth.get_secret_token(user.email)
178 msg = render_plain.signatory_mailer(user, p, token)
0c13f96 @asldevi -wyr mails sent to senators also
asldevi authored
179 web.sendmail(config.from_address, user.email, msg.subject.strip(), str(msg))
c3bc533 @simonbc Petition UI: require sign up to create a new petition, new petition page
simonbc authored
180
6fb4989 @asldevi javascript to add petition URL
asldevi authored
181 def is_author(email, pid):
1e4ffae @asldevi -login no more required for wyr
asldevi authored
182 user = email and helpers.get_user_by_email(email)
183 where = 'id=$pid and owner_id=$user.id and deleted is null'
184 return user and bool(db.select('petition', where=where, vars=locals()))
c3bc533 @simonbc Petition UI: require sign up to create a new petition, new petition page
simonbc authored
185
94b6627 @asldevi indicate if the user has already signed a petition
asldevi authored
186 def is_signatory(email, pid):
187 user = email and helpers.get_user_by_email(email)
ea5df21 @asldevi bug fixes in petitions i210, i211, i213, i214, i215, i217 and i218
asldevi authored
188 where = 'petition_id=$pid and user_id=$user.id and deleted is null'
94b6627 @asldevi indicate if the user has already signed a petition
asldevi authored
189 return user and bool(db.select('signatory', where=where, vars=locals()))
190
73fee6f @simonbc share my email checkbox. first and last name on same line in sign and…
simonbc authored
191 def get_signs(pid):
0c13f96 @asldevi -wyr mails sent to senators also
asldevi authored
192 where = "petition_id=$pid AND users.id=user_id AND deleted is null"
73fee6f @simonbc share my email checkbox. first and last name on same line in sign and…
simonbc authored
193 return db.select(['signatory', 'users'],
194 what='users.fname, users.lname, users.email, '
195 'signatory.share_with, signatory.comment, '
196 'signatory.signed',
1e4ffae @asldevi -login no more required for wyr
asldevi authored
197 where=where,
73fee6f @simonbc share my email checkbox. first and last name on same line in sign and…
simonbc authored
198 order='signed desc',
199 vars=locals())
200
1e4ffae @asldevi -login no more required for wyr
asldevi authored
201 def to_congress(pid):
202 return bool(db.select("petition", where="id=$pid AND to_congress='t'", vars=locals()))
203
204 def get_num_signs(pid):
0c13f96 @asldevi -wyr mails sent to senators also
asldevi authored
205 where = "petition_id=$pid AND deleted is null"
1e4ffae @asldevi -login no more required for wyr
asldevi authored
206 r = db.query("select count(*) from signatory where " + where, vars=locals())
207 return r[0].count
208
209 def get_petition_by_id(pid):
210 try:
211 return db.select('petition', where='id=$pid and deleted is null', vars=locals())[0]
212 except IndexError:
213 return
214
978cf42 @asldevi petition - url fixes, avoid share duplicates etc.
asldevi authored
215 class signatories:
216 def GET(self, pid):
217 user_email = helpers.get_loggedin_email()
1e4ffae @asldevi -login no more required for wyr
asldevi authored
218 p = get_petition_by_id(pid)
23a3469 @asldevi fix crasher in notfound
asldevi authored
219 if not p: raise web.notfound()
1e4ffae @asldevi -login no more required for wyr
asldevi authored
220 ptitle = p.title
73fee6f @simonbc share my email checkbox. first and last name on same line in sign and…
simonbc authored
221 signs = get_signs(pid).list()
978cf42 @asldevi petition - url fixes, avoid share duplicates etc.
asldevi authored
222 return render.signature_list(pid, ptitle, signs, is_author(user_email, pid))
1e4ffae @asldevi -login no more required for wyr
asldevi authored
223
fcdd17b @asldevi track shares of petitions "#71"
asldevi authored
224 def set_referrer_cookie(tid, pid):
225 if helpers.check_trackid(tid, pid):
226 helpers.setcookie('tid', tid)
227
228 def get_referrer(pid, uid):
229 tid = helpers.getcookie('tid')
230 referrer = helpers.check_trackid(tid, pid)
231 if referrer != uid:
232 return referrer
233
e3ccacb @asldevi draft mode for petitions
asldevi authored
234 def is_draft(p):
235 return not bool(p.published)
236
82ae3f3 petitions - first cut
Devi authored
237 class petition:
0c13f96 @asldevi -wyr mails sent to senators also
asldevi authored
238 def GET(self, pid, sf=None, wf=None):
3a7b601 @asldevi Check URL availability with AJAX
asldevi authored
239 i = web.input()
ea5df21 @asldevi bug fixes in petitions i210, i211, i213, i214, i215, i217 and i218
asldevi authored
240 pid = pid.rstrip('/')
1e4ffae @asldevi -login no more required for wyr
asldevi authored
241 p = get_petition_by_id(pid)
23a3469 @asldevi fix crasher in notfound
asldevi authored
242 if not p: raise web.notfound()
1e4ffae @asldevi -login no more required for wyr
asldevi authored
243
978cf42 @asldevi petition - url fixes, avoid share duplicates etc.
asldevi authored
244 options = ['unsign', 'edit', 'delete']
4bd272f @asldevi petitions - delete and unsign; msg_type to differentiate error msgs; …
asldevi authored
245 if i.get('m', None) in options:
246 handler = getattr(self, 'GET_'+i.m)
247 return handler(pid)
248
0c13f96 @asldevi -wyr mails sent to senators also
asldevi authored
249 if not sf:
250 sf = forms.signform()
251 fill_user_details(sf)
252
253 captcha_html = ''
254 if to_congress(pid):
255 if not wf:
256 wf = forms.wyrform()
257 fill_user_details(wf)
258 captcha_html = wyrapp.prepare_for_captcha(wf)
fcdd17b @asldevi track shares of petitions "#71"
asldevi authored
259
260 if 'tid' in i:
261 set_referrer_cookie(i.tid, pid)
262 raise web.seeother('/%s' % pid)
dc90d05 @asldevi little cleanup in template args
asldevi authored
263
264 u = web.storage()
265 u.email = helpers.get_loggedin_email() or helpers.get_unverified_email()
266 u.isauthor = is_author(u.email, pid)
267 u.issignatory = is_signatory(u.email, pid)
268 p.isdraft = is_draft(p)
0c13f96 @asldevi -wyr mails sent to senators also
asldevi authored
269 p.signatory_count = get_num_signs(pid)
270 msg, msg_type = helpers.get_delete_msg()
dc90d05 @asldevi little cleanup in template args
asldevi authored
271 return render.petition(p, u, sf, wf, captcha_html, msg)
c3bc533 @simonbc Petition UI: require sign up to create a new petition, new petition page
simonbc authored
272
98292e5 @simonbc Edit petition UI (integration with wyr still not working)
simonbc authored
273 @auth.require_login
3a7b601 @asldevi Check URL availability with AJAX
asldevi authored
274 def GET_edit(self, pid):
275 user_email = helpers.get_loggedin_email()
6fb4989 @asldevi javascript to add petition URL
asldevi authored
276 if is_author(user_email, pid):
1e4ffae @asldevi -login no more required for wyr
asldevi authored
277 p = get_petition_by_id(pid)
98292e5 @simonbc Edit petition UI (integration with wyr still not working)
simonbc authored
278 u = helpers.get_user_by_email(user_email)
0c13f96 @asldevi -wyr mails sent to senators also
asldevi authored
279 pf = forms.petitionform()
280 pf.fill(userid=u.id, email=user_email, pid=p.id, ptitle=p.title, msg=p.description, tocongress=p.to_congress)
281 wf = forms.wyrform()
282 fill_user_details(wf)
e3ccacb @asldevi draft mode for petitions
asldevi authored
283 isdraft = is_draft(p)
dc90d05 @asldevi little cleanup in template args
asldevi authored
284 return render.petitionform(pf, wf, is_new=False, is_draft=isdraft)
0c13f96 @asldevi -wyr mails sent to senators also
asldevi authored
285 elif user_email:
286 msg = "You don't have permissions to edit this petition."
287 else:
a62c1c1 @asldevi move all user related URLs to be /u/*
asldevi authored
288 login_link = '<a href="/u/login">Login</a>'
0c13f96 @asldevi -wyr mails sent to senators also
asldevi authored
289 msg = 'Only author of this petition can edit it. %s if you are.' % login_link
290 helpers.set_msg(msg)
291 raise web.seeother('/%s' % pid)
c3bc533 @simonbc Petition UI: require sign up to create a new petition, new petition page
simonbc authored
292
293
4bd272f @asldevi petitions - delete and unsign; msg_type to differentiate error msgs; …
asldevi authored
294 def GET_unsign(self, pid):
295 i = web.input()
296 user = helpers.get_user_by_email(i.email)
c3bc533 @simonbc Petition UI: require sign up to create a new petition, new petition page
simonbc authored
297
4bd272f @asldevi petitions - delete and unsign; msg_type to differentiate error msgs; …
asldevi authored
298 if user:
1e4ffae @asldevi -login no more required for wyr
asldevi authored
299 where = 'petition_id=$pid and user_id=$user.id and deleted is null'
300 signatory = db.select('signatory', where=where, vars=locals())
c3bc533 @simonbc Petition UI: require sign up to create a new petition, new petition page
simonbc authored
301
0c13f96 @asldevi -wyr mails sent to senators also
asldevi authored
302 valid_token = auth.check_secret_token(i.get('email', ''), i.get('token', '@'))
1e4ffae @asldevi -login no more required for wyr
asldevi authored
303 if not (user and signatory and valid_token):
4bd272f @asldevi petitions - delete and unsign; msg_type to differentiate error msgs; …
asldevi authored
304 msg = "Invalid token or there is no signature for this petition with this email."
305 msg_type = 'error'
306 else:
0c13f96 @asldevi -wyr mails sent to senators also
asldevi authored
307 msg = str(render_plain.confirm_unsign(pid, user.id))
4bd272f @asldevi petitions - delete and unsign; msg_type to differentiate error msgs; …
asldevi authored
308 msg_type = ''
c3bc533 @simonbc Petition UI: require sign up to create a new petition, new petition page
simonbc authored
309
0c13f96 @asldevi -wyr mails sent to senators also
asldevi authored
310 helpers.set_msg(msg, msg_type)
c3bc533 @simonbc Petition UI: require sign up to create a new petition, new petition page
simonbc authored
311 raise web.seeother('/%s' % pid)
312
4bd272f @asldevi petitions - delete and unsign; msg_type to differentiate error msgs; …
asldevi authored
313 def GET_delete(self, pid):
314 user_email = helpers.get_loggedin_email()
315 if is_author(user_email, pid):
e1b9356 @asldevi fix for broken delete #158
asldevi authored
316 msg = str(render_plain.confirm_deletion(pid))
0c13f96 @asldevi -wyr mails sent to senators also
asldevi authored
317 elif user_email:
318 msg = "You don't have permissions to delete this petition."
319 else:
a62c1c1 @asldevi move all user related URLs to be /u/*
asldevi authored
320 login_link = '<a href="/u/login">Login</a>'
0c13f96 @asldevi -wyr mails sent to senators also
asldevi authored
321 msg = 'Only author of this petition can delete it. %s if you are.' % login_link
322 helpers.set_msg(msg)
c3bc533 @simonbc Petition UI: require sign up to create a new petition, new petition page
simonbc authored
323 raise web.seeother('/%s' % pid)
324
82ae3f3 petitions - first cut
Devi authored
325 def POST(self, pid):
6615660 @asldevi ask user to set password after creating petition
asldevi authored
326 i = web.input('m', _method='GET')
ea5df21 @asldevi bug fixes in petitions i210, i211, i213, i214, i215, i217 and i218
asldevi authored
327 options = ['sign', 'unsign', 'edit', 'delete']
3a7b601 @asldevi Check URL availability with AJAX
asldevi authored
328 if i.m in options:
329 handler = getattr(self, 'POST_'+i.m)
330 return handler(pid)
c3bc533 @simonbc Petition UI: require sign up to create a new petition, new petition page
simonbc authored
331 else:
6615660 @asldevi ask user to set password after creating petition
asldevi authored
332 raise ValueError
c3bc533 @simonbc Petition UI: require sign up to create a new petition, new petition page
simonbc authored
333
6615660 @asldevi ask user to set password after creating petition
asldevi authored
334 def POST_sign(self, pid):
335 i = web.input()
0c13f96 @asldevi -wyr mails sent to senators also
asldevi authored
336 sf = forms.signform()
1e4ffae @asldevi -login no more required for wyr
asldevi authored
337 tocongress = to_congress(pid)
0aca1e4 @asldevi share page/petition
asldevi authored
338 p = get_petition_by_id(pid)
0c13f96 @asldevi -wyr mails sent to senators also
asldevi authored
339
340 is_new = lambda sid: not isinstance(sid, str)
341 get_new = lambda sid: int(web.lstrips(sid, 'old_'))
1e4ffae @asldevi -login no more required for wyr
asldevi authored
342 if tocongress:
343 i.pid, i.ptitle, i.msg = pid, p.title, p.description
0c13f96 @asldevi -wyr mails sent to senators also
asldevi authored
344 wf = forms.wyrform()
345 captcha_needed = require_captcha(i)
346 wyr_valid = wf.validates(i) and not captcha_needed
347 if captcha_needed: wf.valid, wf.note = False, 'Please fill the captcha below'
1e4ffae @asldevi -login no more required for wyr
asldevi authored
348 else:
0c13f96 @asldevi -wyr mails sent to senators also
asldevi authored
349 wf, wyr_valid = None, True
350
351 if sf.validates(i) and wyr_valid:
352 uid = auth.assert_login(i)
353 signid = save_signature(i, pid, uid)
354 if is_new(signid):
355 user = helpers.get_user_by_id(uid)
1e4ffae @asldevi -login no more required for wyr
asldevi authored
356 sendmail_to_signatory(user, pid)
0c13f96 @asldevi -wyr mails sent to senators also
asldevi authored
357 else:
358 signid = get_new(signid)
359 if tocongress: send_to_congress(uid, i, signid)
ea5df21 @asldevi bug fixes in petitions i210, i211, i213, i214, i215, i217 and i218
asldevi authored
360 query = urllib.urlencode(dict(url='/c/%s' % pid, title=p.title))
361 raise web.seeother('/share?%s' % query, absolute=True)
369dbad @asldevi petitions bug fixes, code cleanup
asldevi authored
362 else:
0c13f96 @asldevi -wyr mails sent to senators also
asldevi authored
363 return self.GET(pid, sf=sf, wf=wf)
c3bc533 @simonbc Petition UI: require sign up to create a new petition, new petition page
simonbc authored
364
98292e5 @simonbc Edit petition UI (integration with wyr still not working)
simonbc authored
365 @auth.require_login
3a7b601 @asldevi Check URL availability with AJAX
asldevi authored
366 def POST_edit(self, pid):
367 i = web.input()
98292e5 @simonbc Edit petition UI (integration with wyr still not working)
simonbc authored
368 tocongress = i.get('tocongress', 'off') == 'on'
0c13f96 @asldevi -wyr mails sent to senators also
asldevi authored
369 pf = forms.petitionform()
370 pf.inputs = filter(lambda i: i.name != 'pid', pf.inputs)
371 wf = forms.wyrform()
5b7597d @asldevi petition edit bug fixes
asldevi authored
372 i.email = helpers.get_loggedin_email()
0c13f96 @asldevi -wyr mails sent to senators also
asldevi authored
373 wyr_valid = (not(tocongress) or wf.validates(i))
374 if not pf.validates(i) or not wyr_valid:
dc90d05 @asldevi little cleanup in template args
asldevi authored
375 return render.petitionform(pf, wf, is_new=False, is_draft=is_draft)
e3ccacb @asldevi draft mode for petitions
asldevi authored
376
377 p = dict(title=i.ptitle, description=i.msg, to_congress=tocongress)
378 if 'publish' in i: p['published'] = datetime.now()
379 db.update('petition', where='id=$pid', vars=locals(), **p)
380 if 'publish' in i:
dc79f3e @asldevi don't show sign form for drafts; allow only owner to share drafts; ot…
asldevi authored
381 create_first_signature(i, i.email)
5b7597d @asldevi petition edit bug fixes
asldevi authored
382 update_user_details(i)
4bd272f @asldevi petitions - delete and unsign; msg_type to differentiate error msgs; …
asldevi authored
383 raise web.seeother('/%s' % pid)
c3bc533 @simonbc Petition UI: require sign up to create a new petition, new petition page
simonbc authored
384
04757d0 @asldevi verified and unverified cookies,
asldevi authored
385 def POST_unsign(self, pid):
4bd272f @asldevi petitions - delete and unsign; msg_type to differentiate error msgs; …
asldevi authored
386 i = web.input()
978cf42 @asldevi petition - url fixes, avoid share duplicates etc.
asldevi authored
387 now = datetime.now()
388 db.update('signatory',
389 deleted=now,
c3bc533 @simonbc Petition UI: require sign up to create a new petition, new petition page
simonbc authored
390 where='petition_id=$pid and user_id=$i.user_id',
978cf42 @asldevi petition - url fixes, avoid share duplicates etc.
asldevi authored
391 vars=locals())
4bd272f @asldevi petitions - delete and unsign; msg_type to differentiate error msgs; …
asldevi authored
392 msg = 'Your signature has been removed for this petition.'
393 helpers.set_msg(msg)
394 raise web.seeother('/%s' % pid)
395
396 def POST_delete(self, pid):
978cf42 @asldevi petition - url fixes, avoid share duplicates etc.
asldevi authored
397 now = datetime.now()
398 title = db.select('petition', what='title', where='id=$pid', vars=locals())[0].title
399 db.update('petition', where='id=$pid', deleted=now, vars=locals())
4bd272f @asldevi petitions - delete and unsign; msg_type to differentiate error msgs; …
asldevi authored
400 helpers.set_msg('Petition "%s" deleted' % (title))
401 raise web.seeother('/')
c3bc533 @simonbc Petition UI: require sign up to create a new petition, new petition page
simonbc authored
402
5978bb3 @asldevi Reverting wrong merge
asldevi authored
403 def get_contacts(user, by='id'):
404 if by == 'email':
405 where = 'uemail=$user'
029241d @simonbc fieldset css was lost on style.css webchick merge, put it back in. re…
simonbc authored
406 else:
5978bb3 @asldevi Reverting wrong merge
asldevi authored
407 where = 'user_id=$user'
029241d @simonbc fieldset css was lost on style.css webchick merge, put it back in. re…
simonbc authored
408
c3bc533 @simonbc Petition UI: require sign up to create a new petition, new petition page
simonbc authored
409 contacts = db.select('contacts',
ce522cd @asldevi petitions- more form validations; names for contacts imported from gm…
asldevi authored
410 what='cname as name, cemail as email, provider',
5978bb3 @asldevi Reverting wrong merge
asldevi authored
411 where=where,
ce522cd @asldevi petitions- more form validations; names for contacts imported from gm…
asldevi authored
412 vars=locals()).list()
029241d @simonbc fieldset css was lost on style.css webchick merge, put it back in. re…
simonbc authored
413
414 if by == 'id':
5978bb3 @asldevi Reverting wrong merge
asldevi authored
415 #remove repeated emails due to multiple providers; prefer the one which has name
416 cdict = {}
417 for c in contacts:
418 if c.email not in cdict.keys():
419 cdict[c.email] = c
420 elif c.name:
421 cdict[c.email] = c
422 contacts = cdict.values()
029241d @simonbc fieldset css was lost on style.css webchick merge, put it back in. re…
simonbc authored
423
ce522cd @asldevi petitions- more form validations; names for contacts imported from gm…
asldevi authored
424 for c in contacts:
425 c.name = c.name or c.email.split('@')[0]
c3bc533 @simonbc Petition UI: require sign up to create a new petition, new petition page
simonbc authored
426
ce522cd @asldevi petitions- more form validations; names for contacts imported from gm…
asldevi authored
427 contacts.sort(key=lambda x: x.name.lower())
428 return contacts
029241d @simonbc fieldset css was lost on style.css webchick merge, put it back in. re…
simonbc authored
429
898cbd2 @asldevi share petitions functionality using the imported contacts
asldevi authored
430 class share:
0aca1e4 @asldevi share page/petition
asldevi authored
431 def GET(self, emailform=None, loadcontactsform=None):
898cbd2 @asldevi share petitions functionality using the imported contacts
asldevi authored
432 i = web.input()
0aca1e4 @asldevi share page/petition
asldevi authored
433 url = i.get('url', '/')
434 title = i.get('title', 'The good government site with teeth')
435
ce522cd @asldevi petitions- more form validations; names for contacts imported from gm…
asldevi authored
436 user_id = helpers.get_loggedin_userid()
437 contacts = get_contacts(user_id)
ea5df21 @asldevi bug fixes in petitions i210, i211, i213, i214, i215, i217 and i218
asldevi authored
438 sender = helpers.get_user_by_email(helpers.get_loggedin_email() or helpers.get_unverified_email())
029241d @simonbc fieldset css was lost on style.css webchick merge, put it back in. re…
simonbc authored
439
e3ccacb @asldevi draft mode for petitions
asldevi authored
440 page_or_petition = 'page'
441 isdraft = False
c3bc533 @simonbc Petition UI: require sign up to create a new petition, new petition page
simonbc authored
442 if not emailform:
0aca1e4 @asldevi share page/petition
asldevi authored
443 emailform = forms.emailform()
444 track_id, description = None, None
445 if url.startswith('/c/') and url != '/c/':
e1b9356 @asldevi fix for broken delete #158
asldevi authored
446 url = url.rstrip('/')
447 pid = web.lstrips(url, '/c/')
0aca1e4 @asldevi share page/petition
asldevi authored
448 p = get_petition_by_id(pid)
e3ccacb @asldevi draft mode for petitions
asldevi authored
449 isdraft = is_draft(p)
0aca1e4 @asldevi share page/petition
asldevi authored
450 description = p and p.description
e3ccacb @asldevi draft mode for petitions
asldevi authored
451 track_id = helpers.get_trackid(user_id, pid) if not isdraft else None
ea5df21 @asldevi bug fixes in petitions i210, i211, i213, i214, i215, i217 and i218
asldevi authored
452 contacts = filter(lambda c: not is_signatory(c.email, pid), contacts)
0aca1e4 @asldevi share page/petition
asldevi authored
453 page_or_petition = 'petition'
e3ccacb @asldevi draft mode for petitions
asldevi authored
454 msg = render_plain.share_mail(title, url, sender, description, isdraft, track_id)
0aca1e4 @asldevi share page/petition
asldevi authored
455 emailform.fill(subject=title, body=msg)
456
457 loadcontactsform = loadcontactsform or forms.loadcontactsform()
458
1ab473d @simonbc Petition page: The count of signers goes under the actual petition te…
simonbc authored
459 msg, msg_type = helpers.get_delete_msg()
facde92 @asldevi rename share templates; remove share link on share page
asldevi authored
460 return render.share(title, url, emailform,
0aca1e4 @asldevi share page/petition
asldevi authored
461 contacts, loadcontactsform, page_or_petition, msg)
c3bc533 @simonbc Petition UI: require sign up to create a new petition, new petition page
simonbc authored
462
0aca1e4 @asldevi share page/petition
asldevi authored
463 def POST(self):
898cbd2 @asldevi share petitions functionality using the imported contacts
asldevi authored
464 i = web.input()
0aca1e4 @asldevi share page/petition
asldevi authored
465 emailform, loadcontactsform = forms.emailform(), forms.loadcontactsform()
ce522cd @asldevi petitions- more form validations; names for contacts imported from gm…
asldevi authored
466 if emailform.validates(i):
0aca1e4 @asldevi share page/petition
asldevi authored
467 url, msg, subject = i.url, i.body, i.subject
ce522cd @asldevi petitions- more form validations; names for contacts imported from gm…
asldevi authored
468 emails = [e.strip() for e in i.emails.strip(', ').split(',')]
ea5df21 @asldevi bug fixes in petitions i210, i211, i213, i214, i215, i217 and i218
asldevi authored
469 u = helpers.get_user_by_email(helpers.get_loggedin_email() or helpers.get_unverified_email())
0aca1e4 @asldevi share page/petition
asldevi authored
470 from_address = u and "%s %s <%s>" % (u.fname, u.lname, u.email) or config.from_address
ea5df21 @asldevi bug fixes in petitions i210, i211, i213, i214, i215, i217 and i218
asldevi authored
471 for email in emails:
472 web.sendmail(from_address, email, subject, msg)
0aca1e4 @asldevi share page/petition
asldevi authored
473 page_or_petition = url.startswith('/c/') and 'petition' or 'page'
474 helpers.set_msg('Thanks for sharing this %s with your friends!' % page_or_petition)
475 raise web.seeother(url)
ce522cd @asldevi petitions- more form validations; names for contacts imported from gm…
asldevi authored
476 else:
0aca1e4 @asldevi share page/petition
asldevi authored
477 return self.GET(emailform=emailform, loadcontactsform=loadcontactsform)
63c3e20 @asldevi load responses into DB from mails; schema changes for users table;
asldevi authored
478
369dbad @asldevi petitions bug fixes, code cleanup
asldevi authored
479 app = web.application(urls, globals())
6615660 @asldevi ask user to set password after creating petition
asldevi authored
480
481 if __name__ == '__main__':
482 app.run()
Something went wrong with that request. Please try again.