No description
  • JavaScript 38.9%
  • Rust 37.4%
  • HTML 22.5%
  • CSS 1.2%
Find a file
Hugo Wang 7f54965a4a fix hn
2026-02-20 16:42:59 +08:00
media misc 2026-02-19 20:09:59 +08:00
migrations add 3 apps 2026-02-20 15:04:04 +08:00
src fix hn 2026-02-20 16:42:59 +08:00
static added gpt and mmgo 2026-02-19 18:35:12 +08:00
templates add 3 apps 2026-02-20 15:04:04 +08:00
.env misc 2026-02-20 10:07:36 +08:00
.env.example init 2026-02-18 20:42:31 +08:00
.env.hwsite added tv and uploads 2026-02-19 11:22:57 +08:00
.gitignore init 2026-02-18 20:42:31 +08:00
Cargo.lock misc 2026-02-20 10:07:36 +08:00
Cargo.toml stc code etc 2026-02-19 19:35:58 +08:00
README.md init 2026-02-18 20:42:31 +08:00

hwsite

A word learning web application built with Rust, Axum, and PostgreSQL. Features dictionary lookups, word lists, search history, and OpenAI GPT integration for definitions.

Prerequisites

  • Rust (stable)
  • PostgreSQL

Setup

1. Create the database

createdb hwsite

2. Configure environment variables

Copy the example file and edit it:

cp .env.example .env

Required variables:

Variable Description Default
DATABASE_URL PostgreSQL connection string (required)
SESSION_SECRET Secret key for session signing (use a random 64-char string) default-secret-change-me-in-production-please
OPENAI_API_KEY OpenAI API key for GPT word definitions
MEDIA_ROOT Path to media file directory ./media
HOST Bind address 0.0.0.0
PORT Listen port 3000
RUST_LOG Log level filter hwsite=info,tower_http=info

Example .env:

DATABASE_URL=postgres://user:password@localhost/hwsite
SESSION_SECRET=change-me-to-a-random-64-char-string
OPENAI_API_KEY=sk-xxx
MEDIA_ROOT=/path/to/media

3. Build and run

cargo run

Database migrations run automatically on startup. The app will be available at http://localhost:3000.

Project structure

src/
├── main.rs              # Entry point, router setup
├── config.rs            # Environment/config loading
├── error.rs             # Error types
├── auth/
│   ├── middleware.rs     # AuthUser / OptionalUser extractors
│   └── session.rs       # Password hashing, flash messages
├── db/
│   ├── mod.rs           # Connection pool setup
│   ├── users.rs         # User queries
│   ├── words.rs         # Word queries
│   ├── word_lists.rs    # Word list queries
│   ├── history.rs       # History queries
│   └── session_store.rs # PostgreSQL session backend
├── handlers/            # Route handlers
└── services/
    ├── gpt.rs           # OpenAI GPT integration
    ├── dictcn.rs        # dict.cn scraper
    ├── huffpost.rs      # HuffPost article fetching
    └── pron.rs          # Pronunciation utilities

migrations/              # SQL migrations (auto-applied)
templates/               # Tera HTML templates
static/                  # CSS and JS assets

Database

The app uses SQLx with automatic migrations. Two migrations are included:

  • initialauth_user, accounts_usertoken, and tower_sessions tables
  • wordswords_word, words_wordsapi, words_wordct, words_example, words_wordlist, words_wordlistitem, words_history, words_article tables

The password format is compatible with Django's pbkdf2_sha256 scheme, so existing Django user records can be used directly.

Routes

Authentication

  • GET/POST /accounts/login/ — Login
  • GET /accounts/logout/ — Logout

Words

  • GET /w/ — Home page
  • GET /w/x/ — Dictionary lookup
  • GET /w/word/{text}/ — Word details
  • POST /w/lookup/ — AJAX word search (JSON)
  • GET /w/wordsapi/{word}/ — WordsAPI definitions (JSON)
  • POST /w/counter/ — Word counter tool

Word lists

  • GET/POST /w/create-word-list/ — Create word list
  • GET/POST /w/edit-word-list/{id}/ — Edit word list
  • GET /w/word-list/{id}/ — Run/practice word list
  • GET /w/quick-list/{id}/ — Quick view
  • GET /w/demo/ — Demo list

History & misc

  • GET /w/history/ — Search history
  • POST /w/history/delete/ — Delete history items
  • GET /w/news/ — Latest news
  • GET /w/api/huffpost/ — HuffPost API