mirror of
https://github.com/vinta/awesome-python.git
synced 2026-11-10 01:34:28 -06:00
Sourced from website/data/pypi_downloads.tsv the same way github_stars.json feeds the stars column. The new sortable column sits between GitHub Stars and Last Commit on the homepage and category pages, formatted with thousands separators like stars, with an em dash when no PyPI data exists. Rows are matched by normalized README display name; Built-in entries never show counts since same-named PyPI packages are stdlib backports (e.g. the asyncio package). Below 960px the column hides and the count moves into the expand row, mirroring the existing Last Commit treatment. main.js gains the downloads sort branch and URL param. The deploy workflow fetches the TSV via the new make fetch_pypi_downloads target with a daily actions/cache fallback, mirroring the stars fetch, but non-fatal: the column degrades to dashes when the fetch fails, unlike stars which the build requires. Co-Authored-By: Claude <noreply@anthropic.com>
307 lines
11 KiB
HTML
307 lines
11 KiB
HTML
{% extends "base.html" %}
|
|
{% block title %}{{ category_title }}{% endblock %}
|
|
{% block description %}{{ category_description }}{% endblock %}
|
|
{% block canonical_url %}{{ category_url }}{% endblock %}
|
|
{% block alternate_links %}{% endblock %}
|
|
{% block extra_head %}
|
|
<script type="application/ld+json">{{ category_json_ld | safe }}</script>
|
|
{% endblock %}
|
|
{% block header %}
|
|
<header class="category-hero">
|
|
<div class="hero-sheen" aria-hidden="true"></div>
|
|
<div class="hero-noise" aria-hidden="true"></div>
|
|
|
|
<div class="category-hero-shell">
|
|
<nav class="hero-topbar category-topbar" aria-label="Site">
|
|
<a href="/" class="hero-brand-mini">Awesome Python</a>
|
|
<div class="hero-topbar-actions">
|
|
<a href="/#library-index" class="hero-topbar-link">All projects</a>
|
|
<a
|
|
href="https://github.com/vinta/awesome-python/blob/master/CONTRIBUTING.md"
|
|
class="hero-topbar-link hero-topbar-link-strong"
|
|
target="_blank"
|
|
rel="noopener"
|
|
>Submit a project</a
|
|
>
|
|
<a href="/sponsorship/" class="hero-topbar-link">Sponsorship</a>
|
|
</div>
|
|
</nav>
|
|
|
|
<div class="category-hero-copy">
|
|
{% if parent_category %}
|
|
<p class="category-breadcrumb">
|
|
<a href="/categories/{{ parent_category.slug }}/">{{ parent_category.name }}</a>
|
|
</p>
|
|
{% endif %}
|
|
<h1>{{ category.name }}</h1>
|
|
{% if category.description_html %}
|
|
<p class="category-subtitle">{{ category.description_html | safe }}</p>
|
|
{% endif %}
|
|
</div>
|
|
|
|
{% if group_categories %}
|
|
<nav class="hero-category-nav" aria-labelledby="hero-category-heading">
|
|
<div class="hero-category-meta">
|
|
<h2 id="hero-category-heading">Browse by category</h2>
|
|
</div>
|
|
<ul class="hero-category-links">
|
|
{% for sub in group_categories %}
|
|
<li>
|
|
<a class="hero-category-link" href="{{ category_urls[sub.name] }}"
|
|
>{{ sub.name }}</a
|
|
>
|
|
</li>
|
|
{% endfor %}
|
|
</ul>
|
|
</nav>
|
|
{% endif %}
|
|
</div>
|
|
</header>
|
|
{% endblock %}
|
|
{% block content %}
|
|
<script type="application/json" id="filter-urls">{{ filter_urls_json | safe }}</script>
|
|
<section class="results-section" id="library-index">
|
|
<div class="results-intro section-shell" data-reveal>
|
|
<div>
|
|
<h2>Search every project in one place</h2>
|
|
</div>
|
|
<p class="results-note">
|
|
Press <kbd>/</kbd> to search. Tap a tag to filter. Click any row for
|
|
details.
|
|
</p>
|
|
</div>
|
|
|
|
<div class="controls section-shell" data-reveal>
|
|
<h2 class="sr-only">Search and filter</h2>
|
|
<div class="search-wrap">
|
|
<svg
|
|
class="search-icon"
|
|
width="16"
|
|
height="16"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2.5"
|
|
stroke-linecap="round"
|
|
stroke-linejoin="round"
|
|
>
|
|
<circle cx="11" cy="11" r="8" />
|
|
<line x1="21" y1="21" x2="16.65" y2="16.65" />
|
|
</svg>
|
|
<input
|
|
type="search"
|
|
class="search"
|
|
placeholder="Search {{ entries | length }} projects in {{ category.name }}..."
|
|
aria-label="Search projects"
|
|
/>
|
|
</div>
|
|
<div class="filter-bar" aria-live="polite">
|
|
<span>Filtering for <strong class="filter-value"></strong></span>
|
|
<button class="filter-clear" aria-label="Clear filter">
|
|
Clear filter
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<h2 class="sr-only">Results</h2>
|
|
<div
|
|
class="table-wrap"
|
|
tabindex="0"
|
|
role="region"
|
|
aria-label="Libraries table"
|
|
>
|
|
<table class="table">
|
|
<thead>
|
|
<tr>
|
|
<th class="col-num"><span class="sr-only">Row number</span></th>
|
|
<th class="col-name" data-sort="name">
|
|
<button type="button" class="sort-btn">Project Name</button>
|
|
</th>
|
|
<th class="col-stars" data-sort="stars">
|
|
<button type="button" class="sort-btn">GitHub Stars</button>
|
|
</th>
|
|
<th class="col-downloads" data-sort="downloads">
|
|
<button type="button" class="sort-btn">Downloads/Month</button>
|
|
</th>
|
|
<th class="col-commit" data-sort="commit-time">
|
|
<button type="button" class="sort-btn">Last Commit</button>
|
|
</th>
|
|
<th class="col-cat">Tags</th>
|
|
<th class="col-arrow">
|
|
<button class="back-to-top" aria-label="Back to top">
|
|
Top ↑
|
|
</button>
|
|
</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for entry in entries %}
|
|
<tr
|
|
class="row"
|
|
data-tags="{{ entry.categories | join('||') }}{% if entry.subcategories %}||{{ entry.subcategories | map(attribute='value') | join('||') }}{% endif %}||{{ entry.groups | join('||') }}{% if entry.source_type == 'Built-in' %}||Built-in{% endif %}"
|
|
tabindex="0"
|
|
aria-expanded="false"
|
|
aria-controls="expand-{{ loop.index }}"
|
|
>
|
|
<td class="col-num">{{ loop.index }}</td>
|
|
<td class="col-name">
|
|
<a href="{{ entry.url }}" target="_blank" rel="noopener"
|
|
>{{ entry.name }}</a
|
|
>
|
|
<span class="mobile-cat"
|
|
>{% if entry.subcategories %}{{ entry.subcategories[0].name }}{%
|
|
else %}{{ category.name }}{% endif %}</span
|
|
>
|
|
</td>
|
|
<td class="col-stars">
|
|
{% if entry.stars is not none %}{{ "{:,}".format(entry.stars) }}{%
|
|
elif entry.source_type %}<span class="source-badge"
|
|
>{{ entry.source_type }}</span
|
|
>{% else %}—{% endif %}
|
|
</td>
|
|
<td class="col-downloads">
|
|
{% if entry.downloads is not none %}{{
|
|
"{:,}".format(entry.downloads) }}{% else %}—{% endif %}
|
|
</td>
|
|
<td
|
|
class="col-commit"
|
|
{%
|
|
if
|
|
entry.last_commit_at
|
|
%}data-commit="{{ entry.last_commit_at }}"
|
|
{%
|
|
endif
|
|
%}
|
|
>
|
|
{% if entry.last_commit_at %}<time
|
|
datetime="{{ entry.last_commit_at }}"
|
|
>{{ entry.last_commit_at[:10] }}</time
|
|
>{% else %}—{% endif %}
|
|
</td>
|
|
<td class="col-cat">
|
|
{% for subcat in entry.subcategories %}
|
|
<a class="tag{% if subcat.url == current_path %} active{% endif %}" href="{{ subcat.url }}" data-value="{{ subcat.value }}" data-url="{{ subcat.url }}">
|
|
{{ subcat.name }}
|
|
</a>
|
|
{% endfor %}
|
|
{% for cat in entry.categories %}
|
|
<a
|
|
class="tag{% if category_urls[cat] == current_path %} active{% endif %}"
|
|
href="{{ category_urls[cat] }}"
|
|
data-value="{{ cat }}"
|
|
data-url="{{ category_urls[cat] }}"
|
|
>{{ cat }}</a
|
|
>
|
|
{% endfor %}
|
|
{% if entry.groups %}
|
|
{% set group_url = filter_urls[entry.groups[0]] %}
|
|
<a
|
|
class="tag tag-group{% if group_url == current_path %} active{% endif %}"
|
|
href="{{ group_url }}"
|
|
data-value="{{ entry.groups[0] }}"
|
|
data-url="{{ group_url }}"
|
|
>
|
|
{{ entry.groups[0] }}
|
|
</a>
|
|
{% endif %}
|
|
{% if entry.source_type == 'Built-in' %}
|
|
<a
|
|
class="tag tag-source{% if '/categories/built-in/' == current_path %} active{% endif %}"
|
|
href="/categories/built-in/"
|
|
data-value="Built-in"
|
|
data-url="/categories/built-in/"
|
|
>
|
|
Built-in
|
|
</a>
|
|
{% endif %}
|
|
</td>
|
|
<td class="col-arrow"><span class="arrow">→</span></td>
|
|
</tr>
|
|
{% if entry.description %}
|
|
<tr class="desc-row" aria-hidden="true">
|
|
<td class="col-num"></td>
|
|
<td colspan="6">
|
|
<div class="desc-text">{{ entry.description | safe }}</div>
|
|
</td>
|
|
</tr>
|
|
{% endif %}
|
|
<tr class="expand-row" id="expand-{{ loop.index }}">
|
|
<td></td>
|
|
<td colspan="5">
|
|
<div class="expand-content">
|
|
{% if entry.also_see %}
|
|
<div class="expand-also-see">
|
|
Also see: {% for see in entry.also_see %}<a
|
|
href="{{ see.url }}"
|
|
target="_blank"
|
|
rel="noopener"
|
|
>{{ see.name }}</a
|
|
>{% if not loop.last %}, {% endif %}{% endfor %}
|
|
</div>
|
|
{% endif %}
|
|
<div class="expand-meta">
|
|
{% if entry.owner %}<a
|
|
href="https://github.com/{{ entry.owner }}"
|
|
target="_blank"
|
|
rel="noopener"
|
|
>{{ entry.owner }}</a
|
|
><span class="expand-sep">/</span>{% endif %}<a
|
|
href="{{ entry.url }}"
|
|
target="_blank"
|
|
rel="noopener"
|
|
>{{ entry.url | replace("https://", "") }}</a
|
|
>
|
|
{% if entry.last_commit_at %}<span class="expand-commit"
|
|
><span class="expand-sep">/</span
|
|
><time datetime="{{ entry.last_commit_at }}"
|
|
>{{ entry.last_commit_at[:10] }}</time
|
|
></span
|
|
>{% endif %} {% if entry.downloads is not none %}<span
|
|
class="expand-downloads"
|
|
><span class="expand-sep">/</span>{{
|
|
"{:,}".format(entry.downloads) }} downloads/month</span
|
|
>{% endif %}
|
|
</div>
|
|
</div>
|
|
</td>
|
|
<td></td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<div class="no-results" hidden>
|
|
<p>No projects match your search or filter.</p>
|
|
<p class="no-results-hint">
|
|
Try a broader term, or
|
|
<button class="no-results-clear">browse all projects</button>.
|
|
</p>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="final-cta" data-reveal>
|
|
<div class="section-shell">
|
|
<p class="section-label">Contribute</p>
|
|
<h2>Know a project that belongs here?</h2>
|
|
<p>Tell us what it does and why it stands out.</p>
|
|
<div class="final-cta-actions">
|
|
<a
|
|
href="https://github.com/vinta/awesome-python/blob/master/CONTRIBUTING.md"
|
|
class="hero-action hero-action-primary"
|
|
target="_blank"
|
|
rel="noopener"
|
|
>Submit a project</a
|
|
>
|
|
<a
|
|
href="https://github.com/vinta/awesome-python"
|
|
class="hero-action hero-action-secondary"
|
|
target="_blank"
|
|
rel="noopener"
|
|
>Star the repository</a
|
|
>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
{% endblock %}
|