This repository has been archived by the owner on Aug 26, 2022. It is now read-only.
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Alex Buchanan
committed
Sep 27, 2010
1 parent
3d9d460
commit f919dbd
Showing
28 changed files
with
1,192 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
from datetime import datetime | ||
|
||
from django.template import defaultfilters | ||
|
||
from jingo import register | ||
|
||
|
||
@register.filter | ||
def utctimesince(time): | ||
return defaultfilters.timesince(time, datetime.utcnow()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{# vim: set ts=2 et sts=2 sw=2: #} | ||
{% extends "common/base.html" %} | ||
{% set styles = ('customercare',) %} | ||
{% set scripts = ('customercare',) %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
{# vim: set ts=2 et sts=2 sw=2: #} | ||
{% extends "customercare/base.html" %} | ||
{% set title = _('Join our Army of Awesome') %} | ||
|
||
{% block breadcrumbs %}{% endblock %} | ||
|
||
{% block content_area %} | ||
<div class="feature-contents"> | ||
<h2>Join our <br />Army of Awesome</h2> | ||
<h3>Love Firefox and have a few moments to help? Help other Firefox users on Twitter. Good things will come to those who tweet!</h3> | ||
</div> | ||
|
||
<div id="speach-bubbles"> | ||
<ol> | ||
<li class="choose">Choose a tweet below</li> | ||
<li class="signin">Sign in with Twitter</li> | ||
<li class="respond">Respond to the tweet!</li> | ||
</ol> | ||
<br style="clear:both; height: 1px" /> | ||
</div> | ||
|
||
<div id="tweetcontainer"> | ||
<div class="tweets-header"> | ||
<img src="{{ MEDIA_URL }}/img/customercare/twitter-icon.png" /><h2 class="showhide_heading" id="Where_to_ask_your_question">Choose a tweet to help</h2> | ||
</div> | ||
|
||
<br style="clear:both; height: 1px" /> | ||
|
||
<ul id="tweets"> | ||
{% for tweet in tweets %} | ||
<li class="tweet"> | ||
<a href="http://twitter.com/{{ tweet.user }}" class="avatar"><img src="{{ tweet.profile_img }}" /></a> | ||
<span><span class="twittername">{{ tweet.user }}</span><span class="time">{{ tweet.date|utctimesince }}</span> | ||
<span class="text">{{ tweet.text }}</span> | ||
</li> | ||
{% endfor %} | ||
</ul> | ||
</div> | ||
|
||
<div id="reply-modal"> | ||
{% include 'customercare/reply_modal.html' %} | ||
</div> | ||
|
||
<div id="twitter-modal"> | ||
<h2>Sign in with your Twitter account</h2> | ||
<p>Before you join the Army of Awesome, you need to log in so you can respond to tweets. You will now be redirected to Twitter to log in.</p> | ||
<a href="{{ url('customercare.twitter_auth') }}">Sign in</a> | ||
<a href="#" class="cancel">Cancel</a> | ||
</div> | ||
{% endblock %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
<div id="reply-container"> | ||
<div id="initial-tweet"> | ||
<a href="" class="avatar"><img src="" /></a> | ||
<span class="box"> | ||
<img src="{{ MEDIA_URL }}img/customercare/initial-tweet-arrow.png" alt="" id="arrow" /> | ||
<a href="" class="twittername"></a> | ||
<span class="text"></span> | ||
</span> | ||
</div> | ||
|
||
<div id="replies"> | ||
<h4>What is your reply about?</h4> | ||
<div id="accordion"> | ||
{% for resp in canned_responses %} | ||
<h3><a href="#">{{ resp.title }}</a></h3> | ||
<div> | ||
<ul class="topics"> | ||
{% for topic in resp.responses.all() %} | ||
<li> | ||
<a class="reply-topic" href="#">{{ topic.title }}</a> | ||
<span class="snippet">{{ topic.response }} #fxhelp</span> | ||
</li> | ||
{% endfor %} | ||
</ul> | ||
</div> | ||
{% endfor %} | ||
</div> | ||
|
||
|
||
<div class="hrbreak"></div> | ||
|
||
<div id="reply"> | ||
<h4>Get personal</h4> | ||
<div class="container"> | ||
<div class="character-counter">140</div> | ||
<div class="inner-container"> | ||
<img src="{{ MEDIA_URL }}img/customercare/reply-arrow.png" alt="" id="reply-arrow" /> | ||
<textarea class="reply-message" placeholder="Tweak it and make it your own. Personalized messages go a long way in helping others."></textarea> | ||
</div> | ||
|
||
<span class="submit-message">Your message was sent!</span> | ||
<input type="submit" value="Submit" name="" id="submit" class="submitButton" title="Submit"> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
from django.conf.urls.defaults import patterns, url | ||
|
||
urlpatterns = patterns('customercare.views', | ||
url(r'^$', 'landing', name='customercare.landing'), | ||
url(r'/twitter_auth', 'twitter_auth', name="customercare.twitter_auth"), | ||
url(r'', 'landing', name='customercare.landing'), | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,124 @@ | ||
from datetime import datetime | ||
from email.Utils import parsedate | ||
import json | ||
import logging | ||
from uuid import uuid4 | ||
|
||
from django import http | ||
from django.conf import settings | ||
from django.core.cache import cache | ||
|
||
import jingo | ||
import tweepy | ||
|
||
from .models import CannedCategory, Tweet | ||
|
||
|
||
log = logging.getLogger('custcare') | ||
|
||
token_cache_prefix = 'custcare_token_' | ||
key_prefix = token_cache_prefix + 'key_' | ||
secret_prefix = token_cache_prefix + 'secret_' | ||
|
||
# cookie names are duplicated in js/cusomtercare.js | ||
access_cookie_name = 'custcare_twitter_access_id' | ||
redirect_cookie_name = 'custcare_twitter_redirect_flag' | ||
|
||
|
||
def auth_factory(request): | ||
return tweepy.OAuthHandler(settings.TWITTER_CONSUMER_KEY, | ||
settings.TWITTER_CONSUMER_SECRET, | ||
'https://{0}/{1}/customercare/'.format( | ||
request.get_host(), request.locale)) | ||
|
||
|
||
def set_access_cookie(resp, id): | ||
resp.set_cookie(redirect_cookie_name, '1', httponly=True) | ||
resp.set_cookie(access_cookie_name, id, secure=True) | ||
|
||
|
||
def set_tokens(id, key, secret): | ||
cache.set(key_prefix + id, key) | ||
cache.set(secret_prefix + id, secret) | ||
|
||
|
||
def get_tokens(id): | ||
key = cache.get(key_prefix + id) | ||
secret = cache.get(secret_prefix + id) | ||
return key, secret | ||
|
||
|
||
def landing(request): | ||
"""Customer Care Landing page.""" | ||
return http.HttpResponse(landing.__doc__) | ||
|
||
canned_responses = CannedCategory.objects.all() | ||
tweets = [] | ||
for tweet in Tweet.objects.filter(locale='en')[:10]: | ||
data = json.loads(tweet.raw_json) | ||
parsed_date = parsedate(data['created_at']) | ||
date = datetime(*parsed_date[0:6]) | ||
tweets.append({ | ||
'profile_img': data['profile_image_url'], | ||
'user': data['from_user'], | ||
'text': tweet, | ||
'date': date, | ||
}) | ||
|
||
resp = jingo.render(request, 'customercare/landing.html', { | ||
'canned_responses': canned_responses, | ||
'tweets': tweets, | ||
'now': datetime.utcnow(), | ||
}) | ||
|
||
# TODO HTTP redirect flag checking? | ||
if request.COOKIES.get(redirect_cookie_name): | ||
return http.HttpResponseRedirect('https://{0}/{1}'.format( | ||
request.get_host(), request.get_full_path())) | ||
|
||
# if GET[oauth_verifier] exists, we're handling an OAuth login | ||
verifier = request.GET.get('oauth_verifier') | ||
if verifier: | ||
auth = auth_factory(request) | ||
request_key = request.COOKIES.get('request_token_key') | ||
request_secret = request.COOKIES.get('request_token_secret') | ||
if request_key and request_secret: | ||
resp.delete_cookie('request_token_key') | ||
resp.delete_cookie('request_token_secret') | ||
auth.set_request_token(request_key, request_secret) | ||
|
||
try: | ||
auth.get_access_token(verifier) | ||
except tweepy.TweepError: | ||
log.warning('Tweepy Error with verifier token') | ||
pass | ||
else: | ||
access_id = uuid4().hex | ||
set_access_cookie(resp, access_id) | ||
set_tokens(access_id, auth.access_token.key, auth.access_token.secret) | ||
|
||
return resp | ||
|
||
|
||
def twitter_post(request): | ||
# access_id = request.COOKIES.get(access_cookie_name) | ||
# if access_id: | ||
# key, secret = get_tokens(access_id) | ||
# authed = True | ||
# resp.write('key: %s sec: %s' % (key, secret)) | ||
# set_access_cookie(resp, access_id) | ||
pass | ||
|
||
|
||
def twitter_auth(request): | ||
auth = auth_factory(request) | ||
|
||
try: | ||
redirect_url = auth.get_authorization_url() | ||
except tweepy.TweepError: | ||
log.warning('Tweepy error while getting authorization url') | ||
return http.HttpReponseServerError() | ||
|
||
resp = http.HttpResponseRedirect(redirect_url) | ||
resp.set_cookie('request_token_key', auth.request_token.key, max_age=3600, secure=True) | ||
resp.set_cookie('request_token_secret', auth.request_token.secret, max_age=3600, secure=True) | ||
return resp |
Oops, something went wrong.