Skip to content

Commit 9f02116

Browse files
committed
Support #360
1 parent 4cc124c commit 9f02116

File tree

11 files changed

+167
-15
lines changed

11 files changed

+167
-15
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Generated by Django 4.2.10 on 2024-07-18 15:45
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
("edrnsitecontrols", "0006_rename_socialmedia_socialmedialink"),
10+
]
11+
12+
operations = [
13+
migrations.AddField(
14+
model_name="informatics",
15+
name="ip_address",
16+
field=models.CharField(
17+
default="unknown",
18+
help_text="Last known source IP address of the portal",
19+
max_length=40,
20+
),
21+
),
22+
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Generated by Django 4.2.10 on 2024-07-18 16:12
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
("edrnsitecontrols", "0007_informatics_ip_address"),
10+
]
11+
12+
operations = [
13+
migrations.AddField(
14+
model_name="informatics",
15+
name="ip_address_service",
16+
field=models.URLField(
17+
default="https://api.ipify.org",
18+
help_text="API endpoint of IP address service",
19+
),
20+
),
21+
]

src/edrnsite.controls/src/edrnsite/controls/models.py

+8
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,12 @@ class Informatics(BaseSiteSetting):
7979
)
8080
funding_cycle = models.CharField(default='Ⅴ', max_length=8, null=False, blank=False, help_text='EDRN Funding Cycle')
8181
site_wide_banner = RichTextField(blank=True, help_text='Banner to display site-wide at the top of every page')
82+
ip_address = models.CharField(
83+
default='unknown', max_length=40, null=False, blank=False, help_text='Last known source IP address of the portal'
84+
)
85+
ip_address_service = models.URLField(
86+
default='https://api.ipify.org', null=False, blank=False, help_text='API endpoint of IP address service'
87+
)
8288
panels = [
8389
FieldPanel('in_development'),
8490
FieldPanel('entrez_email'),
@@ -87,6 +93,8 @@ class Informatics(BaseSiteSetting):
8793
FieldPanel('dmcc_url'),
8894
FieldPanel('funding_cycle'),
8995
FieldPanel('site_wide_banner'),
96+
FieldPanel('ip_address'),
97+
FieldPanel('ip_address_service'),
9098
]
9199

