Skip to content
Open
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
8 changes: 4 additions & 4 deletions inspector/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -275,14 +275,14 @@ def distribution(project_name, version, first, second, rest, distname):
h2_paren = "View this project on PyPI"
resp = requests_session().get(f"https://pypi.org/pypi/{project_name}/json")
if resp.status_code == 404:
h2_paren = "Project no longer on PyPI"
h2_paren = "Project no longer on PyPI"

h3_paren = "View this release on PyPI"
resp = requests_session().get(
f"https://pypi.org/pypi/{project_name}/{version}/json"
)
if resp.status_code == 404:
h3_paren = "Release no longer on PyPI"
h3_paren = "Release no longer on PyPI"

if dist:
file_urls = [
Expand Down Expand Up @@ -328,14 +328,14 @@ def file(project_name, version, first, second, rest, distname, filepath):
h2_paren = "View this project on PyPI"
resp = requests_session().get(f"https://pypi.org/pypi/{project_name}/json")
if resp.status_code == 404:
h2_paren = "Project no longer on PyPI"
h2_paren = "Project no longer on PyPI"

h3_paren = "View this release on PyPI"
resp = requests_session().get(
f"https://pypi.org/pypi/{project_name}/{version}/json"
)
if resp.status_code == 404:
h3_paren = "Release no longer on PyPI"
h3_paren = "Release no longer on PyPI"

dist = _get_dist(first, second, rest, distname)
if dist:
Expand Down
23 changes: 23 additions & 0 deletions inspector/static/tailwind.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
"./inspector/templates/**/*.{html,js}",
"./inspector/templates/*.html"
],
theme: {
extend: {
colors: {
'python-blue': '#3776AB',
'python-yellow': '#FFD43B',
'python-blue-dark': '#2D5E8B',
'python-blue-light': '#4E8DC8',
'python-yellow-dark': '#FFCA00',
'python-yellow-light': '#FFE57F',
},
fontFamily: {
'mono': ['ui-monospace', 'SFMono-Regular', 'Consolas', 'Liberation Mono', 'Menlo', 'monospace'],
}
},
},
plugins: [],
}
69 changes: 69 additions & 0 deletions inspector/static/tailwind.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

@layer components {
.btn-primary {
@apply bg-python-blue hover:bg-python-blue-dark text-white font-semibold py-2 px-4 rounded-lg transition-colors duration-200 shadow-md hover:shadow-lg;
}

.btn-secondary {
@apply bg-python-yellow hover:bg-python-yellow-dark text-gray-900 font-semibold py-2 px-4 rounded-lg transition-colors duration-200 shadow-md hover:shadow-lg;
}

.input-primary {
@apply border-2 border-gray-300 rounded-lg px-4 py-2 focus:outline-none focus:border-python-blue focus:ring-2 focus:ring-python-blue/20 transition-all duration-200;
}

.table-custom {
@apply min-w-full divide-y divide-gray-200 shadow-sm rounded-lg overflow-hidden;
}

.table-custom thead {
@apply bg-python-blue text-white;
}

.table-custom th {
@apply px-6 py-3 text-left text-xs font-medium uppercase tracking-wider;
}

.table-custom tbody {
@apply bg-white divide-y divide-gray-200;
}

.table-custom td {
@apply px-6 py-4 whitespace-nowrap text-sm;
}

.table-custom tbody tr:hover {
@apply bg-gray-50 transition-colors duration-150;
}

.card {
@apply bg-white rounded-lg shadow-md p-6 border border-gray-200;
}

.link-primary {
@apply text-python-blue hover:text-python-blue-dark underline transition-colors duration-200;
}

.badge {
@apply inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium;
}

.badge-success {
@apply bg-green-100 text-green-800;
}

.badge-warning {
@apply bg-python-yellow-light text-gray-900;
}

.badge-error {
@apply bg-red-100 text-red-800;
}

.header-gradient {
@apply bg-gradient-to-r from-python-blue via-python-blue-dark to-python-blue;
}
}
21 changes: 20 additions & 1 deletion inspector/templates/404.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,24 @@
{% extends 'base.html' %}

