Giter VIP home page Giter VIP logo

Comments (5)

juftin avatar juftin commented on July 17, 2024

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:
image

At this time I don't have the capacity to develop this feature but would absolutely welcome any outside contributions. Thanks

from camply.

juftin avatar juftin commented on July 17, 2024

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://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.

stjohnjohnson avatar stjohnjohnson commented on July 17, 2024

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.

jingyuanliang avatar jingyuanliang commented on July 17, 2024

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.

juftin avatar juftin commented on July 17, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.