diff --git a/.gitignore b/.gitignore
index db9dd30..2e8e623 100644
--- a/.gitignore
+++ b/.gitignore
@@ -161,3 +161,6 @@ cython_debug/
# Mac
.DS_Store
+
+# Project-specific ignores
+local_settings.py
\ No newline at end of file
diff --git a/dgpf1/dgpf1/facet_modifiers.py b/dgpf1/dgpf1/facet_modifiers.py
index 18719ad..e7abfdb 100644
--- a/dgpf1/dgpf1/facet_modifiers.py
+++ b/dgpf1/dgpf1/facet_modifiers.py
@@ -18,3 +18,17 @@ def lookup_replace_provider_id(facets: dict) -> dict:
"added to the database!")
bucket["custom_display_value"] = "Other"
return facets
+
+
+def combine_info_group(facets: list) -> list:
+ """Collapse Info_GroupID and Info_GroupName into a single 'Resource Group'
+ facet that filters by name. Drops the raw ID facet from display."""
+ combined = []
+ for facet in facets:
+ if facet["field_name"] == "Info_GroupID":
+ continue
+ if facet["field_name"] == "Info_GroupName":
+ facet = dict(facet)
+ facet["name"] = "Resource Group"
+ combined.append(facet)
+ return combined
diff --git a/dgpf1/dgpf1/fields.py b/dgpf1/dgpf1/fields.py
index 3d57b00..b87c6f6 100644
--- a/dgpf1/dgpf1/fields.py
+++ b/dgpf1/dgpf1/fields.py
@@ -5,6 +5,10 @@ def title(result):
return result[0]['Title']
+def software_title(result):
+ return result[0].get('Name', 'Software Detail')
+
+
def general_info(result):
"""Return all basic information in the first gmeta entry"""
return result[0]
@@ -48,3 +52,41 @@ def detail_result_display_fields(result):
# If the date cannot be parsed, just leave it.
pass
return display_fields
+
+
+def software_detail_result_display_fields(result):
+ possible_date_fields = ["CreationTime"]
+ info = general_info(result)
+ leading_fields = [
+ {"field_name": "Name"},
+ {"field_name": "Category"},
+ {"field_name": "Keywords"},
+ {"field_name": "SupportStatus", "display_name": "Support Status"},
+ {"field_name": "Version"},
+ {"field_name": "URL"},
+ {"field_name": "Organization_Name", "display_name": "Organization Name"},
+ {"field_name": "Organization_ID", "display_name": "Organization ID"},
+ {"field_name": "Info_GroupName", "display_name": "Resource Group"},
+ {"field_name": "Info_GroupID", "display_name": "Resource Group ID"},
+ {"field_name": "Info_ResourceName", "display_name": "Resource Name"},
+ {"field_name": "Info_ResourceID", "display_name": "Resource ID"},
+ ]
+ trailing_fields = [
+ {"field_name": "HandleKey", "display_name": "Handle Key"},
+ {"field_name": "HandleType", "display_name": "Handle Type"},
+ {"field_name": "CreationTime", "display_name": "Creation Time"},
+ ]
+ known_field_names = [fl["field_name"] for fl in leading_fields + trailing_fields]
+ other_fields = [{"field_name": f} for f in info if f not in known_field_names]
+ display_fields = leading_fields + other_fields + trailing_fields
+ for item in display_fields:
+ item["display_name"] = item.get("display_name", item["field_name"].replace("_", " "))
+ item["value"] = info.get(item["field_name"])
+ item["is_list"] = isinstance(item["value"], list)
+ if item["field_name"] in possible_date_fields:
+ try:
+ item["value"] = datetime.datetime.fromisoformat(item["value"].replace("Z", "+00:00")).strftime("%b %d %Y %H:%M:%S %Z%z")
+ item["is_list"] = False
+ except Exception:
+ pass
+ return display_fields
diff --git a/dgpf1/dgpf1/settings.py b/dgpf1/dgpf1/settings.py
index 6879fa8..d6d9332 100644
--- a/dgpf1/dgpf1/settings.py
+++ b/dgpf1/dgpf1/settings.py
@@ -19,7 +19,7 @@
import json
import os
import sys
-from dgpf1.fields import title, general_info, detail_result_display_fields
+from dgpf1.fields import title, general_info, detail_result_display_fields, software_title, software_detail_result_display_fields
#import pdb
#pdb.set_trace()
@@ -79,8 +79,10 @@
'DIRS': [BASE_DIR / 'templates'],
'APP_DIRS': True,
'OPTIONS': {
+ 'debug': DEBUG,
'libraries': {
'settings_value': 'templatetags.get_settings',
+ 'urldecode': 'templatetags.custom_tags',
},
'context_processors': [
'django.template.context_processors.debug',
@@ -102,20 +104,21 @@
'default': {
'USER': CONF['DJANGO_USER'],
'PASSWORD': CONF['DJANGO_PASS'],
- 'HOST': os.environ.get('PGHOST', CONF.get('DB_HOSTNAME_WRITE', 'localhost')),
+ 'HOST': os.environ.get('PGHOST', CONF.get('DB_HOSTNAME_WRITE', 'db')),
+ },
+ 'sqlite3': {
+ 'ENGINE': 'django.db.backends.sqlite3',
+ 'NAME': BASE_DIR / 'db.sqlite3',
}
-# 'sqlite3': {
-# 'ENGINE': 'django.db.backends.sqlite3',
-# 'NAME': BASE_DIR / 'db.sqlite3',
-# }
}
for db in DATABASES:
- DATABASES[db]['NAME'] = CONF['DB_DATABASE']
- DATABASES[db]['ENGINE'] = 'django.db.backends.postgresql'
- DATABASES[db]['PORT'] = os.environ.get('PGPORT', CONF.get('DB_PORT', '5432'))
- DATABASES[db]['CONN_MAX_AGE'] = 600 # Persist DB connections
- DATABASES[db]['OPTIONS'] = {'options': '-c search_path=ed_dgpf1,public'}
+ if db == "default":
+ DATABASES[db]['NAME'] = CONF['DB_DATABASE']
+ DATABASES[db]['ENGINE'] = 'django.db.backends.postgresql'
+ DATABASES[db]['PORT'] = os.environ.get('PGPORT', CONF.get('DB_PORT', '5432'))
+ DATABASES[db]['CONN_MAX_AGE'] = 600 # Persist DB connections
+ DATABASES[db]['OPTIONS'] = {'options': '-c search_path=ed_dgpf1,public'}
# Password validation
# https://docs.djangoproject.com/en/4.2/ref/settings/#auth-password-validators
@@ -167,7 +170,8 @@
# https://docs.djangoproject.com/en/4.2/howto/static-files/
STATIC_URL = 'static/'
-STATIC_ROOT = CONF['STATIC_ROOT']
+
+STATIC_ROOT = BASE_DIR / 'static'
STATICFILES_DIRS = [BASE_DIR / 'staticfiles']
# Default primary key field type
@@ -289,8 +293,30 @@
('general_info', general_info),
('detail_result_display_fields', detail_result_display_fields),
],
+ },
+ 'access-software-v4': {
+ 'name': 'ACCESS Software Catalog - Beta catalog v4',
+ 'uuid': '3cc4aeec-55a5-4cd6-96d1-8531aef88e83',
+ 'facets': [
+ {'name': 'Category', 'field_name': 'Category'},
+ {'name': 'Keywords', 'field_name': 'Keywords'},
+ {'name': 'Support Status', 'field_name': 'SupportStatus'},
+ {'name': 'Organization', 'field_name': 'Organization_Name'},
+ {'name': 'Resource Group', 'field_name': 'Info_GroupName'},
+ {'name': 'Resource', 'field_name': 'Info_ResourceName'},
+ ],
+ 'facet_modifiers': [
+ 'globus_portal_framework.modifiers.facets.drop_empty',
+ # 'dgpf1.facet_modifiers.combine_info_group',
+ ],
+ 'fields': [
+ ('title', software_title),
+ ('general_info', general_info),
+ ('detail_result_display_fields', software_detail_result_display_fields),
+ ],
+ 'template_override_dir': 'access-software-v4',
}
}
PROJECT_TITLE = 'Search Pilot'
-APP_VERSION = CONF.get('APP_VERSION', '')
+APP_VERSION = CONF.get('APP_VERSION', '')
\ No newline at end of file
diff --git a/dgpf1/templates/access-software-v4/globus-portal-framework/v2/components/search-results.html b/dgpf1/templates/access-software-v4/globus-portal-framework/v2/components/search-results.html
new file mode 100644
index 0000000..f8bbd6a
--- /dev/null
+++ b/dgpf1/templates/access-software-v4/globus-portal-framework/v2/components/search-results.html
@@ -0,0 +1,37 @@
+
+{% load static %}
+{% load urldecode %}
+{% block headextras %}{% endblock %}
+
+
+
+
Results
+ {% if search.total %}
+
+
+
+ {% endif %}
+
+
+ {% if search.total %}
+
{{search.total}} software items found
+ {% endif %}
+
+
+
+
+ {% for result in search.search_results %}
+
+
+
+ {% if result.general_info.Description %}
+
{{ result.general_info.Description }}
+ {% endif %}
+
+
+ {% endfor %}
+
diff --git a/dgpf1/templates/access-software-v4/globus-portal-framework/v2/detail-overview.html b/dgpf1/templates/access-software-v4/globus-portal-framework/v2/detail-overview.html
new file mode 100644
index 0000000..ee50c15
--- /dev/null
+++ b/dgpf1/templates/access-software-v4/globus-portal-framework/v2/detail-overview.html
@@ -0,0 +1,50 @@
+{% extends 'globus-portal-framework/v2/detail-base.html' %}
+
+
+{% block breadcrumb_items %}
+{{globus_portal_framework.project_title}}
+{{globus_portal_framework.index_data.name}}
+{{title|default:'Software Detail'}}
+{% endblock %}
+
+
+{% block detail_body %}
+
+
+
+
+ {% block detail_search_content %}
+
{{ title|default:'Software' }} — Properties
+
+ {% load urldecode %}
+
+
+ {% for item in detail_result_display_fields %}
+ {% if item.value %}
+
+ | {{ item.display_name }} |
+
+ {% if item.field_name == "URL" %}
+ {{ item.value }}
+ {% elif item.is_list %}
+
+ {% for v in item.value %}- {{ v }}
{% endfor %}
+
+ {% else %}
+ {{ item.value }}
+ {% endif %}
+ |
+
+ {% endif %}
+ {% endfor %}
+
+
+
+
Globus Search Metadata
+ {% include 'globus-portal-framework/v2/components/detail-globus-search-metadata.html' %}
+ {% endblock %}
+
+
+
+
+{% endblock %}
diff --git a/dgpf1/templates/globus-portal-framework/v2/components/detail-general-metadata.html b/dgpf1/templates/globus-portal-framework/v2/components/detail-general-metadata.html
index 300d4d5..28232ef 100644
--- a/dgpf1/templates/globus-portal-framework/v2/components/detail-general-metadata.html
+++ b/dgpf1/templates/globus-portal-framework/v2/components/detail-general-metadata.html
@@ -1,6 +1,8 @@
+{% load urldecode %}
{% block detail_general_metadata %}
+ {{ request.path|urldecode }}
{% for item in detail_result_display_fields %}
| {{item.display_name}} |
diff --git a/dgpf1/templates/globus-portal-framework/v2/components/detail-globus-search-metadata.html b/dgpf1/templates/globus-portal-framework/v2/components/detail-globus-search-metadata.html
index b8a8d6d..880a1b5 100644
--- a/dgpf1/templates/globus-portal-framework/v2/components/detail-globus-search-metadata.html
+++ b/dgpf1/templates/globus-portal-framework/v2/components/detail-globus-search-metadata.html
@@ -1,9 +1,9 @@
-
+{% load urldecode %}
| subject |
- {{ subject }} |
+ {{ subject|urldecode }} |
diff --git a/dgpf1/templates/globus-portal-framework/v2/components/search-results.html b/dgpf1/templates/globus-portal-framework/v2/components/search-results.html
index 5af7984..dd9a66b 100644
--- a/dgpf1/templates/globus-portal-framework/v2/components/search-results.html
+++ b/dgpf1/templates/globus-portal-framework/v2/components/search-results.html
@@ -1,5 +1,6 @@
-{% load static %}
+{% load static %}
+{% load urldecode %}
{% block headextras %}{% endblock %}
@@ -23,14 +24,14 @@
{{search.total}} training items found
- {{result.all.0.Abstract|safe}}
+ {{result.all.0.Abstract|default:result.all.0.Description|safe}}
diff --git a/dgpf1/templatetags/custom_tags.py b/dgpf1/templatetags/custom_tags.py
new file mode 100644
index 0000000..58b4ad2
--- /dev/null
+++ b/dgpf1/templatetags/custom_tags.py
@@ -0,0 +1,10 @@
+from django import template
+from urllib.parse import unquote
+
+register = template.Library()
+
+@register.filter
+def urldecode(value):
+ if value is None:
+ return value
+ return unquote(value)
\ No newline at end of file