{% block body %}
<h1>NOT FOUND</h1>
<div class="text-center py-12">
<div class="inline-flex items-center justify-center w-24 h-24 bg-red-100 rounded-full mb-6">
<svg class="w-12 h-12 text-red-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"></path>
</svg>
</div>

<h1 class="text-4xl font-bold text-gray-800 mb-4">404 - Page Not Found</h1>
<p class="text-lg text-gray-600 mb-8">The page or package you're looking for doesn't exist.</p>

<div class="space-y-2">
<p class="text-gray-500">Try searching for a different package or</p>
<a href="/" class="inline-flex items-center px-6 py-3 bg-python-blue hover:bg-python-blue-dark text-white font-semibold rounded-lg transition-colors duration-200 shadow-md hover:shadow-lg">
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6"></path>
</svg>
Return to Home
</a>
</div>
</div>
{% endblock %}
210 changes: 151 additions & 59 deletions inspector/templates/base.html
Original file line number Diff line number Diff line change
@@ -1,68 +1,160 @@
<html>
<!DOCTYPE html>
<html lang="en">
<head>
{% block head %}{% endblock %}
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>🕵️</text></svg>">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>PyPI Inspector</title>
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>P</text></svg>">
<script src="https://cdn.tailwindcss.com"></script>
<script>
tailwind.config = {
theme: {
extend: {
colors: {
'python-blue': '#3776AB',
'python-yellow': '#FFD43B',
'python-blue-dark': '#2D5E8B',
'python-blue-light': '#4E8DC8',
'python-yellow-dark': '#FFCA00',
'python-yellow-light': '#FFE57F',
}
}
}
}
</script>
<style>
.header-gradient {
background: linear-gradient(135deg, #3776AB 0%, #2D5E8B 50%, #3776AB 100%);
}
</style>
{% block head %}{% endblock %}
</head>
<body>
<main>
<h1><a href="/">Inspector</a></h1>
<form action="/">
{% if h2 %}
<input type="text" name="project" placeholder="Project name" value="{{ h2 }}" autocomplete="off">
{% else %}
<input type="text" name="project" placeholder="Project name" autocomplete="off">
{% endif %}
<input type="submit">
</form>
<hr>
<body class="min-h-screen bg-gray-50 flex flex-col">
<!-- Header -->
<header class="header-gradient shadow-lg">
<div class="container mx-auto px-4 py-6">
<div class="flex flex-col md:flex-row items-center justify-between space-y-4 md:space-y-0">
<h1 class="text-3xl font-bold text-white flex items-center space-x-2">
<a href="/" class="hover:text-python-yellow transition-colors duration-200">PyPI Inspector</a>
</h1>

<!-- Search Form -->
<form action="/" method="get" class="w-full md:w-auto">
<div class="flex space-x-2">
{% if h2 %}
<input type="text" name="project" placeholder="Enter project name..."
value="{{ h2 }}" autocomplete="off"
class="px-4 py-2 rounded-lg border-2 border-white/20 bg-white/10 text-white placeholder-white/70 focus:outline-none focus:border-python-yellow focus:bg-white focus:text-gray-900 transition-all duration-200 w-64">
{% else %}
<input type="text" name="project" placeholder="Enter project name..."
autocomplete="off"
class="px-4 py-2 rounded-lg border-2 border-white/20 bg-white/10 text-white placeholder-white/70 focus:outline-none focus:border-python-yellow focus:bg-white focus:text-gray-900 transition-all duration-200 w-64">
{% endif %}
<button type="submit"
class="bg-python-yellow hover:bg-python-yellow-dark text-gray-900 font-semibold py-2 px-6 rounded-lg transition-all duration-200 shadow-md hover:shadow-lg">
Search
</button>
</div>
</form>
</div>
</div>
</header>

<!-- Main Content -->
<main class="container mx-auto px-4 py-8 flex-1">
{% block above_body %}{% endblock %}
{% if h2 %}
<h2>
{% if h2_link %}
<a href="{{ h2_link }}">{{ h2 }}</a>
{% else %}
{{ h2 }}
{% endif %}
{% if h2_paren_link %}
(<a href="{{ h2_paren_link }}">{{ h2_paren }}</a>)
{% endif %}
</h2>
{% endif %}
{% if h3 %}
<h3>
{% if h3_link %}
<a href="{{ h3_link }}">{{ h3 }}</a>
{% else %}
{{ h3 }}
{% endif %}
{% if h3_paren_link %}
(<a href="{{ h3_paren_link }}">{{ h3_paren }}</a>)
{% endif %}
</h3>
{% endif %}
{% if h4 %}
<h4>
{% if h4_link %}
<a href="{{ h4_link }}">{{ h4 }}</a>
{% else %}
{{ h4 }}
{% endif %}
</h4>
{% endif %}
{% if h5 %}
<h5>
{% if h5_link %}
<a href="{{ h5_link }}">{{ h5 }}</a>
{% else %}
{{ h5 }}
{% endif %}
</h5>

<!-- Breadcrumb Navigation -->
{% if h2 or h3 or h4 or h5 %}
<nav class="mb-6">
<ol class="flex flex-wrap items-center space-x-2 text-sm">
<li><a href="/" class="text-python-blue hover:text-python-blue-dark transition-colors">Home</a></li>

{% if h2 %}
<li class="flex items-center">
<svg class="w-4 h-4 mx-2 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path>
</svg>
<span class="font-semibold text-gray-700">
{% if h2_link %}
<a href="{{ h2_link }}" class="text-python-blue hover:text-python-blue-dark transition-colors">{{ h2 }}</a>
{% else %}
{{ h2 }}
{% endif %}
{% if h2_paren_link %}
(<a href="{{ h2_paren_link }}" class="text-python-blue hover:text-python-blue-dark transition-colors">{{ h2_paren }}</a>)
{% endif %}
</span>
</li>
{% endif %}

{% if h3 %}
<li class="flex items-center">
<svg class="w-4 h-4 mx-2 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path>
</svg>
<span class="text-gray-600">
{% if h3_link %}
<a href="{{ h3_link }}" class="text-python-blue hover:text-python-blue-dark transition-colors">{{ h3 }}</a>
{% else %}
{{ h3 }}
{% endif %}
{% if h3_paren_link %}
(<a href="{{ h3_paren_link }}" class="text-python-blue hover:text-python-blue-dark transition-colors">{{ h3_paren }}</a>)
{% endif %}
</span>
</li>
{% endif %}

{% if h4 %}
<li class="flex items-center">
<svg class="w-4 h-4 mx-2 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path>
</svg>
<span class="text-gray-600">
{% if h4_link %}
<a href="{{ h4_link }}" class="text-python-blue hover:text-python-blue-dark transition-colors">{{ h4 }}</a>
{% else %}
{{ h4 }}
{% endif %}
</span>
</li>
{% endif %}

{% if h5 %}
<li class="flex items-center">
<svg class="w-4 h-4 mx-2 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path>
</svg>
<span class="text-gray-600">
{% if h5_link %}
<a href="{{ h5_link }}" class="text-python-blue hover:text-python-blue-dark transition-colors">{{ h5 }}</a>
{% else %}
{{ h5 }}
{% endif %}
</span>
</li>
{% endif %}
</ol>
</nav>
{% endif %}
{% block body %}{% endblock %}

<!-- Page Content -->
<div class="bg-white rounded-lg shadow-md p-6">
{% block body %}{% endblock %}
</div>
</main>
<footer>
<small>Source: <a href="https://github.com/pypi/inspector">https://github.com/pypi/inspector</a></small>

<!-- Footer -->
<footer class="mt-auto py-8 bg-gray-100 border-t border-gray-200">
<div class="container mx-auto px-4 text-center">
<p class="text-gray-600 text-sm">
Source: <a href="https://github.com/pypi/inspector"
class="text-python-blue hover:text-python-blue-dark transition-colors">
github.com/pypi/inspector
</a>
</p>
</div>
</footer>
</body>
</html>
Loading
Loading