Forráskód Böngészése

Fixes #12384: Add a three-second timeout for RSS reader widget

jeremystretch 2 éve
szülő
commit
9319cffb1c

+ 1 - 0
docs/release-notes/version-3.5.md

@@ -5,6 +5,7 @@
 ### Bug Fixes
 
 * [#12380](https://github.com/netbox-community/netbox/issues/12380) - Allow selecting object change as model under object list widget configuration
+* [#12384](https://github.com/netbox-community/netbox/issues/12384) - Add a three-second timeout for RSS reader widget
 * [#12395](https://github.com/netbox-community/netbox/issues/12395) - Fix "create & add another" action for objects with custom fields
 * [#12396](https://github.com/netbox-community/netbox/issues/12396) - Provider account should not be a required field in REST API serializer
 * [#12405](https://github.com/netbox-community/netbox/issues/12405) - Fix filtering for VLAN groups displayed under site view

+ 32 - 18
netbox/extras/dashboard/widgets.py

@@ -4,6 +4,7 @@ from hashlib import sha256
 from urllib.parse import urlencode
 
 import feedparser
+import requests
 from django import forms
 from django.conf import settings
 from django.contrib.contenttypes.models import ContentType
@@ -269,12 +270,9 @@ class RSSFeedWidget(DashboardWidget):
         )
 
     def render(self, request):
-        url = self.config['feed_url']
-        feed = self.get_feed()
-
         return render_to_string(self.template_name, {
-            'url': url,
-            'feed': feed,
+            'url': self.config['feed_url'],
+            **self.get_feed()
         })
 
     @cached_property
@@ -286,17 +284,33 @@ class RSSFeedWidget(DashboardWidget):
     def get_feed(self):
         # Fetch RSS content from cache if available
         if feed_content := cache.get(self.cache_key):
-            feed = feedparser.FeedParserDict(feed_content)
-        else:
-            feed = feedparser.parse(
-                self.config['feed_url'],
-                request_headers={'User-Agent': f'NetBox/{settings.VERSION}'}
+            return {
+                'feed': feedparser.FeedParserDict(feed_content),
+            }
+
+        # Fetch feed content from remote server
+        try:
+            response = requests.get(
+                url=self.config['feed_url'],
+                headers={'User-Agent': f'NetBox/{settings.VERSION}'},
+                proxies=settings.HTTP_PROXIES,
+                timeout=3
             )
-            if not feed.bozo:
-                # Cap number of entries
-                max_entries = self.config.get('max_entries')
-                feed['entries'] = feed['entries'][:max_entries]
-                # Cache the feed content
-                cache.set(self.cache_key, dict(feed), self.config.get('cache_timeout'))
-
-        return feed
+            response.raise_for_status()
+        except requests.exceptions.RequestException as e:
+            return {
+                'error': e,
+            }
+
+        # Parse feed content
+        feed = feedparser.parse(response.content)
+        if not feed.bozo:
+            # Cap number of entries
+            max_entries = self.config.get('max_entries')
+            feed['entries'] = feed['entries'][:max_entries]
+            # Cache the feed content
+            cache.set(self.cache_key, dict(feed), self.config.get('cache_timeout'))
+
+        return {
+            'feed': feed,
+        }

+ 6 - 4
netbox/templates/extras/dashboard/widgets/rssfeed.html

@@ -1,4 +1,4 @@
-{% if not feed.bozo %}
+{% if feed and not feed.bozo %}
   <div class="list-group list-group-flush">
     {% for entry in feed.entries %}
       <div class="list-group-item px-1">
@@ -16,7 +16,9 @@
   <span class="text-danger">
     <i class="mdi mdi-alert"></i> There was a problem fetching the RSS feed:
   </span>
-  <pre class="m-2">
-Response status: {{ feed.status }}
-Error: {{ feed.bozo_exception|escape }}</pre>
+  {% if feed %}
+    {{ feed.bozo_exception|escape }} (HTTP {{ feed.status }})
+  {% else %}
+    {{ error }}
+  {% endif %}
 {% endif %}