Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 0 additions & 34 deletions .github/ISSUE_TEMPLATE/bug_report.md

This file was deleted.

17 changes: 0 additions & 17 deletions .github/ISSUE_TEMPLATE/feature_request.md

This file was deleted.

4 changes: 0 additions & 4 deletions .github/PULL_REQUEST_TEMPLATE.md

This file was deleted.

16 changes: 0 additions & 16 deletions .github/SUPPORT.md

This file was deleted.

31 changes: 0 additions & 31 deletions .github/workflows/bump.yml

This file was deleted.

27 changes: 0 additions & 27 deletions .github/workflows/pull-requests.yml

This file was deleted.

34 changes: 0 additions & 34 deletions .github/workflows/pypi-publish.yml

This file was deleted.

27 changes: 0 additions & 27 deletions .github/workflows/sync.yml

This file was deleted.

69 changes: 69 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
name: Tests
on: [push, pull_request]
env:
CODE_COVERAGE_THRESHOLD_REQUIRED: 65
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.9'
- name: Install requirements
run: pip install flake8 pycodestyle
- name: Check syntax
run: flake8 . --count --select=E901,E999,F821,F822,F823 --show-source --statistics --exclude ckan

test:
needs: lint
strategy:
matrix:
include:
- ckan-version: "2.11"
ckan-image: "ckan/ckan-dev:2.11-py3.10"
solr-version: "9"
- ckan-version: "2.10"
ckan-image: "ckan/ckan-dev:2.10-py3.10"
solr-version: "9"
- ckan-version: "2.9"
ckan-image: "ckan/ckan-dev:2.9-py3.9"
solr-version: "8"
fail-fast: false
name: CKAN ${{ matrix.ckan-version }}
runs-on: ubuntu-latest
container:
image: ${{ matrix.ckan-image }}
options: --user root
services:
solr:
image: ckan/ckan-solr:${{ matrix.ckan-version }}-solr${{ matrix.solr-version }}
postgres:
image: ckan/ckan-postgres-dev:${{ matrix.ckan-version }}
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: postgres
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
redis:
image: redis:3
env:
CKAN_SQLALCHEMY_URL: postgresql://ckan_default:pass@postgres/ckan_test
CKAN_DATASTORE_WRITE_URL: postgresql://datastore_write:pass@postgres/datastore_test
CKAN_DATASTORE_READ_URL: postgresql://datastore_read:pass@postgres/datastore_test
CKAN_SOLR_URL: http://solr:8983/solr/ckan
CKAN_REDIS_URL: redis://redis:6379/1

steps:
- uses: actions/checkout@v4
- name: Install requirements
run: |
pip install -r dev-requirements.txt
pip install -e .
# Replace default path to CKAN core config file with the one on the container
sed -i -e 's/use = config:.*/use = config:\/srv\/app\/src\/ckan\/test-core.ini/' test.ini
- name: Setup extension
run: |
ckan -c test.ini db init
- name: Run tests
run: pytest --ckan-ini=test.ini --cov=ckanext.contact --disable-warnings --cov-fail-under=${CODE_COVERAGE_THRESHOLD_REQUIRED} ckanext/contact/tests
21 changes: 0 additions & 21 deletions .github/workflows/tests.yml

This file was deleted.

1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ build/
dist/
.idea
**/node_modules/
.DS_Store
49 changes: 48 additions & 1 deletion ckanext/contact/routes/_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from ckan.lib.navl.dictization_functions import unflatten
from ckan.plugins import PluginImplementations, toolkit
from pyisemail import is_email
from urllib.parse import urlparse

from ckanext.contact import recaptcha
from ckanext.contact.interfaces import IContact
Expand All @@ -30,7 +31,7 @@ def validate(data_dict):
"""
errors = {}
error_summary = {}
optional_fields = {'subject'}
optional_fields = {'subject', 'referrer_url'}
recaptcha_error = None

# check each field to see if it has a value and if not, show and error
Expand All @@ -54,6 +55,14 @@ def validate(data_dict):
errors['email'] = ['Email address appears to be invalid']
error_summary['email'] = 'Email address appears to be invalid'

# check if referrer_url starts with site_url
referrer_url = data_dict.get('referrer_url', '').strip()
if referrer_url:
site_url = toolkit.config.get('ckan.site_url', '')
if site_url:
if not referrer_url.startswith(site_url):
data_dict.pop('referrer_url', None)

# only check the recaptcha if there are no errors
if not errors:
try:
Expand Down Expand Up @@ -98,6 +107,36 @@ def build_subject(
return f'{prefix}{" " if prefix else ""}{subject}'


def get_dataset_title_from_url(url):
"""
Try to extract the dataset title from a CKAN URL.

:param url: the URL to parse
:return: dataset title if successful, None on any error
"""
if not url:
return None

try:
# Extract package identifier from URL
parsed_url = urlparse(url)
path_parts = parsed_url.path.split('/')
if len(path_parts) >= 3 and path_parts[1] == 'dataset':
package_id = path_parts[2]
else:
return None

if not package_id:
return None

# Fetch dataset title using package_show action
context = {'ignore_auth': True}
package_dict = toolkit.get_action('package_show')(context, {'id': package_id})
return package_dict.get('title')
except Exception:
return None


def submit():
"""
Take the data in the request params and send an email using them. If the data is
Expand All @@ -124,6 +163,14 @@ def submit():
f' Name: {data_dict["name"]}',
f' Email: {data_dict["email"]}',
]
# include referrer URL if available
referrer_url = data_dict.get('referrer_url', '').strip()
if referrer_url:
body_parts.append(f' Referrer URL: {referrer_url}')
# try to get dataset title if referrer_url is from a dataset
dataset_title = get_dataset_title_from_url(referrer_url)
if dataset_title:
body_parts.append(f' Dataset Title: {dataset_title}')
mail_dict = {
'recipient_email': toolkit.config.get(
'ckanext.contact.mail_to', toolkit.config.get('email_to')
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loading