Comments (5)
Hey @danielpops camply only shows up with campsites since it searches the campground / campsite API endpoints of the Recreation.gov and RIDB APIs which don't include timed entry passes.
Looking closer at timed entry passes this would be a large feature to implement. There would be discovery involved with the API endpoints as well work to implement the logic behind searching for timed entry pass availability which is much different than a campsites availability:
At this time I don't have the capacity to develop this feature but would absolutely welcome any outside contributions. Thanks
from camply.
I'm going to leave this here for future me or anyone who wants to implement it in the meantime:
API Endpoints from the Recreation.gov API to search for timed entry:
- https://www.recreation.gov/api/timedentrycontent/facility/10088426
- https://www.recreation.gov/api/timedentry/availability/facility/10088426/monthlyAvailabilitySummaryView?year=2022&month=03&inventoryBucket=FIT&tourID=10088427
https://ridb.recreation.gov/docs#/Facilities/getFacility
import logging
from pprint import pprint
from typing import Dict, Any
from camply.providers import RecreationDotGov
logging.basicConfig(level=logging.DEBUG)
recdotgov = RecreationDotGov()
response: Dict[str, Any] = recdotgov._ridb_get_data(path="facilities/10088426")
pprint(response)
{
"FacilityID": "10088426",
"LegacyFacilityID": "",
"OrgFacilityID": "",
"ParentOrgID": "128",
"ParentRecAreaID": "2573",
"FacilityName": "Arches National Park Timed Entry",
"FacilityDescription": "Arches National Park is in the heart of canyon country in southeastern Utah and is considered one of America\u2019s scenic wonders. The park preserves 76,679 acres of high desert on the Colorado Plateau, punctuated by rocky ridges, canyons, fins, towers, monoliths, pinnacles, and more than 2,000 arches. Elevations in the park range from 4,085 to 5,653 feet above sea level.\nArches National Park becomes extremely crowded during the park\u2019s busy season from March through October, with the highest visitation occurring in May, June, and September. Since 2010, more than 1 million visitors have visited the park each year. \nIn 2022, Arches National Park will implement a pilot timed entry reservation system to gather data to inform long-term visitor use management at the park.\nEach private vehicle entering the park will need a Timed Entry reservation for each day the vehicle will be in the park between 6 am and 6 pm. The reservation-holder must be in the vehicle with photo identification when you arrive at the park. The Timed Entry reservation includes a $2.00 reservation fee which is separate from the park entrance fee.\nYou may pay the fee by purchasing an Arches National Park entrance pass in advance. The park also honors annual or lifetime passes. Valid entrance passes accepted are: Southeast Utah Parks Annual Pass, Interagency Annual Pass, Interagency Senior Annual Pass, Interagency Access Pass, Interagency Lifetime Senior Pass, Interagency Volunteer Pass, Interagency Military Pass, Interagency 4th Grade Pass. Please Note: You may also purchase the entrance pass upon arrival at the park, but we encourage you to pre-pay the fee.",
"FacilityTypeDescription": "Timed Entry",
"FacilityUseFeeDescription": "",
"FacilityDirections": "The main entrance for Arches National Park is accessed via US HWY 191, five miles north of Moab (if entering from the south) or 22 miles south of Interstate 70 (if entering from the north).",
"FacilityPhone": "435-719-2299",
"FacilityEmail": "",
"FacilityReservationURL": "",
"FacilityMapURL": "",
"FacilityAdaAccess": "",
"GEOJSON": {
"TYPE": "",
"COORDINATES": null
},
"FacilityLongitude": 0,
"FacilityLatitude": 0,
"Keywords": "",
"StayLimit": "",
"Reservable": true,
"Enabled": true,
"LastUpdatedDate": "2021-12-14"
}
from camply.
Okay, I needed to use this for Yosemite Timed Entry. The API for monthlyAvailableSummary
was not accurate. It would show as 1 available, but I couldn't purchase it. So I switched to using the API used by the website to validate purchases: api/timedentry/availability/facility/10088426
. It worked perfectly once I found a spot.
I wrote this tiny code to use:
from camply.providers import RecreationDotGov
from camply.notifications.telegram import TelegramNotifications
from camply.config import (RecreationBookingConfig,
STANDARD_HEADERS,
USER_AGENTS)
from camply.utils import api_utils
from typing import Union
from datetime import datetime, date
from random import choice
from json import loads
from urllib import parse
import logging
import os
import requests
from tenacity import retry, wait_random
logger = logging.getLogger(__name__)
logging.basicConfig(
format='%(asctime)s %(levelname)-8s %(message)s',
level=logging.INFO,
datefmt='%Y-%m-%d %H:%M:%S')
notify = TelegramNotifications()
def get_timed_entry(facility_id: int, date: datetime) -> Union[dict, list]:
try:
base_url = api_utils.generate_url(scheme=RecreationBookingConfig.API_SCHEME,
netloc=RecreationBookingConfig.API_NET_LOC,
path="api/timedentry/availability/facility/")
api_endpoint = parse.urljoin(
base_url, f"{facility_id}")
# BUILD THE HEADERS EXPECTED FROM THE API
headers = STANDARD_HEADERS.copy()
headers.update(choice(USER_AGENTS))
headers.update(RecreationBookingConfig.API_REFERRERS)
response = requests.get(url=api_endpoint, headers=headers,
params=dict(
date=date.strftime("%Y-%m-%d")
),
timeout=30)
assert response.status_code == 200
except AssertionError:
response_error = response.text
error_message = "Bad Data Returned from the RecreationDotGov API"
logger.debug(f"{error_message}, will continue to retry")
logger.debug(f"Error Details: {response_error}")
raise ConnectionError(f"{error_message}: {response_error}")
return loads(response.content)
@retry(wait=wait_random(min=60*5, max=60*6))
def checkLatestInformation():
facility_id = 10086745
days = [
date.fromisoformat('2022-06-27'),
date.fromisoformat('2022-06-28'),
date.fromisoformat('2022-06-29')
]
for day in days:
tours = get_timed_entry(facility_id, day)
for tour in tours:
tour_id = tour["tour_id"]
display_date = day.strftime("%Y-%m-%d")
inventory = sum(tour["inventory_count"].values())
reserved = sum(tour["reservation_count"].values())
available = inventory - reserved
logger.info(f"{display_date}: {available}")
if available > 0:
logger.info("FOUND SOMETHING");
notify.send_message(
f"{available} spot(s) in Yosemite for {display_date}: https://www.recreation.gov/timed-entry/{facility_id}/ticket/{tour_id}")
raise Exception
checkLatestInformation()
from camply.
Okay, I needed to use this for Yosemite Timed Entry. The API for
monthlyAvailableSummary
was not accurate. It would show as 1 available, but I couldn't purchase it. So I switched to using the API used by the website to validate purchases:api/timedentry/availability/facility/10088426
. It worked perfectly once I found a spot.
Thought about this, but it doesn't fit the rest of code which expects monthly search. Also this will 30x the amount of requests sent. Still using monthlyAvailabilitySummaryView in #151. Probably a separate provider (or a provider-specific parameter) to specify the behavior?
UPDATE: added new providers to use the "Daily" behavior. Each available tour / timed entry is still campsite while every slot becomes an equipment, so you should be able to do --equipment 0900 4
when you want a 9:00 AM slot for 4+ people (didn't test it but I think it should work).
from camply.
This issue was resolved with camply 0.9.0
!!! 🎉
https://juftin.com/camply/providers/#recreationgov-tickets-tours-timed-entry
https://juftin.com/camply/command_line_usage/#searching-for-tickets-and-timed-entries
from camply.
Related Issues (20)
- cannot search on ReserveCalifornia HOT 7
- Notifications over MQTT? HOT 7
- Support for novascotia.goingtocamp.com HOT 4
- Olympic National Park doesn't appear as a WA Recreation area HOT 3
- Ability to specify # of people for a campsite HOT 1
- Reserve California doesn't work for me. HOT 12
- yaml search with ReserveCalifornia fails with TypeError: object of type 'NoneType' has no len()
- Support for manitoba.goingtocamp.com HOT 2
- Trouble using search yaml file with equipment option
- Support for reservations.ontarioparks.com (goingtocamp) HOT 4
- Filter campsites for goingtocamp HOT 3
- GoingToCamp Parks Canada does not identify available sites correctly HOT 12
- `POLLING_INTERVAL_MINIMUM` limit clarification HOT 4
- Generic webhook notification HOT 6
- Reserve California website availability not reflecting in Camply searching HOT 1
- campsite geolocation HOT 6
- Webhook crashes on utf-8 characters HOT 1
- Provider for site specific backcountry permits on nps.gov
- GoingToCamp midnrreservations.com ConnectionError HOT 3
- --start-date argument not getting respected HOT 5
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from camply.