Changeset - 6fe13959a3b3
[Not reviewed]
3 2 4
Brett Smith (brett) - 7 years ago 2016-12-02 17:50:21
brett@sfconservancy.org
supporter: Support donors upgrading to supporters.

With a valid URL, a past donor can upgrade to a supporter by donating
the rest of the amount. Django validates the data and, if it passes,
puts it in the form. The JavaScript does most of the work from there.
8 files changed with 49 insertions and 5 deletions:
0 comments (0 inline, 0 general)
www/conservancy/__init__.py
Show inline comments
 
import hashlib
 

	
 
from django.conf import settings
 
from django.shortcuts import render_to_response
 
from django.template import RequestContext
 

	
 
HASH_ENCODING = 'utf-8'
 

	
 
def render_template_with_context(request, template_path, context_dict):
 
    return render_to_response(template_path, context_dict,
 
                              context_instance=RequestContext(request))
 

	
 
def param_if_valid(params, param_name, hash_param_name, default=None):
 
    try:
 
        seed = settings.CONSERVANCY_SECRET_KEY
 
        param_value = params[param_name]
 
        param_bytes = param_value.encode(HASH_ENCODING)
 
        given_hash = params[hash_param_name]
 
    except (AttributeError, KeyError, UnicodeEncodeError):
 
        return default
 
    good_hash = hashlib.sha256()
 
    good_hash.update(seed)
 
    good_hash.update(param_bytes)
 
    if given_hash == unicode(good_hash.hexdigest()):
 
        return param_value
 
    else:
 
        return default
www/conservancy/apps/supporter/__init__.py
Show inline comments
 
new file 100644
www/conservancy/apps/supporter/urls.py
Show inline comments
 
new file 100644
 
from django.conf.urls import patterns
 

	
 
INDEX_VIEW = 'conservancy.apps.supporter.views.index'
 
pattern_pairs = [(r'^/?$', INDEX_VIEW)]
 
pattern_pairs.extend(
 
    (r'^{}(?:\.html|/|)$'.format(basename), INDEX_VIEW)
 
    for basename in ['index', '2015-supporter-appeal', '2016-supporter-appeal']
 
)
 
pattern_pairs.append((r'', 'conservancy.static.views.index'))
 

	
 
urlpatterns = patterns('', *pattern_pairs)
www/conservancy/apps/supporter/views.py
Show inline comments
 
new file 100644
 
import conservancy
 

	
 
def index(request):
 
    partial_amount = conservancy.param_if_valid(request.GET, 'upgrade', 'upgrade_id', 0)
 
    context = {
 
        'partial_amount': partial_amount,
 
        'minimum_amount': 120 - partial_amount,
 
    }
 
    return conservancy.render_template_with_context(request, "supporter/index.html", context)
www/conservancy/static/js/supporter-page.js
Show inline comments
...
 
@@ -128,72 +128,76 @@ $(document).ready(function() {
 
            errorElement.removeClass("form-error").addClass("form-error-show");
 
        }
 
    });
 
    var validateFormAtSubmission = function(element, event) {
 
            var valid = element.hasClass("valid");
 
            if (! valid) {
 
                $("#form-correction-needed").removeClass("form-error").addClass("form-error-show")
 
                                        .css("font-weight", "bold").css("font-size", "150%");
 
	        event.preventDefault();
 
            } else {
 
                $("#form-correction-needed").removeClass("form-error-show").addClass("form-error");
 
            }
 
    };
 
    $(".supporter-form-submit#monthly").click(function (event) {
 
        validateFormAtSubmission($(".supporter-form#monthly input#amount"), event);
 
    });
 
    $(".supporter-form-submit#annual").click(function (event) {
 
        validateFormAtSubmission($(".supporter-form#annual input#amount"), event);
 
    });
 
    $(".supporter-form-submit#renewal").click(function (event) {
 
        validateFormAtSubmission($(".supporter-form#renewal input#amount"), event);
 
    });
 
    $(".dinner-form-submit").click(function (event) {
 
        validateFormAtSubmission($(".dinner-form input#amount"), event);
 
    });
 

	
 
    var selectSupportType = function(event) {
 
        var $selectedLink = $(event.target);
 
        $(".supporter-type-selector a").removeClass("supporter-type-selector-selected");
 
        $selectedLink.addClass("supporter-type-selector-selected");
 
        $(".supporter-type-selection").each(function(index, element) {
 
            var $element = $(element);
 
            if (event.target.href.endsWith("#" + element.id)) {
 
                $element.show();
 
            } else {
 
                $element.hide();
 
            }
 
        });
 
        $("#form-correction-needed").removeClass("form-error-show").addClass("form-error");
 
        return false;
 
    };
 
    $(".supporter-type-selector a").bind("click", selectSupportType);
 

	
 
    var selectSupportTypeFromHash = function() {
 
        return supportTypeSelector(window.location.hash).click();
 
    };
 
    $window.bind("hashchange", selectSupportTypeFromHash);
 
    var $selectorLink = selectSupportTypeFromHash();
 
    if ($selectorLink.length === 0) {
 
    if (parseInt($("form#annual").upgradeFromAmount) > 0) {
 
        supportTypeSelector("#annual").click();
 
        $(".supporter-type-selector").hide();
 
    }
 
    else if ($selectorLink.length === 0) {
 
        supportTypeSelector("#annual").click();
 
    }
 

	
 
    $( ".footnote-mark" ).tooltip({
 
        items: "a",
 
        hide: { duration: 5000 },
 
        position: {
 
            my: "center bottom-20",
 
            at: "center left",
 
            using: function( position, feedback ) {
 
                $( this ).css( position );
 
                $( "<div>" )
 
                    .addClass( "arrow" )
 
                    .addClass( feedback.vertical )
 
                    .addClass( feedback.horizontal )
 
                    .appendTo( this );
 
            }
 
        },
 
        content: function() {
 
            return $('.footnote-1-text').text();
 
        }
 
    });
 
});
www/conservancy/static/supporter/2015-supporter-appeal.html
Show inline comments
 
