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

Make it easier for companies to fund open source #4135

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions gratipay/librariesio.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from __future__ import absolute_import, division, print_function, unicode_literals

import re
import requests
import json


def extract_package_names(full):
lines = full.splitlines()
start = 0
end = -1
for i, line in enumerate(lines):
if not start and line.startswith('<ul class="top-level">'):
start = i
elif line.startswith('<ins class="adsbygoogle"'):
end = i
part = '\n'.join(lines[start:end-1])
return sorted(set(re.findall(r'<a href="[^"]*">(.*)</a>', part)))


def resolve(package_json):
"""Takes a package.json file contents, returns JSON.
"""
package_json = json.loads(package_json)

r = requests.get(url='http://libraries.io/npm/{name}/tree'.format(**package_json))
if r.status_code == 200:
# The package.json has a package name that also exists on npm. Assume this is that.
names = extract_package_names(r.text)
names.remove(package_json['name'])

return names
40 changes: 40 additions & 0 deletions scss/pages/fund-open-source.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#fund-open-source {

form {
text-align: right;
textarea {
width: 100%;
height: 200px;
font: normal 10pt/13pt $Mono;
}
}

.call-to-action {
border: 1px solid $gray;
border-style: solid none;
padding: 10px 0;
text-align: center;
font: bold 28px/40px $Ideal;
input {
width: 120px;
}
button {
font: normal 22px/40px $Ideal;
padding: 2px 28px;
}
.per-week {
font: normal 22px/40px $Ideal;
}
}

.libraries {
font: normal 8pt/13pt $Mono;

li {
margin: 0;
padding: 2px 4px;
list-style: none;
float: left;
}
}
}
24 changes: 19 additions & 5 deletions templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@
</script>
{% endif %}
</head>
{% set homepage = request.path.raw == '/' %}
<body id="{{ 'homepage' if homepage }}">
<body{% if page_id %} id="{{ page_id }}"{% endif %}>

<div id="wrapper">
<div id="header" class="clearfix">
Expand Down Expand Up @@ -67,8 +66,23 @@ <h1><a href="/"><img src="{{ website.asset('gratipay.svg') }}"
{% block banner %}{% if banner %}<h1>{{ banner }}</h1>{% endif %}{% endblock %}
</div>

{% if request.path.raw != '/1.0-payout' %}
{% if not user.participant or user.participant.status_of_1_0_payout == 'pending-application' %}
{% if not request.path.raw.startswith('/fund-open-source/') %}
<table id="notice">
<tr>
<td>&#x2605;</td>
<td>{{ _( "{nowrap}Gratipay is a great way to{_nowrap} {nowrap}{a}fund open source!{_a}{_nowrap}"
, nowrap='<span class="nowrap">'|safe
, _nowrap='</span>'|safe
, a='<a href="/fund-open-source/">'|safe
, _a='</a>'|safe
) }}</td>
<td>&#x2605;</td>
</tr>
</table>
{% endif %}

{% if user.participant and request.path.raw.startswith('/~/%s/' % user.participant.username) %}
{% if user.participant.status_of_1_0_payout == 'pending-application' %}
<table id="notice">
<tr>
<td>&#x2605;</td>
Expand All @@ -82,7 +96,7 @@ <h1><a href="/"><img src="{{ website.asset('gratipay.svg') }}"
<td>&#x2605;</td>
</tr>
</table>
{% elif user.participant and user.participant.status_of_1_0_payout in ('pending-review', 'pending-payout') %}
{% elif user.participant.status_of_1_0_payout in ('pending-review', 'pending-payout') %}
<table id="notice">
<tr>
<td>&#x2605;</td>
Expand Down
8 changes: 8 additions & 0 deletions tests/py/test_librariesio.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from gratipay import inventory
from gratipay.testing import Harness


class Tests(Harness):

