commit ee84c65ceb6516221cb6ea339d66c4c167556fb6
parent d4738d9c29bbc0e736ab458a18d71ab831b6ef27
Author: David Eisinger <[email protected]>
Date: Mon, 6 Oct 2025 14:34:45 -0400
Update README
Diffstat:
| M | README.md | | | 47 | +++++++++++++++++++++++++++++++++++++++++++++-- |
1 file changed, 45 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
@@ -1,10 +1,11 @@
# marky
-A simple web API for bookmarking websites, written in Go. It stores bookmarks in a local SQLite database at `~/.marky/bookmarks.sql` and exposes HTTP endpoints to create and list bookmarks. On creation, Marky archives a plaintext rendering of the page using a pure-Go HTML-to-text conversion and stores it alongside the bookmark.
+A simple web API for bookmarking websites, written in Go. It stores bookmarks in a local SQLite database at `~/.marky/bookmarks.sql`, archives a plaintext rendering of each page, and exposes HTTP endpoints for CRUD and full‑text search. A minimal Vue.js frontend is embedded and served at `/`.
- Language: Go
- Storage: SQLite (via `modernc.org/sqlite`, pure Go)
- Default address: `:8080`
+- Frontend: Vue 3 (from CDN), embedded static files
## Requirements
@@ -21,6 +22,7 @@ A simple web API for bookmarking websites, written in Go. It stores bookmarks in
- `./bin/marky`
- The database file is created automatically at `~/.marky/bookmarks.sql` and migrations are applied on startup.
+- Open the web UI at: `http://localhost:8080/`
## API
@@ -40,6 +42,7 @@ Create a new bookmark.
```
- Responses:
- `201 Created` with JSON body of the created bookmark (archive stored synchronously)
+ - `200 OK` if the URL already exists; the archive is refreshed and `updated_at` is touched (idempotent by URL)
- `400 Bad Request` for invalid payload
- `415 Unsupported Media Type` if not JSON
- `502 Bad Gateway` if archiver fails to fetch content
@@ -82,9 +85,48 @@ curl -s 'http://localhost:8080/bookmarks?q=example' | jq
```
Notes on search excerpts:
-- `excerpt` highlights matches in square brackets, e.g., `... some [example] text ...`.
+- `excerpt` highlights matches using guillemets, e.g., `… some «example» text …`.
- Ellipses `…` indicate omitted surrounding text, and snippets focus on the archived page content.
+### PUT /bookmarks/{id}
+
+Update a bookmark’s URL, title, and/or description.
+
+- Request headers:
+ - `Content-Type: application/json`
+- Request body:
+```
+{
+ "url": "https://example.com", // required
+ "title": "New Title", // required
+ "description": "Updated notes" // optional (omitted preserves existing)
+}
+```
+- Responses:
+ - `200 OK` with updated bookmark JSON
+ - `400 Bad Request` for invalid payload
+ - `404 Not Found` if the bookmark ID does not exist
+ - `500 Internal Server Error` on unexpected errors
+- curl example:
+```
+curl -s -X PUT http://localhost:8080/bookmarks/1 \
+ -H 'Content-Type: application/json' \
+ -d '{"url":"https://example.com","title":"Updated","description":"Notes"}' | jq
+```
+
+### DELETE /bookmarks/{id}
+
+Delete a bookmark (and its search index entry). Archived text is removed from search index but remains in `archives` table only if you retain rows; this implementation removes the FTS entry, and the foreign key setup will cascade archives removal if configured via migrations.
+
+- Responses:
+ - `204 No Content` on success
+ - `404 Not Found` if the bookmark ID does not exist
+ - `500 Internal Server Error` on unexpected errors
+- curl example:
+```
+curl -i -X DELETE http://localhost:8080/bookmarks/1
+```
+
## Data Model
Table: `bookmarks`
@@ -119,6 +161,7 @@ curl -s http://localhost:8080/bookmarks/1/archive
- Database and helpers: `internal/`
- Migrations: `internal/migrations/*.sql`
- Archiver: `internal/archiver.go` (pure-Go HTML-to-text)
+- Embedded web UI: `internal/web/` (served at `/`)
---