Git Product home page Git Product logo

recreation-gov-campsite-checker's Introduction

Campsite Availability Scraping

This has been updated to work with the new recreation.gov site and API!!!

This script scrapes the https://recreation.gov website for campsite availabilities.

Note: Please don't abuse this script. Most folks out there don't know how to run scrapers against websites, so you're at an unfair advantage by using this.

Example Usage

$ python camping.py --start-date 2018-07-20 --end-date 2018-07-23 --parks 232448 232450 232447 232770
โŒ TUOLUMNE MEADOWS: 0 site(s) available out of 148 site(s)
๐Ÿ• LOWER PINES: 11 site(s) available out of 73 site(s)
โŒ UPPER PINES: 0 site(s) available out of 235 site(s)
โŒ BASIN MONTANA CAMPGROUND: 0 site(s) available out of 30 site(s)

You can also read from stdin. Define a file (e.g. parks.txt) with park IDs like this:

232447
232449
232450
232448

and then use it like this:

$ python camping.py --start-date 2018-07-20 --end-date 2018-07-23 --stdin < parks.txt

For powershell, try this:

PS > Get-Content parks.txt | python camping.py --start-date 2021-09-24 --end-date 2022-09-24 --stdin

If you want to see more information about which campsites are available, pass --show-campsite-info along with --nights <int>:

$ python camping.py --start-date 2018-07-20 --end-date 2018-07-23 --parks 232448 232450 232447 232770 --show-campsite-info --nights 1 
There are campsites available from 2018-07-20 to 2018-07-23!!!
๐Ÿ• ELK CREEK CAMPGROUND (SAWTOOTH NF) (232042): 1 site(s) available out of 1 site(s)
  * Site 69800 is available on the following dates:
    * 2018-07-20 -> 2018-07-21 
    * 2018-07-21 -> 2018-07-22

If you only want results for certain campsite IDs, pass --campsite-ids <int>:

$ python camping.py --start-date 2018-07-20 --end-date 2018-07-23 --parks 232431 --show-campsite-info --nights 1 --campsite-ids 18621 

You'll want to put this script into a 5 minute crontab. You could also grep the output for the success emoji (๐Ÿ•) and then do something in response, like notify you that there is a campsite available. See the "Twitter Notification" section below.

Number of nights

If you're flexible on travel dates, you can search for a specific number of contiguous nights within a wide range of dates. This is useful for campgrounds in high-demand areas (like Yosemite Valley) or during peak season when openings are rare. Simply specify the --nights argument. For example, to search for a 5-day reservation in the month of June 2020 at Chisos Basin:

$ python camping.py --start-date 2020-06-01 --end-date 2020-06-30 --nights 5 234038
There are campsites available from 2020-06-01 to 2020-06-30!!!
๐Ÿ• CHISOS BASIN (BIG BEND) (234038): 13 site(s) available out of 62 site(s)

Getting park IDs

What you'll want to do is go to https://recreation.gov and search for the campground you want. Click on it in the search sidebar. This should take you to a page for that campground, the URL will look like https://www.recreation.gov/camping/campgrounds/<number>. That number is the park ID.

Getting campsite IDs

Go to https://recreation.gov and first search for the campground you want and then select the specific campsite within that campground. The URL for the campsite should look like https://www.recreation.gov/camping/campsites/<number>. That number is the campsite ID.

Searching for availability at a specific campsite within a campground

You can search for availability at just a single specific campsite using the '--campsite-ids' argument. This can be useful if you have a favorite campsite you like to use or if you have a reservation at a specific campsite that you want to add days to before or after your existing reservation. This search only works for one campground/campsite combination at a time.

$ python camping.py --start-date 2020-06-01 --end-date 2020-06-30 --nights 5 --parks 234038 --campsite-ids 6943
There are campsites available from 2020-06-01 to 2020-06-30!!!
๐Ÿ• CHISOS BASIN (BIG BEND) (234038): 1 site(s) available out of 62 site(s)

