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

Commit

Permalink
Implement discovery via package.json
Browse files Browse the repository at this point in the history
  • Loading branch information
chadwhitacre committed Jun 16, 2017
1 parent 840b639 commit 54db2ca
Show file tree
Hide file tree
Showing 10 changed files with 461 additions and 23 deletions.
162 changes: 162 additions & 0 deletions gratipay/utils/ghost.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import, division, print_function, unicode_literals

PACKAGE_JSON = '''\
{
"name": "ghost",
"version": "1.0.0-alpha.21",
"description": "Just a blogging platform.",
"author": "Ghost Foundation",
"homepage": "http://ghost.org",
"keywords": [
"ghost",
"blog",
"cms"
],
"repository": {
"type": "git",
"url": "git://github.com/TryGhost/Ghost.git"
},
"bugs": "https://github.com/TryGhost/Ghost/issues",
"contributors": "https://github.com/TryGhost/Ghost/graphs/contributors",
"license": "MIT",
"main": "./core/index",
"scripts": {
"start": "node index",
"test": "grunt validate --verbose",
"init": "yarn global add knex-migrator ember-cli grunt-cli && yarn install && grunt symlink && grunt init || true"
},
"engines": {
"node": "^4.5.0 || ^6.9.0"
},
"dependencies": {
"amperize": "0.3.4",
"archiver": "1.3.0",
"bcryptjs": "2.4.3",
"bluebird": "3.5.0",
"body-parser": "1.17.1",
"bookshelf": "0.10.3",
"brute-knex": "https://github.com/cobbspur/brute-knex/tarball/37439f56965b17d29bb4ff9b3f3222b2f4bd6ce3",
"bson-objectid": "1.1.5",
"chalk": "1.1.3",
"cheerio": "0.22.0",
"compression": "1.6.2",
"connect-slashes": "1.3.1",
"cookie-session": "1.2.0",
"cors": "2.8.3",
"csv-parser": "1.11.0",
"debug": "2.6.6",
"downsize": "0.0.8",
"express": "4.15.2",
"express-brute": "1.0.1",
"express-hbs": "1.0.4",
"extract-zip-fork": "1.5.1",
"fs-extra": "3.0.1",
"ghost-gql": "0.0.6",
"ghost-ignition": "2.8.11",
"ghost-storage-base": "0.0.1",
"glob": "5.0.15",
"gscan": "1.1.0",
"html-to-text": "3.2.0",
"icojs": "0.7.2",
"image-size": "0.5.2",
"intl": "1.2.5",
"intl-messageformat": "1.3.0",
"jsdom": "9.12.0",
"jsonpath": "0.2.11",
"knex": "0.12.9",
"knex-migrator": "2.0.16",
"lodash": "4.17.4",
"markdown-it": "8.3.1",
"markdown-it-footnote": "3.0.1",
"markdown-it-lazy-headers": "0.1.3",
"markdown-it-mark": "2.0.0",
"markdown-it-named-headers": "0.0.4",
"mobiledoc-dom-renderer": "0.6.5",
"moment": "2.18.1",
"moment-timezone": "0.5.13",
"multer": "1.3.0",
"mysql": "2.13.0",
"nconf": "0.8.4",
"netjet": "1.1.3",
"nodemailer": "0.7.1",
"oauth2orize": "1.8.0",
"passport": "0.3.2",
"passport-ghost": "2.3.1",
"passport-http-bearer": "1.0.1",
"passport-oauth2-client-password": "0.1.2",
"path-match": "1.2.4",
"rss": "1.2.2",
"sanitize-html": "1.14.1",
"semver": "5.3.0",
"simple-dom": "0.3.2",
"simple-html-tokenizer": "0.4.1",
"superagent": "3.5.2",
"unidecode": "0.1.8",
"uuid": "3.0.1",
"validator": "6.3.0",
"xml": "1.0.1"
},
"optionalDependencies": {
"sqlite3": "3.1.8"
},
"devDependencies": {
"grunt": "1.0.1",
"grunt-bg-shell": "2.3.3",
"grunt-cli": "1.2.0",
"grunt-contrib-clean": "1.0.0",
"grunt-contrib-compress": "1.3.0",
"grunt-contrib-copy": "1.0.0",
"grunt-contrib-jshint": "1.0.0",
"grunt-contrib-symlink": "^1.0.0",
"grunt-contrib-uglify": "2.0.0",
"grunt-contrib-watch": "1.0.0",
"grunt-cssnano": "2.1.0",
"grunt-docker": "0.0.11",
"grunt-express-server": "0.5.3",
"grunt-jscs": "3.0.1",
"grunt-mocha-cli": "2.1.0",
"grunt-mocha-istanbul": "5.0.2",
"grunt-shell": "1.3.1",
"grunt-subgrunt": "1.2.0",
"grunt-update-submodules": "0.4.1",
"istanbul": "0.4.5",
"jshint": "2.9.4",
"jshint-stylish": "2.2.1",
"matchdep": "1.0.1",
"minimist": "1.2.0",
"mocha": "3.3.0",
"nock": "9.0.13",
"rewire": "2.5.2",
"run-sequence": "1.2.2",
"should": "11.2.1",
"should-http": "0.1.1",
"sinon": "1.17.7",
"supertest": "3.0.0",
"tmp": "0.0.31"
},
"greenkeeper": {
"ignore": [
"glob",
"nodemailer",
"grunt",
"grunt-bg-shell",
"grunt-cli",
"grunt-contrib-clean",
"grunt-contrib-compress",
"grunt-contrib-copy",
"grunt-contrib-jshint",
"grunt-contrib-uglify",
"grunt-contrib-watch",
"grunt-docker",
"grunt-express-server",
"grunt-jscs",
"grunt-mocha-cli",
"grunt-mocha-istanbul",
"grunt-shell",
"grunt-subgrunt",
"grunt-update-submodules",
"sinon"
]
}
}'''
66 changes: 66 additions & 0 deletions scss/pages/npm.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#npm {

