Skip to content
Merged
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
Binary file added public/brand/users/anesthesiasimulation.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 public/brand/users/atomicateam.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 public/brand/users/bgu-aidnd.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 modified public/brand/users/cmu-db.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 modified public/brand/users/codecentric.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified public/brand/users/emsl-computing.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 modified public/brand/users/gemseo.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 public/brand/users/ibm.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 modified public/brand/users/icb-dcm.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 modified public/brand/users/icrar.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified public/brand/users/lanl.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 modified public/brand/users/llnl.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 public/brand/users/nanograv.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 modified public/brand/users/nasa.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 modified public/brand/users/national-digital-twin.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 modified public/brand/users/openmdao.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 modified public/brand/users/openworm.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 public/brand/users/paypal.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 modified public/brand/users/philipmorrisintl.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 modified public/brand/users/qubole.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 modified public/brand/users/sandialabs.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 public/brand/users/seduceproject.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 modified public/brand/users/smtorg.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 public/brand/users/terrapower.png
Binary file modified public/brand/users/wwu-mmll.png
2 changes: 1 addition & 1 deletion src/components/content.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export function mountUsedBy(root: ParentNode = document): void {
<a class="used-by" href="https://github.com/${d.repo}" target="_blank" rel="noopener"
title="${d.name} uses ${d.uses} in ${d.repo}">
<img class="used-by__logo" src="/brand/users/${d.login.toLowerCase()}.png"
alt="${d.name}" width="52" height="52" loading="lazy" decoding="async">
alt="${d.name}" height="68" loading="lazy" decoding="async">
</a>`,
).join('')
}
Expand Down
61 changes: 50 additions & 11 deletions src/data/used-by.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,28 @@
/**
* Organisations that build on these packages.
*
* Every entry was verified against GitHub's live dependency graph, one
* repository at a time: either the SBOM for that repository lists the package,
* or its manifest on the default branch declares it. Entries that only appeared
* in the dependents *index* did not survive — that index lags, and several of
* them had since dropped the dependency or commented it out. Anything that
* could not be confirmed was left off, however good the name would have looked.
* Most entries were verified against the package manifests on the repository's
* default branch: a `requirements*.txt`, `setup.py`, `setup.cfg` or
* `pyproject.toml` that names the package. Entries that only appeared in
* GitHub's dependents *index* did not survive — that index lags, and several of
* them had since dropped the dependency or commented it out.
*
* Only pydoe and pyswarm have organisational users. mcerp and soerp have
* dependents, but individuals rather than organisations.
* The exception is the block marked below, taken from the "Who uses PyDOE?"
* page in the pydoe documentation. Those repositories no longer declare pyDOE
* on their default branch, so they are kept on the strength of that page rather
* than a manifest we can point at today.
*
* Logos are the organisations' own GitHub avatars, desaturated at build time
* rather than in CSS so the strip stays even and nothing flashes colour while
* it loads.
* pyDOE2 and pyDOE3 count as pyDOE: both forks have been merged back and are
* maintained here, so a manifest naming either one is a pyDOE user.
*
* pyswarm is matched on a word boundary so that `pyswarms` — an unrelated
* package by a different author — never counts.
*
* Logos are the organisations' own marks, desaturated and normalised to a single
* height by `tools/build-user-logos.py`, so the strip stays even and nothing
* flashes colour while it loads. Orgs whose avatar is a default identicon, a
* photograph, or an image that turns to mush in greyscale are left off rather
* than shown badly.
*/

export interface Dependent {
Expand Down Expand Up @@ -43,4 +52,34 @@ export const USED_BY: Dependent[] = [
{ login: 'ICB-DCM', name: 'ICB-DCM', repo: 'ICB-DCM/pyPESTO', uses: 'pyswarm' },
{ login: 'openworm', name: 'OpenWorm', repo: 'openworm/ChannelWorm', uses: 'pyswarm' },
{ login: 'wwu-mmll', name: 'Medical Machine Learning Lab', repo: 'wwu-mmll/photonai', uses: 'pyDOE' },

// University research groups.
{
login: 'industrial-optimization-group',
name: 'Multiobjective Optimization Group, University of Jyväskylä',
repo: 'industrial-optimization-group/pyRVEA',
uses: 'pyDOE',
},
{
login: 'Curtin-Timescales-of-Mineral-Systems',
name: 'Timescales of Mineral Systems, Curtin University',
repo: 'Curtin-Timescales-of-Mineral-Systems/UPb-Unmixer',
uses: 'soerp',
},
{ login: 'BGU-AiDnD', name: 'AiDnD, Ben-Gurion University', repo: 'BGU-AiDnD/Debugger', uses: 'pyswarm' },
{ login: 'SeduceProject', name: 'SeDuCe', repo: 'SeduceProject/seduce_ml', uses: 'mcerp' },
{ login: 'atomicateam', name: 'Atomica', repo: 'atomicateam/atomica', uses: 'pyswarm' },
{
login: 'AnesthesiaSimulation',
name: 'Anesthesia Simulation',
repo: 'AnesthesiaSimulation/Python_Anesthesia_Simulator',
uses: 'pyswarm',
},

// From the "Who uses PyDOE?" page in the pydoe docs. Not currently declared
// in these repositories' manifests — see the note at the top of this file.
{ login: 'ibm', name: 'IBM', repo: 'ibm/simulai', uses: 'pyDOE' },
{ login: 'paypal', name: 'PayPal', repo: 'paypal/gators', uses: 'pyDOE' },
{ login: 'terrapower', name: 'TerraPower', repo: 'terrapower/armi', uses: 'pyDOE' },
{ login: 'nanograv', name: 'NANOGrav', repo: 'nanograv/holodeck', uses: 'pyDOE' },
]
13 changes: 9 additions & 4 deletions src/styles/components.css
Original file line number Diff line number Diff line change
Expand Up @@ -863,15 +863,20 @@
.used-by {
display: inline-flex;
align-items: center;
padding: 0.4rem 1.15rem;
padding: 0.4rem 1.35rem;
}

/*
* Every logo is delivered at one height, so the strip needs a single `height`
* here and nothing else. The width cap is for the occasional wordmark that is
* much wider than it is tall.
*/
.used-by__logo {
width: auto;
height: 52px;
max-width: 170px;
height: 68px;
max-width: 210px;
object-fit: contain;
opacity: 0.55;
opacity: 0.62;
transition: opacity var(--dur-base) var(--ease-out);
}

Expand Down
84 changes: 84 additions & 0 deletions tools/build-user-logos.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
"""
Build the "Used by" logo strip.

Each source logo — an organisation's GitHub avatar, or replacement artwork
dropped into the source directory — is flattened onto white, desaturated, and
scaled to one content height. Desaturating here rather than in CSS keeps the
strip even and stops anything flashing colour while it loads; the single height
lands every logo on one optical line instead of a row of mismatched sizes.

python tools/build-user-logos.py <source-dir> [--out public/brand/users]

Source files are named `<github-login>.<ext>`, lowercased; the site looks the
logo up by login. Orgs whose avatar is a default identicon, a photograph, or an
image that turns to mush in greyscale are better left out than shown badly.
"""

import argparse
import os
import sys

import cv2
import numpy as np

HEIGHT = 128 # content height in px — 2x the CSS height, for retina
MAX_WIDTH = 420 # width cap, so a long wordmark cannot take over the strip


def load(path):
"""Read an image path that may contain non-ASCII characters on Windows."""
im = cv2.imdecode(np.fromfile(path, dtype=np.uint8), cv2.IMREAD_UNCHANGED)
if im is None:
raise SystemExit(f"unreadable: {path}")
if im.ndim == 2:
im = cv2.cvtColor(im, cv2.COLOR_GRAY2BGR)
if im.shape[2] == 4:
return im[:, :, :3], im[:, :, 3]
return im, None


def process(src, dest):
bgr, alpha = load(src)

# Avatars ship an alpha channel that only rounds the corners, and the page
# behind the strip is white — so flatten onto white and keep the square.
if alpha is not None:
a = (alpha.astype(np.float32) / 255.0)[:, :, None]
bgr = (bgr.astype(np.float32) * a + 255.0 * (1 - a)).astype(np.uint8)

gray = cv2.cvtColor(bgr, cv2.COLOR_BGR2GRAY)

h, w = gray.shape
scale = min(HEIGHT / h, MAX_WIDTH / w)
size = (max(1, round(w * scale)), max(1, round(h * scale)))
interp = cv2.INTER_AREA if scale < 1 else cv2.INTER_CUBIC
gray = cv2.resize(gray, size, interpolation=interp)

ok, buf = cv2.imencode(".png", cv2.cvtColor(gray, cv2.COLOR_GRAY2BGR),
[cv2.IMWRITE_PNG_COMPRESSION, 9])
if not ok:
raise SystemExit(f"could not encode: {dest}")
buf.tofile(dest)
return size


def main():
ap = argparse.ArgumentParser(description=__doc__)
ap.add_argument("source", help="directory of <github-login>.<ext> logo files")
ap.add_argument("--out", default=os.path.join("public", "brand", "users"))
args = ap.parse_args()

os.makedirs(args.out, exist_ok=True)
names = sorted(f for f in os.listdir(args.source)
if f.lower().endswith((".png", ".jpg", ".jpeg", ".webp")))
if not names:
sys.exit(f"no images in {args.source}")

for name in names:
login = os.path.splitext(name)[0].lower()
w, h = process(os.path.join(args.source, name), os.path.join(args.out, f"{login}.png"))
print(f" {login:38} {w:4}x{h:<4}")


if __name__ == "__main__":
main()