You can also take this site for a spin. Thanks to pastudan!

Excluding specific campsites

You can exclude specific campsites, for example group sites, by defining a file (e.g. excluded.txt) with one campsite ID per line and using the --exclusion-file argument like this:

$ python camping.py --start-date 2018-07-20 --end-date 2018-07-23 --parks 232448 232450 232447 232770 --exclusion-file excluded.txt

Installation

I wrote this in Python 3.7 but I've tested it as working with 3.5 and 3.6 also. It is best to use 3.9+

python3 -m venv myvenv
source myvenv/bin/activate
pip install --upgrade pip
pip install -r requirements.txt
# You're good to go!

Development

This code is formatted using black and isort:

black -l 80 --py36 camping.py
isort camping.py

Note: black only really supports 3.6+ so watch out!

Feel free to submit pull requests, or look at the original: https://github.com/bri-bri/yosemite-camping

Running Tests

All tests should pass before a pull request gets merged. To run all the tests, cd into the project directory and run:

python -m unittest

Differences from the original

  • Python 3 ๐Ÿ๐Ÿ๐Ÿ.
  • Park IDs not hardcoded, passed via the CLI instead.
  • Doesn't give you URLs for campsites with availabilities.
  • Works with any park out of the box, not just those in Yosemite like with the original.
  • Update 2018-10-21: Works with the new recreation.gov site.

Twitter Notification

