Skip to content
This repository has been archived by the owner on Feb 8, 2018. It is now read-only.

Changes to implement DevNet #615

Closed
wants to merge 10 commits into from
7 changes: 6 additions & 1 deletion configure-aspen.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
website.github_client_secret = os.environ['GITHUB_CLIENT_SECRET'].decode('ASCII')
website.github_callback = os.environ['GITHUB_CALLBACK'].decode('ASCII')

website.devnet_consumer_key = os.environ['DEVNET_CONSUMER_KEY'].decode('ASCII')
website.devnet_consumer_secret = os.environ['DEVNET_CONSUMER_SECRET'].decode('ASCII')
website.devnet_callback = os.environ['DEVNET_CALLBACK'].decode('ASCII')

website.twitter_consumer_key = os.environ['TWITTER_CONSUMER_KEY'].decode('ASCII')
website.twitter_consumer_secret = os.environ['TWITTER_CONSUMER_SECRET'].decode('ASCII')
website.twitter_callback = os.environ['TWITTER_CALLBACK'].decode('ASCII')
Expand All @@ -37,10 +41,11 @@


def add_stuff(request):
from gittip.elsewhere import github, twitter
from gittip.elsewhere import github, twitter, devnet
request.context['__version__'] = __version__
request.context['username'] = None
request.context['github'] = github
request.context['devnet'] = devnet
request.context['twitter'] = twitter

website.hooks.inbound_early += [add_stuff]
7 changes: 6 additions & 1 deletion gittip.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,9 @@ def local_env():
print("TWITTER_CONSUMER_KEY=QBB9vEhxO4DFiieRF68zTA", file=output)
print("TWITTER_CONSUMER_SECRET=mUymh1hVMiQdMQbduQFYRi79EYYVeOZGrhj27H59H78", file=output)
print("TWITTER_CALLBACK=http://127.0.0.1:8537/on/twitter/associate", file=output)

print("DEVNET_CONSUMER_KEY=QBB9vEhxO4DFiieRF68zTA", file=output)
print("DEVNET_CONSUMER_SECRET=mUymh1hVMiQdMQbduQFYRi79EYYVeOZGrhj27H59H78", file=output)
print("DEVNET_CALLBACK=http://127.0.0.1:8537/on/devnet/associate", file=output)

def serve():
run()
Expand Down Expand Up @@ -133,6 +135,9 @@ def run():
echo "TWITTER_CONSUMER_KEY=QBB9vEhxO4DFiieRF68zTA" >> tests/env
echo "TWITTER_CONSUMER_SECRET=mUymh1hVMiQdMQbduQFYRi79EYYVeOZGrhj27H59H78" >> tests/env
echo "TWITTER_CALLBACK=http://127.0.0.1:8537/on/twitter/associate" >> tests/env
echo "DEVNET_CONSUMER_KEY=QBB9vEhxO4DFiieRF68zTA" >> tests/env
echo "DEVNET_CONSUMER_SECRET=mUymh1hVMiQdMQbduQFYRi79EYYVeOZGrhj27H59H78" >> tests/env
echo "DEVNET_CALLBACK=http://127.0.0.1:8537/on/devnet/associate" >> tests/env

data: env
./makedb.sh gittip-test gittip-test
Expand Down
44 changes: 44 additions & 0 deletions gittip/elsewhere/devnet.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import datetime
import gittip
import requests
from aspen import json, log, Response
from aspen.utils import to_age, utc, typecheck
from gittip.elsewhere import AccountElsewhere, _resolve


class DevNetAccount(AccountElsewhere):
platform = u'devnet'


def resolve(screen_name):
return _resolve(u'devnet', u'screen_name', screen_name)


def oauth_url(website, action, then=""):
"""Return a URL to start oauth dancing with DevNet.

For GitHub we can pass action and then through a querystring. For Twitter
we can't, so we send people through a local URL first where we stash this
info in an in-memory cache (eep! needs refactoring to scale).

Not sure why website is here. Vestige from GitHub forebear?

"""
return "/on/devnet/login.html?action=%s&then=%s" % (action, then)


