simplesitesearch 0.0.1.dev1__tar.gz → 0.0.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {simplesitesearch-0.0.1.dev1/simplesitesearch.egg-info → simplesitesearch-0.0.3}/PKG-INFO +70 -17
- {simplesitesearch-0.0.1.dev1 → simplesitesearch-0.0.3}/README.md +64 -11
- {simplesitesearch-0.0.1.dev1 → simplesitesearch-0.0.3}/pyproject.toml +6 -6
- {simplesitesearch-0.0.1.dev1 → simplesitesearch-0.0.3}/setup.cfg +6 -6
- {simplesitesearch-0.0.1.dev1 → simplesitesearch-0.0.3}/setup.py +2 -2
- simplesitesearch-0.0.3/simplesitesearch/__init__.py +1 -0
- {simplesitesearch-0.0.1.dev1 → simplesitesearch-0.0.3}/simplesitesearch/templates/simplesitesearch/search_results.html +1 -1
- simplesitesearch-0.0.3/simplesitesearch/utils.py +153 -0
- simplesitesearch-0.0.3/simplesitesearch/views.py +111 -0
- {simplesitesearch-0.0.1.dev1 → simplesitesearch-0.0.3/simplesitesearch.egg-info}/PKG-INFO +70 -17
- {simplesitesearch-0.0.1.dev1 → simplesitesearch-0.0.3}/simplesitesearch.egg-info/SOURCES.txt +1 -0
- simplesitesearch-0.0.1.dev1/simplesitesearch/__init__.py +0 -3
- simplesitesearch-0.0.1.dev1/simplesitesearch/views.py +0 -151
- {simplesitesearch-0.0.1.dev1 → simplesitesearch-0.0.3}/LICENSE +0 -0
- {simplesitesearch-0.0.1.dev1 → simplesitesearch-0.0.3}/MANIFEST.in +0 -0
- {simplesitesearch-0.0.1.dev1 → simplesitesearch-0.0.3}/simplesitesearch/cms_apps.py +0 -0
- {simplesitesearch-0.0.1.dev1 → simplesitesearch-0.0.3}/simplesitesearch/templates/simplesitesearch/pagination.html +0 -0
- {simplesitesearch-0.0.1.dev1 → simplesitesearch-0.0.3}/simplesitesearch/urls.py +0 -0
- {simplesitesearch-0.0.1.dev1 → simplesitesearch-0.0.3}/simplesitesearch.egg-info/dependency_links.txt +0 -0
- {simplesitesearch-0.0.1.dev1 → simplesitesearch-0.0.3}/simplesitesearch.egg-info/not-zip-safe +0 -0
- {simplesitesearch-0.0.1.dev1 → simplesitesearch-0.0.3}/simplesitesearch.egg-info/requires.txt +0 -0
- {simplesitesearch-0.0.1.dev1 → simplesitesearch-0.0.3}/simplesitesearch.egg-info/top_level.txt +0 -0
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: simplesitesearch
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.3
|
|
4
4
|
Summary: Reptile Simple Site Search django app
|
|
5
|
-
Home-page: https://github.com/
|
|
5
|
+
Home-page: https://github.com/FlavienLouis/simplesitesearch
|
|
6
6
|
Author: Reptile Tech
|
|
7
7
|
Author-email: Reptile Tech <flouis@reptile.tech>
|
|
8
8
|
Maintainer-email: Reptile Tech <flouis@reptile.tech>
|
|
9
9
|
License: MIT
|
|
10
|
-
Project-URL: Homepage, https://github.com/
|
|
11
|
-
Project-URL: Documentation, https://github.com/
|
|
12
|
-
Project-URL: Repository, https://github.com/
|
|
13
|
-
Project-URL: Bug Tracker, https://github.com/
|
|
10
|
+
Project-URL: Homepage, https://github.com/FlavienLouis/simplesitesearch
|
|
11
|
+
Project-URL: Documentation, https://github.com/FlavienLouis/simplesitesearch#readme
|
|
12
|
+
Project-URL: Repository, https://github.com/FlavienLouis/simplesitesearch.git
|
|
13
|
+
Project-URL: Bug Tracker, https://github.com/FlavienLouis/simplesitesearch/issues
|
|
14
14
|
Keywords: django,search,cms,django-cms
|
|
15
15
|
Classifier: Development Status :: 5 - Production/Stable
|
|
16
16
|
Classifier: Intended Audience :: Developers
|
|
@@ -48,7 +48,6 @@ Dynamic: requires-python
|
|
|
48
48
|
|
|
49
49
|
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.
|
|
50
50
|
|
|
51
|
-
> **Note**: This is a development version (0.0.1.dev1). The package is still under active development and may have breaking changes in future releases.
|
|
52
51
|
|
|
53
52
|
## Features
|
|
54
53
|
|
|
@@ -119,8 +118,8 @@ urlpatterns = [
|
|
|
119
118
|
### 2. Configure the Page
|
|
120
119
|
|
|
121
120
|
1. Go to **Advanced settings** of the search page
|
|
122
|
-
2. Set
|
|
123
|
-
3. Set **
|
|
121
|
+
2. Set **APPLICATION** to "Site Search"
|
|
122
|
+
3. Set the **Application ID** to `'site_search'` (this is the default value)
|
|
124
123
|
4. Save the page
|
|
125
124
|
5. Remove the page from the menu (uncheck "menu" in the table)
|
|
126
125
|
6. Publish the page in all languages
|
|
@@ -147,10 +146,53 @@ The search results support pagination with a `page` parameter:
|
|
|
147
146
|
/search/?q=your+search+term&page=2
|
|
148
147
|
```
|
|
149
148
|
|
|
149
|
+
### Tags filter
|
|
150
|
+
|
|
151
|
+
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`:
|
|
152
|
+
|
|
153
|
+
```
|
|
154
|
+
/search/?q=your+search+term&tag=news,blog,tutorial
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Pagination links preserve the tag filter.
|
|
158
|
+
|
|
150
159
|
### Honeypot Protection
|
|
151
160
|
|
|
152
161
|
The search includes basic honeypot protection. If a `message` parameter is present, the search will not execute.
|
|
153
162
|
|
|
163
|
+
## Utility functions (QOL)
|
|
164
|
+
|
|
165
|
+
The app provides helpers in `simplesitesearch.utils` for use in views, management commands, or other code.
|
|
166
|
+
|
|
167
|
+
| Function | Description |
|
|
168
|
+
|----------|-------------|
|
|
169
|
+
| **`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": []}`. |
|
|
170
|
+
| **`get_search_api_url(term, current_page, tags=None)`** | Builds the full search API URL (uses Django settings and current language). |
|
|
171
|
+
| **`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`. |
|
|
172
|
+
| **`parse_comma_separated_tags(value)`** | Parses a comma-separated string into a list of stripped tags; returns `[]` if value is falsy. |
|
|
173
|
+
| **`normalize_search_term(term, max_words=10)`** | Trims and limits the search term to a maximum number of words. |
|
|
174
|
+
| **`safe_int(value, default=None)`** | Safely converts a value to `int`; returns `default` on failure. |
|
|
175
|
+
|
|
176
|
+
**Example — fetch results in code:**
|
|
177
|
+
|
|
178
|
+
```python
|
|
179
|
+
from simplesitesearch.utils import get_search_results
|
|
180
|
+
|
|
181
|
+
data = get_search_results("django", current_page=1, tags=["cms", "tutorial"])
|
|
182
|
+
total = data["total_hits"]
|
|
183
|
+
results = data["hits"]
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
**Example — build search/pagination URLs:**
|
|
187
|
+
|
|
188
|
+
```python
|
|
189
|
+
from simplesitesearch.utils import build_search_query_string
|
|
190
|
+
|
|
191
|
+
# Pagination link for page 2 with tag filter
|
|
192
|
+
qs = build_search_query_string("my query", page=2, tags=["blog"])
|
|
193
|
+
# => "?q=my+query&page=2&tag=blog"
|
|
194
|
+
```
|
|
195
|
+
|
|
154
196
|
## Customization
|
|
155
197
|
|
|
156
198
|
### Templates
|
|
@@ -239,18 +281,29 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file
|
|
|
239
281
|
|
|
240
282
|
## Support
|
|
241
283
|
|
|
242
|
-
For support and questions, please open an issue on the [GitHub repository](https://github.com/
|
|
284
|
+
For support and questions, please open an issue on the [GitHub repository](https://github.com/FlavienLouis/simplesitesearch/issues).
|
|
243
285
|
|
|
244
286
|
## Changelog
|
|
245
287
|
|
|
246
|
-
### 0.0.
|
|
247
|
-
-
|
|
248
|
-
-
|
|
249
|
-
-
|
|
250
|
-
|
|
251
|
-
|
|
288
|
+
### 0.0.3
|
|
289
|
+
- 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`
|
|
290
|
+
- Tag filter: `tag` (or `tags`) query parameter forwarded to API as comma-separated `tags`; pagination links preserve tags
|
|
291
|
+
- README: Utility functions section and tags filter documentation
|
|
292
|
+
|
|
293
|
+
### 0.0.2
|
|
294
|
+
- Fixed template include path in search_results.html
|
|
295
|
+
- Updated pagination template include to use full namespace: `simplesitesearch/pagination.html`
|
|
296
|
+
- Improved template isolation and namespace consistency
|
|
297
|
+
|
|
298
|
+
### 0.0.1
|
|
299
|
+
- **First stable release**
|
|
300
|
+
- Django CMS integration with apphook support
|
|
301
|
+
- Pagination support for search results
|
|
302
|
+
- Multi-language support with Django i18n
|
|
303
|
+
- Basic search functionality with API integration
|
|
252
304
|
- Template customization support
|
|
253
305
|
- Support for Python 3.6+ and Django 2.2+
|
|
254
|
-
-
|
|
306
|
+
- Reptile Search API integration
|
|
307
|
+
- Comprehensive documentation and setup instructions
|
|
255
308
|
|
|
256
309
|
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
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.
|
|
4
4
|
|
|
5
|
-
> **Note**: This is a development version (0.0.1.dev1). The package is still under active development and may have breaking changes in future releases.
|
|
6
5
|
|
|
7
6
|
## Features
|
|
8
7
|
|
|
@@ -73,8 +72,8 @@ urlpatterns = [
|
|
|
73
72
|
### 2. Configure the Page
|
|
74
73
|
|
|
75
74
|
1. Go to **Advanced settings** of the search page
|
|
76
|
-
2. Set
|
|
77
|
-
3. Set **
|
|
75
|
+
2. Set **APPLICATION** to "Site Search"
|
|
76
|
+
3. Set the **Application ID** to `'site_search'` (this is the default value)
|
|
78
77
|
4. Save the page
|
|
79
78
|
5. Remove the page from the menu (uncheck "menu" in the table)
|
|
80
79
|
6. Publish the page in all languages
|
|
@@ -101,10 +100,53 @@ The search results support pagination with a `page` parameter:
|
|
|
101
100
|
/search/?q=your+search+term&page=2
|
|
102
101
|
```
|
|
103
102
|
|
|
103
|
+
### Tags filter
|
|
104
|
+
|
|
105
|
+
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`:
|
|
106
|
+
|
|
107
|
+
```
|
|
108
|
+
/search/?q=your+search+term&tag=news,blog,tutorial
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Pagination links preserve the tag filter.
|
|
112
|
+
|
|
104
113
|
### Honeypot Protection
|
|
105
114
|
|
|
106
115
|
The search includes basic honeypot protection. If a `message` parameter is present, the search will not execute.
|
|
107
116
|
|
|
117
|
+
## Utility functions (QOL)
|
|
118
|
+
|
|
119
|
+
The app provides helpers in `simplesitesearch.utils` for use in views, management commands, or other code.
|
|
120
|
+
|
|
121
|
+
| Function | Description |
|
|
122
|
+
|----------|-------------|
|
|
123
|
+
| **`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": []}`. |
|
|
124
|
+
| **`get_search_api_url(term, current_page, tags=None)`** | Builds the full search API URL (uses Django settings and current language). |
|
|
125
|
+
| **`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`. |
|
|
126
|
+
| **`parse_comma_separated_tags(value)`** | Parses a comma-separated string into a list of stripped tags; returns `[]` if value is falsy. |
|
|
127
|
+
| **`normalize_search_term(term, max_words=10)`** | Trims and limits the search term to a maximum number of words. |
|
|
128
|
+
| **`safe_int(value, default=None)`** | Safely converts a value to `int`; returns `default` on failure. |
|
|
129
|
+
|
|
130
|
+
**Example — fetch results in code:**
|
|
131
|
+
|
|
132
|
+
```python
|
|
133
|
+
from simplesitesearch.utils import get_search_results
|
|
134
|
+
|
|
135
|
+
data = get_search_results("django", current_page=1, tags=["cms", "tutorial"])
|
|
136
|
+
total = data["total_hits"]
|
|
137
|
+
results = data["hits"]
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
**Example — build search/pagination URLs:**
|
|
141
|
+
|
|
142
|
+
```python
|
|
143
|
+
from simplesitesearch.utils import build_search_query_string
|
|
144
|
+
|
|
145
|
+
# Pagination link for page 2 with tag filter
|
|
146
|
+
qs = build_search_query_string("my query", page=2, tags=["blog"])
|
|
147
|
+
# => "?q=my+query&page=2&tag=blog"
|
|
148
|
+
```
|
|
149
|
+
|
|
108
150
|
## Customization
|
|
109
151
|
|
|
110
152
|
### Templates
|
|
@@ -193,18 +235,29 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file
|
|
|
193
235
|
|
|
194
236
|
## Support
|
|
195
237
|
|
|
196
|
-
For support and questions, please open an issue on the [GitHub repository](https://github.com/
|
|
238
|
+
For support and questions, please open an issue on the [GitHub repository](https://github.com/FlavienLouis/simplesitesearch/issues).
|
|
197
239
|
|
|
198
240
|
## Changelog
|
|
199
241
|
|
|
200
|
-
### 0.0.
|
|
201
|
-
-
|
|
202
|
-
-
|
|
203
|
-
-
|
|
204
|
-
|
|
205
|
-
|
|
242
|
+
### 0.0.3
|
|
243
|
+
- 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`
|
|
244
|
+
- Tag filter: `tag` (or `tags`) query parameter forwarded to API as comma-separated `tags`; pagination links preserve tags
|
|
245
|
+
- README: Utility functions section and tags filter documentation
|
|
246
|
+
|
|
247
|
+
### 0.0.2
|
|
248
|
+
- Fixed template include path in search_results.html
|
|
249
|
+
- Updated pagination template include to use full namespace: `simplesitesearch/pagination.html`
|
|
250
|
+
- Improved template isolation and namespace consistency
|
|
251
|
+
|
|
252
|
+
### 0.0.1
|
|
253
|
+
- **First stable release**
|
|
254
|
+
- Django CMS integration with apphook support
|
|
255
|
+
- Pagination support for search results
|
|
256
|
+
- Multi-language support with Django i18n
|
|
257
|
+
- Basic search functionality with API integration
|
|
206
258
|
- Template customization support
|
|
207
259
|
- Support for Python 3.6+ and Django 2.2+
|
|
208
|
-
-
|
|
260
|
+
- Reptile Search API integration
|
|
261
|
+
- Comprehensive documentation and setup instructions
|
|
209
262
|
|
|
210
263
|
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
[build-system]
|
|
2
|
-
requires = ["setuptools>=45", "wheel"
|
|
2
|
+
requires = ["setuptools>=45", "wheel"]
|
|
3
3
|
build-backend = "setuptools.build_meta"
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "simplesitesearch"
|
|
7
|
-
|
|
7
|
+
version = "0.0.3"
|
|
8
8
|
description = "Reptile Simple Site Search django app"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = {text = "MIT"}
|
|
@@ -46,10 +46,10 @@ dependencies = [
|
|
|
46
46
|
]
|
|
47
47
|
|
|
48
48
|
[project.urls]
|
|
49
|
-
Homepage = "https://github.com/
|
|
50
|
-
Documentation = "https://github.com/
|
|
51
|
-
Repository = "https://github.com/
|
|
52
|
-
"Bug Tracker" = "https://github.com/
|
|
49
|
+
Homepage = "https://github.com/FlavienLouis/simplesitesearch"
|
|
50
|
+
Documentation = "https://github.com/FlavienLouis/simplesitesearch#readme"
|
|
51
|
+
Repository = "https://github.com/FlavienLouis/simplesitesearch.git"
|
|
52
|
+
"Bug Tracker" = "https://github.com/FlavienLouis/simplesitesearch/issues"
|
|
53
53
|
|
|
54
54
|
[tool.setuptools]
|
|
55
55
|
packages = ["simplesitesearch"]
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
[metadata]
|
|
2
2
|
name = simplesitesearch
|
|
3
|
-
version = 0.0.
|
|
3
|
+
version = 0.0.2
|
|
4
4
|
author = Reptile Tech
|
|
5
5
|
author_email = flouis@reptile.tech
|
|
6
6
|
description = Reptile Simple Site Search django app
|
|
7
7
|
long_description = file: README.md
|
|
8
8
|
long_description_content_type = text/markdown
|
|
9
|
-
url = https://github.com/
|
|
9
|
+
url = https://github.com/FlavienLouis/simplesitesearch
|
|
10
10
|
license = MIT
|
|
11
11
|
license_files = LICENSE
|
|
12
12
|
classifiers =
|
|
@@ -33,10 +33,10 @@ classifiers =
|
|
|
33
33
|
Topic :: Software Development :: Libraries :: Python Modules
|
|
34
34
|
keywords = django search cms django-cms
|
|
35
35
|
project_urls =
|
|
36
|
-
Homepage = https://github.com/
|
|
37
|
-
Documentation = https://github.com/
|
|
38
|
-
Repository = https://github.com/
|
|
39
|
-
Bug Tracker = https://github.com/
|
|
36
|
+
Homepage = https://github.com/FlavienLouis/simplesitesearch
|
|
37
|
+
Documentation = https://github.com/FlavienLouis/simplesitesearch#readme
|
|
38
|
+
Repository = https://github.com/FlavienLouis/simplesitesearch.git
|
|
39
|
+
Bug Tracker = https://github.com/FlavienLouis/simplesitesearch/issues
|
|
40
40
|
|
|
41
41
|
[options]
|
|
42
42
|
packages = find:
|
|
@@ -8,13 +8,13 @@ with open("README.md", "r", encoding="utf-8") as fh:
|
|
|
8
8
|
|
|
9
9
|
setup(
|
|
10
10
|
name="simplesitesearch",
|
|
11
|
-
version="0.0.
|
|
11
|
+
version="0.0.3",
|
|
12
12
|
author="Reptile Tech",
|
|
13
13
|
author_email="flouis@reptile.tech",
|
|
14
14
|
description="Reptile Simple Site Search django app",
|
|
15
15
|
long_description=long_description,
|
|
16
16
|
long_description_content_type="text/markdown",
|
|
17
|
-
url="https://github.com/
|
|
17
|
+
url="https://github.com/FlavienLouis/simplesitesearch",
|
|
18
18
|
packages=find_packages(),
|
|
19
19
|
classifiers=[
|
|
20
20
|
"Development Status :: 5 - Production/Stable",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.0.3"
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Quality-of-life utilities for simplesitesearch.
|
|
3
|
+
"""
|
|
4
|
+
from urllib.parse import quote_plus, urlencode
|
|
5
|
+
|
|
6
|
+
import requests
|
|
7
|
+
|
|
8
|
+
from django.conf import settings
|
|
9
|
+
from django.utils.translation import get_language
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def parse_comma_separated_tags(value):
|
|
13
|
+
"""
|
|
14
|
+
Parse a comma-separated string of tags into a list of stripped tags.
|
|
15
|
+
|
|
16
|
+
Args:
|
|
17
|
+
value: String (e.g. from request.GET) or None.
|
|
18
|
+
|
|
19
|
+
Returns:
|
|
20
|
+
List of non-empty tag strings. Empty list if value is falsy.
|
|
21
|
+
|
|
22
|
+
Example:
|
|
23
|
+
>>> parse_comma_separated_tags("news, blog, tutorial")
|
|
24
|
+
['news', 'blog', 'tutorial']
|
|
25
|
+
>>> parse_comma_separated_tags(None)
|
|
26
|
+
[]
|
|
27
|
+
"""
|
|
28
|
+
if not value or not value.strip():
|
|
29
|
+
return []
|
|
30
|
+
return [t.strip() for t in value.split(",") if t.strip()]
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def tags_to_query_value(tags):
|
|
34
|
+
"""
|
|
35
|
+
Convert a list of tags to a comma-separated string for query params or API.
|
|
36
|
+
|
|
37
|
+
Args:
|
|
38
|
+
tags: Iterable of tag strings.
|
|
39
|
+
|
|
40
|
+
Returns:
|
|
41
|
+
Comma-separated string, or None if tags is empty.
|
|
42
|
+
"""
|
|
43
|
+
if not tags:
|
|
44
|
+
return None
|
|
45
|
+
return ",".join(str(t).strip() for t in tags if str(t).strip())
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def build_search_query_string(term, page=1, tags=None):
|
|
49
|
+
"""
|
|
50
|
+
Build the query string for search URLs (pagination, prev/next).
|
|
51
|
+
|
|
52
|
+
Args:
|
|
53
|
+
term: Search term.
|
|
54
|
+
page: Page number (optional).
|
|
55
|
+
tags: Optional list of tags or comma-separated string; as `tag` param.
|
|
56
|
+
|
|
57
|
+
Returns:
|
|
58
|
+
Query string with leading "?", e.g. "?q=foo&page=2&tag=a,b".
|
|
59
|
+
"""
|
|
60
|
+
params = []
|
|
61
|
+
if term:
|
|
62
|
+
params.append(("q", term))
|
|
63
|
+
if page and page != 1:
|
|
64
|
+
params.append(("page", page))
|
|
65
|
+
parsed = (
|
|
66
|
+
parse_comma_separated_tags(tags) if isinstance(tags, str) else (tags or [])
|
|
67
|
+
)
|
|
68
|
+
tag_value = tags_to_query_value(parsed)
|
|
69
|
+
if tag_value:
|
|
70
|
+
params.append(("tag", tag_value))
|
|
71
|
+
if not params:
|
|
72
|
+
return ""
|
|
73
|
+
return "?" + urlencode(params)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def normalize_search_term(term, max_words=10):
|
|
77
|
+
"""
|
|
78
|
+
Limit search term to a maximum number of words (collapse whitespace).
|
|
79
|
+
|
|
80
|
+
Args:
|
|
81
|
+
term: Raw search string.
|
|
82
|
+
max_words: Maximum number of words to keep.
|
|
83
|
+
|
|
84
|
+
Returns:
|
|
85
|
+
Normalized string with at most max_words.
|
|
86
|
+
"""
|
|
87
|
+
if not term or not term.strip():
|
|
88
|
+
return ""
|
|
89
|
+
return " ".join(term.split()[:max_words])
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def safe_int(value, default=None):
|
|
93
|
+
"""
|
|
94
|
+
Safely convert a value to int.
|
|
95
|
+
|
|
96
|
+
Args:
|
|
97
|
+
value: Value to convert (e.g. from request.GET).
|
|
98
|
+
default: Value to return on failure (default None).
|
|
99
|
+
|
|
100
|
+
Returns:
|
|
101
|
+
int, or default on failure.
|
|
102
|
+
"""
|
|
103
|
+
if value is None:
|
|
104
|
+
return default
|
|
105
|
+
try:
|
|
106
|
+
return int(value)
|
|
107
|
+
except (TypeError, ValueError):
|
|
108
|
+
return default
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def get_search_api_url(term, current_page, tags=None):
|
|
112
|
+
"""
|
|
113
|
+
Build the full search API URL for the given term, page and optional tags.
|
|
114
|
+
|
|
115
|
+
Args:
|
|
116
|
+
term: Search term.
|
|
117
|
+
current_page: Page number (1-based).
|
|
118
|
+
tags: Optional list of tag strings; sent as comma-separated `tags` param.
|
|
119
|
+
|
|
120
|
+
Returns:
|
|
121
|
+
Full URL string for the search API.
|
|
122
|
+
"""
|
|
123
|
+
base_url = settings.SITE_SEARCH_API_BASE_URL
|
|
124
|
+
site_key = settings.SITE_SEARCH_SITE_KEY
|
|
125
|
+
lang = get_language()
|
|
126
|
+
url = "%s%s?term=%s&lang=%s&page=%s" % (
|
|
127
|
+
base_url, site_key, quote_plus(term), lang, current_page
|
|
128
|
+
)
|
|
129
|
+
tag_value = tags_to_query_value(tags)
|
|
130
|
+
if tag_value:
|
|
131
|
+
url += "&tags=%s" % quote_plus(tag_value)
|
|
132
|
+
return url
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def get_search_results(term, current_page, tags=None):
|
|
136
|
+
"""
|
|
137
|
+
Fetch search results from the API for the given term, page and optional tags.
|
|
138
|
+
|
|
139
|
+
Args:
|
|
140
|
+
term: Search term.
|
|
141
|
+
current_page: Page number (1-based).
|
|
142
|
+
tags: Optional list of tag strings (comma-separated in API).
|
|
143
|
+
|
|
144
|
+
Returns:
|
|
145
|
+
Dict with "total_hits" and "hits" (list). On request or JSON error,
|
|
146
|
+
returns {"total_hits": 0, "hits": []}.
|
|
147
|
+
"""
|
|
148
|
+
api_url = get_search_api_url(term, current_page, tags=tags)
|
|
149
|
+
try:
|
|
150
|
+
response = requests.get(api_url, verify=False)
|
|
151
|
+
return response.json()
|
|
152
|
+
except Exception:
|
|
153
|
+
return {"total_hits": 0, "hits": []}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
from math import floor
|
|
2
|
+
|
|
3
|
+
from django.views.generic import TemplateView
|
|
4
|
+
|
|
5
|
+
from .utils import (
|
|
6
|
+
build_search_query_string,
|
|
7
|
+
get_search_results,
|
|
8
|
+
get_search_api_url,
|
|
9
|
+
normalize_search_term,
|
|
10
|
+
parse_comma_separated_tags,
|
|
11
|
+
safe_int,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def get_page_links(pages_count, current_page, term, tags=None):
|
|
16
|
+
page_links = []
|
|
17
|
+
|
|
18
|
+
if pages_count > 1:
|
|
19
|
+
if current_page == 1:
|
|
20
|
+
from_page = 1
|
|
21
|
+
to_page = from_page + 7
|
|
22
|
+
elif current_page == pages_count + 1:
|
|
23
|
+
from_page = to_page = current_page
|
|
24
|
+
else:
|
|
25
|
+
from_page = current_page - 4
|
|
26
|
+
to_page = current_page + 5
|
|
27
|
+
|
|
28
|
+
if from_page < 1:
|
|
29
|
+
from_page = 1
|
|
30
|
+
if to_page > pages_count:
|
|
31
|
+
to_page = pages_count
|
|
32
|
+
|
|
33
|
+
for page in range(from_page, to_page + 1):
|
|
34
|
+
page_link = build_search_query_string(term, page=page, tags=tags)
|
|
35
|
+
page_links.append({"page": page, "url": page_link})
|
|
36
|
+
|
|
37
|
+
return page_links
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def get_prev_next_links(next_page_number, prev_page_number, term, tags=None):
|
|
41
|
+
next_link = build_search_query_string(term, page=next_page_number, tags=tags) if next_page_number else None
|
|
42
|
+
prev_link = build_search_query_string(term, page=prev_page_number, tags=tags) if prev_page_number else None
|
|
43
|
+
return [prev_link, next_link]
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def get_prev_next_page_number(pages_count, current_page):
|
|
47
|
+
current_page = safe_int(current_page, 1)
|
|
48
|
+
pages_count = safe_int(pages_count, 0)
|
|
49
|
+
|
|
50
|
+
prev_page_number = current_page - 1 if current_page > 1 else None
|
|
51
|
+
next_page_number = current_page + 1 if current_page < pages_count else None
|
|
52
|
+
return [prev_page_number, next_page_number]
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def get_total_pages(total_hits):
|
|
56
|
+
pages_count = floor(total_hits / 10)
|
|
57
|
+
if total_hits % 10 > 0:
|
|
58
|
+
pages_count += 1
|
|
59
|
+
return pages_count
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def get_api_re_path(term, current_page, tags=None):
|
|
63
|
+
"""Build the search API URL (delegates to utils for consistency)."""
|
|
64
|
+
return get_search_api_url(term, current_page, tags=tags)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class SearchResult(TemplateView):
|
|
68
|
+
|
|
69
|
+
template_name = "simplesitesearch/search_results.html"
|
|
70
|
+
|
|
71
|
+
def get(self, request, *args, **kwargs):
|
|
72
|
+
context = self.get_context_data(**kwargs)
|
|
73
|
+
|
|
74
|
+
# get term and optional tag(s) from url params (tag can be comma-separated)
|
|
75
|
+
term = request.GET.get("q")
|
|
76
|
+
tag_param = request.GET.get("tag") or request.GET.get("tags")
|
|
77
|
+
tags_list = parse_comma_separated_tags(tag_param)
|
|
78
|
+
honeypot_message = request.GET.get("message")
|
|
79
|
+
|
|
80
|
+
current_page = safe_int(request.GET.get("page"), 1)
|
|
81
|
+
|
|
82
|
+
if term and not honeypot_message:
|
|
83
|
+
term = normalize_search_term(term)
|
|
84
|
+
response_data = get_search_results(
|
|
85
|
+
term, current_page, tags=tags_list or None
|
|
86
|
+
)
|
|
87
|
+
pages_count = get_total_pages(response_data["total_hits"])
|
|
88
|
+
prev_page_number, next_page_number = get_prev_next_page_number(pages_count, current_page)
|
|
89
|
+
prev_link, next_link = get_prev_next_links(
|
|
90
|
+
next_page_number, prev_page_number, term, tags=tags_list or None
|
|
91
|
+
)
|
|
92
|
+
page_links = get_page_links(pages_count, current_page, term, tags=tags_list or None)
|
|
93
|
+
|
|
94
|
+
context.update({
|
|
95
|
+
"pages_count": pages_count,
|
|
96
|
+
"current_page": current_page,
|
|
97
|
+
"results_count": response_data["total_hits"],
|
|
98
|
+
"prev_link": prev_link,
|
|
99
|
+
"next_link": next_link,
|
|
100
|
+
"page_links": page_links,
|
|
101
|
+
"results": response_data["hits"],
|
|
102
|
+
})
|
|
103
|
+
else:
|
|
104
|
+
context.update({"results": None})
|
|
105
|
+
|
|
106
|
+
context.update({
|
|
107
|
+
"query": term,
|
|
108
|
+
"tag": tag_param or "",
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
return self.render_to_response(context)
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: simplesitesearch
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.3
|
|
4
4
|
Summary: Reptile Simple Site Search django app
|
|
5
|
-
Home-page: https://github.com/
|
|
5
|
+
Home-page: https://github.com/FlavienLouis/simplesitesearch
|
|
6
6
|
Author: Reptile Tech
|
|
7
7
|
Author-email: Reptile Tech <flouis@reptile.tech>
|
|
8
8
|
Maintainer-email: Reptile Tech <flouis@reptile.tech>
|
|
9
9
|
License: MIT
|
|
10
|
-
Project-URL: Homepage, https://github.com/
|
|
11
|
-
Project-URL: Documentation, https://github.com/
|
|
12
|
-
Project-URL: Repository, https://github.com/
|
|
13
|
-
Project-URL: Bug Tracker, https://github.com/
|
|
10
|
+
Project-URL: Homepage, https://github.com/FlavienLouis/simplesitesearch
|
|
11
|
+
Project-URL: Documentation, https://github.com/FlavienLouis/simplesitesearch#readme
|
|
12
|
+
Project-URL: Repository, https://github.com/FlavienLouis/simplesitesearch.git
|
|
13
|
+
Project-URL: Bug Tracker, https://github.com/FlavienLouis/simplesitesearch/issues
|
|
14
14
|
Keywords: django,search,cms,django-cms
|
|
15
15
|
Classifier: Development Status :: 5 - Production/Stable
|
|
16
16
|
Classifier: Intended Audience :: Developers
|
|
@@ -48,7 +48,6 @@ Dynamic: requires-python
|
|
|
48
48
|
|
|
49
49
|
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.
|
|
50
50
|
|
|
51
|
-
> **Note**: This is a development version (0.0.1.dev1). The package is still under active development and may have breaking changes in future releases.
|
|
52
51
|
|
|
53
52
|
## Features
|
|
54
53
|
|
|
@@ -119,8 +118,8 @@ urlpatterns = [
|
|
|
119
118
|
### 2. Configure the Page
|
|
120
119
|
|
|
121
120
|
1. Go to **Advanced settings** of the search page
|
|
122
|
-
2. Set
|
|
123
|
-
3. Set **
|
|
121
|
+
2. Set **APPLICATION** to "Site Search"
|
|
122
|
+
3. Set the **Application ID** to `'site_search'` (this is the default value)
|
|
124
123
|
4. Save the page
|
|
125
124
|
5. Remove the page from the menu (uncheck "menu" in the table)
|
|
126
125
|
6. Publish the page in all languages
|
|
@@ -147,10 +146,53 @@ The search results support pagination with a `page` parameter:
|
|
|
147
146
|
/search/?q=your+search+term&page=2
|
|
148
147
|
```
|
|
149
148
|
|
|
149
|
+
### Tags filter
|
|
150
|
+
|
|
151
|
+
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`:
|
|
152
|
+
|
|
153
|
+
```
|
|
154
|
+
/search/?q=your+search+term&tag=news,blog,tutorial
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Pagination links preserve the tag filter.
|
|
158
|
+
|
|
150
159
|
### Honeypot Protection
|
|
151
160
|
|
|
152
161
|
The search includes basic honeypot protection. If a `message` parameter is present, the search will not execute.
|
|
153
162
|
|
|
163
|
+
## Utility functions (QOL)
|
|
164
|
+
|
|
165
|
+
The app provides helpers in `simplesitesearch.utils` for use in views, management commands, or other code.
|
|
166
|
+
|
|
167
|
+
| Function | Description |
|
|
168
|
+
|----------|-------------|
|
|
169
|
+
| **`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": []}`. |
|
|
170
|
+
| **`get_search_api_url(term, current_page, tags=None)`** | Builds the full search API URL (uses Django settings and current language). |
|
|
171
|
+
| **`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`. |
|
|
172
|
+
| **`parse_comma_separated_tags(value)`** | Parses a comma-separated string into a list of stripped tags; returns `[]` if value is falsy. |
|
|
173
|
+
| **`normalize_search_term(term, max_words=10)`** | Trims and limits the search term to a maximum number of words. |
|
|
174
|
+
| **`safe_int(value, default=None)`** | Safely converts a value to `int`; returns `default` on failure. |
|
|
175
|
+
|
|
176
|
+
**Example — fetch results in code:**
|
|
177
|
+
|
|
178
|
+
```python
|
|
179
|
+
from simplesitesearch.utils import get_search_results
|
|
180
|
+
|
|
181
|
+
data = get_search_results("django", current_page=1, tags=["cms", "tutorial"])
|
|
182
|
+
total = data["total_hits"]
|
|
183
|
+
results = data["hits"]
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
**Example — build search/pagination URLs:**
|
|
187
|
+
|
|
188
|
+
```python
|
|
189
|
+
from simplesitesearch.utils import build_search_query_string
|
|
190
|
+
|
|
191
|
+
# Pagination link for page 2 with tag filter
|
|
192
|
+
qs = build_search_query_string("my query", page=2, tags=["blog"])
|
|
193
|
+
# => "?q=my+query&page=2&tag=blog"
|
|
194
|
+
```
|
|
195
|
+
|
|
154
196
|
## Customization
|
|
155
197
|
|
|
156
198
|
### Templates
|
|
@@ -239,18 +281,29 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file
|
|
|
239
281
|
|
|
240
282
|
## Support
|
|
241
283
|
|
|
242
|
-
For support and questions, please open an issue on the [GitHub repository](https://github.com/
|
|
284
|
+
For support and questions, please open an issue on the [GitHub repository](https://github.com/FlavienLouis/simplesitesearch/issues).
|
|
243
285
|
|
|
244
286
|
## Changelog
|
|
245
287
|
|
|
246
|
-
### 0.0.
|
|
247
|
-
-
|
|
248
|
-
-
|
|
249
|
-
-
|
|
250
|
-
|
|
251
|
-
|
|
288
|
+
### 0.0.3
|
|
289
|
+
- 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`
|
|
290
|
+
- Tag filter: `tag` (or `tags`) query parameter forwarded to API as comma-separated `tags`; pagination links preserve tags
|
|
291
|
+
- README: Utility functions section and tags filter documentation
|
|
292
|
+
|
|
293
|
+
### 0.0.2
|
|
294
|
+
- Fixed template include path in search_results.html
|
|
295
|
+
- Updated pagination template include to use full namespace: `simplesitesearch/pagination.html`
|
|
296
|
+
- Improved template isolation and namespace consistency
|
|
297
|
+
|
|
298
|
+
### 0.0.1
|
|
299
|
+
- **First stable release**
|
|
300
|
+
- Django CMS integration with apphook support
|
|
301
|
+
- Pagination support for search results
|
|
302
|
+
- Multi-language support with Django i18n
|
|
303
|
+
- Basic search functionality with API integration
|
|
252
304
|
- Template customization support
|
|
253
305
|
- Support for Python 3.6+ and Django 2.2+
|
|
254
|
-
-
|
|
306
|
+
- Reptile Search API integration
|
|
307
|
+
- Comprehensive documentation and setup instructions
|
|
255
308
|
|
|
256
309
|
|
|
@@ -1,151 +0,0 @@
|
|
|
1
|
-
from math import floor
|
|
2
|
-
|
|
3
|
-
import requests
|
|
4
|
-
from django.conf import settings
|
|
5
|
-
from django.utils.translation import get_language
|
|
6
|
-
from django.views.generic import TemplateView
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
def get_page_links(pages_count, current_page, term):
|
|
10
|
-
|
|
11
|
-
page_links = []
|
|
12
|
-
|
|
13
|
-
if pages_count > 1:
|
|
14
|
-
|
|
15
|
-
if current_page == 1:
|
|
16
|
-
from_page = 1
|
|
17
|
-
to_page = from_page + 7
|
|
18
|
-
if current_page == pages_count + 1:
|
|
19
|
-
pass
|
|
20
|
-
else:
|
|
21
|
-
from_page = current_page - 4
|
|
22
|
-
to_page = current_page + 5
|
|
23
|
-
|
|
24
|
-
if from_page < 1:
|
|
25
|
-
from_page = 1
|
|
26
|
-
|
|
27
|
-
if to_page > pages_count:
|
|
28
|
-
to_page = pages_count
|
|
29
|
-
|
|
30
|
-
for page in range(from_page, to_page + 1):
|
|
31
|
-
page_link = "?q=%s&page=%s" % (term, page)
|
|
32
|
-
|
|
33
|
-
page_links.append({
|
|
34
|
-
'page': page,
|
|
35
|
-
'url': page_link
|
|
36
|
-
})
|
|
37
|
-
|
|
38
|
-
return page_links
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
def get_prev_next_links(next_page_number, prev_page_number, term):
|
|
42
|
-
next_link = None
|
|
43
|
-
if next_page_number:
|
|
44
|
-
next_link = "?q=%s&page=%s" % (term, next_page_number)
|
|
45
|
-
|
|
46
|
-
prev_link = None
|
|
47
|
-
if prev_page_number:
|
|
48
|
-
prev_link = "?q=%s&page=%s" % (term, prev_page_number)
|
|
49
|
-
|
|
50
|
-
return [prev_link, next_link]
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
def get_prev_next_page_number(pages_count, current_page):
|
|
54
|
-
|
|
55
|
-
current_page = int(current_page)
|
|
56
|
-
pages_count - int(pages_count)
|
|
57
|
-
|
|
58
|
-
if current_page > 1:
|
|
59
|
-
prev_page_number = current_page - 1
|
|
60
|
-
else:
|
|
61
|
-
prev_page_number = None
|
|
62
|
-
|
|
63
|
-
if current_page < pages_count:
|
|
64
|
-
next_page_number = current_page + 1
|
|
65
|
-
else:
|
|
66
|
-
next_page_number = None
|
|
67
|
-
|
|
68
|
-
return [prev_page_number, next_page_number]
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
def get_total_pages(total_hits):
|
|
72
|
-
pages_count = floor(total_hits / 10)
|
|
73
|
-
|
|
74
|
-
modulo = total_hits % 10
|
|
75
|
-
if modulo > 0:
|
|
76
|
-
pages_count = pages_count + 1
|
|
77
|
-
|
|
78
|
-
return pages_count
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
def get_api_re_path(term, current_page):
|
|
82
|
-
base_url = settings.SITE_SEARCH_API_BASE_URL
|
|
83
|
-
site_key = settings.SITE_SEARCH_SITE_KEY
|
|
84
|
-
lang = get_language()
|
|
85
|
-
|
|
86
|
-
return "%s%s?term=%s&lang=%s&page=%s" % (base_url, site_key, term, lang, current_page)
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
class SearchResult(TemplateView):
|
|
90
|
-
|
|
91
|
-
template_name = "simplesitesearch/search_results.html"
|
|
92
|
-
|
|
93
|
-
def get(self, request, *args, **kwargs):
|
|
94
|
-
context = self.get_context_data(**kwargs)
|
|
95
|
-
|
|
96
|
-
# get Term from url params
|
|
97
|
-
term = request.GET.get('q', None)
|
|
98
|
-
honeypot_message = request.GET.get('message', None)
|
|
99
|
-
|
|
100
|
-
# get current page from url params
|
|
101
|
-
current_page = int(request.GET.get('page', 1))
|
|
102
|
-
|
|
103
|
-
if term and not honeypot_message:
|
|
104
|
-
|
|
105
|
-
term = ' '.join(term.split()[:10])
|
|
106
|
-
|
|
107
|
-
# get api URl depending on current page
|
|
108
|
-
api_url = get_api_re_path(term, current_page)
|
|
109
|
-
|
|
110
|
-
# get results from api
|
|
111
|
-
response = requests.get(api_url, verify=False)
|
|
112
|
-
# convert results to usable json
|
|
113
|
-
try:
|
|
114
|
-
response_data = response.json()
|
|
115
|
-
except:
|
|
116
|
-
response_data = {
|
|
117
|
-
'total_hits': 0,
|
|
118
|
-
'hits': []
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
# get pages count
|
|
122
|
-
pages_count = get_total_pages(response_data['total_hits'])
|
|
123
|
-
|
|
124
|
-
# get prev and next page numbers
|
|
125
|
-
prev_page_number, next_page_number = get_prev_next_page_number(pages_count, current_page)
|
|
126
|
-
|
|
127
|
-
# get prev and next btn links
|
|
128
|
-
prev_link, next_link = get_prev_next_links(next_page_number, prev_page_number, term)
|
|
129
|
-
|
|
130
|
-
# get pages links
|
|
131
|
-
page_links = get_page_links(pages_count, current_page, term)
|
|
132
|
-
|
|
133
|
-
context.update({
|
|
134
|
-
'pages_count': pages_count,
|
|
135
|
-
'current_page': current_page,
|
|
136
|
-
'results_count': response_data['total_hits'],
|
|
137
|
-
'prev_link': prev_link,
|
|
138
|
-
'next_link': next_link,
|
|
139
|
-
'page_links': page_links,
|
|
140
|
-
'results': response_data['hits']
|
|
141
|
-
})
|
|
142
|
-
else:
|
|
143
|
-
context.update({
|
|
144
|
-
'results': None
|
|
145
|
-
})
|
|
146
|
-
|
|
147
|
-
context.update({
|
|
148
|
-
'query': term
|
|
149
|
-
})
|
|
150
|
-
|
|
151
|
-
return self.render_to_response(context)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{simplesitesearch-0.0.1.dev1 → simplesitesearch-0.0.3}/simplesitesearch.egg-info/not-zip-safe
RENAMED
|
File without changes
|
{simplesitesearch-0.0.1.dev1 → simplesitesearch-0.0.3}/simplesitesearch.egg-info/requires.txt
RENAMED
|
File without changes
|
{simplesitesearch-0.0.1.dev1 → simplesitesearch-0.0.3}/simplesitesearch.egg-info/top_level.txt
RENAMED
|
File without changes
|