[trails] Add alltrails and gaiagps ids to model
This commit is contained in:
@ -0,0 +1,23 @@
|
||||
# Generated by Django 4.2.19 on 2025-06-16 14:20
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("trails", "0004_alter_trail_run_time_seconds"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="trail",
|
||||
name="alltrails_id",
|
||||
field=models.CharField(blank=True, max_length=255, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="trail",
|
||||
name="gaiagps_id",
|
||||
field=models.CharField(blank=True, max_length=255, null=True),
|
||||
),
|
||||
]
|
||||
@ -9,9 +9,7 @@ from locations.models import GeoLocation
|
||||
BNULL = {"blank": True, "null": True}
|
||||
|
||||
|
||||
|
||||
class Trail(ScrobblableMixin):
|
||||
|
||||
class PrincipalType(models.TextChoices):
|
||||
WOODS = "WOODS"
|
||||
ROAD = "ROAD"
|
||||
@ -19,7 +17,7 @@ class Trail(ScrobblableMixin):
|
||||
MOUNTAIN = "MOUNTAIN"
|
||||
|
||||
class ActivityType(models.TextChoices):
|
||||
WALK= "WALK"
|
||||
WALK = "WALK"
|
||||
HIKE = "HIKE"
|
||||
RUN = "RUN"
|
||||
BIKE = "BIKE"
|
||||
@ -39,8 +37,14 @@ class Trail(ScrobblableMixin):
|
||||
)
|
||||
strava_id = models.CharField(max_length=255, **BNULL)
|
||||
trailforks_id = models.CharField(max_length=255, **BNULL)
|
||||
principal_type = models.CharField(max_length=10, choices=PrincipalType.choices, **BNULL)
|
||||
default_activity_type = models.CharField(max_length=10, choices=ActivityType.choices, **BNULL)
|
||||
alltrails_id = models.CharField(max_length=255, **BNULL)
|
||||
gaiagps_id = models.CharField(max_length=255, **BNULL)
|
||||
principal_type = models.CharField(
|
||||
max_length=10, choices=PrincipalType.choices, **BNULL
|
||||
)
|
||||
default_activity_type = models.CharField(
|
||||
max_length=10, choices=ActivityType.choices, **BNULL
|
||||
)
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("trails:trail_detail", kwargs={"slug": self.uuid})
|
||||
|
||||
61
vrobbler/apps/trails/sources/gaiagps.py
Normal file
61
vrobbler/apps/trails/sources/gaiagps.py
Normal file
@ -0,0 +1,61 @@
|
||||
from typing import Optional
|
||||
import requests
|
||||
from bs4 import BeautifulSoup
|
||||
|
||||
|
||||
def get_description_from_soup(soup) -> Optional[int]:
|
||||
rating = None
|
||||
try:
|
||||
potential_desc = soup.find("div", id_="descriptionContainer")
|
||||
potential_rating = soup.find("div", class_="allmusic-rating")
|
||||
if potential_rating:
|
||||
rating = int(strip_and_clean(potential_rating.get_text()))
|
||||
except ValueError:
|
||||
pass
|
||||
return rating
|
||||
|
||||
|
||||
def scrape_gaia_trail(url):
|
||||
headers = {"User-Agent": "Mozilla/5.0"}
|
||||
r = requests.get(url, headers=headers)
|
||||
r.raise_for_status()
|
||||
soup = BeautifulSoup(r.text, "html.parser")
|
||||
|
||||
# Title
|
||||
title = soup.select_one("h1").get_text(strip=True)
|
||||
|
||||
# Stats are inside divs with classes like "flex" and label-value pairs
|
||||
stats = {}
|
||||
stat_blocks = soup.select("div.flex.flex-col.items-start.text-sm span")
|
||||
for i in range(0, len(stat_blocks) - 1, 2):
|
||||
label = stat_blocks[i].get_text(strip=True)
|
||||
value = stat_blocks[i + 1].get_text(strip=True)
|
||||
stats[label] = value
|
||||
|
||||
# Description (under 'Overview' header)
|
||||
overview_heading = soup.find(
|
||||
lambda tag: tag.name == "h2" and "Overview" in tag.text
|
||||
)
|
||||
if overview_heading:
|
||||
desc_parts = []
|
||||
for sib in overview_heading.next_siblings:
|
||||
if sib.name and sib.name.startswith("h"):
|
||||
break
|
||||
if sib.name == "p":
|
||||
desc_parts.append(sib.get_text(strip=True))
|
||||
description = "\n\n".join(desc_parts).strip()
|
||||
else:
|
||||
description = None
|
||||
|
||||
return {
|
||||
"url": url,
|
||||
"title": title,
|
||||
"stats": stats,
|
||||
"description": description,
|
||||
}
|
||||
|
||||
|
||||
# Example usage
|
||||
url = "https://www.gaiagps.com/hike/318136/"
|
||||
trail_data = scrape_gaia_trail(url)
|
||||
print(trail_data)
|
||||
Reference in New Issue
Block a user