Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit ba67baf

Browse files
Package details page up and running!
1 parent 3e91a88 commit ba67baf

File tree

6 files changed

+218
-5
lines changed

6 files changed

+218
-5
lines changed

‎code/ch5-viewmodels/data/package.py‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
class Package:
2+
3+
def __init__(self,
4+
package_name: str,
5+
summary: str,
6+
description: str,
7+
home_page: str,
8+
lic: str,
9+
author_name: str,
10+
maintainers: list = None,
11+
):
12+
if maintainers is None:
13+
maintainers = []
14+
self.maintainers = maintainers
15+
self.author_name = author_name
16+
self.license = lic
17+
self.home_page = home_page
18+
self.description = description
19+
self.summary = summary
20+
self.package_name = package_name
21+
self.id = package_name

‎code/ch5-viewmodels/data/release.py‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import datetime
2+
3+
4+
class Release:
5+
6+
def __init__(self, version: str, created_date: datetime.datetime):
7+
self.version = version
8+
self.created_date = created_date
Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
from typing import List
1+
import datetime
2+
from typing import List, Optional
3+
4+
from data.package import Package
5+
from data.release import Release
26

37

48
def release_count() -> int:
@@ -11,7 +15,19 @@ def package_count() -> int:
1115

1216
def latest_packages(limit: int = 5) -> List:
1317
return [
14-
{'id': 'fastapi', 'summary': "A great web framework"},
15-
{'id': 'uvicorn', 'summary': "Your favorite ASGI server"},
16-
{'id': 'httpx', 'summary': "Requests for an async world"},
17-
][:limit]
18+
{'id': 'fastapi', 'summary': "A great web framework"},
19+
{'id': 'uvicorn', 'summary': "Your favorite ASGI server"},
20+
{'id': 'httpx', 'summary': "Requests for an async world"},
21+
][:limit]
22+
23+
24+
def get_package_by_id(package_name: str) -> Optional[Package]:
25+
package = Package(
26+
package_name, "This is the summary", "Full details here!",
27+
"https://fastapi.tiangolo.com/", "MIT", "Sebastián Ramírez"
28+
)
29+
return package
30+
31+
32+
def get_latest_release_for_package(package_name: str) -> Optional[Release]:
33+
return Release("1.2.0", datetime.datetime.now())
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
<div metal:use-macro="load: ../shared/_layout.pt">
2+
<div metal:fill-slot="content" tal:omit-tag="True">
3+
4+
<div class="content details">
5+
6+
<div class="hero">
7+
<div class="row">
8+
<div class="col-sm-1"></div>
9+
<div class="col-sm-8">
10+
<h1>
11+
${ package.id } ${ latest_version }
12+
</h1>
13+
14+
<div class="install sub-hero">
15+
pip install
16+
${ package.id }<span tal:condition="not is_latest">==${ release_version }</span>
17+
</div>
18+
</div>
19+
20+
<div class="col-sm-2 active-release">
21+
<div class="go-latest-button" tal:condition="is_latest">
22+
Latest version
23+
</div>
24+
<div class="go-older-button" tal:condition="not is_latest">
25+
<a href="/project/${ package.id }">
26+
Newer version available
27+
</a>
28+
</div>
29+
<div class="latest-release-date">
30+
Last release:
31+
<span tal:condition="latest_release">
32+
${ latest_release.created_date.date().isoformat() }
33+
</span>
34+
</div>
35+
</div>
36+
</div>
37+
38+
</div>
39+
40+
<div class="row pypi-stats">
41+
<div class="col-sm-1"></div>
42+
<div class="col-sm-10">
43+
${ package.summary }
44+
</div>
45+
</div>
46+
47+
<div class="project-list container">
48+
<div class="row">
49+
<div class="col-sm-3 nav-sidebar-section">
50+
51+
52+
<h3>Navigation</h3>
53+
<a href="/project/${ package.id }">
54+
<i class="fa fa-align-left" aria-hidden="true"></i>
55+
Project description
56+
</a><br>
57+
<a href="#">
58+
<i class="fa fa-history" aria-hidden="true"></i>
59+
Release history
60+
</a><br>
61+
<a href="#">
62+
<i class="fa fa-download" aria-hidden="true"></i>
63+
Download files
64+
</a>
65+
<hr>
66+
67+
68+
<h3>Project links</h3>
69+
<a href="${ package.home_page }">
70+
<i class="fa fa-home" aria-hidden="true"></i>
71+
Homepage
72+
</a>
73+
<hr>
74+
75+
76+
<h3>Statistics</h3>
77+
78+
<p>View statistics for this project via
79+
<a class="link-inline" href="https://libraries.io/pypi/${ package.id }">Libraries.io</a>,
80+
or by using
81+
<a class="link-inline"
82+
href="https://packaging.python.org/guides/analyzing-pypi-package-downloads/">Google
83+
BigQuery</a>
84+
</p>
85+
<hr>
86+
87+
88+
<h3>Meta</h3>
89+
<div class="meta-topic" tal:condition="package.license">
90+
<span>License</span>: ${ package.license }
91+
</div>
92+
93+
<div class="meta-topic" tal:condition="package.author_name">
94+
<span>Author</span>: ${ package.author_name }
95+
</div>
96+
<hr>
97+
98+
99+
<h3>Maintainers</h3>
100+
<div class="maintainer" tal:repeat="m maintainers">
101+
<img src="${ m.profile_image_url }" alt="">
102+
<a href="#">${ m.name }</a>
103+
</div>
104+
<hr>
105+
<h3>License</h3>
106+
<div class="license">
107+
${ package.license }
108+
</div>
109+
110+
</div>
111+
<div class="col-sm-7">
112+
113+
<h2>Project description</h2>
114+
115+
<pre>${ package.description.strip() }
116+
</pre>
117+
118+
119+
</div>
120+
<div class="col-sm-1"></div>
121+
</div>
122+
</div>
123+
124+
</div>
125+
</div>
126+
127+
<div metal:fill-slot="additional-css" tal:omit-tag="True">
128+
<link rel="stylesheet" href="/static/css/package.css">
129+
</div>
130+
</div>
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import datetime
2+
from typing import List, Optional
3+
4+
from starlette.requests import Request
5+
6+
from data.release import Release
7+
from services import package_service, user_service
8+
from viewmodels.shared.viewmodel import ViewModelBase
9+
10+
11+
class DetailsViewModel(ViewModelBase):
12+
def __init__(self, package_name: str, request: Request):
13+
super().__init__(request)
14+
15+
self.package_name = package_name
16+
self.package = package_service.get_package_by_id(package_name)
17+
self.latest_release = package_service.get_latest_release_for_package(package_name)
18+
self.latest_version = "0.0.0"
19+
self.is_latest = True
20+
self.maintainers = []
21+
22+
if not self.package or not self.latest_release:
23+
return
24+
25+
self.latest_version = self.latest_release.version
26+
self.maintainers = self.package.maintainers
27+
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
11
import fastapi
2+
from fastapi_chameleon import template
3+
from starlette.requests import Request
4+
5+
from viewmodels.packages.details_viewmodel import DetailsViewModel
26

37
router = fastapi.APIRouter()
8+
9+
10+
@router.get('/project/{package_name}')
11+
@template(template_file='packages/details.pt')
12+
def details(package_name: str, request: Request):
13+
vm = DetailsViewModel(package_name, request)
14+
return vm.to_dict()

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /