diff --git a/frontend/forms.py b/frontend/forms.py
index 20747ee3..71f8fa00 100644
--- a/frontend/forms.py
+++ b/frontend/forms.py
@@ -200,4 +200,23 @@ class EmailShareForm(forms.Form):
# allows us to return user to original page by passing it as hidden form input
# we can't rely on POST or GET since the emailshare view handles both
# and may iterate several times as it catches user errors, losing URL info
- next = forms.CharField(widget=forms.HiddenInput())
\ No newline at end of file
+ next = forms.CharField(widget=forms.HiddenInput())
+
+class FeedbackForm(forms.Form):
+ sender = forms.EmailField(widget=forms.TextInput(attrs={'size':50}))
+ subject = forms.CharField(max_length=500, widget=forms.TextInput(attrs={'size':50}))
+ message = forms.CharField(widget=forms.Textarea())
+ page = forms.CharField(widget=forms.HiddenInput())
+ notarobot = forms.IntegerField(label="Please prove you're not a robot")
+ answer = forms.IntegerField(widget=forms.HiddenInput())
+ num1 = forms.IntegerField(widget=forms.HiddenInput())
+ num2 = forms.IntegerField(widget=forms.HiddenInput())
+
+ def clean(self):
+ cleaned_data = self.cleaned_data
+ notarobot = str(cleaned_data.get("notarobot"))
+ answer = str(cleaned_data.get("answer"))
+ if notarobot!=answer:
+ raise forms.ValidationError(_("Whoops, try that sum again."))
+
+ return cleaned_data
diff --git a/frontend/templates/base.html b/frontend/templates/base.html
index 7b2fbc16..8e1a7e6b 100644
--- a/frontend/templates/base.html
+++ b/frontend/templates/base.html
@@ -25,6 +25,9 @@
+
diff --git a/frontend/urls.py b/frontend/urls.py
index 058e0c27..125d7dc5 100644
--- a/frontend/urls.py
+++ b/frontend/urls.py
@@ -5,7 +5,7 @@ from django.views.generic import ListView, DetailView
from django.contrib.auth.decorators import login_required
from regluit.core.models import Campaign
-from regluit.frontend.views import CampaignFormView, GoodreadsDisplayView, LibraryThingView, PledgeView, FAQView
+from regluit.frontend.views import CampaignFormView, GoodreadsDisplayView, LibraryThingView, PledgeView, PledgeCompleteView, PledgeCancelView, FAQView
from regluit.frontend.views import CampaignListView, DonateView, WorkListView
urlpatterns = patterns(
@@ -48,6 +48,8 @@ urlpatterns = patterns(
#may want to deprecate the following
url(r"^setup/work/(?P\d+)/$", "work", {'action':'setup_campaign'}, name="setup_campaign"),
url(r"^pledge/(?P\d+)/$", login_required(PledgeView.as_view()), name="pledge"),
+ url(r"^pledge/cancel/$", PledgeCancelView.as_view(), name="pledge_cancel"),
+ url(r"^pledge/complete/$", PledgeCompleteView.as_view(), name="pledge_complete"),
url(r"^celery/clear/$","clear_celery_tasks", name="clear_celery_tasks"),
url(r"^subjects/$", "subjects", name="subjects"),
url(r"^librarything/$", LibraryThingView.as_view(), name="librarything"),
@@ -57,4 +59,8 @@ urlpatterns = patterns(
url('^500testing/$', direct_to_template, {'template': '500.html'}),
url('^robots.txt$', direct_to_template, {'template': 'robots.txt'}),
url(r"^emailshare/$", "emailshare", name="emailshare"),
+ url(r"^feedback/$", "feedback", name="feedback"),
+ url(r"^feedback/thanks/$", TemplateView.as_view(template_name="thanks.html")),
+ url(r"^press/$", TemplateView.as_view(template_name="press.html"),
+ name="press"),
)
diff --git a/frontend/views.py b/frontend/views.py
index 79993a9b..3e71cc88 100755
--- a/frontend/views.py
+++ b/frontend/views.py
@@ -4,6 +4,7 @@ import json
import urllib
import logging
import datetime
+from random import randint
from re import sub
from itertools import islice
from decimal import Decimal as D
@@ -39,7 +40,7 @@ from regluit.core.search import gluejar_search
from regluit.core.goodreads import GoodreadsClient
from regluit.frontend.forms import UserData, ProfileForm, CampaignPledgeForm, GoodreadsShelfLoadingForm
from regluit.frontend.forms import RightsHolderForm, UserClaimForm, LibraryThingForm, OpenCampaignForm
-from regluit.frontend.forms import ManageCampaignForm, DonateForm, CampaignAdminForm, EmailShareForm
+from regluit.frontend.forms import ManageCampaignForm, DonateForm, CampaignAdminForm, EmailShareForm, FeedbackForm
from regluit.payment.manager import PaymentManager
from regluit.payment.parameters import TARGET_TYPE_CAMPAIGN, TARGET_TYPE_DONATION
from regluit.payment.paypal import Preapproval, IPN_PAY_STATUS_ACTIVE, IPN_PAY_STATUS_INCOMPLETE, IPN_PAY_STATUS_COMPLETED, IPN_PAY_STATUS_CANCELED
@@ -81,6 +82,10 @@ def work(request, work_id, action='display'):
work = get_object_or_404(models.Work, id=work_id)
editions = work.editions.all().order_by('-publication_date')
campaign = work.last_campaign()
+ try:
+ pledged = campaign.transactions().filter(user=request.user, status="ACTIVE")
+ except:
+ pledged = None
try:
pubdate = work.editions.all()[0].publication_date[:4]
except IndexError:
@@ -111,6 +116,7 @@ def work(request, work_id, action='display'):
'base_url': base_url,
'editions': editions,
'pubdate': pubdate,
+ 'pledged':pledged,
})
def manage_campaign(request, id):
@@ -294,6 +300,37 @@ class PledgeView(FormView):
response = t.reference
logger.info("PledgeView paypal: Error " + str(t.reference))
return HttpResponse(response)
+
+class PledgeCompleteView(TemplateView):
+ """A callback for PayPal to tell unglue.it that a payment transaction has completed successfully"""
+
+ template_name="pledge_complete.html"
+
+ def get_context_data(self, **kwargs):
+ # pick up all get and post parameters and display
+ context = super(PledgeCompleteView, self).get_context_data(**kwargs)
+
+ output = "pledge complete"
+ output += self.request.method + "\n" + str(self.request.REQUEST.items())
+ context["output"] = output
+
+ return context
+
+
+class PledgeCancelView(TemplateView):
+ """A callback for PayPal to tell unglue.it that a payment transaction has been canceled by the user"""
+ template_name="pledge_cancel.html"
+
+ def get_context_data(self, **kwargs):
+ # pick up all get and post parameters and display
+ context = super(PledgeCancelView, self).get_context_data(**kwargs)
+
+ output = "pledge cancel"
+ output += self.request.method + "\n" + str(self.request.REQUEST.items())
+ context["output"] = output
+
+ return context
+
class DonateView(FormView):
template_name="donate.html"
@@ -1044,3 +1081,39 @@ def emailshare(request):
form = EmailShareForm(initial={'next':next, 'message':"I'm ungluing books at unglue.it. Here's one of my favorites: "+next, "sender":sender})
return render(request, "emailshare.html", {'form':form})
+
+def feedback(request):
+ num1 = randint(0,10)
+ num2 = randint(0,10)
+ sum = num1 + num2
+
+ if request.method == 'POST':
+ form=FeedbackForm(request.POST)
+ if form.is_valid():
+ subject = form.cleaned_data['subject']
+ message = form.cleaned_data['message']
+ sender = form.cleaned_data['sender']
+ recipient = 'support@gluejar.com'
+ page = form.cleaned_data['page']
+ message = "<<>>"+message
+ send_mail(subject, message, sender, [recipient])
+
+ return render(request, "thanks.html", {"page":page})
+
+ else:
+ num1 = request.POST['num1']
+ num2 = request.POST['num2']
+
+ else:
+ if request.user.is_authenticated():
+ sender=user.email;
+ else:
+ sender=''
+ try:
+ page = request.GET['page']
+ except:
+ page='/'
+ form = FeedbackForm(initial={"sender":sender, "subject": "Feedback on page "+page, "page":page, "num1":num1, "num2":num2, "answer":sum})
+
+ return render(request, "feedback.html", {'form':form, 'num1':num1, 'num2':num2})
+
diff --git a/static/css/campaign.css b/static/css/campaign.css
index 56c7a159..511db518 100755
--- a/static/css/campaign.css
+++ b/static/css/campaign.css
@@ -130,6 +130,9 @@
padding: 0;
cursor: pointer;
}
+.book-detail-info > div.layout div.btn_support.modify input {
+ background: url("/static/images/btn_bg_grey.png") 0 0 no-repeat;
+}
.book-detail-info .btn_wishlist span {
text-align: right;
}
diff --git a/static/css/documentation.css b/static/css/documentation.css
index e5b28990..109b086d 100644
--- a/static/css/documentation.css
+++ b/static/css/documentation.css
@@ -188,6 +188,7 @@ dt {
}
dd {
margin: 0;
+ padding-bottom: 7px;
}
.doc ol li {
margin-bottom: 7px;
@@ -198,3 +199,36 @@ dd {
.collapse ul {
display: none;
}
+/* items on press page */
+.presstoc {
+ overflow: auto;
+ clear: both;
+ padding-bottom: 10px;
+}
+.presstoc div {
+ float: left;
+ padding-right: 15px;
+}
+.presstoc div.pressemail {
+ border: solid 2px #3d4e53;
+ padding: 5px;
+ -moz-border-radius: 7px 7px 7px 7px;
+ -webkit-border-radius: 7px 7px 7px 7px;
+ border-radius: 7px 7px 7px 7px;
+ -moz-border-radius: 7px 7px 7px 7px;
+ -webkit-border-radius: 7px 7px 7px 7px;
+ border-radius: 7px 7px 7px 7px;
+}
+.pressimages {
+ clear: both;
+}
+.pressimages .outer {
+ clear: both;
+}
+.pressimages .outer div {
+ float: left;
+ width: 25%;
+ padding-bottom: 10px;
+ display: table-cell;
+ margin: auto 0;
+}
diff --git a/static/css/landingpage.css b/static/css/landingpage.css
index 890a208c..3835a4cf 100644
--- a/static/css/landingpage.css
+++ b/static/css/landingpage.css
@@ -141,14 +141,19 @@
height: 24px;
line-height: 24px;
width: 24px;
- -moz-border-radius: 12px 12px 12px 12px;
- -webkit-border-radius: 12px 12px 12px 12px;
- border-radius: 12px 12px 12px 12px;
- -moz-border-radius: 12px 12px 12px 12px;
- -webkit-border-radius: 12px 12px 12px 12px;
- border-radius: 12px 12px 12px 12px;
- border: solid 4px #3d4e53;
+ -moz-border-radius: 24px 24px 24px 24px;
+ -webkit-border-radius: 24px 24px 24px 24px;
+ border-radius: 24px 24px 24px 24px;
+ -moz-border-radius: 24px 24px 24px 24px;
+ -webkit-border-radius: 24px 24px 24px 24px;
+ border-radius: 24px 24px 24px 24px;
+ -moz-box-shadow: -1px 1px #3d4e53;
+ -webkit-box-shadow: -1px 1px #3d4e53;
+ box-shadow: -1px 1px #3d4e53;
+ border: solid 3px white;
text-align: center;
+ color: white;
+ background: #3d4e53;
font-size: 17px;
z-index: 5000;
margin-top: -12px;
diff --git a/static/css/sitewide.css b/static/css/sitewide.css
index e698c547..fd8fedd7 100644
--- a/static/css/sitewide.css
+++ b/static/css/sitewide.css
@@ -35,6 +35,42 @@ body {
font-family: "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", Arial, Helvetica, sans-serif;
color: #3d4e53;
}
+#feedback {
+ /* remove after alpha? */
+
+ position: fixed;
+ top: 50%;
+ left: 0;
+ z-index: 500;
+}
+#feedback p {
+ /* see http://scottgale.com/blog/css-vertical-text/2010/03/01/ */
+
+ writing-mode: tb-rl;
+ -webkit-transform: rotate(90deg);
+ -moz-transform: rotate(90deg);
+ -o-transform: rotate(90deg);
+ white-space: nowrap;
+ display: block;
+ bottom: 0;
+ width: 160px;
+ height: 26px;
+ -moz-border-radius: 32px 32px 32px 32px;
+ -webkit-border-radius: 32px 32px 32px 32px;
+ border-radius: 32px 32px 32px 32px;
+ background: #8dc63f;
+ margin-bottom: 0;
+ text-align: center;
+ margin-left: -67px;
+}
+#feedback p a {
+ color: white;
+ font-size: 24px;
+ font-weight: normal;
+}
+#feedback p a:hover {
+ color: #3d4e53;
+}
a {
font-weight: bold;
font-size: 13px;
diff --git a/static/images/btn_bg_grey.png b/static/images/btn_bg_grey.png
new file mode 100644
index 00000000..15a3cd92
Binary files /dev/null and b/static/images/btn_bg_grey.png differ
diff --git a/static/less/campaign.less b/static/less/campaign.less
index d13862d7..41e60ba9 100644
--- a/static/less/campaign.less
+++ b/static/less/campaign.less
@@ -151,6 +151,10 @@
padding:0;
cursor:pointer;
}
+
+ &.modify input {
+ background:url("@{image-base}btn_bg_grey.png") 0 0 no-repeat;
+ }
}
}
diff --git a/static/less/documentation.less b/static/less/documentation.less
index bd814b15..8c476b21 100644
--- a/static/less/documentation.less
+++ b/static/less/documentation.less
@@ -124,6 +124,7 @@ dt {
dd {
margin: 0;
+ padding-bottom: 7px;
}
.doc ol li {
@@ -136,4 +137,36 @@ dd {
.collapse ul {
display: none;
+}
+
+/* items on press page */
+.presstoc {
+ div {
+ float: left;
+ padding-right: 15px;
+
+ &.pressemail {
+ border: solid 2px @text-blue;
+ padding: 5px;
+ .border-radius(7px, 7px, 7px, 7px);
+ }
+ }
+ overflow: auto;
+ clear: both;
+ padding-bottom: 10px;
+}
+
+.pressimages {
+ .outer {
+ clear: both;
+
+ div {
+ float: left;
+ width: 25%;
+ padding-bottom: 10px;
+ display: table-cell;
+ margin: auto 0;
+ }
+ }
+ clear: both;
}
\ No newline at end of file
diff --git a/static/less/landingpage.less b/static/less/landingpage.less
index 4125eadd..bd04be30 100644
--- a/static/less/landingpage.less
+++ b/static/less/landingpage.less
@@ -92,9 +92,14 @@
float: right;
.height(24px);
width: 24px;
- .border-radius(12px, 12px, 12px, 12px);
- border: solid 4px @text-blue;
+ .border-radius(24px, 24px, 24px, 24px);
+ -moz-box-shadow: -1px 1px @text-blue;
+ -webkit-box-shadow: -1px 1px @text-blue;
+ box-shadow: -1px 1px @text-blue;
+ border: solid 3px white;
text-align: center;
+ color: white;
+ background: @text-blue;
font-size: 17px;
z-index:5000;
margin-top: -12px;
diff --git a/static/less/sitewide.less b/static/less/sitewide.less
index d6039d62..eb1990b0 100644
--- a/static/less/sitewide.less
+++ b/static/less/sitewide.less
@@ -32,6 +32,41 @@ body{
color:@text-blue;
}
+#feedback {
+ /* remove after alpha? */
+ position: fixed;
+ top: 50%;
+ left: 0;
+ z-index:500;
+
+ p {
+ /* see http://scottgale.com/blog/css-vertical-text/2010/03/01/ */
+ a {
+ color:white;
+ font-size:24px;
+ font-weight:normal;
+
+ &:hover {
+ color: @text-blue;
+ }
+ }
+ writing-mode:tb-rl;
+ -webkit-transform:rotate(90deg);
+ -moz-transform:rotate(90deg);
+ -o-transform: rotate(90deg);
+ white-space:nowrap;
+ display:block;
+ bottom:0;
+ width:160px;
+ height:26px;
+ .border-radius(32px, 32px, 32px, 32px);
+ background: @call-to-action;
+ margin-bottom: 0;
+ text-align: center;
+ margin-left: -67px;
+ }
+}
+
a {
font-weight:bold;
font-size:13px;