Skip to content

dharbigt/cojak

Cojak: Unihan Database Reference Engine

Cojak is a Flask-based web application that provides comprehensive reference access to Asian language character databases, primarily Unihan, CEDICT, and RADK (Radical Array Kanji Dictionary). It's designed as both a learning tool for students and a reference database for developers, accessible through an intuitive web interface.

Originally created in 2005 as a PHP application, Cojak has been rewritten in Python/Flask to provide modern, performant access to interconnected Unicode and East Asian linguistic data.

Radical index Character detail
Radical index Character detail

Features

Character Discovery & Reference

  • Radical Charts: Browse characters organized by radical and stroke count

    • Kangxi radicals
    • CJK radicals
    • RADK (Radical Array Kanji Dictionary)
    • Each radical links to all characters that contain it
  • Syllable Index: Interactive Mandarin pinyin matrix

    • Organized by initials (consonants) and finals (vowel components)
    • Includes all valid Mandarin syllables with tone marks
    • Click any syllable to see all characters pronounced that way
  • Name Indices: Chinese naming character databases

    • Surname index with usage frequency
    • Given name indices (general, male-only, female-only, ambigender)
    • Shows character count and percentage of usage
  • School Grade Characters: Hong Kong primary school curriculum

    • Grades 1-6 with traditional/simplified variants
    • Organized by stroke count
  • USENET Frequency: Common characters by usage frequency

    • Three frequency tiers
    • Traditional and simplified variants
  • Character Detail Viewer: Comprehensive information on any character

    • Unicode codepoint and hanzi form
    • Radical and stroke analysis
    • Mandarin, Cantonese, Japanese (on/kun), Korean, and Vietnamese readings
    • English definitions
    • Character variants (traditional/simplified)
  • Today's Character: Date-based character selection

  • Random Character: Browse random characters from the database

Visitor Tracking & Analytics

  • Global Visitor Map: Displays all unique visitors as points on an interactive map
    • Tracks IP address, latitude, and longitude
    • Visualizes geographic distribution of Cojak users worldwide
    • Accessible at /map

Data Integration

Cojak interweaves multiple authoritative Asian language databases:

  • Unihan: The Unicode Han Unification database
  • CEDICT: Chinese-English Dictionary
  • RADK: Radical Array Kanji Dictionary

Characters are cross-linked across all databases, allowing you to discover connections between stroke patterns, pronunciation, definitions, and usage.

Setup

Requirements

  • Python 3.12+
  • Flask 3.0+
  • SQLAlchemy 2.0+
  • SQLite 3

See requirements.txt for complete dependency list.

Installation

  1. Clone the repository:
git clone https://github.com/dharbigt/cojak.git
cd cojak
  1. Create a virtual environment:
python3 -m venv geo
source geo/bin/activate
  1. Install dependencies:
pip install -r requirements.txt
  1. Configure environment variables:
cp .env.example .env
# Edit .env — at minimum set SECRET_KEY to a long random value:
python3 -c "import secrets; print(secrets.token_hex(32))"
  1. Obtain the database (see Database section below)

Running Locally

# Development server
python run.py

# Or via Flask directly
export FLASK_APP=run.py
export FLASK_ENV=development
flask run

The application will be available at http://localhost:5000

# Production (gunicorn)
gunicorn -w 4 -b 0.0.0.0:8000 run:app

Database

Structure

Cojak uses a pre-populated SQLite database (instance/cojak.db) containing:

Character & Linguistic Data:

  • unihan: Main Unihan character data with phonetic readings, definitions, and stroke information
  • unihan_radicals: Kangxi radical definitions and Unicode values
  • unihan_folded_radicals: CJK and other radical classification systems
  • radk_index: Radical Array Kanji Dictionary cross-reference
  • cedict_entries: CEDICT Chinese-English dictionary entries
  • cedict_index: CEDICT character index for lookup
  • names_index: Chinese name character usage statistics

Analytics:

  • visitors: User tracking table with fields: ip (unique IP address), latitude, longitude

Obtaining the Database

The compiled database (instance/cojak.db, ~113 MB) is not included in this repository. It is distributed as compressed SQL table dumps in a companion repository:

cojak-db — SQL dumps, one file per table, compressed with gzip

# After cloning cojak-db alongside this repo:
mkdir -p instance
for f in cojak-db/*.sql.gz; do gunzip -c "$f" | sqlite3 instance/cojak.db; done

Alternatively, download a pre-built cojak.db release from the cojak-db releases page and place it at instance/cojak.db.

Data Format Notes

The original import scripts (import/edict/, etc.) predate current distribution formats for Unihan and CEDICT. The database distributed via cojak-db represents a curated snapshot. Pull requests to update or replace the import scripts for current upstream formats are welcome.

Database Initialization

Once instance/cojak.db is in place the application starts without further setup. To reset, delete the file and re-import from cojak-db.

Architecture

Project Structure

cojak/
├── app/                          # Main Flask application
│   ├── __init__.py              # App factory and main routes
│   ├── config.py                # Configuration
│   ├── models.py                # Database models (User, Place)
│   ├── static/                  # CSS, JS, images
│   │   ├── css/                 # Stylesheets
│   │   ├── js/                  # Client-side JavaScript
│   │   └── json/                # Static data files
│   ├── templates/               # HTML templates (Jinja2)
│   └── user/                    # User authentication (legacy)
├── edict/                        # Original data import scripts
├── geo/                          # Python virtual environment
├── migrations/                   # Alembic database migrations
├── instance/                     # Instance-specific files
│   └── cojak.db                # SQLite database
├── index.wsgi                    # WSGI entry point
└── requirements.txt              # Python dependencies

Tech Stack

  • Framework: Flask 3.0.3
  • Database: SQLite with SQLAlchemy 2.0
  • ORM: Flask-SQLAlchemy
  • Frontend: Jinja2 templates, vanilla JavaScript
  • Security: Flask-WTF (CSRF protection), Flask-Bcrypt
  • Server: WSGI-compatible (tested with gunicorn)

Main Routes

All routes serve primarily HTML templates except the /unihan/* and /cedict/* endpoints which return JSON.

Character Browsers:

  • / or /index - Radical index (Kangxi)
  • /kangxi_index - Kangxi radical chart
  • /cjk_index - CJK radical chart
  • /radk_index - RADK (Hanzi structure components)
  • /radk/<unicode> - Characters using a specific RADK component
  • /syllable_index - Mandarin syllable matrix
  • /syllable/<syllable> - Characters with given syllable pronunciation
  • /surname_index, /gn_index, /bgn_index, /ggn_index, /agn_index - Various name indices
  • /school_index/<grade> - School characters by grade (1-6)
  • /usenet_index/<frequency> - Characters by frequency tier (1-3)
  • /zi/ - Interactive character viewer
  • /zi/<codepoint> - Character detail page
  • /zi/today - Today's character
  • /zi/random - Random character

API Endpoints (JSON):

  • /unihan/detail/<row_id> - Full character details
  • /unihan/batch - Paginated character batch
  • /unihan/radicals - All radicals with metadata
  • /cedict/entries/<codepoint> - Dictionary entries for a character
  • /cedict/search/<term> - Search dictionary by definition

Information:

  • /about - About page (data sources, project info)
  • /donate - Donation page
  • /convert - Text to HTML entity converter

Data Sources

Unihan Database

The Unicode Han Unification database. Primary source for character definitions, pronunciations, and structural information.

Note: The original data source information is maintained on the /about page. As of this writing, that page may be outdated as Unihan and other databases have changed their distribution formats.

CEDICT

Chinese-English Dictionary - comprehensive bilingual dictionary with example usage.

RADK

Radical Array Kanji Dictionary - organizes kanji by radical and structural components.

Configuration

All secrets and deployment-specific values are set via environment variables loaded from a .env file (see .env.example).

Variable Required Default Description
SECRET_KEY yes Flask session signing key. Generate with secrets.token_hex(32)
FLASK_ENV no production Set to development to enable debug mode
MAIL_SERVER no smtp.gmail.com SMTP server for registration emails
MAIL_PORT no 587 SMTP port
MAIL_USE_TLS no true Enable STARTTLS
MAIL_USERNAME no SMTP login username
MAIL_PASSWORD no SMTP login password or app password

The database is always loaded from instance/cojak.db relative to the project root.

Deployment

Hosting

Cojak has been hosted continuously since 2005. For deployment:

  1. Use a WSGI application server (e.g., gunicorn, uWSGi)
  2. Configure a reverse proxy (e.g., Nginx, Apache)
  3. Ensure the instance/cojak.db file persists between deployments
  4. Set SESSION_COOKIE_SECURE = True if using HTTPS

Example Gunicorn Command

gunicorn -w 4 -b 0.0.0.0:8000 --access-logfile - index:app

Environment Variables

See .env.example and the Configuration table above. In production, set these in your process manager or web server environment rather than in a .env file.

Development

Running Tests

# To be configured

Database Migrations

Alembic is configured for database schema migrations:

flask db upgrade        # Apply migrations
flask db migrate        # Generate new migration

Notes

Legacy Code

This project was ported from PHP (2005-present). Some scaffolding from the Flask template may remain:

  • User authentication system - Likely to be removed
  • Place model and related code - May be removed in future cleanup

Future Development

The /deck and /exchange endpoints are placeholders for future gameplay features and are currently stubbed out.

License

Cojak is free software released under the GNU General Public License v3.0.

The compiled database distributed via cojak-db is derived from:

  • Unihan — © Unicode, Inc. (Unicode Terms of Use)
  • CC-CEDICT — Creative Commons Attribution-Share Alike 3.0
  • KANJIDIC / RADK — © The Electronic Dictionary Research and Development Group (CC BY-SA 4.0)

Each dataset's own license terms apply to its data.

Contributing

Bug reports and pull requests are welcome. For significant changes, please open an issue first to discuss what you'd like to change.

Areas where contributions are especially useful:

  • Updated import scripts for current Unihan / CEDICT / RADK distribution formats
  • Test coverage
  • Accessibility improvements

Contact & Support

For questions about the Cojak database or this implementation, see the /about page or open a GitHub issue.


Cojak — Making Asian linguistic databases accessible and intertwined since 2005.

About

Making Asian linguistic databases accessible and intertwined since 2005.

Resources

License

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors