Skip to content

Commit d43b658

Browse files
authored
Merge pull request #13 from simple-repository/feature/static-files-at-runtime
(no change) Fully re-format the codebase
2 parents 9b306f6 + 751c20a commit d43b658

21 files changed

+607
-353
lines changed

.pre-commit-config.yaml

Lines changed: 5 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,7 @@
11
repos:
2-
- repo: https://github.com/pre-commit/pre-commit-hooks
3-
rev: "v4.4.0"
2+
- repo: https://github.com/astral-sh/ruff-pre-commit
3+
rev: v0.11.13
44
hooks:
5-
- id: trailing-whitespace
6-
- id: end-of-file-fixer
7-
- id: check-yaml
8-
- id: check-toml
9-
10-
- repo: https://github.com/asottile/add-trailing-comma
11-
rev: "v2.4.0"
12-
hooks:
13-
- id: add-trailing-comma
14-
args:
15-
- "--py36-plus"
16-
17-
- repo: https://github.com/PyCQA/isort
18-
rev: "5.12.0"
19-
hooks:
20-
- id: isort
21-
22-
- repo: https://github.com/pycqa/flake8
23-
rev: "6.0.0"
24-
hooks:
25-
- id: flake8
26-
args:
27-
- "--max-line-length=100"
28-
- '--ignore=E501,E226,W503,E402'
5+
- id: ruff-check
6+
args: ["--fix", "--select=I"]
7+
- id: ruff-format

pyproject.toml

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,8 @@ simple-repository-browser = "simple_repository_browser.__main__:main"
5151
[tool.setuptools_scm]
5252
version_file = "simple_repository_browser/_version.py"
5353

54-
[tool.isort]
55-
multi_line_output = 3
56-
include_trailing_comma = true
57-
force_grid_wrap = 0
58-
use_parentheses = true
59-
ensure_newline_before_comments = true
60-
line_length = 88
61-
force_sort_within_sections = true
54+
[tool.ruff.lint.isort]
55+
force-sort-within-sections = true
6256

6357
# [tool.mypy]
6458
# check_untyped_defs = true

