Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fetch sponsors at build time, show ALL non-skeevy sponsors; closes #4271 #4272

Merged
merged 8 commits into from May 22, 2020
21 changes: 21 additions & 0 deletions docs/_data/blacklist.json
@@ -0,0 +1,21 @@
[
"cheap-writing-service",
"emailmarketingservices-io",
"device-tricks1",
"my-true-media",
"yiannakis-ttafounas-ttafounas",
"writerseperhour",
"casinotop-com",
"casino-topp",
"casinoutanreg",
"supercazino-ro",
"igor-noskov",
"blue-link-seo",
"casino-online",
"domywriting",
"writemypaper4me",
"trust-my-paper",
"seowebsitetraffic-net",
"pfannen-test",
"mochajs"
]
122 changes: 122 additions & 0 deletions docs/_data/supporters.js
@@ -0,0 +1,122 @@
#!/usr/bin/env node
'use strict';

const debug = require('debug')('mocha:docs:data:supporters');
const needle = require('needle');
const blacklist = new Set(require('./blacklist.json'));

const API_ENDPOINT = 'https://api.opencollective.com/graphql/v2';

const query = `query account($limit: Int, $offset: Int, $slug: String) {
account(slug: $slug) {
orders(limit: $limit, offset: $offset) {
limit
offset
totalCount
nodes {
fromAccount {
name
slug
website
imgUrlMed: imageUrl(height:64)
imgUrlSmall: imageUrl(height:32)
type
}
totalDonations {
value
}
createdAt
}
}
}
}`;

const graphqlPageSize = 1000;

const nodeToSupporter = node => ({
name: node.fromAccount.name,
slug: node.fromAccount.slug,
website: node.fromAccount.website,
imgUrlMed: node.fromAccount.imgUrlMed,
imgUrlSmall: node.fromAccount.imgUrlSmall,
firstDonation: node.createdAt,
totalDonations: node.totalDonations.value * 100,
type: node.fromAccount.type
});

/**
* Retrieves donation data from OC
*
* Handles pagination
* @param {string} slug - Collective slug to get donation data from
* @returns {Promise<Object[]>} Array of raw donation data
*/
const getAllOrders = async (slug = 'mochajs') => {
let allOrders = [];
const variables = {limit: graphqlPageSize, offset: 0, slug};

// Handling pagination if necessary (2 pages for ~1400 results in May 2019)
while (true) {
const result = await needle(
'post',
API_ENDPOINT,
{query, variables},
{json: true}
);
const orders = result.body.data.account.orders.nodes;
allOrders = [...allOrders, ...orders];
variables.offset += graphqlPageSize;
if (orders.length < graphqlPageSize) {
debug('retrieved %d orders', allOrders.length);
return allOrders;
} else {
debug(
'loading page %d of orders...',
Math.floor(variables.offset / graphqlPageSize)
);
}
}
};

module.exports = async () => {
const orders = await getAllOrders();
// Deduplicating supporters with multiple orders
const uniqueSupporters = new Map();

const supporters = orders
.map(nodeToSupporter)
.filter(supporter => !blacklist.has(supporter.slug))
.reduce((supporters, supporter) => {
if (uniqueSupporters.has(supporter.slug)) {
// aggregate donation totals
uniqueSupporters.get(supporter.slug).totalDonations +=
supporter.totalDonations;
return supporters;
}
uniqueSupporters.set(supporter.slug, supporter);
return [...supporters, supporter];
}, [])
.sort((a, b) => b.totalDonations - a.totalDonations)
.reduce(
(supporters, supporter) => {
if (supporter.type === 'INDIVIDUAL') {
supporters.backers.push({
...supporter,
avatar: supporter.imgUrlSmall
});
} else {
supporters.sponsors.push({...supporter, avatar: supporter.imgUrlMed});
}
return supporters;
},
{sponsors: [], backers: []}
);

debug(
'found %d valid backers and %d valid sponsors (%d total)',
supporters.backers.length,
supporters.sponsors.length,
supporters.backers.length + supporters.sponsors.length
);
return supporters;
};
12 changes: 8 additions & 4 deletions docs/_includes/backers.md
@@ -1,7 +1,11 @@
## Backers

Find Mocha helpful? Become a [backer](https://opencollective.com/mochajs#support) and support Mocha with a monthly donation.
Find Mocha helpful? Become a [backer](https://opencollective.com/mochajs#support) and support Mocha with a monthly donation.

<!-- markdownlint-disable MD034 -->
{% for i in (0..29) %}[![](https://opencollective.com/mochajs/backer/{{ i }}/avatar.jpg)](https://opencollective.com/mochajs/backer/{{ i }}/website){: target="_blank" rel="noopener"}{% endfor %}
{: .image-list id="_backers" }
{% comment %}
Do not remove whitespace below!
{% endcomment %}

<ul class="image-list faded-images" id="backers">
{% for supporter in supporters.backers %}<li>{% if supporter.website %}<a href="{{ supporter.website }}" target="_blank" rel="noopener" title="{{ supporter.name }}">{% endif %}<img src="{{ supporter.avatar }}" alt="{{ supporter.name }}" />{% if supporter.website %}</a>{% endif %}</li>{% endfor %}
Munter marked this conversation as resolved.
Show resolved Hide resolved
</ul>
2 changes: 2 additions & 0 deletions docs/_includes/default.html → docs/_includes/default.liquid
Expand Up @@ -170,5 +170,7 @@ <h1>
</dd>
</dl>
</footer>

<script src="js/avatars.js"></script>
</body>
</html>
11 changes: 6 additions & 5 deletions docs/_includes/sponsors.md
Expand Up @@ -2,9 +2,10 @@

Use Mocha at Work? Ask your manager or marketing team if they'd help [support](https://opencollective.com/mochajs#support) our project. Your company's logo will also be displayed on [npmjs.com](http://npmjs.com/package/mocha) and our [GitHub repository](https://github.com/mochajs/mocha#sponsors).

<!-- markdownlint-disable MD034 -->
{% comment %}
Do not remove whitespace below!
{% endcomment %}

{% for i in (0..15) %}[![](https://opencollective.com/mochajs/sponsor/{{ i }}/avatar.png)](https://opencollective.com/mochajs/sponsor/{{ i }}/website){: target="\_blank"} {% endfor %}
{: .image-list .faded-images}

<script src="js/avatars.js"></script>
<ul class="image-list faded-images" id="sponsors">
{% for supporter in supporters.sponsors %}<li>{% if supporter.website %}<a href="{{ supporter.website }}" target="_blank" rel="noopener" title="{{ supporter.name }}">{% endif %}<img src="{{ supporter.avatar }}" alt="{{ supporter.name }}" />{% if supporter.website %}</a>{% endif %}</li>{% endfor %}
</ul>
35 changes: 23 additions & 12 deletions docs/css/style.css
Expand Up @@ -74,28 +74,39 @@ nav.badges a + a {
margin-left: 3px;
}

.image-list {
ul.image-list {
overflow: hidden;
text-align: center;
list-style: none;
column-count: 1;
padding: 0;
margin: 0;
}

.image-list a {
ul.image-list li {
border-bottom: none;
display: inline-block;
margin: 6px;
margin: 0 4px 0 4px;
max-height: 64px;
padding: 0;
}

.image-list a img {
ul.image-list li a {
display: inline-block;
}

ul.image-list li img {
margin: 0;
padding: 0;
display: block;
height: 64px;
max-height: 64px;
}

.faded-images {
background-color: #ddd;
border: 1px solid;
border-color: #ddd #ddd #ccc;
border-radius: 3px;
padding: 1em;
box-shadow: inset 0 0 10px #ccc;
ul#backers.image-list li img {
width: 32px;
height: 32px;
/* clip images to 32x32 */
clip-path: inset(0, 0, 32px, 32px);
Munter marked this conversation as resolved.
Show resolved Hide resolved
}

.faded-images img {
Expand Down
1 change: 1 addition & 0 deletions package.json
Expand Up @@ -115,6 +115,7 @@
"markdown-it-prism": "^2.0.5",
"markdown-toc": "^1.2.0",
"markdownlint-cli": "^0.22.0",
"needle": "^2.4.1",
"nps": "^5.9.12",
"nyc": "^15.0.0",
"prettier": "^1.19.1",
Expand Down