def get_user_info(screen_name):
"""Given a unicode, return a dict.
"""
typecheck(screen_name, unicode)
rec = gittip.db.fetchone( "SELECT user_info FROM elsewhere "
"WHERE platform='devnet' "
"AND user_info->'screen_name' = %s"
, (screen_name,)
)
if rec is not None:
user_info = rec['user_info']
else:
user_info = {"screen_name": screen_name}

return user_info
4 changes: 3 additions & 1 deletion gittip/models/elsewhere.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@ class Elsewhere(db.Model):
def resolve_unclaimed(self):
if self.platform == 'github':
out = '/on/github/%s/' % self.user_info['login']
elif self.platform == 'devnet':
out = '/on/devnet/%s/' % self.user_info['screen_name']
elif self.platform == 'twitter':
out = '/on/twitter/%s/' % self.user_info['screen_name']
else:
out = None
return out
return out
6 changes: 4 additions & 2 deletions gittip/models/participant.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,15 +153,17 @@ def change_id(self, desired_id):
raise self.IdAlreadyTaken

def get_accounts_elsewhere(self):
github_account = twitter_account = None
github_account = twitter_account = devnet_account = None
for account in self.accounts_elsewhere.all():
if account.platform == "github":
github_account = account
elif account.platform == "devnet":
devnet_account = account
elif account.platform == "twitter":
twitter_account = account
else:
raise self.UnknownPlatform(account.platform)
return (github_account, twitter_account)
return (github_account, twitter_account, devnet_account)

def get_tip_to(self, tippee):
tip = self.tips_giving.filter_by(tippee=tippee).first()
Expand Down
13 changes: 9 additions & 4 deletions gittip/participant.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,8 @@ def resolve_unclaimed(self):
out = None
elif rec['platform'] == 'github':
out = '/on/github/%s/' % rec['user_info']['login']
elif rec['platform'] == 'devnet':
out = '/on/devnet/%s/' % rec['user_info']['screen_name']
else:
assert rec['platform'] == 'twitter'
out = '/on/twitter/%s/' % rec['user_info']['screen_name']
Expand Down Expand Up @@ -192,13 +194,16 @@ def get_accounts_elsewhere(self):
assert accounts is not None
twitter_account = None
github_account = None
devnet_account = None
for account in accounts:
if account['platform'] == 'github':
github_account = account
elif account['platform'] == 'devnet':
devnet_account = account
else:
assert account['platform'] == 'twitter', account['platform']
twitter_account = account
return (github_account, twitter_account)
return (github_account, twitter_account, devnet_account)


