Metadata-Version: 2.4
Name: simplesitesearch
Version: 0.0.7
Summary: Reptile Simple Site Search django app
Home-page: https://github.com/FlavienLouis/simplesitesearch
Author: Reptile Tech
Author-email: Reptile Tech <flouis@reptile.tech>
Maintainer-email: Reptile Tech <flouis@reptile.tech>
License: MIT
Project-URL: Homepage, https://github.com/FlavienLouis/simplesitesearch
Project-URL: Documentation, https://github.com/FlavienLouis/simplesitesearch#readme
Project-URL: Repository, https://github.com/FlavienLouis/simplesitesearch.git
Project-URL: Bug Tracker, https://github.com/FlavienLouis/simplesitesearch/issues
Keywords: django,search,cms,django-cms
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Framework :: Django
Classifier: Framework :: Django :: 2.2
Classifier: Framework :: Django :: 3.2
Classifier: Framework :: Django :: 4.0
Classifier: Framework :: Django :: 4.1
Classifier: Framework :: Django :: 4.2
Classifier: Framework :: Django :: 5.0
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.6
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: Django>=2.2
Requires-Dist: django-cms>=3.2
Requires-Dist: requests>=2.22.0
Dynamic: author
Dynamic: home-page
Dynamic: license-file
Dynamic: requires-python

# Simple Site Search

A simple Django app for site search functionality with Django CMS integration. This package provides a clean, easy-to-use search interface that can be integrated into Django CMS projects.


## Features

- **Django CMS Integration**: Seamlessly integrates with Django CMS as an apphook
- **Pagination Support**: Built-in pagination for search results
- **Multi-language Support**: Supports internationalization with Django's i18n framework
- **Customizable Templates**: Easy to customize search result templates
- **API Integration**: Connects to external search APIs (like AddSearch)
- **Responsive Design**: Bootstrap-compatible templates

## Installation

Install the package using pip:

```bash
pip install simplesitesearch
```

## Configuration

### 1. Add to INSTALLED_APPS

Add `simplesitesearch` to your Django project's `INSTALLED_APPS`:

```python
INSTALLED_APPS = [
    # ... other apps
    'simplesitesearch',
    # ... other apps
]
```

### 2. Required Settings

Add the following settings to your Django settings file:

```python
# Search API Configuration
SITE_SEARCH_API_BASE_URL = "https://search.rt5.ca/reptile_search/api/search/"
SITE_SEARCH_SITE_KEY = "your-site-key-here"
SITE_SEARCH_API_KEY = "your-api-key-here"  # Optional, if required by your API
```

### 3. URL Configuration

Include the app's URLs in your main `urls.py`:

```python
from django.urls import path, include

urlpatterns = [
    # ... other URL patterns
    path('search/', include('simplesitesearch.urls')),
    # ... other URL patterns
]
```

## Django CMS Integration

### 1. Create a Search Page

1. Log into your Django CMS admin
2. Go to **Django CMS** > **Pages**
3. Create a new page named "Search"
4. Translate the title and slug in all languages
5. Save and continue editing

### 2. Configure the Page

1. Go to **Advanced settings** of the search page
2. Set **APPLICATION** to "Site Search"
3. Set the **Application ID** to `'site_search'` (this is the default value)
4. Save the page
5. Remove the page from the menu (uncheck "menu" in the table)
6. Publish the page in all languages

### 3. Access the Search

Your search functionality will be available at the URL you configured for the search page.

## Usage

### Basic Search

The search form accepts a `q` parameter for the search term:

```
/search/?q=your+search+term
```

### Pagination

The search results support pagination with a `page` parameter:

```
/search/?q=your+search+term&page=2
```

### Tags filter

You can send a comma-separated list of tags to filter results. The `tag` (or `tags`) query parameter is forwarded to the API as `tags`:

```
/search/?q=your+search+term&tag=news,blog,tutorial
```

Pagination links preserve the tag filter.

### Honeypot Protection

The search includes basic honeypot protection. If a `message` parameter is present, the search will not execute.

## Indexing authentication (optional)

When crawling or indexing protected CMS content, enable opaque bearer-token auth so indexers can act as a configured Django user.

### Settings

```python
SIMPLE_SITE_SEARCH_INDEXING_ENABLED = True
SIMPLE_SITE_SEARCH_INDEXING_USER = "indexer"  # username, user id, or pk string
SIMPLE_SITE_SEARCH_INDEXING_BOOTSTRAP_TOKEN = "your-long-random-secret"

# Optional (defaults shown)
SIMPLE_SITE_SEARCH_INDEXING_ACCESS_TTL = 3600       # seconds
SIMPLE_SITE_SEARCH_INDEXING_REFRESH_TTL = 86400      # seconds
SIMPLE_SITE_SEARCH_INDEXING_CACHE_PREFIX = "sss_idx"
```

Use a shared Django cache backend in multi-worker deployments so tokens are visible across processes.

### Middleware

Add after `AuthenticationMiddleware`:

```python
MIDDLEWARE = [
    # ...
    "django.contrib.auth.middleware.AuthenticationMiddleware",
    "simplesitesearch.indexing_middleware.IndexingAccessTokenMiddleware",
    # ...
]
```

### Token endpoints

Both endpoints are under the same URL prefix as search (e.g. `/search/` when included at `path('search/', include('simplesitesearch.urls'))`):

| Endpoint | Auth header | Response |
|----------|-------------|----------|
| `POST …/internal/indexing/token/` | `Authorization: Bearer <bootstrap_token>` | `access_token`, `refresh_token`, `expires_in`, `refresh_expires_in` |
| `POST …/internal/indexing/refresh/` | `Authorization: Bearer <refresh_token>` | New token pair (refresh rotation) |

Send the access token on subsequent requests; the middleware logs in the configured user for that request.

## Utility functions (QOL)

The app provides helpers in `simplesitesearch.utils` for use in views, management commands, or other code.

| Function | Description |
|----------|-------------|
| **`get_search_results(term, current_page, tags=None)`** | Fetches search results from the API. Returns a dict with `total_hits` and `hits`. On error returns `{"total_hits": 0, "hits": []}`. |
| **`get_search_api_url(term, current_page, tags=None)`** | Builds the full search API URL (uses Django settings and current language). |
| **`build_search_query_string(term, page=1, tags=None)`** | Builds the query string for search URLs (e.g. pagination links), e.g. `?q=foo&page=2&tag=a,b`. |
| **`parse_comma_separated_tags(value)`** | Parses a comma-separated string into a list of stripped tags; returns `[]` if value is falsy. |
| **`normalize_search_term(term, max_words=10)`** | Trims and limits the search term to a maximum number of words. |
| **`safe_int(value, default=None)`** | Safely converts a value to `int`; returns `default` on failure. |

**Example — fetch results in code:**

```python
from simplesitesearch.utils import get_search_results

data = get_search_results("django", current_page=1, tags=["cms", "tutorial"])
total = data["total_hits"]
results = data["hits"]
```

**Example — build search/pagination URLs:**

```python
from simplesitesearch.utils import build_search_query_string

# Pagination link for page 2 with tag filter
qs = build_search_query_string("my query", page=2, tags=["blog"])
# => "?q=my+query&page=2&tag=blog"
```

## Customization

### Templates

The package includes two main templates:

- `simplesitesearch/search_results.html` - Main search results template
- `simplesitesearch/pagination.html` - Pagination template

#### Template Customization

You can override these templates in your project by creating templates with the same names in your template directory. The templates are designed to be easily customizable:

**Template Include Paths:**
- `simplesitesearch/search_results.html` - Main search results page
- `simplesitesearch/pagination.html` - Pagination component (included in search_results.html)

**To customize templates:**
1. Create a `templates/simplesitesearch/` directory in your Django project
2. Copy the template files from the package and modify them as needed
3. Your custom templates will override the package defaults

**Example template structure:**
```
your_project/
├── templates/
│   └── simplesitesearch/
│       ├── search_results.html  # Your custom search results template
│       └── pagination.html      # Your custom pagination template
```

### Styling

The templates use Bootstrap classes and can be easily customized with CSS. The main CSS classes used are:

- `.pagination` - Pagination container
- `.search_query` - Search query display
- `.search_results` - Results count display
- `.wrapper_single_result` - Individual result container

## API Response Format

The search expects the API to return JSON in the following format:

```json
{
    "total_hits": 42,
    "hits": [
        {
            "title": "Page Title",
            "url": "https://example.com/page/",
            "highlight": "Search term highlighted content..."
        }
    ]
}
```

## Requirements

- Python 3.6+
- Django 2.2+
- django-cms 3.2+
- requests 2.22.0+

## Development

### Local Development

1. Clone the repository
2. Install in development mode:
   ```bash
   pip install -e .
   ```

### Testing

Run the tests with:

```bash
python manage.py test simplesitesearch
```

## License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

## Support

For support and questions, please open an issue on the [GitHub repository](https://github.com/FlavienLouis/simplesitesearch/issues).

## Changelog

### 0.0.7
- **Added** optional indexing authentication: bootstrap/refresh token endpoints, cache-backed opaque tokens, and `IndexingAccessTokenMiddleware` for indexer login via Bearer access tokens.

### 0.0.6
- **Changed** search results: API hits normalized for templates (`display_title`, `snippet`, domain/type/language/tags/date metadata); highlighted title when available.
- **Changed** templates: `{% load static %}` instead of deprecated `staticfiles` (Django 4+).

### 0.0.5
- **Fixed** tag parsing: single tag string (e.g. `Hometag`) no longer sent as `H,o,m,e,t,a,g`; string is treated as one tag. API URL keeps commas unencoded so multiple tags parse correctly.

### 0.0.4
- SSL verification configurable via `SITE_SEARCH_VERIFY_SSL` (default `True`).

### 0.0.3
- Added `simplesitesearch.utils` QOL helpers: `get_search_results`, `get_search_api_url`, `build_search_query_string`, `parse_comma_separated_tags`, `normalize_search_term`, `safe_int`
- Tag filter: `tag` (or `tags`) query parameter forwarded to API as comma-separated `tags`; pagination links preserve tags
- README: Utility functions section and tags filter documentation

### 0.0.2
- Fixed template include path in search_results.html
- Updated pagination template include to use full namespace: `simplesitesearch/pagination.html`
- Improved template isolation and namespace consistency

### 0.0.1
- **First stable release**
- Django CMS integration with apphook support
- Pagination support for search results
- Multi-language support with Django i18n
- Basic search functionality with API integration
- Template customization support
- Support for Python 3.6+ and Django 2.2+
- Reptile Search API integration
- Comprehensive documentation and setup instructions


