Integrate miniuri library for URI parsing in NamespaceRequest

- Replaced custom URI parsing logic with the miniuri library to simplify and standardize URI handling.
- Updated the _get_domain_from_target method to use miniuri for extracting the hostname from target URLs.
- This change enhances code readability and leverages miniuri's robust URI parsing capabilities.

	modified:   remarkbox/models/namespace_request.py
This commit is contained in:
Russell Ballestrini 2024-10-06 16:26:36 -04:00
parent eb93c955e5
commit 83adeb0a02

View file

@ -7,9 +7,13 @@ from .meta import now_timestamp, foreign_key, get_object_by_id
import requests import requests
import logging import logging
import threading import threading
from datetime import datetime, timedelta
from miniuri import Uri
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
domain_skip_until = {}
class NamespaceRequest(RBase, Base): class NamespaceRequest(RBase, Base):
id = Column(UUIDType, primary_key=True, index=True) id = Column(UUIDType, primary_key=True, index=True)
@ -20,7 +24,6 @@ class NamespaceRequest(RBase, Base):
verified = Column(Boolean, default=False) verified = Column(Boolean, default=False)
last_scrape_timestamp = Column(BigInteger, nullable=True) last_scrape_timestamp = Column(BigInteger, nullable=True)
# Lock for preventing concurrent scrapes
_scrape_lock = threading.Lock() _scrape_lock = threading.Lock()
user = relationship( user = relationship(
@ -70,13 +73,21 @@ class NamespaceRequest(RBase, Base):
): ):
return self.verified return self.verified
# Attempt to acquire the lock without blocking # Extract domain from target using miniuri
domain = self._get_domain_from_target(self.target)
# Check if the domain is currently being skipped
if domain in domain_skip_until and datetime.now() < domain_skip_until[domain]:
log.info(
f"Skipping scrape for domain={domain} until {domain_skip_until[domain]}"
)
return self.verified
if not self._scrape_lock.acquire(blocking=False): if not self._scrape_lock.acquire(blocking=False):
log.info("Scrape already in progress for uuid={}".format(self.id)) log.info("Scrape already in progress for uuid={}".format(self.id))
return self.verified return self.verified
try: try:
# Re-check the cache after acquiring the lock
if ( if (
self.last_scrape_timestamp self.last_scrape_timestamp
and (current_time - self.last_scrape_timestamp) < 300 and (current_time - self.last_scrape_timestamp) < 300
@ -115,14 +126,14 @@ class NamespaceRequest(RBase, Base):
) )
self.last_scrape_timestamp = current_time self.last_scrape_timestamp = current_time
return False return False
log.info( elif resp.status_code == 429: # Too Many Requests
"scraping target={} looking for uuid={} status={} reason={}".format( # Set skip time for the domain
self.target, domain_skip_until[domain] = datetime.now() + timedelta(
namespace_request_id, minutes=30
resp.status_code, )
resp.reason, log.info(
f"Rate limited by domain={domain}, skipping until {domain_skip_until[domain]}"
) )
)
except requests.RequestException as e: except requests.RequestException as e:
log.error(f"Error scraping target={self.target}: {e}") log.error(f"Error scraping target={self.target}: {e}")
@ -131,6 +142,11 @@ class NamespaceRequest(RBase, Base):
finally: finally:
self._scrape_lock.release() self._scrape_lock.release()
def _get_domain_from_target(self, target):
"""Extract the domain from the target URL using miniuri."""
uri = Uri(target)
return uri.hostname
def get_namespace_request_by_id(dbsession, namespace_request_id): def get_namespace_request_by_id(dbsession, namespace_request_id):
"""Try to get NamespaceRequest object by id or return None.""" """Try to get NamespaceRequest object by id or return None."""