Commit Graph

174 Commits

Author SHA1 Message Date
Vinta Chen
d9f26a8635 Improve SEO/AEO discovery surface for awesome-python.com (#3103)
* update gitignore

* feat: tighten homepage metadata

* fix: trim generated HTML whitespace

* feat(website): add discovery files and markdown alternate

* feat(website): add sitemap lastmod

* feat(seo): add Content-Signal directive to robots.txt

Signals search, ai-input, and ai-train to crawlers
via the experimental Content-Signal header in robots.txt.

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-05-02 01:53:19 +08:00
Vinta Chen
35aee20aa9 remove color 2026-04-19 22:51:25 +08:00
Vinta Chen
674c169efd fix(css): scope --accent-underline to sponsor-become hover; restore --line-strong at rest
Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-19 22:48:33 +08:00
Vinta Chen
7625d1f05d style: use --accent-underline on sponsor link underline
Swaps --line-strong for --accent-underline on the 'Become a sponsor'
text-decoration-color so the underline matches the tan hover underline
on project-name links like thealgorithms.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-19 22:47:37 +08:00
Vinta Chen
19496c2c93 refactor(css): replace sponsor-become border underline with text-decoration
Swap the border-bottom + padding-bottom fake underline on .sponsor-become
for a native text-decoration underline with text-underline-offset so the
line hugs the text at the same distance as the hero @vinta/@JinyangWang27
links, rather than sitting a fixed 0.2rem gap away.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-19 22:45:44 +08:00
Vinta Chen
f3c8377bd4 chore: remove arrow from 'Become a sponsor' link and its CSS rules
Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-19 22:43:19 +08:00
Vinta Chen
257b69a932 style(sponsors): bump section-label to --text-lg within sponsor scope
Override font-size to var(--text-lg) inside .sponsor-meta so the
Sponsors heading is larger, while the shared .section-label class
remains --text-sm everywhere else.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-19 22:40:31 +08:00
Vinta Chen
f10337bb31 refactor(tests): modernize test_readme_parser to use pathlib.Path
Replace os.path.join + manual open() with Path(__file__).resolve().parents[2]
and Path.read_text() for locating and reading README.md.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-19 22:07:16 +08:00
Vinta Chen
92936964b6 refactor(readme_parser): fuse _parse_sponsor_item into single pass
Eliminate the redundant _find_link_deep precheck by merging the two
walks over inline.children into one loop that simultaneously locates
the link and records its top-level index.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-19 22:06:41 +08:00
Vinta Chen
420bf8cd9d refactor(readme_parser): collapse render_inline_html/text into _render_inline helper
Merge the two inline-renderer implementations into a single _render_inline(children, *, html) function that handles both output modes. The original public functions become one-line wrappers so all dispatch logic lives in one place. Also aligns html_inline handling: the html=True path now escapes the raw content instead of silently dropping it in the plain-text path.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-19 22:05:35 +08:00
Vinta Chen
0630ee973b refactor(build): flatten extract_entries and annotate result dict
Collapse the if-seen/else-new branches so the category/group/subcategory
merge logic runs once per entry unconditionally, appending to empty lists
on first sight instead of duplicating the append logic in the else branch.

Annotate seen and entries as dict[str, Any] so ty can resolve the mixed
value types (str, list, None) in each entry dict.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-19 22:04:14 +08:00
Vinta Chen
6ae7c89688 refactor: replace manual total_seconds()/3600 with timedelta comparison
Use timedelta(hours=CACHE_MAX_AGE_HOURS) so the cache-age check
reads at the intended hours unit directly, removing the conversion
arithmetic.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-19 22:02:14 +08:00
Vinta Chen
95115f7949 refactor(fetch_github_stars): replace manual slice loop with itertools.batched
Use itertools.batched (stdlib since Python 3.12, targeted by this project)
instead of manual range(0, N, BATCH_SIZE) slicing. Loosen fetch_batch,
build_graphql_query, and parse_graphql_response signatures from list[str]
to Sequence[str] since batched yields tuples.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-19 22:01:35 +08:00
Vinta Chen
39b65bc994 refactor(build): inline format_stars_short into its call site
The helper only appeared once and the logic is two lines, so the named
function added indirection without clarity. Removed the four dedicated
unit tests that covered the function directly.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-19 22:00:45 +08:00
Vinta Chen
85b55efb28 refactor(readme_parser): inline _is_leading_link at its call site
The helper was only called once and the bool(inline.children) guard
was redundant: first_link being non-None already implies inline.children
is non-empty.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-19 21:59:59 +08:00
Vinta Chen
486fbf2185 refactor(readme_parser): replace _find_first_link with _find_child(inline, "link")
The private helper duplicated _find_child with a hardcoded type filter.
Remove it and call the general helper directly at both call sites.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-19 21:59:16 +08:00
Vinta Chen
e0b0dc9c0a refactor(readme_parser): add _href helper to narrow attrGet return type
Extracts a _href(link) helper that returns link.attrGet('href') narrowed
to str (falling back to '') instead of the raw str|int|float|None union.
Replaces all four attrGet('href') or '' call sites with _href(), fixing
ty errors where the widened union leaked into TypedDict url fields.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-19 21:58:27 +08:00
Vinta Chen
7e7de19ef6 refactor(build): remove StarData TypedDict, loosen load_stars return to dict[str, dict]
Cache-write shape mismatches the TypedDict and callers mix .get() and
direct access, so the stricter type was providing false safety. Using
dict[str, dict] accurately reflects the actual runtime contract.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-19 21:57:30 +08:00
Vinta Chen
7f4a163534 refactor(build): tighten extract_entries parameter types to ParsedSection/ParsedGroup
Replace loose list[dict] annotations with concrete TypedDicts imported
from readme_parser so ty can verify call-site compatibility.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-19 21:56:46 +08:00
Vinta Chen
c85f81bb24 refactor(build): accept Path directly in build() signature
Remove internal str->Path conversion; callers and tests now pass
Path objects directly.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-19 21:56:06 +08:00
Vinta Chen
b9236c4925 refactor(fetch_github_stars): drop unnecessary keyword-only marker on fetch_batch
client is the only non-first param and is always required, so the * separator
adds no clarity. Update the call site accordingly.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-19 21:55:32 +08:00
Vinta Chen
a358d45ca4 refactor: use datetime.UTC alias instead of timezone.utc
Python 3.11 introduced datetime.UTC as a cleaner alias for
datetime.timezone.utc. Both build.py and fetch_github_stars.py
are updated to use the shorter form.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-19 21:54:55 +08:00
Vinta Chen
e47d229528 refactor(readme_parser): consolidate state reset to tail of flush_group
State reset (current_group_name = None, current_group_cats = []) was
duplicated in both branches of the early-return guard. Move it after
the conditional so it runs exactly once regardless of path.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-19 21:54:16 +08:00
Vinta Chen
b897676e01 refactor(fetch_github_stars): remove redundant early-return guard in build_graphql_query
The empty-parts check after the loop makes the upfront `if not repos: return ""` guard redundant.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-19 21:53:39 +08:00
Vinta Chen
a4b7fc6878 adjust css 2026-04-19 21:34:14 +08:00
Vinta Chen
774ab69bcd feat(website): add sponsors section parsed from README
Parse the # Sponsors heading in README.md into structured data and
render a dedicated sponsor band above the library index on the site.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-19 21:10:50 +08:00
Vinta Chen
520e285e8e test: add entry validation and broken-link detection tests
Add three tests against the real README: verify all entries have
non-empty names, valid http(s) URLs, and no broken markdown link
syntax (e.g. '[name(url)' missing the closing '](').

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-03 15:55:53 +08:00
Vinta Chen
e9be000b56 refactor(fetch_github_stars): drop underscore prefix from regex constants
Rename _GITHUB_OWNER_RE and _GITHUB_NAME_RE to GITHUB_OWNER_RE and
GITHUB_NAME_RE to match the naming style of the other module-level
constants (GRAPHQL_URL, BATCH_SIZE).

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-30 15:20:01 +08:00
Vinta Chen
1ae889b4fd fix: stricter GitHub owner/repo regexes and injection tests
Split _GITHUB_NAME_RE into separate owner and repo patterns.
Owner regex now rejects leading/trailing hyphens and dots (matching
GitHub's actual username rules). Repo regex requires alphanumeric
start but allows dots and underscores anywhere after.

New tests cover GraphQL injection attempts, invalid leading chars,
and valid hyphenated/underscore/dot combinations.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-30 15:03:06 +08:00
orbisai0security
babb09fc5f fix: use subprocess instead of os.system in fetch_github_stars.py
The Python CLI scripts at website/fetch_github_stars
2026-03-30 04:41:42 +00:00
Vinta Chen
9425ab5921 refactor(js): replace var with const for immutable bindings
Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-24 13:37:35 +08:00
Vinta Chen
7b6829c26e style(html): reformat templates for consistent attribute and block spacing
Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-24 13:35:10 +08:00
Vinta Chen
0b081100d2 fix(css): remove explicit flex layout from .hero-topbar mobile override
The flex properties (align-items, flex-direction, flex-wrap, justify-content)
were overriding the default layout unnecessarily on mobile.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-24 13:35:06 +08:00
Vinta Chen
80d9279f78 refactor(css): consolidate .sort-btn:focus-visible into shared focus-visible selector block
Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-24 13:34:57 +08:00
Vinta Chen
7fdf6ab307 refactor(js): hoist repeated queries, drop stale comments, tighten collapseAll scope
- Hoist reducedMotion and sortHeaders to module scope to avoid repeated
  DOM queries on every call
- collapseAll now queries within tbody instead of the full document
- Replace indexOf with includes for tag filtering
- Remove null check on activeSort (always initialized)
- Drop inline section comments that just restate the code

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-24 13:34:20 +08:00
Vinta Chen
4456783320 docs: update social handle from Twitter to X (twitter.com -> x.com)
Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-24 13:34:11 +08:00
Vinta Chen
57a5b432f6 fix(js): drop legacy category/group URL param aliases for filter
Only the canonical 'filter' query param is supported. The 'category'
and 'group' aliases were never documented and silently accepted wrong
spellings; removing them prevents hidden coupling to old URL shapes.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-24 13:19:42 +08:00
Vinta Chen
d7a7e68475 refactor(js): simplify filter state to a plain string
Replace the { type, value } filter object with a plain string value.
Merge data-cats and data-groups row attributes into a single data-tags
attribute. Drop data-type from tag buttons. Consolidate category/group
URL params into a single filter param, keeping backward-compat fallback.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-24 13:18:26 +08:00
Vinta Chen
3b69697504 refactor(js): extract getScrollBehavior() helper to deduplicate prefers-reduced-motion check
The same matchMedia query was inlined twice (hero scroll and back-to-top).
Extracted into a shared helper. Also renamed loop variable and reformatted
a chained querySelector call for readability. No behavior change.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-24 13:12:10 +08:00
Vinta Chen
57e4adbeb1 style(html): reformat hero CTA anchor tag onto multiple lines
Long attribute list was exceeding line-length; split across lines
for readability. No behavior change.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-24 13:12:04 +08:00
Vinta Chen
66242cf0c9 refactor(css): consolidate .expand-commit into shared mobile media query
Was in a standalone @media (max-width: 960px) block; now lives inside
the existing mobile breakpoint block alongside sibling expand-row rules.
No visual change.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-24 13:12:00 +08:00
Vinta Chen
53684e7c40 fix(css): increase sort button focus outline-offset from 2px to 3px
Gives the focus ring a bit more breathing room so it doesn't
overlap the button text at the new border-radius.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-24 13:11:51 +08:00
Vinta Chen
eb5b37daf5 feat(ux): smooth-scroll hero CTA without updating URL hash
Add a data-scroll-to attribute to the hero 'Browse the List' anchor
and a JS handler that calls scrollIntoView instead of letting the
browser follow the href, so the URL hash is never written.
Respects prefers-reduced-motion.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-24 13:08:22 +08:00
Vinta Chen
8e360e82b7 style(html): reformat index.html for consistent indentation
No behavior change. Reformats inline Jinja2/HTML to follow consistent
two-space indentation and line-length conventions throughout the template.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-24 13:06:04 +08:00
Vinta Chen
6cb0cac16d fix(css): increase footer font size from text-xs to text-sm
Footer text was too small to read comfortably. Bumping to --text-sm
improves legibility without breaking the footer layout.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-24 13:06:00 +08:00
Vinta Chen
856f436022 fix(css): consolidate table-wrap overflow-x into single breakpoint
Moves overflow-x: clip from the 680px breakpoint into the 960px
breakpoint, removing the duplicate rule. The value was applied twice
across two consecutive breakpoints with no override in between.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-24 13:03:01 +08:00
Vinta Chen
cf9cde8e8f fix(css): use display:none for expand-row first/last cells on mobile
Replaces the width/padding/overflow hack with a clean display:none.
The previous approach collapsed the cells to zero size but kept them
in the layout flow; display:none removes them entirely.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-24 13:00:40 +08:00
Vinta Chen
63182f23ab Revert "feat(css): add external link indicator for inline text links"
This reverts commit 65bc88bb4e.
2026-03-24 12:56:47 +08:00
Vinta Chen
7df2e36334 feat(mobile): show last commit date in expand row on mobile
Add an expand-commit span inside the expand row that displays the last
commit date. Hidden on desktop, visible only on mobile (max-width: 960px)
via media query, mirroring the commit column that appears in the full
table. Relative time formatting is applied via JS on page load.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-24 12:56:04 +08:00
Vinta Chen
f1799c2a44 perf(fonts): defer Google Fonts load to avoid render-blocking
Use media='print' + onload swap trick to load the stylesheet
non-blocking. Add noscript fallback for JS-disabled browsers.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-24 12:55:04 +08:00