If you want to be notified about campsite availabilities via Twitter (they're the only API out there that is actually easy to use), you can do this:

  1. Make an app via Twitter. It's pretty easy, go to: https://developer.twitter.com/en/apps.
  2. Change the values in twitter_credentials.json to match your key values.
  3. Pipe the output of your command into notifier.py. See below for an example.
python camping.py --start-date 2018-07-20 --end-date 2018-07-23 --parks 70926 70928 | python notifier.py @banool1

You'll want to make the app on another account (like a bot account), not your own, so you get notified when the tweet goes out.

I left my API keys in here but don't exploit them ty thanks.

Thanks to https://github.com/bri-bri/yosemite-camping for getting me most of the way there for the old version.

recreation-gov-campsite-checker's People

Contributors

andribja avatar banool avatar billxma avatar colossatr0n avatar crheidri avatar dcroote avatar dependabot[bot] avatar drewcm avatar frrad avatar jazzatar avatar karstenpatzwaldt avatar oregev11 avatar rengler33 avatar wise-east avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

recreation-gov-campsite-checker's Issues

Twilio API Integration

Are you interested in a PR integrating with the Twilio API? I would probably implement it as a flag on the main campsite.py instead of a separate program that parses the output of the first like notifier.py.

Change in website?

Followed the instructions but seemed to have run into the follow error. Just wondering if there was a change somewhere in the website that broke the current script! Thanks!

python camping.py --start-date 2018-07-20 --end-date 2018-07-23 --parks 232448 232450 232447 232770
Something went wrong
Traceback (most recent call last):
  File "camping.py", line 191, in <module>
    _main(parks)
  File "camping.py", line 116, in _main
    park_information = get_park_information(park_id, params)
  File "camping.py", line 56, in get_park_information
    return send_request(url, params)
  File "camping.py", line 48, in send_request
    resp.status_code, url, resp.text
RuntimeError: ('failedRequest', 'ERROR, 404 code received from https://www.recreation.gov/api/camps/availability/campground/232448: {"error":"Not Found"}\n')

Python v3.5 pip error with "black"

The README.md says this:

I wrote this in Python 3.7 but I've tested it as working with 3.5 and 3.6 also.

It's worth pointing out that black (one of the project requirements) doesn't support Python 3.5:

Black can be installed by running pip install black. It requires Python 3.6.0+ to run but you can reformat Python 2 code with it, too.

When I run pip from Python v3.5.2 I get an error:

(venv) ~/git/recreation-gov-campsite-checker$ python --version
Python 3.5.2
(venv) ~/git/recreation-gov-campsite-checker$ pip install -r requirements.txt
...
Collecting black==18.9b0 (from -r requirements.txt (line 4))
ERROR: Could not find a version that satisfies the requirement black==18.9b0 (from -r requirements.txt (line 4)) (from versions: none)
ERROR: No matching distribution found for black==18.9b0 (from -r requirements.txt (line 4))

After removing black from requirements.txt I was able to run recreation-gov-campsite-checker fine. Perhaps a note in the README.md would be sufficient to close this ticket.

It also appears that there is an unused dependency in requirements.txt: beautifulsoup4==4.7.1

Create site that shows park IDs

This is more of a separate idea than something that could be put here, but it'd be neat to have a site that scraped recreation.gov very occasionally for park IDs.

End date shouldn't be included in month calculations

When the end date is on the first of a month (e.g. October 1st), a request is issued both for dates in September and October. However, the end date is documented to be exclusive for this script, as it's the checkout date. So an extra unneeded request is being issued, which given the sensitive rate limiting on recreation.gov, would add to the instability.

Cause:
An rrule monthly rule includes the end date by default, so get_park_information ends up fetching for both months.

Solution:
I believe this can be solved by excluding the end date using exdate. Something like this:

start_of_month = datetime(start_date.year, start_date.month, 1)
ruleset = rrule.rruleset()
ruleset.rrule(rrule.rrule(rrule.MONTHLY, dtstart=start_of_month, until=end_date))
# exclude end date as that is the checkout date
ruleset.exdate(end_date)
months = list(ruleset)

I haven't robustly tested this to ensure it doesn't break other scenarios, but seems to work for my use case.

Is the project still working?

Hi,

I have downloaded the project and started it. Somehow the script tells me there are no sites available.

python camping.py --start-date 2023-05-03 --end-date 2023-05-11 --parks 234015

But looking at the website for pinnacles there should be some open spots.

image

Is there something wrong?

Paul

Create site that allows anyone to use this checker

The problem with this checker is only those with coding knowledge can really use it. This puts those without that knowledge at a disadvantage when trying to find a campsite, which is unfair and counter to open source.

I need to make a site that lets anyone use this. It would have a form for entering the site and dates that you want, and allow you to receive notifications when the sites become available.

Add smtplib for notifications

I'm not very github savvy else I would do a pull request?....

For now, I thought I would offer up this block of code I inserted to notify me when a site was available. It worked perfect for me yesterday/today to snatch a very sought after location within 60 seconds. Absolutely appreciate you creating the base script to work with the new recreation.gov site. I just have to find a scraper for the reserveamerica.com site now and wrap them.... Hoping I can pick up PHP and create a web-based wrapper to connect them together.

This is showing the top and bottom parts of the original script so you can see where I put this.
Pretty sure this could be extracted and put into a module instead to better protect the password or maybe just use a dummy email account.

I use my email and sms for notifications that include the link to the site/campground so I can quickly scan sites for which one is open. If I knew the API call to show open sites in a campground that would be even nicer.... Maybe have a link in the notification to "book now" which would place it in your cart and give you 15min to reserve it?

    if availabilities:
        print(
            "There are campsites available from {} to {}!!!".format(
                args.start_date.strftime(INPUT_DATE_FORMAT),
                args.end_date.strftime(INPUT_DATE_FORMAT),
            )
        )
        import smtplib
        from email.mime.text import MIMEText
        me = "[email protected]"
        recipients = ['[email protected]', '[email protected]']
        passwd = "password here"
        body = ("There are " + str(current) + " sites available out of " + str(maximum) + " site(s) at " + name_of_site
             +  "\nLink to Reserve: https://recreation.gov/camping/campgrounds/" + str(park_id) + "/availability")
        msg = MIMEText(body)
        msg['Subject'] = 'Campsites Available for ' + args.start_date.strftime(INPUT_DATE_FORMAT) + ' - ' + args.end_date.strftime(INPUT_DATE_FORMAT)
        msg['From'] = "[email protected]"
        msg['To'] = ", ".join(recipients)
        session = smtplib.SMTP('smtp.comcast.net',587)
        session.login(me, passwd)
        session.sendmail(me, recipients, msg.as_string())
        session.quit()

    else:
        print("There are no campsites available :(")
    print("\n".join(out))

Using a while loop for now until I can do a cron entry... (running this out of a FreeNas jail on python36)

while [ 1 ]; do python camping.py --start-date 2019-07-11 --end-date 2019-07-12 233187; sleep 60; done

image

STDIN doesn't work per usage

Attempting to use --stdin < parks.txt
Not working

(camp) [root@camp recreation-gov-campsite-checker-master 53]# python camping.py --start-date 2019-07-10 --end-date 2019-07-11 --stdin < parks.txt
usage: camping.py [-h] --start-date START_DATE --end-date END_DATE [--stdin]
                  park [park ...]
camping.py: error: the following arguments are required: park

(camp) [root@camp recreation-gov-campsite-checker-master 54]# python camping.py --start-date 2019-07-10 --end-date 2019-07-11 --stdin park < parks.txt
usage: camping.py [-h] --start-date START_DATE --end-date END_DATE [--stdin]
                  park [park ...]
camping.py: error: argument park: invalid int value: 'park'

(camp) [root@camp recreation-gov-campsite-checker-master 56]# python camping.py --start-date 2019-07-10 --end-date 2019-07-11 --stdin parks.txt
usage: camping.py [-h] --start-date START_DATE --end-date END_DATE [--stdin]
                  park [park ...]
camping.py: error: argument park: invalid int value: 'parks.txt'

Add email notifier

This is a simple email notifier using swaks. It requires an account and smtp server that can be used to send emails.

I believe if you want to use gmail to send emails this auth method will not work, so I left the json import at the top of the notifier for future use with a more secure authorization.

The example below sends to both an email and sms. Android Gmail now only appears to allow a different notification sound based in sms messages. The notification sound based on email labels no longer seems to be available.

It is quick and dirty. There is no checking if swaks succeded.


import json
import random
import sys
import time
import os

from hashlib import md5

from camping import SUCCESS_EMOJI

from datetime import datetime

MESSAGE_FILE = "message.txt"

available_site_strings = []
for line in sys.stdin:
    line = line.strip()
    if SUCCESS_EMOJI in line:
        name = " ".join(line.split(":")[0].split(" ")[1:])
        available = line.split(":")[1][1].split(" ")[0]
        s = "{} site(s) available in {}".format(available, name)
        available_site_strings.append(s)

if available_site_strings:
    message = " ๐Ÿ•๐Ÿ•๐Ÿ•\n"
    message += "\n".join(available_site_strings)
    message += "\n" + "๐Ÿ•" * random.randint(5, 20)  # To avoid duplicate messages.
    
    with open(MESSAGE_FILE, "w") as f:
        f.write(message)

    os.system('swaks --body "message.txt" --to [email protected],[email protected] --from "[email protected]" --server smtp.foo.com --auth LOGIN --auth-user "[email protected]" --auth-password "foopassword" -tls --header "Subject: Campsites Available"')
    sys.exit(0)
else:
    now = datetime.now()
    print(now , "No campsites available, not messaging ๐Ÿ˜ž")
    sys.exit(1)

This project appears to be broken

2020-11-23 13:23:25,596 - 1710 - DEBUG - Querying for 231927 with these params: {'start_date': '2020-05-01T00:00:00.000Z'}
Something went wrong
2020-11-23 13:23:25,918 - 1710 - ERROR - Something went wrong
Traceback (most recent call last):
File "camping.py", line 257, in
code = 0 if main(parks) else 1
File "camping.py", line 158, in main
park_id, args.start_date, args.end_date, args.campsite_type
File "camping.py", line 89, in get_park_information
resp = send_request(url, params)
File "camping.py", line 50, in send_request
resp.status_code, url, resp.text
RuntimeError: ('failedRequest', 'ERROR, 400 code received from https://www.recreation.gov/api/camps/availability/campground/231927/month?: {"error":"Please select a date within the next two years."}\n')

API Change?

I'm a beginner and was very happy when I got this all to work on my RaspberryPi 4 but as of a day or two ago I get a 404 error.

Single Date Search Issue

Whenever I try to search for single date such as "/camping.py --start-date 2021-06-09 --end-date 2021-06-10 --parks 232112" the program returns 0 sites even if there are plenty available. I can fix this with a fork that cuts out the "consecutive_nights" def but I am having trouble fixing the bug in camping.py itself. I think it has something to do with the "if len(r) < nights:" in the consecutive nights definition not handling a single night, but can't quite figure it out. Not sure if anyone else can get a single night search working with the program as is.

Script is not working for me

When I run this script it error 403, forbidden. I have been trying to figure out what the problem is, but I am too new to python:

python3 camping.py --start-date 2019-06-23 --end-date 2019-06-25 7232447
There are campsites available from 2019-06-23 to 2019-06-25!!!
Traceback (most recent call last):
File "camping.py", line 115, in <module>
resp_json = send_request(park_id, payload)
File "camping.py", line 39, in send_request
resp.status_code, url, resp.text
RuntimeError: ('failedRequest', 'ERROR, 403 code received from https://www.recreation.gov/api/camps/availability/campground/7232447: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"&gt;\n&lt;HTML&gt;&lt;HEAD&gt;&lt;META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">\n<TITLE>ERROR: The request could not be satisfied</TITLE>\n</HEAD><BODY>\n<H1>403 ERROR</H1>\n<H2>The request could not be satisfied.</H2>\n<HR noshade size="1px">\nRequest blocked.\n\n<BR clear="all">\n<HR noshade size="1px">\n<PRE>\nGenerated by cloudfront (CloudFront)\nRequest ID: DmqulFd2PBxlrq4dKFBCiy380B7wv1Lu9WsL8WdiSCkTBwND9A7Wkg==\n</PRE>\n<ADDRESS>\n</ADDRESS>\n</BODY></HTML>')"

Partial availability between dates

Hey there, great tool. I thought it would be helpful to have the option to search for partial availability between dates. This would be useful for high-demand campgrounds that are completely booked but have occasional openings due to cancellations. Some of us are flexible on traveling, and instead are looking for any opening within a wide date range. This is vaguely related to #7, but I don't want to actually book the reservation through the scraper.

As of now, the tool lists a site if it is available for all dates between --start-date and --end-date. We could add an input flag that instead returns a site if there are any openings (at least one day) between --start-date and --end-date.

I have a proof-of-concept working and can submit a PR if you're interested. Thanks!

User agent code broken

Hi, so I've had great success with this code in the past (around two months ago was my last successful use). Upon trying to use it again, though, I'm getting a strange error (that re-installing didn't fix):

When I run the command python3 camping.py --start-date 2022-12-10 --end-date 2022-12-25 --parks 232448 232450 232447 232449

I get back:

recreation-gov-campsite-checker-master % python3 camping.py --start-date 2022-12-10 --end-date 2022-12-15 --parks 232448 232450 232447 232449
Error occurred during loading data. Trying to use cache server https://fake-useragent.herokuapp.com/browsers/0.1.11
Traceback (most recent call last):
  File "/recreation-gov-campsite-checker-master/myvenv/lib/python3.9/site-packages/fake_useragent/utils.py", line 154, in load
    for item in get_browsers(verify_ssl=verify_ssl):
  File "/recreation-gov-campsite-checker-master/myvenv/lib/python3.9/site-packages/fake_useragent/utils.py", line 99, in get_browsers
    html = html.split('<table class="w3-table-all notranslate">')[1]
IndexError: list index out of range
Traceback (most recent call last):
  File "/recreation-gov-campsite-checker-master/myvenv/lib/python3.9/site-packages/fake_useragent/utils.py", line 154, in load
    for item in get_browsers(verify_ssl=verify_ssl):
  File "/recreation-gov-campsite-checker-master/myvenv/lib/python3.9/site-packages/fake_useragent/utils.py", line 99, in get_browsers
    html = html.split('<table class="w3-table-all notranslate">')[1]
IndexError: list index out of range

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/recreation-gov-campsite-checker-master/myvenv/lib/python3.9/site-packages/fake_useragent/utils.py", line 64, in get
    with contextlib.closing(urlopen(
  File "/opt/anaconda3/lib/python3.9/urllib/request.py", line 214, in urlopen
    return opener.open(url, data, timeout)
  File "/opt/anaconda3/lib/python3.9/urllib/request.py", line 523, in open
    response = meth(req, response)
  File "/opt/anaconda3/lib/python3.9/urllib/request.py", line 632, in http_response
    response = self.parent.error(
  File "/opt/anaconda3/lib/python3.9/urllib/request.py", line 561, in error
    return self._call_chain(*args)
  File "/opt/anaconda3/lib/python3.9/urllib/request.py", line 494, in _call_chain
    result = func(*args)
  File "/opt/anaconda3/lib/python3.9/urllib/request.py", line 641, in http_error_default
    raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 503: Service Unavailable

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/recreation-gov-campsite-checker-master/camping.py", line 13, in <module>
    from clients.recreation_client import RecreationClient
  File "/recreation-gov-campsite-checker-master/clients/recreation_client.py", line 11, in <module>
    class RecreationClient:
  File "/recreation-gov-campsite-checker-master/clients/recreation_client.py", line 19, in RecreationClient
    headers = {"User-Agent": UserAgent().random}
  File "/recreation-gov-campsite-checker-master/myvenv/lib/python3.9/site-packages/fake_useragent/fake.py", line 69, in __init__
    self.load()
  File "/recreation-gov-campsite-checker-master/myvenv/lib/python3.9/site-packages/fake_useragent/fake.py", line 75, in load
    self.data = load_cached(
  File "/recreation-gov-campsite-checker-master/myvenv/lib/python3.9/site-packages/fake_useragent/utils.py", line 250, in load_cached
    update(path, use_cache_server=use_cache_server, verify_ssl=verify_ssl)
  File "/recreation-gov-campsite-checker-master/myvenv/lib/python3.9/site-packages/fake_useragent/utils.py", line 245, in update
    write(path, load(use_cache_server=use_cache_server, verify_ssl=verify_ssl))
  File "/recreation-gov-campsite-checker-master/myvenv/lib/python3.9/site-packages/fake_useragent/utils.py", line 187, in load
    ret = json.loads(get(
  File "/recreation-gov-campsite-checker-master/myvenv/lib/python3.9/site-packages/fake_useragent/utils.py", line 84, in get
    raise FakeUserAgentError('Maximum amount of retries reached')
fake_useragent.errors.FakeUserAgentError: Maximum amount of retries reached

Has anyone else had this error? And if so, do you know how to fix it? Thanks so much!

Filter by Equipment in addition to Site Type

I'd like to be able to filter results by equipment (for example Trailer vs RV/Motorhome vs Tent). Does the API expose this option? If so could you add it? I can also support if you're open to community PRs.

Recreation.gov API

Just a question. How did you figure out what the recreation.gov API was? Was it through monitoring requests or is there a place where the API can actually be viewed?

Trouble implementing in cron

Hi there, I'm able to get the script to run perfectly when launched from the terminal window, but run into issues when I try to command it through cron. Could anyone post the syntax their using for their cronjob? Mine is below. seems to be able to check the sites fine but has trouble handing off to the notifier.

(sorry if its obvious, I'm new and grateful for any pointers)

cronjob:

          • cd /home/pi/Documents/Python/recreation-gov-campsite-checker && /home/pi/Documents/Python/recreation-gov-campsite-checker/myvenv/bin/python /home/pi/Documents/Python/recreation-gov-campsite-checker/camping.py --start-date 2021-04-22 --end-date 2021-04-24 --nights 1 --stdin < parks.txt | python notifier.py @xxx >> ~/cron.log 2>&1

cron.log output:
Traceback (most recent call last):
File "notifier.py", line 8, in
from camping import SUCCESS_EMOJI
File "/home/pi/Documents/Python/recreation-gov-campsite-checker/camping.py", line 10, in
from dateutil import rrule
ImportError: No module named dateutil

Scraper works but does not help users access high demand sites on recreation.gov

Greetings,

Thanks for working on this neat project. My Python skills are much lower than @banool's.

I ran this script on my homelab computer after working through some error bugs due to my python version lacking some needed frameworks. I also created a screencast showing it working which may help less skilled users.

The reason I am writing in though is I do not see how this web scraper can help folks get easier access to high demand sites. In my testing I found that this tool worked best with sites that have low demand and are easy to book on the parent site.

Is this what you're experiencing in your test?

If it is would you consider working on automating the booking process for sites or permits on recreation.gov?

The biggest barrier for many folks is that when new sites are made available at 10am PST daily, they are quickly booked within seconds in many cases. As is such a web automation script launched at 7AM PST would allow folks to access new campsites in micro seconds as soon as they are available. Before, the rec.gov site was updated (fall2018) I was using just such a script. This is a link to a screencast showing it in action.

Would you be open to building something like for the open source community?

Thanks,
~B

Twitter Notifcations not working

python camping.py --start-date 2024-07-19 --end-date 2024-07-21 --parks 233911 | python notifier.py @my_twitter_handle

Here's my output from the above command:

Traceback (most recent call last):
File "/mnt/raid/git/recreation-gov-campsite-checker/notifier.py", line 102, in
main(sys.argv, sys.stdin)
File "/mnt/raid/git/recreation-gov-campsite-checker/notifier.py", line 69, in main
_create_tweet(tweet, tc)
File "/mnt/raid/git/recreation-gov-campsite-checker/notifier.py", line 27, in _create_tweet
resp = api.PostUpdate(tweet)
File "/mnt/raid/git/recreation-gov-campsite-checker/myvenv/lib/python3.10/site-packages/twitter/api.py", line 1177, in PostUpdate
data = self._ParseAndCheckTwitter(resp.content.decode('utf-8'))
File "/mnt/raid/git/recreation-gov-campsite-checker/myvenv/lib/python3.10/site-packages/twitter/api.py", line 4908, in _ParseAndCheckTwitter
self._CheckForTwitterError(data)
File "/mnt/raid/git/recreation-gov-campsite-checker/myvenv/lib/python3.10/site-packages/twitter/api.py", line 4928, in _CheckForTwitterError
raise TwitterError(data['errors'])
twitter.error.TwitterError: [{'message': 'You currently have access to a subset of Twitter API v2 endpoints and limited v1.1 endpoints (e.g. media post, oauth) only. If you need access to this endpoint, you may need a different access level. You can learn more here: https://developer.twitter.com/en/portal/product', 'code': 453}]
(myvenv) root@shawn-UCSC-C220-M5SX:/mnt/raid/git/recreation-gov-campsite-checker#

Option for weekends only?

Is there a way to only check weekends or will I need to create a separate script for each date range?

running in cron and notifications

I've got this running well on my Debian system, using this command:
python3.7 camping.py --start-date 2021-08-01 --end-date 2021-08-13 --nights 1 --stdin < parks-sierras.txt

I'm able to get it to run in cron (have to use the full paths in the cron command) but cannot get it to notify. I'd like to receive a system notification and bell, as well as an email. Any ideas?

Another option would be for it to run as a script in terminal. Actually might prefer that so I can monitor the output. I've read the .sh script from the original 'yosemite-camping' github site but not sure how to ge it to run this version..

cc. @ccritter

certificate error

Thank you for putting this tool together!
Not sure if this is on my end, or if the tool no longer works, but here is the error I'm seeing while running:

urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate in certificate chain (_ssl.c:1056)>

Failure to run

Hi there,

I'm having difficulty getting this script to compile on my local machine. I followed the install instructions, but the script (camping.py) seems to be getting hung up on the clients.recreation_client module not being installed. I've attempted to fix this but nothing seems to be working. Any advice here would be super appreciated.

I'm on Mac and using python 3.9 in case any of this is relevant.

FakeUserAgentError

I'm fairly new to python, but want to try to figure this out. When I run the script, I get the following error:

fake_useragent.errors.FakeUserAgentError: Maximum amount of retries reached

Can anyone help describe what I should do to fix this?

request to include site info that is available?

Would it be possible on the output to show a list of sites available within a campsite?
Maybe push them to a campsite.out file?

my thoughts are this would help on the reservation selection if you had a specific site in mind.... a secondary script could parse through a campsite.out file and notify if/when that site in campsite xyz was available.

Question about API

I've been searching for docs on the api but haven't been able to find anything. Would you be able to point me to the site for the api's docs?

CloudFront

Anyone else getting request blocked CloudFront errors?

BUG - type-hint incompatibility in python 3.7

I used python 3.7 as suggested in the README but when running:
python camping.py --start-date 2018-07-20 --end-date 2018-07-23 --parks 232448 232450 232447 232770
I got the following error:
Traceback (most recent call last): File "camping.py", line 275, in <module> def remove_comments(lines: list[str]) -> list[str]: TypeError: 'type' object is not subscriptable

solution can be either:

  1. use higher version of python (and update the README)
  2. remove the type annotation in line 275 to make it more compatible with earlier python versions:
    def remove_comments(lines: list[str]) -> list[str]: --> def remove_comments(lines):

Always returns 0 availability

Every time I run the script, even on campsites that have availability shown on the recreation.gov website, I get 0 availability. I think I've pinpointed the issue in the code: When checking for consecutive nights, the range on line 185 evaluates to range(0, 0) which will not iterate and produce an empty list for long_enough_consecutive_ranges. I'm not sure what the correct area to fix it would be:

(assuming input values of start_date 2021-06-01 and end_date 2021-06-03)

  1. Change the range to range(0, len(r) - nights + 1). EDIT: just tried this, got an IndexError on line 190 so I suppose that's not it.
  2. Fix the dates set in get_num_available_sites to include the end_date (possibly by changing the range start from 1 to 0?):
    dates = [end_date - timedelta(days=i) for i in range(1, num_days + 1)]

    Otherwise, the value of the dates set will be {'2021-06-02T00:00:00Z', '2021-06-01T00:00:00Z'}. This makes nights equal 2, which is what I would expect. However, the desired_available will only have those two dates (so len(r) also equals 2), which causes the above hiccup with the range in consecutive_nights.

Return Value When Lookup Fails Is The Same As Return Value When No Campsites Found

About 5% of the time the lookup fails, due to the website being busy and returns an error. If I recall correctly, this throws an exception and the return value is also 1. Since the output of the program clearly lists success or failure, it is not necessary to return 1 if no campsites are found and 0 if campsites are found. I changed it to always return 0 and if it fails and throws an exception, i have a shell script that tries a second time after a few seconds. Otherwise as busy times, it will not find campsites.

Script should return 0 on successful completion, even if no campsites are available

Non-zero exit codes should be used to indicate errors that occur during script execution. As long as camping.py completes without exceptions, the script should return a 0. If a user needs to act on whether or not campsites were available, they can do so through grepping the output.

Changing this behavior may break some user scripts, but it will align camping.py with standard scripting practices.

EDIT: Removed portion about cron job behavior. That was just due to output.

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.