#content {
.important-thing-at-the-top {
margin-bottom: 40px;
}
.nav {
margin: 0 20% 60px;

li {
width: 50%;
text-align: center;
display: block;
float: left;
margin: 0;
padding: 0;
a {
font: normal 24px/28px $Ideal;
display: block;
height: 64px;
padding: 18px 0 0;
margin: 0;
border-bottom: 0;

.textwrap {
color: $black;
display: inline-block;
border-bottom: 4px solid transparent;
}

&:hover {
background: none;
}

&.selected {
.textwrap {
border-bottom-color: $green;
font-weight: bold;
}
}
}
&:nth-child(1) a {
padding-left: 33%;
text-align: left;
}
&:nth-child(2) a {
padding-right: 33%;
text-align: right;
}
}
}
.discovery .sorry {
margin: 40px 0;
}

form.package-json {
margin-top: 30px;
}

textarea {
height: 192px;
width: 100%;
font: 10px/12px $Mono;
}
}
}
4 changes: 3 additions & 1 deletion templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -71,18 +71,20 @@ <h1><a href="/"><img src="{{ website.asset('gratipay.svg') }}"
{% block banner %}{% if banner %}<h1>{{ banner }}</h1>{% endif %}{% endblock %}
</div>

{% if page_id != 'npm' %}
<table id="notice">
<tr>
<td>&#x2605;</td>
<td>{{ _( "{nowrap}We have {a}integrated npm{_a} into Gratipay.{_nowrap}{_nowrap}"
, nowrap='<span class="nowrap">'|safe
, _nowrap='</span>'|safe
, a='<a href="https://gratipay.news/integrating-npm-39333109419d">'|safe
, a='<a href="/on/npm/">'|safe
, _a='</a>'|safe
) }}</td>
<td>&#x2605;</td>
</tr>
</table>
{% endif %}

<div id="main">
{% block main %}
Expand Down
4 changes: 2 additions & 2 deletions tests/py/test_notifications.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,5 @@ def test_remove_notification(self):
alice.remove_notification('1234')
assert alice.notifications == ["abcd", "bcde"]

def test_blog_announcement(self):
assert 'integrating-npm-39333109419d">integrated' in self.client.GET('/').body
def test_star_announcement(self):
assert '/on/npm/">integrate' in self.client.GET('/').body
5 changes: 3 additions & 2 deletions tests/py/test_www_npm_package.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def setUp(self):

def test_anon_gets_signin_page_from_unclaimed(self):
body = self.client.GET('/on/npm/foo/').body
assert 'foo</a> npm package:' in body
assert 'foo</a> npm package on Gratipay:' in body

def test_auth_gets_send_confirmation_page_from_unclaimed(self):
self.make_participant('bob', claimed_time='now')
Expand Down Expand Up @@ -60,6 +60,7 @@ class Bulk(Harness):
def setUp(self):
self.make_package()