@require_id
Expand Down Expand Up @@ -594,9 +599,9 @@ def take_over(self, account_elsewhere, have_confirmation=False):
"""Given two unicodes, raise WontProceed or return None.

This method associates an account on another platform (GitHub, Twitter,
etc.) with the Gittip participant represented by self. Every account
elsewhere has an associated Gittip participant account, even if its
only a stub participant (it allows us to track pledges to that account
DevNet, etc.) with the Gittip participant represented by self. Every
account elsewhere has an associated Gittip participant account, even if
its only a stub participant (it allows us to track pledges to that account
should they ever decide to join Gittip).

In certain circumstances, we want to present the user with a
Expand Down
2 changes: 2 additions & 0 deletions templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ <h1>
<span class="nowrap">
<a href="/on/twitter/redirect">Twitter</a>
or
<a href="/on/devnet/login.html">DevNet</a>
or
<a href="{{ github.oauth_url(website, u'opt-in') }}">GitHub</a>.
</span>
</div>
Expand Down
1 change: 1 addition & 0 deletions templates/participant.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

{% if can_tip and user.ANON %}
<h2>Sign in using <a href="/on/twitter/redirect">Twitter</a> or
<a href="/on/devnet/login.html">DevNet</a> or
<a href="{{ github.oauth_url(website, u'opt-in', username) }}">
GitHub</a> to tip {{ username }}.</h2>
{% elif can_tip %}
Expand Down
11 changes: 11 additions & 0 deletions tests/test_pages.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ def test_github_associate():
actual = serve_request('/on/github/associate').body
assert expected in actual, actual

def test_devnet_associate():
expected = "Bad request, program!"
actual = serve_request('/on/devnet/associate').body
assert expected in actual, actual

def test_twitter_associate():
expected = "Bad request, program!"
actual = serve_request('/on/twitter/associate').body
Expand Down Expand Up @@ -71,6 +76,12 @@ def test_github_proxy(requests):
actual = serve_request('/on/github/lgtest/').body
assert expected in actual, actual

def test_devnet_proxy():
with load():
expected = "<b>DevNet</b> has not joined"
actual = serve_request('/on/devnet/devnet/').body
assert expected in actual, actual


# This hits the network. XXX add a knob to skip this
def test_twitter_proxy():
Expand Down
26 changes: 25 additions & 1 deletion www/%participant_id/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
def _extract_username(tip):
if tip['platform'] == 'github':
key = 'login'
elif tip['platform'] == 'devnet':
key = 'screen_name'
else:
assert tip['platform'] == 'twitter', tip # sanity check
key = 'screen_name'
Expand Down Expand Up @@ -86,7 +88,7 @@
tip_or_pledge = "tip"
title = participant.id # used in <title>
username = participant.id # used in footer shared with on/$platform/ pages
github_account, twitter_account = participant.get_accounts_elsewhere()
github_account, twitter_account, devnet_account = participant.get_accounts_elsewhere()

# ========================================================================== ^L
{% extends templates/participant.html %}
Expand Down Expand Up @@ -793,6 +795,28 @@ <h3>Connected Accounts</h3>
<div class="account-type">Twitter</div>
</td>
</tr>
<tr>
<td class="account-type">
<img src="/assets/devnet.png" />
</td>
<td class="account-details">
{% if devnet_account is None %}
{% if not user.ANON and user.id == participant.id %}
Connect a <a href="{{ devnet.oauth_url(website, u'connect') }}">DevNet account</a>.
{% else %}
No DevNet account connected.
{% end %}
{% else %}
<a href="{{ devnet_account.user_info.get('html_url', '') }}"
><img class="avatar"
src="{{ devnet_account.user_info.get('profile_image_url_https', '/assets/%s/no-avatar.png' % __version__) }}"
/>{{ devnet_account.user_info.get('screen_name') }}
{% if devnet_account.user_info.get('name') %}({{ devnet_account.user_info.get('name') }}){% end %}
</a>
{% end %}
<div class="account-type">DevNet</div>
</td>
</tr>
<tr>
<td class="account-type">
<img src="/assets/octocat.png" />
Expand Down
Binary file added www/assets/devnet.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added www/assets/icons/devnet.12.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added www/assets/icons/devnet.16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions www/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@
<h2>Tip someone!</h3>
<form id="jump">
Enter a <select>
<option value="devnet">DevNet</option>
<option value="twitter">Twitter</option>
<option value="github">GitHub</option>
</select> username:
Expand Down
47 changes: 40 additions & 7 deletions www/on/confirm.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@

other = Participant.query.get(account.participant_id)

user_github_account, user_twitter_account = user.get_accounts_elsewhere()
other_github_account, other_twitter_account = other.get_accounts_elsewhere()
user_github_account, user_twitter_account, user_devnet_account = user.get_accounts_elsewhere()
other_github_account, other_twitter_account, other_devnet_account = other.get_accounts_elsewhere()


user_giving = user.get_dollars_giving()
Expand All @@ -40,7 +40,12 @@
combined_receiving = user_receiving + other_receiving

fmt = lambda x: '$' + str(int(round(x))) if x > 0 else '-'
username = user_info['screen_name' if account.platform == 'twitter' else 'login']
if account.platform == 'github':
username = user_info['login']
elif account.platform == 'devnet':
username = user_info['screen_name']
elif account.platform == 'twitter':
username = user_info['screen_name']

title = "Confirm"
can_tip = False
Expand Down Expand Up @@ -138,6 +143,10 @@ <h2>Now</h2>
<img src="/assets/icons/github.12.png" />
{{ user_github_account.user_info['login'] }}<br />
{% end %}
{% if user_devnet_account is not None %}
<img src="/assets/icons/devnet.12.png" />
{{ user_devnet_account['user_info']['screen_name'] }}<br />
{% end %}
{% if user_twitter_account is not None %}
<img src="/assets/icons/twitter.12.png" />
{{ user_twitter_account.user_info['screen_name'] }}<br />
Expand Down Expand Up @@ -166,6 +175,12 @@ <h2>Now</h2>
{{ other_github_account.user_info['login'] }}<br />
{% if account.platform == 'github' %}</span>{% end %}
{% end %}
{% if other_devnet_account is not None %}
<img src="/assets/icons/devnet.12.png" />
{% if account.platform == 'devnet' %}<span class="highlight">{% end %}
{{ other_devnet_account.user_info['screen_name'] }}<br />
{% if account.platform == 'devnet' %}</span>{% end %}
{% end %}
{% if other_twitter_account is not None %}
<img src="/assets/icons/twitter.12.png" />
{% if account.platform == 'twitter' %}<span class="highlight">{% end %}
Expand All @@ -187,13 +202,19 @@ <h2>After Reconnect</h2>
{% if account.platform == 'github' and user_github_account is not None %}
<span class="account-elsewhere">
<img src="/assets/icons/github.12.png" />
{{ user_github_account.user_info['login'] }}<br />
{{ user_github_account.get_user_info()['login'] }}<br />
</span>
{% end %}
{% if account.platform == 'devnet' and user_devnet_account is not None %}
<span class="account-elsewhere">
<img src="/assets/icons/devnet.12.png" />
{{ user_devnet_account.get_user_info()['screen_name'] }}<br />
</span>
{% end %}
{% if account.platform == 'twitter' and user_twitter_account is not None %}
<span class="account-elsewhere">
<img src="/assets/icons/twitter.12.png" />
{{ user_twitter_account.user_info['screen_name'] }}<br />
{{ user_twitter_account.get_user_info()['screen_name'] }}<br />
</span>
{% end %}
</td>
Expand Down Expand Up @@ -225,13 +246,19 @@ <h2>After Reconnect</h2>
{% if user_github_account is not None %}
<span class="account-elsewhere">
<img src="/assets/icons/github.12.png" />
{{ user_github_account.user_info['login'] }}<br />
{{ user_github_account.get_user_info()['login'] }}<br />
</span>
{% end %}
{% if user_devnet_account is not None %}
<span class="account-elsewhere">
<img src="/assets/icons/devnet.12.png" />
{{ user_devnet_account.get_user_info()['screen_name'] }}<br />
</span>
{% end %}
{% if user_twitter_account is not None %}
<span class="account-elsewhere">
<img src="/assets/icons/twitter.12.png" />
{{ user_twitter_account.user_info['screen_name'] }}<br />
{{ user_twitter_account.get_user_info()['screen_name'] }}<br />
</span>
{% end %}

Expand Down Expand Up @@ -276,6 +303,12 @@ <h2>After Reconnect</h2>
{{ other_github_account.user_info['login'] }}<br />
</span>
{% end %}
{% if other_devnet_account is not None and account.platform != 'devnet' %}
<span class="account-elsewhere">
<img src="/assets/icons/devnet.12.png" />
{{ other_devnet_account.user_info['screen_name'] }}<br />
</span>
{% end %}
{% if other_twitter_account is not None and account.platform != 'twitter' %}
<span class="account-elsewhere">
<img src="/assets/icons/twitter.12.png" />
Expand Down
Loading