simple_repository_browser/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
Documentation for the simple_repository_browser package
33
44
"""
5+
56
from . import _version # type: ignore
67

78
__version__ = _version.version # type: ignore

simple_repository_browser/__main__.py

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,25 @@ def configure_parser(parser: argparse.ArgumentParser) -> None:
2020
# parsed arguments.
2121
parser.set_defaults(handler=handler)
2222

23-
parser.add_argument("repository_url", type=str, nargs='?', default='https://pypi.org/simple/')
23+
parser.add_argument(
24+
"repository_url", type=str, nargs="?", default="https://pypi.org/simple/"
25+
)
2426
parser.add_argument("--host", default="0.0.0.0")
2527
parser.add_argument("--port", type=int, default=8080)
26-
parser.add_argument("--cache-dir", type=str, default=Path(os.environ.get('XDG_CACHE_DIR', Path.home() / '.cache')) / 'simple-repository-browser')
28+
parser.add_argument(
29+
"--cache-dir",
30+
type=str,
31+
default=Path(os.environ.get("XDG_CACHE_DIR", Path.home() / ".cache"))
32+
/ "simple-repository-browser",
33+
)
2734
parser.add_argument("--url-prefix", type=str, default="")
28-
parser.add_argument('--no-popular-project-crawl', dest='crawl_popular_projects', action='store_false', default=True)
29-
parser.add_argument('--templates-dir', default=here / "templates", type=Path)
35+
parser.add_argument(
36+
"--no-popular-project-crawl",
37+
dest="crawl_popular_projects",
38+
action="store_false",
39+
default=True,
40+
)
41+
parser.add_argument("--templates-dir", default=here / "templates", type=Path)
3042

3143

3244
def handler(args: typing.Any) -> None:
@@ -38,9 +50,9 @@ def handler(args: typing.Any) -> None:
3850
# Include the base templates so that the given templates directory doesn't have to
3951
# implement *all* of the templates. This must be at a lower precedence than the given
4052
# templates path, so that they can be overriden.
41-
here/"templates"/"base",
53+
here / "templates" / "base",
4254
# Include the "base" folder, such that upstream templates can inherit from "base/...".
43-
here/"templates",
55+
here / "templates",
4456
],
4557
static_files_paths=[here / "static"],
4658
crawl_popular_projects=args.crawl_popular_projects,
@@ -49,10 +61,12 @@ def handler(args: typing.Any) -> None:
4961
).create_app()
5062

5163
log_conf = LOGGING_CONFIG.copy()
52-
log_conf["formatters"]["default"]["fmt"] = "%(asctime)s [%(name)s] %(levelprefix)s %(message)s"
53-
log_conf["formatters"]["access"][
54-
"fmt"
55-
] = '%(asctime)s [%(name)s] %(levelprefix)s %(client_addr)s - "%(request_line)s" %(status_code)s'
64+
log_conf["formatters"]["default"]["fmt"] = (
65+
"%(asctime)s [%(name)s] %(levelprefix)s %(message)s"
66+
)
67+
log_conf["formatters"]["access"]["fmt"] = (
68+
'%(asctime)s [%(name)s] %(levelprefix)s %(client_addr)s - "%(request_line)s" %(status_code)s'
69+
)
5670

5771
uvicorn.run(
5872
app=app,
@@ -71,8 +85,8 @@ def main():
7185
args.handler(args)
7286

7387

74-
if __name__ == '__main__':
88+
if __name__ == "__main__":
7589
logging.basicConfig(level=logging.INFO)
76-
logging.getLogger('httpcore').setLevel(logging.WARNING)
77-
logging.getLogger('httpx').setLevel(logging.WARNING)
90+
logging.getLogger("httpcore").setLevel(logging.WARNING)
91+
logging.getLogger("httpx").setLevel(logging.WARNING)
7892
main()

simple_repository_browser/_app.py

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ def __init__(
3737
self.crawl_popular_projects = crawl_popular_projects
3838
self.browser_version = browser_version
3939

40-
self.cache = diskcache.Cache(str(cache_dir/'diskcache'))
41-
self.db_path = cache_dir / 'projects.sqlite'
40+
self.cache = diskcache.Cache(str(cache_dir / "diskcache"))
41+
self.db_path = cache_dir / "projects.sqlite"
4242
self.con = sqlite3.connect(
4343
self.db_path,
4444
detect_types=sqlite3.PARSE_DECLTYPES,
@@ -51,7 +51,6 @@ def create_app(self) -> fastapi.FastAPI:
5151
_view = self.create_view()
5252

5353
async def lifespan(app: fastapi.FastAPI):
54-
5554
async with (
5655
httpx.AsyncClient(timeout=30) as http_client,
5756
aiosqlite.connect(self.db_path, timeout=5) as db,
@@ -72,7 +71,9 @@ async def lifespan(app: fastapi.FastAPI):
7271
# convenient for development purposes.
7372
@app.get("/")
7473
async def redirect_to_index():
75-
return fastapi.responses.RedirectResponse(url=app.url_path_for('index'))
74+
return fastapi.responses.RedirectResponse(
75+
url=app.url_path_for("index")
76+
)
7677

7778
yield
7879

@@ -92,7 +93,7 @@ async def catch_exceptions_middleware(request: fastapi.Request, call_next):
9293
detail = f"Internal server error ({err})"
9394
# raise
9495
logging.getLogger("simple_repository_browser.error").error(
95-
'Unhandled exception',
96+
"Unhandled exception",
9697
exc_info=err,
9798
)
9899
content = _view.error_page(
@@ -104,14 +105,20 @@ async def catch_exceptions_middleware(request: fastapi.Request, call_next):
104105
status_code=status_code,
105106
)
106107

107-
app.middleware('http')(catch_exceptions_middleware)
108+
app.middleware("http")(catch_exceptions_middleware)
108109

109110
return app
110111

111112
def create_view(self) -> view.View:
112-
return view.View(self.template_paths, self.browser_version, static_files_manifest=self.static_files_manifest)
113+
return view.View(
114+
self.template_paths,
115+
self.browser_version,
116+
static_files_manifest=self.static_files_manifest,
117+
)
113118

114-
def create_crawler(self, http_client: httpx.AsyncClient, source: SimpleRepository) -> crawler.Crawler:
119+
def create_crawler(
120+
self, http_client: httpx.AsyncClient, source: SimpleRepository
121+
) -> crawler.Crawler:
115122
return crawler.Crawler(
116123
http_client=http_client,
117124
crawl_popular_projects=self.crawl_popular_projects,
@@ -120,7 +127,9 @@ def create_crawler(self, http_client: httpx.AsyncClient, source: SimpleRepositor
120127
cache=self.cache,
121128
)
122129

123-
def _repo_from_url(self, url: str, http_client: httpx.AsyncClient) -> SimpleRepository:
130+
def _repo_from_url(
131+
self, url: str, http_client: httpx.AsyncClient
132+
) -> SimpleRepository:
124133
if urlparse(url).scheme in ("http", "https"):
125134
return HttpRepository(
126135
url=url,
@@ -129,7 +138,9 @@ def _repo_from_url(self, url: str, http_client: httpx.AsyncClient) -> SimpleRepo
129138
else:
130139
return LocalRepository(Path(url))
131140

132-
def create_model(self, http_client: httpx.AsyncClient, database: aiosqlite.Connection) -> model.Model:
141+
def create_model(
142+
self, http_client: httpx.AsyncClient, database: aiosqlite.Connection
143+
) -> model.Model:
133144
source = MetadataInjector(
134145
self._repo_from_url(self.repository_url, http_client=http_client),
135146
http_client=http_client,
@@ -141,7 +152,9 @@ def create_model(self, http_client: httpx.AsyncClient, database: aiosqlite.Conne
141152
crawler=self.create_crawler(http_client, source),
142153
)
143154

144-
def create_controller(self, view: view.View, model: model.Model) -> controller.Controller:
155+
def create_controller(
156+
self, view: view.View, model: model.Model
157+
) -> controller.Controller:
145158
return controller.Controller(
146159
model=model,
147160
view=view,

simple_repository_browser/_search.py

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ class Term:
1313

1414

1515
class FilterOn(Enum):
16-
name = 'name'
17-
summary = 'summary'
18-
name_or_summary = 'name_or_summary'
16+
name = "name"
17+
summary = "summary"
18+
name_or_summary = "name_or_summary"
1919

2020

2121
@dataclasses.dataclass
@@ -57,8 +57,8 @@ def prepare_name(term: Filter) -> SafeSQLStmt:
5757
value = term.value[1:-1]
5858
else:
5959
value = normalise_name(term.value)
60-
value = value.replace('*', '%')
61-
return "canonical_name LIKE ?", (f'%{value}%',)
60+
value = value.replace("*", "%")
61+
return "canonical_name LIKE ?", (f"%{value}%",)
6262

6363

6464
def prepare_summary(term: Filter) -> SafeSQLStmt:
@@ -67,16 +67,16 @@ def prepare_summary(term: Filter) -> SafeSQLStmt:
6767
value = term.value[1:-1]
6868
else:
6969
value = term.value
70-
value = value.replace('*', '%')
71-
return "summary LIKE ?", (f'%{value}%',)
70+
value = value.replace("*", "%")
71+
return "summary LIKE ?", (f"%{value}%",)
7272

7373

7474
def build_sql(term: typing.Union[Term, typing.Tuple[Term, ...]]) -> SafeSQLStmt:
7575
# Return query and params to be used in SQL. query MUST not be produced using untrusted input, as is vulnerable to SQL injection.
7676
# Instead, any user input must be in the parameters, which undergoes sqllite built-in cleaning.
7777
if isinstance(term, tuple):
7878
if len(term) == 0:
79-
return '', ()
79+
return "", ()
8080

8181
# No known query can produce a multi-value term
8282
assert len(term) == 1
@@ -103,7 +103,7 @@ def build_sql(term: typing.Union[Term, typing.Tuple[Term, ...]]) -> SafeSQLStmt:
103103
return f"({sql1} OR {sql2})", terms1 + terms2
104104
elif isinstance(term, Not):
105105
sql1, terms1 = build_sql(term.term)
106-
return f'(Not {sql1})', terms1
106+
return f"(Not {sql1})", terms1
107107
else:
108108
raise ValueError(f"unknown term type {type(term)}")
109109

@@ -145,11 +145,11 @@ def query_to_sql(query) -> SafeSQLStmt:
145145
| -> ())
146146
"""),
147147
{
148-
'And': And,
149-
'Or': Or,
150-
'Filter': Filter,
151-
'Not': Not,
152-
'FilterOn': FilterOn,
148+
"And": And,
149+
"Or": Or,
150+
"Filter": Filter,
151+
"Not": Not,
152+
"FilterOn": FilterOn,
153153
},
154154
)
155155

@@ -166,7 +166,7 @@ def simple_name_from_query(terms: typing.Tuple[Term, ...]) -> typing.Optional[st
166166
for term in terms:
167167
if isinstance(term, Filter):
168168
if term.filter_on in [FilterOn.name_or_summary, FilterOn.name]:
169-
if '*' in term.value or '"' in term.value:
169+
if "*" in term.value or '"' in term.value:
170170
break
171171
return normalise_name(term.value)
172172
else:

0 commit comments

Comments
 (0)