deleted file
www/conservancy/static/supporter/index.html
Show inline comments
 
deleted file
www/conservancy/templates/supporter/index.html
Show inline comments
 
file renamed from www/conservancy/static/supporter/2016-supporter-appeal.html to www/conservancy/templates/supporter/index.html
...
 
@@ -16,105 +16,106 @@
 
<h3 class="donate-box-highlight">Become a Supporter Now:</h3>
 

	
 
<p>Support us now!</p>
 

	
 
<h4><a href="#annual"><span class="donate-box-highlight">Annual supporter</span> via PayPal, ACH, or credit card.</a></h4>
 
<h4><a href="#monthly"><span class="donate-box-highlight">Monthly supporter</span> via PayPal, ACH, or credit card.</a></h4>
 
<h4><a href="#renewal"><span class="donate-box-highlight">Renewing Annual supporter</span> via PayPal, ACH, or credit card.</a></h4>
 
   
 
<span class="donate-box-highlight">Other annual supporters methods:</span>
 
<div class="toggle-unit">
 
    <h4 class="toggle-control" data-text="Wire Transfer" 
 
    data-expanded-text="Wire Transfer:">Wire Transfer</h4>
 
    <div class="toggle-content">
 
       Contact <a href="mailto:accounting@sfconservancy.org">Conservancy
 
            by email</a><br/> for wire transfer instructions.<br/>
 
            Include  currency &amp; country.<br/>
 
    </div><!-- /.toggle-content -->
 
</div><!-- /.toggle.unit -->
 

	
 
<div class="toggle-unit">
 
    <h4 class="toggle-control" data-text="Paper Check" 
 
    data-expanded-text="Paper Check:">Paper Check</h4>
 
    <div class="toggle-content">
 
    Send paper check for $120 to:<br/>
 
    Software Freedom Conservancy, Inc.<br/>
 
    137 MONTAGUE ST  STE 380<br/>
 
    BROOKLYN, NY 11201-3548 &nbsp; USA<br/>
 
    Please write <q>SUPPORTER</q>, t-shirt size, if you are renewing, and if
 
    you want public acknowledgment in memo line. 
 
    </div><!-- /.toggle-content -->
 
</div><!-- /.toggle.unit -->
 

	
 
<p><a href="/donate">Even More Ways to Donate</a></p>
 
<!-- Flattr end -->
 
</td></tr></table>
 
</div>
 
<div class="content-with-donate-sidebar">
 
  <h1 class="appeal"><img class="appeal-header" alt="Become a Conservancy Supporter!" src="/img/conservancy-supporter-header.png"/></h1>
 

	
 
  
 
<div class="supporter-type-selector">
 
  <strong>Become a Supporter Now:</strong>   <a id="annualSelector" href="#annual">Annual</a> | <a id="monthlySelector" href="#monthly">Monthly</a> | <a id="renewalSelector" href="#renewal">Annual Renew</a></div>
 
<div id="annual" class="supporter-type-selection">
 
<h3>Join as an Annual Supporter</h3>
 
<a id="annual"></a>
 
<p><strong>Note:</strong> annual supporter is not an automatic renewal
 
  relationship.  If you join today, you'll receive an email in about one year to remind you to
 
  optionally renew.</p>
 
<form id="annual" class="supporter-form" action="https://www.paypal.com/cgi-bin/webscr" method="post" name="supporter">
 
<form id="annual" class="supporter-form" action="https://www.paypal.com/cgi-bin/webscr" method="post" name="supporter"
 
      data-upgrade-from-amount="{{ partial_amount }}">
 
<div class="supporter-form-inputs">
 
            <input type="hidden" name="return" value="https://sfconservancy.org/supporter/thank-you.html" />
 
            <input type="hidden" name="cmd" value="_xclick" />
 
            <input type="hidden" name="business" value="supporter@sfconservancy.org" />
 
            <input type="hidden" name="item_name" value="Conservancy Supporter, Annual" />
 
            <input id="no_shipping" type="hidden" name="no_shipping" value="0" />
 
  <label for="amount"><strong>Amount:</strong> $</label>
 
  <input id="amount" type="number" name="amount" size="7" min="120" value="120" />
 
  <input id="amount" type="number" name="amount" size="7" min="{{ minimum_amount }}" value="{{ minimum_amount }}" />
 
  <span id="error" class="form-error-show">$120 is a minimum for Conservancy
 
  Supporters.  <a href="/donate">Donate smaller amounts here</a>.</span><br/>
 

	
 
                      <label for="wantGift"><strong>Do you want to receive a t-shirt? </strong></label>
 
                      <input type="radio" name="on0" value="wantGiftYes" />Yes
 
                      <input type="radio" checked="checked" name="on0" value="wantGiftNo" />No
 
                      <br />
 
                      <span class="t-shirt-size-selector">
 
                      <label for="tShirtSize"><strong>T-shirt size: </strong></label>
 
                      <select name="os0" id="os0">
 
                        <option name="os0" id="os0" value="MenS">Men's S</option>
 
                        <option name="os0" id="os0" value="MenM">Men's M</option>
 
                        <option name="os0" id="os0" value="MenL">Men's L</option>
 
                        <option name="os0" id="os0" value="MenXL">Men's XL</option>
 
                        <option name="os0" id="os0" value="Men2XL">Men's 2XL</option>
 
                        <option name="os0" id="os0" value="StandardLadiesS">Standard Ladies' S</option>
 
                        <option name="os0" id="os0" value="StandardLadiesM">Standard Ladies' M</option>
 
                        <option name="os0" id="os0" value="StandardLadiesL">Standard Ladies' L</option>
 
                         <option name="os0" id="os0" value="StandardLadiesXL">Standard Ladies' XL</option>
 
                        <option name="os0" id="os0" value="FittedLadiesS">Fitted Ladies' S</option>
 
                        <option name="os0" id="os0" value="FittedLadiesM">Fitted Ladies' M</option>
 
                        <option name="os0" id="os0" value="FittedLadiesL">Fitted Ladies' L</option>
 
                         <option name="os0" id="os0" value="FittedLadiesXL">Fitted Ladies' XL</option>
 
                      </select><br/></span>
 
                      <label for="publicAck"><strong>
 
                          Should we <a href="/sponsors#supporters">list you publicly</a> as a Conservancy Supporter? </strong></label>
 
                      <input type="radio" checked="checked" name="on1" value="publicAckYes" />Yes
 
                      <input type="radio" name="on1" value="publicAckNo" />No<br/>
 
            
 
                      <label for="joinList"><strong>Join Conservancy's
 
                      Low-Traffic Announcement Email List? </strong></label>
 
                      <input type="radio" checked="checked" name="os1" value="joinListYes" />Yes
 
                      <input type="radio" name="os1" value="joinListNo" />No<br/>
 
                      <br />
 
                      <br /></div>
 
                      <div id="annual" class="supporter-form-submit">
 
                      <input type="image"
 
                             src="/img/supporter-payment-button-annual.png"
 
                             height="81" width="188"
 
                             border="0" name="submit" alt="Become an Annual Supporter Now!">
 
                      <img alt="" border="0" src="https://www.paypalobjects.com/en_US/i/scr/pixel.gif" width="1" height="1">
 
<br/><br/><small>Button above redirects to PayPal's site for credit
 
        card, bank account or PayPal balance payment methods.  Select options first.</small>
 
                      </div>
 
</form>
 
</div>
 
<div id="monthly" class="supporter-type-selection">
 
<h3>Join as an Monthly Supporter</h3>
0 comments (0 inline, 0 general)