`
+
+ });
+
+ document.getElementById('hydroshare-resources-list-plugin').innerHTML = resourcesHTML;
+
+ // For example, you could iterate over the data and append it to an element in your HTML
+ })
+ .catch(error => {
+ console.error('There was a problem with the fetch operation:', error);
+ });
+ }
+
+const create_placeholders = () => {
+ console.log('Creating placeholders');
+ let placeholdersHtmlElement = document.getElementById('placeholder-hydroshare-resources');
+ let htmlPlaceholders = '';
+ for(var i = 0; i < 10; i++){
+ htmlPlaceholders+=`
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ `
+ }
+ placeholdersHtmlElement.innerHTML = htmlPlaceholders;
+}
+
+
+document.addEventListener('DOMContentLoaded', function() {
+ // Select all radio buttons with name 'radio'
+ const radioButtons = document.querySelectorAll('input[name="radio"]');
+
+ // Function to handle selection changes
+ function handleSelection(value) {
+ document.getElementById('placeholder-hydroshare-resources').classList.remove('hidden');
+ document.getElementById('hydroshare-resources-list-plugin').classList.add('hidden');
+ console.log(`${value.charAt(0).toUpperCase() + value.slice(1)} selected`);
+ requestData.curated = (value === 'curated');
+ create_placeholders();
+ fetchHydroShareResources();
+ }
+
+ // Initial function call based on default selection
+ const selectedRadio = document.querySelector('input[name="radio"]:checked');
+ if (selectedRadio && selectedRadio.value) {
+ handleSelection(selectedRadio.value);
+ } else {
+ console.error('No radio button is selected by default.');
+ }
+
+ // Add event listeners to each radio button
+ radioButtons.forEach(function(radio) {
+ radio.addEventListener('change', function() {
+ if (this.checked) {
+ handleSelection(this.value);
+ }
+ });
+ });
+});
+
+// Inspiration for radio buttons
+// https://codepen.io/gabrielferreira/pen/oYxNVy
\ No newline at end of file
diff --git a/hydroshare_community_resources_app/templates/hydroshare-community-resources-base.html b/hydroshare_community_resources_app/templates/hydroshare-community-resources-base.html
new file mode 100644
index 0000000..bae0781
--- /dev/null
+++ b/hydroshare_community_resources_app/templates/hydroshare-community-resources-base.html
@@ -0,0 +1,16 @@
+{% extends CMS_TEMPLATE %}
+
+{% load sekizai_tags static cms_tags %}
+
+{% addtoblock "js" %}
+
+{% endaddtoblock %}
+
+{% addtoblock "css" %}
+
+
+{% endaddtoblock %}
+
+{% block content %}
+
+{% endblock %}
diff --git a/hydroshare_community_resources_app/templates/hydroshare-community-resources.html b/hydroshare_community_resources_app/templates/hydroshare-community-resources.html
new file mode 100644
index 0000000..f65e660
--- /dev/null
+++ b/hydroshare_community_resources_app/templates/hydroshare-community-resources.html
@@ -0,0 +1,49 @@
+{% load cms_tags sekizai_tags static %}
+
+ {% csrf_token %}
+
+
+
+{% addtoblock "css" %}
+
+
+{% endaddtoblock %}
+
+{% addtoblock "js" %}
+
+
+
+{% endaddtoblock %}
+
+{% block content %}
+
+
CSS Radio Button
+
+
+
+
+
+
+
+{% endblock %}
+
+
\ No newline at end of file
diff --git a/hydroshare_community_resources_app/urls.py b/hydroshare_community_resources_app/urls.py
new file mode 100644
index 0000000..7879873
--- /dev/null
+++ b/hydroshare_community_resources_app/urls.py
@@ -0,0 +1,13 @@
+from django.urls import re_path
+
+
+from .views import base_view, hydroshare_community_resources_view
+
+urlpatterns = [
+ re_path(r"^$", base_view, name="base"),
+ re_path(
+ r"^update-hydroshare-community-resources/$",
+ hydroshare_community_resources_view,
+ name="update-hydroshare-community-resources",
+ ),
+]
diff --git a/hydroshare_community_resources_app/utils.py b/hydroshare_community_resources_app/utils.py
new file mode 100644
index 0000000..d7649f0
--- /dev/null
+++ b/hydroshare_community_resources_app/utils.py
@@ -0,0 +1,124 @@
+import requests
+from bs4 import BeautifulSoup
+import json
+from itertools import chain
+import datetime
+import re
+
+
+def get_curated_resources(
+ composite_resource_id="302dcbef13614ac486fb260eaa1ca87c", hs=None
+):
+ science = hs.getScienceMetadata(composite_resource_id)
+ relations = science.get("relations", [])
+ resource_ids = []
+ for item in relations:
+ if item.get("type") == "hasPart":
+ value = item.get("value", "")
+ # Regular expression to find the resource ID in the URL
+ match = re.search(
+ r"http://www\.hydroshare\.org/resource/([a-f0-9]{32})", value
+ )
+ if match:
+ resource_id = match.group(1)
+ resource_ids.append(resource_id)
+ return resource_ids
+
+
+def filter_resources_list_by_resources_id(resources, ids):
+ filtered_resources = []
+ for resource in resources:
+ if resource["resource_id"] in ids:
+ filtered_resources.append(resource)
+ return filtered_resources
+
+
+def join_generators(generators):
+ seen_resource_ids = set()
+ for gen in generators:
+ for item in gen:
+ resource_id = item.get("resource_id")
+ if resource_id not in seen_resource_ids:
+ seen_resource_ids.add(resource_id)
+ yield item
+
+
+def get_group_ids(community_id):
+ url = f"https://www.hydroshare.org/community/{community_id}/"
+ response = requests.get(url)
+ soup = BeautifulSoup(response.content, "html.parser")
+
+ group_ids = []
+
+ # Find the script tag with id 'community-app-data'
+ script_tag = soup.find("script", id="community-app-data", type="application/json")
+ if script_tag and script_tag.string:
+ data = json.loads(script_tag.string)
+ # The group data is in data['members']
+ for group in data.get("members", []):
+ group_id = group.get("id")
+ if group_id:
+ href = f"{group_id}"
+ group_ids.append(href)
+ else:
+ print(
+ "No script tag with id 'community-app-data' found or it contains no data."
+ )
+
+ return group_ids
+
+
+def get_dict_with_attribute(list_of_dicts, attribute, value):
+ # Loop through each dictionary in the list
+ for dictionary in list_of_dicts:
+ # logging.warning(dictionary)
+ # if attribute in dictionary:
+ # logging.warning(dictionary[attribute])
+ # Check if the attribute exists in the dictionary and has the specified value
+ if attribute in dictionary and dictionary[attribute] == value:
+ return dictionary # Return the dictionary if found
+
+ return None # Return None if not found in any dictionary
+
+
+def get_most_recent_date(date_local_resource, date_api):
+ # logging.warning(f'{date_local_resource} , {date_api}')
+
+ # Convert strings to datetime objects
+ date_time_local_resource = datetime.datetime.fromisoformat(date_local_resource[:-1])
+ date_time_api = datetime.datetime.fromisoformat(date_api[:-1])
+ # logging.warning(f'{date_time_local_resource} , {date_time_api}')
+ # Compare the datetime objects
+ if date_time_local_resource > date_time_api:
+ return False
+ elif date_time_local_resource < date_time_api:
+ return True
+ else:
+ return False
+
+
+def update_resource(resource):
+ single_resource = {}
+ single_resource = {
+ "title": resource["resource_title"],
+ "abstract": resource["abstract"],
+ "resource_id": resource["resource_id"],
+ "date_last_updated": resource["date_last_updated"],
+ "resource_type": resource["resource_type"],
+ "resource_url": resource["resource_url"],
+ }
+ return single_resource
+
+
+def extract_value_by_name(html, name):
+ soup = BeautifulSoup(html, "html.parser")
+ rows = soup.select("#extraMetaTable tbody tr")
+
+ for row in rows:
+ name_cell = row.select_one("td:first-child")
+ value_cell = row.select_one("td:nth-child(2)")
+
+ if name_cell and value_cell and name_cell.get_text(strip=True) == name:
+ return value_cell.get_text(strip=True)
+
+ return None
diff --git a/hydroshare_community_resources_app/views.py b/hydroshare_community_resources_app/views.py
new file mode 100644
index 0000000..a94c1e0
--- /dev/null
+++ b/hydroshare_community_resources_app/views.py
@@ -0,0 +1,100 @@
+from django.utils.translation import gettext_lazy as _
+from .utils import (
+ join_generators,
+ get_group_ids,
+ get_dict_with_attribute,
+ get_most_recent_date,
+ update_resource,
+ filter_resources_list_by_resources_id,
+ get_curated_resources,
+)
+
+from .models import (
+ HydroShareCommunityResourcesList,
+)
+from hs_restclient import HydroShare, HydroShareAuthBasic
+import logging
+import json
+from django.http import JsonResponse
+from django.shortcuts import render
+
+logger = logging.getLogger(__name__)
+
+
+def base_view(request):
+
+ context = {}
+ return render(request, "hydroshare-community-resources-base.html", context)
+
+
+def hydroshare_community_resources_view(request):
+
+ body_unicode = request.body.decode("utf-8")
+ body = json.loads(body_unicode)
+ instance = HydroShareCommunityResourcesList.objects.get(id=body["instance_id"])
+ is_curated = body["curated"]
+
+ json_resources = {"resources": []}
+ if instance.user != "" and instance.password != "":
+ auth = HydroShareAuthBasic(username=instance.user, password=instance.password)
+ hs = HydroShare(auth=auth)
+ else:
+ hs = HydroShare(prompt_auth=False)
+ try:
+ generators_rs = []
+
+ # GET THE IDS OF THE GROUPS FROM THE COMMUNITY
+ group_ids = get_group_ids(instance.community_id)
+
+ # QUERY THE RESOURCES OF EACH ONE OF THE GROUPS
+ for group_id in group_ids:
+ generators_rs.append(hs.resources(group=group_id))
+
+ # JOIN THE RESOURCES OF EACH ONE OF THE GROUPS AND ALSO MAKE SURE NO RESOURCE IS REPEATED
+ resources_api = join_generators(generators_rs)
+
+ # FILTER THE RESOURCES BY THE CURATED IDS IF NEEDED
+ if is_curated:
+ curated_ids = get_curated_resources(hs=hs)
+ resources_api = filter_resources_list_by_resources_id(
+ resources_api, curated_ids
+ )
+ resources_model = instance.resources.get("resources", [])
+
+ for resource_api in resources_api:
+ matching_resource_model = get_dict_with_attribute(
+ resources_model, "resource_id", resource_api["resource_id"]
+ )
+
+ # If resource found locally, then check last update date
+ if matching_resource_model:
+ is_recent_date = get_most_recent_date(
+ matching_resource_model["date_last_updated"],
+ resource_api["date_last_updated"],
+ )
+ if (
+ is_recent_date
+ ): # If the resource retrieved from api is more recent, then update resource
+ # logging.warning("resource has a more recent version")
+ single_resource = update_resource(resource_api)
+ # logging.warning(single_resource)
+ json_resources["resources"].append(single_resource)
+ instance.resources = json_resources
+
+ else: # resource is the same, then retrieve the resource saved locally
+ single_resource = matching_resource_model
+ json_resources["resources"].append(single_resource)
+ instance.resources = json_resources
+ # If the resource is not here then create one
+ else:
+ single_resource = update_resource(resource_api)
+ json_resources["resources"].append(single_resource)
+
+ instance.resources = json_resources
+
+ instance.save(update_fields=["resources"])
+ return JsonResponse(json_resources)
+
+ except Exception as e:
+ logging.warning(e)
+ instance.resources = {"Error": [f"The following error: {e}"]}
diff --git a/setup.sh b/setup.sh
index 5d95fef..b49bc9d 100755
--- a/setup.sh
+++ b/setup.sh
@@ -66,6 +66,11 @@ python manage.py migrate hydrolearn_modules_app
python manage.py makemigrations hydroshare_resources_app
python manage.py migrate hydroshare_resources_app
+python manage.py makemigrations hydroshare_community_resources_app
+python manage.py migrate hydroshare_community_resources_app
+
+
+
if [ -z "${SKIP_CREATION_USER}" ]; then
python manage.py createsuperuser --noinput --username $DJANGO_SUPERUSER_USERNAME --email $DJANGO_SUPERUSER_EMAIL
fi