92100

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# encoding: utf-8
2+
3+
'''🎛 EDRN Site Controls: asynchronous tasks.'''
4+
5+
from .models import Informatics
6+
from celery import shared_task
7+
from django.core.cache import cache
8+
from urllib.request import urlopen
9+
from wagtail.models import Site
10+
import logging
11+
12+
13+
_logger = logging.getLogger(__name__)
14+
15+
16+
@shared_task
17+
def do_update_my_ip():
18+
_logger.info('🔓 Getting lock for `update_my_up`')
19+
with cache.lock('update_my_ip', timeout=300):
20+
settings = Informatics.for_site(Site.objects.filter(is_default_site=True).first())
21+
_logger.info('🤓 Looking up my IP with %s', settings.ip_address_service)
22+
try:
23+
with urlopen(settings.ip_address_service) as io:
24+
my_ip = io.read().decode('utf-8')
25+
_logger.info('🎉 Got %s', my_ip)
26+
except Exception as ex:
27+
my_ip = str(ex)
28+
_logger.exception('😔 Could not get my_ip')
29+
settings.ip_address = my_ip
30+
settings.save()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{% load wagtailadmin_tags %}
2+
<section class='panel summary nice-padding'>
3+
<div style='display: grid; grid-template-columns: repeat(2, 1fr); grid-gap: 1rem;
4+
grid-auto-rows: minmax(100px, auto);'>
5+
<div>
6+
<h2 class='title-wrapper'>EDRN Site Controls</h2>
7+
<dl>
8+
<dt>My IP</dt>
9+
<dd>{{my_ip}}</dd>
10+
</dl>
11+
12+
</div>
13+
<div>
14+
<a href='{% url "update_my_ip" %}' class='button button-longrunning' role='button'>Update my IP</a>
15+
</div>
16+
</div>
17+
</section>
18+
{# -*- Django HTML -*- #}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# encoding: utf-8
2+
3+
'''🎛 EDRN Site Controls: URL patterns.'''
4+
5+
6+
from .views import update_my_ip
7+
from django.urls import path
8+
9+
10+
urlpatterns = [
11+
path('update_my_ip', update_my_ip, name='update_my_ip'),
12+
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# encoding: utf-8
2+
3+
'''🎛 EDRN Site Controls: views.'''
4+
5+
from .tasks import do_update_my_ip
6+
from django.http import HttpRequest, HttpResponse, HttpResponseRedirect, HttpResponseForbidden
7+
from edrn.auth.views import logged_in_or_basicauth
8+
9+
10+
def _get_referrer(request: HttpRequest) -> str:
11+
try:
12+
return request.META['HTTP_REFERER']
13+
except KeyError:
14+
return '/'
15+
16+
17+
@logged_in_or_basicauth('edrn')
18+
def update_my_ip(request: HttpRequest) -> HttpResponse:
19+
'''Update my IP address.'''
20+
if request.user.is_staff or request.user.is_superuser:
21+
do_update_my_ip.delay()
22+
return HttpResponseRedirect(_get_referrer(request))
23+
else:
24+
return HttpResponseForbidden()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# encoding: utf-8
2+
3+
'''🎛 EDRN Site Controls: Wagtail hooks and interceptors.'''
4+
5+
from .models import Informatics
6+
from django.http import HttpRequest
7+
from django.template.loader import render_to_string
8+
from wagtail import hooks
9+
from wagtail.admin.ui.components import Component
10+
11+
12+
class EDRNSiteControlsControlPanel(Component):
13+
'''Custom control panel for EDRN site controls.'''
14+
15+
name = 'edrnsite_controls'
16+
order = 210
17+
18+
def __init__(self, request: HttpRequest):
19+
self.request = request
20+
21+
def render_html(self, parent_context: list) -> str:
22+
context = {'my_ip': Informatics.for_request(self.request).ip_address}
23+
return render_to_string('edrnsite.controls/edrnsite-controls.html', context, request=self.request)
24+
25+
26+
@hooks.register('construct_homepage_panels')
27+
def add_ingest_controls(request: HttpRequest, panels: list):
28+
'''Add the custom EDRN site controls control panel.'''
29+
panels.append(EDRNSiteControlsControlPanel(request))

src/edrnsite.policy/src/edrnsite/policy/urls.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,17 @@
1111
from django.urls import path, include, re_path
1212
from edrn.auth.urls import urlpatterns as edrnAuthURLs
1313
from edrn.metrics.urls import urlpatterns as edrn_metrics_urls
14+
from edrnsite.controls.urls import urlpatterns as edrnsite_controls_urlpatterns
1415
from edrnsite.search.urls import urlpatterns as edrnSiteSearchURLs
1516
from eke.knowledge.urls import urlpatterns as ekeKnowledgeURLs
17+
from wagtail import urls as wagtail_urls
1618
from wagtail.admin import urls as wagtailadmin_urls
1719
from wagtail.contrib.sitemaps.views import sitemap
18-
from wagtail import urls as wagtail_urls
1920
from wagtail.documents import urls as wagtaildocs_urls
2021
from wagtail_favicon.urls import urls as favicon_urls
2122

2223

23-
urlpatterns = ekeKnowledgeURLs + edrnSiteSearchURLs + edrnAuthURLs + edrn_metrics_urls + [
24+
urlpatterns = edrnsite_controls_urlpatterns + ekeKnowledgeURLs + edrnSiteSearchURLs + edrnAuthURLs + edrn_metrics_urls + [
2425
path('clear-caches', clear_caches, name='clear_caches'),
2526
path('django-admin/', admin.site.urls),
2627
path('admin/', include(wagtailadmin_urls)),

src/eke.knowledge/src/eke/knowledge/templates/eke.knowledge/ingest-controls.html

-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66
<h2 class='title-wrapper'>EDRN Ingest Controls</h2>
77
{% if last_ingest_start %}
88
<dl>
9-
<dt>My IP</dt>
10-
<dd>{{my_ip}}</dd>
119
<dt>Last started</dt>
1210
<dd>{{last_ingest_start|naturaltime}}</dd>
1311
<dt>Duration</dt>

src/eke.knowledge/src/eke/knowledge/wagtail_hooks.py

-11
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@
88
from django.template.loader import render_to_string
99
from wagtail.admin.ui.components import Component
1010
from wagtail import hooks
11-
from urllib.request import urlopen
12-
import os
1311

1412

1513
class IngestControlPanel(Component):
@@ -27,20 +25,11 @@ def render_html(self, parent_context: list) -> str:
2725
settings = RDFIngest.for_request(self.request)
2826
folders = KnowledgeFolder.objects.all().order_by('ingest_order')
2927

30-
# ipify.org is having problems
31-
# try:
32-
# with urlopen(self._ip_service) as f:
33-
# my_ip = f.read().decode('utf-8')
34-
# except Exception as ex:
35-
# my_ip = str(ex)
36-
my_ip = 'unknown'
37-
3828
context = {
3929
'last_ingest_start': settings.last_ingest_start,
4030
'last_ingest_duration': settings.last_ingest_duration,
4131
'ingest_running': lock.locked(),
4232
'knowledge_folders': folders,
43-
'my_ip': my_ip,
4433
}
4534
return render_to_string('eke.knowledge/ingest-controls.html', context, request=self.request)
4635

0 commit comments

Comments
 (0)