def test_anon_gets_signin_page(self):
def test_anon_gets_payment_flow(self):
body = self.client.GET('/on/npm/').body
assert 'Paste a package.json' in body
assert '0 out of all 1 npm package' in body
4 changes: 2 additions & 2 deletions tests/ttw/test_package_claiming.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,10 +162,10 @@ def setUp(self):
def visit_as(self, username):
self.visit('/')
self.sign_in(username)
self.visit('/on/npm/')
self.visit('/on/npm/?flow=receive')

def test_anon_gets_sign_in_prompt(self):
self.visit('/on/npm/')
self.visit('/on/npm/?flow=receive')
assert self.css('.important-button button').text == 'Sign in / Sign up'

def test_auth_without_email_gets_highlighted_link_to_email(self):
Expand Down
54 changes: 54 additions & 0 deletions tests/ttw/test_package_discovery.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import, division, print_function, unicode_literals

from gratipay.testing import BrowserHarness


class Tests(BrowserHarness):

def assertDiscovery(self):
instructions = self.css('.instructions').text
assert instructions == 'Paste a package.json to find packages to pay for:'

def test_anon_gets_discovery_page_by_default(self):
self.visit('/on/npm/')
self.assertDiscovery()

def test_auth_also_gets_discovery_page_by_default(self):
self.make_participant('alice')
self.sign_in('alice')
self.visit('/on/npm/')
self.assertDiscovery()

def test_pasting_a_package_json_works(self):
self.make_package(name='amperize', description='Amperize!')
mysql = self.make_package(name='mysql', description='MySQL!', emails=['[email protected]'])
self.make_package(name='netjet', description='Netjet!', emails=['[email protected]'])
scape = self.make_package(name='scape', description='Reject!', emails=['[email protected]'])
self.claim_package(self.make_participant('alice'), 'amperize')
self.claim_package(self.make_participant('bob'), 'mysql')
self.claim_package(self.make_participant('goat'), 'scape')

admin = self.make_admin()
mysql.team.update(name='MySQL')
mysql.team.update_review_status('approved', admin)
scape.team.update_review_status('rejected', admin)

self.visit('/on/npm/')
self.css('textarea').fill('''\
{ "dependencies": {"scape": "...", "mysql": "...", "amperize": "..."}
, "optionalDependencies": {"netjet": "...", "falafel": "..."}
}
''')
self.css('form.package-json button').click()

names = [x.text for x in self.css('.listing-name')]
assert names == ['MySQL (mysql on npm)', 'scape', 'amperize', 'netjet', 'falafel']

statuses = [x.text[3:] for x in self.css('.listing-details .status')]
assert statuses == ['Approved', 'Rejected', 'Unreviewed', 'Unclaimed']

enabled = [not x.has_class('disabled') for x in self.css('td.item')]
assert enabled == [True, True, True, True, False]
1 change: 1 addition & 0 deletions www/assets/gratipay.css.spt
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
@import "scss/pages/history";
@import "scss/pages/identities";
@import "scss/pages/team";
@import "scss/pages/npm";
@import "scss/pages/package";
@import "scss/pages/profile-edit";
@import "scss/pages/giving";
Expand Down
17 changes: 11 additions & 6 deletions www/on/npm/%package/index.html.spt
Original file line number Diff line number Diff line change
Expand Up @@ -51,17 +51,22 @@ if user.participant:
<p class="sorry important-thing-at-the-top">{{ _("No description available.") }}</p>
{% endif %}

<p class="instructions">
{{ _( 'Apply to accept payments for the {package_link} npm package:'
, package_link=('<a href="' + package.remote_human_url + '">' + package_name + '</a>')|safe
) }}
</p>

{% if user.ANON %}
<p class="instructions">
{{ _( 'Claim the {package_link} npm package on Gratipay:'
, package_link=('<a href="' + package.remote_human_url + '">' + package_name + '</a>')|safe
) }}
</p>
<div class="important-button">
{{ sign_in_using(button_class='large') }}
</div>
{% else %}
<p class="instructions">
{{ _( 'Apply to accept payments for the {package_link} npm package:'
, package_link=('<a href="' + package.remote_human_url + '">' + package_name + '</a>')|safe
) }}
</p>

{% if len(emails) == 0 %}
<p class="sorry">{{ _("No email addresses on file.") }}</p>
{% else %}
Expand Down
Loading

0 comments on commit 54db2ca

Please sign in to comment.