def test_inventory_python_returns_something(self):
inventory.python('Django')
1 change: 1 addition & 0 deletions www/assets/gratipay.css.spt
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
@import "scss/pages/homepage";
@import "scss/pages/history";
@import "scss/pages/identities";
@import "scss/pages/fund-open-source";
@import "scss/pages/team";
@import "scss/pages/profile-edit";
@import "scss/pages/giving";
Expand Down
11 changes: 11 additions & 0 deletions www/assets/librariesio.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
55 changes: 55 additions & 0 deletions www/fund-open-source/index.html.spt
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
from collections import OrderedDict
[---]
title = _("Fund Open Source")
suppress_sidebar = True
page_id = 'fund-open-source'
[---]
{% extends "templates/base.html" %}
{% block head %}
<link rel="publisher" href="https://plus.google.com/104524895706770139568">
<link type="application/opensearchdescription+xml" rel="search" href="/opensearch.osdd" />
<meta name="description" content="Fund Open Source on Gratipay" />
<meta name="fb:app_id" content="229465400522758" />
<meta name="og:type" content="website" />
<meta name="og:url" content="https://gratipay.com/fund-open-source/" />
<meta name="og:title" content="Fund Open Source on Gratipay" />
<meta name="og:image" content="{{ website.asset('gratipay.opengraph.png') }}" />
{% endblock %}

{% block content %}

<p>{{ _("Gratipay is a great way to fund the open source software projects that your company or organization depends on! Keep the open source ecosystem sustainable for years to come by locating the open source projects in your technology stack, and funding them all with one simple weekly payment on Gratipay.") }}</p>

<h2>{{ _("Step 1: Analyze Your Code") }}</h2>

<p><a href="https://libraries.io/">Powered by <img src="{{ website.asset('librariesio.svg') }}" height="24"></a></p>

<p>{{ _("Paste your <code>package.json</code> for a report of your open source dependencies and their licenses." | safe) }}</p>

<p>{{ _( "Want a sample? Try the {a}<code>package.json</code> from npm itself{_a}"|safe
, a="<a class='sample' href='https://raw.githubusercontent.com/npm/npm/master/package.json'>"|safe
, _a="</a>"|safe
) }}.</p>

<form action="/fund-open-source/report" method="POST">
<input type="hidden" name="csrf_token" value="{{ csrf_token }}" />
<textarea name="package_json" autofocus></textarea>
<button class="selected larger">{{ _("Analyze") }}</button>
</form>
{% endblock %}

{% block scripts %}
<script>
// Load the example into the textarea.
$(document).ready(function() {
$('a.sample').click(function(e) {
e.preventDefault();
e.stopPropagation();
$.get(this.href, function(data) {
$('textarea').val(data);
});
return false;
});
});
</script>
{% endblock %}
33 changes: 33 additions & 0 deletions www/fund-open-source/report.spt
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
from aspen import Response
from gratipay import librariesio
[---]
if request.method != 'POST':
website.redirect('/fund-open-source/')

package_json = request.body['package_json']
names = librariesio.resolve(package_json)
suppress_sidebar = True
title = _("Your Open Source Inventory")
page_id = 'fund-open-source'
[---] text/html
{% extends "templates/base.html" %}

{% block content %}

<p><a href="https://libraries.io/">Powered by <img src="{{ website.asset('librariesio.svg') }}" height="24"></a></p>

<h2>{{ _("Step 2: Review Inventory and Set Amount") }}</h2>

<form class="call-to-action">
$<input type="amount" value="1,000">
<span class="per-week">per week</span>
<button class="selected larger">Go</button>
</form>

<ul class="libraries">
{% for name in names %}
<li><a href="/on/npm/{{ name }}/">{{ name }}</a></li>
{% endfor %}
</ul>

{% endblock %}
1 change: 1 addition & 0 deletions www/index.html.spt
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ for key, tab in tabs.items():
title = _("Teams")
suppress_sidebar = True
suppress_welcome = 'suppress-welcome' in request.cookie
page_id = 'homepage'
[---]
{% extends "templates/base.html" %}
{% block head_early %}
Expand Down