Skip to content

Commit b04739a

Browse files
authored
Merge pull request #8 from leozqin/sort
Add sorting options for list book page
2 parents 965af2e + e72a77c commit b04739a

File tree

7 files changed

+65
-13
lines changed

7 files changed

+65
-13
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Local Library
2-
Local Library is a simple read-only ebook library that indexes your `epub` ebooks against a read-only file system and provides a nice UI to browse and download them.
2+
Local Library is a simple read-only ebook library that indexes your `epub` ebooks against a read-only file system and provides a nice UI to browse and download them. For some more color on the intent and architecture of this application, [see this blog post](https://www.leozqin.me/posts/local-library/).
33

44
![a screenshot of the main (and only) page of local-library](assets/library.png)
55

@@ -13,7 +13,7 @@ To start the web interface, first install nodejs 22. Then, navigate to `web` and
1313

1414
To run both the API and web interface at the same time, you'll need to create separate terminal sessions, of course.
1515

16-
If you're using nix, you can install pre-reqs by doing `nix-shell nodejs_22 python312`.
16+
If you're using nix, you can install pre-reqs by doing `nix-shell -p nodejs_22 python312`.
1717

1818
## Docker
1919
Modify [the Compose stack](docker-compose.yml) to your heart's content, and then run `docker compose up` to start the app.

main.py

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,23 @@
1-
from fastapi import FastAPI
1+
from enum import Enum
2+
from operator import attrgetter
3+
from typing import Optional
4+
5+
from fastapi import FastAPI, Query, Depends
26
from fastapi.responses import FileResponse
37
from fastapi_utilities import repeat_every
8+
from pydantic import BaseModel, Field
49
from contextlib import asynccontextmanager
510
from random import shuffle
611
import lib
712

13+
class SortMethod(str, Enum):
14+
random = "random"
15+
az = "az"
16+
za = "za"
17+
18+
class ListBooksQuery(BaseModel):
19+
sort: Optional[SortMethod] = Field(Query(default=SortMethod.random))
20+
821
@asynccontextmanager
922
async def lifespan(app: FastAPI):
1023
lib.parse_library()
@@ -18,10 +31,16 @@ async def reparse_library():
1831
app = FastAPI(lifespan=lifespan)
1932

2033
@app.get("/list-books")
21-
def list_books():
34+
def list_books(sort: SortMethod = SortMethod.random):
2235
books = lib.list_books()
23-
shuffle(books)
24-
36+
37+
if sort is SortMethod.random:
38+
shuffle(books)
39+
elif sort is SortMethod.az:
40+
books.sort(key=attrgetter("title"), reverse=False)
41+
elif sort is SortMethod.za:
42+
books.sort(key=attrgetter("title"), reverse=True)
43+
2544
return books
2645

2746

web/package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

web/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "web",
33
"type": "module",
4-
"version": "0.0.5",
4+
"version": "0.0.6",
55
"scripts": {
66
"dev": "astro dev",
77
"build": "astro build",

web/src/components/Books.astro

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,13 @@ type Book = {
88
creators: Array<string>;
99
};
1010
11+
const sort = Astro.url.searchParams.get("sort") || "random";
12+
1113
const apiEndpoint: string = import.meta.env.API_BASE_URL
1214
? import.meta.env.API_BASE_URL
1315
: "http://api";
1416
15-
const response = await fetch(`${apiEndpoint}/list-books`);
17+
const response = await fetch(`${apiEndpoint}/list-books?sort=${sort}`);
1618
const data: Array<Book> = await response.json();
1719
---
1820

web/src/components/Header.astro

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1+
---
2+
import SortOption from "./SortOption.astro"
3+
---
14
<section class="library-header">
2-
<h1>
5+
<h1 class="header-items">
36
<a href="/"><i>Local Library</i></a>
47
</h1>
8+
<SortOption />
59
</section>
610
<style>
711
* {
@@ -12,8 +16,8 @@
1216
padding-left: 2rem;
1317
background-color: black;
1418
height: 100%;
15-
padding-top: 1rem;
16-
padding-bottom: 1rem;
19+
padding-top: 0.5rem;
20+
padding-bottom: 0.5rem;
1721
margin-bottom: 0.5rem;
1822
position: sticky;
1923
top: 0;
@@ -25,4 +29,7 @@
2529
color: white;
2630
}
2731
}
32+
.header-items {
33+
display: inline-block;
34+
}
2835
</style>

web/src/components/SortOption.astro

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<ul class="header-item">
2+
<li class="header-item sort-button"><a href="/?sort=random">Sort Random</a></li>
3+
<li class="header-item sort-button"><a href="/?sort=az">Sort A-Z</a></li>
4+
<li class="header-item sort-button"><a href="/?sort=za">Sort Z-A</a></li>
5+
</ul>
6+
7+
<style>
8+
.header-item {
9+
display: inline-block
10+
}
11+
.sort-button {
12+
margin-right: 0.5rem;
13+
margin-left: 0.5rem;
14+
margin-bottom: 0.5rem;
15+
border-color: white;
16+
border-style: solid;
17+
border-radius: 6px;
18+
border-width: 2px;
19+
padding: 0.5rem;
20+
a {
21+
color: white
22+
}
23+
}
24+
</style>

0 commit comments

Comments
 (0)